comparison src/stack.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
children
comparison
equal deleted inserted replaced
118:cddbe8bc07e5 119:a6a53e5c04bd
1 *pragmapush list
2 *pragma list
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; Call stack management.
5 ;
6 ; The call stack exists above the interpreter stack. The call stack consists of a sequence of stack records of varying
7 ; sizes which start with an 8 bit length field, then the payload, which will usually begin with an 8 bit type code. The
8 ; bottom of the call stack is stored in cstackptr. The frame sizes must all be <= 125 bytes since a 2 byte frame header
9 ; will be included in the sizing
10 ;
11 ; Allocate a call stack frame of size B and type A. Return a pointer to the payload area of the allocated entry in U
12 cstack_alloc pshs a ; save type flag
13 addb #2 ; account for the frame header
14 negb ; so we can subtract from pointers
15 leax ,s ; point to current stack pointer
16 leas b,s ; move the stack pointer down
17 leau ,s ; point to new stack pointer for data copy
18 cstack_alloc0 lda ,x+ ; copy a byte in the stack down
19 sta ,y+
20 cmpx cstackptr ; have we reached the original call stack?
21 bne cstack_alloc0 ; brif not
22 negb ; get back original size
23 stu cstackptr ; save the new bottom of the call stack
24 stb ,u++ ; save size in entry
25 puls a ; get back type flag
26 sta -11,u ; put it in the stack frame
27 cstack_pop0 rts
28 ; Clear call stack without resetting the interpreter stack
29 cstack_clear ldd stringtab ; point to the bottom of the string space
30 subd #1 ; make room for a NULL stack frame marking the top of the stack
31 cstack_pop1 tfr d,u ; save new call stack pointer - destination of copy
32 subd cstackptr ; subtract out the current call stack pointer
33 beq cstack_clear1 ; brif the stack is already empty
34 tfr d,y ; save byte count to move in counter
35 sts ,--s ; save the current stack pointer - end of copy address
36 ldx cstackptr ; get current call stack pointer - source of copy
37 stu cstackptr ; save new call stack pointer
38 clr ,u ; put the NULL frame at the top of the call stack
39 cstack_clear0 lda ,-x ; copy a byte upward
40 sta ,-u
41 cmpx ,s ; have we reached the end of the copy?
42 bne cstack_clear0 ; brif not
43 leas ,u ; reset the main stack to the moved location
44 cstack_clear1 rts
45 ; Pop the entry pointed to by U off the call stack and all entries below it
46 cstack_popto ldb ,u ; get size of the current entry
47 bra cstack_popto0 ; go do the rest of the processing
48 ; Pop the first entry off the call stack
49 cstack_pop ldu cstackptr ; point to the call stack
50 ldb ,u ; get size of this frame
51 beq cstack_pop0 ; brif there's nothing to pop - do nothing
52 cstack_popto0 leau b,u ; point to the next entry
53 tfr u,d ; put pointer where we need it
54 bra cstack_pop1 ; go adjust the call stack
55 ; Search for the first matching stack frame where the second byte matches the value in A. Enter
56 ; at cstack_searchnext to search from the entry following the entry pointed to by X. Return with
57 ; C set if not found.
58 cstack_search ldx cstackptr ; point to the call stack
59 cstack_search0 ldb ,x ; get size of this entry
60 bne cstack_search2 ; brif not the end of the call stack
61 cstack_search1 comb ; clear C for not found
62 rts
63 cstack_search2 cmpa 1,x ; does the type match?
64 bne cstack_search3 ; brif not
65 rts ; return result (C is clear from CMPA match)
66 cstack_searchnext
67 ldb ,x ; get length of this frame
68 beq cstack_search1 ; brif we're already at the end of the stack
69 cstack_search3 abx ; move to next entry
70 bra cstack_search0 ; check if this one matches
71 ; Point X to the first entry on the call stack
72 cstack_first ldx cstackptr ; point to stack entry
73 lda ,x++ ; set Z set if end of stack, move to payload
74 rts
75 ; Point X to the next entry on the call stack
76 cstack_next ldb -2,x ; get length of this entry
77 abx ; adjust to next entry payload
78 ldb -2,x ; set Z if end of stack
79 rts
80 *pragmapop list