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