OK, here's what I believe is a better solution...
First, I have decided to use the "caller fixes PCLATH" method of page management and use the following macro;
Code:
; far call macro ** for far (long) gotos, use the MPASM psuedo lgoto k
_fcall macro subroutine_name
local __fcall_here
lcall subroutine_name
pagesel __fcall_here
__fcall_here:
endm
Basically, it defines a local variable so the current page can be restored upon return of the long call. The MPASM lcall psuedo generates the page selection code for the subroutine you are calling, and the subroutine is called. Upon return, the psuedo pagesel restores the original page bits.
However, I have found that the above code will not work properly when calling a table, so I have come up with the following routine;
Code:
; table call macro
_tcall macro table
movwf temp ; save W
local __tcall_here
pageselw table ; select the proper page
movfw temp ; restore W
call table
pagesel __tcall_here
__tcall_here:
endm
Same basic principle, but notice the use of pagesel
w instead of pagesel for the table! This routine also preserves W as it is changed upon using pageselw.
So, all I have done now is gone back and changed "call" to "_tcall" for any table call I make. I am still using the above mentioned checks on the tables to make sure they don't cross the 256 word boundary.
Any "module" that I am working with has the page bits set before entering that module... any call outside of that module (table or otherwise) will use _tcall or _fcall to make sure the page bits are restored upon return -- so the page bits are always set to the active module. When calling to anything within the active module, simply use the standard call instruction -- Just make sure the active module doesn't cross any 2K page boundary! (I am going to also look into the MPASM keyword 'code'.) If you need to "goto" a far module, use the MPASM pseudo lgoto.