Page 1 of 1

escape from nested subroutines

Posted: Mon May 22, 2017 7:32 am
by pifu
Hi all,
I need a way to escape from any level of nested subroutines and get back to the first caller level (somewhat like an exception handler), ensuring that its last RTS will be handled correctly.
Neither the main loop nor the subroutines make explicit use of the stack (i.e., it is used only by the jsr/rts mechanism).
Do you think it is enough to have the stack pointer saved and restored, as in following example?

Code: Select all

;LEVEL 0 - MAIN
        tsx
        stx CPU_STACK_PTR
main_loop:
        ...
        jsr sub1
        ...
        jsr sub2
        ...
        <test_end_loop here>
        bne main_loop
        ...
        rts

sub1:   ...
        jsr sub1_1
        ...
        <some test here>
        bne +
        jmp exception
+       ...
        jsr sub1_2
        ...
        rts

...

sub1_2: ...
        <some test here>
        bne +
        jmp exception
+       ...
        rts

;EXCEPTION HANDLER
exception:
        ...
        <do some useful stuff>
        ...
        ;ESCAPE TO LEVEL 0 - MAIN
        ldx CPU_STACK_PTR
        txs
        jmp main_loop

Re: escape from nested subroutines

Posted: Mon May 22, 2017 7:55 am
by GARTHWILSON
It looks ok, unless something else besides MAIN might try the same thing and overwrite CPU_STACK_PTR.

Where does the RTS at the end of main_loop return to? Is there anything higher to call it, or does the program counter just slide into main_loop from the reset routine? If it does, why not just jump back to somewhere near the end of the reset routine where the stack pointer get initialized with LDX #$FF, TXS?

Re: escape from nested subroutines

Posted: Mon May 22, 2017 8:11 am
by pifu
Thank you.
Yes, CPU_STACK_PTR is not used elsewhere. The RTS at the end of main_loop must return to a BASIC program.
---
BTW: I think I'll study your 6502 STACK Treatise...

Re: escape from nested subroutines

Posted: Tue May 23, 2017 1:15 am
by CurtisP
This is exactly how you do it. It's why the TSX and TXS instructions exist.

Re: escape from nested subroutines

Posted: Tue May 23, 2017 3:07 am
by GARTHWILSON
CurtisP wrote:
It's why the TSX and TXS instructions exist.
Actually, there are lots of cool things you can do with them, as covered in the stacks treatise; stack frames, local variables, using data inlined in the program, and more.
pifu wrote:
BTW: I think I'll study your 6502 STACK Treatise...
I do wish that part of my site were ore popular. I guess the people who need it the most don't realize/appreciate the potential of stacks. (And BTW, it's stacks, plural, not just the page-1 hardware stack, but also virtual stacks.) The most popular section of the site is the 6502 primer, followed by the section on scaled-integer math and large look-up tables. Last month, visitors requested more than a thousand page downloads per day on average (36,000 for the month).

Re: escape from nested subroutines

Posted: Tue May 23, 2017 9:25 am
by pifu
BTW, I'm coding an interpreter for executing OCaml bytecode on a 6510-based hw (i.e., the C64; but it should be easily generalized).
The interpreter, as you can imagine, makes heavy use of a stack: not only for math, but also for function calls, exception frames, and so on. Some detail of the project are here.