Mercurial > hg > index.cgi
comparison src/progctrl.s @ 74:e74d00ac6b79
Split some code into separate files for easier management (2)
Because the source for lwbasic is so large, split it into several
different files to make it easier to navigate and modify. This is
part two of the split. Also includes fix for dependency tracking
related to the split in the make file.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 06 Aug 2023 00:36:48 -0600 |
parents | |
children | a6a53e5c04bd |
comparison
equal
deleted
inserted
replaced
73:2d52cd154ed1 | 74:e74d00ac6b79 |
---|---|
1 *pragmapush list | |
2 *pragma list | |
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
4 ; The END command. | |
5 cmd_end bne SNERROR ; error out if there is an argument | |
6 ;jsr closeall ; close all files for END | |
7 clra ; flag END (clear carry) | |
8 bra cmd_stop0 ; go do the stop/end | |
9 cmd_stop bne SNERROR ; raise error if there was an argument | |
10 coma ; flag STOP - set carry | |
11 cmd_stop0 ror endflag ; set stop/end flag | |
12 cmd_stop1 clr filenum ; reset I/O to console | |
13 ldx curline ; in immediate mode? | |
14 beq cmd_stop2 ; brif so - don't save the continue pointers | |
15 stx contline ; save pointer to current line for CONT | |
16 ldx curstmt ; get current statement address | |
17 stx contstmt ; save it for CONT | |
18 cmd_stop2 rol endflag ; get STOP/END to C (1=STOP) | |
19 bcc cmd_stop3 ; brif END - don't do message | |
20 ldx #breakmsg ; do "BREAK IN" | |
21 jmp ERROR2 ; the bottom half of the error handler can deal with the details | |
22 cmd_stop3 puls x,pc ; lose return address and return to caller of interpretation loop | |
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
24 ; The NEW command. | |
25 ; | |
26 ; This also includes several useful entry points: | |
27 ; | |
28 ; cmd_newraw: does the whole NEW but without any syntax checks | |
29 ; cmd_newinptr: skips clearing the program text | |
30 ; cmd_newvars: clears variables and resets the stack and other misc state | |
31 ; cmd_newstack: just reset the stack and other misc state | |
32 cmd_new bne cmd_new0 ; brif there was an argument - don't wipe things out on syntax error | |
33 cmd_newraw ldx progtext ; point to start of program | |
34 clr -1,x ; make sure there's a NUL before the start of the program | |
35 clr ,x+ ; put a NULL pointer at the start of the program | |
36 clr ,x+ | |
37 stx vartab ; set start of variables after that | |
38 cmd_newinptr ldx progtext ;* set input pointer to the NUL before the program; this will cause the | |
39 leax -1,x ;* the interpreter to drop to immediate mode no matter what it was | |
40 stx inputptr ;* executing before this call if called from the main loop | |
41 cmd_newvars ldx memsize ; get top of memory | |
42 stx stringtab ; clear out string space | |
43 ldx vartab ; get start of variables | |
44 stx objecttab ; set start of large objects (arrays) there too (clear vars) | |
45 stx freestart ; set start of free memory (end of large objects) (clear arrays) | |
46 cmd_newstack ldx #stringstackend ; reset string stack (string stack counts down) | |
47 stx stringstackptr | |
48 ldx ,s ; get return address | |
49 lds freetop ; reset stack to top of memory | |
50 clr ,-s ; put a flag to stop stack searches (NEXT, RETURN) | |
51 sts stackptr ; reset pointer for call stack | |
52 clr contstmt ; clear "CONT" destination | |
53 clr contstmt+1 | |
54 jmp ,x ; return to caller | |
55 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
56 ; REM and ' commands; also ELSE comes here since it needs to skip the rest of the line in that case. | |
57 cmd_else | |
58 cmd_apos | |
59 cmd_rem clra ; clear carry | |
60 ldx curline ; get start of current line | |
61 beq cmd_stop3 ; brif immediate mode - fall back to caller | |
62 ldx ,x ; get address of next line | |
63 leax -1,x ; move back one | |
64 stx inputptr ; put input pointer there | |
65 cmd_new0 rts | |
66 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
67 ; DATA command | |
68 ; | |
69 ; need to skip to the end of the current statement, which is either the end of the line OR a colon not included inside | |
70 ; a quoted string | |
71 cmd_data ldx inputptr ; get input pointer | |
72 cmd_data0 lda ,x+ ; get character at pointer | |
73 beq cmd_data1 ; brif end of line | |
74 cmpa #': ; end of statement? | |
75 bne cmd_data2 ; brif not | |
76 cmd_data1 leax -1,x ; move back to the NUL or colon | |
77 stx inputptr ; reset input pointer for interpreter | |
78 rts | |
79 cmd_data2 cmpa #'" ; start of constant string? | |
80 bne cmd_data0 ; brif not - process more characters | |
81 cmd_data3 lda ,x+ ; get next string character | |
82 beq cmd_data1 ; brif end of line | |
83 cmpa #'" ; string delimiter? | |
84 bne cmd_data3 ; brif not - keep going | |
85 bra cmd_data0 ; process stuff outside string | |
86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
87 ; RUN command | |
88 cmd_run ;jsr closeall ; close all files | |
89 jsr curchar ; what do we have as an argument? | |
90 bcs cmd_goto ; brif a digit - it's a line number (RUN ###); do GOTO | |
91 lbne SNERROR ; brif anything else on the line - not legit command | |
92 ldx progtext ; point to start of program | |
93 bra cmd_goto0 ; go transfer control to the start of the program | |
94 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
95 ; GOTO command | |
96 cmd_goto jsr parse_lineno ; parse the line number | |
97 cmd_gosub0 jsr prog_findlinecl ; go look up line number | |
98 bcc cmd_goto0 ; brif line found | |
99 ULERROR ldb #err_ul ; raise undefined line error | |
100 jmp ERROR | |
101 cmd_goto0 stx curline ; make sure we aren't flagging immediate mode | |
102 leax -1,x ; move input pointer to NUL before destination line | |
103 stx inputptr ; put input pointer there | |
104 rts ; resume interpretation at the new location | |
105 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
106 ; GOSUB command | |
107 cmd_gosub jsr parse_lineno ; parse the destination line so return location is after the line number | |
108 ldd #tok_gosub*256+4 ; stack frame details | |
109 bsr callstack_alloc ; make a stack frame | |
110 ldx curline ; save current line pointer | |
111 stx ,u | |
112 ldx inputptr ; save current input pointer | |
113 stx 2,u | |
114 bra cmd_gosub0 ; go finish up as a GOTO | |
115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
116 ; RETURN command | |
117 ; POP command | |
118 ; | |
119 ; RETURN will search the call stack for the first GOSUB frame and remove all other placeholders it finds. A frame type | |
120 ; of 0 will cause it to stop. | |
121 cmd_pop skip1lda ; set nonzero for POP | |
122 cmd_return clra ; set zero for RETURN | |
123 pshs a ; save operation type | |
124 bsr callstack_first ; get first entry on call stack | |
125 bne cmd_return1 ; brif there's a frame - don't error | |
126 RG_ERROR ldb #err_rg ; raise RETURN without GOSUB | |
127 jmp ERROR | |
128 cmd_return0 bsr callstack_next ; move to next entry | |
129 beq RG_ERROR ; brif end of stack - raise error | |
130 cmd_return1 cmpb #tok_gosub ; do we have a GOSUB frame? | |
131 bne cmd_return0 ; brif not - try again | |
132 lda ,s+ ; is it "POP"? | |
133 bne cmd_return2 ; brif so - don't change flow control but clear stack frame | |
134 ldx ,u ; get back saved line pointer | |
135 stx curline | |
136 ldx 2,u ; get back saved input pointer | |
137 stx inputptr | |
138 cmd_return2 bsr callstack_pop ; clean up call stack | |
139 bra cmd_data ; move to end of statement (move past any "ON GOSUB" entries | |
140 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
141 ; Point to the first entry on the call stack; yes this is trivial but it points to the payload, not the header. Also | |
142 ; sets Z if there is nothing on the stack. | |
143 callstack_first ldu stackptr ; get stack pointer | |
144 ldb ,u++ ; set flags on frame type and adjust pointer | |
145 rts | |
146 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
147 ; Move to the next frame on the call stack; enter with U pointing to a stack frame payload area | |
148 callstack_next ldb -1,u ; get length of this frame | |
149 leau b,u ; move to the next frame | |
150 ldb -2,u ; set flags on frame type code | |
151 rts | |
152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
153 ; Create a stack frame. Enter with the frame type flag in A and the size in B. | |
154 ; | |
155 ; The stack frame of size B bytes plus 2 bytes for the length and type flag will be allocated between the actual | |
156 ; hardware stack and the current call stack pointer. Return with the pointer to the allocated frame in U. As long as | |
157 ; there are no pointers to anything on the hardware stack, this will allow the stack to be entirely intact after | |
158 ; the call. | |
159 callstack_alloc addb #2 ; account for the header bytes | |
160 pshs a,b ; save the type and length | |
161 negb ; need a negative offset | |
162 leax ,s ; point to current bottom of stack | |
163 leas b,s ; make a hole below the stack | |
164 leau ,s ; get a pointer to the destination for copying | |
165 callstack_alloc0 | |
166 lda ,x+ ; copy a byte down | |
167 sta ,u+ | |
168 cmpx stackptr ; have we reached the top of the stack? | |
169 blo callstack_alloc0 ; brif not | |
170 stu stackptr ; save the new call stack pointer | |
171 puls d ; get back the type and length values | |
172 std ,u++ ; save type and length | |
173 rts | |
174 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
175 ; Pop the call stack to the end of the frame pointed to by U; this will relocate the hardware stack to close the | |
176 ; newly made gap in memory. | |
177 callstack_pop leau -2,u ; move back to header | |
178 ldb 1,u ; get length of frame | |
179 leax b,u ; point to element after this frame | |
180 sts ,--s ; save the current bottom of the stack | |
181 stx stackptr ; save new call stack pointer | |
182 callstack_pop0 lda ,-u ; copy a byte up | |
183 sta ,-x | |
184 cmpu ,s ; at the bottom of the call stack? | |
185 bhi callstack_pop0 ; brif not | |
186 leas 2,x ; reset the stack pointer (and lose the saved stack pointer value) | |
187 rts | |
188 *pragmapop list |