PAGE 60,132
; BREAKPT.ASM: A DEBUGGING UTILITY
; TO BE USED IN CONJUNCTION WITH THE DOS DEBUG UTILITY OR ANY DEBUGGER
; WHICH CAN INTERCEPT THE BREAKPOINT INTERRUPT.
; USAGE: RUN BREAKPT.COM ONCE UNDER DOS TO INSTALL.
;        LOAD DEBUGGER WITH PROGRAM TO BE DEBUGGED.
;        SET A BREAKPOINT (ANY BREAKPOINT) AND EXECUTE PROGRAM.
;        WHILE PROGRAM RUNS, HITTING CTRL-ESC JUMPS TO THIS ROUTINE,
;        WHICH HANDS CONTROL TO DEBUGGER.
;        NOTE THIS METHOD CAN BE USED TO INTERRUPT BOTH ROM
;        AND RAM EXECUTION.
;                               PROGRAM BY RICH WINKEL
BOTTOM  SEGMENT AT 0H
        ORG     024H
KBDIP   DW      ?               ;IP FOR KBD INT
KBDCS   DW      ?               ;CS FOR KBD INT
        ORG     0417H
KB_FLAG DB      ?               ;ROM BIOS DATA
BOTTOM  ENDS
;
BREAKPT SEGMENT
        ASSUME CS:BREAKPT,DS:BOTTOM
        ORG     100H
MAIN    PROC    NEAR
        JMP     INIT
;
; KEYBOARD INTERRUPT INTERCEPT ROUTINE
;
CATCH:  STI                     ;INTERRUPTS BACK ON
        PUSH    AX
        IN      AL,60H          ;CHECK SCAN CODE
        CMP     AL,01H          ;IS IT ESC KEY?
        JNZ     L2              ;NO, ON TO KEYBOARD ROUTINE
        PUSH    DS              ;OTHERWISE, CHECK FOR
        XOR     AX,AX           ;CONTROL KEY SHIFT
        MOV     DS,AX           ;GET DOWN TO THE BOTTOM
        MOV     AL,KB_FLAG      ;GET KEYBOARD FLAG BYTE FROM ROM DATA
        TEST    AL,04H          ;CTRL SHIFT?
        JZ      L1              ;NO, ON TO KEYBOARD ROUTINE
        IN      AL,61H          ;OTHERWISE, WE TAKE IT FROM HERE
        MOV     AH,AL           ;RESET
        OR      AL,80H          ;THE
        OUT     61H,AL          ;KEYBOARD
        MOV     AL,AH           ;CONTROL
        OUT     61H,AL          ;PORT
        CLI                     ;TURN OFF INTERRUPTS
        MOV     AL,20H          ;RESET INTERRUPT CONTROLLER (8259)
        OUT     20H,AL
        POP     DS
        POP     AX
        STI                     ;LET PENDING INTERRUPTS EXECUTE
        NOP
        INT     03H             ;NOW GIVE DEBUG CONTROL
        IRET                    ;SINGLE STEP BACK TO INTERRUPTED PGM
L1:     POP     DS              ;ONWARD TO KBD ROUTINE
L2:     POP     AX
        DB      0EAH            ;PREFIX BYTE FOR FAR JUMP
JFARIP  DW      0H              ;IP FOR KBD ROUTINE
JFARCS  DW      0H              ;CS FOR KBD ROUTINE
INIT:   XOR     AX,AX           ;GET INTO
        MOV     DS,AX           ;BOTTOM SEGMENT
        MOV     AX,KBDIP        ;GET IP FOR KBD INTERRUPT
        MOV     CS:JFARIP,AX    ;PUT IN OUR FAR JUMP
        MOV     AX,KBDCS        ;GET CS FOR KBD INTERRUPT
        MOV     CS:JFARCS,AX    ;PUT IN OUR FAR JUMP
        MOV     AX,CS           ;BACK TO
        MOV     DS,AX           ;OUR SEGMENT
        MOV     DX,OFFSET CATCH ;USE DOS TO POINT KBD INT TO US
        MOV     AX,2509H        ;'RESET INT 9H VECTOR TO DS:DX'
        INT     21H             ;DO IT
        MOV     AH,09H          ;PRINT MESSAGE
        MOV     DX,OFFSET MSG   ;POINT TO MESSAGE
        INT     21H             ;DO IT
        MOV     DX,OFFSET INIT  ;GET LAST ADDRESS OF RESIDENT CODE
        INT     27H             ;TERMINATE AND STAY RESIDENT
;
MSG     DB 'Breakpoint debugging utility.',0DH,0AH
        DB 'Load a program under DEBUG, '
        DB 'set a breakpoint, (any breakpoint) and go.',0DH,0AH
        DB 'To stop the program for debugging, hit Ctrl-Esc, then type:',0DH,0AH
        DB  09H,'RIP <enter> 12D <enter> T <enter>',0DH,0AH
        DB 'to jump over the INT 3, execute an IRET, and',0DH,0AH
        DB 'get back to where your program was executing.',0DH,0AH
        DB "WARNING: Don't hit Ctrl-Esc except while under DEBUG!$"
;
MAIN    ENDP
BREAKPT ENDS
        END MAIN
                                                                                           P
BREAKPT ENDS
        END MAIN
                                                                                           