Thanks Kevin ... for those interested, here's the code and description of what COMTRAP is and how it works (neat stuff!) ...
;
; COMTRAP 1.0 - A TSR to trap unexpected hardware interrupts
;
; This TSR solves a problem that only occurs when using you wish to
; popup a swapping TSR over a communications program. Even then, the
; problem it solves occurs rather infrequently. The problem is that the
; swapping TSR will restore the vector table to what it was when the TSR
; was first installed (which temporarily removes the communications
; program's vectors). Unfortunately, the UART and PIC are still configured
; to process serial port interrupts, the old serial port vector gets called.
; Usually, this will be the BIOS's ISR to handle unexpected interrupts. This
; BIOS ISR will clear the interrupt but then mask further interrupts from
; that particular IRQ. When the swapping TSR is finally popped down
; interrupts remain masked off for the serial port IRQ; so, the communications
; program won't receive any more interrupts -- meaning no more serial I/O
; will take place and, in some cases, the communications program will
; appear to be hung.
;
; This TSR avoids the problem by installing its own serial port ISR so that
; when the swapping TSR replaces the vector table the serial port vectors
; will point to COMTRAP's ISR rather than the BIOS ISR. COMTRAP's ISR will
; clear any received interrupts but leave the IRQ unmasked.
;
; Note that versions of Object Professional 1.13 and beyond avoid this problem
; by saving and restoring the PIC state (the chip that controls which
; hardware interrupts are currently masked on or off). So, you'll only need
; COMTRAP if using earlier versions of Object Professional or with other
; TSRs or TSR libraries that don't save and restore the PIC.
;
; Note that it is still possible for a TSR (swapping or otherwise) to
; disrupt a communications program even if you are using COMTRAP. If the
; communications program using interrupt-driven transmits (as does Async
; Professional) and the TSR prevents the communications program from getting
; a transmit completion interrupt then the communications program will
; likely not be able to recover from this. You can protect your
; communications programs from this situation by installing a clock
; ISR that periodically checks for lost transmit interrupts and calls
; StartTransmitter when this occurs.
;
; To use COMTRAP, simply type
;
; COMTRAP x x
;
; where x is either 1 or 2 (for COM1 or COM2)
;
; Examples:
;
; COMTRAP 1 2
; traps both COM1 and COM2
;
; COMTRAP 1
; traps COM1 only
;
; If you wish to modify COMTRAP.ASM, use the following steps to rebuild it:
;
; TASM comtrap
; TLINK /t comtrap (use /t to generate a .COM executable)
;
; 1/8/92
; Terry Hughes
; released to the public domain
.model small
.code
ORG 80H
CmdLen LABEL BYTE ;command line length
ORG 81H
CmdLin LABEL BYTE ;first character of command line
ORG 100h ;this is a COM file
Initialize:
JMP NonResCode ;jump to start up code
NullComHandler:
PUSH AX
INC CS:BadCnt
MOV AL,020h ;non specific EOI
OUT 020h,AL ;issue the EOI
POP AX
IRET
GoRes:
CMP CS:GotArg,0
JE ErrMsg
MOV AX,CS
MOV ES,AX
MOV DX,OFFSET NonResCode
ADD DX,15 ;force round up
MOV CL,4 ;for div 16
SHR DX,CL ;convert bytes to paragraphs
MOV AX,3100h ;terminate and stay resident
INT 21h
Flag DB 'BadCnt:'
BadCnt DW 0
NonResCode:
CLI
MOV SP,0FFh ;use command of PSP as temp stack
STI
MOV AH,09h ;show title
MOV DX,OFFSET TitleMsg
INT 21h
MOV SI,OFFSET CmdLin ;point to command line
CLD
Get1: LODSB ;get first non-blank
CMP AL,32 ;skip space
JE Get1 ;
CMP AL,9 ;skip tab
JE Get1 ;
CMP AL,13 ;finished if no more input
JE GoRes ;
CMP AL,'1' ;
JL ErrMsg ;error if less than '1'
CMP AL,'2' ;
JG ErrMsg ;error if greater than '2'
CMP AL,'1' ;
JNE InstallCom2 ;
MOV DX,OFFSET NullComHandler ;install handler for com1
MOV AX,250Ch
INT 21h
INC CS:GotArg
JMP Get1
InstallCom2:
MOV DX,OFFSET NullComHandler ;install handler for com2
MOV AX,250Bh
INT 21h
INC CS:GotArg
JMP Get1
ErrMsg:
MOV AH,09h ;show title
MOV DX,OFFSET UsageMsg
INT 21h
MOV AX,4C01H
INT 21H
TitleMsg:
DB 'COMTRAP 1.0', 0Dh, 0Ah
DB 'released to the public domain', 0Dh, 0Ah, '$'
UsageMsg:
DB 0Dh, 0Ah, 'Usage: COMTRAP x x', 0Dh, 0Ah
DB ' where x x are the numbers of the COM port to trap [1..2]', 0Dh, 0Ah
DB ' example: COMTRAP 1 2 will trap invalid interrupts to COM1 and COM2', 0Ah, 0Dh, '$'
GotArg DB 0
_TEXT ENDS
END Initialize