Repository navigation
Host Bus Timing
This page documents what the PICO9918 actually does on the TMS9918A host bus, cycle by cycle. Every figure here is derived from the PIO programs in src/tms9918.pio, measured against the CPU-VDP interface timing in the TMS9918A datasheet (Figures 5-3 and 5-4). Read the note below before relying on a number.
Important
The cycle-by-cycle figures on this page do not match any released firmware. They were derived from a development state that predates the v1.2.0 release. Every public release from v1.2.0 (the newest one) onward differs in three ways:
-
The PIO clock is not pinned. This page assumes a fixed 252 MHz PIO rate on every clock preset.
v1.2.0 sets
clkdiv = 1.0on both bus state machines (src/main.c:741,760; the same call is atsrc/tms_bus.c:223,237on the development branch), so the PIO runs at the full system clock and every nanosecond figure below scales with the selected preset. -
The read program samples MODE before driving the bus, not after. In
src/tms9918.piothenop [7]settling delay andin pins, 1both come ahead ofout pindirs, 8, so the real order is settling check -> MODE ->pindirs-> data byte. The Read cycle table below has the opposite order, and the paragraph above it explains at length why the opposite order was necessary. -
The write program delays its MODE sample by 8 PIO cycles (
wait 0 gpio CSW_PIN [7]), where this page assumes MODE is captured immediately on the strobe edge.
Nothing structural is wrong. The signal path, the settle-then-commit glitch rejection, the read-ahead FIFO
word and the reason MODE and write data are sampled at opposite ends of a write all still hold. But the
numbers want re-deriving, and pico9918-read-cycle.svg encodes the superseded instruction order.
It is a reference for two situations: diagnosing a host that misbehaves, and understanding why the interface is built the way it is. If you are looking for the firmware's overall structure instead, see Firmware Architecture.
Both host interface state machines run on pio1 with clkdiv = 1.0 - that is, at the full system clock, whatever preset is selected. There is one timing profile per preset, not one overall:
| Preset | System clock | PIO cycle |
|---|---|---|
| VGA 0 (default) | 252 MHz | 3.968 ns |
| VGA 1 | 302.4 MHz | 3.307 ns |
| VGA 2 | 352 MHz | 2.841 ns |
| SCART 0 (default) | 270 MHz | 3.704 ns |
| SCART 1 and 2 | 324 MHz | 3.086 ns |
Every [n] delay in the PIO programs is a cycle count, so the settling windows and guard bands below shrink by 28% between the slowest and the fastest preset. Read the tables that follow as cycle counts first and nanoseconds second, and scale the nanosecond column by the row for your preset.
Note
The nanosecond figures throughout the rest of this page are the 252 MHz column, and they also assume the pre-v1.2.0 instruction order described in the banner above. Treat them as the shape of the timing rather than as measurements.
MODE, /CSW and /CSR all reach the MCU through U6, but not by the same route.
/CSR is deliberately jumpered back through four of U6's channels instead of one. The read cycle specifies tsu(A-RL) = 0 ns, meaning MODE is only guaranteed valid at the falling edge with no setup margin at all. The extra passes manufacture that margin in hardware: by the time the MCU sees /CSR_L fall, MODE_L has been stable at the pin for 11-20 ns.
MODE and /CSW take a single pass each, so their buffer delay is common mode and cancels between them. That is what allows the write path to sample MODE right at the /CSW edge.
The same delayed /CSR_L also drives U5's DIR pin, which has a consequence for the read cycle below.
U5's direction pin is wired straight to /CSR_L, so the transceiver turns toward the host on the strobe edge whether or not the MCU is ready. The PIO therefore drives CD0-7 as soon as it recognises the strobe, before the settling check rather than after it. Driving later would leave U5 forwarding an MCU-side input that nothing was driving.
| Event | After /CSR_L
|
Cycles |
|---|---|---|
| GPIO synchroniser | 8-12 ns | 2-3 |
| Poll loop detects the strobe | +0-12 ns | 0-3 |
pindirs set to outputs |
16-32 ns | 4-8 |
| Data byte on the bus | 20-36 ns | 5-9 |
| Settling check | 56-71 ns | 14-18 |
| MODE sampled | 60-75 ns | 15-19 |
| Status byte on the bus | 71-87 ns | 18-22 |
End to end, a data read takes 44-86 ns from the host's /CSR edge to a valid byte back at the socket, adding U6 (11-20 ns) and U5 (13-30 ns). On v1.3 boards add U4, a further 4-7 ns. A Z80 at 4 MHz allows roughly 375 ns, so the margin is comfortable.
The read program cannot know which byte the host wants until it has sampled MODE, and it drives before that. So on a status read the data byte appears at 20-36 ns and is replaced by the status byte at 71-87 ns.
Against any real host's sampling point this is invisible, but it is worth knowing when probing the bus with an analyser: a status read genuinely does show two different bytes during the cycle.
The write cycle is the mirror image of the read, and the two halves are sampled at opposite ends on purpose:
-
MODE is only guaranteed for
th(WL-A)= 30 ns after/CSWfalls. It is sampled about 4 ns in, leaving 26 ns of margin. The GPIO synchroniser delay cancels between thewaitand the read, because both observe the same synchronised signal. -
Write data is only guaranteed for
tsu(D-WH)= 100 ns before/CSWrises. It is captured 4-16 ns before the rise, from the poll loop's last sample.
Sampling either one at the other's moment would be a spec violation, which is why the program captures MODE once at the start and then polls the bus continuously until the strobe releases.
| Event | Timing | Budget |
|---|---|---|
| MODE sampled | ~4 ns after the fall |
th(WL-A) = 30 ns |
| Entry settling check | 24 ns after the fall |
tw(WL) = 200 ns |
| Data captured | 4-16 ns before the rise |
tsu(D-WH) = 100 ns |
| Exit settling check | 32 ns after the rise |
th(WH-D) = 30 ns |
| Word reaches the FIFO | ~48 ns after the rise |
tw(CS-H2) = 2 us |
The exit check sits past the 30 ns data hold time, which looks wrong at first glance. It is safe because the value pushed was latched before the strobe rose; nothing is read from the bus after it.
Both strobes are checked for settling before the access is allowed to proceed.
On the write path this matters most. Without it, a few nanoseconds of ringing on /CSW is enough to start a cycle, and the result is a phantom write: a VRAM byte, a register write, or a desynchronised address flip-flop, depending on what MODE and the data bus happened to hold.
The check is placed after MODE and the data are sampled, not before. Sampling first costs nothing against th(WL-A), and the cycle can still be discarded afterwards if the strobe turns out not to have settled.
The window is 24 ns, about 12% of the 200 ns a real write cycle is specified to hold /CSW low. A genuine cycle from any supported host clears it by an order of magnitude.
On the read path the equivalent check happens after the bus has already been driven, so a short pulse still gets valid data. What the check decides there is whether to continue to the MODE sample and complete the transaction.
- All nanosecond figures are the 252 MHz column. They do move with the configured system clock - multiply the cycle counts by that preset's PIO cycle from the table above.
- Buffer delays are taken from the 74LVC245A and 74HC245 datasheets and vary with temperature and supply voltage; the ranges given are typical, not worst case.
-
tw(CS-H1)= 8 us is the datasheet's minimum interval between accesses. Fast hosts violate it routinely, a 4 MHz Z80 runningOTIRmanages about 5.25 us, and the original part drops or corrupts accesses under that condition. The PICO9918 does not. - The board revisions differ in the data path only. v1.3 has two buffer hops (U5 and U4), v2.0 has one (U5). MODE and strobe timing is identical on both.
- Firmware Architecture - how the PIO state machines fit into the wider firmware
- Hardware - board revisions, connectors and buffer topology
- TMS9918 Family - the original parts and their variants
- PICO9918 Programmers Reference - register and VRAM behaviour
Hardware
Supported Devices
Firmware
- Firmware
- Firmware Version History
- Display Output
- Building from Source
- Firmware Architecture
- Firmware Testing
Configurator
Programming
Reference