This is a multi-part message in MIME format. ------=_NextPart_000_0017_01C01BCC.E565B460 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit > The problem first appeared, when I tried to implement my macros supporting > the bank switching ... Yes, I remember this, and I also remember I tried to respond with a bunch of macros I've been using for a long time for this purpose. I then noticed that my message never got posted on the list. Now I know why. Wojtek, your message comes to the list with the reply address set to you, not this list. Therefore anyone simply doing a reply will send it only to you unless they notice and manually change the TO address as I did this time. Unfortunately the list server only inserts a REPLY TO address if there isn't one, and won't unconditionally set it to the list address as one would expect. It's annoying to take the trouble to post something you think everyone will get only to have it apparently dissappear. James prefers the list server to work this way, so in the mean time it would be helpful if we all refrained from using a REPLY TO address when sending to the list. Anyway, this message is another attempt to post my bank switching macros to everyone. The attached file is a snippet from my standard include file I use for all modules. This version is only for the 16C architecture. One of my current projects is a 17C, and I have modified the inlude file accordingly but don't want to release it yet until I've had more chance to test with the new code. The full version of STD.INS.ASPIC contains other stuff like general register support, software stack for saving/restoring the general registers, a bunch of simple wrapper macros for error-prone or unobvious instructions (wouldn't you rather say SKIP_WGT "skip if w greater than" than BTFSC STATUS, C ?), USART baud rate setup, subroutine linkage with save/restore, and a few other things. I can post the whole thing someday if there is interest. ------=_NextPart_000_0017_01C01BCC.E565B460 Content-Type: application/octet-stream; name="std.ins.aspic" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="std.ins.aspic" ; ;*********************************************************************** ; ; Bank and page switching. ; ; The assembler variables CURRIB and CURRDB are used to keep track of = the ; current indirect and direct register bank settings. Note that these ; are only assembly time, not run time variables. They reflect which ; bank is currently ASSUMED to be selected. The programmer must = therefore ; play an active role in making sure these variables are set correctly ; if they are used. Proper use can avoid unneccessary bank switching ; instructions. ; nobank equ -1 ;value to indicate current bank is unknown currdb set nobank ;init current direct register bank = assumption currib set nobank ;init current indirect register bank = assumption ; ;******************** ; ; Inline macro functions related to register banks and code pages: ; ; ; BANKOF (ADR) ; ; Returns the direct register bank number containing the RAM address = ADR. ; #define bankof(adr) (((adr) >> 7) & 3) ; ; IBANKOF (ADR) ; ; Returns the indirect register bank number containing the RAM address = ADR. ; #define ibankof(adr) (((adr) >> 8) & 1) ; ; BANKADR (BANK) ; ; Returns the starting address of the direct register bank BANK. ; #define bankadr(bank) (((bank) & 3) << 7) ; ; IBANKADR (BANK) ; ; Returns the starting address of the indirect register bank BANK. ; #define ibankadr(bank) (((bank) & 1) << 8) ; ; These constants provide addresses that are guaranteed to be within ; particular register banks. Note that the bank switching macros = below ; take addresses, not bank numbers. These constants can be used to ; convert from bank numbers to addresses within the banks by using the ; #v(n) assembler syntax. For example, if "b" is a bank number, then: ; ; bank#v(b)adr ; ; is an address within bank b, which can be passed to the DBANKIF = macro, ; for example. ; bank0adr equ bankadr(0) ;address in register bank 0 bank1adr equ bankadr(1) ;address in register bank 1 bank2adr equ bankadr(2) ;address in register bank 2 bank3adr equ bankadr(3) ;address in register bank 3 ; ;******************** ; ; Macro DBANK? ; ; Invalidate the current direct register data bank assumption. ; This macro produces no code, only sets assembly time state. ; dbank? macro currdb set nobank endm ; ;******************** ; ; Macro IBANK? ; ; Invalidate the current indirect register data bank assumption. ; This macro produces no code, only sets assembly time state. ; ibank? macro currib set nobank endm ; ;******************** ; ; Macro UNBANK ; ; Invalidates all register bank assumptions. ; unbank macro dbank? ibank? endm ; ;******************** ; ; Macro DBANKIS ; ; Set the current direct register bank assumption to the bank = containing ; ADR. This macro generates no code to switch the register bank. It = only ; updates assembly time state. ; dbankis macro adr currdb set bankof(adr) ;set assumed direct register bank number endm ; ;******************** ; ; Macro IBANKIS ; ; Set the current indirect register bank assumption to the bank = containing ; ADR. This macro generates no code to switch the register bank. It = only ; updates assembly time state. ; ibankis macro adr currib set ibankof(adr) ;set assumed indirect register bank number endm ; ;******************** ; ; Macro DBANKIF ; ; Set the register bank for direct access to address ADR. This macro ; sets the RP0, RP1 bits of STATUS appropriately. The bank bits are ; not set if they are assumed to already be set correctly as indicated ; by the assembler variable CURRDB. CURRDB is updated to the new ; setting. ; dbankif macro adr local newbank newbank set bankof(adr) ;find 0-3 desired bank number if nregbanks > 1 ;bank bit 0 is meaningful ? if (currdb < 0) || (currdb > 3) || ((currdb & 1) !=3D (newbank & 1)) = ;need update ? if newbank & 1 bsf status, rp0 else bcf status, rp0 endif endif endif if nregbanks > 2 ;bank bit 1 is meaningful ? if (currdb < 0) || (currdb > 3) || ((currdb & 2) !=3D (newbank & 2)) = ;need update ? if newbank & 2 bsf status, rp1 else bcf status, rp1 endif endif endif currdb set newbank ;update current bank assumption endm ; ;******************** ; ; Macro DBANK ; ; Unconditionally set the direct access register bank for access to = address ; ADR. CURRDB is updated. ; dbank macro adr dbank? ;invalidate current register bank = assumption dbankif adr ;set the new register bank endm ; ;******************** ; ; Macro IBANKIF ; ; Set the register bank for indirect access to address ADR, if needed. ; The assembler variable CURRIB is assumed to indicate the current ; indirect register bank setting. CURRIB is updated. This macro ; sets the IRP bit of STATUS appropriately. ; ibankif macro adr local newbank newbank set ibankof(adr) ;find 0-1 desired bank number if nregbanks > 2 ;there is more than one indirect bank ? if (currib < 0) || (currib > 1) || (currib !=3D newbank) ;need update = ? if newbank & 1 bsf status, irp else bcf status, irp endif endif endif currib set newbank ;update current bank assumption endm ; ;******************** ; ; Macro IBANK ; ; Unconditionally set the indirect access register bank for access to ; address ADR. CURRIB is updated. ; ibank macro adr ibank? ;invalidate current register bank = assumption ibankif adr ;set the new register bank endm ------=_NextPart_000_0017_01C01BCC.E565B460-- ***************************************************************** Olin Lathrop, embedded systems consultant in Devens Massachusetts (978) 772-3129, olin@cognivis.com, http://www.cognivis.com -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.