5372H - Program Variables
The first ten bytes of the file are the program's variables. They load with the same values that the start-up code at 537CH stores into them, so the program also works when it is restarted from 5889H.
5372
DEFB 01H 01
No-Appendage Flag. 01H = no appendage is to be attached (no new load base has been given, or the appendage was suppressed). 00H = an appendage will be attached. Set at 5381H and 55D7H-55E5H; tested at 5558H, 5597H and 563EH.
5373
DEFB 00H 00
Output Phase Flag. 00H while a source module is being read and set up; set to 01H at 56E6H once a destination is asked for. 5866H uses it to choose between ANOTHER DESTINATION FILE? and ANOTHER SOURCE FILE TO PROCESS?.
5374-5375
DEFW 5E9AH 9A 5E
Module Buffer Pointer. Address of the last byte stored in the module buffer. It starts at 5E9AH, so the first byte goes to 5E9BH. Advanced by 547BH.
5376-5377
DEFW FFFFH FF FF
Lowest Load Address of the object code records that load at 4000H or above. Starts at FFFFH. Updated by 54AFH.
5378-5379
DEFW 0000H 00 00
Highest Load Address: the last byte loaded by any object code record at 4000H or above. Starts at 0000H. Updated by 54C6H.
537A-537B
DEFW 0000H 00 00
Load Offset: the new load base minus the lowest load address (55C5H-55CCH), added to every load address that is moved. Starts at 0000H.
537CH - Program Entry Point and Start-Up
The transfer address of LMOFFSET/CMD. Also reached from 5889H when the operator asks for another source file. Sets the stack, resets every variable, clears the 64-byte appendage patch area and displays the title.
537C
LD SP,5E95H 31 95 5E
Set the Stack Pointer to 5E95H. The stack grows down from 5E94H; the six bytes at 5E95H-5E9AH hold the tape module name (5787H) and the module buffer starts at 5E9BH.
537F
LD A,01H 3E 01
Load Register A with 01H.
5381
LD (5372H),A 32 72 53
Store 01H into the No-Appendage Flag at 5372H: no new load base yet.
5384
XOR A AF
Set Register A to 00H.
5385
LD (5373H),A 32 73 53
Clear the Output Phase Flag at 5373H.
5388
LD HL,58C6H 21 C6 58
Point HL to 58C6H, the 64-byte appendage patch area (not part of the file).
538B
LD B,40H 06 40
Load Register B with 40H (64 bytes).
538D
LD (HL),A 77
Store 00H into the patch area.
538F
LOOP back to 538DH until all 64 bytes are zero.
5391
LD H,A 67
Set Register H to 00H.
5392
LD L,A 6F
Set Register L to 00H, so HL = 0000H.
5393
LD (5378H),HL 22 78 53
Set the Highest Load Address at 5378H to 0000H.
5396
LD (537AH),HL 22 7A 53
Set the Load Offset at 537AH to 0000H.
5399
DEC HL 2B
DECrement HL to FFFFH.
539A
LD (5376H),HL 22 76 53
Set the Lowest Load Address at 5376H to FFFFH.
539D
LD HL,5E9AH 21 9A 5E
Point HL to 5E9AH, the byte before the module buffer.
53A0
LD (5374H),HL 22 74 53
Store it as the Module Buffer Pointer at 5374H: the buffer is empty.
53A3
GOSUB to 5D15H, which resets the appendage record length at 58C3H to 50H and returns HL pointing to the title at 5A3EH.
53A6
GOSUB to the SYS0 routine at 4467H to display the title APPARAT LOAD MODULE OFFSET PROGRAM, VERSION 2.0 on a cleared screen.
53A9H - Ask for the Source: Disk or Tape
Repeats until the reply is exactly one character, D or T.
53A9
LD HL,5ACBH 21 CB 5A
Point HL to the message SOURCE FROM DISK OR TAPE? (D OR T) at 5ACBH.
53AC
GOSUB to 5893H to display it and read a reply. Register B = the length of the reply, Register A = its first character.
53AF
DECrement Register B and LOOP back to 53A9H unless the reply was exactly one character long.
53B1
CP 44H FE 44
Compare the reply against D (44H).
53B3
If it is D, JUMP to 54DCH to read the source from disk.
53B6
CP 54H FE 54
Compare the reply against T (54H).
53B8
If it is not T either, JUMP back to 53A9H to ask again.
53BAH - Read a SYSTEM Tape: Find the Leader
The tape is read into the module buffer as load module records. Anything that is not part of a normal SYSTEM tape is kept in marker records (see Module Buffer Records), and a status character is shown in the top line of the screen: * at 3C3DH when reading starts (the ROM adds two more at 3C3EH-3C3FH when the sync byte is found), P at 3C3CH for bytes before the 55H header byte, I at 3C3DH for bytes between blocks, and C at 3C3EH for a bad checksum.
53BA
LD A,2AH 3E 2A
Load Register A with * (2AH).
53BC
LD (3C3DH),A 32 3D 3C
Display it at 3C3DH, near the right-hand end of the top line of the screen: the program is ready for the tape.
53BF
GOSUB to 583AH. That address holds only a RET.
53C2
DI F3
Disable interrupts for the tape timing.
53C3
GOSUB to the ROM routine at 0293H to turn on the cassette motor and find the leader and the A5H sync byte. When it finds the sync byte it puts two asterisks at 3C3EH-3C3FH, so the screen now shows ***.
53C6
LD A,FFH 3E FF
Load Register A with FFH, the marker for bytes before the header.
53C8
GOSUB to 5457H to start an FFH record in the module buffer. HL points to its two-byte count and BC = 0000H.
Read bytes until the 55H that starts a SYSTEM tape. Every other byte is kept in the FFH record and counted.
53CB
GOSUB to 583BH to check the up-arrow key.
53CE
GOSUB to the ROM routine at 0235H to read a byte from the tape into Register A.
53D1
CP 55H FE 55
Compare it against 55H, the byte that starts a SYSTEM tape.
53D3
If it is 55H, JUMP to 53DFH.
53D5
Otherwise GOSUB to 5492H to store the byte in the buffer and add one to the count of the FFH record.
53D8
LD A,50H 3E 50
Load Register A with P (50H).
53DA
LD (3C3CH),A 32 3C 3C
Display it at 3C3CH: extra bytes were found before the header.
53DD
LOOP back to 53CBH for the next byte.
53DFH - Read a SYSTEM Tape: the Name
After the 55H, the bytes up to the first 3CH (object code block) or 78H (entry point) are kept in an FEH record. On a normal tape these are the six bytes of the module name.
53DF
LD A,FEH 3E FE
Load Register A with FEH, the marker for bytes after the header.
53E1
GOSUB to 5457H to start an FEH record. HL points to its count, BC = 0000H.
53E4
GOSUB to 583BH to check the up-arrow key.
53E7
GOSUB to the ROM routine at 0235H to read a byte from the tape.
53EA
CP 78H FE 78
Compare it against 78H, the byte that starts the entry point block.
53EC
If it is 78H, JUMP to 54CAH to read the entry point and finish.
53EF
CP 3CH FE 3C
Compare it against 3CH, the byte that starts an object code block.
53F1
If it is 3CH, JUMP to 53F8H to read the block.
53F3
Otherwise GOSUB to 5492H to store the byte and count it in the current marker record (FEH, or FDH when reached from 543FH).
53F6
LOOP back to 53E4H for the next byte.
53F8H - Read a SYSTEM Tape: Object Code Block
A tape block is 3CH, a count byte (00H = 256), the two-byte load address, the data and a checksum. It is stored in the disk load module format instead: 01H, a length byte equal to the count plus 2, the load address and the data. The checksum (the sum of the address bytes and the data) is checked but not stored.
53F8
LD A,01H 3E 01
Load Register A with 01H, the disk record type for object code.
53FA
GOSUB to 547BH to store it in the module buffer.
53FD
GOSUB to the ROM routine at 0235H to read the count byte from the tape.
5400
LD B,A 47
Keep the count in Register B.
5401
ADD A,02H C6 02
Add 2 for the two address bytes, giving the disk length byte (a count of 00H, 256 bytes, gives 02H, which also means 256 data bytes on disk).
5403
GOSUB to 547BH to store the length byte.
5406
GOSUB to 5467H to read the two-byte load address from the tape into HL, storing both bytes. Register A = H on return.
5409
ADD A,L 85
Add Register L to Register A.
540A
LD C,A 4F
Start the checksum in Register C with H + L.
540B
GOSUB to 549BH to check the load address and update the lowest and highest load addresses.
540E
GOSUB to 5478H to read a data byte from the tape and store it.
5411
ADD A,C 81
Add it to the checksum in Register C.
5412
LD C,A 4F
Store the new checksum in Register C.
5413
LOOP back to 540EH until all the data bytes are read.
5415
GOSUB to the ROM routine at 0235H to read the checksum byte from the tape.
5418
CP C B9
Compare it with the checksum computed in Register C.
5419
If they differ, JUMP to 5442H.
541B
LD A,(3C3FH) 3A 3F 3C
Fetch the character at 3C3FH (the last of the three asterisks).
541E
XOR 0AH EE 0A
Switch it between * (2AH) and a space (20H).
5420
LD (3C3FH),A 32 3F 3C
Store it back, so the asterisk blinks once per good block.
5423
GOSUB to 583BH to check the up-arrow key. Also reached from 5455H after a checksum error.
5426
GOSUB to the ROM routine at 0235H to read the next byte from the tape.
5429
CP 3CH FE 3C
Compare it against 3CH (another object code block).
542B
If it is 3CH, JUMP back to 53F8H to read the block.
542E
CP 78H FE 78
Compare it against 78H (the entry point block).
5430
If it is 78H, JUMP to 54CAH.
Any other byte between blocks is extraneous. Start an FDH record for it and go on reading as at 53F3H.
5433
PUSH AF F5
Save the byte (and the flags) on the stack.
5434
LD A,49H 3E 49
Load Register A with I (49H).
5436
LD (3C3DH),A 32 3D 3C
Display it at 3C3DH: extra bytes were found between blocks.
5439
LD A,FDH 3E FD
Load Register A with FDH, the marker for bytes between blocks.
543B
GOSUB to 5457H to start an FDH record. HL points to its count, BC = 0000H.
543E
POP AF F1
Restore the extraneous byte into Register A.
543F
JUMP to 53F3H to store and count it, and keep reading until a 3CH or 78H.
5442H - Checksum Error
The block's data is already in the buffer. An FCH record of three bytes follows it: FCH, the checksum read from the tape and the checksum computed. It has no count, and 5733H does not accept it later (see Module Buffer Records).
5442
PUSH AF F5
Save the checksum read from the tape.
5443
LD A,FCH 3E FC
Load Register A with FCH, the marker for a checksum error.
5445
GOSUB to 547BH to store it.
5448
POP AF F1
Restore the checksum read from the tape into Register A.
5449
GOSUB to 547BH to store it.
544C
LD A,C 79
Load Register A with the checksum computed in Register C.
544D
GOSUB to 547BH to store it.
5450
LD A,43H 3E 43
Load Register A with C (43H).
5452
LD (3C3EH),A 32 3E 3C
Display it at 3C3EH: a checksum error was found.
5455
JUMP back to 5423H to read the next block.
5457H - Start a Marker Record
Stores the marker type in Register A and a two-byte count of zero after it. Returns HL pointing to the count and BC = 0000H, ready for 5492H.
5457
GOSUB to 547BH to store the marker type.
545A
LD HL,(5374H) 2A 74 53
Fetch the Module Buffer Pointer (the address of the marker just stored).
545D
INC HL 23
Bump HL to where the count will go.
545E
XOR A AF
Set Register A to 00H.
545F
LD B,A 47
Set Register B to 00H.
5460
LD C,A 4F
Set Register C to 00H: the count is 0000H.
5461
GOSUB to 547BH to store the low byte of the count.
5464
JUMP to 547BH to store the high byte and return.
5467H - Read a Two-Byte Address From the Tape
Reads the low byte and then the high byte into HL, storing both in the module buffer. Returns Register A = H.
5467
GOSUB to 5478H to read and store the low byte.
546A
LD L,A 6F
Put it in Register L.
546B
GOSUB to 5478H to read and store the high byte.
546E
LD H,A 67
Put it in Register H.
5470H - Copy Bytes Into the Module Buffer
Copies Register B bytes from HL (00H = 256) to the end of the module buffer. Used to add the appendage (56CDH-56E3H). Returns HL pointing past the last byte copied.
5470
LD A,(HL) 7E
Fetch a byte.
5471
INC HL 23
Bump the source pointer.
5472
GOSUB to 547BH to store the byte in the module buffer.
5475
LOOP back to 5470H until Register B bytes are copied.
5478H - Store a Byte in the Module Buffer
5478H reads a byte from the tape first. 547BH stores the byte in Register A after the last byte in the module buffer. If the buffer has reached the top of memory (the DOS high memory address at 4049H), it stops with INSUFFICIENT RAM MEMORY. All registers are preserved.
5478
GOSUB to the ROM routine at 0235H to read a byte from the tape, then fall into 547BH.
547D
LD HL,(5374H) 2A 74 53
Fetch the Module Buffer Pointer (the last byte stored).
5480
LD DE,(4049H) ED 5B 49 40
Fetch the top of usable memory from 4049H.
5484
PUSH AF F5
Save the byte and the flags.
5485
RST 18H DF
Compare HL with DE (RST 18H): the CARRY FLAG is set if HL is lower.
5486
If the buffer pointer has reached the top of memory, JUMP to 585CH to report INSUFFICIENT RAM MEMORY.
5489
INC HL 23
Bump HL to the next free byte.
548A
POP AF F1
Restore the byte and the flags.
548B
LD (HL),A 77
Store the byte.
548C
LD (5374H),HL 22 74 53
Update the Module Buffer Pointer.
5492H - Store a Byte and Count It
Stores Register A in the module buffer, adds one to the count in BC and writes the count into the current marker record at HL (set up by 5457H).
5492
GOSUB to 547BH to store the byte.
5495
INC BC 03
Add one to the count in BC.
5496
LD (HL),C 71
Store the low byte of the count.
5498
LD (HL),B 70
Store the high byte of the count.
5499
DEC HL 2B
Move HL back to the low byte.
549BH - Check a Load Address
Called for every object code record, with HL = the load address and Register B = the number of data bytes (00H = 256). Records below 3C00H, and records in the 3F00H page that run past 3FFFH, stop the program with SOURCE ILLEGAL LOAD-TO-MEMORY ADDRESS. Records that start in the display (3C00H-3FFFH) are accepted but are not counted in the load range, so they are never moved. Records at 4000H or above update the lowest and highest load addresses.
549B
LD A,H 7C
Load Register A with the high byte of the load address.
549C
CP 3FH FE 3F
Compare it against 3FH.
549E
If the record does not start in the 3F00H page, JUMP to 54A7H.
54A0
LD A,B 78
Load Register A with the number of data bytes.
54A1
DEC A 3D
Subtract 1 for the last byte.
54A2
ADD A,L 85
Add the low byte of the load address.
54A3
If the record runs past 3FFFH, JUMP to 584BH to report SOURCE ILLEGAL LOAD-TO-MEMORY ADDRESS.
54A6
RET C9
RETurn: the record stays inside the display.
54A7
If the high byte is above 3FH (the NC FLAG is still set from the compare at 549CH), JUMP to 54AFH.
54A9
CP 3CH FE 3C
Compare the high byte against 3CH.
54AB
If the record starts below 3C00H (in the ROM), JUMP to 584BH to report SOURCE ILLEGAL LOAD-TO-MEMORY ADDRESS.
54AE
RET C9
RETurn: the record starts in the display at 3C00H-3EFFH.
54AF
LD DE,(5376H) ED 5B 76 53
Fetch the Lowest Load Address into DE.
54B3
RST 18H DF
Compare the load address with it.
54B4
If the load address is not lower, JUMP to 54B9H.
54B6
LD (5376H),HL 22 76 53
Otherwise it becomes the new Lowest Load Address.
54B9
LD DE,(5378H) ED 5B 78 53
Fetch the Highest Load Address into DE.
54BD
LD A,B 78
Load Register A with the number of data bytes.
54BF
ADD A,L 85
Add the low byte of the load address.
54C0
LD L,A 6F
Store it in Register L.
54C1
If there was no carry, JUMP to 54C4H.
54C3
INC H 24
Otherwise add the carry to Register H. HL = the address of the record's last byte.
54C4
RST 18H DF
Compare it with the highest load address so far.
54C5
RET C D8
If it is lower, RETurn.
54C6
LD (5378H),HL 22 78 53
Otherwise it becomes the new Highest Load Address.
54CAH - Read a SYSTEM Tape: Entry Point
The 78H byte is followed by the two-byte entry point. It is stored as a disk transfer record: 02H, 02H and the address.
54CA
LD A,02H 3E 02
Load Register A with 02H, the disk record type for the transfer address.
54CC
GOSUB to 547BH to store the type.
54CF
GOSUB to 547BH to store 02H again as the length byte.
54D2
GOSUB to 5467H to read the entry point from the tape and store it.
54D5
GOSUB to the ROM routine at 01F8H to turn off the cassette motor.
54D8
EI FB
Enable interrupts again.
54D9
JUMP to 5550H to display the load information.
54DCH - Read a Load Module From Disk
Opens the source file and copies it record by record into the module buffer. The file is read through the alternate register set: HL' = the position in the sector buffer at 5200H, DE' = the FCB at 5300H, B' = the bytes left in the sector buffer. Every byte read is stored in the module buffer as it is. Object code records (01H) have their load address checked; a transfer record (02H) ends the file.
54DC
LD HL,5B15H 21 15 5B
Point HL to the message SOURCE FILESPEC? at 5B15H.
54DF
GOSUB to 5521H to display it and read the filespec into the FCB at 5300H. If a filespec was typed, the alternate register set is now active with HL = 5200H, DE = 5300H and B = 00H.
54E2
If the reply was empty, JUMP back to 54DCH to ask again.
54E4
GOSUB to the SYS0 routine at 4424H to open the existing file (FCB at DE, sector buffer at HL, record length 256).
54E7
If the open failed, JUMP to 5855H to display the DOS error.
54EA
INC H 24
Set HL to 5300H, the end of the sector buffer.
54EB
LD B,01H 06 01
Load Register B with 01H, so the first byte request reads a sector (see 5537H).
54ED
EXX D9
Switch back to the main register set, keeping the file registers in the alternate set.
54EE
GOSUB to 5537H to read the record type from the file (and store it).
54F1
PUSH AF F5
Save the type.
54F2
GOSUB to 5537H to read the record length byte.
54F5
LD B,A 47
Keep the length in Register B.
54F6
POP AF F1
Restore the type into Register A.
54F7
CP 02H FE 02
Compare it against 02H (transfer address).
54F9
If it is 02H, JUMP to 550EH.
54FB
CP 01H FE 01
Compare it against 01H (object code).
54FD
If it is any other type (for example the 05H header record), JUMP to 5507H to copy the record unchanged.
54FF
GOSUB to 5547H to read the two-byte load address into HL.
5502
DEC B 05
DECrement Register B.
5503
DEC B 05
DECrement Register B again: B = the number of data bytes (00H = 256).
5504
GOSUB to 549BH to check the load address and update the load range.
5507
GOSUB to 5537H to read and store the next byte of the record.
550A
LOOP back to 5507H until Register B bytes are copied (00H = 256).
550C
JUMP back to 54EEH for the next record.
550E
LD HL,(5374H) 2A 74 53
Fetch the Module Buffer Pointer, which points to the length byte just stored.
5511
LD (HL),02H 36 02
Set the length byte to 02H, whatever the file had.
5513
GOSUB to 5537H to read and store the low byte of the entry point.
5516
GOSUB to 5537H to read and store the high byte.
5519
EXX D9
Switch to the file registers.
551A
GOSUB to the SYS0 routine at 4428H to close the file.
551D
EXX D9
Switch back to the main register set.
551E
JUMP to 5550H to display the load information.
5521H - Ask for a Filespec
Displays the message at HL and reads up to 31 characters into the FCB at 5300H. Returns the Z FLAG set if the reply was empty. Otherwise it switches to the alternate register set and loads it for the DOS file routines: HL = 5200H (sector buffer), DE = 5300H (FCB), B = 00H (record length 256). Used for the source (54DFH) and the destination (56FFH).
5521
GOSUB to the SYS0 routine at 4467H to display the message.
5524
LD HL,5300H 21 00 53
Point HL to the FCB at 5300H, which receives the typed filespec.
5527
LD A,1FH 3E 1F
Load Register A with 1FH, the maximum length (31 characters).
5529
GOSUB to 589BH to read the reply into 5300H.
552C
RET Z C8
If the reply was empty, RETurn with the Z FLAG set.
552D
EXX D9
Switch to the alternate register set.
552E
LD DE,5300H 11 00 53
Point DE to the FCB at 5300H.
5531
LD HL,5200H 21 00 52
Point HL to the sector buffer at 5200H.
5534
LD B,00H 06 00
Load Register B with 00H (record length 256).
5536
RET C9
RETurn with the NZ FLAG set and the file registers active.
5537H - Read a Byte From the Source File
Returns the next byte of the source file in Register A and stores it in the module buffer (547BH). Uses the alternate register set: B' counts the bytes left in the sector buffer and HL' points into it. When the buffer is empty the next sector is read into 5200H.
5537
EXX D9
Switch to the file registers.
5538
DECrement the bytes left in the sector buffer; if any are left, JUMP to 5541H.
553A
GOSUB to the SYS0 routine at 4436H to read the next sector into 5200H.
553D
If the read failed (including the end of the file), JUMP to 5855H to display the DOS error.
5540
DEC H 25
Move HL back from 5300H to 5200H, the start of the buffer. Register B is now 00H, which counts 256 bytes.
5541
LD A,(HL) 7E
Fetch the byte from the sector buffer.
5542
INC HL 23
Bump the buffer pointer.
5543
EXX D9
Switch back to the main register set.
5544
JUMP to 547BH to store the byte in the module buffer and return.
5547H - Read a Two-Byte Address From the File
Reads the low byte and then the high byte into HL, storing both in the module buffer.
5547
GOSUB to 5537H to read the low byte.
554A
LD L,A 6F
Put it in Register L.
554B
GOSUB to 5537H to read the high byte.
554E
LD H,A 67
Put it in Register H.
5550H - Display the Load Information
Shows MODULE LOADS TO XXXX-XXXX for the module as it will load (the load range plus the offset). When an appendage is to be attached, the end address includes 4EH more bytes, the size of the DOS-enabled appendage; the DOS-disabled appendage is larger (137H bytes), but that choice is only made later (563EH). Then warns if the new start address is in the ROM or the DOS. Also reached from 55DEH and 55E6H after a new load base has been given.
5550
LD HL,(5378H) 2A 78 53
Fetch the Highest Load Address.
5553
LD DE,(537AH) ED 5B 7A 53
Fetch the Load Offset.
5557
ADD HL,DE 19
Add them: HL = the new address of the last byte.
5558
LD A,(5372H) 3A 72 53
Fetch the No-Appendage Flag.
555C
If there is no appendage, JUMP to 5562H.
555E
LD DE,004EH 11 4E 00
Load DE with 004EH, the size of the DOS-enabled appendage (78 bytes).
5561
ADD HL,DE 19
Add it to the end address.
5562
EX DE,HL EB
Move the end address to DE.
5563
LD HL,5B53H 21 53 5B
Point HL to the second XXXX in the message at 5B53H.
5566
GOSUB to 5A25H to write DE there in hexadecimal.
5569
LD DE,(5376H) ED 5B 76 53
Fetch the Lowest Load Address into DE.
556D
LD HL,(537AH) 2A 7A 53
Fetch the Load Offset.
5570
ADD HL,DE 19
Add them: HL = the new start address.
5571
EX DE,HL EB
Move it to DE.
5572
PUSH DE D5
Save the start address.
5573
LD HL,5B4EH 21 4E 5B
Point HL to the first XXXX in the message at 5B4EH.
5576
GOSUB to 5A25H to write the start address there.
5579
LD HL,5B3EH 21 3E 5B
Point HL to the message MODULE LOADS TO XXXX-XXXX at 5B3EH.
557C
GOSUB to the SYS0 routine at 4467H to display it.
557F
POP DE D1
Restore the start address into DE.
5580
LD HL,3FFFH 21 FF 3F
Load HL with 3FFFH, the last byte of the display.
5583
RST 18H DF
Compare 3FFFH with the start address (RST 18H).
5584
LD HL,5B9BH 21 9B 5B
Point HL to the message MODULE LOAD WILL OVERLAP ROM at 5B9BH.
5587
If the start address is 3FFFH or lower, GOSUB to the SYS0 routine at 4467H to display it.
558A
LD HL,51FFH 21 FF 51
Load HL with 51FFH, the last byte of the DOS area.
558D
RST 18H DF
Compare 51FFH with the start address.
558E
LD HL,5B58H 21 58 5B
Point HL to the message MODULE LOAD OVERLAPS DOS (4000-51FF) at 5B58H.
5591
If the start address is 51FFH or lower, GOSUB to the SYS0 routine at 4467H to display it.
5594H - Display the Entry Point and Ask for a New Load Base
With an appendage, the entry point is the first byte of the appendage, just past the module's last byte at its new address. Without one, it is the module's own entry point plus the offset; this is only the value displayed, since 561BH moves the entry point only if it lies inside the load range. The new entry point is also stored in the appendage's transfer record at 5A03H. Also reached from 55C3H when the reply is not valid hexadecimal.
5594
GOSUB to 5771H to fetch the entry point from the module's transfer record into DE.
5597
LD A,(5372H) 3A 72 53
Fetch the No-Appendage Flag.
559B
If there is no appendage, JUMP to 55A2H with DE = the module's entry point.
559D
LD DE,(5378H) ED 5B 78 53
Otherwise fetch the Highest Load Address.
55A1
INC DE 13
Add 1: DE = the byte after the module, where the appendage starts.
55A2
LD HL,(537AH) 2A 7A 53
Fetch the Load Offset.
55A5
ADD HL,DE 19
Add DE: HL = the new entry point.
55A6
LD (5A03H),HL 22 03 5A
Store it in the appendage's transfer record at 5A03H.
55A9
EX DE,HL EB
Move it to DE.
55AA
LD HL,5C3AH 21 3A 5C
Point HL to the XXXX in the message at 5C3AH.
55AD
GOSUB to 5A25H to write the entry point there.
55B0
LD HL,5C2CH 21 2C 5C
Point HL to the message ENTRY POINT = XXXX at 5C2CH.
55B3
GOSUB to the SYS0 routine at 4467H to display it.
55B6
LD HL,5B7DH 21 7D 5B
Point HL to the message NEW LOAD BASE ADDRESS (HEX)? at 5B7DH.
55B9
GOSUB to 5893H to display it and read a reply.
55BC
If the reply is empty (ENTER), JUMP to 55E9H to finish the source module.
55BE
LD A,B 78
Load Register A with the length of the reply.
55BF
EX DE,HL EB
Point DE to the reply.
55C0
GOSUB to 5A05H to convert up to four hexadecimal digits into HL.
55C3
If the reply is not a valid hexadecimal number, JUMP back to 5594H to ask again.
55C5
LD DE,(5376H) ED 5B 76 53
Fetch the Lowest Load Address into DE.
55C9
OR A B7
Clear the CARRY FLAG.
55CA
SBC HL,DE ED 52
Subtract it from the new load base.
55CC
LD (537AH),HL 22 7A 53
Store the result as the Load Offset.
55CF
LD HL,5C3FH 21 3F 5C
Point HL to the message SHALL APPENDAGE BE SUPPRESSED? (Y OR N) at 5C3FH.
55D2
GOSUB to 5893H to display it and read a reply.
55D5
LOOP back to 55CFH unless the reply was exactly one character long.
55D7
LD HL,5372H 21 72 53
Point HL to the No-Appendage Flag.
55DA
LD (HL),00H 36 00
Set it to 00H: attach an appendage.
55DC
CP 4EH FE 4E
Compare the reply against N (4EH).
55DE
If it is N, JUMP to 5550H to display the new load information.
55E1
CP 59H FE 59
Compare the reply against Y (59H).
55E3
If it is neither, JUMP back to 55CFH to ask again.
55E5
INC (HL) 34
Set the flag to 01H: the appendage is suppressed.
55E6
JUMP to 5550H to display the new load information.
55E9H - Move the Load Addresses
The operator has accepted the load base. The module's original entry point is saved in the appendage's move code at 59FFH. Then every record in the module buffer is walked through: marker records (FEH, FFH) are skipped (5733H), every object code record at 4000H or above gets the offset added to its load address, and the transfer address gets the offset only if it lies inside the load range. With an offset of 0000H nothing changes.
55E9
GOSUB to 5771H to fetch the module's entry point into DE.
55EC
LD (59FFH),DE ED 53 FF 59
Store it as the JP target in the appendage's move code at 59FFH.
55F0
LD HL,5E9BH 21 9B 5E
Point HL to 5E9BH, the first record in the module buffer.
55F3
DEC HL 2B
Move HL back one byte for the end test.
55F4
LD DE,(5374H) ED 5B 74 53
Fetch the Module Buffer Pointer (the last byte in the buffer) into DE.
55F9
If there are no more records, JUMP to 563EH.
55FB
INC HL 23
Move HL forward again to the record.
55FC
GOSUB to 5733H. A marker record is skipped (NC FLAG). Any other record returns the CARRY FLAG set, its type in Register A and HL still pointing to it.
55FF
If it was a marker record, JUMP back to 55F3H.
5601
INC HL 23
Point HL to the length byte.
5602
LD C,(HL) 4E
Fetch the length into Register C.
5603
LD B,00H 06 00
Set Register B to 00H.
5605
INC HL 23
Point HL to the first byte after the length (the load address in a 01H or 02H record).
5606
CP 02H FE 02
Compare the type against 02H (transfer address).
5608
If it is 02H, JUMP to 561BH.
560A
CP 01H FE 01
Compare the type against 01H (object code).
560C
If it is 01H, JUMP to 5615H.
560E
INC C 0C
Any other record is skipped. INCrement Register C...
560F
DEC C 0D
...and DECrement it again to test for zero.
5610
If the length is not zero, JUMP to 5613H.
5612
INC B 04
A length of 00H means 256 bytes: set BC = 0100H.
5613
JUMP to 563BH to step over the record.
5615
LD A,C 79
Load Register A with the length.
5616
CP 03H FE 03
Compare it against 03H.
5618
If it is 03H or more, JUMP to 561BH.
561A
INC B 04
A length of 00H, 01H or 02H means 254, 255 or 256 data bytes: add 256 to BC.
561B
LD E,(HL) 5E
Fetch the low byte of the address.
561C
INC HL 23
Point HL to the high byte.
561D
LD D,(HL) 56
Fetch the high byte. DE = the address.
561E
PUSH HL E5
Save the pointer.
561F
LD A,D 7A
Load Register A with the high byte.
5620
CP 40H FE 40
Compare it against 40H.
5622
If the address is below 4000H (a record in the display, or an entry point below 4000H), JUMP to 5637H to leave it unchanged.
5624
LD HL,(5378H) 2A 78 53
Fetch the Highest Load Address.
5627
RST 18H DF
Compare it with the address.
5628
If the address is above the load range, JUMP to 5637H to leave it unchanged. This only happens for the entry point.
562A
LD HL,(5376H) 2A 76 53
Fetch the Lowest Load Address.
562D
EX DE,HL EB
Swap: HL = the address, DE = the lowest load address.
562F
EX DE,HL EB
Swap back: DE = the address.
5630
If the address is below the load range, JUMP to 5637H to leave it unchanged.
5632
LD HL,(537AH) 2A 7A 53
Fetch the Load Offset.
5635
ADD HL,DE 19
Add the address.
5636
EX DE,HL EB
Move the new address to DE.
5637
POP HL E1
Restore the pointer to the high byte.
5638
LD (HL),D 72
Store the high byte of the address.
5639
DEC HL 2B
Move back to the low byte.
563A
LD (HL),E 73
Store the low byte.
563B
ADD HL,BC 09
Add the length in BC: HL now points to the next record.
563EH - Ask Whether to Disable DOS
Only asked when an appendage is to be attached. The appendage is placed at the byte after the module's new last byte. With N the DOS-enabled appendage is used unchanged. With Y the addresses inside the DOS-disabled appendage are filled in and its first record is lengthened to C1H. The reply is also stored into the instruction at 56D6H, where 00H selects the DOS-enabled appendage. See The Appendages for their layout.
563E
LD A,(5372H) 3A 72 53
Fetch the No-Appendage Flag.
5642
If there is no appendage, JUMP to 56E6H to ask for the destination.
5645
LD HL,5BB8H 21 B8 5B
Point HL to the message DISABLE DOS? (Y OR N) at 5BB8H.
5648
GOSUB to 5893H to display it and read a reply.
564B
LOOP back to 5645H unless the reply was exactly one character long.
564D
LD HL,(5378H) 2A 78 53
Fetch the Highest Load Address.
5650
LD DE,(537AH) ED 5B 7A 53
Fetch the Load Offset.
5654
ADD HL,DE 19
Add them.
5655
INC HL 23
Add 1: HL = the appendage's load address (called X below).
5656
LD (58C4H),HL 22 C4 58
Store it as the load address of the appendage's first record at 58C4H.
5659
SUB 4EH D6 4E
Subtract N (4EH) from the reply: 00H for N, 0BH for Y.
565B
LD (56D7H),A 32 D7 56
Store the result into the operand of the LD A,00H instruction at 56D6H.
565E
If the reply was N, JUMP to 568FH.
5660
CP 0BH FE 0B
Check for 0BH (Y).
5662
If the reply was neither, JUMP back to 5645H to ask again.
DOS is to be disabled. Fill in the addresses the DOS-disabled appendage uses when it runs. Its code starts at X+40H, after the 64-byte patch area.
5664
LD DE,005EH 11 5E 00
Load DE with 005EH.
5667
ADD HL,DE 19
Add it: HL = X+5EH, where the six bytes at 5924H will be.
5668
LD (5912H),HL 22 12 59
Store it at 5912H, the source of the copy to 42E9H.
566B
LD DE,0006H 11 06 00
Load DE with 0006H.
566E
ADD HL,DE 19
Add it: HL = X+64H, where the message at 592AH will be.
566F
LD (591DH),HL 22 1D 59
Store it at 591DH, the message address for the SYS0 display call.
5672
LD DE,005BH 11 5B 00
Load DE with 005BH.
5675
ADD HL,DE 19
Add it: HL = X+BFH, the load address of the second record.
5676
LD (5987H),HL 22 87 59
Store it in the second record's header at 5987H.
5679
LD DE,005FH 11 5F 00
Load DE with 005FH.
567C
ADD HL,DE 19
Add it: HL = X+11EH, where the code at 59E8H will be.
567D
LD (5928H),HL 22 28 59
Store it at 5928H, the target of the JP that the copy puts at 42ECH.
5680
LD DE,0019H 11 19 00
Load DE with 0019H.
5683
ADD HL,DE 19
Add it: HL = X+137H, the first byte after the appendage.
5684
LD (59E9H),HL 22 E9 59
Store it at 59E9H, the source address for restoring the screen.
5687
LD (5907H),HL 22 07 59
Store it at 5907H too, the destination address for saving the screen.
568A
LD HL,58C3H 21 C3 58
Point HL to the length byte of the appendage's first record at 58C3H.
568D
LD (HL),C1H 36 C1
Set it to C1H: 64 patch bytes and 127 code bytes.
568FH - Fill In the Move Code and Add the Appendage
Fills in the move code at 59F3H-5A00H that both appendages end with: LD HL,new start / LD DE,original start / LD BC,length / LDIR or LDDR / JP original entry point. If the module now loads lower than its original address it is copied upward, so LDDR is used with the addresses of the last bytes. Then the transfer record at the end of the module buffer is removed and the appendage records (which end with their own transfer record) are added in its place.
568F
LD DE,(5376H) ED 5B 76 53
Fetch the Lowest Load Address into DE.
5693
LD HL,(5378H) 2A 78 53
Fetch the Highest Load Address.
5696
XOR A AF
Clear the CARRY FLAG.
5697
SBC HL,DE ED 52
Subtract: HL = the module size minus 1.
5699
If the highest address is below the lowest, there were no object code records at 4000H or above: JUMP to 5850H to report SOURCE MODULE BAD FORMAT.
569C
LD B,H 44
Copy the size minus 1...
569E
INC HL 23
Add 1 for the module size.
569F
LD (59FAH),HL 22 FA 59
Store it as the byte count of the move code at 59FAH.
56A2
LD DE,(5376H) ED 5B 76 53
Fetch the Lowest Load Address into DE: the original start, where the module must be moved to.
56A6
LD HL,(537AH) 2A 7A 53
Fetch the Load Offset.
56A9
LD A,B0H 3E B0
Load Register A with B0H, the second byte of LDIR.
56AB
ADD HL,DE 19
Add the offset: HL = the new start, where the module is loaded. The CARRY FLAG is set if the new start is lower than the original.
56AC
If the new start is higher, JUMP to 56B4H: copying upward with LDIR is safe.
56AE
LD A,B8H 3E B8
Otherwise load Register A with B8H, the second byte of LDDR.
56B0
ADD HL,BC 09
Point HL to the last byte at the new address.
56B2
ADD HL,BC 09
...point DE to the last byte at the original address...
56B3
EX DE,HL EB
...and swap back.
56B4
LD (59FDH),A 32 FD 59
Store B0H or B8H into the move code at 59FDH.
56B7
LD (59F4H),HL 22 F4 59
Store the source address at 59F4H.
56BA
LD (59F7H),DE ED 53 F7 59
Store the destination address at 59F7H.
56BE
LD HL,(5374H) 2A 74 53
Fetch the Module Buffer Pointer.
56C1
LD DE,FFFCH 11 FC FF
Load DE with FFFCH (-4).
56C4
ADD HL,DE 19
Subtract 4: the module's transfer record (the last four bytes) is dropped.
56C5
LD (5374H),HL 22 74 53
Update the Module Buffer Pointer.
56C8
LD B,44H 06 44
Load Register B with 44H (68 bytes).
56CA
LD HL,58C2H 21 C2 58
Point HL to the appendage's first record header at 58C2H.
56CD
GOSUB to 5470H to copy the header and the 64-byte patch area into the module buffer. HL returns 5906H.
56D0
EX DE,HL EB
Keep 5906H in DE.
56D1
LD HL,59F3H 21 F3 59
Point HL to the move code at 59F3H.
56D4
LD B,12H 06 12
Load Register B with 12H (18 bytes: the move code and the transfer record).
56D6
LD A,00H 3E 00
Load Register A with the reply stored at 565BH: 00H = DOS-enabled, 0BH = DOS-disabled.
56D9
If DOS stays enabled, JUMP to 56E3H to copy the move code and the transfer record.
56DB
EX DE,HL EB
Otherwise point HL to 5906H (and DE to 59F3H).
56DC
LD B,7FH 06 7F
Load Register B with 7FH (127 bytes).
56DE
GOSUB to 5470H to copy 5906H-5984H, the rest of the first record.
56E1
LD B,80H 06 80
Load Register B with 80H (128 bytes): the second record (5985H-5A00H) and the transfer record.
56E3
GOSUB to 5470H to copy them into the module buffer.
56E6H - Ask for the Destination: Disk or Tape
Also reached from 587CH when the operator wants the same module written to another file.
56E6
LD HL,5373H 21 73 53
Point HL to the Output Phase Flag.
56E9
LD (HL),01H 36 01
Set it to 01H.
56EB
LD HL,5AF0H 21 F0 5A
Point HL to the message DESTINATION DISK OR TAPE? (D OR T) at 5AF0H.
56EE
GOSUB to 5893H to display it and read a reply.
56F1
LOOP back to 56EBH unless the reply was exactly one character long.
56F3
CP 54H FE 54
Compare the reply against T (54H).
56F5
If it is T, JUMP to 577AH to write to tape.
56F8
CP 44H FE 44
Compare the reply against D (44H).
56FA
If it is neither, JUMP back to 56E6H to ask again.
56FC
LD HL,5B27H 21 27 5B
Point HL to the message DESTINATION FILESPEC? at 5B27H.
56FF
GOSUB to 5521H to display it and read the filespec into the FCB at 5300H.
5702
If the reply was empty, JUMP back to 56FCH to ask again.
5704
GOSUB to the SYS0 routine at 4420H to open the file, creating it if it does not exist (FCB at DE, sector buffer at HL, record length 256).
5707
If the open failed, JUMP to 5855H to display the DOS error.
570AH - Write the Module to Disk
Writes every record in the module buffer to the file in load module format. Marker records are skipped. Object code records and other record types are written unchanged; the transfer record is written last and the file is closed. The file registers are in the alternate set: HL' = the position in the sector buffer at 5200H, B' = a byte counter that reaches zero after every 256 bytes.
570A
EXX D9
Switch to the main register set, keeping the file registers in the alternate set.
570B
LD HL,5E9BH 21 9B 5E
Point HL to 5E9BH, the first record in the module buffer.
570E
GOSUB to 5733H. A marker record is skipped (NC FLAG); any other record returns the CARRY FLAG set and its type in Register A.
5711
If it was a marker record, JUMP back to 570EH.
5713
CP 01H FE 01
Compare the type against 01H (object code).
5715
If it is 01H, JUMP to 5721H.
5717
CP 02H FE 02
Compare the type against 02H (transfer address).
5719
If it is 02H, JUMP to 5744H to finish the file.
571C
Any other record: GOSUB to 575CH to write the type and the length byte, with Register B = the length.
571F
JUMP to 572CH to write the rest of the record.
5721
GOSUB to 575CH to write the type and the length byte, with Register B = the length.
5724
DEC B 05
DECrement Register B.
5725
DEC B 05
DECrement Register B again: B = the number of data bytes.
5726
GOSUB to 5760H to write the low byte of the load address.
5729
GOSUB to 5760H to write the high byte.
572C
GOSUB to 5760H to write the next byte of the record.
572F
LOOP back to 572CH until Register B bytes are written (00H = 256).
5731
JUMP back to 570EH for the next record.
5733H - Check a Record Type
HL points to a record in the module buffer. Types below 20H are load module records: return the CARRY FLAG set, Register A = the type and HL unchanged. FEH and FFH are marker records made by the tape reader: step HL past the record (type, two-byte count and the bytes) and return with the NC FLAG and Register A = 00H. Any other type, including the FCH and FDH records the tape reader makes for checksum errors and extra bytes, stops the program with BAD MAIN MEMORY.
5733
LD A,(HL) 7E
Fetch the record type.
5734
CP 20H FE 20
Compare it against 20H.
5736
RET C D8
If it is below 20H, RETurn with the CARRY FLAG set.
5737
CP FEH FE FE
Compare it against FEH.
5739
If it is 20H-FDH, JUMP to 5846H to report BAD MAIN MEMORY.
573C
INC HL 23
Point HL to the count.
573D
LD E,(HL) 5E
Fetch the low byte of the count.
573F
LD D,(HL) 56
Fetch the high byte of the count.
5740
INC HL 23
Point HL to the first byte of the marker record.
5741
ADD HL,DE 19
Add the count: HL now points to the next record.
5742
XOR A AF
Set Register A to 00H and clear the CARRY FLAG.
5744H - Write the Transfer Record and Close the File
The four bytes of the transfer record are written. If the sector buffer holds anything not yet written, it is written, and then the file is closed.
5744
GOSUB to 575CH to write the type (02H) and the length byte.
5747
GOSUB to 575CH again to write the two bytes of the entry point.
574A
EXX D9
Switch to the file registers.
574B
LD A,B 78
Load Register A with the byte counter.
574D
If it is 00H, every byte has already been written: JUMP to 5752H.
574F
Otherwise GOSUB to the SYS0 routine at 443CH to write the partly filled sector. The result is not checked.
5752
GOSUB to the SYS0 routine at 4428H to close the file. The result is not checked.
5755
EXX D9
Switch back to the main register set.
5756
LD HL,5C27H 21 27 5C
Point HL to the message DONE at 5C27H. Also reached from 5837H when a tape has been written.
5759
JUMP to 585FH to display it and ask what to do next.
575CH - Write Bytes to the Destination File
575CH writes the byte at HL and the one after it, and returns Register B = that second byte (a length). 5760H writes the byte at HL, steps HL, and returns Register A = the next byte. Bytes are collected in the sector buffer at 5200H through the alternate register set; every 256 bytes the sector is written.
575C
GOSUB to 5760H to write the byte at HL. Register A returns the next byte.
575F
LD B,A 47
Keep it in Register B, then fall into 5760H to write it too.
5760
LD A,(HL) 7E
Fetch the byte from the module buffer.
5761
INC HL 23
Bump the module buffer pointer.
5762
EXX D9
Switch to the file registers.
5763
LD (HL),A 77
Store the byte in the sector buffer.
5764
INC HL 23
Bump the sector buffer pointer.
5765
DECrement the byte counter; if it has not reached zero, JUMP to 576EH.
5767
GOSUB to the SYS0 routine at 443CH to write the full sector from 5200H.
576A
If the write failed, JUMP to 5855H to display the DOS error.
576D
DEC H 25
Move HL back from 5300H to 5200H, the start of the buffer.
576E
EXX D9
Switch back to the main register set.
576F
LD A,(HL) 7E
Fetch the next byte of the module buffer into Register A.
5771H - Fetch the Entry Point
Returns DE = the address in the last two bytes of the module buffer, which is the entry point of the module's transfer record.
5772
LD HL,(5374H) 2A 74 53
Fetch the Module Buffer Pointer (the last byte).
5775
LD D,(HL) 56
Fetch the high byte of the entry point.
5776
DEC HL 2B
Move back one byte.
5777
LD E,(HL) 5E
Fetch the low byte.
577AH - Write to Tape: Ask for the Name
The name must be one to six characters, each a letter or a digit; it is padded with spaces to six characters at 5E95H. The message says the first character must be a letter, but the check is the same for every character, so a digit is also accepted first.
577A
LD HL,5C79H 21 79 5C
Point HL to the message INPUT 1-6 CHAR TAPE MODULE NAME. / 1ST CHAR MUST BE A-Z; OTHERS A-Z OR 0-9 at 5C79H.
577D
GOSUB to 5893H to display it and read a reply. HL = the reply, Register B = its length.
5780
If the reply is empty, JUMP back to 577AH to ask again.
5782
LD A,B 78
Load Register A with the length.
5783
CP 07H FE 07
Compare it against 07H.
5785
If it is seven characters or more, JUMP back to 577AH to ask again.
5787
LD DE,5E95H 11 95 5E
Point DE to the name buffer at 5E95H.
578A
LD C,06H 0E 06
Load Register C with 06H, the length of a tape name.
578C
PUSH DE D5
Save the name buffer address for 57C8H. If the name is rejected at 57A1H, this word is left on the stack.
578D
LD A,(HL) 7E
Fetch a character of the reply.
578E
LD (DE),A 12
Store it in the name buffer.
578F
INC DE 13
Bump the name pointer.
5790
INC HL 23
Bump the reply pointer.
5791
SUB 30H D6 30
Subtract 0 (30H).
5793
CP 0AH FE 0A
Compare against 0AH.
5795
If it is a digit, JUMP to 579BH (the CARRY FLAG is set).
5797
SUB 11H D6 11
Subtract 11H more (from A).
5799
CP 1AH FE 1A
Compare against 1AH: the CARRY FLAG is set for A-Z.
579B
If the character is a digit or a capital letter, JUMP to 57A3H.
579D
SUB 20H D6 20
Subtract 20H more (from a).
579F
CP 1AH FE 1A
Compare against 1AH. 5893H has already turned lower case letters into capitals, so this never matches.
57A1
If the character is not a letter or a digit, JUMP back to 577AH to ask again.
57A3
DEC C 0D
Count one more name character.
57A4
If six characters are done, JUMP to 57AFH.
57A6
LOOP back to 578DH while the reply has more characters.
57A8
LD A,20H 3E 20
Load Register A with a space (20H).
57AA
LD (DE),A 12
Store it in the name buffer.
57AB
DEC C 0D
Count one more name character.
57AC
INC DE 13
Bump the name pointer.
57AD
LOOP back to 57A8H until the name is six characters long.
57AFH - Write to Tape: Header and Name
Waits for ENTER, then writes the leader, the sync byte, the 55H header byte and the six-character name.
57AF
GOSUB to 583AH. That address holds only a RET.
57B2
LD HL,5CC2H 21 C2 5C
Point HL to the message REPLY ENTER WHEN TAPE POSITIONED AND IN RECORD MODE at 5CC2H.
57B5
GOSUB to 5893H to display it and read a reply.
57B8
If anything was typed before ENTER, JUMP back to 57B2H to ask again.
57BA
DI F3
Disable interrupts for the tape timing.
57BB
GOSUB to the ROM routine at 0284H to turn on the cassette motor and write the leader and the A5H sync byte.
57BE
LD A,2AH 3E 2A
Load Register A with * (2AH).
57C0
LD (3C3FH),A 32 3F 3C
Display it at 3C3FH, the top right corner of the screen.
57C3
LD A,55H 3E 55
Load Register A with 55H, the byte that starts a SYSTEM tape.
57C5
GOSUB to the ROM routine at 0264H to write it.
57C8
POP HL E1
Restore the address of the name buffer (5E95H) into HL.
57C9
LD B,06H 06 06
Load Register B with 06H.
57CB
LD A,(HL) 7E
Fetch a character of the name.
57CC
INC HL 23
Bump the pointer.
57CD
GOSUB to the ROM routine at 0264H to write it to the tape.
57D0
LOOP back to 57CBH until all six characters are written.
57D2H - Write to Tape: the Records
Walks through the module buffer. Each object code record is written as a SYSTEM tape block: 3CH, the data byte count (00H = 256), the load address, the data and a checksum (the sum of the address bytes and the data). Marker records and record types other than 01H and 02H are not written. The transfer record ends the tape.
57D2
LD HL,5E9BH 21 9B 5E
Point HL to 5E9BH, the first record in the module buffer.
57D5
LD A,(HL) 7E
Fetch the record type.
57D6
CP 01H FE 01
Compare it against 01H (object code).
57D8
If it is 01H, JUMP to 57F0H.
57DA
CP 02H FE 02
Compare it against 02H (transfer address).
57DC
If it is 02H, JUMP to 5827H.
57DE
GOSUB to 5733H. A marker record is skipped (NC FLAG).
57E1
If it was a marker record, JUMP back to 57D5H.
57E3
INC HL 23
Any other record is skipped. Point HL to the length byte.
57E4
LD C,(HL) 4E
Fetch the length into Register C.
57E5
LD B,00H 06 00
Set Register B to 00H.
57E7
INC HL 23
Point HL to the first byte after the length.
57E8
LD A,C 79
Load Register A with the length.
57EA
If it is not zero, JUMP to 57EDH.
57EC
INC B 04
A length of 00H means 256 bytes: set BC = 0100H.
57ED
ADD HL,BC 09
Add the length: HL now points to the next record.
57F0
LD A,3CH 3E 3C
Load Register A with 3CH, the byte that starts an object code block.
57F2
GOSUB to the ROM routine at 0264H to write it.
57F5
INC HL 23
Point HL to the length byte.
57F6
LD B,(HL) 46
Fetch the length into Register B.
57F7
DEC B 05
DECrement Register B.
57F8
DEC B 05
DECrement Register B again: B = the number of data bytes (00H = 256).
57F9
INC HL 23
Point HL to the load address.
57FA
LD A,B 78
Load Register A with the data byte count.
57FB
GOSUB to the ROM routine at 0264H to write it.
57FE
LD E,(HL) 5E
Fetch the low byte of the load address.
5800
LD D,(HL) 56
Fetch the high byte of the load address.
5801
LD A,E 7B
Load Register A with the low byte.
5802
INC HL 23
Point HL to the first data byte.
5803
GOSUB to the ROM routine at 0264H to write the low byte of the load address.
5806
LD A,D 7A
Load Register A with the high byte.
5807
GOSUB to the ROM routine at 0264H to write it.
580A
LD A,D 7A
Load Register A with the high byte...
580B
ADD A,E 83
...add the low byte...
580C
LD C,A 4F
...and start the checksum in Register C.
580D
LD A,(HL) 7E
Fetch a data byte.
580E
GOSUB to the ROM routine at 0264H to write it.
5811
LD A,(HL) 7E
Fetch the data byte again.
5812
ADD A,C 81
Add it to the checksum.
5813
LD C,A 4F
Store the new checksum in Register C.
5815
LOOP back to 580DH until all the data bytes are written. Register A = the checksum.
5817
GOSUB to the ROM routine at 0264H to write the checksum.
581A
GOSUB to 583BH to check the up-arrow key.
581D
LD A,(3C3FH) 3A 3F 3C
Fetch the character at 3C3FH.
5820
XOR 0AH EE 0A
Switch it between * and a space.
5822
LD (3C3FH),A 32 3F 3C
Store it back, so the asterisk blinks once per block.
5825
LOOP back to 57D5H for the next record.
5827
LD A,78H 3E 78
Load Register A with 78H, the byte that starts the entry point block.
5829
GOSUB to the ROM routine at 0264H to write it.
582C
INC HL 23
Skip the type...
582D
INC HL 23
...and the length byte.
582E
LD A,(HL) 7E
Fetch the low byte of the entry point.
5830
GOSUB to the ROM routine at 0264H to write it.
5833
LD A,(HL) 7E
Fetch the high byte of the entry point.
5834
GOSUB to the ROM routine at 0264H to write it.
5837
JUMP to 5756H to display DONE. The cassette motor is turned off at 5862H.
583AH - Before a Tape Operation
Only a RET. It is called before the tape is read (53BFH) and before the operator is asked to ready the tape for writing (57AFH).
583BH - Check the Up-Arrow Key
Reads keyboard row 6 at 3840H. If the up-arrow key (bit 3) is down, the current function is abandoned with FUNCTION CANCELLED BY OPERATOR. This is a jump, not a return, so the caller's return address is left on the stack; 537CH resets the stack when a new source file is started. Called while the tape is read or written and after every line typed (58A2H).
583B
LD A,(3840H) 3A 40 38
Fetch keyboard row 6 (ENTER, CLEAR, BREAK, up-arrow, down-arrow, left-arrow, right-arrow, space).
583E
AND 08H E6 08
Keep only bit 3, the up-arrow key.
5840
RET Z C8
If it is not pressed, RETurn.
5841
LD HL,5CF6H 21 F6 5C
Point HL to the message FUNCTION CANCELLED BY OPERATOR at 5CF6H.
5844
JUMP to 585FH to display it.
5846H - Error Exits
Each loads the address of a message and goes to 585FH. 5855H displays a DOS error instead.
5846
LD HL,5C69H 21 69 5C
Point HL to the message BAD MAIN MEMORY at 5C69H (from 5739H).
584B
LD HL,5C01H 21 01 5C
Point HL to the message SOURCE ILLEGAL LOAD-TO-MEMORY ADDRESS at 5C01H (from 549BH).
5850
LD HL,5BD0H 21 D0 5B
Point HL to the message SOURCE MODULE BAD FORMAT at 5BD0H (from 5699H).
5855
OR C0H F6 C0
A DOS routine returned an error code in Register A. Set bits 6 and 7 of the code.
5857
GOSUB to the SYS0 routine at 4409H to display the DOS error message. It returns here.
585C
LD HL,5BE9H 21 E9 5B
Point HL to the message INSUFFICIENT RAM MEMORY at 5BE9H (from 5486H).
585FH - Display a Message and Ask What to Do Next
Every function ends here: after DONE, an error or a cancel. If a destination was being written, the operator can write the same module to another file; otherwise, or after N, the operator can start another source module or go back to DOS.
585F
GOSUB to the SYS0 routine at 4467H to display the message at HL.
5862
GOSUB to the ROM routine at 01F8H to turn off the cassette motor.
5865
EI FB
Enable interrupts again.
5866
LD A,(5373H) 3A 73 53
Fetch the Output Phase Flag.
586A
If no destination has been asked for yet, JUMP to 587FH.
586C
LD HL,5A70H 21 70 5A
Point HL to the message *********** ANOTHER DESTINATION FILE? (Y OR N) at 5A70H.
586F
GOSUB to 5893H to display it and read a reply.
5872
LOOP back to 5866H unless the reply was exactly one character long.
5874
CP 4EH FE 4E
Compare the reply against N (4EH).
5876
If it is N, JUMP to 587FH.
5878
CP 59H FE 59
Compare the reply against Y (59H).
587A
If it is neither, JUMP back to 5866H to ask again.
587C
JUMP to 56E6H to ask for another destination for the same module.
587F
LD HL,5AA0H 21 A0 5A
Point HL to the message ANOTHER SOURCE FILE TO PROCESS? (Y OR N) at 5AA0H.
5882
GOSUB to 5893H to display it and read a reply.
5885
LOOP back to 587FH unless the reply was exactly one character long.
5887
CP 59H FE 59
Compare the reply against Y (59H).
5889
If it is Y, JUMP to 537CH to start again.
588C
CP 4EH FE 4E
Compare the reply against N (4EH).
588E
If it is neither, JUMP back to 587FH to ask again.
5890
JUMP to 402DH in SYS0 to return to DOS.
5893H - Display a Message and Read a Reply
5893H displays the message at HL and reads up to 64 characters into the buffer at 5332H. 589BH reads a line into the buffer at HL with the maximum length in Register A. BREAK makes it read the line again; the up-arrow key is checked after every line (583BH). Lower case letters are changed to capitals. Returns HL = the buffer, Register B = the number of characters typed, Register A = the first character and the Z FLAG set if nothing was typed.
5893
GOSUB to the SYS0 routine at 4467H to display the message.
5896
LD HL,5332H 21 32 53
Point HL to the input buffer at 5332H (just below the program).
5899
LD A,40H 3E 40
Load Register A with 40H, the maximum length (64 characters).
589B
LD B,A 47
Load Register B with the maximum length.
589C
PUSH HL E5
Save the buffer address.
589D
PUSH BC C5
Save the maximum length.
589E
GOSUB to the ROM routine at 0040H to read a line from the keyboard into the buffer. It returns Register B = the number of characters typed and the CARRY FLAG set if BREAK was pressed.
58A1
PUSH AF F5
Save the flags.
58A2
GOSUB to 583BH to check the up-arrow key.
58A5
POP AF F1
Restore the flags.
58A6
LD A,B 78
Load Register A with the number of characters typed.
58A7
POP BC C1
Restore the maximum length.
58A8
POP HL E1
Restore the buffer address.
58A9
If BREAK was pressed, JUMP back to 589CH to read the line again.
58AB
PUSH HL E5
Save the buffer address.
58AC
LD B,A 47
Keep the number of characters typed in Register B.
58AD
LD A,(HL) 7E
Fetch a character.
58AE
SUB 61H D6 61
Subtract a (61H).
58B0
CP 1AH FE 1A
Compare against 1AH.
58B2
If it is not a lower case letter, JUMP to 58B7H.
58B4
ADD A,41H C6 41
Otherwise add A (41H), giving the capital letter...
58B6
LD (HL),A 77
...and store it back.
58B7
LD A,(HL) 7E
Fetch the character.
58B8
CP 0DH FE 0D
Compare it against a carriage return (0DH), which ends the line.
58BA
INC HL 23
Bump the pointer.
58BB
LOOP back to 58ADH until the carriage return.
58BD
POP HL E1
Restore the buffer address.
58BE
LD A,(HL) 7E
Fetch the first character.
58BF
CP 0DH FE 0D
Set the Z FLAG if it is the carriage return, i.e. nothing was typed.
58C2H - Appendage: First Record Header and Patch Area
The appendage is kept here as ready-made load module records. This header starts its first object code record: type 01H, the length byte and the load address. The length is 50H for the DOS-enabled appendage (5D15H) and C1H for the DOS-disabled one (568DH); the load address is filled in at 5656H. 56CDH copies these four bytes and the 64 patch bytes after them into the module buffer. See The Appendages.
58C2
DEFB 01H 01
Record type 01H (object code).
58C3
DEFB 50H 50
Length byte: 50H (78 data bytes) for the DOS-enabled appendage, changed to C1H (191 data bytes) for the DOS-disabled one.
58C4-58C5
DEFW 0000H 00 00
Load address of the appendage, set at 5656H to the byte after the module's new last byte.
58C6H - Appendage Patch Area
Not part of the file: the file has no load record for 58C6H-5905H. 5388H sets these 64 bytes to zero, and they become the first 64 bytes of every appendage. The manual describes them as a patch area: code patched in here runs first when the output module is started, before the program is moved and before DOS is disabled.
58C6-5905
DEFS 64
Patch Area (64 bytes, cleared at 5388H).
5906H - DOS-Disabled Appendage: Save the Screen and Show the Instructions
This code is not run here. From 5906H to 5A00H it is copied into the module being written (56DEH-56E3H), where it runs at X+40H, X being the appendage's load address. The zero operands are filled in at 5664H-5687H. It saves the screen above the appendage, puts a jump at 42E9H (the start of the non-disk BASIC program area), shows the instructions and waits in a loop for the operator to reset the computer into non-disk BASIC.
5906
LD DE,0000H 11 00 00
Point DE to X+137H (filled in at 5687H), the byte after the appendage: the screen is saved there.
5909
LD HL,3C00H 21 00 3C
Point HL to the start of the screen at 3C00H.
590C
LD BC,0400H 01 00 04
Load BC with 0400H (1,024 bytes).
590F
LDIR ED B0
Copy the screen to X+137H.
5911
LD HL,0000H 21 00 00
Point HL to X+5EH (filled in at 5668H), where the six bytes from 5924H are.
5914
LD DE,42E9H 11 E9 42
Point DE to 42E9H, the start of the program area of non-disk BASIC.
5917
LD BC,0006H 01 06 00
Load BC with 0006H.
591A
LDIR ED B0
Copy the six bytes: three NOPs and a jump to the rest of the appendage.
591C
LD HL,0000H 21 00 00
Point HL to X+64H (filled in at 566FH), where the message from 592AH is.
591F
GOSUB to the SYS0 routine at 4467H to display the instructions. DOS is still in memory at this point.
5922
JR 5922H 18 FE
Loop here for ever. The operator now holds BREAK and presses RESET.
The six bytes copied to 42E9H-42EEH. The displayed instructions end with SYSTEM and /; this jump is where the appendage expects execution to continue. The three NOPs are presumably there because non-disk BASIC writes zeros at the start of its program area when it starts up.
5924
NOP 00
No operation (at 42E9H).
5925
NOP 00
No operation (at 42EAH).
5926
NOP 00
No operation (at 42EBH).
5927
JP 0000H C3 00 00
JUMP to X+11EH (filled in at 567DH), where the code from 59E8H is.
592AH - DOS-Disabled Appendage: Instructions to the Operator
Displayed by 591FH. The text is split between the appendage's two records: 5985H-5988H in the middle is the header of the second record, which is not part of the text once the records are loaded. The manual gives the message as RECORD AND THEN PERFORM THE FOLLOWING INSTRUCTIONS and step 4 as ENTER "."; the file has DO THE FOLLOWING: and ENTER "/".
592A-592B
DEFB 1CH,1FH 1C 1F
Cursor home (1CH) and clear to the end of the screen (1FH).
592C-593C
DEFM "DO THE FOLLOWING:" 44 4F 20 54 48 45 20 46 4F 4C 4C 4F 57 49 4E 47 3A
593D-593E
DEFB 0AH,0AH 0A 0A
Two line feeds.
593F-5979
DEFM "1. HOLD DOWN BREAK KEY AND PRESS RESET TO ACTIVATE NON-DISK" 31 2E 20 48 4F 4C 44 20 44 4F 57 4E 20 42 52 45 41 4B 20 4B 45 59 20 41 4E 44 20 50 52 45 53 53 20 52 45 53 45 54 20 54 4F 20 41 43 54 49 56 41 54 45 20 4E 4F 4E 2D 44 49 53 4B
597A
DEFB 0AH 0A
Line feed.
597B-5984
DEFM " BASIC." / DEFB 0AH 20 20 20 42 41 53 49 43 2E 0A
The last byte of the first record is the line feed at 5984H.
5985H - DOS-Disabled Appendage: Second Record Header
The second object code record of the DOS-disabled appendage: type 01H, length 7AH (120 data bytes: 5989H-5A00H) and the load address X+BFH, filled in at 5676H. 56E1H-56E3H copies this header, the record and the transfer record after it.
5985
DEFB 01H 01
Record type 01H (object code).
5986
DEFB 7AH 7A
Length byte: 120 data bytes and 2 address bytes.
5987-5988
DEFW 0000H 00 00
Load address of the second record, set at 5676H to X+BFH.
5989H - DOS-Disabled Appendage: Instructions, Continued
The rest of the message started at 592AH, ended by a carriage return.
5989-59C6
DEFM "2. RELEASE BREAK KEY AND INPUT BASIC INITIALIZATION RESPONSES." 32 2E 20 52 45 4C 45 41 53 45 20 42 52 45 41 4B 20 4B 45 59 20 41 4E 44 20 49 4E 50 55 54 20 42 41 53 49 43 20 49 4E 49 54 49 41 4C 49 5A 41 54 49 4F 4E 20 52 45 53 50 4F 4E 53 45 53 2E
59C7
DEFB 0AH 0A
Line feed.
59C8-59D9
DEFM '3. ENTER "SYSTEM".' 33 2E 20 45 4E 54 45 52 20 22 53 59 53 54 45 4D 22 2E
59DA
DEFB 0AH 0A
Line feed.
59DB-59E7
DEFM '4. ENTER "/"' / DEFB 0DH 34 2E 20 45 4E 54 45 52 20 22 2F 22 0D
Ended by a carriage return.
59E8H - DOS-Disabled Appendage: Restore the Screen
Reached through the jump at 42ECH after the operator has started non-disk BASIC and answered SYSTEM with /. Runs at X+11EH. Copies the saved screen back and falls into the move code.
59E8
LD HL,0000H 21 00 00
Point HL to X+137H (filled in at 5684H), where the screen was saved.
59EB
LD DE,3C00H 11 00 3C
Point DE to the start of the screen at 3C00H.
59EE
LD BC,0400H 01 00 04
Load BC with 0400H (1,024 bytes).
59F1
LDIR ED B0
Copy the screen back.
59F3H - Appendage: Move the Program and Start It
The end of both appendages. In the DOS-enabled appendage it runs at X+40H, straight after the patch area; in the DOS-disabled one it follows 59F1H. Moves the program from where the output module loads it back to its original addresses and jumps to the original entry point. The operands are filled in at 55ECH and 569FH-56BAH.
59F3
LD HL,0000H 21 00 00
Point HL to the first byte of the program as loaded (the new start), or its last byte when LDDR is used (filled in at 56B7H).
59F6
LD DE,0000H 11 00 00
Point DE to the first byte of the original load address, or its last byte for LDDR (filled in at 56BAH).
59F9
LD BC,0000H 01 00 00
Load BC with the size of the program (filled in at 569FH).
59FC
LDIR ED B0
Copy the program to its original address. The second byte is B0H (LDIR) or B8H (LDDR), set at 56B4H.
59FE
JP 0000H C3 00 00
JUMP to the program's original entry point (filled in at 55ECH).
The appendage's transfer record, copied with the move code. It becomes the output module's entry point.
5A01
DEFB 02H 02
Record type 02H (transfer address).
5A02
DEFB 02H 02
Length byte.
5A03-5A04
DEFW 0000H 00 00
The entry point: the appendage's load address X, set at 55A6H.
5A05H - Convert a Hexadecimal Number
Converts the characters at DE into HL. Register A = the number of characters. Returns the CARRY FLAG set if there are more than four characters or one of them is not 0-9 or A-F. Used for the new load base (55C0H).
5A05
LD B,A 47
Keep the number of characters in Register B.
5A06
ADD A,FBH C6 FB
Add FBH: the CARRY FLAG is set if there are five or more characters.
5A08
RET C D8
If there are, RETurn with the CARRY FLAG set.
5A09
LD HL,0000H 21 00 00
Set HL to 0000H.
5A0C
ADD HL,HL 29
Shift HL left...
5A0D
ADD HL,HL 29
...four bits...
5A0E
ADD HL,HL 29
...to make room...
5A0F
ADD HL,HL 29
...for the next digit.
5A10
LD A,(DE) 1A
Fetch a character.
5A11
SUB 30H D6 30
Subtract 0 (30H).
5A13
CP 0AH FE 0A
Compare against 0AH.
5A15
INC DE 13
Bump the pointer.
5A16
If it is a digit, JUMP to 5A20H with its value in Register A.
5A18
SUB 11H D6 11
Subtract 11H more (from A).
5A1A
CP 06H FE 06
Compare against 06H.
5A1C
CCF 3F
Reverse the CARRY FLAG: it is now set if the character is not A-F.
5A1D
RET C D8
If it is not, RETurn with the CARRY FLAG set.
5A1E
ADD A,0AH C6 0A
Add 0AH, giving 0AH-0FH.
5A20
OR L B5
Merge the digit into the low four bits of Register L. This also clears the CARRY FLAG.
5A21
LD L,A 6F
Store it back.
5A22
LOOP back to 5A0CH for the next character.
5A24
RET C9
RETurn with the value in HL and the CARRY FLAG clear.
5A25H - Write a Hexadecimal Number
5A25H writes DE as four hexadecimal characters at HL, 5A2AH writes Register A as two and 5A33H writes the low four bits of Register A as one. HL is left pointing past the last character. Used to fill in the XXXX fields of the messages.
5A25
LD A,D 7A
Load Register A with the high byte, Register D.
5A26
GOSUB to 5A2AH to write it as two characters.
5A29
LD A,E 7B
Load Register A with the low byte, Register E, and fall into 5A2AH.
5A2A
PUSH AF F5
Save the byte.
5A2B
RRCA 0F
Rotate the high four bits...
5A2C
RRCA 0F
...of Register A...
5A2D
RRCA 0F
...into the low...
5A2F
GOSUB to 5A33H to write the high digit.
5A32
POP AF F1
Restore the byte, and fall into 5A33H to write the low digit.
5A33
AND 0FH E6 0F
Keep only the low four bits.
5A35
ADD A,90H C6 90
Add 90H.
5A37
DAA 27
Decimal adjust: 90H-99H for 0-9, and 00H-05H with the CARRY FLAG set for 0AH-0FH.
5A38
ADC A,40H CE 40
Add 40H and the carry.
5A3A
DAA 27
Decimal adjust again, giving 0-9 (30H-39H) or A-F (41H-46H).
5A3B
LD (HL),A 77
Store the character.
5A3C
INC HL 23
Bump the pointer.
5A3EH - Messages
All displayed through the SYS0 routine at 4467H. Messages ended by 03H leave the cursor on the same line for the reply; those ended by 0DH end the line. The XXXX fields are filled in by 5A25H before the message is shown.
5A3E-5A3F
DEFB 1CH,1FH 1C 1F
Cursor home and clear to the end of the screen: the title starts on a clear screen.
5A40-5A6F
DEFM "APPARAT LOAD MODULE OFFSET PROGRAM, VERSION 2.0" / DEFB 0DH 41 50 50 41 52 41 54 20 4C 4F 41 44 20 4D 4F 44 55 4C 45 20 4F 46 46 53 45 54 20 50 52 4F 47 52 41 4D 2C 20 56 45 52 53 49 4F 4E 20 32 2E 30 0D
The title, displayed at 53A6H.
5A70-5A9F
DEFM "*********** ANOTHER DESTINATION FILE? (Y OR N) " / DEFB 03H 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 20 41 4E 4F 54 48 45 52 20 44 45 53 54 49 4E 41 54 49 4F 4E 20 46 49 4C 45 3F 20 28 59 20 4F 52 20 4E 29 20 03
Asked at 586CH after a destination has been written or has failed.
5AA0-5ACA
DEFM "ANOTHER SOURCE FILE TO PROCESS? (Y OR N) " / DEFB 03H 41 4E 4F 54 48 45 52 20 53 4F 55 52 43 45 20 46 49 4C 45 20 54 4F 20 50 52 4F 43 45 53 53 3F 20 20 28 59 20 4F 52 20 4E 29 20 03
Asked at 587FH.
5ACB-5AEF
DEFM "SOURCE FROM DISK OR TAPE? (D OR T) " / DEFB 03H 53 4F 55 52 43 45 20 46 52 4F 4D 20 44 49 53 4B 20 4F 52 20 54 41 50 45 3F 20 20 28 44 20 4F 52 20 54 29 20 03
Asked at 53A9H.
5AF0-5B14
DEFM "DESTINATION DISK OR TAPE? (D OR T) " / DEFB 03H 44 45 53 54 49 4E 41 54 49 4F 4E 20 44 49 53 4B 20 4F 52 20 54 41 50 45 3F 20 20 28 44 20 4F 52 20 54 29 20 03
Asked at 56EBH.
5B15-5B26
DEFM "SOURCE FILESPEC? " / DEFB 03H 53 4F 55 52 43 45 20 46 49 4C 45 53 50 45 43 3F 20 03
Asked at 54DCH.
5B27-5B3D
DEFM "DESTINATION FILESPEC? " / DEFB 03H 44 45 53 54 49 4E 41 54 49 4F 4E 20 46 49 4C 45 53 50 45 43 3F 20 03
Asked at 56FCH.
5B3E-5B57
DEFM "MODULE LOADS TO XXXX-XXXX" / DEFB 0DH 4D 4F 44 55 4C 45 20 4C 4F 41 44 53 20 54 4F 20 58 58 58 58 2D 58 58 58 58 0D
Displayed at 5579H. The first XXXX (5B4EH) is the start address, the second (5B53H) the end address.
5B58-5B7C
DEFM "MODULE LOAD OVERLAPS DOS (4000-51FF)" / DEFB 0DH 4D 4F 44 55 4C 45 20 4C 4F 41 44 20 4F 56 45 52 4C 41 50 53 20 44 4F 53 20 28 34 30 30 30 2D 35 31 46 46 29 0D
Displayed at 5591H.
5B7D-5B9A
DEFM "NEW LOAD BASE ADDRESS (HEX)? " / DEFB 03H 4E 45 57 20 4C 4F 41 44 20 42 41 53 45 20 41 44 44 52 45 53 53 20 28 48 45 58 29 3F 20 03
Asked at 55B6H.
5B9B-5BB7
DEFM "MODULE LOAD WILL OVERLAP ROM" / DEFB 0DH 4D 4F 44 55 4C 45 20 4C 4F 41 44 20 57 49 4C 4C 20 4F 56 45 52 4C 41 50 20 52 4F 4D 0D
Displayed at 5587H.
5BB8-5BCF
DEFM "DISABLE DOS? (Y OR N) " / DEFB 03H 44 49 53 41 42 4C 45 20 44 4F 53 3F 20 20 28 59 20 4F 52 20 4E 29 20 03
Asked at 5645H.
5BD0-5BE8
DEFM "SOURCE MODULE BAD FORMAT" / DEFB 0DH 53 4F 55 52 43 45 20 4D 4F 44 55 4C 45 20 42 41 44 20 46 4F 52 4D 41 54 0D
Error from 5850H.
5BE9-5C00
DEFM "INSUFFICIENT RAM MEMORY" / DEFB 0DH 49 4E 53 55 46 46 49 43 49 45 4E 54 20 52 41 4D 20 4D 45 4D 4F 52 59 0D
Error from 585CH.
5C01-5C26
DEFM "SOURCE ILLEGAL LOAD-TO-MEMORY ADDRESS" / DEFB 0DH 53 4F 55 52 43 45 20 49 4C 4C 45 47 41 4C 20 4C 4F 41 44 2D 54 4F 2D 4D 45 4D 4F 52 59 20 41 44 44 52 45 53 53 0D
Error from 584BH.
5C27-5C2B
DEFM "DONE" / DEFB 0DH 44 4F 4E 45 0D
Displayed at 5756H when the destination is written.
5C2C-5C3E
DEFM "ENTRY POINT = XXXX" / DEFB 0DH 45 4E 54 52 59 20 50 4F 49 4E 54 20 3D 20 58 58 58 58 0D
Displayed at 55B0H. The XXXX is at 5C3AH.
5C3F-5C68
DEFM "SHALL APPENDAGE BE SUPPRESSED? (Y OR N) " / DEFB 03H 53 48 41 4C 4C 20 41 50 50 45 4E 44 41 47 45 20 42 45 20 53 55 50 50 52 45 53 53 45 44 3F 20 20 28 59 20 4F 52 20 4E 29 20 03
Asked at 55CFH.
5C69-5C78
DEFM "BAD MAIN MEMORY" / DEFB 0DH 42 41 44 20 4D 41 49 4E 20 4D 45 4D 4F 52 59 0D
Error from 5846H.
5C79-5C99
DEFM "INPUT 1-6 CHAR TAPE MODULE NAME." / DEFB 0AH 49 4E 50 55 54 20 31 2D 36 20 43 48 41 52 20 54 41 50 45 20 4D 4F 44 55 4C 45 20 4E 41 4D 45 2E 0A
Asked at 577AH. The line feed starts the second line.
5C9A-5CC1
DEFM "1ST CHAR MUST BE A-Z; OTHERS A-Z OR 0-9" / DEFB 0DH 31 53 54 20 43 48 41 52 20 4D 55 53 54 20 42 45 20 41 2D 5A 3B 20 4F 54 48 45 52 53 20 41 2D 5A 20 4F 52 20 30 2D 39 0D
5CC2-5CF5
DEFM "REPLY ENTER WHEN TAPE POSITIONED AND IN RECORD MODE" / DEFB 03H 52 45 50 4C 59 20 45 4E 54 45 52 20 57 48 45 4E 20 54 41 50 45 20 50 4F 53 49 54 49 4F 4E 45 44 20 41 4E 44 20 49 4E 20 52 45 43 4F 52 44 20 4D 4F 44 45 03
Asked at 57B2H.
5CF6-5D14
DEFM "FUNCTION CANCELLED BY OPERATOR" / DEFB 0DH 46 55 4E 43 54 49 4F 4E 20 43 41 4E 43 45 4C 4C 45 44 20 42 59 20 4F 50 45 52 41 54 4F 52 0D
Displayed at 5841H when the up-arrow key is pressed.
5D15H - Reset the Appendage Length and Point to the Title
Called once at start-up (53A3H). Sets the length byte of the appendage's first record back to 50H, the DOS-enabled size, because 568DH changes it to C1H when DOS is to be disabled. Returns HL pointing to the title.
5D15
LD A,50H 3E 50
Load Register A with 50H.
5D17
LD (58C3H),A 32 C3 58
Store it as the length byte at 58C3H.
5D1A
LD HL,5A3EH 21 3E 5A
Point HL to the title at 5A3EH.
5D1EH - Unused Bytes
The last 100 bytes of the file are zero and nothing refers to them.
5D1E-5D81
DEFB 00H x 100 00 x 100
Not referenced.