Reliable use of interrupt mode 2 on the CPC
Basic operation of interrupt mode 2
In Z80 interrupt mode 2, the following actions occur:
- Device issues a interrupt request to the Z80
- If maskable interrupts are enabled:
- the Z80 will acknowledge the interrupt
- the interrupting device will "see" the interrupt acknowledge and put a 8-bit interrupt vector on the Z80 databus.
- the Z80 will read a 8-bit interrupt vector from the Z80 databus.
- the Z80 will form a "look-up address" using the I register and the 8-bit interrupt vector in the following way:
|Bit 15..8||Bit 7..0|
|I register bit 7..0||8-bit interrupt vector bit 7..0|
The I register therefore describes the base of a table in memory of 16-bit values. The 8-bit interrupt vector is used to index into the table. Each entry is a 16-bit value which gives the memory address of the interrupt handler associated with that interrupt vector
- The address of the interrupt handler is read from the interrupt-handler table, this is formed by reading 2 consecutive bytes from the calculated look-up address.
- the program counter is loaded with this interrupt handler address and the interrupt handler is executed
If maskable interrupts are disabled:
- the Z80 will ignore the interrupt request and will not generate a interrupt acknowledge
If I = "&80" and the 8-bit interrupt vector is 0, the lookup address will be &8000. The address of the interrupt handler will be generated from the bytes at &8000 and &8001. The Z80 Program Counter (PC) is set to this value and the interrupt handler will be executed.
If I = "&80" and the 8-bit interrupt vector is &ff, the lookup address will be &80ff. The address of the interrupt handler will be generated from the bytes at &80ff and &8100. The Z80 Program Counter (PC) is set to this value and the interrupt handler will be executed.
Some expansion peripherals, which support Z80 interrupt mode 2 can be used on the CPC with the standard method, because the 8-bit interrupt vector can be predicted and is guaranteed to be a particular value depending on the source of the interrupt. This method can be used on the CPC+ when the special features have been enabled.
Example 1: [ highlighted | original ]
Reliable method for CPC
If there are no expansion peripherals connected, or they are not being used, the 8-bit interrupt vector can't be predicted. (In a lot of cases the 8-bit interrupt vector will be &FF but this can't be guaranteed).
This document describes how it is possible to use interrupt mode 2 in this case. The benefit of using this method is that the program will run on the CPC+ without modification. (This assumes that the program will not use the additional features of the CPC+)
The 8-bit vector can be any value in the range &00 and &FF inclusive. For interrupt 2 to give the same result in all cases, the interrupt handler must be the same for all 8-bit vectors.
When the 8-bit interrupt vector is "&00", the interrupt handler is fetched from (I*256)+0 and (I*256)+1.
When the 8-bit interrupt vector is "&01", the interrupt handler is fetched from (I*256)+1 and (I*256)+2.
Since the interrupt handlers must be the same for these: (I*256)+0 = (I*256)+1 and (I*256+1) = (I*256+2).
If this is extended to all 8-bit interrupt vectors we find that (I*256)+n = (I*256)+n+1, and from this bits 15..8 of the interrupt handler must be the same as bits 7..0. (e.g. a valid interrupt handler could be &8080).
Example 2 shows one method to setup interrupt mode 2 for the CPC:
Example 2: [ highlighted | original ]