This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to use LJMP with variable address?

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
Which registers do I load up with my address so that the jump to ?C?ICALL succeeds?

Parents Reply Children
  • 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
    I had to ensure that my bootloader code specified NOINTVECTOR as you suggested in an earlier post. Thanks for your help. I still have one more problem, which I posted in another thread.

    -Ted

  • 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.