The Need for Bit-Banging

The Z80 CPU does not have a built-in UART (Universal Asynchronous Receiver/Transmitter) for serial communication. To send data to a modem or another computer, we must bit-bang the signal: we use software and timing loops to manually control the state of an I/O pin.

Key Components:

  1. I/O Port: A dedicated hardware output port (often the same as the beeper port) where one bit is wired to the serial output pin.
  2. Timing Loops: Precise timing loops (using T-states) to control the Baud Rate (bits per second).

The Serial Data Format

Serial communication sends one byte at a time, surrounded by fixed timing signals:

  1. Start Bit: Always a logic 0 (low signal).
  2. Data Bits: The 8 bits of the data byte (sent least significant bit first).
  3. Stop Bit: Always a logic 1 (high signal) to end the transmission.

Sending a Byte (The Bit-Banging Routine)

The routine requires one main loop that runs 10 times (1 start bit + 8 data bits + 1 stop bit).

The Steps:

SERIAL_PORT EQU 0FEH        ; Example I/O port address
SERIAL_BIT  EQU 04H         ; Bit 4 controls the serial pin (00010000B)

SEND_BYTE:
    ; Assume the byte to send is in the C register.
    LD   B, 10              ; 10 bits total (Start, 8 Data, Stop)

    ; --- 1. Send Start Bit (Always 0) ---
    RES  4, A               ; Ensure bit 4 is 0 (low signal)
    OUT  (SERIAL_PORT), A
    CALL DELAY_ROUTINE      ; Delay for exactly 1 bit-time

SEND_LOOP:
    ; --- 2. Send Data Bit (Check Carry Flag) ---
    RRCA                    ; Rotate the lowest bit of A into the Carry Flag (C)
    JP   C, SEND_ONE        ; If C=1, send a high signal
    
    ; Send Zero (0) Signal
    RES  4, A               ; Set bit 4 low
    OUT  (SERIAL_PORT), A
    JP   NEXT_BIT

SEND_ONE:
    ; Send One (1) Signal
    SET  4, A               ; Set bit 4 high
    OUT  (SERIAL_PORT), A

NEXT_BIT:
    CALL DELAY_ROUTINE      ; Wait 1 bit-time (Baud Rate Delay)
    DJNZ SEND_LOOP          ; Loop 8 times for data, then 1 for stop bit

    ; --- 3. Final Cleanup ---
    SET  4, A               ; Ensure line ends high (Stop Bit)
    OUT  (SERIAL_PORT), A
    RET

The DELAY_ROUTINE: This routine must be precisely timed to match the desired baud rate (e.g., 9600 baud requires a delay of ~104 microseconds per bit). Any deviation will corrupt the data.