The first question you might be asking yourself is, given that all input (and all output) vectors map to the same address (and therefore the same dispatch routine), how does the routine know which high-level ISR to call? Clearly, the dispatch routine needs to have some knowledge of which device caused the interrupt.
The answer as to how the dispatch routine knows which device caused the interrupt varies according to the hardware the O/S is running on. Some systems provide a mechanism that allows the dispatch routine to query the hardware asking for the device address or interrupt vector. Another possibility is for the dispatcher to poll devices in order to find out which has an interrupt pending.
XINU does neither of these. Instead, XINU uses the PS values held in the dispatch table cleverly (please see note on terminology).
Remember that the dispatch table contains a PC and PS to be loaded on interrupt. It turns out, though, that the only important bits in the PS are the ones that disable interrupts. Regardless, the H/W, upon receiving an interrupt, loads the entire PS stored in the dispatch table. When the dispatch table is set up on initialization by XINU, XINU records in the low-order 4 bits of each PS a value which identifies the device for that vector. Thus the first thing the low-level service routine does once its invoked is to store the low-order 4 bits of the PS for safe keeping. These four bits identify the interrupting device.
Now that the four bits identifying the interrupting device are known, the low-level dispatcher uses them as an index in to a high-level dispatch table to invoke the appropriate high-level service routine.
I suggest you take a look at the assembly code for the dispatcher routine (in ioint.s) and the header file that defines the high-level dispatch table (io.h). It is quite illuminating.
It is important to note that the BIOS calls can cause problems. Rescheduling must not occur during a BIOS call. Thus, a separate stack is provided. As well, the interrupt for some devices (i.e. CTRL-BREAK) should not have the BIOS call executed as then the control would return to MS-DOS, which would be a bad thing.
Please note that in the version of the code made available for the Spring 1999 version of CS 415, the code differs significantly from the old version of the textbook and from the new version of the textbook. Thus, I will not be developing any ideas here in any great detail. The detail will be left to particular interrupt handlers as described in later chapters. Also, the discussion of interrupt dispatchers can be seen in the appropriate group project