1- ; ************************************************************************************************
2- ; ************************************************************************************************
3- ;
4- ; Name: for.asm
5- ; Purpose: For/Next loop
6- ; Created: 1st October 2022
7- ; Reviewed: 1st December 2022
8- ; Author: Paul Robson (paul@robsons.org.uk)
9- ;
10- ; ************************************************************************************************
11- ; ************************************************************************************************
1+ ;;
2+ ; [for]/[next] loop implementation
3+ ;;
4+
5+ ;;
6+ ; `STK_FOR` frame layout in `basicStack`:
127;
13- ; +16..+19 Step value (in 2's complement format.)
14- ; +12..+15 Terminal value (in 2's complement format.)
15- ; +8..+11 Value of index variable (in 2's complement format.)
16- ; +6..+7 Address of index variable
17- ; +1..5 Loop back address
8+ ; The active [for] loop frame stores its payload in fixed byte offsets within
9+ ; the return-stack frame pointed to by `basicStack`. The offsets used by this
10+ ; module are:
1811;
19- ; ************************************************************************************************
12+ ; - `+16..+19` Step value in four-byte two's complement form.
13+ ; - `+12..+15` Terminal value in four-byte two's complement form.
14+ ; - `+8..+11` Current value of the loop index in four-byte two's complement
15+ ; form.
16+ ; - `+6..+7` Address of the loop index variable.
17+ ; - `+1..+5` Saved loop-back code position.
18+ ;;
2019
2120 .section code
2221
23- ; ************************************************************************************************
22+ ;;
23+ ; Handle the [for] statement.
2424;
25- ; For command
25+ ; Parses a [for] loop header, validates that the loop variable is an integer
26+ ; reference, evaluates the initial and terminal values, determines the step
27+ ; value (defaulting to `+1` for [to] and `-1` for [downto]), and builds the
28+ ; corresponding `STK_FOR` frame on the return stack. Once the frame is set up,
29+ ; it writes the initial loop index back to the referenced variable.
2630;
27- ; ************************************************************************************************
31+ ; \in Y Relative offset to the statement arguments.
32+ ; \sideeffects - Opens an `STK_FOR` frame on the return stack.
33+ ; - Evaluates expressions into number-stack slots `0..2`.
34+ ; - Stores loop metadata in `basicStack`.
35+ ; - Saves the loop-back code position.
36+ ; - Writes the initial loop index to the referenced variable.
37+ ; - Modifies registers `A`, `X`, and `Y`.
38+ ; - Raises `TypeError` or `SyntaxError` on invalid input.
39+ ; \see FCIntegerToStack, CopyIndexToReference, NextCommand
40+ ;;
2841
2942ForCommand: ;; [for]
3043 lda #STK_FOR+11 ; allocate 22 bytes on the return stack (see above).
@@ -134,11 +147,21 @@ _FCError:
134147_FCSyntaxError:
135148 jmp SyntaxError
136149
137- ; ************************************************************************************************
150+ ;;
151+ ; Copy an integer number-stack value into the [for] frame.
138152;
139- ; Copy stack element X to BasicStack offset Y
153+ ; Converts the integer value in number-stack slot `X` to four-byte two's
154+ ; complement form if necessary, then writes the four mantissa bytes to the
155+ ; `basicStack` frame starting at offset `Y`.
140156;
141- ; ************************************************************************************************
157+ ; \in X Number-stack slot containing the integer value to copy.
158+ ; \in Y Destination offset within `basicStack`.
159+ ; \sideeffects - May negate `NSMantissa[0..3],x` in place for negative values
160+ ; before copying them.
161+ ; - Advances `Y` while storing four bytes.
162+ ; - Modifies register `A`.
163+ ; \see ForCommand, NSMNegateMantissa
164+ ;;
142165
143166FCIntegerToStack:
144167 bit NSStatus,x ; is the value negative
@@ -158,11 +181,21 @@ _FCNotNegative:
158181 sta (basicStack),y
159182 rts
160183
161- ; ************************************************************************************************
184+ ;;
185+ ; Write the current [for] loop index back to the referenced variable.
162186;
163- ; Copy the index register out to the variable referenced.
187+ ; Reads the loop-variable address and current loop index from the active
188+ ; `STK_FOR` frame in `basicStack`, converts the stored two's complement loop
189+ ; value back into the variable's packed integer format, and writes it to the
190+ ; referenced variable record.
164191;
165- ; ************************************************************************************************
192+ ; \sideeffects - Uses `zTemp0` as the destination pointer.
193+ ; - Reads the loop variable address and loop index from the
194+ ; active `basicStack` frame.
195+ ; - Writes four bytes to the referenced variable storage.
196+ ; - Modifies registers `A`, `X`, and `Y`.
197+ ; \see ForCommand, NextCommand
198+ ;;
166199
167200CopyIndexToReference:
168201 phy
@@ -215,11 +248,25 @@ _CITRNormal:
215248 ply ; and exit.
216249 rts
217250
218- ; ************************************************************************************************
251+ ;;
252+ ; Handle the [next] statement.
219253;
220- ; NEXT command
254+ ; Validates that the top return-stack frame is a [for] frame, increments the
255+ ; loop index by the stored step value, writes the updated index back to the
256+ ; loop variable, and compares the new value against the terminal bound using a
257+ ; signed comparison direction derived from the sign of the step. Control then
258+ ; either loops back to the saved code position or closes the [for] frame.
221259;
222- ; ************************************************************************************************
260+ ; \in Y Relative offset to the statement arguments.
261+ ; \sideeffects - Verifies the top return-stack frame type.
262+ ; - Uses `zTemp1` as a temporary pointer and comparison offsets.
263+ ; - Updates the loop index stored in `basicStack`.
264+ ; - Writes the updated index to the referenced variable.
265+ ; - Either reloads the saved loop-back position or closes the
266+ ; current [for] frame.
267+ ; - Modifies registers `A`, `X`, and `Y`.
268+ ; \see CopyIndexToReference, STKLoadCodePosition, StackClose
269+ ;;
223270
224271NextCommand: ;; [next]
225272 lda #STK_FOR+11 ; check FOR is TOS
@@ -298,15 +345,3 @@ _NCLoopBack:
298345 jmp STKLoadCodePosition ; loop back
299346
300347 .send code
301-
302- ; ************************************************************************************************
303- ;
304- ; Changes and Updates
305- ;
306- ; ************************************************************************************************
307- ;
308- ; Date Notes
309- ; ==== =====
310- ; 01/03/26 Added support for optional use of STEP (from Kevin Cozens' patch)
311- ;
312- ; ************************************************************************************************
0 commit comments