"w. v. ooijen / f. hanneman" wrote: > A short answer: when you move your pointer to the fsr, > exchange bits 5 and 7, so the bit that distinguishes between > the shared and the paged registers (5) was [most of detailed post about low-end PIC indirect addressing omitted for brevity] > I have not found any way to keep both the increment / decrement > and the transfer to FSR trivial. I use this method for incrementing a pointer if I want a buffer to span multiple banks: incf ptr bsf ptr,4 Decrementing could probably be done similarly, except that W is needed: decf ptr movlw 0x01 btfss ptr,4 subwf ptr Normally I use the increment method in a more elaborate macro that handles wrapping the pointer in a ring buffer, and tries to special case some boundary conditions that it can optimize. It's fairly complex; here's a simplified version without all of the optimization (presented as an example; I haven't tested this version): ringadv macro ptr,rbase,rend incf ptr ; increment pointer bsf ptr,4 ; advance bank if needed movf ptr,w ; is pointer at end? xorlw rend movlw rbase ; prepare for worst btfsc status,z movwf ptr ; yes, it was at end, store base endif endm Note that this assumes that the pointer must always be in banked memory. The buffer can't start in unbanked memory (0x00..0x0f). Here's the macro I use to allocate the buffer (again simplified and untested): ringres macro size local s2,bend,bleft s2 set size while s2>0 bend set ($&0xe0)+0x20 ; where's the end of the current bank? bleft set bend-$ ; how many words can we reserve here if bleft>s2 ; more than we need? bleft set s2 ; yes, don't go too far endif res bleft ; reserve the space org ($|0x10) ; skip unbanked register area s2 set s2-bleft ; update remaining size endw endm The way I use this stuff (again simplified and untested): tx_ring_size equ 16 rx_ring_size equ 48 org 0x08 ; vars must be in unbanked regs temp: res 1 tx_ring_ip: res 1 ; transmit ring input tx_ring_op: res 1 ; and output pointers tx_ring_cnt: res 1 rx_ring_ip: res 1 ; receive ring input rx_ring_op: res 1 ; and output pointers rx_ring_cnt: res 1 org 0x90 tx_ring: ringres tx_ring_size tx_ring_end: rx_ring: ringres rx_ring_size rx_ring_end: [...] ; add a byte in W to the transmit buffer ; returns 1 in W if successful, 0 if buffer full xmit: movwf temp ; save character movf tx_ring_cnt,w ; test for buffer already full xorlw tx_ring_size btfsc status,z retlw 0 movf tx_ring_ip,w ; put character into buffer movwf fsr movf temp,w movwf ind,w ringadv tx_ring_ip,tx_ring,tx_ring_end ; advance input pointer incf tx_ring_cnt ; increment count retlw 1