I'm trying to use simple lookup tables in assembly by adding a certain index to the program counter. It appears to be working in a range of the PCL
(so until 0xff
) but afterwards, when the PCH
comes in to play the PCH
just resets after the addwf
instruction.
How do I prevent the PCH
from resetting after addition? Do I need to manipulate the PCLATH
and PCLATU
in some way so PCH
will keep its value.
I'm using a pic18f25k50 with the mpasm assembler.
So this lookup table works fine:
TABLE_GET_VALUE
movf index, 0 ; memory location = 0x9E
mullw 4
movf PRODL, 0
addwf PC
movf 0x20, 0
return
movf 0x21, 0
return
movf 0x22, 0
return
movf 0x23, 0
return
movf 0x24, 0
return
movf 0x25, 0
return
movf 0x26, 0
return
movf 0x27, 0
return
movf 0x28, 0
return ; memory location = 0xC8
while this one resets the program back to the first instructions:
TABLE_GET_COEFFICIENT
movf index, 0 ; memory location 0x108
mullw 4
movf PRODL, 0
addwf PC
movf 0x30, 0
return
movf 0x31, 0
return
movf 0x32, 0
return
movf 0x33, 0
return
movf 0x34, 0
return
movf 0x35, 0
return
movf 0x36, 0
return
movf 0x37, 0
return
movf 0x38, 0
return ; memory location 0x132
This is one example of a complete way to code the table look up for a PIC18F controller.
;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
MAIN_CODE CODE ; let linker place main program
Main:
movlw 8
call TableOneLookup
bra Main
;------------------------------------------------------------------------------
;
; TableOneLookup
;
; Description: Look up data in table placed in code space
;
; Input: WREG = byte offset in table
;
; Output: WREG = byte from table
;
;------------------------------------------------------------------------------
TABLE_ONE_CODE code
TableOneLookup:
push
clrf TOSU
clrf TOSH
movwf TOSL ; Save offset in to TableOne
addwf TOSL,F ; Double offset in to TableOne
rlcf TOSH,F ; Propagate carry
movlw LOW(TabelOne) ; Add TableOne address low byte
addwf TOSL,F
movlw HIGH(TabelOne) ; Add TableOne address high byte
addwfc TOSH,F
movlw UPPER(TabelOne) ; Add TableOne address upper byte
addwfc TOSU,F
return ; Branch in to TableOne
TabelOne:
DT 0x30
DT 0x31
DT 0x32
DT 0x33
DT 0x34
DT 0x35
DT 0x36
DT 0x37
DT 0x38
end
There are better ways to do this using the assembly language opcodes specifically designed for program memory read operations.