To use the maskable interrupt request /INT
on a Spectrum, you need a program that does the following:
- Implements your Interrupt Service Routine (ISR). This should include a
RST 56h
instruction to call the ROM's ISR so keyboard scanning etc. keeps working.
- Disables maskable interrupts with a
DI
instruction.
- Sets up an interrupt service address table in RAM on a page (256 byte) address boundary.
- Loads the I register with the high byte of the table address.
- Loads the table's highest vector (
xxFEh
) with your ISR address.
- Changes the Interrupt Mode to 2 with an
IM 2
instruction.
- Enables maskable interrupts with an
EI
instruction.
Because of a somewhat tragic mistake in the Spectrum's ROM software, the Non-Maskable Interrupt /NMI
pin and function cannot be used, without extra hardware to overlay the existing ROM.
In the standard Spectrum, the idea was that the NMI ISR address would be stored in system variable NMIADDR
and on an NMI the ROM would jump to NMIADDR
unless it held 0000h
as an 'unused' marker. Tragically, the ROM's ISR at 0066h
gets the test upside-down: if NMIADDR
is zero, it jumps to address NMIADDR
, instead of if NMIADDR
is non-zero.
That single mistake (a JR NZ
instead of a JR Z
) renders the Spectrum's NMI and NMIADDR
useless. (It could be argued that it can be used to conditionally reset the Spectrum based on NMIADDR
. But no-one has been seen to have found an application for that and publicised it in the last 40 years, so it can safely be called useless.)