Problem: how to allocate bit flags and allow for code re-use.
Example:
I have a project that has several modules generated from a combination of common code and module specific code. I/O code is common, what is done with the I/O is module specific. I have several bit flags that are common and some flags unique to each module. I wanted code that is clean: for example, flag X might be bit 3 of byte 9 in one module, bit 7 of byte 10 in another module. As I use flags in my code way more often than bytes, I put them in the common bank when the module is a 16C57 (not all output modules run on the same model PIC)
I have written some macros:
BYTEALLOC allocate a byte of storage
BITALLOC allocate
BITON turn on a flag
BITOFF
IFBITON do next if bit on
IFBITOFF
Sample code
NEXTBYTEADDR SET 8 ; next free byte of storage
BITALLOC FRED ; allocate bit flag
......
BITON FRED ; set bit flag
.......
IFBITON FRED ; is flag set?
GOTO PROC1 ; yes!
Sample macro source:
BYTEALLOC MACRO VAR
VAR EQU NEXTBYTEADDR
NEXTBYTEADDR SET NEXTBYTEADDR+1
ENDM
BITALLOCV SET 0 ; no bits allocated yet
BITALLOC MACRO VAR
IF BITALLOCV==0
BYTEALLOC BIT_FLAGS ; flags in register BIT_FLAGS
ENDIF
IF BITALLOCV==8
BYTEALLOC BIT_FLAGS1 ; flags in register BIT_FLAGS1
ENDIF
IF BITALLOCV==.16
BYTEALLOC BIT_FLAGS2 ; flags in register BIT_FLAGS2
ENDIF
IF BITALLOCV==.24
BYTEALLOC BIT_FLAGS3 ; flags in register BIT_FLAGS3
ENDIF
IF BITALLOCV==.32
BYTEALLOC BIT_FLAGS4 ; flags in register BIT_FLAGS4
ENDIF
IF BITALLOCV==.40
BYTEALLOC BIT_FLAGS5 ; flags in register BIT_FLAGS5
ENDIF
VAR EQU BITALLOCV
BITALLOCV SET BITALLOCV+1
ENDM
BITMACRO MACRO BITREQ,CASE
BMV1 SET BITREQ/8
BMV2 SET BITREQ-(8*BMV1)
IF CASE==0
BTFSC BIT_FLAGS+BMV1,BMV2 ; do next if bit is set
ENDIF
IF CASE==1
BTFSS BIT_FLAGS+BMV1,BMV2 ; do next if bit is not set
ENDIF
IF CASE==2
BSF BIT_FLAGS+BMV1,BMV2 ; set bit
ENDIF
IF CASE==3
BCF BIT_FLAGS+BMV1,BMV2 ; clear bit
ENDIF
ENDM
IFBITON MACRO BIT
BITMACRO BIT,0 ; check if bit on
ENDM
IFBITOFF MACRO BIT
BITMACRO BIT,1 ; check if bit off
ENDM
BITON MACRO BIT
BITMACRO BIT,2 ; turn bit on
ENDM
BITOFF MACRO BIT
BITMACRO BIT,3 ; turn bit off
ENDM
There are some limits: all BITALLOC's must be together, no other variables can be placed between them. There are no bank tests, so all flags must be in a common bank (for a 57) or you have to make sure you are in the right bank outside the macros.
What I find most useful is that I don't need to remember which byte a flag is in: I used to often forget which byte a flag was in. When I change chips, I just have to change the NEXTBYTEADDR value.
I put all 'common' flags in one include file, makes life way easier.
<edtodd@sni.net> Ed Todd