C128 hardware bugs


While developing software for a few new C128/C64 I/O devices, which are targeted for CP/M mostly (z80 side of the c128) I have discovered a very interesting bug in the c128 and c128d with respect to the I/O timing cycle when used from the z80. I was optimizing the code to get the absolute best native transfer rate, and things stopped working. Upon looking at the C128 hardware reference guide, and comparing the timing diagrams of the Z80 CPU, I discovered that CBM missed one case as far as the transaltions from a Z80 cycle to an AEC cycle.

Normally, the z80 is clocked on the opposite cycle of the VIC chip, and gets to perform 2 t-cycles. While this works, it fails on but a few handy instructions. The instructions that end up out of sync with theta2 (the main clock on the 64/128 CPU bus) are:
OUTI
OUTIR
OUTD
OUDR

The reason for this is quite obvious, if one looks at the cycle timings of the instructions. The only way to get arround this hardware bug is to use plain out (c),X instructions. The loss in T-ststes will cause a drop in performance, unfortunatly. A hardware fix would involve trapping the 4 cases in hardware, and inserting a wait state on the z80.
Here is a diagram of any of the above opcodes, overlayed on an AEC access.
Timing Diagram
Scanned from "Commodore 128 Programmer's Reference Guide", page 576

Note how the Z80 gets 2 clocks to do it's work. On the second clock, depending on the state of the read and write lines from the Z80, will depend on if data is presented to the Z80 from an on-board latch from the previous AEC cycle while it is low. If it is a write, the data is written from the Z80 via a buffer chip. This is done to syncronize with on-board I/O cycles and form a 65xx family access cycle, page 575 describes it fully.

In order to understand the effect, one needs to look at what the Z80 cycle looks like during the instruction. In plain words, without the need for another timing diagram, the each clock cycle is considered a T-state. The automatic out timing (with instruction fetch) does the following:
OUTI: (C) <- (HL), B = B -1, HL = HL + 1
16 Tstates (4, 5, 3, 4), 4 M cycles

M1 gets the data from (HL)
M2 saves the data to (BC)
M3 decrements B
M4 increments HL

Note that M2 is an odd number. This is important, since the data won't make it to the hardware. Outputs on an EVEN cycle do.
Compare to:
OUT (C),r: (C) <- r
12 Tstates (4,4,4) 3 M cycles

All 3 M cycles are EVEN, thus work! I'm not certain what M cycle does the actual work, but if you look thru the entire Z80 opcode timings, all others do the access on an even Tstate count, thus they function without trouble on the C128.

All Z80 cycle counts and timing diagrams can be compared to the graphic on this page. The document is available at www.zilog.com/docs/z80/um0080.pdf
Testing software:
source and Binary for C128 CP/M mode.

Same info in:
Staroffice 5 Version
Word95 Version


All pages (C) Andrew J. Kroll, FTSOY priest, SAASTLA member
ALL YOUR BASE ARE BELONG TO US

Valid HTML 4.01 Transitional