When the Z80 is in IM2, on receiving a maskable interrupt it reads the two bytes (LSB first) at ( 0x100 * I + x ) where I is the Z80's I register and x is the value on the data bus at interrupt time. In "theory", the value on the data bus should always be 0xff, but certain pieces of hardware (notably Kempston joystick interfaces) have been alleged to cause other values to be on the bus at interrupt time. This means that IM2 is slightly more fiddly to use and slightly less useful than it would be without this problem. Two possible confusions here:
- It is not actually necessary for a device to actively put data on the bus; if the device adds some capacitance to the bus, then it may cause any zeros on the bus to "linger"
and be read as the Spectrum has no active pull-ups for the lines.
- Some mouse hardware (AMX?) generates an interrupt when its buttons are pressed. As this means an interrupt can occur at any time, any code which uses such hardware is definitely going to have to handle data bytes on the bus which are not 0xff.
The traditional workaround for this issue is to create a table of 257 identical bytes b at 0x100 * I and then to put the ISR at 0x101 * b. A modification of this technique uses the fact that the 48K ROM contains empty space from 0x386e to 0x3cff which is filled with 0xff. Setting I to 0x38, 0x39, 0x3a or 0x3b thus means that the ISR will jump to 0xffff, at which 0x18 (JR) is placed. The JR then uses the fact that the first byte of ROM is 0xf3 (DI), so the JR occurs to 0xfff4, at which the "real" ISR is placed (quite likely a JP to somewhere else).
This technique works fine on the 48K machine, but the 128K ROM removed the full table of 0xff bytes. However, it did leave 0xffff at 0x38ff, 0x39ff, 0x3aff and 0x3bff, which are sufficient to make this work if the data bus value is 0xff (as it "almost always" is). The +3 ROM has 0xffff only at 0x3bff, so setting I to 0x38, 0x39 or 0x3a will definitely not work on that machine.
- Peripherals believed to place random data on the bus
- Peripherals believed not to place random data on the bus
- (Original) DivIDE