Computer Engineering II
Potts, Spring 2001

Machine Problem 3: Typing-Tutor 291

Assigned Tuesday, February 27, 2001
Purpose Text-Mode Graphics, Timer and Keyboard Interrupts
Points 50
Due Date March 21 - 5:00pm


Ever used a typing tutor to learn how to type? Ever think of doing so? We're about to create one, but don't expect it to be as good as Mavis Beacon.

Problem Description

Our typing tutor has to do three main things:

To do these somewhat efficiently, we're going to hook into the computer's keyboard and timer interrupts, to run some of the code asynchronously from the main loop. Asynchronously means, in this sense, that you never know ahead of time when it will run. You could have two move opcodes, or a compare and a conditional jump, and either could be interrupted to run the Interrupt Service Routine (ISR). More on this shortly.


Interrupt Service Routines

Hardware Interrupts are generated when various hardware events occur.  Examples include the timer, which triggers 18.2 times per second, the keyboard, which triggers for every key press and release, and the mouse which triggers for any movement or button press or release. These interrupts are the hardware's way of saying "I need attention," so that the rest of the time the CPU can completely ignore such devices, and just execute code.

When the interrupt happens, the CPU is informed.  The current opcode finishes execution, and then the current program is interrupted. This is when your Interrupt Service Routine (ISR) is executed. As it happens between two effectively random lines of your program, the ISR needs to save all registers and the flags. The hardware takes care of part of this (by pushing of the flags); the rest you must take care of by using IRET instead of RET (to pop the flags), and saving your registers like normal.

The Timer

The timer will be used to keep track of how long it takes the typist to type the sentences. While we could probably be saving these scores for charting improvement, we'll just use it to report back to the user immediately. Every time your timer ISR is called, increment the tick counter, [ticks]. Then, every 18 ticks increment the seconds counter and the fifths counter, [seconds] and [fifths] respectively, and reset the tick counter to 0. Finally, every 5 seconds, decrement the time counter (to make up for the .2 of the 18.2 ticks per second) and reset the second counter to 0.

The Keyboard

When your keyboard handler is called, you know a key has been pressed or released. Unfortunately, you don't know what key, whether it was pressed or released, and whether the press is a true press or an auto-repeat press. There's no way for us find out the last (except keeping track yourself), but as for which key and press or release, you can (and must) find this out by asking the keyboard for the scancode. See the lab manual, page 75 or thereabouts, for information on retrieving these scancodes. The pages after that describe how scancodes work.

The Keyboard Lookup Tables

If you look at the scancodes, and you look at your ascii table, the first thing you'll probably notice is that there's no connection. If you then look down at the keyboard, however, you may notice a general correlation between the scancode and the location of the key, with ESC being scancode 1, and the numbers following an increasing pattern.

While theoretically we could try to come up with some arbitrary math procedure to translate from scancode to ascii code, it's much easier and much faster to just use a lookup table. And since there are several bits of information we want to handle, using multiple lookup tables is definitely the choice.

The tables we'll be using are as follows:

The Strings

As the user types a string, it needs to be compared against the correct string.  As the user makes mistakes, they need to be highlighted. When the user hits backspace, we need to back up the user version. All these things need to be tracked, and drawn in the appropriate colors.

Similarly, the keyboard must be updated to match the current state of the keyboard (yes, there are some keys that make it look like shift was pressed when it wasn't.  Don't worry about them; just treat the shift scancode as you always would).

Rather than redrawing the entire keyboard every time, just use HighlightKey to change the attribute of a given key by scancode (for easy use of the lookup table). But do redraw the entire keyboard (not changing the attributes) using the Shift tables, if [shift] changes to true (or the normal tables if it changes to false).












Monitor the newsgroup and this on-line section for revisions to the MP or to the write-up


Final Steps

1. Demonstrate your MP3.EXE to a TA. You may be asked to recompile and demo the program. Your program must work with all given input.

2. Be prepared to answer questions about any aspect of the operation of your program. The TAs will not accept an MP if you cannot fully explain your code and your implementation. Delayed MPs will be subject to late penalties as described in the course syllabus (10/pts per day).

3. The TA will complete the code submission procedure.