19.5.1 Trapping Errors

A TSR committing an error that triggers an interrupt must handle the interrupt to trap the error. Otherwise, the existing interrupt routine, which belongs to the underlying process, would attempt to service an error the underlying process did not commit.

For example, a TSR that accepts keyboard input should include handlers for Interrupts 23h and 1Bh to trap keyboard break signals. When DOS detects CTRL+C from the keyboard or input stream, it transfers control to Interrupt 23h (CTRL+C Handler). Similarly, the BIOS keyboard routine calls Interrupt 1Bh (CTRL+BREAK Handler) when it detects a CTRL+BREAK key combination. Both routines normally terminate the current process.

A TSR that calls DOS should also trap critical errors through Interrupt 24h (Critical Error Handler). DOS functions call Interrupt 24h when they encounter certain hardware errors. The TSR must not allow the existing interrupt routine to service the error, since the routine might allow the user to abort service and return control to DOS. This would terminate both the TSR and the underlying process. By handling Interrupt 24h, the TSR retains control if a critical error occurs.

An error-trapping handler differs in two ways from a TSR's other handlers:

1.It is temporary, in service only while the TSR executes. At start-up, the TSR copies the handler's address to the interrupt vector table; it then restores the original vector before terminating.

2.It provides complete service for the interrupt; it does not pass control on to the original routine. However, if the error is not a TSR error, the handler needs to pass the error to the original routine.

Error-trapping handlers often set a flag to let the TSR know that the error has occurred. For example, a handler for Interrupt 1Bh might set a flag when the user presses CTRL+BREAK. The TSR can check the flag as it polls for keyboard input, as shown here:

BrkHandler PROC FAR ; Handler for Interrupt 1Bh

mov BreakFlag, TRUE ; Raise break flag

iret ; Terminate interrupt

BrkHandler ENDP

.

.

.

mov BreakFlag, FALSE ; Initialize break flag

poll: .

.

.

cmp BreakFlag, TRUE ; Keyboard break pressed?

je exit ; If so, break polling loop

mov ah, 1

int 16h ; Key waiting?

jnz poll ; If not, repeat polling loop