PIA 63F21

Friday 14 June 2024, by 63F09 // Peripherals

This component runs as a regular MC6821. Please note that 63F21 only contains half MC6821.

The parallel interface (PIA 63F21)

PIA_63F21 is a peripheral interface adapter modelled on the classic 6821 PIA — but, as the source itself warns, only half of one: a single 8-bit bidirectional port with its two handshake lines (C1, C2), not the real chip’s two independent ports.

One port, direction set per bit

PORT_D is a genuine bidirectional bus, built from one IOBUF primitive per bit, each individually steered by its own bit of PORT_DDR (the Data Direction Register): '0' makes that bit an input, '1' an output. Reading the port returns either the last value written (PORT_DATA, for output bits) or the live external level (PORT_D_IN, for input bits) — bit by bit, so a single port can freely mix input and output lines.

Two addresses, disambiguated by the control register

The peripheral only exposes two register addresses (A='0'/A='1'), and one bit of the control register decides what A='0' actually reaches:

  • Control register (A='1', 6 writable bits plus two read-only flags) — bit 2 selects whether A='0' currently means the DDR or the data port; bit 1 picks which edge of C1 counts as active (high-to-low or low-to-high); bit 0 enables the IRQ this active edge raises; bits 5-3 configure C2, described below. Bits 7 and 6, read only, are the latched C1/C2 interrupt flags themselves.
  • Data/DDR register (A='0') — the data direction register while control bit 2 is '0', the actual port data once it is '1'.

C1: a pure edge-triggered interrupt input

C1 only ever generates an interrupt flag — it drives nothing back out. Its rising and falling edges are both tracked; whichever one control bit 1 selects as “active” sets the IRQ1 latch, which stays set until the data port is actually read (PORT_READ, driven whenever a read with CS asserted targets the data-port address).

C2: input or a small set of output behaviours

Control bit 5 decides C2’s whole personality: '0' makes it a second edge-triggered interrupt input, exactly like C1 (polarity picked by bit 4, latched into IRQ2, cleared the same way by a port read). '1' turns it into an output, and bits 4-3 then pick one of four fixed behaviours: pulse high on a C1 active edge and low again on the next port read; toggle low/high once per E cycle around a port read; or simply drive a fixed '0' or '1'.

Interrupt output

IRQ_n is the OR of the two latches, each gated by its own enable — IRQ1 by control bit 0, IRQ2 by control bit 3, the latter itself only meaningful while C2 is configured as an input (bit 5 clear). The peripheral never inserts wait states of its own — MRDY is tied permanently to '1'.