The Drawback of Polling
Printers are extremely slow compared to the Z80 CPU. If the main program waits for the NOT BUSY status bit (Part 76) after sending every single character, the CPU spends most of its time sitting idle, waiting for the printer to finish.
The Solution: Interrupt Spooling Spooling (Simultaneous Peripheral Operations On-Line) uses interrupts to feed the printer one byte at a time in the background, allowing the main program to continue executing tasks.
The Print Buffer (The Spool)
The OS kernel maintains a Circular Buffer (or Ring Buffer) in RAM, often called the Print Spool.
How the Buffer Works:
- Main Program: Writes an entire block of text to the buffer quickly, then continues.
- ISR: The background Interrupt Service Routine (ISR) slowly reads the characters out of the buffer one by one, sending them to the printer.
The Printer Interrupt Service Routine (ISR)
The ISR is the core of the spooler. It must be triggered when the printer is ready for the next character. This can be done by a dedicated Peripheral Interrupt (if the printer interface supports it) or a fixed-rate Timer Interrupt.
The ISR Logic:
PRINTER_ISR:
PUSH AF, HL, DE, BC ; Save Context
; 1. Check Printer Status: Poll the Status Port (Part 76)
CALL PRINTER_GET_STATUS
BIT 7, A ; Check if NOT BUSY (Ready)
JP NZ, ISR_EXIT ; If Busy, exit immediately
; 2. Check Spool Buffer: See if there is data waiting
CALL SPOOL_BUFFER_EMPTY
JP Z, ISR_EXIT ; If buffer is empty, nothing to print
; 3. Get Next Character: Read the next character from the Ring Buffer
CALL SPOOL_BUFFER_READ ; A ← Next character to print
; 4. Send Data and Strobe
OUT (PRINTER_DATA_PORT), A ; Send character
CALL PRINTER_STROBE ; Activate the strobe signal
ISR_EXIT:
POP BC, DE, HL, AF
RETI ; Return from Interrupt
Writing to the Spool
The OS provides a system call (`PUT_SPOOL_CHAR′) that allows a user program to add data to the buffer without having to wait for the slow printer.
The PUT_SPOOL_CHAR Logic:
- Check if the spool buffer is full.
- If full, the main program must halt (`HALT′) until the background ISR clears some space.
- If space is available, write the character into the buffer and update the buffer’s Write Pointer.
- Return control immediately to the main program.