page,132
title BRK.ASM - BREAK PROCEDURES for MICROSOFT 'C' (4.0)
;
;  This program will take control of the keyboard interupt vector
;  and disable the CTRL key, eliminating the CTRL-C or CTRL-BREAK
;  during program execution.  Because this handler does not stay
;  resident it must be reset prior to exiting the program. I used
;  some unusual techniques in this code just for fun.
;
;      brk_off();    Turn off CTRL key.
;      brk_on();     Turn CTRL on and reset vector.
;
;                               by Mike Elkins   10-10-86
;
;

_romdata    segment at 0h
    org  417h                           ;Ctrl shift flag offset
_keyflag  label byte                    ;here's where we'll access it
_romdata  ends

_text       segment byte public 'code'
            assume  cs:_text


;-----establish interrupt vector

        public  _brk_off
_brk_off    proc    near

;    first check to see if brk_int is already loaded
        pushf                        ;save calling int status
        cli
        mov    ah,35h                ;get vector
        mov    al,09h                ;keyboard vector #
        int    21h

;    check the keyboard interrupt vector (in es:bx)
        cmp    bx,offset brk_int     ;check offset portion
        jne    on001                 ;not same
        mov    ax,es
        cmp    ax,seg brk_int        ;check segment portion
        je     on002                 ;same

;    save away origional vector
on001:  mov    cs:rom_key_int,bx     ;offset to storage
        mov    ax,es
        mov    cs:rom_key_int[2],ax  ;segment to storage

;    load our vector
        push    ds                   ;temp save
        mov     ax,seg brk_int
        mov     ds,ax
        mov     dx,offset brk_int    ;replace with our interrupt
        mov     ah,25h               ;set vector
        mov     al,09h               ;vector number
        int     21h
        pop     ds                   ;recover
        popf                         ;recover int status
        ret

;    already loaded - exit with error flag
on002:        popf
        mov     ax,-1                 ;set error
        ret

_brk_off    endp

page +
;----- terminates interrupt vector

        public    _brk_on
_brk_on    proc    near

;    test for vector in storage
        cmp     cs:rom_key_int[2],0
        je      of001            ;no - exit

;    restore old vector
        pushf
        cli
        push    ds                     ;temp save
        mov     dx,cs:rom_key_int      ;offset portion
        mov     ax,cs:rom_key_int[2]   ;segment portion
        mov     ds,ax
        mov     ah,25h                 ;set vector
        mov     al,09h                 ;keyboard vector #
        int     21h
        pop     ds                     ;restore
        popf

of001:
        ret

_brk_on    endp

page +
;------ This procedure responds to keyboard interrupt (09h)
;
brk_int:
        sti
	push	ax
	push	bx
	push	dx
	push	ds
	push	es
	push	si
	push	di
	push	bp

        assume  ds:_romdata     
        mov     ax, _romdata
        mov     ds,ax
        test    byte ptr _keyflag, 04h  ;Check for Ctrl shift state
        jz      key_released
        in      al,060h                 ;read keyboard
        test    al,080h                 ;see if key release
        jnz     key_released            ;ignore if released
        cmp     al,02eh                 ;scan for C key
        jz      brk_hit                 ;no, handle normally
        cmp     al,046h                 ;scan for scroll lock key
        jz      brk_hit                 ;no, handle normally
        jmp     brk_exit
;
; Get rid of CTRL key
;
brk_hit:
        in      al,061h                 ;read 8255 port
        or      al,080h                 ;set ack signal bit
        out     061h,al                 ;send ack to port
        and     al,07fh                 ;reset ack bit
        out     061h,al                 ;restor port status
;
        mov     al,020h                 ;send EOI to 8259
        out     020h,al
;        
        pop     bp
        pop     di
        pop     si
        pop     es
        pop     ds
        pop     dx
        pop     bx
        pop     ax
        iret
;
key_released:
brk_exit:
           pop    bp
           pop    di
           pop    si
           pop    es
           pop    ds
           pop    dx
           pop    bx
           pop    ax
            db    0eah              ; long-jump to old vector
;
rom_key_int    dw      2 dup (?)    ;contains the ROM jump-to-address

_text        ends

        end
