'===========================================================================
' Subject: EDWARD LAM/BRENT ASHLEY            Date: 02-01-93               
'  Author: DISABLE PAUSE BUTTON               Code: ASM, QB, PDS           
'  Origin: NANET-BASIC                      Packet: KEYBOARD.ABC
'===========================================================================
'   Because B_OnExit might have too many routines registered already, I've made
'NoPause a function returning TRUE(-1) if everything is ok, otherwise FALSE(0).
'   The B_OnExit routine does look a little eratic to me in the environment but
'try it and see what happens.

'cut here for NOPDEMO2.BAS

'Example program for NoPause2 module.
'
DECLARE FUNCTION NoPause%
'
CLS
PRINT "Press N for NoPause, U to Unhook NoPause, ESC to exit"
DO
  I = (I + 1) MOD 1000
  LOCATE 5, 5: PRINT "     ";
  LOCATE 5, 5: PRINT I;
  A$ = UCASE$(INKEY$)
  IF A$ = "N" THEN
     IF NOT NoPause% THEN   'We call NoPause here
        LOCATE 2, 1
        PRINT "B_OnExit Full!  Can't stop pause key"
     END IF
  END IF
  IF A$ = "U" THEN
      CALL UnhookNoPause  'Have option to disable nopause from
                           'within program
      LOCATE 2, 1
      PRINT SPACE$(36)
  END IF
LOOP UNTIL A$ = CHR$(27)
'Note that we don't care the state of the vectors since B_OnExit will call
'UnHookNoPause for us.  You can call UnHookExit as many times as you like

 ;NoPause2.ASM

;Note that this file has been modified so that the UnHookNoPause routine
;does not need ever (or should it) to be called.  --EKL

EXTRN   B_OnExit:FAR            ;QB's internal routine calls all clean
                                ;up routines registered with it ony
_any_ exit

;
; NoPause.ASM by Brent Ashley  /  NoPause2.ASM modified by Edward Lam 01/31/93
;
.model medium, basic
.code
Old1C        Label Dword          ;Label for to old Int 1Ch
Old1COffset  dw ?                 ;Offset part
Old1CSegment dw ?                 ;Segment part
Hooked       db 0                 ;Our installed flag

;Note that if an error occurs registering NoHookPause, NoPause will return
;FALSE.  Right, it's a function now instead of a sub -- EKL
NoPause proc uses ds dx           ;From BASIC: Ok% = NoPause%
                                  ;Use UnhookNoPause to disable NoPause

        cmp cs:Hooked,0           ;Are we already hooked?
        jnz InstallExit           ;If so, exit

        ;following section just cut&paste from EVENTCHN.ASM by Jim Mack
        mov     dx, offset UnHookNoPause
        push    cs                ; push far address of UnHookNoPause
        push    dx                ; to register the exit routine
        call    B_OnExit          ; so that we don't hang machine
        or      ax, ax            ; registered OK?
        jz      ErrorExit         ; error: too many registered routines

        mov ax,351Ch              ;Get current vector for int 09h
        int 21h

        mov cs:Old1CSegment,es    ;Remember it for later
        mov cs:Old1COffset,bx
        mov ax,251Ch
        push ds
        push cs
        pop ds                    ;Point int 1Ch to our code
        mov dx, offset OurInt1C
        int 21h
        pop ds
        mov cs:Hooked,-1          ;Set our installed flag
        mov ax, -1                ;return TRUE for ok
        jmp InstallExit

ErrorExit:
        sub ax, ax                ;put 0 into ax to return with error

InstallExit:
        ret

OurInt1C:                         ;Our Int 1Ch handler
        push ds                   ;
        push bx
        push ax
        xor bx, bx                ;point DS to BIOS data area
        mov ds, bx                ;
        mov bx, 0418h
        mov al, [bx]
        and al, 0F7h              ;reset nopause flag
        mov [bx], al
        pop ax
        pop bx
        pop ds
        jmp dword ptr cs:[Old1C]  ;Transfer to orig Int 1Ch

NoPause endp

UnhookNoPause proc                ; from BASIC: CALL UnHookNoPause
        cmp cs:Hooked,0           ; are we installed?
        jz UnHooked               ; nope - exit

        push ax
        push ds
        mov ax,251Ch              ;Unhook ourself
        mov ds,Old1CSegment
        mov dx,Old1COffset
        int 21h                   ;Point Int 1Ch back to original
        pop ds
        pop ax
        mov cs:Hooked,0           ;Set installed flag back to zero

UnHooked:
        ret
UnhookNoPause endp

END
