The Einstein 'sInterrupts and Polling
Introduction
This article like many others I will be doing, is a recreation, tidy up, etc of articles originally published in old User Group Magazines. As the quality of these old magazines is quite poor, I decided to take it upon myself to recreate those articles and present them in an improved format, with pictorial enhancements and where possible improved content.
This article was originally written by Philip Eley and Published in Einstein Monthly News Volume 1 Issue 9.
The Article
If you'd always thought that polling was something to do with voting in an election, and that an interrupt was something like, ‘the phone ringing whilst you were taking a bath’, then you'd be right. But, like so many other words, these two words have been hi-jacked from their familiar surroundings and applied to specific computer concepts, acquiring an air of mystery in the process. In computer terminology interrupts and polling are alternative ways of detecting when something has changed, for example, when a key is pressed or a printer has run out of paper. This article is an attempt to de-mystify these two concepts, with the aid of from real life.
Imagine the following: I want to spend the day gardening; I am also expecting a very important letter to arrive, but I can’t see or hear the letter-box while I’m gardening. How do we solve the problem of gardening yet still getting the letter soon after it has arrived? For the purposes of this explanation,I'11 look at two possible solutions.
The first is to stop gardening every few minutes, walk into the house, and check if the letter has arrived. Thus I will be able to to do two things at once, although gardening will obviously take longer to complete due to the time involved in checking the letter box. The alternative solution is to leave a note for the postman asking him to ring the bell when he delivers the post. That way I can spend all my time gardening until I hear the doorbell, with no unproductive activity. Also, I will know immediately that the letter has arrived - if I had used the first method and the letter arrived just after one of my checks, it may be five or ten minutes before I was aware of its arrival.
These two solutions represent polling and interrupts respectively. From a computer viewpoint, the processor does the polling (equivalent to the gardener checking the letter-box), but an interrupt comes into processor from an external source (the postman rings the bell). The Machine Operating System,(MOS)), in the Einstein uses a mixture of polling and interrupts to control the peripherals attached to the 280 microprocessor. Two examples from MOS: the keyboard is polled, the timer, which updates the real time clock, generates interrupts. Deeper examination of these examples should further clarify the subject.
Polling of the keyboard takes two distinctive forms depending on the reason a key might be pressed. Like any computer, the Einstein spends a great deal of time waiting for commands or data to be input from the keyboard. Nothing else can happen until the user types something, so a form of polling is used which does nothing else but check if a key has been pressed. In the postman example this is equivalent to sitting next to the letter-box doing nothing else but waiting for the letter to arrive. It wastes lots of time, but that’s okay for the computer which, as I've already said, has nothing else to do anyway.
Once the commands to run an XBAS program have been typed, the keyboard is still polled, but only after each BASIC instruction has been executed. XBAS checks in case SHIFT/BREAK has been pressed, stopping the program if this happens. This is the exact equivalent of the gardener checking the letter-box every few minutes and has the same drawbacks; time is wasted checking the keyboard, and the keypress will not be picked up immediately, although, in practice, the delay is hardly noticeable due to the speed of the Z80. Balanced against the slight loss of execution speed is the ability to break into a program that might have got stuck in an infinite loop.
The example of the timer demonstrates how certain effects may only be achieved through the use of interrupts; in this case the provision of a real time clock, updated every second regardless of what program (if any) is running. For a start, think about how to program such a clock without interrupts. The only approach is to set up a loop which takes exactly one second to execute, then update the clock, then go into the loop again. This is quite feasible to program but it has the big disadvantage of completely excluding any other processing - imagine trying to keep the timing correct whilst doing other things inside the loop. The amount of work needed to add this to every program would be astronomical, so we can effectively rule out this idea.
The programming problems are drastically simplified with the introduction of a hardware interrupt. The price paid is more complicated (and thus more costly) hardware circuitry - in this case a timer which interrupts every second. The processor detects each interrupt and executes a small chunk of assembly code built into the operating system. The interrupts will continue to update the clock, stealing only the required amount of time from whatever program is running; the program will be unaware that anything has happened unless, of course, it is looking for a change in the real time clock! The clock is simply there when needed, and may be ignored by a program if not required. Thus interrupts make the clock a practical proposition.
Having covered the differences and uses of polling and interrupts I’ll now dig deeper into the MOS and describe the Einsteins interrupt system in more detail. There are a couple of other. aspects to be covered and I will introduce you to a travelling fish-salesman, who will help with the explanations. Read on......
Back to our example, we will extend the original scenario thus: apart from the postman, I might receive a visit from Fred the travelling fish-salesman. I don’t always wish to buy fish, but Fred will always ring the doorbell "just in case”. We now have a situation where the doorbell might ring for one of two reasons - the postman or the fishmonger. Two different courses of action are required depending on the person ringing. If it is the postman , I don't have to open the, door (he is not expecting me to), just collect the post; if it's Fred, he will expect me to answer, even if it is only to say that I don’t require any fish. Because of these two alternate courses of action it would be handy if I could arrange for two different "signals" e.g. the postman to give one ring, Fred to give two. (Ed. The postman never knocks twice).
The Z80 processor used in the Einstein is capable of handling 128different interrupts and so it is not just “handy” to be able to distinguish the source of a particular interrupt, it is imperative in order that the right course of action may be followed. More of how that’s done later.
Having trained the postman and Fred (and any other potential door bell ringers) to use a code (the number of rings), I wish to have a lazy day in bed, without being interrupted by the doorbell... so I disconnect the doorbell from its battery. In computer terminology this is known as DISABLING the interrupts. Notice that this stops ALL the interrupts. It also be desired to stop particular interrupts, whilst letting others happen. In our real-world example this is equivalent to pinning a note to the door asking that only the milkman should ring.
Back to the Einstein. What follows is a description of the way the hardware and software are prepared to deal with interrupts. This is part of the MOS.
When the machine is switched on, or when the reset button is pressed, the micro-processor starts executing the machine code resident in the ROM. At this point all interrupts are disabled, because the so called Interrupt Service Routines (IRSs) have not been set up, and this is one of the first tasks of the MOS. This consists of copying a table of addresses to a known place in the RAM. The address of this table is placed in a special register in the Z80 (theI-register); if you type Z2 at the MOS prompt, you will see, under the I, the actual value of FB (hex) giving a base address of FBOO (hex). This is used, whenever an interrupt occurs, in conjunction with an offset provided by the interrupting device (equivalent to the number of rings made by the postman or fishmonger). The Einstein uses only two interrupts (of the potential 128) - the timer, and the parallel port, the actual offsets being 06 and 10 (hex)respectively. These offsets, along with other parameters, are programmed into the devices during this initialisation process. The addresses in the copied table are the actual addresses of the ISRs which deal with the interrupts (in MNOS 1.21 these are FC47 and FC84 (hex)). The actual ISRs are also copied from the ROM into the RAM at the relevant addresses.
You may wonder why the table and routines are copied into RAM, instead of being left in the ROM. There are two reasons: by placing them in RAM, they can easily be changed by a program which has its own ISR; more importantly, the architecture of the Einstein is such that the addresses in the ROM are not directly available during normal operation, because they duplicate those of the lower part of the RAM, which ig switched in after initialisation. The higher addressed RAM is not switched, thus is available to all programs whether in ROM or RAM.
Having completed its initialisation, the MOS enables interrupts, the immediate effect being to start the real time clock, driven, as I’ve already said, by interrupts from the timer. The user is now in, and the MOS commands may be used, or DOS loaded and used. Irrespective of what is done, the timer is still updated every second. We can now complete the explanation by following the actual path of one of these timer interrupts.
The timer, after each second has elapsed, sends an interrupt to the Z80. Inaddition, the timer sends the pre-programmed offset (06) which identifies it aaa timer interrupt. The Z80 uses its I-register (containing FB (hex)) to form anaddress in the ISR address table, in this case FB06 (hex). It then takes thecontents of FB06 and FBO07, forming them into the ISR address(FC47) - note that addresses are formed in reverse order (low byte first) FB96 contains 47, FB07 contains FC. Before jumping to this address, further interrupts areautomatically disabled, and the address of the instruction which would havebeen executed had not the interrupt occurred is saved (on the stack) so thatthe interrupted program can be resumed after dealing with the interrupt.
The ISR must first save the contents of any registers that it is going to change; they will be restored unchanged when the interrupted program is resumed. The ISR for the timer, like all ISR e, is very simple and quick. It updates a counter of seconds. If the counter reaches 60 then it is reset and a counter of minutes is incremented. In a similar fashion, when 60 is reached on the minute counter, the hour counter is incremented and the minute counter is reset, likewise the hour counter when 24 is reached. Once the processing is finished, the saved registers are restored, interrupts are enabled, and the interrupted program is resumed exactly where it was interrupted, without any ill effects. And that’s all there is to it.....