Wednesday, January 7, 2009

Interrupts

Interrupts
In a typical computer system, the software can be divided into 3 possible groups. One is the Operating Loop, another is the Interrupt Service Routines, and the last is the BIOS/OS functions and subroutines. The Operating Loop is the main part of the system. It will usually end up being a sequence of calls to BIOS/OS subroutines, arranged in an order that accomplishes what we set out to do, with a little manipulation and data transfer in between. At the same time, at least it looks like it's happening at the same time, interrupts are being serviced as they happen. In the 8085, there are thirteen (13) possible events that can trigger an interrupt. Five of them are from external hardware interrupt inputs (TRAP, RST 7.5, 6.5, 5.5, and INTR), that can be from whatever hardware we've added to the 8085 that we deem to need servicing as soon as they happen. The remainder are software instructions that cause an interrupt when they are executed (RST 0 – 7).
To digress just a moment, there are two ways to service, or act on, events that happen in the system. One is to scan or poll them and the other is to use interrupts. Scanning is just what is sounds like. Each possible event is scanned in a sequence, one at a time. This is ok for things that don't require immediate action. Interrupts, on the other hand, cause the current process to be suspended temporarily and the event that caused the interrupt is serviced, or handled, immediately. The routine that is executed as a result of an interrupt is called the interrupt service routine (ISR), or recently, the interrupt handler routine.
In the 8085, as with any CPU that has interrupt capability, there is a method by which the interrupt gets serviced in a timely manner. When the interrupt occurs, and the current instruction that is being processed is finished, the address of the next instruction to be executed is pushed onto the Stack. Then a jump is made to a dedicated location where the ISR is located.. Some interrupts have their own vector, or unique location where it's service routine starts. These are hard coded into the 8085 and can't be changed (see below).
TRAP - has highest priority and cannot be masked or disabled. A rising-edge pulse will cause a jump to location 0024H.
RST 7.5- 2nd priority and can be masked or disabled. Rising-edge pulse will cause a jump to location 7.5 * 8 = 003CH.
This interrupt is latched internally and must be reset before it can be used again.
RST 6.5 – 3rd priority and can be masked or disabled. A high logic level will cause a jump to location 6.5 * 8 = 0034H.
RST 5.5 – 4th priority and can be masked or disabled. A high logic level will cause a jump to location 5.5 * 8 = 002CH.
INTR – 5th priority and can be masked or disabled. A high logic level will cause a jump to specific location as follows:
When the interrupt request (INTR) is made, the CPU first completes it’s current execution. Provided no other interrupts are pending, the CPU will take the INTA pin low thereby acknowledging the interrupt. It is up to the hardware device that first triggered the interrupt, to now place an 8-bit number on the data bus, as the CPU will then read whatever number it finds on that data bus and do the following: multiply it by 8 and jump to the resulting address location. Since the 8-bit data bus can hold any number from 00 – FFH (0 – 255) then this interrupt can actually jump you to any area of memory between 0*8 and 255*8 ie: 0000 and 07FFH ( a 2K space). N.B: This interrupt does not save the PC on the stack, like all other hardware and software interrupts!
You will notice that there isn't many locations between vector addresses. What is normally done is that at the start of each vector address, a jump instruction (3 bytes) is placed, that jumps to the actual start of the service routine which may be in RAM.. This way the service routines can be anywhere in program memory. The vector address jumps to the service routine. There is more than enough room between each vector address to put a jump instruction. Looking at the table above, there are at least 8 locations for each of the vectors except RST 5.5, 6.5, and 7.5. When actually writing the software, at address 0000h will be a jump instruction that jumps around the other vector locations.
Besides being able to disable/enable all of the interrupts at once (DI / EI) ie: except TRAP, there is a way to enable or disable them individually using the SIM instruction and also, check their status using RIM.
There are other things about interrupts that we will cover as they come up, but this lesson was to get you used to the idea of interrupts and what they're used for in a typical system. It’s similar to the scene where one is standing at a busy intersection waiting for the traffic light to change, when a person came up and tapped us on the shoulder and asked what time it was. It didn't stop us from going across the street, it just temporarily interrupted us long enough to tell them what time it was. This is the essence of interrupts. They interrupt normal program execution long enough to handle some event that has occurred in the system.
Polling, or scanning, is the other method used to handle events in the system. It is much slower than interrupts because the servicing of any single event has to wait its turn in line while other events are checked to see if they have occurred. There can be any number of polled events but a limited number of interrupt driven events. The choice of which method to use is determined by the speed at which the event must be handled.
The software interrupts are the instructions RST n, where n = 0 – 7. The value n is multiplied by 8 and the result forms an address that the program jumps to as it vector address ie: RST 4 would jump to location 4*8 = 32 (20H).

1 comment: