Reputation: 29
I'm struggling to implement a function jump table and hoping someone can help out.
Here's one of the code examples I've tried, without success. It appears that the program just goes off into space when the jump table is called. Here's the setup and call to a function that is meant to set up the jump table call.
; call the next routine
movlw 1 ; this should call the second function
movwf programIndex
call runCurrentProgram
And here's where the PC should be set up based on the programIndex value. I'm unsure about the need for a multiplier. When I look at the table assembly output, it appears to be just 2 words, so the multiplier seems unnecessary.
runCurrentProgram:
bcf programIndex, 7 ; clear high bit for rotate
rlf programIndex, W ; multiply index by two
addlw low programTable
movwf tabLow ; tabLow is a temporary variable
movlw high programTable
btfsc STATUS,STATUS_CARRY_POSITION
addlw 1
movwf PCLATH
movf tabLow,w
movwf PCL
And finally, here's how I defined the jump table.
programTable:
goto Function1
goto Function2
As mentioned earlier, both Function1 and Function2 are contained in a separate library. They work just fine if called directly from the control program.
I've found several examples of similar code, using goto's, BRA or BRW but none have been specifically for the PIC16F1503 and have not worked for me.
Can anyone help me out here?
Thanks to @TimRoberts for the suggestion. Replacing with DW did not work. Replacing with BRA DID work. I'm still trying to understand the use of the PCL, PCLATH code, but I can see clearly (from the listing) that DW has rendered the absolute address, i.e. the address the linker allocates to the functions, while BRA generates something else.
The listing shows Function1 loaded at 014B and Function2 at 016F and the code generated with DW and BRA is shown below.
340 0100 324A bra Function1
341 0101 326D bra Function2
340 0100 014B dw Function1
341 0101 016F dw Function2
I also did some experimentation to try and understand PCL better by loading PCLATH and PCL with the absolute address of one of the functions (obtained from the assembler/linker listing) and was able to satisfy myself that provided PCLATH is set to the correct register bank, and PCL is set to the function address in the bank, then everything works just fine. I'll now spend a bit more time working on the dynamic table entry selection code.
Upvotes: 0
Views: 85
Reputation: 29
I have the following working code which uses BRA to jump to the required function (using its relative address). The linker option -pprogramTable=100h is used in the build to locate the jump table at 0x100.
; The jump table is located on the start of a page boundary 0x100
global programTable
psect programTable,global,class=CODE,delta=2
programTable:
bra f1
bra f2
bra f3
bra endOfTable
endOfTable: ; reset the index back to start of table
clrf programIndex
return
Here's the code that uses the jump table.
runCurrentProgram:
movf programIndex,w
addlw low programTable
movwf tabLow ; tabLow is a temporary variable
movlw high programTable
btfsc STATUS,STATUS_CARRY_POSITION
addlw 1
movwf PCLATH
movf tabLow,w
movwf PCL
Upvotes: 1