5450H - Program Header and Identification
This section contains the program identification string "ASP" (Apparat Spooler) padded with NOPs. The program entry point begins at 545BH.
5450
NOP 00
No operation - padding byte
5451
NOP 00
No operation - padding byte
5452
NOP 00
No operation - padding byte
5453
NOP 00
No operation - padding byte
5454
LD B,C 41
ASCII 'A' - forms "ASP" program identifier
5455
LD D,E 53
ASCII 'S' - second character of identifier
5456
LD D,B 50
ASCII 'P' - third character of identifier (Apparat Spooler Program)
5457H - Main Entry Point and Command Parser
Program entry point that parses the command line for spooler commands. Recognizes commands: P (Print), S (Stop), C (Clear), W (Write buffer to disk). Invalid commands result in a Syntax Error at 4409H. Entry: HL points to command line buffer. Exit: Jumps to appropriate command handler or returns via 402DH.
5457
Skip past spaces in command line - if current character is not a space (NZ FLAG set), jump to parse command at 5479H
5459
Continue skipping spaces - if not a space, jump to error handler
[MAIN COMMAND PARSER ENTRY] The main parsing loop begins here, examining each character in the command buffer
545B
If not a space, jump to user input handler at 54DBH (this appears to be the true entry point after space skipping)
545D
CP 0DH FE0D
Compare Register A with carriage return (0DH). If equal, Z FLAG is set (end of command line reached); otherwise NZ FLAG is set
545F
If Z FLAG is set (carriage return found, meaning no command specified), jump to status display routine at 5486H
Command character validation begins - Register A contains the command character to be tested
5461
Call subroutine at 547DH to get the next non-ENTER character from command line (advances HL past subsequent characters and loads A with last character before ENTER)
5464
CP 50H FE50
Compare Register A with 50H (ASCII 'P') for Print command. If equal, Z FLAG is set; otherwise NZ FLAG is set
5466
If Z FLAG is set (command is 'P'), jump to Print routine at 56F6H to activate printer output
5469
CP 53H FE53
Compare Register A with 53H (ASCII 'S') for Stop command. If equal, Z FLAG is set; otherwise NZ FLAG is set
546B
If Z FLAG is set (command is 'S'), jump to Stop spooler routine at 5505H
546E
CP 43H FE43
Compare Register A with 43H (ASCII 'C') for Clear command. If equal, Z FLAG is set; otherwise NZ FLAG is set
5470
If Z FLAG is set (command is 'C'), jump to Clear buffer routine at 54D5H
5473
CP 57H FE57
Compare Register A with 57H (ASCII 'W') for Write command. If equal, Z FLAG is set; otherwise NZ FLAG is set
5475
If Z FLAG is set (command is 'W'), jump to Write buffer to disk routine at 5501H
[INVALID COMMAND ERROR] No valid command was recognized, generate syntax error
5478
LD A,2FH 3E2F
Load Register A with 2FH (Syntax Error code) to indicate invalid command
547A
Jump to DOS error handler at 4409H to display Syntax Error message
547DH - Get Last Character Before ENTER
Subroutine that advances through the command line buffer to find the last character before the carriage return (ENTER). This allows parsing command modifiers that follow the main command. Entry: HL points to current position in command buffer. Exit: A contains last character before ENTER, HL points to that character.
547D
INC HL 23
Increment HL to point to next character in command buffer
547E
LD A,(HL) 7E
Load Register A with the character at current buffer position
547F
CP 0DH FE0D
Compare Register A with carriage return (0DH). If equal, Z FLAG is set (end of command found); otherwise NZ FLAG is set
5481
If NZ FLAG is set (not ENTER yet), jump back to 5478H to... ERROR: This should loop back to 547DH to continue scanning, but jumps to error handler instead - likely a bug or the code has been modified
5483
DEC HL 2B
Decrement HL to point back to the last character before the ENTER
5484
LD A,(HL) 7E
Load Register A with the last command character (before ENTER)
5485
RET C9
Return to caller with A containing the last character and HL pointing to it
5486H - Display Spool Status
Displays the current status of the spooler when no command is specified. Shows "SPOOL STATUS", whether output is currently being printed, number of files spooling, and backlog count. Entry: Called when ENTER is pressed without a command. Exit: Returns to DOS via 402DH.
[STATUS DISPLAY ROUTINE] Display main status header
5486
LD HL,5830H 213058
Load HL with 5830H (address of "SPOOL STATUS" + 0DH message string)
5489
Call DOS print string routine at 4467H to display "SPOOL STATUS"
Check if spooler is stopping
548C
LD A,(56F1H) 3AF156
Load Register A with stop flag byte at 56F1H (C9H = RET instruction means stopping, 00H means active)
548F
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H, Z FLAG is set (spooler active); if A≠00H (C9H), NZ FLAG is set (spooler stopping)
5490
If Z FLAG is set (stop flag is 00H, spooler active), jump to 549AH to display normal status
[STOPPING MESSAGE] Spooler is in the process of shutting down
5492
LD HL,587CH 217C58
Load HL with 587CH (address of "SPOOL STOPPING." + 0DH message)
5495
Call DOS print string routine to display stopping message
5498
Jump to 54A3H to continue with printing status display
[NORMAL STATUS] Display spooling count
549A
LD A,(5534H) 3A3455
Load Register A with spooling file count from 5534H (number of files currently being spooled)
549D
LD HL,5848H 214858
Load HL with 5848H (address of "SPOOLING: " + 03H message)
54A0
Call display routine at 54C5H to print "SPOOLING: " followed by the count in Register A
Display printing status
54A3
LD A,(5766H) 3A6657
Load Register A with printing flag from 5766H (non-zero if currently printing to physical printer)
54A6
LD HL,583DH 213D58
Load HL with 583DH (address of "PRINTING: " + 03H message)
54A9
Call display routine to print "PRINTING: " followed by the flag value
[BACKLOG DISPLAY LOOP] Count and display each pool's backlog
54AC
LD HL,5828H 212858
Load HL with 5828H (start of pool status table - first pool's status byte)
54AF
LD C,01H 0E01
Load Register C with 01H (pool counter, starting with pool 1)
54B1
LD A,(HL) 7E
[LOOP START] Load Register A with current pool's status byte (00H=empty, FFH=end marker, 01H-FEH=active)
54B2
INC A 3C
Increment Register A. If pool status was FFH (end marker), A becomes 00H and Z FLAG is set
54B3
INC HL 23
Increment HL to point to next pool's status byte
54B4
If Z FLAG is set (status was FFH = end of pool table), jump to DOS return routine at 402DH (status display complete)
54B7
CP 03H FE03
Compare Register A with 03H. After the INC, this tests if original status was 02H (active pool). If equal, Z FLAG is set; if greater, C FLAG is clear; if less, C FLAG is set
54B9
PUSH HL E5
Save HL (pointer to next pool) on the stack
54BA
LD A,C 79
Load Register A with Register C (current pool number for display)
54BB
LD HL,5853H 215358
Load HL with 5853H (address of "BACK LOG: " + 03H message)
54BE
INC C 0C
Increment Register C to advance pool counter for next iteration
54BF
If NC FLAG is set (status byte was ≥02H, meaning active pool), call display routine at 54C7H to print pool number
54C2
POP HL E1
Restore HL (pointer to next pool) from stack
54C3
[LOOP END] Jump back to 54B1H to process next pool in the table
54C5H - Display Number with Message
Conditionally displays a message with a numeric value. If the value in Register A is zero, returns immediately without displaying. Otherwise, converts the number to ASCII and displays the message. Entry: A contains numeric value to display, HL points to message string. Exit: Message displayed if A was non-zero.
54C5
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H, Z FLAG is set; otherwise NZ FLAG is set
54C6
RET Z C8
If Z FLAG is set (value is zero), return immediately without displaying anything
Convert number to ASCII and display
54C7
ADD 30H C630
Add 30H to Register A to convert numeric value (0-9) to ASCII digit ('0'-'9')
54C9
LD (5822H),A 322258
Store ASCII digit at 5822H (position within "POOL_:" message template where the digit appears)
54CC
Call DOS print string routine to display the complete message with embedded digit
54CF
LD HL,581EH 211E58
Load HL with 581EH (address of "POOL_:1" + 0DH message for single-digit display)
54D2
Jump to DOS print string routine to display trailing newline, then return to caller
54D5H - Clear Backlog Command Handler
Handles the 'C' (Clear) command which prompts the user to either clear the backlog or print it. Displays prompt and waits for 'B' (backlog clear) or 'P' (print) response. Entry: Called from command parser when 'C' command detected. Exit: Either clears buffer (returns via 402DH) or continues printing (jumps to 56C5H).
[CLEAR COMMAND HANDLER] Prompt user for clear or print option
54D5
LD HL,585EH 215E58
Load HL with 585EH (address of "CLEAR BACK LOG OR PRINT (B/P)?" + 03H message)
54D8
Call DOS print string routine to display the prompt
[USER INPUT LOOP] Wait for valid 'B' or 'P' response
54DB
LD B,01H 0601
Load Register B with 01H (input buffer size = 1 character)
54DD
LD HL,5826H 212658
Load HL with 5826H (input buffer address for single character response)
54E0
Call DOS keyboard input routine at 0040H to get one character from user
54E3
LD A,(HL) 7E
Load Register A with the character entered by user from input buffer
54E4
CP 42H FE42
Compare Register A with 42H (ASCII 'B') for Backlog clear. If equal, Z FLAG is set; otherwise NZ FLAG is set
54E6
If Z FLAG is set (user pressed 'B'), jump to 54F2H to clear the backlog buffer
54E8
CP 50H FE50
Compare Register A with 50H (ASCII 'P') for Print. If equal, Z FLAG is set; otherwise NZ FLAG is set
54EA
If NZ FLAG is set (user pressed neither 'B' nor 'P'), jump back to 54D5H to re-prompt
[PRINT SELECTED] User chose to print the backlog
54EC
LD (56C5H),A 32C556
Store 50H ('P') at 56C5H (print activation flag to enable printer output)
54EF
Jump to DOS return routine at 402DH (print will be activated by the stored flag)
[BACKLOG CLEAR ROUTINE] Clear all pool buffers
54F2
LD HL,5828H 212858
Load HL with 5828H (start of pool status table)
54F5
LD A,(HL) 7E
[CLEAR LOOP START] Load Register A with current pool status byte
54F6
SUB 02H D602
Subtract 02H from Register A. If result is negative (status was 00H or 01H), C FLAG is set. If status was ≥02H (active pool), result is ≥00H
54F8
CP FDH FEFD
Compare Register A with FDH. After subtracting 02H, this tests if original status was FFH (end marker: FFH-02H=FDH). If equal, Z FLAG is set
54FA
If NC FLAG is set (result ≥00H, meaning status was ≥02H = active pool needing clearing), jump to 54FEH to continue
54FC
LD (HL),00H 3600
Store 00H at current pool status location to mark it as empty/cleared
54FE
INC HL 23
Increment HL to point to next pool status byte
54FF
[LOOP END] If NZ FLAG is set (not at end marker FFH), jump back to 54F5H to process next pool
5501H - Write Buffer Command Entry
Entry point for the 'W' (Write) command which writes spooler buffer to disk. Sets up operation code and falls through to common spool operation handler. Entry: Called from command parser when 'W' command detected. Exit: Continues to shared spool operation code at 5507H.
5501
LD C,03H 0E03
Load Register C with 03H (operation code for Write buffer to disk command)
5503
Jump to 5507H to continue with common spool operation processing
5505H - Stop Spooler Command Entry
Entry point for the 'S' (Stop) command which stops the spooler. Sets up operation code and continues to shared handler. Entry: Called from command parser when 'S' command detected. Exit: Falls through to shared code at 5507H.
5505
LD C,04H 0E04
Load Register C with 04H (operation code for Stop spooler command)
5507H - Common Spool Operation Handler
Common handler for spool operations (Write and Stop). Sets up return address stack, preserves registers, and calls main spooler logic. Entry: C contains operation code (03H=Write, 04H=Stop). Exit: Returns to DOS via 402DH after operation completes.
[COMMON OPERATION HANDLER] Set up stack and call main spooler routine
5507
LD HL,402DH 212D40
Load HL with 402DH (DOS return routine address)
550A
PUSH HL E5
Push return address (402DH) onto stack - this will be the final return point after all operations complete
550B
PUSH HL E5
Push return address again (second copy for nested return path) - NOTE: Address 550BH is modified by code at 5636H to C9H (RET) when stopping spooler
550C
PUSH DE D5
Save Register DE on stack (preserve DE across operation)
550D
PUSH BC C5
Save Register BC on stack (preserve operation code in C)
550E
Call screen output handler at 567DH to display operation status messages
5511
Call main spooler operation routine at 5518H to execute the requested operation
5514
POP BC C1
Restore Register BC from stack
5515
POP DE D1
Restore Register DE from stack
5516
POP HL E1
Restore return address from stack (will be 402DH)
5517
RET C9
Return to caller (address in HL, typically 402DH DOS return routine)
5518H - Main Spooler Operation Logic
Main logic routine for spooler operations. Checks DOS mode, handles operation code dispatching for Write (C=03H) and Stop (C=04H) commands. Entry: C contains operation code (03H=Write, 04H=Stop), E=00H initially. Exit: Operation completed, returns to caller.
5518
LD E,00H 1E00
Load Register E with 00H (initialize status/error flag to zero)
Check if running from DOS or application
551A
LD A,(4369H) 3A6943
Load Register A with DOS mode flags from 4369H (bit 6 set = in DOS, clear = in application)
551D
AND 40H E640
Perform logical AND with 40H to isolate bit 6. If bit 6 set, result is 40H (in DOS); if clear, result is 00H (in application)
551F
LD (5519H),A 321955
Store result at 5519H (self-modifying code location - changes the SUB operand at 551AH for DOS detection)
5522
If Z FLAG is set (not in DOS, bit 6 was clear), jump to 552DH to continue with spooler operation
[IN DOS ERROR PATH] Cannot spool from DOS
5524
LD A,E 7B
Load Register A with Register E (error flag, initially 00H)
5526
OR A B7
Perform logical OR of Register A with itself to test if zero. If E=00H, Z FLAG is set; otherwise NZ FLAG is set
5527
RET NZ C0
If NZ FLAG is set (error already flagged), return immediately without displaying message again
5529
LD HL,58E5H 21E558
Load HL with 58E5H (address of "CAN'T SPOOL FROM DOS" + 0DH error message)
552C
Jump to DOS print string routine to display error message and return
[OPERATION DISPATCHER] Determine which operation to perform
552D
LD A,C 79
Load Register A with Register C (operation code: 03H=Write, 04H=Stop)
552E
CP 04H FE04
Compare Register A with 04H (Stop command code). If equal, Z FLAG is set; otherwise NZ FLAG is set
5530
If Z FLAG is set (operation is Stop), jump to 5634H to execute stop spooler routine
[WRITE OPERATION] Handle buffer write to disk (C=03H)
5533
LD A,00H 3E00
Load Register A with 00H - NOTE: This is a self-modifying code location (address 5534H holds current spool count)
5535
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (no files spooling), Z FLAG is set; otherwise NZ FLAG is set
5536
If Z FLAG is set (no files currently spooling), call 55F7H to initialize new spool session
5539
LD HL,582EH 212E58
Load HL with 582EH (screen position counter for display tracking)
553C
LD A,C 79
Load Register A with Register C (operation code for subsequent tests)
Check for cursor movement commands (0CH=Clear, 0DH=Enter)
553D
CP 0DH FE0D
Compare Register A with 0DH (ENTER/carriage return). If equal, Z FLAG is set; otherwise NZ FLAG is set
553F
If NZ FLAG is set (not ENTER), jump to 5557H to check for other commands
[ENTER KEY HANDLER] Process carriage return with optional line feed count
5541
Call output character routine at 557EH to send carriage return to spool buffer
5544
LD A,(HL) 7E
Load Register A with current line feed counter from 582EH
5545
INC A 3C
Increment Register A (add one line feed)
5546
LD (HL),A 77
Store updated line feed count back to 582EH
5547
LD A,00H 3E00
Load Register A with 00H - NOTE: This is self-modifying code location (address 5548H can be modified to control line feed behavior)
5549
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (no additional line feeds), Z FLAG is set; otherwise NZ FLAG is set
554A
If Z FLAG is set (no multi-line feed mode), jump to 5551H to check overflow
Multi-line feed mode active
554C
LD A,(HL) 7E
Load Register A with current line feed count from 582EH
554D
SUB 00H D600
Subtract limit value from line feed count - NOTE: Address 554EH is self-modifying, contains maximum line feed count
554F
If NC FLAG is set (line feed count ≥ maximum), jump back to 5546H to increment again until limit reached
Check for line feed overflow (FFH = 255)
5551
LD A,(HL) 7E
Load Register A with line feed count from 582EH
5552
CP FFH FEFF
Compare Register A with FFH (255) to check for counter overflow. If equal, Z FLAG is set; if less, C FLAG is set; if greater (impossible), NC FLAG is set
5554
RET C D8
If C FLAG is set (count < 255, normal range), return to caller - NOTE: Address 5554H is modified by code at 5931H to either C9H (RET) or D8H (RET C)
5555
Jump to 555BH to handle overflow condition
[CLEAR SCREEN COMMAND] Handle form feed (0CH)
5557
CP 0CH FE0C
Compare Register A with 0CH (form feed/clear screen). If equal, Z FLAG is set; otherwise NZ FLAG is set
5559
If NZ FLAG is set (not form feed), jump to 557AH to check for other control codes
Reset or clear line feed counter based on configuration
555B
LD A,(5548H) 3A4855
Load Register A with multi-line feed mode flag from 5548H (00H=normal, non-zero=multiple line feeds)
555E
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (normal mode), Z FLAG is set; otherwise NZ FLAG is set
555F
If NZ FLAG is set (multi-line feed mode active), jump to 5566H to handle special clearing
Normal mode - clear line feed counter
5561
LD (HL),A 77
Store 00H at 582EH to reset line feed counter to zero
5562
LD A,0CH 3E0C
Load Register A with 0CH (form feed character) to send to output
5564
If Z FLAG still set from earlier OR A test, jump to 557EH to output the form feed character
[MULTI-LINE FEED CLEAR] Calculate line feeds needed to reach form boundary
5566
LD A,(554EH) 3A4E55
Load Register A with maximum line feed count from 554EH (form feed line boundary)
5569
SUB (HL) 96
Subtract current line feed count at (HL=582EH) from maximum to get remaining lines needed
556A
LD B,A 47
Load Register B with result (number of line feeds to send)
556B
NEG ED44
Negate Register A (two's complement). If result is positive, P FLAG is set; if negative, M FLAG is set. Changes sign for proper counter handling
556D
LD (HL),A 77
Store negated value at 582EH (update line feed counter)
556E
If P FLAG is set (result is positive or zero), jump to 555BH to continue processing
[LINE FEED OUTPUT LOOP] Send required number of carriage returns
5571
LD A,0DH 3E0D
[LOOP START] Load Register A with 0DH (carriage return) for output
5573
Call output routine to send carriage return to spool buffer
5576
[LOOP END] Decrement Register B and jump to 5571H if not zero (send B line feeds total)
5578
LD (HL),B 70
Store 00H (Register B is now zero after DJNZ completion) at 582EH to reset counter
5579
RET C9
Return to caller after completing form feed operation
[CONTROL CHARACTER CHECK] Test for ETX (End of Text)
557A
CP 03H FE03
Compare Register A with 03H (ETX - End of Text). If equal, Z FLAG is set; otherwise NZ FLAG is set
557C
If Z FLAG is set (ETX character found), jump to 55B9H to finalize and close spool buffer
557EH - Output Character to Spool Buffer
Outputs a character to the memory-based spool buffer at 5300H-5400H range. Handles screen position tracking and buffer wrapping. When buffer fills, writes to disk. Entry: A contains character to output. Exit: Character written to buffer, buffer pointer advanced.
557E
PUSH HL E5
Save HL on stack (preserve screen position counter pointer)
557F
LD HL,582FH 212F58
Load HL with 582FH (screen column position counter)
Handle carriage return - reset column position
5582
CP 0DH FE0D
Compare Register A with 0DH (carriage return). If equal, Z FLAG is set; otherwise NZ FLAG is set
5584
If NZ FLAG is set (not carriage return), jump to 5590H to handle as normal character
5586
DEC (HL) 35
Decrement screen column counter at (HL=582FH) to move back one position
5587
LD A,20H 3E20
Load Register A with 20H (space character) to fill remaining line
5589
If NZ FLAG is set (column counter was not zero), call 5597H to output space for column alignment
558C
LD A,0DH 3E0D
Load Register A with 0DH (carriage return) again for actual output
558E
LD (HL),00H 3600
Store 00H at 582FH to reset column position to start of line
Check if character is printable (≥ space)
5590
CP 20H FE20
Compare Register A with 20H (space character). If less than space, C FLAG is set (control character); if ≥ space, NC FLAG is set (printable character)
5592
If C FLAG is set (control character, less than space), jump to 5596H to output without incrementing column counter
5594
LD (HL),01H 3601
Store 01H at 582FH to mark that at least one printable character has been output on this line
[BUFFER OUTPUT] Write character to memory buffer
5596
POP HL E1
Restore HL from stack (original value on entry)
5597
PUSH HL E5
Save HL on stack again (need to preserve across buffer write)
5598
LD HL,0000H 210000
Load HL with 0000H - NOTE: This is self-modifying code - address 5599H-559AH contains current buffer write pointer (initially 5300H)
559B
LD (HL),A 77
Store character from Register A at current buffer position (HL)
559C
INC HL 23
Increment HL to point to next buffer location
Check if buffer is full (reached 5300H + 100H = 5400H)
559D
LD DE,5300H 110053
Load DE with 5300H (base address of spool buffer) - note byte order appears reversed in the disassembly
55A0
LD A,L 7D
Load Register A with low byte of buffer pointer (L)
55A1
CP E BB
Compare low byte of buffer pointer with low byte of base address. Tests if pointer has wrapped to buffer boundary
55A2
If NZ FLAG is set (not at boundary yet), jump to 55B4H to update pointer and continue
[BUFFER FULL] Write buffer to disk file
55A4
PUSH DE D5
Save DE on stack (preserve buffer base address)
55A7
LD DE,5420H 112054
Load DE with 5420H (spool file DCB/FCB address for disk operations)
55A8
Call DOS write record routine at 443CH to write 256-byte buffer to disk file
55AB
LD HL,58C3H 21C358
Load HL with 58C3H (address of "CAN'T WRITE TO" + 03H error message)
55AE
If NZ FLAG is set (write error occurred), jump to 5626H to display error and abort
55B0
Call buffer management routine at 55F0H to handle post-write processing
55B3
POP HL E1
Restore HL from stack (buffer base address to reset pointer)
Update buffer pointer and return
55B4
LD (5599H),HL 229955
Store updated buffer pointer at 5599H (self-modifying code location used by LD HL,nnnn at 5598H)
55B7
POP HL E1
Restore HL from stack (original register value)
55B8
RET C9
Return to caller with character successfully written to buffer
55B9H - Finalize Spool Buffer (ETX Handler)
Handles End of Text (ETX, 03H) character to finalize the current spool buffer. Fills remaining buffer with ETX markers and writes final buffer to disk. Updates pool counters to reflect completed spool file. Entry: A=03H (ETX), HL points to screen position. Exit: Buffer finalized and written, pool status updated.
[ETX FINALIZATION] Handle end of spooled output
55B9
LD A,(HL) 7E
Load Register A with screen position counter at (HL=582EH or 582FH)
55BA
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (no content on line), Z FLAG is set; otherwise NZ FLAG is set
55BB
If NZ FLAG is set (content exists), call 555BH to handle line feed clearing and buffer alignment - NOTE: Address 55BBH is modified by code at 5963H to either C4H (CALL NZ) or 11H (LD DE,nnnn)
Get current buffer position and fill rest with ETX
55BE
LD HL,(5599H) 2A9955
Load HL with current buffer write pointer from 5599H (where next character would be written)
55C1
LD DE,5300H 110053
Load DE with 5300H (buffer base address for comparison)
55C4
LD A,L 7D
Load Register A with low byte of buffer pointer
55C5
CP E BB
Compare low byte of pointer with low byte of base (test if buffer is empty)
55C6
If Z FLAG is set (buffer pointer = base, buffer empty), jump to 55D0H to close file without writing
Buffer has content - write final partial buffer
55C8
LD (HL),03H 3603
Store 03H (ETX) at current buffer position to mark end of data
55CA
LD DE,5420H 112054
Load DE with 5420H (spool file DCB address)
55CD
Call DOS write record routine to write final partial buffer to disk
[FILE CLOSE] Close spool file and update pool status
55D0
LD DE,5420H 112054
Load DE with 5420H (spool file DCB address)
55D3
Call DOS close file routine at 4428H to finalize spool file
[POOL STATUS UPDATE] Count completed files in pool
55D6
LD HL,5827H 212758
Load HL with 5827H (address immediately before first pool status byte at 5828H)
55D9
LD E,00H 1E00
Load Register E with 00H (initialize file counter to zero)
55DB
PUSH HL E5
[COUNT LOOP START] Save HL on stack (preserve position in pool table)
55DC
INC HL 23
Increment HL to point to next pool status byte
55DD
LD A,(HL) 7E
Load Register A with pool status byte (00H=empty, 01-FEH=active, FFH=end)
55DE
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (empty slot), Z FLAG is set; otherwise NZ FLAG is set
55DF
If Z FLAG is set (empty slot), jump back to 55DCH to skip this slot and check next
55E1
INC E 1C
Increment Register E (count this active file)
55E2
INC A 3C
Increment Register A to test for end marker (FFH becomes 00H)
55E3
[LOOP END] If NZ FLAG is set (not end marker), jump back to 55DCH to continue counting
Update pool status with new counts
55E5
LD D,A 57
Load Register D with 00H (A is zero after incrementing FFH)
55E6
LD A,E 7B
Load Register A with file count from Register E
55E7
LD HL,5534H 213455
Load HL with 5534H (current spooling count storage location - self-modifying code operand at 5533H)
55EA
LD E,(HL) 5E
Load Register E with old spooling count from 5534H
55EB
LD (HL),D 72
Store 00H (Register D) at 5534H to reset spooling count (file completed)
55EC
POP HL E1
Restore HL from stack (pointer into pool table)
55ED
ADD HL,DE 19
Add DE to HL to calculate position in pool table for completed file entry
55EE
LD (HL),A 77
Store new file count at calculated pool position
55EF
RET C9
Return to caller with spool file finalized and pool status updated
55F0H - Buffer Write Verification and Management
Verifies disk write operations and manages buffer state after writes. Checks for write completion, handles printer wait conditions if buffer is full. Entry: Called after writing buffer to disk. Exit: C FLAG clear on success, set on error.
55F0
Call DOS verify write routine at 444BH to confirm disk write completed successfully. Returns with Z FLAG set if successful, NZ FLAG set on error
55F3
RET Z C8
If Z FLAG is set (write verified successfully), return to caller
55F4
Call file close routine at 55D0H to properly close file after error
55F7H - Initialize New Spool Session
Initializes a new spooler session when first starting to spool output. Creates new spool file, displays "waiting on printer" message if needed, and sets up buffer pointers. Entry: C contains operation code, no files currently spooling. Exit: Spool file opened and ready, buffer initialized.
55F7
PUSH BC C5
Save BC on stack (preserve operation code)
[CHECK POOL AVAILABILITY] Verify there's room for new spool file
55F8
Call pool counter routine at 5642H to count active files in pool. Returns with Z FLAG set if pool empty, C contains count
55FB
If Z FLAG is set (pool empty, safe to create new file), jump to 560BH to continue initialization
[POOL FULL] Display waiting message and wait for printer
55FD
LD HL,5898H 219858
Load HL with 5898H (address of "SPOOL FULL. WAITING ON PRINTER" + 0DH message)
5600
Call DOS print string routine to display waiting message to user
5603
[WAIT LOOP START] Call screen output handler at 567DH to check printer status
5606
Call pool counter to check if space available yet
5609
[LOOP END] If NZ FLAG is set (still no space), jump back to 5603H to continue waiting
[INITIALIZE SPOOL FILE] Create new file and set up buffers
560B
LD A,C 79
Load Register A with Register C (pool counter / file number for this session)
560C
LD (5534H),A 323455
Store file number at 5534H (self-modifying code operand - current spool count at 5533H)
560F
LD DE,5420H 112054
Load DE with 5420H (spool file DCB/FCB address)
5612
Call filename setup routine at 5651H to create "POOL_:n" filename in FCB (where n is the pool number)
5615
LD HL,5300H 210053
Load HL with 5300H (base address of spool output buffer)
5618
LD (5599H),HL 229955
Store buffer pointer at 5599H (self-modifying code location at 5598H - reset buffer write pointer to start)
561B
LD B,00H 0600
Load Register B with 00H (file attribute = normal file)
561D
Call DOS create file routine at 4420H to create new spool file on disk. Returns with Z FLAG set on success, NZ FLAG set on error
5620
POP BC C1
Restore BC from stack (operation code)
5621
If Z FLAG is set (file created successfully), jump to 55F0H to verify and return
[FILE CREATION ERROR] Display error message and abort
5623
LD HL,58B8H 21B858
Load HL with 58B8H (address of "CAN'T OPEN" + 03H error message)
5626
OR 0C0HOR 11000000 F6C0
Perform logical OR of Register A with C0H to set error flag bits (marks as fatal error)
5628
Call DOS error handler at 4409H to set error code for display
562B
Call DOS print string routine to display "CAN'T OPEN" message
562E
LD HL,58D2H 21D258
Load HL with 58D2H (address of "SPOOL OUTPUT FILE" + 0DH message)
5631
Call DOS print string routine to display complete error message "CAN'T OPEN SPOOL OUTPUT FILE"
5634H - Stop Spooler Command Handler
Handles the 'S' (Stop) command to shut down the spooler. Patches the spooler entry points with RET instructions to disable spooling, displays stopping message. Entry: Called from command dispatcher when C=04H (Stop command). Exit: Spooler disabled, message displayed, returns to DOS.
[STOP SPOOLER] Disable spooler by patching code
5634
LD A,C9H 3EC9
Load Register A with C9H (RET instruction opcode) to patch code with immediate returns
5636
LD (550BH),A 320B55
Store C9H at 550BH (patches second PUSH HL in common handler at 5507H to become RET, disabling nested operations)
5639
LD (56F1H),A 32F156
Store C9H at 56F1H (stop flag - checked by status display at 548CH, non-zero means stopping)
563C
LD HL,587CH 217C58
Load HL with 587CH (address of "SPOOL STOPPING." + 0DH message)
563F
Jump to DOS print string routine to display "SPOOL STOPPING." message and return to DOS
5642H - Count Active Spool Files
Counts the number of active spool files in the pool table. Scans pool status bytes from 5828H onwards until finding FFH end marker. Entry: None. Exit: C contains count of active files (01H-FEH range), Z FLAG set if count=0, NZ FLAG set if count>0, A contains incremented final value.
5642
LD HL,5828H 212858
Load HL with 5828H (start of pool status table)
5645
LD C,01H 0E01
Load Register C with 01H (initialize file counter to 1)
5647
LD A,(HL) 7E
[COUNT LOOP START] Load Register A with pool status byte (00H=empty, 01-FEH=active, FFH=end)
5648
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (empty slot), Z FLAG is set; otherwise NZ FLAG is set
5649
RET Z C8
If Z FLAG is set (found empty slot meaning no more active files), return with current count in C
564A
INC HL 23
Increment HL to point to next pool status byte
564B
INC C 0C
Increment Register C (count this file)
564C
INC A 3C
Increment Register A to test for end marker (FFH becomes 00H)
564D
[LOOP END] If NZ FLAG is set (not end marker), jump back to 5647H to continue counting
564F
INC A 3C
Increment Register A again (sets A=01H, NZ FLAG set to indicate files found)
5650
RET C9
Return to caller with count in C and NZ FLAG set
5651H - Setup Pool Filename in FCB
Creates the spool filename "POOL_:n" in the File Control Block (FCB) at 5420H. Converts the pool number to ASCII and embeds it in the template string. Entry: A contains pool number (1-9), DE points to FCB at 5420H. Exit: FCB filename field populated with "POOL_:n" where n is the pool number.
5651
ADD 30H C630
Add 30H to Register A to convert pool number (1-9) to ASCII digit ('1'-'9')
5653
LD (5822H),A 322258
Store ASCII digit at 5822H (digit position in "POOL_:1" template string at 581EH)
5656
PUSH DE D5
Save DE on stack (preserve FCB pointer)
5657
LD HL,581EH 211E58
Load HL with 581EH (source address of "POOL_:1" + 0DH template string)
565A
LD BC,0008H 010800
Load BC with 0008H (8 bytes to copy - length of "POOL_:n" filename)
565D
LDIR EDB0
Block copy 8 bytes from (HL=581EH) to (DE=5420H+offset), incrementing both pointers. Copies "POOL_:n" into FCB filename field
565F
POP DE D1
Restore DE from stack (FCB pointer)
5660
RET C9
Return to caller with filename configured in FCB
5661H - Printer Input Buffer Check
Checks for available character from printer input buffer. Saves system state (clock values) if character available. Entry: None. Exit: A contains character if available (NZ), or 00H if buffer empty (Z). System clock state saved if character read.
5661
Call printer input buffer read routine at 57FAH to check for available character. Returns with A containing character (NZ if available) or 00H (Z if empty)
5664
OR A B7
Perform logical OR of Register A with itself to set flags. If A=00H (no character), Z FLAG is set; otherwise NZ FLAG is set
5665
PUSH AF F5
Save AF on stack (preserve character and flags)
5666
If NZ FLAG is set (character available), jump to 566DH to save system clock state
[NO CHARACTER PATH] Buffer empty, handle screen output
5668
Call screen output handler at 567DH to process any pending screen output
566B
Jump to 567BH to restore flags and return
[CHARACTER AVAILABLE PATH] Save system clock state for timing
566D
LD A,(4041H) 3A4140
Load Register A with system clock seconds from 4041H (NEWDOS/80 system time)
5670
LD (576DH),A 326D57
Store seconds value at 576DH (self-modifying code operand in SUB instruction at 576CH - saves timestamp of character arrival)
5673
PUSH HL E5
Save HL on stack (preserve register)
5674
LD HL,(4042H) 2A4240
Load HL with system clock minutes:hours from 4042H-4043H (16-bit time value)
5677
LD (5777H),HL 227757
Store minutes:hours at 5777H (self-modifying code operand in LD DE,nnnn at 5776H - saves upper time bytes)
567A
POP HL E1
Restore HL from stack
567B
POP AF F1
Restore AF from stack (character and flags)
567C
RET C9
Return to caller with character in A and flags set appropriately
567DH - Screen Output Handler and Printer Management
Main screen output handler that manages printer output for applications. Checks DOS mode, printer status flags, and coordinates output to physical printer or screen. Calls print buffer processor and manages pool file operations. Entry: None. Exit: Registers preserved, output processed.
567D
PUSH HL E5
Save HL on stack (preserve register)
567E
PUSH DE D5
Save DE on stack (preserve register)
567F
PUSH BC C5
Save BC on stack (preserve register)
[TEMPORARY PATCH] Modify code to enable screen processing
5680
LD HL,5759H 215957
Load HL with 5759H (NOP location before print routine at 575AH)
5683
LD (HL),C9H 36C9
Store C9H (RET instruction) at 5759H to temporarily disable print routine (creates early return)
5685
PUSH HL E5
Save HL on stack (save address of patched location)
5686
Call print processor at 575AH (will immediately return due to RET at 5759H - allows screen update without printer output)
5689
POP HL E1
Restore HL from stack (address 5759H)
568A
LD (HL),00H 3600
Store 00H (NOP instruction) at 5759H to restore original code (re-enable print routine)
Check DOS mode - cannot print from DOS
568C
LD A,(4369H) 3A6943
Load Register A with DOS mode flags from 4369H (bit 6 = DOS mode indicator)
568F
BIT 6,A CB77
Test bit 6 of Register A. If bit 6 is set (in DOS), Z FLAG is clear; if bit 6 is clear (in application), Z FLAG is set
5691
If NZ FLAG is set (bit 6 set, in DOS), jump to 5514H to restore registers and return (cannot print from DOS)
[PRINTER STATUS CHECK] Check if printer output is active
5694
LD A,(5766H) 3A6657
Load Register A with printer active flag from 5766H (non-zero = printer output active)
5697
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (printer inactive), Z FLAG is set; otherwise NZ FLAG is set
5698
If Z FLAG is set (printer not active), jump to 56E1H to check pool files without printer processing
[PRINTER ACTIVE PATH] Check buffer availability
569A
Call buffer comparison routine at 5739H to verify buffer pointers are valid. Returns with C FLAG set if buffer full, NC FLAG if space available
569D
If NC FLAG is set (buffer has space), jump to 56B6H to continue with printer operation
569F
If C FLAG set (buffer full), jump to 5514H to exit (cannot output to full buffer)
[INITIALIZE PRINTER FILE] Open printer output spool file
56A2
LD A,C 79
Load Register A with Register C (pool number for printer file)
56A3
LD (5766H),A 326657
Store pool number at 5766H (printer active flag - marks printer as active with this pool number)
56A6
LD DE,5400H 110054
Load DE with 5400H (printer file DCB/FCB address for disk operations)
56A9
Call filename setup routine at 5651H to create "POOL_:n" filename in printer FCB
56AC
LD HL,5200H 210052
Load HL with 5200H (printer input/output buffer base address)
56AF
LD B,00H 0600
Load Register B with 00H (normal file attribute)
56B1
Call DOS open file routine at 4424H to open existing printer spool file. Returns with Z FLAG set on success, NZ FLAG set on error
56B4
If NZ FLAG is set (file open error - file doesn't exist yet), jump to 56CDH to clear printer status and return
[FILE OPENED SUCCESSFULLY] Seek to start of file
56B6
LD DE,5400H 110054
Load DE with 5400H (printer file DCB address)
56B9
If Z FLAG is set (file opened successfully), call DOS seek routine at 4436H to position at start of file for reading
56BC
If NZ FLAG is set (seek error), jump to 56CAH to close file and clear status
Set up buffer pointer for reading
56BE
LD HL,5200H 210052
Load HL with 5200H (printer buffer base address)
56C1
LD (573DH),HL 223D57
Store buffer pointer at 573DH (self-modifying code operand in LD HL,nnnn at 573CH - current read position)
56C4
LD A,00H 3E00
Load Register A with 00H - NOTE: This is self-modifying code location (address 56C5H can be set to 50H 'P' to activate printing)
56C6
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (print not activated), Z FLAG is set; if A=50H ('P' print command), NZ FLAG is set
56C7
If Z FLAG is set (print not activated yet), jump to 5514H to restore registers and return (file ready but not printing)
[FILE CLOSE AND CLEANUP] Error path or print completion
56CA
Call file cleanup routine at 5745H to clear FCB fields and close file
56CD
XOR A AF
Perform logical XOR of Register A with itself, setting A to 00H and setting Z FLAG
56CE
LD (5766H),A 326657
Store 00H at 5766H to clear printer active flag (printer now inactive)
56D1
LD (56C5H),A 32C556
Store 00H at 56C5H to clear print activation flag (disable printing)
[UPDATE POOL STATUS] Decrement completed file in pool table
56D4
LD HL,5827H 212758
Load HL with 5827H (address before first pool status byte at 5828H)
56D7
INC HL 23
[SCAN LOOP START] Increment HL to point to next pool status byte
56D8
LD A,(HL) 7E
Load Register A with pool status byte (00H=empty, 01-FEH=active, FFH=end)
56D9
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (empty slot), Z FLAG is set; otherwise NZ FLAG is set
56DA
If Z FLAG is set (empty slot), jump back to 56D7H to continue scanning for active pools
56DC
DEC (HL) 35
Decrement pool count at (HL) - reduce count of files in this pool by 1 (printed file completed)
56DD
INC A 3C
Increment Register A to test for end marker (FFH becomes 00H, setting Z FLAG)
56DE
[LOOP END] If NZ FLAG is set (not end marker, more pools to check), jump back to 56D7H to continue
56E0
INC (HL) 34
Increment (HL) to undo the decrement of the FFH end marker (restore it to FFH)
[POOL FILE SCANNER] Search for next file to print
56E1
LD HL,5828H 212858
Load HL with 5828H (first pool status byte)
56E4
LD C,01H 0E01
Load Register C with 01H (pool counter starting at pool 1)
56E6
LD A,(HL) 7E
[POOL SEARCH LOOP START] Load Register A with pool status byte
56E7
DEC A 3D
Decrement Register A. If status was 01H (one file available), result is 00H and Z FLAG is set
56E8
If Z FLAG is set (found pool with one file ready to print), jump to 56A2H to open and start printing this pool
56EA
INC A 3C
Increment Register A to restore original value (undo the DEC A)
56EB
INC HL 23
Increment HL to point to next pool status byte
56EC
INC C 0C
Increment Register C (advance pool counter)
56ED
INC A 3C
Increment Register A to test for end marker (FFH becomes 00H)
56EE
[LOOP END] If NZ FLAG is set (not end marker), jump back to 56E6H to check next pool
56F0
LD A,00H 3E00
Load Register A with 00H - NOTE: This is self-modifying code (address 56F1H modified by stop command at 5639H to C9H=RET)
56F2
OR A B7
Perform logical OR of Register A with itself. If stop flag active (A=C9H), NZ FLAG is set; if normal (A=00H), Z FLAG is set
56F3
If Z FLAG is set (not stopping), jump to 5514H to restore registers and return normally
56F6H - Print Command Handler
Handles the 'P' (Print) command to activate printer output from spool files. Closes any active spool file, sets up printer driver vectors, adjusts memory limits, and starts printing. Entry: Called from command parser when 'P' command detected. Exit: Printer activated and started, returns to DOS.
[PRINT ACTIVATION] Close active spool file if present
56F6
LD A,(5534H) 3A3455
Load Register A with current spool count from 5534H (number of files currently being spooled)
56F9
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (no active spool file), Z FLAG is set; otherwise NZ FLAG is set
56FA
LD DE,5420H 112054
Load DE with 5420H (spool file DCB address)
56FD
If NZ FLAG is set (spool file active), call cleanup routine at 5745H to close the active spool file
[PRINTER DRIVER SETUP] Install printer output vectors
5700
LD DE,5755H 115557
Load DE with 5755H (printer driver vector table: 00 01 01 01 - configuration bytes)
5703
Call DOS vector installation routine at 4413H to install printer driver (sets up @PUT, @GET, @CTL vectors)
[SYSTEM MEMORY ADJUSTMENT] Protect printer buffers from DOS
5706
DI F3
Disable interrupts to protect critical memory pointer updates
5707
LD HL,0000H 210000
Load HL with 0000H (null pointer)
570A
LD (4026H),HL 222640
Store 0000H at 4026H (NEWDOS/80 keyboard break vector - disable break checking during print)
570D
LD HL,0000H 210000
Load HL with 0000H again
5710
LD (4016H),HL 221640
Store 0000H at 4016H (NEWDOS/80 pointer - likely disk buffer pointer to disable disk operations)
Adjust HIGH$ memory limit to protect printer buffers
5713
LD DE,5200H 110052
Load DE with 5200H (start of printer buffer area)
5716
DEC DE 1B
Decrement DE to 51FFH (one byte below buffer start)
5717
LD HL,(4049H) 2A4940
Load HL with current HIGH$ value from 4049H (top of available memory for programs)
571A
OR A B7
Clear carry flag for subtraction
571B
SBC HL,DE ED52
Subtract DE from HL (check if HIGH$ already points to printer buffer area). If equal, result is 0000H and Z FLAG is set
571D
If NZ FLAG is set (HIGH$ not at buffer location), jump to 5726H to skip adjustment
HIGH$ already at buffer, adjust to protect program area
571F
LD HL,06FAH 21FA06
Load HL with 06FAH (1786 bytes - size of spooler program to protect)
5722
ADD HL,DE 19
Add DE (51FFH) to HL, calculating new HIGH$ = 51FFH + 06FAH = 58F9H (protects spooler code 5200H-58F9H)
5723
LD (4049H),HL 224940
Store new HIGH$ value at 4049H to protect printer buffer and spooler code from DOS
5726
EI FB
Enable interrupts after completing critical section
[PROGRAM CHAIN] Reload spooler and return to caller
5727
LD HL,5450H 215054
Load HL with 5450H (start of spooler program)
572A
Call DOS command executor at 4464H to execute/chain to spooler (reloads program state)
572D
POP BC C1
Restore BC from stack (return address pushed by caller)
572E
LD HL,4408H 210844
Load HL with 4408H (DOS error return address)
5731
OR A B7
Clear carry flag for subtraction
5732
SBC HL,BC ED42
Subtract BC from HL to check if return address is error handler. If equal, Z FLAG is set
5734
RET Z C8
If Z FLAG is set (returning to error handler), return directly
5735
Jump to 5515H to restore remaining registers and return to original caller
5738
NOP 00
No operation - padding byte
5739H - Buffer Pointer Comparison
Compares buffer write pointer against buffer limit to check for overflow. Entry: BC and HL contain pointers to compare. Exit: Z FLAG set if pointers equal (buffer at limit), C FLAG set if buffer full, NC FLAG if space available.
5739
LD BC,5300H 010053
Load BC with 5300H (buffer limit address for comparison) - NOTE: Bytes appear reversed in disassembly due to little-endian storage
573C
LD HL,0000H 210000
Load HL with current pointer value - NOTE: This is self-modifying code (address 573DH-573EH contains actual pointer, updated by code at 56C1H, 57C8H)
573F
LD A,H 7C
Load Register A with high byte of pointer (H)
5740
CP B B8
Compare high byte with B (high byte of limit). If equal, Z FLAG is set; if A < B, C FLAG is set; if A > B, NC FLAG is set
5741
RET NZ C0
If NZ FLAG is set (high bytes differ), return with current comparison result in flags
5742
LD A,L 7D
Load Register A with low byte of pointer (L)
5743
CP C B9
Compare low byte with C (low byte of limit). Sets flags: Z if equal, C if A < C, NC if A > C
5744
RET C9
Return with comparison result in flags (Z=at limit, C=below limit, NC=above limit)
5745H - Clear FCB Fields and Close File
Clears specific fields in the File Control Block and closes the file. Zeros out extent and record count fields in the FCB. Entry: DE points to FCB. Exit: FCB fields cleared, file closed via DOS.
5745
XOR A AF
Perform logical XOR of Register A with itself, setting A to 00H (value to store in FCB fields)
5746
LD HL,0008H 210800
Load HL with 0008H (offset to extent field in FCB)
5749
ADD HL,DE 19
Add DE (FCB base) to HL, calculating address of extent field (FCB+8)
574A
LD (HL),A 77
Store 00H at extent field (FCB+8) to clear extent number
574B
INC HL 23
Increment HL to FCB+9
574C
INC HL 23
Increment HL to FCB+10
574D
INC HL 23
Increment HL to FCB+11
574E
INC HL 23
Increment HL to FCB+12 (record count low byte)
574F
LD (HL),A 77
Store 00H at FCB+12 (clear record count low byte)
5750
INC HL 23
Increment HL to FCB+13 (record count high byte)
5751
LD (HL),A 77
Store 00H at FCB+13 (clear record count high byte)
5752
Jump to DOS close file routine at 4428H to close the file and return to caller
5755H - Printer Driver Vector Table
Data table containing printer driver configuration bytes. Used by DOS vector installation routine to configure printer I/O vectors.
5755
NOP 00
Data byte: 00H (device flags - no special flags)
5756
LD BC,0101H 010101
Data bytes: 01 01 01H (vector configuration: @PUT=01, @GET=01, @CTL=01 - all point to custom handlers)
5759
NOP 00
Patchable location - modified by code at 5683H to C9H (RET) to temporarily disable print routine
575AH - Printer Output Main Entry
Main entry point for printer output processing. Preserves IX register and calls actual printer handler. Entry: Called by DOS when output sent to printer device. Exit: Character processed, IX preserved.
575A
PUSH IX DDE5
Save IX register on stack (preserve index register across printer operation)
575C
Call printer handler routine at 5762H to process printer output
575F
POP IX DDE1
Restore IX register from stack
5761
RET C9
Return to DOS with character processed
5762H - Printer Character Output Handler
Processes characters for printer output. Calls keyboard input routine to get character from buffer, checks timeout against saved clock values, validates buffer position, and dispatches to appropriate output handler based on system configuration. Entry: Character available in buffer or timeout check needed. Exit: Character output to physical printer or error returned.
5762
Call keyboard input routine at 57DDH to get character from spool buffer. Returns with A containing character or 00H if buffer empty
5765
LD A,00H 3E00
Load Register A with 00H - NOTE: This is self-modifying code (address 5766H contains printer active flag, set by code at 56A3H)
5767
OR A B7
Perform logical OR of Register A with itself to test printer flag. If A=00H (no active printer), Z FLAG is set; otherwise NZ FLAG is set
5768
RET Z C8
If Z FLAG is set (printer not active), return immediately without processing
[TIMEOUT CHECK] Calculate elapsed time since last character
5769
LD A,(4041H) 3A4140
Load Register A with current system clock seconds from 4041H
576C
SUB 00H D600
Subtract saved seconds value from current seconds - NOTE: Address 576DH is self-modifying, contains seconds when last character received (set by code at 5670H)
576E
If NC FLAG is set (no borrow, current time ≥ saved time), jump to 5773H to continue timeout check
Time wrapped past 60 seconds, adjust for clock wrap
5770
ADD 3CH C63C
Add 3CH (60 decimal) to Register A to handle seconds wrap (adjust negative result to positive elapsed time)
5772
SCF 37
Set carry flag to indicate time adjustment was made
5773
LD HL,(4042H) 2A4240
Load HL with current system clock minutes:hours from 4042H-4043H
5776
LD DE,0000H 110000
Load DE with saved minutes:hours - NOTE: Address 5777H-5778H is self-modifying, contains time when last character received (set by code at 5677H)
5779
SBC HL,DE ED52
Subtract DE from HL with borrow (calculate elapsed minutes:hours considering any carry from seconds)
577B
If NZ FLAG is set (minutes or hours changed), jump to 5780H to continue with character processing
Check seconds threshold - if less than timeout value, return
577D
CP 00H FE00
Compare elapsed seconds in A with timeout threshold - NOTE: Address 577EH is self-modifying, contains timeout value in seconds (set by code at 5991H)
577F
RET C D8
If C FLAG is set (elapsed time less than timeout), return without processing (waiting for more data)
[BUFFER VALIDATION] Verify buffer pointer is valid
5780
Call buffer pointer comparison routine at 5739H to check if buffer pointer is valid. Returns with flags indicating buffer state
5783
RET NC D0
If NC FLAG is set (buffer pointer invalid or beyond limit), return without processing
[CHARACTER PROCESSING] Get character and dispatch to output
5784
LD A,(HL) 7E
Load Register A with character from current buffer position
5785
CP 03H FE03
Compare Register A with 03H (ETX - End of Text). If equal, Z FLAG is set; otherwise NZ FLAG is set
5787
LD C,A 4F
Load Register C with character (preserve for output routine)
5788
If NZ FLAG is set (not ETX, normal character), jump to 5791H to output character
[ETX HANDLER] End of file marker found
578A
LD HL,5301H 210153
Load HL with 5301H (position just past buffer start - forces buffer reload on next access)
578D
LD (573DH),HL 223D57
Store new pointer at 573DH (self-modifying code location - updates buffer read pointer)
5790
RET C9
Return after handling end of file (file complete, will reload next file on next call)
5791H - Physical Printer Output Dispatcher
Dispatches character output to appropriate physical printer interface based on system configuration. Checks configuration flags and routes to RS-232, Model III printer port, or hardware printer port. Entry: C contains character to output. Exit: Character sent to printer, buffer pointer advanced.
[PRINTER TYPE DETECTION] Determine which printer interface to use
5791
LD A,01H 3E01
Load Register A with 01H - NOTE: This is self-modifying code (address 5792H contains printer type: 00H=hardware port, 01H=Model III port, 02H=RS-232)
5793
CP 01H FE01
Compare Register A with 01H (Model III printer port). If equal, Z FLAG is set; if less (00H=hardware), C FLAG is set; if greater (02H=RS-232), NC FLAG is set
5795
If C FLAG is set (hardware printer port), jump to 57B8H to output via hardware port
5797
If Z FLAG is set (Model III printer port), jump to 57AAH to output via Model III port
[RS-232 OUTPUT PATH] Send to RS-232 serial port
5799
PUSH HL E5
Save HL on stack (preserve buffer pointer)
579A
PUSH BC C5
Save BC on stack (preserve character)
579B
LD DE,4025H 112540
Load DE with 4025H (RS-232 device control block address)
579E
PUSH DE D5
Save DE on stack
579F
POP IX DDE1
Pop into IX register (IX now points to RS-232 DCB)
57A1
LD B,02H 0602
Load Register B with 02H (function code: output character via RS-232)
57A3
Call RS-232 driver entry point at 0000H - NOTE: Address 57A4H-57A5H is self-modifying, contains actual RS-232 driver address
57A6
POP BC C1
Restore BC from stack (character)
57A7
POP HL E1
Restore HL from stack (buffer pointer)
57A8
Jump to 57C7H to advance buffer pointer and continue
57AAH - Model III Printer Port Output
Outputs character to TRS-80 Model III printer port. Checks printer compatibility and sends character directly to hardware. Entry: C contains character to output. Exit: Character sent to Model III printer port or error returned.
[MODEL III PRINTER OUTPUT] Verify Model III compatibility
57AA
LD A,(37E8H) 3AE837
Load Register A with system configuration byte from 37E8H (hardware identification)
57AD
AND 0F0HAND 11110000 E6F0
Perform logical AND with F0H to isolate upper nibble (model type identifier)
57AF
CP 30H FE30
Compare Register A with 30H (Model III identifier). If equal, Z FLAG is set; otherwise NZ FLAG is set
57B1
RET NZ C0
If NZ FLAG is set (not Model III), return without outputting (incompatible hardware)
Send character to Model III printer port
57B2
LD A,C 79
Load Register A with character from Register C (prepare for output)
57B3
LD (37E8H),A 32E837
Store character at 37E8H (Model III printer port address - memory-mapped printer output)
57B6
Jump to 57C7H to advance buffer pointer and return
57B8H - Hardware Printer Port Output
Outputs character to hardware printer port via I/O ports. Checks printer ready status and sends character when ready. Handles both Model I expansion interface (port EAH) and alternate interface (port E8H). Entry: C contains character to output. Exit: Character sent to hardware printer port.
[HARDWARE PRINTER OUTPUT] Check primary printer port ready status
57B8
IN A,(EAH) DBEA
Input status byte from port EAH (Model I expansion interface printer status port)
57BA
BIT 6,A CB77
Test bit 6 of status byte. If bit 6 is set (printer ready), NZ FLAG is set; if bit 6 is clear (printer busy), Z FLAG is set
57BC
RET Z C8
If Z FLAG is set (printer busy), return without sending character (wait for printer to become ready)
57BD
If printer ready, jump to 57C4H to send character - NOTE: Address 57BDH is modified by initialization code at 5947H to either 18H (JR) or 3EH (LD A,n) to select printer interface
[ALTERNATE PRINTER PORT] Check secondary printer interface
57BF
IN A,(E8H) DBE8
Input status byte from port E8H (alternate printer interface status port)
57C1
BIT 6,A CB77
Test bit 6 of status byte. If bit 6 is set (printer ready), NZ FLAG is set; if bit 6 is clear (printer busy), Z FLAG is set
57C3
RET Z C8
If Z FLAG is set (printer busy), return without sending character
Send character to printer data port
57C4
LD A,C 79
Load Register A with character from Register C (prepare for output)
57C5
OUT (EBH),A D3EB
Output character to port EBH (printer data port - sends character to physical printer)
[BUFFER ADVANCEMENT] Move to next character position
57C7
INC HL 23
Increment HL to point to next character in buffer
57C8
LD (573DH),HL 223D57
Store updated buffer pointer at 573DH (self-modifying code location - current read position)
57CB
LD A,C 79
Load Register A with character from Register C (check for carriage return)
57CC
CP 0DH FE0D
Compare Register A with 0DH (carriage return). If equal, Z FLAG is set; otherwise NZ FLAG is set
57CE
If Z FLAG is set (carriage return output), jump to 57D5H to return (don't process next character immediately)
Continue processing next character
57D0
Call keyboard input routine at 57DDH to check for any input interruption
57D3
Jump back to 5780H to continue processing next character from buffer
57D5
RET C9
Return to caller after carriage return output
57D6H - Line Feed Insertion (Unused)
Appears to be unused code for inserting line feed (0AH) before carriage return. This routine is not called in normal execution flow. Entry: HL points to buffer position. Exit: 0AH inserted, buffer pointer updated.
57D6
DEC HL 2B
Decrement HL to back up one position in buffer
57D7
LD (HL),0AH 360A
Store 0AH (line feed) at current position
57D9
LD (573DH),HL 223D57
Store updated pointer at 573DH (self-modifying code location)
57DC
RET C9
Return to caller
57DDH - Keyboard Input Check During Print
Checks for keyboard input during printer operations. Uses ROM keyboard scanning routine and manages circular input buffer at 5440H. Handles buffer wrapping when full. Entry: None. Exit: A contains character if available (NZ), or 00H if no input (Z).
57DD
NOP 00
No operation - padding or disabled instruction
57DE
LD IX,4015H DD211540
Load IX with 4015H (keyboard device control block address for ROM routines)
57E2
Call ROM keyboard scan routine at 03E3H to check for key press. Returns with A containing character (NZ) or 00H (Z)
57E5
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (no key pressed), Z FLAG is set; otherwise NZ FLAG is set
57E6
RET Z C8
If Z FLAG is set (no key available), return with Z FLAG set
[BUFFER INPUT CHARACTER] Store character in circular buffer
57E7
LD HL,5440H 214054
Load HL with 5440H (base address of keyboard input circular buffer)
57EA
LD (HL),A 77
Store character at current write position in buffer
57EB
INC HL 23
Increment HL to point to next buffer position
Check for buffer wrap
57EC
LD A,(57FDH) 3AFD57
Load Register A with buffer write position counter from 57FDH
57EF
INC A 3C
Increment counter. If counter was FFH (255), result is 00H and Z FLAG is set (buffer full/wrap)
57F0
If Z FLAG is set (buffer wrapped), call 5817H to reset buffer pointers to start
57F3
LD (57E8H),HL 22E857
Store next write position at 57E8H - NOTE: This address is not referenced elsewhere, appears to be unused storage
57F6
LD (57FDH),A 32FD57
Store updated buffer counter at 57FDH
57F9
RET C9
Return with NZ FLAG set (character available)
57FAH - Read Character from Printer Input Buffer
Reads next character from the circular printer input buffer at 5440H. Manages buffer read pointer and handles wraparound. Entry: None. Exit: A contains character from buffer (NZ) or 00H if buffer empty (Z). HL and BC preserved.
57FA
LD A,F6H 3EF6
Load Register A with F6H - NOTE: This is self-modifying code (address 57FBH contains buffer read position counter, initialized to F6H)
57FC
SUB F6H D6F6
Subtract F6H from Register A. If read counter equals F6H (initial/empty state), result is 00H and Z FLAG is set
57FE
RET Z C8
If Z FLAG is set (buffer empty, no characters available), return with A=00H
[BUFFER READ] Get character from circular buffer
57FF
PUSH HL E5
Save HL on stack (preserve register)
5800
PUSH BC C5
Save BC on stack (preserve register)
5801
LD HL,5440H 214054
Load HL with 5440H (base address of keyboard input circular buffer)
5804
LD B,(HL) 46
Load Register B with character at buffer start (current read position)
5805
INC HL 23
Increment HL to point to next buffer position
Update read pointer and check for wrap
5806
LD A,(57FBH) 3AFB57
Load Register A with buffer read counter from 57FBH
5809
INC A 3C
Increment read counter. If counter was FFH (255), result is 00H and Z FLAG is set (buffer wrap)
580A
If Z FLAG is set (counter wrapped), call 5817H to reset buffer pointers to start
580D
LD (5802H),HL 220258
Store next read position at 5802H (self-modifying code operand in LD HL,nnnn at 5801H - updates buffer base pointer)
5810
LD (57FBH),A 32FB57
Store updated read counter at 57FBH
5813
LD A,B 78
Load Register A with character from Register B (retrieve character for return)
5814
POP BC C1
Restore BC from stack
5815
POP HL E1
Restore HL from stack
5816
RET C9
Return with character in A and NZ FLAG set (character available)
5817H - Reset Buffer Pointers
Resets circular buffer pointers to start position when buffer wraps. Entry: Called when buffer counter wraps to 00H. Exit: HL points to buffer start, A contains reset counter value.
5817
LD HL,5440H 214054
Load HL with 5440H (base address of circular buffer - reset to start)
581A
LD A,F6H 3EF6
Load Register A with F6H (reset counter to initial value)
581C
RET C9
Return to caller with buffer pointers reset
581DH - Data Area and Message Strings
Program data area containing message strings for display, spool status table, and working variables. Includes pool filename templates, status messages, and configuration data.
[POOL FILENAME TEMPLATE] Used to generate POOL_:n filenames
581E
LD D,B 50
Data: ASCII 'P' - first character of "POOL_:1"
581F
LD C,A 4F
Data: ASCII 'O' - second character
5820
LD C,A 4F
Data: ASCII 'O' - third character
5821
LD C,H 4C
Data: ASCII 'L' - fourth character
5822
LD SP,313AH 313A31
Data: ASCII "1:1" - pool number template with colon separator. Byte at 5822H is modified to contain pool number digit
5825
DEC C 0D
Data: 0DH (carriage return) - terminates display string
5826
JR NZ,5848H 2020
Data: Two space characters (20H 20H) - unused/padding
[POOL STATUS TABLE] Array tracking spool file states (5828H-582DH)
5828
NOP 00
Pool 1 status: 00H=empty, 01-FEH=file count, FFH=end marker
582D
RST 38H FF
End marker: FFH indicates end of pool status table
[WORKING VARIABLES]
582E
NOP 00
Variable: Line feed counter for form feed calculations
582F
NOP 00
Variable: Screen column position flag (00H=start of line, 01H=content on line)
[MESSAGE STRINGS] Display messages for user interface
5830-583C
DEFM "SPOOL STATUS" + 0DH
583D-5847
DEFM "PRINTING: " + 03H
5848-5850
DEFM "SPOOLING: " + 03H
5853-585B
DEFM "BACK LOG: " + 03H
585E-586B
DEFM "CLEAR BACK LOG OR PRINT (B/P)?" + 03H
587C-588A
DEFM "SPOOL STOPPING." + 0DH
588B-5897
DEFM "SPOOL PURGED" + 0DH
5898-58B7
DEFM "SPOOL FULL. WAITING ON PRINTER" + 0DH
58B8-58C2
DEFM "CAN'T OPEN" + 03H
58C3-58D1
DEFM "CAN'T WRITE TO" + 03H
58D2-58E4
DEFM "SPOOL OUTPUT FILE" + 0DH
58E5-58F9
DEFM "CAN'T SPOOL FROM DOS" + 0DH
58FAH - Configuration Initialization Entry Point
Main initialization routine that prompts user for spooler configuration settings. Configures printer type, form feed handling, line counts, and other operational parameters through interactive prompts. Entry: Called during program installation. Exit: Configuration complete, returns to DOS via 402DH.
[PRINTER DRIVER SELECTION] Check if user wants to use existing printer driver
58FA
LD HL,5A55H 21555A
Load HL with 5A55H (address of "USE EXISTING PRINTER DRIVER (Y/N)?" + 03H prompt)
58FD
Call yes/no prompt routine at 5A18H to display message and get Y/N response. Returns with Z FLAG set for 'N', NZ FLAG set for 'Y'
5900
LD HL,5792H 219257
Load HL with 5792H (printer type configuration byte at address 5791H+1 in self-modifying code)
5903
LD (HL),02H 3602
Store 02H at 5792H (set printer type to RS-232 serial as default)
5905
If Z FLAG is set (user answered 'N', not using existing driver), jump to 5928H to continue with printer configuration
[PARALLEL/SERIAL SELECTION] User wants existing driver - determine type
5907
DEC (HL) 35
Decrement printer type to 01H (Model III printer port)
5908
PUSH HL E5
Save HL on stack (preserve printer type address)
5909
LD HL,5A78H 21785A
Load HL with 5A78H (address of "PARALLEL OR SERIAL PRINTER (P/S)?" + 03H prompt)
590C
LD BC,5053H 015350
Load BC with 5053H (B=50H='P' for parallel, C=53H='S' for serial)
590F
Call two-option prompt routine at 5A1BH to get P/S response. Returns with Z FLAG set if first option selected ('P')
5912
POP HL E1
Restore HL from stack (printer type address)
5913
If Z FLAG is set (user selected 'P' for parallel), jump to 5928H with type=01H (Model III/parallel)
[H14 PRINTER CHECK] Serial printer - check for H14 interface
5915
DEC (HL) 35
Decrement printer type to 00H (hardware I/O port printer)
5916
LD HL,5A9AH 219A5A
Load HL with 5A9AH (address of "H14 PRINTER (Y/N)?" + 03H prompt - asking about Heath H14 interface)
5919
Call yes/no prompt routine to check for H14 printer interface
591C
LD HL,57BDH 21BD57
Load HL with 57BDH (address of printer port selection code in hardware output routine)
591F
LD (HL),18H 3618
Store 18H (JR opcode) at 57BDH to enable jump to primary printer port (port EAH)
5921
If NZ FLAG is set (not H14, standard hardware port), jump to 5928H to continue
H14 printer - use alternate port
5923
LD A,3EH 3E3E
Load Register A with 3EH (LD A,n opcode) to disable primary port check
5925
LD (57BDH),A 32BD57
Store 3EH at 57BDH (changes JR to LD A,n - skips primary port, uses alternate port E8H)
[PAGE FORMATTING SETUP] Configure form feed handling
5928
LD HL,5AADH 21AD5A
Load HL with 5AADH (address of "PAGES (Y/N)?" + 03H prompt - asking about page mode)
592B
Call yes/no prompt routine to check if user wants page formatting
592E
LD HL,5554H 215455
Load HL with 5554H (address of line feed overflow return instruction at 5553H+1)
5931
LD (HL),C9H 36C9
Store C9H (RET opcode) at 5554H (disable overflow check - normal return)
5933
If NZ FLAG is set (user answered 'Y' for pages), jump to 5940H to configure page parameters
No page mode - set up unlimited line count
5935
LD (HL),D8H 36D8
Store D8H (RET C opcode) at 5554H (return if line count < FFH, allows counting to 255)
5937
LD HL,5AF6H 21F65A
Load HL with 5AF6H (address of "PRINT LINES PER PAGE (10-99)?" prompt - but will skip this in non-page mode)
593A
Call numeric input routine at 5A3AH to get print lines value (though not used in non-page mode)
593D
LD (5553H),A 325355
Store value at 5553H (maximum line count configuration byte) - unused in non-page mode
[FORM FEED TYPE SELECTION] Soft or hard form feed
5940
LD HL,5ABAH 21BA5A
Load HL with 5ABAH (address of "SOFT OR HARD FORM FEED (S/H)?" + 03H prompt)
5943
LD BC,4853H 015348
Load BC with 4853H (B=48H='H' for hard, C=53H='S' for soft) - note: appears reversed, likely B=53H='S', C=48H='H'
5946
Call two-option prompt routine to get S/H response
5949
LD HL,5548H 214855
Load HL with 5548H (address of multi-line feed mode flag at 5547H+1)
594C
LD (HL),00H 3600
Store 00H at 5548H (disable multi-line feed mode - default for hard form feed)
594E
If Z FLAG is set (first option selected, likely 'S' for soft), jump to 595AH to configure soft form feed
Hard form feed selected - no additional line configuration needed
5950
INC (HL) 34
Increment value at 5548H to 01H (enable multi-line feed mode for soft form feed)
5951
LD HL,5AD8H 21D85A
Load HL with 5AD8H (address of "TOTAL LINES PER PAGE (10-99)?" + 03H prompt)
5954
Call numeric input routine to get total lines per page (form feed boundary)
5957
LD (554EH),A 324E55
Store total lines value at 554EH (form feed line limit at 554DH+1 in self-modifying code)
[ETX HANDLING CONFIGURATION] Configure end-of-file behavior
595A
LD HL,5B14H 21145B
Load HL with 5B14H (address of configuration prompt - content not shown in disassembly)
595D
Call yes/no prompt routine for ETX handling configuration
5960
LD HL,55BBH 21BB55
Load HL with 55BBH (address of ETX finalization call instruction at 55BAH+1)
5963
LD (HL),C4H 36C4
Store C4H (CALL NZ opcode) at 55BBH (call finalization if content exists)
5965
If Z FLAG is set (user answered 'N'), jump to 5969H to skip next configuration
5967
LD (HL),11H 3611
Store 11H (LD DE,nnnn opcode high byte) at 55BBH (changes CALL NZ to LD DE,nnnn - disables finalization call)
[LINE FEED INSERTION CONFIGURATION]
5969
LD HL,5B36H 21365B
Load HL with 5B36H (address of line feed prompt - content not shown)
596C
Call yes/no prompt routine for line feed insertion option
596F
LD HL,57D5H 21D557
Load HL with 57D5H (address of return instruction after carriage return in printer output routine)
5972
LD (HL),00H 3600
Store 00H (NOP opcode) at 57D5H (replace RET with NOP - allows fall-through to line feed insertion)
5974
If Z FLAG is set (user answered 'N', no line feed insertion), jump to 5978H
5976
LD (HL),C9H 36C9
Store C9H (RET opcode) at 57D5H (restore return, disable line feed insertion)
[POOL NUMBER CONFIGURATION] Get pool number for default operation
5978
LD HL,5B5AH 215A5B
Load HL with 5B5AH (address of pool number prompt)
597B
Call prompt and input routine at 5A2FH to display prompt and get single character response
597E
Decrement B and jump back to 5978H if not zero - NOTE: This creates a loop but B's initial value is unknown from this code segment
Validate pool number input (must be 0-3)
5980
LD A,(HL) 7E
Load Register A with character from input buffer (pool number character)
5981
SUB 30H D630
Subtract 30H from Register A to convert ASCII digit to numeric value ('0'-'3' becomes 00H-03H)
5983
CP 04H FE04
Compare Register A with 04H. If less than 4, C FLAG is set (valid pool 0-3); if ≥4, NC FLAG is set (invalid)
5985
If NC FLAG is set (invalid pool number ≥4), jump back to 5978H to re-prompt
5987
LD A,(HL) 7E
Load Register A with pool number character again (validated ASCII '0'-'3')
5988
LD (5824H),A 322458
Store pool number character at 5824H (position in display template string)
[TIMEOUT CONFIGURATION] Get printer timeout value
598B
LD HL,5B78H 21785B
Load HL with 5B78H (address of timeout prompt)
598E
Call numeric input routine to get timeout value in seconds (10-99)
5991
LD (577EH),A 327E57
Store timeout value at 577EH (timeout threshold at 577DH+1 in self-modifying code)
[ADDITIONAL CONFIGURATION OPTIONS]
5994
LD HL,5BAFH 21AF5B
Load HL with 5BAFH (address of another configuration prompt)
5997
Call yes/no prompt routine for additional configuration
599A
LD HL,5DB4H 21B45D
Load HL with 5DB4H (configuration flag address - content beyond visible disassembly)
599D
LD (HL),01H 3601
Store 01H at configuration location (enable option)
599F
If Z FLAG is set (user answered 'N'), jump to 59A2H to continue
59A1
DEC (HL) 35
Decrement configuration flag to 00H (disable option)
59A2
LD HL,5BD4H 21D45B
Load HL with 5BD4H (another configuration flag address)
59A5
Call yes/no prompt routine for additional configuration option
59A8
LD HL,5C88H 21885C
Load HL with 5C88H (configuration flag address)
59AB
LD (HL),01H 3601
Store 01H at configuration location (enable option)
59AD
If Z FLAG is set (user answered 'N'), jump to 59B0H to continue
59AF
DEC (HL) 35
Decrement configuration flag to 00H (disable option)
59B0H - Program Installation to Disk
Writes configured spooler program to disk with embedded configuration. Creates three copies of program data at different memory locations, then writes to disk file. Entry: Configuration complete. Exit: Program written to disk, returns to DOS.
[MEMORY IMAGE PREPARATION] Copy program to multiple memory locations
59B0
LD DE,5450H 115054
Load DE with 5450H (source: start of spooler program)
59B3
LD HL,5C32H 21325C
Load HL with 5C32H (destination address buffer for hex string generation)
59B6
Call hex address formatter at 59FDH to convert DE address to ASCII hex string at (HL)
59B9
LD DE,5DD0H 11D05D
Load DE with 5DD0H (end address or length parameter)
59BC
LD HL,5C38H 21385C
Load HL with 5C38H (another address buffer for hex string)
59BF
Call hex formatter to convert end address to ASCII hex string
59C2
LD DE,5C4BH 114B5C
Load DE with 5C4BH (filename or parameter address)
59C5
LD HL,5C3EH 213E5C
Load HL with 5C3EH (third address buffer)
59C8
Call hex formatter for third address parameter
[DISPLAY SAVE MESSAGE]
59CB
LD HL,5BEFH 21EF5B
Load HL with 5BEFH (address of save confirmation message)
59CE
Call DOS print string routine to display message to user
[GET FILENAME] Prompt for output filename
59D1
LD HL,5C16H 21165C
Load HL with 5C16H (input buffer for filename)
59D4
LD B,1AH 061A
Load Register B with 1AH (26 decimal) (maximum filename length including extension)
59D6
Call DOS keyboard input routine at 0040H to get filename from user
[PAD FILENAME] Fill filename with spaces to required length
59D9
LD B,1CH 061C
Load Register B with 1CH (28 decimal) (counter for padding loop)
59DB
LD HL,5C31H 21315C
Load HL with 5C31H (end of filename buffer)
59DE
LD A,(HL) 7E
[PADDING LOOP START] Load Register A with character at current position
59DF
CP 0DH FE0D
Compare Register A with 0DH (carriage return). If equal, Z FLAG is set (end of user input found)
59E1
LD (HL),20H 3620
Store 20H (space character) at current position to pad filename
59E3
DEC HL 2B
Decrement HL to move backward through buffer
59E4
If Z FLAG is set (found carriage return, padding complete), jump to 59E8H
59E6
[LOOP END] Decrement B and jump back to 59DEH if not zero (continue padding)
[CREATE OUTPUT FILE] Write configured program to disk
59E8
LD HL,5C11H 21115C
Load HL with 5C11H (start of command buffer with formatted save command)
59EB
Call DOS command interpreter at 4419H to execute save command. Returns with C FLAG set on error, Z FLAG state indicates success/failure
59EE
If C FLAG is set (command aborted by user), jump to DOS return routine at 402DH
59F1
If NZ FLAG is set (error occurred during save), jump to DOS error handler at 4409H
[SAVE SUCCESSFUL] Display completion message
59F4
LD HL,5C0CH 210C5C
Load HL with 5C0CH (address of success message)
59F7
Call DOS print string routine to display success message
59FA
Jump to DOS return routine at 402DH (exit to DOS)
59FDH - Convert Address to Hex String
Converts 16-bit address in DE to ASCII hexadecimal string at (HL). Processes high byte then low byte. Entry: DE contains address to convert, HL points to output buffer. Exit: 4-character hex string written to (HL), HL advanced past string.
59FD
LD A,D 7A
Load Register A with high byte of address from Register D
59FE
Call byte-to-hex converter at 5A02H to convert high byte to two hex characters
5A01
LD A,E 7B
Load Register A with low byte of address from Register E
5A02H - Convert Byte to Hex Characters
Converts byte in A to two ASCII hexadecimal characters at (HL). Processes high nibble then low nibble. Entry: A contains byte to convert, HL points to output buffer. Exit: Two hex characters written, HL advanced by 2.
5A02
PUSH AF F5
Save AF on stack (preserve byte value)
5A03
RRCA 0F
Rotate Register A right through carry (shift right 1 bit)
5A04
RRCA 0F
Rotate Register A right again (shift right 2 bits total)
5A05
RRCA 0F
Rotate Register A right again (shift right 3 bits total)
5A06
RRCA 0F
Rotate Register A right again (shift right 4 bits total - high nibble now in low nibble position)
5A07
Call nibble-to-hex converter at 5A0BH to convert high nibble to ASCII hex character
5A0A
POP AF F1
Restore AF from stack (get original byte value back)
5A0BH - Convert Nibble to Hex Character
Converts low nibble of A to ASCII hexadecimal character. Handles 0-9 as '0'-'9', A-F as 'A'-'F'. Entry: A contains nibble in low 4 bits, HL points to output location. Exit: ASCII hex character stored at (HL), HL incremented.
5A0B
AND 0FHAND 00001111 E60F
Perform logical AND with 0FH to isolate low nibble (mask out high bits)
5A0D
CP 0AH FE0A
Compare Register A with 0AH (10 decimal). If less than 10, C FLAG is set (digit 0-9); if ≥10, NC FLAG is set (hex A-F)
5A0F
If C FLAG is set (value 0-9), jump to 5A13H to convert to ASCII digit
5A11
ADD 07H C607
Add 07H to Register A to adjust for hex letters (0AH+07H+30H='A', 0FH+07H+30H='F')
5A13
ADD 30H C630
Add 30H to convert to ASCII ('0'-'9' or 'A'-'F')
5A15
LD (HL),A 77
Store ASCII hex character at (HL)
5A16
INC HL 23
Increment HL to point to next output position
5A17
RET C9
Return to caller
5A18H - Yes/No Prompt Handler
Displays prompt and waits for Y or N response. Returns with Z FLAG set for 'N', NZ FLAG set for 'Y'. Continues prompting until valid response received. Entry: HL points to prompt string. Exit: Z FLAG indicates response (Z='N', NZ='Y'), BC contains response characters.
5A18
LD BC,594EH 014E59
Load BC with 594EH (B=59H='Y', C=4EH='N') - the two valid response characters - NOTE: Bytes appear reversed, likely B=4EH='N', C=59H='Y'
5A1BH - Two-Option Prompt Handler
Generic prompt handler for two-character choices (P/S, S/H, etc.). Displays prompt and waits for response matching either character in BC. Returns with Z FLAG set if first option selected. Entry: HL points to prompt string, B contains first option character, C contains second option character. Exit: Z FLAG set if B matched, NZ FLAG set if C matched.
5A1B
PUSH HL E5
Save HL on stack (preserve prompt address)
5A1C
PUSH BC C5
Save BC on stack (preserve option characters)
5A1D
Call prompt and input routine at 5A2FH to display prompt and get single character from user
5A20
EX DE,HL EB
Exchange DE and HL (move input buffer pointer to DE)
5A21
DEC B 05
Decrement Register B (purpose unclear - may be counter manipulation)
5A22
POP BC C1
Restore BC from stack (option characters)
5A23
POP HL E1
Restore HL from stack (prompt address)
5A24
If NZ FLAG is set (condition unclear), jump back to 5A1BH to re-prompt
Validate response against expected characters
5A26
LD A,(DE) 1A
Load Register A with character from input buffer at (DE)
5A27
CP B B8
Compare Register A with first option character in B. If equal, Z FLAG is set; otherwise NZ FLAG is set
5A28
If Z FLAG is set (first option matched), jump to 5A2DH to return with Z FLAG set
5A2A
CP C B9
Compare Register A with second option character in C. If equal, Z FLAG is set; otherwise NZ FLAG is set
5A2B
If NZ FLAG is set (neither option matched, invalid input), jump back to 5A1BH to re-prompt
5A2D
CP B B8
Compare Register A with B again to set Z FLAG appropriately (Z if first option, NZ if second option)
5A2E
RET C9
Return to caller with Z FLAG indicating which option was selected
5A2FH - Display Prompt and Get Single Character
Displays a prompt string and reads one character from the keyboard. Used by configuration routines for single-character responses. Entry: HL points to prompt string (terminated with 03H). Exit: Character read into buffer at 5C44H, HL updated.
5A2F
Call DOS print string routine at 4467H to display prompt at (HL). String terminated by 03H byte
5A32
LD B,01H 0601
Load Register B with 01H (input buffer size = 1 character)
5A34
LD HL,5C44H 21445C
Load HL with 5C44H (input buffer address for single character response)
5A37
Jump to DOS keyboard input routine at 0040H to get one character from user and return
5A3AH - Get Two-Digit Numeric Input (10-99)
Prompts for and validates two-digit numeric input in range 10-99. Continues prompting until valid input received. Entry: HL points to prompt string. Exit: A contains validated numeric value (10-99 decimal).
5A3A
EX DE,HL EB
Exchange DE and HL (move prompt address to DE, preserve in case needed)
5A3B
EX DE,HL EB
[INPUT LOOP START] Exchange back (HL now has prompt address for display)
5A3C
PUSH HL E5
Save HL on stack (preserve prompt address for re-prompting)
5A3D
Call DOS print string routine to display prompt
5A40
LD B,02H 0602
Load Register B with 02H (input buffer size = 2 characters for two digits)
5A42
LD HL,5C46H 21465C
Load HL with 5C46H (input buffer address for two-character response)
5A45
Call DOS keyboard input routine to get two characters from user
5A48
POP DE D1
Restore DE from stack (prompt address for potential re-display)
Validate that exactly 2 characters were entered
5A49
LD A,B 78
Load Register A with Register B (remaining buffer count - should be 0 if 2 chars entered)
5A4A
CP 02H FE02
Compare Register A with 02H. If equal, Z FLAG is set (no characters entered); otherwise NZ FLAG is set
5A4C
If NZ FLAG is set (wrong number of characters entered), jump back to 5A3BH to re-prompt
Convert ASCII digits to binary value
5A4E
Call ROM decimal conversion routine at 0E6CH to convert two ASCII digits to binary number
5A51
LD A,(4121H) 3A2141
Load Register A with converted numeric value from 4121H (result of conversion routine)
5A54
RET C9
Return to caller with numeric value in Register A
5A55H - Configuration Prompt Strings
Data area containing all configuration prompt strings used during spooler installation. Each string is terminated with 03H byte (ETX). Strings are displayed to guide user through configuration process.
5A55-5A77
DEFM "USE EXISTING PRINTER DRIVER (Y/N)?" + 03H
5A78-5A99
DEFM "PARALLEL OR SERIAL PRINTER (P/S)?" + 03H
5A9A-5AAC
DEFM "H14 PRINTER (Y/N)?" + 03H
5AAD-5AB9
DEFM "PAGES (Y/N)?" + 03H
5ABA-5AD7
DEFM "SOFT OR HARD FORM FEED (S/H)?" + 03H
5AD8-5AF5
DEFM "TOTAL LINES PER PAGE (10-99)?" + 03H
5AF6-5B13
DEFM "PRINT LINES PER PAGE (10-99)?" + 03H
5B14-5B35
DEFM "TOP-OF-FORM AT END OF FILE (Y/N)?" + 03H
5B36-5B59
DEFM "LINE FEED ON CARRIAGE RETURN (Y/N)?" + 03H
5B5A-5B77
DEFM "DRIVER # FOR POOL FILES (0-3)?" + 03H
5B78-5BAE
DEFM "# SECONDS PRINT DELAY AFTER LATEST INPUT KEY (00-59)?" + 03H
5BAF-5BD3
DEFM "INTERRUPT DRIVEN PRINTER (Y/N)?" + 03H
5BD4-5BEE
DEFM "USE CIRCULAR BUFFER (Y/N)?" + 03H
5BEF-5C0A
DEFM "NEW SPOOL PROGRAM FILES SPEC?" + 03H
5C0C-5C10
DEFM "DONE" + 0DH
5C11H - DUMP Command Template String
Template for DUMP command used to write configured program to disk. Contains placeholder addresses that are filled in by hex conversion routines during installation. Command format: "DUMP device/filename startaddr endaddr entryaddr".
5C11-5C43
DEFM "DUMP NNNNNN/TTTT.PPPPPPP 00000H 00000H 00000H" + 0DH
Explanation: "NNNNNN" is drive number, "TTTT" is filename (up to 8 chars), "PPPPPPP" is extension (up to 3 chars). Three address fields are filled by hex conversion at 59B6H-59C8H: start address (5450H), end address (5DD0H), and entry point (5C4BH)
5C44H - Input Buffer Area
Working buffer space for keyboard input during configuration. Single character responses stored at 5C44H, two-character responses at 5C46H.
5C44
JR NZ,5C66H 2020
Data: Two space characters (20H 20H) - input buffer for single character responses
5C46
JR NZ,5C68H 2020
Data: Two space characters (20H 20H) - input buffer for two-character numeric input
5C4BH - Alternative Command Entry Point
Alternative entry point for ASP command processing. Handles 'I' command for installation/configuration and 'A' command for purging all pool files. Entry: HL points to command line. Exit: Command processed or error generated.
5C4B
Call get last character routine at 547DH to scan command line and get final character before ENTER
[INSTALL COMMAND CHECK] Test for 'I' command
5C4E
CP 49H FE49
Compare Register A with 49H (ASCII 'I') for Install/configuration command. If equal, Z FLAG is set; otherwise NZ FLAG is set
5C50
If Z FLAG is set (Install command), jump to 58FAH to start configuration initialization routine
[PURGE ALL COMMAND CHECK] Test for 'A' command
5C53
CP 41H FE41
Compare Register A with 41H (ASCII 'A') for purge All pools command. If equal, Z FLAG is set; otherwise NZ FLAG is set
5C55
If NZ FLAG is set (not 'A' command, invalid command), jump to 5478H to generate syntax error
5C58H - Purge All Pool Files Command Handler
Handles the 'A' (purge All) command to delete all pool files (POOL_:1 through POOL_:5). Iterates through each pool number, opens and closes each file to clear it. Entry: Called from 5C55H when 'A' command detected. Exit: All pool files purged, returns to main command handler.
5C58
LD A,01H 3E01
Load Register A with 01H (first pool number to purge)
5C5A
LD DE,5400H 110054
Load DE with 5400H (FCB address for pool file operations)
5C5D
PUSH AF F5
[PURGE LOOP START] Save AF on stack (preserve current pool number)
5C5E
Call filename setup routine at 5651H to create "POOL_:n" filename in FCB at DE for current pool number in A
5C61
LD B,00H 0600
Load Register B with 00H (file attribute: normal file)
5C63
Call DOS open file routine at 4424H to open pool file. Returns with Z FLAG set if file opened successfully, NZ FLAG if file doesn't exist
5C66
If Z FLAG is set (file opened), call cleanup routine at 5745H to clear FCB fields and close file (effectively purging it)
5C69
POP AF F1
Restore AF from stack (retrieve pool number)
5C6A
INC A 3C
Increment Register A to next pool number
5C6B
CP 06H FE06
Compare Register A with 06H (pool 6). If less than 6, C FLAG is set (more pools to process); if equal or greater, NC FLAG is set
5C6D
[LOOP END] If C FLAG is set (more pools remain, A < 6), jump back to 5C5DH to purge next pool
5C6FH - Save System Vectors and Configuration
Saves NEWDOS/80 system vectors and applies configuration settings. Stores keyboard break vector, disk buffer pointer, and configures interrupt/buffer options based on installation settings. Entry: All pools purged. Exit: System vectors saved to self-modifying code locations.
[SAVE SYSTEM VECTORS] Preserve DOS vectors for later restoration
5C6F
LD HL,(4026H) 2A2640
Load HL with keyboard break vector from 4026H (NEWDOS/80 break key handler address)
5C72
LD (5708H),HL 220857
Store break vector at 5708H (self-modifying code operand in LD (nnnn),HL at 5707H - for later restoration)
5C75
LD (57A4H),HL 22A457
Store break vector at 57A4H (self-modifying code operand in CALL nnnn at 57A3H - RS-232 driver address)
5C78
LD HL,(4016H) 2A1640
Load HL with disk buffer pointer from 4016H (NEWDOS/80 system pointer)
5C7B
LD (570EH),HL 220E57
Store disk buffer pointer at 570EH (self-modifying code operand in LD (nnnn),HL at 570DH - for later restoration)
[INTERRUPT DRIVEN PRINTER CONFIG] Check configuration flag
5C7E
LD A,(5DB4H) 3AB45D
Load Register A with interrupt driven printer flag from 5DB4H (configuration byte set during installation)
5C81
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (interrupt mode disabled), Z FLAG is set; if A=01H (enabled), NZ FLAG is set
5C82
If NZ FLAG is set (interrupt mode enabled), jump to 5C87H to skip keyboard buffer configuration
5C84
LD (57E3H),HL 22E357
Store disk buffer pointer at 57E3H (self-modifying code location in keyboard input routine at 57E2H+1 - modifies CALL address)
[CIRCULAR BUFFER CONFIG] Check buffer mode setting
5C87
LD A,01H 3E01
Load Register A with 01H - NOTE: This is self-modifying code (address 5C88H contains circular buffer flag from installation)
5C89
OR A B7
Perform logical OR of Register A with itself to test buffer mode. If A=00H (circular buffer disabled), Z FLAG is set; if A=01H (enabled), NZ FLAG is set
5C8A
If NZ FLAG is set (circular buffer enabled), jump to 5C94H to skip printer input buffer configuration
5C8C
LD (5662H),HL 226256
Store disk buffer pointer at 5662H (self-modifying code operand in CALL at 5661H - modifies printer buffer check routine address)
5C8F
LD A,C9H 3EC9
Load Register A with C9H (RET instruction opcode)
5C91
LD (57DDH),A 32DD57
Store C9H at 57DDH (keyboard input check routine - changes NOP to RET, disabling keyboard monitoring during print)
5C94H - Hardware Printer Port Initialization
Initializes hardware printer port if using I/O port printer (not RS-232 or Model III). Configures expansion interface ports E8H/E9H/EAH for printer communication. Looks up baud rate from configuration table. Entry: Configuration loaded. Exit: Printer port initialized if needed.
5C94
LD A,(5792H) 3A9257
Load Register A with printer type from 5792H (00H=hardware I/O port, 01H=Model III, 02H=RS-232)
5C97
OR A B7
Perform logical OR of Register A with itself to test if zero. If A=00H (hardware port), Z FLAG is set; otherwise NZ FLAG is set
5C98
If NZ FLAG is set (not hardware port, using Model III or RS-232), jump to 5CB2H to skip hardware initialization
[HARDWARE PORT INITIALIZATION] Configure expansion interface
5C9A
OUT (E8H),A D3E8
Output A (00H) to port E8H (printer data port - clear/reset)
5C9C
IN A,(E9H) DBE9
Input from port E9H (expansion interface configuration port) to read current settings
5C9E
AND 0F8HAND 11111000 E6F8
Perform logical AND with F8H (11111000 binary) to mask out lower 3 bits (baud rate bits)
5CA0
OR 04H F604
Perform logical OR with 04H (00000100 binary) to set bit 2 (specific printer configuration)
5CA2
OUT (EAH),A D3EA
Output modified configuration to port EAH (printer control port)
Read baud rate configuration and set
5CA4
IN A,(E9H) DBE9
Input from port E9H again to read baud rate setting
5CA6
AND 07HAND 00000111 E607
Perform logical AND with 07H (00000111 binary) to isolate lower 3 bits (baud rate index)
5CA8
LD HL,5DBCH 21BC5D
Load HL with 5DBCH (base address of baud rate lookup table)
5CAB
LD C,A 4F
Load Register C with baud rate index from Register A
5CAC
LD B,00H 0600
Load Register B with 00H (form 16-bit offset with BC = 00nn)
5CAE
ADD HL,BC 09
Add BC to HL (calculate address in baud rate table: 5DBCH + baud_rate_index)
5CAF
LD A,(HL) 7E
Load Register A with baud rate value from table
5CB0
OUT (E9H),A D3E9
Output baud rate configuration to port E9H (set printer baud rate)
5CB2H - Calculate Relocation and Copy Program
Calculates new memory location for spooler program, copies program data to new location with address relocation, and installs program at calculated address. Adjusts HIGH$ memory limit, copies code blocks, relocates addresses in copied code. Entry: Configuration complete. Exit: Program relocated and installed, ready for operation.
[CALCULATE NEW PROGRAM LOCATION] Determine where to relocate spooler
5CB2
LD HL,(4049H) 2A4940
Load HL with HIGH$ value from 4049H (top of available memory for programs)
5CB5
LD BC,06FAH 01FA06
Load BC with 06FAH (1786 decimal) (size of spooler program in bytes)
5CB8
OR A B7
Clear carry flag for subtraction
5CB9
SBC HL,BC ED42
Subtract BC from HL to calculate new program start address (HIGH$ - program_size = relocation address)
5CBB
PUSH HL E5
Save HL on stack (preserve calculated program start address for later use)
[COPY FIRST BLOCK] Copy program header/entry
5CBC
INC HL 23
Increment HL (adjust destination address by 1 byte)
5CBD
LD DE,0250H 115002
Load DE with 0250H (592 decimal) (offset for buffer area or data section)
5CC0
ADD HL,DE 19
Add DE to HL (calculate destination address for first copy: new_base + 0251H)
5CC1
EX DE,HL EB
Exchange DE and HL (DE now has destination address, HL will get source)
5CC2
LD HL,5450H 215054
Load HL with 5450H (source: start of spooler program)
5CC5
LD BC,000CH 010C00
Load BC with 000CH (12 decimal) (number of bytes to copy in first block - program header)
5CC8
LDIR EDB0
Block copy from (HL) to (DE) for BC bytes, incrementing both pointers. Copies program header (545CH is new location)
[COPY MAIN BLOCK] Copy bulk of program code
5CCA
PUSH DE D5
Save DE on stack (preserve destination pointer after first copy)
5CCB
PUSH HL E5
Save HL on stack (preserve source pointer after first copy)
5CCC
LD BC,049EH 019E04
Load BC with 049EH (1182 decimal) (number of bytes to copy in main block)
5CCF
LDIR EDB0
Block copy main program code from source to destination
[CALCULATE RELOCATION OFFSET] Determine address adjustment needed
5CD1
POP DE D1
Restore DE from stack (get source pointer back)
5CD2
POP HL E1
Restore HL from stack (get destination pointer back)
5CD3
OR A B7
Clear carry flag for subtraction
5CD4
SBC HL,DE ED52
Subtract DE from HL to calculate relocation offset (destination - source = address_delta)
5CD6
PUSH HL E5
Save HL on stack (preserve relocation offset for address adjustment)
[CALCULATE CODE RANGE] Determine addresses to scan for relocation
5CD7
ADD HL,DE 19
Add DE to HL to restore destination address
5CD8
EX DE,HL EB
Exchange DE and HL (HL now has start of copied code block)
5CD9
LD HL,03C1H 21C103
Load HL with 03C1H (961 decimal) (size of code section to scan for addresses)
5CDC
ADD HL,DE 19
Add DE to HL (calculate end address of code section to relocate)
5CDD
LD B,H 44
Load Register B with high byte of end address
5CDE
LD C,L 4D
Load Register C with low byte of end address (BC now = end address)
5CDF
EX DE,HL EB
Exchange DE and HL (HL = start address, BC = end address for scan loop)
5CE0H - Address Relocation Scanner
Scans through copied code and relocates all absolute addresses that point to spooler code area. Identifies instructions with 16-bit address operands, checks if addresses fall within spooler range (5200H-58F9H), and adjusts them by relocation offset. Entry: HL points to start of code, BC points to end, relocation offset on stack. Exit: All addresses relocated, spooler ready for execution.
5CE0
LD A,(HL) 7E
[SCAN LOOP START] Load Register A with opcode at current address
[INSTRUCTION LENGTH DETECTION] Determine if instruction has address operand
5CE1
CP C0H FEC0
Compare Register A with C0H (192 decimal). If less than C0H, C FLAG is set (opcodes 00-BF); if ≥C0H, NC FLAG is set (opcodes C0-FF)
5CE3
If NC FLAG is set (opcode ≥C0H, upper range), jump to 5D39H to check for multi-byte instructions (CALL, JP, etc.)
5CE5
CP 40H FE40
Compare Register A with 40H (64 decimal). Tests range 00-3F vs 40-BF
5CE7
If NC FLAG is set (opcode ≥40H, range 40-BF), jump to 5D30H to advance 1 byte (single-byte instruction)
Check for LD instructions with 16-bit immediate operands (opcodes 01H, 11H, 21H, 31H)
5CE9
AND 0FHAND 00001111 E60F
Perform logical AND with 0FH to isolate lower 4 bits of opcode
5CEB
CP 01H FE01
Compare with 01H. If equal, Z FLAG is set (LD BC/DE/HL/SP,nnnn instructions)
5CED
If Z FLAG is set (16-bit load instruction), jump to 5D0FH to process address operand
5CEF
AND 07HAND 00000111 E607
Perform logical AND with 07H to further isolate bits
5CF1
If NZ FLAG is set (not special case), jump to 5CF8H to continue checking
5CF3
LD A,(HL) 7E
Load Register A with opcode again
5CF4
CP 10H FE10
Compare with 10H (DJNZ opcode). If less, C FLAG is set; if ≥10H, NC FLAG is set
5CF6
If NC FLAG is set (opcode ≥10H), jump to 5D0CH to advance 2 bytes (instruction + 1-byte operand)
5CF8
LD A,(HL) 7E
Load Register A with opcode
5CF9
CP 20H FE20
Compare with 20H (JR NZ opcode). Tests if opcode ≥20H
5CFB
If C FLAG is set (opcode < 20H), jump to 5D03H for additional checks
5CFD
AND 07HAND 00000111 E607
Isolate lower 3 bits
5CFF
CP 02H FE02
Compare with 02H (LD (BC/DE),A or LD A,(BC/DE) instructions)
5D01
If Z FLAG is set, jump to 5D0FH to process 3-byte instruction
5D03
LD A,(HL) 7E
Load Register A with opcode
5D04
AND 07HAND 00000111 E607
Isolate lower 3 bits
5D06
CP 06H FE06
Compare with 06H (LD r,n instructions)
5D08
If NZ FLAG is set (not LD r,n), jump to 5D30H to advance 1 byte
5D0A
DEC HL 2B
Decrement HL (back up)
5D0B
INC HL 23
Increment HL (net effect: no change, possible debugging artifact)
5D0C
INC HL 23
Increment HL to skip 1 byte
5D0D
Jump to 5D30H to advance pointer and continue
[PROCESS 3-BYTE INSTRUCTION] Extract and relocate 16-bit address operand
5D0F
INC HL 23
Increment HL to point to address low byte
5D10
LD E,(HL) 5E
Load Register E with address low byte
5D11
INC HL 23
Increment HL to point to address high byte
5D12
LD D,(HL) 56
Load Register D with address high byte (DE now contains full 16-bit address)
5D13
PUSH HL E5
Save HL on stack (preserve instruction pointer)
Check if address is within spooler code range (5200H-58F9H)
5D14
LD HL,51FFH 21FF51
Load HL with 51FFH (one below spooler buffer start 5200H - lower bound check)
5D17
OR A B7
Clear carry flag for subtraction
5D18
SBC HL,DE ED52
Subtract DE from HL. If DE > 51FFH, result is negative and C FLAG is set; if DE ≤ 51FFH, NC FLAG is set
5D1A
If NC FLAG is set (address ≤ 51FFH, below spooler range), jump to 5D2FH to skip relocation
5D1C
LD HL,58F9H 21F958
Load HL with 58F9H (end of spooler code - upper bound check)
5D1F
OR A B7
Clear carry flag for subtraction
5D20
SBC HL,DE ED52
Subtract DE from HL. If DE > 58F9H, result is negative and C FLAG is set (above range)
5D22
If C FLAG is set (address > 58F9H, above spooler range), jump to 5D2FH to skip relocation
[RELOCATE ADDRESS] Address is in range, adjust it
5D24
POP HL E1
Restore HL from stack (instruction pointer)
5D25
EX (SP),HL E3
Exchange HL with top of stack (get relocation offset, save instruction pointer)
5D26
EX DE,HL EB
Exchange DE and HL (HL now has address to relocate, DE has offset)
5D27
ADD HL,DE 19
Add relocation offset to address (HL = original_address + offset)
5D28
EX DE,HL EB
Exchange back (DE now has relocated address)
5D29
EX (SP),HL E3
Exchange HL with top of stack (restore instruction pointer, save offset back)
5D2A
DEC HL 2B
Decrement HL to point back to address low byte in copied code
5D2B
LD (HL),E 73
Store relocated address low byte
5D2C
INC HL 23
Increment HL to point to address high byte
5D2D
LD (HL),D 72
Store relocated address high byte (address now updated in copied code)
5D2E
PUSH HL E5
Save HL on stack again
5D2F
POP HL E1
Restore HL from stack (cleanup stack or get instruction pointer back)
[ADVANCE POINTER] Move to next instruction
5D30
INC HL 23
Increment HL to next byte in code
5D31
OR A B7
Clear carry flag for subtraction
5D32
SBC HL,BC ED42
Subtract end address (BC) from current position (HL). If HL ≥ BC, result is ≥0 and NC FLAG is set (scan complete)
5D34
If NC FLAG is set (reached or passed end address), jump to 5D82H to complete installation
5D36
ADD HL,BC 09
Add BC back to HL to restore current address
5D37
[LOOP END] Jump back to 5CE0H to process next instruction
[SPECIAL INSTRUCTION HANDLERS] Handle JP, CALL, and prefix instructions
5D39
CP C3H FEC3
Compare with C3H (JP nnnn opcode)
5D3B
If Z FLAG is set (JP instruction), jump to 5D0FH to process 3-byte instruction
5D3D
CP CDH FECD
Compare with CDH (CALL nnnn opcode)
5D3F
If Z FLAG is set (CALL instruction), jump to 5D0FH to process 3-byte instruction
5D41
CP DDH FEDD
Compare with DDH (IX prefix)
5D43
If Z FLAG is set (IX prefix instruction), jump to 5D6BH to handle prefix byte
5D45
CP FDH FEFD
Compare with FDH (IY prefix)
5D47
If Z FLAG is set (IY prefix instruction), jump to 5D6BH to handle prefix byte
5D49
CP EDH FEED
Compare with EDH (extended instruction prefix)
5D4B
If Z FLAG is set (ED prefix), jump to 5D61H to handle extended instructions
5D4D
CP CBH FECB
Compare with CBH (bit instruction prefix)
5D4F
If Z FLAG is set (CB prefix), jump to 5D0CH to advance 2 bytes
5D51
CP D3H FED3
Compare with D3H (OUT (n),A opcode)
5D53
If Z FLAG is set (OUT instruction), jump to 5D0CH to advance 2 bytes
5D55
CP DBH FEDB
Compare with DBH (IN A,(n) opcode)
5D57
If Z FLAG is set (IN instruction), jump to 5D0CH to advance 2 bytes
5D59
AND 07HAND 00000111 E607
Isolate lower 3 bits
5D5B
CP 04H FE04
Compare with 04H (CALL cc,nnnn instructions)
5D5D
If Z FLAG is set (conditional CALL), jump to 5D0FH to process 3-byte instruction
5D5F
Jump back to 5CFDH for further processing
[ED PREFIX HANDLER] Handle extended instructions
5D61
INC HL 23
Increment HL to get next byte after ED prefix
5D62
LD A,(HL) 7E
Load Register A with extended opcode
5D63
AND C7H E6C7
Mask bits to check for specific instructions
5D65
CP 43H FE43
Compare with 43H (LD (nnnn),rr instructions)
5D67
If Z FLAG is set (LD (nnnn),rr), jump to 5D0FH to process 4-byte instruction (ED prefix + 3 bytes)
5D69
Otherwise jump to 5D30H to advance 1 byte
[IX/IY PREFIX HANDLER] Handle index register instructions
5D6B
INC HL 23
Increment HL to get next byte after DD/FD prefix
5D6C
LD A,(HL) 7E
Load Register A with indexed instruction opcode
5D6D
SUB 34H D634
Subtract 34H (test for INC (IX+d) or DEC (IX+d) range)
5D6F
CP 02H FE02
Compare result with 02H
5D71
If C FLAG is set (result < 02H, opcodes 34H-35H), jump to 5D0CH to advance 2 bytes (prefix + opcode + displacement)
5D73
If Z FLAG is set (result = 02H, opcode 36H = LD (IX+d),n), jump to 5D0BH to advance 3 bytes
5D75
LD A,(HL) 7E
Load Register A with indexed opcode again
5D76
CP CBH FECB
Compare with CBH (indexed bit instruction prefix)
5D78
If Z FLAG is set (DDCB or FDCB instruction), jump to 5D0BH to advance 3 bytes
5D7A
SUB 40H D640
Subtract 40H to check instruction range
5D7C
CP 80H FE80
Compare with 80H (128 decimal)
5D7E
If NC FLAG is set (result ≥80H), jump to 5D31H to advance 1 byte
5D80
Otherwise jump to 5D0CH to advance 2 bytes
5D82H - Installation Completion
Completes spooler installation after relocation. Verifies relocation successful, displays "SPOOL ACTIVE" message, updates system vectors to point to relocated code, adjusts HIGH$ memory limit, and initializes printer driver. Entry: Relocation complete, offset and addresses on stack. Exit: Spooler installed and active, returns to DOS.
[VERIFY RELOCATION COMPLETE] Error check
5D82
LD A,3AH 3E3A
Load Register A with 3AH (DOS error code: colon - indicates error)
5D84
If NZ FLAG is set (relocation ended prematurely, error condition), jump to DOS error handler at 4409H with error code in A
[DISPLAY ACTIVATION MESSAGE]
5D87
LD HL,5DC4H 21C45D
Load HL with 5DC4H (address of "SPOOL ACTIVE" + 0DH message)
5D8A
Call DOS print string routine to display activation message to user
[INSTALL RELOCATED PROGRAM] Update system pointers
5D8D
DI F3
Disable interrupts during critical system vector updates
5D8E
POP DE D1
Restore DE from stack (get relocation offset)
5D8F
LD HL,5450H 215054
Load HL with 5450H (original program start address)
5D92
ADD HL,DE 19
Add relocation offset to get new program start address (relocated entry point)
5D93
PUSH DE D5
Save DE on stack (preserve offset)
5D94
Call DOS routine at 4461H to install program at address in HL. Returns with Z FLAG set on success, NZ FLAG on error
5D97
If NZ FLAG is set (installation error), jump to DOS error handler at 4409H
[UPDATE SYSTEM VECTORS] Point vectors to relocated code
5D9A
POP DE D1
Restore DE from stack (relocation offset)
5D9B
POP HL E1
Restore HL from stack (original HIGH$ - program_size from 5CBBH)
5D9C
LD (4049H),HL 224940
Store new HIGH$ value at 4049H (protect relocated spooler from BASIC/DOS memory allocation)
5D9F
LD HL,550BH 210B55
Load HL with 550BH (address of return instruction in spooler's operation handler)
5DA2
ADD HL,DE 19
Add relocation offset (calculate new address of return point)
5DA3
LD (4026H),HL 222640
Store relocated return address at 4026H (keyboard break vector - spooler intercepts break key)
5DA6
LD HL,5661H 216156
Load HL with 5661H (address of printer input buffer check routine)
5DA9
ADD HL,DE 19
Add relocation offset (calculate new address)
5DAA
LD (4016H),HL 221640
Store relocated buffer check address at 4016H (system vector - intercepts printer operations)
5DAD
LD HL,5755H 215557
Load HL with 5755H (address of printer driver vector table)
5DB0
ADD HL,DE 19
Add relocation offset (calculate new address of vector table)
5DB1
EX DE,HL EB
Exchange DE and HL (DE now has relocated vector table address)
5DB2
EI FB
Enable interrupts after completing critical section
[INSTALL PRINTER DRIVER] Conditionally install driver if configured
5DB3
LD A,01H 3E01
Load Register A with 01H - NOTE: This is self-modifying code (address 5DB4H contains interrupt driven printer flag from installation)
5DB5
OR A B7
Perform logical OR of Register A with itself to test flag. If A=00H (driver not needed), Z FLAG is set; if A=01H (install driver), NZ FLAG is set
5DB6
If NZ FLAG is set (install driver requested), call DOS driver installation routine at 4410H with vector table address in DE
5DB9
Jump to DOS return routine at 402DH to exit to DOS (spooler now installed and active)
5DBCH - Baud Rate Lookup Table
Lookup table for printer baud rate configuration values. Indexed by baud rate setting from expansion interface port E9H (bits 0-2). Table contains port configuration values for different baud rates.
5DBC
DEFB 22H 22
Data: 100 baud (index 0)
5DBD
DEFB 44H 44
Data: 150 baud (index 1)
5DBE
DEFB 55H 55
Data: 300 baud (index 2)
5DBF
DEFB 66H 66
Data: 600 baud (index 3)
5DC0
DEFB 77H 77
Data: 1,200 baud (index 4)
5DC1
DEFB AAH AA
Data: 2,400 baud (index 5)
5DC2
DEFB CCH CC
Data: 4,800 baud (index 6)
5DC3
DEFB EEH EE
Data: 9,600 baud (index 7)
5DC4H - Final Message String
Completion message displayed when spooler is successfully installed and activated.
5DC4-5DD0
DEFM "SPOOL ACTIVE" + 0DH
End of Program
Program Entry Point: 5C4BH - Alternative command entry for 'I' (Install) and 'A' (purge All) commands.