Mike Keitz says:
...There are two situations where "paging" of the program memory is an issue. For CALL or GOTO, the pages are 800h instructions long [on the more advanced PIC processors]. Most short programs don't need to be concerned with them. [HOWEVER] For writing to PCL, the pages are only 100h instructions long. So [any] 256-value table definitely crosses one of those pages. And the program will crash when the index into the table gets large enough if your table-access code doesn't set up PCLATH properly.
[Here is some code that sets up PCLATH correctly]movlw high (TABLE_START) movwf pclath movf index,w addlw TABLE_START skpnc incf pclath,f movwf pcl TABLE_START retlw ...
If the table is called such that W is the index:addlw TABLE_START movwf temp rlf known_zero,w addlw high(TABLE_START) movwf pclath movf temp,w movwf pcl TABLE_START retlw ...
Andrew Warren of Fast Forward Engineering - San Diego, California https://geocities.restorativland.org/SiliconValley/2499/ says:
...write table-lookup code [with] automatic page-crossing checks built in.
I generally do it like this:ADDWF PCL TABLE1: DT "Test" IF ((HIGH ($)) != (HIGH (TABLE1))) ERROR "TABLE1 CROSSES PAGE BOUNDARY!" ENDIF
P.S. By the way, another common way that a newly-inserted CALL can screw up previously-working code is if the called routine changes the PCLATH register... Or if your previously-working code expected the W register or STATUS flags to remain unchanged across the portion of the program where you inserted your CALL.
Rich Leggitt says:
...something like this should work for arbitrary table of any length located anywhere in the program space.... movlw high string ; point to a string movwf look_hi ; in reality, a macro... movlw low string movwf look_lo call process ; go process it ... ; subroutine to process string at look_hi/look_lo process call lookup ; get a byte (this is the magic) ; here, do something with byte in W ; also, return if end of string ; otherwise... goto process ; do it again ; Jump to address in look_hi/look_lo, which presumably is an RETLW. ; Note pointer post increment. ; Equivalent to: W=*look_ptr++ lookup movf look_hi,w ; set PCLATH movwf PCLATH movf look_lo,w ; and get PCL incf look_lo,f ; but post inc skpnz incf look_hi,f movwf PCL ; ok, now jump
|file: /Techref/scenix/lib/mem/tables.htm, 3KB, , updated: 2020/2/15 22:15, local time: 2020/3/30 01:08,
|©2020 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?|
<A HREF="http://www.massmind.org/Techref/scenix/lib/mem/tables.htm"> Table lookups</A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to www.massmind.org!