; From Steve Leach ; ; This is a short TSR to trap and display current ; Registers, flags, and a dump of the next instruction... ; hitting 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 " 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 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 ; 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 ;