Spectranet CPLD
Adapted from Spectranet CPLD.
The Spectranet glue logic is implemented in a Xilinx XC9572 CPLD. In the classic hardware it has two main jobs:
- trapping execution at selected addresses or instructions
- paging Spectranet flash, SRAM, and device memory into the lower 16K of the Spectrum address space
Execution trapper overview
The ZX Spectrum has no formal sideways-ROM mechanism, so peripherals commonly page their own ROM by detecting instruction fetches at selected addresses. The CPLD watches the address bus, /M1, and /MREQ; when the CPU fetches an instruction at a trapped address, the Spectranet memory is paged in and the Spectrum ROM is hidden.
The CPLD can also trap an instruction sequence. For the socket library entry points it decodes a CALL into the range 0x3FF8 to 0x3FFF, allowing code in main RAM to call Spectranet routines through the public dispatch entry points.
Because multiple peripherals may have their own ROM paging hardware, the Spectranet uses an A15 daisy-chain scheme. When Spectranet memory is paged in, downstream peripherals see lower-ROM accesses as upper-RAM accesses and should keep their ROMs out of the bus.
Page-in traps
Fixed page-in traps include:
0x0000, conditionally after reset0x0008, conditionally for the RST 8 BASIC extension trap0x0066, conditionally for Spectranet NMI handlingCALL 0x3FF8throughCALL 0x3FFF, unconditionally for the Spectranet call gateways
The address traps are latched only when the bus condition remains valid at the relevant /MREQ edge. This avoids latching false page-ins while the address bus is still settling.
Page-out trap
Spectranet memory is paged out by executing at 0x007C. The CPLD resets the page-in latch at the end of the instruction fetch, restoring normal Spectrum ROM visibility.
NMI behavior
The CPLD distinguishes Spectranet NMI events from NMIs generated by downstream peripherals. When the Spectranet NMI button is pressed, the CPLD generates an NMI and traps the CPU fetching the NMI vector at 0x0066. The NMI state remains set until the CPLD sees RETN, which allows handlers to page out and call the Spectrum ROM without causing repeated NMI events.
Programmable execution trap
The programmable trap can be set to any Z80 address. It does not directly page in memory; instead it raises an internal NMI, and the normal Spectranet NMI handler decides whether the event was a button press or a programmable trap.
The trap address is written as a 16-bit little-endian value to port 0x023B, and the trap is enabled with bit 3 of the control register at port 0x033B.
Control and status register
Port 0x033B is the CPLD control/status register. When writing, the significant bits are:
- bit 0: page Spectranet memory in when set
- bit 3: enable the programmable execution trap
- bit 5: deny downstream A15
Programs should read the register, modify only the bits they need, and write the merged value back. When reading, the register also reports state such as the saved border colour, trap enable state, 128K screen page, downstream A15 denial, and W5100 interrupt pin state.