I have a 16-bit address in the A register. I need to make a long jump to this address, however it seems there is no way to do this with assembly code. By looking at some assembly produced by Keil, when they want to do this type of jump then end up doing:
LJMP ?C?ICALL
If you speak about the 51th controller and you need to make a jump to an explicit 16-bit address, you may load this address into DPTR (DPH, DPL), clear your accumulator and use JMP @A+DPTR. Michael.
Thanks!
If Ted is going to be doing this from C interrupt function to C interrupt function, he's still going to have problems, I think. FWIW, I've posted a means to re-vector an ISR in Ted's other thread. --Dan Henry
Hey Dan, I ended up doing it this way:
UART_0_INT EQU 23h ; . . . CSEG AT UART_0_INT LJMP UART_0_ISR ; . . . UART_0_ISR: ; if (!missionCodeIsRunning()) { ; bootloader_uart0_isr(); ; else ; mission_uart0_isr(); ; } LCALL _?missionCodeIsRunning MOV A,R7 JZ bootloader_uart0 JMP mission_uart0 bootloader_uart0: LJMP uart0_isr mission_uart0: LCALL _?goAddr MOV DPH,R6 MOV DPL,R7 CLR A ADD A, #UART_0_INT JMP @A+DPTR
Ted, You may be posting only sections of the code, so what I'm not seeing may well be present, but... Are you saving the interrupted states of PSW, ACC, R6, R7, DPTR, and whatever registers missionCodeIsRunning() also modifies? Do both uart0_isr() and the destination ISR jumped to through DPTR know to how to restore these same registers? --Dan Henry
Good point. I'll have to modify my code to account for the registers used in the functions. Thanks.
That's why in the assembly code I posted earlier left the MCU with nothing modified at the time of the "jump". If you had a single variable of "bit" type that holds the boot/mission status you could do a bit test (which doesn't disturb the MCU state) and "jump" accordingly to boot or mission ISR's. With no MCU state disturbed using this technique, you can write the ISR's without worrying about what's been modified at entry. More ideas, which by now you've got plenty of. --Dan Henry
I hope your returning with RETI not RET in those functions your calling from your ISR. If you don't RETI you'll never get another interrupt until you reset (or stumble across a RETI). - Mark
I hope your returning with RETI not RET in those functions your calling from your ISR. If you don't RETI you'll never get another interrupt until you reset (or stumble across a RETI). I am. Thanks.