vgreenberg@watnot.UUCP (03/12/87)
Following is the binary and source for Quickey. This is a very handy
little utility (from PC Magazine V5N5) that overcomes the sluggishness
of the IBM PC keyboard. The program increases the auto-repeat rate to
about 18 characters / second, by patching itself into the keyboard and
timer interrupts, and stuffing the last key pressed into the input
buffer with every clock tick (until the key is released).
The program can be run more than once, each time increasing the auto-
repeat rate (each copy contributes a character with every clock tick).
I fixed a small bug in the original listing -- it was not working
correctly with Alt numeric-keypad entries.
Quickey also provides a way to flush the input buffer with Alt-Shift. Enjoy!
begin 644 quickey.com
MZ<D !P$>4[M ([;+L8�$ BQX< )PN_QX' 3L>' !U
M%2['!@L!___V!A< "G0XB1X: .LRD(L?"O]T)"X['@L!+HD>"P$NBAX/ 74%
M+HH>$ $NB!X. 2[&!@T! >L(D"['!@L!__];'\\N@#X- 0%U2"[^#@X!=4$>
M5U-0NT CMN+'AP B_N#PP*#^SYU [L> #L>&@!U"2[&!@T! .L5D/HNH0L!
MB06)'AP ^RZ@$ $NH@X!6%M?'R[_+@,!,\".P":A( FBQXB ":+#B0 )HL6
M)@"C P&)'@4!B0X' 8D6"0'ZC09W 2:C( FC XB (T&$0$FHR0 )HP.)@#[
&C1;, <TG
end
--- cut here ---
; Quickey.asm: speed up the IBM PC keyboard auto-repeat
; This program was obtained from a PC Magazine listing (V5N5)
; Bug fixed: now responds correctly to ALT numeric-keypad entries
;
; To create quickey.com:
; masm quickey;
; link quickey;
; exe2bin quickey quickey.com
; del quickey.exe
BIOS_SEG segment at 40h
BIOS_SEG ends
CSEG segment
assume cs:CSEG
org 100h
begin: jmp initialize
rom_int8 dw ?,? ; save original timer vector
rom_int9 dw ?,? ; and keyboard vector
dup_char dw ? ; char to be repeated next
dup_switch db 0 ; 1 if char to be repeated
dup_count db 0 ; tics left before repeat
dup_delay1 db 7 ; tics before first repeat
dup_delay2 db 1 ; tics between repeats
ALT_SHIFT equ 0Ah ; KBFLAGS mask
BIOS_KBFLAGS equ 17h
BIOS_HEAD equ 1Ah
BIOS_TAIL equ 1Ch
BIOS_END equ 3Eh
BIOS_START equ 1Eh
;keystroke interrupt
int9:
push ds
push bx
mov bx,BIOS_SEG
mov ds,bx
assume DS:BIOS_SEG
mov dup_switch,0 ; turn off auto key repeat
mov bx,ds:[BIOS_TAIL] ; get current tail
pushf
call dword ptr rom_int9 ; call bios
cmp bx,ds:[BIOS_TAIL] ; see if tail moved
jne was_new_key ; yes
mov dup_char,-1 ; match any key next time
test byte ptr ds:[BIOS_KBFLAGS],ALT_SHIFT
jz key_return ; no.
mov ds:[BIOS_HEAD],bx ; empty kb buffer
jmp key_return
was_new_key:
mov bx,[bx] ; get char
or bh,bh ; if scan code == 0: ALT-keypad
jz false_key
cmp bx,dup_char ; see if same as before
mov dup_char,bx ; - and store
mov bl,dup_delay1 ; if different key - start slow
jne switch_on
mov bl,dup_delay2 ; if not different - autorepeat
switch_on:
mov dup_count,bl ; set repeat rate
mov dup_switch,1 ; turn tick ctr back on
jmp key_return
false_key:
mov dup_char,-1 ; match any key next time
key_return:
pop bx
pop ds
iret
;timer interrupt
int8:
cmp dup_switch,1 ; see if should repeat
jne move_on
dec dup_count
jnz move_on
push ds
push di
push bx
push ax
mov bx,BIOS_SEG
mov ds,bx
mov bx,ds:[bios_tail]
mov di,bx
add bx,2 ; move ptr to next word
cmp bx,bios_end
jne full_check
mov bx,bios_start ; wrap around
full_check:
cmp bx,ds:[bios_head]
jne have_room
mov dup_switch,0 ; no more room
jmp reg_restore
have_room:
cli
mov ax,dup_char
mov [di],ax
mov ds:[bios_tail],bx ; stuff dup_char into kb buffer
sti
mov al,dup_delay2
mov dup_count,al ; set dup_count for high rate
reg_restore:
pop ax
pop bx
pop di
pop ds
move_on:
jmp dword ptr rom_int8 ; call timer interrupt
initialize:
assume ds:CSEG
xor ax,ax
mov es,ax
mov ax,es:[8*4] ; timer code offset
mov bx,es:[8*4+2] ; timer code segment
mov cx,es:[9*4] ; keyboard code offset
mov dx,es:[9*4+2] ; keyboard code segment
mov rom_int8,ax
mov rom_int8[2],bx
mov rom_int9,cx
mov rom_int9[2],dx
cli
lea ax,int8
mov es:[8*4],ax
mov es:[8*4+2],cs
lea ax,int9
mov es:[9*4],ax
mov es:[9*4+2],cs
sti
lea dx,initialize
int 27h
CSEG ends
end begin
------
Victor Greenberg
{allegra,decvax,ihnp4,tektronix,utai}!watmath!watnot!vgreenberg