The Challenge of Reliable Input
In receiving serial data, the Z80 must wait for the exact moment the Start Bit arrives and then sample the input line precisely at the center of each of the next eight data bits. If the CPU misses the timing, the data is corrupted.
The Solution: Interrupt-Driven Sampling The CPU cannot wait in a tight timing loop for data to arrive. Instead, we use a timer interrupt to tell the CPU exactly when to check the input line.
The Two-Stage Process
Serial receiving is handled in two stages:
Stage 1: Detecting the Start Bit The CPU monitors the serial input pin (often using a short loop or a dedicated hardware interrupt) until it detects the line drops from a high signal (1) to a low signal (0) — the start bit.
SERIAL_INPUT_BIT EQU 08H ; Bit 3 of I/O port FFH (Example)
INPUT_PORT EQU 0FFH
WAIT_FOR_START:
IN A, (INPUT_PORT)
BIT 3, A ; Check the state of the input line
JP NZ, WAIT_FOR_START ; Loop while the line is high (1)
; Line is now low (0). Start bit detected!
CALL ARM_TIMER_INTERRUPT ; Set timer to fire at the center of the first data bit
RET
Stage 2: Sampling via Timer Interrupt
The CPU arms a Timer Interrupt that is configured to fire exactly at the time midpoint of each subsequent data bit.
The ISR (Interrupt Service Routine) Logic:
ISR_SERIAL_HANDLER:
PUSH AF ; Save the Accumulator and Flags
; 1. Read the input line at the sample point
IN A, (INPUT_PORT)
; 2. Extract the data bit (e.g., using AND and a mask)
AND SERIAL_INPUT_BIT ; Mask out all other bits
; 3. Store the bit into a shift register in RAM
CALL SHIFT_DATA_IN ; Routine to build the byte from 8 individual bits
; 4. Check if 8 bits are received (the byte is complete)
; If complete, store the finished byte in a receive buffer (FIFO).
POP AF
RETI ; Return from interrupt
Buffering Input Data (FIFO)
Because serial data can arrive faster than the main CPU loop can process it, the Interrupt Service Routine must place received bytes into a First-In, First-Out (FIFO) buffer in RAM. The main program loop then reads data from the FIFO buffer when it is ready. This is critical for preventing data loss.