A METHOD FOR PIC ASSEMBLY CODE INTEGRATION AND REUSE - Part 8 Allocating flags ---------------- If you are programming for code reuse it doesn't look correct to assign flags belonging to different components with something like: PERSISTENT flags #define MDIerror flags,0 #define KEYcapsLock flags,1 #define EEPerror flags,2 ...etc. ...because for a different project you might need only some of these components along with others, and that would force you to reassign flags by hand, changing them in duplicate source files or doing all allocations in the main source file. None of these look very neat nor practical. On the other hand, placing each component's flags on a local non-persistent variable would be a waste of RAM if you are to assign only two or three flags for each component, which I consider normal. A macro that allocates flags would be useful, and making it is no big deal. As for now I'm not differentiating persistent flags from non-persistent because I don't see much to win. The reason to allocate non-persistent data is to save RAM by permitting overlapping. Flags, being only one bit long, don't add much unless a component uses a lot of flags, and in that case those flags could be placed on local non-persistent variables instead of using the macro. Surely, if you are desperate for RAM and could profit from it, this macro could be expanded to handle non-persistent flags. The algorithm I use to allocate the flags is simply the following: * If there is no persistent byte available for flags allocate a new one * Allocate the flag on the next bit available on that byte This is handled by the following macro: ----------------------------- cut here --------------------------------- ; ***************************************** ; * RESERVE_FLAG nameByte, nameBit * ; ***************************************** RESERVE_FLAG MACRO nombreByte, nombreBit IF BYTE_FLAGS#v(RAM_PAGE)==H'FF' BIT_FLAGS#v(RAM_PAGE) SET 8 BYTE_FLAGS#v(RAM_PAGE) SET 0 ELSE BIT_FLAGS#v(RAM_PAGE) SET BIT_FLAGS#v(RAM_PAGE)+1 ENDIF IF BIT_FLAGS#v(RAM_PAGE)==8 BYTE_FLAGS#v(RAM_PAGE) SET BYTE_FLAGS#v(RAM_PAGE)+1 BIT_FLAGS#v(RAM_PAGE) SET 0 PERSISTENT FLAGS#v(BYTE_FLAGS#v(RAM_PAGE)) ENDIF nameByte EQU BYTE_FLAGS#v(RAM_PAGE) nameBit EQU BIT_FLAGS#v(RAM_PAGE) ENDM ----------------------------- cut here --------------------------------- Which needs the following initialization: ----------------------------- cut here --------------------------------- BYTE_FLAGS0 SET H'FF' BYTE_FLAGS1 SET H'FF' ----------------------------- cut here --------------------------------- This, again, is for a two-RAM-page processor. I guess that if you only add "BYTE_FLAGS2" and "...3" it would work on a four-page. The macro returns a reference to a register and a bit number for you to allocate the flag with something like: RAM_PAGE SET 0 RESERVE_FLAG XXXmyFlagByte,XXXmyFlagBit #define XXXmyFlag FLAGS#v(XXXmyFlagByte),#v(XXXmyFlagBit) Or, for a 1-page flag and to avoid messages: RAM_PAGE SET 1 RESERVE_FLAG XXXmyFlagByte,XXXmyFlagBit #define XXXmyFlag FLAGS#v(XXXmyFlagByte) & H'7F',#v(XXXmyFlagBit) The ideal thing would had been to be able to do something like: FLAG XXXmyFlag ...but it is not possible, as far as I know, because the assembler won't perform substitutions in a "#define". It's a pity, not only it would save some cut and pasting and typing, it would also be much clearer to read. I hope I'm missing something or, if I'm not, that future versions of MPASM include something to handle this. As always, I appreciate your feedback. Regards! Andres adjordj@aleph.fi.uba.ar