These 3 pages are a breakdown of the Model I ROM, with comments to help you understand what is going on. The two thing to keep in mind while reading this disassembly are:


  • The ROM had to be one big long program starting from 0000H and ending at 2FFFH and everything it does had to be wedged into that single long block of code. This means that jumps to other locations are a necessity because once a particular portion of the ROM executes, if it was allowed to keep going, unintended portions would also execute. With this, there is a LOT of jumping away.
  • There are only so many variables and only so many Z-80 instructions. There is no Z-80 instruction, for example, LD BC,SP. With this, there is a huge amount of variable swapping. I would dare say that whatever part of the ROM isn’t jumping, is just swapping variables around. The ROM would be a fraction of the size if there were more variables and more Z-80 instructions.

0000H-0004H – POWER UP ROUTINE – “DOSCLD” or “$RESET”

0000H
DI
Disables the interrupts and turns off clock
0001H
XOR A
Clears the A register and status
0002H-0004H
Go to the Level II BASIC initialization routine.
0005H-0007H
Go to RST 0008H code via 4000H.
0008H
“SYNTAX”
(RST 008H)
Jumps to 4000H. 4000H passes control to 1C96H. This routine is used for scanning strings. It compares the character pointed to by the HL register pair with the character pointed to by the return address on the top of the stack (Note that a RST instruction is in effect a CALL and places a return address on the stack) formula: (HL)=((SP))? If they are not equal an SN ERROR will result; if they are equal then the return address on the stack will be incremented to bypass the test character and control will be passed to RST 10H logic. RST 8H is used to look for expected characters in a string and then return with (HL) pointing to the next non-blank character. (see RST l0H) (BC and DE registers unaffected.). This routine can be used by CALLing 1C96H or RST 8H.
This is the COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call. If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the Aregister and HL incremented by one. If the two characters do not match, a syntax error message is given and control returns to the Input Phase).

000BH-000FH – DISK ROUTINE – “WHERE”

000BH
POP HL
Get the address from the stack and put it in register pair HL.
000CH
JP (HL)
Jump to the location of the address in register pair HL.
000DH-000FH
“DBOOT”
Jump to the disk load and run sector routine at 069FH.
0010H
(RST 010H)
Jumps to 1D78H (RST 0010H vector) through 4003H.

This routine INCrements HL and tests the characters pointed to by the HL register pair. It will bypass any spaces and CHAR’S 9 and 10 (shifted left and down arrows respectively). Upon return from this routine HL will point to the next non-blank character; the carry flag will be SET if HL is pointing to a numeric ASCII character and the Z flag will be SET if the character pointed to happens to be zero (ASCII 30H) or 3AH (“:”). (BC and DE registers are unaffected) This routine can be used by CALLing 1D78H or RST l0H.

0013H-0017H – KEYBOARD ROUTINE

  • This routine Inputs a byte from an input device. When calling, DE = starting address of DCB of device. On exit, A = byte received from device, Z set if device ready. Uses AF.
0013H
“INBYT”
PUSH BC
Save the value in register pair BC on the stack.
0014H-0015H
LD B, 01H
Load register B with the device type entry code of 01H.
0016H-0017H
Jump to the Level II BASIC driver entry routine at 0046H.
0018H
“RST18”
(RST 018H)
Jumps to lC90H through 4006H. This routine can be called by using RST 18H or CALL lC90H. It compares two 16 bit values in HL and DE and sets the S and Z flags accordingly (they are set in the same way as for a normal 8 bit CP). All registers are unchanged except for A.
This is the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).

001BH-001EH – DRIVER ENTRY ROUTINE – Part 1 – “PUT”

  • This routine outputs a byte to a device. When calling, A = output byte, DE = starting address of DCB of device. On exit, Z set if device ready. Uses AF.
001BH
“OUTBYT”
PUSH BC
Save the value in register pair BC on the stack.
001CH-001DH
LD B,02H
Load register B with the device type entry code of 02H.
001EH-001FH
Jump to the Level II BASIC driver entry routine.
0020H
(RST 020H)
This routine jumps to 25D9H through 4009H. If the NTF=8 then C=RESET or else C=SET, Z flag will be SET if NTF=3 (S flag is valid also.). After execution of RST 20H or CALL 25D9H, A will contain the value NTF-3, all other registers are unchanged.
Returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH). Integer = NZ/C/M/E and A is -1; String = Z/C/P/E and A is 0; Single Precision = NZ/C/P/O and A is 1; and Double Precision is NZ/NC/P/E and A is 5. This CALL is usually made to determine the type of the current value in REG 1. It should be used with caution, however since the mode flag and REG 1 can get out of phase particularly if some of the CALLS described here are used to load REG l.

0023H-0027H – DISK ROUTINE

0023H
“CTLBYT”
PUSH BC
Save the value in register pair BC on the stack.
0024H-0025H
LD B,04H
Load register B with the device type entry code of 04H.
0026H-0027H
Jump to the Level II BASIC driver entry routine at 0046H.
0028H
(RST 028H)
Jumps to 400CH which contains C9H (RET) under Level II BASIC. This vector is only used by Disk BASIC. It is called by the BREAK key routine, and can be used to intercept the BREAK key logic.
This is the DOS FUNCTION CALL routine at RST 28 (which passes request code in A-register to DOS for processing. Returns for non-disk system. For disk systems, the A register must contain a legitimate DOS function code. If the code is positive, the CALL is ignored and control returns to the caller. Note that the DOS routine discards the return address stored on the stack by the RST instruction. After processing control will be returned to the previous address on the stack).

002BH-002FH – KEYBOARD ROUTINE – “KBDSCN” or “$KBCHAR”

  • Keyboard scanning routine. After CALLing 2BH, the A register will contain the ASCII value for the key that was pressed. The A register will contain 00H if no key was pressed at the time. Apart from the AF register pair the DE register pair is also used by the routine.
    This Routine Performs an instantaneous scan of the keyboard. If no key is depressed control is returned to the caller with the Aregister and status register set to zero. If any key (except the BREAK key) is active the ASCII value for that character is returned in the A-register. If the BREAK key is active, a RST 28 with a system request code of 01 is executed. The RST instruction results in a JUMP to the DOS Exit 400C. On non-disk systems the Exit returns, on disk systems control is passed to SYSO where the request code will be inspected and ignored, because system request codes must have bit 8 on. After inspection of the code, control is returned to the caller of 002B. Characters detected at 002B are not displayed. Uses DE, status, and A register
  • This routine loads DE with address of keyboard DCB and scans keyboard. On exit, if no key pressed the A register will contain a zero byte, else the character input from the keyboard wi 11 be returned in A. Character is not echoed to video. Uses AF,DE (to save DE use routine at 03588).
002BH-002DH
“KBSCAN”
LD DE,4015H
Load register pair DE with the starting address of the keyboard device control block.
Note: 4015H holds Keyboard DCB – Device type.
002EH-002FH
Jump to the Level II BASIC driver entry routine.
0030H
(RST 030H)
This location passes control to 400FH which contains a RET (C9H) under Level II. This location is only used by a Disk system.
This is the LOAD DEBUG routine, and loads the DEBUG program and transfers control to it. When DEBUG processing is complete, control is returned to the orginal caller. For non-disk systems control is returned immediately.

0033H-0037H – VIDEO ROUTINE – “$VDCHAR”

  • Character print routine. A CALL 33H will print a character at the current cursor position. The A register must contain the ASCII code for the character or graphics figure that is to be printed before CALLing this routine. The DE register pair is used by the routine.
    A call to 0033H displays the character in the A-register on the video. Control codes are permitted. All registers are used.
0033H-0035H
“VDCHAR”
LD DE,401DH
Load register pair DE with the starting address of the video display device control block.
Note: 401DH holds Video DCB – Device type.
0036H-0037H
Jump to the Level II BASIC driver entry routine at 001BH.
0038H
(RST 038H)
This location will pass control to 4012H. This location is only used by a Disk system.
This is the INTERRUPT ENTRY POINT routine at RST 38H which is the system entry point for all interrupts. It contains a jump to a section of code in the Communications Region designed to field interrupts. That section of code consists of a DI (disables further interrupts) followed by a RET (returns to the point of interrupt) for non-disk systems, or a jump to an interrupt processor in SYSO if it is a DOS system. For DOS systems the interrupt handler consists of a task scheduler, where the exact cause of the interrupt is determined (usually a clock interrupt) and the next task from the task control block is executed. After task completion, control returns to the point of interrupt.

003BH-003FH – PRINTER ROUTINE – “PRCHAR” or “$PRCHAR”

  • Character LPRINT routine. Same as 33H but outputs to line printer. (Contents of A register will be printed).
  • A call to 003BH causes the character contained in the C-register to be sent to the printer. A line count is maintained by the driver in the DCB. When a full page has been printed (66 lines), the line count is reset and the status register returned to the caller is set to zero. Control codes recognized by the printer driver are:
    • 00=Returns the printer status in the upper two bits of the A-register and sets the status as zero if not busy, and non-zero if busy.
    • OB=Unconditionally skips to the top of the next page.
    • OC=Resets the line count (DCB 4) and compares its previous value to the lines per page (DCB 3) value. If the line count was zero, no action is taken. If the line count was non-zero then a skip to the top form is performed.
    • OD=Line terminator. Causes line count to be incremented and tested for full page. Usually causes the printer to begin printing.
003BH-003DH
“LPTBYT”
LD DE,4025H
Load register pair DE with the starting address of the printer device control block.
Note: 4025H holds Printer DCB – Device type.
003EH-003FH
Jump to the Level II BASIC printer driver entry routine.

0040H-0042H – INPUT ROUTINE – “KBLINE”

0040H-0042H
Jump to the “WAIT FOR NEXT LINE” keyboard input routine at 05D9 (which takes keyboard entry until a carriage return, a break, or buffer overrun occurs).
0043H
RET
0044H
NOP
0045H
NOP

0046H-0048H – DRIVER ENTRY ROUTINE – Part 2

0046H-0048H
“DRIVRV”
Jump to the Level II BASIC keyboard driver entry routine.
0049H-004BH
“GETCHR”
Go scan the keyboard and return with the key pressed, if any, in register A.
A CALL to this memory location returns as soon as any key on keyboard is pressed. ASCII value for character entered is returned in A register. Uses A, status, and DE registers.

0049H-004FH – KEYBOARD ROUTINE – “$KBWAIT”

  • A call to 0049H returns as soon as any key on keyboard is pressed. ASCII value for character entered is returned in A register.
0049H
Character input routine. This routine is the same as 2BH (=Scan the Keyboard routine) except that it will not return until a key is pressed.
004CH
OR A
Check the value in register A to see if a key was pressed.
004DH
RET NZ
Return if a key was pressed.
004EH-004FH
Loop until a key is pressed.

0050H-005FH – KEYBOARD LOOKUP TABLE

  • This is a table of control characters used by BASIC.
0050H
“KBTBL”
0DH
ENTER (ODH)
0051H
0DH
Shift ENTER (ODH)
0052H
1FH
CLEAR (lFH)
0053H
1FH
Shift CLEAR (lFH)
0054H
01H
BREAK (01H)
0055H
01H
Shift BREAK (01H)
0056H
5BH
Up Arrow (5BH)
0057H
1BH
Shift Up Arrow (lBH)
0058H
0AH
Down Arrow (OAH)
0059H
1AH
ROM before v1.3 – Shift Down Arrow (lAH); ROM v1.3 – NOP to permit Shift-Down-Arrow to act as a control key.
005AH
08H
Left Arrow (08H)
005BH
18H
Shift Left Arrow (18H)
005CH
09H
Right Arrow (09H)
005DH
19H
Shift Right Arrow (19H)
005EH
20H
SPACE (20H)
005FH
20H
Shift SPACE (20H)

0060H-0065H – DELAY ROUTINE – “$DELAY”

  • This is a delay loop. The BC register pair is used as the loop counter. The duration of the delay, in microseconds, is the value of BC times 14.65. Register A is used.
0060H
DEC BC
Decrement the counter in register pair BC
0061H
LD A,B
Load register A with the counter’s MSB in register B.
0062H
OR C
Combine with the LSB in register C.
0063H-0064H
Loop until the counter in register pair BC is equal to zero.
0065H
RET
Return.

0066H-0068H
“NMI”
LD SP,0600H
Set the stack pointer to 0600H.
This is the location to which program control jumps when the RESET button is pressed (Non Maskable Interrupt address).

0069H-0074H – NMI INTERRUPT ROUTINE (RESET) – “$INITIO”

  • This part of the initialization routine checks to see if a disk drive is connected. If so, it will jump to 00H. (This is why the reset button will reinitialize DOS.)
0069H-006BH
LD A,(37ECH)
Load register A with the disk controller status (stored in 37ECH).
006CH
INC A
Increment the disk controller status in register A.
006DH-006EH
CP 02H
Check the value in register A to see if a disk is present. It is usually FFH if there is no expansion interface operating.
006FH-0071H
If a disk is present, go to the Level II BASIC power up routine.
0072H-0074H
Since we are without disk drives at this, this would be for power on or reset … so jump to the Level II BASIC READY routine at 06CCH.

0075H-0104H – INITIALIZATION ROUTINE

  • This is part of the Level II initialization procedure. It moves a block of memory from 18F7H to l9lEH up to 4080H to 40A7H. (reserved RAM. area).
    Note: 4080H-408DH is a division support routine.
0075H-0077H
“CSTLII”
LD DE,4080H
Load register pair DE with the ROM storage location of the Level II BASIC division routine.
Note: 4080H-408DH is a division support routine.
0078H-007AH
LD HL,18F7H
Load register pair HL with the RAM storage location of the Level II BASIC division routine.
007BH-007DH
LD BC,0027H
Load register pair BC with the length of the Level II BASIC division routine (39 bytes).
007EH-007FH
LDIR
Move the Level II BASIC division routine in ROM (18F7H-191DH) to RAM (4080H-40A6H).
0080H-0082H
LD HL,41E5H
Continue with the communication region initialization by loading register pair HL with an RAM memory pointer).
0083H-0084H
LD (HL),3AH
Save a 3AH (which is 58) at the location of the memory pointer in register pair HL (which is 41E5H).
0085H
INC HL
Increment the memory pointer in register pair HL from 41E5H to 41E6H.
0086H
LD (HL),B
Zero out 41E6H (the location of the memory pointer in register pair HL).
0087H
INC HL
Increment the memory pointer in register pair HL from 41E6H to 41E7H.
0088H-0089H
LD (HL),2CH
Save a 2CH at 41E7H (the location of the memory pointer in register pair HL).
008AH
INC HL
Increment the memory pointer in register pair HL from 41E7H to 41E8H.
008BH-008DH
LD (40A7H),HL
This loads the input buffer pointer (held at 40A7H) with the kayboard buffer location address of 41E8H. (40A7H is the I/O buffer pointer and can be changed to relocate the buffer.). Save the value in register pair HL as the starting address of the keyboard input buffer area.
Note: 40A7H-40A8H holds the input Buffer pointer.
008EH-0090H
LD DE,012DH
In prepartaion for a jump, load register pair DE with the starting address of the ?L3 ERROR routine.

0091H-0104H – The rest of the initialization routine. Asks MEMORY SIZE ?, sets the memory pointers accordingly and prints RADIO SHACK LEVEL II BASIC , then it jumps to 1A19H which is the entry point for the BASIC command mode.

0091H-0092H
LD B,1CH
Load register B with the number of times (=28) to save the jump to the ?L3 ERROR routine.
0093H-0095H
LD HL,4152H
Load register pair HL with the starting address of the Disk Basic links (which is 4152H) in preparation for generating an error if disk basic commands are attempted.
Note: 4152H-41A3H holds Disk Basic links.
0096H-0097H
LD (HL),C3H
Save a C3H to 4152H (the location of the memory pointer in register pair HL).
0098H
INC HL
Increment the memory pointer in register pair HL from 4152H to 4153H.
0099H
LD (HL),E
Save the LSB of the ?L3 ERROR routine’s starting address in register E (i.e., a 2DH) to 4153H (i.e., the location of the memory pointer in register pair HL).
009AH
INC HL
Increment the memory pointer in register pair HL from 4153H to 4154H.
009BH
LD (HL),D
Save the MSB of the ?L3 ERROR routine’s starting address in register D (i.e., a 01H) to 4154H (i.e., the location of the memory pointer in register pair HL).
009CH
INC HL
Increment the memory pointer in register pair HL from 4154H to 4155H.
009DH-009EH
Do this 28 times (=84 locations) until all of the Disk Basic links have been set to jump to the ?L3 ERROR routine.
009FH-00A0H
LD B,15H
Load register B with the number of DOS links to set to RETs.
00A1H-00A2H
LD (HL),C9H
Save a C9H to the location of the memory pointer in register pair HL fill it with RET instructions (C9H is RET).
00A3H
INC HL
Increment the memory pointer in register pair HL.
00A4H
INC HL
Increment the memory pointer in register pair HL.
00A5H
INC HL
Increment the memory pointer in register pair HL.
00A6H-00A7H
Loop from 4156H until all of the DOS links have been set to RETs.

001BH-001FH – VIDEO AND PRINTER ROUTINE

00A8H-00AAH
LD HL,42E8H
Load register pair HL with the starting address of user RAM (which is 42E8H).
00ABH
LD (HL),B
Zero 42E8H (i.e., the location of the memory pointer in register pair HL).
00ACH-00AEH
LD SP,41F8H
Set the current stack pointer to 41F8H (which is 16888).
00AFH-00B1H
Go initialize the Level II BASIC variables and pointers.
00B2H-00B4H
Call the CLEAR SCREEN routine at 01C9 (which clears the screen, changes to 64 characters, and homes the screen).
00B5H-00B7H
LD HL,0105H
Load register pair HL with the starting address of the MEMORY SIZE? message.
00B8H-00BAH
We need to display the MEMORY SIZE? prompt so we must call the WRITE MESSAGE routine at 28A7H.
NOTE:
  • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
  • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
  • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
00BBH-00BDH
Print a “?” and get input from the keyboard.
00BEH-00BFH
If the BREAK key was pressed, ask again.
00C0H
RST 10H
Since we now need to increment the input buffer pointer until it points to the first character of the input, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
00C1H
OR A
Set the status flag based on if the character at the location of the input buffer pointer in register A is an end of the input character (00H).
00C2H-00C3H
Jump forward to 00D6H if there was a response to the MEMORY SIZE? question.
00C4H-00C6H
“MEMSIZ”
LD HL,434CH
If just an ENTER was hit, need to figure it out dynamically, so load register pair HL with the starting address for the memory size check.
00C7H
INC HL
We are going to start testing RAM at 17229 (i.e., 434DH) toward 65535, so increment the memory pointer in register pair HL.
00C8H
LD A,H
Load register A with the MSB of the current memory pointer in register H.
00C9H
OR L
Combine the LSB of the current memory pointer in register L with the MSB of the current memory pointer in register A.
00CAH-00CBH
Since we need to scan all the way up to 65535, jump to 00E7H (which drops the memory size pointer by 1) if the current memory pointer in register pair HL is equal to zero.
00CCH
LD A,(HL)
Load register A with the value at the location of the current memory pointer in register pair HL.
00CDH
LD B,A
Load register B with the value in register A to preserve it, as A is about to get used.
00CEH
CPL
Complement the value in register A (which is basically a test pattern).
00CFH
LD (HL),A
Save the test pattern in register A to the location of the current memory pointer in register pair HL.
00D0H
CP (HL)
Check to see if the value at the location of the memory pointer in register pair HL is the same as the value in register A.
00D1H
LD (HL),B
Put back the original memory value (which was saved in B) to the location of the memory pointed in register pair HL.
00D2H-00D3H
If the address exists, loop back to 00C7H until the end of memory is found.
00D4H-00D5H
If the address didn’t exist, jump to 00E7H (which goes to he next address and tries again).
00D6H-00D8H
Here the MEMORY SIZE? answer is in HL so call the ASCII TO INTEGER routine at 1E5AH.
NOTE:
  • The routine at 1E5A converts the ASCII string pointed to by HL to an integer deposited into DE. If the routine finds a non-numerica character, the conversion is stopped
00D9H
OR A
Check to see if register A is equal to zero.
00DAH-00DCH
Display a ?SN ERROR if register A is not equal to zero.
00DDH
EX DE,HL
Load register pair HL with the MEMORY SIZE?, which is curently stored in register pair DE.
00DEH
DEC HL
Decrement the MEMORY SIZE? in register pair HL.
00DFH-00E0H
LD A,8FH
Load register A with a memory test value.
00E1H
LD B,(HL)
Load register B with the value at the location of the MEMORY SIZE? pointer in register pair HL (to save the data thats there).
00E2H
LD (HL),A
Put the test pattern (in A which is 8FH) into that the location of the MEMORY SIZE? pointer in register pair HL.
00E3H
CP (HL)
Check to see if the value in the memory location set in HL matches the test pattern in A.
00E4H
LD (HL),B
Restore the old memory contents back.
00E5H-00E6H
At this point, the specified memory size was not present, so we have to ask again by jumping to 00B5H.
00E7H
DEC HL
Decrement the memory size pointer in register pair HL, so it is the amount of memory – 2.
00E8H-00EAH
LD DE,4414H
Load register pair DE with the minimum MEMORY SIZE? response (which is 17428).
00EBH
RST 18H
Now we need to check to see if the MEMORY SIZE? pointer (in HL) is less than the minimum MEMORY SIZE? response (in DE), so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
00ECH-00EEH
If C is set, then the mount of actual memory (in HL) is less than the minimum memory required (in DE), so we have to go to the Level II BASIC error routine and display an OM ERROR.
00EFH-00F1H
LD DE,FFCEH
Load register pair DE with the default size of the string area (i.e., negative fifty).
00F2H-00F4H
LD (40B1H),HL
Save the MEMORY SIZE? amount (which is in HL) to 40B1H (which holds the MEMORY SIZE? pointer).
00F5H
ADD HL,DE
Subtract the size of the string data (which was -50) from the highest memory address (stored in HE).
00F6H-00F8H
LD (40A0H),HL
Save the start of string space pointer (which is now held register pair HL) to 40A0H.
Note: 40A0H-40A1H holds the start of string space pointer.
00F9H-00FBH
Go initialize/reset the Level II BASIC variables and pointers.
00FCH-00FEH
LD HL,0111H
Load register pair HL with the starting address of the RADIO SHACK LEVEL II BASIC message. 00FFH-0101H Go display the RADIO SHACK LEVEL II BASIC message.
00FFH-0101H
We need to display the RADIO SHACK LEVEL II BASIC message so we call the WRITE MESSAGE routine at 28A7.
NOTE:
  • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
  • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
  • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
0102H-0104H
Go to the Level II BASIC READY routine.

0105H-0110H – MESSAGE STORAGE

0105H-0110H
“DMEMSZ”
MEMORY SIZE? message is stored here.
*0108H-010DH
“SIZE”+00H
In ROM 1.2, this shortend the “MEMORY SIZE”
*010EH-011BH
“R/S L2
BASIC”
In ROM 1.2, this is shortend version.
*011CH
PUSH BC
*In R/S L2 BASIC, this is the debounce routine. First, Put the Row Address in BC into the stack so BC can be used for the debounce routine.
*011DH-011FH
LD BC,0500H
Put 0500H into BC (which would be the debounce delay).
*0120H-0122H
CALL 0060H
Call the delay at 0060H based on the delay count in BC (which is 7.33 milliseconds).
*0123H
POP BC
Restore the Row Address back to BC.
*0124H
LD A,(BC)
Reload the original flags from active row.
*0125H
AND E
Combine the current flag lists with the original flag bits.
*0126H
RET Z
Return to caller if zero because the row was not active on the second test.
*0127H
LD A,D
Otherwise, we have a legitimate active row
*0128H
RCLA
Multiply the row index by 2. (Note: This was needed because a RCLA was sacrificed at the call location to give up the bytes needed for the call).
*0129H
RCLA
Multiply the row index by 2 again. (Note: This was needed because a RCLA was sacrificed at the call location to give up the bytes needed for the call).
*012AH-012CH
JP 03FEH
Resume the keyboard driver routine.

012DH-0131H – ?L3 ERROR ROUTINE

012DH-012EH
“L3ERR”
LD E,2CH
Load register E with the ?L3 ERROR code of 2CH.
012FH-0131H
Go to the Level II BASIC error routine with 2CH loaded into Register E.

0132H-0134H – LEVEL II BASIC “POINT” COMMAND ENTRY POINT
POINT

0132H
“GRPHCS”
RST 10H
Since we need to bump the current BASIC program pointer until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
0133H
XOR A
A will wind up being 0 if the POINT command was entered … otherwise.
0134H
013E80
Z-80 Trick! The byte at this memory location, 01H, is there to turn the real instruction that follows (the operative action of the SET command) into a harmless LD BC,xxxx. This way, they didn’t have to jump over SET or RESET to get to the common graphics code. If parsing straight down, this loads BC with 0380H and then moves to 0136H. But if jump straight to 0136H, you skip that 01H opcode, and get a real instruciton of 3EH 80H.

0135H-0137H – LEVEL II BASIC SET COMMAND ENTRY POINT
SET

0135H-0136H
“SET”
LD A,80H
Load register A with 80H (which is 128) which is SET.
0136H
1A
Z-80 Trick – See the note at 0134H for an explanation.

0138H-0139H – LEVEL II BASIC RESET COMMAND ENTRY POINT
“RESET”

0138H-0139H
“RESET”
LD A,01H
Load register A with 01H which is RESET.

013AH-019CH GRAPHICS ROUTINE
“GRAPH”

  • Common code for SET/RESET/POINT – A will be 0 if POINT, 80H if SET and 1 for RESET.
013AH
PUSH AF
Save the graphics mode in register A on the stack so we can use A for other things.
013BH-013CH
RST 08H
28H
Since SET/RESET/POINT all need a “(” to start with, call the COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call. If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the Aregister and HL incremented by one. If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
013DH-013FH
CALL 2B1CH
Go evaluate the expression at the location of the current BASIC program pointer in register pair HL (which is the X variable) and return with the 8-bit value in register A.
0140H-0141H
CP 80H
Check to see if the X value in register A is greater than 128.
0142H-0144H
If A is greater than 128, go to 1E4AH to display a ?FC ERROR.
0145H
PUSH AF
Save the X value in register A on the stack.
0146H-0147H
RST 08H
2CH
At this point we have SET/RESET/POINT, an open parenthesis, and an X variable, so now we must find a ,. To do this call the COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call. If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the Aregister and HL incremented by one. If the two characters do not match, a syntax error message is given and control returns to the Input Phase).
0148H-014AH
Go evaluate the expression at the location of the current BASIC program pointer in register pair HL (which is the Y variable) and return with the 8-bit value in register A.
014BH-014CH
CP 30H
Check to see if the Y value in register A is greater than 48.
014DH-014FH
If the Y value is greater than 48, go to 1E4AH to display a ?FC ERROR.
0150H-0151H
“SETRES”
LD D,FFH
Prepare to divide y coordinate by 3 … load register D with starting quotient.
0152H
INC D
Increment the quotient in register D.
0153H-0154H
SUB 03H
Divide by subtraction; in this case subtract 3 from register A.
0155H-0156H
Loop until register D equals the Y value divided by 3.
0157H-0158H
ADD 03H
Make the remainder positive by adjust the remainder in register A by adding back 3.
0159H
LD C,A
Save the remainder in register C.
015AH
POP AF
Get the X value from the stack and put it in register A.
015BH
ADD A,A
Multiply the X value in register A by two.
015CH
LD E,A
Load register E with the X value times two in register A.
015DH-015EH
LD B,02H
Load register B with the number of times to shift register pair DE (which is 2).
015FH
LD A,D
Load register A with the adjusted Y value in register D.
0160H
RRA
Divide the adjusted Y value in register A by two.
0161H
LD D,A
Save the new Y value in register A in register D.
0162H
LD A,E
Load register A with the adjusted X value in register E.
0163H
RRA
Divide the adjusted X value in register A by two.
0164H
LD E,A
Load register E with the new X value in register A.
0165H-0166H
Loop until the memory offset in register pair DE has been figured.
0167H
LD A,C
Now we need to computer the position of the point so load register A with the value in register C.
0168H
ADC A,A
Multiply the value in register A by two and add the value of the Carry flag to register A.
0169H
INC A
Increment the value in register A.
016AH
LD B,A
Save the bit position in register A in register B.
016BH
XOR A
Zero register A and reset the Carry flag.
016CH
SCF
Set the Carry flag.
016DH
ADC A,A
Add the value of the Carry flag to register A.
016EH-016FH
Loop until the graphic mask has been completed in register A.
0170H
LD C,A
Save the graphic mask in register A in register C.
0171H
LD A,D
Load register A with the MSB of the video memory offset in register D.
0172H-0173H
OR 3CH
Mask the MSB of the video memory offset in register A with 0011 1100 so that it will point to the correct location in video memory.
0174H
LD D,A
Save the MSB of the video memory pointer in register A in register D.
0175H
LD A,(DE)
Load register A with the character at the location of the video memory pointer in register pair DE.
0176H
OR A
Check to see if the character in register A is a graphic character.
0177H-0179H
Skip the next optcode if the character in register A is a graphic character.
017AH-017BH
LD A,80H
Load register A with a blank graphic character which is CHR$(128).
017CH
LD B,A
Set the flags according to the graphic mode in register A.

Save the graphic character in register A in register B.
017DH
POP AF
Get the graphic character from the stack (Register B) and put it in register A.
017EH
OR A
Set the flags according to the graphic mode in register A.
017FH
LD A,B
Get the graphic character from register B and put it in register A.
0180H-0181H
Jump forward to 0192H if the graphic mode is POINT.
0182H
LD (DE),A
Save the graphic character in register A at the location of the video memory pointer in register pair DE.
0183H-0185H
Jump forward to 018FH if the graphic mode is SET.
0186H
LD A,C
Load register A with the graphic mask in register C.
0187H
CPL
Reverse the graphic mask in register A.
0188H
LD C,A
Load register C with the adjusted graphic mask in register A.
0189H
LD A,(DE)
Load register A with the character at the location of the video memory pointer in register pair DE.
018AH
AND C
RESET the graphic bit by combining the graphic mask in register C with the graphic character in register A.
018BH
LD (DE),A
Save the adjusted graphic character in register A at the location of the video memory pointer in register pair DE.
018CH-018DH
CF 29H
Check the syntax. The character at the location of the current BASIC program pointer in register pair HL must be a ) character (“)” is 29H).
018EH
RET
Return.

018FH
OR C
SET the graphic bit by combining the graphic mask in register C with the graphic character in register A.
0190H-0191H
Jump back a few bytes to 018BH.
0192H
AND C
POINT the graphic bit by combining the graphic mask in register C with the graphic character in register A.
0193H-0194H
ADD FFH
Subtract one from the value in register A.
0195H
SBC A,A
Adjust the value in register A so that A will equal zero if the bit was off in register A.
0196H
PUSH HL
Save the current BASIC program pointer in register pair HL on the stack.
0197H-0199H
Save the value in register A as the current result in REG 1.
019AH
POP HL
Get the current BASIC program pointer from the stack and put it in register pair HL.
019BH-019CH
Jump to 018CH.

019DH-01C8H – LEVEL II BASIC INKEY$ ROUTINE

019DH
“INKEY”
RST 10H
Since we need to bump the current BASIC program pointer in register pair HL until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
019EH
PUSH HL
Save the current BASIC program pointer in register pair HL on the stack.
019FH-01A1H
LD A,(4099H)
Put the last key pressed (stored at 4099H) and put it in Register A.
01A2H
OR A
Set the status flags.
01A3H-01A4H
Jump to 01ABH (to skip the next carachter scan) if a key has been pressed.
01A5H-01A7H
Go scan the keyboard.
01A8H
OR A
Set the status flags.
01A9H-01AAH
Jump to 01BCH if a key wasn’t pressed.
01ABH
PUSH AF
Save the key pressed in register A on the stack.
01ACH
XOR A
Zero register A and clear the A Register status flags.
01ADH-01AFH
LD (4099H),A
Save the value in register A as the last key pressed (which is kept at 16537).
Note: 4099H holds the Last key pressed.
01B0H
INC A
Increment the value in register A (which is going to represet the size of the character string to be built).
01B1H-01B3H
Make sure there is room for this character string by calling 2857H to make an entry in string space.
01B4H
POP AF
Get the last key pressed from the stack and put it in register A.
01B5H-01B7H
LD HL,(40D4H)
Load register pair HL with the string’s starting address (which is kept in 40D4H).
01B8H
LD (HL),A
Save the last key pressed in register A at the location of the string pointer in register pair HL.
01B9H-01BBH
Go save the string’s VARPTR as the current result.
01BCH-01BEH
LD HL,1928H
Load register pair HL with the starting address of the “READY” message (which is 6440).
01BFH-01C1H
LD (4121H),HL
Save the address in register pair HL as the current result in REG 1 (which is 16673).
01C2H-01C3H
LD A,03H
Load register A with a string number type flag.
01C4H-01C6H
LD (40AFH),A
Save the value in register A as the current number type (which is at 16559).
Note: 40AFH holds Current number type flag.
01C7H
POP HL
Get the current BASIC program pointer from the stack and put it in register pair HL.
01C8H
RET
Return.

01C9H-01D2H – LEVEL II BASIC CLS ROUTINE – “$VDCLS”

  • A CALL lC9H will clear the screen, select 64 characters and home the cursor. All registers are used.
  • To use a ROM call to clear the screen, CALL 01C9H. The cursor is reset to the home position, which is 3C00H.
01C9H-01CAH
LD A,1CH
Load register A with the ASCII character to home the cursor.
01CBH-01CDH
Go send the character in register A (i.e., the ASCII character to home the cursor) to the video display.
01CEH-01CFH
LD A,1FH
Load register A with the ASCII character to clear to the end of the screen.
01D0H-01D2H
Go send the character in register A (i.e., the ASCII character to clear to the end of the screen) to the video display.

01D3H-01D8H – LEVEL II BASIC RANDOM ROUTINE
RANDOM

  • This is part of the RANDOM routine which takes a value out of the REFRESH register, stores it in location 40ABH and then returns.
    A call to 01D3H reseeds the random number seed (location 40AB) with the current contents of the refresh register.
  • NOTE: To run a RANDOM (seed the random number generator) via a ROM call just call CALL 01D3H. This causes the contents of R (memory refresh) to be stored in 40ABH. The entire 24 bit seed is stored in 40AAH-40ACH.
01D3H
“RANDOM”
LD A,R
Load register A with the current value of the refresh register.
01D5H-01D7H
LD (40ABH),A
Save the pseudi-random value in register A to 40ABH (the random number seed).
01D8H
RET
Return.

01D9H-01F7H – CASSETTE ROUTINE

01D9H-01DBH
“CWBIT”
LD HL,FC01H
Load register pair HL with the command to send to the cassette.
01DCH-01DEH
Go send the command to the cassette controller.
01DFH-01E0H
LD B,0BH
Load register B with the delay count.
01E1H-01E2H
Loop for delay.
01E3H-01E5H
LD HL,FC02H
Load register pair HL with the command to send to the cassette.
01E6H-01E8H
Go send the command to the cassette controller.
01E9H-01EAH
LD B,0BH
Load register B with the delay count.
01EBH-01ECH
Loop for delay.
01EDH-01EFH
LD HL,FC00H
Load register pair HL with the command to send to the cassette.
01F0H-01F2H
Go send the command to the cassette controller.
01F3H-01F4H
LD B,5CH
Load register B with the delay count.
01F5H-01F6H
Loop for delay.
01F7H
RET
Return.

01F8H-01FDH – CASSETTE ROUTINE (TURN OFF CASSETTE) – “$CSOFF”

  • Turns cassette recorder off.
  • To use a ROM call to turn the cassette off, CALL 01F8H
01F8H
PUSH HL
Save the value in register pair HL on the stack.
01F9H-01FBH
LD HL,FB00H
Load register pair HL with the command to send to the cassette to turn it off.
01FCH-01FDH
Jump to the cassette driver routine at 0219H.

  • 00FEH-0211H – CASSETTE ROUTINE (EVALUATE DRIVE NUMBER)
01FEH
“CTON”
LD A,(HL)
Get the character at the location of the current BASIC program pointer and put it in register A.
01FFH-0200H
SUB 23H
Check to see if the character in register A is a # character.
0201H-0202H
LD A,00H
Zero register A.
0203H-0204H
Jump to the TURN ON MOTOR routine at 0212H if the character at the location of the current BASIC program pointer in register pair HL isn’t a # character.
0205H-0207H
Go evaluate the drive number at the location of the current BASIC program pointer in register pair HL and return with the drive number in register E.
0208H-0209H
RST 08H
2CH
We need to see if the character at the location of the current BASIC program pointer in register pair HL is a ,, so call the RST 08H routine to do so.
020AH
LD A,E
Need to convert from the negative number to positive so, load register A with the drive number in register E …
020BH
AND D
… and combine the MSB of the drive number in register D with the LSB of the drive number in register A and then …
020CH-020DH
ADD 02H
… add 2 to make the drive number in register A positive.
020EH-0210H
If the drive number in register A is invalid, jump to 14E4H to display a FC ERROR.
0211H
DEC A
Decrement the drive number in register A.

0212H-021DH – CASSETTE ROUTINE (TURN ON CASSETTE)
“DEFCAS”

  • CALL 212H will select the cassette unit specified in A-register and starts motor. Units are numbered from one. All registers are used.
  • To use a ROM call to turn on the cassette, execute the following instructions:
    LD A,0
    CALL 0212H
0212H-0214H
“DEFDRV”
Set the current drive as specified by register A.
0215H
PUSH HL
Save the current BASIC program pointer in register pair HL on the stack.
0216H-0218H
LD HL,FF04H
Load register pair HL with the command to turn on the cassette.
0219H-021BH
Go send the “turn on the cassette” command stored in HL to the cassette controller.
021CH
POP HL
Get the current BASIC program pointer from the stack and put it in register pair HL.
021DH
RET
Return.

  • 021EH-022BH – CASSETTE ROUTINE
021EH-0220H
“CLRCFF”
LD HL,FF00H
Load register pair HL with the mask to preserve video controller flags.
0221H-0223H
“STATFF”
LD A,(403DH)
Load register A with the 32/64 character per line flag (which is stored at 403DH).
Note: 403DH-4040H is used by DOS.
0224H
AND H
Combine the value in register H with the 32/64 character per line flag in register A.
0225H
OR L
Combine the value to send to the cassette in register L with the adjusted value in register A (which relates to video).
0226H-0227H
OUT (FFH),A
Send the value in register A to port 255 (which is the cassette and video port).
0228H-022AH
LD (403DH),A
Save the value in register A as the 32/64 character per line flag.
Note: 403DH-4040H is used by DOS.
022BH
RET
Return.

022CH-0234H – CASSETTE ROUTINE (BLINK **)

  • Alternately displays and clears an asterisk in the upper right hand comer. Uses all registers.
022CH-022EH
“CSTAR”
LD A,(3C3FH)
Get the character being displayed in the upper right hand corner of the video display from 3C3FH and put that character in register A.
022FH-0230H
XOR 0AH
If the character in register A is a * then make it a space, else if the character in register A is a space make it a *·
0231H-0233H
LD (3C3FH),A
Display the character in register A in the upper right hand comer of the video display.
0234H
RET
Return.

0235H-0240H – CASSETTE ROUTINE (READ A BYTE) – “$CSIN”

  • This routine will read a byte from tape. A CALL 235H will return with the byte read from tape in the A register BC, DE and HL are unchanged.
  • To use a ROM call to read a character from cassette (after the cassette has been turned on and leader and sync have been found), CALL 0235H. The input character will be in the A register. Again, the routine at 0235H must be called frequently enough to sustain the 500 baud rate if more than one character is to be read.
0235H
PUSH BC
Save the value in register pair BC on the stack.
0236H
PUSH HL
Save the value in register pair HL on the stack.
0237H-0238H
LD B,08H
Load register B (which is what DJNZ decrements to loop) with the number of bits to read (which is 8).
0239H-023BH
Go read a bit from the cassette recorder (the resulting byte will be assembled into the A register).
023CH-023DH
Loop that instruction until all eight bits have been read into A.
023EH
POP HL
Get the value from the stack and put it in register pair HL.
023FH
POP BC
Get the value from the stack and put it in register pair BC.
0240H
RET
Return.

0241H-0260H – CASSETTE ROUTINE (READ A BIT)

  • Routine waits for timing pulse, and then performs a timing loop. When the time is up it tests the tape for a bit, which will be “1” if present and “0” if not. A CALL 241H is used by 235H eight times to input one byte.
0241H
“CRBIT”
PUSH BC
Save the value in register pair BC on the stack.
0242H
PUSH AF
Save the value in register A on the stack.
0243H-0244H
IN A,(FFH)
Read a bit from the cassette port.
0245H
RLA
Check to see if this is a start bit.
0246H-0247H
Loop back to 0243H until the start bit is found.
0248H-0249H
LD B,40H
No that we have the start bit we need a delay, so load register B with the delay count of 40H.
*0248H-0249H
LD B,60H
In ROM v1.2, load B with a delay count of 60H (=476/703 microseconds) instead of 40H.
024AH-024BH
Loop (don’t jump unless B is zero; with a decrement of B each time) for delay.
024CH-024EH
Go clear the cassette controller so we can get to reading.
024FH-0250H
LD B,76H
We need a delay so load register B with the delay count of 76H.
*024FH-0250H
LD B,85H
In ROM v1.2, load B with a delay count of 85H (865/975 microseconds) instead of 76H.
0251H-0252H
Loop for delay.
0253H-0254H
IN A,(FFH)
Load register A with the value of the cassette port.
0255H
LD B,A
Since we are going to need to use A, load A’s value (the bit read from the cassette port) into register B.
0256H
POP AF
Get the value from the stack (which was the bits already read for this byte) and put it in register A.
0257H-0258H
RL B
Shift the that data bit read in register B into the Carry flag.
0259H
RLA
Shift the value in the Carry flag (which was B) into register A.
025AH
PUSH AF
Save the value in register A on the stack because its gonna get erased by the next step.
025BH-025DH
Go clear the cassette controller so we can get to reading.
025EH
POP AF
Get the value from the stack and put it in register A.
025FH
POP BC
Get the value from the stack and put it in register pair BC.
0260H
RET
Return.

0261H-0263H – CASSETTE ROUTINE

0261H-0263H
“CW2BYT”
Write the clock pulse by calling the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register).

0264H-027DH – CASSETTE ROUTINE (WRITE A BYTE) – “$CSOUT”

  • Writes the byte in the A register to tape. BC, DE and HL are unchanged by a CALL 264H.
  • To use a ROM call to write a character onto cassette tape (after the cassette has been turned on and leader and sync have been recorded), load the character into the A register and CALL 0264H. If more than one character is to be written, the CALL 0264H must be executed with sufficient frequency to sustain the 500 baud recording rate. The routine provides automatic timing.
0264H
PUSH HL
Save the value in register pair HL on the stack.
0265H
PUSH BC
Save the value in register pair BC on the stack.
0266H
PUSH DE
Save the value in register pair DE on the stack.
0267H
PUSH AF
Save the value in register A on the stack.
0268H-0269H
LD C,08H
Load register C with the number of bits to be written (i.e., 7).
026AH
LD D,A
Load register D with the byte to be written from register A because A is about to get used in the next line.
026BH-026DH
Go write the start/clock bit.
026EH
LD A,D
Load register A with the byte to be written in register D.
026FH
RLCA
Shift the bit to be written into the Carry flag.
0270H
LD D,A
Save the adjusted byte to be written in register A in register D.
0271H-0272H
Jump if the bit to be written is equal to zero.
0273H-0275H
Go write that (non-zero) bit.
0276H
DEC C
Decrement the counter in register C.
0277H-0278H
Loop until all eight bits have been written.
0279H
POP AF
Get the value from the stack and put it in register A.
027AH
POP DE
Get the value from the stack and put it in register pair DE.
027BH
POP BC
Get the value from the stack and put it in register pair BC.
027CH
POP HL
Get the value from the stack and put it in register pair HL.
027DH
RET
Return.

027EH-0283H – CASSETTE ROUTINE

027EH-027FH
LD B,87H
Load register B with the delay count of 135.
0280H-0281H
Loop for the delay.
0282H-0283H
Jump to 0276H to count the number of bits written.

0284H-0292H – CASSETTE ROUTINE (TURN ON CASSETTE AND WRITE LEADER)

  • A call to 0284H writes a Level II leader on currently selected unit. The leader consists of 256 (decimal) binary zeros followed by a A5H. Uses the B and A registers.
0284H-0286H
“CWONWL”
Go evaluate the cassette drive number and turn on that cassette drive’s motor.
0287H-0288H
“$CSHWR”
LD B,FFH
Writes tape leader and the A5H sync byte. DE and HL are unchanged.

Load register B with the number of bytes to be written.
  • To use a ROM call to write the cassette leader and sync byte, CALL 0287H
0289H
XOR A
Zero register A.
028AH-028CH
Calls the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register).
028DH-028EH
Loop until leader has been written.
028FH-0290H
LD A,A5H
Load register A with the sync byte value.
0291H-0292H
Calls the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register). In this case, it writes the SYNC byte.

0293H-029EH – CASSETTE ROUTINE (TURN ON CASSETTE AND READ LEADER)

0293H-0295H
“CRONRL”
Go evaluate the drive number and turn on that cassette drive’s motor.
0296H
“$CSHIN”
PUSH HL
Reads from tape until the leader is found, then keeps going until it is bypassed and the sync byte (A5H) is found, when it returns. DE, BC and HL are unchanged by this.

Save the current BASIC program pointer in register pair HL on the stack.
  • To use a ROM call to search for leader and sync byte, CALL 0296H
0297H
XOR A
Zero register A and status flags.
0298H-029AH
Go read a byte from the cassette and return with it in register A.
029BH-029CH
CP A5H
Check to see if the byte read from the cassette in register A is a sync byte.
029DH-029EH
Loop until sync byte found.

029FH-02A8H – CASSETTE ROUTINE (DISPLAY “**” ON VIDEO)

029FH-02A0H
“CTSTARS”
LD A,2AH
Places the double asterisk in the right top corner to show that the sync byte has been found.

Load register A with a * character. (“*” is 2AH).
02A1H-02A3H
LD (3C3EH),A
Display the * character in register A on the video display at location 15422.
02A4H-02A6H
LD (3C3FH),A
Display the * character in register A on the video display at location 15423.
02A7H
POP HL
Get the current BASIC program pointer from the stack and put it in register pair HL.
02A8H
RET
Return.

02A9H-0329H – LEVEL II SYSTEM ROUTINE-ENTRY POINT-02B2H

02A9H-02ABH
“GSYSTR”
Go read 2 bytes from the cassette, which should be the execution address, and return with it in register pair HL.
02ACH-02AEH
LD (40DFH),HL
Save the just read execution address from HL into 40DFH.
Note: 40DFH-40E0H holds Used by DOS.
02AFH-02B1H
Go turn off the cassette motor.
02B2H-02B4H
“SYSTEM”
Go call the DOS link at 41E2H.
In NEWDOS 2.1, this is called during a SYSTEM operation.
02B5H-02B7H
LD SP,4288H
Set the stack pointer to 4288H (which is the assumed load address). This location passes control to the routine used by the BASIC command SYSTEM.
02B8H-02BAH
Go display a carriage return on the video display if necessary.
02BBH-02BCH
LD A,2AH
Load register A with an * character (which will form the next prompt).
02BDH-02BFH
Go display the * character in register A on the video display.
02C0H-02C2H
We need a filename now, so go get the input from the keyboard.
02C3H-02C5H
If a BREAK key was hit (because the Carry flag is now on), go to the Level II BASIC READY routine.
02C6H
RST 10H
Since we need to bump the input buffer pointer in register pair HL until it points to the first character input, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
02C7H-02C9H
Display a ?SN ERROR if there wasn’t any input.
02CAH-02CBH
CP 2FH
Check to see if the character at the location of the input buffer pointer in register A is a / character. “/” is 2FH.
02CCH-02CDH
Jump to 031DH if the character at the location of the input buffer pointer in register A is a /.
02CEH-02D0H
Go turn on the cassette motor.
02D1H-02D3H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (whichh reads one byte from the cassette drive specified in register A, and returns the byte in register A).
02D4H-02D5H
CP 55H
Check to see if the byte read from the cassette in register A is a header byte.
02D6H-02D7H
Loop until the header byte is found.
02D8H-02D9H
LD B,06H
Load register B with the length of the filename to read from the cassette (which is 6 characters).
02DAH
LD A,(HL)
Load register A with the character at the location of the current input buffer pointer in register pair HL.
02DBH
OR A
Check to see if the character at the location of the current input buffer pointer in register A is an end of input character.
02DCH-02DDH
Jump out of this ‘read the filename from the cassette’ routine if the character at the location of the current input buffer pointer in register A is an end of input character.
02DEH-02E0H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
02E1H
CP (HL)
Check to see if the character at the location of the current input buffer pointer in register pair HL is the same as the character read from the cassette in register A.
02E2H
INC HL
Increment the input buffer pointer in register pair HL.
02E3H-02E4H
Jump to 02D1H (skip to the next program on cassette) if the character at the location of the current input buffer pointer in register pair HL isn’t the same as the character read from the cassette in register A.
*02E2H-02E3H
Jump to 02D1H (skip to the next program on cassette) if the character at the location of the current input buffer pointer in register pair HL isn’t the same as the character read from the cassette in register A.
*02E4H
INC HL
Increment the input buffer pointer in register pair HL.
02E5H-02E6H
Loop until the whole of the filename has been read from the cassette and checked against the user response.
02E7H-02E9H
Call the BLINK ASTERISK routine at 022CH which alternatively displays and clears an asterisk in the upper right hand corner of the video display.
02EAH-02ECH
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (whichh reads one byte from the cassette drive specified in register A, and returns the byte in register A).
02EDH-02EEH
CP 78H
Check to see if the byte read from the cassette in register A is an execution address header byte (which is 120).
02EFH-02F0H
Jump if the byte read from the cassette in register A is an execution address header byte.
02F1H-02F2H
CP 3CH
Check to see if the byte read from the cassette in register A is a file block header byte (which is 60).
02F3H-02F4H
Loop until either an execution address header byte or a file block header byte is read from the cassette.
02F5H-02F7H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
02F8H
LD B,A
Load register B with the number of bytes to be loaded in register A.
02F9H-02FBH
Go read the file block’s starting address from the cassette and return with it in register pair HL.
02FCH
ADD A,L
Add the LSB of the file block’s starting address in register L to the MSB of the file block’s starting address in register A.
02FDH
LD C,A
Load register C with the file block’s starting checksum in register A.
02FEH-0300H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
0301H
LD (HL),A
Save the byte read from the cassette in register A at the location of the memory pointer in register pair HL.
0302H
INC HL
Increment the memory pointer in register pair HL.
0303H
ADD A,C
Add the value of the current checksum in register C to the value in register A.
0304H
LD C,A
Load register C with the updated checksum in register A.
0305H-0306H
Loop until the whole file block has been read.
0307H-0309H
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (which reads one byte from the cassette drive specified in register A, and returns the byte in register A).
030AH
CP C
Check to see if the computed checksum in register C is the same as the checksum read from the cassette in register A.
030BH-030CH
If its the same, jump to 02E7H because the next instructions are for bad checksums.
030DH-030EH
LD A,43H
Load register A with a C character.
030FH-0311H
LD (3C3EH),A
Display the C character in register A on the video display (at 15422).
0312H-0313H
Jump to 02EAH and keep reading bytes.

0314H-0316H – This routine reads two bytes from tape (providing that the tape is already running) and puts them in the HL register pair. It is used by the SYSTEM routine to read the last two bytes on tape which give the entry point. A JP (HL) can then be executed to jump to the location specified, when used for this purpose. Only HL is used by this routine.

0314H
“GETADR”
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (whichh reads one byte from the cassette drive specified in register A, and returns the byte in register A).
0317H
LD L,A
Load register L with the byte read from the cassette in register A (which is the LSB of the 16 bit value).
0318H-031AH
Calls the READ ONE BYTE FROM CASSETTE routine at 0235H (whichh reads one byte from the cassette drive specified in register A, and returns the byte in register A).
031BH
LD H,A
Load register H with the byte read from the cassette in register A (which is the MSB of the 16 bit value).
031CH
RET
Return.

031DH
“SYSGO”
EX DE,HL
Load register pair DE with the input buffer pointer in register pair HL.
031EH-0320H
LD HL,(40DFH)
Load register pair HL with the current execution address (which is stored at 40DFH).
Note: 40DFH-40E0H holds Used by DOS.
0321H
EX DE,HL
So that we can run a RST 10H in the next instruction, we need to exchange the execution address in register pair HL with the input buffer pointer in register pair DE.
0322H
RST 10H
Since we need to bump the current input buffer pointer in register pair HL until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
0323H-0325H
Call the ASCII TO INTEGER routine at 1E5AH.
NOTE:
  • The routine at 1E5A converts the ASCII string pointed to by HL to an integer deposited into DE. If the routine finds a non-numerica character, the conversion is stopped
0326H-0327H
Jump if it turns out there weren’t any digits in the input.
0328H
EX DE,HL
Since there were digits (or else we would have jumped in the prior instruction), exchange the input buffer pointer in register pair HL with the execution address in register pair DE.
0329H
Jump to the execution address (i.e. “/xxxx”) which is in register pair HL.

032AH-0347H – OUTPUT ROUTINE
“OUTCHR”

  • This is a general purpose output routine which outputs a byte from the A register to video, tape or printer. In order to use it, the location 409CH must be loaded with -1 for tape, 0 for video or 1 for the line printer.
    Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
  • This routine outputs a byte to device determined by byte stored at (409CH) – FFH=Tape, 0=Video, l=Printer. When calling, A = output byte. Uses AF. Warning: This routine CALLs a Disk BASIC link at address 41ClH which may have to be “plugged” with a RETurn (C9H) instruction.
032AH
“DSPCHR”
PUSH BC
We are going to need to use Register C, so push register pair BC into the stack.
032BH
LD C,A
Load register C with the character to be output in register A.
032CH-032EH
Go call the DOS link at 41ClH.
In NEWDOS 2.1, this writes to the system output device.
032FH-0331H
LD A,(409CH)
Load register A with the current output device number stored in 409CH.
Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
0332H
OR A
Set the flags according to the current output device number in register A.
0333H
LD A,C
Load register A with the character to be output in register C.
0334H
POP BC
Get the value from the stack and put it in register pair BC.
0335H-0337H
Jump to the the WRITE ONE BYTE TO CASSETTE routine at 0264H (which writes the byte in the A register to the cassette drive selected in the A register) if the character in register A is to be sent to the cassette.
0338H-0339H
Jump to 039CH if the character in register A is to be sent to the printer.

033AH-0347H – “CRTOUT” OUTPUT ROUTINE

  • To use a ROM call to print a single character at the current cursor position, and to update the cursor position, load the ASCII value of the character into the A register and then CALL 033AH.
  • To display special functions using a ROM call, load the A register with the value given below for the special function and then CALL 033AH.
    1. Backspace and erase previous character – 08H
    2. Carriage return and linefeed – 0DH
    3. Turn on cursor – 0EH
    4. Turn off cursor – 0FH
    5. Convert to 32 characters per line mode – 17H
    6. Backspace cursor – 18H
    7. Advance cursor one position – 19H
    8. Downward line feed – 1AH
    9. Upward line feed – 1BH
    10. Home (cursor to upper left corner) – 1CH
    11. Move cursor to beginning of current line – 1DH
    12. Erase from cursor position to end of line – 1EH
    13. Erase from cursor position to end of screen – 1FH
033AH
“CRTOUT”
PUSH DE
If we’re here, then that value in A wasn’t going to the cassette or the printer, so it must be going to the video. This routine performs the same function as 33H except that it doesn’t destroy the contents of the DE register pair. This means that all the general purpose registers are saved, which is often desirable.

Save the value in register pair DE on the stack.
033BH-033DH
Call the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
033EH
PUSH AF
Save the character in register A on the stack.
033FH-0341H
Go update the current cursor position and test to see if the display memory is full.
0342H-0344H
LD (40A6H),A
Save the current cursor line position stored in 40A6H to register A.
Note: 40A6H holds the current cursor line position.
0345H
POP AF
Get the character from the stack and put it in register A.
0346H
POP DE
Get the value from the stack and put it in register pair DE.
0347H
RET
Return.

0348H-0357H – VIDEO ROUTINE

0348H-034AH
LD A,(403DH)
Load register A with the 32/64 character per line flag (which is stored in 16445).
Note: 403DH-4040H is used by DOS.
034BH-034CH
AND 08H
Set the flags according to the status of the 32/64 character per line flag in register A.
034DH-034FH
LD A,(4020H)
Load register A with the LSB of the current cursor position.
Note: 4020H-4021H holds Video DCB – Cursor location.
0350H-0351H
Jump if this is the 64 character per line mode.
0352H
RRCA
Divide the LSB of the current cursor position in register A by two.
0353H-0354H
AND 1FH
Mask the cursor line position in register A for a 32 character per line (AND against 0001 1111) to force its position to be no less than 3C00H.
0355H-0356H
AND 3FH
Mask the cursor line position in register A for 64 characters per line (AND against 0011 1111) to force its position to be no more than 3FFFH.
0357H
RET
Return.

0358H-0360H – KEYBOARD ROUTINE
Here is the routine to simulate the INKEY$ function. It performs exactly the same function as 2BH but it restores all registers, whereas 2BH destroys the contents of the DE register pair. This makes 35BH more useful than 2BH.

0358H-035AH
“KBD2”
Go call the DOS link at 41C4H.
035BH
PUSH DE
Since the next routine uses DE, save the value in register pair DE on the stack.
035CH-035EH
Call the SCAN KEYBOARD routine at 002BH.
035FH
POP DE
Get the value from the stack and put it in register pair DE.
0360H
RET
Return.

0361H-0383H – INPUT ROUTINE
“KIBUFF”

  • This is one of the general purpose input routines (see 5D9 and 1BB3 also). This routine inputs a string from the keyboard, up to a maximum of 240 characters (F0H), and echoes them to the screen. It puts this data into a buffer located at the address pointed to by the buffer pointer at 40A7H. (e.g. If 40A7H contains 5000H the data will be stored from 5000H onwards). The string is terminated with a zero byte. The program returns from this routine as soon as the ENTER key has been pressed. When it does so, HL contains the start address of the input string and B contains the length of the string. (RST 10H can be used to make HL point to the first character of the string, if required.).
    Note: 40A7H-40A8H holds the input Buffer pointer.
0361H
“LINP2”
XOR A
Zero register A.
0362H-0364H
LD (4099H),A
Save the value in register A as the last key pressed (which is stored in 4099H).
Note: 4099H holds the Last key pressed.
0365H-0367H
LD (40A6H),A
Save the value in register A as the current cursor line position (which is stored in 40A6H).
Note: 40A6H holds the current cursor line position.
0368H-036AH
Go call the DOS link at 41AFH.
In NEWDOS 2.1, this is the satrt of keyboard input.
036BH
PUSH BC
Save register pair BC on the stack.
036CH-036EH
LD HL,(40A7H)
Load register pair HL with the starting address of the input buffer (which is stored in 40A7H).
Note: 40A7H-40A8H holds the input Buffer pointer.
036FH-0370H
LD B,F0H
Load register B with the length of the input buffer (which is 240).
0371H-0373H
“WAIT FOR NEXT LINE” keyboard input routine at 05D9H (which takes keyboard entry until a carriage return, a break, or buffer overrun occurs).
0374H
PUSH AF
Save the flags on the stack.
0375H
LD C,B
Load register C with the length of the input in register B.
0376H-0377H
LD B,00H
Zero register B so that register pair BC will have the length of the input.
0378H
ADD HL,BC
Add the length of the input in register pair BC to the starting address of the input buffer in register pair HL.
0379H-037AH
LD (HL),00H
Save an end of the input character at the location of the end of input pointer in register pair HL.
037BH-037DH
LD HL,(40A7H)
Load register pair HL with the starting address of the input buffer (which is 40A7H).
Note: 40A7H-40A8H holds the input Buffer pointer.
037EH
POP AF
Get the flags from the stack.
037FH
POP BC
Get the value from the stack and put it in register pair BC.
0380H
DEC HL
Decrement the input buffer pointer in register pair HL (so that HL is the input area pointer – 1).
0381H
RET C
Return if the BREAK key was pressed.
0382H
XOR A
Otherwise (i.e., the BREAK key was not pressed), zero all the status flags.
0383H
RET
Return.

0384H-038AH – KEYBOARD ROUTINE

  • Waits for keypress
0384H-0386H
“KBWT2”
Go scan the keyboard.
0387H
OR A
Check to see if a key was pressed.
0388H
RET NZ
Return if a key was pressed (meaning OR A was set to NZ).
0389H-038AH
Loop until a key is pressed.

038BH-039BH – PRINTER ROUTINE

  • This routine resets device type flag at 409CH to zero (output to video display), also outputs a carriage return to the line printer if printer is not at beginning of line (determined by checking the contents of the printer line position flag at 409BH – if flag contains zero, printer is at start of line). Note that if printer line position flag does not contain zero and the printer is not on line, the computer will “hang up” waiting for a “printer ready” signal.
038BH
XOR A
Zero register A, which then means it contains the device code for VIDEO.
038CH-038EH
LD (409CH),A
Save the value in register A (the current output device code of video) to 409CH.
Note: 409CH holds the current output device flag: -1=cassette, 0=video and 1=printer.
038FH-0391H
LD A,(409BH)
Load register A with the current printer carriage position (which is stored at 409BH).
Note: 409BH holds the printer carriage position.
0392H
OR A
Check to see if the carriage position in register A is equal to zero.
0393H
RET Z
Return if the carriage position in register A is equal to zero.
0394H-0395H
LD A,0DH
Load register A with a carriage return character (i.e., 0DH).
0396H
PUSH DE
Save the value in register pair DE on the stack.
0397H-0399H
Go send the carriage return character in register A to the printer.
039AH
POP DE
Get the value from the stack and put it in register pair DE.
039BH
RET
Return.

039CH-03C1H – PRINTER ROUTINE

  • This is the LPRINT routine. All registers are saved. The byte to be printed should be in the A register.
039CH
PUSH AF
Save the value in register pair AF on the stack.
039DH
PUSH DE
Save the value in register pair DE on the stack.
039EH
PUSH BC
Save the value in register pair BC on the stack.
039FH
LD C,A
Load register C with the character to be sent to the printer in register A.
03A0H-03A1H
LD E,00H
Zero register E (whcih will ultimately hold the new character/line count of 0CH, 0DH, or 0AH).
03A2H-03A3H
CP 0CH
Check to see if the character to be sent to the printer in register A is equal to 0CH (which is ‘skip to next line’).
03A4H-03A5H
Jump to 03B6H if the character to be sent to the printer in register A is equal to 0CH.
03A6H-03A7H
CP 0AH
Check to see if the character to be sent to the printer in register A is a line feed character (i.e., 0AH).
03A8H-03A9H
Jump to 03ADH if the character to be sent to the printer in register A isn’t a line feed character.
03AAH-03ABH
LD A,0DH
Load register A with a carriage return character (i.e., 0DH).
03ACH
LD C,A
Load register C with the character to be sent to printer in register A.
03ADH-03AEH
CP 0DH
Check to see if the character to be sent to the printer in register A is a carriage return character.
03AFH-03B0H
Jump to 03B6H if the character to be sent to the printer in register A is a carriage return character.
03B1H-03B3H
LD A,(409BH)
Load register A with the current printer carriage position (stored in 409BH).
Note: 409BH holds the printer carriage position.
03B4H
INC A
Increment the current carriage position in register A.
03B5H
LD E,A
Load register E with the current carriage position in register A.
03B6H
LD A,E
Load register A with the current carriage position in register E. Why do this since its obviously already done? Becasuse this is a jump point!
03B7H-03B9H
LD (409BH),A
Save the current carriage position (which is stored in 409BH) in register A.
Note: 409BH holds the printer carriage position.
03BAH
LD A,C
Load register A with the character to be sent to the printer in register C.
03BBH-03BDH
Call the PRINT CHARACTER routine at 003B (which sends the character in the C register to the printer).
03BEH
POP BC
Get the value from the stack and put it in register pair BC.
03BFH
POP DE
Get the value from the stack and put it in register pair DE.
03C0H
POP AF
Get the value from the stack and put it in register pair AF.
03C1H
RET
Return.

03C2H-03E2H – DRIVER ENTRY ROUTINE

  • This routine is called from a RST 14 (with a device code of 01H in Register B), RST 1C (with a device code of 02H in Register B), and RST 24 (with a device code of 04H in Register B).
03C2H
PUSH HL
Save register pair HL on the stack.
03C3H-03C4H
PUSH IX
Save the value in register pair IX on the stack.
03C5H
PUSH DE
Save the starting address of the device control block in register pair DE on the stack.
03C6H-03C7H
POP IX
Get the starting address of the device control block from the stack and put it in register pair IX.
03C8H
PUSH DE
Save the value in register pair DE on the stack.
03C9H-03CBH
LD HL,03DDH
Load register pair HL with a return address of 03DDH.
03CCH
PUSH HL
Save the return address in register pair HL on the stack.
03CDH
LD C,A
Save the character to output (current held in register A) to register C.
03CEH
LD A,(DE)
Load register A with the device type code at the location of the device control block pointer in register pair DE.
03CFH
AND B
Isolate the device code bits in A by AND’ing with the device codes in B.
03D0H
CP B
Check to see if the updated device type code in register A is the same as the driver entry code in register B.
03D1H-03D3H
Jump to the DOS exit link at 4033H if the updated device type code in register A isn’t the same as the driver entry code in register B.
03D4H-03D5H
CP 02H
At this point we know that the updated device type code in A is the same as the driver code entry, so let’s move on. First, reset the flags.
03D6H-03D8H
LD L,(IX+01H)
Load register L with the LSB of the driver entry address at the location of the device control block pointer in register pair IX plus one.
03D9H-03DBH
LD H,(IX+02H)
Load register H with the MSB of the driver entry address at the location of the device control block pointer in register pair IX plus one.
03DCH
Jump to the driver entry address in register pair HL.
03DDH
POP DE
Get the value from the stack and put it in register pair DE.
03DEH-03DFH
POP IX
Get the value from the stack and put it in register pair IX.
03E0H
POP HL
Get the value from the stack and put it in register pair HL.
03E1H
POP BC
Get the value from the stack and put it in register pair BC.
03E2H
RET
Return.

03E3H-0457H – KEYBOARD DRIVER

  • This is the keyboard driver. It scans the keyboard and converts the bit pattern obtained to ASCII and stores it in the A register.
03E3H-03E5H
LD HL,4036H
Load register pair HL with the keyboard work area’s starting address (which is 4036H).
Note: 4036H-403CH is the keyboard work area.
03E6H-03E8H
LD BC,3801H
Load register pair BC with the keyboard memory’s starting address (which is 3801H).
03E9H-03EAH
LD D,00H
Zero register D.
03EBH
LD A,(BC)
Load register A with the value at the location of the keyboard memory pointer in register pair BC (which is row N).
03ECH
LD E,A
Load register E with the keyboard memory value in register A (8 column bits).
03EDH
XOR (HL)
Check for inequality by XORing the value at the location of the keyboard work area pointer in register pair HL with the keyboard memory value in register A.
03EEH
LD (HL),E
Save the keyboard memory value (the column bits) in register E at the location of the keyboard work area pointer in register pair HL.
03EFH
AND E
Test for the active row by masking the adjusted value in register A with the value at the location of the keyboard work area pointer in register pair HL.
03F0H-03F1H
Jump to 03FAH if the new key pressed is in row N.
03F2H
INC D
Increment the keyboard row counter in register D.
03F3H
INC L
Increment the keyboard work area pointer in register pair HL.
03F4H-03F5H
RLC C
Adjust the keyboard memory pointer in register pair BC by stepping it from 3801 to 3840 by rotating the bits left (RLC).
03F6H-03F8H
Jump to 03EBH if the whole of keyboard memory hasn’t been checked (by the Parity bit being on).
03F9H
RET
Return.

03FAH
LD E,A
Save the column number in register A in register E.
03FBH
LD A,D
Load register A with the row counter in register D (this is going to cycle from 0 through 6).
03FCH
RLCA
Multiply the row counter in register A by two.
03FDH
RLCA
Multiply the row counter in register A by two.
*03FBH-03FDH
JP 011CH
For ROM v1.2, jump to the new keyboard debounce routine. That routine includes the now deleted RCLA, RCLA instructions which had to be killed to make room for this 3 byte jump opcode.
03FEH
RLCA
Multiply the row counter in register A by two.
03FFH
LD D,A
Load register D with the row counter in register A.
0400H-0401H
LD C,01H
Load register C with the starting column counter (as bit 0).
0402H
LD A,C
Load register A with the column counter in register C (as a mask).
0403H
AND E
Check to see if the column counter in register A is the same as the active column number in register E.
0404H-0405H
Jump to 040BH if the column counter in register A is the same as the active column number in register E.
0406H
INC D
Increment the column number (which is held in register D).
0407H-0408H
RLC C
Adjust the column counter in register C left 1 bit to align the mask.
0409H-040AH
Loop back to 0402H until the value in register D is adjusted for its column.
040BH-040DH
LD A,(3880H)
Load register A with the value of the SHIFT but from memory location 3880H.
040EH
LD B,A
Load register B with the SHIFT value in register A.
040FH
LD A,D
Load register A with the value in register D (Row * 8 + column 0-7).
0410H-0411H
ADD 40H
Adjust the ASCII value in register A (Row * 8 + column (0-7) + 64 decimal).
0412H-0413H
CP 60H
Check to see if the value in register A is alphabetic by testing for the 4 rows (@, A-Z).
0414H-0415H
Jump to 0429H if the value in register A is nonalphabetic.
0416H-0417H
RRC B
Put the SHIFT value in register B in the carry flag (as the RRC command rotates right, and puts bit 0 into the carry bit).
0418H-0419H
Jump if the SHIFT key wasn’t pressed (i.e., the rotated right register B’s bit zero wasn’t a zero).
041AH-041BH
ADD 20H
Adjust the value in register A for lower case (by ANDing it against 0010 0000).
041CH
LD D,A
Load register D with the adjusted character in register A.
041DH-041FH
LD A,(3840H)
Load register A with the value at keyboard memory row six (which is 14400).
0420H-0421H
AND 10H
Check to see if the down arrow key (or ENTER) was pressed (by ANDing it against 0001 0000).
0422H-0423H
Jump to 044CH if down arrow (or ENTER) wasn’t pressed.
0424H
LD A,D
Load register A with the character in register D.
0425H-0426H
SUB 60H
Adjust the value of the character in register A down by 96.
0427H-0428H
Jump to 044BH.
0429H-042AH
SUB 70H
Adjust the value of the character in register A down by 112 (for ENTER or SPACE).
042BH-042CH
Jump to 043DH if the character in register A is for keyboard row six.
042DH-042EH
ADD 40H
Readjust the value of character in register A by adding 64 to adjust to rows 4-5.
042FH-0430H
CP 3CH
Check to see if the character in register A is a 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, “:”, “;”, or “,” ,character.
0431H-0432H
Jump to 0435H if the character in register A is one of those characters.
0433H-0434H
XOR 10H
Adjust the character in register A by XORing against 0001 0000 to invert bit 5.
0435H-0436H
RRC B
Put the SHIFT value in register B into the Carry flag.
0437H-0438H
Jump to 044BH if the SHIFT key wasn’t pressed.
0439H-043AH
XOR 10H
Adjust the character in register A by XORing against 0001 0000 to reinvert bit 5.
043BH-043CH
Jump to 044BH to output.
043DH
RLCA
Adjust the value in register A to be (ROW*8 + COLUMN-48) * 2).
043EH-043FH
RRC B
Put the SHIFT value in register B into the Carry flag.
0440H-0441H
Jump to 0443H if the SHIFT key wasn’t pressed.
0442H
INC A
Increment the value in register A to turn (ROW*8 + COLUMN-48) * 2) into (COLUMN*2+1).
0443H-0445H
LD HL,0050H
Load register pair HL with the starting address of the keyboard lookup table at 50H, which is the last row.
0446H
LD C,A
Load register C with the offset in register A (which is either 43D or 442).
0447H-0448H
LD B,00H
Zero register B.
0449H
ADD HL,BC
Add the offset in register pair BC to the starting address of the keyboard lookup table in register pair HL.
044AH
LD A,(HL)
Load register A with the ASCII value at the location of the keyboard lookup table pointer in register pair HL.
044BH
LD D,A
Load register D with the ASCII value for the key pressed in register A.
044CH-044EH
LD BC,0DACH
Load register pair BC with the delay count (which is 3500).
044FH-0451H
Call the delay routine at 0060H (which will delay BC times 14.65).
0452H
LD A,D
Load register A with the ASCII value for the key pressed in register D.
0453H-0454H
CP 01H
Check to see if the BREAK key was pressed.
0455H
RET NZ
Return if the BREAK key wasn’t pressed.
0456H
RST 28H
If the BREAK key was pressed,call the DOS FUNCTION CALL routine at RST 28 (which passes request code in A-register to DOS for processing. Returns for non-disk system. For disk systems, the A register must contain a legitimate DOS function code. If the code is positive, the CALL is ignored and control returns to the caller. Note that the DOS routine discards the return address stored on the stack by the RST instruction. After processing control will be returned to the previous address on the stack).
0457H
RET
Return.

0458H-058CH – VIDEO DRIVER

  • This is the video driver. The character to be displayed should be in the C register. This routine handles scrolling etc.
0458H-045AH
LD L,(IX+03H)
Load register L with the LSB of the current cursor position at the location of the video device control block pointer in register pair IX plus three.
045BH-045DH
LD H,(IX+04H)
Load register H with the MSB of the current cursor position at the location of the video device control block pointer in register pair IX plus four.
045EH-045FH
Jump to 049AH if get last character.
0460H-0462H
LD A,(IX+05H)
Load register A with the cursor on/off flag (which is stored at the location of the video device control block pointer in register pair IX plus five).
0463H
OR A
Check to see if the cursor is on or off.
0464H-0465H
Jump to 0467H if the cursor is off.
0466H
LD (HL),A
Display the character in register A at the location of the current cursor position in register pair HL since the cursor is on.
0467H
LD A,C
Load register A with the character to be displayed in register C.
0468H-0469H
CP 20H
Check to see if the character to be displayed in register A is a control code.
046AH-046CH
Jump to 0506H if the character to be displayed in register A is a control code.
046DH-046EH
CP 80H
Check to see if the character to be displayed in register A is a graphic character or space compression code.
046FH-0470H
Jump to 04A6H if the character to be displayed in register A is a graphic character or space compression code.
0471H-0472H
CP 40H
Check to see if the character to be displayed in register A is an alphabetic character.
0473H-0474H
Jump to 047DH if the character to be displayed in register A is a nonalphabetic character.
0475H-0476H
SUB 40H
Adjust the alphabetic character in register A down by 64 so that it will be in the range of from 0 to 25.
0477H-0478H
CP 20H
Check to see if the character to be displayed in register A is a lower case character.
0479H-047AH
Jump to 047DH if the character to be displayed in register A isn’t lower case.
047BH-047CH
SUB 20H
Convert the lower case character in register A to upper case by subtracting 32.
047DH-047FH
Go to 0541H display the character in register A (and scroll the screen if necessary).
0480H
LD A,H
Load register A with the MSB of the current cursor position in register H.
0481H-0482H
AND 03H
Mask the value in register A so that it will be in the range of video memory (3C00H-3FFFH) by ANDing it against 0000 0011.
0483H-0484H
OR 3CH
Force the MSB of the buffer to be 3C-3Fh (i.e., video memory) by ORing it against 0011 1100.
0485H
LD H,A
Load register H with the updated MSB value (which was forced to be within video memory) in register A.
0486H
LD D,(HL)
Load register D with the value at the location of the current cursor position in register pair HL.
0487H-0489H
LD A,(IX+05H)
Load register A with the cursor on/off flag at the location of the video device control block pointer in register pair IX plus five.
048AH
OR A
Check to see if the cursor is on or off.
048BH-048CH
Jump to 0492H if the cursor is off.
048DH-048FH
LD (IX+05H),D
Since the cursor is on, save the character being displayed in register D as the cursor on/ off flag at the location of the video device control block pointer in register pair IX plus five.
0490H-0491H
LD (HL),5FH
Display the cursor character (of 5FH) at the current location of the cursor in register pair HL.
0492H-0494H
LD (IX+03H),L
Save the LSB of the current cursor position in register L at the location of the video device control block in register pair IX plus three.
0495H-0497H
LD (IX+04H),H
Save the MSB of the current cursor position in register H at the location of the video device control block in register pair IX plus four.
0498H
LD A,C
Load register A with the character that was displayed in register C.
0499H
RET
Return.

049AH-049CH
LD A,(IX+05H)
Load register A with the cursor on/off flag.
049DH
OR A
Check to see if the cursor is on or off.
049EH
RET NZ
Return if the cursor is on.
049FH
LD A,(HL)
If the cursor is off, show the character it was hiding instead by loading Register A with the character at the location of the current cursor position in register pair HL.
04A0H
RET
Return.

04A1H
LD A,L
Load register A with the LSB of the current position in register L.
04A2H-04A3H
AND C0H
Point to the beginning of the line by ANDing it against 1100 0000 to remove the lowest 6 bits (so it will be XX00H, XX40H, XX80H, or XXC0H).
04A4H
LD L,A
Load register L with the updated value in register A.
04A5H
RET
Return with the new video buffer address stored in HL.

04A6H-04A7H
CP C0H
Check to see if the character to be displayed in register A is a space compression character.
04A8H-04A9H
Jump to 047DH if the character to be displayed in register A isn’t a space compression character (which means it is a graphic character).
04AAH-04ABH
SUB C0H
Now we know we have a space compresison code, so adjust the value in register A so that it will hold the number of spaces to be displayed.
04ACH-04ADH
Jump to 0480H if there aren’t any spaces to be displayed.
04AEH
LD B,A
Now we know it is a space compression character and that at least one space is to be displayed, so load register B with the number of spaces to be displayed in register A.
04AFH-04B0H
LD A,20H
Load register A with a space character.
04B1H-04B3H
Gosub to 0541H to display the blank character in register A (and scroll the screen if necessary).
04B4H-04B5H
Loop back to 04AFH until all of the spaces have been displayed.
04B6H-04B7H
Once all the spaces have been displayed, jump to 0480H.
04B8H
LD A,(HL)
Load Register A with the character being displayed at the location of the current cursor position in register pair HL.
04B9H-04BBH
LD (IX+05H),A
Save the value in register A as the cursor on/off flag at the location of the video device control block pointer in register pair IX plus five.
04BCH
RET
Return.

04BDH
XOR A
Zero register A to turn the cursor flag off.
04BEH-04BFH
Jump to 04B9H.
04C0H-04C2H
LD HL,3C00H
Load register pair HL with the starting address of video memory (which is 3C00H).
04C3H-04C5H
LD A,(403DH)
Load register A with the 32/64 character per line flag (which is stored at 403DH).

This changes display to 64 character mode (A register is used).
Note: 403DH-4040H is used by DOS.
04C6H-04C7H
AND F7H
Adjust the value in register A for 64 characters per line by clearing the 32 character/line bit (i.e., AND it againt 1111 0111).
04C8H-04CAH
LD (403DH),A
Save the value in register A as the 32/64 character per line flag (which is at 403DH).
Note: 403DH-4040H is used by DOS.
04CBH-04CCH
OUT (FFH),A
Send the value in register A out port 255 which is the video/cassette port.
04CDH
RET
Return.

04CEH
DEC HL
Decrement the current cursor position (i.e., backspace) in register pair HL.
04CFH-04D1H
LD A,(403DH)
Load register A with the 32/64 character per line flag (which is at 403DH).
Note: 403DH-4040H is used by DOS.
04D2H-04D3H
AND 08H
Check to see if it’s 32 or 64 characters per line by ANDing it against 0000 1000.
04D4H-04D5H
Jump to 04D7H if it’s 64 characters per line.
04D6H
DEC HL
Right now we know it is 32 characters per line, so we need to backspace AGAIN by decrementing the current cursor position in register pair HL.
04D7H-04D8H
LD (HL),20H
Display a space character at the location of current cursor position in register pair HL.
04D9H
RET
Return.

04DAH-04DCH
LD A,(403DH)
Load register A with the 32/64 character per line flag (which is at 403DH).
Note: 403DH-4040H is used by DOS.
04DDH-04DEH
AND 08H
Check to see if it’s 32 or 64 characters per line by ANDing it against 0000 1000.
04DFH-04E1H
Gosub to 04E2H if it’s 32 characters per line.
04E2H
LD A,L
Since we now know its 64 characters per line, load register A with the LSB of the current cursor position in register L.
04E3H-04E4H
AND 3FH
Mask the value in register A by ANDing it against 0011 1111 to backspace LSB of curstor to the previous line and then …
04E5H
DEC HL
Backspace the cursor by 1 by decrementing the current cursor position in register pair HL.
04E6H
RET NZ
Return if still on the same line.
04E7H-04E9H
LD DE,0040H
We know we are not on the same line anymore so load register pair DE with the length of a line on the video display (which is 64).
04EAH
ADD HL,DE
Skip down 1 line by adding the length of a line on the video display in register pair DE to the current cursor position in register pair HL.
04EBH
RET
Return.

04ECH
INC HL
Increment the current cursor position in register pair HL.
04EDH
LD A,L
Load register A with the LSB of the current cursor position in register L.
04EEH-4EFH
AND 3FH
Check to see if the cursor is still on the same line via an overflow through ANDing it against 0011 1111.
04F0H
RET NZ
Return if the cursor is still on the same line.
04F1H-04F3H
LD DE,FFC0H
Now we know the cursor is no longer on the same line, so we need to load register pair DE with a negative length of a line on the video display (which is -64).
04F4H
ADD HL,DE
Add the negative length of a line on the video display in register pair DE (i.e., -64) to the current cursor position in register pair HL.
04F5H
RET
Return.

04F6H-04F8H
LD A,(403DH)
This routine is going to change the display to 32 character mode so first we need to load register A with the 32/64 character per line flag stored at 04F6H.
Note: 403DH-4040H is used by DOS.
04F9H-04FAH
OR 08H
Adjust the value in register A for 32 characters per line by ORing it against 0000 1000.
04FBH-04FDH
LD (403DH),A
Save the resulting value in register A back into 403DH (the 32/64 character per line flag).
Note: 403DH-4040H is used by DOS.
04FEH-04FFH
OUT (FFH),A
Send the value in register A out the port 255 (the video/cassette).
0500H
INC HL
Increment the current cursor position in register pair HL.
0501H
LD A,L
Load register A with the LSB of the current cursor position in register L.
0502H-0503H
AND FEH
Make the LSB value (in register A) to be an even value (since we are in 32 character per line mode) by ANDing it against 1111 1110.
0504H
LD L,A
Load register L with the updated value in register A.
0505H
RET
Return.

0506H-0508H
“CURCON”
LD DE,0480H
Load register pair DE with the return address.
0509H
PUSH DE
Save the return address in register pair DE on the stack.
050AH-050BH
CP 08H
Check to see if the character in register A is a backspace and erase character (i.e., 08H).
050CH-050DH
Jump to 04CEH if the character to be displayed in register A is a backspace cursor and erase character.
050EH-050FH
CP 0AH
Check to see if the character in register A is less than a line feed character.
0510H
RET C
Return if the character to be displayed in register A is less than a line feed character so we can ignore them.
0511H-0512H
CP 0EH
Check to see if the character to be displayed in register A is less than or equal to a turn on the cursor character.
0513H-0514H
Jump if the character to be displayed in register A is less than a turn on the cursor character so that a carriage return will be displayed.
0515H-0516H
Jump if the character to be displayed in register A is a turn on the cursor character.
0517H-0518H
CP 0FH
Check to see if the character in register A is a turn off the cursor character.
0519H-051AH
Jump if the character to be displayed in register A is a turn off the cursor character.
051BH-051CH
CP 17H
Check to see if the character to be displayed in register A is a turn on the 32 character per line mode character.
051DH-051EH
Jump if the character to be displayed in register A is a turn on the 32 character per line mode character.
051FH-0520H
CP 18H
Check to see if the character to be displayed in register A is a left arrow character.
0521H-0522H
Jump if the character to be displayed in register A is a left arrow character.
0523H-0524H
CP 19H
Check to see if the character to be displayed in register A is a right arrow character.
0525H-0526H
Jump if the character to be displayed in register A is a right arrow character.
0527H-0528H
CP 1AH
Check to see if the character to be displayed in register A is a down arrow character.
0529H-052AH
Jump if the character to be displayed in register A is a down arrow character.
052BH-052CH
CP 1BH
Check to see if the character to be displayed in register A is an up arrow character.
052DH-052EH
Jump if the character to be displayed in register A is an up arrow character.
052FH-0530H
CP 1CH
Check to see if the character to be displayed in register A is a home the cursor character.
0531H-0532H
Jump if the character to be displayed in register A is a home the cursor character.
0533H-0534H
CP 1DH
Check to see if the character to be displayed in register A is a backspace to the beginning of the line character.
0535H-0537H
Jump if the character to be displayed in register A is a backspace to the beginning of the line character.
0538H-0539H
CP 1EH
Check to see if the character to be displayed in register A is an erase to the end of the line character.
053AH-053BH
Jump if the character to be displayed in register A is an erase to the end of the line character.
053CH-053DH
CP 1FH
Check to see if the character to be displayed in register A is an erase to the end of the screen character.
053EH-053FH
Jump if the character to be displayed in register A is an erase to the end of the screen character.
0540H
RET
Return if the character to be displayed isn’t any of the above control codes.

  • 0541H – This subroutine displays the character in register A at the location HL and scrolls the screen if needed.
0541H
LD (HL),A
Put the character stored in A into the memory location stored in HL.
0542H
INC HL
Increment the current cursor position in register pair HL.
0543H-0545H
LD A,(403DH)
Load register A with the 32/64 character per line flag (stored in 403DH).
Note: 403DH-4040H is used by DOS.
0546H-0547H
AND 08H
Check to see if it’s 32 or 64 characters per line by ANDing it against 0000 1000.
0548H-0549H
Jump to 054BH if it’s 64 characters per line.
054AH
INC HL
Increment the current cursor position in register pair HL.
054BH
LD A,H
Load register A with the MSB of the current cursor position in register H.
054CH-054DH
CP 40H
Check to see if the end of video memory plus one has been reached.
054EH
RET NZ
Return if the end of video memory plus one hasn’t been reached.
054FH-0551H
LD DE,FFC0H
Load register pair DE with a negative length of a line on the video display (i.e., -64).
0552H
ADD HL,DE
Move the pointer back 1 line by adding the negative length of a line on the video display in register pair DE to the current cursor position in register pair HL.
0553H
PUSH HL
Save the current cursor position in register pair HL on the stack.
  • To use a ROM call to scroll (shift the entire display upward one line), CALL 0553H.
0554H-0556H
LD DE,3C00H
Load register pair DE with the starting address of video memory.
0557H-0559H
LD HL,3C40H
Load register pair HL with the starting address of the second line of the video memory.
055AH
PUSH BC
Save the value in register pair BC on the stack.
055BH-055DH
LD BC,03C0H
Load register pair BC with the length of video memory to be moved (which is 15 lines or 960 bytes).
055EH-055FH
LDIR
Move the last fifteen lines of video memory to the first fifteen lines of video memory to scroll 1 line.
0560H
POP BC
Get the value from the stack and put it in register pair BC.
0561H
EX DE,HL
Load register pair HL with the starting address of the sixteenth line of video memory.
0562H-0563H
Jump forward to 057DH.
0564H
LD A,L
Load register A with the LSB of the current cursor position in register L.
0565H-0566H
AND C0H
Adjust the value in register A so that it’s the start of the current line by ANDing it with 1100 0000.
0567H
LD L,A
Load register L with the updated value in register A.
0568H
PUSH HL
Save the current cursor position in register pair HL on the stack.
0569H-056BH
LD DE,0040H
Load register pair DE with the length of a line on the video display (which is 64).
056CH
ADD HL,DE
Add the length of a line on the video display in register pair DE to the current cursor position in register pair HL.
056DH
LD A,H
Load register A with the MSB of the current cursor position in register H.
056EH-056FH
CP 40H
Check to see if the end of video memory plus one has been reached (which is 64).
0570H-0571H
Jump to 0554H (to scroll the screen) if the end of video memory plus one has been reached.
0572H
POP DE
Get the cursor position from the stack and put it in register pair DE.
0573H
PUSH HL
Save the new cursor position in register pair HL on the stack.
0574H
LD D,H
Load register D with the MSB of the current cursor position in register H.
0575H
LD A,L
Load register A with the LSB of the current cursor position in register L.
0576H-0577H
OR 3FH
Isolate the screen line by masking the value in register A by ORing it against 0011 1111.
0578H
LD E,A
Save the updated value in register A in register E.
0579H
INC DE
Increment the adjusted cursor position in register pair DE.
057AH-057BH
Jump forward to the line blanking code of 0580H.
057CH
PUSH HL
Save the cursor position in register pair HL on the stack.

Clear to end of frame routine. To use this routine load the HL register pair with the screen address from which you want the erasing to start. The DE and A registers are used.
  • To use a ROM call to clear the video screen from (including) position N – where N is an integer between 0 and 1023 (decimal), inclusive – to the end of the display, Load the HL register with the value 3C00H + N and then CALL 057CH.
057DH-057FH
LD DE,4000H
Load register pair DE with the end of video memory plus one (which is 4000H).
0580H-0581H
LD (HL),20H
Display a space (which is 20H) at the video memory pointer in register pair HL.
0582H
INC HL
Increment the video memory pointer in register pair HL.
0583H
LD A,H
Load register A with the MSB of the video memory pointer m register H.
0584H
CP D
Check to see if the MSB of the video memory pointer in register A is the same as the MSB of the ending memory pointer in register D.
0585H-0586H
Jump back to 0580H (display a space and move forward 1) if the MSB of the video memory pointer in register A isn’t the same as the MSB of the ending memory pointer in register D.
0587H
LD A,L
Load register A with the LSB of the video memory pointer in register L.
0588H
CP E
Check to see if the LSB of the video memory pointer in register A is the same as the LSB of the ending memory pointer in register E.
0589H-058AH
Jump to 0580H (display a space and move forward 1) if the LSB of the video memory pointer in register A isn’t the same as the LSB of the ending memory pointer in register E.
058BH
POP HL
Get the current cursor position from the stack and put it in register pair HL.
058CH
RET
Return.

058DH-0D8H – PRINTER DRIVER

  • LPRINT driver routine, handling printer I/O etc. The character to be printed should be in register C.
058DH
LD A,C
Load register A with the character to be sent to the printer in register C.
058EH
OR A
Set the status flags and test A to see if it is zero.
058FH-0590H
Jump to 05D1H (get the printer status and return) if the character to be sent to the printer in register A is equal to zero.
0591H-0592H
CP 0BH
Check to see if the character to be sent to the printer in register A is a skip to the top of the form character which is CHR$(11).
0593H-0594H
Jump to 059FH if the character to be sent to the printer in register A is a skip to the top of the form character.
0595H-0596H
CP 0CH
Check to see if the character to be sent to the printer in register A is a conditional skip to the top of the form character which is CHR$(12).
0597H-0598H
Jump to 05B4H if the character to be sent to the printer in register A isn’t a conditional skip to the top of the form character.
0599H
XOR A
Zero register A (which causes the null character to be printed).
059AH-059CH
OR (IX+03H)
Check to see if the number of lines per page at the location of the printer device control block pointer in register pair IX plus three is the same as the value in register A.
059DH-059EH
Jump to 05B4H if zero lines are to be skipped.
059FH-05A1H
LD A,(IX+03H)
Load register A with the number of lines per page at the location of the printer device control block in register pair IX plus three.
05A2H-05A4H
SUB (IX+04H)
Subtract the lines printed so far at the location of the printer device control block pointer in register pair IX plus four from the number of lines per page in register A.
05A5H
LD B,A
A now has the number of lines to skip, so load B with with the number of lines to skip (since DJNZ loops based on B).
05A6H-05A8H
Call the GET PRINTER STATUS routine at 05D1H (which returns the status of the line printer in the status register as 0 if the printer is ready, and otherwise with a reason code if not ready).
05A9H-05AAH
Loop bac to 05A6H until the printer is ready.
05ABH-05ACH
LD A,0AH
Now the printer is ready and B has the number of lines to skip. Load register A with a line feed character which is CHR$(10).
05ADH-05AFH
LD (37E8H),A
Send the value in register A to the printer by loading it into memory location 37E8H.
05B0H-05B1H
Loop back to 05A6H until all of the lines have been skipped.
05B2H-05B3H
Now all the lines have been skipped, so jump to 05CCH to reset the line counter and return.
05B4H
PUSH AF
Save the character to be sent to the printer in register A on the stack.
05B5H-05B7H
Call the GET PRINTER STATUS routine at 05D1H (which returns the status of the line printer in the status register as 0 if the printer is ready, and otherwise with a reason code if not ready).
05B8H-05B9H
Loop back to 05B5H until the printer is ready.
05BAH
POP AF
Get the character to be sent to the printer from the stack and put it in register A.
05BBH-05BDH
LD (37E8H),A
Send the character in register A to the printer by putting the character into 37E8H.
05BEH-05BFH
CP 0DH
Check to see if the character which was just sent to the printer was a carriage return.
05C0H
RET NZ
If the character sent to the printer in register A isn’t a carriage return, return out of the print routine.
05C1H-05C3H
INC (IX+04H)
Now we know the printer just got a carriage return, so increment the number of lines printed so far at the location of the printer device control block pointer in register pair IX plus four.
05C4H-05C6H
LD A,(IX+04H)
Load register A with the number of lines printed so far at the location of the printer device control block pointer in register pair IX plus four.
05C7H-05C9H
CP (IX+03H)
Check to see if the number of lines printed so far in register A is the same as the number of lines per page at the location of the printer device control block pointer in register pair IX plus three.
05CAH
LD A,C
Load register A with the character sent to the printer in register C.
05CBH
RET NZ
Return if the number of lines printed so far isn’t the same as the number of lines per page.
05CCH-05CFH
LD (IX+04H),04H
Zero the number of lines printed so far at the location of the printer device control block pointer in register pair IX plus four.
05D0H
RET
Return.

05D1H – Get printer status routine.

  • A call to 05D1 will return the status of the line printer in the status register as 0 if the printer is ready/selected, and non-zero if not ready, as follows:
    • Bit 7 = Printer Busy. 1=Busy
    • Bit 6 = Paper Status. 1= Out of paper.
    • Bit 5 = Printer Ready. 1 = Ready.
    • All other bits are not used.
05D1H-05D3H
LD A,(37E8H)
Get the status value from the printer (which is held in 37E8H) and put it in register A.
05D4H-05D5H
AND F0H
Since only bits 7, 6, and 5 are used, mask out the rest of Register A by ANDing it against 1111 0000.
05D6H-05D7H
CP 30H
Check to see if the printer is ready by comparing the ANDed value against 0011 0000 (which isolates bits 5 and 4, so the result is either ZERO if they are set or anything else if they are not).
05D8H
RET
Return.

05D9H-0673H – ACCEPT KEYBOARD INPUT ROUTINE
“KLINE”

  • This is the most basic of the string input routines and is used by the two others (1BB3H and 0361H) as a subroutine. To use it, load HL with the required buffer address and the B register with the maximum buffer length required. Keyboard input over the specified maximum buffer length is ignored, and after pressing the (ENTER) key it will return with HL containing the original buffer address and B with the string length.
    A call to this memory location Accepts keyboard input and stores each character in a buffer supplied by caller. Input continues until either a carriage return or a BREAK is typed, or until the buffer is full. All edit control codes are recognized, e.g. TAB, BACKSPACE, etc.
    On exit the registers contain: HL=Buffer address, B=Number of characters transmitted excluding last, C=Orginal buffer size, A=Last character received if a carriage return or BREAK is typed. Carry Set if break key was terminator, reset otherwise. If the buffer is full, the A register will contain the buffer size.
  • To use a ROM call to accept a restricted number of keyboard characters for input (n), use:
    LD HL,(40A7H)
    LD B,n
    CALL 05D9H
    Up to n characters will be accepted, after which the keyboard will simply be ignored until the ENTER (or LEFT ARROW, or BREAK, or CLEAR) key is pressed. These characters will be stored in consecutive memory cells starting at the address contained in 40A7H-40A8H (the keyboard buffer area), with a 0DH (carriage return) byte at the end. Upon completion, the HL register pair will contain the address of the first character of the stored input, and the B register will contain the number of characters entered. NOTE: No “?” is displayed as a result of the execution of the above program. If the “?” display is desired to prompt the typing of the input, precede the above program segment with:
    LD A,3FH
    CALL 033AH
    LD A,20H
    CALL 033AH
05D9H
“LINP1”
PUSH HL
Save the start of the input buffer area pointer in register pair HL on the stack.
05DAH-05DBH
LD A,0EH
Load register A with a turn on the cursor character (which is 14).
05DCH-05DEH
Display a cursor by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
05DFH
LD C,B
Load register C with the size of the input buffer in register B.
05E0H-05E2H
Call the “WAIT FOR KEYBOARD INPUT” routine at 0049H, so as to wait until a key is pressed.
05E3H-05E4H
CP 20H
Check to see if the key that was pressed in register A is greater than a SPACE.
05E5H-05E6H
Jump if the key that was pressed in register A is greater than or equal to a SPACE.
05E7H-05E8H
CP 0DH
Check to see if the key that was pressed in register A is a CARRIAGE RETURN.
05E9H-05EBH
Jump if the key that was pressed in register A is a CARRIAGE RETURN.
05ECH-05EDH
CP 1FH
Check to see if the key that was pressed in register A is the CLEAR key.
05EEH-05EFH
Jump if the key that was pressed in register A is the CLEAR key.
05F0H-05F1H
CP 01H
Check to see if the key that was pressed in register A is the BREAK key.
05F2H-05F3H
Jump if the key that was pressed in register A is the BREAK key.
05F4H-05F6H
LD DE,05E0H
Load register pair DE with the return address of 05E0H.
05F7H
PUSH DE
Save the return address in register pair DE on the stack.
05F8H-05F9H
CP 08H
Check to see if the key that was pressed in register A is a backspace (which is 08) the cursor and erase character.
05FAH-05FBH
Jump if the key was pressed in register A is a backspace the cursor and erase character.
05FCH-05FDH
CP 18H
Check to see if the key that was pressed in register A is a backspace character.
05FEH-05FFH
Jump if the key that was pressed in register A is a backspace character.
0600H-0601H
CP 09H
Check to see if the key that was pressed in register A is a tab character.
0602H-0603H
Jump if the key that was pressed in register A is a tab character.
0604H-0605H
CP 19H
Check to see if the key that was pressed in register A is a turn on the 32 character per line mode character.
0606H-0607H
Jump if the key that was pressed in register A is a turn on the 32 character per line mode character.
0608H-0609H
CP 0AH
Check to see if the key that was pressed in register A is a line feed character of CHR$(10).
060AH
RET NZ
Return (to 05E0H) if the key that was pressed in register A isn’t a line feed character.
060BH
POP DE
Get the return address from the stack and put it in register pair DE (so that it isn’t 05E0H anymore).
060CH
LD (HL),A
We now know that the key pressed is a printable character so save the key that was pressed in register A at the location of the input buffer pointer in register pair HL.
060DH
LD A,B
Load register A with the length of the buffer remaining in register B.
060EH
OR A
Check to see if there is any more of the input buffer remaining (and set status).
060FH-0610H
Jump to 05E0H if the end of the input buffer has been reached.
0611H
LD A,(HL)
Now we know the end of the input buffer has not been reached, so load register A with the value at the location of the input buffer pointer in register pair HL.
0612H
INC HL
Increment the input buffer pointer in register pair HL.
0613H-0615H
Display the character by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
0616H
DEC B
Decrement the number of bytes remaining in the input buffer area in register B.
0617H-0618H
Jump to 05E0H to get the next character.
0619H-061BH
Call the CLEAR SCREEN routine at 01C9H (which clears the screen, changes to 64 characters, and homes the screen).
061CH
LD B,C
Load register B with the length of the input buffer in register C (which resets the counter of characters transmitted).
061DH
POP HL
Get the starting address for the input buffer area from the stack and put it in register pair HL (which resets the buffer address).
061EH
PUSH HL
Save the starting address for the input buffer area in register pair HL on the stack.
061FH-0621H
Jump to 05E0H (to get the next character, which is now the first character in the buffer).
0622H-0624H
Gosub to wait for the next key and back up the input buffer pointer in register pair HL if necessary.
0625H
DEC HL
Backup to the previous character (the one before the CARRIAGE RETURN) by decrementing the input buffer pointer in register pair HL.
0626H
LD A,(HL)
Load register A with the character at the location of the input buffer pointer in register pair HL.
0627H
INC HL
Increment the input buffer pointer in register pair HL to the net availabile position.
0628H-0629H
CP 0AH
Check to see if the character in register A is the line feed character of CHR$(10).
062AH
RET Z
Return if the character in register A is a line feed character.
062BH
LD A,B
Now we know that character wasn’t a line feed, so we need to test for a buffer full. This loads register A with the number of bytes remaining in the input buffer area in register B.
062CH
CP C
Check to see if the number of characters remaining in the input buffer area in register A is the same as the length of the input buffer area in register C.
062DH-062EH
Jump to 0622H if there is room for more characters.
062FH
RET
The buffer is full! Return.

0630H – This subroutine assumes B is the number of characters received, and C is the size of the buffer.

0630H
LD A,B
Load register A with the number of bytes remaining in the input buffer area in register B.
0631H
CP C
Compare the number of bytes remaining in the input buffer (held in Register A) against the size of the buffer (held in Register C) to see if the buffer is full.
0632H
RET Z
Return if the input buffer area is full.
0633H
DEC HL
Decrement the input buffer area pointer in register pair HL to backspace the previous character …
0634H
LD A,(HL)
… and then get that character into Register A.
0635H-0636H
CP 0AH
Check to see if the character in register A is the line feed character of CHR$(10).
0637H
INC HL
Increment the input buffer area pointer in register pair HL.
0638H
RET Z
Return if the character in register A is a line feed character.
0639H
DEC HL
Decrement the input buffer area pointer in register pair HL to backspace the previous character in the buffer …
063AH-063BH
LD A,08H
Load register A with a backspace of CHR$(08) and then …
063CH-063EH
Effectuate the backspace by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
063FH
INC B
Increment the number of characters remaining in the input buffer area in register B.
0640H
RET
Return.

0641H – This subroutine sends the position command.

0641H-0642H
LD A,17H
Load register A with “23” so as to turn on the 32 character per line mode character.
0643H-0645H
Call the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen). Since that is the 32 character per line mode, that’s what happens.
0646H-0648H
Go get the cursor line position and return with it in register A.
0649H-064AH
AND 07H
Mask the cursor line position in register A by ANDing it against 0000 0111.
064BH
CPL
Inverse the value in register A.
064CH
INC A
Increment the value in register A so that it is 1 <= A <= 8.
064DH-064EH
ADD 08H
Clear the upper bits of the counter.
064FH
LD E,A
Load register E with the number of spaces to be added in register A.
0650H
LD A,B
Load register A with the number of bytes remaining in the input buffer area in register B.
0651H
OR A
Check to see if the buffer is full.
0652H
RET Z
Return if the input buffer is full.
0653H-0654H
LD A,20H
Load register A with a space character.
0655H
LD (HL),A
Save the space character in register A at the location of the input buffer area pointer in register pair HL.
0656H
INC HL
Increment the input buffer area pointer in register pair HL.
0657H
PUSH DE
Save the value in register pair DE on the stack.
0658H-065AH
Display the space by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
065BH
POP DE
Get the value from the stack and put it in register pair DE.
065CH
DEC B
Since you just displayed one of the spaces, decrement the number of bytes remaining in the input buffer area in register B …
065DH
DEC E
… and decrement the number of spaces to be added in register E.
065EH
RET Z
Return if the number of spaces has been added to the input buffer.
065FH-0660H
Loop back to 0650H until all the spaces have been added to the input buffer.

0661H – This subroutine is called when a BREAK key is hit.

0661H
SCF
Set the Carry flag.
0662H
PUSH AF
Save the value in register pair AF on the stack.
0663H-0664H
LD A,0DH
Load register A with a carriage return character.
0665H
LD (HL),A
Save the carriage return character in register A at the location of the input buffer area pointer in register pair HL.
0666H-0668H
Display the carriage return by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen). Since that is a CARRIAGE RETURN, that’s what happens.
0669H-066AH
LD A,0FH
Load register A with a turn off the cursor character.
066BH-066DH
Turn off the cursor by calling the DISPLAY A CHARACTER routine at 0033H (which puts the character in register A on the video screen).
066EH
LD A,C
Load register A with the length of the input (=buffer size) in register C.
066FH
SUB B
Subtract the number of bytes remaining in the input buffer area in register B from the length of the input buffer area in register A.
0670H
LD B,A
Load register B with the number of characters in the input buffer area in register A.
0671H
POP AF
Get the value from the stack and put it in register pair AF. This also sets the CARRY flag if BREAK and unsets it if CARRIAGE RETURN.
0672H
POP HL
Get the starting address of the input buffer area from the stack and put it in register pair HL.
0673H
RET
Return.

0674H-06D1H – INITIALIZATION ROUTINE

0674H-0675H
OUT (FFH),A
Send the zero in register A out the video/cassette port.
0676H-0678H
LD HL,06D2H
Load register pair HL with the starting address of the video/keyboard/printer DCB’s.
0679H-067BH
LD DE,4000H
Load register pair DE with the starting address of the communications region.
067CH-067EH
LD BC,0036H
Load register pair BC with the length of the ROM area to be moved (which is 54 bytes).
067FH-0680H
LDIR
Move the 06D2H-0707H to 4000H-4035H.
0681H
DEC A
Decrement the value in register A.
0682H
DEC A
Decrement the value in register A.
0683H-0684H
Loop back to 0674H until the block move has occurred 128 times, jump to 0674H (which sends a click to the cassette port).
*0683H-0684H
Loop back to 0676H until the block move has occurred 128 times, jump to 0676H (which runs the routine AFTER the click, so no more click).
0685H-0686H
LD B,27H
Load register B with the number of bytes of memory to be zeroed (which is 39).
0687H
LD (DE),A
Save the zero in register A at the location of the memory pointer in register pair DE.
0688H
INC DE
Increment the destination pointer in register pair DE.
0689H-068AH
Loop back to 0687H until all of the memory locations between 4036H and 4062H have been zeroed.
068BH-068DH
LD A,(3840H)
Load register A with the location of keyboard memory for the BREAK key (which is 14400).
068EH-068FH
AND 04H
Check to see if the BREAK key is being pressed.
0690H-0692H
Jump to 0075H if the BREAK key was pressed.
0693H-0695H
LD SP,407DH
Set the stack pointer to 407DH.
0696H-0698H
LD A,(37ECH)
Load register A with the status of the disk controller (which is stored in 37ECH).
0699H
INC A
Increment the value in register A so that we can …
069AH-069BH
CP 02H
… check to see if the disk controller is present.
069CH-069EH
Jump to the Level II Initialization Routine at 0075H if the disk controller isn’t present.
069FH-06A0H
LD A,01H
So now we know there is a disk controller, so lets load register A with the drive to turn on.
06A1H-06A3H
LD (37E1H),A
Turn on drive 0 (by loading 01 into 37E1H).
06A4H-06A6H
LD HL,37ECH
Load register pair HL with the address of the disk command/status register of 37ECH.
06A7H-06A9H
LD DE,37EFH
Load register pair DE with the address of the disk data register of 37EFH.
06AAH-06ABH
LD (HL),03H
Load the disk command/status register (37ECH) with command 03H (which restores and positions to track 0).
06ACH-06AEH
LD BC,0000H
Load register pair BC with the delay count.
06AFH-06B1H
Call the delay routine at 0060H (which will delay BC times 14.65).
06B2H-06B3H
BIT 0,(HL)
Check to see if the disk is busy by testing 37ECH.
06B4H-06B5H
Loop back to that test in 06B2H until the disk is no longer busy.
06B6H
XOR A
Zero register A.
06B7H-06B9H
LD (37EEH),A
Save the value in register A in the disk sector register (at 37EEH).
06BAH-06BCH
LD BC,4200H
Load register pair BC with the address in memory to place the sector read (which is 4200H).
06BDH-06BEH
LD A,8CH
Load register A with the command to read the sector.
06BFH
LD (HL),A
Put the command in register A (read the sector) in the disk command register of 37ECH.
06C0H-06C1H
BIT 1,(HL)
Check the disk command/status register of 37ECH to see if there is data available.
06C2H-06C3H
Loop back to 06C0H until there is data available.
06C4H
LD A,(DE)
So now we know there is data available, so we load register A with the byte read from the disk (i.e., the data in disk data register of 37EFH).
06C5H
LD (BC),A
Save the value in register A at the location of the memory pointer in register pair BC.
06C6H
INC C
Increment the LSB of the memory pointer in register C.
06C7H-06C8H
Loop back to 06C0H until the whole 256 bytes of the sector has been read into 4200H-4455H.
06C9H-06CBH
Now that the entire first sector has been read into 4200H-4455H, jump to 4200H.

06CCH-06CEH – Alternative re-entry point into BASIC.

  • A JP to here is often better than a jump to lA19H as the latter sometimes does strange things to any resident BASIC program.
06CCH-06CEH
LD BC,1A18H
Load register pair BC with the starting address of the Level II BASIC READY routine (which is kept at 1A18H).
06CFH-06D1H
Jump to 19AEH to initialize BASIC’s variables and pointers.

06D2H-0707H – ROM STORAGE LOCATION FOR DATA TO BE MOVED TO RAM BY THE INITIALIZATION PROCESS.

06D2H
This will be 4000H – it is a jump to the RST 08H routine (COMPARE SYMBOL routine).
06D5H
This will be 4003H – it is a jump to RST 10H (get the next character)
06D8H
This will be 4006H – it is a jump to RST 18H (compare DE and HL)
06DBH
This will be 4009H – it is a jump to RST 20H (tests for data type)
06DEH
RET
This will be 400CH – is a RETurn from RST 28H (which is a jump to 4BA2H for DOS)

06DFH
NOP
06E0H
NOP
06E1H
RET
This will be 400FH – it is a RETurn from RST 30H (which is a jump to 44B4H for DOS)

06E2H
NOP
06E3H
NOP
This will be 4012H – RST 38H vector DI/RET (JP 4518H for DOS)
06E4H
EI
This is the interrfupt entry point vector
06E5H
RET

06E6H
NOP
06E7H
LD BC,03E3H
This will be 4015H – The keyboard DCB
06EAH
NOP
06EBH
NOP
06ECH
NOP
06EDH
LD C,E
06EEH
LD C,C
This will be 401DH – The video DCB
06EFH
RLCA
06F0H
LD E,B
06F1H
INC B
06F2H
NOP
06F3H
INC A
06F4H
NOP
06F5H
LD B,H
06F6H
LD C,A
This will be 4025H – The line printer DCB
06F7H
LD B,8DH
06F9H
DEC B
06FAH
LD B,E
06FBH
NOP
06FCH
NOP
06FDH
LD D,B
06FEH
LD D,D
06FFH
JP 5000H
This will be 402DH, and SYS 0 will change this to JP 4400H
0702H
RST 00H
This will be 4030H, and SYS 0 will change this to LD A,A3H
0703H
NOP
0704H
NOP
This will be 4032H, and SYS 0 will change this to RST 28H
0705H
LD A,00H
This will be 4033H, and SYS 0 will change this to 44BBH
0707H
RET

070BH-070FH – SINGLE PRECISION ADDITION, REG 1 = (HL) + REG 1

  • Single-precision addition (REG 1=(HL)+ACC) involving a buffer pointed to by the HL register pair and REG 1 (see arithmetic section in Part 2 of this manual for information on the ACC). This part of the program loads the BCDE registers with the value from the buffer, then passes control to 716H.
0708H-070AH
LD HL,1380H
Load register pair HL with the starting address of a single precision value stored in ROM at 1380H.
070BH-070DH
Call 09C2H (which loads a SINGLE PRECISION value pointed to by register pair HL into register pairs BC and DE).
070EH-070FH
Jump to the SINGLE PRECISION ADD routine at 0716H (which adds the single precision value in (BC/DE) to the single precision value in REG 1. The sum is left in REG 1).

0710H-0712H – SINGLE PRECISION SUBTRACTION, REG 1 = (HL) – REG 1

  • Single-precision subtraction (REG 1=(HL)-REG 1). This loads the BCDE registers with the value from (HL), then passes control to 0713H.
0710H-0712H
Call 09C2H (which loads a SINGLE PRECISION value pointed to by register pair HL into register pairs BC and DE).

0713H-0715H – SINGLE PRECISION SUBTRACTION, REG 1 = BCDE – REG 1
“SUBSP”

  • Single-precision subtraction (REG 1=BCDE-REG 1). The routine actually inverts REG 1 and adds it to the contents of the BCDE registers which, in effect, is a subtraction. The result will be stored in the arithmetic work area (REG 1).
  • Note: If you wanted to subtract two single precision numbers, store the minuend in the BCDE registers and store the subtrahend in 4121H-4124H and then CALL 0713H. The result (in single precision format) is in 4121H-4124H in approximately 670 microseconds.

.

0713H-0715H
“SSUB”
Go reverse the sign of the single precision value in register pairs BC and DE.

0716H-0752H – SINGLE PRECISION ADDITION, REG 1 = BCDE + REG 1
“ADDSP”

  • Single-precision addition (REG 1=BCDE+ACC). This routine adds two single-precision values and stores the result in REG 1 area.
  • Note: If you wanted to add 2 single precision numbers via a ROM call, store one input into BCDE (with the exponent in B and the LSB in E) and the other into 4121H-4124H, and then call 0716H. The single precision result will be in 4121H-4124H approximately 1.3 milliseconds later.
0716H
“SADD”
LD A,B
Load register A with the exponent of the single precision value in register B.
0717H
OR A
Check to see if the single precision value in register pairs BC and DE is equal to zero.
0718H
RET Z
Return if the single precision value in register pairs BC and DE is equal to zero.
0719H-071BH
LD A,(4124H)
Load register A with the exponent of the single precision value in REG 1 (which is stored in 4124H).
071CH
OR A
Check to see if the single precision value in REG 1 is equal to zero.
071DH-071FH
Jump to 09B4H (which moves the SINGLE PRECISION value in DC/DE into REG 1) if the single precision value in REG 1 is equal to zero.
0720H
SUB B
Subtract the value of the exponent for the single precision value in register B from the value of the exponent for the single precision value in REG 1 in register A..
0721H-0722H
Jump if the single precision value in register pairs BC and DE is smaller than the single precision value in REG 1.
0723H
CPL
Adjust the difference in the exponents in register A so that it is positive.
0724H
INC A
Increment the difference in the exponents in register A so that it will be the correct positive number.
0725H
EX DE,HL
Load register pair HL with the 16-bit value in register pair DE.
0726H-0728H
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
0729H
EX DE,HL
Load register pair DE with the 16-bit value in register pair HL.
072AH-072CH
Call 09B4H which moves the SINGLE PRECISION value in DC/DE into REG 1.
072DH
POP BC
Get the 16-bit value from the stack and put it in register pair BC.
072EH
POP DE
Get the 16-bit value from the stack and put it in register pair DE.
072FH-0730H
CP 19H
Check to see if the difference in the exponents in register A is greater than 24 (because if it is, the numbre cannot be added because of the difference in magnitude).
0731H
RET NC
Return if the difference in the exponents is too great.
0732H
PUSH AF
Save the difference in the exponents in register A on the stack.
0733H-0735H
Set the sign bits for the single precision values and return with the equality of the sign bits in register A.
0736H
LD H,A
Load register H with the equality of the sign bits in register A.
0737H
POP AF
Get the difference of the exponents from the stack and put it in register A.
0738H-073AH
Go shift the single precision value in register pairs BC and DE until it lines up with the single precision value in REG 1.
073BH
OR H
Check to see if the sign bits are equal.
073CH-073EH
LD HL,4121H
Load register pair HL with the starting address of REG 1.
073FH-0741H
Jump if the signs aren’t equal.
0742H-0744H
Go add the single precision value in BCDE to the single precision value in REG 1.
0745H-0747H
Jump if the exponent remains unchanged.
0748H
INC HL
Increment the memory pointer in register pair HL, so that it points to the exponent in REG 1.
0749H
INC (HL)
Increment the exponent in REG 1 at the location of the memory pointer in register pair HL.
074AH-074CH
If the exponent in REG 1 is too large, go to 07B2H to output an OV ERROR message.
074DH-074EH
LD L,01H
Load register L with the number of bits to shift the single precision result in register pairs BC and DE.
074FH-0751H
Go shift the single precision result in register pairs BC and DE.
0752H-0753H
Jump to 0796H.

0754H-077CH – SINGLE PRECISION MATH ROUTINE

0754H
XOR A
Zero register A.
0755H
SUB B
Subtract the 8-bit value in register B from the value in register A.
0756H
LD B,A
Load register B with the result in register A.
0757H
LD A,(HL)
Load register A with the value at the memory pointer in register pair HL.
0758H
SBC A,E
Subtract the value in register E from the value in register A.
0759H
LD E,A
Load register E with the result in register A.
075AH
INC HL
Increment the memory pointer in register pair HL.
075BH
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
075CH
SBC A,D
Subtract the value in register D from the value in register A.
075DH
LD D,A
Load register D with the result in register A.
075EH
INC HL
Increment the memory pointer in register pair HL.
075FH
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
0760H
SBC A,C
Subtract the value in register C from the value in register A.
0761H
LD C,A
Load register C with the result in register A.
0762H-0764H
If the Carry flag is set, go convert the single precision value to a positive number.
0765H
LD L,B
Load register L with the exponent of the original value in register pairs BC and DE.
0766H
LD H,E
Load register H with the LSB of the single precision value in register E.
0767H
XOR A
Zero register A.
0768H
LD B,A
Load register B with the new exponent in register A.
0769H
LD A,C
Load register A with the MSB of the single precision value in register C.
076AH
OR A
Check to see if the value in register A is equal to zero.
076BH-076CH
Jump if the MSB of the single precision value is nonzero.
076DH
LD C,D
Shift the NMSB into the MSB by loading register C with the value in register D.
076EH
LD D,H
Shift the LSB into the NMSB by loading register D with the value in register H.
076FH
LD H,L
Load register H with the value in register L.
0770H
LD L,A
Load register L with the value in register A.
0771H
LD A,B
Load register A with the new exponent counter in register B.
0772H-0773H
SUB 08H
Subtract the number of bits just shifted from the new exponent counter in register A.
0774H-0775H
CP E0H
Check to see if three bytes have been shifted.
0776H-0777H
Loop until shift is completed.
0778H
“RSETSA”
XOR A
Zero register A.
0779H-077BH
LD (4124H),A
Save the value in register A as the exponent of the single precision result in REG 1 (which is 16676).
077CH
RET
Return with a single precision value of zero in REG 1.

077DH-07A7H – SINGLE PRECISION MATH ROUTINE

077DH
DEC B
Decrement the new exponent counter in register B.
077EH
ADD HL,HL
Shift the 16-bit value in register pair HL left one bit.
077FH
LD A,D
Load register A with the NMSB in register D.
0780H
RLA
Shift the NMSB in register A left one bit and shift a bit from register pair HL if necessary.
0781H
LD D,A
Save the adjusted NMSB in register A into register D.
0782H
LD A,C
Load register A with the MSB in register C.
0783H
ADC A,A
Shift the MSB in register A left one bit and shift a bit from register D if necessary.
0784H
LD C,A
Load register C with the adjusted value in register A.
0785H-0787H
Loop until the most significant bit of the single precision value is equal to one.
0788H
LD A,B
Load register A with the new exponent counter in register B.
0789H
LD E,H
Load register E with the LSB of the single precision value in register H.
078AH
LD B,L
Load register B with the value in register L.
078BH
OR A
Check to see if there were any bits shifted.
078CH-078DH
Jump if there weren’t any bits shifted.
078EH-0790H
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0791H
ADD A,(HL)
Add the value of the original exponent at the location of the memory pointer in register pair HL to the number of bits shifted in register A.
0792H
LD (HL),A
Save the new exponent in register A at the location of the memory pointer in register pair HL.
0793H-0794H
Jump if exponent is too small.
0795H
RET Z
Return if exponent is equal to zero.
0796H
LD A,B
Load register A with the LSB of the single precision value in register B.
0797H-0799H
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
079AH
OR A
Check to see if the most significant bit of the value in register A is set.
079BH-079DH
Go check for overflow if the most significant bit in the value in register A is set.
079EH
LD B,(HL)
Load register B with the exponent at the location of the memory pointer in register pair HL.
079FH
INC HL
Increment the memory pointer in register pair HL.
07A0H
LD A,(HL)
Load register A with the value of the sign at the location of the memory pointer in register pair HL.
07A1H-07A2H
AND 80H
Mask the sign bit in register A (1000 0000).
07A3H
XOR C
Set the sign bit in register A.
07A4H
LD C,A
Load register C with the adjusted MSB of the single precision value in register A.
07A5H-07A7H
Jump to 09B4H (which moves the SINGLE PRECISION value in DC/DE into REG 1).

07A8H-07B6H – SINGLE PRECISION MATH ROUTINE

07A8H
INC E
Increment the LSB of the single precision value in register E.
07A9H
RET NZ
Return if the adjusted LSB of the single precision value in register E is nonzero.
07AAH
INC D
Increment the NMSB of the single precision value in register D.
O7ABH
RET NZ
Return if the adjusted NMSB of the single precision value in register D is nonzero.
07ACH
INC C
Increment the MSB of the single precision value in register C.
07ADH
RET NZ
Return if the adjusted MSB of the single precision value in register C is nonzero.
07AEH-07AFH
LD C,80H
Adjust the MSB of the single precision value in register C.
07B0H
INC (HL)
Increment the exponent of the single precision value at the location of the memory pointer in register pair HL.
07B1H
RET NZ
Return if the adjusted exponent of the single precision value at the location of the memory pointer in register pair HL is nonzero.
07B2H-07B3H
LD E,0AH
Load register E with an OV ERROR code.

This is the OV ERROR entry point.
07B4H-07B6H
Go to the Level II BASIC error routine and display an OV ERROR message if the value has overflowed.

07B7H-07C2H SINGLE PRECISION MATH ROUTINE

07B7H
LD A,(HL)
Load register A with the LSB of the single precision value at the location of the memory pointer in register pair HL.
07B8H
ADD A,E
Add the LSB of the single precision value in register E to the LSB of the single precision value in register A.
07B9H
LD E,A
Load register E with the result in register A.
07BAH
INC HL
Increment the memory pointer in register pair HL.
07BBH
LD A,(HL)
Load register A with the NMSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
07BCH
ADC A,D
Add the NMSB of the single precision value in register D to the NMSB of the single precision value in register A.
07BDH
LD D,A
Load register D with the result in register A.
07BEH
INC HL
Increment the memory pointer in register pair HL.
07BFH
LD A,(HL)
Load register A with the MSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
07C0H
ADC A,C
Add the MSB of the single precision value in register C to the MSB of the single precision value in register A.
07C1H
LD C,A
Load register C with the result in register A.
07C2H
RET
Return.

07C3H-07D6H – SINGLE PRECISION MATH ROUTINE – Convert to a single precision number to positive.

07C3H-07C5H
LD HL,4125H
Load register pair HL with the address of the sign flag storage location.
Note: 4125H-4126H is used by floating point routines.
07C6H
LD A,(HL)
Load register A with the value of the sign flag at the location of the memory pointer in register pair HL.
07C7H
CPL
Complement the sign flag in register A.
07C8H
LD (HL),A
Save the adjusted sign flag in register A at the location of the memory pointer in register pair HL.
07C9H
XOR A
Zero register A.
07CAH
LD L,A
Load register L with the value in register A.
07CBH
SUB B
Figure the negative value for register B by subtracting the current value in register B from the value in register A.
07CCH
LD B,A
Save the adjusted value in register A in register B.
07CDH
LD A,L
Load register A with zero.
07CEH
SBC A,E
Figure the negative LSB of the single precision value in register E by subtracting the current LSB of the single precision value in register E from the value in register A.
07CFH
LD E,A
Load register E with the adjusted LSB of the single precision value in register A.
07D0H
LD A,L
Load register A with zero.
07D1H
SBC A,D
Figure the negative NMSB of the single precision value in register D by subtracting the current NMSB of the single precision value in register D from the value in register A.
07D2H
LD D,A
Load register D with the adjusted NMSB of the single precision value in register A.
07D3H
LD A,L
Load register A with zero.
07D4H
SBC A,C
Figure the negative MSB of the single precision value in register C by subtracting the current MSB of the single precision value in register C from the value in register A.
07D5H
LD C,A
Load register C with the adjusted MSB of the single precision value in register A.
07D6H
RET
Return.

07D7H-07F7H – SINGLE PRECISION MATH ROUTINE

07D7H-07D8H
LD B,00H
Load register B with zero.
07D9H-07DAH
SUB 08H
Check to see if the shift counter in register A still indicates at least 8 bits have to be shifted.
07DBH-07DCH
Jump if less than 8 bits are left to be shifted.
07DDH
LD B,E
Load register B with the LSB of the single precision value in register E.
07DEH
LD E,D
Load register E with the NMSB of the single precision value in register D.
07DFH
LD D,C
Load register D with the MSB of the single precision value in register C.
07E0H-07E1H
LD C,00H
Load register C with zero.
07E2H-07E3H
Loop until there is less than 8 bits left to be shifted.
07E4H-07E5H
ADD 09H
Adjust the shift counter in register A to its correct value.
07E6H
LD L,A
Load register L with the shift counter in register A.
07E7H
XOR A
Zero register A.
07E8H
DEC L
Decrement the shift counter in register L.
07E9H
RET Z
Return if there are no more bits to be shifted.
07EAH
LD A,C
Load register A with the MSB of the single precision value in register C.
07EBH
RRA
Shift the MSB of the single precision value in register A one place to the right.
07ECH
LD C,A
Load register C with the adjusted MSB of the single precision value in register A.
07EDH
LD A,D
Load register A with the NMSB of the single precision value in register D.
07EEH
RRA
Shift the NMSB of the single precision value in register A one place to the right and pick up the value of the Carry flag.
07EFH
LD D,A
Load register D with the adjusted NMSB of the single precision value in register A.
07F0H
LD A,E
Load register A with the LSB of the single precision value in register E.
07F1H
RRA
Shift the LSB of the single precision value in register A one place to the right and pick up the value of the Carry flag.
07F2H
LD E,A
Load register E with the adjusted LSB of the single precision value in register A.
07F3H
LD A,B
Load register A with the value in register B.
07F4H
RRA
Shift the value in register A one place to the right and pick up the value of the Carry flag.
07F5H
LD B,A
Load register B with the adjusted value in register A.
07F6H-07F7H
Loop until all of the bits have been shifted.

07F8H-07FBH – SINGLE PRECISION CONSTANT STORAGE LOCATION

07F8H-07FBH
00 00 00 81
A single precision constant equal to 1.0 is stored here.

07FCH-0808H – SINGLE PRECISION CONSTANTS STORAGE LOCATION2

07FCH
03
The number of single precision constants which follows is stored here.
07FDH-0800H
AA 56 19 80
A single precision constant equal to .598978 is stored here.
0801H-0804H
F1 22 76 80
A single precision constant equal to .961471 is stored here.
0805H-0808H
45 AA 38 82
A single precision constant equal to 2.88539 is stored here.

0809H-0846H – LEVEL II BASIC LOG ROUTINE – LOG

  • The LOG(n) routine, (REG 1=LOG (REG 1)). This routine finds the LOGarithm of the value in REG 1 area.
    A call to 0809H computes the natural log (base E) of the single precision value in REG 1. The result is returned as a single precision value in REG 1.
  • NOTE: To use a ROM call to find LOG(X), where X is a positive single precision variable, store the value of X in 4121H-4124H and then CALL 0809H. The result (in single precision format) is in 4121H-4124Hin approximately 19 milliseconds. NOTE: A fatal error occurs if the value of the input variable is zero or negative.
0809H-080BH
“LOG”
Go check the sign of the single precision value in REG 1.
080CH
OR A
Check to see if the single precision value in REG 1 is negative or positive.
080DH-080FH
Go the Level II BASIC error routine and display a FC ERROR message if the current single precision value in REG 1 is negative.
0810H-0812H
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0813H
LD A,(HL)
Load register A with the exponent of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
0814H-0816H
LD BC,8035H
Load register BC with the exponent and the MSB of a single precision constant (which is 32821).
0817H-0819H
LD DE,04F3H
Load register DE with the NMSB and the LSB of a single precision constant (which is 1267). Register pairs BC and DE are now equal to the single precision constant of .707107.
081AH
SUB B
Subtract the exponent in register B from the exponent of the x-value in register A.
081BH
PUSH AF
Save the difference between the two exponents in register A on the stack.
081CH
LD (HL),B
Save the exponent in register B as the exponent of the x-value in REG 1 at the location of the memory pointer in register pair HL.
081DH
PUSH DE
Save the NMSB and the LSB of the single precision value in register pair DE on the stack.
081EH
PUSH BC
Save the exponent and the MSB of the single value in register pair BC on the stack.
081FH-0831H
Go add the x-value to the single precision constant in register pairs BC and DE and return with the result in REG 1, by calling the SINGLE PRECISION ADD routine at 0716H (which adds the single precision value in (BC/DE) to the single precision value in REG 1. The sum is left in REG 1).
0822H
POP BC
Get the exponent and the MSB of the single precision value from the stack and put it in register pair BC.
0823H
POP DE
Get the NMSB and the LSB of the single precision value from the stack and put it in register pair DE.
0824H
INC B
Multiply the single precision value in register pairs BC and DE by two by bumping the exponent in register B.
0825H-0827H
Go divide the single precision value in register pairs BC and DE by the x-value in REG 1 and return with the result in REG 1.
0828H-082AH
LD HL,07F8H
Load register pair HL with the starting address of a single precision constant (which is at 2040).
082BH-082DH
Go subtract the x-value in REG 1 from the single precision constant of 1. 0 at the location of the memory pointer in register pair HL and return with the result in REG 1.
082EH-0830H
LD HL,07FCH
Load register pair HL with the starting address of a storage location for single precision constants to be used for a series of computations (which is at 2044).
0831H-0833H
Go do a series of computations and return with the result in REG 1.
0834H-0836H
LD BC,8080H
Load register BC with the exponent and the MSB of a single precision constant.
0837H-0839H
LD DE,0000H
Load register pair DE with the NMSB and the LSB of a single precision. Register pairs BC and DE are now equal to a single precision of -0.5.
083AH-083CH
Go add the x-value in REG 1 to the single precision constant in register pairs BC and DE and return with the result in REG 1, by calling the SINGLE PRECISION ADD routine at 0716H (which adds the single precision value in (BC/DE) to the single precision value in REG 1. The sum is left in REG 1).
083DH
POP AF
Get the difference between the two original exponents from the stack and put it in register A.
083EH-0840H
Go convert the value in register A to a single precision number and add it to the x-value in REG 1. Return with the result in REG 1.
0841H-0843H
LD BC,8031H
Load register pair BC with the exponent and the MSB of a single precision constant.
0844H-0846H
LD DE,7218H
Load register pair DE with the NMSB and the LSB of a single precision constant. Register pairs BC and DE are now equal to a single precision value of 0.693147.

0847H-0891H – SINGLE PRECISION MULTIPLICATION, REG 1 = BCDE * REG 1 – “MLTSP”

  • Single-precision multiplication (REG 1=BCDE*ACC).
    Multiplies the current value in WRAl by the value in (BC/DE). the product is left in WRAl.
  • Note: If you wanted to multiply two single precision numbers store one operand in the BCDE registers, the other in 4121H-4124H CALL 0847H. The result (in single precision format) is in 4121H-4124H in approximately 2.2 milliseconds.
0847H-0849H
“SMUL”
Go check to see if the single precision value in REG 1 is equal to zero.
084AH
RET Z
Return if the single precision value in REG 1 is equal to zero.
084BH-084CH
LD L,00H
Load register L with a bit mask.
084DH-084FH
Go check for possible overflow and the single precision value in register pairs BC and DE equal to zero.
0850H
LD A,C
Load register A with the single precision value’s MSB in register C.
0851H-0853H
LD (414FH),A
Save the MSB of the single precision value in register A at memory location 414FH.
0854H
EX DE,HL
Load register pair HL with the NMSB and the LSB of the single precision value in register pair DE.
0855H-0857H
LD (4150H),HL
Save the NMSB and the LSB of the single precision value in register pair HL at memory locations 4150H and 4151H.
0858H-085AH
LD BC,0000H
Load register pair BC with zero.
085BH
LD D,B
Load register D with the value in register B.
085CH
LD E,B
Load register E with the value in register B.
085DH-085FH
LD HL,0765H
Load register pair HL with the return address.
0860H
PUSH HL
Save the return address in register pair HL on the stack.
0861H-0863H
LD HL,0869H
Load register pair HL with the return address.
0864H
PUSH HL
Save the return address in register pair HL on the stack.
0865H
PUSH HL
Save the return address in register pair HL on the stack.
0866H-0868H
LD HL,4121H
Load register pair HL with the starting address of the single precision value in REG 1.
0869H
LD A,(HL)
Load register A with the LSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
085AH
INC HL
Increment the memory pointer in register pair HL.
085BH
OR A
Check to see if the LSB of the single precision value in REG 1 in register A is equal to zero.
086CH-086DH
Jump if the LSB of the single precision value in REG 1 is equal to zero.
086EH
PUSH HL
Save the memory pointer in register HL on the stack.
086FH-0870H
LD L,08H
Load register L with the bit shift counter.
0871H
RRA
Shift the LSB of the single precision value in REG 1 in register A one place to the right.
0872H
LD H,A
Load register H with the adjusted LSB in register A.
0873H
LD A,C
Load register A with the MSB of the single precision value in register C.
0874H-0875H
Jump forward to 0881H if bit 0 in the LSB just shifted wasn’t set.
0876H
PUSH HL
Save the value in register pair HL on the stack.
0877H-0879H
LD HL,(4150H)
Load register pair HL with the NMSB and the LSB of the original value in register pairs BC and DE.
087AH
ADD HL,DE
Add the NMSB and the LSB of the total figured so far in register pair DE to the NMSB and the LSB of the original value in register pair HL.
087BH
EX DE,HL
Load register pair DE with the adjusted total in register pair HL.
087CH
POP HL
Get the value from the stack and put it in register pair HL.
087DH-087FH
LD A,(414FH)
Load register A with the MSB of the original value in register pairs BC and DE.
0880H
ADC A,C
Add the MSB of the original value in register A to the MSB of the total figured so far in register C.
0881H
RRA
Shift the adjusted MSB of the total in register A one place to the right.
0882H
LD C,A
Load register C with the adjusted MSB of the total in register A.
0883H
LD A,D
Load register A with the NMSB of the total in register D.
0884H
RRA
Shift the NMSB of the total in register A one place to the right.
0885H
LD D,A
Load register D with the adjusted NMSB of the total in register A.
0886H
LD A,E
Load register A with the LSB of the total in register E.
0887H
RRA
Shift the LSB of the total in register A one place to the right.
0888H
LD E,A
Load register E with the adjusted LSB of the total in register A.
0889H
LD A,B
Load register A with the value in register B.
088AH
RRA
Shift the value in register A one place to the right.
088BH
LD B,A
Load register B with the adjusted value in register A.
088CH
DEC L
Decrement the bit counter in register L.
088DH
LD A,H
Load register A with the LSB of the current value in register H.
088EH-088FH
Loop until 8 bits have been shifted.
0890H
POP HL
Get the memory pointer from the stack and put it in register pair HL.
0891H
RET
Return.

0892H-0896H – SINGLE PRECISION MATH ROUTINE
This is accomplished by a circular shift of BC/DE one byte – B is lost, C is replaced by A.

0892H
LD B,E
Load register B with the LSB of the single precision value in register E.
0893H
LD E,D
Load register E with the NMSB of the single precision value in register D.
0894H
LD D,C
Load register D with the MSB of the single precision value in register C.
0895H
LD C,A
Load register C with the value in register A.
0896H
RET
Return.

0897H-08AlH – SINGLE PRECISION MATH ROUTINE

0897H-0899H
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
089AH-089CH
LD HL,0DD8H
Load register pair HL with the starting address of a single precision constant equal to 10.
089DH-089FH
Call 09B1H (which moves a SINGLE PRECISION number pointed to by HL to REG 1).
08A0H
POP BC
Get the exponent and the MSB of the single precision value on the stack and put it in register pair BC.
08A1H
POP DE
Get the NMSB and the LSB of the single precision value from the stack and put it in register pair DE.

08A2H-0903H – SINGLE PRECISION DIVISION, REG 1 = BCDE / REG 1

  • “DIVSP” – Single-precision division (REG 1=BCDE/REG 1). If REG 1=0 a ” /0 ERROR ” will result.
    This routine will divide the SINGLE PRECISION value in register pairs BC and DE by the single precision value in REG 1. The result is returned in REG 1.
  • To use a ROM call to divide two single precision numbers, store the dividend in registers BCDE, and the divisor in 4121H-4124H and then CALL 08A2H. The result (in single precision format) is in 4121H-4124H and then pproximately 4.8 milliseconds. Overflow or /0 will error out and return to Level II.
08A2H-08A4H
“SDIV”
Go check to see if the single precision value in REG 1 is equal to zero.
08A5H-08A7H
Go to the Level II BASIC error routine and display an /0 ERROR message if the single precision value in REG 1 is equal to zero.
08A8H-08A9H
LD L,FFH
Load register L with a bit mask.
08AAH-08ACH
Go adjust the exponent in REG 1 for division.
08ADH
INC (HL)
Increment the value of the exponent for the single precision value in REG 1 at the location of the memory pointer in register pair HL.
08AEH
INC (HL)
Increment the value of the exponent for the single precision value in REG 1 at the location of the memory pointer in register pair HL.
08AFH
DEC HL
Decrement the value of the memory pointer in register pair HL.
08B0H
LD A,(HL)
Load register A with the MSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
08B1H-08B3H
LD (4089H),A
Save the MSB of the single precision value in REG 1 in register A at memory location 4089H.
08B4H
DEC HL
Decrement the value of the memory pointer in register pair HL.
08B5H
LD A,(HL)
Load register A with the NMSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
08B6H-08B8H
LD (4085H),A
Save the NMSB of the single precision value in REG 1 in register A at memory location 4085H.
08B9H
DEC HL
Decrement the value of the memory pointer in register pair HL.
08BAH
LD A,(HL)
Load register A with the LSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
08BBH-08BDH
LD (4081H),A
Save the LSB of the single precision value in REG 1 in register A at memory location 4081H.
08BEH
LD B,C
Load register B with the MSB of the single precision value in register C.
08BFH
EX DE,HL
Load register pair HL with the NMSB and the LSB of the single precision value in register pair DE.
08C0H
XOR A
Zero register A.
08C1H
LD C,A
Zero the MSB of the total by loading register C with the value in register A.
08C2H
LD D,A
Zero the NMSB of the total by loading register D with the value in register A.
08C3H
LD E,A
Zero the LSB of the total by loading register E with the value in register A.
08C4H-08C6H
LD (408CH),A
Zero memory location 408CH.
08C7H
PUSH HL
Save the NMSB and LSB of the dividend in register pair HL on the stack.
08C8H
PUSH BC
Save the MSB of the dividend in register B on the stack.
08C9H
LD A,L
Load register A with the LSB of the dividend in register L.
08CAH-08CCH
Go to the Level II BASIC division routine.
Note: 4080H-408DH is a division support routine.
08CDH-08CEH
SBC 00H
Adjust the flags.
08CFH
CCF
Invert the Carry flag.
08D0H-08D1H
Jump down to 08D9H (which is a Z-80 trick) if not done.
08D2H-08D4H
LD (408CH),A
Save the value in register A at memory location 408CH.
08D5H
POP AF
Get the value from the stack and put it in register pair AF.
08D6H
POP AF
Get the value from the stack and put it in register pair AF.
08D7H
SCF
Set the Carry flag.
08D8H
D2
Z-80 Trick – See the note at 0134H for an explanation.
08D9H
POP BC
Get the value from the stack and put it in register pair BC.
08DAH
POP HL
Get the value from the stack and put it in register pair HL.
08DBH
LD A,C
Load register A with the MSB of the total in register C.
08DCH
INC A
Increment the MSB of the total in register A.
08DDH
DEC A
Decrement the MSB of the total in register A.
08DEH
RRA
Shift the MSB of the total in register A one place to the right.
08DFH-08E1H
Jump back to 0797H if done.
08E2H
RLA
Reset the Carry flag.
08E3H
LD A,E
Load register A with the LSB of the total in register E.
08E4H
RLA
Multiply the LSB of the total in register A by two.
08E5H
LD E,A
Load register E with the adjusted LSB of the total in register A.
08E6H
LD A,D
Load register A with the NMSB of the total in register D.
08E7H
RLA
Multiply the NMSB of the total in register A by two.
08E8H
LD D,A
Load register D with the adjusted NMSB of the total in register A.
08E9H
LD A,C
Load register A with the MSB of the total in register C.
08EAH
RLA
Multiply the MSB of the total in register A by two.
08EBH
LD C,A
Load register C with the adjusted MSB of the total in register A.
08ECH
ADD HL,HL
Multiply the NMSB and the LSB of the dividend in register pair HL by two.
08EDH
LD A,B
Load register A with the MSB of the dividend in register B.
08EEH
RLA
Multiply the MSB of the dividend in register A by two.
08EFH
LD B,A
Load register B with the adjusted MSB of the dividend in register A.
08F0H-08F2H
LD A,(408CH)
Load register A with the value at memory location 408CH.
08F3H
RLA
Multiply the value in register A by two.
08F4H-08F6H
LD (408CH),A
Save the adjusted value in register A at memory location 408CH.
08F7H
LD A,C
Load register A with the MSB of the total in register C.
08F8H
OR D
Combine the NMSB of the total in register D with the value in register A.
08F9H
OR E
Combine the LSB of the total in register E with the value in register A.
08FAH-08FBH
Jump back to 08C7H if the total isn’t equal to zero.
08FCH
PUSH HL
Save the NMSB and the LSB of the dividend in register pair HL on the stack.
08FDH-08FFH
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0900H
DEC (HL)
Decrement the exponent in REG 1 at the location of the memory pointer in register pair HL.
0901H
POP HL
Get the NMSB and the LSB of the dividend from the stack and put it in register pair HL.
0902H-0903H
Jump back to 08C7H if the exponent in REG 1 isn’t equal to zero.

0904H-0906H – DISPLAY OV ERROR MESSAGE

0904H-0906H
Display an ?OV ERROR.

0907H-0913H – DOUBLE PRECISION MATH ROUTINE

0907H-0908H
LD A,FFH
Load register A with a bit mask.
0909H
2E
Z-80 Trick – See the note at 0134H for an explanation.
090AH
XOR A
Zero A and clear the flags.
090BH-090DH
LD HL,412DH
Load register pair HL with the address of the MSB in REG 2.
090EH
LD C,(HL)
Load register C with the MSB of the value in REG 2 at the location of the memory pointer in register pair HL.
090FH
INC HL
Increment the value of the memory pointer in register pair HL.
0910H
XOR (HL)
Combine the value of the exponent in REG 2 at the location of the memory pointer in register pair HL with the bit mask in register A.
0911H
LD B,A
Load register B with the adjusted exponent in register A.
0912H-0913H
LD L,00H
Load register L with a bit mask.

0914H-0930H – SINGLE PRECISION MATH ROUTINE

0914H
LD A,B
Load register A with the exponent in register B.
0915H
OR A
Check to see if the exponent in register A is equal to zero.
0916H-0917H
Jump to 0937H if the exponent in register A is equal to zero.
0918H
LD A,L
Load register A with the bit mask in register L.
0919H-091BH
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
091CH
XOR (HL)
Combine the value of the exponent at the location of the memory pointer in register pair HL with the bit mask in register A.
091DH
ADD A,B
Add the value of the exponent in register B to the value of the exponent in register A.
091EH
LD B,A
Load register B with the combined exponents in register A.
091FH
RRA
Shift the value of the combined exponents in register A one place to the right.
0920H
XOR B
Check to see if the Carry flag was set by combining the two exponents.
0921H
LD A,B
Load register A with the combined exponents value in register B.
0922H-0924H
Jump to 0936H if overflow has occurred.
0925H-0926H
ADD 80H
Reload the new exponent into A and turn on bit 8.
0927H
LD (HL),A
Save the value of the combined exponent in register A as the exponent in REG 1 at the location of the memory pointer in register pair HL.
0928H-092AH
Jump if the combined exponent in register A is equal to zero.
092BH-092DH
Go turn on the sign bit of the MSB in REG 1 and register B and save the sign bits.
092EH
LD (HL),A
Save the value in register A at the location of the memory pointer in register pair HL.
092FH
DEC HL
Decrement the memory pointer in register pair HL so that it points to the exponent in REG 1.
093OH
RET
Return.

0931H-093DH – SINGLE PRECISION MATH ROUTINE

0931H-0933H
Go check the value of the sign bit for the value in REG 1.
0934H
CPL
Reverse the result of the sign bit test in register A.
0935H
POP HL
Get the value from the stack and put it in register HL.
0936H
OR A
Set the flags according to the value of the sign bit test.
0937H
POP HL
Get the value from the stack and put it in register pair HL.
0938H-093AH
Jump to 0778H if the value in REG 1 is negative.
093BH-093DH
If its not negative, jump to 07B2H.

093EH-0954H – SINGLE PRECISION MATH ROUTINE

093EH-0940H
Call 09BF which loads the SINGLE PRECISION value in REG 1 into register pair BC/DE.
0941H
LD A,B
Load register A with the value of the exponent in register B.
0942H
OR A
Check to see if the exponent in register A is equal to zero.
0943H
RET Z
Return if the single precision value in register pairs BC and DE is equal to zero.
0944H-0945H
ADD 02H
Multiply the value of the exponent in register A by four.
0946H-0948H
Display an ?OV ERROR if the adjusted exponent in register A is too large.
0949H
LD B,A
Load register B with the adjusted exponent in register A.
094AH-094CH
Go add the original value in REG 1 to the adjusted value in register pairs BC and DE and return with the original result in REG 1 by calling the SINGLE PRECISION ADD routine at 0716H (which adds the single precision value in (BC/DE) to the single precision value in REG 1. The sum is left in REG 1).
094DH-094FH
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0950H
INC (HL)
Increment the value of the exponent in REG 1 at the location of the memory pointer in register pair HL. REG 1 now holds the original value times ten.
0951H
RET NZ
Return if the new value in REG 1 is in an acceptable range.
0952H-0954H
Display an ?OV ERROR if the value of the exponent at the location of the memory pointer in register pair HL is too large.

0955H-0963H – SINGLE PRECISION MATH ROUTINE

  • Checks if REG 1=0. If so, the Z flag will be set.
0955H-0957H
LD A,(4124H)
Load register A with the value of the exponent in REG 1.
0958H
OR A
Check to see if the exponent in register A is equal to zero.
0959H
RET Z
Return if the single precision value in REG 1 is equal to zero.
095AH-095CH
LD A,(4123H)
Load register A with the MSB of the single precision value in REG 1.
095EH
CP 2FH
Reverse the value in register A.
095FH
RLA
Put the value of the sign bit in register A into the Carry flag.
0960H
SBC A,A
Make register A equal to -1 if the sign bit is negative or a value of 0 if the sign bit is positive.
0961H
RET NZ
Return if the single precision value in REG 1 is negative.
0962H
INC A
Increment the value in register A so that register A will be equal to 1 if the single precision value in REG 1 is positive.
0963H
RET
Return.

0964H-0976H – SINGLE PRECISION MATH ROUTINE

0964H-0965H
LD B,88H
Load register B with an exponent for an integer value.
0966H-0968H
LD DE,0000H
Load register pair DE with zero.
0969H-096BH
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
096CH
LD C,A
Load register C with the MSB of the integer value.
096DH
LD (HL),B
Save the exponent in register B in REG 1 at the location of the memory pointer in register pair HL.
096EH-096FH
LD B,00H
Load register B with zero.
0970H
INC HL
Increment the memory pointer in register pair HL.
0971H-0972H
LD (HL),80H
Save the sign value at the location of the memory pointer in register pair HL.
0973H
RLA
Shift the value of the sign bit for the MSB in register A into the Carry flag.
0974H-0976H
Jump to 0762H.

0977H-0989H – LEVEL II BASIC MATH ROUTINE
ABS

  • ABS routine (REG 1=ABS(REG 1)) input and output can be integer, single-precision or double-precision, depending on what is placed in the NTF (NTF=2, 4 or 8).
    A call to 0977H converts the value in Working Register Area 1 (WRAl) to its positive equivalent. The result is left in REG 1. If a negative integer greater than 2** 15 is encountered, it is converted to a single precision value. The data type or mode flag (40AFH) will be updated to reflect any change in mode.
  • NOTE: To use a ROM call to find ABS(X),store the value of X in 4121H-4122H (integer), in 4121H-4124H (single precision), or in 411DH and then H (double precision), and store the variable type (2, 4, or 8, respectively) in 40AFH. Then CALL 0977H. The result (in the same format as the input variable) is in the same locations in which the input variable was stored. If the input was an integer, the result is also in the HL register pair.
0977H-0979H
“ABS”
Go determine the sign of the current value in REG 1.
097AH
RET P
Return if the value in REG 1 is positive.
097BH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
097CH-097EH
If that test showed INTEGER, jump to 0C5BH
097FH-0981H
If that test showed STRING, Display a ?TM ERROR message.
0982H-0984H
“MVVAR”
LD HL,4123H
Load register pair HL with the address of the MSB in REG 1.

NEGATE function for single-precision values (REG 1=-REG 1). Only BC and DE are saved.
0985H
LD A,(HL)
Load register A with the MSB in REG 1 at the location of the memory pointer in register pair HL.
0986H-0987H
XOR 80H
Set the sign bit in the MSB in register A.
0988H
LD (HL),A
Save the adjusted MSB in register A in REG 1 at the location of the memory pointer in register pair HL.
0989H
RET
Return.

098AH-0993H – LEVEL II BASIC MATH ROUTINE
SGN

  • SGN function (REG 1=SGN(REG 1)). After execution, NTF=2 and REG 1=-l, 0 or 1 depending on sign and value of ACC before execution.
  • NOTE: To use a ROM call to find SGN(X), store the value of X in 4121H-4122H (integer), in 4121H-4124H (single precision), or in, s-4124H (double precision) and then store the variable type (2, 4, or 8, respectively) in 40AFH and then CALL 098AH. The result (in integer format) is in 4121H-4122H and in the HL register pair.
098AH-098CH
“SGN”
Go test the sign of the current value in REG 1.
098DH
LD L,A
Load register L with the result of the sign test in register A.
098EH
RLA
Shift the sign bit in register A into the Carry flag.
098FH
SBC A,A
Adjust the value in register A so that it will be equal to zero if the current value in REG 1 is positive and equal to -1 if the current value in REG 1 is negative.
0990H
LD H,A
Save the adjusted value in register A in register H.
0991H-0993H
Jump to 0A9AH.

0994H-09A3H – LEVEL II BASIC MATH ROUTINE

  • This routine checks the sign of the ACC. NTF must be set. After execution A register=00 if REG 1=0, A=01 if ACC > 0 or A=FFH if A < 1. The Flags are also valid.
0994H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0995H-0997H
If that test showed STRING, Display a ?TM ERROR message.
0998H-099AH
Since P means string, single precision, or double precision; and if it was a string it would have jumped already, this line says jump to 0955H if the current value in REG 1 is single precision or double precision.
099BH-099DH
LD HL,(4121H)
At this point, we know we have an integer. Load register pair HL with the integer value in REG 1.
099EH
LD A,H
Load register A with the MSB of the integer value in register H.
099FH
OR L
Check to see if the integer value in REG 1 is equal to zero.
09A0H
RET Z
Return if the integer value in REG 1 is equal to zero.
09A1H
LD A,H
Load register A with the MSB of the integer value in register H.
09A2H-09A3H
Jump to 095FH.

09A4H-09B0H – SINGLE PRECISION MATH ROUTINE
“LDSTSA”

  • Loads Single-precision value from ACC to stack ((SP)=ACC). To retrieve this value, POP BC followed by POP DE. A, BC and HL are unchanged by this function.
09A4H
“SSTAK”
EX DE,HL
Load register pair DE with the value in register pair HL.
09A5H-09A7H
LD HL,(4121H)
Load register pair HL with the LSB and the NMSB of the single precision value in REG 1.
09A8H
EX (SP),HL
Exchange the return address on the stack with the NMSB and the LSB of the single precision value in register pair HL.
09A9H
PUSH HL
Save the return address in register pair HL on the stack.
09AAH-09ACH
LD HL,(4123H)
Load register pair HL with the exponent and the MSB of the single precision value in REG 1.
09ADH
EX (SP),HL
Exchange the return address on the stack with the exponent and the MSB of the single precision value in register pair HL.
09AEH
PUSH HL
Save the return address in register pair HL on the stack.
09AFH
EX DE,HL
Load register pair HL with the value in register pair DE.
09B0H
RET
Return.

09BlH-09BEH – SINGLE PRECISION MATH ROUTINE
“LDSAHL”

  • This routine loads four bytes from the location pointed to by HL, into the ACC. (REG 1=(HL)).
09B1H-09B3H
“SCOPY”
Call 09C2H (which loads a SINGLE PRECISION value pointed to by register pair HL into register pairs BC and DE).
09B4H
“DSTOR”
EX DE,HL
Load register pair HL with the NMSB and the LSB of the single precision value in register pair DE.

This routine loads REG 1 with the contents of the BC and DE register pairs. (REG 1=BCDE). BC and HL remain unaltered.
09B5H-09B7H
LD (4121H),HL
Save the NMSB and the LSB of the single precision value in register pair HL in REG 1.
09B8H
LD H,B
Load register H with the exponent of the single precision value in register B.
09B9H
LD L,C
Load register L with the MSB of the single precision value in register C.
09BAH-09BCH
LD (4123H),HL
Save the exponent and the MSB of the single precision value in register pair HL in REG 1
09BDH
EX DE,HL
Load register pair HL with the value in register pair DE.
09BEH
RET
Return.

09BFH-09CAH – SINGLE PRECISION MATH ROUTINE
“LDRASA”

  • This routine is the opposite of the 09B4H routine. It loads four bytes from REG 1 (single-precision) into the BC and DE register pairs. (BCDE=ACC). A is unchanged.
09BFH-09C1H
LD HL,4121H
Load register pair HL with the starting address for a single precision value in REG 1.
09C2H
“SGET”
LD E,(HL)
Load register E with the LSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.

This routine will load the BCDE register pairs with four bytes from the location pointed to by HL. (BCDE=(HL)),. With these types of data movements, the E register is loaded with the LSB and the B register. with the MSB.
09C3H
INC HL
Increment the value of the memory pointer in register pair HL.
09C4H
LD D,(HL)
Load register D with the NMSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
09C5H
INC HL
Increment the value of the memory pointer in register pair HL.
09C6H
LD C,(HL)
Load register C with the MSB of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
09C7H
INC HL
Increment the value of the memory pointer in register pair HL.
09C8H
LD B,(HL)
Load register B with the exponent of the single precision value in REG 1 at the location of the memory pointer in register pair HL.
09C9H
INC HL
Increment the value of the memory pointer in register pair HL.
09CAH
RET
Return.

09CBH-09DlH – SINGLE PRECISION MATH ROUTINE
“LDHLSA”

  • This routine is the opposite of the 9B1H routine. It loads four bytes from REG 1 to the memory location pointed to by HL. ((HL)=ACC).
09CBH-09CDH
LD DE,4121H
Load register pair DE with the starting address for a single precision value in REG 1 (whci is at 16673).
09CEH-09CFH
LD B,04H
Load register B with the number of bytes to be moved for a single precision value.

Data move routine. This moves four bytes from the location pointed to by DE into the location pointed to by HL. ((HL)=(DE)).
09D0H-09D1H
Jump to 09D7H (which is the GENERAL PURPOSE MOVE routine and moves the contents of the B Register bytes from the address in DE to the address in HL).

09D2H-09DEH – MOVE VALUE POINTED TO BY HL TO THE LOCATION POINTED TO BY DE
“LDDEHL”

  • This is the VARIABLE MOVE Routine which moves the number of bytes specified in the type flag (40AFH) from the address in DE to the address in HL. Uses A, DE and HL.
09D2H
EX DE,HL
Exchange the value in register pair HL with the value in register pair DE.

Data move routine. The location pointed to by DE is loaded with bytes from the location pointed to by HL. The number of bytes moved is determined by the value in the NTF. ((DE)=(HL)).
09D3H-09D5H
“LDHLDE”
LD A,(40AFH)
Load register A with the current value of the number type flag (which is in 40AFH).

This routine is similar to 9D2H above. The only difference is that it moves data in the opposite direction. ((HL) = (DE)).
Note: 40AFH holds Current number type flag.
09D6H
“MOVEA”
LD B,A
Load register B with the number of bytes to be moved in register A.

This routine is the same as 9D3H except that the number of bytes moved depends on the value in the A register ((HL) = (DE)).
09D7H
“MOVEB”
LD A,(DE)
Load register A with the value at the location of the memory pointer in register pair DE.

This routine is the same as 9D6H except that the number of bytes shifted is determined by the value in the B register ((HL)=(DE)).
This is the GENERAL PURPOSE MOVE routine and moves the contents of the B Register bytes from the address in DE to the address in HL).
09D8H
LD (HL),A
Save the value in register A at the location of the memory pointer in register pair HL.
09D9H
INC DE
Increment the value of the memory pointer in register pair DE.
09DAH
INC HL
Increment the value of the memory pointer in register pair HL.
09DBH
DEC B
Decrement the value of the byte counter in register B.
09DCH-09DDH
Loop until all of the bytes have been moved.
09DEH
RET
Return.

09DFH-09F3H – SINGLE PRECISION MATH ROUTINE

09DFH-09E1H
LD HL,4123H
Load register pair HL with the address of the MSB of the value in REG 1.
09E2H
LD A,(HL)
Load register A with the MSB of the value in REG 1 at the location of the memory pointer in register pair HL.
09E3H
RLCA
Move the value of the sign bit in register A into the Carry flag.
09E4H
SCF
Set the Carry flag.
09E5H
RRA
Turn off the sign bit in register A by moving the value of the Carry flag into register A and moving the previous value of the sign bit from bit 0 of register A into the Carry flag.
09E6H
LD (HL),A
Save the adjusted MSB in register A in REG 1 at the location of the memory pointer in register pair HL.
09E7H
CCF
Invert the value of the sign bit in the Carry flag.
09E8H
RRA
Move the inverted sign bit from the Carry flag into register A.
09E9H
INC HL
Increment the value of the memory pointer in register pair HL.
09EAH
INC HL
Increment the value of the memory pointer in register pair HL.
09EBH
LD (HL),A
Save the value in register A at the location of the memory pointer in register pair HL.
09ECH
LD A,C
Load register A with the MSB of the single precision value in register C.
09EDH
RLCA
Move the value of the sign bit in register A into the Carry flag.
09EEH
SCF
Set the Carry flag.
09EFH
RRA
Turn on the sign bit in register A by moving the value of the Carry flag into register A and moving the previous value of the sign bit from bit 0 of register A into the Carry flag.
09F0H
LD C,A
Load register C with the adjusted MSB in register A.
09F1H
RRA
Move the value of the sign bit from the Carry flag into register A.
09F2H
XOR (HL)
Combine the value of the sign bit for the single precision value in register A with the value of the sign bit for the single precision value at the location of the memory pointer in register pair HL.
09F3H
RET
Return.

09F4H-09FBH – LEVEL II BASIC MATH ROUTINE

  • This routine is used by the double-precision logic. It moves a number of bytes (the number depending on the value stored in the NTF) from the AACC into the ACC. ((REG 1)=(AACC)).
09F4H-09F6H
LD HL,4127H
Load register pair HL with the starting address of REG 2.
Note: 4127H-412EH holds REG 2.
09F7H-09F9H
“MVSAHL”
LD DE,09D2H
Load register pair DE with the return address.
09FAH-09FBH
Jump to 0A02 (which is 2562).

09FCH-0A0BH – LEVEL II BASIC MATH ROUTINE

  • This is the opposite of 9F4H. ((AACC)=(REG 1)).
09FCH-09FEH
“MVALT”
LD HL,4127H
Load register pair HL with the starting address of REG 2 (which is 16679).
Note: 4127H-412EH holds REG 2.
09FFH-0A01H
LD DE,09D3H
Load register pair DE with the return address.
0A02H
PUSH DE
Save the return address in register pair DE on the stack.
0A03H-0A05H
LD DE,4121H
Load register pair HL with the starting address for a single precision value in REG 1.
0A06H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0A07H
RET C
If that test is anything other than double precision, return out of this subroutine.
0A08H-0A0AH
LD DE,411DH
Load register pair DE with the starting address of REG 1.
Note: 411DH-4124H holds REG l.
0A0BH
RET
Return.

0A0CH-0A25H – SINGLE PRECISION COMPARE
“CPSP”

  • Single-precision compare. Compares REG 1 with the contents of BCDE registers. After execution of this routine, the A register will contain: A=0 if REG 1=BCDE, A=1 if ACC>BCDE or A=FFH if ACC<BCDE.
  • NOTE: To use a ROM call to compare two single precision numbers, store the first input in registers BCDE, the second input in 4121H-4124H and then CALL 0A0CH. If the numbers are equal, the Z (zero) flag will be set. If they are not equal, the Z flag will be turned off. If the first input number is the smaller, the S (sign) and C (carry) flags will also be turned off. If the second input number is the smaller, the S and C flags will both be set.
0A0CH
LD A,B
Load register A with the value of the exponent in register B.
0A0DH
OR A
Check to see if the exponent in register A is equal to zero.
0A0EH-0A10H
Jump if the exponent in register A is equal to zero.
0A11H-0A13H
LD HL,095EH
Load register pair HL with the return address.
0A14H
PUSH HL
Save the return address in register pair HL on the stack.
0A15H-0A17H
Go check the signs of the single precision numbers.
0A18H
LD A,C
Load register A with the MSB of the single precision value in register C.
0A19H
RET Z
Return if the signs of the single precision values aren’t equal.
0A10H-0A1CH
LD HL,4123H
Load register pair HL with the address of the MSB in register A.
0A1DH
XOR (HL)
Combine the MSB in REG 1 at the location of the memory pointer in register pair HL with the MSB in register A.
0A1EH
LD A,C
Load register A with the MSB in register C.
0A1FH
RET M
Return if the MSBs don’t match.
0A20H-0A22H
Go compare the single precision values.
0A23H
RRA
Move the value of the Carry flag from the comparison into register A.
0A24H
XOR C
Combine the value of the MSB of the single precision value in register C with the value in register A.
0A25H
RET
Return.

0A26H-0A38H – SINGLE PRECISION COMPARISON ROUTINE

0A26H
INC HL
Increment the value of the memory pointer in register pair HL so that it points to the exponent in REG 1.
0A27H
LD A,B
Load register A with the value of the exponent for the single precision value in register B.
0A28H
CP (HL)
Check to see if the exponent for the single precision value in REG 1 at the location of the memory pointer in register pair HL is the same as the value of the exponent for the single precision value in register A.
0A29H
RET NZ
Return if the value of the exponent in REG 1 isn’t the same as the value of the exponent in register A.
0A2AH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0A2BH
LD A,C
Load register A with the MSB for the single precision value in register C.
0A2CH
CP (HL)
Check to see if the MSB for the single precision value in REG 1 at the location of the memory pointer in register pair HL is the same as the value of the MSB for the single precision value in register A.
0A2DH
RET NZ
Return if the value of the MSB in REG 1 isn’t the same as the value of the MSB in register A.
0A2EH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0A2FH
LD A,D
Load register A with the NMSB of the single precision value in register D.
0A30H
CP (HL)
Check to see if the NMSB for the single precision value in REG 1 at the location of the memory pointer in register pair HL is the same as the value of the NMSB for the single precision value in register A.
0A31H
RET NZ
Return if the value of the NMSB in REG 1 isn’t the same as the value of the NMSB in register A.
0A32H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0A33H
LD A,E
Load register A with the LSB of the single precision value in register E.
0A34H
SUB (HL)
Check to see if the LSB for the single precision value in REG 1 at the location of the memory pointer in register pair HL is the same as the value of the LSB for the single precision value in register A.
0A35H
RET NZ
Return if the value of the LSB in REG 1 isn’t the same as the value of the LSB in register A.
0A36H
POP HL
Get the value from the stack and put it in register pair HL.
0A37H
POP HL
Get the value from the stack and put it in register pair HL.
0A3BH
RET
Return.

0A39H-0A48H – INTEGER COMPARE

  • Integer compare. Compares HL with DE. After execution, A=0 if HL=DE, A=1 if HL>DE or A=FFH if HL<DE. The S and Z flags are valid.
  • NOTE: To use a ROM call to compare two integers, store the first input in DE, the second in HL and then CALL 0A39H. If the numbers are equal, the Z (zero) flag will be set. If they are not equal, the Z flag will be turned off. If the first input number is the smaller, the S (sign) and C (carry) flags will also be turned off. If the second input number is the smaller, the S and C flags will both be set.
0A39H
LD A,D
Load register A with the MSB of the integer value in register D.
0A3AH
XOR H
Check to see if the sign bit for the MSB of the integer value in register H is the same as the sign bit for the MSB for the integer value in register A.
0A3BH
LD A,H
Load register A with the MSB of the integer value in register H.
0A3CH-0A3EH
Jump if the sign bits for the integer values aren’t equal.
0A3FH
CP D
Check to see if the MSB for the integer value in register D is the same as the MSB for the integer value in register A.
0A40H-0A42H
Jump if the MSB for the integer value in register D isn’t the same as the MSB for the integer value in register A.
0A33H
LD A,L
Load register A with the LSB of the integer value in register L.
0A44H
SUB E
Check to see if the LSB for the integer value in register E is the same as the LSB for the integer value in register A.
0A45H-0A47H
Jump if the LSB for the integer value in register E isn’t the same as the LSB for the integer value in register A.
0A48H
RET
Return.

0A49H-0A77H – DOUBLE PRECISION COMPARE

  • Double-precision compare. Compares REG 1 with the AACC. After execution the A register will contain: A=0 if REG 1=AACC, A=1 if ACC > AACC or A=FFH if ACC < AACC. S and Z flags are valid.
0A49H-0A4BH
LD HL,4127H
Load register pair HL with the starting address of REG 2.
Note: 4127H-412EH holds REG 2.
0A4CH-0A4EH
Go move the double precision value pointed to by register pair DE to REG 2.
0A4FH-0A51H
LD DE,412EH
Load register pair DE with the address of the exponent in REG 2.
0A52H
LD A,(DE)
Load register A with the exponent for the double precision value in REG 2 at the location of the memory pointer in register pair DE.
0A53H
OR A
Check to see if the double precision value in REG 2 is equal to zero.
0A54H-0A56H
Jump if the double precision value in REG 2 is equal to zero.
0A57H-0A59H
LD HL,095EH
Load register pair HL with the return address.
0A5AH
PUSH HL
Save the return address in register pair HL on the stack.
0A5BH-0A5DH
Go check to see if the double precision value in REG 1 is equal to zero.
0A5EH
DEC DE
Decrement the value of the memory pointer in register pair DE.
0A5FH
LD A,(DE)
Load register A with the MSB of the double precision value in REG 2 at the location of the memory pointer in register pair DE.
0A60H
LD C,A
Load register C with the MSB of the double precision value in REG 2 in register A.
0A61H
RET Z
Return if the double precision value in REG 1 is equal to zero.
0A62H-0A64H
LD HL,4123H
Load register pair HL with the address of the MSB of the double precision value in REG 1.
0A65H
XOR (HL)
Check to see if the sign bit for the MSB of the double precision value in REG 1 at the location of the memory pointer in register pair HL is the same as the sign bit for the MSB of the double precision value in REG 2 in register A.
0A66H
LD A,C
Load register A with the MSB of the double precision value in REG 2 in register C.
0A67H
RET M
Return if the sign bits for the double precision values in REG 1 and REG 2 aren’t the same.
0A68H
INC DE
Increment the value of the memory pointer in register pair DE.
0A69H
INC HL
Increment the value of the memory pointer in register pair HL.
0A6AH-OA6BH
LD B,08H
Load register B with the number of bytes to be compared.
0A6CH
LD A,(DE)
Load register A with the value at the location of the memory pointer in register pair DE.
0A6DH
SUB (HL)
Check to see if the value in register A is the same as the value at the location of the memory pointer in register pair HL.
0A6EH-0A70H
Jump back to 0A23H if the value in register A isn’t the same as the value at the location of the memory pointer in register pair HL.
0A71H
DEC DE
Decrement the value of the memory pointer in register pair DE.
0A72H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0A73H
DEC B
Decrement the number of bytes remaining to be compared in register B.
0A74H-0A75H
Loop until all of the bytes have been compared.
0A76H
POP BC
Get the value from the stack and put it in register pair BC.
0A77H
RET
Return.

0A78H-0A7EH – DOUBLE PRECISION COMPARE
“CPDP”

  • Double-precision compare. This compare is the opposite of the A4FH compare. It compares the AACC with the ACC. (Remember that a compare is actually a subtraction that is never executed therefore a compare can be done in two ways with the same values. (A-B and B-A)). The results are the same as the A4FH routine.
  • NOTE: To use a ROM call to compare two double precision number, store the first input in 411DH-4124H, and store the second input in 4127H-412EH and then CALL 0A78H. If the numbers are equal, the Z (zero) flag will be set. If they are not equal, the Z flag will be turned off. If the first input number is the smaller, the S (sign) and C (carry) flags will also be turned off. If the second input number is the smaller, the S and C flags will both be set.
0A78H-0A7AH
Go compare the double precision value in REG 2 to the double precision value in REG 1.
0A7BH-0A7DH
Jump if the double precision value in REG 1 and the double precision value in REG 2 aren’t the same.
0A7EH
RET
Return.

0A7FH-0AB0H – LEVEL II BASIC CINT ROUTINE

  • CINT routine. Takes a value from ACC, converts it to an integer value and puts it back into the ACC. On completion, the HL register pair contains the LSB of the integer value, and the NTF contains 2 (Integer=2). If NTF=3 (string) a TM ERROR will be generated and control will be passed to BASIC.
0A7FH
“CINT”
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0A80H-0A82H
LD HL,(4121H)
Load register pair HL with the integer value in REG 1
0A83H
RET M
If that test showed we have an INTEGER, then return out of this subroutine.
0A84H-0A86H
If that test showed we have a STRING, Display a ?TM ERROR message.
0A87H-0A89H
If that test shows we have DOUBLE PRECISION, call 0AB9H to convert the number to single precision.
  • NOTE: To use a ROM call to call the CINT routine, store the single precision input variable in 4121H-4124H and then call to 0A8AH and bypass all the foregoing. After the call, the integer result would be in 4121H-4122H and in the HL register pair. Too big a number will generate a ?OV Error.
0A8AH-0A8CH
LD HL,07B2H
Load register pair HL with the return address.
0A8DH
PUSH HL
Save the return address in register pair HL on the stack.
0A8EH-0A90H
LD A,(4124H)
Load register A with the exponent for the single precision value in REG 1.
0A91H-0A92H
CP 90H
Check to see if the exponent for the single precision value in REG 1 in register A indicates more than 16 bits of precision.
0A93H-0A94H
Jump if the exponent for the single precision value in REG 1 in register A indicates more than 16 bits of precision.
0A95H-0A97H
Go convert the single precision value in REG 1 to an integer and return with the integer value in register pair DE.
0A98H
EX DE,HL
Load register pair HL with the integer value in register pair DE.
0A99H
POP DE
Get the value from the stack and put it in register pair DE.
0A9AH-0A9CH
“ISTOR”
LD (4121H),HL
Save the integer value in register pair HL as the current value in REG 1.

This is the routine that returns the value in the HL register pair to the BASIC program that called it. In effect it moves the content of HL into REG 1 (ACC = HL).
0A9DH-0A9EH
“FLAGIN”
LD A,02H
Load register A with an integer number type flag.

Set NTF to Integer (2). (A=used).
0A9FH-0AA1H
LD (40AFH),A
Save the integer number type flag in register A as the current value of the number type flag.
Note: 40AFH holds Current number type flag.
0AA2H
RET
Return.

0AA3H-0AA5H
LD BC,9080H
Load register pair BC with the exponent and the MSB of a single precision value.
0AA6H-0AA8H
LD DE,0000H
Load register pair DE with the NMSB and the LSB of a single precision value. Register pairs BC and DE now hold a single precision value equal to -32768.
0AA9H-0AABH
Call the SINGLE PRECISION COMPARISON routine at 0A0CH.

NOTE: The routine at 0A0CH algebraically compares the single precision value in BC/DE to the single precision value REG 1.
The results are stored in A as follows:
  • A=0 if REG 1 = BCDE
  • A=1 if REG 1>BCDE; and
  • A=FFH if REG 1<BCDE.
0AACH
RET NZ
Display an ?OV ERROR if the value in REG 1 isn’t equal to -32768.
0AADH
LD H,C
Load register H with the MSB of the single precision value in register C.
0AAEH
LD L,D
Load register L with the NMSB of the single precision value in register D.
0AAFH-0AB0H
Jump to 0A99H.

0AB1H-0ACBH – LEVEL II BASIC CSNG ROUTINE
“CSASP”

  • CSNG routine. Takes value from ACC and converts it to single-precision. The result is put in ACC and NTF contains 4.
0AB1H
“CSNG”
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0AB2H
RET PO
If that test shows we have SINGLE PRECISION, return out of this subroutine.
0AB3H-0AB5H
If that test shows we have an INTEGER, jump to 0ACCH.
0AB6H-0AB8H
If that test shows we have a STRING, display a ?TM ERROR .
0AB9H-0ABBH
At this point, we have a DOUBLE PRECISION number, so call 09BF which loads the SINGLE PRECISION value in REG 1 (which is currently the most significant four bytes of the double precision value in REG 1) into register pair BC/DE.
0ABCH-0ABEH
Go set the current number type flag to single precision.
0ABFH
LD A,B
Load register A with the exponent of the double precision value in register B.
0AC0H
OR A
Check to see if the double precision value in REG 1 is equal to zero.
0AC1H
RET Z
Return if the double precision value in REG 1 is equal to zero.
0AC2H-0AC4H
Go turn on the most significant bit of the single precision value in REG 1.
0AC5H-0AC7H
LD HL,4120H
Load register pair HL with the address of the most significant byte chopped off the double precision value.
0AC8H
LD B,(HL)
Loaded register B with the most significant byte chopped off the double precision value at the location of the memory pointer in register pair HL.
0AC9H-0ACBH
Jump to 0796H.

0ACCH-0ADAH – LEVEL II BASIC MATH ROUTINE
“CHGIS”

  • Convert Integer to Single Precision.
  • Note: If you wanted to convert integer to single precision via a ROM call, you would store the integer input variable in 4121H-4122H and then call to 0ACCH. The result (as a single precision number) will be in 4121H-4124H.
0ACCH-0ACEH
LD HL,(4121H)
Load register pair HL with the integer value at the location of an integer storage in REG 1.
0ACFH-0AD1H
Go set the current number type flag to single precision.
0AD2H
LD A,H
Load register A with the MSB of the integer value in register H.
0AD3H
LD D,L
Load register D with the LSB of the integer value in register L.
0AD4H-0AD5H
LD E,00H
Zero register E.
0AD6H-0AD7H
LD B,90H
Load register B with the initial maximum exponent.
0AD8H-0ADAH
Jump to 0969H.

0ADBH-0AEDH – LEVEL II BASIC CDBL ROUTINE
“CSADP”

  • CDBL routine. Takes a value from ACC and converts it to double-precision. The result will be in ACC and NTF will be 8.
0ADBH
“CDBL”
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0ADCH
RET NC
If that test shows we have a DOUBLE PRECISION number, return out of the subroutine.
0ADDH-0ADFH
If that test shows we have a STRING, Display a TM ERROR message.
0AE0H-0AE2H
If that test shows we have an INTEGER, then go to 0ACCH to convert it to SINGLE PRECISION..
0AE3H-0AE5H
LD HL,0000H
So now we know we have a SINGLE PRECISION value. Load register pair HL with zero.
0AE6H-0AE8H
LD (411DH),HL
Save the value in register pair HL as the first and second bytes of REG 1.
Note: 411DH-4124H holds REG l.
0AE9H-0AEBH
LD (411FH),HL
Save the value in register pair HL as the third and fourth bytes of REG 1.
0AECH-0AEDH
“FLAGDP”
LD A,08H
Load register A with a double precision number type flag.

0AEEH-0AF3H – LEVEL II BASIC MATH ROUTINE

0AEEH
01
Z-80 Trick – See the note at 0134H for an explanation.
0AEFH-0AF0H
“FLAGSP”
LD A,04H
Load register A with a single precision number type flag (of 4).
0AF1H-0AF3H
Jump away to 0A9FH to save the value in register A as the current number type flag.

0AF4H-0AFAH – LEVEL II BASIC MATH ROUTINE

  • This routine calls 20H (RST 20H) and returns if NTF=3 (string) else if NTF is not 3 then it generates a TM ERROR. BC, DE, and HL are saved.
0AF4H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0AF5H
RET Z
If that test shows we have a STRING, return out of the subroutine.
0AF6H-0AF7H
LD E,18H
Load register E with a TM ERROR code.

This is the entry point for the TM ERROR.
0AF8H-0AFAH
Display a TM ERROR message if the current value in REG 1 isn’t a string.

0AFBH-0B1EH – LEVEL II BASIC MATH ROUTINE

  • This routine will reset the BC and DE register pairs if the A register contains 0. (XOR A before calling this routine).
0AFBH
LD B,A
Load register B with the exponent of the single precision number in register A.
0AFCH
LD C,A
Load register C with the exponent of the single precision number in register A.
0AFDH
LD D,A
Load register D with the exponent of the single precision number in register A.
0AFEH
LD E,A
Load register E with the exponent of the single precision number in register A.
0AFFH
OR A
Check to see if the single precision number in REG 1 is equal to zero.
0B00H
RET Z
Return if the single precision value in REG 1 is equal to zero.
0B01H
PUSH HL
Save the value in register pair HL on the stack.
0B02H-0B04H
Call 09BF which loads the SINGLE PRECISION value in REG 1 into register pair BC/DE.
0B05H-0B07H
Go turn on the sign bit of the single precision value in register pairs BC and DE.
0B08H
XOR (HL)
Set the sign bit according to the sign of the value at the location of the memory pointer in register pair HL.
0B09H
LD H,A
Load register H with the value of the sign in register A.
0B0AH-0B0CH
Go decrement the single precision value in register pairs BC and DE if the sign of the value is negative.
0B0DH-0B0EH
LD A,98H
Load register A with the maximum exponent.
0B0FH
SUB B
Figure the number of bits to be shifted by subtracting the exponent in register B from the exponent in register A.
0B10H-0B12H
Go shift the single precision value in register pairs BC and DE.
0B13H
LD A,H
Load register A with the value of the sign in register H.
0B14H
RLA
Put the sign bit into the Carry flag.
0B15H-0B17H
Go bump the value in register pairs BC and DE if the original number was negative.
0B18H-0B19H
LD B,00H
Load register B with an exponent.
0B1AH-0B1CH
Go make the integer negative if the original number was negative. Return with the integer value in register pair DE.
0B1DH
POP HL
Get the value from the stack and put it in register pair HL.
0B1EH
RET
Return.

0BlFH-0B25H – LEVEL II BASIC MATH ROUTINE

0B1FH
DEC DE
Decrement the NMSB and the LSB of the single precision value in register pair DE.
0B20H
LD A,D
Load register A with the value of the NMSB for the single precision value in register D.
0B21H
AND E
Combine the LSB of the single precision value in register E with the NMSB of the single precision value in register A.
0B22H
INC A
Increment the combined value in register A.
0B23H
RET NZ
Return if the NMSB and the LSB of the single precision value in register pair DE isn’t equal to FFFFH.
0B24H
DEC BC
Decrement the value of the exponent and the MSB of the single precision value in register pair BC.
0B25H
RET
Return.

0B26H-0B58H – LEVEL II BASIC FIX ROUTINE
“FIX”

  • FIX routine. Takes a value from ACC and converts it to an integer value. The result will be in ACC. NTF will be 2 if value is smaller than 32767 else it will be 4. An error will be generat
  • ed if NTF=3 (string).
    A call to 0B26H unconditionally truncates the fractional part of a floating point number in REG 1. The result is stored in WRAl and the type flag is set to integer.
  • Note: If you wanted to call the FIX routine via a ROM call, you would store the single-precision input variable in 4121H-4124H, then put a 4 into 40AFH to flag as single precision, and then call to 0B26H. If the result can be an integer, it will be in 4121H-4122H and in the HL register pair. If single precision, the result will be in 4121H-4124H. If double precision, in 411DH-4124H. In all cases 40AFH will have the data mode flag as 2, 4, or 8, accordingly.
0B26H
“FIX”
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0B27H
RET M
If that test shows we have an INTEGER, return out of the subroutine.
0B28H-0B2AH
Go check the sign of the current value in REG 1.
0B2BH-0B2DH
If the current value in REG 1 is positive, jump to the RETURN INTEGER (INT[N]) routine at 0B37H (which returns the integer portion of a floating point number. If the value is positive, the integer portion is returned. If the value is negative with a fractional part, it is rounded up before truncation. The integer portion is left in REG 1. The mode flag is updated.).
0B2EH-0B30H
Gosub to 0982H to convert the current value in REG 1 to positive.
0B31H-0B33H
Now that REG 1 is positive, call the RETURN INTEGER (INT[N]) routine at 0B37H (which returns the integer portion of a floating point number. If the value is positive, the integer portion is returned. If the value is negative with a fractional part, it is rounded up before truncation. The integer portion is left in REG 1. The mode flag is updated.).
0B34H-0B36H
Jump back to 097BH (which is in the middle of the ABS(x) routine.

0B37H – LEVEL II BASIC INT( ROUTINE

A call to 0B37H returns the integer portion of a floating point number. If the value is positive, the integer portion is returned. If the value is negative with a fractional part, it is rounded up before truncation. The integer portion is left in REG 1. The mode flag is updated.

0B37H
“INT”
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0B38H
RET M
If that test shows we have an INTEGER, return out of this subroutine.
0B39H-0B3AH
Jump if the current value in REG 1 is double precision.
0B3BH-0B3CH
Display a ?TM ERROR if the current value in REG 1 isa string.

Note: If you wanted to call the INT routine via a ROM call, you would store the single precision input variable in 4121H-4124H, put a 4 into 40AFH (to flag as single precision), and then call 0B3DH and bypass all the foregoing. After the call, the integer result would be in 4121H-4122H and in the HL register pair IF the absolute value of the input did not exceed 32767. Otherwise it will be in 4121H-4124H in single precision format, and 40AF will be a 2 for integer or 4 for single precision..

0B3DH-0B3FH
Go convert the single precision value in REG 1 to an integer.
0B40H-0B42H
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0B43H
LD A,(HL)
Load register A with the value of the exponent in REG 1 at the location of the memory pointer in register pair HL.
0B44H-0B45H
CP 98H
Check to see if there is more than 24 bits of precision used by the current value in REG 1.
0B46H-0B48H
LD A,(4121H)
Load register A with the LSB of the single precision number in REG 1.
0B49H
RET NC
Return if more than 24 bits of precision is used by the single precision value in REG 1.
0B4AH
LD A,(HL)
Load register A with the exponent of the single precision number in REG 1.
0B4BH-0B4DH
Go convert the single precision number in REG 1 to an integer.
0B4EH-0B4FH
LD (HL),98H
Save an exponent in REG 1.
0B50H
LD A,E
Load register A with the LSB of the integer value in register E.
0B51H
PUSH AF
Save the LSB of the integer value in register A on the stack.
0B52H
LD A,C
Load register A with the value in register C.
0B53H
RLA
Move the sign bit in register A into the Carry flag.
0B54H-0B56H
Go make the number in REG 1 single precision.
0B57H
POP AF
Get the LSB of the single precision value from the stack and put it in register A.
0B58H
RET
Return.

0B59H-0B9DH – LEVEL II BASIC MATH ROUTINE

0B59H-0B5BH
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0B5CH
LD A,(HL)
Load register A with the value of the exponent for the double precision number in REG 1 at the location of the memory pointer in register pair HL.
0B5DH-0B5EH
CP 90H
Check to see if the double precision number in REG 1 uses more or less than 16 bits of precision (which is 0001 0100 0100 in binary).
0B5FH-0B61H
If the double precision value in REG 1 uses less than 16 bits of precision, jump to the CONVERT TO INTEGER routine at 0A7F (where the contents of REG 1 are converted from single or double precision to integer and stored in HL).
0B62H-0B63H
Jump forward to 0B78H if the double precision number in REG 1 uses more than 16 bits of precision.
0B64H
LD C,A
Load register C with the exponent for the double precision number in register A.
0B65H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0B66H
LD A,(HL)
Load register A with the MSB of the double precision value in REG 1 at the location of the memory pointer in register pair HL.
0B67H-0B68H
XOR 80H
Complement the value of the sign bit in register A (which is 1000 0000).
0B69H-0B6AH
LD B,06H
Load register B with the number of bytes to be checked.
0B6BH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0B6CH
OR (HL)
Combine the value at the location of the memory pointer in register HL with the value in register A.
0B6DH
DEC B
Decrement the byte counter in register B.
0B6EH-0B6FH
Loop until all of the bytes have been checked.
0B70H
OR A
Check to see if the double precision value in REG 1 is equal to a -32768.
0B71H-0B73H
LD HL,8000H
Load register pair HL with a negative zero.
0B74H-0B76H
Jump back to 0A9AH if the double precision value in REG 1 is a -32768.
0B77H
LD A,C
Load register A with the exponent for the double precision value in register C.
0B78H-0B79H
CP B8H
Check to see if more than 56 bits of precision has been used for the double precision value in REG 1.
0B7AH
RET NC
Return if more than 56 bits of precision have been used for the double precision value in REG 1.
0B7BH
PUSH AF
Save the exponent in register A on the stack.
0B7CH-0B7EH
Gosub to 09BF which loads most significant four bytes of the double precision value in REG 1 into register pair BC/DE.
0B7FH-0B81H
Gosub to 09DFH to turn on the sign bit and return with the value of the sign.
0B82H
XOR (HL)
Combine the value at the location of the memory pointer in register pair HL with the result of the sign test in register A.
0B83H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0B84H-0B85H
LD (HL),B8H
Save an exponent at the location of the memory pointer in register HL.
0B86H
PUSH AF
Save the value of the sign test in register A on the stack.
0B87H-0B89H
Go adjust the number in REG 1 if it’s negative.
0B8AH-0B8CH
LD HL,4123H
Load register pair HL with the address of the MSB in REG 1.
0B8DH-0B8EH
LD A,B8H
Load register A with the maximum value of an exponent.
0B8FH
SUB B
Subtract the value of the exponent at the location of the memory pointer in register pair HL from the value in register A.
0B90H-0B92H
Go adjust the value in REG 1.
0B93H
POP AF
Get the value of the sign test from the stack and put it in register A.
0B94H-0B96H
Go adjust the value in REG 1 if it’s negative.
0B97H
XOR A
Zero register A.
0B98H-0B9AH
LD (411CH),A
Zero memory location 16668.
Note: 411CH holds Used by floating point routines.
0B9BH
POP AF
Get the value of the original exponent test from the stack and put it in register pair AF.
0B9CH
RET NC
Return if more than 56 bits are used by the double precision number.
0B9DH-0B9FH
Jump to 0CD8H.

0BA0H-0BA9H – LEVEL II BASIC MATH ROUTINE

0BA0H-0BA2H
LD HL,411DH
Load register pair HL with the starting address of REG 1.
Note: 411DH-4124H holds REG l.
0BA3H
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
0BA4H
DEC (HL)
Decrement the value at the location of the memory pointer in register pair HL.
0BA5H
OR A
Check to see if the value in register A is equal to zero.
0BA6H
INC HL
Decrement the value of the memory pointer in register pair HL.
0BA7H-0BA8H
Loop until the value at the location of the memory pointer in register pair HL is equal to a nonzero value.
0BA9H
RET
Return.

0BAAH-0BC6H – LEVEL II BASIC MATH ROUTINE

0BAAH
PUSH HL
Save the value in register pair HL on the stack.
0BABH-0BADH
LD HL,0000H
Load register pair HL with zero.
0BAEH
LD A,B
Load register A with the MSB of the integer value in register B.
0BAFH
OR C
Combine the LSB of the integer value in register C with the MSB of the integer value in register A.
0BB0H-0BB1H
Jump if the integer value in register pair BC is equal to zero.
0BB2H-0BB3H
LD A,10H
Load register A with the counter value (which is 16).
0BB4H
ADD HL,HL
Multiply the result in register pair HL by two.
0BB5H-0BB7H
Display a BS ERROR message if the result in register pair HL has overflowed.
0BB8H
EX DE,HL
Exchange the integer value in register pair DE with the result in register pair HL.
0BB9H
ADD HL,HL
Multiply the integer value in register pair HL by two.
0BBAH
EX DE,HL
Exchange the result in register pair DE with the integer value in register pair HL.
0BBBH-0BBCH
Jump if the most significant bit in the integer value in register DE wasn’t set.
0BBDH
ADD HL,BC
Add the integer value in register pair BC to the result in register pair HL.
0BBEH-0BC0H
Display a BS ERROR message if the result in register pair HL has overflowed.
0BC1H
DEC A
Decrement the counter in register A.
0BC2H-0BCJH
Loop until the multiplication has been completed.
0BC4H
EX DE,HL
Load register pair DE with the result in register pair HL.
0BC5H
POP HL
Get the value from the stack and put it in register pair HL.
0BC6H
RET
Return.

0BC7H-0BD1H – INTEGER SUBTRACTION
“SUBINT”

  • Integer subtract. (REG 1=DE-HL) The result is returned in both REG 1 and the HL register pair.
    Subtracts the value in DE from the value in HL. The difference is left in the HL register pair. DE is preserved. In the event of underflow, both values are converted to single precision and the subtraction is repeated. The result is left in REG 1 and the mode flag is updated accordingly.
  • Note: If you wanted to subtract 2 integers via a ROM call, store one into DE and the subtrahend in HL (i.e., to do 26-17, DE gets 26), and then call 0BC7H. The integer result will be stored in 4121H-4122H approximately 210 microseconds later, and 40AFH will be set to 2 (to flag it as an integer). If there is an overflow, it will be converted to single precision (with 40AFH being a 4 in that case) and will be stored in 4121H-4124H.
0BC7H
“ISUB”
LD A,H
Load register A with the MSB of the integer value in register H.
0BC8H
RLA
Put the value of the sign bit into the Carry flag.
0BC9H
SBC A,A
Adjust register A according to the value of the sign bit.
0BCAH
LD B,A
Load register B with the result of the sign test.
0BCBH-0BCDH
Go complement the value in register pair HL.
0BCEH
LD A,C
Load register A with zero.
0BCFH
SBC A,B
Adjust the value of the sign test.
0BD0H-0BD1H
Jump to 0BD5H.

0BD2H-0BF1H – INTEGER ADDITION
“ADDINT”

  • Integer addition (REG 1=DE+HL). After execution NTF=2, or 4 if overflow has occurred, in which case the result in REG 1 will be single-precision. The result is returned in both REG 1 and the HL register pair.
    Adds the integer value in DE to the integer in HL. The sum is left in HL and the orginal contents of DE are preserved. If overflow occurs (sum exceeds 2**15), both values are converted to single precision and then added. The result would be left in Reg 1 and the mode flag would be updated.
  • Note: If you wanted to add 2 integers via a ROM call, store one input into DE and the other into HL, and then call 0BD2H. The result will be in 4121H-4122H and in HL, with a 2 in 40AFH, and will take about 130 microseconds. If there is an overflow, the result will be converted to Single Precision and put into 4121H-4124H (with a 4 in 40AFH).
0BD2H
LD A,H
Load register A with the MSB of the integer value in register pair HL.
0BD3H
RLA
Put the value of the sign bit into the Carry flag.
0BD4H
SBC A,A
Adjust register A according to the value of the sign bit.
0BD5H
LD B,A
Load register B with the result of the sign test.
0BD6H
PUSH HL
Save the integer value in register pair HL on the stack.
0BD7H
LD A,D
Load register A with the MSB of the integer value in register pair DE.
0BD8H
RLA
Put the value of the sign bit into the Carry flag.
0BD9H
SBC A,A
Adjust register A according to the value of the sign bit.
0BDAH
ADD HL,DE
Add the integer value in register pair DE to the integer value in register pair HL.
0BDBH
ADC A,B
Add the Carry flag and the value from the sign test for the integer value in register pair HL in register B to the value of the sign test for the integer value in register pair DE in register A.
0BDCH
RRCA
Put the value of the Carry flag in register A.
0BDDH
XOR H
Combine the value of the sign bit for the result in register H with the value in register A.
0BDEH-0BE0H
Jump unless overflow has occurred.
0BE1H
PUSH BC
Save the value of the sign test in register B on the stack.
0BE2H
EX DE,HL
Load register pair HL with the integer value in register pair DE.
0BE3H-0BE5H
Go convert the register value in register pair HL to single precision and return with the result in REG 1.
0BE6H
POP AF
Get the value of the sign test from the stack and put it in register A.
0BE7H
POP HL
Get the integer value from the stack and put it in register pair HL.
0BE8H-0BEAH
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
0BEBH
EX DE,HL
Load register pair DE with the integer value in register pair HL.
0BECH-0BEEH
Go convert the integer value in register pair DE to single precision and return with the result in REG 1.
0BEFH-0BF1H
Go perform single precision addition.

0BF2H-0ClEH – INTEGER MULTIPLICATION
“MLTINT”

  • Integer multiply. (REG 1=DE*HL). Multiplies HL by DE. The product is left in HL and DE is preserved. If overflow occurs, both values are converted to single precision and the operation is restarted. The product would be left in REG 1.
  • Note: If you wanted to multiply two integers, store one input in DE, the other in HL CALL 0BF2H. The result is in 4121H-4122H and in HL, with a 2 in 40AFH (but in an overflow the result is converted to single precision format and stored in 4121H-4124H, with a 4 in 40AFH. Process takes approximately 900 microseconds.
0BF2H
“IMUL”
LD A,H
Load register A with the MSB of the integer value in register H.
0BF3H
OR L
Combine the LSB of the integer value in register L with the MSB of the integer value in register A.
0BF4H-0BF6H
Jump if the integer value in register pair HL is equal to zero.
0BF7H
PUSH HL
Save the integer value in register pair HL on the stack.
0BF8H
PUSH DE
Save the integer value in register pair DE on the stack.
0BF9H-0BFBH
Go convert any negative integer values to positive and return with register B set according to the value of the sign bits.
0BFCH
PUSH BC
Save the value of the sign bit test in register B on the stack.
0BFDH
LD B,H
Load register B with the MSB of the integer value in register H.
0BFEH
LD C,L
Load register C with the LSB of the integer value in register L.
0BFFH-0C01H
LD HL,0000H
Load register pair HL with zero.
0C02H-0C03H
LD A,10H
Load register A with the counter value (which is 16).
0C04H
ADD HL,HL
Multiply the result in register pair HL by two.
0C05H-0C06H
Jump if the result in register pair HL has overflowed.
0C07H
EX DE,HL
Exchange the integer value in register pair DE with the integer result in register pair HL.
0C08H
ADD HL,HL
Multiply the integer value in register pair HL by two.
0C09H
EX DE,HL
Exchange the integer result in register pair DE with the integer value in register pair HL.
0C0AH-0C0BH
Jump if the most significant bit of the integer register pair DE wasn’t set.
0C0CH
ADD HL,BC
Add the integer value in register pair BC to the integer result in register pair HL.
0C0DH-0C0FH
Jump if the result in register pair HL has overflowed.
0C10H
DEC A
Decrement the value of the counter in register A.
0C11H-0C12H
Loop until the multiplication has been completed.
0C13H
POP BC
Get the value of the sign test from the stack and put it in register B.
0C14H
POP DE
Get the integer value from the stack and put it in register pair DE.
0C15H
LD A,H
Load register A with the MSB of the result in register H.
0C16H
OR A
Check to see if the sign bit in the MSB of the integer result in register A is set.
0C17H-0C19H
Jump if the integer result in register pair HL is negative.
0C1AH
POP DE
Get the integer value from the stack and put it in register pair DE.
0C1BH
LD A,B
Load register A with the value of the sign test in register B.
0C1CH-0C1EH
Jump to 0C4DH.

0ClFH-0C34H – LEVEL II BASIC MATH ROUTINE

0C1FH-0C20H
XOR 80H
Clear the sign bit for the MSB of the integer value in register A which is 1000 0000.
0C21H
OR L
Combine the value of the LSB for the integer value in register L with the adjusted MSB of the integer value in register A.
0C22H-0C23H
Jump if the result is equal to zero.
0C24H
EX DE,HL
Load register pair HL with the integer value in register pair DE.
0C25H-0C28H
LD BC,E1C1H
Z-80 Trick – See the note at 0134H for an explanation.
0C26H
POP BC
Get the value of the sign test from the stack and put it in register B.
0C27H
POP HL
Get the integer value from the stack and put it in register pair HL.
0C28H-0C2AH
Go convert the integer value in register pair HL to single precision and return with the result in REG 1.
0C2BH
POP HL
Get the integer value from the stack and put it in register pair HL.
0C2CH-0C2EH
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
0C2FH-0C31H
Go convert the integer value in register pair HL to single precision and return with the result in REG 1.
0C32H
POP BC
Get the exponent and the MSB of the single precision value from the stack and put it in register pair BC.
0C33H
POP DE
Get the NMSB and the LSB of the single precision value from the stack and put it in register pair DE.
0C34H-0C36H
Jump to the SINGLE PRECISION MULTIPLY routine at 0847H (which multiplies the current value in REG 1 by the value in (BC/DE). The product is left in REG 1.

0C37H-0C44H – LEVEL II BASIC MATH ROUTINE

0C37H
LD A,B
Load register A with the result of the sign test in register B.
0C38H
OR A
Check to see if the result is supposed to be negative.
0C39H
POP BC
Get the value from the stack and put it in register pair BC.
0C3AH-0CJCH
Jump if the result is supposed to be negative.
0C3DH
PUSH DE
Save the integer value in register pair DE on the stack.
0C3EH-0C40H
Go convert the integer result in register pair HL to single precision and return with the result in REG 1.
0C41H
POP DE
Get the integer value from the stack and put it in register pair DE.
0C42H-0C44H
Jump to 0982H.

0C45H-0C5AH – LEVEL II BASIC MATH ROUTINE

0C45H
LD A,H
Load register A with the MSB of the integer value in register H.
0c46H
XOR D
Combine the MSB of the integer value in register D with the MSB of the integer value in register A.
0C47H
LD B,A
Save the result of the combined signs in register A into register B.
0C48H-0C4AH
Go convert a negative integer value in register pair HL to positive.
0C4BH
EX DE,HL
Exchange the integer value in register pair DE with the integer value in register pair HL.
0C4CH
LD A,H
Load register A with the MSB of the integer value in register H.
0C4DH
OR A
Check the value of the sign for the MSB of the integer value in register A.
0C4EH-0C50H
Jump if the integer value in register pair HL is positive.
0C51H
XOR A
Zero register A.
Negate HL routine. This routine changes the sign of the HL register pair and stores it in the ACC. (HL=REG 1=-HL) The result is returned in both the HL register pair and the ACC.
0C52H
LD C,A
Load register C with the value in register A.
0C53H
SUB L
Subtract the LSB of the integer value in register L from the value in register A.
0C54H
LD L,A
Save the adjusted value in register A in register L.
0C55H
LD A,C
Load register A with the value in register C.
0C56H
SBC A,H
Subtract the MSB of the integer value in register H from the value in register A.
0C57H
LD H,A
Save the adjusted value in register A into register H.
0C58H-0C5AH
Jump to 0A9AH.

0C5BH-0C6FH – LEVEL II BASIC MATH ROUTINE

0C5BH-0C5DH
LD HL,(4121H)
Load register pair HL with the integer value in REG 1.
0C5EH-0C60H
Go convert the integer value in register pair HL to positive if it’s negative.
0C61H
LD A,H
Load register A with the MSB of the integer value in register H.
0C62H-0C63H
XOR 80H
Invert the value of the sign bit in register A which is 1000 0000.
0C64H
OR L
Combine the LSB of the integer value in register L with the adjusted MSB of the integer value in register A.
0C65H
RET NZ
Return if the integer value in REG 1 isn’t equal to -32768.
0C66H
EX DE,HL
Load register pair DE with the integer value in register pair HL.
0C67H-0C69H
Go set the number type flag to single precision.
0C6AH
XOR A
Zero register A.
0C6BH-0C6CH
LD B,98H
Load register B with an exponent.
0C6DH-0C6FH
Jump to 0969H.

0C70H-0C76H – DOUBLE PRECISION SUBTRACTION
“SUBDP”

  • Double-precision subtraction (REG 1=ACC-AACC).
    Subtracts the double precision value in REG 2 from the value in REG 1. The difference is left in REG 1.
  • Note: If you wanted to subtract two double precision numbers, store the minuend in 411DH-4124H and the subtrahend in 4127H-412EH, and CALL 0C70H. The result (in double precision format) is in 411DH-4124H in approximately 1.3 milliseconds.
0C70H-0C72H
“DSUB”
LD HL,412DH
Load register pair HL with the address of the MSB in REG 2.
0C73H
LD A,(HL)
Load register A with the MSB of the double precision value in REG 2 at the location of the memory pointer in register pair HL.
0C74H-0C75H
XOR 80H
Invert the value of the sign bit for the MSB of the double precision value in register A which is 1000 0000.
0C76H
LD (HL),A
Save the adjusted MSB of the double precision value in register A in REG 2 at the location of the memory pointer in register pair HL.

0C77H-0CCEH -DOUBLE PRECISION ADDITION
“ADDDP”

  • Double-precision addition (REG 1=ACC+AACC).
    Adds the double precision value in REG 2 to the value in REG 1. Sum is left in REG 1.
  • Note: If you wanted to add 2 double precision numbers via a ROM call, store one input into 411DH-4124H and the other in 4127H-412EH. Then call 0C77H. The double precision result will be stored in 411DH-4124H approximately 1.3 milliseconds later.
0C77H-0C79H
“DADD”
LD HL,412EH
Load register pair HL with the address of the exponent in REG 2.
0C7AH
LD A,(HL)
Load register A with the exponent of the double precision value in REG 2 at the location of the memory pointer in register pair HL.
0C7BH
OR A
Check to see if the double precision value in REG 2 is equal to zero.
0C7CH
RET Z
Return if the double precision value in REG 2 is equal to zero.
0C7DH
LD B,A
Load register B with the value of the exponent for the double precision value in register A.
0C7EH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0C7FH
LD C,(HL)
Load register C with the value of the MSB of the double precision value in REG 2 at the location of the memory pointer in register pair HL.
0C80H-0C82H
LD DE,4124H
Load register pair DE with the address of the exponent in REG 1.
0C83H
LD A,(DE)
Load register A with the value of the exponent of the double precision value in REG 1 at the location of the memory pointer in register pair DE.
0C84H
OR A
Check to see if the double precision value in REG 1 is equal to zero.
0C85H-0C87H
Jump if the double precision value in REG 1 is equal to zero.
0C88H
SUB B
Subtract the value of the exponent for the double precision value in REG 2 in register B from the value of the exponent for the double precision value in REG 1 in register A.
0C89H-0C8AH
Jump if the double precision value in REG 1 is greater than or equal to the double precision value in REG 2.
0C8BH
CPL
Complement the difference between the two exponents in register A.
0C8CH
INC A
Increment the value of the difference for the exponents in register A so that register A will hold the positive difference.
0C8DH
PUSH AF
Save the difference for the exponents in register A on the stack.
0C8EH-0C8FH
LD C,08H
Load register C with the counter value which is 8.
0C90H
INC HL
Increment the value of the memory pointer in register pair HL so that it will be pointing to the exponent of the double precision value in REG 2.
0C91H
PUSH HL
Save the value of the memory pointer in register pair HL on the stack.
0C92H
LD A,(DE)
Load register A with the value at the location of the memory pointer in register pair DE.
0C93H
LD B,(HL)
Load register B with the value at the location of the memory pointer in register pair HL.
0C94H
LD (HL),A
Save the value in register A at the location of the memory pointer in register pair HL.
0C95H
LD A,B
Load register A with the value in register B.
0C96H
LD (DE),A
Save the value in register A at the location of the memory pointer in register pair DE.
0C97H
DEC DE
Decrement the value of the memory pointer in register pair DE.
0C98H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0C99H
DEC C
Decrement the value of the counter in register C.
0C9AH-0C9BH
Loop until the double precision values in REG 1 and REG 2 have been exchanged.
0C9CH
POP HL
Get the value of the memory pointer from the stack and put it in register pair HL.
0C9DH
LD B,(HL)
Load register B with the value of the exponent for the double precision value in REG 2 at the location of the memory pointer in register pair HL.
0C9EH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0C9FH
LD C,(HL)
Load register C with the value of the MSB for the double precision value in REG 2 at the location of the memory pointer in register pair HL.
0CA0H
POP AF
Get the difference for the exponents from the stack and put it in register A.
0CA1H-0CA2H
CP 39H
Check to see if the difference between the two exponents is greater than 56 bits.
0CA3H
RET NC
Return if the difference between the two exponents is greater than 56 bits.
0CA4H
PUSH AF
Save the difference for the exponents in register A on the stack.
0CA5H-0CA7H
Go turn on the sign bits for the double precision numbers.
0CA8H
INC HL
Increment the value of the memory pointer in register pair HL.
0CA9H-0CAAH
LD (HL),00H
Zero the location of the memory pointer in register pair HL.
0CABH
LD B,A
Save the result of the sign test in register A in register B.
0CACH
POP AF
Get the difference for the exponents from the stack and put it in register A.
0CADH-0CAFH
LD HL,412DH
Load register pair HL with the address of the MSB in REG 2.
0CB0H-0CB2H
Go shift the double precision value in REG 2 until it lines up with the double precision value in REG 1.
0CB3H-0CB5H
LD A,(4126H)
Get the bits shifted out of the double precision value in REG2 and put it in register A.
0CB6H-0CB8H
LD (411CH),A
Save the value in register A.
Note: 411CH holds Used by floating point routines.
0CB9H
LD A,B
Load register A with the value of the sign test in register B.
0CBAH
OR A
Check to see if the signs are equal.
0CBBH-0CBDH
Go subtract the values if the signs aren’t equal.
0CBEH-0CC0H
Go add the values.
0CC1H-0CC3H
Jump if the Carry flag isn’t set.
0CC4H
EX DE,HL
Load register pair HL with the value of the memory pointer in register pair DE.
0CC5H
INC (HL)
Increment the value of the exponent at the location of the memory pointer in register pair HL.
0CC6H-0CC8H
Display an ?OV ERROR if the exponent for the double precision result in REG 1 is too large.
0CC9H-0CCBH
Go adjust the double precision result in REG 1.
0CCCH-0CCEH
Jump to 0D0EH.

0CCFH-0DlFH – DOUBLE PRECISION MATH ROUTINE

0CCFH-0CD1H
Go subtract the double precision values.
0CD2H-0CD4H
LD HL,4125H
Load register pair HL with the address of the sign for the result.
Note: 4125H-4126H is used by floating point routines.
0CD5H-0CD7H
Go complement the result in REG 1 if the Carry flag is set.
0CD8H
XOR A
Zero register A.
0CD9H
LD B,A
Load register B with the value in register A.
0CDAH-0CDCH
LD A,(4123H)
Load register A with the value of the MSB of the double precision result in REG 1.
0CDDH
OR A
Check to see if the MSB of the double precision result is equal to zero.
0CDEH-0CDFH
Jump forward to 0CFEH if the MSB of the double precision value is nonzero.
0CE0H-0CE2H
LD HL,411CH
Load register pair HL with the starting address of REG 1 minus one.
Note: 411CH holds Used by floating point routines.
0CE3H-0CE4H
LD C,08H
Load register C with the number of bytes to be shifted.
0CE5H
LD D,(HL)
Load register D with the value at the location of the memory pointer in register pair HL.
0CE6H
LD (HL),A
Save the value in register A at the location of the memory pointer in register pair HL.
0CE7H
LD A,D
Load register A with the value in register D.
0CE8H
INC HL
Increment the value of the memory pointer in registerpair HL.
0CE9H
DEC C
Decrement the number of bytes to be shifted in register C.
0CEAH-0CEBH
Loop until all of the bytes in the double precision value have been shifted.
0CECH
LD A,B
Load register A with the number of bits shifted in register B.
0CEDH-0CEEH
SUB 08H
Subtract the number of bits just shifted from the shift counter in register A.
0CEFH-0CF0H
CP C0H
Check to see if the whole of the double precision value has been shifted.
0CF1H-0CF2
H Jump if the whole of the double precision value hasn’t been shifted.
0CF3H-0CF5H
Go make the double precision value equal to zero if the whole of the double precision value has been shifted.
0CF6H
DEC B
Decrement the shift counter in register B.
0CF7H-0CF9H
LD HL,411CH
Load register pair HL with the starting address of REG 1 minus one.
Note: 411CH holds Used by floating point routines.
0CFAH-0CFCH
Gosub to shift the double precision value in REG 1 once.
0CFDH
OR A
Check to see if the sign bit of the MSB of the double precision value in register A is set.
0CFEH-0D00H
Loop until the sign bit is set.
0D01H
LD A,B
Load register A with the value of the shift counter in register B.
0D02H
OR A
Check to see if the shift counter in register A is equal to zero.
0D03H-0D04H
Jump if the value in REG 1 wasn’t shifted at all.
0D05H-0D07H
LD HL,4124H
Load register pair HL with the address of the exponent in REG 1.
0D08H
ADD A,(HL)
Add the value of the exponent for the double preci­sion value in REG 1 at the location of the memory pointer in register pair HL to the value of the shift counter in register A.
0D09H
LD (HL),A
Save the adjusted exponent for the double precision value in register A at the location of the memory pointer in register pair HL.
0D0AH-0D0CH
Jump if overflow didn’t occur.
0D0DH
RET Z
Return if the double precision value is equal to zero.
0D0EH-0D10H
LD A,(411CH)
Load register A with the value of the rounding byte at the location of the starting address of REG 1 minus one.
Note: 411CH holds Used by floating point routines.
0D11H
OR A
Check to see if there is a bit to be shifted into the double precision value in REG 1.
0D12H-0D14H
Go move the bit into the double precision value if necessary.
0D15H-0D17H
LD HL,4125H
Load register pair HL with the address of the sign for the result.
Note: 4125H-4126H is used by floating point routines.
0D18H
LD A,(HL)
Load register A with the value of the sign for the result at the location of the memory pointer in register pair HL.
0D19H-0D1AH
AND 80H
Mask the value of the sign for the result in register A which is 1000 0000.
0D1BH
DEC HL
Decrement the value of the memory pointer in register pair HL so that it points to the exponent in REG 1.
0D1CH
DEC HL
Decrement the value of the memory pointer in register pair HL so that it points to the MSB inREG 1
0D1DH
XOR (HL)
Combine the value of the MSB of the double preci­sion value in REG 1 at the location of the memory pointer in register pair HL with the value of the sign for the result in register A.
0D1EH
LD (HL),A
Save the adjusted MSB of the double precision value in register A at the location of the memory pointer in register pair HL.
0D1FH
RET
Return.

0D20H-0D32H – DOUBLE PRECISION MATH ROUTINE

0D20H-0D22H
LD HL,411DH
Load register pair HL with the starting address in REG 1.
Note: 411DH-4124H holds REG l.
0D23H-0D24H
LD B,07H
Load register B with the number of bytes to be bumped for the double precision value in REG 1.
0D25H
INC (HL)
Increment the value at the location of the memory pointer in register pair HL.
0D26H
RET NZ
Return if the value at the location of the memory pointer in register pair HL isn’t equal to zero.
0D27H
INC HL
Increment the value of the memory pointer in register pair HL.
0D28H
DEC B
Decrement the value of the byte counter in register B.
0D29H-0D2AH
Loop until all of the necessary bytes have been bumped.
0D2BH
INC (HL)
Increment the value of the exponent at the location of the memory pointer in register pair HL.
0D2CH-0D2EH
Go to the Level II BASIC error routine and display an OV ERROR message if the exponent for the double precision value in REG 1 is too large.
0D2FH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0D30H-0D31H
LD (HL),80H
Save a new MSB at the location of the memory pointer in register pair HL.
0D32H
RET
Return.

0D33H-0D44H – DOUBLE PRECISION MATH ROUTINE

0D33H-0D35H
LD HL,4127H
Load register pair HL with the starting address of REG 2.
Note: 4127H-412EH holds REG 2.
0D36H-0D38H
LD DE,411DH
Load register pair DE with the starting address of REG 1.
Note: 411DH-4124H holds REG l.
0D39H-0D3AH
LD C,07H
Load register C with the number of bytes to be added.
0D3BH
XOR A
Clear the Carry flag.
0D3CH
LD A,(DE)
Load register A with the value in REG 1 at the location of the memory pointer in register pair DE.
0D3DH
ADC A,(HL)
Add the value in REG 2 at the location of the memory value in register A.
0D3EH
LD (DE),A
Save the result in register A in REGI at the location of the memory pointer in register pair DE.
0D3FH
INC DE
Increment the value of the memory pointer in register pair DE.
0D40H
INC HL
Increment the value of the memory pointer in register pair HL.
0D41H
DEC C
Decrement the number of bytes to be added in register C.
0D42H-0D43H
Loop until all of the bytes for the double precision values have been added.
0D44H
RET
Return.

0D45H-0D56H – DOUBLE PRECISION MATH ROUTINE

0D45H-0D47H
LD HL,4127H
Load register pair HL with the starting address of REG 2.
Note: 4127H-412EH holds REG 2.
0D48H-0D4AH
LD DE,411DH
Load register pair DE with the starting address of REG 1.
Note: 411DH-4124H holds REG l.
0D4BH-0D4CH
LD C,07H
Load register C with the number of bytes to be subtracted.
0D4DH
XOR A
Clear the Carry flag.
0D4EH
LD A,(DE)
Load register A with the value in REGI at the loca­tion of the memory pointer in register pair DE.
0D4FH
SBC A,(HL)
Subtract the value in REG 2 at the location of the memory pointer in register pair HL from the value in register A.
0D50H
LD (DE),A
Save the result in register A in REG 1 at the location of the memory pointer in register pair DE.
0D51H
INC DE
Increment the value of the memory pointer in register pair DE.
0D52H
INC HL
Increment the value of the memory pointer in register pair HL.
0D53H
DEC C
Decrement the number of bytes to be subtracted for the double precision values in register C.
0D54H-0D55H
Loop until all of the bytes for the double precision values have been subtracted.
0D56H
RET
Return.

0D57H-0D68H – DOUBLE PRECISION MATH ROUTINE

0D57H
LD A,(HL)
Load register A with the value of the sign at the location of the memory pointer in register pair HL.
0D58H
CPL
Complement the value of the sign in register A.
0D59H
LD (HL),A
Save the value of the sign in register A at the location of the memory pointer in register pair HL.
0D5AH-0D5CH
LD HL,411CH
Load register pair HL with the starting address of REG 1 minus one.
Note: 411CH holds Used by floating point routines.
0D5DH-0D5EH
LD B,08H
Load register B with the number of bytes to be reversed.
0D5FH
XOR A
Zero register A.
0D60H
LD C,A
Load register C with the value in register A.
0D61H
LD A,C
Load register A with the value in register C.
0D62H
SBC A,(HL)
Subtract the value at the location of the memory pointer in register pair HL from the value in register A.
0D63H
LD (HL),A
Save the reversed value in register A at the location of the memory pointer in register pair HL.
0D64H
INC HL
Increment the value of the memory pointer in register pair HL.
0D65H
DEC B
Decrement the number of bytes to be reversed in register B.
0D66H-0D67H
Loop until all of the bytes for the double precision number in REG 1 have been reversed.
0D68H
RET
Return.

0D69H-0D8FH – DOUBLE PRECISION MATH ROUTINE

0D69H
LD (HL),C
Save the MSB of the double precision value in register C at the location of the memory pointer in register pair HL.
0D6AH
PUSH HL
Save the value of the memory pointer in register pair HL on the stack.
0D6BH-0D6CH
SUB 08H
Subtract 8 from the number of bits to be shifted from the number of bits to be shifted in register A.
0D6DH-0D6EH
Jump if there are less than 8 bits to be shifted.
0D6FH
POP HL
Get the value of the memory pointer from the stack and put it in register pair HL.
0D70H
PUSH HL
Save the value of the memory pointer in register pair HL on the stack.
0D71H-0D73H
LD DE,0800H
Load register pair DE with the number of bytes to be shifted (which is 2048) and the value to be shifted into the double precision value.
0D74H
LD C,(HL)
Load register C with the value at the location of the memory pointer in register pair HL.
0D75H
LD (HL),E
Save the value in register E at the location of the memory pointer in register pair HL.
0D76H
LD E,C
Load register E with the value in register C.
0D77H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0D78H
DEC D
Decrement the number of bytes shifted in register D.
0D79H-0D7AH
Loop until all of the bytes have been shifted.
0D7BH-0D7CH
Loop until there are less than 8 bits to be shifted.
0D7DH-0D7EH
ADD 09H
Adjust the number of bits to be shifted in register A so that it holds the correct value (adjustment against 0000 1001).
0D7FH
LD D,A
Load register D with the number of bits to be shifted in register A.
0D80H
XOR A
Zero register A.
0D81H
POP HL
Get the value of the memory pointer from the stack and put it in register pair HL.
0D82H
DEC D
Decrement the number of bits to be shifted in register D.
0D83H
RET Z
Return if all of the bits have been shifted.
0D84H
PUSH HL
Save the value of the memory pointer in register pair HL on the stack.
0D85H-0D86H
LD E,08H
Load register E with the number of bytes to be shifted.
0D87H
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
0D88H
RRA
Shift the value in register A.
0D89H
LD (HL),A
Save the adjusted value in register A at the location of the memory pointer in register pair HL.
0D8AH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0D8BH
DEC E
Decrement the number of bytes to be shifted in register E.
0D8CH-0D8DH
Loop until all of the bytes have been shifted.
0D8EH-0D8FH
Loop until all of the bits have been shifted.

0D90H-0D96H – DOUBLE PRECISION MATH ROUTINE

0D90H-0D92H
LD HL,4123H
Load register pair HL with the address of the MSB of the double precision value in REG 1.
0D93H-0D94H
LD D,01H
Load register D with the number of bits to be shifted.
0D95H-0D96H
Jump to 0D84H.

0D97H-0DA0H – DOUBLE PRECISION MATH ROUTINE

0D97H-0D98H
LD C,08H
Load register C with the number of bytes to be shifted.
0D99H
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
0D9AH
RLA
Shift the value in register A.
0D9BH
LD (HL),A
Save the shifted value in register A at the location of the memory pointer in register pair HL.
0D9CH
INC HL
Increment the value of the memory pointer in register pair HL.
0D9DH
DEC C
Decrement the byte counter in register C.
0D9EH-0D9FH
Loop until all of the bytes have been shifted.
0DA0H
RET
Return.

0DAlH-0DD3H – DOUBLE PRECISION MULTIPLICATION
“MLTDP”

  • Double-precision multiplication (REG 1=ACC*AACC).
    Multiplies the double precision value in REG 1 by the value in REG 2. The product is left in REG 1.
  • Note: If you wanted to multiply two double precision numbers store one operand in 411DH-4124H, and store the other in 4127H-412EH and then CALL 0DA1H. The result (in double precision format) is in 411DH-4124H in approximately 22 milliseconds.
0DA1H-0DA3H
“DMUL”
Go check to see if the value in REG 1 is equal to zero.
0DA4H
RET Z
Return if the double precision value in REG 1 is equal to zero.
0DA5H-0DA7H
Go figure the new exponent.
0DA8H-0DAAH
Go move the double precision value in REG 1 to a temporary work area.
0DABH
LD (HL),C
Zero the location at the current value of the memory pointer in register pair HL.
0DACH
INC DE
Increment register pair DE so that it points to the LSB of the double precision value in the temporary work area.
0DADH-0DAEH
LD B,07H
Load register B with the number of bytes to be figured.
0DAFH
LD A,(DE)
Load register A with the value at the location of the memory pointer in register pair DE.
0DB0H
INC DE
Increment the value of the memory pointer in register pair DE.
0DB1H
OR A
Check to see if the value in register A is equal to zero.

0DB2H – INTEGER ADD routine

Adds the integer value in DE to the integer in HL. The sum is left in HL and the orginal contents of DE are preserved. If overflow occurs (sum exceeds 2**15), both values are converted to single precision and then added. The result would be left in REG 1 and the mode flag would be updated.

0DB2H
“IADD”
PUSH DE
Save the value of the memory pointer in register pair DE on the stack.
0DB3H-0DB4H
Jump if the value in register A is equal to zero.
0DB5H-0DB6H
LD C,08H
Load register C with the numberofbits to be shifted.
0DB7H
PUSH BC
Save the value in register pair BC on the stack.
0DB8H
RRA
Shift the value in register A one place to the right.
0DB9H
LD B,A
Load register B with the value in register A.
0DBAH-0DBCH
Go add the value in REG 2 to the total in REG 1 if bit zero of register A was set.
0DBDH-0DBFH
Go shift the value of the total in REG 1.
0DC0H
LD A,B
Load register A with the adjusted value in register B.
0DC1H
POP BC
Get the value from the stack and put it in register pair BC.
0DC2H
DEC C
Decrement the number of bits to be shifted in regis­ter C.
0DC3H-0DC4H
Loop back to 0DB7H until all of the bits have been shifted.
0DC5H
POP DE
Get the value from the stack and put it in register pair DE.
0DC6H
DEC B
Decrement the number of bytes to be figured in register B.
0DC7H-0DC8H
Loop back to 0DAFH until all of the bytes have been figured.
0DC9H-0DCBH
Jump to 0CD8H.
0DCCH-0DCEH
LD HL,4123H
Load register pair HL with the address of the MSB in REG 1
0DCFH-0DD1H
Go shift the double precision total in REG 1.
0DD2H-0DD3H
Jump to 0DC5H.

0DD4H-0DDBH – DOUBLE PRECISION CONSTANT STORAGE AREA

0DD4H-0DDBH
00 00 00 00 00 00 20 84
A double precision constant equal to 10.0 is stored here.

0DDCH-0DE4H – DOUBLE PRECISION MATH ROUTINE

0DDCH-0DDEH
LD DE,0DD4H
Load register pair DE with the starting address of the double precision constant stored above.
0DDFH-0DE1H
LD HL,4127H
Load register pair HL w1 th the starting address of REG 2.
Note: 4127H-412EH holds REG 2.
0DE2H-0DE4H
Go move the double precision constant into REG 2.

0DE5H-0E38H – DOUBLE PRECISION DIVISION
“DIVDP”

  • Double-precision division (REG 1=ACC / AACC).
    Divides the double precision value in WRAl by the value in REG 2. The quotient is left in REG 1.
  • To use a ROM call to divide two double precision numbers, store the dividend in 411DH-4124H, and the divisor in 4127H-412EH and then CALL 0DE5H. The result (in double precision format) is in 411DH-4124H and then pproximately 42 milliseconds. Overflow or /0 will error out and return to Level II.
0DE5H-0DE7H
“DDIV”
LD A,(412EH)
Load register A with the value of the exponent for the double precision value in REG 2.
0DE8H
OR A
Check to see if the double precision value in REG 2 is equal to zero.
0DE9H-0DEBH
Display a /0 ERROR message if the double precision value in REG 2 is equal to zero.
0DECH-0DEEH
Go figure the value of the new exponent.
0DEFH
INC (HL)
Increment the value of the exponent in REG 1.
0DF0H
INC (HL)
Increment the value of the exponent in REG 1.
0DF1H-0DF3H
Go move the double precision value from REG 1 into the temporary work area.
0DF4H-0DF6H
LD HL,4151H
Load register pair HL with the address of the expo­nent in the temporary work area.
0DF7H
LD (HL),C
Zero the value of the exponent in the temporary work area at the location of the memory pointer in register pair HL.
0DF8H
LD B,C
Zero register B.
0DF9H-0DFBH
LD DE,414AH
Load register pair DE with the starting address of the double precision value in the temporary work area.
Note: 414AH-4151H holds Used by floating pointer routines.
0DFCH-0DFEH
LD HL,4127H
Load register pair HL with the starting address of the double precision value in REG 2.
Note: 4127H-412EH holds REG 2.
0DFFH-0E01H
Go subtract the double precision value in REG 2 from the double precision value in the temporary work area.
0E02H
LD A,(DE)
Load register A with the value at the location of the memory pointer in register pair DE.
0E03H
SBC A,C
Subtract the value in register C from the value in register A.
0E04H
CCF
Complement the value of the Carry flag.
0E05H-0E06H
Jump if the double precision value in REG 2 is greater than the double precision value in the temporary work area.
0E07H-0E09H
LD DE,414AH
Load register pair DE with the starting address of the double precision value in the temporary work area.
Note: 414AH-4151H holds Used by floating pointer routines.
0E0AH-0E0CH
LD HL,4127H
Load register pair HL with the starting address of tht double precision value in REG 2.
Note: 4127H-412EH holds REG 2.
0E0DH-0E0FH
Go add the double precision value in REG 2 to the double precision value in the temporary work area.
0E10H
XOR A
Zero register A.
0E12H
Save the value of the exponent in register A at the location of the memory pointer in register pair DE.
0E13H
LD A,(4123H)
Increment the counter in register B.
0E14H-0E16H
INC A
Load register A with the value of the MSB of the total in REG 1.
0E17H
DEC A
Increment the value of the MSB for the double precision result in register A.
0E18H
RRA
Decrement the value of the MSB for the double precision result in register A.
0E19H
Put the value of the Carry flag into register A as the sign bit.
0E1AH-0E1CH
RLA
Jump if the sign bit was set. 0ElDH Put the sign bit in register A back into the Carry flag.
0E1EH-0E20H
LD HL,411DH
Load register pair HL with the starting address of the double precision result in REG 1.
Note: 411DH-4124H holds REG l.
0E21H-0E22H
LD C,07H
Load register C with the number of bytes to be shifted.
0E23H-0E25H
Go shift the double precision result in REG 1.
0E26H-0E28H
LD HL,414AH
Load register pair HL with the starting address of the double precision value in the temporary work area.
Note: 414AH-4151H holds Used by floating pointer routines.
0E29R-0E2BH
Go shift the double precision value in the temporary work area.
0E2CH
LD A,B
Load register A with the value of the counter in register B.
0E2DH
OR A
Check to see if the value of the counter in register A is equal to zero.
0E2EH-0E2FH
Loop until done if the value of the counter in register A isn’t equal to zero.
0E30H-0E32H
LD HL,4124H
Load register pair HL with the address of the exponent for the double precision result in REG 1 (which is 16676).
0E33H
DEC (HL)
Decrement the value of the exponent for the double precision result in REG 1 at the location of the mem­ory pointer in register pair HL.
0E34H-0E35H
Loop until done if overflow didn’t occur.
0E36H-0E38H
Display an ?OV ERROR if the exponent for the result in REG 1 is too small.

0E39H-0E4CH – DOUBLE PRECISION MATH ROUTINE

0E39H
LD A,C
Load register A with the MSB of the double preci­sion value in REG 2 in register C.
0E3AH-0E3CH
LD (412DH),A
Save the MSB of the double precision value in REG 2 in register A.
0E3DH
DEC HL
Decrement the value of the memory pointer in register pair HL.
0E3EH-0E40H
LD DE,4150H
Load register pair DE with the starting address of the temporary work area.
0E41H-0E43H
LD BC,0700H
Load register B with the number of bytes to be moved (which is 1792) and zero register C.
0E44H
LD A,(HL)
Load register A with the value at the location of the memory pointer in register pair HL.
0E45H
LD (DE),A
Save the value in register A at the location of the memory pointer in register pair DE.
0E46H
LD (HL),C
Zero the location of the memory pointer in register pair HL.
0E47H
DEC DE
Decrement the value of the memory pointer in register pair DE.
0E48H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0E49H
DEC B
Decrement the value of the byte counter in register B.
0E4AH-0E4BH
Loop until the double precision value has been moved to the temporary work area.
0E4CH
RET
Return.

0E4DH-0E64H – LEVEL II BASIC MATH ROUTINE

  • This routine multiplies the current DP value by 2 by adding it to itself. First the current value is moved to a saved location, and then DP add routine adds the current value to that saved value.
0E4DH-0E4FH
Go move the value in REG 1 to REG 2.
0E50H
EX DE,HL
Load register pair HL with the value of the memory pointer in register pair DE.
0E51H
DEC HL
Decrement the value of the memory pointer in register pair HL.
0E52H
LD A,(HL)
Load register A with the value of the exponent in REG 1 at the location of the memory pointer in register pair HL.
0E53H
OR A
Check to see if the value in REG 1 is equal to zero.
0E54H
RET Z
Return if the value in REG 1 is equal to zero.
0E55H-0E56H
ADD 02H
Adjust the exponent for the following addition.
0E57H-0E59H
Display an ?OV ERROR if the adjusted exponent in register A is too large.
0E5AH
LD (HL),A
Save the adjusted exponent in register A in REG 1 at the location of the memory pointer in register pair HL.
0E5BH
PUSH HL
Save the value of the memory pointer in register pair HL on the stack.
0E5CH-0E5EH
Call the DOUBLE PRECISION ADD function (whcih adds the double precision value in REG 2 to the value in REG 1. Result is left in REG 1).
0E5FH
POP HL
Get the value of the memory pointer from the stack and put it in register pair HL.
0E60H
INC (HL)
Increment the value of the exponent for the double preci­sion value in REG 1 at the location of the memory pointer in register pair HL.
0E61H
RET NZ
Return if overflow didn’t occur.
0E62H-0E64H
Display an ?OV ERROR if the exponent in REG 1 at the location of the memory pointer in register pair HL is too large.

0E65H-0F88H – ASCII TO DOUBLE PRECISION

  • This routine converts an ASCII string (pointed to by HL) to a double-precision value and stores it in the ACC. The NTF is fixed accordingly. The string must be terminated with a , or zero byte. Note that the AACC is destroyed in the process and that HL will point to the delimiter at the end of the string. The string formats must follow the same rules as in BASIC.
0E65H-0E67H
Go zero the exponent in REG 1.
0E68H-0E6AH
Go set the current number type flag to double precision.

0E6CH – ASCII to Binary Converter

  • A call to 0E6CH converts the ASCII string pointed to by HL to binary. If the value is less than 2** 16 and does not contain a decimal point or an E or D descriptor (exponent), the string will be converted to its integer equivalent. If the string contains a decimal point or an E, or D descriptor or if it exceeds 2** 16 it will be converted to single or double precision. The binary value will be left in REG 1 and the mode flag will be to the proper value.
  • Note: If you wanted to do this conversion via a ROM call, first have the characters assembled in consecutive memory locations, with either a comma or a 00H at the end. Load HL with the address of the first character. Call 0E6CH. If the output can be an integer, it will be in 4121H-4122H (with 40AFH being a 2). If the output has to be single precision, it will be in 4121H-4124H (with 40AFH being a 4). If the output has to be double precision, it will be in 411DH-4124H (with 40AFH being an 8).
0E6CH
“ASTOR”
OR AFH
Zero register A (by issuing an OR against 1010 1111).
This routine is the same as E65H above, except that it fixes REG 1 and NTF to the smallest possible number type.
0E6DH
EX DE,HL
Load register pair DE with the current input buffer pointer in register pair HL.
0E6EH-0E70H
LD BC,00FFH
Load register pair BC with a zero and a negative one.
0E71H
LD H,B
Load register H with zero.
0E72H
LD L,B
Load register L with zero.
0E73H-0E75H
Go set the current number type flag to integer if the routine was entered from OE6CH.
0E76H
EX DE,HL
Load register pair HL with the input buffer pointer in register pair DE.
0E77H
LD A,(HL)
Load register A with the character at the location of the current input buffer pointer in register pair HL.
0E78H-0E79H
CP 2DH
Check to see if the character at the location of the current input buffer pointer in register A is a minus sign(-).
0E7AH
PUSH AF
Save the value in register pair AF on the stack.
0E7BH-0E7DH
Jump if the character at the location of the current input buffer pointer in register A is a minus sign (-).
0E7EH-0E7FH
CP 2BH
Check to see if the character at the location of the current input buffer pointer in register A is a plus sign(+).
0E80H-0E81H
Jump if the character at the location of the current input buffer pointer in register A is a plus sign ( +).
0E82H
DEC HL
Decrement the value of the current input buffer pointer in register pair HL.
0E83H
RST 10H
Since we need to bump the current input buffer pointer in register pair HL until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H (which Loads the next character from the string pointed to by the HL register set into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric. Blanks and control codes 09 and OB are ignored causing the following character to be loaded and tested. The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one. The string must be terminated by a byte of zeros).
0E84H-0E86H
Jump if the character at the location of the current input buffer pointer in register A is numeric.
0E87H-0E88H
CP 2EH
Check to see if the character at the location of the current input buffer pointer in register A is a decimal point (.).
0E89H-0E8BH
Jump if the character at the location of the current input buffer pointer in register A is a decimal point (.).
0ESCH-0E8DH
CP 45H
Check to see if the character at the location of the current input buffer pointer in register A is an E.
0E8EH-0E8FH
Jump if the character at the location of the current input buffer pointer in register A is an E.
0E90H-0E91H
CP 25H
Check to see if the character at the location of the current input buffer pointer in register A is a %.
0E92H-0E94H
Jump if the character at the location of the current input buffer pointer in register A is a %.
0E95H-0E96H
CP 23H
Check to see if the character at the location of the current input buffer pointer in register A is a #.
0E97H-0E99H
Jump if the character at the location of the current input buffer pointer in register A is a #.
0E9AH-0E9BH
CP 21H
Check to see if the character at the location of the current input buffer pointer in register A is an ! .
0E9CH-0E9EH
Jump if the character at the location of the current input buffer pointer in register A is an ! .
0E9FH-0EA0H
CP 44H
Check to see if the character at the location of the current input buffer pointer in register A is a D.
0EA1H-0EA2H
Jump if the character at the location of the current input buffer pointer in register A isn’t a D.
0EA3H
OR A
Set the flags according to the value of the character at the location of the current input buffer pointer in register A.
0EA4H-0EA6H
Go convert the current value in REG 1 to either single precision or double precision.
0EA7H
PUSH HL
Save the current input buffer pointer in register pair HL on the stack.
0EA8H-0EAAH
LD HL,0EBDH
Load register pair HL with the return address (which is 3773).
0EABH
EX (SP),HL
Exchange the return address in register pair HL with the value of the current input buffer pointer in register pair HL.
0EACH
RST 10H
Since we need to bump the current input buffer pointer in register pair HL until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
0EADH
DEC D
Decrement the value in register D.
0EAEH-0EAFH
CP CEH
Check to see if the character at the location of the current input buffer pointer in register A is a minus sign token ( CEH).
0EB0H
RET Z
Return if the character at the location of the current input buffer pointer in register A is a minus sign token (CEH).
0EB1H-0EB2H
CP 2DH
Check to see if the character at the location of the current input buffer pointer in register A is a minus sign(-).
0EB3H
RET Z
Return if the character at the location of the current input buffer pointer in register A is a minus sign (-).
0EB4H
INC D
Increment the value in register D.
0EB5H-0EB6H
CP CDH
Check to see if the character at the location of the current input buffer pointer in register A is a plus sign token (CDH.)
0EB7H
RET Z
Return if the character at the location of the current input buffer pointer in register A is a plus sign token (CDH).
0EB8H-0EB9H
CP 2BH
Check to see if the character at the location of the current input buffer pointer in register A is a plus sign ( +).
0EBBH
RET Z
Return if the character at the location of the current input buffer pointer in register A is a plus sign ( +).
0EBAH
DEC HL
Decrement the value of the input buffer pointer in register pair HL.
0EBCH
POP AF
Get the value from the stack and put it in register pair AF.
0EBDH
RST 10H
Since we need to bump the current input buffer pointer in register pair HL until it points to the next character, call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY flag if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
0EBEH-0EC0H
Jump if the character at the location of the input buffer pointer in register A is numeric.
0EC1H
INC D
Increment the value in register D.
0EC2H-0EC3H
Jump if the exponent is positive.
0EC4H
XOR A
Zero register A.
0EC5H
SUB E
Subtract the value of the exponent in register E from register A.
0EC6H
LD E,A
Load register E with the value of the exponent in register A.
0EC7H
PUSH HL
Save the current input buffer pointer in register pair HL on the stack.
0EC8H
LD A,E
Load register A with the value of the exponent in register E.
0EC9H
SUB B
Subtract the value in register B from the exponent in register A.
0ECAH-0ECCH
Go multiply the current value by ten if necessary.
0ECDH-0ECFH
Go divide the current value by ten if necessary.
0ED0H-0ED1H
Loop until the value is adjusted correctly.
0ED2H
POP HL
Get the value of the current input buffer pointer from the stack and put it in register pair HL.
0ED3H
POP AF
Get the value from the stack and put it in register pair AF.
0ED4H
PUSH HL
Save the value of the current input buffer pointer in register pair HL on the stack.
0ED5H-0ED7H
Go convert the current value to negative if necessary.
0ED8H
POP HL
Get the value of the current input buffer pointer from the stack and put it in register pair HL.
0ED9H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0EDAH
RET PE
If that test shows we have anything other than a SINGLE PRECISION number, return out of the subroutine.
0EDBH
PUSH HL
Save the current value of the input buffer pointer in register pair HL on the stack.
0EDCH-0EDEH
LD HL,0890H
Load register pair HL with the return address of 2192.
0EDFH
PUSH HL
Save the value of the return address in register pair HL on the stack.
0EE0H-0EE2H
Go convert the current value in REG 1 to an integer if possible.
0EE3H
RET
Return.

0EE4H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0EE5H
INC C
Increment the value in register C.
0EE6H-0EE7H
If that test shows we have a number, jump to 0EC7H since there is no need to convert the current value.
0EE8H-0EEAH
If that test shows we have anything other than DOUBLE PRECISION, go to 0EFBH to convert the current value in REG 1 to single precision.
0EEBH-0EEDH
Jump to 0E83H.
0EEEH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0EEFH-0EF1H
If that test shows anything butn an INTEGER, jump to the Level II BASIC error routine and display a SN ERROR message.
0EF2H
INC HL
Increment the value of the current input buffer pointer in register pair HL.
0EF3H-0EF4H
Jump to 0EC7H.
0EF5H
OR A
Set the flags according to the character at the location of the current input buffer pointer in register pair HL.
0EF6H-0EF8H
Go convert the current value in REG 1 to either single precision or double precision.
0EF9H-0EFAH
Jump to 0EF2H.
0EFBH
PUSH HL
Save the value in register pair HL on the stack.
0EFCH
PUSH DE
Save the value in register pair DE on the stack.
0EFDH
PUSH BC
Save the value in register pair BC on the stack.
0EFEH
PUSH AF
Save the value in register pair AF on the stack.
0EFFH-0F01H
Call the CONVERT TO SINGLE PRECISION routine at 0AB1H (which converts the contents of REG 1 from integer or double precision into single precision).
0F02H
POP AF
Get the value from the stack and put it in register pair AF.
0F03H-0F05H
Call the CONVERT TO DOUBLE PRECISION routine at 0ADBH (where the contents of REG 1 are converted from integer or single precision to double precision).
0F06H
POP BC
Get the value from the stack and put it in register pair BC.
0F07H
POP DE
Get the value from the stack and put it in register pair DE.
0F08H
POP HL
Get the value from the stack and put it in register pair HL.
0F09H
RET
Return.

0F0AH
RET Z
Return if the current value is an integer.
0F0BH
PUSH AF
Save the value in register pair AF on the stack.
0F0CH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0F0DH
PUSH AF
Save the value in register pair AF on the stack.
0F0EH-0F10H
If that test shows SINGLE PRECISION, go to 093EH to multiply the current value in REG 1 by ten.
0F11H
POP AF
Get the value from the stack and put it in register pair AF.
0F12H-0F14H
If that test shows DOUBLE PRECISION, go to 0E4DH to multiply the current value in REG 1 by ten.
0F15H
POP AF
Get the value from the stack and put it in register pair AF.
0F16H
DEC A
Decrement the value in register A.
0F17H
RET
Return.

0F18H
PUSH DE
Save the value in register pair DE on the stack.
0F19H
PUSH HL
Save the value in register pair HL on the stack.
0F1AH
PUSH AF
Save the value in register pair AF on the stack.
0F1BH
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0F1CH
PUSH AF
Save the value in register pair AF on the stack.
0F1DH-0F1FH
If that test shows SINGLE PRECISION, go to 0897H to divide the current value in REG 1 by ten.
0F20H
POP AF
Get the value from the stack and put it in register pair AF.
0F21H-0F23H
If that test shows DOUBLE PRECISION, go to 0DDCH to divide the current value in REG 1 by ten.
0F24H
POP AF
Get the value from the stack and put it in register pair AF.
0F25H
POP HL
Get the value from the stack and put it in register pair HL.
0F26H
POP DE
Get the value from the stack and put it in register pair DE.
0F27H
INC A
Increment the value in register A.
0F28H
RET
Return.

0F29H
PUSH DE
Save the value in register pair DE on the stack.
0F2AH
LD A,B
Load register A with the value in register B.
0F2BH
ADC A,C
Add the value in register C to the value in register A.
0F2CH
LD B,A
Load register B with the adjusted value in register A.
0F2DH
PUSH BC
Save the value in register pair BC on the stack.
0F2EH
PUSH HL
Save the value in register pair HL on the stack.
0F2FH
LD A,(HL)
Load register A with the character at the location of the current input buffer pointer in register pair HL.
0F30H-0F31H
SUB 30H
Subtract 30H from the ASCII value in register A so that it will be binary.
0F32H
PUSH AF
Save the adjusted value in register A on the stack.
0F33H
RST 20H
We need to check the value of the current number type flag, so we call the TEST DATA MODE routine at RST 20H.
NOTE: The RST 20H routine determines the type of the current value in REG 1 and returns a combination of STATUS flags and unique numeric values in the A Register according to the data mode flag (40AFH).

The results are returned as follows:
  • Integer = NZ/C/M/E and A is -1
  • String = Z/C/P/E and A is 0
  • Single Precision = NZ/C/P/O and A is 1
  • and Double Precision is NZ/NC/P/E and A is 5.
0F34H-0FJ6H
If that test shows we have anything but an INTEGER, jump to 0F5DH.
0F37H-0FJ9H
LD HL,(4121H)
Now that we know we have an integer, load register pair HL with the integer value in REG 1.
0F3AH-0FJCH
LD DE,0CCDH
Load register pair DE with 3277.
0F3DH
RST 18H
Now we need to check to see if the integer value in HL is greater than or equal to 0CCDH (in DE), so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
0F3EH-0FJFH
Jump if the integer value in register pair HL is greater than or equal to 3277.
0F40H
LD D,H
Load register D with the MSB of the integer value in register H.
0F41H
LD E,L
Load register E with the LSB of the integer value in register L.
0F42H
ADD HL,HL
Multiply the integer value in register pair HL by two.
0F43H
ADD HL,HL
Multiply the integer value in register pair HL by two. Register pair HL now holds the original integer value times four.
0F44H
ADD HL,DE
Add the original integer value in register pair DE to the integer value in register pair HL. Register pair HL now holds the original integer value times five.
0F45H
ADD HL,HL
Multiply the integer value in register pair HL by two. Register pair HL now holds the origmal integer value times ten.
0F46H
POP AF
Get the binary value for the next character from the stack and put it in register A.
0F47H
LD C,A
Load register C with the value of the character in register A.
0F48H
ADD HL,BC
Add the value of the character in register pair BC to the integer value in register pair HL.
0F49H
LD A,H
Load register A with the MSB of the integer value in register H.
0F4AH
OR A
Check to see if the sign bit is set.
0F4BH-0F4DH
Jump if the sign bit is set in the integer value in register pair HL.
0F4EH-0F50H
LD (4121H),HL
Save the integer value in register pair HL as the current integer value in REG 1.
0F51H
POP HL
Get the value from the stack and put it in register pair HL.
0F52H
POP BC
Get the value from the stack and put it in register pair BC.
0F53H
POP DE
Get the value from the stack and put it in register pair DE.
0F54H-0F56H
Jump to 0E83H.
0F57H
LD A,C
Load register A with the binary value of the charac­ter in register C.
0F58H
PUSH AF
Save the value in register A on the stack.
0F59H-0F5BH
Go convert the current value in REG 1 to single precision.
0F5CH
SCF
Set the Carry flag.
0F5DH-0F5EH
Jump if the current value in REG 1 is double preci­sion.
0F5FH-0F61H
LD BC,9474H
Load register pair BC with the exponent and the MSB of a single precision constant.
0F62H-0F64H
LD DE,2400H
Load register pair DE with the NMSB and the LSB of a single precision constant. Register pairs BC and DE now hold a single precision constant equal to 1E6.
0F65H-0F67H
Call the SINGLE PRECISION COMPARISON routine at 0A0CH.

NOTE: The routine at 0A0CH algebraically compares the single precision value in BC/DE to the single precision value REG 1.
The results are stored in A as follows:
  • A=0 if REG 1 = BCDE
  • A=1 if REG 1>BCDE; and
  • A=FFH if REG 1<BCDE.
0F68H-0F6AH
Jump if the single precision value in REG 1 is greater than or equal to 1E6.
0F6BH-0F6DH
Go multiply the single precision value in REG 1 by 10.
0F6EH
POP AF
Get the binary value of the character from the stack and put it in register A.
0F6FH-0F71H
Go add the value in register A to the single precision value in REG 1.
0F72H-0F33H
Jump to 0F51H.
0F74H-0F76H
Go convert the single precision value in REG 1 to double precision.
0F77H-0F79H
Go multiply the double precision value in REG 1 by ten.
0F7AH-0F7CH
Go move the double precision value in REG 1 to REG 2.
0F7DH
POP AF
Get the binary value for the character from the stack and put it in register A.
0F7EH-0F80H
Go convert the binary value in register A to single precision.
0F81H-0F83H
Go convert the single precision value in REG 1 to double precision.
0F84H-0F86H
Call the DOUBLE PRECISION ADD function (whcih adds the double precision value in REG 2 to the value in REG 1. Result is left in REG 1).
0F87H-0F88H
Jump to 0F51H.

0F89H-0F93H – SINGLE PRECISION MATH ROUTINE

0F89H-0F8BH
Call 09A4 which moves the SINGLE PRECISION value in REG 1 to the stack (stored in LSB/MSB/Exponent order).
0F8CH-0F8EH
Go convert the value in register Ato single precision and return with the result in REG 1.
0F8FH
POP BC
Get the exponent and the MSB for the single preci­sion value from the stack and put it in register pair BC.
0F90H
POP DE
Get the NMSB and the LSB of the single precision value from the stack and put it in register pair DE.
0F91H-0F93H
Jump to the SINGLE PRECISION ADD routine at 0716H (which adds the single precision value in (BC/DE) to the single precision value in REG 1. The sum is left in REG 1).

0F94H-0FA6H – LEVEL II BASIC MATH ROUTINE

0F94H
LD A,E
Load register A with the value of the exponent in register E.
0F95H-0F96H
CP 0AH
Check to see if the value of the exponent in register A is greater than or equal to 10.
0F97H-0F98H
Jump if the value of the exponent in register A is greater than or equal to 10.
0F99H
RLCA
Multiply the value in register A by two.
0F9AH
RLCA
Multiply the value in register A by two. Register A now holds the original value of the exponent times four.
0F9BH
ADD A,E
Add the original value of the exponent in register E to the adjusted value of the exponent in register A.
0F9CH
RLCA
Multiply the value in register A by two. Register A now holds the original value of the exponent times ten.
0F9DH
ADD A,(HL)
Add the value of the current character at the location of the input buffer pointer in register pair HL to the adjusted value in register A.
0F9EH-0F9FH
SUB 30H
Convert the adjusted value in register A to it’s binary equivalent (which is subtracting 0011 0000).
0FA0H
LD E,A
Load register E with the adjusted value in register A.
0FA2H-0FA3H
Load register E with the maximum exponent.
0FA4H-0FA6H
Jump to 0EBDH.

0FA7H-0FAEH – DISPLAY MESSAGE ROUTINE

0FA7H
PUSH HL
Save the value in register pair HL on the stack.
0FA8H-0FAAH
LD HL,1924H
Load register pair HL with the starting address of the IN message (which is 1924H).
0FABH-0FADH
Call the WRITE MESSAGE routine at 28A7H..
NOTE:
  • The routine at 28A7 displays the message pointed to by HL on current system output device (usually video).
  • The string to be displayed must be terminated by a byte of machine zeros or a carriage return code 0D.
  • If terminated with a carriage return, control is returned to the caller after taking the DOS exit at 41D0H (JP 5B99H).
0FAEH
POP HL
Get the value from the stack and put it in register pair HL.

0FAFH-0FBCH – CONVERT BINARY TO ASCII AND DISPLAY RESULT

This routine converts the value in the HL register pair (which is assumed to be an integer) to ASCII and display it at the current cursor position on the video screen.

0FAFH-0FB1H
Go save the value in register pair HL as the current value in REG 1.
0FB2H
XOR A
Zero register A.
0FB3H-0FB5H
Go initialize the input buffer for the ASCII conver­sion.
0FB6H
OR (HL)
Set the flags.
0FB7H-0FB9H
Go convert the integer value in REG 1 to an ASCII string. Return with register pair HL pointing to the result.
0FBAH-0FBCH
Go display the message pointed to by register pair HL.

0FBDH-1363H – BINARY TO ASCII CONVERSION ROUTINE
“CSAASC”

  • Conversion routine. Converts the value from REG 1 to an ASCII string delimited with a zero byte. The number type can be any of Integer, single or double-precision. After execution HL will be pointing to the start of the string. REG 1 and AACC are destroyed by the process.
  • To use a ROM call to convert a number to a string of digits, and to display the latter on the video screen starting at the current cursor position, store the number in 4121H-4122H (if it’s an integer), or in 4121H-4124H (if it’s single precision), or in 411DH-4124H (if it’s double precision). Then store the variable type (2, 4, or 8, respectively) in 40AFH. Call 0FBDH and then call the WRITE MESSAGE routine at 28A7H.
    • NOTE 1: The routine at 0FBDH is the conversion routine described in Section 3.3 (a). The subroutine at 28A7H is a general program for displaying a string of characters and updating the cursor position. The string to be displayed must be terminated by a zero byte, and the HL register pair must contain the address of the first character of the string before 28A7H is called. (The routine at 0FBDH effects this setup automatically.)
    • NOTE 2: Many of the ROM routines described in this book require a numeric input (or inputs). For most of these, the instructions given for calling them have not included the storage of the variable type flag in 40AFH. The reason is that, wherever possible, the variable type flag storage has been finessed by the choice of the subroutine entry point. In the routine of this section, that has not been possible, nor was it possible for the INT, the FIX, the Number to Numeric String, the SGN, or the ABS routines. Storing a 2, 4, or 8 in 40AFH takes only 5 bytes of machine code, but there are subroutines in the Level II ROM that can reduce the required code to 3 bytes. CALL 0A9DH will store a 2 in 40AFH. CALL 0AEFH will store a 4 in 40AFH. And, finally, CALL 0AECH will store an 8 in 40AFH; this last subroutine, however, destroys the contents of the BC register pair. DISK SYSTEM CAUTION: The subroutine at 28A7H has two exits to DISK BASIC, with RAM transfer points at 41C1H and 41D0H. To use this routine safely, either be certain that DISK BASIC is in place or have your assembly language program fill locations 41C1H and 41D0H with RET’s (C9H), before calling the routine.
0FBDH
“NEDIT”
XOR A
Zero register A.

0FBEH-0FC0H – FLOATING to ASCII Conversion Routine

  • This routine converts a single or double precision number in REG 1 to its ASCII equivalent. The ASCII value is stored at the buffer pointed to by the HL register pair. As the value is converted from binary to ASCII, it is formatted as it would be if a PRINT USING statement had been invoked. The format modes that can be specified are selected by loading the following values into the A, B, and C registers as follows:
    • A=0 means do not edit; this is a binary to ASCII conversion
    • A=X means edit as follows: Bit 7=1 means edit the value, Bit 6=Print commas every third digit, Bit 5=Include leading asterisks, Bit 4=Print a leading $, Bit 3=Sign Follows Value, and Bit 1=Exponential Notation
    • B = The number of digits to the left of the decimal point.
    • C = The number of digits after the decimal point.
  • Note: If you wanted to convert any integer/single/double into its character string, store the variable in 4121H-4122H for integer, 4121H-4124H for single, or in 411DH-4124H for double. Then load 40AFH with a 2, 4, or 8 depending on whether that variable was integer, single, or double. Then call 0FBDH. Upon return, the character string is stored in 4130H and on, ending with a 00H.
0FBEH-0FC0H
“FEDIT”
Initialize the input buffer for the ASCII conversion by calling 1034H (which puts the EDIT flag into A, loads HL with the starting address of the input buffer, and inserts a space).
0FC1H-0FC2H
AND 08H
Check the value of the edit flag in register A to see if the sign is to be included.
0FC3H-0FC4H
Jump to 0FC7H if the sign isn’t to be included in the ASCII string.
0FC5H-0FC6H
LD (HL),2BH
Save a plus sign (+)at the location of the input buffer pointer in register pair HL.
0FC7H
EX DE,HL
Load register pair DE with the value of the input buffer pointer in register pair HL.
0FC8H-0FCAH
Go determine the value of the sign for the current value in REG 1.
0FCBH
EX DE,HL
Load register pair HL with the input buffer pointer in register pair DE.
0FCCH-0FCEH
Jump down to 0FD9H if the current value in REG 1 is positive.
0FCFH-0FD0H
LD (HL),2DH
Save a minus sign (-) at the location of the input buffer pointer in register pair HL.
0FD1H
PUSH BC
Save the value in register pair BC on the stack.
0FD2H
PUSH HL
Save the value in register pair HL on the stack.
0FD3H-0FD5H
Gosub to 097BH to convert the negative value in REG 1 to it’s positive equivalent.
0FD6H
POP HL
Get the value from the stack and put it in register pair HL.
0FD7H
POP BC
Get the value from the stack and put it in register pair HL.
0FD8H
OR H
Set the flags.
OFD9H
INC HL
Increment the input buffer pointer in register pair HL.
0FDAH-0FDBH
LD (HL),30H
Save an ASCII zero (0) at the location of the input buffer pointer in register pair HL.
0FDCH-0FDEH
LD A,(40D8H)
Load register A with the value of the edit flag (stored at 16600).
Note: 40D8H-40D9H holds the temporary storage location.
0FDFH
LD D,A
Load register D with the value of the edit flag in register A.
0FE0H
RLA
Move the edit on/off bit in register A into the Carry flag.
0FE1H-0FE3H
LD A,(40AFH)
Load register A with the value of the current number type flag (stored at 16559).
Note: 40AFH holds Current number type flag.
0FE4H-0FE6H
Jump to 109AH if value is to be edited.
0FE7H-0FE9H
Jump to 1092H if no edit.
0FEAH-0FEBH
CP 04H
Check to see if the current value in REG 1 is single or double precision.
0FECH-0FEEH
Jump if the current value in REG 1 is single or double precision.
0FEFH-0FF1H
LD BC,0000H
Load register pair BC with zero.
0FF2H-0FF4H
Call the INTEGER TO ASCII routine at 1232F (which converts the integer in REG 1 to ASCII and stores the ASCII string in the buffer pointed to in HL).
0FF5H-0FF7H
LD HL,4130H
Load register pair HL with the starting address of the input buffer, which is at 16688.
Note: 4130H-4149H holds Internal print buffer.
0FF8H
LD B,(HL)
Load register B with the character at the location of the input buffer pointer in register pair HL.
0FF9H-0FFAH
LD C,20H
Load register C with a space character.
0FFBH-0FFDH
LD A,(40D8H)
Load register A with the value of the edit flag (which is stored in 40D8H).
Note: 40D8H-40D9H holds the temporary storage location.
0FFEH
LD E,A
Load register E with the value of the edit flag in register A.
0FFFH-1000H
AND 20H
Check the value of the edit flag in register A (by AND againt 0010 0000) to see if leading * are to be printed.