The time interrupt occurs roughly once every 1/300th of a second. On machines with PAL monitors (as in the UK) or SECAM monitors (as in France) the timer is synchronised with frame flyback every sixth tick. On machines using NTSC monitors (as in the US) the timer is synchronised with frame flyback every fifth tick. The time interrupt is processed by the Kernel and presented to the rest of the system in a number of ways :
The Z80 is run in interrupt mode 1. Which is to say that all interrupts cause an RST #38 to be executed by the processor. The interrupt handling code in the Kernel can distinguish between the time interrupt and an external interrupt. It does this by re-enabling interrupts inside the interrupt routine. If the interrupt repeats then it is assumed to be an external interrupt, otherwise it is taken to be a time interrupt. Note that this requires that the source of external interrupts should not clear the interrupt condition until the software resets it. Unless special action is taken in hardware, Z80 peripheral chips will not obey this requirement. In such cases the recommended course of action is described in Appendix XIII.
Before an external interrupt is enabled its interrupt handler must be 'installed'. This is done by copying the 5 bytes at address #0038 to a new location and replacing them by suitable code (probably including a jump). When the Kernel detects an external interrupt it calls address #0038 in RAM to process the interrupt.
No conditions.
AF, BC, DE and HL corrupt.
All other registers preserved.
Interrupts are disabled and must remain disabled.
The lower ROM is disabled.
The upper ROM select and state are indeterminate.
The alternate register set must not be touched.
The interrupt routine must establish whether it can deal with the interrupt, and if so it must at least clear it. If the interrupt is not the responsibility of the routine then it should jump to the copy of the bytes taken from location #0038 which may be competent to deal with the interrupt. This requires the code patched at location #0038 to be position independent in case a second external interrupt handler is installed. The code put at #0038 at EMS is position independent - it merely returns.
Note that interrupt handling code must be in RAM somewhere between #0040 and #BFFF. Interrupt handlers should be as short as possible. If an interrupt requires a lot of processing beyond that required to clear it, then the interrupt should kick an event to do the work outside the interrupt path.
There is no provision for handling a nonmaskable interrupt (NMI) in the firmware (despite the fact that NMI i s available on the external bus connector). Various firmware routines (notably those connected with driving the Centronics port, the PPI to access the sound chip and keyboard, and the cassette) will have timing constraints violated if NMIs occur whilst they are active. It is recommended that NMI should not be used.
As a general rule hardware interrupts should be transformed into their software equivalents, 'events', as soon as possible. The handling of events is more flexible than the handling of hardware interrupts – for example there are no restrictions on where event routines may reside, or on interrupt enabling.
Events are described by an event block. This block contains the event class, the event count and an event routine address. When an event occurs the event block is 'kicked' a nd the Kernel arranges for the event routine to be called once for each kick (the number of kicks outstanding is kept in the event block). The event routine is not necessarily called immediately. When the event routine is actually run depends on the event class as follows:
The various time interrupts provide three sources of 'kicks' for events. The events to be kicked when each of the interrupts occur are stored on queues, one queue for each source of kicks. The user provides an area to store for the Kernel's use. The size of the area depends on which queue it is for. The last 7 bytes of the area are always an event block which the user should initialize appropriately. Appendix X describes the layout of these blocks in greater detail.