This is a draft design for the CPC-compatibility circuit. This logic will reside in the FPGA, and will equip the CPCNG with e CPC-compatibility mode in which almost all old CPC software will run. Exceptions will be anything which makes use of precise timing, since the eZ80 runs at a totally different pace to the old Z80, the video memory arbitration is organised differently in the CPCNG, and there is an extra overhead associated with translation and emulation of CPC I/O.
Refer to the below diagram of the CPC-compatibility circuit. If we use schematic entry for the FPGA we can enter this circuit for the I/O intercept trick. I have marked the main chips in this design with equivalent TTL 74LS-series part numbers, just so that their functionality is well defined (in reality 74LS logic would be too slow to be able to build his circuit for real).
The signals at the left of the diagram connect directly to the eZ80 CPU. At the top, the /IORQ signal from the CPU goes only to this circuit, not to any I/O devices in the rest of the CPCNG. There is a mode signal, which will come from 1 bit of a mode register elsewhere in the FPGA, which is logic 0 when in CPCNG mode, and 1 when in the CPC mode. When this bit is 0 (CPCNG mode) the /IORQ signal from the CPU is propagated directly to the output /IORQ signal which is sent to the rest of the circuit.
But when in CPC mode, a 1 is forced to the /IORQ output via the top OR gate, so that I/O requests are disabled. When an I/O request occurs in CPC mode (/IORQ goes to 0), this PResets the D-type flip flop IC1. The /Q output of this flip flop is therefore 1 when in normal CPC operating mode, but 0 when an I/O has occurred and the interrupt intercept software is running. This signal is sent back to the CPU as /NMI (non-maskable interrupt). So, when an I/O request occurs, /NMI is generated by setting this signal to 0.
When /IORQ goes back to 1, IC7 (also a D-type flip flop) clocks this signal so that for the next instruction, the I/O is re-enabled. This means that the I/O intercept routine can do the required translated CPCNG I/O. The output of this flip flop also goes to the memory mapping circuit, where it causes the ROM to be switched in at address &000000 so that we can be sure there is sensible I/O intercept code at the /NMI address &0066.
Now see the 8-bit latches at the bottom of my diagram. The NOR gate at the bottom left detects an op-code read. When an op-code read is in progress, the eZ80 /INSTRD pin is low (0). So is /RD and /MREQ, so the NOR output will be 1 only during op-code read. The next rising clock edge clocks this 1 into IC2 (D-type flip flop), whose Q output clocks both IC3 and IC4. These are 8-bit latches, IC3 latches what was on the CPU databus (the current opcode), while its output (the previously read opcode) is moved into IC4.
At the same time as the intercept mode is entered, when /IORQ goes low in CPC-mode and IC1 is PReset, the Q output of IC1 clocks the contents of IC3 and IC4 into latches IC5 and IC6. This means that when the intercept occurs and /NMI Is generated, IC5 and 6 will contain the two most recent opcodes which occured just prior to the /IORQ. That is, IC5 and IC6 contain the Opcode of the I/O instruction! All Z80 I/O instructions are 2 bytes. IC5 and IC6 have 3-state outputs, which will be enabled onto the CPU databus when a certain I/O port is read. This decoding of I/O ports will occur elsewhere in the FPGA.
Therefore, the first thing the I/O intercept software needs to do is read from these two ports to determine what I/O instruction was being performed at the time of the /NMI. This extra hardware isn't really necessary, because you could do it in software: you would need to read two bytes off the stack, representing the return address from the /NMI. Then you'd need to subtract 2 to get the address of the I/O instruction. Then you'd need to do some work with the memory banking to ensure that you could read from that address. Then you'd read it. That will all take quite a number of instructions so I thought it would be beneficial to provide this functionality in hardware since it's more simple there.
Then the I/O intercept software can work out what I/O instruction was being attempted, and perform necessary CPCNG I/O's to replicate the intended effect of the CPC I/O. The CPU registers should be put into the state which the CPC would have expected, i.e. an IN instruction should put the appropriate IN byte in the expected register etc.
Finally the intercept software executes a RETN instruction (return from /NMI). This has the opcode ED 45. The two most recent opcodes are stored in the intercept circuit in IC3 and IC4. A set of inverters and 16-input AND gate on the output of these two registers decodes the opcodes ED 45. When it occurs, the output of the 16-input AND gate will be 1. When /MREQ goes back to 1, IC1 is cleared, releasing the /NMI, switching out the ROM, and putting the circuit back into normal CPC mode.
That completes the whole interrupt interception operation.