As an example of using interrupt routines, we write a program that displays the current time. When the computer is powered up, the current time can be entered by the user or supplied by a real-time clock circuit that is battery powered. This time value is kept in memory and updated by a timer circuit using interrupt 8. A program can call the DOS INT 21h, function 2Ch, to access the time.
Our time display program has the following steps:
The procedure GET_TIME is used to get the current time and the procedure CONVERT is used to convert a number into ASCII. It first divides the number in AL by 10. This puts the ten's digit value in AL and the unit's digit value in AH (note that the input value is less than 60). Then, it converts both digits to ASCII. These two procedures are shown below:
To display the current time, a time buffer, TIME_BUF, is initialized with 00:00:00. The procedure GET_TIME is then called to store the current time in the time buffer. Then, the time_buffer is displayed using INT 21h, function 9. This program is shown below:
User Interrupt ProceduresTo make the time display program more interesting, let us write a second version that displays the time and updates it every second.
One way to continuously update the time is to execute a loop that keeps obtaining the time via INT 21h, function 2Ch and displaying it. The problem here is to find a way to stop the program.
Instead, this can be done by writing a routine for interrupt 1Ch. This interrupt is generated by the INT 8 routine which is activated by a timer circuit about 18.2 times a second. When our interrupt routine is called, it will get the time and display it.
Set Interrupt Vector
To set up an interrupt routine we need to do the following steps:
We use the INT 21h, function 35h, to get the old vector and function 25h to set up the new interrupt vector.
The following procedure, SETUP_INT, saves an old interrupt vector and sets up a new vector. It gets the interrupt number in AL, a buffer to save the old vector at DS:DI, and a buffer containing the new interrupt vector at DS:SI. By reversing the two buffers, SETUP_INT can also be used to restore the old vector.
Cursor ControlEach display of the current time by INT 21h, function 9, will advance the cursor. If a new time is then displayed, it appears at a different screen position. So, to view the time updated at the same screen position we must restore the cursor to its original position before we display the time. This is achieved by first determining the current cursor position; then, after each print string operation, we move the cursor back.
We use the INT 10h, functions 3 and 2, to save the original cursor position and to move the cursor to its original position after each print string operation.
Interrupt ProcedureThe interrupt procedure, TINE_INT, is written to perform the following steps:
The main procedure is written to have the following steps:
To do step 2, we use OFFSET and SEG to obtain the offset and segment of procedure SETUP_INT; the vector is then stored in the buffer NEW_VEC. The procedure SETUP_INT, is called to set up the vector for interrupt type 1Ch, timer tick. The interrupt 16h, function 0 is used for step 3, key input. Procedure SETUP_INT is again used in step 4; this time SI points to the old vector and DI points to the vector for TIME_INT.
After setting up the cursor and interrupt vectors, the main procedure just waits for a keystroke. In the meantime, the interrupt procedure, TIME_INT, keeps updating the time whenever the timer circuit ticks. After a key is hit, the old interrupt vector is restored and the program terminates. The complete program is given below.