TRS-80 DOS - NEWDOS/80 v2.0 for the Model I - ASPOOL/MAS Disassembled

Page Customization

Introduction/Summary

NEWDOS/80 v2.0 ASPOOL/MAS Disassembly - The Automatic Spooler (Model I)

ASPOOL/MAS is the automatic print spooler supplied on the NEWDOS/80 diskette (manual section 6.7: H. S. Gentry's spooler, changed by Apparat to work with NEWDOS/80 and to relocate itself). While it is active, everything a program sends to the printer goes to one of five disk files, POOL1 to POOL5 on a drive chosen at setup, and the files are printed in the background whenever the program reads the keyboard or sends another character to the printer, and with the interrupt option also from the 25 ms timer interrupt.

The file loads at 5450H-5DD0H in ten load records (2,433 bytes), transfer address 5C4BH; the rest of its last sector is zero bytes after the transfer record. It is never run in place: ASPOOL/MAS,I asks the setup questions and writes a working module with DUMP (the master on the diskette is not changed), and filespec,A run on that module copies 5450H-58F9H to the top of memory, relocates it and hooks it into the printer and keyboard drivers. Once active it answers the DOS command *ASP, as a *name routine on SYS9's list.

The page shows every byte of the file once, in address order, written from S:\1\ASPOOL.MAS and its listing. The old version of this page had misaligned rows at 5479H-547BH, 5525H-552DH and 55A5H-55A8H (its seven TODO rows), named the commands and options wrongly (a W "write mode", P "print mode", an A "purge all" command), described a 256-byte circular buffer at 5440H-5540H, and described printer hardware that the Model I file does not use.

Commands

CommandWhereWhat it does
ASPOOL/MAS,I58FAHAsk the setup questions, store the answers into the code, and write 5450H-5DD0H to a new file with DUMP filespec 5450H 5DD0H 5C4BH through DOS-CALL.
filespec,A5C58HActivate: empty POOL1-POOL5 on the spool drive, keep the drivers found in 4026H and 4016H, set up the RS-232 board for a serial printer, copy the spooler below HIMEM and relocate it, put ASP on the *name list (error 35H if it is already there), lower HIMEM, point the printer and keyboard drivers into the copy and, with the interrupt option, enqueue the timer routine. Then SPOOL ACTIVE and DOS READY.
*ASP5486HSPOOL STATUS, then SPOOL STOPPING or the file being spooled, the file being printed, and every file waiting (BACK LOG).
*ASP,W or 03H5501HEnd the file being spooled (a part-filled sector gets the end mark 03H) and queue it for printing.
*ASP,S or 04H5505HStop: printer output is ignored from now on, the queued files are still printed, and when the queue is empty the purge runs.
*ASP,C54D5HCLEAR BACKLOG OR PRINT (B/P)? B frees the waiting files and then does W; P empties the file being printed after its next sector read.
*ASP,P56F6HPurge: empty the file being spooled, take the timer routine out, put the old drivers back, give HIMEM back if nothing has lowered it since, take ASP off the *name list.

Any other letter, or text after the letter, gives BAD PARAMETER(S) (2FH). Once the spooler has been purged, *ASP gives FILE NOT IN DIRECTORY (from SYS9). The manual says the purge shows SPOOL PURGED; the message is in the file at 588BH but no instruction displays it.

Memory Use

All addresses on this page are those of the file. At activation the area 5200H-58F9H (06FAH bytes) is placed at HIMEM - 06FAH + 1, and the code's addresses in that area are relocated (the scan at 5CE0H); the area below 5450H is not in the file and holds the buffers.

AreaContents
5200H-52FFHThe print sector buffer: the sector of the file being printed (read at 56B9H).
5300H-53FFHThe spool sector buffer: the bytes being spooled until the sector is full (5598H).
5400H-541FHThe FCB of the file being printed (POOLn:d, buffer 5200H).
5420H-543FHThe FCB of the file being spooled (POOLn:d, buffer 5300H).
5440H-5449HThe circular keyboard buffer, 10 bytes (57DDH, 57FAH).
5450H-545BHThe *name block (check word, link, the name ASP).
545CH-581CHThe resident code, relocated at activation.
581DH-58F9HThe resident data: name template, print queue, page counters, messages.
58FAH-5DD0HSetup and activation code and data; not copied, so its memory is free once the spooler is active.

Pool Files and the Print Queue

The bytes 5828H-582CH belong to POOL1-POOL5, with FFH at 582DH after them. 00H means the file is free or is the one being spooled; 01H the file being printed, or printed next; 02H-05H its place in the queue. When a spool file is ended (55D0H) its byte becomes one more than the number of files queued. When a printed file is finished (56CAH) its EOF is set to 0 and it is closed, so the DOS frees its space, and every byte from 01H up is lowered by one. When a sixth file is needed while five are queued, SPOOL FULL. WAITING ON PRINTER is shown and the spooler only prints until one is free. When the spool diskette is full, the current file is ended and queued and the output goes on in the next file (55F0H).

Spooled output passes through 557EH, which puts a space before a carriage return that ends an empty line. With the paging option the lines are counted (5539H) and a form feed is done when the print lines per page are reached; the hard form feed is a 0CH byte, the soft one carriage returns up to the total lines per page (555BH). Characters that the DOS sends to the printer while an overlay function runs (bit 6 of 4369H) are dropped, with CAN'T SPOOL FROM DOS shown for the first of them (5518H).

Printing (5762H) waits until the print delay chosen at setup has passed since the last key, then sends the buffer up to the next carriage return, as long as the printer is ready. Disk reads are only done from 567DH (keyboard reads with no key waiting, and each character spooled), never from the timer interrupt, and not while an overlay function runs.

Setup Answers

QuestionAnswerStored
USE EXISTING PRINTER DRIVER (Y/N)?Y / N5791H kind 02H (call the driver found in 4026H at activation), else the next question
PARALLEL OR SERIAL PRINTER (P/S)?P / SKind 01H (status and data at 37E8H) or 00H (RS-232 board, ports E8H-EBH)
H14 PRINTER (Y/N)?Y / N57BDH LD A,05H (also wait for bit 6 of port E8H) or JR (no such test)
PAGES (Y/N)?Y / N5554H RET C (form feed when the page is full) or RET
PRINT LINES PER PAGE (10-99)?two charactersOperand 5552H (5553H)
SOFT OR HARD FORM FEED (S/H)?S / HOperand of 5547H (5548H): 01H soft, 00H hard
TOTAL LINES PER PAGE (10-99)?two charactersOperand of 554DH (554EH), asked for S only
TOP-OF-FORM AT END OF FILE (Y/N)?Y / N55BBH CALL NZ,555BH or LD DE,555BH
LINE FEED ON CARRIAGE RETURN (Y/N)?Y / N57D5H NOP (a line feed follows every carriage return) or RET
DRIVE # FOR POOL FILES (0-3)?0-35824H, the drive digit of POOLn:d
# SECONDS PRINT DELAY AFTER LATEST INPUT KEY (00-59)?two charactersOperand of 577DH (577EH)
INTERRUPTS ALSO DRIVE PRINTER (Y/N)?Y / NOperand of 5DB3H (5DB4H): enqueue the timer routine; also chooses the ROM keyboard routine for the circular buffer
USE CIRCULAR BUFFER (Y/N)?Y / NOperand of 5C87H (5C88H)
NEW SPOOL PROGRAM FILESPEC?up to 26 charactersThe filespec of the DUMP command at 5C11H

The number questions take exactly two characters and convert them with the ROM's FIN; the ranges in the questions are not checked. In the file the options are: printer kind 01H (parallel), no port E8H test, pages with FFH print lines and a hard form feed, top of form at the end of a file, no line feed, drive 1, no print delay, interrupts and circular buffer used.

Relocation

5CB2H copies 5450H-58F9H to the area start + 0250H; the offset (area start - 5200H) stays on the stack. 5CE0H then walks the copied code 545CH-581CH instruction by instruction, working out each instruction's length from its opcode, and adds the offset to every 16-bit address operand between 5200H and 58F9H. The scan must end exactly at the copy of 581DH, otherwise error 3AH. The data from 581DH on, and the *name block, hold no addresses and are not scanned. Addresses outside the area (SYS0, the ROM, the device control blocks) are left alone.

Variables

Self-Modified Operands and Opcodes

Address
Size
Contents
5519H
1 byte
DOS Output State
Operand of the LD E,nn at 5518H: bit 6 of 4369H for the previous character, stored by 551FH.
5534H
1 byte
Spool File Number
Operand of the LD A,nn at 5533H: the pool file being spooled (1-5) or 00H; stored by 560CH, cleared by 55EBH.
5548H
1 byte
Form Feed Kind
Operand of 5547H: 00H hard (0CH), 01H soft (carriage returns).
554EH
1 byte
Total Lines Per Page
Operand of the SUB at 554DH, for the soft form feed.
5553H
1 byte
Print Lines Per Page
Operand of the CP at 5552H.
5554H
1 byte
Page Test
The RET C (D8H) or RET (C9H) at 5554H.
5599H-559AH
2 bytes
Spool Buffer Pointer
Operand of 5598H: the next free byte of 5300H-53FFH.
55BBH
1 byte
Top of Form at End of File
The CALL NZ (C4H) or LD DE (11H) opcode at 55BBH.
550BH
1 byte
Printer Driver Gate
PUSH HL as loaded, RET (C9H) after the spooler is stopped (5636H).
5662H-5663H
2 bytes
Key Source
Operand of the CALL at 5661H: 57FAH (circular buffer) or the old keyboard driver.
56C5H
1 byte
Abort Printing
Operand of 56C4H: 50H after *ASP,C answered P.
56F1H
1 byte
Stopping
Operand of 56F0H: C9H after the spooler is stopped.
5708H-5709H
2 bytes
Old Printer Driver
Operand of 5707H, restored into 4026H by the purge.
570EH-570FH
2 bytes
Old Keyboard Driver
Operand of 570DH, restored into 4016H by the purge.
573DH-573EH
2 bytes
Print Pointer
Operand of 573CH: the next byte of 5200H-52FFH to print; 5301H at the end mark.
5759H
1 byte
Timer Routine Gate
The NOP at 5759H, a RET while 567DH prints.
5766H
1 byte
Printing File Number
Operand of 5765H: the pool file being printed or 00H.
576DH
1 byte
Second of the Last Key
Operand of the SUB at 576CH, stored by 5670H.
5777H-5778H
2 bytes
Minute and Hour of the Last Key
Operand of 5776H, stored by 5677H.
577EH
1 byte
Print Delay
Operand of the CP at 577DH: seconds after the last key.
5792H
1 byte
Printer Kind
Operand of 5791H: 00H serial, 01H parallel, 02H old driver.
57A4H-57A5H
2 bytes
Old Printer Driver
Operand of the CALL at 57A3H.
57BDH
1 byte
Port E8H Test
JR (18H) or LD A,nn (3EH) at 57BDH.
57D5H
1 byte
Line Feed Option
RET (C9H) or NOP (00H) at 57D5H.
57DDH
1 byte
Keyboard Check Gate
NOP, or RET without the circular buffer, at 57DDH.
57E3H-57E4H
2 bytes
Keyboard Routine
Operand of the CALL at 57E2H: ROM 03E3H or the old keyboard driver.
57E8H-57E9H
2 bytes
Circular Write Pointer
Operand of 57E7H.
57FBH
1 byte
Circular Read Count
Operand of 57FAH, F6H-FFH.
57FDH
1 byte
Circular Write Count
Operand of the SUB at 57FCH, F6H-FFH.
5802H-5803H
2 bytes
Circular Read Pointer
Operand of 5801H.
5C88H
1 byte
Circular Buffer Option
Operand of 5C87H.
5DB4H
1 byte
Interrupt Option
Operand of 5DB3H.

Resident Data

Address
Size
Contents
5822H
1 byte
Pool File Digit
In the template POOLn:d at 581EH.
5824H
1 byte
Spool Drive Digit
In the template, set by setup.
5826H-5827H
2 bytes
B/P Answer
The answer of *ASP,C and its 0DH.
5828H-582DH
6 bytes
Print Queue
One byte per pool file, FFH after them.
582EH
1 byte
Line Count
Lines on the current page of the spool file.
582FH
1 byte
Line Flag
01H when the current line has a printable character.
5C44H-5C48H
5 bytes
Setup Answer Buffers
One character at 5C44H, two at 5C46H.

Outside Addresses

Address
Size
Contents
4015H-401CH
8 bytes
Keyboard Device Control Block
Its driver address 4016H-4017H is taken over at activation and put back by the purge; 57DEH passes 4015H to the keyboard routine in Index Register IX.
4025H-402CH
8 bytes
Printer Device Control Block
Its driver address 4026H-4027H is taken over and put back; 579BH passes 4025H to the old driver.
4041H-4043H
3 bytes
Clock
Seconds, minutes and hours, read for the print delay (566DH, 5769H).
4049H-404AH
2 bytes
HIMEM
Lowered by 06FAH at activation (5D9CH), raised again by the purge if unchanged (5723H).
4121H-4122H
2 bytes
ROM Accumulator
The integer result of FIN, read at 5A51H.
4369H
1 byte
System Flags
Bit 6, an overlay function is running: no disk I/O (568FH) and no spooling (551DH).
37E8H
1 byte
Printer Port
Status read and character written for the parallel printer (57AAH).
Ports E8H-EBHRS-232 Board
E8H reset (written) and status (read, H14), E9H switches (read) and baud rate (written), EAH UART control (written) and status (read), EBH data.

Outside Routines Called

AddressContents
0040HROM KEYIN: line input (54E0H, 59D6H, 5A37H, 5A45H).
03E3HROM keyboard driver (57E2H as loaded).
0E6CHROM FIN: ASCII to number (5A4EH).
402DHSYS0: DOS READY.
4409HSYS0: DOS error exit.
4410H / 4413HSYS0: enqueue / dequeue a timer routine (5DB6H / 5703H).
4419HSYS0: DOS-CALL (59EBH).
4420H / 4424H / 4428HSYS0: open new or existing / open existing / close.
4436H / 443CH / 444BHSYS0: read / write with verify / allocate.
4461H / 4464HSYS0: put a *name routine on SYS9's list / take it off (5D94H / 572AH).
4467HSYS0: display a message ended by 03H or 0DH.

Disassembly

5450H - The *name Block

ASPOOL/MAS loads at 5450H-5DD0H (ten load records, transfer address 5C4BH). 5450H-58F9H is the resident spooler: when it is activated, 5CB2H copies this part to the top of memory and 5D94H puts the copy's first 12 bytes on SYS9's list of *name routines (head at 4051H) through 4461H. The block is SYS9's format: a check word, a link to the next block, an 8-character name, then the code at +12. With ASP on the list, a DOS command line starting with *ASP makes SYS1 call SYS9, which finds the block by its name and jumps to its code at +12 (545CH) with Register Pair HL pointing past the name and its comma.

5450-5451
DEFW 0000H 00 00
Block+0 and +1, the check word. 0000H in the file; SYS9's enqueue (4461H, code 2BH) stores the address of block+2 here, and every later search through the list checks it before it trusts the block.
5452-5453
DEFW 0000H 00 00
Block+2 and +3, the link to the next block on the *name list. 0000H in the file; SYS9's enqueue stores the old list head from 4051H here when this block is put at the front of the list.
5454-545B
DEFM "ASP " 41 53 50 20 20 20 20 20
Block+4 to +11, the name: ASP padded with five spaces to 8 characters. SYS9 compares the name typed after the asterisk, padded the same way, against these 8 bytes.

545CH - *ASP Command: Pick the Option

Block+12, the code SYS9 runs for a *ASP command (DOS command line, or CMD"*ASP..." from BASIC). Register Pair HL points to the command line just past the name and the comma or spaces after it, so it is at the option letter, or at the 0DH that ends the line when *ASP is typed alone. The return address on the stack is 4408H in SYS0, pushed by SYS1 above 402DH (DOS READY). *ASP alone shows the status; *ASP,P purges the spooler, *ASP,S stops it, *ASP,C clears the backlog or the file being printed, *ASP,W ends the file being spooled.

545C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (the command line just past *ASP and its separator): the option letter, or 0DH when nothing follows the name.
545D
CP 0DH FE 0D
Compare Register A (the first character after the name) against 0DH, the carriage return that ends the command line. The Z FLAG is set if no option was given.
545F
If the Z FLAG is set (Register A = 0DH: *ASP alone), JUMP to 5486H to display the spooler's status.
5461
GOSUB to 547DH with Register Pair HL at the option letter: the letter must be the last character on the line. It returns with Register A = the letter and Register Pair HL still pointing at it.
5464
CP 50H FE 50
Compare Register A (the option letter) against 50H, ASCII P. The Z FLAG is set for *ASP,P.
5466
If the Z FLAG is set (Register A = P), JUMP to 56F6H to purge the spooler: drivers and memory back, the *name block and the timer routine taken off their lists.
5469
CP 53H FE 53
Compare Register A (the option letter) against 53H, ASCII S. The Z FLAG is set for *ASP,S.
546B
If the Z FLAG is set (Register A = S), JUMP to 5505H to stop the spooler: no new spooling, but the files already queued are still printed.
546E
CP 43H FE 43
Compare Register A (the option letter) against 43H, ASCII C. The Z FLAG is set for *ASP,C.
5470
If the Z FLAG is set (Register A = C), JUMP to 54D5H to ask CLEAR BACKLOG OR PRINT (B/P)? and drop the files waiting or the file being printed.
5473
CP 57H FE 57
Compare Register A (the option letter) against 57H, ASCII W. The Z FLAG is set for *ASP,W.
5475
If the Z FLAG is set (Register A = W), JUMP to 5501H to end the file being spooled and queue it for printing, as a 03H byte in the printer output does.
5478
LD A,2FH 3E 2F
Any other letter, or a letter that is not the last character on the line (from 5481H), or an option other than I or A when the program is run (from 5C55H): load Register A with 2FH, error code BAD PARAMETER(S).
547A
JUMP to SYS0 4409H, the DOS error exit, with Register A = 2FH and bit 7 clear: the error message is displayed and the command ends at DOS READY.

547DH - The Option Letter Must End the Line

Called from 5461H (the *ASP command) and from 5C4BH (the program run with filespec,I or filespec,A) with Register Pair HL at the option letter. The letter must be followed directly by the 0DH that ends the command line, otherwise BAD PARAMETER(S). When nothing was typed after the name, Register Pair HL is on that 0DH, and the test reads the byte after it in the command buffer.

547D
INC HL 23
Increment Register Pair HL (the command line pointer) from the option letter to the character after it.
547E
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the character after the option letter.
547F
CP 0DH FE 0D
Compare Register A (the character after the letter) against 0DH, the carriage return that ends the command line.
5481
If the NZ FLAG is set (more text follows the letter), JUMP to 5478H for error 2FH, BAD PARAMETER(S).
5483
DEC HL 2B
Decrement Register Pair HL (the command line pointer) back to the option letter.
5484
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the option letter itself.
5485
RET C9
RETURN to the caller with Register A = the option letter and Register Pair HL pointing at it.

5486H - *ASP Alone: Display the Status

Displays SPOOL STATUS, then either SPOOL STOPPING (after *ASP,S or a 04H byte) or the file being spooled, then the file being printed and every file waiting in the queue (BACK LOG). Each file is shown as POOLn:d, where n is its number 1-5 and d the spool drive chosen at setup. The queue is the five bytes at 5828H-582CH (one per pool file, FFH after them): 00H = free or being spooled, 01H = the file being printed or the next one to print, 02H-05H = its place in the queue.

5486
LD HL,5830H 21 30 58
Load Register Pair HL with 5830H, the message SPOOL STATUS ended by 0DH.
5489
GOSUB to SYS0 4467H to display the message at Register Pair HL (5830H): SPOOL STATUS and a new line.
548C
LD A,(56F1H) 3A F1 56
Load Register A with the byte at 56F1H, the operand of the LD A,nn at 56F0H: 00H while the spooler runs normally, C9H after 5639H has stopped it (*ASP,S or a 04H byte).
548F
OR A B7
OR Register A (the stop flag from 56F1H) with itself to set the flags. The Z FLAG is set if the spooler has not been stopped.
5490
If the Z FLAG is set (Register A = 00H: not stopped), JUMP to 549AH to show the file being spooled.
5492
LD HL,587CH 21 7C 58
The spooler has been stopped: load Register Pair HL with 587CH, the message SPOOL STOPPING ended by 0DH.
5495
GOSUB to SYS0 4467H to display the message at Register Pair HL (587CH): SPOOL STOPPING and a new line.
5498
JUMP to 54A3H to show the file being printed; nothing is being spooled any more.
549A
LD A,(5534H) 3A 34 55
Load Register A with the byte at 5534H, the operand of the LD A,nn at 5533H: the number (1-5) of the pool file being spooled now, or 00H if none is open.
549D
LD HL,5848H 21 48 58
Load Register Pair HL with 5848H, the message SPOOLING: ended by 03H (no new line, POOLn:d follows).
54A0
GOSUB to 54C5H with Register A = the spooling file's number and Register Pair HL = 5848H: shows SPOOLING: POOLn:d, or nothing when Register A is 00H.
54A3
LD A,(5766H) 3A 66 57
Load Register A with the byte at 5766H, the operand of the LD A,nn at 5765H: the number (1-5) of the pool file being printed, or 00H if none.
54A6
LD HL,583DH 21 3D 58
Load Register Pair HL with 583DH, the message PRINTING: ended by 03H.
54A9
GOSUB to 54C5H with Register A = the printing file's number and Register Pair HL = 583DH: shows PRINTING: POOLn:d, or nothing when Register A is 00H.
54AC
LD HL,5828H 21 28 58
Load Register Pair HL with 5828H, the first of the five queue bytes (pool file 1).
54AF
LD C,01H 0E 01
Load Register C with 01H, the number of the pool file whose queue byte Register Pair HL points at.

Loop Start
Walk the queue bytes 5828H-582CH up to the FFH after them; every file whose byte is 02H or more is waiting and is shown as BACK LOG: POOLn:d.

54B1
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the queue byte of pool file Register C (00H free, 01H printing, 02H-05H waiting, FFH the end of the table).
54B2
INC A 3C
Increment Register A (the queue byte): FFH becomes 00H and sets the Z FLAG; 00H becomes 01H, 01H becomes 02H, a waiting file gives 03H-06H.
54B3
INC HL 23
Increment Register Pair HL to the next queue byte. INC HL does not change the flags.
54B4
If the Z FLAG is set (the byte was FFH, the end of the table), JUMP to SYS0 402DH: the status display is complete and the command ends at DOS READY.
54B7
CP 03H FE 03
Compare Register A (the queue byte + 1) against 03H. The NO CARRY FLAG is set if the byte was 02H or more: a file waiting in the queue.
54B9
PUSH HL E5
Save Register Pair HL (the pointer to the next queue byte) on the stack.
54BA
LD A,C 79
Load Register A with Register C, the number of the pool file just looked at. LD does not change the flags.
54BB
LD HL,5853H 21 53 58
Load Register Pair HL with 5853H, the message BACK LOG: ended by 03H.
54BE
INC C 0C
Increment Register C to the number of the next pool file. INC C does not change the CARRY FLAG.
54BF
If the NO CARRY FLAG is set (a waiting file), GOSUB to 54C7H with Register A = its number and Register Pair HL = 5853H to show BACK LOG: POOLn:d.
54C2
POP HL E1
Restore Register Pair HL from the stack: the pointer to the next queue byte.
54C3
LOOP back to 54B1H to look at the next queue byte, the one Register Pair HL now points at.

Loop End

54C5H - Display a Message and a Pool File Name

Called with Register A = a pool file number and Register Pair HL = a message ended by 03H. 54C5H shows nothing when Register A is 00H; 54C7H always shows the message followed by POOLn:d and a new line. The digit n goes into the name template at 581EH (POOL1:1 and 0DH), whose drive digit at 5824H was set at setup.

54C5
OR A B7
OR Register A (the pool file number) with itself to set the flags. The Z FLAG is set if it is 00H (no file).
54C6
RET Z C8
If the Z FLAG is set (Register A = 00H), RETURN without displaying anything.
54C7
ADD A,30H C6 30
Add 30H to Register A (the pool file number 1-5), turning it into the ASCII digit 1-5. Entry from 54BFH for a BACK LOG line.
54C9
LD (5822H),A 32 22 58
Store Register A (the ASCII digit) at 5822H, the file number position in the name template POOLn:d at 581EH.
54CC
GOSUB to SYS0 4467H to display the message at Register Pair HL (PRINTING:, SPOOLING: or BACK LOG:), which ends with 03H and so stays on the line.
54CF
LD HL,581EH 21 1E 58
Load Register Pair HL with 581EH, the name template: POOL, the file digit at 5822H, a colon, the drive digit at 5824H and 0DH.
54D2
JUMP to SYS0 4467H to display the name at Register Pair HL (581EH) and a new line; its RET returns to the caller of 54C5H or 54C7H.

54D5H - *ASP,C: Clear the Backlog or the File Being Printed

Asks CLEAR BACKLOG OR PRINT (B/P)? and repeats the question until the answer starts with B or P. P stores 50H in the operand at 56C5H: when the next sector of the file being printed has been read, 56C4H sees it, and the file is emptied and closed without printing the rest. B frees every file that is waiting (queue byte 02H or more) and then falls into the W code at 5501H, so the file being spooled is ended and queued too. The freed files keep their data on the diskette; the next spool file with that number is written over them.

54D5
LD HL,585EH 21 5E 58
Load Register Pair HL with 585EH, the question CLEAR BACKLOG OR PRINT (B/P)? ended by 03H. 54EAH comes back here for any other answer.
54D8
GOSUB to SYS0 4467H to display the question at Register Pair HL (585EH); it ends with 03H, so the cursor stays after it.
54DB
LD B,01H 06 01
Load Register B with 01H, the most characters the line input may take.
54DD
LD HL,5826H 21 26 58
Load Register Pair HL with 5826H, the buffer for the answer: one character at 5826H, then the 0DH the ROM stores after it at 5827H.
54E0
GOSUB to the ROM line input at 0040H (KEYIN) with Register Pair HL = 5826H and Register B = 01H. It returns with Register Pair HL = 5826H, Register B = the number of characters typed, and the text ended by 0DH.
54E3
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (5826H), the first character of the answer (0DH if only ENTER was pressed).
54E4
CP 42H FE 42
Compare Register A (the answer) against 42H, ASCII B (clear the backlog).
54E6
If the Z FLAG is set (Register A = B), JUMP to 54F2H to free the waiting files.
54E8
CP 50H FE 50
Compare Register A (the answer) against 50H, ASCII P (stop printing the current file).
54EA
If the NZ FLAG is set (neither B nor P), JUMP back to 54D5H to ask again.
54EC
LD (56C5H),A 32 C5 56
Store Register A (50H, P) at 56C5H, the operand of the LD A,nn at 56C4H: after its next sector read, the file being printed is emptied and closed (56CAH). The flag is cleared again at 56D1H.
54EF
JUMP to SYS0 402DH: the command ends at DOS READY.
54F2
LD HL,5828H 21 28 58
Answer B: load Register Pair HL with 5828H, the first of the five queue bytes.

Loop Start
Every queue byte from 02H to FEH (a waiting file) becomes 00H (free); 00H, 01H and the FFH end mark are kept.

54F5
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a queue byte (00H free, 01H printing, 02H-05H waiting, FFH the end).
54F6
SUB 02H D6 02
Subtract 02H from Register A: 00H, 01H and FFH become FEH, FFH and FDH; a waiting file's 02H-05H becomes 00H-03H.
54F8
CP FDH FE FD
Compare Register A (the queue byte minus 2) against FDH. The NO CARRY FLAG is set for FDH-FFH (free, printing or the end mark); the Z FLAG only for FDH, the end mark.
54FA
If the NO CARRY FLAG is set (the byte is not a waiting file), JUMP to 54FEH and leave it as it is.
54FC
LD (HL),00H 36 00
Store 00H at Register Pair HL (the queue byte of a waiting file): the file is free again and will not be printed.
54FE
INC HL 23
Increment Register Pair HL to the next queue byte. INC HL does not change the flags.
54FF
If the NZ FLAG is set (from the CP at 54F8H: not the FFH end mark), LOOP back to 54F5H.

Loop End
Fall into 5501H: the W code ends the file being spooled and queues it.

5501H - *ASP,W and *ASP,S

W ends the file being spooled and queues it for printing, as a 03H byte in the printer output does; S stops the spooler, as a 04H byte does. Both put the code in Register C as if it were a character sent to the printer and go through the printer driver entry 550BH, with 402DH (DOS READY) as the final return address. After the spooler has been stopped 550BH is a RET, so a later W or S goes straight to DOS READY.

5501
LD C,03H 0E 03
Load Register C with 03H, the code that ends the current spool file (also reached by falling out of the B answer at 54FFH).
5503
JUMP to 5507H to pass Register C (03H) through the printer driver.
5505
LD C,04H 0E 04
Load Register C with 04H, the code that stops the spooler (*ASP,S).
5507
LD HL,402DH 21 2D 40
Load Register Pair HL with 402DH, SYS0's DOS READY exit, to be the return address.
550A
PUSH HL E5
Save Register Pair HL (402DH) on the stack: the RET at 5517H (or the RET at 550BH once the spooler is stopped) goes to DOS READY.

550BH - Printer Driver: Spool One Character

5D9FH stores the relocated address of 550BH into 4026H-4027H, the driver address of the printer device control block at 4025H, so every character sent to the printer comes here with the character in Register C. 550BH first does the spooler's background work (567DH: print from the buffer, read the next sector, start the next file), then spools the character (5518H), and returns with Register Pairs BC, DE and HL as they were. The stop code (5634H) turns the PUSH HL at 550BH into a RET, after which printer output is ignored.

550B
PUSH HL E5
Self-Modifying Code
Save Register Pair HL on the stack: the caller's HL, or 402DH from 5507H. 5636H stores C9H (RET) over this byte when the spooler is stopped, so the driver then returns at once and the character in Register C is dropped.
550C
PUSH DE D5
Save Register Pair DE (the caller's DE; the ROM's driver call sets it to the device control block 4025H) on the stack.
550D
PUSH BC C5
Save Register Pair BC (Register C = the character to spool) on the stack.
550E
GOSUB to 567DH, the background work: print what is in the print buffer, read the next sector of the file being printed, or start printing the next queued file.
5511
GOSUB to 5518H to put the character in Register C into the spool file (Register C was restored by 567DH).
5514
POP BC C1
Restore Register Pair BC from the stack (Register C = the character). 567DH and 5518H also leave through here.
5515
POP DE D1
Restore Register Pair DE from the stack, the caller's DE. 5735H comes here after 572DH has already taken Register Pair BC.
5516
POP HL E1
Restore Register Pair HL from the stack, the caller's HL.
5517
RET C9
RETURN to the caller (the ROM's driver call, or 402DH for *ASP,W and *ASP,S) with Register Pairs BC, DE and HL as they were and Register A as the spooling code left it.

5518H - Spool a Character: Refuse Output From the DOS

Called from 5511H with Register C = the character. While an overlay function is running (4369H bit 6, set by the SYS0 RST 28H dispatcher), the character comes from the DOS itself (a DIR listing with P, J-K-L, PRINT) and the spooler must not do disk I/O in the middle of it: the character is dropped and CAN'T SPOOL FROM DOS is shown, but only for the first character of each run of such output. The operand at 5519H keeps the state of bit 6 for the previous character.

5518
LD E,00H 1E 00
Self-Modifying Code
Load Register E with the operand at 5519H: 40H if the previous character sent to the spooler came while an overlay function was running, 00H otherwise. 551FH stores it for every character; 00H in the file.
551A
LD A,(4369H) 3A 69 43
Load Register A with the byte at 4369H, SYS0's system flags (bit 6 = an overlay function is running, set and cleared by the RST 28H dispatcher at 4BC2H).
551D
AND 40H E6 40
AND Register A (the flags from 4369H) with 40H, keeping bit 6. The Z FLAG is set if no overlay function is running.
551F
LD (5519H),A 32 19 55
Store Register A (40H or 00H, bit 6 of 4369H) at 5519H, the operand of the LD E,nn at 5518H, for the next character. LD does not change the flags.
5522
If the Z FLAG is set (no overlay function running: the output comes from a program), JUMP to 552DH to spool the character.
5524
LD A,E 7B
The output comes from the DOS: load Register A with Register E, the state saved for the previous character.
5525
OR A B7
OR Register A (the previous state) with itself to set the flags. The NZ FLAG is set if the previous character also came from the DOS.
5526
RET NZ C0
If the NZ FLAG is set (the warning has been shown already for this run of DOS output), RETURN to 5514H and drop the character.
5527
LD HL,58E5H 21 E5 58
Load Register Pair HL with 58E5H, the message CAN'T SPOOL FROM DOS ended by 0DH.
552A
JUMP to SYS0 4467H to display the message at Register Pair HL (58E5H); its RET returns to 5514H and the character is dropped.

552DH - Spool a Character: Codes 04H, 0DH, 0CH and 03H

Register C is the character. 04H stops the spooler (5634H). Any other character first makes sure a spool file is open (55F7H when the operand at 5534H is 00H). 0DH is written and counted on the page; 0CH becomes a form feed (555BH); 03H ends the spool file (55B9H); anything else goes to 557EH. The line count is the byte at 582EH.

552D
LD A,C 79
Load Register A with Register C, the character to spool.
552E
CP 04H FE 04
Compare Register A (the character) against 04H, the code that stops the spooler (sent as LPRINT CHR$(4) or by *ASP,S).
5530
If the Z FLAG is set (Register A = 04H), JUMP to 5634H to stop the spooler.
5533
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand at 5534H: the number (1-5) of the pool file being spooled, or 00H when no spool file is open. 560CH stores the number when a file is opened, 55EBH stores 00H when it is closed; 00H in the file.
5535
OR A B7
OR Register A (the spool file number) with itself to set the flags. The Z FLAG is set if no spool file is open.
5536
If the Z FLAG is set (no spool file open), GOSUB to 55F7H to open the next free pool file (waiting for one if all five are in use). Register C is kept.
5539
LD HL,582EH 21 2E 58
Load Register Pair HL with 582EH, the line count of the current page.
553C
LD A,C 79
Load Register A with Register C, the character to spool.
553D
CP 0DH FE 0D
Compare Register A (the character) against 0DH, carriage return: the end of a line.
553F
If the NZ FLAG is set (not a carriage return), JUMP to 5557H to test for the other codes.
5541
GOSUB to 557EH to write Register A (0DH) into the spool file; Register Pair HL (582EH) is kept.
5544
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (582EH), the line count of the page.
5545
INC A 3C
Increment Register A (the line count): one more line is on the page.

Loop Start
With the soft form feed, the line count is brought below the total lines per page by subtracting that total until it fits.

5546
LD (HL),A 77
Store Register A (the new line count) at Register Pair HL (582EH).
5547
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand at 5548H, the form feed kind: 00H hard (a 0CH byte, also in the file), 01H soft (carriage returns to the end of the page). Setup stores it at 594CH and 5950H.
5549
OR A B7
OR Register A (the form feed kind) with itself to set the flags. The Z FLAG is set for the hard form feed.
554A
If the Z FLAG is set (hard form feed: no page length is kept), JUMP to 5551H.
554C
LD A,(HL) 7E
Soft form feed: load Register A with the byte at Register Pair HL (582EH), the line count.
554D
SUB 00H D6 00
Self-Modifying Code
Subtract the operand at 554EH from Register A (the line count): the total lines per page, stored by setup at 5957H (00H in the file). The NO CARRY FLAG is set if the count has reached the total.
554F
If the NO CARRY FLAG is set (the count reached the page length), LOOP back to 5546H to store the reduced count in Register A.

Loop End

5551
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (582EH), the line count of the page.
5552
CP FFH FE FF
Self-Modifying Code
Compare Register A (the line count) against the operand at 5553H, the print lines per page stored by setup at 593DH (FFH in the file). The CARRY FLAG is set while the page has room.
5554
RET C D8
Self-Modifying Code
If the CARRY FLAG is set (the page is not full), RETURN. Setup stores D8H (RET C) here when the output is formed into pages and C9H (RET, always return) when it is not (592EH, 5935H); D8H in the file.
5555
The page is full: JUMP to 555BH to do a form feed.
5557
CP 0CH FE 0C
Compare Register A (the character) against 0CH, form feed.
5559
If the NZ FLAG is set (not a form feed), JUMP to 557AH to test for 03H.

555BH - Form Feed

Called from 5555H (page full), from 5559H (a 0CH byte) and through the CALL NZ at 55BBH (top of form at the end of a file) with Register Pair HL = 582EH, the line count. Hard: a 0CH byte is written and the count set to 0. Soft: carriage returns are written until the count reaches the total lines per page, then the count is set to 0.

555B
LD A,(5548H) 3A 48 55
Load Register A with the byte at 5548H, the operand of the LD A,nn at 5547H: the form feed kind, 00H hard or 01H soft. 556EH comes back here.
555E
OR A B7
OR Register A (the form feed kind) with itself to set the flags. The NZ FLAG is set for the soft form feed.
555F
If the NZ FLAG is set (soft form feed), JUMP to 5566H to write carriage returns.
5561
LD (HL),A 77
Hard form feed: store Register A (00H) at Register Pair HL (582EH): the new page has no lines yet.
5562
LD A,0CH 3E 0C
Load Register A with 0CH, the form feed character. LD does not change the flags.
5564
If the Z FLAG is set (always, from the OR at 555EH), JUMP to 557EH to write Register A (0CH) into the spool file; its RET returns to this routine's caller.
5566
LD A,(554EH) 3A 4E 55
Soft form feed: load Register A with the byte at 554EH, the operand of the SUB at 554DH: the total lines per page.
5569
SUB (HL) 96
Subtract the byte at Register Pair HL (582EH, the line count) from Register A (the total lines): the lines left on the page.
556A
LD B,A 47
Load Register B with Register A, the number of carriage returns needed to reach the end of the page.
556B
NEG ED 44
Negate Register A (the lines left): Register A = the line count minus the total, negative while the page still has lines left.
556D
LD (HL),A 77
Store Register A (the count minus the total) at Register Pair HL (582EH). LD does not change the flags.
556E
If the P FLAG is set (Register A not negative: the count had reached the total), JUMP back to 555BH with the reduced count.

Loop Start
Write Register B carriage returns.

5571
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return to write as one line of the rest of the page.
5573
GOSUB to 557EH to write Register A (0DH) into the spool file. The count at 582EH is not changed by it.
5576
Decrement Register B (the carriage returns still to write); if it is not 0, LOOP back to 5571H.

Loop End

5578
LD (HL),B 70
Store Register B (00H) at Register Pair HL (582EH): the new page has no lines yet.
5579
RET C9
RETURN to the caller with the page count at 582EH reset to 0.
557A
CP 03H FE 03
Compare Register A (the character) against 03H, the end of a spool file (sent as LPRINT CHR$(3) or by *ASP,W).
557C
If the Z FLAG is set (Register A = 03H), JUMP to 55B9H to end the spool file and queue it for printing. Any other character falls into 557EH.

557EH - Write a Byte Into the Spool File

Register A is the byte. 582FH remembers whether the current line has a printable character: before a carriage return on an empty line a space is written first. The byte goes into the spool sector buffer 5300H-53FFH at the pointer kept in the operand at 5599H; when the buffer is full it is written to the spool file with verify (443CH) and the next sector is allocated (55F0H). Register Pair HL is kept; Register Pair DE is changed when a sector is written.

557E
PUSH HL E5
Save Register Pair HL (582EH, or the caller's HL) on the stack.
557F
LD HL,582FH 21 2F 58
Load Register Pair HL with 582FH, the line flag: 01H if the current line has a printable character, 00H if not.
5582
CP 0DH FE 0D
Compare Register A (the byte to write) against 0DH, carriage return.
5584
If the NZ FLAG is set (not a carriage return), JUMP to 5590H.
5586
DEC (HL) 35
Decrement the line flag at Register Pair HL (582FH): 01H becomes 00H with the Z FLAG set; 00H (an empty line) becomes FFH with the NZ FLAG.
5587
LD A,20H 3E 20
Load Register A with 20H, a space. LD does not change the flags.
5589
If the NZ FLAG is set (the line was empty), GOSUB to 5597H to write Register A (a space) first.
558C
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return to write.
558E
LD (HL),00H 36 00
Store 00H at Register Pair HL (582FH): the next line has no printable character yet.
5590
CP 20H FE 20
Compare Register A (the byte to write) against 20H. The CARRY FLAG is set for a control character below a space.
5592
If the CARRY FLAG is set (a control character), JUMP to 5596H and leave the line flag as it is.
5594
LD (HL),01H 36 01
Store 01H at Register Pair HL (582FH): the line now has a printable character.
5596
POP HL E1
Restore Register Pair HL from the stack, the caller's HL.
5597
PUSH HL E5
Save Register Pair HL (the caller's HL) on the stack. 5589H calls here to write the space.
5598
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the operand at 5599H, the spool buffer pointer: the next free byte of 5300H-53FFH. 5618H sets it to 5300H when a file is opened, 55B4H stores it after every byte; 0000H in the file.
559B
LD (HL),A 77
Store Register A (the byte) at Register Pair HL, the next free byte of the spool buffer.
559C
INC HL 23
Increment Register Pair HL (the spool buffer pointer) to the following byte.
559D
LD DE,5300H 11 00 53
Load Register Pair DE with 5300H, the start of the spool buffer (Register E = 00H for the test).
55A0
LD A,L 7D
Load Register A with Register L, the low byte of the spool buffer pointer.
55A1
CP E BB
Compare Register A (the pointer's low byte) against Register E (00H). The Z FLAG is set when the pointer has reached 5400H: the buffer is full.
55A2
If the NZ FLAG is set (the buffer has room), JUMP to 55B4H to store the pointer.
55A4
PUSH DE D5
Save Register Pair DE (5300H, the new buffer pointer) on the stack.
55A5
LD DE,5420H 11 20 54
Load Register Pair DE with 5420H, the spool file's FCB (its buffer is 5300H).
55A8
GOSUB to SYS0 443CH to write the 256 bytes at 5300H as the next sector of the spool file, with verify. Register A returns the error code, the NZ FLAG if it failed.
55AB
LD HL,58C3H 21 C3 58
Load Register Pair HL with 58C3H, the message CAN'T WRITE TO ended by 03H. LD does not change the flags.
55AE
If the NZ FLAG is set (the write failed, Register A = the error code), JUMP to 5626H to report it and stop the spooler.
55B0
GOSUB to 55F0H with Register Pair DE = 5420H to allocate the next sector of the spool file (or start a new file when the diskette is full).
55B3
POP HL E1
Restore Register Pair HL from the stack: 5300H, the start of the empty buffer.
55B4
LD (5599H),HL 22 99 55
Store Register Pair HL (the new spool buffer pointer) at 5599H, the operand of the LD HL,nnnn at 5598H.
55B7
POP HL E1
Restore Register Pair HL from the stack, the caller's HL.
55B8
RET C9
RETURN to the caller with Register A = the byte written or the last byte the code loaded.

55B9H - End the Spool File (03H)

Reached from 557CH with Register Pair HL = 582EH, the line count. If the page has lines on it and top of form at the end of a file was chosen, a form feed is written first. A part-filled buffer is ended with a 03H byte (the print side stops at it, 5784H) and written; then the file is closed and queued.

55B9
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (582EH), the line count of the page.
55BA
OR A B7
OR Register A (the line count) with itself to set the flags. The NZ FLAG is set if the page has lines on it.
55BB
Self-Modifying Code
If the NZ FLAG is set, GOSUB to 555BH for a form feed. Setup stores C4H (CALL NZ) here for top of form at the end of a file, or 11H, which makes the three bytes LD DE,555BH and does nothing useful (5963H, 5967H); C4H in the file.
55BE
LD HL,(5599H) 2A 99 55
Load Register Pair HL with the 16-bit value at 5599H, the operand of the LD HL,nnnn at 5598H: the spool buffer pointer.
55C1
LD DE,5300H 11 00 53
Load Register Pair DE with 5300H, the start of the spool buffer (Register E = 00H for the test).
55C4
LD A,L 7D
Load Register A with Register L, the low byte of the spool buffer pointer.
55C5
CP E BB
Compare Register A (the pointer's low byte) against Register E (00H). The Z FLAG is set if the buffer is empty.
55C6
If the Z FLAG is set (nothing in the buffer), JUMP to 55D0H to close the file.
55C8
LD (HL),03H 36 03
Store 03H at Register Pair HL, the byte after the last one spooled: the end mark the print side looks for.
55CA
LD DE,5420H 11 20 54
Load Register Pair DE with 5420H, the spool file's FCB.
55CD
GOSUB to SYS0 443CH to write the buffer at 5300H as the last sector of the spool file, with verify. An error here is not tested.

55D0H - Close the Spool File and Queue It

Called from 55F4H (diskette full) and reached from 55C6H/55CDH. The file is closed, then counted into the print queue: its queue byte becomes one more than the number of files already queued, so it is printed after them. 5534H is set to 00H: no spool file is open. Register Pair DE is left at 5420H.

55D0
LD DE,5420H 11 20 54
Load Register Pair DE with 5420H, the spool file's FCB.
55D3
GOSUB to SYS0 4428H to close the file whose FCB is at Register Pair DE (5420H): its directory entry gets the EOF.
55D6
LD HL,5827H 21 27 58
Load Register Pair HL with 5827H, the byte before the five queue bytes.
55D9
LD E,00H 1E 00
Load Register E with 00H, the count of queued files.
55DB
PUSH HL E5
Save Register Pair HL (5827H, the byte before the queue) on the stack for 55ECH.

Loop Start
Count the queue bytes that are not 00H, the FFH end mark included: Register E = the files already queued + 1.

55DC
INC HL 23
Increment Register Pair HL to the next queue byte.
55DD
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a queue byte (00H free, 01H-05H queued, FFH the end).
55DE
OR A B7
OR Register A (the queue byte) with itself to set the flags. The Z FLAG is set for a free entry.
55DF
If the Z FLAG is set (a free entry), LOOP back to 55DCH without counting it.
55E1
INC E 1C
Increment Register E, the count of queue bytes that are not 00H.
55E2
INC A 3C
Increment Register A (the queue byte): FFH, the end mark, becomes 00H and sets the Z FLAG.
55E3
If the NZ FLAG is set (not the end mark), LOOP back to 55DCH.

Loop End

55E5
LD D,A 57
Load Register D with Register A (00H), the high byte for the 16-bit add below.
55E6
LD A,E 7B
Load Register A with Register E: the queued files + 1, this file's place in the queue.
55E7
LD HL,5534H 21 34 55
Load Register Pair HL with 5534H, the operand of the LD A,nn at 5533H: the number of the spool file being closed.
55EA
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL (5534H), the spool file's number 1-5. Register Pair DE = 00nnH.
55EB
LD (HL),D 72
Store Register D (00H) at Register Pair HL (5534H): no spool file is open now.
55EC
POP HL E1
Restore Register Pair HL from the stack: 5827H.
55ED
ADD HL,DE 19
Add Register Pair DE (the file number) to Register Pair HL (5827H): Register Pair HL = the file's queue byte (5828H for POOL1).
55EE
LD (HL),A 77
Store Register A (its place in the queue) at Register Pair HL, the file's queue byte.
55EF
RET C9
RETURN to the caller with the closed file queued; Register D = 00H and Register E = the file number.

55F0H - Allocate the Next Sector of the Spool File

Called after every sector written (55B0H) and right after a spool file is opened (5621H), with Register Pair DE = 5420H. 444BH makes sure the sector at the FCB's NEXT exists, taking a granule when needed. If it cannot (the diskette is full), the file is closed and queued, and a new spool file is opened, so the output goes on in the next pool file.

55F0
GOSUB to SYS0 444BH to allocate the spool file's space up to the sector at NEXT in the FCB at Register Pair DE (5420H). The Z FLAG returns set if it worked.
55F3
RET Z C8
If the Z FLAG is set (the sector is there), RETURN to the caller.
55F4
The diskette is full: GOSUB to 55D0H to close this spool file and queue it for printing. Then fall into 55F7H to open the next one.

55F7H - Open a New Spool File

Called from 5536H with Register C = the character to spool, and reached from 55F4H. The first free pool file (queue byte 00H) is taken; if all five are queued, SPOOL FULL. WAITING ON PRINTER is shown and the spooler does its background work (567DH) until printing frees one. The file POOLn:d is opened in the FCB 5420H with buffer 5300H, created if needed, and its first sector allocated.

55F7
PUSH BC C5
Save Register Pair BC (Register C = the character to spool) on the stack.
55F8
GOSUB to 5642H to look for a free pool file: the Z FLAG with Register C = its number, or the NZ FLAG if all five are queued.
55FB
If the Z FLAG is set (a free pool file was found), JUMP to 560BH.
55FD
LD HL,5898H 21 98 58
Load Register Pair HL with 5898H, the message SPOOL FULL. WAITING ON PRINTER ended by 0DH.
5600
GOSUB to SYS0 4467H to display the message at Register Pair HL (5898H).

Loop Start
Do the background work until a pool file has been printed and freed.

5603
GOSUB to 567DH: print from the buffer, read the next sector, finish a printed file. Register Pairs BC, DE and HL are kept.
5606
GOSUB to 5642H to look for a free pool file: the Z FLAG with Register C = its number.
5609
If the NZ FLAG is set (still none free), LOOP back to 5603H.

Loop End

560B
LD A,C 79
Load Register A with Register C, the number (1-5) of the free pool file.
560C
LD (5534H),A 32 34 55
Store Register A (the file number) at 5534H, the operand of the LD A,nn at 5533H: this is now the spool file.
560F
LD DE,5420H 11 20 54
Load Register Pair DE with 5420H, the spool file's FCB.
5612
GOSUB to 5651H with Register A = the file number and Register Pair DE = 5420H: the name POOLn:d and 0DH are copied into the FCB.
5615
LD HL,5300H 21 00 53
Load Register Pair HL with 5300H, the spool sector buffer.
5618
LD (5599H),HL 22 99 55
Store Register Pair HL (5300H) at 5599H, the operand of the LD HL,nnnn at 5598H: the buffer is empty.
561B
LD B,00H 06 00
Load Register B with 00H, the logical record length (256) for the open.
561D
GOSUB to SYS0 4420H to open the file named in the FCB at Register Pair DE (5420H), creating it if it does not exist, with Register Pair HL = 5300H as its buffer and Register B = 00H. The Z FLAG returns set if it worked; Register A = the error code otherwise.
5620
POP BC C1
Restore Register Pair BC from the stack (Register C = the character to spool). POP does not change the flags.
5621
If the Z FLAG is set (the file is open), JUMP to 55F0H to allocate its first sector; the RET there returns to the caller of 55F7H.
5623
LD HL,58B8H 21 B8 58
The open failed: load Register Pair HL with 58B8H, the message CAN'T OPEN ended by 03H. Register A still holds the error code.

5626H - Spool File Error: Report and Stop

Reached from 5623H (the open failed) and 55AEH (a sector write failed) with Register A = the DOS error code and Register Pair HL = CAN'T OPEN or CAN'T WRITE TO. The DOS error message is shown, then the message and SPOOL OUTPUT FILE, and the spooler is stopped (5634H).

5626
OR C0H F6 C0
OR Register A (the DOS error code) with C0H: bit 7 set makes 4409H display the message and return here; NEWDOS/80 ignores bit 6.
5628
GOSUB to SYS0 4409H with Register A = the error code OR C0H: the DOS error message is displayed and 4409H returns.
562B
GOSUB to SYS0 4467H to display the message at Register Pair HL (CAN'T OPEN or CAN'T WRITE TO), which ends with 03H and so stays on the line.
562E
LD HL,58D2H 21 D2 58
Load Register Pair HL with 58D2H, the message SPOOL OUTPUT FILE (with a leading space) ended by 0DH.
5631
GOSUB to SYS0 4467H to display the message at Register Pair HL (58D2H). Then fall into 5634H to stop the spooler.

5634H - Stop the Spooler

Reached for the 04H code (5530H: *ASP,S or LPRINT CHR$(4)) and after a spool file error. The printer driver entry 550BH becomes a RET, so any further printer output is ignored, and the flag at 56F1H is set: the files already queued are still printed, and when the queue is empty 56F3H runs the purge at 56F6H. The file being spooled, if any, stays open until that purge empties it.

5634
LD A,C9H 3E C9
Load Register A with C9H, the opcode of RET, to be stored into two places.
5636
LD (550BH),A 32 0B 55
Store Register A (C9H) at 550BH, the first byte of the printer driver entry: from now on the driver returns at once and drops every character.
5639
LD (56F1H),A 32 F1 56
Store Register A (C9H) at 56F1H, the operand of the LD A,nn at 56F0H: the spooler is stopping, and the status display shows SPOOL STOPPING.
563C
LD HL,587CH 21 7C 58
Load Register Pair HL with 587CH, the message SPOOL STOPPING ended by 0DH.
563F
JUMP to SYS0 4467H to display the message at Register Pair HL (587CH); its RET returns to the caller of this code.

5642H - Find a Free Pool File

Returns the Z FLAG with Register C = the number (1-5) of the first pool file whose queue byte is 00H (free), or the NZ FLAG (Register A = 01H) if all five are queued. Register Pair HL is left at the free entry or after the end mark.

5642
LD HL,5828H 21 28 58
Load Register Pair HL with 5828H, the first of the five queue bytes (pool file 1).
5645
LD C,01H 0E 01
Load Register C with 01H, the number of the pool file whose queue byte Register Pair HL points at.

Loop Start

5647
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the queue byte of pool file Register C.
5648
OR A B7
OR Register A (the queue byte) with itself to set the flags. The Z FLAG is set if the file is free.
5649
RET Z C8
If the Z FLAG is set (a free pool file), RETURN with Register C = its number.
564A
INC HL 23
Increment Register Pair HL to the next queue byte.
564B
INC C 0C
Increment Register C to the number of the next pool file.
564C
INC A 3C
Increment Register A (the queue byte): FFH, the end mark, becomes 00H and sets the Z FLAG.
564D
If the NZ FLAG is set (not the end mark), LOOP back to 5647H.

Loop End

564F
INC A 3C
Increment Register A (00H) to 01H, which sets the NZ FLAG: no pool file is free.
5650
RET C9
RETURN with the NZ FLAG set and Register A = 01H.

5651H - Put POOLn:d Into an FCB

Called with Register A = a pool file number (1-5) and Register Pair DE = an FCB (5400H for printing and at activation, 5420H for spooling). The number is put into the name template at 581EH and the 8 bytes POOLn:d and 0DH are copied into the FCB as the filespec for the open. Register Pair DE is kept; Register Pair HL returns 5826H and Register Pair BC 0000H.

5651
ADD A,30H C6 30
Add 30H to Register A (the pool file number 1-5), turning it into the ASCII digit 1-5.
5653
LD (5822H),A 32 22 58
Store Register A (the ASCII digit) at 5822H, the file number position in the template POOLn:d at 581EH.
5656
PUSH DE D5
Save Register Pair DE (the FCB address) on the stack.
5657
LD HL,581EH 21 1E 58
Load Register Pair HL with 581EH, the template: POOL, the digit, a colon, the drive digit stored by setup at 5824H, and 0DH.
565A
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the 8 bytes of the filespec and its 0DH.
565D
LDIR ED B0
Copy Register Pair BC (8) bytes from Register Pair HL (581EH) to Register Pair DE (the FCB): the filespec POOLn:d is in the FCB. HL ends at 5826H, DE at FCB+8, BC at 0000H.
565F
POP DE D1
Restore Register Pair DE from the stack: the FCB address.
5660
RET C9
RETURN with Register Pair DE = the FCB holding POOLn:d.

5661H - Keyboard Driver

5DA6H stores the relocated address of 5661H into 4016H-4017H, the driver address of the keyboard device control block at 4015H, so every keyboard read comes here. With the circular buffer (setup answer Y) the key is taken from the buffer at 5440H, which 57DDH fills; otherwise 5C8CH has put the previous keyboard driver's address into the CALL at 5661H. When no key is there, the spooler does its background work (567DH); when a key is there, the time of the key is kept for the print delay (5769H).

5661
Self-Modifying Code
GOSUB to the operand at 5662H: 57FAH as loaded (the next key from the circular buffer at 5440H, or 00H), or the keyboard driver that was in 4016H when the spooler was activated, stored by 5C8CH when the circular buffer is not used. Register A returns the key or 00H.
5664
OR A B7
OR Register A (the key, or 00H) with itself to set the flags. The Z FLAG is set if no key was pressed.
5665
PUSH AF F5
Save Register Pair AF (Register A = the key and its flags) on the stack, to be returned to the caller.
5666
If the NZ FLAG is set (a key was pressed), JUMP to 566DH to note the time of the key.
5668
No key: GOSUB to 567DH to do the spooler's background work (print, read the next sector, start the next file). Registers BC, DE and HL are kept.
566B
JUMP to 567BH to return Register A = 00H (no key) to the caller.
566D
LD A,(4041H) 3A 41 40
Load Register A with the byte at 4041H, SYS0's clock seconds (0-59).
5670
LD (576DH),A 32 6D 57
Store Register A (the seconds) at 576DH, the operand of the SUB at 576CH: the second of the last key, for the print delay.
5673
PUSH HL E5
Save Register Pair HL (the caller's HL) on the stack.
5674
LD HL,(4042H) 2A 42 40
Load Register Pair HL with the 16-bit value at 4042H: Register L = SYS0's clock minutes (4042H), Register H = its hours (4043H).
5677
LD (5777H),HL 22 77 57
Store Register Pair HL (the minutes and hours) at 5777H, the operand of the LD DE,nnnn at 5776H: the minute and hour of the last key.
567A
POP HL E1
Restore Register Pair HL from the stack, the caller's HL.
567B
POP AF F1
Restore Register Pair AF from the stack: Register A = the key (or 00H) with its flags.
567C
RET C9
RETURN to the ROM's driver call with Register A = the key, or 00H and the Z FLAG when no key was pressed.

567DH - Background Work

Called from the keyboard driver (5668H) when no key is waiting, from the printer driver (550EH) before each character is spooled, and from the SPOOL FULL wait (5603H). It prints from the print buffer (575AH) with the timer routine held off, and then does the disk work, which the timer routine never does: read the next sector of the file being printed, finish a printed file, start the next queued file, or run the purge when the spooler has been stopped and the queue is empty. Nothing is done while an overlay function is running. Register Pairs BC, DE and HL are kept.

567D
PUSH HL E5
Save Register Pair HL (the caller's HL) on the stack.
567E
PUSH DE D5
Save Register Pair DE (the caller's DE) on the stack.
567F
PUSH BC C5
Save Register Pair BC (the caller's BC) on the stack.
5680
LD HL,5759H 21 59 57
Load Register Pair HL with 5759H, the first instruction of the timer routine (a NOP, the entry of the timer block at 5755H).
5683
LD (HL),C9H 36 C9
Store C9H (RET) at Register Pair HL (5759H): while this code prints, a timer interrupt only finds a RET and does not print at the same time.
5685
PUSH HL E5
Save Register Pair HL (5759H, the timer routine's first byte) on the stack.
5686
GOSUB to 575AH to print from the print buffer (Index Register IX is saved there): one or more lines, if the printer is ready and the print delay has passed.
5689
POP HL E1
Restore Register Pair HL from the stack: 5759H.
568A
LD (HL),00H 36 00
Store 00H (NOP) at Register Pair HL (5759H): the timer routine works again.
568C
LD A,(4369H) 3A 69 43
Load Register A with the byte at 4369H, SYS0's system flags (bit 6 = an overlay function is running).
568F
BIT 6,A CB 77
Test bit 6 of Register A (4369H): the Z FLAG is set if no overlay function is running.
5691
If the NZ FLAG is set (an overlay function is running), JUMP to 5514H to restore the registers and return: no disk I/O now.
5694
LD A,(5766H) 3A 66 57
Load Register A with the byte at 5766H, the operand of the LD A,nn at 5765H: the number (1-5) of the pool file being printed, or 00H.
5697
OR A B7
OR Register A (the printing file number) with itself to set the flags. The Z FLAG is set if no file is being printed.
5698
If the Z FLAG is set (nothing being printed), JUMP to 56E1H to look for the next queued file.
569A
GOSUB to 5739H to compare the print pointer (the operand at 573DH) with 5300H: the CARRY FLAG while the buffer 5200H-52FFH still has bytes to print, the Z FLAG when it is used up, the NZ and NO CARRY FLAGS at the end mark 5301H.
569D
If the NO CARRY FLAG is set (the buffer is used up or the file's end mark was met), JUMP to 56B6H with the Z FLAG telling which.
569F
The buffer still has bytes to print: JUMP to 5514H to restore the registers and return.

56A2H - Start Printing a Queued File

Reached from 56E8H with Register C = the number of the pool file whose queue byte is 01H. The file is opened in the FCB 5400H with buffer 5200H and its first sector read; 56B6H also reads every following sector. A failed open drops the file from the queue; a failed read (also the end of the file) or the end mark 03H finishes it.

56A2
LD A,C 79
Load Register A with Register C, the number (1-5) of the pool file to print.
56A3
LD (5766H),A 32 66 57
Store Register A (the file number) at 5766H, the operand of the LD A,nn at 5765H: this file is now being printed.
56A6
LD DE,5400H 11 00 54
Load Register Pair DE with 5400H, the print file's FCB.
56A9
GOSUB to 5651H with Register A = the file number and Register Pair DE = 5400H: the name POOLn:d and 0DH are copied into the FCB.
56AC
LD HL,5200H 21 00 52
Load Register Pair HL with 5200H, the print sector buffer.
56AF
LD B,00H 06 00
Load Register B with 00H, the logical record length (256) for the open.
56B1
GOSUB to SYS0 4424H to open the existing file named in the FCB at Register Pair DE (5400H) with Register Pair HL = 5200H as its buffer and Register B = 00H. The Z FLAG returns set if it worked.
56B4
If the NZ FLAG is set (the file could not be opened), JUMP to 56CDH to drop it from the queue.
56B6
LD DE,5400H 11 00 54
Load Register Pair DE with 5400H, the print file's FCB. LD does not change the flags. 569DH comes here with the Z FLAG set when the buffer is used up, the NZ FLAG at the end mark.
56B9
If the Z FLAG is set (just opened, or the buffer is used up), GOSUB to SYS0 4436H to read the next sector of the file at Register Pair DE (5400H) into 5200H. The Z FLAG returns set if it worked.
56BC
If the NZ FLAG is set (a read error, the end of the file, or the end mark 03H from 569DH), JUMP to 56CAH to empty and close the file.
56BE
LD HL,5200H 21 00 52
Load Register Pair HL with 5200H, the start of the sector just read.
56C1
LD (573DH),HL 22 3D 57
Store Register Pair HL (5200H) at 573DH, the operand of the LD HL,nnnn at 573CH: the next byte to print.
56C4
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand at 56C5H: 50H (P) after *ASP,C was answered P (54ECH), otherwise 00H (also in the file).
56C6
OR A B7
OR Register A (the P answer flag) with itself to set the flags. The Z FLAG is set if printing should go on.
56C7
If the Z FLAG is set (go on printing), JUMP to 5514H to restore the registers and return.

56CAH - Finish the Printed File

Reached when the file has been printed (end of file, end mark), when it could not be read, or when *ASP,C was answered P. 5745H sets its EOF to 0 and closes it, so the DOS frees its space. Then the file is taken out of the queue: every queue byte from 01H up is lowered by one, so the next file gets 01H.

56CA
GOSUB to 5745H with Register Pair DE = 5400H to set the print file's EOF to 0 and close it.
56CD
XOR A AF
Set Register A to 00H (XOR A with itself). 56B4H comes here when the open failed.
56CE
LD (5766H),A 32 66 57
Store Register A (00H) at 5766H, the operand of the LD A,nn at 5765H: no file is being printed.
56D1
LD (56C5H),A 32 C5 56
Store Register A (00H) at 56C5H, the operand of the LD A,nn at 56C4H: the P answer has been dealt with.
56D4
LD HL,5827H 21 27 58
Load Register Pair HL with 5827H, the byte before the five queue bytes.

Loop Start
Lower every queue byte that is not 00H by one, the FFH end mark included; it is put back at 56E0H.

56D7
INC HL 23
Increment Register Pair HL to the next queue byte.
56D8
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a queue byte (00H free, 01H-05H queued, FFH the end).
56D9
OR A B7
OR Register A (the queue byte) with itself to set the flags. The Z FLAG is set for a free entry.
56DA
If the Z FLAG is set (a free entry), LOOP back to 56D7H.
56DC
DEC (HL) 35
Decrement the queue byte at Register Pair HL: the file moves up one place, the printed file (01H) becomes free.
56DD
INC A 3C
Increment Register A (the queue byte before the decrement): FFH, the end mark, becomes 00H and sets the Z FLAG.
56DE
If the NZ FLAG is set (not the end mark), LOOP back to 56D7H.

Loop End

56E0
INC (HL) 34
Increment the byte at Register Pair HL (the end mark, lowered to FEH at 56DCH) back to FFH.

56E1H - Find the Next File to Print

Looks for the queue byte 01H. If a file has it, printing of that file starts (56A2H). If none has it and the spooler has been stopped (56F1H = C9H), the purge at 56F6H runs; otherwise nothing more is done.

56E1
LD HL,5828H 21 28 58
Load Register Pair HL with 5828H, the first of the five queue bytes (pool file 1). 5698H comes here when nothing is being printed.
56E4
LD C,01H 0E 01
Load Register C with 01H, the number of the pool file whose queue byte Register Pair HL points at.

Loop Start

56E6
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the queue byte of pool file Register C.
56E7
DEC A 3D
Decrement Register A (the queue byte): the Z FLAG is set if it was 01H, the next file to print.
56E8
If the Z FLAG is set (pool file Register C is next), JUMP to 56A2H to start printing it.
56EA
INC A 3C
Increment Register A (the queue byte minus 1) back to the queue byte.
56EB
INC HL 23
Increment Register Pair HL to the next queue byte.
56EC
INC C 0C
Increment Register C to the number of the next pool file.
56ED
INC A 3C
Increment Register A (the queue byte): FFH, the end mark, becomes 00H and sets the Z FLAG.
56EE
If the NZ FLAG is set (not the end mark), LOOP back to 56E6H.

Loop End

56F0
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand at 56F1H: C9H after the spooler has been stopped (5639H), otherwise 00H (also in the file).
56F2
OR A B7
OR Register A (the stop flag) with itself to set the flags. The Z FLAG is set if the spooler has not been stopped.
56F3
If the Z FLAG is set (not stopped), JUMP to 5514H to restore the registers and return. Otherwise the queue is empty after a stop: fall into the purge.

56F6H - *ASP,P: Purge the Spooler

Reached from 5466H (*ASP,P, with SYS0's return address 4408H on top of the stack) and from 56F3H (stopped and the queue empty, with the three registers of 567DH on the stack). The file being spooled is emptied and closed, the timer routine is taken out of the chain, the printer and keyboard drivers that were there at activation are put back, HIMEM is given back if nothing has lowered it since, and the *name block is taken off SYS9's list. The manual says SPOOL PURGED is shown; the code never shows that message (588BH). Pool files still queued are not printed and keep their space.

56F6
LD A,(5534H) 3A 34 55
Load Register A with the byte at 5534H, the operand of the LD A,nn at 5533H: the number of the pool file being spooled, or 00H.
56F9
OR A B7
OR Register A (the spool file number) with itself to set the flags. The NZ FLAG is set if a spool file is open.
56FA
LD DE,5420H 11 20 54
Load Register Pair DE with 5420H, the spool file's FCB. LD does not change the flags.
56FD
If the NZ FLAG is set (a spool file is open), GOSUB to 5745H to set its EOF to 0 and close it: what was spooled into it is lost.
5700
LD DE,5755H 11 55 57
Load Register Pair DE with 5755H, the spooler's timer block.
5703
GOSUB to SYS0 4413H to take the timer block at Register Pair DE (5755H) out of the timer chain; nothing changes if it was not in it (the interrupt option N).
5706
DI F3
Disable interrupts while the device control blocks and HIMEM are changed.
5707
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the operand at 5708H: the printer driver address that was in 4026H when the spooler was activated, stored by 5C72H (0000H in the file).
570A
LD (4026H),HL 22 26 40
Store Register Pair HL (the previous printer driver) at 4026H, the driver address of the printer device control block: printer output no longer comes to the spooler.
570D
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the operand at 570EH: the keyboard driver address that was in 4016H when the spooler was activated, stored by 5C7BH (0000H in the file).
5710
LD (4016H),HL 22 16 40
Store Register Pair HL (the previous keyboard driver) at 4016H, the driver address of the keyboard device control block.
5713
LD DE,5200H 11 00 52
Load Register Pair DE with 5200H, the start of the spooler's area. The relocation at 5D0FH has changed this operand into the copy's area start, the first byte above the HIMEM set at activation.
5716
DEC DE 1B
Decrement Register Pair DE to the area start - 1: the HIMEM value 5D9CH stored at activation.
5717
LD HL,(4049H) 2A 49 40
Load Register Pair HL with the 16-bit value at 4049H, HIMEM now.
571A
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
571B
SBC HL,DE ED 52
Subtract Register Pair DE (the HIMEM set at activation) from Register Pair HL (HIMEM now). The Z FLAG is set if HIMEM has not been changed since.
571D
If the NZ FLAG is set (something else has changed HIMEM), JUMP to 5726H and leave it: the spooler's memory stays reserved.
571F
LD HL,06FAH 21 FA 06
Load Register Pair HL with 06FAH, the size of the spooler's area (5200H-58F9H).
5722
ADD HL,DE 19
Add Register Pair DE (the area start - 1) to Register Pair HL (06FAH): Register Pair HL = the HIMEM from before the activation.
5723
LD (4049H),HL 22 49 40
Store Register Pair HL (the old HIMEM) at 4049H: the spooler's memory is free again.
5726
EI FB
Enable interrupts again: the drivers and HIMEM are consistent.
5727
LD HL,5450H 21 50 54
Load Register Pair HL with 5450H, the spooler's *name block (changed by the relocation into the copy's block).
572A
GOSUB to SYS0 4464H to take the *name block at Register Pair HL off SYS9's list: *ASP gives FILE NOT IN DIRECTORY from now on.
572D
POP BC C1
Restore Register Pair BC from the stack: 4408H when this is the *ASP,P command, or the BC that 567DH saved when it is the end of a stopped spooler.
572E
LD HL,4408H 21 08 44
Load Register Pair HL with 4408H, the return address SYS1 pushes for a command (SYS0's RET Z there).
5731
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5732
SBC HL,BC ED 42
Subtract Register Pair BC (the word taken off the stack) from Register Pair HL (4408H). The Z FLAG is set if they are the same.
5734
RET Z C8
If the Z FLAG is set (the *ASP,P command), RETURN to SYS0 402DH, DOS READY, which SYS1 put under 4408H.
5735
Otherwise JUMP to 5515H to restore Register Pairs DE and HL and return to the caller of 567DH; Register Pair BC already holds its value.
5738
DEFB 00H 00
One zero byte that no instruction reaches or names (the JP at 5735H ends the purge). The relocation scan at 5CE0H passes over it as a NOP.

5739H - Is the Print Buffer Used Up

Compares the print pointer, the operand at 573DH (the next byte of 5200H-52FFH to print), with 5300H. Returns the CARRY FLAG while bytes are left, the Z FLAG when the pointer is exactly 5300H (read the next sector), and the NZ and NO CARRY FLAGS when it is 5301H, the value 578AH stores when it meets the end mark 03H. Register Pair HL returns the pointer, Register Pair BC = 5300H.

5739
LD BC,5300H 01 00 53
Load Register Pair BC with 5300H, the first address past the print buffer 5200H-52FFH.
573C
LD HL,0000H 21 00 00
Self-Modifying Code
Load Register Pair HL with the operand at 573DH, the print pointer: 5200H after every sector read (56C1H), the next byte after each one printed (57C8H), 5301H at the end mark (578DH); 0000H in the file.
573F
LD A,H 7C
Load Register A with Register H, the high byte of the print pointer.
5740
CP B B8
Compare Register A (the pointer's high byte) against Register B (53H). The CARRY FLAG is set below 5300H.
5741
RET NZ C0
If the NZ FLAG is set (the high byte is not 53H), RETURN with the CARRY FLAG set: bytes are left to print.
5742
LD A,L 7D
Load Register A with Register L, the low byte of the print pointer.
5743
CP C B9
Compare Register A (the pointer's low byte) against Register C (00H): the Z FLAG for 5300H (used up), the NZ FLAG for 5301H (end mark); the CARRY FLAG is never set here.
5744
RET C9
RETURN with the flags from the compare and Register Pair HL = the print pointer.

5745H - Empty a Pool File and Close It

Called with Register Pair DE = an FCB (5400H or 5420H). The EOF in the FCB (bytes +8, +12 and +13) is set to 0 and the file is closed, so the DOS releases all its space. Register A returns 00H; the close's result is returned.

5745
XOR A AF
Set Register A to 00H (XOR A with itself), the value for the three EOF bytes.
5746
LD HL,0008H 21 08 00
Load Register Pair HL with 0008H, the offset of the FCB's EOF low byte.
5749
ADD HL,DE 19
Add Register Pair DE (the FCB) to Register Pair HL (0008H): Register Pair HL = FCB+8, the EOF byte within the last sector.
574A
LD (HL),A 77
Store Register A (00H) at Register Pair HL, FCB+8.
574B
INC HL 23
Increment Register Pair HL to FCB+9 (the record length, left alone).
574C
INC HL 23
Increment Register Pair HL to FCB+10 (NEXT middle byte, left alone).
574D
INC HL 23
Increment Register Pair HL to FCB+11 (NEXT high byte, left alone).
574E
INC HL 23
Increment Register Pair HL to FCB+12, the EOF middle byte.
574F
LD (HL),A 77
Store Register A (00H) at Register Pair HL, FCB+12.
5750
INC HL 23
Increment Register Pair HL to FCB+13, the EOF high byte.
5751
LD (HL),A 77
Store Register A (00H) at Register Pair HL, FCB+13: the EOF is 0.
5752
JUMP to SYS0 4428H to close the file whose FCB is at Register Pair DE; with EOF 0 the close frees all its granules. Its RET returns to the caller of 5745H.

5755H - Timer Block

The block SYS0's timer chain walks every 25 ms tick (4610H) once 5DB6H has enqueued it through 4410H (interrupt option Y). Bytes 0-1 are the chain link, written by the enqueue; byte 2 the interval in ticks, byte 3 the countdown; when the countdown runs out SYS0 reloads it from byte 2 and calls byte 4. The routine at byte 4 prints from the print buffer only: disk I/O is never done from the interrupt. 567DH turns its first byte into a RET while it prints itself.

5755-5756
DEFW 0100H 00 01
Bytes 0-1 of the timer block, the chain link: the bytes 00H 01H in the file are not used; 4410H (SYS3 4D4BH) stores the old chain head here when the block is put at the front of the chain.
5757
DEFB 01H 01
Byte 2 of the timer block, the interval: 01H, the routine runs at every 25 ms tick. SYS0 4626H reads it and copies it into byte 3 each time the countdown runs out.
5758
DEFB 01H 01
Byte 3 of the timer block, the countdown to the next run: 01H. SYS0 4629H decrements it every tick and calls the routine at byte 4 when it reaches 0.
5759
NOP 00
Self-Modifying Code
Byte 4 of the timer block, where SYS0 starts the routine: a NOP, so the routine goes on at 575AH. 5683H stores C9H (RET) here while 567DH prints, and 568AH puts the 00H back.

575AH - Print From the Buffer

Entered at 5759H from the timer chain and called from 567DH. SYS0 saves Register Pairs AF, BC, DE and HL around a timer routine, so only Index Register IX, which the keyboard check and the printer driver call change, is saved here.

575A
PUSH IX DD E5
Save Index Register IX on the stack: 57DEH and 579FH load it with a device control block.
575C
GOSUB to 5762H to take a key into the circular buffer and print what the buffer holds.
575F
POP IX DD E1
Restore Index Register IX from the stack, as it was before the timer routine or 567DH.
5761
RET C9
RETURN to SYS0's timer chain (or to 5689H) with Index Register IX as it was.

5762H - Print Delay After a Key

First a key is taken into the circular buffer (57DDH). Nothing is printed when no file is being printed, or within the number of seconds chosen at setup after the last key (the time kept by 566DH). The seconds are compared modulo 60 and the minutes and hours as a word, with the borrow from the seconds.

5762
GOSUB to 57DDH to read the keyboard into the circular buffer at 5440H (a RET when the circular buffer is not used).
5765
LD A,00H 3E 00
Self-Modifying Code
Load Register A with the operand at 5766H, the number (1-5) of the pool file being printed: stored by 56A3H, cleared by 56CEH; 00H in the file.
5767
OR A B7
OR Register A (the printing file number) with itself to set the flags. The Z FLAG is set if no file is being printed.
5768
RET Z C8
If the Z FLAG is set (nothing to print), RETURN.
5769
LD A,(4041H) 3A 41 40
Load Register A with the byte at 4041H, SYS0's clock seconds (0-59).
576C
SUB 00H D6 00
Self-Modifying Code
Subtract the operand at 576DH from Register A (the seconds now): the second of the last key, stored by 5670H (00H in the file). The CARRY FLAG is set if the seconds have wrapped past 59.
576E
If the NO CARRY FLAG is set (no wrap), JUMP to 5773H with Register A = the seconds since the key.
5770
ADD A,3CH C6 3C
Add 3CH (60) to Register A: the seconds since the key, counted across the minute.
5772
SCF 37
Set the CARRY FLAG: one minute is borrowed from the minute and hour compare below.
5773
LD HL,(4042H) 2A 42 40
Load Register Pair HL with the 16-bit value at 4042H: Register L = SYS0's clock minutes, Register H = its hours.
5776
LD DE,0000H 11 00 00
Self-Modifying Code
Load Register Pair DE with the operand at 5777H: the minutes (Register E) and hours (Register D) of the last key, stored by 5677H (0000H in the file).
5779
SBC HL,DE ED 52
Subtract Register Pair DE (the minute and hour of the key) and the CARRY FLAG (the borrow) from Register Pair HL (the minute and hour now). The Z FLAG is set if the key was within the last minute.
577B
If the NZ FLAG is set (a minute or more since the key), JUMP to 5780H to print.
577D
CP 00H FE 00
Self-Modifying Code
Compare Register A (the seconds since the key) against the operand at 577EH, the print delay stored by setup at 5991H (00H in the file). The CARRY FLAG is set if fewer seconds have passed.
577F
RET C D8
If the CARRY FLAG is set (the delay has not passed), RETURN without printing.

5780H - Print Up to the End of a Line

Prints bytes from the print buffer until a carriage return has been sent, the buffer is used up, the printer is not ready, or the end mark 03H is met. Register Pair HL is the print pointer; the character is kept in Register C. Between characters the keyboard is read into the circular buffer.

Loop Start

5780
GOSUB to 5739H to compare the print pointer with 5300H: Register Pair HL = the pointer, the CARRY FLAG while bytes are left in 5200H-52FFH. 57D3H comes back here for the next byte.
5783
RET NC D0
If the NO CARRY FLAG is set (the buffer is used up, or the end mark was met), RETURN: 567DH reads the next sector or finishes the file.
5784
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the next byte to print.
5785
CP 03H FE 03
Compare Register A (the byte) against 03H, the end mark written after the last byte of a spool file (55C8H).
5787
LD C,A 4F
Load Register C with Register A, the byte to print. LD does not change the flags.
5788
If the NZ FLAG is set (not the end mark), JUMP to 5791H to send it to the printer.
578A
LD HL,5301H 21 01 53
Load Register Pair HL with 5301H, the print pointer value that marks the end of the file.
578D
LD (573DH),HL 22 3D 57
Store Register Pair HL (5301H) at 573DH, the operand of the LD HL,nnnn at 573CH: 5739H now gives the NZ and NO CARRY FLAGS and 567DH finishes the file.
5790
RET C9
RETURN without printing the end mark: the print pointer now holds 5301H.
5791
LD A,01H 3E 01
Self-Modifying Code
Load Register A with the operand at 5792H, the printer kind chosen at setup (58FAH-5915H): 02H the driver that was in 4026H, 01H parallel (37E8H), 00H serial (ports EAH and EBH). 01H in the file.
5793
CP 01H FE 01
Compare Register A (the printer kind) against 01H: the CARRY FLAG for 00H (serial), the Z FLAG for 01H (parallel).
5795
If the CARRY FLAG is set (Register A = 00H, serial), JUMP to 57B8H.
5797
If the Z FLAG is set (Register A = 01H, parallel), JUMP to 57AAH.
5799
PUSH HL E5
The previous driver (02H): save Register Pair HL (the print pointer) on the stack.
579A
PUSH BC C5
Save Register Pair BC (Register C = the character) on the stack.
579B
LD DE,4025H 11 25 40
Load Register Pair DE with 4025H, the printer device control block.
579E
PUSH DE D5
Save Register Pair DE (4025H) on the stack, to move it into Index Register IX.
579F
POP IX DD E1
Restore Index Register IX from the stack: Index Register IX = 4025H, the printer device control block, as the ROM's driver call would set it.
57A1
LD B,02H 06 02
Load Register B with 02H, the ROM's device code for output.
57A3
Self-Modifying Code
GOSUB to the operand at 57A4H, the printer driver that was in 4026H at activation (stored by 5C75H; 0000H in the file), with Register C = the character, Register B = 02H, Register Pair DE and Index Register IX = 4025H.
57A6
POP BC C1
Restore Register Pair BC from the stack (Register C = the character just printed).
57A7
POP HL E1
Restore Register Pair HL from the stack, the print pointer.
57A8
JUMP to 57C7H to move the print pointer past the character.

57AAH - Parallel Printer at 37E8H

The status byte at 37E8H must show not busy (bit 7 clear), not out of paper (bit 6 clear), ready (bit 5 set) and bit 4 set; otherwise nothing is sent and the byte is tried again next time.

57AA
LD A,(37E8H) 3A E8 37
Load Register A with the byte at 37E8H, the printer status (bit 7 busy, bit 6 out of paper, bit 5 ready).
57AD
AND F0H E6 F0
AND Register A (the printer status) with F0H, keeping bits 4-7.
57AF
CP 30H FE 30
Compare Register A (the status bits 4-7) against 30H: the Z FLAG only for not busy, paper present, ready and bit 4 set.
57B1
RET NZ C0
If the NZ FLAG is set (the printer is not ready), RETURN: the byte stays at the print pointer for the next time.
57B2
LD A,C 79
Load Register A with Register C, the character to print.
57B3
LD (37E8H),A 32 E8 37
Store Register A (the character) at 37E8H: the printer prints it.
57B6
JUMP to 57C7H to move the print pointer past the character.

57B8H - Serial Printer Through the RS-232 Board

The UART's status (port EAH) must have bit 6, transmitter buffer empty, set. With the setup answer Y to H14 PRINTER, bit 6 of port E8H must also be set before the character is sent; with N the JR at 57BDH skips that test. The character goes to the UART's data port EBH.

57B8
IN A,(EAH) DB EA
Load Register A from port EAH, the RS-232 board's UART status (bit 6 = the transmitter buffer is empty).
57BA
BIT 6,A CB 77
Test bit 6 of Register A (the UART status): the Z FLAG is set while the UART is still sending.
57BC
RET Z C8
If the Z FLAG is set (the UART cannot take a character yet), RETURN: the byte stays at the print pointer.
57BD
Self-Modifying Code
JUMP to 57C4H, past the port E8H test. Setup stores 18H (this JR) at 591FH, and for H14 PRINTER Y then 3EH at 5925H, which makes the two bytes LD A,05H, so the test at 57BFH runs.
57BF
IN A,(E8H) DB E8
Load Register A from port E8H, the RS-232 board's status input. Reached only when 57BDH is LD A,05H (H14 PRINTER Y).
57C1
BIT 6,A CB 77
Test bit 6 of Register A (port E8H): the Z FLAG is set while the bit is clear.
57C3
RET Z C8
If the Z FLAG is set (bit 6 of port E8H is clear), RETURN: the byte stays at the print pointer.
57C4
LD A,C 79
Load Register A with Register C, the character to print.
57C5
OUT (EBH),A D3 EB
Output Register A (the character) to port EBH, the UART's data register: the RS-232 board sends it.

57C7H - After Each Character

The print pointer moves on; after a carriage return the line ends here (with the line feed option a 0AH is put in its place first, so the line feed is printed next). Otherwise the keyboard is read and the next byte printed.

57C7
INC HL 23
Increment Register Pair HL (the print pointer) past the character just sent.
57C8
LD (573DH),HL 22 3D 57
Store Register Pair HL (the print pointer) at 573DH, the operand of the LD HL,nnnn at 573CH.
57CB
LD A,C 79
Load Register A with Register C, the character just sent.
57CC
CP 0DH FE 0D
Compare Register A (the character just sent) against 0DH, carriage return.
57CE
If the Z FLAG is set (a carriage return: the line is printed), JUMP to 57D5H.
57D0
GOSUB to 57DDH to read the keyboard into the circular buffer between two characters.
57D3
LOOP back to 5780H to print the next byte at the print pointer in Register Pair HL.

Loop End

57D5
RET C9
Self-Modifying Code
RETURN after the carriage return. Setup stores 00H (NOP) here for LINE FEED ON CARRIAGE RETURN Y and C9H (RET) for N (5972H, 5976H); C9H in the file.
57D6
DEC HL 2B
Line feed option Y: decrement Register Pair HL (the print pointer) back to the carriage return just sent.
57D7
LD (HL),0AH 36 0A
Store 0AH (line feed) at Register Pair HL, over the carriage return already printed.
57D9
LD (573DH),HL 22 3D 57
Store Register Pair HL (pointing at the 0AH) at 573DH, the operand of the LD HL,nnnn at 573CH: the line feed is printed next.
57DC
RET C9
RETURN after the line, with the line feed waiting at the print pointer.

57DDH - Read the Keyboard Into the Circular Buffer

The buffer is the 10 bytes 5440H-5449H. The write pointer is the operand at 57E8H and the write count the operand at 57FDH; the count runs from F6H to FFH, and when it wraps to 00H the pointer goes back to 5440H and the count to F6H (5817H). Nothing stops the writer from passing the reader: 10 keys that are not read make the buffer look empty again.

57DD
NOP 00
Self-Modifying Code
No operation. 5C91H stores C9H (RET) here when the circular buffer is not used, so the keyboard is then only read by the previous driver from 5661H.
57DE
LD IX,4015H DD 21 15 40
Load Index Register IX with 4015H, the keyboard device control block, for the keyboard routine.
57E2
Self-Modifying Code
GOSUB to the operand at 57E3H: 03E3H, the ROM's keyboard driver (KEY), when the timer interrupts drive the printer; otherwise 5C84H stores the keyboard driver that was in 4016H at activation. Register A returns the key or 00H.
57E5
OR A B7
OR Register A (the key, or 00H) with itself to set the flags. The Z FLAG is set if no key was pressed.
57E6
RET Z C8
If the Z FLAG is set (Register A = 00H, no key), RETURN with nothing stored.
57E7
LD HL,5440H 21 40 54
Self-Modifying Code
Load Register Pair HL with the operand at 57E8H, the write pointer into the circular buffer 5440H-5449H (5440H in the file), stored by 57F3H.
57EA
LD (HL),A 77
Store Register A (the key) at Register Pair HL, the write pointer.
57EB
INC HL 23
Increment Register Pair HL (the write pointer) to the next buffer byte.
57EC
LD A,(57FDH) 3A FD 57
Load Register A with the byte at 57FDH, the operand of the SUB at 57FCH: the write count (F6H-FFH).
57EF
INC A 3C
Increment Register A (the write count): the Z FLAG is set when it wraps from FFH to 00H after the tenth byte.
57F0
If the Z FLAG is set (the end of the buffer), GOSUB to 5817H: Register Pair HL = 5440H and Register A = F6H.
57F3
LD (57E8H),HL 22 E8 57
Store Register Pair HL (the new write pointer) at 57E8H, the operand of the LD HL,nnnn at 57E7H.
57F6
LD (57FDH),A 32 FD 57
Store Register A (the new write count) at 57FDH, the operand of the SUB at 57FCH.
57F9
RET C9
RETURN with the key stored in the circular buffer at 5440H-5449H.

57FAH - Take a Key From the Circular Buffer

The keyboard driver's first call (5661H). The read count (operand at 57FBH) is compared with the write count (operand at 57FDH): equal means empty, and Register A returns 00H with the Z FLAG. Otherwise the key at the read pointer (operand at 5802H) is returned and the pointer and count move on, wrapping like the writer. Register Pairs BC and HL are kept.

57FA
LD A,F6H 3E F6
Self-Modifying Code
Load Register A with the operand at 57FBH, the read count (F6H-FFH; F6H in the file), stored by 5810H.
57FC
SUB F6H D6 F6
Self-Modifying Code
Subtract the operand at 57FDH (the write count, stored by 57F6H; F6H in the file) from Register A (the read count). The Z FLAG is set and Register A = 00H when they are equal.
57FE
RET Z C8
If the Z FLAG is set (the buffer is empty), RETURN with Register A = 00H: no key.
57FF
PUSH HL E5
Save Register Pair HL (the caller's HL) on the stack.
5800
PUSH BC C5
Save Register Pair BC (the caller's BC) on the stack.
5801
LD HL,5440H 21 40 54
Self-Modifying Code
Load Register Pair HL with the operand at 5802H, the read pointer into 5440H-5449H (5440H in the file), stored by 580DH.
5804
LD B,(HL) 46
Load Register B with the byte at Register Pair HL, the key at the read pointer.
5805
INC HL 23
Increment Register Pair HL (the read pointer) to the next buffer byte.
5806
LD A,(57FBH) 3A FB 57
Load Register A with the byte at 57FBH, the operand of the LD A,nn at 57FAH: the read count.
5809
INC A 3C
Increment Register A (the read count): the Z FLAG is set when it wraps from FFH to 00H after the tenth byte.
580A
If the Z FLAG is set (the end of the buffer), GOSUB to 5817H: Register Pair HL = 5440H and Register A = F6H.
580D
LD (5802H),HL 22 02 58
Store Register Pair HL (the new read pointer) at 5802H, the operand of the LD HL,nnnn at 5801H.
5810
LD (57FBH),A 32 FB 57
Store Register A (the new read count) at 57FBH, the operand of the LD A,nn at 57FAH.
5813
LD A,B 78
Load Register A with Register B, the key taken from the buffer.
5814
POP BC C1
Restore Register Pair BC from the stack, the caller's BC.
5815
POP HL E1
Restore Register Pair HL from the stack, the caller's HL.
5816
RET C9
RETURN with Register A = the key (the flags are those of the count's INC; 5664H tests Register A again).

5817H - Wrap a Circular Buffer Pointer

Called by the writer (57F0H) and the reader (580AH) when their count has wrapped to 00H.

5817
LD HL,5440H 21 40 54
Load Register Pair HL with 5440H, the first byte of the circular buffer: the pointer starts again.
581A
LD A,F6H 3E F6
Load Register A with F6H, the count's start value: ten more bytes until the next wrap.
581C
RET C9
RETURN with Register Pair HL = 5440H and Register A = F6H.

581DH - Resident Data

The last part of the resident area. 5CB2H copies it to the top of memory with the code, but the relocation scan stops at 581DH, so nothing here is changed by the relocation. It holds the name template POOLn:d, the B/P answer, the print queue, the page counters and the messages of the *ASP command and of the printer driver.

581D
DEFB 00H 00
One zero byte that no instruction names. The relocation scan's end address (5CD9H: 545CH + 03C1H) is 581DH, the first byte after the code.
581E-5821
DEFM "POOL" 50 4F 4F 4C
The start of the pool file name template, copied into an FCB by 5651H and displayed by 54CFH. The whole template is POOLn:d followed by 0DH.
5822
DEFM "1" 31
The pool file number in the template: an ASCII digit 1-5, stored by 5653H and 54C9H before the name is used.
5823
DEFM ":" 3A
The colon before the drive number in the template POOLn:d.
5824
DEFM "1" 31
The spool drive digit in the template: 1 in the file, set by setup at 5988H to the answer to DRIVE # FOR POOL FILES (0-3)?
5825
DEFB 0DH 0D
The carriage return that ends the template: it ends the filespec in the FCB, and 4467H shows it as a new line.
5826
DEFB 20H 20
The answer buffer of *ASP,C: the ROM line input at 54E0H stores the one character typed (B or P) here.
5827
DEFB 20H 20
The byte before the queue. The line input at 54E0H stores its ending 0DH here; 55D6H and 56D4H start their queue walks here and step to 5828H before reading.
5828-582C
DEFB 00H, 00H, 00H, 00H, 00H 00 00 00 00 00
The print queue, one byte for each pool file POOL1 to POOL5: 00H free or being spooled, 01H being printed or printed next, 02H-05H its place in the queue. 55EEH queues a file, 56DCH moves the queue up, 54FCH frees waiting files.
582D
DEFB 0FFH FF
The end mark of the print queue: every walk through the five bytes stops at the FFH (54B4H, 54FFH, 55E3H, 564DH, 56DEH, 56EEH).
582E
DEFB 00H 00
The line count of the current page of the spool file, kept by 5544H-5578H, reset by a form feed.
582F
DEFB 00H 00
The line flag: 01H when the current line of the spool file has a printable character (5594H), 00H after a carriage return (558EH). 5586H uses it to put a space on an empty line.
5830-583C
DEFM "SPOOL STATUS", 0DH 53 50 4F 4F 4C 20 53 54 41 54 55 53 0D
The heading of the *ASP status display, shown by 5489H.
583D-5847
DEFM "PRINTING: ", 03H 50 52 49 4E 54 49 4E 47 3A 20 03
Shown by 54A9H before the name of the file being printed; 03H keeps the name on the same line.
5848-5852
DEFM "SPOOLING: ", 03H 53 50 4F 4F 4C 49 4E 47 3A 20 03
Shown by 54A0H before the name of the file being spooled.
5853-585D
DEFM "BACK LOG: ", 03H 42 41 43 4B 20 4C 4F 47 3A 20 03
Shown by 54BFH before the name of each file waiting in the queue.
585E-587B
DEFM "CLEAR BACKLOG OR PRINT (B/P)?", 03H 43 4C 45 41 52 20 42 41 43 4B 4C 4F 47 20 4F 52 20 50 52 49 4E 54 20 28 42 2F 50 29 3F 03
The question of *ASP,C, shown by 54D8H; the answer is read into 5826H.
587C-588A
DEFM "SPOOL STOPPING", 0DH 53 50 4F 4F 4C 20 53 54 4F 50 50 49 4E 47 0D
Shown by 563FH when the spooler is stopped and by 5495H in the status display after a stop.
588B-5897
DEFM "SPOOL PURGED", 0DH 53 50 4F 4F 4C 20 50 55 52 47 45 44 0D
No instruction names this message: the purge at 56F6H ends without showing it.
5898-58B7
DEFM "SPOOL FULL. WAITING ON PRINTER", 0DH 53 50 4F 4F 4C 20 46 55 4C 4C 2E 20 20 57 41 49 54 49 4E 47 20 4F 4E 20 50 52 49 4E 54 45 52 0D
Shown by 5600H when all five pool files are queued and a new spool file is needed.
58B8-58C2
DEFM "CAN'T OPEN", 03H 43 41 4E 27 54 20 4F 50 45 4E 03
Shown by 562BH when a spool file cannot be opened (from 5623H).
58C3-58D1
DEFM "CAN'T WRITE TO", 03H 43 41 4E 27 54 20 57 52 49 54 45 20 54 4F 03
Shown by 562BH when a spool sector cannot be written (from 55ABH).
58D2-58E4
DEFM " SPOOL OUTPUT FILE", 0DH 20 53 50 4F 4F 4C 20 4F 55 54 50 55 54 20 46 49 4C 45 0D
Shown by 5631H after CAN'T OPEN or CAN'T WRITE TO.
58E5-58F9
DEFM "CAN'T SPOOL FROM DOS", 0DH 43 41 4E 27 54 20 53 50 4F 4F 4C 20 46 52 4F 4D 20 44 4F 53 0D
Shown by 552AH for the first character the DOS sends to the printer while an overlay function runs. 58F9H, the 0DH, is the last byte copied to the top of memory (the area 5200H-58F9H, 06FAH bytes).

58FAH - filespec,I: Set Up a Working Module

Reached from 5C50H when the program is run as ASPOOL/MAS,I. Each answer is stored straight into the resident code as an opcode or an operand; then the DUMP command at 5C11H writes 5450H-5DD0H, with these changes, to the new file named by the user. The master file on the diskette is not changed. Every question is asked again until the answer has the right form: one character for the letter and drive questions, exactly two characters for the numbers.

58FA
LD HL,5A55H 21 55 5A
Load Register Pair HL with 5A55H, the question USE EXISTING PRINTER DRIVER (Y/N)? ended by 03H.
58FD
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y, the NZ FLAG for N.
5900
LD HL,5792H 21 92 57
Load Register Pair HL with 5792H, the operand of the LD A,nn at 5791H: the printer kind. LD does not change the flags.
5903
LD (HL),02H 36 02
Store 02H at Register Pair HL (5792H), the printer kind for the driver that is in 4026H at activation.
5905
If the Z FLAG is set (Y: use the existing driver), JUMP to 5928H with the kind 02H.
5907
DEC (HL) 35
Decrement the byte at Register Pair HL (5792H) to 01H, the parallel printer at 37E8H.
5908
PUSH HL E5
Save Register Pair HL (5792H, the printer kind) on the stack for 5912H.
5909
LD HL,5A78H 21 78 5A
Load Register Pair HL with 5A78H, the question PARALLEL OR SERIAL PRINTER (P/S)? ended by 03H.
590C
LD BC,5053H 01 53 50
Load Register Pair BC with 5053H: Register B = 50H (P), Register C = 53H (S), the two answers allowed.
590F
GOSUB to 5A1BH to ask the question at Register Pair HL until the answer is the letter in Register B or Register C: the Z FLAG for P, the NZ FLAG for S.
5912
POP HL E1
Restore Register Pair HL from the stack: 5792H. POP does not change the flags.
5913
If the Z FLAG is set (P: parallel), JUMP to 5928H with the kind 01H.
5915
DEC (HL) 35
Decrement the byte at Register Pair HL (5792H) to 00H, the serial printer on the RS-232 board.
5916
LD HL,5A9AH 21 9A 5A
Load Register Pair HL with 5A9AH, the question H14 PRINTER (Y/N)? ended by 03H.
5919
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
591C
LD HL,57BDH 21 BD 57
Load Register Pair HL with 57BDH, the JR at the serial printer's port E8H test. LD does not change the flags.
591F
LD (HL),18H 36 18
Store 18H (JR) at Register Pair HL (57BDH): the port E8H test is jumped over.
5921
If the NZ FLAG is set (N), JUMP to 5928H and keep the JR.
5923
LD A,3EH 3E 3E
Load Register A with 3EH, the opcode of LD A,nn.
5925
LD (57BDH),A 32 BD 57
Store Register A (3EH) at 57BDH: the two bytes there become LD A,05H and the port E8H test at 57BFH is done (H14 PRINTER Y).
5928
LD HL,5AADH 21 AD 5A
Load Register Pair HL with 5AADH, the question PAGES (Y/N)? ended by 03H.
592B
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
592E
LD HL,5554H 21 54 55
Load Register Pair HL with 5554H, the RET C after the page count test. LD does not change the flags.
5931
LD (HL),C9H 36 C9
Store C9H (RET) at Register Pair HL (5554H): no page is ever full.
5933
If the NZ FLAG is set (N: no pages), JUMP to 5940H.
5935
LD (HL),D8H 36 D8
Store D8H (RET C) at Register Pair HL (5554H): a page is full when the count reaches the print lines.
5937
LD HL,5AF6H 21 F6 5A
Load Register Pair HL with 5AF6H, the question PRINT LINES PER PAGE (10-99)? ended by 03H.
593A
GOSUB to 5A3AH to ask the question at Register Pair HL until two characters are typed: Register A = their value.
593D
LD (5553H),A 32 53 55
Store Register A (the print lines per page) at 5553H, the operand of the CP at 5552H.
5940
LD HL,5ABAH 21 BA 5A
Load Register Pair HL with 5ABAH, the question SOFT OR HARD FORM FEED (S/H)? ended by 03H.
5943
LD BC,4853H 01 53 48
Load Register Pair BC with 4853H: Register B = 48H (H), Register C = 53H (S), the two answers allowed.
5946
GOSUB to 5A1BH to ask the question at Register Pair HL until the answer is the letter in Register B or Register C: the Z FLAG for H, the NZ FLAG for S.
5949
LD HL,5548H 21 48 55
Load Register Pair HL with 5548H, the operand of the LD A,nn at 5547H: the form feed kind. LD does not change the flags.
594C
LD (HL),00H 36 00
Store 00H at Register Pair HL (5548H): the hard form feed, a 0CH byte (555BH).
594E
If the Z FLAG is set (the answer H), JUMP to 595AH with the hard form feed: no total lines are needed.
5950
INC (HL) 34
The answer S: increment the byte at Register Pair HL (5548H) to 01H, the soft form feed with carriage returns (5566H).
5951
LD HL,5AD8H 21 D8 5A
Load Register Pair HL with 5AD8H, the question TOTAL LINES PER PAGE (10-99)? ended by 03H.
5954
GOSUB to 5A3AH to ask the question at Register Pair HL until two characters are typed: Register A = their value.
5957
LD (554EH),A 32 4E 55
Store Register A (the total lines per page) at 554EH, the operand of the SUB at 554DH.
595A
LD HL,5B14H 21 14 5B
Load Register Pair HL with 5B14H, the question TOP-OF-FORM AT END OF FILE (Y/N)? ended by 03H.
595D
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
5960
LD HL,55BBH 21 BB 55
Load Register Pair HL with 55BBH, the CALL NZ,555BH at the end of a spool file. LD does not change the flags.
5963
LD (HL),C4H 36 C4
Store C4H (CALL NZ) at Register Pair HL (55BBH): a form feed ends every spool file that has lines on its last page.
5965
If the Z FLAG is set (Y), JUMP to 5969H and keep the CALL NZ.
5967
LD (HL),11H 36 11
Store 11H at Register Pair HL (55BBH): the three bytes become LD DE,555BH and no form feed is done.
5969
LD HL,5B36H 21 36 5B
Load Register Pair HL with 5B36H, the question LINE FEED ON CARRIAGE RETURN (Y/N)? ended by 03H.
596C
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
596F
LD HL,57D5H 21 D5 57
Load Register Pair HL with 57D5H, the RET after a printed carriage return. LD does not change the flags.
5972
LD (HL),00H 36 00
Store 00H (NOP) at Register Pair HL (57D5H): 57D6H puts a line feed after every carriage return.
5974
If the Z FLAG is set (Y), JUMP to 5978H and keep the NOP.
5976
LD (HL),C9H 36 C9
Store C9H (RET) at Register Pair HL (57D5H): no line feed is added.

Loop Start
Ask for the spool drive until one character 0-3 is typed.

5978
LD HL,5B5AH 21 5A 5B
Load Register Pair HL with 5B5AH, the question DRIVE # FOR POOL FILES (0-3)? ended by 03H.
597B
GOSUB to 5A2FH to show the question at Register Pair HL and read up to one character: Register Pair HL = 5C44H, Register B = the characters typed.
597E
Decrement Register B (the characters typed); if it is not 0 (nothing was typed), LOOP back to 5978H.
5980
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (5C44H), the character typed.
5981
SUB 30H D6 30
Subtract 30H from Register A, turning the ASCII digits 0-9 into 00H-09H.
5983
CP 04H FE 04
Compare Register A (the digit value) against 04H. The NO CARRY FLAG is set for anything but 0-3.
5985
If the NO CARRY FLAG is set (not 0-3), LOOP back to 5978H.

Loop End

5987
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL (5C44H), the drive digit as typed (ASCII).
5988
LD (5824H),A 32 24 58
Store Register A (the drive digit) at 5824H, the drive position in the template POOLn:d.
598B
LD HL,5B78H 21 78 5B
Load Register Pair HL with 5B78H, the question # SECONDS PRINT DELAY AFTER LATEST INPUT KEY (00-59)? ended by 03H.
598E
GOSUB to 5A3AH to ask the question at Register Pair HL until two characters are typed: Register A = their value (no range check).
5991
LD (577EH),A 32 7E 57
Store Register A (the delay in seconds) at 577EH, the operand of the CP at 577DH.
5994
LD HL,5BAFH 21 AF 5B
Load Register Pair HL with 5BAFH, the question INTERRUPTS ALSO DRIVE PRINTER (Y/N)? ended by 03H.
5997
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
599A
LD HL,5DB4H 21 B4 5D
Load Register Pair HL with 5DB4H, the operand of the LD A,nn at 5DB3H: enqueue the timer routine at activation. LD does not change the flags.
599D
LD (HL),01H 36 01
Store 01H at Register Pair HL (5DB4H): the timer routine is enqueued.
599F
If the Z FLAG is set (Y), JUMP to 59A2H and keep 01H.
59A1
DEC (HL) 35
Decrement the byte at Register Pair HL (5DB4H) to 00H: no timer routine.
59A2
LD HL,5BD4H 21 D4 5B
Load Register Pair HL with 5BD4H, the question USE CIRCULAR BUFFER (Y/N)? ended by 03H.
59A5
GOSUB to 5A18H to ask the question at Register Pair HL until the answer is Y or N: the Z FLAG for Y.
59A8
LD HL,5C88H 21 88 5C
Load Register Pair HL with 5C88H, the operand of the LD A,nn at 5C87H: use the circular buffer. LD does not change the flags.
59AB
LD (HL),01H 36 01
Store 01H at Register Pair HL (5C88H): the circular buffer is used.
59AD
If the Z FLAG is set (Y), JUMP to 59B0H and keep 01H.
59AF
DEC (HL) 35
Decrement the byte at Register Pair HL (5C88H) to 00H: no circular buffer.

59B0H - Write the Working Module With DUMP

The command at 5C11H is completed: the three hex addresses 5450H (start), 5DD0H (end) and 5C4BH (entry) and the filespec typed by the user. It is run through DOS-CALL (4419H), so SYS7's DUMP writes the changed program 5450H-5DD0H to the new file with its transfer address 5C4BH.

59B0
LD DE,5450H 11 50 54
Load Register Pair DE with 5450H, the first address to write, the start of the program.
59B3
LD HL,5C32H 21 32 5C
Load Register Pair HL with 5C32H, the first hex field of the DUMP command.
59B6
GOSUB to 59FDH to write Register Pair DE (5450H) as four hex digits at Register Pair HL (5C32H). Register Pair HL ends past them.
59B9
LD DE,5DD0H 11 D0 5D
Load Register Pair DE with 5DD0H, the last address to write, the end of the program.
59BC
LD HL,5C38H 21 38 5C
Load Register Pair HL with 5C38H, the second hex field of the DUMP command.
59BF
GOSUB to 59FDH to write Register Pair DE (5DD0H) as four hex digits at Register Pair HL (5C38H).
59C2
LD DE,5C4BH 11 4B 5C
Load Register Pair DE with 5C4BH, the entry address of the working module.
59C5
LD HL,5C3EH 21 3E 5C
Load Register Pair HL with 5C3EH, the third hex field of the DUMP command.
59C8
GOSUB to 59FDH to write Register Pair DE (5C4BH) as four hex digits at Register Pair HL (5C3EH).
59CB
LD HL,5BEFH 21 EF 5B
Load Register Pair HL with 5BEFH, the question NEW SPOOL PROGRAM FILESPEC? ended by 03H.
59CE
GOSUB to SYS0 4467H to display the question at Register Pair HL (5BEFH); it ends with 03H, so the cursor stays after it.
59D1
LD HL,5C16H 21 16 5C
Load Register Pair HL with 5C16H, the filespec field of the DUMP command.
59D4
LD B,1AH 06 1A
Load Register B with 1AH, at most 26 characters for the filespec.
59D6
GOSUB to the ROM line input at 0040H (KEYIN) with Register Pair HL = 5C16H and Register B = 1AH: the filespec is typed over the placeholder and ended by 0DH.
59D9
LD B,1CH 06 1C
Load Register B with 1CH, the 28 bytes from 5C31H down to 5C16H.
59DB
LD HL,5C31H 21 31 5C
Load Register Pair HL with 5C31H, the last byte of the filespec field.

Loop Start
From 5C31H down to the 0DH the line input left after the filespec, every byte becomes a space, the 0DH included: the rest of the placeholder is blanked.

59DE
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, a byte of the filespec field.
59DF
CP 0DH FE 0D
Compare Register A (the byte) against 0DH, the end of the typed filespec.
59E1
LD (HL),20H 36 20
Store 20H (a space) at Register Pair HL. LD does not change the flags.
59E3
DEC HL 2B
Decrement Register Pair HL to the byte before. DEC HL does not change the flags.
59E4
If the Z FLAG is set (the 0DH was reached), JUMP to 59E8H.
59E6
Decrement Register B (the bytes left); if it is not 0, LOOP back to 59DEH.

Loop End

59E8
LD HL,5C11H 21 11 5C
Load Register Pair HL with 5C11H, the command DUMP filespec 5450H 5DD0H 5C4BH ended by 0DH.
59EB
GOSUB to SYS0 4419H, DOS-CALL, to run the command at Register Pair HL (5C11H). Register A returns the error code: the CARRY FLAG if the error was already displayed, the NZ FLAG for an error not yet shown.
59EE
If the CARRY FLAG is set (the error has been shown), JUMP to SYS0 402DH, DOS READY.
59F1
If the NZ FLAG is set (Register A = the error code), JUMP to SYS0 4409H to display it and end at DOS READY.
59F4
LD HL,5C0CH 21 0C 5C
Load Register Pair HL with 5C0CH, the message DONE ended by 0DH.
59F7
GOSUB to SYS0 4467H to display the message at Register Pair HL (5C0CH).
59FA
JUMP to SYS0 402DH, DOS READY: the working module has been written.

59FDH - Hex Digits

59FDH writes Register Pair DE as four hex digits at Register Pair HL, 5A02H Register A as two, 5A0BH the low four bits of Register A as one. Register Pair HL is moved past what is written.

59FD
LD A,D 7A
Load Register A with Register D, the high byte of the address to write.
59FE
GOSUB to 5A02H to write Register A (the high byte) as two hex digits at Register Pair HL.
5A01
LD A,E 7B
Load Register A with Register E, the low byte of the address. Fall into 5A02H to write it.
5A02
PUSH AF F5
Save Register Pair AF (Register A = the byte to write) on the stack.
5A03
RRCA 0F
Rotate Register A (the byte) right one bit, the first of four.
5A04
RRCA 0F
Rotate Register A (the byte) right a second bit, the second of four.
5A05
RRCA 0F
Rotate Register A (the byte) right a third bit, the third of four.
5A06
RRCA 0F
Rotate Register A right a fourth bit: the high four bits of the byte are now in bits 0-3 of Register A.
5A07
GOSUB to 5A0BH to write the low four bits of Register A (the byte's high digit) at Register Pair HL.
5A0A
POP AF F1
Restore Register Pair AF from the stack: Register A = the byte again. Fall into 5A0BH for its low digit.
5A0B
AND 0FH E6 0F
AND Register A with 0FH, keeping bits 0-3: the digit value 00H-0FH.
5A0D
CP 0AH FE 0A
Compare Register A (the digit value) against 0AH. The CARRY FLAG is set for 0-9.
5A0F
If the CARRY FLAG is set (0-9), JUMP to 5A13H.
5A11
ADD A,07H C6 07
Add 07H to Register A (0AH-0FH), so that the ADD at 5A13H gives the ASCII letters A-F.
5A13
ADD A,30H C6 30
Add 30H to Register A, turning the digit value into its ASCII character.
5A15
LD (HL),A 77
Store Register A (the ASCII digit) at Register Pair HL.
5A16
INC HL 23
Increment Register Pair HL to the next position.
5A17
RET C9
RETURN with Register Pair HL past the digit written.

5A18H - Ask a Question With Two Letter Answers

5A18H asks a Y/N question; 5A1BH any question whose answers are the letters in Register B and Register C. The question at Register Pair HL is shown and the answer read (5A2FH) until exactly one character is typed and it is one of the two letters. Returns the Z FLAG for the letter in Register B, the NZ FLAG for the one in Register C, and Register Pair DE = 5C44H, the answer.

5A18
LD BC,594EH 01 4E 59
Load Register Pair BC with 594EH: Register B = 59H (Y), Register C = 4EH (N).

Loop Start

5A1B
PUSH HL E5
Save Register Pair HL (the question) on the stack.
5A1C
PUSH BC C5
Save Register Pair BC (Register B and Register C = the two letters) on the stack.
5A1D
GOSUB to 5A2FH to show the question at Register Pair HL and read up to one character: Register Pair HL = 5C44H, Register B = the characters typed.
5A20
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = 5C44H, the answer.
5A21
DEC B 05
Decrement Register B (the characters typed): the Z FLAG is set if exactly one was typed.
5A22
POP BC C1
Restore Register Pair BC from the stack: the two letters. POP does not change the flags.
5A23
POP HL E1
Restore Register Pair HL from the stack: the question.
5A24
If the NZ FLAG is set (nothing typed), LOOP back to 5A1BH to ask again.
5A26
LD A,(DE) 1A
Load Register A with the byte at Register Pair DE (5C44H), the letter typed.
5A27
CP B B8
Compare Register A (the letter) against Register B, the first allowed letter.
5A28
If the Z FLAG is set (the first letter), JUMP to 5A2DH.
5A2A
CP C B9
Compare Register A (the letter) against Register C, the second allowed letter.
5A2B
If the NZ FLAG is set (neither letter), LOOP back to 5A1BH to ask again.

Loop End

5A2D
CP B B8
Compare Register A (the letter) against Register B again: the Z FLAG for the first letter, the NZ FLAG for the second.
5A2E
RET C9
RETURN with the flags from the compare and Register A = the letter.

5A2FH - Show a Question and Read One Character

Displays the question at Register Pair HL and reads up to one character into 5C44H with the ROM line input. Returns Register Pair HL = 5C44H and Register B = the number of characters typed (0 or 1); the 0DH follows at 5C45H.

5A2F
GOSUB to SYS0 4467H to display the question at Register Pair HL; it ends with 03H, so the cursor stays after it.
5A32
LD B,01H 06 01
Load Register B with 01H, the most characters the line input may take.
5A34
LD HL,5C44H 21 44 5C
Load Register Pair HL with 5C44H, the one-character answer buffer.
5A37
JUMP to the ROM line input at 0040H (KEYIN) with Register Pair HL = 5C44H and Register B = 01H; its RET returns to the caller with Register B = the characters typed.

5A3AH - Ask for a Two-Digit Number

Shows the question at Register Pair HL and reads up to two characters into 5C46H until exactly two are typed; their value is taken with the ROM's number conversion FIN (0E6CH). The ranges in the questions (10-99, 00-59) are not checked, and characters that are not digits are not refused. Returns Register A = the low byte of the value from 4121H; Register Pair DE = the question.

5A3A
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the question, for the exchange at 5A3BH.

Loop Start

5A3B
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the question (also when 5A4CH comes back with it in Register Pair DE).
5A3C
PUSH HL E5
Save Register Pair HL (the question) on the stack.
5A3D
GOSUB to SYS0 4467H to display the question at Register Pair HL; it ends with 03H, so the cursor stays after it.
5A40
LD B,02H 06 02
Load Register B with 02H, the most characters the line input may take.
5A42
LD HL,5C46H 21 46 5C
Load Register Pair HL with 5C46H, the two-character answer buffer.
5A45
GOSUB to the ROM line input at 0040H (KEYIN) with Register Pair HL = 5C46H and Register B = 02H: Register B returns the characters typed, the text is ended by 0DH.
5A48
POP DE D1
Restore Register Pair DE from the stack: the question.
5A49
LD A,B 78
Load Register A with Register B, the number of characters typed.
5A4A
CP 02H FE 02
Compare Register A (the characters typed) against 02H.
5A4C
If the NZ FLAG is set (not exactly two), LOOP back to 5A3BH to ask again.

Loop End

5A4E
GOSUB to the ROM's FIN at 0E6CH to convert the number at Register Pair HL (5C46H): the value goes into the ROM's accumulator, the integer at 4121H.
5A51
LD A,(4121H) 3A 21 41
Load Register A with the byte at 4121H, the low byte of the converted value.
5A54
RET C9
RETURN with Register A = the low byte of the number typed.

5A55H - Setup Questions

The questions of filespec,I, each ended by 03H so the answer is typed on the same line. 4467H displays them.

5A55-5A77
DEFM "USE EXISTING PRINTER DRIVER (Y/N)?", 03H 55 53 45 20 45 58 49 53 54 49 4E 47 20 50 52 49 4E 54 45 52 20 44 52 49 56 45 52 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 58FAH and shown with the answer read after it.
5A78-5A99
DEFM "PARALLEL OR SERIAL PRINTER (P/S)?", 03H 50 41 52 41 4C 4C 45 4C 20 4F 52 20 53 45 52 49 41 4C 20 50 52 49 4E 54 45 52 20 28 50 2F 53 29 3F 03
Setup question, loaded at 5909H and shown with the answer read after it.
5A9A-5AAC
DEFM "H14 PRINTER (Y/N)?", 03H 48 31 34 20 50 52 49 4E 54 45 52 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 5916H and shown with the answer read after it.
5AAD-5AB9
DEFM "PAGES (Y/N)?", 03H 50 41 47 45 53 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 5928H and shown with the answer read after it.
5ABA-5AD7
DEFM "SOFT OR HARD FORM FEED (S/H)?", 03H 53 4F 46 54 20 4F 52 20 48 41 52 44 20 46 4F 52 4D 20 46 45 45 44 20 28 53 2F 48 29 3F 03
Setup question, loaded at 5940H and shown with the answer read after it. The answer H gives the hard form feed (0CH), S the soft one (594EH).
5AD8-5AF5
DEFM "TOTAL LINES PER PAGE (10-99)?", 03H 54 4F 54 41 4C 20 4C 49 4E 45 53 20 50 45 52 20 50 41 47 45 20 28 31 30 2D 39 39 29 3F 03
Setup question, loaded at 5951H and shown with the answer read after it. The range 10-99 is not checked by 5A3AH.
5AF6-5B13
DEFM "PRINT LINES PER PAGE (10-99)?", 03H 50 52 49 4E 54 20 4C 49 4E 45 53 20 50 45 52 20 50 41 47 45 20 28 31 30 2D 39 39 29 3F 03
Setup question, loaded at 5937H and shown with the answer read after it. The range 10-99 is not checked by 5A3AH.
5B14-5B35
DEFM "TOP-OF-FORM AT END OF FILE (Y/N)?", 03H 54 4F 50 2D 4F 46 2D 46 4F 52 4D 20 41 54 20 45 4E 44 20 4F 46 20 46 49 4C 45 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 595AH and shown with the answer read after it.
5B36-5B59
DEFM "LINE FEED ON CARRIAGE RETURN (Y/N)?", 03H 4C 49 4E 45 20 46 45 45 44 20 4F 4E 20 43 41 52 52 49 41 47 45 20 52 45 54 55 52 4E 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 5969H and shown with the answer read after it.
5B5A-5B77
DEFM "DRIVE # FOR POOL FILES (0-3)?", 03H 44 52 49 56 45 20 23 20 46 4F 52 20 50 4F 4F 4C 20 46 49 4C 45 53 20 28 30 2D 33 29 3F 03
Setup question, loaded at 5978H and shown with the answer read after it.
5B78-5BAE
DEFM "# SECONDS PRINT DELAY AFTER LATEST INPUT KEY (00-59)?", 03H 23 20 53 45 43 4F 4E 44 53 20 50 52 49 4E 54 20 44 45 4C 41 59 20 41 46 54 45 52 20 4C 41 54 45 53 54 20 49 4E 50 55 54 20 4B 45 59 20 20 28 30 30 2D 35 39 29 3F 03
Setup question, loaded at 598BH and shown with the answer read after it. The range 00-59 is not checked by 5A3AH.
5BAF-5BD3
DEFM "INTERRUPTS ALSO DRIVE PRINTER (Y/N)?", 03H 49 4E 54 45 52 52 55 50 54 53 20 41 4C 53 4F 20 44 52 49 56 45 20 50 52 49 4E 54 45 52 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 5994H and shown with the answer read after it.
5BD4-5BEE
DEFM "USE CIRCULAR BUFFER (Y/N)?", 03H 55 53 45 20 43 49 52 43 55 4C 41 52 20 42 55 46 46 45 52 20 28 59 2F 4E 29 3F 03
Setup question, loaded at 59A2H and shown with the answer read after it.
5BEF-5C0B
DEFM "NEW SPOOL PROGRAM FILESPEC? ", 03H 4E 45 57 20 53 50 4F 4F 4C 20 50 52 4F 47 52 41 4D 20 46 49 4C 45 53 50 45 43 3F 20 03
Setup question, loaded at 59CBH and shown with the answer read after it.
5C0C-5C10
DEFM "DONE", 0DH 44 4F 4E 45 0D
Shown by 59F7H after DUMP has written the working module.

5C11H - The DUMP Command

Run through DOS-CALL at 59EBH. 59D6H types the filespec over the placeholder 5C16H-5C30H and 59DEH blanks what is left of it; 59B6H, 59BFH and 59C8H fill in the three hex fields. SYS7's DUMP takes spaces as separators, so the finished line is DUMP filespec 5450H 5DD0H 5C4BH.

5C11-5C15
DEFM "DUMP " 44 55 4D 50 20
The DOS command DUMP and a space, the start of the line run by 59EBH.
5C16-5C30
DEFM "NNNNNNNN/TTT.PPPPPPPP:254 " 4E 4E 4E 4E 4E 4E 4E 4E 2F 54 54 54 2E 50 50 50 50 50 50 50 50 3A 32 35 34 20 20
The placeholder for the filespec of the working module: up to 26 characters are typed here (59D6H), the rest is turned into spaces (59DEH).
5C31
DEFB 20H 20
The space after the filespec field; 59DBH starts blanking from here.
5C32-5C37
DEFM "0000H " 30 30 30 30 48 20
The start address, 5450H after 59B6H, and a space.
5C38-5C3D
DEFM "0000H " 30 30 30 30 48 20
The end address, 5DD0H after 59BFH, and a space.
5C3E-5C43
DEFM "0000H", 0DH 30 30 30 30 48 0D
The entry address, 5C4BH after 59C8H, and the 0DH that ends the command.

5C44H - Answer Buffers

Used by the ROM line input during setup.

5C44-5C45
DEFB 20H, 20H 20 20
The one-character answer buffer of 5A2FH: the character at 5C44H, the 0DH after it at 5C45H.
5C46-5C48
DEFB 20H, 20H, 00H 20 20 00
The two-character answer buffer of 5A3AH: the digits at 5C46H-5C47H, the 0DH at 5C48H, where FIN stops.
5C49-5C4A
DEFB 00H, 00H 00 00
Two zero bytes after the answer buffers that no instruction names.

5C4BH - Program Entry: filespec,I or filespec,A

The transfer address of ASPOOL/MAS and of every working module. SYS2 runs the program with Register Pair HL past the filespec and its comma, at the option letter (or at the 0DH when none was typed). I sets up a working module (58FAH); A activates the spooler; anything else is BAD PARAMETER(S).

5C4B
GOSUB to 547DH with Register Pair HL at the option letter: the letter must end the command line. Register A returns the letter.
5C4E
CP 49H FE 49
Compare Register A (the option letter) against 49H, ASCII I.
5C50
If the Z FLAG is set (I), JUMP to 58FAH to ask the setup questions and write a working module.
5C53
CP 41H FE 41
Compare Register A (the option letter) against 41H, ASCII A.
5C55
If the NZ FLAG is set (neither I nor A), JUMP to 5478H for error 2FH, BAD PARAMETER(S).

5C58H - filespec,A: Empty the Old Pool Files

The five files POOL1:d to POOL5:d on the spool drive are opened if they exist and emptied (EOF 0, close), so nothing spooled before is printed and their space is free.

5C58
LD A,01H 3E 01
Load Register A with 01H, the first pool file number.
5C5A
LD DE,5400H 11 00 54
Load Register Pair DE with 5400H, the FCB used here (the print FCB of the resident part, not yet relocated).

Loop Start

5C5D
PUSH AF F5
Save Register Pair AF (Register A = the pool file number) on the stack.
5C5E
GOSUB to 5651H with Register A = the pool file number and Register Pair DE = 5400H: POOLn:d is copied into the FCB; Register Pair HL returns 5826H.
5C61
LD B,00H 06 00
Load Register B with 00H, the logical record length (256) for the open.
5C63
GOSUB to SYS0 4424H to open the existing file named in the FCB at Register Pair DE (5400H), with Register Pair HL = 5826H as the buffer address (no sector is read through it) and Register B = 00H. The Z FLAG returns set if the file exists.
5C66
If the Z FLAG is set (the file exists), GOSUB to 5745H with Register Pair DE = 5400H to set its EOF to 0 and close it.
5C69
POP AF F1
Restore Register Pair AF from the stack: Register A = the pool file number.
5C6A
INC A 3C
Increment Register A to the next pool file number.
5C6B
CP 06H FE 06
Compare Register A (the next number) against 06H. The CARRY FLAG is set for 1-5.
5C6D
If the CARRY FLAG is set (more pool files), LOOP back to 5C5DH.

Loop End

5C6FH - Keep the Old Drivers and Apply the Options

The printer driver (4026H) and keyboard driver (4016H) found now are stored into the code that calls or restores them. Without the interrupt option the keyboard check calls the old keyboard driver instead of the ROM's; without the circular buffer the spooler's keyboard driver calls the old one and the keyboard check is a RET.

5C6F
LD HL,(4026H) 2A 26 40
Load Register Pair HL with the 16-bit value at 4026H, the printer driver address in the printer device control block.
5C72
LD (5708H),HL 22 08 57
Store Register Pair HL (the printer driver) at 5708H, the operand of the LD HL,nnnn at 5707H: the purge puts it back.
5C75
LD (57A4H),HL 22 A4 57
Store Register Pair HL (the printer driver) at 57A4H, the operand of the CALL at 57A3H: used when the printer kind is 02H.
5C78
LD HL,(4016H) 2A 16 40
Load Register Pair HL with the 16-bit value at 4016H, the keyboard driver address in the keyboard device control block.
5C7B
LD (570EH),HL 22 0E 57
Store Register Pair HL (the keyboard driver) at 570EH, the operand of the LD HL,nnnn at 570DH: the purge puts it back.
5C7E
LD A,(5DB4H) 3A B4 5D
Load Register A with the byte at 5DB4H, the operand of the LD A,nn at 5DB3H: 01H when the timer interrupts drive the printer.
5C81
OR A B7
OR Register A (the interrupt option) with itself to set the flags. The NZ FLAG is set for the option Y.
5C82
If the NZ FLAG is set (interrupts used), JUMP to 5C87H: the keyboard check keeps calling the ROM's keyboard driver 03E3H.
5C84
LD (57E3H),HL 22 E3 57
Store Register Pair HL (the old keyboard driver) at 57E3H, the operand of the CALL at 57E2H: the keyboard check calls it instead of the ROM's.
5C87
LD A,01H 3E 01
Self-Modifying Code
Load Register A with the operand at 5C88H: 01H when the circular buffer is used, 00H when not, stored by setup at 59ABH and 59AFH (01H in the file).
5C89
OR A B7
OR Register A (the circular buffer option) with itself to set the flags. The NZ FLAG is set for the option Y.
5C8A
If the NZ FLAG is set (circular buffer used), JUMP to 5C94H.
5C8C
LD (5662H),HL 22 62 56
Store Register Pair HL (the old keyboard driver) at 5662H, the operand of the CALL at 5661H: the spooler's keyboard driver takes its keys from the old driver.
5C8F
LD A,C9H 3E C9
Load Register A with C9H, the opcode of RET, for 57DDH.
5C91
LD (57DDH),A 32 DD 57
Store Register A (C9H) at 57DDH: the keyboard check into the circular buffer returns at once.

5C94H - Set Up the RS-232 Board for a Serial Printer

Only for the printer kind 00H. The UART is reset (port E8H), its control register is loaded from the board's switches (port E9H bits 3-7) with bit 2, transmit enable, set (port EAH), and its baud rate is set from switch bits 0-2 through the table at 5DBCH (port E9H).

5C94
LD A,(5792H) 3A 92 57
Load Register A with the byte at 5792H, the operand of the LD A,nn at 5791H: the printer kind (00H serial, 01H parallel, 02H old driver).
5C97
OR A B7
OR Register A (the printer kind) with itself to set the flags. The Z FLAG is set for the serial printer.
5C98
If the NZ FLAG is set (not serial), JUMP to 5CB2H.
5C9A
OUT (E8H),A D3 E8
Output Register A (00H) to port E8H: any write there resets the UART.
5C9C
IN A,(E9H) DB E9
Load Register A from port E9H, the switches on the RS-232 board (bit 7 parity, bits 5-6 word length, bit 4 stop bits, bit 3 parity disable).
5C9E
AND F8H E6 F8
AND Register A (the switches) with F8H, keeping bits 3-7.
5CA0
OR 04H F6 04
OR Register A with 04H, setting bit 2: transmit enable; bits 0 and 1 clear turn on RTS and DTR.
5CA2
OUT (EAH),A D3 EA
Output Register A (the UART control byte) to port EAH, the UART control register.
5CA4
IN A,(E9H) DB E9
Load Register A from port E9H, the switches again.
5CA6
AND 07H E6 07
AND Register A (the switches) with 07H, keeping bits 0-2: the baud rate switch, 0-7.
5CA8
LD HL,5DBCH 21 BC 5D
Load Register Pair HL with 5DBCH, the baud rate table.
5CAB
LD C,A 4F
Load Register C with Register A, the baud rate switch.
5CAC
LD B,00H 06 00
Load Register B with 00H, so that Register Pair BC = the switch value.
5CAE
ADD HL,BC 09
Add Register Pair BC (the switch value) to Register Pair HL (5DBCH): Register Pair HL = the table entry.
5CAF
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the baud rate code from the table.
5CB0
OUT (E9H),A D3 E9
Output Register A (the baud rate code) to port E9H, the baud rate generator: the same rate for sending and receiving.

5CB2H - Copy the Spooler to the Top of Memory

The area 5200H-58F9H (06FAH bytes: 250H bytes of buffers, then the code and data from 5450H) is placed just below HIMEM: the new HIMEM is HIMEM - 06FAH, the area starts 1 above it, and 5450H-58F9H is copied to the area start + 250H. The difference between the copy and the original (the area start - 5200H) is kept on the stack for the relocation.

5CB2
LD HL,(4049H) 2A 49 40
Load Register Pair HL with the 16-bit value at 4049H, HIMEM: the highest address free for programs.
5CB5
LD BC,06FAH 01 FA 06
Load Register Pair BC with 06FAH, the size of the spooler's area 5200H-58F9H.
5CB8
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5CB9
SBC HL,BC ED 42
Subtract Register Pair BC (06FAH) from Register Pair HL (HIMEM): Register Pair HL = the new HIMEM, just below the area.
5CBB
PUSH HL E5
Save Register Pair HL (the new HIMEM) on the stack, for 5D9BH.
5CBC
INC HL 23
Increment Register Pair HL to the area start, the copy's 5200H.
5CBD
LD DE,0250H 11 50 02
Load Register Pair DE with 0250H, the distance from 5200H to 5450H.
5CC0
ADD HL,DE 19
Add Register Pair DE (0250H) to Register Pair HL (the area start): Register Pair HL = the copy's 5450H.
5CC1
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copy's 5450H, the destination.
5CC2
LD HL,5450H 21 50 54
Load Register Pair HL with 5450H, the *name block, the first byte to copy.
5CC5
LD BC,000CH 01 0C 00
Load Register Pair BC with 000CH, the 12 bytes of the block before its code.
5CC8
LDIR ED B0
Copy Register Pair BC (12) bytes from Register Pair HL (5450H) to Register Pair DE (the copy's 5450H). Register Pair HL ends at 545CH, Register Pair DE at the copy's 545CH.
5CCA
PUSH DE D5
Save Register Pair DE (the copy's 545CH) on the stack.
5CCB
PUSH HL E5
Save Register Pair HL (545CH, the original code start) on the stack.
5CCC
LD BC,049EH 01 9E 04
Load Register Pair BC with 049EH, the bytes from 545CH to 58F9H.
5CCF
LDIR ED B0
Copy Register Pair BC (049EH) bytes from Register Pair HL (545CH) to Register Pair DE (the copy's 545CH): the code and the resident data are copied.
5CD1
POP DE D1
Restore Register Pair DE from the stack: 545CH.
5CD2
POP HL E1
Restore Register Pair HL from the stack: the copy's 545CH.
5CD3
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5CD4
SBC HL,DE ED 52
Subtract Register Pair DE (545CH) from Register Pair HL (the copy's 545CH): Register Pair HL = the relocation offset, the area start - 5200H.
5CD6
PUSH HL E5
Save Register Pair HL (the relocation offset) on the stack, for 5D25H and 5D8EH.
5CD7
ADD HL,DE 19
Add Register Pair DE (545CH) to Register Pair HL (the offset): Register Pair HL = the copy's 545CH again.
5CD8
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copy's 545CH.
5CD9
LD HL,03C1H 21 C1 03
Load Register Pair HL with 03C1H, the length of the code 545CH-581CH.
5CDC
ADD HL,DE 19
Add Register Pair DE (the copy's 545CH) to Register Pair HL (03C1H): Register Pair HL = the copy's 581DH, the end of the code.
5CDD
LD B,H 44
Load Register B with Register H, the high byte of the end address.
5CDE
LD C,L 4D
Load Register C with Register L: Register Pair BC = the copy's 581DH, where the scan stops.
5CDF
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the copy's 545CH, the first instruction to look at.

5CE0H - Relocate the Copy

Walks the copied code instruction by instruction, working out each length from its opcode. Every instruction with a 16-bit address operand (LD rr,nn, LD (nn),HL and LD HL,(nn), LD (nn),A and LD A,(nn), JP, CALL, the conditional JP and CALL, ED-prefixed LD (nn),rr and LD rr,(nn)) has its operand moved by the offset when it lies in 5200H-58F9H. For a DD or FD prefix whose next byte is below 40H or from C0H up, the scan steps only over the prefix, so LD IX,nn and the like are relocated as LD HL,nn. Register Pair HL is the scan pointer, Register Pair BC the end, the offset is the word on top of the stack.

Loop Start

5CE0
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the opcode of the instruction to look at.
5CE1
CP C0H FE C0
Compare Register A (the opcode) against C0H. The NO CARRY FLAG is set for C0H-FFH.
5CE3
If the NO CARRY FLAG is set (C0H-FFH), JUMP to 5D39H.
5CE5
CP 40H FE 40
Compare Register A (the opcode) against 40H. The NO CARRY FLAG is set for 40H-BFH, the one-byte register loads and arithmetic.
5CE7
If the NO CARRY FLAG is set (40H-BFH), JUMP to 5D30H: one byte.
5CE9
AND 0FH E6 0F
Opcodes 00H-3FH: AND Register A with 0FH, keeping the low four bits.
5CEB
CP 01H FE 01
Compare Register A (the low four bits) against 01H, the LD rr,nn group 01H, 11H, 21H, 31H.
5CED
If the Z FLAG is set (LD rr,nn), JUMP to 5D0FH to relocate its operand.
5CEF
AND 07H E6 07
AND Register A with 07H, keeping the low three bits.
5CF1
If the NZ FLAG is set (the low three bits are not 0), JUMP to 5CF8H.
5CF3
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the opcode again (00H, 08H, 10H, 18H, 20H, 28H, 30H or 38H).
5CF4
CP 10H FE 10
Compare Register A (the opcode) against 10H. The NO CARRY FLAG is set for DJNZ and the JR group.
5CF6
If the NO CARRY FLAG is set (DJNZ or JR, two bytes), JUMP to 5D0CH.
5CF8
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the opcode.
5CF9
CP 20H FE 20
Compare Register A (the opcode) against 20H. The CARRY FLAG is set for 00H-1FH.
5CFB
If the CARRY FLAG is set (00H-1FH), JUMP to 5D03H.
5CFD
AND 07H E6 07
AND Register A (the opcode) with 07H, keeping the low three bits. 5D5FH comes here for C0H-FFH.
5CFF
CP 02H FE 02
Compare Register A (the low three bits) against 02H: 22H, 2AH, 32H, 3AH (LD with (nn)), or C2H-FAH (JP cc,nn).
5D01
If the Z FLAG is set, JUMP to 5D0FH to relocate the operand.
5D03
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the opcode.
5D04
AND 07H E6 07
AND Register A with 07H, keeping the low three bits.
5D06
CP 06H FE 06
Compare Register A (the low three bits) against 06H: LD r,n or an arithmetic instruction with a byte operand.
5D08
If the NZ FLAG is set (any other), JUMP to 5D30H: one byte.
5D0A
DEC HL 2B
Decrement Register Pair HL (the scan pointer), undone by the INC at 5D0BH: the two-byte case.
5D0B
INC HL 23
Increment Register Pair HL (the scan pointer). 5D73H and 5D78H come here for four-byte DD or FD instructions.
5D0C
INC HL 23
Increment Register Pair HL (the scan pointer). The two-byte instructions come here.
5D0D
JUMP to 5D30H to step past the last byte of the instruction.
5D0F
INC HL 23
Increment Register Pair HL (the scan pointer) to the low byte of the 16-bit operand.
5D10
LD E,(HL) 5E
Load Register E with the byte at Register Pair HL, the operand's low byte.
5D11
INC HL 23
Increment Register Pair HL to the operand's high byte.
5D12
LD D,(HL) 56
Load Register D with the byte at Register Pair HL: Register Pair DE = the operand.
5D13
PUSH HL E5
Save Register Pair HL (the operand's high byte address) on the stack.
5D14
LD HL,51FFH 21 FF 51
Load Register Pair HL with 51FFH, the address just below the spooler's area.
5D17
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5D18
SBC HL,DE ED 52
Subtract Register Pair DE (the operand) from Register Pair HL (51FFH). The NO CARRY FLAG is set if the operand is 51FFH or lower.
5D1A
If the NO CARRY FLAG is set (below the area), JUMP to 5D2FH and leave the operand.
5D1C
LD HL,58F9H 21 F9 58
Load Register Pair HL with 58F9H, the last address of the spooler's area.
5D1F
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction.
5D20
SBC HL,DE ED 52
Subtract Register Pair DE (the operand) from Register Pair HL (58F9H). The CARRY FLAG is set if the operand is above 58F9H.
5D22
If the CARRY FLAG is set (above the area), JUMP to 5D2FH and leave the operand.
5D24
POP HL E1
Restore Register Pair HL from the stack: the operand's high byte address.
5D25
EX (SP),HL E3
Exchange Register Pair HL with the word on top of the stack (at the Stack Pointer): Register Pair HL = the relocation offset, the stack holds the address.
5D26
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the operand, Register Pair DE = the offset.
5D27
ADD HL,DE 19
Add Register Pair DE (the offset) to Register Pair HL (the operand): the address in the copy.
5D28
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the new operand, Register Pair HL = the offset.
5D29
EX (SP),HL E3
Exchange Register Pair HL with the word on top of the stack (at the Stack Pointer): the offset goes back on the stack, Register Pair HL = the operand's high byte address.
5D2A
DEC HL 2B
Decrement Register Pair HL to the operand's low byte.
5D2B
LD (HL),E 73
Store Register E (the new operand's low byte) at Register Pair HL.
5D2C
INC HL 23
Increment Register Pair HL to the operand's high byte.
5D2D
LD (HL),D 72
Store Register D (the new operand's high byte) at Register Pair HL.
5D2E
PUSH HL E5
Save Register Pair HL (the operand's high byte address) on the stack, for the POP at 5D2FH.
5D2F
POP HL E1
Restore Register Pair HL from the stack: the operand's high byte address, the last byte of the instruction.
5D30
INC HL 23
Increment Register Pair HL (the scan pointer) to the next instruction.
5D31
OR A B7
OR Register A with itself to clear the CARRY FLAG for the compare. 5D7EH comes here without the INC.
5D32
SBC HL,BC ED 42
Subtract Register Pair BC (the copy's 581DH) from Register Pair HL (the scan pointer). The NO CARRY FLAG is set at or past the end; the Z FLAG exactly at it.
5D34
If the NO CARRY FLAG is set (the end of the code), JUMP to 5D82H with the Z FLAG telling whether the scan ended exactly on it.
5D36
ADD HL,BC 09
Add Register Pair BC back to Register Pair HL: the scan pointer again.
5D37
LOOP back to 5CE0H for the next instruction at Register Pair HL.
5D39
CP C3H FE C3
Compare Register A (the opcode, C0H-FFH) against C3H, JP nn.
5D3B
If the Z FLAG is set (JP nn), JUMP to 5D0FH to relocate its operand.
5D3D
CP CDH FE CD
Compare Register A (the opcode) against CDH, CALL nn.
5D3F
If the Z FLAG is set (CALL nn), JUMP to 5D0FH to relocate its operand.
5D41
CP DDH FE DD
Compare Register A (the opcode) against DDH, the Index Register IX prefix.
5D43
If the Z FLAG is set (DD prefix), JUMP to 5D6BH.
5D45
CP FDH FE FD
Compare Register A (the opcode) against FDH, the Index Register IY prefix.
5D47
If the Z FLAG is set (FD prefix), JUMP to 5D6BH.
5D49
CP EDH FE ED
Compare Register A (the opcode) against EDH, the extended prefix.
5D4B
If the Z FLAG is set (ED prefix), JUMP to 5D61H.
5D4D
CP CBH FE CB
Compare Register A (the opcode) against CBH, the bit instruction prefix.
5D4F
If the Z FLAG is set (CB, two bytes), JUMP to 5D0CH.
5D51
CP D3H FE D3
Compare Register A (the opcode) against D3H, OUT (n),A.
5D53
If the Z FLAG is set (OUT, two bytes), JUMP to 5D0CH.
5D55
CP DBH FE DB
Compare Register A (the opcode) against DBH, IN A,(n).
5D57
If the Z FLAG is set (IN, two bytes), JUMP to 5D0CH.
5D59
AND 07H E6 07
AND Register A (the opcode) with 07H, keeping the low three bits.
5D5B
CP 04H FE 04
Compare Register A (the low three bits) against 04H, CALL cc,nn (C4H-FCH).
5D5D
If the Z FLAG is set (CALL cc,nn), JUMP to 5D0FH to relocate its operand.
5D5F
JUMP to 5CFDH for JP cc,nn, the byte-operand instructions and the one-byte ones.
5D61
INC HL 23
ED prefix: increment Register Pair HL (the scan pointer) to the second byte.
5D62
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the second byte of the ED instruction.
5D63
AND C7H E6 C7
AND Register A with C7H, keeping bits 0-2 and 6-7.
5D65
CP 43H FE 43
Compare Register A against 43H: ED 43H, 4BH, 53H, 5BH, 63H, 6BH, 73H, 7BH, the 16-bit loads to and from memory.
5D67
If the Z FLAG is set (a 16-bit load with an address), JUMP to 5D0FH to relocate its operand.
5D69
JUMP to 5D30H: any other ED instruction is two bytes.
5D6B
INC HL 23
DD or FD prefix: increment Register Pair HL (the scan pointer) to the second byte.
5D6C
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the second byte.
5D6D
SUB 34H D6 34
Subtract 34H from Register A: INC (IX+d) and DEC (IX+d) become 00H and 01H, LD (IX+d),n becomes 02H.
5D6F
CP 02H FE 02
Compare Register A against 02H. The CARRY FLAG is set for 34H and 35H.
5D71
If the CARRY FLAG is set (INC or DEC with a displacement, three bytes), JUMP to 5D0CH.
5D73
If the Z FLAG is set (36H, LD (IX+d),n, four bytes), JUMP to 5D0BH.
5D75
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the second byte again.
5D76
CP CBH FE CB
Compare Register A (the second byte) against CBH, the bit instructions with a displacement.
5D78
If the Z FLAG is set (DD CB or FD CB, four bytes), JUMP to 5D0BH.
5D7A
SUB 40H D6 40
Subtract 40H from Register A (the second byte).
5D7C
CP 80H FE 80
Compare Register A against 80H. The NO CARRY FLAG is set for a second byte below 40H or from C0H up.
5D7E
If the NO CARRY FLAG is set, JUMP to 5D31H with Register Pair HL at the second byte: it is looked at as an opcode of its own, so LD IX,nn is relocated like LD HL,nn.
5D80
A second byte of 40H-BFH (a load or arithmetic with (IX+d), three bytes): JUMP to 5D0CH.

Loop End

5D82H - Install the Copy

The scan must end exactly on the copy's 581DH, else error 3AH. SPOOL ACTIVE is shown, the copy's *name block is put on SYS9's list (error 35H, FILE ALREADY EXISTS, if a spooler is already active), HIMEM is lowered, the printer and keyboard drivers are pointed into the copy, and with the interrupt option the copy's timer block is enqueued.

5D82
LD A,3AH 3E 3A
Load Register A with 3AH, the error code DATA COMPARE MISMATCH. LD does not change the flags.
5D84
If the NZ FLAG is set (the scan went past the end of the code), JUMP to SYS0 4409H to display error 3AH and end at DOS READY.
5D87
LD HL,5DC4H 21 C4 5D
Load Register Pair HL with 5DC4H, the message SPOOL ACTIVE ended by 0DH.
5D8A
GOSUB to SYS0 4467H to display the message at Register Pair HL (5DC4H). It is shown before the check at 5D97H.
5D8D
DI F3
Disable interrupts while the drivers and HIMEM are changed. They stay disabled if 5D97H takes the error exit.
5D8E
POP DE D1
Restore Register Pair DE from the stack: the relocation offset.
5D8F
LD HL,5450H 21 50 54
Load Register Pair HL with 5450H, the original *name block.
5D92
ADD HL,DE 19
Add Register Pair DE (the offset) to Register Pair HL (5450H): Register Pair HL = the copy's *name block.
5D93
PUSH DE D5
Save Register Pair DE (the offset) on the stack.
5D94
GOSUB to SYS0 4461H to put the *name block at Register Pair HL on SYS9's list. Register A returns 35H with the NZ FLAG if ASP is already there.
5D97
If the NZ FLAG is set (Register A = the error, 35H when a spooler is already active), JUMP to SYS0 4409H to display it and end at DOS READY. Nothing has been changed.
5D9A
POP DE D1
Restore Register Pair DE from the stack: the relocation offset.
5D9B
POP HL E1
Restore Register Pair HL from the stack: the new HIMEM, pushed at 5CBBH.
5D9C
LD (4049H),HL 22 49 40
Store Register Pair HL (the new HIMEM) at 4049H: the spooler's area is now above HIMEM.
5D9F
LD HL,550BH 21 0B 55
Load Register Pair HL with 550BH, the printer driver entry.
5DA2
ADD HL,DE 19
Add Register Pair DE (the offset) to Register Pair HL (550BH): the copy's printer driver entry.
5DA3
LD (4026H),HL 22 26 40
Store Register Pair HL (the copy's 550BH) at 4026H, the driver address of the printer device control block: printer output now goes to the spooler.
5DA6
LD HL,5661H 21 61 56
Load Register Pair HL with 5661H, the keyboard driver entry.
5DA9
ADD HL,DE 19
Add Register Pair DE (the offset) to Register Pair HL (5661H): the copy's keyboard driver.
5DAA
LD (4016H),HL 22 16 40
Store Register Pair HL (the copy's 5661H) at 4016H, the driver address of the keyboard device control block.
5DAD
LD HL,5755H 21 55 57
Load Register Pair HL with 5755H, the timer block.
5DB0
ADD HL,DE 19
Add Register Pair DE (the offset) to Register Pair HL (5755H): the copy's timer block.
5DB1
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the copy's timer block.
5DB2
EI FB
Enable interrupts again: the drivers and HIMEM point at the copy.
5DB3
LD A,01H 3E 01
Self-Modifying Code
Load Register A with the operand at 5DB4H: 01H when the timer interrupts drive the printer, 00H when not, stored by setup at 599DH and 59A1H (01H in the file).
5DB5
OR A B7
OR Register A (the interrupt option) with itself to set the flags. The NZ FLAG is set for the option Y.
5DB6
If the NZ FLAG is set (interrupts used), GOSUB to SYS0 4410H to put the timer block at Register Pair DE (the copy's 5755H) into the timer chain.
5DB9
JUMP to SYS0 402DH, DOS READY: the spooler is active.

5DBCH - Baud Rate Table and Message

The table is indexed by switch bits 0-2 of port E9H (5CA6H); each byte gives the same rate in both halves (high four bits sending, low four bits receiving).

5DBC-5DC3
DEFB 22H, 44H, 55H, 66H, 77H, AAH, CCH, EEH 22 44 55 66 77 AA CC EE
The baud rate codes for the switch values 0-7: 22H 100, 44H 150, 55H 300, 66H 600, 77H 1200, AAH 2400, CCH 4800, EEH 9600 baud, sent to port E9H by 5CB0H.
5DC4-5DD0
DEFM "SPOOL ACTIVE", 0DH 53 50 4F 4F 4C 20 41 43 54 49 56 45 0D
Shown by 5D8AH when the spooler is installed. 5DD0H, the 0DH, is the last byte of the file and the end address in the DUMP command (59B9H).