The NEXT keyword is followed by the name of the FOR variable, so firstly we get the address of that variable into DE. | ||||
0649 | CD1B07 | Next | CALL GetVar | |
Save the prog ptr in HL to PROG_PTR_TEMP. This currently points to the end of the NEXT statement, and we need to get it back later in case we find that the FOR loop has completed. | ||||
064C | 225D01 | SHLD PROG_PTR_TEMP | ||
GetFlowPtr to get access to the FOR flow struct on the stack. | ||||
064F | CD9201 | CALL GetFlowPtr | ||
0652 | F9 | SPHL | ||
Push address of FOR variable | ||||
0653 | D5 | PUSH D | ||
Load A with first byte of struct (0x01), advance HL, and preserve A. | ||||
0654 | 7E | MOV A,M | ||
0655 | 23 | INX H | ||
0656 | F5 | PUSH PSW | ||
Push address of FOR variable again. | ||||
0657 | D5 | PUSH D | ||
If GetFlowPtr returned without the zero (Z) flag set, then the FOR struct was not found and we error out with Next without For (NF). | ||||
0658 | 1E00 | MVI E,00 | ||
065A | C2D501 | JNZ Error | ||
The next 4 bytes of the flow struct are the STEP number. We load this into FACCUM here. | ||||
065D | CD0F0A | CALL FLoadFromMem | ||
Get FOR variable address into HL and push the struct ptr | ||||
0660 | E3 | XTHL | ||
Add the FOR variable to the STEP number and update the FOR variable with the result. | ||||
0661 | E5 | PUSH H | ||
0662 | CD0408 | CALL FAddMem | ||
0665 | E1 | POP H | ||
0666 | CD290A | CALL FCopyToMem | ||
Restore struct ptr to HL. This now points to the TO number, which we load into BCDE. | ||||
0669 | E1 | POP H | ||
066A | CD200A | CALL FLoadBCDEfromMem | ||
Compare the updated FOR variable (in FACCUM) with the TO number (in BCDE). The result of the compare is in A and will be 0xFF if FOR var is less than the TO number, 0x00 if equal, and 0x01 if the FOR variable is greater than the TO number. | ||||
066D | E5 | PUSH H | ||
066E | CD4C0A | CALL FCompare | ||
0671 | E1 | POP H | ||
Restore the direction byte to B. Remember this is 0x01 for forward iteration, 0xFF for backwards (when there is a -ve STEP number). | ||||
0672 | C1 | POP B | ||
This is marvellous! By subtracting the direction byte from the result of FCompare we can tell if the FOR loop has completed (the result of the subtraction will be zero) with the minimum of fuss. Read the two above comments and it should make sense. | ||||
0673 | 90 | SUB B | ||
NOT loading a floating point number, this is just a handy way of getting the last four bytes of the struct. BC is loaded with the prog ptr to just beyond the FOR statement, and DE is loaded with the line number of the FOR statement. | ||||
0674 | CD200A | CALL FLoadBCDEfromMem | ||
If FOR loop is complete (see two comments up) then jump ahead. | ||||
0677 | CA8306 | JZ ForLoopIsComplete | ||
FOR loop is not yet complete. Here we save the line number of the FOR statement to the CURRENT_LINE variable, load HL with the prog ptr to the end of the FOR statement, and jump to EndOfForHandler which pushes the last byte of the for_struct on the stack and falls into ExecNext. | ||||
067A | EB | XCHG | ||
067B | 226101 | SHLD CURRENT_LINE | ||
067E | 69 | MOV L,C | ||
067F | 60 | MOV H,B | ||
0680 | C31D04 | JMP EndOfForHandler | ||
The FOR loop is complete. Therefore we don't need the for_struct on the stack any more, and since HL points just past it we can load the stack pointer from HL to reclaim that bit of stack space. | ||||
0683 | F9 | ForLoopIsComplete | SPHL | |
0684 | 2A5D01 | LHLD PROG_PTR_TEMP | ||
0687 | C32104 | JMP ExecNext |