|
Z80 Build From Scratch |
| PAGE 11: UART Addressing |
|
Input/Output (I/O): We could use an 82C55A PPI (programmable peripheral interface) with 3 parallel input/output data ports to talk to a keypad input, LCD panel output, etc., but not at this time. Instead we're going to adapt a PC16550D which is a UART (universal asynchronous receiver transmitter) to communicate with our PC's terminal emulation program, Tera Term.
MREQ & IORQ: The MREQ (Memory Request) and IORQ (Input/Output Request) signals are control lines used by the Z80 to differentiate between memory operations and I/O device operations using a method called isolated I/O. The CPU uses the same physical address and data buses for both memory and I/O. The MREQ and IORQ signals on the control bus determine which type of device should respond to the address on the address bus.
I/O Access: The CPU places the I/O port address on the address bus. The CPU pulls the IORQ line low. External I/O interface logic recognizes the low IORQ signal and enables the I/O device (e.g., an input port or output port) to respond to the address on the address bus, connecting the device to the data bus. The MREQ line remains high, so memory chips do not respond. An IORD is the combination of both IORQ and RD being low, whereas an IOWR is the combination of both IORQ and WR being low.
The Z80 system allows the microprocessor to use a separate address space for I/O devices from its main memory address space. ROM can exist at address $0000 to $7FFF and I/O can exist in the same range but limited to 256 locations $00 to $FF using address lines A0 to A7. We will need combinational logic to address the I/O devices differently than memory devices. If the maximum number of registers needed for any I/O device is typically 8, and 256 addresses / 8 registers = 16, then we could support 16 different devices with 8 registers each. That means we'll need an addressing scheme to keep the devices and address ranges separate. The PC16550DN uses 8 registers to initialize and run the UART.
A 74HCT138 3-line to 8-line decoder/multiplexer will work: three input lines can give us 8 output lines. If combined with a 74HCT139, we could double that number. But not today.
74138 3-Line to 8-Line Decoder
How do we address devices? In the table above, if the Select Inputs C, B, A are address lines A2, A1 and A0 then we'll start at line 6. If all 3 inputs are low, then the Y0 output will be low. We could use this to select the first device like a UART. In line 7 above, if address line A0 is a high, then the Y1 output will be a low. We could use this to select the second device like a PPI. In all we could address 8 different devices using this scheme.
However... If we use A2 to A0 to select a device like a UART and it has own 3 address lines using A2 to A0 to accept commands or transfer data, then how do we send commands to a PPI? We select a higher starting address for the device. We know we need 3 sequential input lines so let's use the address weighting table below that's named I/O Addressing Ranges. If we choose A3 thru A5 to select the device, then the device selected with A5 = 0, A4 = 0 and A3 = 0 would be binary address 000xxx or decimal 0. Its address range would be 000000 to 000111 or 0 to 7. If A3 = 1, then the range would start with 001xxx or decimal 8. With the device selected then its first register address would be $08 and the last register address would be $0F. Consult the table to see other examples. So... the UART could be at $00 or 0x00 or 00h or 0 - however you wish to describe it. A PPI could be at $08 An LCD panel could be at $10. A keypad could be at $18. Etc.
When we define the register addresses at the top of our Z80 assembly code for the PPI as an example, we could say that the device base = $08, the first register would be at base +1, the second at base +2. This will make it much easier to keep track of the registers rather than having to use $8, $9, etc. An if we need to make a change, we only have to change the base value. You will see this in several upcoming code examples.
|
Updated 2025-11-27