Department of Electronics
ELEC 4601 Laboratory 2 Manual 80×86 Interrupts
October 2, 2020
Backstory:
Against all advice from other students, you decided to take a research position in Prof. X’s lab for the Fall term. Money was tight, and he couldn’t be as bad as everyone said, could he?
You showed up the first day to meet the professor and find out your assigned duties. “Here. Read this.”, is all he said to you, as he turned his back and continued with his measurements. You looked at the document he handed you and read the title: “ELEC 4601 Laboratory 2 Manual 80×86 Interrupts”. Well, that looks interesting you thought to yourself.
You looked around the lab while the professor was occupied with his measurements. It was strange…there were rows of what looked like large hamster wheels connected to old computers. Off to the side you spotted a rack containing fourteen large cages. “What was going on here?” you wondered silently. As the contents of the lab came into focus your apprehension grew. Suddenly the professor turned, marched to a cage, and using a large pair of forceps pulled a struggling groundhog (chonker) from the cage and forcefully placed it into one of the wheels. He then activated the old computer connected to the wheel, spun some dials on what looked like a signal generator, and cackled, “Run chonker, run”. He muttered to himself as he observed power output from the turning wheel on a nearby monitor. Not satisfied with the power levels, he adjusted the dial on the signal generator upwards, and the chonker ran faster in response.
The realization hit you: this was an energy harvesting installation, using chonkers as biological batteries, like some nightmare scene from the Matrix. The signal generator was zapping the captive chonker causing it to run on the large wheel.
An expletive burst from the professor, and he quickly shut down the mechanism. The chonker sat on the wheel, looking depressed and exhausted from the ordeal. “Is the chonker ok?”, you ventured to ask. The professor glared at you. “Of course it is. It loves this.”. You were not convinced.
“I want you to fix this mechanism”, the professor stated bluntly. “The rotational speed of the wheel is not measured accurately for my purposes. Read the manual and figure it out.”
“So that’s it?”, you said only to yourself. You were not comfortable with this chonker forced labour situation, but rent money was tight. You decide to read the manual and see if you can figure out the mechanism. You sit at a desk and open the manual and begin reading. “Cute”, you think to yourself, “The professor is disguising his research as some kind of fourth year course engineering lab. So that’s how he gets away with this.”
You continue reading….
Part A: 80×86 Hardware Interrupts
Interrupts offer an alternative way of responding to external events in a microprocessor system. The microprocessor can poll for changes in the environment by constantly looking for those changes, or it can wait until a device signals for a change. For real time events (e.g., a keyboard press), an actual hardware signal, referred to as an interrupt request (IRQ), can be generated. IRQs are usually numbered according to their priority, with IRQ0 having the highest priority (the system time of day) and IRQ7 having the lowest (the LPT1 printer port). For simple microprocessor systems, the following flowchart applies.
No
Execute instruction
Interrupt received?
Yes
Save state
Service the interrupt
Restore saved state
The software procedure (usually small and fast) that runs in response to an interrupt is referred to as an interrupt service routine (ISR). 80×86 processors operating in real mode (the simple microprocessor mode used in the lab) make use of an interrupt descriptor table (IDT), which consists of 256 ISR addresses, starting at 0000:0000. Most of these entries are for the 255 software interrupts and processor exceptions that the processor supports. Some of the entries in this table have been set aside for hardware interrupts, with IRQ0 to IRQ7 using up the IDT slots at positions 8 to 15. In response to an interrupt, the processor will finish executing the current instruction, immediately jump to the address stored in the IDT and continue executing instructions from there.
For hardware generated interrupts there is a signal path from the interrupt generating device to the microprocessor that needs to be correctly laid out using specific bits within specific registers in the I/O mapped memory space of the microprocessor. In this lab, the microprocessor is a member of the 80×86 family, but the process of laying out and enabling the interrupt path is fundamentally the same for all microprocessors.
There are typically three places where interrupts can be enabled or disabled:
(1) The microprocessor itself usually has a global interrupt enable bit(s) as part of a FLAGS register. If there is a subsystem that is responsible for arbitrating incoming interrupts—in this case,
(2) the 8259 Programmable Interrupt Controller (PIC)—then it will have registers and bits that need configuring. Finally,
(3) the interface subsystem that actually connects to the interrupt source will have some set of registers and bits that need to be configured in order to let the interrupt proceed to the interrupt arbitrator.
Once the hardware path has been properly enabled and interrupts can reach the CPU, the software has to be written to recognize the interrupt, service it, and gracefully restore the system back to its normal (waiting for an interrupt) state.
Unless everything is working properly, the system will fail. Debugging a hardware interrupt in real time is notoriously difficult, but once you have done it for a system such as this one, you will know what to look for in any microprocessor system.
“Ok”, you think to yourself, “That’s all well and good. But how does this relate to the measurement of the rotational speed of the chonker wheel?”
You decide to make a sketch of the entire lab set-up for one chonker wheel, and you come up with the following drawing:
Now you have a good idea how the system is tied together. The signal generator zaps the chonker, and the more often it zaps the chonker, the faster the chonker runs. The faster the chonker runs, the faster the wheel spins. The wheel has a magnet attached to it that causes the IRQ7 signal to be enabled every time the wheel rotates through one whole revolution. The IRQ7 signal goes directly into the single board computer.
You decide to keep reading the lab manual at this point.
Part 1: Simple Square Wave Interrupts
Part 1 (of 2) of this lab maps a square wave generator to the IRQ7 hardware interrupt of the 80×86 PC. We have included the full assembly code that continuously services and counts the requested interrupts and prints the total number on an LED printer port. It is your job to observe the program running using a logic analyzer, characterize the timing of the ISR, and understand and comment the included code.
“Ok, now we are getting somewhere!”, you think. “So when the chonkers run, it causes a signal to go to the CPU, triggering an interrupt that is serviced by an interrupt service routine. The interrupt service routine keeps a running count of how many interrupts are received and displays the count as a binary display on some LEDs attached to the printer port. The way the wheel is connected causes one interrupt to be generated each time the wheels rotates fully.” It all made sense now.
But then you wondered to yourself, “How come when the professor turned up the signal generator frequency too high, the count shown on the LEDs just stopped?” You decide to follow the lab procedure to see what’s going on.
Procedure
1. Download the code (CODE2.ZIP) provided on cuLearn and extract the contents onto your home computer.
2. Take some time to understand the code. Open LAB2A.PAS using a text editor (e.g. Visual Studio Code, Notepad, TextEdit, etc.) and read all the comments and come to an understanding of how the code works.
3. Find the comments in the code relating to “markers”. Read in the code why the markers are necessary. There are two markers. Make sure you find them both.
“So far, so good”, you congratulate yourself. “This is not too bad.” The code is well commented and although written in some ancient Turbo Pascal language, it’s easy enough to follow. You make sure that you fully read through the code before proceeding further.
4. Log on to your assigned 4135ME computer, run Exceed and start the logic analyzer connection, start the webcam, and run the Python script to connect to the signal generator. This is all shown in the videos on cuLearn.
5. Setup the pin assignments on the logic analyzer, exactly as you did in Lab 1
6. Use the signal generator controller application to control the signal generator. Set the output amplitude to 5V and the waveform type to Sine or Square (it doesn’t matter which). Use channel 1. Set the frequency to 100Hz. Note that you must press the Enable Output button in order to generate the signal. The
physical connection has already been made for you.
You don’t like the cold dispassionate description of the procedure in step 6. “Press the enable output button in order to generate the signal” is what zaps the poor little chonker. How can such cruelty be so callously implemented and described? Oh well, rent is due soon so you continue.
7. Observe the LEDs connected to the printer port at the front of the DOS machine. What is happening? You can reduce the frequency of the function generator to get a better look, just make sure to return it to 100 Hz afterwards
8. Measure the response time of the software. The response time will be defined as the time difference between the rising edge of the IRQ7 interrupt signal and the final execution of code inside the ISR. The logic analyzer is used to make this measurement.
Now you’re stuck. The lab manual says to use the logic analyzer to measure the time response of the software. You know from previous experience that the logic analyzer only monitors events external to the CPU. For example, you recall that you can monitor activity on the address bus and the data bus. So how in the world can you measure the timing of some code running inside the CPU? You decide to take short break and watch some cat videos on YouTube.
A few hours later, it dawns on you that the solution is written right in the lab manual. You continue reading.
9. Performing timing measurements on an interrupt driven system is sometimes tricky, as there may not be a clear piece of code to trigger on. For the ISR in LAB2A.PAS, there are two pieces of code (markers) that provide trigger events. Find the first marker added into the ISR and set up the logic analyzer to trigger on it.
“Brilliant! That makes sense. Some extra code was added to the program that forces activity on the address bus, data bus, and some other signal lines external to the CPU. So if I set up the logic analyzer to trigger on those specific events I can capture the points in time corresponding to when the program runs the associated instructions!”, you talk out loud to yourself as you give yourself a congratulatory high-five. You continue with the lab manual.
10. Run the logic analyzer and verify that you can see trigger event due to the first marker. Always make sure to set the Delay of the waveform to 0 μs (the time at which the analyzer triggers)
11. There is another instruction inside the ISR that should be clearly visible as a second marker. Hint: it occurs slightly after the first marker in the code. Take a screenshot of the logic analyzer output that shows the time from the beginning of the execution of the first marker to the end of the execution of the second marker.
12. Take a screenshot that shows the time between the rising edge of IRQ7 and the beginning of the first marker. You will probably need to zoom out a few times on the logic analyzer window.
Suddenly, all the puzzle pieces fit together! “This is absolutely amazing!”, you shout. “Eureka! I have it! I know how to solve the issue with the wheel measurement!”. But, no one else is with you to hear about your brilliance. You live alone.
You realized that at some high signal generation frequency the chonker is zapped so frequently that the chonker is just running too fast, and the wheel is turning so fast, that the ISR code can no longer keep up with the rate of the incoming IRQ7 signals. You think that through some adjustments of the signal generator output frequency you can find the condition under which the failure occurs. You decide to keep reading the lab manual to see if it helps you figure out the condition under which failure occurs.
13. Increase the frequency of the signal generator output signal. At what frequency does the program fail? Think about how a program that uses an ISR to count the number of IRQ7 events would fail if it could not keep up with the rate of the incoming IRQ7 events. Hint: You will need to use the logic analyzer to show the program failing, as the LEDs will be blinking much too fast to observe.
“Well, ok that was of some help……but it didn’t really give me the solution,” you whine to yourself. “I guess the professor would have fixed this himself if it was all solved in the lab manual. Time to earn my pay I suppose.”
You think about what external signals are visible to the logic analyzer, and you think about what combination of signals and trigger events would indicate that the ISR had failed to correctly count the number of IRQ7 events. After a little while, you think you know how to proceed so you implement your method. You notice some more instructions in the lab manual:
Before moving on, make sure you have:
1. A screenshot that shows the time elapsed between the two externally visible instructions of the ISR.
2. A screenshot that shows the time elapsed between the IRQ7 rising edge and the first marker.
3. A screenshot that shows the program failing above a certain frequency. Note the frequency.
Ok, so you make sure you have all that data. Next you file your report to the professor. You use the Google Form linked on cuLearn to do that. Since you’re a pro at this, you type everything up in a text editor beforehand and then cut-and-paste it into the Google Form (just in case the Google Form decides to lose your report). Also, since you’re a pro, you review the entire Google Form to make sure you have all the information you need to answer all the questions, before you start working on the answers to the questions.
“That wasn’t so bad.”, you think, “I am really good at this hardware debugging stuff.” But still you are troubled. What about the chonkers?
You drop by the professor’s lab to collect your pay. He barely looks at you as he stuffs a wad of cash in your outstretched palm. “Here. Get yourself a haircut.”, he muttered, as if he cared about your well-being. “I’ll have more work for you next week”.
As you leave the lab you take a look back at the rack of cages and see the chonkers within. They all look back at you with sad, pleading eyes. You don’t know if you can go on with this.
You return home exhausted. Straight to bed. You lay there tossing and turning thinking about the sad look the chonkers gave you as you exited the lab. Hours pass by and you cannot sleep. Finally you doze off only to reawaken in a pool of cold sweat fresh from a nightmare.
You jump from your bed and you determine that you must sabotage the professor’s clean energy efforts.
The chonkers just need to be shown how to escape. You sit on your couch and type furiously on your laptop. You can’t keep your eyes open and you fall asleep again, and in the morning when you awaken you find that in your exhausted state you had typed up your ideas as a document. You will implement your ideas and save the chonkers! Nothing will stop you from this mission. You read through your manifesto.
Part B: 80×86 Software Interrupts
“A software interrupt is requested by the processor itself upon executing particular instructions or when certain conditions are met. Every software interrupt signal is associated with a particular interrupt handler.
A software interrupt may be intentionally caused by executing a special instruction which, by design, invokes an interrupt when executed. Such instructions function similarly to subroutine calls and are used for a variety of purposes, such as requesting operating system services and interacting with device drivers (e.g., to read or write storage media).
Software interrupts may also be unexpectedly triggered by program execution errors. These interrupts typically are called traps or exceptions. For example, a divide-by-zero exception will be “thrown” (a software interrupt is requested) if the processor executes a divide instruction with divisor equal to zero. Typically, the operating system will catch and handle this exception.”
— https://en.wikipedia.org/wiki/Interrupt#Software_interrupts
“INT is an assembly language instruction for x86 processors that generates a software interrupt. It takes the interrupt number formatted as a byte value. When written in assembly language, the instruction is written like this:
INT X
where X is the software interrupt that should be generated (0-255).
As is customary with machine binary arithmetic, interrupt numbers are often written in hexadecimal form, which can be indicated with a prefix 0x or with the suffix h. For example, INT 13H will generate the 20th software interrupt (0x13 is the number 19 — nineteen — written in hexadecimal notation, and the count starts with 0), causing the function pointed to by the 20th vector in the interrupt table to be executed, which is typically a DOS API call.”
— https://en.wikipedia.org/wiki/INT_(x86_instruction)
You read through what you wrote, and think “Maybe I wasn’t as creative as I thought I was last night. This is all just stuff I copied from Wikipedia. Ok, but at least I know there are two kinds of interrupts: hardware and software. So I guess in my tired state I was thinking to somehow use software interrupts to save the chonkers.”
You keep reading, trying to remember your rescue plan.
The Rescue Plan:
A game will be surreptitiously installed on the lab computers. The game will demonstrate to the chonkers how they can escape the lab facility by tunneling through the floor and downwards into the soil beneath the lab. The chonkers will play the game whenever the professor is not observing them, and thereby practice the skills required for a successful escape.
The game (Chonker’s Escape) is played on a computer screen in VGA text mode. You choose that mode because of your prior experience using it to print messages on the screen. The game concept screen is shown below.
The rocks are randomly placed on the bottom row of the screen, and the chonker is drawn near the middle of the screen. The entire screen is scrolled upwards, so the rocks move upwards and the chonker leaves a tunnel behind itself. The chonker is controlled with the “a” key to move left and the “s” key to move right. The chonker must avoid the rocks for as long as possible. The “q” key quits the game.
The game is written in X86 assembly code and uses software interrupt service routines to keep the required amount of programming to a minimum. Software interrupts must be used to draw the screen elements (rocks and the chonker), check for keypresses, scroll the screen, and provide a small delay between each frame of the game (e.g. when a new rock is placed at the bottom row).
The game can be developed on DosBox-X. The MASM assembler can be used and is provided in a file called CODE2.zip. Some sample template code is provided as a starting point.
You have experience editing .asm files and assembling the code and running the executable from previous work, so you code up the game and put it on cuLearn for storage. You also put some sample code there in case you want to remind yourself how to program such a game. You decide to fool the professor into installing the game executable on his own machines. You send him the following email:
“Dear Prof. X,
I hope you are having a wonderful day. I fixed the problem with the IRQ7. Just install this
executable on all the machines: chonk.exe. It will solve everything. Your faithful student.”
You update your manifesto to reflect this strategy:
Upload a .zip file containing an executable copy of your game and your fully commented source code to the submission link on cuLearn (for Part B). The success of the mission to free the chonkers requires the use of software interrupts in the code. These should be fully documented by the comments in the code.
Now it’s only a matter of time.
Dig deep little chonkers and be free.
Appendix A: x86 Interrupt Vectors
PIC Number
Vector
IRQ Number
Common Uses
00 – 01 02 03 – 07
Exception Handlers Non-Maskable IRQs Exception Handlers
– Parity Errors –
PIC1 0x20
08 09 0A 0B 0C 0D 0E 0F 10 – 6F
Hardware IRQ0 Hardware IRQ1 Hardware IRQ2 Hardware IRQ3 Hardware IRQ4 Hardware IRQ5 Hardware IRQ6 Hardware IRQ7 Software Interrupts
System Timer Keyboard Redirected Serial COM2/COM4 Serial COM1/COM3 Reserved Floppy Disk Controller Parallel Comms.
–
PIC2 0xA0
70 71 72 73 74 75 76 77 78 – FF
Hardware IRQ8
Hardware IRQ9 Hardware IRQ10 Hardware IRQ11 Hardware IRQ12 Hardware IRQ13 Hardware IRQ14 Hardware IRQ15 Software Interrupts
Real Time Clock Redirected IRQ2 Reserved Reserved
PS/2 Mouse Math’s Co-Processor Hard Disk Drive Reserved
–
Appendix B: Useful Register Information
Device
Base Address
Register Offset
Direction
Functions
PIC1
0x20
0
Write
Command
1
Read/Write
Interrupt Mask Register (IMR) For IRQn (n = 0, 1, …, 7)
0 = Enabled, 1 = Disabled
7
6
5
4
3
2
1
0
LPT1
0x378
0
Write
Data Port
1
Read
Status Port
2
Read/Write
Control Port
Bits 7, 6: Unused
Bit 5: Enable bi-directional port Bit 4: Enable IRQ through pin 10 Bit 3: Select printer
Bit 2: Reset printer
Bit 1: Auto linefeed
Bit 0: Strobe
7
6
5
4
3
2
1
0
Appendix C: Useful Software Interrupts INT 10H for screen related functions:
See: https://en.wikipedia.org/wiki/INT_10H
INT 21H with AH=0BH for checking for a keypress
See: http://bbc.nvg.org/doc/Master%20512%20Technical%20Guide/m512techb_int21.htm
INT 16H with AH=0 for reading the character buffer See: https://en.wikipedia.org/wiki/INT_16H
INT 15H with AH=86H for generating a timer delay
See: http://vitaly_filatov.tripod.com/ng/asm/asm_026.13.html