The purpose of this lab is to familiarize you with the use of interrupts, and to compare their use to that of polling. We will do so by re-implementing your lab5 game using interrupts (you can of course re-use parts of your code).
The disadvantage to polling is that a program must constantly check and recheck to determine when a peripheral is ready to be used. As more peripherals are added to a system, the time spent to check these increases accordingly, making it more and more difficult to perform other tasks at the same time.
An alternative to constantly polling is interrupts. Rather than having the processor constantly check the device status, an interrupt will signal the processor when it is ready for use. This allows a program to work on other tasks, and only deal with the devices when they are available. Obviously this makes a program much more efficient, and often simpler as well, since events are taken care of in a single interrupt service routine, allowing the rest of the program to ignore it.
In this lab, you will need to modify the program you designed in lab 5 (the scrolling numbers game) in two ways.
You should consult your class notes and the appropriate device documentation for how to initialize interrupts. But in general, you have to perform the following steps:
After enabling interrupts on both the processor and the device, device interrupts will cause the processor to jump to location 0x1000020. It is crucial that you make sure your interrupt service routine is located here, which you can do by following these steps:
/***** Start of Code *****/ .org 0x20 myISR: |
/***** Start of Code *****/ nop nop nop nop nop nop nop nop .org 0x20 myISR: |
/***** Start of Code *****/ nop nop nop nop nop nop nop nop nop .org 0x20 myISR: |
When an interrupt is triggered and your interrupt service routine is invoked, you need to first find out what device, and then what event has caused the interrupt. Finding which device interrupted can be done by examining the ctrl4 (aka ipending) register which tells you which IRQ line(s) have triggered an interrupt. Some devices, such as the timer, have only one event which causes an interrupt, so you know if bit 3 of ienable is high that Timer0 has timed out. But devices such as the JTAG UART have multiple events which cause interrupts (for either reads or writes, provided you enabled both). In that case you need to check the device's appropriate control register(s) to see what event actually caused the interrupt.
When a device interrupt occurs the address of the next instruction is
saved in register ea. However the current instruction which was
interrupted never gets completed. Therefore you must adjust the saved address
in ea so that it re-executes the interrupted instruction. To do this, simply
subtract 4 from ea (remember each instruction is 4 bytes). Then execute the
"eret" (exception return) instruction to return to normal program execution.
Read the documentation on the 7-segment display. Then create two versions of your lab 5 as described above - one with a counter, the other with both a counter and interrupts. Bring both programs, to the lab. Don't forget to comment your program!
Demonstrate both programs to the TAs and comment on the speed of the counter for both programs.