TRS-80 DOS – TRSDOS v1.3 – SYS12/SYS Disassembled

General:

SYS12/SYS handles the CMD “C” (Compress) and NAME (Renumber) functions.



Disassembly:

 
ORG 4E00H
“START”
4E00
AND 0F0H
MASK off the SYSTEM NUMBER from the byte passed to this OVERLAY by masking against F0H (1111 0000). This has the effect of turning off bits 3, 2, 1, 0, leaving only bits 7, 6, 5, 4 active.
4E02
CP 90H
Compare the remainder of Register A against 90H, which would be the “COMPRESS” function call. If the masked value is 90H, then the COMPRESS function is being requested so …
4E04
JP Z,CMPRES
     [5093H]
… do it via a JUMP to 5093H.

4E07H – “RENUMBER” Function.

This routine can take up to 3 parameters: RESEQ (NN(,MM(,INC)))

  • NN = Starting line number to use in renumbering
  • MM = Starting line to renumber (lines below do not get renumbered)
  • INC = Increment (default = 10).
“REN”
4E07
CALL 1B61H
     [1B61H]
Clear all BASIC variables and pointers via a GOSUB to the Model III ROM Routine at 1B61H.
4E0A
LD BC,1D1EH
Let Register Pair BC equal 1D1EH, which is the MODEL III ROM routine for the Level II BASIC Interpreter. This is the JUMP POINT for when the routine ends.
4E0D
DEC HL
HL was set to be the current value of the BASIC program pointer in that CALL. DECrement the value stored in Register Pair HL by 1 to prepare for a RST 10H which advances HL.
4E0E
RST 10H
Get a character from the BASIC program in RAM (which is the command line calling for the RENUMBER) via a call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4E0F
PUSH BC
Save the pointer to Level II BASIC Interpreter (held in Register Pair BC) to the top of the stack. Stack = this.
4E10
LD BC,000AH
As a default, set BC to be a default starting line of 10 (i.e., the base number plus a default of 10 as “INC”).
4E13
PUSH BC
Save the default starting line number (held in Register Pair BC) to the top of the stack. Stack = INC, Level II Jump Point.
4E14
LD D,B
Since BC is 000AH, B = 00H. As a default, set DE (to zero) so that “NN” (starting line number) is zero, to renumber ALL lines.
4E15
LD E,B
Register B is still zero, so set Register E = 0 by copying the contents of Register B into Register E.
4E16
JR Z,RESNN
     [4E3EH]
If there was no character found in the RST 10H (meaning that the user just entered RENUM without any parameters), then JUMP to 4E3EH to process with “ALL LINES” starting with line 10.
4E18
CP 2CH
We know the user included some parameter when calling RENUM, so first check for a first character of “,” by comparing the value held in Register A against 2CH (ASCII: ,). If the character is a “,” then the user did not designate a “first line to process” …
4E1A
JR Z,EATCOM
     [4E25H]
… so JUMP to 4E25H to process that.
4E1C
PUSH DE
Save “NN” (i.e., the first line number to be resquenced) held in Register Pair DE to the top of the stack, as it is about to get overwritten by the next instruction. Stack = NN, INC, Level II Jump Point
4E1D
CALL LINSPC
     [1E4FH]
Get the new NN by evaluating the line number at the location of the current BASIC program pointer in register pair HL and return with the line number’s binary value in register pair DE via a GOSUB to 1E4FH.
4E20
4E21
LD B,D
LD C,E
DE now holds the new “NN”. Let Register Pair BC = the new NN.
4E22
POP DE
Restore “NN” (i.e., the first line number to be resquenced) from the top of the STACK into Register Pair DE, and then remove the entry from the stack. Stack = INC, Level II Jump Point. BC = New NN, DE = Old NN, HL = Pointer on the command line calling for the RENUM.
4E23
JR Z,RESNN
     [4E3EH]
If the Z FLAG (Zero) has been set then we have no more command line to process, so JUMP to 4E3EH.
“EATCOM”
4E25
RST 08H
2C
RST 08H is used to look for expected characters (in this case, a ,) in a string and then return with (HL) pointing to the next non-blank character.

It is a COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.

If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given.

The prior instruction found a “,” meaning that we have a parameter to interpret. So the next instruction converts the parameter from ASCII to Decimal.

4E27
CALL 1E4FH
     [1E4FH]
Get new MM by converting the ASCII character at (HL) to binary with the result in DE via GOSUB to the Model III ROM routine at 1E4FH. Returns with Z FLAG set if it finds a 00H or a :. Stack = INC, Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM.
4E2A
JR Z,RESNN
     [4E3EH]
If the Z FLAG (Zero) has been set, JUMP to 4E3EH.
4E2C
POP AF
Discard the value held at the top of the STACK (which was the old “INC”, put into the stack at 4E13H). Stack = Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM, AF = Old INC.
4E2D
RST 08H
2C
RST 08H is used to look for expected characters (in this case, a ,) in a string and then return with (HL) pointing to the next non-blank character.

It is a COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.

If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given.
4E2F
PUSH DE
Save the “MM” to the top of the stack. Stack = MM, Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM.

Next, we process a new “INC” value.

4E30
CALL 1E5AH
     [1E5AH]
Convert the ASCII string pointed to by HL (which should be the new “INC”) to an integer deposited into DE via a GOSUB to the Model III ROM routine at 1E5AH. After execution HL points to the delimiter and the A register contains the delimiter value. The Z flag is set if the delimiter equals 00 or 3A. Z is reset if any other delimiter is used. If the routine finds a non-numerical character, the conversion is stopped.

Stack = MM, Level II Jump Point. BC = New NN, DE = INC, HL = Pointer on the command line calling for the RENUM.
4E33
JP NZ,1997H
      [1997H]
If the routine at 1E5AH returns with the NZ FLAG (Not Zero) set, abort with a “SYNTAX ERROR” via a JUMP to the Model III ROM Routine at 1997H.

We now need to check to see if the new INC is a 0, which would be illegal.

4E36
4E37
LD A,D
OR E
Since the Z-80 cannot test Register Pair DE against zero, the common trick is to set Register A to equal to Register D, and then OR A against Register E. Only if both Register D and Register E were zero can the Z FLAG be set.
4E38
JP Z,1E4AH
     [1E4AH]
If the new “INC” is 0, the Z FLAG (Zero) will have set, so we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
4E3B
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE (currently, the “INC”).

Stack = MM, Level II Jump Point. BC = New NN, HL= INC, DE = Pointer on the command line calling for the RENUM.
4E3C
EX (SP),HL
EXchange the “INC” (now stored in Register Pair HL) with the value stored in Register Pair SP (i.e., “MM” as pushed in 4E2FH).

Stack = INC, Level II Jump Point. BC = New NN, HL= MM, DE = Pointer on the command line calling for the RENUM.
4E3D
EX DE,HL
Restore HL and DE to what they were.

Stack = INC, Level II Jump Point. BC = New NN, DE= MM, HL = Pointer on the command line calling for the RENUM.

4E3EH – Still in the Renumber Function, finished parsing the command line.

“RESNN”
4E3E
PUSH BC
Save “NN” (held in Register Pair BC) to the top of the stack.

Stack = NN, INC, Level II Jump Point. BC = New NN, DE= MM, HL = Pointer on the command line calling for the RENUM.
4E3F
LD (LINE1),DE
Store “MM” (held in Register Pair DE) into memory location 63B8H.
4E43
CALL 1B2CH
     [1B2CH]
Search RAM for line “MM” (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= MM, HL = Pointer on the command line calling for the RENUM.
4E46
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.

Stack = INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM. Why is MM gone? Since MM is the lowest line to work from, and BC now has that location, we no longer need to keep track of MM.
4E47
PUSH DE
Save the contents of Register Pair DE to the top of the stack.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
4E48
PUSH BC
Save the contents of Register Pair BC to the top of the stack.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
4E49
CALL 1B2CH
     [1B2CH]
Search RAM for line “NN” (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
4E4C
4E4D
LD H,B
LD L,C
Let HL = BC.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= NN, HL = RAM location where line NN is to be found. What happened to HL? We don’t need to parse the RENUM command line anymore, and that’s what HL was pointing to.
4E4E
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= RAM location where line MM is to be found, HL = RAM location where line NN is to be found. What happened to HL? We don’t need to parse the RENUM command line anymore, and that’s what HL was pointing to.
4E4F
RST 18H
RST 18 to see if the variable address in HL (RAM location where line NN is to be found) is the same as in DE (RAM location where line MM is to be found), so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
4E50
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, HL= RAM location where line MM is to be found, DE = RAM location where line NN is to be found.
4E51
JP C,1E4AH
     [1E4AH]
If RAM location where line NN is to be found (HL) < RAM location where line MM is to be found (DE), which will have set the CARRY FLAG, then we cannot proceed because the program will be renumbered on top of itself. With this, we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
4E54
POP DE
Put the value held at the top of the STACK (i.e., NN) into Register Pair DE, and then remove the entry from the stack.

Stack = INC, Level II Jump Point. BC = RAM location where line NN is to be found, HL= RAM location where line MM is to be found, DE = NN.
4E55
POP BC
Put the value held at the top of the STACK (i.e., INC) into Register Pair BC, and then remove the entry from the stack.

Stack = Level II Jump Point. BC = INC, HL= RAM location where line MM is to be found, DE = NN.
4E56
POP AF
Put the value held at the top of the STACK into Register Pair AF, and then remove the entry from the stack.

Stack = EMPTY. BC = INC, HL= RAM location where line MM is to be found, DE = NN, AF = Level II Jump Point.
4E57
PUSH DE
Save the contents of Register Pair DE (i.e, NN) to the top of the stack.

Stack = NN. BC = INC, HL= RAM location where line MM is to be found, DE = NN, AF = Level II Jump Point.
4E58
JR NXTRSL
   [4E68H]
JUMP to 4E68H.

4E5AH – Bump the line number by the INC. This routine is not in order. It is jumped to by 4E77, but ultimately would flow down the 4E68H so this was a RAM saver.

“NXTRSC”
4E5A
ADD HL,BC
LET Register Pair HL (i.e., the LINE NUMBER ACCUMULATOR) = Register Pair HL + Register BC (i.e., INC).
4E5B
JP C,1E4AH
     [1E4AH]
If that addition caused the line number to go above 65529, the C FLAG (Carry) will have been set, and we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
4E5E
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINE NUMBER ACCUMULATOR) with the value stored in Register Pair DE (i.e., the LINK FIELD).
4E5F
PUSH HL
Save the contents of Register Pair HL (i.e., the LINK FIELD) to the top of the stack.
4E60
LD HL,0FFF9H
Let Register Pair HL equal 0FFF9H to see if the LINK FIELD will exceed the highest possibleline number of 65529.
4E63
RST 18H
RST 18 to see if the variable address in HL is the same as in DE, so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
4E64
POP HL
Put the value held at the top of the STACK (i.e., the LINK FIELD) into Register Pair HL, and then remove the entry from the stack.
4E65
JP C,1E4AH
     [1E4AH]
If the C FLAG (Carry) has been set then the “INC” was too large and resulted in an invalid line number. With this we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.

4E68H – Continuation of RENUM from 4E58H (with BC = INC, HL= RAM location where line MM is to be found, DE = NN) -or- pass through from 4E5AH (from 4E77H) with HL holding the LINK FIELD and DE holding the current LINE NUMBER ACCUMULATOR.

“”
4E68
PUSH DE
Save the contents of Register Pair DE (i.e., the current LINE NUMBER ACCUMULATOR, which would be NN on the first run if passed through) to the top of the stack.
4E69
LD E,(HL)
Fetch the LSB of the value held in the memory location pointed to by Register Pair HL (i.e., the RAM location of the first line to renumber on the first pass, or the LINK FIELD for all other passes) and store it into Register E. This puts the LINK FIELD into (DE).
4E6A
LD A,E
Prepare to test for a zero. First copy the contents of Register E into Register A.
4E6B
INC HL
INCrement the Register Pair HL by 1.
4E6C
LD D,(HL)
Fetch the MSB of the LINK FIELD (held in the memory location pointed to by Register Pair HL) and store it into Register D.
4E6D
OR D
OR Register D against Register A (which is Register E). The results are stored in Register A.
4E6E
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINK FIELD) with the value stored in Register Pair DE (i.e., the value of the next link field)
4E6F
POP DE
Put the LINE NUMBER ACCUMULATOR (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
4E70
JR Z,4E79H
     [4E79H]
If the next link is 0, then the Z FLAG (Zero) will have been set, and we are done. JUMP to 4E79H.
4E72
LD A,(HL)
Fetch the first byte of the link (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4E73
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4E74
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4E75
DEC HL
DECrement the pointer (stored in Register Pair HL) by 1.
4E76
EX DE,HL
Put the pointer into Register Pair DE.
4E77
JR NZ,NXTRSC
      [4E5AH]
If the NZ FLAG (Not Zero) has been set then we are good to process, so JUMP to 4E5AH to increment the line number accumulator.
“”
4E79
PUSH BC
Save the INC (held in Register Pair BC) to the top of the stack.
4E7A
CALL LINSCN
     [4F97H]
Convert all line number references via a GOSUB to 4F97H.
4E7D
CALL SCCLIN
     [4EA5H]
Scan the program, converting lines to pointers via a GOSUB to 4EA5H.
4E80
LD HL,(63B8H)
Fetch the starting line number position (held in memory location 63B8H) and store it into Register Pair HL.
4E83
EX DE,HL
Put the starting line number position into Register Pair DE.
4E84
CALL 1B2CH
     [1B2CH]
Search RAM for the starting line number (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
4E87
4E88
LD H,B
LD L,C
Copy BC (i.e., the location of the found line) into HL.
4E89
POP BC
Put “INC” (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
4E8A
POP DE
Put “NN” a/k/a LINE NUMBER (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
“RESNX1”
4E8B
PUSH DE
Save the LINE NUMBER (held in Register Pair DE) to the top of the stack.
4E8C
LD E,(HL)
Now we need to process and review the LINK FIELD. First, fetch the LSB of the location in RAM of the line number we were looking for (held in the memory location pointed to by Register Pair HL) and store it into Register E.
4E8D
LD A,E
Prepare for a test against 0 by copying the contents of Register E into Register A.
4E8E
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the MSB of the location in RAM of the line number we were looking for.
4E8F
LD D,(HL)
Fetch the MSB of the location in RAM of the line number we were looking for (held in the memory location pointed to by Register Pair HL) and store it into Register E.
4E90
OR D
OR the MSB (Register D) against the LSB (Register A). The results are stored in Register A.
4E91
JR Z,4EA0H
     [4EA0H]
If the location in RAM of the line number we were looking for is ZERO, then we are at the end of the program, so JUMP to 4EA0H.
4E93
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINE POINTER) with the value stored in Register Pair DE (i.e., the LINK FIELD).
4E94
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the LINK FIELD) with the value stored at the top of the stack (i.e., the NEW LINE NUMBER).
4E95
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the NEW LINE NUMBER) with the value stored in Register Pair DE (i.e., the LINE POINTER).
4E96
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the line number field.
4E97
LD (HL),E
We now need to move the new line number (held in DE) into the HL pointer memory location. Store the LSB of the line number (held in Register E) into the memory location pointed to by Register Pair HL.
4E98
INC HL
INCrement the value stored in Register Pair HL by 1.
4E99
LD (HL),D
Store the MSB of the line number (held in Register E) into the memory location pointed to by Register Pair HL.
4E9A
EX DE,HL
Put the new line number into HL.
4E9B
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC (i.e., the “INC”).
4E9C
EX DE,HL
Put the new line number back into DE.
4E9D
POP HL
Put the pointer to the next line (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
4E9E
JR RESNX1
   [4E8BH]
Continue renumbering via a JUMP BACK to 4E8BH.

4EA0H – Convert all line numbers to pointers and back again; excluding “ON ERROR GOTO 0” which is left untouched.

“SCCALL”
4EA0
LD BC,1A18H
Let Register Pair BC equal 1A18H, which is the Model III ROM Routine to POP BC and then return to BASIC’s READY prompt.
4EA3
PUSH BC
Save the return address in BC to the top of the stack.
“SCCLIN”
4EA4
CP 0F6H
No idea what this is doing. It is possibly a DEFB instead of a CP
“SCCPTR”
4EA6
XOR A
Set Register A to ZERO.
4EA7
LD (63B7H),A
Store the value held in Register A into memory location 63B7H which is used to denote if we want LINE NUMBERS or POINTERS.
“SCNPGM”
4EAA
LD HL,(40A4H)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
4EAD
DEC HL
Back up to 1 byte before the BASIC program, since the next instruction is the start of a loop that BUMPS HL by 1.
“SCNPLN”
4EAE
INC HL
INCrement the value stored in Register Pair HL by 1 so as to point to the start of the next line in the program in RAM.
4EAF
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL (i.e., the LINK FIELD) and store it into Register A.
4EB0
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4EB1
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4EB2
RET Z
If the Z FLAG (Zero) has been set then we are all done with the renumbering, so RETurn to the caller.
4EB3
INC HL
IF we didn’t return, then INCrement the value stored in Register Pair HL by 1 to go 1 byte past the line number.
4EB4
LD E,(HL)
Fetch the LSB of the line number (memory location pointed to by Register Pair HL) and store it into Register E.
4EB5
INC HL
INCrement the value stored in Register Pair HL by 1.
4EB6
LD D,(HL)
Fetch the MSB of the line number (memory location pointed to by Register Pair HL) and store it into Register D.
“SCNEXT”
4EB7
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
“SCNEX2”
4EB8
OR A
Test to see if we are at the end of the line by setting the flags based on Register A as returned from the RST 10H call.
4EB9
JR Z,SCNPLN
     [4EAEH]
If the Z FLAG (Zero) has been set then we are at the end of the program line, so JUMP to 4EAEH to process the next line.
“SCNEXX”
4EBB
LD C,A
Save the character returned from the RST 10H operation into Register C.
4EBC
LD A,(63B7H)
Fetch the value held in memory location 63B7H and store it into Register A to see whether we are converting to/from LINE NUMBERS and POINTERS.
4EBF
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4EC0
LD A,C
Put the character returned from the RST 10H operation back into Register A.
4EC1
JP Z,SCNPT2
     [4F2AH]
If the Z FLAG (Zero) has been set, then we are changing POINTERS into LINE NUMBERS. JUMP to 4F2AH.

This routine will convert LINE NUMBERS into POINTERS.

4EC4
CP 9EH
Compare the value held in Register A against 9EH (BASIC Token: ERROR). If the current character is not the BASIC TOKEN for ERROR, the NZ FLAG will be set …
4EC6
JR NZ,NTERRG
      [4EEAH]
… so JUMP to 4EEAH to process it. Otherwise, we need to keep checking for the ON ERROR GOTO 0.
4EC8
RST 10H
We next need to see if we have a “GOTO” token. Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4EC9
CP 8DH
Compare the value held in Register A against 8DH (BASIC Token: GOTO). If the current character is not the BASIC TOKEN for GOTO, the NZ FLAG will be set …
4ECB
JR NZ,SCNEX2
      [4EB8H]
… JUMP to 4EB8H to process it. Otherwise, we need to keep checking for the ON ERROR GOTO 0.
4ECD
RST 10H
We next need to see what line number may be next, as we already have “ERROR GOTO”. Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4ECE
CP 0EH
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is not a LINE NUMBER CONSTANT, the NZ FLAG will be set …
4ED0
JR NZ,SCNEX2
      [4EB8H]
… JUMP to 4EB8H to process it.

If we are here then we have found “ERROR GOTO” and a line number constant. Need to see if this is the special case of a “0” or some other line number.

4ED2
PUSH DE
Save the contents of Register Pair DE to the top of the stack, as it is about to get used.
4ED3
CALL LINGT3
     [4F71H]
Get the line number after the “ERROR GOTO” and put it into Register Pair DE via a GOSUB to 4F71H.
4ED6
4ED6
LD A,D
OR E
Since the Z-80 cannot test Register Pair DE against zero, the common trick is to set Register A to equal to Register D, and then OR A against Register E. Only if both Register D and Register E were zero can the Z FLAG be set.
4ED8
JR NZ,4EF3H
      [4EF3H]
If the NZ FLAG (Not Zero) has been set, then the line number is not 0; so we will want to change it to a pointer since we will be renumbering it. To do so, JUMP to 4EF3H.
4EDA
PUSH HL
Save the contents of Register Pair HL to the top of the stack because we’re about to use HL. Will POP it back at the end.
4EDB
LD HL,(CONTXT)
Fetch the value held in memory location 63BAH and store it into Register Pair HL.
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
4EDE
DEC HL
DECrement the value stored in Register Pair HL by 1.
4EDF
LD (HL),20H
Store a SPACE into the memory location pointed to by Register Pair HL.
4EE1
DEC HL
DECrement the value stored in Register Pair HL by 1.
4EE2
LD (HL),20H
Store a SPACE into the memory location pointed to by Register Pair HL.
4EE4
DEC HL
DECrement the value stored in Register Pair HL by 1.
4EE5
LD (HL),30H
Store a 0 into the memory location pointed to by Register Pair HL.
4EE7
POP HL
Restore HL from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
4EE8
JR SCNEX3
   [4F16H]
Continue processing via a JUMP to 4F16H.

4EEAH – Continue converting LINE NUMBERS into POINTERS now that we know that we are not dealing with an ON ERROR.

“NTERRG”
4EEA
CP 0EH
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is not a LINE NUMBER CONSTANT, the NZ FLAG will be set …
4EEC
JP NZ,4EB7H
      [4EB7H]
… and we keep scanning by a JUMP BACK to 4EB7H.
4EEF
PUSH DE
If it WAS a line number constant, save the contents of Register Pair DE to the top of the stack.
4EF0
CALL 4F71H
     [4F71H]
Get the line number and put it into Register Pair DE via a GOSUB to 4F71H.
“CHGPTR”
4EF3
PUSH HL
Save the text pointer (held in Register Pair HL) to the top of the stack.
4EF4
CALL 1B2CH
     [1B2CH]
Search RAM for the starting line number (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
4EF7
DEC BC
DECrement the value stored in Register Pair BC (i.e., the found line nunber in RAM) by 1, so now BC will point to the 00H terminating the prior line.
4EF8
LD A,0DH
Let Register A equal 0DH to denote a POINTER instead of a LINE NUMBER CONSTANT.
4EFA
JP C,MAKPTR
     [4F59H]
If the C FLAG (Carry) has been set then the routine at 1B2CH found the line number, so we JUMP to 4F59H to change the LINE NUMBER to a POINTER.
4EFD
CALL 20F9H
     [20F9H]
If we are here, then 1B2CH didn’t find the line number, which is a bad thing and we are going to error out. First, GOSUB to the Model III ROM Routine at 20F9H to see if we need to move to the next line on the screen, and if so, do it.
4F00
LD HL,4F1BH
Let Register Pair HL equal 4F1BH to point to the “UNDEFINED LINE” error message.
4F03
PUSH DE
Save the contents of Register Pair DE (i.e., the line number at issue) to the top of the stack.
4F04
CALL 28A7H
     [28A7H]
We want to do more than just display the error message. The routine at 28A7 in the Model III ROM will display the message pointed to by HL onto the current output device, BUT, if that message ends in an 0DH, the program takes the DOS exit at 41D0H.
4F07
POP HL
Put line number at issue (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
4F08
CALL 0FAFH
     [0FAFH]
Convert the value held in HL to ASCII and display that value via a GOSUB to the Model III ROM Routine at 0FAFH.
4F0B
POP BC
Put the text pointer (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
4F0C
CALL SPCOTL
     [4F7DH]
Replace the line number reference with 5 spaces via a GOSUB to 4F7DH.
4F0F
POP HL
Put the current line number (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
4F10
PUSH HL
Put the current line number (held in Register Pair HL) to the top of the stack.
4F11
PUSH BC
Save the text pointer (held in Register Pair BC) to the top of the stack.
4F12
CALL 0FA7H
     [0FA7H]
Display the word “IN” and then the line number via a GOSUB to the Model III ROM Routine at 0FA7H.
“SCNPOP”
4F15
POP HL
Put the current text pointer (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
“SCNEX3”
4F16
POP DE
Put the current line number (held held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
4F17
DEC HL
Back up the current text pointer by 1 by DECrementing the value stored in Register Pair HL by 1.
4F18
JP SCNEXT
   [4EB7H]
Skip the scanning by JUMPing to 4EB7H.

4F1BH – “RENUM” Message Storage Area.

4F1B
DEFM “Undefined line” + 00H

4F2AH – “RENUM” – Change POINTERS into LINE NUMBERS.

“SCNPT2”
4F2A
CP 0DH
Check to see if Register A equals 0DH to denote a POINTER instead of a LINE NUMBER CONSTANT.
4F2C
JP NZ,SCNEXT
      [4EB7H]
If Register A did NOT designate a POINTER, then the NZ FLAG (Not Zero) will have been set, and we are NOT going to process this line. Instead JUMP to 4EB7H.
4F2F
PUSH DE
Save the CURRENT LINE NUMBER (held in Register Pair DE) to the top of the stack.
4F30
CALL LINGT3
     [4F71H]
Get the line number and put it into Register Pair DE via a GOSUB to 4F71H.
4F33
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the CURRENT TEXT POINTER) with the value stored in Register Pair DE (i.e., the LINE NUMBER).
4F34
4F35
4F36
INC HL
INC HL
INC HL
Point HL to the line number field by INCrementing the value stored in Register Pair HL by 3.
4F37
LD C,(HL)
Fetch the LSB of the line number (held in the memory location pointed to by Register Pair HL) and store it into Register C.
4F38
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the MSB of the line number.
4F39
LD B,(HL)
Fetch the LSB of the line number (held in the memory location pointed to by Register Pair HL) and store it into Register B.
4F3A
EX DE,HL
Put the TEXT POINTER into DE.
4F3B
4F3C
LD H,B
LD L,C
Let HL = BC (i.e., the line number).
4F3D
CALL LINDSP
     [5088H]
Convert the value held in Register Pair HL into INTEGER and then into ASCII (held in Register Pair HL) via a GOSUB to 5088H.
4F40
EX DE,HL
Put the STRING NUMBER POINTER into Register Pair DE.
4F41
INC DE
INCrement the value stored in Register Pair DE by 1 to skip over the sign.
4F42
LD HL,(CONTXT)
Fetch the pointer after the pointer (held in memory location 63BAH) and store it into Register Pair HL
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
4F45
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the LSB).
4F46
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the MSB).
4F47
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the character before).
4F48
LD C,05H
We need to fill 5 characters so set Register C to 05H.
“LPLINI”
4F4A
LD A,(DE)
Top of a loop. Fetch the value held in the memory location pointed to by Register Pair DE and store it into Register A.
4F4B
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4F4C
JR Z,NSPCFL
     [4F69H]
If that character was 0, then we are at the end of the line, so JUMP to 4F69H to put in a space.
4F4E
LD (HL),A
Store the value held in Register A into the memory location pointed to by Register Pair HL.
4F4F
INC HL
INCrement the value stored in Register Pair HL by 1.
4F50
INC DE
INCrement the value stored in Register Pair DE by 1.
4F51
DEC C
DECrement the value stored in Register C by 1.
4F52
JR NZ,LPLINI
      [4F4AH]
If the NZ FLAG (Not Zero) has been set (meaning we still have more characters to process), LOOP BACK to 4F4AH.
“NINDON”
4F54
POP DE
Put the line number (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
4F55
DEC HL
DECrement the value stored in Register Pair HL by 1.
4F56
JP SCNEXT
   [4EB7H]
Continue scanning by JUMPing BACK to 4EB7H.

4F59H – Change a LINE NUMBER to a POINTER.

“MAKPTR”
4F59
LD HL,4F15H
Let Register Pair HL equal 4F15H which will act as the RETURN JUMP POINT.
4F5C
PUSH HL
Save the return jump point to the top of the stack.
“CONCHG”
4F5D
LD HL,(CONTXT)
Fetch the value held in memory location 63BAH and store it into Register Pair HL
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program to the character after a constant.
“CONCH2”
4F60
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
4F61
DEC HL
DECrement the value stored in Register Pair HL by 1.
4F62
LD (HL),B
Store the MSB of the pointer (held in Register B) into the memory location pointed to by Register Pair HL.
4F63
DEC HL
DECrement the value stored in Register Pair HL by 1.
4F64
LD (HL),C
Store the LSB of the pointer (held in Register C) into the memory location pointed to by Register Pair HL.
4F65
DEC HL
DECrement the value stored in Register Pair HL by 1 to now point to the constant.
4F66
LD (HL),A
Change the constant to the value held in Register A.
4F67
POP HL
Restore the pointer to the character after the constant from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
4F68
RET
RETurn to the caller.

4F69H – Non-Fast RENUM. Fills C characters of (HL) with a SPACE and then JUMPs to NSPCFL.

“NSPCFL”
4F69
LD (HL),20H
Top of a loop. Store a SPACE into the memory location pointed to by Register Pair HL.
4F6B
INC HL
INCrement the value stored in Register Pair HL by 1.
4F6C
DEC C
DECrement the value stored in Register C by 1.
4F6D
JR NZ,NSPCFL
      [4F69H]
If the counter in C has not yet hit zero, LOOP BACK to 4F69H.
4F6F
JR NINDON
   [4F54H]
JUMP BACK to 4F54H.

4F71H – Get the line number pointed to by Register Pair HL – 1 and put it into Register Pair DE and then run a RST 10H to get the next character into Register A.

“LINGT3”
4F71
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program, which will be the LSB of the line number.
4F72
LD E,(HL)
Fetch the LSB of the line number pointed to by Register Pair HL and store it into Register E.
4F73
INC HL
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program, which will be the MSB of the line number.
4F74
LD D,(HL)
Fetch the MSB of the line number pointed to by Register Pair HL and store it into Register D.
4F75
INC HL
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program.
4F76
LD (CONTXT),HL
Store the current pointer in the BASIC Program (held in Register Pair HL) into memory location 63BAH
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
4F79
DEC HL
Back up the pointer held in HL in preparation for the RST 10H.
4F7A
JP 1D78H
   [1D78H]
JUMP to 1D78H to get a character from the BASIC program in RAM (which is the command line calling for the RENUMBER) via a call the EXAMINE NEXT SYMBOL routine at RST 10H. Since this ia JUMP, the RET at the end of the RST 10H will RETurn from this subroutine.

4F7DH – Fill (BC), which points to the line number in the program, with 5 SPACES.

“SPCOTL”
4F7D
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
4F7E
PUSH BC
Save the contents of Register Pair BC (which is the text pointer) to the top of the stack.
4F7F
LD A,20H
Let Register A equal SPACE.
4F81
LD E,05H
Set up for a loop of 5 iterations by setting Register E to 05H.
“LPSPCI”
4F83
DEC BC
Top of a loop of 5 iterations. DECrement the value stored in Register Pair BC by 1.
4F84
LD (BC),A
Store the value held in Register A into the memory location pointed to by Register Pair BC.
4F85
DEC E
DECrement the value stored in Register E by 1.
4F86
JR NZ,4F83H
      [4F83H]
If E hasn’t counted down fully from 5, LOOP BACK to 4F83H.
4F88
POP BC
Restore BC from the stach.
4F89
POP DE
Restore DE from the stach.
4F8A
RET
RETurn to the caller.

4F8BH – RENUM Token List.

“TOKLST”4F8B
DEFB B7H
Token for AUTO command.
4F8C
DEFB B6H
Token for DELETE command.
4F8D
DEFB 9DH
Token for EDIT command.
4F8E
DEFB 9FH
Token for RESUME command.
4F8F
DEFB C2H
Token for ERL command.
4F90
DEFB 8EH
Token for RUN command.
4F91
DEFB B4H
Token for LIST command.
4F92
DEFB B5H
Token for LLIST command.
4F93
DEFB 8DH
Token for GOTO command.
4F94
DEFB CAH
Token for THEN command.
4F95
DEFB 91H
Token for GOSUB command.
4F96
DEFB 95H
Token for ELSE command.

4F97H – Convert all line number references to a binary line number + 2 spaces

“LINSCN”
4F97
LD HL,(40A4H)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
“PNXTLN”
4F9A
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
4F9B
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4F9C
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4F9D
JR Z,DOCNVR
     [4FDBH]
If the next character in the program is a 00H then we are done, so JUMP to 4FDBH.
4F9F
4FA0
4FA1
INC HL
INC HL
INC HL
INCrement the value stored in Register Pair HL by 3 to point to the first character after the line number.
“PNXTCH”
4FA2
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
4FA3
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4FA4
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4FA5
JR Z,PNXTLN
     [4F9AH]
If the Z FLAG (Zero) has been set, JUMP to 4F9AH to process the next line in the program.
4FA7
JP P,PNXTCH
     [4FA2H]
If the P FLAG has SET, LOOP BACK 5 instructions to 4FA2H to process the next character.
“ISTOKN”
4FAA
DEC HL
Back up HL to point to the prior character by DECrementing the value stored in Register Pair HL by 1.
4FAB
LD DE,TOKLST
Let Register Pair DE point to the TOKEN LIST at 4F8BH.
4FAE
LD C,0CH
The TOKEN LIST is 12 long so set Register C equal 0CH.
“LOPTKS”
4FB0
LD A,(DE)
Top of a loop to examine the tokens. First, fetch a token (i.e., the value held in the memory location pointed to by Register Pair DE) and store it into Register A.
4FB1
CP (HL)
Compare the token from the list agains the token in the program as pointed to by (HL). Results: If Register A equals the value held in Register HL, the Z FLAG is set; otherwise the NZ FLAG is set.
4FB2
JR Z,LINFOL
     [4FFEH]
If the Z FLAG (Zero) has been set, JUMP to 4FFEH.
4FB4
INC DE
If they didn’t match, then move to the next token in the list by INCrementing the value stored in Register Pair DE by 1.
4FB5
DEC C
Reduce the loop counter by DECrementing the value stored in Register C by 1.
4FB6
JR NZ,LOPTKS
      [4FB0H]
If we haven’t parsed all 12 token in the token list then LOOP BACK to 4FB0H.
4FB8
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
4FB9
CP 89H
Compare that character against the token for the INPUT command.
4FBB
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next character in the BASIC Program.
4FBC
JR NZ,4FA2H
      [4FA2H]
If the NZ FLAG (Not Zero) has been set, then we didn’t have an INPUT, so JUMP to 4FA2H to process the next character.

If we’re here, then we got an INPUT, but now we need to check to see if it was INPUT # or not.

4FBE
PUSH HL
Save the location of the character in the BASIC Program being examined in case it turns out not to be a INPUT #LEN <FORMULA>, <LINE NUMBER>; command and we need to process what we thought might have been the #.
4FBF
DEC HL
Move back 1 character in the BASIC program by DECrementing the value stored in Register Pair HL by 1.
4FC0
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FC1
CP 23H
Compare the value held in Register A against 23H (ASCII: #). If the character following the INPUT wasn’t a #
4FC3
JR NZ,NOILEN
      [4FD7H]
… JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.

If we’re here, then we got an INPUT #, but now we need to check to see if it was INPUT # LEN or not.

4FC5
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FC6
CP 0F3H
Compare the value held in Register A against 0F3H (BASIC Token: LEN). If the character following the INPUT # wasn’t a LEN
4FC8
JR NZ,NOILEN
      [4FD7H]
… JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.

If we’re here, then we got an INPUT # LEN, but now we need to check to see if it was INPUT # LEN , or not.

“”
4FCA
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FCB
JP Z,NOILEN
     [4FD7H]
If there was no next character, and we ended with INPUT # LEN, JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.
4FCE
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). If the character following INPUT # LEN was NOT a ,
4FD0
JP NZ,4FCAH
      [4FCAH]
… JUMP to 4FCAH.
4FD3
POP AF
Get rid of the location of the character in the BASIC Program being examined held at the top of the stack, because we don’t need it, as we have found INPUT #LEN ,, which would need to be followed by a line number.
4FD4
JP 4FFEH
   [4FFEH]
JUMP to LINFOL to process that line number.

4FD7H – This is an exit to the prior routine where we ultimately figured out we were not going to be processing a INPUT #LEN <FORMULA>, <LINE NUMBER>; command.

“NOILEN”
4FD7
POP HL
Restore the pointer to the location of the character in the BASIC Program into Register Pair HL. This would be the character after the span class=”code”>INPUT token.
4FD8
JP PNXTCH
   [4FA2H]
JUMP to 4FA2H to process the next character in the BASIC program.

4FDBH – Part of the “Convert all line number references to a binary line number + 2 spaces” routine if we have determined that the next character is the end of the program.

“DOCNVR”
4FDB
LD HL,(40A4H)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
4FDE
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the start of the BASIC program) with the value stored in Register Pair DE.
“LCHEAD”
4FDF
4FE0
LD H,D
LD L,E
Let HL = DE.
4FE1
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4FE2
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4FE3
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4FE4
JP Z,CLEARZ
     [5067H]
If the Z FLAG (Zero) has been set, JUMP to 5067H to zero out the ARRAY variable table and RETurn.
4FE7
4FE8
4FE9
INC HL
INC HL
INC HL
INCrement the value stored in Register Pair HL by 3 to point to the first character after the line number.
“LZLOOP”
4FEA
LD A,(HL)
Top of a loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4FEB
INC HL
INCrement the pointer in the BASIC program (stored in Register Pair HL) by 1.
4FEC
CP 0EH
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is a LINE NUMBER CONSTANT, the Z FLAG will be set …
4FEE
JR Z,TWOINX
     [4FF9H]
… so JUMP to the next routine at 4FF9H to skip over the 2 bytes of the line number and continue the loop.
4FF0
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4FF1
JR NZ,LZLOOP
      [4FEAH]
If the NZ FLAG (Not Zero) has been set, JUMP to the top of this loop at 4FEAH.

The next instructions swap out the line number with the binary version.

4FF3
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the pointer in the BASIC Program) with the value stored in Register Pair DE.
4FF4
LD (HL),E
Store the value held in Register E into the memory location pointed to by Register Pair HL.
4FF5
INC HL
INCrement the value stored in Register Pair HL by 1.
4FF6
LD (HL),D
Store the value held in Register D into the memory location pointed to by Register Pair HL.
4FF7
JR LCHEAD
   [4FDFH]
LOOP back to 4FDFH.

4FF9H – Part of the “Convert all line number references to a binary line number + 2 spaces” routine if the chararacter in the BASIC program was a LINE NUMBER CONSTANT.

“TWOINX”
4FF9
4FFA
INC HL
INC HL
INCrement the value stored in Register Pair HL by 2 to move the pointer in the BASIC program (held in Register Pair HL) past that line number constant.
4FFB
JR LZLOOP
   [4FEAH]
Continue processing by re-entering the loop at 4FEAH.

4FFDH – Routine is out of sequence and is only called by 5049H if we determine the the character in A is not numeric

“LINFL1”
4FFD
DEC HL
Back up the pointer in the BASIC program (stored in Register Pair HL) by 1 in preparation for the RST 10H command which advances HL.
“LINFOL”
4FFE
RST 10H
We are still looking for a line number. Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FFF
PUSH HL
Save the pointer in the BASIC Program (stored in Register Pair HL) to the top of the stack.
5000
OR A
Set FLAGS based on the contents of Register A to see if we are at end of line (00H) or not. If we are at the end of the line …
5001
JR Z,NOLF
     [500CH]
… JUMP to 500CH since we don’t need to check for a LINE FEED.

The LOKLF routine looks for a LINE FEED character.

“LOKLF”
5003
INC HL
INCrement the pointer in the BASIC program (stored in Register Pair HL) by 1.
5004
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5005
CP 0AH
Compare the value held in Register A against 0AH (ASCII: LINE FEED). If the current character in the BASIC program is a LINE FEED
5007
JR Z,CLRLF
     [500FH]
… replace it with a “*” and continue via a JUMP to 500FH.
5009
OR A
Set FLAGS based on the contents of Register A. If it is not end of line (i.e., 00H) ….
500A
JR NZ,LOKLF
      [5003H]
LOOP back to the top of the LOKLF routine and keep looking for the LINE FEED.

Next we are going to put a “*” wherever there was a LINE FEED. If (HL) is not a line feed, then a dummy HL of 4121H is offered as the sacrificial location to put the “*“.

“NOLF”
500C
LD HL,4121H
If (HL) wasn’t pointing to a LINE FEED we don’t want the next line to overwrite that character with a *, so let Register Pair HL equal 4121H as a dummy location to put the *.
“CLRLF”
500F
LD (HL),2AH
Store a * into the memory location pointed to by Register Pair HL (which is either the dummy location if there wasn’t a LINE FEED there, or to overwrite a LINE FEED if it was there).
5011
EX DE,HL
Put the value stored in Register Pair HL (which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) into DE. HL is discarded so it doesn’t matter what was in DE.
5012
POP HL
Restore the pointer in the BASIC Program (before searching for the LF) held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5013
PUSH HL
Save the pointer in the BASIC Program (before searching for the LF) to the top of the stack.
5014
PUSH DE
Save the contents of Register Pair DE (which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) to the top of the stack.
5015
CALL 1E5AH
     [1E5AH]
Convert the ASCII string pointed to by HL to an integer deposited into DE via a GOSUB to the Model III ROM routine at 1E5AH. After execution HL points to the delimiter and the A register contains the delimiter value. The Z flag is set if the delimiter equals 00 or 3A. Z is reset if any other delimiter is used. If the routine finds a non-numerical character, the conversion is stopped
5018
LD A,0AH
Let Register A equal 0AH (ASCII: LINE FEED.
501A
POP BC
Put the value held at the top of the STACK which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) into Register Pair BC, and then remove the entry from the stack.
501B
LD (BC),A
Restore the LINE FEED into the memory location pointed to by Register Pair BC.

Next we need to check to see if we advanced in the BASIC program.

501C
POP BC
Restore the pointer in the BASIC Program (before searching for the LF) held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
501D
LD A,L
Copy the contents of Register L (i.e., the current location in the program) into Register A.
501E
SUB C
Subtract the LSB from the program before searching for the LF from the LSB of the current location of the program, to see if we have moved. If this is NZ, there was a Line Feed.
501F
JR Z,NOLIN
     [5045H]
If the Z FLAG (Zero) has been set, go back to whence we came and continue processing characters via a JUMP to 5045H.
5021
PUSH DE
Otherwise, save the LINE NUMBER (held in Register Pair DE) to the top of the stack.

The next steps calculate the number of SPACES we need to add.

5022
LD E,A
Copy the contents of Register A into Register E.
5023
LD A,02H
Assume we want TWO spaces, so set Register A to 02H.
5025
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
5026
LD A,05H
Let Register A equal 05H.
5028
SUB E
LET Register A = Register A – Register E. Register A now holds the number of spaces we need to insert to make room for a hard line number.
5029
JR NC,MOVPR2
      [5032H]
If the number spaces is still positive, JUMP to 5032H to move the program to make room for the line number.
502B
CPL
If, however, the number of spaces went negative because the line number was more than 5 characters including zeros and spaces, we need to make even more room. First, reverse each bit in Register A (which is the same as NOT) to become positive.
502C
INC A
INCrement the value stored in Register A by 1.
502D
POP DE
Put the value held at the top of the STACK (which should be 02H) into Register Pair DE, and then remove the entry from the stack.
502E
ADD A,02H
Add two assumed spaces by letting Register A = Register A + 02H.
5030
PUSH AF
Save the space count (held in Register Pair AF) to the top of the stack.
5031
XOR A
Set Register A to ZERO and clear all Flags.

Next we make room for the hard line number, put in the hard line number indicator byte, the line number, and then spaces to fill the remainder.

“MOVPR2”
5032
PUSH BC
Save the location that the LINE VALUE CONSTANT is going to be placed (held in Register Pair BC) to the top of the stack.
5033
CALL NZ,MOVPRG
        [5071H]
If the NZ FLAG (Not Zero) has been set, ??? move (HL) for (A) bytes via a GOSUB to 5071H.
5036
POP HL
Restore the pointer to the to the BASIC program (held at the top of the Stack) into Register Pair HL). This should be the 5 bytes that need to be replaced with an actual hard line number.
5037
LD (HL),0EH
Store the flag for a LINE VALUE CONSTANT into the memory location pointed to by Register Pair HL.
5039
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
503A
POP BC
Restore the space count into Register B from the top of the STACK, as B acts as the counter of a DJNZ loop.
503B
POP DE
Restore the LINE VALUE CONSTANT (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
503C
LD (HL),E
Store the LSB of LINE VALUE CONSTANT (held in Register E) into the BASIC Program at the memory location pointed to by Register Pair HL.
503D
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
503E
LD (HL),D
Store the MSB of LINE VALUE CONSTANT (held in Register D) into the BASIC Program at the memory location pointed to by Register Pair HL.
“SPCPUR”
503F
INC HL
Top of a DJNZ loop. INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
5040
LD (HL),20H
Store a SPACE into the BASIC Program at the memory location pointed to by Register Pair HL.
5042
DJNZ SPCPUR
     [503FH]
LOOP back to 503FH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.

The line number and spaces are now present. If passing through, we need to bump HL because the routine starts off by reducing it because the RST 10H needs it to be HL-1.

“SNOLIN”
5044
INC HL
INCrement the value stored in Register Pair HL by 1.
“NOLIN”
5045
DEC HL
DECrement the value stored in Register Pair HL by 1.
5046
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
5047
5048
INC A
DEC A
Set the Z or NZ flag based on the character in Register A.
5049
JR C,LINFL1
     [4FFDH]
If the C FLAG (Carry) has been set then the character is alphabetic (and not alphanumeric), so JUMP to 4FFDH.
504B
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
504C
JP Z,PNXTLN
     [4F9AH]
If the Z FLAG (Zero) has been set then the RST 10H returned a 0, which is end of line. With this, we need to move to process the next line via a JUMP to 4F9AH.

If we are here, we know that the character held in Register A is alphanumeric and not a 00H EOL marker.

504F
DEC HL
In preparation for the next set of tests which would need such thing, we do a one time DECrement the pointer to the BASIC program (held in Register Pair HL) by 1.
5050
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE) since we want to skip any between line separators. If there is a SPACE there …
5052
JR Z,SNOLIN
     [5044H]
… push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
5054
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). If it is a ,
5056
JR Z,SNOLIN
     [5044H]
… push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
5058
CP 0CEH
Compare the value held in Register A against CEH (Decimal: 206). Results: If Register A equals 0CEH …
505A
JR Z,SNOLIN
     [5044H]
… push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
505C
CP 0D4H
Compare the value held in Register A against D4H (Decimal: 212). If A < D4H, the CARRY FLAG will be set …
505E
JR C,5064H
     [5064H]
If the C FLAG (Carry) has been set, JUMP to 5064H to zero out the array variable table and RETurn.
5060
CP 0D7H
Compare the value held in Register A against 0D7H (Decimal: 215). If A < 0D7H …
5062
JR C,5044H
     [5044H]
… push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
“GOPNXT”
5064
JP PNXTCH
   [4FA2H]
JUMP to 4FA2H to process the next character in the BASIC program.

5067H – Zero out the ARRAY variable table and RETurn.

“CLEARZ”
5067
LD HL,(40F9H)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
506A
LD (40FBH),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FBH, which is the starting address of the ARRAY VARIABLE TABLE.
506D
LD (40FDH),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FDH, which is the ending address of the ARRAY VARIABLE TABLE (a/k/a start of free memory pointer).
5070
RET
RETurn to the caller.

5071H – Routine to make room for line numbers. Moves the BASIC program down (A) bytes starting at (HL).

“MOVPRG”
5071
PUSH HL
Save the pointer to the BASIC program (held in Register Pair HL) to the top of the stack.
5072
LD HL,(40F9H)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
5075
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the END OF BASIC PROGRAM pointer) with the value stored in Register Pair DE.
5076
5078
LD H,00H
LD L,A
Let Register Pair HL = the number of bytes to move the BASIC Program down (held in Register A).
5079
ADD HL,DE
LET Register Pair HL = the offset (held in Register Pair HL) + the end of the BASIC Program in RAM (held in Register DE).
507A
LD (40F9H),HL
Store the new end of the BASIC program in RAM into memory location 40F9H which houses that very information.
507D
507E
LD B,H
LD C,L
Let BC = the new end of the BASIC program in RAM (held in Register Pair HL).
507F
POP HL
Restore the currently being worked on pointer to the BASIC program (held at the top of the stack) into Register Pair HL, and then remove the entry from the stack.
“LOPMVP”
5080
LD A,(DE)
Top of a loop that will ony exit if the variable address in DE and the variable address in HL are equal. Fetch a character from the BASIC program from the old end of the BASIC program in RAM (held in the memory location pointed to by Register Pair DE) and store it into Register A.
5081
LD (BC),A
Store that character at the new end of the BASIC program (at the memory location pointed to by Register Pair BC).
5082
RST 18H
RST 18 to see if the variable address in HL is the same as in DE, so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
5083
RET Z
If the variable address in DE and the variable address in HL are equal, RETurn to the caller.
5084
5085
DEC DE
DEC BC
If the variable address in DE and the variable address in HL are NOT the same, DECrement the value stored in Register Pair DE and BC each by 1.
5086
JR LOPMVP
   [5080H]
LOOP BACK to 5080H.

5088H – Convert the value held in Register Pair HL into INTEGER and then into ASCII (held in Register Pair HL).

“LINDSP”
5088
CALL 0A9AH
     [0A9AH]
GOSUB to 0A9AH in the Model III ROM routine to put the value in HL into the single precision number storage area of 4121H and is flagged as an INTEGER.
508B
XOR A
Set Register A to ZERO.
508C
CALL 1034H
     [1034H]
GOSUB to 1034H to turn off the EDIT flag and initialize the 4130H input buffer for a FLOATING POINT to ASCII conversion by putting a SPACE into 4130H.
508F
OR (HL)
Set the flags by merging the value held in Register A against the byte of the program pointed to by Register Pair HL.
5090
JP 0FD9H
   [0FD9H]
JUMP to 0FD9H in the Model III ROM to convert the integer value in 4124H to an ASCII string pointed to by Register Pair HL.

5093H – “COMPRESS” a BASIC Program Routine.

“CMPRES”
5093
LD HL,(40A4H)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
5096
LD (BUFPNT),HL
Store begining pointer to the BASIC program (held in Register Pair HL) into memory location 51AEH.
5099
LD A,(HL)
Fetch the value held at the beginning of the BASIC program and store it into Register A.
509A
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
509B
OR (HL)
Set the flags by merging the first byte of the program (held in Register A) against the second byte of the program (in the memory location pointed to by Register Pair HL)
509C
RET Z
If the Z FLAG (Zero) has been set based on that OR, then there is no program present; so RETurn to the caller.

509DH – Continuation of “COMPRESS”. We at least know that there is a program in RAM.

509D
LD A,E
Test to see if there are spaces, REMs, or both via the next few instructions. First, copy the contents of Register E into Register A. I have no idea how E is loaded, but if E is 0, it will handle SPACES, if E is 1, it will handle REMarks, and if E is 2, it will handle both.
509E
ADD A,A
LET Register A = Register E * 2, as the SWITCH TABLE is a table of 2 byte addresses.
509F
50A0
LD E,A
LD D,00H
Let Register Pair DE = old Register E * 2. This will serve as an offset in the SWITCH TABLE.
50A2
LD HL,SWTAB
Let Register Pair HL equal 50ABH which is a SWITCH TABLE.
50A5
ADD HL,DE
LET Register Pair HL = the SWITCH TABLE (held in Register Pair HL) + and offset of either 0, 2, or 4 (held in Register Pair DE).
50A6
LD E,(HL)
Fetch the LSB of the address from the SWITCH TABLE into Register E.
50A7
INC HL
INCrement to the next byte of the SWITCH TABLE.
50A8
LD D,(HL)
Fetch the MSB of the address from the SWITCH TABLE into Register D.
50A9
EX DE,HL
Since there is no JP (DE) comment in the Z-80, we need to EXchange the value stored in Register Pair HL (i.e., the pointer to the MSB in the SWITCH TABLE) with the value stored in Register Pair DE (i.e., the address from the SWITCH TABLE).
50AA
JP (HL)
   [HL])
JUMP to the address from the SWITCH TABLE (held in Register Pair HL).

50ABH – “COMPRESS” – Switch Table.

“SWTAB”
50AB
DEFW 6C 51H
For Spaces
50AD
DEFW BAH 50H
For Remarks
50AF
DEFW B1H 50H
For BOTH

50B1H – Continuation of “COMPRESS” – Jump Table Point for BOTH

“BOTH”
50B1
CALL SPACES
     [516CH]
Process the compression for SPACE via a GOSUB to 516CH.
50B4
LD HL,(40A4H)
Since we’re now going to pass through to REM, the pointers are no longer what they would have been if we jumped, so we need to fix that. Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
50B7
LD (BUFPNT),HL
Store the value held in Register Pair HL into memory location 51AEH.

50BAH – Continuation of “COMPRESS” – Jump Table Point for REMARK

This routine will remove all REMarks from a BASIC program. If REM is the first token on a line, the comment is removed but the REM stays (as there may be GOTOs to those lines). Otherwise, the :, the REM, and the comment are all struck.

“REMARK”
50BA
LD HL,(BUFPNT)
Fetch the value held in memory location 51AEH and store it into Register Pair HL.
50BD
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
50BE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
50BF
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
50C0
JP Z,DOCLN
     [5136H]
If the Z FLAG (Zero) has been set based on that OR, then there is no program present (or we are at the end of the program); so clean up (and return to BASIC) via a JUMP to 5136H.
50C3
LD DE,0003H
Set up for an offset of 03 charagcters (Address of next line PLUS a line number) by setting Register Pair DE to 0003H.
50C6
ADD HL,DE
LET Register Pair HL = the pointer to the BASIC program (held in Register Pair HL) + 03H (held in Register DE). HL now points to the first character of the line.
50C7
LD E,00H
Prepare a counter by setting Register E to 00H.
“REMAR1”
50C9
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
50CA
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
50CB
OR A
Set FLAGS based on the contents of Register A to see if we are at the end of the line (Z) or not (NZ).
50CC
JR NZ,50D3H
      [50D3H]
If we are not at the end of the program line yet JUMP to 50D3H to continue.
50CE
LD (BUFPNT),HL
If we are, however, at the end of the program line, then this program line is done; so set the buffer pointer (of 51AEH) to point to the next character of the program.
50D1
JR REMARK
   [50BAH]
JUMP to the top of this REMARK (at 50BAH) routine and keep processing, now with the new HL.

50D3H – Continuation of “COMPRESS” routine processing REMarks. Jumped here if we are not at the end of the line and still need to process it.

“REMAR2”
50D3
INC E
INCrement the counter (stored in Register E) by 1.
50D4
CP 93H
Compare the value held in Register A against 93H (BASIC TOKEN: REM). If the character in the BASIC program pointed to by HL is a REM token …
50D6
JR Z,REMAR3
     [50E5H]
… JUMP to 50E5H.
50D8
CP 27H
Compare the value held in Register A against 27H (ASCII: ). If the character in the BASIC program pointed to by HL is a token …
50DA
JR Z,REMAR3
     [50E5H]
… JUMP to 50E5H.
50DC
LD B,22H
Let Register B equal 22H (ASCII: ).
50DE
CP 22H
Compare the character in the BASIC Program (held in Register A) against a (ASCII: ). If Register A is a
50E0
CALL Z,SKQUOT
       [511DH]
… skip over it via a GOSUB to 511DH …
50E3
JR REMAR1
   [50C9H]
… and then LOOP BACK to process the next character via a JUMP to 50C9H.

50E5H – Continuation of “COMPRESS” routine processing REMarks. See if the REMark is at the beginning of the line or not.

“REMAR3”
50E5
LD A,E
Copy the counter (in Register E) into Register A.
50E6
CP 01H
Check to see if the REMark token or character was in first position. If not then …
50E8
JR NZ,REMAR4
      [50F4H]
See what is after that REMark token via a JUMP to 50F4H.
50EA
LD A,(HL)
If, however, the first character was not a REM, keep processing characters by fetching a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
50EB
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
50EC
JR NZ,REMAR5
      [50FCH]
If that byte was NOT a zero, then we are NOT at the end of the line, so JUMP to 50FCH to clear the rest of the line.
50EE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
50EF
LD (51AEH),HL
Store the current character into 51AEH to be the new pointer (thus erasing everything after it).
50F2
JR REMARK
   [50BAH]
JUMP to 50BAH to keep looking for REMarks.

50F4H – Continuation of “COMPRESS” routine processing REMarks; deal with whatever followed the REM token.

“REMAR4”
50F4
50F5
DEC HL
DEC HL
Back up the pointer to the BASIC program (held in Register Pair HL) by 1 to get to the :.
50F6
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A. This should be a :.
50F7
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). If Register A equals :
50F9
JR Z,50FCH
     [50FCH]
… JUMP to 50FCH to continue.
50FB
INC HL
If Register A was not the : we expected, we need to leave that character alone by INCrementing the pointer to the BASIC program (held in Register Pair HL) by 1.
“REMAR5”
50FC
LD (HL),00H
End the program line by putting a 00H into the position in the BASIC program pointed to by Register Pair HL.
50FE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1 to now be the character after the REM.
50FF
LD (TEMPX),HL
Store the pointer into memory location 51B0H.

The next instructions move us to the end of the line.

5102
LD E,00H
Prepare a counter by setting Register E to 00H.
“REMAR6”
5104
LD A,(HL)
Top of a loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5105
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5106
JR Z,510CH
     [510CH]
If the Z FLAG (Zero) has been set, then we are at the end of the line, so exit via a JUMP to 510CH.
5108
INC E
If we are, however, not at the end of the line, we need to keep going. INCrement the counter (stored in Register E) by 1.
5109
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
510A
JR REMAR6
   [5104H]
LOOP BACK 6 instructions until we hit the end of the line via a JUMP to 5104H.

510CH – Continuation of “COMPRESS” routine processing REMarks; deal with the end of line.

“REMAR7”
510C
LD A,E
Copy the counter (from Register E) into Register A.
510D
LD BC,(TEMPX)
Fetch the “move to” pointer (held in memory location 51B0H) and store it into Register Pair BC.
5111
INC HL
INCrement the “move from” pointer (held in Register Pair HL) by 1.
5112
CALL MOVPGM
     [5159H]
Move the program down via a GOSUB to 5159H.
5115
LD HL,(TEMPX)
Fetch the “move to” pointer (held in memory location 51B0H) and store it into Register Pair HL.
5118
LD (BUFPNT),HL
Store “move to” pointer (held in Register Pair HL) and put it as the current line (being tracked in memory location 51AEH).
511B
JR REMARK
   [50BAH]
Move to the next line and keep processing by a JUMP BACK to 50BAH.

511DH – Continuation of “COMPRESS” routine processing REMarks. Subroutine to skip over a QUOTE mark.

“SKQUOT”
511D
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
511E
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
511F
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
5120
JR NZ,SKQUO1
      [5124H]
If the NZ FLAG (Not Zero) has been set, then we are NOT at the end of the line, so JUMP to 5124H to check.
5122
SCF
Otherwise, we are at the end of the line and since the CARRY FLAG is going to be important, turn the CARRY FLAG on.
5123
RET
RETurn to the caller.

5124H – Continuation of “COMPRESS” routine processing REMarks. Continuation of the subroutine to skip over a QUOTE mark if we are NOT at the end of line.

“SKQUO1”
5124
INC E
INCrement the counter (stored in Register E) by 1.
5125
CP B
Compare the value held in Register A against the value held in Register B (which is a (ASCII: ). If the current character is a
5126
RET Z
… RETurn to the caller.
5127
JR SKQUOT
   [511DH]
… otherwise …, we need to keep looking for the close quote via a JUMP BACK to 511DH.

5129H – Continuation of “COMPRESS” routine, but called later in the program. This subroutine skips space and tabs.

“SKIPSP”
5129
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
512A
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
512B
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). If the current character is a SPACE
512D
JR Z,SKIPSP
     [5129H]
… skip over it by JUMPing to the top of this subroutine.
512F
CP 09H
Compare the value held in Register A against 09H (ASCII: TAB). If the current character is a TAB
5131
JR Z,SKIPSP
     [5129H]
… skip over it by JUMPing to the top of this subroutine.
5133
DEC HL
If we’re here, then we are at a character in the BASIC program we don’t want remove, so back up the pointer to the BASIC program (held in Register Pair HL) by 1.
5134
OR A
Before we return, we want to set the flags to see if we are at the END OF LINE (i.e., 00H), so do an OR A to set the Z FLAG.
5135
RET
RETurn to the caller.

5136H – Continuation of “COMPRESS” routine. Jumped to when it is time to clean up the linked addresses and then exit.

“DOCLN”
5136
LD DE,(40A4H)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H into Register Pair DE.
“LDHEAD”
513A
513B
LD H,D
LD L,E
Let HL = DE.
513C
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A. This byte should be a LINKED ADDRESS.
513D
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
513E
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
513F
JR Z,CLEARY
     [514FH]
Set the new END OF PROGRAM and EXIT TO BASIC via a JUMP to 514FH.
5141
5142
5143
INC HL
INC HL
INC HL
Bump past the 3 characters for a line number by INCrementing the pointer to the BASIC program (held in Register Pair HL) by 3.
“LJLOOP”
5144
LD A,(HL)
Top of a 4 instruction loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5145
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
5146
OR A
Check to see if that prior byte (held in A) is an END OF LINE (i.e., 00H), and if NOT …
5147
JR NZ,LJLOOP
      [5144H]
LOOP BACK to 5144H.
5149
EX DE,HL
At this point, we are at the END OF A LINE and HL holds the byte after the END OF LINE BYTE. Put the LINKED ADDRESS into Register Pair DE.
514A
LD (HL),E
Store the LSB of the LINKED ADDRESS held in Register E into the memory location pointed to by Register Pair HL.
514B
INC HL
INCrement the value stored in Register Pair HL by 1.
514C
LD (HL),D
Store the MSB of the LINKED ADDRESS held in Register D into the memory location pointed to by Register Pair HL.
514D
JR LDHEAD
   [513AH]
LOOP BACK to the 2nd line of this routine (513AH) to cycle through the entire BASIC program.

514FH – Continuation of “COMPRESS” routine. We are done so set the RAM Pointers to the new End of Program and then EXIT to BASIC.

“CLEARY”
514F
LD HL,(40F9H)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
5152
LD (40FBH),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FBH, which is the starting address of the ARRAY VARIABLE TABLE.
5155
LD (40FDH),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FDH, which is the ending address of the ARRAY VARIABLE TABLE (a/k/a start of free memory pointer).
5158
RET
RETurn to BASIC.

5159H – Subroutine in the COMPRESS” routine. This routine moves the BASIC program down starting at (HL) into (BC).

“MOVPGM”
5159
PUSH HL
Save the “move from” address (held in Register Pair HL) to the top of the stack.
515A
LD DE,(40F9H)
Fetch the END OF BASIC PROGRAM pointer from memory location 40F9H and store it into Register Pair DE.
515E
EX DE,HL
Since DE will always be bigger than HL, and the Z-80 does not have an instruction to subtract against DE, swap them.
515F
OR A
The CARRY FLAG will be important here so clear the CARRY FLAG.
5160
SBC HL,DE
Calculate the number of bytes to move by SUBtracting DE from HL.

The next instructions move all the variables around so that they fit into the LDIR mold.

5162
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the number of bytes to move) with the value stored at the top of the stack (i.e., the MOVE FROM address).
5163
5164
PUSH BC
POP DE
Copy the “move to” address (held in Register Pair BC) to Register Pair DE.
5165
POP BC
Put the the number of bytes to move ( held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
5166
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
5168
LD (40F9H),HL
Set the END OF BASIC PROGRAM pointer in RAM to the end of the code we just moved (held in Register Pair HL).
516B
RET
RETurn to the caller.

516CH – – Continuation of “COMPRESS” – Jump Table Point for CLEAR SPACES processing. Routine will clear out SPACES and TABS except inside QUOTES and FIELD statements.

“SPACES”
516C
LD HL,(BUFPNT)
Fetch the location in the BASIC program to process (held in memory location 51AEH) and store it into Register Pair HL.
516F
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
5170
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
5171
OR (HL)
Test to see if the next character is 00H by OR’ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
5172
JP Z,DOCLN
     [5136H]
If the Z FLAG (Zero) has been set, we are at the end of the program so clean up (and return to BASIC) via a JUMP to 5136H.
5175
LD DE,0003H
We want to skip over the 3 bytes of a line number and space so set Register Pair DE = 0003H.
5178
ADD HL,DE
Advance our BASIC Pointer by 3 by setting Register Pair HL = Register Pair HL + Register DE.
“SPACE1”
5179
LD A,(HL)
Top of a Loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
517A
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
517B
OR A
Set FLAGS based on the contents of Register A.
517C
JR NZ,SPACE2
      [5183H]
If the character is not an END OF LINE, JUMP to 5183H.
517E
LD (BUFPNT),HL
Save our current poition as the new line pointer in memory location 51AEH.
5181
JR SPACES
   [516CH]
LOOP BACK to the top of this routine (516CH) to keep processing via the next line.

5183H – Continuation of CLEAR SPACES subroutine of the “COMPRESS” routine. Jumped to if we are past the line number + space and NOT at end of line.

“SPACE2”
5183
LD B,22H
Let Register B equal .
5185
CP 22H
Compare the current character in the BASIC program (held in Register A) against 22H (ASCII: ). If it is a
5187
JR Z,DOSKIP
     [518FH]
… skip over processing it via a JUMP to 518FH because we aren’t removing spaces from quoted text.
5189
LD B,3AH
Let Register B equal :.
518B
CP 0A3H
Compare the value held in Register A against 0A3H (BASIC Token: FIELD). If the character of the BASIC program was not a FIELD token …
518D
JR NZ,SPACE3
      [5199H]
… continue with the removing of the spaces by JUMPing to 5199H.

We are here either because we jumped here from 5187 because we are inside a quote, or because we passed through and we hit a FIELD token. Either way, we want to skip over deleting the spaces.

“DOSKIP”
518F
CALL SKQUOT
     [511DH]
Skip over the spaces (and don’t delete them) via a GOSUB to 511DH.
5192
JR NC,SPACE1
      [5179H]
If the NC FLAG (No Carry) has been set by that routine, then we are NOT at the END OF LINE, so LOOP BACK to 5179H to keep processing.
5194
LD (BUFPNT),HL
If we’re here then that routine indicated we are at the end of a line, so save our current position as the new line pointer in memory location 51AEH.
5197
JR SPACES
   [516CH]
LOOP BACK to the very top of the compress spaces routine at 516CH.

5199H – Continuation of CLEAR SPACES subroutine of the “COMPRESS” routine. Jumped here if we know that we are not within a QUOTE or in a FIELD statement.

“SPACE3”
5199
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). If we are at a SPACE) …
519B
JR Z,SPACE4
     [51A1H]
… eliminate it via a JUMP to 51A1H.
519D
CP 09H
Compare the value held in Register A against 09H (ASCII: TAB). If we are NOT at a TAB) …
519F
JR NZ,SPACE1
      [5179H]
… move to the next character in the BASIC program via a JUMP to 5179H.

Actually elimiate the TAB or SPACE character.

“SPACE4”
51A1
DEC HL
Back up the pointer to the BASIC program to the character to be deleted.
51A2
LD B,H
LD C,L
Let BC = HL so that BC also points to the character being deleted.
51A4
CALL SKIPSP
     [5129H]
Skip over spaces and tabs via a GOSUB to 5129H which will adjust HL to point to the first non-space and non-tab character (and set the Z flag if we are at the END OF LINE). BC is not modified by that routine.
51A7
PUSH BC
Save the pointer to the character being deleted (held in Register Pair BC) to the top of the stack.
51A8
CALL MOVPGM
     [5159H]
Compress the program to eliminate the SPACE/TAB byte via a GOSUB to 5159H.
51AB
POP HL
Restore the pointer to the character being deleted from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
51AC
JR SPACE1
   [5179H]
Continue by jumping back into the main routine at 5179H.

51AEH – “COMPRESS” routine MESSAGE and BYTE storage area.

“BUFPNT”
51AE
DEFS 02
“TEMPX”
51B0
DEFS 02
 
END 4E00H
That’s it!