; From Steve Leach
;
; This is a short TSR to trap <CTR><ALT><DEL> and display current
; Registers, flags, and a dump of the next instruction...
; hitting <CTRL><ALT><DEL> again will reboot.
;
; Based on Paul Cullum's NOCAD program
CODE_SEG SEGMENT
BEGSEG EQU $
ASSUME CS:CODE_SEG, DS:CODE_SEG, ES:CODE_SEG, SS:CODE_SEG
ORG 100H
BEGIN:
JMP INIT ; Install in memory and exit to DOS
INT9: ;
STI ; Enable interrupts
PUSH AX ;
IN AL, 60H ; Get key from keyboard controller
CMP AL, 53H ; Is it Del?
JNZ NOT_DEL ; Nope, let it through
PUSH BX ;
PUSH ES ;
XOR BX, BX ; Segment 0
MOV ES, BX ;
MOV BX, 417H ; Offset 417 - key flags
TEST BYTE PTR ES:[BX], 08H ; Test for Alt press
JZ NOT_OURS ; Nope
TEST BYTE PTR ES:[BX], 04H ; Test for Ctrl press
JZ NOT_OURS ; Nope
JMP DEL_PRESS ; Yep, absorb this keystroke
NOT_OURS: ;
POP ES ; Restore ES and BX
POP BX ;
NOT_DEL: ;
POP AX ;
DB 0EAH ; Call old INT 9 handler
INT9OFF DW 0000 ; Offset and
INT9SEG DW 0000 ; Segment stored here
DEL_PRESS: ;
IN AL, 61H ; This stuff is to tell the
MOV AH, AL ; Key controller that we
OR AL, 80H ; Have gotten the key.
OUT 61H, AL ; (for XT's)
MOV AL, AH ;
OUT 61H, AL ;
MOV AL,020H ; Send EOI to 8259 command reg.
OUT 020H,AL ;
MOV AX,3 ; Set Vid. mode 3
INT 10H ;
POP ES ; Restore ES and BX
POP BX ;
MOV AX,ES ; Save all registers
PUSH AX ; To stack
MOV AX,DS ;
PUSH AX ;
PUSH BP ;
PUSH DI ;
PUSH SI ;
PUSH DX ;
PUSH CX ;
PUSH BX ;
JMP PAST_DATA ;
REGS DB 13,10,13,10,"ANYONE ELSE MISS FRONT PANNELS? HIT <CTRL><ALT><DEL>"
DB " AGAIN TO EXIT",13,10,13,10 ;
DB "BX",9,"CX",9,"DX",9,"SI",9,"DI",9,"BP",9,"DS",9,"ES",9,"AX"
DB 13,10,0 ;
;
FLAG_MSG DB 13,10,13,10,"FLAGS: ",0 ;
;
INST_MSG DB 13,10,13,10,"NEXT INSTRUCTION: ",0
PAST_DATA:
;
MOV BX,OFFSET REGS ; Display register names
CALL DISP_MSG ;
MOV CX,9 ; Number of registers to display
PE_L2: ;
POP AX ; Pop register value from stack
MOV BX,16 ; Base
MOV SI,4 ; Didgits
CALL DISP_UAX ; Display value
MOV AH,0EH ; Tty print
MOV AL," " ; Space
INT 10H ; Print it
INT 10H ;
LOOP PE_L2 ;
MOV WORD PTR CS:DEL_PRESS, 00EAH ; Next time <CTRL><ALT><DEL>
MOV WORD PTR CS:DEL_PRESS+2,0FF00H ; Is pressed, JMP FFFF:0000
MOV BYTE PTR CS:DEL_PRESS+4,0FFH ; Will be executed
MOV BX,OFFSET INST_MSG ; Display instruction message
CALL DISP_MSG ;
POP DI ; Ds:di points to instruction
POP DS ;
MOV DX,10 ; Number of words to display
;
PRINT_INSTRUCTION: ;
MOV AX,DS:[DI] ; Load next instruction word
MOV SI,4 ; Didgits
MOV BX,16 ; Base
CALL DISP_UAX ; Display value
INC DI ; Update pointer
INC DI ;
DEC DX ; Decrement counter
JNZ PRINT_INSTRUCTION ; Loop until 10 words displayed
MOV BX,OFFSET FLAG_MSG ; Display flag message
CALL DISP_MSG ;
POP AX ; Flags
MOV SI,16 ; Didgits
MOV BX,2 ; Base
CALL DISP_UAX ; Display flags value
WAIT_FOR_RELEASE: ; Infinate loop (until user presses
JMP WAIT_FOR_RELEASE ; <Ctrl><Alt><Del> again)
; -----------------------------------------------------------
DISP_MSG: ; Display string
MOV AH,0EH ; Tty write
PRNT_MSG: ;
MOV AL,CS:[BX] ;
OR AL,AL ;
JZ PRINT_DONE ;
CMP AL,9 ;
JNE NO_TAB ;
MOV AL," " ;
MOV CX,3 ;
TAB: ;
INT 10H ;
LOOP TAB ;
NO_TAB: ;
INT 10H ;
INC BX ;
JMP PRNT_MSG ;
PRINT_DONE: ;
RET ;
;
; -----------------------------------------
;
DISP_UAX: ; Display unsigned number in AX
PUSH BX ;
PUSH CX ; Bx = base to convert to
PUSH DX ;
MOV CX,SI ; Cx = number of didgets
DISP_UAX_LOOP: ;
XOR DX,DX ; Devide by base storing remainders
DIV BX ;
CMP DX,9 ;
JBE DU_NH ;
ADD DX,55 ;
JMP DU_H ;
DU_NH:
ADD DX,'0' ;
DU_H: ;
PUSH DX ;
LOOP DISP_UAX_LOOP ;
MOV CX,SI ;
DISP_UAX_LOOP2: ;
POP AX ; Restore remainders and print in
MOV AH,0EH ;
INT 10H ; Reverse order...
LOOP DISP_UAX_LOOP2 ;
POP DX ;
POP CX ;
POP BX ;
RET ;
DW 15H DUP (0) ;
RESSIZ EQU (($ - BEGSEG) / 16) + 1 ; Number of para. to keep
INIT: ;
MOV AX, 3509H ; Get interrupt vector for key press
INT 21H ; Call DOS
MOV [INT9OFF], BX ; Store offset
MOV [INT9SEG], ES ; And segment
MOV AX, 2509H ; Set interrupt vector for key press
MOV DX, OFFSET INT9 ; To our interrupt handler
INT 21H ; Call DOS
MOV AX, 3100H ; Terminate and Stay Resident
MOV DX, RESSIZ ; Number of paragraphs needed
INT 21H ; Call DOS
CODE_SEG ENDS ;
END BEGIN ;