Zilog Z8615

Clawgrip sent me a 40-pin DIP from the SGI O2 keyboard labeled Zilog 1118 RT101+228A 119565-002A. The die was marked 8615, so it's the Z8615 keyboard controller. The datasheet's feature list matches with the Z8611 general purpose microcontroller, so I bought a few of those off ebay. Well, actually the chips were marked U8611DC08.

The Z8611 can be electronically dumped by attaching a ROM and entering test mode by applying 7.5 volts to /reset, but on the Z8615 the address strobe output was replaced with a watchdog timer output. So the idea was to dump the Z8611 electronically, decap it, then map the bits in the ROM array to the ROM dump, and use that to transcribe the bits in the Z8615. The Z8611s I got were not even half-filled, so there is the potential that the unused part of the ROM might be mapped differently.

Both ROM arrays have 256 columns and 130 rows. 128 of the rows provide the 4K of program ROM space and the other 2 rows are the 64 bytes of test ROM.

There is a Zilog Application Note from 1982 titled Z8 MCU Test Mode that contains the code from the test ROM of the Z8601, the 2K little brother of Z8611. When executed, it configures the chip for external ROM, then jumps to address $0812 in that external ROM (the first 18 bytes are reserved for 6 vectors). The app note says the interrupt vectors in the Z8611 test ROM point to $10xx addresses instead of $08xx addresses used in Z8601, so I assumed everything else was the same but shifted.

I built a circuit on a piece of experimenter perf board, using a GAL to latch the address signals from the Z8611 and a 2732 EPROM to hold my code. I only connected the lower 8 address lines, so my code had to fit in 256 bytes, but that was much more than needed. My code set port 2 as output, set one register pair to the address $0000 and another to the count of $1000, then used the LDC opcode to read a byte indirectly from the first register pair. I stored that byte in port 2, toggled a flag bit, then incremented the address and decremented the count, and repeated until all the bytes were read.

I clocked the chip externally at 1MHz, slower than the 12.5MHz listed in the datasheet. I connected port 2 to a Saleae Logic, started a capture, turned on power and raised /reset to 7.5V, but I only saw the flag bit toggling. I tried different frequencies and 7v-8v on /reset, and played around with the code a bit, but still didn't see any data. I went back to the datasheet and saw that port 2 is open drain and one of the bits in the port 3 mode register turns on pullups. Since I already had the board at my solder station checking for problems, I just added a 1K resistor network. Now when I powered up I got output.

I counted 1-bits in the electronic dump and my visual transcription of the Z8611 ROM array and they nearly matched. Then I compared counts of 1-bits in each bit position 0-7 of the electronic dump to counts of 1-bits in each group of 32 columns of the ROM array. Turns out they were in order, msb on the right. Now I had all 4K bytes, but I had to figure out what order to put them into. In many microcontrollers, the ROM array columns are pages; bytes come from one column (in some order, not necessarily top to bottom) for every row, then switch to another column (in some order, not necessarily left to right).

After lots of experimentation, I figured out that this one was different; the 32 columns in each row were used first, then another row was selected. The column order was not sequential (1, 17, 9, 25, 5, 21, 13, 29, ...) and neither were the rows (1, 0, 2, 3, 5, 4, 6, 7, ...) The first 2 rows had the test ROM, which differed from the app note code in more than just the address offsets, but luckily still jumped to $1012.

The rest of the rows were nearly identical to the electronic dump; 4 differences were from bits I had transcribed incorrectly.

I used this mapping on the visual transcription of Z8615's ROM, then disassembled the resulting file using MAME's unidasm. There were quite a few illegal instructions, many of those due to data tables getting disassembled. But I kept seeing opcode $5F over and over in good code. My guess is that it's used to clear the watchdog timer.

I searched for all the CALL instructions and checked the addresses to make sure they looked reasonable and I am confident the row mapping is correct. Since the ROM was visually transcribed, it is certainly possible that there are errors, but while examining the disassembly, I found a simple checksum routine at $FDE, and the sum of the bytes from $0FED to $0001 matches what it expects. Since it's a simple sum of bytes, there could be multiple errors in my transcription that cancel out.

App Note AN0087 discusses the Z8615 and other Z8 keyboard controllers. It has a map of how the registers are used as well as lists of scan codes the keyboard outputs. Some of the scan codes are long, like Scan Code Set 2 Key No 126, which outputs E1 14 77 E1 F0 14 F0 77 on make. This string, null terminated, is in the ROM at offset $88C.

The Z8615 also has 64 bytes of test ROM, different from the app note and from Z8611. I tried entering test mode on a second chip, but even with /reset at 8 volts it output the keyboard column scanning pulses. I also experimented with other pins, including pin 7, which the datasheet says must be grounded. It's possible that there is some way to initiate test mode on these chips.

Here are the die shots, dumps and some datasheets.


back to chip decap page

back to Home page