And here are my notes on another source of ideas (good and bad): the Z8000 series.
The Z8000 appeared early in 1979, in between the 8086 and the 68000. It was not a direct successor to the Z80, but shared its philosophy. It came in two versions, the Z8001 and the Z8002. The Z8002 was very similar to the 99xxx but with conventional registers and without the macrostore concept. The Z8001 added segmentation to the Z8002: each address was extended by a 7 bit segment number. Like the 68000, the Z8000 started without an established software ecosystem and Zilog ported V7 Unix instead, called “Zeus”. Zeus included a version of RM/Cobol to make it attractive as a business machine. Microsoft also ported Xenix to the Z8000. Nonetheless the chip failed to be a market success.
Segmentation on the Z8000 was somewhat similar to the page “0” and “1” on a 99xxx, but then with 128 segments instead of 2 pages. Each segment was up to 64KB in size. The program counter had a dedicated segment register and data accesses used two adjacent registers or memory words to hold an address and a segment number. The 7 bit segment and the 16 bit offset were distinct and could not easily be used as a 23 bit “flat” address. Next to these explicit segments, the Z8000 could also use functional segmentation (instructions/data/stack and user/supervisor). There was a companion Z8010 MMU chip that mapped up to 64 segments to real addresses; two of these could be used in parallel.
The Z8001 and Z8002 had an input signal to report memory faults. This input effectively was a non-maskable interrupt that could abort a faulting program. However, the faulting instruction itself ran to completion and could have irrevocably changed register values. Zilog realised early on that this was a mistake and announced the Z8003 and Z8004 that could abort instructions halfway through, along with a paging MMU, the Z8015. I did not find any 1981/82 designs that used the 03/04, maybe they were released later.
The abort mechanism on a Z8003/4 is intriguing: the abort signal seems to be a form of reset. When a memory access causes a fault the abort signal must be held active for 5 clocks simultaneously with the ‘wait’ signal active as well. Then a non-maskable interrupt must be asserted and the abort and wait signals released (note that on a Z8000 the reset signal must also be held active for 5 clocks to be recognised). What seems to happen is the following:
- asserting ‘wait’ stops the bus transaction from completing
- asserting ‘abort’ resets the microcode sequencer to a state where it recognises a non-maskable interrupt at the end of the current bus cycle (instead of the end of the current instruction)
- asserting the non-maskable interrupt causes the state of the processor (PC, status) to be saved and a recovery routine entered.
The Z8015 MMU latches the PC into a register on every instruction fetch, and counts the number of bus cycles since the last instruction fetch. After a fault, this information is frozen. Using these registers, a relatively simple routine can revert any changes the aborted instruction made so that it can be restarted later. All the details are in the 1983 data book (section 7, 9 and Appendix D):
I'm not sure the Z8015 ever made it into production -- maybe it never got beyond engineering samples, like the later Z80,000 CPU.
Note that on the NS16032 abort and reset are actually the same pin, which suggests a close link also on that processor. It also almost makes you wonder if the Z8003/04 were really different from the Z8001/02 or whether it was just marketing, a bit like the 99105 has turned out not to be unique silicon.
Maybe the equivalent approach will also work on a 99xxx. On a 99xxx the reset signal is actually also a non-maskable interrupt, and it too will abort an instruction at the end of a bus cycle. However, it takes 3 clocks to be recognised and that could equate to 3 bus cycles. The following might work:
- identify an abort condition before the falling edge of CLKOUT;
- simultaneously assert ‘reset’ and de-assert ‘ready’, and wait for 3 clocks;
- release ‘reset’ and re-assert ‘ready’.
According to the datasheet, the 99xxx CPU will now finish the current bus cycle and proceed to save the processor state in the reset workspace R13-R15.
It will take some experimentation to find out if further hardware support is needed to be able to revert back any changes the aborted instruction may have made.