Mercurial > hg > index.cgi
diff src/progctrl.s @ 119:a6a53e5c04bd
Make a call stack implementation that is more complete and maybe cleaner.
author | William Astle <lost@l-w.ca> |
---|---|
date | Fri, 29 Dec 2023 01:40:39 -0700 |
parents | e74d00ac6b79 |
children | 9d57279c900e |
line wrap: on
line diff
--- a/src/progctrl.s Thu Dec 28 22:00:32 2023 -0700 +++ b/src/progctrl.s Fri Dec 29 01:40:39 2023 -0700 @@ -48,7 +48,7 @@ ldx ,s ; get return address lds freetop ; reset stack to top of memory clr ,-s ; put a flag to stop stack searches (NEXT, RETURN) - sts stackptr ; reset pointer for call stack + sts cstackptr ; reset pointer for call stack clr contstmt ; clear "CONT" destination clr contstmt+1 jmp ,x ; return to caller @@ -106,7 +106,7 @@ ; GOSUB command cmd_gosub jsr parse_lineno ; parse the destination line so return location is after the line number ldd #tok_gosub*256+4 ; stack frame details - bsr callstack_alloc ; make a stack frame + jsr cstack_alloc ; make a stack frame ldx curline ; save current line pointer stx ,u ldx inputptr ; save current input pointer @@ -121,11 +121,11 @@ cmd_pop skip1lda ; set nonzero for POP cmd_return clra ; set zero for RETURN pshs a ; save operation type - bsr callstack_first ; get first entry on call stack + jsr cstack_first ; get first entry on call stack bne cmd_return1 ; brif there's a frame - don't error RG_ERROR ldb #err_rg ; raise RETURN without GOSUB jmp ERROR -cmd_return0 bsr callstack_next ; move to next entry +cmd_return0 jsr cstack_next ; move to next entry beq RG_ERROR ; brif end of stack - raise error cmd_return1 cmpb #tok_gosub ; do we have a GOSUB frame? bne cmd_return0 ; brif not - try again @@ -135,54 +135,6 @@ stx curline ldx 2,u ; get back saved input pointer stx inputptr -cmd_return2 bsr callstack_pop ; clean up call stack +cmd_return2 jsr cstack_popto ; clean up call stack bra cmd_data ; move to end of statement (move past any "ON GOSUB" entries -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Point to the first entry on the call stack; yes this is trivial but it points to the payload, not the header. Also -; sets Z if there is nothing on the stack. -callstack_first ldu stackptr ; get stack pointer - ldb ,u++ ; set flags on frame type and adjust pointer - rts -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Move to the next frame on the call stack; enter with U pointing to a stack frame payload area -callstack_next ldb -1,u ; get length of this frame - leau b,u ; move to the next frame - ldb -2,u ; set flags on frame type code - rts -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Create a stack frame. Enter with the frame type flag in A and the size in B. -; -; The stack frame of size B bytes plus 2 bytes for the length and type flag will be allocated between the actual -; hardware stack and the current call stack pointer. Return with the pointer to the allocated frame in U. As long as -; there are no pointers to anything on the hardware stack, this will allow the stack to be entirely intact after -; the call. -callstack_alloc addb #2 ; account for the header bytes - pshs a,b ; save the type and length - negb ; need a negative offset - leax ,s ; point to current bottom of stack - leas b,s ; make a hole below the stack - leau ,s ; get a pointer to the destination for copying -callstack_alloc0 - lda ,x+ ; copy a byte down - sta ,u+ - cmpx stackptr ; have we reached the top of the stack? - blo callstack_alloc0 ; brif not - stu stackptr ; save the new call stack pointer - puls d ; get back the type and length values - std ,u++ ; save type and length - rts -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Pop the call stack to the end of the frame pointed to by U; this will relocate the hardware stack to close the -; newly made gap in memory. -callstack_pop leau -2,u ; move back to header - ldb 1,u ; get length of frame - leax b,u ; point to element after this frame - sts ,--s ; save the current bottom of the stack - stx stackptr ; save new call stack pointer -callstack_pop0 lda ,-u ; copy a byte up - sta ,-x - cmpu ,s ; at the bottom of the call stack? - bhi callstack_pop0 ; brif not - leas 2,x ; reset the stack pointer (and lose the saved stack pointer value) - rts *pragmapop list