home *** CD-ROM | disk | FTP | other *** search
- title KTIME-XT.ASM ;8-10-88
-
- ;BY J.W.G.
-
- ;for IBM PC and XT & compatible
- ;If this program is executed without
- ;a command line parameter, or an
- ;invalid parameter then the
- ;time of 2 minutes will be used.
-
- ;The optional command line parameter
- ;is a number from 1 to 3600
- ;representing the number of seconds
- ;the keyboard will be disabled.
-
- ;Example... KTIME-XT 105
- ;means.. kbd disabled 1 min 45 sec.
-
- ;memory resident INT 8 routine
- ;Takes up 496 bytes of RAM.
- ;INT 8 is "timer tick interrupt"
- ;and is executed 18.2 times per sec.
- ;
- ;Installation routine disables
- ;keyboard.
- ;
- ;Resident routine counts timer
- ;ticks up to a value, then
- ;re-enables the keyboard.
-
- cseg segment para public 'code'
- org 100h
-
- KILLKBD proc far
- assume cs:cseg, ds:cseg
- jmp install
- oldint dd 0
- counter dw 0
- ticks dw 7008h ;870H / 2160 decimal
- ;default 2 min time
- ;delay time if no
- ;parameter on
- ;command line.
- intloc equ 8h*4
-
- newint:
- ;NOTE: when time interval is up
- ;a JMP 013Bh instruction will be
- ;placed here.
- push bx
- push es
- push si
- push ax
- pushf
- ;
- xor ax,ax
- mov es,ax
- mov si,offset counter
- mov ax,cs:[si]
- inc ax
- mov cs:[si],ax
- lea si,ticks
- mov bx,cs:[si] ;get compare value ticks
- cmp ax,bx
-
- ;int 8 is called 18.2 times per sec.
- ;in one minute it is called 1080 times
- ;
- jb return ;jump if count short
- ;Now short circuit this routine by
- ;installing a JMP at newint:
- mov si,offset newint
- mov ax,2EEBh ;opcodes for JMP 13B
- ;(backwards fashion)
- mov cs:[si],ax ;install JMP intstr.
- ;JMP 013Bh at 010B
- ;enable keyboard now.
- mov al,4Ch
- out 61h,al ;enable keyboard.
- return:
- popf
- pop ax
- pop si
- pop es
- pop bx
- ;short circuit will jump to here.!
- ;target of JMP 013Bh
- jmp cs:[oldint]
- install:
- CALL GET_PARAM
- mov ax,0
- mov es,ax
- ;set counter to zero
- mov si,offset counter
- mov cs:[si],ax
- ;
- mov di,intloc
- mov ax,es:[di]
- mov bx,es:[di+2]
- mov si,offset oldint
- mov [si],ax
- mov [si+2],bx
- mov ax,0
- mov es,ax
- mov bx,ds
- cli
- mov di,intloc
- mov ax,offset newint
- mov es:[di],ax
- mov es:[di+2],bx
- sti
- ;
- ;disable keyboard now
- mov al,0CCh
- out 61h,al
- ;
- mov dx,offset install
- int 27h ;terminate stay resident
- KILLKBD endp
-
- GET_PARAM proc near
- ;get parameters from command line
- mov ax,0000h
- mov al,cs:[0080h] ;byte contains
- ;length of
- ;command tail + 1
- cmp al,00h
- je QUIT2 ;no param on command line
- dec al ;The byte at cs:0080 is
- ;supposed to be the # of
- ;characters making up the
- ;command tail, however it
- ;is really that value + 1
- cmp al,04h ;more than 4 chars in
- ja QUIT2 ;com line parameter ?
- push ax
- CALL GET_ONES
- pop ax
- dec al
- cmp al,00h
- je QUIT
- push ax
- CALL GET_TENS
- pop ax
- dec al
- cmp al,00h
- je QUIT
- push ax
- CALL GET_HUNDREDS
- pop ax
- dec al
- cmp al,00h
- je QUIT
- CALL GET_THOUSANDS
- QUIT:
- ;BX now contains number of seconds
- ;of desired wait period.
- ;we must multiply it by 18.2 to get
- ;value of ticks.
- cmp bx,0
- je QUIT2 ;use default time
- cmp bx,3600 ;too large ?
- ja QUIT2 ;use default time
- mov ax,0012h ;18 decimal
- mul bx
- ;AX now contains BX * 18
- ;but we needed BX * 18.2 !
- ;First we will divide by 10 and then
- ;multiply by 2 (by Lshift 1 bit)
- mov cx,ax ;save AX in CX
- mov ax,bx ;bx = seconds param.
- mov dx,0 ;will = remainder
- mov bx,000Ah
- div bx ;divide AX by 10 dec.
- cmp dx,5 ;is remainder > 5
- jb SKIP
- inc ax ;round off if
- ;remainder > 5
- SKIP:
- shl ax,1 ;AX = AX * 2
- add ax,cx
- mov ticks,ax ;store valid value
- QUIT2:
- ret
- GET_PARAM endp
-
- GET_ONES proc near
- ;parameters start at cs:005Dh
- ;reg al contains length command tail
- add ax,005Ch
- push ax
- pop si ;si points to rightmost byte
- mov bx,0
- mov bl,cs:[si]
- sub bl,30h ;convert ASCII number to
- ;decimal number
- ret
- GET_ONES endp
-
- GET_TENS proc near
- dec si
- mov ax,0
- mov al,cs:[si]
- sub al,30h
- mov cx,000Ah
- mul cx ;ax = ax * 10 (cx)
- add bx,ax ;new subtotal
- ret
- GET_TENS endp
-
- GET_HUNDREDS proc near
- dec si
- mov ax,0
- mov al,cs:[si]
- sub al,30h
- mov cx,0064h
- mul cx ;ax = ax * 100 (cx)
- add bx,ax ;new subtotal
- ret
- GET_HUNDREDS endp
-
- GET_THOUSANDS PROC NEAR
- dec si
- mov ax,0
- mov al,cs:[si]
- sub al,30h
- mov cx,03E8h
- mul cx ;ax = ax * 1000 (cx)
- add bx,ax ;final total seconds
- ret
- GET_THOUSANDS ENDP
-
- cseg ends
- end KILLKBD
-
-