TRS-80 – Level 1 ROM Disassembled

0000H
DI
Disable Interrupts.
0001H
LD HL,00FFH
Let Register Pair HL equal 00FFH, which, when the very next instruction hits, will turn HL into FFFFH.
0004H
JUMP to 018EH to determine How Much RAM is in the System and then continue with startup.
0007H
NOP
No Operation (Do Nothing).

0008H – RST 08H Routine – This routine requires TWO parameters … a value as the next bit and a byte offset. DE is advanced to the next non-space and tests it against the value. If there is no match, jumps to the return value PLUS the offset. If there is match, jumps to the byte after the offset.

0008H
EX (SP),HL
Since this routine ultimately changes the place to which it returns, we need to get that address so EXchange the value stored in Register Pair HL with the value stored in Register Pair SP.
0009H
RST 28H
Call RST 28H to move DE to point to the next non-space character, with Register A holding that character.
000AH
CP (HL)
Compare the next non-space character (held in Register A) against the value held at the top of the stack (i..e, in the memory location pointed to by the value held in Register Pair HL). Results:
  • If Register A equals the value held in Register (HL), the Z FLAG is set.
  • If A < (HL), the CARRY FLAG will be set.
  • if A >= (HL), the NO CARRY FLAG will be set.
000BH
Continue on with a JUMP to 0098H.

000EH – Display a CARRIAGE RETURN.

000EH
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN). Routine then falls through to RST 10H which displays the character.

0010H – RST 10H Routine – This routine will send a character to the screen or to the cassette.

0010H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0011H
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0012H
GOSUB to 0FF0H to check to see if the cassette motor is running.
0015H
JUMP to 0ACBH to send the byte held in Register A either to the screen or the cassette.

0018H – RST 18H Routine – This routine will parse an expression.

0018H
GOSUB to 07ADH to parse an expressions.
001BH
NOP
No Operation (Do Nothing).
001CH
JUMP to 075DH to parse an optional relational expression (“>” “<” or “=“).
001FH
NOP
No Operation (Do Nothing).

0020H – RST 20H Routine – This routine will compare HL and DE. NZ means no match, Z means match.

0020H
LD A,H
Copy the contents of Register H into Register A.
0021H
CP D
Compare Register H (held in Register A) against Register D. Results:
  • If Register A equals the value held in Register D, the Z FLAG is set.
  • If A < D, the CARRY FLAG will be set.
  • if A >= D, the NO CARRY FLAG will be set.
0022H
RET NZ
If the NZ FLAG (Not Zero) has been set, RETurn to the caller.
0023H
LD A,L
If we’re here, then H matched D so let’s keep going. Copy the contents of Register L into Register A.
0024H
CP E
Compare Register L (held in Register A) against Register E. Results:
  • If Register A equals the value held in Register E, the Z FLAG is set.
  • If A < E, the CARRY FLAG will be set.
  • if A >= E, the NO CARRY FLAG will be set.
0025H
RET
RETurn to the caller.
0026H
NOP
No Operation (Do Nothing).
0027H
NOP
No Operation (Do Nothing).

0028H – RST 28H Routine – This routine will skip forward from DE until the first non-space character, with Register A holding that character.

0028H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0029H
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE).. Results: If Register A equals SPACE, the Z FLAG is set.
002BH
RET NZ
If the NZ FLAG (Not Zero) has been set, then we have a non-space held in A, so RETurn to the caller.
002CH
INC DE
Otherwise, we still have a space so INCrement the value stored in Register Pair DE by 1.
002DH
JUMP to 0028H to test that character.

0030H – RST 30H Routine – This routine will continue execution.

0030H
POP AF
Put the return address (which should be held at the top of the STACK) into Register Pair AF.
0031H
GOSUB to 08B3H to check if the next character is a “:” and if yes, JUMP to 08BAH to check for a CARRIAGE RETURN and if not then jump to the MIDDLE of the EXECUTE NEXT LINE routine.
0034H
JUMP to 08C9H to display the “WHAT” error.
0037H
NOP
No Operation (Do Nothing).

0038H – RST 38H Routine – This routine will check a variable to make sure it exists. If it doesn’t, CARRY will be set. If it does, HL will point to the variable and NC will be set. Note that only variables A-Z and A(n) are valid in Level 1.

0038H
RST 28H
First, move to where the variable should be via a Call RST 28H to search DE until a non-space character is found, with Register A holding that character.
0039H
SUB 41H
SUBtract the value 41H (ASCII: A) from Register A.
003BH
RET C
If the CARRY FLAG has been set then the variable (i.e., the non-space character) was less than A, meaning an invalid variable. RETurn to the caller with the CARRY FLAG set.
003CH
CP 1AH
Compare the value held in Register A against 1AH (Decimal: 26). Results:
  • If Register A equals 26, the Z FLAG is set.
  • If A < 26, the CARRY FLAG will be set.
  • if A >= 26, the NO CARRY FLAG will be set.
003EH
CCF
So at this point, a good variable will be less than 26 (with the CARRY FLAG set) and a bad variable will be greater than or equal to 26 (with the NC set). This is backwards from an error, so invert the state of the CARRY FLAG, so that a bad variable has the CARRY set and a good variable has the NC set.
003FH
RET C
If the CARRY FLAG has been set, meaning we have a bad variable, RETurn to the caller.
0040H
INC DE
If we’re here then we have a good variable at DE. INCrement the value stored in Register Pair DE by 1.
0041H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself). This tests to see if the variable at DE is an “A” or not, as “A” is the only variable that can be an array in Level 1.
0042H
If the NZ FLAG (Not Zero) has been set (meaning that the variable is not “A”), JUMP to 0082H to continue processing the single valid non-array variable.
0044H
RST 08H
28H
3AH
Next we need to check for the array, which means a parenthesis. We do this a call to RST 08H with parameters of “(” and an offset of 3AH. RST 08H will move to the next non-space character and check it against 28H (which is a “(“). If there is no match, jump to the return (of the next instruction, i.e. 0047H) + 3AH instructions (which would be 0081H).
0047H
If we are here then the next character pointed to by DE is the subscript of an A() variable. GOSUB to 080BH to determine that subscript as a non-negative integer.
004AH
INC HL
Now we need to position HL to point to the variable. INCrement the value stored in Register Pair HL by 1.
004BH
ADD HL,HL
Double HL.
004CH
ADD HL,HL
Double HL Again!
004DH
If the C FLAG (Carry) has been set because of all that math, then HL doesn’t have a valid value anymore so display the “HOW?” error via a JUMP to 01A2H.
0050H
PUSH HL
If the CARRY FLAG didn’t trip, then we have a valid pointer value in HL so save it to the top of the stack.
0051H
RST 08H
29H
35H
Next we need to check for close parenthesis. We do this a call to RST 08H with parameters of “)” and an offset of 35H. RST 08H will move to the next non-space character and check it against 29H (which is a “)”). If there is no match, jump to the return (of the next instruction, i.e. 0054H) + 35H instructions (which would be 0089H).
0054H
POP HL
Restore HL from the top of the stack.
0055H
PUSH DE
Save the current pointer on the line being analyzed (held in Register Pair DE) to the top of the stack.
0056H
PUSH HL
Save the pointer to the variable (held in Register Pair HL) to the top of the stack.
0057H
LD HL,(406AH)
Fetch the value of the top of physical memory (held in memory location 406AH) and store it into Register Pair HL.
005AH
LD DE,(406CH)
Fetch the pointer to the top of user RAM (held in memory location 406CH) and store it into Register Pair DE.
005EH
XOR A
Set Register A to ZERO and clear all Flags.
005FH
SBC HL,DE
Subtracts the top of user RAM and the CARRY FLAG from the top of physical memory, with the results into Register Pair HL.
0061H
POP DE
Restore the pointer to the variable (formerly held in Register Pair HL) from the top of the stack into Register Pair DE.
0062H
RST 20H
Compare HL and DE via a call to RST 20H – NZ means no match, Z means match. If H=D but L < E, then the C flag will be set.
0063H
Continue on via a JUMP to 0076H.

0066H – Non-Maskable Interrupt Routine. This would be triggered on hitting the RESET BUTTON.

0066H
DI
Disable Interrupts.
0067H
LD SP,4200H
Set the Stack Pointer to 4200H.
006AH
XOR A
Set Register A to ZERO and clear all Flags.
006BH
LD (4090H),A
Store the ZERO held in Register A into the cassette port status cache (held in memory location 4090H).
006EH
OUT (FFH),A
Send the ZERO held in Register A into the cassette port.
0070H
LD A,0CH
Let Register A equal 0CH (ASCII: Form Feed).
0072H
RST 10H
Send the character held in Register A (i.e., 0CH) to the cassette or screen via a RST 10 call.
0073H
Show the READY prompt via a JUMP to 01C9H.

0076H – Continuation point for the RST 38H routine. At this point, HL has the current pointer to the line being examined is at the top of the stack, DE has the pointer to the variable, Z/NZ is set based on whether the location of the array variable is in or out of bounds, and if Register A is greater than Register E, the CARRY FLAG is set.

0076H
If the C FLAG (Carry) has been set then we have a problem, so JUMP to 08F5H to display the “SORRY” error.
0079H
LD HL,(406AH)
Fetch the value of the top of physical memory (held in memory location 406AH) and store it into Register Pair HL.
007CH
SBC HL,DE
Subtracts the value stored in Register Pair DE (the pointer to the variable) and the carry flag from the value stored in Register Pair HL (the top of physical memory).
007EH
POP DE
Put he current pointer to the line being examined (held at the top of the STACK) back into Register Pair DE.
007FH
XOR A
Set Register A to ZERO and clear all Flags.
0080H
RET
RETurn to the caller.

0081H – Continuation point for the RST 38H routine; jumped to if the variable is “A” and no “(” was found after it. This routine will set HL to point to the RAM address which holds the variables “A” – “Z”

0081H
XOR A
Set Register A to ZERO and clear all Flags.

0082H – Continuation point for the RST 38H routine; jumped to if the variable is “B”-“Z”. Register A will contain 0-25, representing variables “A”-“Z”.

0082H
LD H,40H
Let Register H equal 40H to set the MSB to the variable list of 4000H (Variable A) through 4064H (Variable Z)
0084H
0085H
RLA
RLA
Rotate the bits of Register left (i.e., lower bit moves higher) two bit positions so that A will correspond to 00H (Variable A) to 64H (Variable Z)
0086H
LD L,A
Set the LSB of the Register Pair HL variable pointer to the offset calculated and held in Register A.
0087H
XOR A
Set Register A to ZERO and clear all Flags.
0088H
RET
RETurn to the caller.

0089H – Jump to the routine to Display the “WHAT” error.

0089H
JUMP to 08C9H to display the “WHAT” error.

008CH – Subroutine to check to see if the character pointed to by Register Pair DE is, or is not, a digit. If a digit is found, will retuen with Register A containing the digit and NC set, or the CARRY FLAG set otherwise.

008CH
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
008DH
CP 30H
Compare the value held in Register A against 30H (ASCII: 0). Results:
  • If Register A equals 0, the Z FLAG is set.
  • If A < 0, the CARRY FLAG will be set.
  • if A >= 0, the NO CARRY FLAG will be set.
008FH
RET C
If the C FLAG (Carry) has been set then its not a digit because it’s below 0, so RETurn to the caller with the CARRY FLAG set.
0090H
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :), which is 1 character higher than a 9. Results:
  • If Register A equals :, the Z FLAG is set.
  • If A < :, the CARRY FLAG will be set.
  • if A >= :, the NO CARRY FLAG will be set.
0092H
CCF
If we have a good character, the CARRY FLAG will have been set by the CP instruction. Since the CARRY FLAG being set is supposed to signal a bad character, we need to invert the state of the CARRY FLAG.
0093H
RET C
If the C FLAG (Carry) has been set then its not a digit because it’s above9, so RETurn to the caller with the CARRY FLAG set.
0094H
INC DE
If we are here then we have a good digit stored in Register A. Now a bit of cleanup. First advance the pointer on the line being examined (held in Register Pair DE) by 1 to point to the next character instead of the one we just examined.
0095H
AND 0FH
Cap the number at 15 by MASKing the value of Register A against 0FH (0000 1111). This has the effect of turning off bits 7, 6, 5, 4, leaving only bits 3, 2, 1, 0 active.
0097H
RET
RETurn to the caller.

0098H – Continuation of the RST 08H routine. At this point Register A holds the next non-space character, Register Pair HL holds what used to be the value held at the Stack Pointer, and the value held at the Stack Pointer contains what used to be HL.

0098H
INC HL
INCrement the value stored in Register Pair HL by 1 so as to point to the OFFSET parameter passed to the RST 08H routine.
0099H
If the Z FLAG (Zero) has been set, then the characters we were comparing did, in fact, match, so JUMP to 00A2H.
009BH
PUSH BC
If we are here, then the characters didn’t match, so we need to calculate THAT offset. Save the contents of Register Pair BC to the top of the stack since we are about to use those registers to set up an OFFSET.
009CH
LD C,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register C.
009DH
LD B,00H
Since this is an offset and needs to be below 256, the MSB will always be 00H, so set B (the MSB) to 00H. Register Pair BC now contains the offset.
009FH
ADD HL,BC
LET Register Pair HL = Register Pair HL (the location of the next instruction) + Register BC (the offset).
00A0H
POP BC
Restore BC from the top of the STACK.
00A1H
DEC DE
DECrement the pointer to the current character on the line we are examining (stored in Register Pair DE) by 1.
00A2H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
00A3H
INC HL
INCrement the pointer to the next instruction (as calculated) by 1.
00A4H
EX (SP),HL
EXchange the pointer to the next instruction (stored in Register Pair HL) with the value stored in at the top of the stack. The top of the stack now holds the next instruction to execute, which is pulled by the Z-80 for use in a RETurn.
00A5H
RET
RETurn to the designated address.

00A6H – Analyze a Floating Point Constant.

00A6H
GOSUB to 0155H which resets Bit 6 of Register B, swaps register sets, sets H, L, and C to 00H, swaps register sets, and RETurns. This is in anticipation of starting to parse.
00A9H
LD B,00H
Let Register B equal 00H.
00ABH
LD C,B
Set Register C to 00H (i.e., the contents of Register B). In this routine, Register C will contain the number of digits found after a decimal point and Register B will contain various statuses of the analysis.
00ACH
RST 28H
Call RST 28H to move DE to point to the next non-space character, with Register A holding that character.
00ADH
GOSUB to 00B2H to continue processing the numbers.
00B0H
LOOP BACK one instruction.

00B2H – Subroutine called from the FLOATING POINT CONSTANT routine at 00A6H.

00B2H
GOSUB to 008CH to check to see if the character pointed to by Register Pair DE is, or is not, a digit. Returns Register A contaning the digit, or the CARRY FLAG set otherwise.
00B5H
If the C FLAG (Carry) has been set then we do not have a digit, so JUMP away to 00D7H.
00B7H
SET 6,B
If we are here, then Register A contains a digit, so we need to start processing. SET (i.e., set as 1) BIT 6 of Register B. Bit 6 of Register B will mean that a digit was found.
00B9H
BIT 7,B
Test Bit Number 7 of Register B, which is set if there are a lot of digits to process and reset if there are not. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
00BBH
If the NZ FLAG (Not Zero) has been set then there are not a lot of digits to process so JUMP to 00D2H.
00BDH
GOSUB to 00C5H to do some processing.
00C0H
BIT 0,B
Test Bit Number 0 of Register B, which is set if a decimal point has been found and reset if a decimal point has not been found. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
00C2H
RET Z
If the Z FLAG (Zero) has been set, meaning we found a decimal point, RETurn to the caller.
00C3H
DEC C
DECrement the value stored in Register C by 1.
00C4H
RET
RETurn to the caller.

00C5H – Subroutine called from the FLOATING POINT CONSTANT routine at 00A6H. This routine will accumulate the current digit and set the bits of Register B accordingly.

00C5H
GOSUB to 015EH to to accumulate the digit by multiplying the accumulator by 10 and then adding in A to the newly vacant one’s spot. Routine will return a NZ SET if an overflow occurs from the accumulation.
00C8H
RET Z
If the Z FLAG (Zero) has been set then the accumulator is still small so RETurn to the caller.
00C9H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
00CAH
00CBH
LD H,D
LD L,E
Let HL = DE.
00CCH
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
00CDH
LD C,A
Copy the contents of Register A into Register C.
00CEH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
00CFH
SET 7,B
SET (i.e., set as 1) BIT 7 of Register B so as to indicate that there are a large number of digits.
00D1H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
00D2H
BIT 0,B
Since we have a “large number”, we need to track the digits after the decimal point. Test Bit Number 0 of Register B, which will be set if a decimal point was already found and reset if no decimal point has been found. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
00D4H
RET NZ
If the NZ FLAG (Not Zero) has been set, meaning that no decimal point has been found, RETurn to the caller.
00D5H
INC C
INCrement the value stored in Register C (which holds the number of digits found after the decimal point) by 1.
00D6H
RET
RETurn to the caller.

00D7H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here from 00B5H if we were processing characters and came across a non-digit.

00D7H
RST 08H
2EH
05H
If we have a non-digit, the ONLY valid character that still has us continuing without an error would be a “.”. With this, we call to RST 08H with parameters of “.” and an offset of DFH. RST 08H will move to the next non-space character and check it against 2EH (which is a “.”). If there is no match, jump to the return (of the next instruction, i.e. 00DAH) + 05HH instructions (which would be 00DFH).
00DAH
BIT 0,B
If we are here, then the next character was a “.”. Test Bit Number 0 of Register B which would be set if we had already found a decimal point and reset if we hadn’t. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
00DCH
SET 0,B
SET (i.e., set as 1) BIT 0 of Register B to indicate that we have found a decimal point, noting that if the Z flag is set, we have TWO decimal points, which is a problem.
00DEH
RET Z
If the Z FLAG (Zero) has been set, then we have two decimal points which is a problem, so RETurn to the caller.
POP AF
Put the value held at the top of the STACK into Register Pair AF.
00E0H
BIT 6,B
Test Bit Number 6 of Register B (which tracks whether or not we have found a digit). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
00E2H
RET Z
If the Z FLAG (Zero) has been set then we haven’t actually seen any digits yet … so RETurn to the caller.
00E3H
LD L,18H
Let Register L equal 18H (Decimal: 24).
00E5H
LD H,00H
Let Register H equal 00H.
00E7H
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
00E8H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
00E9H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
00EAH
GOSUB to 0E00H to normalize C, H, and L.
00EDH
LD BC,000AH
Let Register Pair BC equal 000AH (Decimal: 10).
00F0H
ADD IX,BC
Move the FLOATING POINT STACK pointer of IX down 2 sets of FLOATING POINT NUMBERS (i.e., 5 bytes * 2).
00F2H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
00F3H
LD BC,00FBH
Let Register Pair BC equal 00FBH (Decimal: -5).
00F6H
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
00F7H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
00F8H
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

00FBH – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if we have a non-digit that isn’t a “.”. This routine will check for “E” and “+“.

00FBH
POP BC
Put the value held at the top of the STACK into Register Pair BC.
00FCH
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
00FDH
RST 08H
45H
1CH
If we have a non-digit that wasn’t a “.” we next check for other non-digits which are valid … in this case an “E” which would be part of an EXPONENT. With this, we call to RST 08H with parameters of “E” and an offset of 1CH. RST 08H will move to the next non-space character and check it against 45H (which is a “E”). If there is no match, jump to the return (of the next instruction, i.e. 0100H) + 1CH instructions (which would be 011CH).
0100H
RST 08H
2BH
02H
If we have a non-digit that wasn’t a “.” we next check for other non-digits which are valid … in this case a “+” which would be part of an EXPONENT. With this, we call to RST 08H with parameters of “+” and an offset of 1CH. RST 08H will move to the next non-space character and check it against 2BH (which is a “+“). If there is no match, jump to the return (of the next instruction, i.e. 0103H) + 02H instructions (which would be 0105H).
0103H
JUMP to 010AH.

0105H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if we have a non-digit that isn’t a “.”, “E”, or “+“. This routine will check for ““.

0105H
RST 08H
2DH
02H
If we have a non-digit that wasn’t a “.”, “E”, or “+” we next check for other non-digits which are valid … in this case a “” which would be part of an EXPONENT. With this, we call to RST 08H with parameters of “” and an offset of 02H. RST 08H will move to the next non-space character and check it against 2DH (which is a ““). If there is no match, jump to the return (of the next instruction, i.e. 0108H) + 02H instructions (which would be 010AH).
0108H
SET 1,B
If we’re here then we got a match on the “” so we SET (i.e., set as 1) BIT 1 of Register B to indicate that an exponent minus sign has been parsed.

010AH – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if we have a non-digit that isn’t a “.”, “E”, or “+“, or ““.

010AH
GOSUB to 0157H to zero out the integer accumulator.
010DH
GOSUB to 008CH to check to see if the character pointed to by Register Pair DE is, or is not, a digit. Returns Register A contaning the digit, or the CARRY FLAG set otherwise.
0110H
If the CARRY FLAG has been set, and we do not have a digit, JUMP to 0120H.
0112H
SET 5,B
SET (i.e., set as 1) BIT 5 of Register B to indicate that we have found a digit in an exponent position.
0114H
GOSUB to 015EH to accumulate the exponent’s digit by multiplying the accumulator by 10 and then adding in A to the newly vacant one’s spot. Routine will return a NZ SET if an overflow occurs from the accumulation.
0117H
If the NZ FLAG (Not Zero) has been set, meaning we have an overflow, display the “HOW?” error via a JUMP to 01A2H.
011AH
JUMP to 010DH to parse the next character.

011CH – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if we have a non-digit that isn’t a “.” or an “E”.

011CH
POP DE
Restore the current position on the line being evaluated from the top of the stack into Register Pair DE.
011DH
XOR A
Set Register A to ZERO and clear all Flags.
011EH
JUMP to 0137H.

0120H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if we have started processing an exponent and then hit a non-digit.

0120H
BIT 5,B
Test Bit Number 5 of Register B to determine if we already have exponent digits. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0122H
If the Z FLAG (Zero) has been set and we have no exponent digits, JUMP to 011CH.
0124H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
0125H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0126H
LD A,C
Copy the contents of Register C into Register A.
0127H
OR H
OR Register H against Register A. The results are stored in Register A.
0128H
The NZ will be set if either Register C or Register H is not zero. If that’s the case, then we have a problem (most likely an overflow) and the NZ FLAG (Not Zero) will have been set, JUMP to 0151H to swap the registers back and give a “HOW” error.
012AH
LD A,L
Copy the exponent (held in Register L) into Register A.
012BH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
012CH
BIT 7,A
Test Bit Number 7 of Register A to see if we have a large number of digits (meaning, over 128). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
012EH
If the NZ FLAG (Not Zero) has been set, display the “HOW?” error via a JUMP to 01A2H.
0131H
BIT 1,B
Test Bit Number 1 of Register B to see if we have found a exponent minus sign. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0133H
If the Z FLAG (Zero) has been set, JUMP to 0137H.
0135H
NEG
At this point, we have a valid exponent … but its sign is wrong. Negate the contents of Register A (which is the same as -A).
0137H
ADD A,C
LET Register A = Register A + Register C.
0138H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0139H
If the Z FLAG (Zero) has been set, then Register A, after all that, is still zero — so we were given an E00. Since that’s not relevant, JUMP away to 014EH to exit the routine.
013BH
BIT 7,A
Test Bit Number 7 of Register A to see if we have a large number of digits (meaning, over 128). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
013DH
If the Z FLAG (Zero) has been set then we have a POSITIVE exponent to process … JUMP to 0146H.
013FH
INC A
INCrement the value stored in Register A by 1.
0140H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0141H
GOSUB to 0C95H to divide the floating point stack by 10.
0144H
JUMP to 014BH.

0146H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; jumped here if to process a POSITIVE exponent.

0146H
DEC A
DECrement the value stored in Register A by 1.
0147H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0148H
GOSUB to 0C84H to multiply the floating point stack by 10.
014BH
POP AF
Put the value held at the top of the STACK into Register Pair AF.
014CH
JUMP to 0138H.

014EH – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; exit the floating point routine.

014EH
BIT 6,B
Test Bit Number 6 of Register B to see if we had found any digits. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0150H
RET
RETurn to the caller – If Z is set, then we had a bad value.

0151H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; exit the floating point routine with a HOW error.

0151H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0152H
Display the “HOW?” error via a JUMP to 01A2H.

0155H – Continuation of the FLOATING POINT CONSTANT routine at 00A6H; Clear out H’, L’, C’, and Bit 6 of Register B’ in anticipation of starting to parse.

0155H
RES 6,B
RESet (i.e., set as 0) BIT 6 of Register B to zero out the flag as to whether we have found a digit yet or not.
0157H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0158H
LD L,00H
Let Register L equal 00H.
015AH
LD H,L
Copy a 0 (i.e., the contents of Register L) into Register H.
015BH
LD C,L
Copy a 0 (i.e., the contents of Register L) into Register C.
015CH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
015DH
RET
RETurn to the caller.

015EH – Continuation of the FLOATING POINT CONSTANT routine at 00A6H. This basically multiplies the 24 bit digit represented by C’H’L’ by 10 and then adds in A’ with overflow going to B’ thus leaving a 32 bit result of B’C’H’L’. Specifically it accumulates the digit by multiplying the accumulator by 10 and then adding in A to the newly vacant one’s spot. Routine will return a NZ SET if an overflow occurs from the accumulation. On entry, the REGULAR REGISTER SET is active.

015EH
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
015FH
EXX
Set the ALTERNATE REGISTER SET as active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0160H
0161H
LD D,H
LD E,L
Let Register Pair DE’ = Register Pair HL’.
0162H
LD A,C
Copy the contents of Register C’ into Register A’.
0163H
LD B,00H
Let Register B’ equal 00H. Register B’ tracks a whole lot of status bits for the floating point routine. Bit 0=Decimal point has been found, Bit 1 = Exponent with a Minus Sign has been Found, Bit 5 = Digits in an exponent have been found, Bit 6 = A digit has been found, and Bit 7 = A large number of digits (more than 127) have been found.
0165H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0166H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
0167H
RL C
Rotate the bits of Register C left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register C by 2.
0169H
RL B
Rotate the bits of Register B left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register B by 2.

So at this point HL, C, and B have all been multiplied by 2.

016BH
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
016CH
RL C
Rotate the bits of Register C left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register C by 2.
016EH
RL B
Rotate the bits of Register B left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register B by 2.

So at this point HL, C, and B have all been multiplied by 4 total.

0170H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE.
0171H
ADC A,C
LET Register A = Register A + Register C. So now Register A = Register C * 5.
0172H
LD C,A
Save Register C * 5 to Register C.
0173H
LD A,00H
Let Register A equal 00H.
0175H
ADC A,B
LET Register A = Register A + Register B. So now Register A = Register B * 5.
0176H
LD B,A
Save Register B * 5 to Register B.

So at this point HL, C, and B have all been multiplied by 5 total.

0177H
POP AF
Restore the original value of C into A from the stack.
0178H
ADD HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
0179H
RL C
Rotate the bits of Register C left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register C by 2.
017BH
RL B
Rotate the bits of Register B left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register B by 2.

So at this point HL, C, and B have all been multiplied by 10 total.

017DH
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.

The rest of the routine is devoted to adding Register A to Register Pairs HL and BC.

017EH
ADD A,L
LET Register A = Register A + Register L.
017FH
LD L,A
Copy A + L back into Register L.
0180H
LD A,00H
Let Register A equal 00H.
0182H
ADC A,H
LET Register A = Register A + Register H.
0183H
LD H,A
Copy A + H back into Register H.
0184H
LD A,00H
Let Register A equal 00H.
0186H
ADC A,C
LET Register A = Register A + Register C.
0187H
LD C,A
Copy the contents of Register A into Register C.
0188H
LD A,00H
Let Register A equal 00H.
018AH
ADC A,B
LET Register A = Register A + Register B.
018BH
LD B,A
Copy the contents of Register A into Register B.
018CH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
018DH
RET
RETurn to the caller.

018EH – Determine How Much RAM is in the System.

018EH
DEC H
DECrement the value stored in Register H by 1. On the first run this turns HL’s 00FFH into FFFFH.
018FH
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
0190H
CPL
Reverse each bit in Register A (which is the same as NOT).
0191H
LD (HL),A
Store the value held in Register A into the memory location pointed to by Register Pair HL.
0192H
XOR (HL)
eXclusive OR the value stored at (HL) against Register A. Why XOR the value against itself (since the value at HL was just set as A) when XORing a value against itself produces a Zero? Well, the ram location might not exist, which is the only way that XOR would produce a NZ result.
0193H
If the NZ FLAG (Not Zero) has been set then the RAM location pointed to by HL didn’t accept the value, so LOOP back to 018EH to keep reducing the page of RAM to test (so FFFF to FEFF to FDFF …).
0195H
LD (406AH),HL
If we are here, then we hit the first tested address that stored a value. Store THAT address (held in Register Pair HL) into memory location 406AH (which is the top of physical memory).
0198H
XOR A
Set Register A to ZERO and clear all Flags.
0199H
LD (4090H),A
Store a 0 (held in Register A) into the cassett port status cache (held at memory location 4090H).
019CH
LD SP,4200H
Set the stack pointer to 4200H / (Decimal: 16896).
019FH
JUMP to 037BH to continue with the startup process.

01A2H – Display the “HOW?” error.

01A2H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
01A3H
LD DE,01A9H
Let Register Pair DE equal 01A9H to point to the HOW? message
01A6H
JUMP to 08CDH.

01A9H – MESSAGE STORAGE AREA.

01A9H
“HOW?” + 0DH
01AEH
“READY” + 0DH
01B4H
“WHAT?” + 0DH
01BAH
“SORRY” + 0DH
01C0H
“BREAK AT”
01C8H
DEFB 00H

01C9H – BASIC’s READY Entry Point. If JUMPed here, the BASIC RUN STATE is cleared.

01C9H
LD SP,4200H
Set the stack pointer to 4200H.
01CCH
GOSUB to 0FE4H to turn off the cassette motor.

01CFH – BASIC’s READY Alternate Entry Point. If JUMPed here, the BASIC RUN STATE is not affected.

01CFH
GOSUB to 000EH to display a CARRIAGE RETURN.
01D2H
LD DE,01AEH
Let Register Pair DE equal 01AEH, which is the message storage area for the READY prompt.
01D5H
GOSUB to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found

01D8H – Process a line of code in a READY loop

01D8H
LD SP,4200H
Set the stack pointer to 4200H.
01DBH
GOSUB to 0239H to clear the 10 bytes starting at 409DH and set Register Pair DE to 4200. 409D is the pointer to the line where a STOP statement was activated, 409F is the pointer to the current line being executed, 40A1 is the pointer for the READ statement, 40A3 is the BASIC Stack Pointer location, and 40A5 is the porter for the current FOR variable.
01DEH
LD IX,40F4H
Let Special Index Register Pair IX, which is used in the floating point math routines, equal 40F4H, which is the bottom of floating point stack. Each entry is 5 bytes consisting of LSB, Middle, MSB (with Bit 7 set), Exponent and Sign (in Bit 7)
01E2H
GOSUB to 08FAH to fetch a line of input.
01E5H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
01E6H
LD DE,40ACH
Let Register Pair DE equal 40ACH.
NOTE: 40ACH is the storage location for buffer for command input AND the print output to cassette.
01E9H
The first thing we should find is a line number, so GOSUB to 0EC4H to parse an integer into Register Pair HL. Note, this moves DE forward to point to the first non-blank character.
01ECH
01ECH
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
01EEH
POP BC
Restore the prior contents of Register Pair DE into Register Pair BC.
01EFH
The flag is currently set by the OR above. If the value is 0, then we are on the command line instead of being inside a program. So … if the Z FLAG (Zero) has been set, JUMP to 0340H.
01F2H
DEC DE
If we are here, then we are parsing a line in a program. DECrement the value stored in Register Pair DE by 1 to go back to the second number in the 2 byte line number (as DE was moved forward in the call to 0EC4H).
01F3H
LD A,H
Copy the second byte of the line number (held in Register H) into Register A.
01F4H
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
01F5H
DEC DE
DECrement the value stored in Register Pair DE by 1 to point DE to the first number in the 2 byte line number.
01F6H
LD A,L
Copy the first byte of the line number (held in Register L) into Register A.
01F7H
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
01F8H
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
01F9H
PUSH DE
Save the contents of Register Pair DE (currently pointing to the line number of the line to be parsed) to the top of the stack.
01FAH
LD A,C
Copy the contents of Register C into Register A.
01FBH
SUB E
LET Register A = Register C – Register E.
01FCH
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
01FDH
GOSUB to 092AH to find the line in RAM which matches the line number pointed to by Register Pair HL. Note: A jump to 092AH resets DE. To do the routine while preserving DE, jump instead to 092DH.

The line number has been found, so we will overwrite/delete the old line

0200H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0201H
If the NZ FLAG (Not Zero) has been set, JUMP to 0213H.
0203H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0204H
GOSUB to 0945H to scan the entire line.
0207H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0208H
LD HL,(406CH)
Fetch the pointer to the top of used RAM (held in memory location 406CH) and store it into Register Pair HL.
020BH
GOSUB to 0A6FH to copy the bytes held at (DE) to (BC), backwards, until DE = HL.
020EH
LD H,B
LD L,C
Copy the contents of Register Pair BC into Register Pair HL because there is no LD (xxxx),BC command in the Z-80!
0210H
LD (406CH),HL
Now that we used up some RAM, set the NEW top of used RAM to HL by putting HL into 406CH (which points to the top of used RAM).

If we are here we will add a new line to the program UNLESS it was just a line number, in which case we delete the line.

0213H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0214H
LD HL,(406CH)
Fetch the pointer to the top of used RAM (held in memory location 406CH) and store it into Register Pair HL.
0217H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
0218H
PUSH HL
Save the contents of Register Pair HL (which should be holding the pointer to the end of the line to be moved) to the top of the stack. This will be POPed into DE at 022EH.
0219H
CP 03H
Compare the value held in Register A against the end-of-line terminator 03H. Results: If Register A equals 03H, the Z FLAG is set.
021BH
If the Z FLAG (Zero) has been set then we are at EOL delimeter, so JUMP to the top of the READY LOOP (minus the READY prompt) at 01D8H to inifintely process another line of code.

If we are here then we did not hit the EOL delimter. The next bunch of calls and math is first designed to make sure there is enough RAM to store the whole line, so HL is set up to be the highest RAM location needed to store the line.

021DH
ADD A,L
LET Register A = Register A + Register L.
021EH
LD L,A
Copy the contents of Register A into Register L. These 2 commands are basically HL = HL + A.
021FH
LD A,00H
Let Register A equal 00H.
0221H
ADC A,H
LET Register A = Register A + Register H.
0222H
LD H,A
Copy the contents of Register A into Register H.
0223H
LD DE,(406AH)
Fetch the value of the top of physical memory (held in memory location 406AH) and store it into Register Pair DE.
0227H
RST 20H
Call the routine at RST 20H to This routine will compare HL (the highest RAM address needed to store the line) and DE (the highest possible RAM location). Results: NZ means no match, Z means match. If H=D but L < E, then the C flag will be set.
0228H
Since the RST 20H in the prior instruction was testing too see if the byte we need to store in RAM exceeds the amount of free RAM or not, a NC means we are out of RAM. If the NC FLAG (No Carry) has been set, JUMP to 08F4H to display the “WHAT” error.
022BH
LD (406CH),HL
If we are here, then we still had enough RAM left and BC remains untouched so that it still points to the starting location of the text to move via the call at 0A77H. We still need to set up DE and HL for that call, so store the value held in Register Pair HL into memory location 406CH (which points to the top of used RAM), as HL is where the bytes from (BC) to (DE) will be moved to.
022EH
POP DE
Put the value held at the top of the STACK into Register Pair DE.
022FH
GOSUB to 0A77H to copy the bytes, backwards, from BC through DE to HL.
0232H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0233H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0234H
GOSUB to 0A6FH to copy the bytes held at (DE) to (BC), backwards, until DE = HL.
0237H
JUMP to the top of the READY LOOP (minus the READY prompt) at 01D8H to inifintely process another line of code.

0239H – Clear the 10 bytes from 409DH to 40A6H and set Register Pair DE to 4200H.

0239H
LD B,0AH
Let Register B equal 0AH (Decimal: 10) for a DJNZ loop of 10 iterations.
023BH
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
023CH
LD HL,409DH
Let Register Pair HL equal 409DH, which is the parse pointer which is saved when a STOP command is executed.
023FH
LD (HL),00H
Store the value 00H into the memory location pointed to by Register Pair HL.
0241H
INC HL
INCrement the value stored in Register Pair HL by 1.
0242H
LOOP back to 023FH, 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.
0244H
LD DE,4200H
Let Register Pair DE equal 4200H.
0247H
POP HL
Restore whatever was in Register Pair HL before this routine back into Register Pair HL.
0248H
RET
RETurn to the caller.

0249H – RESERVED WORD LOOKUP/VECTOR TABLE.

0249H
DEFM “LIST”
024DH
DEFW 8401H
The entry point for the LIST command is 0401H.
024FH
DEFM “RUN”
0251H
DEFW 838CH
The entry point for the RUN command is 038CH.
0249H
DEFM “NEW”
0257H
DEFW 8378H
The entry point for the NEW command is 0378H.
0259H
DEFM “CONT”
025DH
DEFW 83EBH
The entry point for the CONT command is 03EBH.
025FH
DEFM “CLOAD”
0264H
DEFW 8EE9H
The entry point for the CLOAD command is 0EE9H.
0266H
DEFM “CSAVE”
026BH
DEFW 8F3BH
The entry point for the CSAVE command is 0F3BH.
026DH
DEFM “NEXT”
0271H
DEFW 85A3H
The entry point for the NEXT command is 05A3H.
0273H
DEFM “LET”
0276H
DEFW 86B8H
The entry point for the LET command is 06B8H.
0278H
DEFM “INPUT”
027DH
DEFW 8623H
The entry point for the INPUT command is 0623H.
027FH
DEFM “IF”
0281H
DEFW 85FBH
The entry point for the IF command is 05FBH.
0283H
DEFM “ON”
0285H
DEFW 84FEH
The entry point for the ON command is 04FEH.
0287H
DEFM “GOTO”
028BH
DEFW 83B5H
The entry point for the GOTO command is 03B5H.
028DH
DEFM “GOSUB”
0292H
DEFB 84C4H
The entry point for the GOSUB command is 04C4H.
0294H
DEFM “RESET”
0299H
DEFB 8838H
The entry point for the RESET command is 0838H.
029BH
DEFM “RETURN”
02A1H
DEFB 84E6H
The entry point for the RETURN command is 04E6H.
02A3H
DEFM “READ”
02A7H
DEFB 86F9H
The entry point for the READ command is 06F9H.
02A9H
DEFM “RESTORE”
02B0H
DEFB 86CDH
The entry point for the RESTORE command is 06CDH.
02B2H
DEFM “REM”
02B5H
DEFB 85F6H
The entry point for the REM command is 05F6H.
0287H
DEFM “DATA”
02BBH
DEFB 85F6H
The entry point for the DATA command is 05F6H.
02BDH
DEFM “FOR”
02C0H
DEFB 8546H
The entry point for the FOR command is 0546H.
02C2H
DEFM “PRINT”
02C7H
DEFB 842FH
The entry point for the PRINT command is 042FH.
02C9H
DEFM “SET”
02CCH
DEFB 883CH
The entry point for the SET command is 083CH.
02CEH
DEFM “STOP”
02D2H
DEFB 83C5H
The entry point for the STOP command is 03C5H.
02D4H
DEFM “END”
02D7H
DEFB 8387H
The entry point for the END command is 0387H.
02D9H
DEFM “CLS”
02DCH
DEFB 84B5H
The entry point for the CLS command is 04B5H.
02DEH
DEFB 86B3H
That’s the end of the single command reserved words. If none of the above reserved words were found, JUMP to 06B3H, which will process a variable assignment.
02E0H
“GOTO”
02E4H
DEFW 850FH
The entry point for the ON x GOTO command is 050FH.
02E6H
“GOSUB”
02EBH
DEFW 8517H
The entry point for the ON x GOSUB command is 0517H.
02EDH
DEFW 88C9H
If we were looking for a GOTO or GOSUB, and they weren’t found, the JUMP here to 08C9H will display the “WHAT” error.
02EFH
“RND”
02F2H
DEFW 8E47H
The entry point for the RND command is 0E47H.
02F4H
“ABS”
02F7H
DEFW 8819H
The entry point for the ABS command is 0819H.
02F9H
“MEM”
02FCH
DEFW 8821H
The entry point for the MEM command is 0821H.
02FEH
“INT”
0301H
DEFW 882FH
The entry point for the INT command is 082FH.
0303H
“POINT”
0308H
DEFW 8840H
The entry point for the POINT command is 0840H.
030AH
DEFW 87F2H
030CH
DEFM “TO”
030EH
DEFB 8555H
The entry point for the TO command is 0555H.
0310H
DEFB 88C9H
0312H
DEFM “STEP”
0316H
DEFB 8560H
The entry point for the STEP command is 0560H.
0318H
DEFB 8565H
031AH
DEFM “TAB”
031D
DEFB 849FH
The entry point for the TAB command is 049FH.
031FH
DEFM “AT”
0321H
DEFB 8473H
The entry point for the AT command is 0473H.
0323H
DEFM “A$”
0325H
DEFB 8459H
The entry point for the A$ command is 0459H.
0327H
DEFM “B$”
0329H
DEFB 845EH
The entry point for the B$ command is 045EH.
032DH
>
032EH
DEFW 8763H
The entry point for the > operator is 0763H.
0330H
=
0331H
DEFW 878BH
The entry point for the = operator is 078BH.
0333H
<
0334H
DEFW 8773H
The entry point for the “<” operator is 0773H.
0336H
DEFW 8797H
This is the jump point for when a relational expression is not found.
0338H
DEFM “THEN”
033CH
DEFW 8611H
The entry point for the THEN command is 0611H.
033EH
DEFW 8617H

0340H – Part of the READY loop routine; jumped to when the instruction line being interpreted is on the command line instead of being part of a program.

0340H
LD HL,0248H
Let Register Pair HL equal 0248H, which is the top of the RESERVED WORD LOOKUP LIST, in preparation to check to see if the next character(s) (which are pointed to by Register Pair DE) is/are a reserved word.

The next batch of code is to try to match the instruction to a reserved word.


0343H
RST 28H
Call RST 28H to move DE (which should be the pointer to the current character of the line being interpreted) to point to the next non-space character, with Register A holding that character.
0344H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
0345H
LD A,(DE)
Fetch the non-space character to interpret from the instruction line (pointed to by Register Pair DE) and store it into Register A.
0346H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0347H
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next entry in the RESERVED WORD LOOKUP/VECTOR TABLE.
0348H
CP (HL)
Compare the value held in Register A (i.e., the current character being interpreted from the instruction line) against the reserved word value held in the memory location pointed to by the value held in Register Pair HL. Results If Register A equals the value held in Register (HL), the Z FLAG is set.
0349H
If the Z FLAG (Zero) has been set then we have a potential match between the character on the instruction line and a reserved word, so JUMP to 0351H.
034BH
BIT 7,(HL)
We have a mismatch, so lets see if we hit the branch addresses instead of a reserved word by testing Bit Number 7 of Register (HL) (which would be an “8”). Z FLAG will be set if that bit is 0 (meaning the next item in the RESERVED WORD LOOKUP/VECTOR TABLE did NOT start with an 8), and NZ FLAG will be set if that bit is 1 (meaning the next item in the RESERVED WORD LOOKUP/VECTOR TABLE did start with an 8).
034DH
If the NZ FLAG (Not Zero) has been set then we are at a branch address instead of a reserved word, so JUMP to 035BH.
034FH
If we are here, then we hit NEITHER a first letter match NOR a branch instruction, so JUMP to 0362H.

0351H – Continuation of the routine to parse an instruction line; jumped from 0349H if we have a first character match from the instruction line vs a reserved word.

0351H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0352H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0353H
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next entry in the RESERVED WORD LOOKUP/VECTOR TABLE.
0354H
CP (HL)
Compare the value held in Register A (i.e., the current character being interpreted from the instruction line) against the reserved word value held in the memory location pointed to by the value held in Register Pair HL. Results If Register A equals the value held in Register (HL), the Z FLAG is set.
0355H
If the Z FLAG (Zero) has been set then we have another match, so keep looping back to 0351H.
0357H
BIT 7,(HL)
We have a mismatch, so lets see if we hit the branch addresses instead of a reserved word by testing Bit Number 7 of Register (HL) (which would be an “8”). Z FLAG will be set if that bit is 0 (meaning the next item in the RESERVED WORD LOOKUP/VECTOR TABLE did NOT start with an 8), and NZ FLAG will be set if that bit is 1 (meaning the next item in the RESERVED WORD LOOKUP/VECTOR TABLE did start with an 8).
0359H
If the Z FLAG (Zero) has been set then we have matched an entire keyword BUT did not hit an address, so we don’t have a match yet. JUMP to 035EH.
035BH
DEC DE
If we are here then we got a match! Back up 1 character on the instruction line so DE points to the first character in the address instead of the second one.
035CH
JUMP to 0370H.

035EH – Continuation of the routine to parse an instruction line; jumped here from 0359H if we MIGHT have a match. The following code will see if we are using an abbreviation instead.

035EH
CP 2EH
Compare the value held in Register A against 2EH (ASCII: .). Results: If Register A equals ., the Z FLAG is set.
0360H
If the Z FLAG (Zero) has been set then it turns out we did have a match, just that we matched against an abbreviation. JUMP to 036BH.
0362H
INC HL
If we are here then there we finally know we had no match. Move to the next instruction in the RESERVED WORD LOOKUP/VECTOR TABLE by skipping the address … to do this, INCrement the value stored in Register Pair HL by 1.
0363H
BIT 7,(HL)
Test Bit Number 7 of Register (HL) to see if it is an “8” meaning that there is a SECOND address. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0365H
If the Z FLAG (Zero) has been set then there is yet another address, so loop back to 0362H to strip the address.
0367H
INC HL
Move to the next character in the RESERVED WORD LOOKUP/VECTOR TABLE by INCrementing the value stored in Register Pair HL by 1.
0368H
POP DE
Restore the the current character of the line being interpreted from the stack (put there at 0344H).
0369H
LOOP BACK to 0343H to look for more keyword matches.

036BH – Continuation of the routine to parse an instruction line. This loops to skip all characters until we hit an address.

036BH
INC HL
Move to the next instruction in the RESERVED WORD LOOKUP/VECTOR TABLE by INCrementing the value stored in Register Pair HL by 1.
036CH
BIT 7,(HL)
Test Bit Number 7 of Register (HL) to see if it is an “8” meaning that there is an address. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
036EH
If the Z FLAG (Zero) has been set then we haven’t found an address yet, so LOOP back to 036BH.
0370H
LD A,(HL)
If we are here, then we found an address in the RESERVED WORD LOOKUP/VECTOR TABLE. Now we fetch the MSB (the value held in the memory location pointed to by Register Pair HL) and store it into Register A.
0371H
INC HL
Move to the next character in the RESERVED WORD LOOKUP/VECTOR TABLE by INCrementing the value stored in Register Pair HL by 1.
0372H
LD L,(HL)
Fetch the LSB (held in the memory location pointed to by Register Pair HL) and store it into Register L.
0373H
AND 7FH
MASK the value of Register A against 7FH (0111 1111). This has the effect of turning off bits 7, leaving only bits 6, 5, 4, 3, 2, 1, 0 active. We need to do this because we were using bit 7 for something else and it isn’t part of the address!
0375H
LD H,A
Copy the converted MSB (held in Register A) into Register H.
0376H
POP AF
Clear the routine return address from the stack.
0377H
JP (HL)
JUMP to the address now held in (HL).

0378H – Entry point for the NEW Command.

0378H
GOSUB to 08C5H which will check the next character on the instruction line (pointed to by DE) for a CARRIAGE RETURN. If that’s what it finds, it returns here. If it finds anything else (meaning, an unwanted character), it will display the “WHAT” error message.

037BH – Continuation of the start-up process, following determination of the RAM in the system.

037BH
LD A,0CH
Let Register A equal 0CH (ASCII: Form Feed).
037DH
RST 10H
Send the character held in Register A (i.e., a form feed) to the cassette or screen via a RST 10 call.
037EH
LD HL,4200H
Let Register Pair HL equal 4200H.
0381H
LD (406CH),HL
Store the value held in Register Pair HL into memory location 406CH (which points to the top of used RAM) to signify that 4200H and on is available.
0384H
Enter they READY command line routine via a JUMP to 01C9H.

0387H – Entry point for the END Command.

0387H
GOSUB to 08C5H which will check the next character on the instruction line (pointed to by DE) for a CARRIAGE RETURN. If that’s what it finds, it returns here. If it finds anything else (meaning, an unwanted character), it will display the “WHAT” error message.
038AH
Enter they READY command line routine via a JUMP to 01C9H.

038CH – Entry point for the RUN Command.

038CH
GOSUB to 08C2H to parse an integer into Register Pair HL.
038FH
GOSUB to 0239H to clear the 10 byte byffer starting at 409DH and set Register Pair DE to 4200.
0392H
Preserve Register Pair HL (which is the line number to RUN) by skipping the next instruction (which resets HL to 0000H) and JUMP to 0397H.

0394H – Common routine continuation point. Execute the Next Line.

0394H
LD HL,0000H
Let Register Pair HL equal 0000H.
0397H
GOSUB to 092DH to find the line in RAM which matches the line number pointed to by Register Pair HL, while preserving the value held in Register Pair DE.
039AH
If the C FLAG (Carry) has been set, enter they READY command line routine via a JUMP to 01C9H.
039CH
LD (409FH),DE
If we are here then DE is pointing to the line to execute. Store the value held in Register Pair DE into memory location 409FH (which is the pointer to the current line being executed).
03A0H
03A1H
INC DE
INC DE
INCrement the value stored in Register Pair DE by 2 to bypass the line number.
03A2H
GOSUB to 0B40H to fetch a keystroke from the keyboard (note: does not wait for a keypress).
03A5H
CP 03H
Compare the value held in Register A against 03H, which would indicate a BREAK. Results: If Register A equals BREAK, the Z FLAG is set.
03A7H
If the Z FLAG (Zero) has been set, JUMP to 03C5H (which is the entry point for the STOP Command).
03A9H
GOSUB to 0FE4H to turn off the cassette motor.
03ACH
LD IX,40F4H
Let Special Index Register Pair IX equal 40F4H, which is the bottom of the floating point stack.
03B0H
LD HL,026CH
Let Register Pair HL equal 026CH which is in the middle of the RESERVED WORD LOOKUP/VECTOR TABLE.
03B3H
JUMP to 0343H in the READY COMMAND LOOP, albeit with an odd pointed to the RESERVED WORD LOOKUP/VECTOR TABLE starting point.

03B5H – Entry point for the GOTO Command.

03B5H
GOSUB to 0EBDH to parse an integer into HL or set NZ for an error. RETURN if NZ, or JUMP to 08C9H to display the “WHAT” error otherwise.
03B8H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
03B9H
GOSUB to 08C5H which will check the next character on the instruction line (pointed to by DE) for a CARRIAGE RETURN. If that’s what it finds, it returns here. If it finds anything else (meaning, an unwanted character), it will display the “WHAT” error message.
03BCH
GOSUB to 092AH to find the line in RAM which matches the line number pointed to by Register Pair HL. Note: A jump to 092AH resets DE. To do the routine while preserving DE, jump instead to 092DH.
03BFH
If the NZ FLAG (Not Zero) has been set, JUMP to 01A3H to display the “HOW?” error.
03C2H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
03C3H
JUMP to 039CH in the prior routine to keep processing instructions on the already-identified line.

03C5H – Entry point for the STOP Command.

03C5H
LD (409DH),DE
Store the value held in Register Pair DE as the parse pointer which is saved when a STOP command is executed (held in memory location 409DH).
03C9H
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
03CBH
RST 10H
Send the character held in Register A (i.e., CARRIAGE RETURN) to the cassette or screen via a RST 10 call.
03CCH
LD DE,01C0H
Let Register Pair DE equal 01C0H, to point to the “BREAK AT” message in the ROM message table.
03CFH
GOSUB to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found. This message is going to be followed by a line number.
03D2H
LD HL,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair HL.
03D5H
LD (4097H),HL
Store the value held in Register Pair HL into memory location 4097H (which is the address of the current line).
03D8H
LD E,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register E.
03D9H
INC HL
INCrement the value stored in Register Pair HL by 1.
03DAH
LD D,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register D.
03DBH
LD HL,0000H
Let Register Pair HL equal 0000H.
03DEH
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
03E1H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.

A this point, Register Pair HL contains the line number to display.

03E2H
GOSUB to 096DH to display the contents of Register Pair HL as a decimal number.
03E5H
LD A,0DH
Let Register A equal 0DH (ASCII: CARRIAGE RETURN).
03E7H
RST 10H
Send the character held in Register A (i.e., CARRIAGE RETURN) to the cassette or screen via a RST 10 call.
03E8H
JUMP to the middle of the READY COMMAND LINE LOOP at 01DEH, at a point after SP and DE are reset, and leaving the 10 byte buffer at 409DH alone.

03EBH – Entry point for the CONT Command.

03EBH
CONT does not take parameters so GOSUB to 08C5H which will check the next character on the instruction line (pointed to by DE) for a CARRIAGE RETURN. If that’s what it finds, it returns here. If it finds anything else (meaning, an unwanted character), it will display the “WHAT” error message.
03EEH
LD HL,(409DH)
Let Register Pair HL equal the value stored at 409DH, which is the parse pointer which is saved when a STOP command is executed.
03F1H
03F2H
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
03F3H
If the Z FLAG (Zero) has been set then there was no address to continue to; so enter they READY command line routine via a JUMP to 01C9H.
03F5H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
03F6H
LD HL,(4097H)
Restore the current execution line by first fetching the address of the current line (held in memory location 4097H) and store it into Register Pair HL.
03F9H
LD (409FH),HL
… and then storing it into 409FH (which is the pointer to the current line being executed).
03FCH
GOSUB to 08B3H to check if the next character is a “:” and if yes, JUMP to 08BAH to check for a CARRIAGE RETURN and if not then jump to the MIDDLE of the EXECUTE NEXT LINE routine.
03FFH
Execute the code pointed to by Register Pair DE via JUMP to 03A2H in the middle of the EXECUTE NEXT LINE, which will check for BREAK (and if found, STOP) or else reset the cassette motor, set IX to the bottom of the floating point stack, set HL to point to the middle of the reserved word list, and parse for matching reserved words.

0401H – Entry point for the LIST Command.

0401H
First, let’s see if we were given a parameters line number (such as LIST 20) by GOSUBing to 08C2H to parse an integer into Register Pair HL.
0404H
GOSUB to 092AH to find the line in RAM which matches the line number pointed to by Register Pair HL. Note: A jump to 092AH resets DE. To do the routine while preserving DE, jump instead to 092DH.
0407H
LD C,0CH
Let Register C equal 0CH (Decimal: 12) for a loop of 12 lines to display.
0409H
If the C FLAG (Carry) has been set then no line was found in RAM so JUMP to 042DH (which just JUMPs to 03E8H which just JUMPS to 01DEH) to the middle of the READY COMMAND LINE LOOP.
040BH
DEC C
DECrement the value stored in Register C by 1.
040CH
If the Z FLAG (Zero) has been set, JUMP to the next routine at 0418H.
040EH
PUSH BC
Preserve BC to the stack due to the next CALL.
040FH
GOSUB to 0A63H to display the line number pointed to by Register Pair DE on screen.
0412H
POP BC
Restore BC from the stack.
0413H
GOSUB to 092DH to find the line in RAM which matches the line number pointed to by Register Pair HL, while preserving the value held in Register Pair DE.
0416H
LOOP BACK 7 instructions to 0409H.

0418H – Continuation of the LIST command, once a counter of 12 lines has been displayed.

0418H
GOSUB to 0A63H to display the line number pointed to by Register Pair DE on screen.
041BH
GOSUB to 092DH to find the line in RAM which matches the line number pointed to by Register Pair HL, while preserving the value held in Register Pair DE.
041EH
If the C FLAG (Carry) has been set then no line was found in RAM so JUMP to 042DH (which just JUMPs to 03E8H which just JUMPS to 01DEH) to the middle of the READY COMMAND LINE LOOP.
0420H
GOSUB to 0B40H to fetch a keystroke from the keyboard (note: does not wait for a keypress).
0423H
If the Z FLAG (Zero) has been set, meaning no key found, LOOP BACK 1 instruction and keep polling.
0425H
CP 1BH
Compare the value held in Register A against 1BH (ASCII: ). Results:
  • If Register A equals 1BH, the Z FLAG is set; otherwise the NZ FLAG is set.
0427H
If the Z FLAG (Zero) has been set, meaning an was detected, JUMP to the top of this routine at 0418H to redisplay another line of the LIST and wait for a key.
0429H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A does NOT equal CARRIAGE RETURN, the NZ FLAG is set.
042BH
If the NZ FLAG (Not Zero) has been set (meaning, a key OTHER than CARRIAGE RETURN), LOOP back to 0420H to keep polling for keystrokes.
042DH
If a CARRIAGE RETURN was received, meaning “STOP LISTING”, JUMP to 03E8H (which just JUMPS to 01DEH) to the middle of the READY COMMAND LINE LOOP.

042FH – Entry point for the PRINT Command.

042FH
RST 08H
23H
09H
We have PRINT, but there can be MANY parameters! First, let’s check for a “#” via a call to RST 08H with parameters of 23H and an offset of 09H. RST 08H will move to the next non-space character and check it against 23H (which is a “#”). If there is no match, jump to the return (of the next instruction, i.e. 0432H) + 09H instructions (which would be 043BH).
0432H
LD HL,40ACH
Let Register Pair HL equal 40ACH which is a dual purpose location: Buffer for command input AND output to cassette.
0435H
LD (4099H),HL
Store the value held in Register Pair HL into memory location 4099H (which is the address of the printer buffer in RAM).
0438H
GOSUB to 0FE9H to turn on the cassette motor.

043BH – If the PRINT was not followed by a #, it jumped here.

043BH
RST 08H
3AH
05H
Check for a “:” via a call to RST 08H with parameters of 3AH and an offset of 05H. RST 08H will move to the next non-space character and check it against 3AH (which is a “:”). If there is no match, jump to the return (of the next instruction, i.e. 043EH) + 09H instructions (which would be 0443H).
043EH
CALL 000EH
GOSUB to 000EH to display a CARRIAGE RETURN.
0441H
JUMP to 03FFH, which will JUMP to 03A2H in the middle of the EXECUTE NEXT LINE, which will check for BREAK (and if found, STOP) or else reset the cassette motor, set IX to the bottom of the floating point stack, set HL to point to the middle of the reserved word list, and parse for matching reserved words.

0443H – If the PRINT was not followed by a :, it jumped here.

0443H
RST 08H
0DH
06H
Check for a CARRIAGE RETURN by calling to RST 08H with parameters of 0DH and an offset of 06H. RST 08H will move to the next non-space character and check it against 3AH (which is a CARRIAGE RETURN). If there is no match, jump to the return (of the next instruction, i.e. 0446H) + 04H instructions (which would be 044CH).
0446H
CALL 000EH
GOSUB to 000EH to display a CARRIAGE RETURN.
0449H
JUMP to the top of EXECUTE NEXT LINE routine at 0394H.

044CH – If the PRINT was not followed by a CARRIAGE RETURN, it jumped here.

044CH
LD HL,0319H
Let Register Pair HL equal 0319H, which is in the middle of the RESERVED WORD LOOKUP/VECTOR TABLE.
044FH
JUMP to 0343H to look for keyword matches but starting with the keywords at 0319H (i.e., TAB, AT, A$, B$ …).

0452H – If the PRINT had a QUOTE, it jumped here.

0452H
GOSUB to 095BH to display a quoted expression pointed to by Register Pair DE and JUMP to the command line parsing routine if a CR is found, otherwise JUMP to the return address + 2 bytes.
0455H
JUMP to 0499H which is the concluding code of the PRINT AT routine.

0457H – If the expression to print in 0452H did not end in a CARRIAGE RETURN, it JUMPs here (the return address (0455H) + 2) as there is more to print.

0457H
JUMP to 0464H to process the display of a COMMA or TAB STOP if needed.

0459H – Entry point for the PRINT A$ Command.

0459H
LD HL,4070H
Let Register Pair HL equal 4070H, which is the value stored in the variable A$.
045CH
JUMP to 0461H to print the variable pointed to by Register Pair HL.

045EH – Entry point for the PRINT B$ Command.

045EH
LD HL,4080H
Let Register Pair HL equal 4080H, which is the value stored in the variable B$.

0461H – Routine to print a string variable.

0461H
GOSUB to 04B9H to display the contents of a string variable pointed to by Register Pair HL until either 00H is reached OR 16 bytes have been displayed.
0464H
RST 08H
2CH
26H
Check for a , by calling to RST 08H with parameters of 2CH and an offset of 26H. RST 08H will move to the next non-space character and check it against 2CH (which is a ,). If there is no match, jump to the return (of the next instruction, i.e. 0467H) + 26H instructions (which would be 0467H).

If we are here, then we got a comma, so we need to handle the display of a TAB.

0467H
LD A,(4068H)
Copy the CURSOR POSITION (held in 4068H) into Register A.
046AH
AND 0FH
MASK the value of Register A against 0FH (0000 1111). This has the effect of turning off bits 7, 6, 5, 4, leaving A to be 00H-0FH only.
046CH
If that is a 0, then we are already at a TAB STOP, so JUMP to 0490H.
046EH
LD A,20H
Otherwise, let Register A equal 20H (ASCII: SPACE).
0470H
RST 10H
Send the character held in Register A (i.e., ASCII: SPACE) to the cassette or screen via a RST 10 call.
0471H
LOOP BACK to 0467H until we are at a “0” location (a tab stop).

0473H – Entry point for the PRINT AT Command.

0473H
Determine the location on the screen being asked for via a GOSUB to 0807H to calculate an integer expression with the results into Register Pair HL.
0476H
LD BC,(4068H)
Fetch the cursor position on screen (held in memory location 4068H) and store it into Register Pair BC.
047AH
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
047CH
LD (BC),A
Erase the cursor by putting the SPACE held in Register A onto the cursor position.
047DH
LD A,H
Copy the contents of Register H (from the integer) into Register A.
047EH
OR FCH
OR Register A against FCH (1111 1100). This has the effect of turning on bits 7-3, leaving the only possible values to be 252-255.
0480H
AND 3FH
MASK the value of Register A against 3FH (0011 1111). This has the effect of turning off bits 7 and 6, leaving the only possible values to be 63 and lower, which are the number of columns on a TRS-80 screen.
0482H
LD H,A
Copy the modified contents of Register A into Register H.
0483H
LD (HL),5FH
Store the value 5FH (ASCII: _) onto the screen at the pointed to by Register Pair HL.
0485H
LD (4068H),HL
Store the value held in Register Pair HL into memory location 4068H (which holds the cursor position on screen).
0488H
RST 08H
2CH
02H
Check for a “,” by calling to RST 08H with parameters of 2CH and an offset of 02H. RST 08H will move to the next non-space character and check it against 2CH (which is a ,). If there is no match, jump to the return (of the next instruction, i.e. 048BH) + 02H instructions (which would be 048DH).

If a , is found, then we are here.

048BH
JUMP to 0490H to GOSUB to 08B3H to check if the next character is a “:” and if yes, JUMP to 08BAH to check for a CARRIAGE RETURN and if not then jump to the MIDDLE of the EXECUTE NEXT LINE routine.

048DH – Middle of the PRINT AT Routine.

048DH
RST 08H
3BH
05H
Check for a “;” by calling to RST 08H with parameters of 3BH and an offset of 05H. RST 08H will move to the next non-space character and check it against 3BH (which is a ;). If there is no match, jump to the return (of the next instruction, i.e. 0490H) + 05H instructions (which would be 0495H).

If a ; is found, then we are here.

0490H
GOSUB to 08B3H to check if the next character is a “:” and if yes, JUMP to 08BAH to check for a CARRIAGE RETURN and if not then jump to the MIDDLE of the EXECUTE NEXT LINE routine.
0493H
JUMP to 044CH to look for keyword matches but starting with the keywords at 0319H (i.e., TAB, AT, A$, B$ …).

0495H – Middle of the PRINT AT Routine where a “;” was not found, so process the end of the line

0495H
GOSUB to 000EH to display a CARRIAGE RETURN since we are not trying to continue displaying characters on that line.
0498H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.
0499H
RST 18H
RST 18 to parse an expression (and an optional expression, if any).
049AH
GOSUB to 0970H to display the contents of Register Pair HL as a decimal number.
049DH
JUMP to 0464H to process the display of a COMMA or TAB STOP if needed.

049FH – Entry point for the PRINT TAB Command.

049FH
GOSUB to 0814H to verify that an integer is within parenthesis, and calculate the integer expression with the result in Register Pair HL.
04A2H
LD A,L
We only care about the 8 bit value of Register L, so copy the contents of Register L into Register A.
04A3H
AND 3FH
MASK the value of Register A against 3FH (Decimal: 63) to set the possible values to be between 0 and 63, which are the possible column numbers for a Model I screen. This is the column we want to go to.
04A5H
LD L,A
Copy the masked contents back into Register L.
04A6H
LD A,(4068H)
Fetch the cursor position on screen (held in memory location 4068H) and store it into Register A.
04A9H
AND 3FH
MASK the value of Register A against 3FH (Decimal: 63) to set the possible values to be between 0 and 63, which are the possible column numbers for a Model I screen. This is the column that the cursor is currently in.
04ABH
CP L
Compare the current column on the screen line (held in Register A) against the column held in Register L. Results:
  • If Register A equals the value held in Register L, the Z FLAG is set.
  • If Register A < Register L, the CARRY FLAG will be set.
  • if Register A > Register L, the NO CARRY FLAG will be set.
04ACH
If the Z FLAG (Zero) has been set, then the GOAL column is the same as the CURRENT column, so we will do nothing here and JUMP to 0488H to keep processing whatever else might be on the PRINT TAB line.
04AEH
If the NC FLAG (No Carry) has been set, then the GOAL column is PAST the CURRENT column, so we will do nothing here and JUMP to 0488H to keep processing whatever else might be on the PRINT TAB line.

If we are here, then we are not yet on screen where we want to be, so we need to space over until we get there.

04B0H
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
04B2H
RST 10H
Send the character held in Register A (i.e., SPACE) to the screen via a RST 10 call.
04B3H
Loop back to 04A6H to check to see if we have hit the GOAL column yet. This is a far more time consuming way to do this than if the number of spaces had just been calculated and filled.

04B5H – Entry point for the CLS Command.

04B5H
LD A,0CH
Let Register A equal 0CH (ASCII: FORM FEED. This will act as a clear screen command.
04B7H
RST 10H
Send the character held in Register A (i.e., 0CH) to the cassette or screen via a RST 10 call.
04B8H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

04B9H – Subroutine to display the contents of a string variable pointed to by Register Pair HL until either a 00H is reached OR 16 bytes have been displayed.

04B9H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
04BAH
INC HL
INCrement Register Pair HL by 1 to point to the next character in the string.
04BBH
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
04BCH
RET Z
If the Z FLAG (Zero) has been set, then we have a 00H delimeter, so we are done! RETurn to the caller.
04BDH
RST 10H
Send the character held in Register A to the cassette or screen via a RST 10 call.
04BEH
LD A,L
Copy the contents of the LSB of string pointer (held in Register L) into Register A.
04BFH
AND 0FH
MASK the LSB against 0FH (0000 1111). This has the effect of turning off bits 7, 6, 5, 4, leaving a value 15 or lower.
04C1H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
04C2H
LOOP back to the top of the routine at 04B9H.

04C4H – Entry point for the GOSUB Command.

04C4H
GOSUB to 0A9FH to move the BASIC language stack to make room for a new stack entry (like the return address of a GOSUB or the value of a FOR loop).
04C7H
Fetch the line number associated with the GOSUB command by GOSUBing to 0EBDH to parse an integer into HL or set NZ for an error. RETURN if NZ, or JUMP to 08C9H to display the “WHAT” error otherwise.
04CAH
PUSH DE
Save the contents of Register Pair DE to the top of the stack because the next instruction will reset DE.
04CBH
GOSUB to 092AH to find the line in RAM which matches the line number pointed to by Register Pair HL. Note: A jump to 092AH resets DE. To do the routine while preserving DE, jump instead to 092DH.
04CEH
If the number after the GOSUB command does not correspond to a line number in RAM the NZ FLAG (Not Zero) will have been set, so JUMP to 01A3H to display the “HOW?” error.
04D1H
LD HL,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair HL. This would be the RETURN point.
04D4H
PUSH HL
Save the line number to RETURN to (held in Register Pair HL) to the top of the stack.
04D5H
LD HL,(40A3H)
Fetch the saved stack pointer (held in memory location 40A3H) and store it into Register Pair HL.
04D8H
PUSH HL
Save the saved BASIC stack pointer (held in Register Pair HL) to the top of the stack.
04D9H
LD HL,0000H
Let Register Pair HL equal 0000H.
04DCH
LD (40A5H),HL
Store the value held in Register Pair HL into memory location 40A5H (which is the pointer to the current FOR LOOP variable).
04DFH
ADD HL,SP
LET Register Pair HL = Register Pair HL + Register SP.
04E0H
LD (40A3H),HL
Store the value held in Register Pair HL into memory location 40A3H (which is the saved stack pointer).
04E3H
JUMP to 039CH to execute the BASIC instructions at the RAM location pointed to by Register Pair DE.

04E6H – Entry point for the RETURN Command.

04E6H
GOSUB to 08C5H which will check the next character on the instruction line (pointed to by DE) for a CARRIAGE RETURN. If that’s what it finds, it returns here. If it finds anything else (meaning, an unwanted character), it will display the “WHAT” error message.
04E9H
LD HL,(40A3H)
Fetch the saved BASIC stack pointer (held in memory location 40A3H) and store it into Register Pair HL.
04ECH
04ECH
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
04EEH
If the BASIC stack pointer is 0000H, which is a bad thing, the Z FLAG (Zero) will have been set, so JUMP to 08C9H to display the “WHAT” error.
04F1H
LD SP,HL
Copy the contents of Register Pair HL into Register Pair SP so that the system’s stack pointer now points to the BASIC stack pointer.
04F2H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
04F3H
LD (40A3H),HL
Store the value held in Register Pair HL into memory location 40A3H (which is the saved stack pointer).
04F6H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
04F7H
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
04FAH
POP DE
Put the value held at the top of the STACK into Register Pair DE.
04FBH
JUMP to 05F2H to restore the values from the BASIC stack into their RAM locations, clear the RETurn address, and continue processing the current BASIC line.

04FEH – Entry point for the ON Command.

04FEH
GOSUB to 080BH to calculate a non-negative integer into Register Pair HL.
0501H
0501H
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
0503H
If HL was zero then the Z FLAG (Zero) will have been set, so JUMP to 050BH.
0505H
PUSH HL
Save the non-negative integer expression held Register Pair HL to the top of the stack.
0506H
LD HL,02DFH
Let Register Pair HL equal 02DFH, which will be the location in ROM where the command lookup table is, starting with the PRINT command.
0509H
JUMP to 0552H which JUMPs to 0343H in the READY COMMAND LOOP to try to match reserved words, starting with the PRINT command.

050BH – Part of the ON Command; jumped here if the index passed to ON was a ZERO.

050BH
GOSUB to 053CH to ead (and discard) characters on the BASIC line until we hit a CARRIAGE RETURN or a :
050EH
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

050FH – Entry point for the ON x GOTO Command.

050FH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0510H
GOSUB to 0526H to turn the value passed after the ON (i.e., the ON x expression) into a line number.
0513H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0514H
JUMP to 03BCH which is inside the GOTO routine.

0517H – Entry point for the ON x GOSUB Command.

0517H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0518H
GOSUB to 0526H to turn the value passed after the ON (i.e., the ON x expression) into a line number.
051BH
LD (409BH),HL
Store the value held in Register Pair HL into the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH).
051EH
GOSUB to 0A9FH to move the BASIC language stack to make room for a new stack entry (like the return address of a GOSUB or the value of a FOR loop).
0521H
LD HL,(409BH)
Fetch the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH) and store it into Register Pair HL.
0524H
JUMP to 04CAH which is inside the GOSUB routine.

0526H – Part of the ON Command; turns the value/expression passed after the ON into a line number.

0526H
DEC L
DECrement the value stored in Register L by 1.
0527H
If the Z FLAG (Zero) has been set, JUMP to 0539H to parse the referenced line number.
0529H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
052AH
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
052CH
If the character is a CARRIAGE RETURN, then we don’t have a good value and the Z FLAG (Zero) has been set, so JUMP BACK to 050BH to continue processing as if the index passed was zero.
052EH
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG will be set.
0530H
If the character is a :, then we don’t have a good value and the Z FLAG (Zero) has been set, so JUMP BACK to 050BH to continue processing as if the index passed was zero.
0532H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0533H
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). Results: If Register A equals ,, the Z FLAG is set; otherwise the NZ FLAG will be set.
0535H
If the character was a , then we have to process the list, so continue the routine by JUMPing to 0526H.
0537H
JUMP to 0529H to continue parsing the command line.

0539H – Part of the ON Command; parse the line number of an ON x LINE NUMBER command, and then read (and discard) characters on the BASIC line until we hit a CARRIAGE RETURN or a :.

0539H
GOSUB to 0EBDH to parse an integer into HL or set NZ for an error. RETURN if NZ, or JUMP to 08C9H to display the “WHAT” error otherwise.
053CH
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
053DH
CP 3AH
Compare the value held in Register A against 3AH (ASCII: :). Results: If Register A equals :, the Z FLAG is set; otherwise the NZ FLAG is set.
053FH
RET Z
If the character was a :, then the Z FLAG will have been set, so RETurn to the caller.
0540H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
0542H
RET Z
If the character was a CARRIAGE RETURN, then the Z FLAG will have been set, so RETurn to the caller.
0543H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0544H
LOOP BACK to the top of this routine at 053CH to keep checking characters until we hit a CARRIAGE RETURN) or a :).

0546H – Entry point for the FOR Command.

0546H
GOSUB to 0A9FH to move the BASIC language stack to make room for a new stack entry (like the return address of a GOSUB or the value of a FOR loop).
0549H
GOSUB to 08A8H to parse for a variable which is then followed by an equal and an expression.
054CH
LD (40A5H),HL
Store the value held in Register Pair HL into memory location 40A5H (which is the pointer to the current FOR LOOP variable).
054FH
LD HL,030BH
Let Register Pair HL equal 030BH, which will be the location in ROM where the command lookup table is, starting with the TO command.
JUMP to 0343H in the READY COMMAND LOOP to try to match reserved words, starting at the TO command.

0555H – Entry point for the TO Command.

0555H
Determine the TO value which is present on the command line via a GOSUB to 0807H to calculate an integer expression with the results into Register Pair HL.
0558H
LD (406EH),HL
Store the “TO” value, held in Register Pair ,HL into memory location 406EH (which holds current FOR LOOP END (i.e., the TO) value).
055BH
LD HL,0311H
Let Register Pair HL equal 0311H, which will be the location in ROM where the command lookup table is, starting with the STEP command.
055EH
JUMP to 0343H in the READY COMMAND LOOP to try to match reserved words, starting at the STEP command.

0560H – Entry point for the STEP Command.

0560H
Determine the STEP value which is present on the command line via a GOSUB to 0807H to calculate an integer expression with the results into Register Pair HL.
0563H
Skip over the next instruction via a JUMP to 0568H.

0565H – Continuation of the STEP Command.

0565H
LD HL,0001H
Set a default STEP value as 1 by setting Register Pair HL equal to 0001H.
LD (4091H),HL
Store the STEP value (held in Register Pair HL) into the of the FOR LOOP STEP (held in memory location 4091H).
056BH
LD HL,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair HL.
056EH
LD (4093H),HL
Store the value held in Register Pair HL into memory location 4093H (which holds address of the top of the current FOR LOOP).
0571H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
0572H
LD (4095H),HL
Store the value held in Register Pair HL into memory location 4095H (which holds address of the current FOR statement).
0575H
LD BC,000AH
Let Register Pair BC equal 000AH (Decimal: 10).
0578H
LD HL,(40A5H)
Fetch the value held in memory location 40A5H (which is the pointer to the current FOR LOOP variable) and store it into Register Pair HL.
057BH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
057CH
LD H,B
Copy the contents of Register B (which is a 00H) into Register H.
057DH
LD L,B
Copy the contents of Register B (which is a 00H) into Register L.
057EH
ADD HL,SP
LET Register Pair HL = Register Pair HL + Register SP.
057FH
LD A, 09H
Let Register A equal 09H. So on first pass, perhaps this sets Register A to 09, just to be overwritten by a LD A,xx. Since there is a jump point to 0580H, I assume that this some cleverness to also have a LD HL,BC on future passes.
0580H
ADD HL,BC
Let HL = HL + BC.
0581H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
0582H
INC HL
INCrement the value stored in Register Pair HL by 1.
0583H
OR (HL)
OR the value stored at (HL+1) against the value stored at (HL) which is now in Register A. The results are stored in Register A.
0584H
If (HL+1) = (HL) then the Z FLAG will have been set, JUMP to 059EH to clean up and exit the routine.
0586H
LD A,(HL)
If they differ, then fetch the value held in the memory location pointed to by Register Pair HL and store it into Register A.
0587H
DEC HL
DECrement the value stored in Register Pair HL by 1.
0588H
CP D
Compare the value held in Register A against the value held in Register D. Results:
  • If Register A equals the value held in Register D, the Z FLAG is set.
  • If A < D/9/, the CARRY FLAG will be set.
  • if A >= D/9/, the NO CARRY FLAG will be set.
0589H
If the NZ FLAG (Not Zero) has been set, LOOP BACK to 0580H.
058BH
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
058CH
CP E
Compare the value held in Register A against the value held in Register E. Results:
  • If Register A equals the value held in Register E, the Z FLAG is set.
  • If A < E/9/, the CARRY FLAG will be set.
  • if A >= E/9/, the NO CARRY FLAG will be set.
058DH
If the NZ FLAG (Not Zero) has been set, LOOP BACK to 0580H.
058FH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
0590H
LD HL,0000H
Let Register Pair HL equal 0000H.
0593H
ADD HL,SP
LET Register Pair HL = Register Pair HL + Register SP.
0594H
LD B,H
Copy the contents of Register H into Register B.
0595H
LD C,L
Copy the contents of Register L into Register C.
0596H
LD HL,000AH
Let Register Pair HL equal 000AH (Decimal: 10).
0599H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE.
059AH
GOSUB to 0A77H to copy the bytes, backwards, from BC through DE to HL.
059DH
LD SP,HL
Copy the contents of Register Pair HL into Register Pair SP.
059EH
LD HL,(4095H)
Fetch the value held in memory location (4095H) and store it into Register Pair HL.
05A1H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
05A2H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

05A3H – Entry point for the NEXT Command.

05A3H
RST 38H
RST 38H checks the command line to see if the next non-space character is an existing variable; HL to point to the variable if it exists and CARRY set if it doesn’t.
05A4H
If the C FLAG (Carry) has been set, then we didn’t get a variable after the NEXT command so JUMP to 08C9H to display the “WHAT” error.
05A7H
LD (409BH),HL
Store the value held in Register Pair HL into the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH).
05AAH
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
05ABH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
05ACH
LD HL,(40A5H)
Fetch the value held in memory location 40A5H (which is the pointer to the current FOR LOOP variable) and store it into Register Pair HL.
05AFH
05AFH
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
05B1H
If HL=0 then there is no active FOR command so JUMP to 08CAH to display the “WHAT” error message .
05B4H
RST 20H
Compare the NEXT variable with the FOR variable (i.e., HL and DE) via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
05B5H
If they match, jump away to 05C0H.
05B7H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
05B8H
GOSUB to 0A84H to move the various items held in the BASIC stack to their corresponding RAM location values. Essentially a group POP from the BASIC stack.
05BBH
LD HL,(409BH)
Fetch the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH) and store it into Register Pair HL.
05BEH
JUMP to 05AAH to see if the NEXT command now matches the proper variable.

05C0H – Continuation of the NEXT Command; jumped here if the FOR and NEXT variables match the current BASIC stack frame.

05C0H
GOSUB to 0BC3H to push the variable held in Register Pair HL into the FLOATING POINT STACK.
05C3H
GOSUB to 0C0BH to convert the number in the FLOATING POINT STACK into an INTEGER to be stored in Register Pair HL.
05C6H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
05C7H
LD HL,(4091H)
Fetch the FOR LOOP STEP (held in memory location 4091H) and store it into Register Pair HL.
05CAH
PUSH HL
Save the FOR LOOP STEP value (held in Register Pair HL) to the top of the stack.
05CBH
ADD HL,DE
Calculate the new step value by adding that value with Register Pair DE; results in Register Pair HL.
05CCH
PUSH HL
Save the new STEP value (held in Register Pair HL) to the top of the stack.
05CDH
GOSUB to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.
05D0H
LD HL,(40A5H)
Fetch the value held in memory location 40A5H (which is the pointer to the current FOR LOOP variable) and store it into Register Pair HL.
05D3H
GOSUB to 0BE9H to update the FOR variable to a new value.
05D6H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
05D7H
LD HL,(406EH)
Fetch the current FOR LOOP END (i.e., the TO) value (held in memory location 406EH) and store it into Register Pair HL.
05DAH
POP AF
Put the value held at the top of the STACK into Register Pair AF.
05DBH
OR A
Set FLAGS based on the contents of Register A, most notedly in this case, the SIGN bit of the STEP value.
05DCH
If the S FLAG has been RESET, skip the next instruction and JUMP to 05E0H.
05DFH
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
05E0H
LD A,H
Copy the MSB of Register Pair HL (i.e., the contents of Register H) into Register A.
05E1H
XOR D
eXclusive OR Register D against Register A. The results are stored in Register A.
05E2H
If the S FLAG has been RESET, skip the next instruction and JUMP to 05E6H.
05E5H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
05E6H
RST 20H
Compare HL and DE via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
05E7H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
05E8H
If the C FLAG (Carry) has been set then the loop is done, so JUMP to 05F2H to restore the values from the BASIC stack into their RAM locations, clear the RETurn address, and continue processing the current BASIC line.
05EAH
LD HL,(4093H)
If we are here then the loop is not done, so fetch the address of the top of the current FOR LOOP (held in memory location 4093H) and store it into Register Pair HL.
05EDH
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
05F0H
JUMP to 059EH to continue processing the LOOP.

05F2H – Jump point to exit out of BASIC stack operations — routine restores the values from the BASIC stack into their RAM locations, clears the RETurn address, and continues processing the current BASIC line.

05F2H
GOSUB to 0A84H to move the various items held in the BASIC stack to their corresponding RAM location values. Essentially a group POP from the BASIC stack.
05F5H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

05F6H – Entry point for the REM and DATA Commands.

05F6H
LD HL,0000H
Let Register Pair HL equal 0000H.
05F9H
Skip the next intruction via a JUMP to 05FEH.

05FBH – Entry point for the IF Command.

05FBH
GOSUB to 0807H to calculate an integer expression with the results into Register Pair HL.
05FEH
05FFH
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
0600H
If the NZ FLAG (Not Zero) has been set, then we have IF followed by a valid entry, so JUMP to 060BH to look for the THEN.
0602H
GOSUB to 0947H to look for the next line.
0605H
If the next line was found then the NC FLAG will have been set, so JUMP to 039CH to execute that line.
0608H
Otherwise, enter they READY command line routine via a JUMP to 01C9H.

060BH – Look for the THEN Command.

060BH
LD HL,0337H
Let Register Pair HL equal 0337H, which is in the RESERVED WORD LOOKUP TABLE just before the THEN command.
060EH
JUMP to 0343H in the READY COMMAND LOOP to try to match reserved words, starting at the THEN command.

0611H – Entry point for the THEN Command.

0611H
GOSUB to 0EC4H to parse an integer into Register Pair HL to see if we have a number or a command.
0614H
If the NZ FLAG (Not Zero) has been set, then we have a non-Zero integer line number after the THEN (i.e., IF A=10 THEN 30), so we need to GO TO that line number via a JUMP to 0513H which will PUSH DE and then JUMP to 03BCH in the GOTO routine.
0617H
If we’re here, then we didn’t get a line number after the THEN, so we need to see if it’s a reserved word instead. JUMP to 03A2H in the middle of the EXECUTE NEXT LINE, which will check for BREAK (and if found, STOP) or else reset the cassette motor, set IX to the bottom of the floating point stack, set HL to point to the middle of the reserved word list, and parse for matching reserved words.

061AH – Restore SP from a temporary storage space of 409BH and restore the current line being executed back into Register Pair HL and the associated memory location; this is jumped to at 08DCH.

061AH
LD SP,(409BH)
Fetch the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH) and store it into Register Pair SP.
061EH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
061FH
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
0622H
POP DE
Put the value held at the top of the STACK into Register Pair DE.

0623H – Entry point for the INPUT Command.

0623H
RST 08H
23H
0AH
Check for a “#” via a call to RST 08H with parameters of 23H and an offset of 0AH. RST 08H will move to the next non-space character and check it against 23H (which is a “#”). If there is no match, jump to the return (of the next instruction, i.e. 0626H) + 0A instructions (which would be 0630H).
0626H
If we are here, then there was a “#”, meaning this INPUT is from cassette, so GOSUB to 0EF4H which turns on the cassette motor, reads the data header and then read the number of bytes needed to fill RAM based on the block addresses. Routine exits with Register A holding the CRC and flags set based on Register A; DE is preserved.
0629H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
062AH
LD HL,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair HL.
062DH
PUSH HL
Save the pointer to the current line being executed (held in Register Pair HL) to the top of the stack.
062EH
JUMP to 064EH which JUMPs to 06D4H which continues the INPUT routine by parsing the line (DE must point to the current character to be parsed).

0630H – Continuation of the INPUT Command; jumped here if the INPUT was not followed by a “#”, meaning that we are inputting from the keyboard.

0630H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
0631H
GOSUB to 095BH to display a quoted expression pointed to by Register Pair DE and JUMP to the command line parsing routine if a CR is found, otherwise JUMP to the return address + 2 bytes, which will check for a “;“.
0634H
Skip the next instruction and JUMP to 0639H.

0636H – Continuation of the INPUT Command.

0636H
RST 08H
3BH
18H
Check for a “;” via a call to RST 08H with parameters of 3BH and an offset of 18H. RST 08H will move to the next non-space character and check it against 3BH (which is a “;“). If there is no match, jump to the return (of the next instruction, i.e. 0639H) + 18H instructions (which would be 0651H).
0639H
LD HL,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair HL.
063CH
PUSH HL
Save the pointer to the current line being executed (held in Register Pair HL) to the top of the stack.
063DH
LD HL,0630H
Let Register Pair HL equal 0630H / (Decimal: 1584).
0640H
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
0643H
LD (409BH),SP
Store the value held in Register Pair SP into the pointer to the FOR LOOP’s NEXT variable (held in memory location 409BH).
0647H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
0648H
LD A,3FH
Let Register A equal 3FH (ASCII: ?).
064AH
GOSUB to 08FCH to display a prompt of the character held in Register A then then fetch a line of input into a 53 character buffer between 40ACH and 40F3H pointed to by Register Pair DE.
064DH
POP DE
Restore the current character of the line being interpreted from the top of the stack back into Register Pair DE.
064EH
JUMP to 06D4H which continues the INPUT routine by parsing the line (DE must point to the current character to be parsed).

0651H – Continuation of the INPUT Command; jumped here if there was no “;” when one was expected.

0651H
POP AF
Clear the return address from the stack.
0652H
JUMP to 06CAH which JUMPs to 08C9H to display the “WHAT” error.

0654H – Multi-Command Routine. Used by LET, INPUT, and READ to parse the characters pointed to by Register Pair DE.

0654H
If the Z FLAG (Zero) has been set, JUMP to 08AEH to parse a numeric value.
0657H
RST 28H
Call RST 28H to move DE to point to the next non-space character, with Register A holding that character.
0658H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0659H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise, the NZ FLAG is set.
065BH
If the character at the BASIC line being processed is a CARRIAGE RETURN, then the Z FLAG will have been set, so JUMP to 066FH to fill the rest of the 15 character buffer pointed to by Register Pair HL with 00H’s and RETurn.
065DH
CP 22H
Compare the value held in Register A against 22H (ASCII: ). Results: If Register A equals , the Z FLAG is set; otherwise, the NZ FLAG is set.
065FH
If the character at the BASIC line being processed is a , then the Z FLAG will have been set, so JUMP to 0678H to parse a quoted string into a 15 character buffer pointed to by Register Pair HL.
0661H
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). Results: If Register A equals ,, the Z FLAG is set; otherwise, the NZ FLAG is set.
0663H
If the character at the BASIC line being processed is a ,, then the Z FLAG will have been set, so JUMP to fill the rest of the 15 character buffer pointed to by Register Pair HL with 00H’s and RETurn.

If we’re here then we didn’t get a CARRIAGE RETURN, , or so we are just going to copy the data to the buffer pointed to by Register Pair HL.

0665H
LD (HL),A
Store the character held in Register A into the memory location pointed to by Register Pair HL.
0666H
INC HL
Bump HL to point to the next open space in the 15 character buffer.
0667H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0668H
LD A,L
Copy the contents of Register L (i.e., the LSB of HL) into Register A.
0669H
AND 0FH
MASK the value of Register A against 0FH (0000 1111), thus setting a maximum value of Register A at 15.
066BH
If masked value of L is zero then we have run out of space in the 15 character buffer and the Z FLAG will have been set, so JUMP to 068AH.
066DH
If we are here, then we still have room in the 15 character buffer pointed to by Register Pair HL so LOOP BACK to 0658H in this routine.

066FH – Routine to fill the rest of the 15 character buffer pointed to by Register Pair HL with 00H’s; jumped here if the next character is a CARRIAGE RETURN.

066FH
LD (HL),00H
Store the value 00H into the memory location pointed to by Register Pair HL.
0671H
INC HL
INCrement the value stored in Register Pair HL by 1.
0672H
LD A,L
Copy the contents of Register L (i.e., the LSB of HL) into Register A.
0673H
AND 0FH
MASK the value of Register A against 0FH (0000 1111), thus setting a maximum value of Register A at 15.
0675H
If masked value of L is NOT zero, then the NZ FLAG will have been set, JUMP to 066FH.
0677H
RET
Otherwise, if the masked value of L is a zero then RETurn to the caller.

0678H – Parse a quoted string into a 15 character buffer pointed to by Register Pair HL.

0678H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0679H
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
067AH
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise, the NZ FLAG is set.
067CH
If the character on the BASIC line being processed (currently pointed to by DE) is a CARRIAGE RETURN, then the Z FLAG will have been set, so JUMP to 066FH to fill the rest of the 15 character buffer pointed to by Register Pair HL with 00H’s and RETurn.
067EH
INC DE
Bump DE to point to the next character on the BASIC line being processed.
067FH
CP 22H
CP 22H
Compare the value held in Register A against 22H (ASCII: ). Results: If Register A equals , the Z FLAG is set; otherwise, the NZ FLAG is set.
0681H
If the character on the BASIC line being processed (currently pointed to by DE) is a , then the Z FLAG will have been set, so JUMP 066FH to fill the rest of the 15 character buffer pointed to by Register Pair HL with 00H’s and RETurn.
0683H
LD (HL),A
Store the character held in Register A into the memory location pointed to by Register Pair HL.
0684H
INC HL
Bump HL to point to the next open space.
0685H
LD A,L
Copy the contents of Register L (i.e., the LSB of HL) into Register A.
0686H
AND 0FH
MASK the value of Register A against 0FH (0000 1111), thus setting a maximum value of Register A at 15.
0688H
If masked value of L is NOT zero, then the NZ FLAG will have been set, JUMP to 0679H.
068AH
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
068BH
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). Results: If Register A equals ,, the Z FLAG is set; otherwise, the NZ FLAG is set.
068DH
RET Z
If the character on the BASIC line being processed (currently pointed to by DE) is a ,, then the Z FLAG will have been set, so RETurn to the caller.
068EH
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise, the NZ FLAG is set.
0690H
RET Z
If the character on the BASIC line being processed (currently pointed to by DE) is a CARRIAGE RETURN, then the Z FLAG will have been set, so RETurn to the caller.
0691H
INC DE
If we are here then we are out of space in the buffer, so we loop to fewtch and discard the characters until we hit a CARRIAGE RETURN or ,. First, bump DE to point to the next character on the BASIC line being processed.
0692H
JUMP 5 instructions to 068AH to keep fetching command characters from DE and checking them against a ,) and a CARRIAGE RETURN.

0694H – Multi Command Subroutine; parse the next characters of a variable. Used in the LET command and the INPUT command for the characters after the “;“. If the variable does not exist, the C FLAG is set; a close array returns with the Z FLAG set; and a $ returns with register L holding either 70H (for A$) or 80H (for B$) and the Z FLAG set.

0694H
RST 38H
RST 38H checks the command line to see if the next non-space character is an existing variable; HL to point to the variable if it exists and CARRY set if it doesn’t.
0695H
RET C
If the C FLAG (Carry) has been set then the next non-space character is NOT an existing variable, RETurn to the caller.
0696H
DEC DE
Otherwise, since the next non-space character IS an existing variable, back up 1 space on the instruction line by DECrementing the value stored in Register Pair DE by 1 to we can see how the variable ended … was it an array? was it a string?.
0697H
LD A,(DE)
Fetch the character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0698H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0699H
CP 29H
Compare the value held in Register A against 29H (ASCII: )). Results: If Register A equals ), the Z FLAG is set; otherwise the NZ FLAG is set.
069BH
RET Z
If the character on the BASIC line being processed (currently pointed to by DE) is a ), then the Z FLAG will have has been set, so we RETurn to the caller.
069CH
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
069DH
CP 24H
Compare the value held in Register A against 24H (ASCII: $). Results:
  • If Register A equals $, the Z FLAG is set; otherwise the NZ FLAG is set.
069FH
If the character on the BASIC line being processed (currently pointed to by DE) is a $, then the Z FLAG will have been set, so JUMP to 06A3H to validate to A$ or B$ only (results in Register L being 70H or 80H respectively), or throw a WHAT error otherwise.
06A1H
XOR A
Set Register A to ZERO and clear all Flags.
06A2H
RET
RETurn to the caller.

06A3H – Continuation of the above routine; jumped here if the variable found on the BASIC line being processed ended in a “$”. On exit, Register L will be either 70H if the variable is A$ or 80H if the variable is B$. DE will point to the next character on the BASIC line being processed.

06A3H
LD A,L
Copy the contents of Register L (i.e., the LSB of HL) into Register A. Register L will be a 00H if the variable is A$ and will be 04H if the variable is a B$; C$ is 08H.
06A4H
CP 07H
Compare the value held in Register A against 07H since that is 1 less than the first invalid string value of C$. Results:
  • If Register A equals 07H, the Z FLAG is set.
  • If A < 07H, the CARRY FLAG will be set.
  • if A >= 07H, the NO CARRY FLAG will be set.
06A6H
If A >= 07H (meaning we received a C$ or higher) then the NC FLAG will have been set, so JUMP to 08C9H to display the “WHAT” error.
06A9H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
06AAH
06AAH
SLA A
SLA A
If the variable was B$ then this will rotate Register A from 04 to 08 to 10. If the variable was A$ then 00H remains 00H.
06AEH
ADD 70H
LET Register A = Register A + 70H. If the variable was A$ then Register A = 70H and if the variable was B$ then Register A will be 80H
06B0H
LD L,A
Copy the contents of Register A (70H if the variable was A$ and 80H if the variable was B$) into Register L.
06B1H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
06B2H
RET
RETurn to the caller.

06B3H – This routine is JUMPed to from the RESERVED WORD LOOKUP list, if the main commands are not found. The reserved words after this are functions, math symbols, and the like.

06B3H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
06B4H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results:
  • If Register A equals CARRIAGE RETURN, the Z FLAG is set.
  • If A < CARRIAGE RETURN, the CARRY FLAG will be set.
  • if A >= CARRIAGE RETURN, the NO CARRY FLAG will be set.
06B6H
If the character pointed to by Register Pair DE is a CARRIAGE RETURN then the Z FLAG will have been set, so JUMP to 06C5H which will execute a RST 30H, clear the RET, and continue processing the BASIC instruction line.

06B8H – Entry point for the LET Command. This is also a pass through from the exhausted RESERVE WORD LOOKUP list jump; meaning that if the ROM cannot find a command where it expected one, it is willing to assume that the line is actually a variable assignment.

06B8H
GOSUB to 0694H to parse the next characters of a variable. If the variable does not exist, the C FLAG is set; a close array returns with the Z FLAG set; and a $ returns with register L holding either 70H (for A$) or 80H (for B$) and the Z FLAG set.
06BBH
If the variable does not exist then the C FLAG will have been set, JUMP to 06CAH which JUMPs to 08C9H to display the “WHAT” error.
06BDH
PUSH AF
Preserve Register Pair AF to the top of the stack due to the next RST call.
06BEH
RST 08H
3DH
09H
Check for a “=” via a call to RST 08H with parameters of 3DH and an offset of 09H. RST 08H will move to the next non-space character and check it against 3DH (which is a “=“). If there is no match, jump to the return (of the next instruction, i.e. 06C1H) + 09H instructions (which would be 06CAH) to display the “WHAT” error.
06C1H
POP AF
Restore AF from the stack.
06C2H
GOSUB to 0654H to parse the characters pointed to by Register Pair DE (i.e., everthing after “LET variable =”).
06C5H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

06C6H – Continuation of the INPUT Command; jumped to by 06D7H and 06EBH.

06C6H
POP HL
Restore the value of the current line being executed from the top of the stack into Register Pair HL.
06C7H
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
06CAH
JUMP to 08C9H to display the “WHAT” error.

06CDH – Entry point for the RESTORE Command.

06CDH
LD HL,0000H
Let Register Pair HL equal 0000H so as to represent the beginning of the READ list when put into 401AH.
06D0H
LD (40A1H),HL
Store the value held in Register Pair HL into memory location 40A1H (which is the pointer for the READ command).
06D3H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

06D4H – Continuation of the INPUT Command; this will parse the line. On entry, DE must point to the current character in t he BASIC line being parsed.

06D4H
GOSUB to 0694H to parse the next characters of a variable. If the variable does not exist, the C FLAG is set; a close array returns with the Z FLAG set; and a $ returns with register L holding either 70H (for A$) or 80H (for B$) and the Z FLAG set.
06D7H
If the variable doesn’t exist then the C FLAG will have been set, so JUMP to 06C6H to restore the pointer to the current line being executed to its place in RAM and to HL and then abort with a “WHAT” error.
06D9H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
06DAH
LD DE,40ACH
Let Register Pair DE equal 40ACH which is a dual purpose location: Buffer for command input AND output to cassette.
06DDH
GOSUB to 0654H to parse the characters in the input buffer (pointed to by Register Pair DE).
06E0H
LD (4099H),DE
Store the value held in Register Pair DE into memory location 4099H (which is the address of a buffer in RAM).
06E4H
POP DE
Restore the pointer to the current character of the line being interpreted into Register Pair DE.
06E5H
RST 08H
2CH
53H
Check for a “,” via a call to RST 08H with parameters of 2CH and an offset of 53H. RST 08H will move to the next non-space character and check it against 2CH (which is a “,“). If there is no match, jump to the return (of the next instruction, i.e. 06E8H) + 53H instructions (which would be 073BH).
06E8H
GOSUB to 0694H to parse the next characters of a variable. If the variable does not exist, the C FLAG is set; a close array returns with the Z FLAG set; and a $ returns with register L holding either 70H (for A$) or 80H (for B$) and the Z FLAG set.
06EBH
If the C FLAG (Carry) has been set, JUMP to 06C6H to restore the pointer to the current line being executed to its place in RAM and to HL and then abort with a “WHAT” error.
06EDH
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
06EEH
PUSH AF
Temporarily save the contents of Register Pair AF to the top of the stack so that the RST 08H doesn’t destroy them.
06EFH
LD DE,(4099H)
Fetch the address of the buffer in RAM (held in memory location 4099H) and store it into Register Pair DE.
06F3H
RST 08H
2CH
4BH
Check for a “,” via a call to RST 08H with parameters of 2CH and an offset of 4BH. RST 08H will move to the next non-space character and check it against 2CH (which is a “,“). If there is no match, jump to the return (of the next instruction, i.e. 06F6H) + 4BH instructions (which would be 0741H).
06F6H
POP AF
Restore AF from the stack.
06F7H
JUMP to 06DDH to parse the next value.

06F9H – Entry point for the READ Command.

06F9H
GOSUB to 0694H to parse the next characters of a variable. If the variable does not exist, the C FLAG is set; a close array returns with the Z FLAG set; and a $ returns with register L holding either 70H (for A$) or 80H (for B$) and the Z FLAG set.
06FCH
PUSH DE
>Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
06FDH
If the variable doesn’t exist then the C FLAG will have been set, so JUMP to 0742H to handle the situation where a “,” was needed but not found.
06FFH
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0700H
LD DE,(40A1H)
Fetch the pointer for the READ command (held in memory location 40A1H) and store it into Register Pair DE.
0704H
0705H
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.
0706H
If the READ POINTER is not zero, then JUMP to 0731H.
0708H
LD DE,4200H
Since the READ POINTER was zero, we need to start from scratch. Let Register Pair DE equal 4200H.
NOTE: 4200H is the top of system stack pointer.
070BH
PUSH HL
Temporarily preserve contents of Register Pair HL to the top of the stack.
070CH
GOSUB to 0751H to examine the current BASIC instruction line for DATA statements. If we hit the end of the program with no DATA statements, the C FLAG will be set.
070FH
POP HL
Restore Register Pair HL from the stack.
0710H
If the C FLAG (Carry) has been set then no DATA statements were found; making the triggered READ command a problem, so JUMP to 0745H to display the “HOW” error.
0712H
POP AF
Restore Register Pair HL from the stack.
0713H
LD BC,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair BC.
0717H
PUSH BC
Temporarily save the contents of Register Pair BC to the top of the stack for the next 3 instructions.
0718H
LD BC,0000H
Let Register Pair BC equal 0000H.
071BH
LD (409FH),BC
Store the value held in Register Pair BC into memory location 409FH (which is the pointer to the current line being executed).
071FH
GOSUB to 0654H to parse the characters in the input buffer (pointed to by Register Pair DE).
0722H
POP BC
Restore the current line being executed to Register Pair BC from the stack.
0723H
LD (409FH),BC
Store the current line being executed (held in Register Pair BC) into memory location 409FH (which is the pointer to the current line being executed).
0727H
LD (40A1H),DE
Store the value held in Register Pair DE into memory location 40A1H (which is the pointer for the READ command).
072BH
POP DE
Restore the pointer to the current character of the BASIC instruction line being interpreted back into Register Pair DE.
072CH
RST 08H
2CH
11H
Check for a “,” via a call to RST 08H with parameters of 2CH and an offset of 11H. RST 08H will move to the next non-space character and check it against 2CH (which is a “,“). If there is no match, jump to the return (of the next instruction, i.e. 072FH) + 11H instructions (which would be 0740H).
072FH
If the next character is a “,” then JUMP to 06F9H to the top of this READ routine.
0731H
RST 08H
2CH
02H
Check for a “,” via a call to RST 08H with parameters of 2CH and an offset of 02H. RST 08H will move to the next non-space character and check it against 2CH (which is a “,“). If there is no match, jump to the return (of the next instruction, i.e. 0734H) + 02H instructions (which would be 0736H).
0734H
LOOP BACKto 0712H.
0736H
RST 08H
0DH
08H
Check for a “CARRIAGE RETURN” via a call to RST 08H with parameters of 0DH and an offset of 08H. RST 08H will move to the next non-space character and check it against 0DH (which is a “CARRIAGE RETURN”). If there is no match, jump to the return (of the next instruction, i.e. 0739H) + 08H instructions (which would be 07F1H).
0739H
LOOP BACK to 070BH.

073BH – Continuation of the INPUT Command; JUMPed here if a “,” wasn’t found at 06E5H.

073BH
POP HL
Restore the pointer to the current line being executed into Register Pair HL.
073CH
LD (409FH),HL
Store the value held in Register Pair HL into memory location 409FH (which is the pointer to the current line being executed).
073FH
POP AF
Discard the next stack entry.
0740H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

0741H – Continuation of the INPUT Command; JUMPed here if a “,” wasn’t found at 06F3H.

0741H
POP AF
Clear the RETurn address from the stack.
0742H
JUMP to 08CAH to display the “WHAT” error message.

0745H – Continuation of the READ Command; jumped here from 0710H when no DATA statements were found.

0745H
POP AF
Clear the RETurn address from the stack.
0746H
JUMP to 01A3H to display the “HOW?” error.

0749H – JUMPed here from the DATA PARSE TABLE (at 0BBFH) if the DATA statement is located, and DE now points to the first entry of that DATA statement.

0749H
XOR A
Set Register A to ZERO and clear all Flags.
074AH
RET
RETurn to the caller.

074BH – This is JUMPed to by the JP (HL) in 0377H and in the DATA PARSE TABLE if DATA statement was not found. This routine loops through the characters on the BASIC line being processed until it hits a CARRIAGE RETURN

074BH
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
074CH
INC DE
Bump DE to point to the next character on the BASIC line being processed.
074DH
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
074FH
If the CARRIAGE RETURN has still not been found, the NZ FLAG will have been set, so LOOP to back to the top of this routine at 074BH.

0751H – Examine the current BASIC instruction line for DATA statements. If we hit the end of the program with no DATA statements, the C FLAG will be set.

0751H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0752H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0753H
LD HL,(406CH)
Fetch the pointer to the top of used RAM (held in memory location 406CH) and store it into Register Pair HL.
0756H
RST 20H
Compare HL and DE via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
0757H
RET C
If HL < DE then the C FLAG (Carry) will have been set, RETurn to the caller.
0758H
LD HL,0BBAH
Let Register Pair HL equal 0BBAH.
075BH
JUMP to 07AAH which JUMPs to 0343H in the READY COMMAND LOOP, with HL pointing to 0BBAH as the RESERVED WORD LOOKUP/VECTOR TABLE starting point.

075DH – Parse an optional relational expression “>” “<” or “=“.

075DH
GOSUB to 07A7H to look for “>” “<” or “=” on the command line.
0760H
GOSUB to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.

0763H – Entry point for a > Command.

0763H
RST 08H
3DH
06H
Check for a “=” via a call to RST 08H with parameters of 3DH and an offset of 06H. RST 08H will move to the next non-space character and check it against 3DH (which is a “=“). If there is no match, jump to the return (of the next instruction, i.e. 0766H) + 06H instructions (which would be 076CH) to process a straight >.
0766H
If we are here, then the “=” was found after the “>” so GOSUB to 0799H to compare two numbers on a “>=” basis.
0768H
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.
0769H
RET C
If the C FLAG (Carry) has been set, RETurn to the caller.
076AH
Otherwise, JUMP to 07A3H in the NUMERIC COMPARISON routine to set HL to 0001H (meaning TRUE) and RETurn to the routine caller.

076CH – Part of the span class=”code”>> Command; JUMPed here if the “=” was not found in 0763H, to process a straight >.

076CH
GOSUB to 0799H to compare two numbers.
076FH
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
0770H
RET C
If the C FLAG (Carry) has been set, RETurn to the caller.
0771H
JUMP to 07A3H in the NUMERIC COMPARISON routine to set HL to 0001H (meaning TRUE) and RETurn to the routine caller.

0773H – Entry point for a “<” Command.

0773H
RST 08H
3DH
0CH
Check for a “=” via a call to RST 08H with parameters of 3DH and an offset of 0CH. RST 08H will move to the next non-space character and check it against 3DH (which is a “=“). If there is no match, jump to the return (of the next instruction, i.e. 0776H) + 0CH instructions (which would be 0782H) to check for <>.
0776H
If an “=” was found, GOSUB to 0799H to compare two numbers on a “<=” basis.
0779H
LD HL,0001H
Let Register Pair HL equal 0001H to indicate TRUE.
077CH
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
077DH
RET C
If the C FLAG (Carry) has been set, RETurn to the caller.
077EH
LD HL,0000H
Let Register Pair HL equal 0000H to indicate FALSE.
0781H
RET
RETurn to the caller.

0782H – Part of the “<” Command; JUMPed here if an “=” was NOT found (so no <=), to next check for <>.

0782H
RST 08H
3EH
0CH
Check for a “>” via a call to RST 08H with parameters of 3EH and an offset of 0CH. RST 08H will move to the next non-space character and check it against 3EH (which is a “>“). If there is no match, jump to the return (of the next instruction, i.e. 0785H) + 0CH instructions (which would be 0791H) to handle a straight “<“.
0785H
If the “>” was found, GOSUB to 0799H to compare two numbers on a “<>” basis.
0788H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
0789H
JUMP to 07A3H in the NUMERIC COMPARISON routine to set HL to 0001H (meaning TRUE) and RETurn to the routine caller.

078BH – Entry point for a = Command.

078BH
GOSUB to 0799H to compare two numbers on an “=” basis.
078EH
RET NZ
If the NZ FLAG (Not Zero) has been set, RETurn to the caller.
078FH
JUMP to 07A3H in the NUMERIC COMPARISON routine to set HL to 0001H (meaning TRUE) and RETurn to the routine caller.

0791H – Part of the “<” Command; JUMPed here to test a straight “<” math operation.

0791H
GOSUB to 0799H to compare two numbers on a “<” basis.
0794H
RET NC
If the NC FLAG (No Carry) has been set, RETurn to the caller.
0795H
JUMP to 07A3H in the NUMERIC COMPARISON routine to set HL to 0001H (meaning TRUE) and RETurn to the routine caller.

0797H – This is the jump point in the RESERVED WORD LOOKUP TABLE for where “>“, “<” and “=” pass through. This is where we go if the relational expression was not found.

0797H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
0798H
RET
RETurn to the caller.

0799H – Subroutine to compare two numbers.

0799H
GOSUB to 07ADH to parse an expression.
079CH
GOSUB to 0CB1H to fetch the top 2 entries from the Floating Point Stack into their register sets, remove them from the Floating Point Stack, and do a bunch of comparisons between the two.
079FH
LD HL,0000H
Let Register Pair HL equal 0000H.
07A2H
RET
RETurn to the caller.

07A3H – Part of the NUMERIC COMPARISON routines. In these routines HL=0 means TRUE and HL=1 means FALSE. This routine sets HL to FALSE and RETurns to caller.

07A3H
LD HL,0001H
Let Register Pair HL equal 0001H.
07A6H
RET
RETurn to the caller.

07A7H – Check the current BASIC program line against relational operators.

07A7H
LD HL,032CH
Let Register Pair HL equal 032CH, which is in the middle of the RESERVED WORD LOOKUP/VECTOR TABLE.
07AAH
JUMP to 0343H to look for keyword matches but starting with the keywords at 0319H (i.e., “>“, “=“, “<“).

07ADH – Parse an expression. This is part of the RST 18H routine as well as other locations and is the main expression parsing routine.

07ADH
RST 08H
2DH
08H
Check for a “” via a call to RST 08H with parameters of 2DH and an offset of 08H. RST 08H will move to the next non-space character and check it against 2DH (which is a ““). If there is no match, jump to the return (of the next instruction, i.e. 07B0H) + 08H instructions (which would be 07B8H).
07B0H
LD HL,0000H
If we are here, then a “” was found, so prepare for math by setting Register Pair HL equal 0000H.
07B3H
GOSUB to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.
07B6H
JUMP to 07CCH to continue the math by resulting from having found a “-“.

07B8H – Parse an expression. This is part of the RST 18H routine as well as other locations; JUMPed here if a “” wasn’t found, to now check for a “+“.

07B8H
RST 08H
2BH
00H
Check for a “+” via a call to RST 08H with parameters of 2BH and an offset of 00H. RST 08H will move to the next non-space character and check it against 2BH (which is a “+“). If there is no match, jump to the return (of the next instruction, i.e. 00H) + 07BBH instructions (which would be 07BBH).
07BBH
If we are here, then a “+” was found, so GOSUB to 07D4H to keep looking for other possible operators and functions in the expression.
07BEH
RST 08H
2BH
08H
Check for a “+” via a call to RST 08H with parameters of 2BH and an offset of 08H. RST 08H will move to the next non-space character and check it against 2BH (which is a “+“). If there is no match, jump to the return (of the next instruction, i.e. 08H) + 07C1H instructions (which would be 07C9H).
07C1H
If we are here, then a “+” was found, so GOSUB to 07D4H to keep looking for other possible operators and functions in the expression.
07C4H
GOSUB to 0CD3H to handle floating point addition.
07C7H
LOOP BACK 2 instructions (to 07BEH) to keep parsing.

07C9H – Parse an expression. This is part of the RST 18H routine as well as other locations; JUMPed here if a “” and “+” wasn’t found, to now check for a ““.

07C9H
RST 08H
2DH
37H
Check for a “” via a call to RST 08H with parameters of 2DH and an offset of 37H. RST 08H will move to the next non-space character and check it against 2DH (which is a ““). If there is no match, jump to the return (of the next instruction, i.e. 07CCH) + 37H instructions (which would be 0803H).
07CCH
If we are here, then a “” was found, so GOSUB to 07D4H to keep processing.
07CFH
GOSUB to 0CBFH to handle Floating Point Subtraction.
07D2H
JUMP BACK to 07BEH in the prior routine to keep parsing.

07D4H – Parse an expression. This is part of the RST 18H routine as well as other locations; JUMPed here if a “+” was found.

07D4H
GOSUB to 07EDH which will which JUMPs to 0343H in the READY COMMAND LOOP, with HL pointing to 02EEH (RND) as the RESERVED WORD LOOKUP/VECTOR TABLE starting point. This would be the list of RESERVED WORDS that could be part of math expression: RND, ABS, MEM, INT, and POINT.
07D7H
RST 08H
2AH
08H
Check for a “*” via a call to RST 08H with parameters of 2AH and an offset of 08H. RST 08H will move to the next non-space character and check it against 2AH (which is a “*“). If there is no match, jump to the return (of the next instruction, i.e. 08H) + 07DAH instructions (which would be 07E2H).
07DAH
If we are here, then the “*” was found, so GOSUB to 07EDH which will which JUMPs to 0343H in the READY COMMAND LOOP, with HL pointing to 02EEH (RND) as the RESERVED WORD LOOKUP/VECTOR TABLE starting point. This would be the list of RESERVED WORDS that could be part of math expression: RND, ABS, MEM, INT, and POINT.
07DDH
GOSUB to 0C87H to do Floating Point Multiplication.
07E0H
LOOP BACK 2 instructions (to 07D7H) to keep parsing.

07E2H – arse an expression. This is part of the RST 18H routine as well as other locations; JUMPed here if the check at 07D7H didn’t find a “*“.

07E2H
RST 08H
2FH
1EH
Check for a “/” via a call to RST 08H with parameters of 2FH and an offset of 1EH. RST 08H will move to the next non-space character and check it against 2FH (which is a “/”). If there is no match, jump to the return (of the next instruction, i.e. 07E5H) + 1EH instructions (which would be 0803H).
07E5H
GOSUB to 07EDH which JUMPs to 0343H in the READY COMMAND LOOP, with HL pointing to 02EEH (RND) as the RESERVED WORD LOOKUP/VECTOR TABLE starting point. This would be the list of RESERVED WORDS that could be part of math expression: RND, ABS, MEM, INT, and POINT.
07E7H
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.
07E8H
GOSUB to 0C98H to do a FLOATING POINT DIVIDE of the numbers at the top of the FLOATING POINT STACK.
07EBH
JUMP BACK to 07D7H to keep parsing.

07EDH – Parse an expression. This is part of the RST 18H routine as well as other locations. This will parse a primary expression.

07EDH
LD HL,02EEH
Let Register Pair HL equal 02EEH (RND) as the RESERVED WORD LOOKUP/VECTOR TABLE starting point. This would be the list of RESERVED WORDS that could be part of math expression: RND, ABS, MEM, INT, and POINT.
07F0H
JUMP to 07AAH which JUMPs to 0343H in the READY COMMAND LOOP, with HL pointing to 02EEH as the RESERVED WORD LOOKUP/VECTOR TABLE starting point.

07F2H – ???? Don’t see how we get here. Part of the PARSE AN EXPRESSION routine. Supposedly jumps here if “intrinsic function not found” to parse a regular expression.

07F2H
RST 38H
RST 38H checks the command line to see if the next non-space character is an existing variable; HL to point to the variable if it exists and CARRY set if it doesn’t.
07F3H
If the C FLAG (Carry) has been set, then the variable doesn’t exist, so JUMP to 07F8H to see if it is a constant instead.
07F5H
JUMP to 0BC3H to put the number pointed to by Register Pair HL onto the FLOATING POINT STACK.

07F8H – Part of the PARSE AN EXPRESSION routine. If we need to parse a regular expression, but the variable was not found, we need to assume that we have a constant; so we wind up here.

07F8H
GOSUB to 00A6H to analyze a Floating Point Constant.
07FBH
RET NZ
If the NZ FLAG (Not Zero) has been set, RETurn to the caller.

07FCH – Subroutine to verify that an integer is inside parenthesis, and parse it via a RST 18H call.

07FCH
RST 08H
28
05H
We need to see if the number is surrounded by parenthesis. We do this a call to RST 08H with parameters of “(” and an offset of 05H. RST 08H will move to the next non-space character and check it against 28H (which is a “(“). If there is no match, jump to the return (of the next instruction, i.e. 07FFH) + 05H instructions (which would be 0804H – which will give a WHAT error).
07FFH
RST 18H
We expect a number to be here, so we call RST 18 to parse an expression (and an optional expression, if any).
0800H
RST 08H
29
01H
We had an open parenthesis so we need to find the close. We do this a call to RST 08H with parameters of “)” and an offset of 01H. RST 08H will move to the next non-space character and check it against 29H (which is a “)”). If there is no match, jump to the return (of the next instruction, i.e. 0803H) + 01H instructions (which would be 0804H – which will give a WHAT error).
0803H
RET
RETurn to the caller.
0804H
JP 08C9H
JUMP to 08C9H to display the “WHAT” error.

0806H – ??? I don’t see what jumps to this instruction. Whatever it is, its trying to get to 0807H but AF and AF’ are backwards.

0806H
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.

0807H – Calculate an integer expression with the results into Register Pair HL.

0807H
RST 18H
RST 18 to parse an expression (and an optional expression, if any).
0808H
JUMP to 0C0BH to convert a FLOATING number to an INTEGER; results stored in Register Pair HL.

080BH – Compute the number held in Regster Pair HL as a non-negative integer.

080BH
GOSUB to 0807H to calculate an integer expression with the results into Register Pair HL.
080EH
BIT 7,H
Test Bit Number 7 of Register H, which is the bit which tracks the SIGN of the number. Z FLAG will be set if that bit is 0 (positive), and NZ FLAG will be set if that bit is 1 (negative).
0810H
If the NZ FLAG (Not Zero) has been set, meaning the number which needed to be positive is actually negative, so display the “HOW?” error via a JUMP to 01A2H.
0813H
RET
RETurn to the caller.

0814H – Verify that an integer is within parenthesis, and calculate the integer expression with the result in Register Pair HL.

0814H
GOSUB to 07FCH to verify that an integer is inside parenthesis, and parse it via a RST 18H call.
0817H
JUMP to 0808H to JUMP to 0C0BH to convert the number in the FLOATING POINT STACK into an INTEGER to be stored in Register Pair HL.

0819H – Entry point for the ABS() command.

0819H
Since the ABS() instruction has a number in parenthesis, we first need to GOSUB to 07FCH to verify that an integer is inside parenthesis, and parse it via a RST 18H call.
081CH
RES 7,(IX+FFH)
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK. RESet (i.e., set as 0) BIT 7 of the SIGN of NUMBER 1 stored at the memory location pointed to by Register (IX-01H). Bit 7 is the bit which contains the sign, so by resetting it, the value in Register A is then positive.
0820H
RET
RETurn to the caller.

0821H – Entry point for the “MEM” command.

0821H
PUSH DE
Save the contents of Register Pair DE (i.e., the current character of the line being interpreted) to the top of the stack.
0822H
LD DE,(406CH)
Fetch the pointer to the top of used RAM (held in memory location 406CH) and store it into Register Pair DE.
0826H
LD HL,(406AH)
Fetch the value of the top of physical memory (held in memory location 406AH) and store it into Register Pair HL.
0829H
XOR A
Set Register A to ZERO and clear all Flags.
082AH
SBC HL,DE
Subtracts the amount of used RAM (held stored in Register Pair DE) and the carry flag from the amount of total physical RAM (stored in Register Pair HL).
082CH
POP DE
Restore the pointer to the current character of the line being interpreted into Register Pair DE.
082DH
JUMP to 0835H which Jumps to 0C59H which converts the value stored in Register Pair HL (i.e., the amount of free RAM available) to a floating point number in the Floating Point Stack.

082FH – Entry point for the INT() command.

082FH
Since the INT() instruction has a number in parenthesis, we first need to GOSUB to 07FCH to verify that an integer is inside parenthesis, and parse it via a RST 18H call.
0832H
GOSUB to 0808H which JUMPs to 0C0BH to convert a FLOATING number to an INTEGER; results stored in Register Pair HL.
0835H
JUMP to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.

0838H – Entry point for the RESET Command.

0838H
LD A,80H
Let Register A equal (Decimal: 128).
083AH
JUMP to 0842H in the POINT with A set to 128.

083CH – Entry point for the SET Command.

083CH
LD A,01H
Let Register A equal 01H (Decimal: 1).
083EH
JUMP to 0842H in the POINT with A set to 1.

0840H – Entry point for the POINT Command.

0840H
LD A,00H
Let Register A equal 00H. This will differentiate from other routines entering this routine, whereby A is 1 for a SET and 128 for a RESET

0842H – This is the main routine for graphics. On Entry A=128 for SET, 1 for RESET, and 0 for POINT.

0842H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0843H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0844H
RST 08H
28H
52H
Check for a “(” via a call to RST 08H with parameters of 28H and an offset of 52H. RST 08H will move to the next non-space character and check it against 28H (which is a “(“). If there is no match, jump to the return (of the next instruction, i.e. 0847H) + 52H instructions (which would be 0899H – which JUMPs to 08C9H to display the “WHAT” error).
0847H
GOSUB to 080BH to convert the number held in Register Pair HL into a non-negative integer. This will be the X coordinate in SET (x,y).
084AH
PUSH HL
Save the X coordinate (held in Register Pair HL) to the top of the stack.
084BH
RST 08H
2CH
4BH
Check for a “,” via a call to RST 08H with parameters of 2CH and an offset of 4BH. RST 08H will move to the next non-space character and check it against 2CH (which is a “,”). If there is no match, jump to the return (of the next instruction, i.e. 084EH) + 4BH instructions (which would be 0899H – which JUMPs to 08C9H to display the “WHAT” error).
084EH
GOSUB to 080BH to convert the number held in Register Pair HL into a non-negative integer. This will be the Y coordinate in SET (x,y).
0851H
RST 08H
29H
45H
Check for a “)” via a call to RST 08H with parameters of 29H and an offset of 45H. RST 08H will move to the next non-space character and check it against 29H (which is a “)”). If there is no match, jump to the return (of the next instruction, i.e. 0851H) + 45H instructions (which would be 0899H – which JUMPs to 08C9H to display the “WHAT” error).
0854H
LD BC,0030H
Let Register Pair BC equal 0030H (Decimal: 48), which is the highest vertical number.
0857H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).

Do some division … first let’s divide out the Y value by subtracting until it goes negative

0858H
SBC HL,BC
Subtract the value stored in Register Pair BC and the carry flag from the value stored in Register Pair HL.
085AH
If there is still NO CARRY (meaning it did not yet go negative), JUMP BACK to the prior instruction.
085CH
ADD HL,BC
Once we have a carry, we bust out of that loop, and make the remainder positive by adding BC back into HL. With this, HL will be the “Y” value, between (and including) 0 and 47.
085DH
LD A,L
Copy the Y-Value (held in Register L) into Register A.

Next, let’s get Y MOD 3 into Register H.

085EH
LD H,FFH
Load register H with the starting quotient.
0860H
INC H
INCrement the value stored in Register H by 1.
0861H
SUB 03H
Divide by subtraction … SUBtract the value 03H from Register A.
0863H
If the NC FLAG (No Carry) has been set, LOOP BACK 2 instructions to increment H and then subtract another 3 from Register A.
0865H
ADD 03H
We have gone negative, so now add back 03H so that Register H = the Y-Value MOD 3.
0867H
POP BC
Put the X-value (held at the top of the STACK) into Register Pair BC.
0868H
LD B,H
Copy the contents of Register H into Register B.
0869H
SLA C
Shift the bits in Register C left one position, with the contents of bit 7 being copied to the CARRY FLAG and Bit 0 being set as ZERO.
086BH
RR B
Divide Register B by 2 via a RRB which rotates the Bits in Register B to the right one bit position, with Bit 0 being copied to the CARRY FLAG and CARRY FLAG being copied to Bit 7.
086DH
RR C
Divide Register C by 2 via a RRB which rotates the Bits in Register C to the right one bit position, with Bit 0 being copied to the CARRY FLAG and CARRY FLAG being copied to Bit 7.
086FH
RR B
Divide Register B by 2 via a RRB which rotates the Bits in Register B to the right one bit position, with Bit 0 being copied to the CARRY FLAG and CARRY FLAG being copied to Bit 7.
0871H
RR C
Divide Register C by 2 via a RRB which rotates the Bits in Register C to the right one bit position, with Bit 0 being copied to the CARRY FLAG and CARRY FLAG being copied to Bit 7.
0873H
RLA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and the previous contents of the carry flag are copied to bit 0.
0874H
INC A
INCrement the value stored in Register A by 1.
0875H
SCF
Since the CARRY FLAG is going to be important, turn the CARRY FLAG on.

At this point, Register A is the number of iterations that we have to rotate the graphic mask, Register H, to the left.

0876H
LD H,00H
Let Register H equal 00H. Register H will be the graphic mask.
0878H
RL H
Top of a loop. Rotate the bits in Register H left one bit position, with the contents of Bit 7 copied to the CARRY FLAG and CARRY FLAG copied to Bit 0.
087AH
DEC A
DECrement the value stored in Register A by 1.
087BH
Keep rotating H until A = 0 via a JUMP to 0878H.

Next, we need to calculate the screen location by masking B with an OR for FCH and AND for 3FH to get a value between 0 and 63 (the screen width).

087DH
LD A,B
Copy the contents of Register B into Register A.
087EH
OR FCH
OR Register A against FCH, which turns on all bits other than bits 0 and 1.
0880H
AND 3FH
MASK the value of Register A against 3FH (0011 1111). This has the effect of turning off bits 7, 6, leaving only bits 5, 4, 3, 2, 1, 0 active, for a maximum value of 63, which is the number of characters a screen line can handle.
0882H
LD B,A
Copy the contents of Register A into Register B.
0883H
LD A,(BC)
Fetch the character at the screen location pointed to by Register Pair BC.
0884H
BIT 7,A
Test Bit Number 7 of Register A to see if the screen location had a graphic character or not. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0886H
If the NZ FLAG (Not Zero) has been set, JUMP to 088BH to test the graphic character.

If we didn’t jump away, the Bit 7 of Register A was a 0, meaning that it was not a graphic character, so we need to put one there!

0888H
LD A,80H
Let Register A equal 80H (Decimal: 128), which is the lowest graphic character (which is also empty).
088AH
LD (BC),A
Store the dummy graphic character held in Register A into the memory location pointed to by Register Pair BC.

At this point, Register Pair BC points to the screen location at which the revised graphic character will be placed, and Register H has the graphic mask to apply to the character.

088BH
POP AF
Restore the routine entry flags (0=Point, 1=Set, 128=Reset).
088CH
LD A,(BC)
Load Register A with the graphic character at the location of the video memory pointer in register pair BC.
088DH
If the Z FLAG (Zero) has been set, meaning we entered the routine with a 00H or POINT instruction, JUMP to 089BH.
088FH
If the S FLAG has been RESET, JUMP to 08A5H to finish the SET command.
0892H
LD A,H
If we are here, then we have a RESET command … copy the graphic mask in Register H into Register A.
0893H
CPL
Reverse each bit in Register A (which is the same as NOT).
0894H
LD H,A
Copy the contents of Register A into Register H.
0895H
LD A,(BC)
Fetch the graphic character at the location of the video memory pointer in register pair BC and put into into Register A.
0896H
AND H
RESET the graphic bit by combining the graphic mask in register H with the graphic character in Register A.
0897H
LD (BC),A
Save the adjusted graphic character in Register A at the location of the video memory pointer in register pair BC.
0898H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.
0899H
JUMP to 08C9H to display the “WHAT” error.

089BH – Part of the Generic Graphics Routine; final processing of POINT command.

089BH
AND H
POINT the graphic bit by combining the graphic mask in register H with the graphic character in Register A.
089CH
LD HL,0000H
Let Register Pair HL equal 0000H.
089FH
If the Z FLAG (Zero) has been set, skip the next instruction.
08A1H
INC L
INCrement the value stored in Register L by 1.

At this point, HL will be 0 if the SQUOT being tested if OFF and HL = 1 if the SQUOT being tested if ON.

08A2H
JUMP to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.

08A5H – Part of the Generic Graphics Routine; final processing of SET command.

08A5H
OR H
SET the graphic bit by combining the graphic mask in register H with the graphic character in Register A.
08A6H
LD (BC),A
Save the adjusted graphic character in Register A at the location of the video memory pointer in register pair BC.
08A7H
RST 30H
RST 30H will clear the RETurn address from the stack, and continue processing the current instruction line.

08A8H – Parse a variable name followed by an “=” and an expression (such as “FOR X = 4”).

08A8H
RST 38H
RST 38H checks the command line to see if the next non-space character is an existing variable; HL to point to the variable if it exists and CARRY set if it doesn’t.
08A9H
If the C FLAG (Carry) has been set, JUMP to 08C9H to display the “WHAT” error.
08ABH
RST 08H
3DH
1BH
Check for a “=” via a call to RST 08H with parameters of 3DH and an offset of 1BH. RST 08H will move to the next non-space character and check it against 3DH (which is a =). If there is no match, jump to the return (of the next instruction, i.e. 08AEH) + 1BH instructions (which would be 08C9H).
08AEH
PUSH HL
Save the location of the variable at issue (held in Register Pair HL) to the top of the stack, which is necessary for the JUMP to 0BE8H.
08AFH
RST 18H
RST 18 to parse an expression (and an optional expression, if any).
08B0H
JUMP to 0BE8H to take the value held in the FLOATING POINT STACK and put it in the VARIABLE pointed to by HL (and then remove it from the FLOATING POINT STACK). Since this is a JUMP, that routine will RETurn out of this one.

08B3H – Check if the next character is a “:” and if yes, JUMP to 08BAH to check for a CARRIAGE RETURN and if not then jump to the MIDDLE of the EXECUTE NEXT LINE routine.

08BAH
RST 08H
3AH
04H
Check for a “:” by calling to RST 08H with parameters of 3AH and an offset of 04H. RST 08H will move to the next non-space character and check it against 3AH (which is a “:”). If there is no match, jump to the return (of the next instruction, i.e. 08B6H) + 04H instructions (which would be 08BAH).
08B6H
POP AF
Clear the RETurn location from the stack
08B7H
JUMP to 03A2H in the middle of the EXECUTE NEXT LINE, which will check for BREAK (and if found, STOP) or else reset the cassette motor, set IX to the bottom of the floating point stack, set HL to point to the middle of the reserved word list, and parse for matching reserved words.

08BAH – Check if the next character is a CARRIAGE RETURN and if YES, keep processing the next line and if NO then RETurn.

08BAH
RST 08H
0DH
04H
Check for a CARRIAGE RETURN by calling to RST 08H with parameters of 0DH and an offset of 04H. RST 08H will move to the next non-space character and check it against 3AH (which is a CARRIAGE RETURN). If there is no match, jump to the return (of the next instruction, i.e. 08BDH) + 04H instructions (which would be 08C1H).
08BDH
POP AF
Clear the RETurn location from the stack
08BEH
JUMP to the top of EXECUTE NEXT LINE routine at 0394H.
08C1H
RET
RETurn to the caller.

08C2H – Very common routine to parse an integer.

08C2H
GOSUB to 0EC4H to parse an integer into Register Pair HL.

08C5H – Very common jump point. This is jumped to when a command is executed that has no further parameters and, therefore, REQUIRES a CARRIAGE RETURN as the next character. It will return out of the main routine if the next character is a a CARRIAGE RETURN, and display a WHAT error otherwise.

08C5H
RST 28H
Call RST 28H to move DE to point to the next non-space character, with Register A holding that character.
08C6H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set.
08C8H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller. Otherwise will pass through to the “WHAT” error routine which follows.

08C9H – Display the “WHAT” error.

08C9H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
08CAH
LD DE,01B4H
Let Register Pair DE equal 01B4H, which points to the “WHAT” error message in the ROM.
08CDH
GOSUB to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found
08D0H
LD DE,(409FH)
Fetch the pointer to the current line being executed (held in memory location 409FH) and store it into Register Pair DE.
08D4H
08D4H
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.
08D6H
If the Z FLAG (Zero) has been set, meaning that we are not at a line number, JUMP to 08F1H to return to the READY PROMPT.
08D8H
INC DE
If we are here, then DE holds the pointer to the line number being executed. Bump DE to point to the next character on the BASIC line being processed.
08D9H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
08DAH
DEC DE
DECrement the value stored in Register Pair DE by 1 so that it once again holds the pointer to the line number being executed.
08DBH
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
08DCH
If the S FLAG has been SET, JUMP to 061AH to restore SP from a temporary storage space of 409BH and restore the current line being executed back into Register Pair HL and the associated memory location.
08DFH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
08E0H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
08E1H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
08E2H
SUB A
LET Register A = 0.
08E3H
LD (HL),A
Store a ZERO (i.e., the value held in Register A) into the memory location pointed to by Register Pair HL.
08E4H
GOSUB to 0A63H to display the line number pointed to by Register Pair DE on screen.
08E7H
DEC DE
DECrement the value stored in Register Pair DE by 1.
08E8H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
08E9H
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
08EAH
LD A,3FH
Let Register A equal 3FH (ASCII: ?).
08ECH
RST 10H
Send the character held in Register A (i.e., 0CH) to the cassette or screen via a RST 10 call.
08EDH
SUB A
LET Register A = 0.
08EEH
GOSUB to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found
08F1H
Enter they READY command line routine via a JUMP to 01C9H.

08F4H – Display the “SORRY” error.

08F4H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
08F5H
LD DE,01BAH
Let Register Pair DE equal 01BAH, which points to the “SORRY” error message in the ROM.
08F8H
JUMP to 08CDH which GOSUBs to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found

08FAH – If entry is 08FAH, display a prompt of the character held in Register A then then fetch a line of input into a 53 character buffer between 40ACH and 40F3H pointed to by Register Pair DE.

08FAH
LD A,3EH
Let Register A equal 3EH (ASCII: >), which is the standard TRS-80 prompt.
08FCH
RST 10H
Send the character held in Register A to the screen via a RST 10 call.
08FDH
LD DE,40ACH
Let Register Pair DE equal 40ACH which is a dual purpose location: Buffer for command input AND output to cassette.
0900H
GOSUB to 0B40H to fetch a keystroke from the keyboard (note: does not wait for a keypress).
0903H
If the Z FLAG (Zero) has been set, loop back to the prior instruction to fetch a keystroke.
0905H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
0907H
If the keystroke was a CARRIAGE RETURN, then the Z FLAG will have been set, so JUMP to 0915H to add that CARRIAGE RETURN to the buffer.
0909H
CP 1DH
Compare the value held in Register A against 1DH (Decimal: 29). Results: If Register A equals 1DH, the Z FLAG is set; otherwise the NZ FLAG is set.
090BH
If the Z FLAG (Zero) has been set, JUMP to 0922H.
090DH
CP 03H
Compare the value held in Register A against 03H (Keyboard: BREAK). Results: If Register A equals BREAK, the Z FLAG is set; otherwise the NZ FLAG is set.
090FH
If the keystroke was a BREAK, then the Z FLAG will have been set, so JUMP to 08F1H which JUMPs to JP 01C9H to return to the READY command line routine.
0911H
CP 20H
Compare the value held in Register A against 20H (Decimal: 32). Results:
  • If Register A equals 20H, the Z FLAG is set.
  • If A < 20H, the CARRY FLAG will be set.
  • if A >= 20H, the NO CARRY FLAG will be set.
0913H
If the keystroke was a character < 20H, meaning a control code, the C FLAG (Carry) will have been set, so JUMP to 0900H to ignore the character and keep polling the keyboard.
0915H
LD (DE),A
If we are here, then we want to keep the character, so store the keystroke (held in Register A) into the buffer memory location pointed to by Register Pair DE.
0916H
INC DE
Bump DE to point to the next character in the input buffer.
0917H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
0919H
RET Z
If the character is a CARRIAGE RETURN, then the Z FLAG will have been set, meaning we are done with this line of INPUT, so RETurn to the caller.

If we are here, then we had a character we wanted to keep, and it wasn’t a CARRIAGE RETURN, so we need to keep getting more characters.

091AH
LD A,E
Copy the LSB of the pointer to the buffer (i.e., the contents of Register E) into Register A.
091BH
CP F3H
Compare the value held in Register A against F3H (meaning, to check it see if we hit 40F3H in filling the buffer). Results: If Register A equals F3H, the Z FLAG is set; otherwise the NZ FLAG will be set.
091DH
If the NZ FLAG was set, then we still have room in the buffer pointed to by DE, so JUMP back to 0900H to get more keystrokes.

If we are here, then we have run out of buffer space for INPUT.

091FH
LD A,1DH
Let Register A equal 1DH to delete the new character.
0921H
RST 10H
Send the character held in Register A (i.e., 1DH) to the cassette or screen via a RST 10 call.
0922H
LD A,E
Copy the LSB of the pointer to the buffer (i.e., the contents of Register E) into Register A.
0923H
CP ACH
Compare the value held in Register A against ACH (meaning, to check it see if we hit 40ACH in filling the buffer, which is the start of the buffer). Results: If Register A equals ACH, the Z FLAG is set; otherwise the NZ FLAG will be set.
0925H
If the Z FLAG (Zero) has been set, then we are at the start of the buffer, so discard everything and start again via a JUMP to 08FAH to fetch a line of input from the user.
0927H
DEC DE
If we weren’t at the start of the buffer, then back up the pointer to the buffer by 1 by DECrementing the value stored in Register Pair DE by 1.
0928H
JUMP to 0900H to keep fetching keystrokes.

092AH – Find the line in RAM which matches the line number pointed to by Register Pair HL starting at the address held in Register Pair DE. If jumped HERE it starts at the beginning of BASIC RAM. Will set the CARRY FLAG if nothing was found.

092AH
LD DE,4200H
Let Register Pair DE equal 4200H, to point to the start of BASIC RAM. So if the jump was to 092AH, it scans all of RAM. if the call was to 092DH, then it starts where DE was set before the CALL.

092DH – Find the line in RAM which matches the line number pointed to by Register Pair HL starting at the address held in Register Pair DE. If no line is found, it will point to the line BEFORE where the line contained in HL should have been AND will set the CARRY and NZ FLAGs.

092DH
PUSH HL
Save the contents of Register Pair HL (i.e., the line number being looked for) to the top of the stack.

First we need to verify that the RAM we are searching (held in DE) isn’t less than 4200H or higher than the top of RAM (held in 406CH). First, check for too low …

092EH
LD A,D
Copy the MSB of the RAM address being examined (held in Register D) into Register A.
092FH
CP 42H
Compare the value held in Register A against 42H, below which would be an improper search location. Results: If Register A < 42H, the CARRY FLAG will be set.
0931H
If the C FLAG (Carry) has been set, then we are trying to search starting too low, so exit via a JUMP to 08F1H which will JUMP to 01C9H to return to the READY command line routine.

.. and now, check for too high. Involves a temporary repurpose of HL.

0933H
LD HL,(406CH)
Fetch the pointer to the top of used RAM (held in memory location 406CH) and store it into Register Pair HL.
0936H
DEC HL
Step back one byte from the highest RAM location.
0937H
RST 20H
Compare the top of RAM (held in HL) and the starting point for the line number search (held in DE) via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
0938H
POP HL
Restore the the line number being looked for back into HL from the STACK.
0939H
RET C
If the C FLAG (Carry) has been set, then we are trying to search starting too high and nothing can be found, so RETurn to the caller with the C FLAG set to indicate NOTHING WAS FOUND.

093AH – Continuation of the FIND THE LINE NUMBER IN RAM routine, to actually do the search. Register Pair DE holds the RAM location to examine, and Register Pair HL holds the line number being looked for.

093AH
LD A,(DE)
LD A,(DE)
Fetch character in RAM to examine for the line number.
093BH
SUB L
LET Register A = Register A – the LSB of the line number being looked for (held in Register L).
093CH
LD B,A
Put the results of that subtraction into Register B.
093DH
INC DE
Bump DE to point to the next character in RAM to examine.
093EH
LD A,(DE)
Fetch that character and put it into Register A.
093FH
SBC A,H
LET Register A = Register A – the MSB of the line number being looked for (held in Register H), with the carry flag being used as well.
0940H
If the C FLAG (Carry) has been set, JUMP to 0946H which will advance DE 1 places and then search for the next line in RAM.
0942H
DEC DE
If there was no carry, then back up DE to the prior character in RAM.
0943H
OR B
OR Register B against Register A. The results are stored in Register A.
0944H
RET
RETurn to the caller with the CARRY FLAG reset (as OR resets) to indicate FOUND.

0945H – Continuation of the FIND THE LINE NUMBER IN RAM routine. Jumped here to skip to the end of the line and then to jump back to continue searching.

0945H
INC DE
Advance DE one character.
0946H
INC DE
Advance DE one character.
0947H
LD A,(DE)
LD A,(DE)
Fetch character in RAM to examine for the line number.
0948H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A DOES NOT equal CARRIAGE RETURN, the NZ FLAG is set.
094AH
If the current character in RAM, pointed to by DE, is not a CARRIAGE RETURN, then the NZ FLAG will have been set, so JUMP to 0946H to advance DE and check again.
094CH
INC DE
Advance DE one character.
094DH
JUMP to 092DH to continue parsing RAM (from the new DE) for the line number pointed to by Register Pair HL.

094FH – Display the message pointed to by Register Pair DE until a either a CARRIAGE RETURN or the contents of REGISTER A is found.

094FH
XOR A
Set Register A to ZERO and clear all Flags.
0950H
LD B,A
Top of a loop. Set Register B to the delimeter character we are looking for.
0951H
LD A,(DE)
LD A,(DE)
Fetch the current character to display (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0952H
INC DE
Bump DE to point to the next character to display.
0953H
CP B
Compare the character at DE – 1 against the delimeter character (held in Register B). If they match, the Z FLAG will be set.
0954H
RET Z
If the Z FLAG (Zero) has been set, meaning a delimeter was hit, RETurn to the caller.
0955H
RST 10H
If we did not get the delimeter, then send the character held in Register A (i.e., a character in the message to display) to the cassette or screen via a RST 10 call.
0956H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
0958H
If the NZ FLAG (Not Zero) has been set, JUMP to 0951H to fetch the next character and continue the loop.
095AH
RET
RETurn to the caller.

095BH – Part of the PRINT routine. Display a quoted expression pointed to by Register Pair DE and JUMP to the command line parsing routine if a CR is found, otherwise JUMP to the return address + 2 bytes.

095BH
RST 08H
22H
0EH
Call to RST 08H with parameters of 22H and an offset of 0EH. RST 08H will move to the next non-space character and check it against 22H (which is a ). If there is no match, jump to the return (of the next instruction, i.e. 095EH) + 0EH instructions (which would be 096CH, which is just a RET).
095EH
LD A,22H
Store a into Register A, as that will act as the END OF ROUTINE delimeter in the CALL to 0950H.
0960H
CALL 0950H
GOSUB to 0950H in the prior routine to display the message pointed to by Register Pair DE until a is found.
0963H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results: If Register A equals CARRIAGE RETURN, the Z FLAG is set.
0965H
POP HL
Put the ROUTINE RETURN ADDRESS (held at the top of the STACK) into Register Pair HL.
0966H
If we had a CARRIAGE RETURN, then the Z FLAG (Zero) will have been set, JUMP to the top of EXECUTE NEXT LINE routine at 0394H.
0969H
096AH
INC HL
INC HL
Advance HL 2 bytes to point 2 bytes after the prior routine return address.
096BH
JP (HL)
JUMP to (HL).

096CH – Exit out of the prior routine based on the RST 08H call not matching a .

096CH
RET
RETurn to the caller.

096DH – Display the contents of Register Pair HL as a decimal number.

096DH
GOSUB to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.

0970H
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0971H
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
0972H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0973H
LD A,(IX+FEH)
IX+FEH is the same as IX-02H, which is the EXPONENT of NUMBER 1 in the FLOATING POINT STACK. Fetch the EXPONENT of the number in the FLOATING POINT STACK (held at IX-2) into Register A.
0976H
CP 80H
Compare the EXPONENT (held in Register A) against 80H (Decimal: 128). If Register A is NOT 128, the NZ FLAG will be set.
0978H
If the NZ FLAG (Not Zero) has been set, meaning the number is NOT ZERO, JUMP to the next routine at 0983H.

If we are here, then we need to print a zero value.

097AH
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
097CH
RST 10H
Send the character held in Register A (i.e., 0CH) to the cassette or screen via a RST 10 call.
097DH
LD A,30H
Let Register A equal 30H (ASCII: 0).
097FH
RST 10H
Send the character held in Register A (i.e., 0CH) to the cassette or screen via a RST 10 call.
0980H
JUMP to 0A41H to exit by first displaying a SPACE, POPing HL/BC/DE from the STACK, POPing the FLOATING POINT STACK, and then RETurning to the caller of this routine.

0983H – Continuation of the routine to display the contents of Register Pair HL as a decimal number; jumped here if the number is NOT a Zero.

0983H
LD A,(IX+FFH)
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK.Fetch the SIGN of the number in the FLOATING POINT STACK (held at IX-1) into Register A.
0986H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0987H
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
0989H
If the Z FLAG (Zero) has been set, meaning a POSITIVE NUMBER, skip the next instruction and JUMP to 098DH to display the leading SPACE.
098BH
LD A,2DH
If we are here, then NZ was set, meaning a NEGATIVE number, so replace the character we are about to display with a .
098DH
RST 10H
Send the character held in Register A (i.e., either a SPACE if the sign is POSITIVE or a “-” if the sign is NEGATIVE) to the cassette or screen via a RST 10 call.
098EH
XOR A
Set Register A to ZERO and clear all Flags.
098FH
LD (IX+FFH),A
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK. Store a ZERO over the SIGN BIT of the number in the FLOATING POINT STACK (held at IX-1).
0992H
LD A,FFH
Let Register A equal FFH (Decimal: -1).
0994H
PUSH AF
Top of a loop. Save the contents of Register Pair AF to the top of the stack.
0995H
LD HL,0EB9H
Let Register Pair HL equal 0EB9H, which is a pointer to a constant in ROM holding CCH CCH CCH 7EH
0998H
GOSUB to 0CA6H which is part of the FLOATING POINT DIVIDE routine. This routine pushes that constant to the FLOATING POINT STACK, converts the top two numbers in the FLOATING POINT STACK to to B/D/B’/D’/E’ and C/L/C’/H’/L’, and then replaces BC with -5 before JUMPing to 0CB7H.
099BH
If the NC FLAG (No Carry) has been set, JUMP to 09A4H to continue, skipping the multiplication of the FLOATING POINT STACK number by 10.
099DH
GOSUB to 0C84H to multiply the floating point stack by 10.
09A0H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
09A1H
DEC A
DECrement the value stored in Register A by 1.
09A2H
LOOP BACK to 0994H.

09A4H – Continuation of the routine to display the contents of Register Pair HL as a decimal number.

09A4H
LD HL,0EB5H
Let Register Pair HL equal 0EB5H, which is a location in ROM holding 00H 00H 80H 80H.
09A7H
GOSUB to 0CA6H which is part of the FLOATING POINT DIVIDE routine. This routine pushes HL to the FLOATING POINT STACK, converts the top two numbers in the FLOATING POINT STACK to to B/D/B’/D’/E’ and C/L/C’/H’/L’, and then replaces BC with -5 before JUMPing to 0CB7H.
09AAH
If the C FLAG (Carry) has been set, JUMP to 09B4H to continue, skipping the division of the FLOATING POINT STACK number by 10.
09ACH
GOSUB to 0C95H to divide the floating point stack by 10.
09AFH
POP AF
Put the value held at the top of the STACK into Register Pair AF.
09B0H
INC A
INCrement the value stored in Register A by 1.
09B1H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
09B2H
LOOP BACK to the top of this routine at 09A4H.

09B4H – Continuation of the routine to display the contents of Register Pair HL as a decimal number.

09B4H
LD A,(IX+FEH)
IX+FEH is the same as IX-02H, which is the EXPONENT of NUMBER 1 in the FLOATING POINT STACK. Fetch the EXPONENT of the number in the FLOATING POINT STACK (held at IX-2) into Register A.
09B7H
NEG
Negate the contents of Register A (which is the same as -A). This will now be a counter to the number of times we are going to rotate the bits NUMBER 2.
09B9H
Top of a loop. If the Z FLAG (Zero) has been set, stop rotating and JUMP to the next routine at 09C6H.
09BBH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’ so we can access the value of NUMBER 2. Note: AF is not handled via EXX.
09BCH
SRL C
Shift the bits of the MSB of NUMBER 2 (held in Register C’) right one bit position, with Bit 0 being copied to the CARRY FLAG and Bit 7 set to zero.
09BEH
RR H
Rotate the bits of the NMSB of NUMBER 2 (held in Register H’) right one bit position, with bit 0 copied to the CARRY FLAG and the previous contents of the CARRY FLAG copied to bit 7.
09C0H
RR L
Rotate the bits of the LSB of NUMBER 2 (held in Register L’) right one bit position, with bit 0 copied to the CARRY FLAG and the previous contents of the CARRY FLAG copied to bit 7.
09C2H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
09C3H
DEC A
DECrement the value stored in Register A by 1.
09C4H
JUMP to 09B9H.

09C6H – Continuation of the routine to display the contents of Register Pair HL as a decimal number. I will not make believe I know what is going on.

09C6H
LD B,07H
Let Register B equal 07H, for a DJNZ loop of 7.
09C8H
09CAH
PUSH IX
POP HL
Let Register Pair HL = Special Index Register IX (i.e., the pointer to the FLOATING POINT STACK).
09CBH
LD (HL),00H
IX+00H is the LSB of NUMBER 2 in the FLOATING POINT STACK. Store the value 00H as the LSB of NUMBER 2.
09CDH
INC HL
INCrement the value stored in Register Pair HL by 1 to now point to IX+01H.
09CEH
LD A,00H
Top of a DJNZ loop of 7. Let Register A equal 00H.
09D0H
GOSUB to 015EH to to accumulate the digit by multiplying the accumulator by 10 and then adding in A to the newly vacant one’s spot. Routine will return a NZ SET if an overflow occurs from the accumulation.
09D3H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
09D4H
LD A,B
Copy the contents of Register B’ into Register A.
09D5H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
09D6H
LD (HL),A
Store the value held in Register A into the memory location pointed to by Register Pair HL (which will be a number between IX+01H and IX+08H).
09D7H
INC HL
INCrement the value stored in Register Pair HL by 1.
09D8H
LOOP back to 09CEH, 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.
09DAH
LD B,06H
Let Register B equal 06H in preparation for a 6 interation DJNZ LOOP of 09E2H-09F7H.
09DCH
LD C,00H
Let Register C equal 00H.
09DEH
DEC HL
DECrement the value stored in Register Pair HL by 1. HL is pointing to the FLOATING POINT STACK.
09DFH
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
09E0H
CP 05H
Compare the value held in Register A against 05H (Decimal: 5). Results:
  • If Register A equals 05H, the Z FLAG is set.
  • If A < 05H, the CARRY FLAG will be set.
  • if A >= 05H, the NO CARRY FLAG will be set.
09E2H
CCF
Top of a 6 iteration DJNZ loop if passing down, or a 1 iteration if this routine was about to end. Invert the state of the CARRY FLAG so that A < 05H will produce a NO CARRY, and A >= 05H will produce a CARRY.
09E3H
LD A,00H
Let Register A equal 00H as an accumulator.
09E5H
DEC HL
DECrement the value stored in Register Pair HL by 1. HL is pointing to the FLOATING POINT STACK.
09E6H
ADC A,(HL)
Add, with CARRY, A and the value stored in the FLOATING POINT STACK pointed to by HL.
09E7H
SLA C
Shift the bits of Register C left one position, with the contents of bit 7 copied to the CARRY FLAG and a zero is put into bit 0.
09E9H
CP 0AH
Compare the value held in Register A against 0AH (Decimal: 10). If A < 10, the CARRY FLAG will be set.
09EBH
If the C FLAG (Carry) has been set, SKIP the next instruction and then continue at 09EFH.
09EDH
LD A,00H
If A was => 10, the reset Register A back to 0.
09EFH
LD (HL),A
Store the value held in Register A into the FLOATING POINT STACK location pointed to by Register Pair HL.
09F0H
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
09F1H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
09F2H
If the Z FLAG (Zero) has been set, SKIP the next instruction and then continue at 09F6H.
09F4H
SET 0,C
If the Z flag wasn’t set, SET (i.e., set as 1) BIT 0 of Register C.
09F6H
POP AF
Put the value held at the top of the STACK into Register Pair AF.
09F7H
LOOP back to 09E2H, 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.
09F9H
LD A,C
Copy the contents of Register C into Register A.
09FAH
POP BC
Put the value held at the top of the STACK into Register Pair BC.
09FBH
If the C FLAG (Carry) has been set, JUMP to 0A03H.
09FDH
INC B
INCrement the value stored in Register B by 1.
09FEH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
09FFH
LD B,01H
Let Register B equal 01H for a 1-iteration DJNZ Loop.
0A01H
JUMP to 09E2H for that loop.

0A03H – Continuation of the routine to display the contents of Register Pair HL as a decimal number. I will not make believe I know what is going on.

0A03H
LD C,A
Copy the contents of Register A into Register C.
0A04H
LD A,B
Copy the contents of Register B into Register A.
0A05H
INC A
INCrement the value stored in Register A by 1.
0A06H
If the S FLAG has been SET, JUMP to the next routine at 0A13H.
0A09H
CP 07H
Compare the value held in Register A against 07H. If A >= 07H, the NO CARRY FLAG will be set.
0A0BH
If A >= 07H, then the NC FLAG will have been set, JUMP to the next routine at 0A13H.
0A0DH
LD B,A
Copy the contents of Register A into Register B.
0A0EH
GOSUB to 0A4DH to decrement B, displays a “.” if B didn’t hit zero, and then display a number. Then, if a shifted C isn’t zero, loops back to the top and if it is zero, Decrements B twice, exiting if the sign changes, or redoing the routine otherwise.
0A11H
JUMP to 0A41H to exit by first displaying a SPACE, POPing HL/BC/DE from the STACK, POPing the FLOATING POINT STACK, and then RETurning to the caller of this routine.

0A13H – Continuation of the routine to display the contents of Register Pair HL as a decimal number. This will process the exponent display by first displaying the “E” if needed, set up to display the sign after the “E”, and load Register A with the number (negated if it was negative).

0A13H
PUSH BC
Temporarily save the contents of Register Pair BC to the top of the stack so that Register B can be used over the next 4 instructions.
0A14H
LD B,01H
Let Register B equal 01H, which will be the parameter passed in the next CALL.
0A16H
GOSUB to 0A4DH with B=01H. This will display a “.” and then more numbers.
0A19H
LD A,45H
Let Register A equal 45H (ASCII: E).
0A1BH
RST 10H
Send the character held in Register A (i.e., E) to the cassette or screen via a RST 10 call.
0A1CH
POP BC
Restore Registers B and C from the stack.
0A1DH
BIT 7,B
Test Bit Number 7 of Register B. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0A1FH
LD A,2BH
Set up Register A so that it will display a +.
0A21H
If the Z FLAG (Zero) has been set, then the SIGN was positive, so JUMP to the next routine at 0A2BH (which starts by displaying the + held in Register A).
0A23H
LD A,2DH
If Bit 7 of Register B was 1, then the number is negative, so set Register A to a .
0A25H
RST 10H
Send the character held in Register A (i.e., ) to the cassette or screen via a RST 10 call.
0A26H
LD A,B
Since you can’t negate Register B, copy the contents of Register B into Register A.
0A27H
NEG
Negate the contents of Register A (which is the same as -A) so that the number is represented as a negative number.
0A29H
Skip over the next 2 instructions (which would have applied if the number was positive – showing the “+” and then setting A = B instead of A=-B) via a JUMP to 0A2DH.

0A2BH – Continuation of the routine to display the contents of Register Pair HL as a decimal number. Display the sign, and put the number from Register B into Register A.

0A2BH
RST 10H
Send the character held in Register A (i.e., +) to the cassette or screen via a RST 10 call.
0A2CH
LD A,B
Copy the contents of Register B into Register A.
0A2DH
LD B,00H
Let Register B equal 00H, which will be the accumulator of the next higher digit.
0A2FH
CP 0AH
Top of a loop. Compare the value held in Register A against 0AH (Decimal: 10). If A < 10, the CARRY FLAG will be set.
0A31H
This is the exit point of the loop. So long as the number we to display is less than 10 (i.e., the C FLAG has been set), JUMP to 0A38H to display the number held in Register B and then the number held in Register A, followed by a SPACE. It will then POP all the registers, including the FLOATING POINT STACK, and RETurn.
0A33H
ADD F6H
If we are heree then the number was higher than 10, so we need to reduce it by 10 by LETing Register A = Register A + F6H (Decimal: -10).
0A35H
INC B
INCrement the accumulator (tracked by Register B) by 1 for each time we reduced by 10.
0A36H
LOOP BACK to to 0A2FH to either display the number if it is less than 10, or keep reducing by 10 and incremementing B until that happens.

0A38H – Continuation of the routine to display the contents of Register Pair HL as a decimal number. This will display the number held in Register B (which was tracking how many times 10 had to be removed from Registter A) and then the number held in Register A, followed by a SPACE. It will then POP all the registers, including the FLOATING POINT STACK, and RETurn

0A38H
OR 30H
OR Register A against 30H to convert Register A into the ASCII equivalent of a number.
0A3AH
LD C,A
Copy the ASCII equivalent of the number (held in Register A) into Register C.
0A3BH
LD A,B
Copy the contents of Register B into Register A.
0A3CH
OR 30H
OR Register A against 30H to convert Register A into the ASCII equivalent of a number.
0A3EH
RST 10H
Send the character held in Register A (i.e., the ASCII equivalent of the number which was heeld in Register B) to the cassette or screen via a RST 10 call.
0A3FH
LD A,C
Restore the ASCII equivalent of the original Register A back into Register A.
0A40H
RST 10H
Send the character held in Register A (i.e., the ASCII equivalent of the number which was held in Register A on Entry of this Routine) to the cassette or screen via a RST 10 call.
0A41H
LD A,20H
Let Register A equal 20H (ASCII: SPACE).
0A43H
RST 10H
Send the character held in Register A (i.e., SPACE) to the cassette or screen via a RST 10 call.
0A44H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A45H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0A46H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0A47H
LD BC,FFFBH
Let Register Pair BC equal FFFBH, which is -5.
0A4AH
ADD IX,BC
“POP” the FLOATING POINT STACK by resetting Special Index Register IX back 5 bytes (the amount of bytes for a single floating point entry).
0A4CH
RET
RETurn to the caller.

0A4DH – Continuation of the routine to display the contents of Register Pair HL as a decimal number. Decrements B, and so long as that’s not a zero, displays a “.” and a number. Then, if a shifted C isn’t zero, loops back to the top and if it is zero, Decrements B twice, exiting if the sign changes, or redoing the routine otherwise.

0A4DH
INC B
INCrement the value stored in Register B by 1 so that it is ready for the DEC B that starts the loop on the next line.
0A4EH
DEC B
Top of a Loop. DECrement the value stored in Register B by 1.
0A4FH
If the NZ FLAG (Not Zero) has been set, skip the display of a “.” via a JUMP to 0A54H.
0A51H
LD A,2EH
Let Register A equal 2EH (ASCII: .).
0A53H
RST 10H
Send the character held in Register A (i.e., “.“) to the cassette or screen via a RST 10 call.
0A54H
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
0A55H
OR 30H
OR Register A against 30H to convert Register A into the ASCII equivalent of a number.
0A57H
RST 10H
Send the character held in Register A (i.e., the ASCII code for the number held in Register A) to the cassette or screen via a RST 10 call.
0A58H
INC HL
INCrement the value stored in Register Pair HL by 1.
0A59H
SRL C
Shift the bits of Register C right one bit position, with Bit 0 being copied to the CARRY FLAG and Bit 7 set to zero.
0A5BH
If the NZ FLAG (Not Zero) has been set, JUMP to 0A4EH.
0A5DH
DEC B
DECrement the value stored in Register B by 1.
0A5EH
DEC B
DECrement the value stored in Register B by 1.
0A5FH
RET M
If the S FLAG has been SET, RETurn to the caller.
0A60H
INC B
INCrement the value stored in Register B by 1, which, on top of the INC B at the top of the routine, undoes the two DEC B’s.
0A61H
LOOP BACK to the top of this routine at 0A4DH.

0A63H – Display the line number pointed to by Register Pair DE.

0A63H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0A64H
LD L,A
Copy the contents of Register A (which is the LSB of the line number) into Register L.
0A65H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0A66H
LD A,(DE)
LD A,(DE)
Fetch the next character on the BASIC line being processed (held in the memory location pointed to by Register Pair DE) and store it into Register A.
0A67H
LD H,A
Copy the contents of Register A into Register H; now HL contains the line number that had been in RAM pointed to by Register Pair DE.
0A68H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0A69H
GOSUB to 096DH to display the contents of Register Pair HL as a decimal number.
0A6CH
JUMP to 094FH to display the message pointed to by Register Pair DE, returning once a 00H is found. That RETurn will return from this routine.

0A6FH – Copy the bytes held at (DE) to (BC), backwards, until DE = HL.

0A6FH
RST 20H
Compare HL and DE via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
0A70H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
0A71H
LD A,(DE)
Fetch the value held in the memory location pointed to by Register Pair (DE) and store it into Register A.
0A72H
LD (BC),A
Store the value held in Register A into the memory location pointed to by Register Pair BC.
0A73H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0A74H
INC BC
INCrement the value stored in Register Pair BC by 1.
0A75H
LOOP back to the top of this routine at 0A6FH.

0A77H – COPY the bytes, backwards, from BC through DE to HL.

0A77H
LD A,B
Copy the MSB of the number of bytes to copy from Register B into Register A.
0A78H
SUB D
LET Register A = Register A – Register D to make sure that DE is greater than BC.
0A79H
If the NZ FLAG (Not Zero) has been set, JUMP to 0A7EH to decrement both pointers (DE and HL), and to move the character held in (DE) into (HL), and continue at the top of this routine.
0A7BH
LD A,C
Copy the LSB of the number of bytes to copy from Register C into Register A.
0A7CH
SUB E
LET Register A = Register A – Register E to make sure that DE is greater than BC.
0A7DH
RET Z
If the Z FLAG (Zero) has been set then we have reached the end of the move, RETurn to the caller.
0A7EH
DEC DE
We have the RAM so do the actual copying of the byte. First, DECrement the pointer to the SOURCE byte (held in Register Pair DE) by 1.
0A7FH
DEC HL
DECrement the pointer to the DESTINATION byte (held in Register Pair HL) by 1.
0A80H
LD A,(DE)
Fetch the value held in the memory location pointed to by Register Pair (DE) and store it into Register A and …
0A81H
LD (HL),A
… put it into the memory location pointed to by Register Pair HL.
0A82H
LOOP back to the top of this routine at 0A77H.

0A84H – This Subroutine is the opposite of 0A9FH This routine puts the contents from the BASIC stack pointer into the various RAM locations.

0A84H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0A85H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A86H
LD (40A5H),HL
Store the value held in Register Pair HL into memory location 40A5H (which is the pointer to the current FOR LOOP variable).
0A89H
0A89H
LD A,H
OR L* A,H
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
0A8BH
If the Z FLAG (Zero) has been set, JUMP to 0A9DH.
0A8DH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A8EH
LD (4091H),HL
Store the value held in Register Pair HL into the FOR LOOP STEP (held in memory location 4091H).
0A91H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A92H
LD (406EH),HL
Store the value held in Register Pair HL into memory location 406EH (which holds current FOR LOOP END (i.e., the TO) value).
0A95H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A96H
LD (4093H),HL
Store the value held in Register Pair HL into address of the top of the current FOR LOOP (held in memory location 4093H).
0A99H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0A9AH
LD (4095H),HL
Store the value held in Register Pair HL into memory location 4095H (which holds the pointer to the current FOR LOOP).
0A9DH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
0A9EH
RET
RETurn to the caller.

0A9FH – This Subroutine will move BASIC’s stack to make room for an additional stack item (like GOSUB, FOR-LOOP) and then put those values into that BASIC stack. If it runs out of space, it will end in an error.

0A9FH
LD HL,4180H
Let Register Pair HL equal 4180H, which is the bottom of the Level 1 stack pointer.
0AA2H
0AA3H
0AA4H
LD A,H
CPL
LD H,A
Invert the bits in Register H. If H started as 41H, which is 01000001, then the CPL would be 10111110, or 0BEH
0AA5H
0AA6H
0AA7H
LD A,L
CPL
LD L,A
Invert the bits in Register L. If L started as 80H, which is 10000000, then the CPL would be 01111111, or 7FH. HL would then be BE7FH or 48767 or -16000.
0AA8H
INC HL
INCrement the value stored in Register Pair HL by 1, to back up one byte.
0AA9H
POP BC
Put the value held at the top of the STACK into Register Pair BC. This will get put back at the top at the end of the routine.
0AAAH
ADD HL,SP
LET Register Pair HL = Register Pair HL + Register SP to check to see how much room there is in the stack.
0AABH
If the NC FLAG (No Carry) has been set then there is not enough room, JUMP to 08F4H to display the “SORRY” error.

If we are here, then there is room to move the stack. A LOT of variables deal with a FOR LOOP so check to see if we even have one at this point.

0AAEH
LD HL,(40A5H)
Fetch the value held in memory location 40A5H (which is the pointer to the current FOR LOOP variable) and store it into Register Pair HL.
0AB1H
0AB1H
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
0AB3H
If the Z FLAG (Zero) has been set, then we are not in a FOR LOOP, so skip over the FOR LOOP stuff and JUMP to 0AC8H.
0AB5H
LD HL,(4095H)
Fetch the value of the current location in a FOR LOOP (held in memory location 4095H) and store it into Register Pair HL.
0AB8H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0AB9H
LD HL,(4093H)
Fetch the address of the top of the current FOR LOOP (held in memory location 4093H) and store it into Register Pair HL.
0ABCH
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0ABDH
LD HL,(406EH)
Fetch the current FOR LOOP END (i.e., the TO) value (held in memory location 406EH) and store it into Register Pair HL.
0AC0H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0AC1H
LD HL,(4091H)
Fetch the FOR LOOP STEP (held in memory location 4091H) and store it into Register Pair HL.
0AC4H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0AC5H
LD HL,(40A5H)
Fetch the value held in memory location 40A5H (which is the pointer to the current FOR LOOP variable) and store it into Register Pair HL.
0AC8H
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0AC9H
PUSH BC
Save the original contents of Register Pair BC and put it back to the top of the stack.
0ACAH
RET
RETurn to the caller.

0ACBH – Continuation of the RST 10H routine. On entry the flags are set based on BIT 2 of the status of the Cassette port.

0ACBH
If the Z FLAG (Zero) has been set then we are sending the character held in Register A to the screen instead of the cassette, so JUMP to 0AE6H.

If we are here then the character is to be sent to cassette and not the screen.

0ACDH
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0ACEH
LD DE,(4099H)
Fetch the address of the print buffer in RAM (held in memory location 4099H) and store it into Register Pair DE.
0AD2H
LD (DE),A
Store the character to display (held in Register A) into the print buffer (at the memory location pointed to by Register Pair DE).
0AD3H
INC DE
Bump DE to point to the next character on the BASIC line being processed.
0AD4H
LD (4099H),DE
Store the the first available byte of the print buffer (held held in Register Pair DE) into memory location 4099H (which is the address of the printer buffer in RAM).
0AD8H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). Results:
  • If Register A equals CARRIAGE RETURN, the Z FLAG is set.
  • If A < CARRIAGE RETURN, the CARRY FLAG will be set.
  • if A >= CARRIAGE RETURN, the NO CARRY FLAG will be set.
0ADAH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0ADBH
RET NZ
If the character to display was not a CARRIAGE RETURN, the NZ FLAG will have been set, so RETurn to the caller.

If the character to display was a CARRIAGE RETURN then we are here.

0ADCH
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0ADDH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0ADEH
LD HL,40ACH
Let Register Pair HL equal 40ACH, which is the buffer for output.
0AE1H
GOSUB to 0F4BH to write the header and then all data from HL to DE.
0AE4H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0AE5H
RET
RETurn to the caller.

0AE6H – Continuation of the RST 10H routine. Jumped here if BIT 2 of the status of the cassette port was ZERO, meaning that we are outputting to the screen and not the cassette.

0AE6H
LD HL,(4068H)
Fetch the cursor position on screen (held in memory location 4068H) and store it into Register Pair HL.
0AE9H
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0AEAH
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0AEBH
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). Results:
  • If Register A equals SPACE, the Z FLAG is set.
  • If A < SPACE, the CARRY FLAG will be set.
  • if A >= SPACE, the NO CARRY FLAG will be set.
0AEDH
If the S FLAG has been SET, JUMP to 0B11H to display a CONTROL CODE.
0AF0H
LD (HL),A
Store the character held in Register A into the screen location pointed to by Register Pair HL.
0AF1H
INC HL
INCrement the location on the screen (stored in Register Pair HL) by 1.
0AF2H
LD A,H
Copy the contents of Register H into Register A.
0AF3H
CP 40H
Check to see if we have hit the end of a row by comparing the value held in Register A against 40H (Decimal: 64). Results: If Register A equals 64, the Z FLAG is set; otherwise the NZ FLAG is set.
0AF5H
If the NZ FLAG (Not Zero) has been set, then we are not yet at the end of the line, so JUMP to 0B09H to display the cursor and exit the RST 10H routine.

If we are here, then we are at the end of a screen line, and need to scroll the screen.

0AF7H
LD DE,3C00H
Let Register Pair DE equal 3C00H, which is the location of the beginning of the first line on the screen.
0AFAH
LD HL,3C40H
Let Register Pair HL equal 3C40H, which is the location of the beginning of the second line on the screen.
0AFDH
LD BC,03C0H
Let Register Pair BC equal 03C0H (Decimal: 960), which is the number of remaining characters on the screen (1024 characters total, minus one line of 64 characters = 960 remaining characters).
0B00H
LDIR
Move the lines up via a LDIR which 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.
0B02H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
0B03H
GOSUB to 0B37H to clear the line on the screen at the location pointed to by Register Pair HL.
0B06H
LD HL,3FC0H
Let Register Pair HL equal 3FC0H which is the start of the very last line of the screen.
0B09H
LD (HL),5FH
Store the value 5FH (ASCII: _) into the memory location pointed to by Register Pair HL.
0B0BH
LD (4068H),HL
Store the value held in Register Pair HL into memory location 4068H (which is the cursor position on screen).
0B0EH
POP AF
Put the value held at the top of the STACK into Register Pair AF.
0B0FH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0B10H
RET
RETurn to the caller.

0B11H – Continuation of the RST 10H routine. Jumped here from 0AEDH if the character is a control code.

0B11H
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). If Register A is NOT CARRIAGE RETURN, the NZ FLAG will be set.
0B13H
If the character held in Register A is not a CARRIAGE RETURN, then the NZ FLAG will have been set, so JUMP to 0B1AH.
0B15H
GOSUB to 0B37H to clear the line on the screen at the location pointed to by Register Pair HL.
0B18H
JUMP BACK to the middle of the prior routine at 0AF2H.

0B1AH – Continuation of the RST 10H routine. Jumped here from 0B11H if the character is a control code which is not a CARRIAGE RETURN.

0B1AH
CP 0CH
Compare the value held in Register A against 0CH (ASCII: FORM FEED). If the character held in Register A is NOT a FORM FEED, the NZ FLAG will be set.
0B1CH
If the character held in Register A is NOT a FORM FEED, the NZ FLAG will have been set, so JUMP to 0B2EH.
0B1EH
LD HL,3C00H
Let Register Pair HL equal 3C00H, which is the location of the first character on the display.
0B21H
GOSUB to 0B37H to clear the line on the screen at the location pointed to by Register Pair HL. On return HL points to the start of the next line.
0B24H
LD A,H
Copy the MSB of the current screen location (held in Register H) into Register A.
0B25H
CP 40H
Compare the value held in Register A against 40H. If the MSB of the current screen location is not 40H (meaning, it is still a valid screen ram address), the NZ FLAG will be set..
0B27H
If the NZ FLAG (Not Zero) has been set, LOOP back to 0B21H to clear a line on the screen (and keep doing so until the entire screen has been cleared).
0B29H
LD HL,3C00H
If we are here then HL is now pointing beyond the screen RAM (ending in 3FFF), so reset HL to the beginning of the screen by setting Register Pair HL equal to 3C00H.
0B2CH
JUMP to 0B09H to display the cursor, POP AF, swap out alternate registers and RETurn.

0B2EH – Continuation of the RST 10H routine. Jumped here from 0B11H if the character is a control code which is not a CARRIAGE RETURN or a FORM FEED.

.

0B2EH
CP 1DH
Compare the value held in Register A against 1DH (ASCII: BACK SPACE). If Register A does NOT equal 1DH then the NZ FLAG will be set.
0B30H
If we got a BACK SPACE, then the NZ FLAG (Not Zero) will have been set, so JUMP to 0B09H to display the cursor, POP AF, swap out alternate registers and RETurn.
0B32H
LD (HL),20H
Erase the character at the current screen location by storing the value 20H (ASCII: SPACE) into the memory location pointed to by Register Pair HL.
0B34H
DEC HL
Back up HL by 1 to point to the prior character on the screen.
0B35H
JUMP to 0B09H to display the cursor, POP AF, swap out alternate registers and RETurn.

0B37H – VIDEO – Clear the line on the screen at the location pointed to by Register Pair HL.

0B37H
LD (HL),20H
Store the value 20H (ASCII: SPACE) into the screen location pointed to by Register Pair HL.
0B39H
INC HL
INCrement the Register Pair HL to point to the next location on the screen.
0B3AH
LD A,L
Copy the contents of Register L into Register A.
0B3BH
AND 3FH
MASK the value of Register A against 3FH (0011 1111). This has the effect of turning off bits 7, 6, leaving only values of 0-63 possible.
0B3DH
If the masked Register L is NOT zero, then we have not reached the end of that line, so LOOP BACK to 0B37H to keep writing the spaces.
0B3FH
RET
RETurn to the caller.

0B40H – KEYBOARD – Check the keyboard for a keypress – If found, display it and put it into Register A. If no key, A=0 and Z FLAG is set.

0B40H
LD A,(387FH)
Fetch the value held in the keyboard memory location of 387FH and store it into Register A.
0B43H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0B44H
RET Z
If the Z FLAG (Zero) has been set them no key was pressed so RETurn to the caller.

If we are here, then a key was pressed when we polled, and it is stored in Register A.

0B45H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0B46H
GOSUB to 0B55H to decode the keystroke held in Register A (routine include debounce).
0B49H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0B4AH
RST 10H
Send the character held in Register A to the cassette or screen via a RST 10 call.

Let’s make sure the key is released.

0B4BH
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0B4CH
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
0B4DH
LD A,(387FH)
Fetch the value held in the keyboard memory location of 387FH and store it into Register A.
0B50H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0B51H
If the NZ FLAG (Not Zero) has been set then the key is likely just being held down, so LOOP back 2 instructions to 0B4DH to keep checking.

The key has been released!

0B53H
POP AF
Restore the original key into Register Pair A and restore the flags based on Register A.
0B54H
RET
RETurn to the caller.

0B55H – KEYBOARD – Do a little debounce and then Decode the keystroke held in Register A.

The keyboard matrix is:
3801H – @ABCDEFG
3802H – HIJKLMNO
3804H – PQRSTUVW
3808H – XYZ
3810H – 01234567
3820H – 89:;,-./
3840H – ENT CLR BRK ↑ ↓ ← → SPC

0B55H
LD B,FFH
Let Register B equal FFH (Decimal: 255) for a debounce delay.
0B57H
LOOP back to 0B57H, 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.
0B59H
LD DE,0BACH
Let Register Pair DE equal 0BACH, which is the location in ROM with the Keyboard Decode Table.
0B5CH
LD HL,3801H
Let Register Pair HL equal 3801H (Decimal: 14337).
NOTE: 3801H is the value held at Keyboard Row 1, contaning the @ABCDEFG keys.
0B5FH
LD A,00H
Let Register A equal 00H.
0B61H
OR (HL)
Top of a loop. OR the value stored at (HL) against Register A. The results are stored in Register A.
0B62H
If combining the bits from keyboard keypress on the row pointed to by Register Pair HL and Register A results in NOT ZERO, JUMP to 0B6EH.
0B64H
INC E
INCrement the value stored in Register E by 1 so that DE points to the next entry in the Keyboard Decode Table.
0B65H
SLA L
Shift the bits in Register L left, but Bit 7 going to CARRY, and Bit 0 remaining unchanged. This moves to HL to the next keyboard row, as it is not otherwise as simple adding 1 (i.e., the keyboard rows are 3801, 3802, 3804, 3808, 3810, and 3820).
0B67H
If the S FLAG has been RESET, continue scanning the keyboard with the new HL via a JUMP to 0B61H.
0B6AH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0B6BH
POP AF
Discard the RETurn address at the top of thee stack.
0B6CH
JUMP to 0B40H to fetch a keystroke from the keyboard (note: does not wait for a keypress). The RET in that routine will RETurn from this one.

0B6EH – Continuation of the Keyboard Decode Routine; JUMPed here if we found a key pressed.

0B6EH
EX DE,HL
EXchange the value stored in Register Pair HL (currently, the address of the keyboard row which had the keypress) with the value stored in Register Pair DE (currently, the position in the Keyboard Decode Table in ROM).
0B6FH
LD B,(HL)
Fetch the key (i.e, the value held in the memory location pointed to by Register Pair HL) and store it into Register B.
0B70H
INC B
INCrement the value stored in Register B by 1.
0B71H
SRL A
Shift the bits in Register A shifted right position, with bit 0 being put into the CARRY FLAG.
0B73H
Loop back to 0B70H until the Z FLAG is set.
0B75H
LD A,B
Since you can’t COMPARE against Register B, copy the contents of Register B into Register A.
0B76H
CP 40H
Compare the value held in Register A against 40H (ASCII: @). If A >= @, the NO CARRY FLAG will be set.
0B78H
If the NC FLAG (No Carry) has been set, JUMP to 0B91H.
0B7AH
CP 3CH
Compare the value held in Register A against 3CH (ASCII: “<“). If A >= “<“, the NO CARRY FLAG will be set.
0B7CH
If the NC FLAG (No Carry) has been set, JUMP to 0B9FH.
0B7EH
CP 30H
Compare the value held in Register A against 30H (ASCII: 0). if A >= 0, the NO CARRY FLAG will be set.
0B80H
If the NC FLAG (No Carry) has been set, JUMP to 0B98H.
0B82H
LD HL,0BB2H
Let Register Pair HL equal 0BB2H, which is the last entry in the KEYBOARD DECODE TABLE. The next INC HL points HL to the CONTROL CHARACTER LOOKUP TABLE.
0B85H
INC HL
This is the top of a loop which advances HL by B bytes. INCrement the value stored in Register Pair HL by 1 to point to the next line of the CONTROL CHARACTER LOOKUP TABLE.
0B86H
DEC B
DECrement the value stored in Register B by 1.
0B87H
If Register B has not yet hit ZERO, LOOP BACK to 0B85H to INC HL and keep going until B bytes.
0B89H
LD B,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register B.
0B8AH
GOSUB to 0BA5H to check for a SHIFT, set the FLAGS, and put Register B into Register A.
0B8DH
RET NZ
If the NZ FLAG (Not Zero) has been set (meaning, SHIFT was found), RETurn to the caller.

0B8EH – Continuation of the Keyboard Decode Routine; passed through since the key was not greater than @, “<“, or 0.

0B8EH
AND 3FH
MASK the value of Register A against 3FH (0011 1111) to convert UP, DOWN, LEFT, and RIGHT into 01BH, 01CH, 01DH, and 01EH.
0B90H
RET
RETurn to the caller.

0B91H – Continuation of the Keyboard Decode Routine; JUMPed here from 0B76H if the key is >= @.

0B91H
GOSUB to 0BA5H to check for a SHIFT, set the FLAGS, and put Register B into Register A.
0B94H
RET Z
If the Z FLAG (Zero) has been set (meaning, no SHIFT), RETurn to the caller.

0B95H – Continuation of the Keyboard Decode Routine; passed through if the key was >= @, but it was unshifted.

0B95H
AND 3FH
MASK the value of Register A against 3FH (0011 1111) to turn A-Z into 01H to 27H (noting that 1DH is converted again, so SHIFT-H will not produce a BACKSPACE).
0B97H
RET
RETurn to the caller.

0B98H – Continuation of the Keyboard Decode Routine; JUMPed here from 0B80H if the key is >= 0.

0B98H
GOSUB to 0BA5H to check for a SHIFT, set the FLAGS, and put Register B into Register A.
0B9BH
RET Z
If the Z FLAG (Zero) has been set (meaning, no SHIFT), RETurn to the caller.

0B9CH – Continuation of the Keyboard Decode Routine; passed through if the key was >= 0, but it was unshifted.

0B9CH
AND 2FH
MASK the value of Register A against 2FH to convert the numbers into their shifted counterparts (1 to !, etc).
0B9EH
RET
RETurn to the caller.

0B9FH – Continuation of the Keyboard Decode Routine; JUMPed here from 0B7CH if the key is >= “<“.

0B9FH
GOSUB to 0BA5H to check for a SHIFT, set the FLAGS, and put Register B into Register A.
0BA2H
RET NZ
If the NZ FLAG (Not Zero) has been set (meaning, SHIFT was found), RETurn to the caller.

0BA3H – Continuation of the Keyboard Decode Routine; JUMPed here from 0B7CH if the key is >= “<“, but it was shifted.

0BA3H
JUMP to 0B9CH which will convert SHIFT@ into 0.

0BA5H – Continuation of the Keyboard Decode Routine; this will check for a SHIFT, set the FLAGS (NZ if SHIFTED), and put Register B into Register A.

0BA5H
LD A,(3880H)
Fetch the value held in memory location 3880H and store it into Register A.
0BA8H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0BA9H
LD A,B
Copy the contents of Register B into Register A.
0BAAH
RET
RETurn to the caller.

0BABH – No idea what calls this!.

0BABH
RET
RETurn to the caller.

0BACH – Data Storage – Keyboard Decode Table.

0BACH
DEFB 3FH
The ? key.
0BADH
DEFB 47H
The G key.
0BAEH
DEFB 4FH
The O key.
0BAFH
DEFB 57H
The W key.
0BB0H
DEFB 2FH
The / key.
0BB1H
DEFB 37H
The 7 key.
0BB2H
DEFB 00H
End of List Delimeter.

0BB3H – Data Storage – Control Characters

0BB3H
DEFB 0DH
The ENTER key.
0BB4H
DEFB 0CH
CLEAR SCREEN
0BB5H
DEFB 03H
The BREAK key.
0BB6H
DEFB 6BH
The key.
0BB7H
DEFB 5CH
The key.
0BB8H
DEFB 5DH
The key.
0BB9H
DEFB 5EH
The $rarr; key.
0BBAH
DEFB 20H
The SPACE key.

0BBBH – Data Storage – Parse Table for DATA Statement

0BBBH
DEFM ‘DATA’
The word DATA
0BBFH
DEFW 8749H
JUMP location if DATA is found (0749H).
0BC1H
DEFW 874BH
JUMP location if DATA is NO found (074BH).

0BC3H – This routine will copy the 4 bytes pointed to by Register Pair HL into the Floating Point Stack (which is 5 bytes).

0BC3H
0BC4H
0BC5H
PUSH DE
PUSH HL
PUSH AF
Save DE, HL, and AF – Will be restored before RETurning.
0BC6H
LD BC,0004H
Set up for a move of 4 bytes via a LDIR by setting Register Pair BC equal 0004H.
0BC9H
0BCBH
PUSH IX
POP DE
Let Register Pair DE = Special Index Register IX, so now DE points to the current location in the Floating Point Stack.
0BCCH
LDIR
Transfer 4 bytes fromthe 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.
0BCEH
RL (IX+02H)
IX+02H is the MSB of NUMBER 2 in the FLOATING POINT STACK. Rotates the bytes of IX+02H (the MSB of the NUMBER 2 in the Floating Point Stack at IX) to the left with the CARRY value moving to bit 0 and bit 7 moving to the CARRY.
0BD2H
RL (IX+03H)
IX+03H is the EXPONENT of NUMBER 2 in the FLOATING POINT STACK. Rotates the bytes of IX+03H (the EXPONENT of NUMBER 2 in the Floating Point Stack at IX) to the left with the CARRY value moving to bit 0 and bit 7 moving to the CARRY.
0BD6H
LD A,B
Copy the contents of Register B into Register A.
0BD7H
RRA
Rotates the bits in Register A to the right, with CARRY put into bit 7, and BIT 0 put into CARRY.
0BD8H
LD (IX+04H),A
IX+04H is the SIGN of NUMBER 2 in the FLOATING POINT STACK. Store the modified Register B into IX+04H (the SIGN of NUMBER 2 in the Floating Point Stack at IX).
0BDBH
SCF
Since the CARRY FLAG is going to be important, turn the CARRY FLAG on.
0BDCH
RR (IX+02H)
IX+02H is the MSB of NUMBER 2 in the FLOATING POINT STACK. With the CARRY freshly set, rotates the bytes of IX+02H (the MSB of NUMBER 2 in the Floating Point Stack at IX) to the left with the CARRY value moving to bit 0 and bit 7 moving to the CARRY.
0BE0H
LD C,05H
Let Register C equal 05H, which is the number of bytes in a Floating Point Stack representing a single number.
0BE2H
ADD IX,BC
Advance the Floating Point Stack pointer (Register Pair IX) to the nexy number in the Floating Point Stack.
0BE4H
0BE5H
0BE6H
POP AF
POP HL
POP DE
Restore AF, HL, and DE from the stack.
0BE7H
RET
RETurn to the caller.

0BE8H – This routine will assign a value held at the top of the FLOATING POINT STACK to a variable in a FOUR BYTE FORMAT and the number is then removed from the FLOATING POINT STACK. The top of the stack must hold the address of the variable being set.

0BE8H
POP HL
Put the memory location of the variable to be set (i.e., the value held at the top of the STACK) into Register Pair HL.
0BE9H
LD BC,FFFBH
Let Register Pair BC equal FFFBH, which is -5.
0BECH
ADD IX,BC
Position the FLOATING POINT STACK back 1 entry (i.e., -5 bytes) to point to the FLOATING POINT NUMBER we want to access.
0BEEH
LD BC,0004H
Let Register Pair BC equal 0004H (Decimal: 4) representing the number of bytes that will be used for the variable, which will be used for a LDIR of 4 bytes.
0BF1H
PUSH DE
Save the contents of Register Pair DE to the top of the stack. Will be restored from the stack before exiting this routine.
0BF2H
PUSH HL
Save the contents of Register Pair HL to the top of the stack. Will be restored from the stack before exiting this routine.
0BF3H
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the location in RAM of the variable to be set) with the value stored in Register Pair DE (which will be discarded).
0BF4H
0BF6H
PUSH IX
POP HL
Let Register Pair HL = Special Index Register IX, which will be the source of the data; DE is still the location in RAM of the variable to be set.
0BF7H
LDIR
Transfers the 4 bytes of the FLOATING POINT STACK (pointed to by HL) into the variable (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.
0BF9H
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the current pointer to the FLOATING POINT STACK after the 4 byte move) with the value stored in Register Pair DE (i.e., the pointer to the VARIABLE in RAM after the move).
0BFAH
0BFBH
DEC HL
Back up HL (i.e., the pointer to the variable in RAM) two bytes.
0BFCH
RL (HL)
Rotates the byte held at (HL) to the left with the CARRY value moving to bit 0 and bit 7 moving to the CARRY.
0BFEH
INC HL
Point to the next byte of the variable by INCrementing the value stored in Register Pair HL by 1.

Now we move the SIGN BIT to the top bit of the exponent byte.

0BFFH
LD A,(IX+04H)
IX+04H is the SIGN of NUMBER 2 in the FLOATING POINT STACK. Fetch the value held in the memory location pointed to by Special Index Register Pair (IX+04H) (i.e., the SIGN of the number in the Floating Point Stack at IX) into Register A.
0C02H
RLA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and the previous contents of the carry flag are copied to bit 0.
0C03H
RR (HL)
With the CARRY freshly set, rotate the byte of the VARIABLE pointed to by Register Pair HL to the right one bit position with bit 0 copied to the CARRY FLAG and the previous contents of the CARRY FLAG copied to bit 7.
0C05H
DEC HL
Back up the pointer to the byte in the VARIABLE by 1.
0C06H
RR (HL)
Rotate the byte of the VARIABLE pointed to by Register Pair HL to the right one bit position with bit 0 copied to the CARRY FLAG and the previous contents of the CARRY FLAG copied to bit 7.
0C08H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0C09H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0C0AH
RET
RETurn to the caller.

0C0BH – Convert a FLOATING number to an INTEGER; results stored in Register Pair HL.

0C0BH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0C0CH
LD BC,FFFBH
Let Register Pair BC’ equal FFFBH, which is -5.
0C0FH
ADD IX,BC
Move the pointer of the FLOATING POINT STACK back 1 number’s worth of bytes (i.e., 5 bytes).
0C11H
LD DE,0000H
Let Register Pair DE equal 0000H.
0C14H
LD A,(IX+03H)
IX+03H is the EXPONENT of NUMBER 2 in the FLOATING POINT STACK. Fetch the EXPONENT OF NUMBER 2 from the current FLOATING POINT STACK (held at IX + 03H) and store it into Register A.
0C17H
LD C,(IX+04H)
IX+04H is the SIGN of NUMBER 2 in the FLOATING POINT STACK. Fetch the SIGN OF NUMBER 2 from the current FLOATING POINT STACK (held at IX + 04H) and store it into Register A.
0C1AH
CP 80H
Compare the EXPONENT (held in Register A) against 80H (Decimal: 128). Results: If Register A equals 80H, the Z FLAG is set; otherwise the NZ FLAG is set.
0C1CH
If the EXPONENT was 80H, then the Z FLAG will have been set, JUMP to 0C52H to PUSH DE’ to the top of the stack (for transfer to HL), swap back the alternate registers, RESTORE the top of the stack to HL, and RETurn.
0C1EH
CP 01H
Compare the EXPONENT (held in Register A) against 01H. Results:
  • If Register A equals 01H, the Z FLAG is set.
  • If A < 01H, the CARRY FLAG will be set.
  • if A >= 01H, the NO CARRY FLAG will be set.
0C20H
If the EXPONENT was lower than 02 (and the M FLAG was set, meaning negative; meaning also that BIT 7 was set), JUMP to 0C2CH to shift.
0C23H
CP 10H
Compare the EXPONENT (held in Register A) against 10H (Decimal: 16). Results:
  • If Register A equals 10H, the Z FLAG is set.
  • If A < 10H, the CARRY FLAG will be set.
  • if A >= 10H, the NO CARRY FLAG will be set.
0C25H
If the EXPONENT was lower than 10H (Decimal: 16), the number is smaller than 2^16 so JUMP to 0C30H.
0C28H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0C29H
display the “HOW?” error via a JUMP to 01A2H.

0C2CH – Part of the CONVERT A FLOATING NUMBER TO AN INTEGER routine; JUMPed here from 0C20H if the EXPONENT was lower than 01H.

0C2CH
LD A,FFH
Let Register A equal FFH (Decimal: 255).
0C2EH
JUMP to 0C46H to shift Register C left one position, round if needed, Put DE’ into HL, and RETurn.

0C30H – Part of the CONVERT A FLOATING NUMBER TO AN INTEGER routine; JUMPed here from 0C25H if the EXPONENT was lower than 10H. This routine will shift a small FLOATING POINT number into the correct position based on the EXPONENT. Register A is a number less than 16.

0C30H
LD B,A
Copy the contents of Register A into Register B to act as the number of times the number needs to be rotated.
0C31H
LD A,(IX+00H)
IX+00H is the LSB of NUMBER 2 in the FLOATING POINT STACK. Fetch the LSB of NUMBER 2 from the FLOATING POINT STACK (held at IX+00H) and store it into Register A.
0C34H
LD L,(IX+01H)
IX+01H is the NMSB of NUMBER 2 in the FLOATING POINT STACK. Fetch the NMSB of NUMBER 2 from the FLOATING POINT STACK (held at IX+01H) and store it into Register L.
0C37H
LD H,(IX+02H)
IX+02H is the MSB of NUMBER 2 in the FLOATING POINT STACK. Fetch the MSB of NUMBER 2 from the FLOATING POINT STACK (held at IX+02H) and store it into Register H.
0C3AH
SLA A
Top of a loop of Register B iterations. The contents of the LSB (stored in Register A) are shifted left one bit position, with the contents of bit 7 copied to the carry flag and a zero is put into bit 0.
0C3CH
RL L
The contents of Register L are rotated left one bit position with the contents of bit 7 copied to the carry flag and the previous contents of the carry flag copied to bit 0.
0C3EH
RL H
The contents of Register H are rotated left one bit position with the contents of bit 7 copied to the carry flag and the previous contents of the carry flag copied to bit 0.
0C40H
RL E
The contents of Register E are rotated left one bit position with the contents of bit 7 copied to the carry flag and the previous contents of the carry flag copied to bit 0.
0C42H
RL D
The contents of Register D are rotated left one bit position with the contents of bit 7 copied to the carry flag and the previous contents of the carry flag copied to bit 0.
0C44H
LOOP back to 0C3AH to keep rotating, 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.
0C46H
SLA C
The contents of the Register C are shifted left one bit position, with the contents of bit 7 copied to the carry flag and a zero is put into bit 0.
0C48H
If the NC FLAG (No Carry) has been set, then we do not need to round up, so JUMP to 0C52H.
0C4AH
OR H
OR Register H against Register A. The results are stored in Register A.
0C4BH
OR L
OR Register L against Register A. The results are stored in Register A.
0C4CH
If the Z FLAG (Zero) has been set, then the value was have is zero, and we certainly don’t need to round that up, so JUMP to 0C4FH.
0C4EH
INC DE
Bump DE.
0C4FH
GOSUB to 0C78H to NEGate Register Pair DE.
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
0C53H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0C54H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0C55H
RET
RETurn to the caller.

0C56H – Set HL to 10.0 and then, by passing through, convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.

0C56H
LD HL,000AH
Let Register Pair HL equal 000AH (Decimal: 10).

0C59H – Convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack. On Entry DE still points to the current character of the BASIC command line being examined.

0C59H
PUSH DE
Save the pointer current character of the BASIC command line being examined (i.e., Register Pair DE) to the top of the stack.
0C5AH
EX DE,HL
Let DE = the floating point number.
0C5BH
LD BC,000AH
Let Register Pair BC’ equal 000AH (Decimal: 10), which would be two sets of 5-byte entries in the FLOATING POINT STACK.
0C5EH
ADD IX,BC
Advance the pointer to the FLOATING POINT STACK pointer (i.e., Special Index Register IX) forward 2 entries (i.e., 10 bytes).
0C60H
GOSUB to 0C75H to process a number held in Register Pair DE (with negative numbers being turned upside down so -3 would gets turned into 0FFFD).
0C63H
PUSH DE
Save the resulting modified Register Pair DE’ to the top of the stack so that it can be recalled into DE when DE is swapped with DE’.
0C64H
LD H,00H
Let Register H’ equal 00H.
0C66H
RR H
Rotate Register H’ right one bit position, with the contents of bit 0 copied to the carry flag, and the previous contents of the carry flag are copied to bit 7.
0C68H
LD L,10H
Let Register L’ equal 10H (Decimal: 16).
0C6AH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0C6BH
POP DE
Put the value held at the top of the STACK (i.e., DE’) into Register Pair DE.
0C6CH
LD L,00H
Let Register L equal 00H.
0C6EH
LD H,E
Copy the contents of Register E into Register H.
0C6FH
LD C,D
Copy the contents of Register D into Register C.
0C70H
GOSUB to 0E00H to normalize C, H, and L.
0C73H
JUMP to 0CA4H to check to see if H, combined with L, equals A (and if so, JUMP to 0C4FH) and if not, increase and negate DE.

0C75H – This subroutine is called from 0C60H and processes the sign. If DE is negative, then DE = -DE and CARRY will be set. On entry the REGULAR REGISTER SET is active.

0C75H
XOR A
Set Register A to ZERO and clear all Flags.
0C76H
ADD A,D
LET Register A = Register A + the SIGN of NUMBER 1 (Stored in D).
0C77H
RET P
If the number is POSITIVE (S FLAG has been RESET), RETurn to the caller.

If we are here, then a negative number was passed. Will give some examples.

0C78H
LD A,E
Copy the contents of the LSB of the number held in Register Pair DE into Register A. (If -3 was given then DE is 0003, so A is now 03H)
0C79H
NEG
Negate the contents of Register A (which is the same as -A). (If -3 was given then DE is 0003, so A is now FDH)
0C7BH
LD E,A
Put the negated value of Register E into Register E. (If -3 was given then DE is 00FD)
0C7CH
LD A,D
Copy the the MSB of the number held in Register Pair DE into Register A. (If -3 was given then DE is 00FD, so A is now 00H)
0C7DH
CPL
Reverse each bit in Register A (which is the same as NOT). (If -3 was given then DE is 00FD, so A is now FFH and the CARRY FLAG is SET). Note that CPL does not affect the CARRY FLAG.
0C7EH
CCF
Invert the state of the CARRY FLAG. (If -3 was given then DE is 00FD, so A is now FFH and the CARRY FLAG is RESET).
0C7FH
ADC 00H
LET Register A = Register A + 00H to incorporate the CARRY FLAG into Register A. (If -3 was given then DE is 00FD and A was now FFH and the CARRY FLAG didn’t change).
0C81H
LD D,A
Copy the modified NOT’d Register D back into Register D. (If -3 was given then DE is FFFD, so A is FFH and the CARRY FLAG is still RESET).
0C82H
SCF
Turn the CARRY FLAG on. (If -3 was given then DE is FFFD, so A is FFH and the CARRY FLAG is now SET).
0C83H
RET
RETurn to the caller.

0C84H – Part of the math routines. This is MULTIPLY. If 0C84H is called, it first moves the ONES to TENS, TENS TO HUNDREDS, etc.

0C84H
GOSUB to 0C56H to multiply the number at the top of the FLOATING POINT STACK by 10.
0C87H
GOSUB to 0E1EH which puts the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L. A returns with 80H.
0C8AH
If the Z FLAG (Zero) has been set (meaning that the exponent of the NUMBER 2 is 80H), JUMP to 0CCAH which will then JUMP to 0D20H to will move the Floating Point Stack tracker index IX back to the prior Floating Point Stack entry (i.e., back 5 bytes), RESTORE DE from the Stack, and RETurn out of this routine (since this is a JUMP).
0C8CH
CP E
If we are here, then the exponent of NUMBER 2 was not 80H, so we now compare the exponent of NUMBER 1 (held in E) against 80H (held in A). If they are equal …
0C8DH
… JUMP to 0D0DH to set Register L to 80H, store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.
0C90H
If they were NOT equal, GOSUB to 0D27H to multiply the numbers in the Floating Point Stack.
0C93H
JUMP to 0CA4H to JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0C95H – Part of the math routines. This is FLOATING POINT DIVIDE. It first moves the ONES to TENS, TENS TO HUNDREDS, etc. and then divides the two numbers at the top of the FLOATING POINT STACK.

0C95H
GOSUB to 0C56H to multiply the number at the top of the FLOATING POINT STACK by 10.
0C98H
GOSUB to 0E1EH which puts the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L. A returns with 80H.
0C9BH
If the Z FLAG (Zero) has been set (meaning that the exponent of the NUMBER 2 is 80H), JUMP to 0CCAH which will then JUMP to 0D20H to will move the Floating Point Stack tracker index IX back to the prior Floating Point Stack entry (i.e., back 5 bytes), RESTORE DE from the Stack, and RETurn out of this routine (since this is a JUMP).
0C9DH
CP E
If we are here, then the exponent of NUMBER 2 was not 80H, so we now compare the exponent of NUMBER 1 (held in E) against 80H (held in A). If they are equal …
0C9EH
If the Z FLAG (Zero) has been set, meaning the exponent to NUMBER 1 was 80H, we then have a problem, so JUMP to 01A3H to display the “HOW?” error.
0CA1H
GOSUB to 0D5CH to handle the floating point division.
0CA4H
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0CA6H – Part of the FLOATING POINT DIVIDE routine. This routine pushes HL to the FLOATING POINT STACK, converts the top two numbers in the FLOATING POINT STACK to to B/D/B’/D’/E’ and C/L/C’/H’/L’, and then replaces BC with -5 before JUMPing to 0CB7H.

0CA6H
GOSUB to 0BC3H to push the variable held in Register Pair HL into the FLOATING POINT STACK.
0CA9H
GOSUB to 0E1EH to put the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L.
0CACH
LD BC,FFFBH
Let Register Pair BC equal FFFBH, which is -5.
0CAFH
Skip the next 2 instructions (which would also affect the FLOATING POINT STACK and BC) and JUMP to 0CB7H to move the FLOATING POINT STACK POINTER by BC and continue processing.

0CB1H – Math Routine. Fetch the top 2 entries from the Floating Point Stack into their register sets, remove them from the Floating Point Stack, and do a bunch of comparisons between the two.

0CB1H
GOSUB to 0E1EH
GOSUB to 0E1EH which puts the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L.
0CB4H
LD BC,FFF6H
Let Register Pair BC equal FFF6H, which will be -10 so as to back up IX two Floating Point Stack entries, thus treating those 2 numbers as if they were POP’d off of the Floating Point Stack.
0CB7H
ADD IX,BC
LET Register Pair IX = Register Pair IX + Register BC. This will move IX back 10 bytes to a different FP set of numbers.
0CB9H
CP L
Compare the value held in Register A against the EXPONENT of NUMBER 2 (held in Register L). Results:
  • If Register A equals the value held in Register L, the Z FLAG is set.
  • If A < L, the CARRY FLAG will be set.
  • if A >= L, the NO CARRY FLAG will be set.
0CBAH
GOSUB to 0D94H which will JUMP to 0DA0 if they were the same, compare A to the EXPONENT of NUMBER 1 (if different) and if THOSE are the same JUMP to 0DA8H, otherwise XOR the sign of NUMBER 2 against the sign of NUMBER 1, and JUMP to 0DB3 if THOSE are the same, and JUMP to 0DA7H otherwise. 0DA7H will either RETurn if the Z Flag is set OR test the sign and, if positive, rotate A right, turn on the carry, rotate A left, and RETurn.
0CBDH
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0CBEH
RET
RETurn to the caller.

0CBFH – Math Routine. Floating Point Subtraction.

0CBFH
GOSUB to 0E1EH
GOSUB to 0E1EH which puts the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L.
0CC2H
If the NZ FLAG (Not Zero) has been set, then there are actually TWO numbers to work with, so JUMP to 0CC9H.
0CC4H
GOSUB to 0D03H to set the FLOATING POINT STACK registers for NUMBER 2 = NUMBER 1. Returns with both sets equal to NUMBER 1 and DE at the top of the stack.
0CC7H
JUMP to 0CF9H to flip the sign of the Floating Point number just below the Floating Point Stack pointer, POP DE, and RETurn to the caller routine (since this is a JUMP, not a CALL).

0CC9H – Math Routine. Continuation of the Floating Point Subtraction routine. Jumped here from 0CC2H if there are 2 numbers to work with.

0CC9H
CP E
Compare the value held in Register A against the Exponent (the value held in Register E). If they match, the Z FLAG will be set.
0CCAH
If the Z FLAG (Zero) has been set, JUMP to 0D20H which will move the Floating Point Stack tracker index IX back to the prior Floating Point Stack entry (i.e., back 5 bytes), RESTORE DE from the Stack, and RETurn out of this routine (since this is a JUMP).
0CCCH
XOR D
eXclusive OR the SIGN byte (held in Register D) against Register A. The results are stored in Register A.
0CCDH
LD D,A
Put the results of that XOR back into Register D.
0CCEH
JUMP BACK to 0CDBH to POP DE, and RETurn to the caller routine (since this is a JUMP, not a CALL).

0CD0H – Math Routine. Entry point to add the value held in Register Pair HL.

0CD0H
GOSUB to 0BC3H to push the variable held in Register Pair HL into the FLOATING POINT STACK.

0CD3H – Math Routine – Floating Point Addition. On entry the ALTERNATE REGISTER SET is active.

0CD3H
GOSUB to 0E1EH which puts the various parts of two floating point numbers into the registers. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L.
0CD6H
If the Z FLAG (Zero) has been set, then there was no second number, JUMP to 0D04H to set the second number to match the first number.
0CD8H
CP E
Compare the EXPONENT (held in Register E) against 80H (which is held in A upon exit from 0E1EH). If Register A equals the value held in Register E, the Z FLAG is set.
0CD9H
If the Z FLAG (Zero) has been set, then the number was ZERO, so just JUMP to 0D20H which will move the Floating Point Stack tracker index IX back to the prior Floating Point Stack entry (i.e., back 5 bytes), RESTORE DE from the Stack, and RETurn out of this routine (since this is a JUMP).
0CDBH
Since its not zero, we need to process. First, GOSUB to 0DB3H to compare the exponents of two numbers and, if equal, the mantissas.
0CDEH
If the Z FLAG (Zero) has been set, meaning that they are the same, JUMP to 0CEEH to check the signs of the two numbers, and if they are the same, add the two exponents together and put the numbers back into the FLOATING POINT STACK and exit the routine.
0CE0H
If the NC FLAG (No Carry) has been set, JUMP to 0CE9H to CALL 0DCBH to do floating point addition, returning with NC if the precision will be lost and putting the register back in the FLOATING POINT STACK.
0CE2H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
0CE3H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0CE4H
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.
0CE5H
LD A,C
Copy the contents of Register C into Register A.
0CE6H
LD C,B
Copy the contents of Register B into Register C.
0CE7H
LD B,A
Copy the contents of Register A into Register B.
0CE8H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0CE9H
GOSUB to 0DCBH to do floating point addition, returning with NC if the precision will be lost.
0CECH
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0CEEH – Part of the Floating Point Addition routine; will check the signs of the two numbers, and if they are the same, add the two exponents together and put the numbers back into the FLOATING POINT STACK. On entry, the REGULAR REGISTER SET is active.

0CEEH
LD A,H
Copy the SIGN of NUMBER 2 (Stored in H) into Register A.
0CEFH
XOR D
eXclusive OR the SIGN of NUMBER 1 (Stored in D) against SIGN of NUMBER 1 (from Register H). The results are stored in Register A.
0CF0H
If the SIGNs of NUMBER 1 and NUMBER 2 are not the same (i.e., the NZ FLAG has been set), JUMP to 0D0DH to set Register L to 80H, store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.
0CF2H
LD E,01H
If the signs ARE the same, then set Register E (which is the EXPONENT) equal to 01H.
0CF4H
GOSUB to 0DF3H which will add the two sets of EXPONENTS together (i.e., L = L + E with Carry) and a test for overflow.
0CF7H
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0CF9H – Math Routine. Flip the sign of the Floating Point number just below the Floating Point Stack pointer, POP DE, and RETurn.

0CF9H
LD A,(IX+FFH)
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK. Fetch the value held in the memory location pointed to by Special Index Register Pair (IX – 1) and store it into Register A.
0CFCH
XOR 80H
eXclusive OR 80H (Binary:1000 0000) against Register A to flip Bit 7 (the SIGN bit). If it was on then its now off and vice versa. The results are stored in Register A.
0CFEH
LD (IX+FFH),A
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK. Put the modified byte back into the Floating Point Stack.
0D01H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0D02H
RET
RETurn to the caller.

0D03H – Math Routine. This routine sets the FLOATING POINT STACK registers for NUMBER 2 = the FLOATING POINT STACK registers for NUMBER 1 and with DE at the top of the stack. On entry the REGULAR REGISTER SET is active.

As a reminder, NUMBER 1 is stored in B’ (MSB), D’ (NMSB), and E’ (LSB), with the SIGN in D and the EXPONENT in E,. NUMBER 2 is stored in C’ (MSB), H’ (NMSB), and L’ (LSB), with the SIGN in H and the EXPONENT in L.

0D03H
PUSH DE
Save the SIGN and EXPONENT of NUMBER 1 (held in Register Pair DE) to the top of the stack.
0D04H
LD H,D
Copy the SIGN of NUMBER 1 (Stored in D) into Register H (i.e., the SIGN of NUMBER 2).
0D05H
LD L,E
Copy the EXPONENT of NUMBER 1 (Stored in E) into Register L (i.e., the EXPONENT of NUMBER 2)
0D06H
EXX
Set the ALTERNATE REGISTER SET to ACTIVE and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D07H
LD L,E
Copy the LSB of NUMBER 1 (stored in E’) into Register L’ (i.e., the LSB of NUMBER 2).
0D08H
LD H,D
Copy the NMSB of NUMBER 1 (stored in D’) into Register H (i.e., the NMSB of NUMBER 2).
0D09H
LD C,B
Copy the MSB of NUMBER 1 (stored in B’) into Register C (i.e., the MSB of NUMBER 2).
0D0AH
EXX
Set the REGULAR REGISTER SET to ACTIVE and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D0BH
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0D0DH – Set L to 80H and store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started), POP DE, and RETurn.

0D0DH
LD L,80H
Let Register L equal 80H (Decimal: 128) to indicate a very small exponent.
0D0FH
LD (IX-06H),H
This is a common jump point, with the purpose to store the registers into the Floating Point Stack. First, store the SIGN BIT (held in Register H) into the memory location pointed to by Special Index Register Pair IX-06H.
0D12H
LD (IX-07H),L
Store the EXPONENT (held in Register L) into the memory location pointed to by Special Index Register Pair IX-07H.
0D15H
EXX
Exchange the REGULAR registers OUT and the ALTERNATE registers IN.. Note: AF is not handled via EXX.
0D16H
LD (IX-10H),L
Store the LSB of the MANTISSA (held in Register L’) into the memory location pointed to by Special Index Register Pair IX-10H.
0D19H
LD (IX-09H),H
Store the NMSB of the MANTISSA (held in Register H’) into the memory location pointed to by Special Index Register Pair IX-09H.
0D1CH
LD (IX-08H),C
Store the MSB of the MANTISSA (held in Register C’) into the memory location pointed to by Special Index Register Pair IX-08H.
0D1FH
EXX
Exchange the ALTERNATE registers OUT and the REGULAR registers IN.. Note: AF is not handled via EXX.
0D20H
LD BC,FFFBH
This is a common jump point for any routine that wants to POP the floating point stack as it backs up IX 5 bytes and restores DE. First, let Register Pair BC equal FFFBH, which is -5.
0D23H
ADD IX,BC
Reset Special Index Register IX back 5 bytes (the amount of bytes for a single floating point entry).
0D25H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0D26H
RET
RETurn to the caller.

0D27H – Multiply Floating Point Numbers – Number 1 is D (Sign), E (Exponent), B’, D:’ E’, and Number 2 is H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB).

0D27H
LD A,H
Copy the SIGN of NUMBER 2 (Register H) into Register A.
0D28H
XOR D
eXclusive OR the SIGN of NUMBER 1 (Register D) against SIGN of NUMBER 2 (Register A). The results are stored in Register A.
0D29H
LD H,A
Since this will be the sign of the ultimate product of the two numbers, let’s keep that! Copy the results of that XOR into into Register H (the SIGN of NUMBER 2).
0D2AH
DEC E
DECrement the EXPONENT of NUMBER 1 (Register E) by 1.
0D2BH
PUSH HL
Save the contents of Register Pair HL (SIGN and EXPONENT of NUMBER 2) to the top of the stack.
0D2CH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
0D2DH
LD B,18H
Let Register B equal 18H (Decimal: 24) to represent the maximum number of bits we can shift and maintain accuracy.
0D2FH
LD L,(IX+F6H)
Fetch the value held in the memory location pointed to by Special Index Register Pair (IX-10), which is the LSB of NUMBER 2, and store it into Register L.
0D32H
LD H,(IX+F7H)
Fetch the value held in the memory location pointed to by Special Index Register Pair (IX-09), which is the NMSB of NUMBER 2, and store it into Register H.
0D35H
LD C,(IX+F8H)
Fetch the value held in the memory location pointed to by Special Index Register Pair (IX-08), which is the MSB of NUMBER 2, and store it into Register C.
0D38H
EXX
EXchanges REGULAR registers out and the ALTERNATE registers in. Note: AF is not handled via EXX.
0D39H
XOR A
Set Register A to ZERO and clear all Flags.
0D3AH
LD L,A
Copy the contents of Register A into Register L’.
0D3BH
LD H,A
Copy the contents of Register A into Register H’.
0D3CH
LD C,A
Copy the contents of Register A into Register C’.
0D3DH
EXX
EXchanges ALTERNATE registers out and the REGULAR registers in. Note: AF is not handled via EXX.
0D3EH
SRL C
Shift the bits of Register C right, with bit 0 put into the carry flag.
0D40H
RR H
Rotate the bits of Register H right one bit position, with bit 0 copied to the CARRY FLAG and the previous CARRY FLAG copied to bit 7.
0D42H
RR L
Rotate the bits of Register L right one bit position, with bit 0 copied to the CARRY FLAG and the previous CARRY FLAG copied to bit 7.
0D44H
EXX
EXchanges REGULAR registers out and the ALTERNATE registers in. Note: AF is not handled via EXX.
0D45H
If the NC FLAG (No Carry) has been set, then there is no need to do addition JUMP to 0D4BH.

The next instructions are C’:H’:L’ = C’:H’:L’ + A:D:E

0D47H
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE.
0D48H
LD A,C
Copy the contents of Register C into Register A.
0D49H
ADC A,B
LET Register A = Register A + Register B.
0D4AH
LD C,A
Copy the contents of Register A into Register C.
0D4BH
EXX
EXchanges ALTERNATE registers out and the REGULAR registers in. Note: AF is not handled via EXX.
0D4CH
Jump to 0D53H, 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.

We have finished, so prepare to exit.

0D4EH
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0D4FH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0D50H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D51H
JUMP to 0D83H which will JUMP to 0DE9H.

0D53H – Part of the Multiply Floating Point Number Routine. This handles the SHIFTING of C, H, and L right one bit. On entry the REGULAR REGISTER SET is active, but on exit the ALTERNATE REGISTER SET is active.

0D53H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D54H
RR C
Rotate the MSB of NUMBER 2 (stored in C’)
0D56H
RR H
Rotate the NMSB of NUMBER 2 (stored in H’)
0D58H
RR L
Rotate the LSB of NUMBER 2 (stored in L’)
0D5AH
JUMP BACK into the multiply routine at 0D3DH.

0D5CH – Floating Point Number Division Routine. On entry the REGULAR registers are in effect, although DE and HL have been swapped with DE’ and HL’. No real clue what is happening.

0D5CH
0D5DH
0D5FH
LD A,E
NEG
LD E,A
Let E = -E (since Division is a bunch of subtractions). This turns the EXPONENT of NUMBER 1 negative.
0D60H
0D61H
0D62H
LD A,H
XOR D
LD H,A
Let H = H XOR D. H and D are the signs of the numbers being worked on.
0D63H
PUSH HL
Save the SIGN and EXPONENT of NUMBER 2 (held in Register Pair HL) to the top of the stack.
0D64H
PUSH BC
Save the pointer to the memory location of the line being interpreted (held in Register Pair BC) to the top of the stack.
0D65H
LD B,19H
Let Register B equal 19H (Decimal: 25) for a DJNZ loop 0D85H-0D78H of 25 iterations.
0D67H
EXX
Make the ALTERNATE REGISTER SET active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D68H
SBC HL,DE
Subtracts the value stored in Register Pair DE and the carry flag from the value stored in Register Pair HL.
0D6AH
LD A,C
Copy the contents of Register C into Register A.
0D6BH
SBC A,B
Subtracts the value stored in Register Pair B and the carry flag from the value stored in Register Pair A.
0D6CH
LD C,A
Copy the contents of Register A into Register C.
0D6DH
If the NC FLAG (No Carry) has been set, JUMP to 0D72H.
0D6FH
ADD HL,DE
LET Register Pair HL = Register Pair HL + Register DE.
0D70H
ADC A,B
LET Register A = Register A + Register B.
0D71H
LD C,A
Copy the contents of Register A into Register C.
0D72H
EXX
Make the REGULAR REGISTER SET active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D73H
CCF
Invert the state of the CARRY FLAG.
0D74H
ADC HL,HL
LET Register Pair HL = Register Pair HL + Register HL.
0D76H
RL C
Rotate the bits of Register C left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register C by 2.
0D78H
LOOP back to 0D85H, 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.
0D7AH
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
0D7BH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
0D7CH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D7DH
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0D7EH
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0D7FH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D80H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0D81H
POP HL
Put the value held at the top of the STACK into Register Pair HL.
0D82H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D83H
JUMP to 0DE9H.

0D85H – Part of the Floating Point Number Division Routine. On entry the REGULAR registers are in effect.

0D85H
EXX
Make the ALTERNATE REGISTER SET active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0D86H
ADD HL,HL
Double the NMSB + LSB of NUMBER 2.
0D87H
RL C
Rotate the bits of the MSB of NUMBER 2 (Register C’) left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively doubles MSB of NUMBER 2.
0D89H
If the NC FLAG (No Carry) has been set, JUMP to 0D68H in the prior routine to do some subtraction.
0D8BH
CCF
Reset the CARRY FLAG in preparation for the next intructions.
0D8CH
SBC HL,DE
Subtracts the NMSB and LSB of NUMBER 2 (Register Pair DE’) and the carry flag from the NMSB and LSB of NUMBER 1 (Register Pair HL’).
0D8EH
LD A,C
Copy the MSB of NUMBER 2 (Register C’) into Register A.
0D8FH
SBC A,B
Subtract the MSB of NUMBER 1 (Register B’) and the carry flag from the MSB of NUMBER 2 (Register A/C’).
0D90H
LD C,A
Copy MSB of NUMBER 1 – MSB of NUMBER 2 into Register C’.
0D91H
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
0D92H
JUMP to 0D72H in the prior routine.

0D94H – Part of the Floating Point Division routine. On entry the REGULAR registers are in effect. If the EXPONENTS were the same between the 2 numbers (on entry) the Z FLAG will be set.

0D94H
If the Z FLAG (Zero) has been set, JUMP to 0DA0H which will compare A against the exponent, returning with Z FLAG if they match. If not, continuing to 0DAAH with NC if Register A < Register E, C if Register A >= Register E, Z if the sign bit is 0, and NZ if the sign bit is 1.
0D96H
CP E
Compare the value held in Register A against the EXPONENT of NUMBER 1 (held in Register E). If they are the same …
0D97H
… JUMP to 0DA8H.
0D99H
LD A,H
Copy the SIGN of one number into Register A.
0D9AH
XOR D
eXclusive OR against the SIGN of the other. The results are stored in Register A.
0D9BH
If the SIGNs match, GOSUB to 0DB3H to compare the exponents of two numbers and, if equal, the mantissas.
0D9EH
JUMP to 0DA7H to either RETurn if the Z Flag is set OR test the sign and, if positive, rotate A right, turn on the carry, rotate A left, and RETurn.

0DA0H – Part of the Floating Point Division routine.

0DA0H
CP E
Compare the value held in Register A against the value held in Register E (which holds an exponent). Results:
  • If Register A equals the value held in Register E, the Z FLAG is set.
  • If A < Register E, the CARRY FLAG will be set.
  • if A >= Register E, the NO CARRY FLAG will be set.
0DA1H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller.
0DA2H
SCF
Set the CARRY FLAG to ON
0DA3H
BIT 7,D
Test Bit Number 7 of Register D (which holds the sign). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0DA5H
JUMP down two instructions to 0DAAH.

0DA7H – Part of the Floating Point Division routine. RETurn if the Z Flag is set OR test the sign and, if positive, rotate A right, turn on the carry, rotate A left, and RETurn.

0DA7H
RET Z
If the Z FLAG (Zero) has been set, RETurn to the caller. Otherwise, pass through …

0DA8H – Part of the Floating Point Division routine. Will test the sign and, if positive, rotate A right, turn on the carry, rotate A left, and RETurn. On entry the REGULAR registers are in effect.

0DA8H
BIT 7,H
Test the SIGN of NUMBER 2 (Bit Number 7 of Register H). Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0DAAH
Whether via pass through or jump, the Z/NZ flag is holding the sign bit. If the NZ FLAG (Not Zero) has been set, JUMP to 0DB1H to flip the state of the CARRY FLAG and RETurn.
0DACH
RRA
If the Z FLAG was 0, meaning the SIGN of NUMBER 2 (Register H) was positive, then rotate the contents of A are rotated right one bit position, with the the contents of bit 0 being copied to BOTH the carry flag AND bit 7.
0DADH
SCF
Set the CARRY FLAG to ON
0DAEH
RL A
Rotate Register A left one bit position, with the contents of bit 7 being copied to the carry flag and the previous contents of the CARRY FLAG (which is now ON) copied to bit 0.
0DB0H
RET
RETurn to the caller.

0DB1H – Part of the Math Routine. Flip the state of the CARRY FLAG and RETurn.

0DB1H
CCF
Invert the state of the CARRY FLAG.
0DB2H
RET
RETurn to the caller.

0DB3H – Part of the Floating Point math routines. This will compare the exponents of two numbers and, if equal, the mantissas. On entry the REGULAR registers are in effect.

0DB3H
LD A,L
Copy the EXPONENT of NUMBER 2 (Register L) into Register A.
0DB4H
SUB E
LET Register A = Register A – the EXPONENT of NUMBER 1 (Register E).
0DB5H
If the EXPONENTs were the same (i..e, Register L = Register E), JUMP to 0DBEH to compare the mantiassas (returning witH Z if equal, and NZ otherwise).
0DB7H
If the PARITY/OVERFLOW FLAG has been RESET, JUMP to 0DBCH to handle Floating Point Addition.
0DBAH
NEG
Negate the difference in the EXPONENTs (Register A) (which is the same as -A).
0DBCH
RLCA
Rotate the bits of Register left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and to bit 0.
0DBDH
RET
RETurn to the caller.

0DBEH – Part of the Floating Point math routines. This will compare the mantissas of the numbers returning with NZ set if they don’t match and Z set if they do. On entry the REGULAR registers are in effect.

0DBEH
EXX
Make the ALTERNATE register set active by EXchanging the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0DBFH
LD A,C
Copy the contents of Register C’ (MSB of NUMBER 2) into Register A.
0DC0H
CP B
Compare the value held in Register A against the value held in Register B’ (MSB of NUMBER 1). If they are NOT the same, the NZ FLAG will be set.
0DC1H
If they are NOT the same, JUMP to 0DC9H to swap back the register sets and RETurn out of this routine with the NZ FLAG set.
0DC3H
LD A,H
Copy the contents of Register H’ (NMSB of the NUMBER 2) into Register A.
0DC4H
CP D
Compare the value held in Register A against the value held in Register D’ (NMSB of the NUMBER 1). If they are NOT the same, the NZ FLAG will be set.
0DC5H
If they are NOT the same, JUMP to 0DC9H to swap back the register sets and RETurn out of this routine with the NZ FLAG set.
0DC7H
LD A,L
Copy the contents of Register L’ (LSB of the NUMBER 2) into Register A.
0DC8H
CP E
Compare the value held in Register A against the value held in Register E’ (LSB of the NUMBER 1).
0DC9H
EXX
Make the REGULAR register set active by EXchanging the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0DCAH
RET
RETurn to the caller.

0DCBH – Floating Point Math Routine – Addition. On entry the REGULAR registers are in effect.

0DCBH
LD A,L
Since we can’t do math on Register L, Copy the contents of EXPONENT of NUMBER 2 (Register L) into Register A.
0DCCH
SUB E
Subtract the EXPONENT of NUMBER 1 (Stored in E) from the EXPONENT of NUMBER 2 (Register L).
0DCDH
If the two EXPONENTs were the same (Z FLAG has been set), JUMP to 0DDDH.
0DCFH
CP 18H
Compare the value held in Register A (i.e., the difference in the exponents) against 18H (Decimal: 24) to check for precision. If the difference in the exponents is >= 18H, the NO CARRY FLAG will be set.
0DD1H
RET NC
If the NC FLAG (No Carry) has been set then the exponents are just too far apart for Level 1 to handle the math, so abort the procedure and RETurn to the caller.
0DD2H
EXX
Othwerwise, let’s get to work. First, EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0DD3H
0DD5H
0DD7H
SRL B
RR D
RR E
Start by processing the exponent — Shift the B’/D’/E’ combination (representing the MSB, NSBN, and LSB of the second digit) 1 bit to the right each.
0DD9H
DEC A
DECrement the difference between the exponents (stored in Register A) by 1.
0DDAH
If A hasn’t hit zero yet, then LOOP BACK to 0DD3H to keep shifting.
0DDCH
EXX
Swap out the Floating Point Stack (alt) registers for the regular registers.
0DDDH
LD E,00H
Let Register E equal 00H.
0DDFH
LD A,H
Copy the SIGN of NUMBER 2 (Register H) into Register A.
0DE0H
XOR D
eXclusive OR the SIGN of NUMBER 1 (Register D) against the SIGN of NUMBER 2 (Register H a/k/a Register A). The results are stored in Register A.
0DE1H
If the S FLAG has been SET, JUMP to 0DFAH to use subtraction for an addition noting that on exit, the ALTERNATE registers are in effect.
0DE4H
EXX
Make the ALTERNATE REGISTER SET active (noting that AF remains as the REGULAR set).
0DE5H
ADD HL,DE
LET Register Pair HL = the sum of the NMSB and LSB of the two floating point numbers.
0DE6H
LD A,C
Copy the contents of Register C’ (the MSB of NUMBER 2) into Register A.
0DE7H
ADC A,B
LET Register A = the sum of the MSB of the two floating point numbers.
0DE8H
LD C,A
Copy that sum into Register C’ (the MSB of the first floating point number).
0DE9H
If the NC FLAG (No Carry) has been set then we don’t have to worry about shifting the numbers, so skip all that and JUMP to 0DF2H.
0DEBH
0DEDH
0DEFH
RR C
RR H
RR L
If the addition of the two MSB’s triggered a carry, then we need to shift the 3 bytes representing NUMBER 2 to the right.
0DF1H
SCF
Turn the CARRY FLAG on to indicate that we had to do a shift.
0DF2H
EXX
Swap out the Floating Point Stack (alt) registers for the regular registers.
0DF3H
LD A,L
Copy the EXPONENT of NUMBER 2 (Register L) into Register A.
0DF4H
ADC A,E
LET Register A = the sum of the EXPONENTS of the two numbers (including that CARRY bit!).
0DF5H
If the PARITY/OVERFLOW FLAG has been SET, JUMP to 0E15H which tests the sign of Register H, if NEGATIVE then JUMP to 0E0EH and otherwise clear the return address from the stack and error out with “HOW?”.
0DF8H
LD L,A
Copy the sum of the EXPONENTS of the two numbers (including that CARRY bit) into Register L.
0DF9H
RET
RETurn to the caller.

0DFAH – Floating Point Math Routine – Subtraction. On entry the REGULAR registers are in effect, but on exit the ALTERNATE registers are in effect.

0DFAH
EXX
Swap out the regular registers out and the Floating Point Stack (alt) registers in. Note: AF is not handled via EXX.
0DFBH
SBC HL,DE
Subtract the NMSB and LSB of NUMBER 1 (stored in DE’) from the NMSB and LSB of NUMBER 2 (stored in HL’), and the carry flag, with the result in HL’.
0DFDH
LD A,C
Copy the MSB of NUMBER 2 (stored in C’) into Register A.
0DFEH
SBC A,B
Subtracts the MSB of NUMBER 1 (held in Register B’) and the carry flag from the MSB of NUMBER 2 (stored in Register Pair A).
0DFFH
LD C,A
Copy MSB of NUMBER 2 – MSB of NUMBER 1 into Register C’.

This is a common jump point … On Entry the ALTERNATE REGISTERS are in effect.

0E00H
LD B,18H
Let Register B equal 18H (Decimal: 24) for a DJNC loop at 0E05H-0E0CH so as to shift no more than 24 times.
0E02H
XOR A
Set Register A to ZERO and clear all Flags as Register A will count those shifts.
0E03H
INC C
INCrement the MSB of NUMBER 2 (stored in C’) by 1.
0E04H
DEC C
DECrement MSB of NUMBER 2 (stored in C’) by 1.
0E05H
If the S FLAG (i.e., the high bit) has been SET, JUMP to 0E11H which swaps the alternate registers, adds Register L to Register A, and JUMPs to 0DF5H which JUMPs to 0E15H (which tests the sign of Register H, if NEGATIVE then JUMP to 0E0EH and otherwise clear the return address from the stack and error out with “HOW?”) if the PE FLAG is set, and if not Let Register L = Register A and RETurn.
0E08H
DEC A
OTHERWISE, bump Register A by 1 to keep count of the number of times we shift.
0E09H
ADD HL,HL
LET Register Pair HL = the NMSB and LSB of NUMBER 2 (stored in HL’) * 2, which shifts HL’ left one bit.
0E0AH
RL C
Rotate the bits of the MSB of NUMBER 2 (stored in C’) left 1 position, with 7 going to CARRY and CARRY going to 0. This effectively multiplies Register C by 2.
0E0CH
LOOP back to 0E05H, 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.
0E0EH
LD L,80H
Let thhe EXPONENT of NUMBER 2 (Stored in L) equal 80H (Decimal: 128).
0E10H
RET
RETurn to the caller.

0E11H – Part of the MATH ROUTINE. JUMPed here from 0E05H if the SIGN flag was set based on Register C. On entry the ALTERNATE REGISTER SET is active, on EXIT the REGULAR REGISTER SET is active.

0E11H
EXX
Set the REGULAR REGISTER SET as active by EXchanging the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E12H
ADD A,L
LET Register A = Register A + EXPONENT of NUMBER 2 (Stored in L).
0E13H
JUMP to 0DF5H which JUMPs to 0E15H (which tests the sign of Register H, if NEGATIVE then JUMP to 0E0EH and otherwise clear the return address from the stack and error out with “HOW?”) if the PE FLAG is set, and if not Let Register L = Register A and RETurn.

0E15H – MATH ROUTINE. Test the sign of Register H, if NEGATIVE then JUMP to 0E0EH and otherwise clear the return address from the stack and error out with “HOW?”.

0E15H
LD A,H
Copy the contents of Register H into Register A.
0E16H
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).
0E17H
If the S FLAG has been SET, JUMP to 0E0EH to set Register L to 80H and RETurn.
0E1AH
POP AF
Clear the RETurn address from the stack.
0E1BH
JUMP to 01A3H to display the “HOW?” error.

0E1EH – Math Subroutine. This routine will fill all the registers with various parts of two floating point numbers. On entry, the REGULAR REGISTER SET is active. On exit, the original DE is in the stack, the Z FLAG is set if the exponent NUMBER 2 is 80H, NUMBER 1 is stored in B’, D’, and E’, with the sign in D and the exponent in E, and NUMBER 2 is stored in C’, H’, and L’, with the sign in H and the exponent in L.

0E1EH
POP HL
Put the value held at the top of the STACK, which is the RETurn address from the CALL, into Register Pair HL so we can put something one level below it in the stack and then put it back on top.
0E1FH
PUSH DE
Save the contents of Register Pair DE to the top of the stack. This will NOT be POP’ed back in this routine.
0E20H
PUSH HL
Save the RETurn address from the CALL (held in Register Pair HL) so it is at the top of the stack.
0E21H
LD D,(IX+FFH)
IX+FFH is the same as IX-01H, which is the SIGN of NUMBER 1 in the FLOATING POINT STACK. Put the sign of NUMBER 1, pointed to in the Floating Point Stack at location (IX-1), into Register D.
0E24H
LD E,(IX+FEH)
IX+FEH is the same as IX-02H, which is the EXPONENT of NUMBER 1 in the FLOATING POINT STACK. Put the exponent of NUMBER 1, pointed to in the Floating Point Stack at location (IX-2), into Register E.
0E27H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E28H
LD E,(IX+FBH)
IX+FBH is the same as IX-05H, which is the LSB of NUMBER 1 in the FLOATING POINT STACK. Put the LSB of NUMBER 1, pointed to in the Floating Point Stack at location (IX-5), into Register E’.
0E2BH
LD D,(IX+FCH)
IX+FCH is the same as IX-04H, which is the NMSB of NUMBER 1 in the FLOATING POINT STACK. Put the NMSB of NUMBER 1, pointed to in the Floating Point Stack at location (IX-4), into Register D’.
0E2EH
LD B,(IX+FDH)
IX+FDH is the same as IX-03H, which is the MSB of NUMBER 1 in the FLOATING POINT STACK. Put the MSB of NUMBER 1, pointed to in the Floating Point Stack at location (IX-3), into Register B’.
0E31H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E32H
LD H,(IX+FAH)
Put the sign of NUMBER 2, pointed to in the Floating Point Stack at location (IX-6), into Register H.
0E35H
LD L,(IX+F9H)
Put the exponent of NUMBER 2, pointed to in the Floating Point Stack at location (IX-7), into Register L.
0E38H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E39H
LD L,(IX+F6H)
Put the LSB of NUMBER 2, pointed to in the Floating Point Stack at location (IX-10), into Register L’.
0E3CH
LD H,(IX+F7H)
Put the NMSB of NUMBER 2, pointed to in the Floating Point Stack at location (IX-9), into Register H’.
0E3FH
LD C,(IX+F8H)
Put the MSB of NUMBER 2, pointed to in the Floating Point Stack at location (IX-8), into Register C’.
0E42H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E43H
LD A,80H
Let Register A equal 80H (Decimal: 128).
0E45H
CP L
Compare the value held in Register A against the value held in Register L. Results:
  • If Register A equals the value held in Register L, the Z FLAG is set.
  • If A < L/128/, the CARRY FLAG will be set.
  • if A >= L/128/, the NO CARRY FLAG will be set.
0E46H
RET
RETurn to the caller with Z set of the EXPONENT of NUMBER 2 = 80H (128) and NZ set otherwise.

0E47H – Entry point RND().

0E47H
GOSUB to 0814H to verify that an integer is within parenthesis, and calculate the integer expression with the result in Register Pair HL.
0E4AH
0E4AH
LD A,H
OR L
Since the Z-80 cannot test Register Pair HL against zero, the common trick is to set Register A to equal to Register H, and then OR A against Register L. Only if both Register H and Register L were zero can the Z FLAG be set.
0E4CH
If the seed provided within the RND() command was zero, the Z FLAG (Zero) will have been set, JUMP to 0E64H.
0E4FH
BIT 7,H
Test the sign (bit 7) of Register H. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0E51H
If a negative number was passed, the NZ FLAG will have been set which is a bad thing, so , display the “HOW?” error via a JUMP to 01A2H.
0E54H
GOSUB to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack.
0E57H
GOSUB to 0E64H to process a RND(0) command.
0E5AH
GOSUB to 0C87H to multiply that RND(0) result into an appropriate number based on DE and not just RND(0).
0E5DH
GOSUB to 0C0BH to convert the number in the FLOATING POINT STACK into an INTEGER to be stored in Register Pair HL.
0E60H
INC HL
INCrement the value stored in Register Pair HL by 1.
0E61H
JUMP to 0C59H to convert the value stored in Register Pair HL to a floating point number in the Floating Point Stack, but with the RET in that routine RETurning out of THIS one.

0E64H – Continuation of the RND() routine; JUMPed here to calculate RND(0).

0E64H
PUSH DE
Save the contents of Register Pair DE (i.e., the n of RND[n]).
0E65H
EXX
Swap out the regular registers for the ALT set. Note: AF is not handled via EXX.
0E66H
LD HL,40A7H
Let Register Pair HL equal 40A7H, which points to the Random Number Generator state.
0E69H
LD E,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register E’.
0E6AH
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next byte of the Random Number Generator state.
0E6BH
LD D,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register D’.
0E6CH
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next byte of the Random Number Generator state.
0E6DH
LD B,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register B’.
0E6EH
EXX
Swap out the ALTernate Registers and use the regular registers. Note: AF is not handled via EXX.
0E6FH
Zero out C’, H’, and L’ via a GOSUB to 0155H which resets Bit 6 of Register B, swaps register sets, sets H, L, and C to 00H, swaps register sets, and RETurns.
0E72H
LD HL,0EB2H
Let Register Pair HL equal 0EB2H which is the Random Number Generator Multiplier value table in this ROM.
0E75H
LD C,03H
Let Register C equal 03H for the 3 bytes of the Random Number Generator Multiplier value table, as a big loop.
0E77H
LD B,08H
Let Register B equal 08H for a DJNZ LOOP (at 0E89H) of 8.
0E79H
LD D,(HL)
Fetch a value from the Random Number Generator Multiplier table and store it into Register D.
0E7AH
EXX
Top of the DJNZ loop from 0E7AH-0E89H. Swap out the regular registers for the ALT set. Note: AF is not handled via EXX.
0E7BH
ADD HL,HL
Shift C’, H’, and L’ each one bit to the left … first LET Register Pair HL = Register Pair HL + Register HL.
0E7CH
RL C
That leaves C’ … so shift C’ as well.
0E7EH
EXX
Swap out the ALTernate Registers and use the regular registers. Note: AF is not handled via EXX.
0E7FH
RL D
Rotate Register D (which is a value from the Random Number Generator Multiplier table) one bit to the left
0E81H
If the NC FLAG (No Carry) has been set, JUMP to 0E89H.
0E83H
EXX
Swap out the regular registers for the ALT set. Note: AF is not handled via EXX.
0E84H
ADD HL,DE
The next 3 instructions perform C’/H’/L’ = C’/H’/L’ + B’/D’/E’. First, LET Register Pair HL = Register Pair HL + Register DE.
0E85H
LD A,C
Copy the contents of Register C into Register A.
0E86H
ADC A,B
LET Register A = Register A + Register B.
0E87H
LD C,A
Copy the contents of Register A into Register C.
0E88H
EXX
Swap out the ALTernate Registers and use the regular registers. Note: AF is not handled via EXX.
0E89H
LOOP back to 0E7AH, 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.
0E8BH
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next of the 3 bytes of the Random Number Generator Multiplier value table.
0E8CH
DEC C
DECrement the value stored in Register C by 1 to keep track of the loop of 3.
0E8DH
If the NZ FLAG (Not Zero) has been set, meaning we have not processed all 3 bytes of the Random Number Generator Multiplier value table, JUMP to 0E77H.

If we are here, we have processed all 3 bytes of the Random Number Generator Multiplier value table and have rotated 8 times per.

0E8FH
LD HL,0000H
Let Register Pair HL equal 0000H.
0E92H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0E93H
LD DE,40A7H
Let Register Pair DE equal 40A7H, which points to the Random Number Generator state.
0E96H
LD A,L
Copy the contents of Register L into Register A.
0E97H
ADD 65H
LET Register A = Register A + 65H.
0E99H
LD (DE),A
Store the value held in Register A into the byte of the Random Number Generator state pointed to by Register Pair DE.
0E9AH
INC DE
Bump DE to point to the next byte of the Random Number Generator state
0E9BH
LD L,A
Copy the contents of Register A into Register L.
0E9CH
LD A,H
Copy the contents of Register H into Register A.
0E9DH
ADC B0H
LET Register A = Register A + B0H.
0E9FH
LD (DE),A
Store the value held in Register A into the byte of the Random Number Generator state pointed to by Register Pair DE.
0EA0H
INC DE
Bump DE to point to the next byte of the Random Number Generator state
0EA1H
LD H,A
Copy the contents of Register A into Register H.
0EA2H
LD A,C
Copy the contents of Register C into Register A.
0EA3H
ADC 05H
LET Register A = Register A + 05H.
0EA5H
LD (DE),A
Store the value held in Register A into the byte of the Random Number Generator state pointed to by Register Pair DE.
0EA6H
LD C,A
Copy the contents of Register A into Register C.
0EA7H
GOSUB to 0E00H to normalize C, H, and L (even though they aren’t actually a float).
0EAAH
LD BC,000AH
Let Register Pair BC equal 000AH (Decimal: 10) which is the number of bytes for TWO floating numbers in the Floating Point Stack.
0EADH
ADD IX,BC
Advance the Floating Point Stack pointer (Register Pair IX) by TWO floating numbers (i.e., 10 bytes).
0EAFH
JUMP to 0D0FH leave Register L unchanged but otherwise store the H (Sign), L (Exponent), C’ (MSB), H’ (NLSB), L’ (LSB) registers into the Floating Point Stack at one set earlier than the location pointed to by Special Index Register IX, adust IX to point to that entry (i.e., -5 bytes from where it started)and POP DE. Since this is a JUMP, the RETurn in that routine will actually RETurn to this routine’s caller.

0EB2H – Byte Storage Area – Random Number Generator Multiplier Values.

0EB2H
DEFB 40H E7H 4DH

0EB5H – Byte Storage Area – Constants used to Display Floating Point Numbers.

0EB5H
DEFB 00H 00H 80H 80H
0EB9H
DEFB CCH CCH CCH 7EH

0EC4H – Parse the instruction line to see if the next characters are integers and, if so, put them into Register Pair HL. On entry the REGULAR REGISTER SET is active.

0EC4H
GOSUB to 0155H which resets Bit 6 of Register B, swaps to the ALTERNATE REGISTER SET, sets H’, L’, and C’ to 00H, swaps back to the REGULAR REGISTER SET, and RETurns.
0EC7H
LD HL,0000H
Let Register Pair HL equal 0000H.
0ECAH
LD B,L
Copy the contents of Register L (which is now 00H thanks to the prior instruction) into Register B.
0ECBH
RST 28H
Call RST 28H to move DE to point to the next non-space character, with Register A holding that character.
0ECCH
GOSUB to 008CH to check to see if the character pointed to by Register Pair DE is, or is not, a digit. Returns Register A contaning the digit, or the CARRY FLAG set otherwise.
0ECFH
If the C FLAG (Carry) has been set then there was no digit to be found so JUMP to the next routine set at 0EDAH.
0ED1H
INC B
If we are here, then DE is pointing to a digit. INCrement the value stored in Register B by 1.
0ED2H
GOSUB to 015EH to to accumulate the digit by multiplying the accumulator by 10 and then adding in A to the newly vacant one’s spot. Routine will return a NZ SET if an overflow occurs from the accumulation.
0ED5H
So long as no overlow occurred in that CALL (i.e., the NC FLAG has been set), LOOP back a couple of instructions to 0ECCH and keep processing.
0ED7H
If we are here, then we got an overflow, so display the “HOW?” error via a JUMP to 01A2H.

0EDAH – Continuation of the above parsing routine. On entry the REGULAR REGISTER SET is active.

0EDAH
EXX
Set the ALTERNATE REGISTER SET to active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0EDBH
PUSH HL
Save the contents of Register Pair HL’ to the top of the stack.
0EDCH
LD A,C
Copy the contents of Register C into Register A.
0EDDH
BIT 7,H
Test Bit Number 7 of Register H. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0EDFH
EXX
Set the REGULAR REGISTER SET to active and EXchange the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0EE0H
POP HL
Put the value held at the top of the STACK (which was HL’) into Register Pair HL.
0EE1H
If the NZ FLAG (Not Zero) has been set, JUMP to 0ED7H which JUMPs to 01A2 to display the “HOW?” error.
0EE3H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0EE4H
If the NZ FLAG (Not Zero) has been set, JUMP to 0ED7H which JUMPs to 01A2 to display the “HOW?” error.
0EE6H
LD A,B
Copy the contents of Register B into Register A.
0EE7H
AND A
Reset the CARRY FLAG and set the Z/NZ FLAGS based on Register A via an AND A (which masks the value of Register A against itself).
0EE8H
RET
RETurn to the caller.

0EE9H – Entry point for the CLOAD Command.

0EE9H
GOSUB to 0EF4H which turns on the cassette motor, reads the data header and then read the number of bytes needed to fill RAM based on the block addresses. Routine exits with Register A holding the CRC and flags set based on Register A; DE is preserved.
0EECH
LD (406CH),HL
Store the value held in Register Pair HL into memory location 406CH (which points to the top of used RAM).
0EEFH
If the NZ FLAG (Not Zero) has been set, JUMP to 0EC1H.
0EF1H
Enter they READY command line routine via a JUMP to 01C9H.


0EF4H – CASSETTE – Turn on the cassette motor, read the data header and then read the number of bytes needed to fill RAM based on the block addresses. Routine exits with Register A holding the CRC and flags set based on Register A; DE is preserved.

0EF4H
GOSUB to 0FE9H to turn on the cassette motor.
0EF7H
PUSH DE
Save the contents of Register Pair DE to the top of the stack since this routine will use it. DE is restored once the appropriate number of bytes have been read from the cassette, at 0F37H.
0EF8H
XOR A
Set Register A to ZERO and clear all Flags.
0EF9H
GOSUB to 0F81H to READ a BYTE from the Cassette Port.
0EFCH
CP A5H
Compare the value held in Register A against A5H, which is the SYNC byte. Results: If Register A equals A5H, the Z FLAG is set; otherwise the NZ FLAG is set.
0EFEH
If the NZ FLAG (Not Zero) has been set, LOOP BACK 2 instructions to 0EF9H to read another byte from the cassette port.
0F00H
LD A,2AH
Let Register A equal 2AH (ASCII: *).
0F02H
LD (3C00H),A
Store the value held in Register A into memory location 3C00H.
NOTE: 3C00H is the location of the first character on the display.
0F05H
LD (3C01H),A
Store the value held in Register A into memory location 3C01H.

When bytes are written, the header including the A5H is written, then Registers H, L, D, and E; so the below loads E, D, L, and H from the cassette. The bytes then get loaded into RAM starting at the memory location held in Register Pair DE.

0F08H
GOSUB to 0FA1H to read a BYTE to the Cassette Port.
0F0BH
LD D,A
Copy the byte held in Register A into Register D.
0F0CH
GOSUB to 0FA1H to read a BYTE to the Cassette Port.
0F0FH
LD E,A
Copy the byte held in Register A into Register E.
0F10H
GOSUB to 0FA1H to read a BYTE to the Cassette Port.
0F13H
LD H,A
Copy the byte held in Register A into Register H.
0F14H
GOSUB to 0FA1H to read a BYTE to the Cassette Port.
0F17H
LD L,A
Copy the byte held in Register A into Register L.
0F18H
LD C,00H
In preparation for Register C accumulating the CRC, let Register C equal 00H.
0F1AH
GOSUB to 0FA1H to read a BYTE to the Cassette Port.
0F1DH
LD (DE),A
Store the value held in Register A into the memory location pointed to by Register Pair DE.
0F1EH
INC DE
INCrement the RAM pointer (stored in Register Pair DE) by 1.
0F1FH
CP 0DH
Compare the value held in Register A against 0DH (ASCII: CARRIAGE RETURN). If Register A equals CARRIAGE RETURN, the Z FLAG is set; otherwise the NZ FLAG is set.
0F21H
If we did not read a CARRIAGE RETURN then the the NZ FLAG will have been set, so JUMP to 0F2DH to add the character to the CRC and continue reading, otherwise continue by flipping the “” and ” ” and THEN adding the character to the CRC.
0F23H
PUSH AF
Preserve the contents of Register Pair AF to the top of the stack for the next 3 instructions which use Register A to flip the “**” display.
0F24H
LD A,(3C01H)
Fetch the value held in the 2nd byte of screen memory location (3C01H) and store it into Register A.
0F27H
XOR 0AH
eXclusive OR 0AH (0000 1010) against Register A (which is either 00101010 if the “” is on or 00100000 if there is a space instead). The results are stored in Register A.
0F29H
LD (3C01H),A
Store the “” or ” ” held in Register A into the 2nd byte of screen memory location (3C01H).
0F2CH
POP AF
Restore Register A from the stack.
0F2DH
ADD A,C
Add the currentl read byte to Register C for purposes of tracking the CRC.
0F2EH
LD C,A
Copy the updated CRC from Register A back into Register C.
0F2FH
RST 20H
Compare HL (which is the END of the block being read) and DE (which is the current RAM location in the block being read) via a call to RST 20H. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
0F30H
If the NC FLAG (No Carry) has been set then we have not yet reached the END pointer, so LOOP BACK to 0F1AH to continue reading bytes.

If we are here, then we have finished reading all the bytes which were to be placed within the read/designated RAM block of DE to HL.

0F32H
PUSH HL
Temporarily save HL to the stack, for purposes of the next instruction..
0F33H
GOSUB to 0FE4H to turn off the cassette motor.
0F36H
POP HL
Restore Register Pair HL from the stack.
0F37H
POP DE
Put the value held at the top of the STACK into Register Pair DE.
0F38H
LD A,C
Copy the CRC value (held in Register C) into Register A.
0F39H
AND A
Set the flags based on Register A via an AND A.
0F3AH
RET
RETurn to the caller.

0F3BH – Entry Point for the “CSAVE” Routine.

0F3BH
GOSUB to 0FE9H to turn on the cassette motor.
0F3EH
LD HL,4200H
Let Register Pair HL equal 4200H, which is the top of system stack pointer in Level 1.
0F41H
LD DE,(406CH)
Fetch the pointer to top of used memory from memory location 406CH and store it into Register Pair DE.
0F45H
GOSUB to 0F4BH to write the header and then all data from HL to DE.
0F48H
Enter they READY command line routine via a JUMP to 01C9H.

0F4BH – CASSETTE – Write the cassette header (128 0’s and then an A5 sync byte) and then H, L, D, E, then all the bytes from HL to DE, and then the checksum.

0F4BH
LD A,80H
Let Register A equal 80H (Decimal: 128) so as to prepare to write a header of 128 0’s.
0F4DH
PUSH BC
Save the contents of Register Pair BC to the top of the stack.
0F4EH
EX AF,AF’
Save the 80H iteration counter because EVERYTHING needs to use Register A by EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0F4FH
XOR A
Set Register A to ZERO and clear all Flags.
0F50H
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F53H
EX AF,AF’
Restore the 80H iteration counter because EVERYTHING needs to use Register A by EXchanging BACK the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0F54H
DEC A
DECrement the number of 0 bytes to write (tracked by Register A) by 1.
0F55H
If the NZ FLAG (Not Zero) has been set then we still have more 0’s to write, so LOOP back to 0F4EH.

The 80 “0” bytes have now been written, time to write the SYNC byte.

0F57H
LD A,A5H
Let Register A equal A5H which is the SYNC byte.
0F59H
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.

Next send H, L, D, and E to the Cassette.

0F5CH
LD A,H
Copy the contents of Register H into Register A.
0F5DH
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F60H
LD A,L
Copy the contents of Register L into Register A.
0F61H
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F64H
POP BC
Put the value held at the top of the STACK into Register Pair BC.
0F65H
LD A,D
Copy the contents of Register D into Register A.
0F66H
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F69H
LD A,E
Copy the contents of Register E into Register A.
0F6AH
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.

Next, send all the bytes from HL to DE to the Cassette.

0F6DH
LD C,00H
Let Register C equal 00H.
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair (HL) and store it into Register A.
0F70H
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F73H
INC HL
INCrement the value stored in Register Pair HL by 1.
0F74H
RST 20H
Compare HL and DE. Results: NZ means no match, Z means match, and if H=D but L < E, then the C flag will be set.
0F75H
If HL hasn’t reached DE yet then the NZ FLAG (Not Zero) will have been set, so LOOP back to 0F6FH to keep writing out the byte at the current (HL) memory location.

If we are here, then all of that has been written out.

0F77H
LD A,C
Copy the contents of Register C into Register A.
0F78H
NEG
Negate the contents of Register A (which is the same as -A).
0F7AH
GOSUB to 0FA9H to write the BYTE held in Register A to the Cassette Port.
0F7DH
GOSUB to 0FE4H to turn off the Cassette Motor.
0F80H
RET
RETurn to the caller.

0F81H – CASSETTE – READ a BYTE to the Cassette Port. Routine reads a bit and then rotates it into Register A.

0F81H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.

Preserve Register A so we can do all the following operations without destroying it.

0F82H
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0F83H
Fetch a byte from the cassette port.
0F85H
RLA
Rotate the bits of Register A left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and the previous contents of the carry flag are copied to bit 0.
0F86H
If the NC FLAG (No Carry) has been set, meaning that the current bit being examined is a ZERO, JUMP back two instructions to 0F83H to get the next bit.

If we’re here, then the bit was a 1.

0F88H
LD B,7CH
Let Register B equal 7CH (Decimal: 124) for a delay loop of 124 iterations.
0F8AH
Delay by LOOPing back to this very instruction, 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.
0F8CH
GOSUB to 0FF0H to check the state of cassette motor/input bit.
0F8FH
LD B,F8H
Let Register B equal F8H (Decimal: 248) for a delay loop of 248 iterations.
0F91H
Delay by LOOPing back to this very instruction, 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.
0F93H
Fetch a byte from the cassette port.
0F95H
LD B,A
Copy the fetched byte (held in Register A) into Register B since we are about to swap A and A’.

Now let’s restore the original Register A and proceed.

0F96H
EX AF,AF’
EXchange the value stored in Register Pair AF’ with the value stored in Register Pair AF.
0F97H
RL B
Rotate the bits of Register B left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and the previous contents of the carry flag are copied to bit 0.
0F99H
RLA
Rotate the bits of Register A left (i.e., lower bit moves higher) one bit position. The contents of bit 7 are copied to the CARRY FLAG and the previous contents of the carry flag are copied to bit 0.
0F9AH
PUSH AF
Save the contents of Register Pair AF to the top of the stack so we don’t lose A on the next command.
0F9BH
GOSUB to 0FF0H to check the state of cassette motor/input bit.
0F9EH
POP AF
Restore Register AF from the STACK.
0F9FH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’.
Note: AF is not handled via EXX.
0FA0H
RET
RETurn to the caller.

0FA1H – CASSETTE – Read a BYTE to the Cassette Port by calling 0F81H eight times.

0FA1H
LD B,08H
Let Register B equal 08H (Decimal: 8) for a loop to process the 8 bits in a byte.
0FA3H
GOSUB to 0F81H to READ a BYTE from the Cassette Port.
0FA6H
LOOP back to the prior instruction, 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.
0FA8H
RET
RETurn to the caller.

0FA9H – CASSETTE – Write a BYTE to the Cassette Port. On entry Register A should hold the byte to output and Register C should be tracking the CRC.

0FA9H
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Note: AF is not handled via EXX.
0FAAH
LD C,08H
Let Register C equal 08H (Decimal: 8) for a loop to process the 8 bits in a byte.
0FACH
LD D,A
Copy the byte to be output (held in Register A) into Register D.
0FADH
GOSUB to 0FC5H to write a bit to the cassette port.
0FB0H
RLC D
Since this routine is using the bit in the CARRY FLAG to be the one to output, rotate Register D left one bit position, with bit 7 being copied to both the CARRY FLAG and bit 0.
0FB2H
If the NC FLAG (No Carry) has been set, then the bit to be output is a zero. We don’t output a 0, we just delay and let the tape run, so do that via a JUMP to 0FBFH.
0FB4H
GOSUB to 0FC5H to write a bit to the cassette port.
0FB7H
DEC C
DECrement the value stored in Register C by 1 since we just wrote one of the 8 bits.
0FB8H
If the counter in Register C has not yet hit ZERO, LOOP back to 0FADH to keep processing the bits in the byte.
0FBAH
LD A,D
Copy the contents of Register D into Register A, thus restoring the original byte to output into Register A.
0FBBH
EXX
EXchanges the 16-bit contents of BC, DE, and HL with BC’, DE’, and HL’. Among other things, this restores the CRC count to Register C.
Note: AF is not handled via EXX.
0FBCH
ADD A,C
LET Register A = Register A + Register C so as to update the CRC counter held in Register C.
0FBDH
LD C,A
Copy the updated CRC count from Register A into Register C.
0FBEH
RET
RETurn to the caller.

0FBFH – CASSETTE – Delay Loop of 256 (which represents writing a 0 bit to the moving cassette).

0FBFH
LD B,00H
Let Register B equal 00H, which will mean a DJNZ loop of 256 iterations.
0FC1H
LOOP back to this very instruction, 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.
0FC3H
JUMP to 0FB7H.

0FC5H – CASSETTE – Write a BIT to the Cassette Port.

0FC5H
LD HL,FC01H
Let Register Pair HL equal FC01H, so Register H is 1111 1100 and Register L is 0000 0001.
0FC8H
GOSUB to 0FF3H which will fetch a byte from the cassette port status cache (stored at 4090H), mask it against 1111 1100 (so its values can only be FC-252 to FF-255), OR that against 0000 0001 (so its values can only be FD-253 or FF-255), send that to the cassette port (Port FFH), test Bit 2, and RETurn.
0FCBH
LD B,0AH
Let Register B equal 0AH (Decimal: 10), for a DJNZ delay loop of 10.
0FCDH
LOOP back to this very instruction 10 times, 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.
0FCFH
LD HL,FC02H
Let Register Pair HL equal FC02H, so Register H is 1111 1100 and Register L is 0000 0010.
0FD2H
GOSUB to 0FF3H which will fetch a byte from the cassette port status cache (stored at 4090H), mask it against 1111 1100 (so its values can only be FC-252 to FF-255), OR that against 0000 0010 (so its values can only be FE-254 or FF-255), send that to the cassette port (Port FFH), test Bit 2, and RETurn.
0FD5H
LD B,0AH
Let Register B equal 0AH (Decimal: 10), for a DJNZ delay loop of 10.
0FD7H
LOOP back to this very instruction 10 times, 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.
0FD9H
LD HL,FC00H
Let Register Pair HL equal FC00H, so Register H is 1111 1100 and Register L is 0000 0000.
0FDCH
GOSUB to 0FF3H which will fetch a byte from the cassette port status cache (stored at 4090H), mask it against 1111 1100 (so its values can only be FC-252 to FF-255), OR that against 0000 0000 (leaving it unchanged), send that to the cassette port (Port FFH), test Bit 2, and RETurn.
0FDFH
LD B,DAH
Let Register B equal DAH (Decimal: 218).
0FE1H
LOOP back to this very instruction 218 times, 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.
0FE3H
RET
RETurn to the caller.

0FE4H – CASSETTE – Turn off the cassette motor.

0FE4H
LD HL,FB00H
Let Register Pair HL equal FB00H. The FBH will be ANDed against the cassette port status byte and the 00H will be OR’d against the result. The result will be sent to the CASSETTE PORT of FFH.
0FE7H
JUMP to 0FF3H.

0FE9H – CASSETTE – Turn on the cassette motor.

0FE9H
LD HL,FF04H
Let Register Pair HL equal FF04H. The FFH will be ANDed against the cassette port status byte and the 04H will be OR’d against the result. The result will be sent to the CASSETTE PORT of FFH.
0FECH
GOSUB to 0FF3H.
0FEFH
RET
RETurn to the caller.

0FF0H – CASSETTE – Check to see if the cassette motor is running.

0FF0H
LD HL,FF00H
Let Register Pair HL equal FF00H.
0FF3H
LD A,(4090H)
Fetch the cassette port status cache byte (held in memory location 4090H) and store it into Register A.
0FF6H
AND H
MASK the value of Register A against the value held in Register H.
0FF7H
OR L
OR Register L against Register A. The results are stored in Register A.
0FF8H
Send the value held in Register A to the cassette port of 0FFH.
0FFAH
LD (4090H),A
Store the value held in Register A into the cassett port status cache (held in memory location 4090H).
0FFDH
BIT 2,A
Test Bit Number 2 of Register A. Z FLAG will be set if that bit is 0, and NZ FLAG will be set if that bit is 1.
0FFFH
RET
RETurn to the caller.