home *** CD-ROM | disk | FTP | other *** search
- TITLE QUICKEYS
-
- COMMENT | This memory resident routine augments the typematic key repetition
- feature of the IBM PC, XT, and AT. Upon each keystroke interrupt,
- QUICKEYS resets itself, then calls the standard keystroke routines for
- processing. Upon return to QUICKEYS, if a new keystroke has been
- stored in the ROM BIOS keyboard buffer, it is memorized and a count-
- down is begun. If not reset by release of the key, the key will be
- repeated in the buffer after a delay of DUP_DELAY1 timer ticks and
- then again every DUP_DELAY2 ticks thereafter, until the key is
- released.
-
- Timer delay settings of 9 and 2 for DUP_DELAY1 and DUP_DELAY2 are
- effectively equivalent to the standard IBM PC typematic settings for
- the delay before the first repeat of a held-down key and for the delay
- between subsequent repetions of it while the key remains down.
-
- Press the (Alt) and left (Shift) keys together, to empty the buffer
- if too many keystrokes have been entered. Handy way to get around
- spread sheet is to fill buffer with cursor keys and then zap excess
- with (ALT)(Shift) when arrive where wanted to go.
-
- Copyright 1986 - Ziff-Davis Publishing Company
- |
- BIOS_SEG SEGMENT AT 40H ;ESTABLISH BIOS SEG
- BIOS_SEG ENDS ;ADDRESS.
-
- CSEG SEGMENT
- ASSUME CS:CSEG ;WHEN RESIDENT, NOT SURE OF DS OR ES.
- ORG 100H ;STD CODE OFFSET FOR COM FILES.
- BEGIN: JMP INITIALIZE ;GO SET VECTORS, WHEN LOADED BY DOS.
- ROM_INT8 DW ?,? ;ORIGINAL TIMER VECTOR ADDRESS
- ROM_INT9 DW ?,? ;ORIGINAL KEYSTROKE VECTOR ADDR
- DUP_CHAR DW ? ;CHAR TO BE REPEATED NEXT.
- DUP_SWTCH DB 0 ;1, IF CHAR IS TO BE REPEATED
- DUP_CNT DB 0 ;TIMER TICKS LEFT B/4 REPEAT KEY
- DUP_DELAY1 DB 7 ;# TICKS B/4 1ST REPEAT OF A KEY.
- DUP_DELAY2 DB 1 ;# TICKS DELAY BETWEEN REPEATS.
- ALT_SHFT EQU 0AH ;BITS SET WHEN IN ALT-LEFT_SHIFT STATE.
- BIOS_KBFLAGS EQU 17H ;BIOS OFFSET TO KEYBOARD SHIFT FLAGS.
- BIOS_HEAD EQU 1AH ;BIOS BUFFER ADDRESS OF NEXT OUTPUT KEY.
- BIOS_TAIL EQU 1CH ;BIOS BUFFER ADDRESS FOR NEXT INPUT KEY.
- BIOS_END EQU 3EH ;ENDING LOCATION OF BIOS KEYBOARD BUFFER.
- BIOS_START EQU 1EH ;START LOCATION OF BIOS KEYBOARD BUFFER.
- ;*****************************************************************************
- INT9: ;KEYSTROKE INTERRUPT PROCESSING
- ;*****************************************************************************
- PUSH DS ;SAVE CALLER'S DATA SEGMENT ADDRESS
- PUSH BX ;SAVE, SO CAN USE TO STORE CURRENT TAIL.
- MOV BX,BIOS_SEG ;SET UP ADDRESSING TO BIOS DATA SEGMENT.
- MOV DS,BX
- ASSUME DS:BIOS_SEG
- MOV DUP_SWTCH,0 ;TURN OFF AUTOMATIC KEY REPETITIONS.
- MOV BX,DS:[BIOS_TAIL] ;SAVE CURRENT KEYBOARD TAIL LOCATION.
- PUSHF ;CALL ROM BIOS KEYSTROKE PROCESSING
- CALL DWORD PTR ROM_INT9 ; INTERRUPT, AND RETURN HERE WHEN DONE.
- CMP BX,DS:[BIOS_TAIL] ;IF NEW CHARACTER ENTERED, TAIL MOVED.
- JNE WAS_NEW_KEY ;IF NOT MOVED, SET DUP_CHAR SO WILL NOT
- MOV DUP_CHAR,-1 ;MATCH ANY KEY PUSHED NEXT TIME.
- TEST BYTE PTR DS:[BIOS_KBFLAGS],ALT_SHFT ;SEE IF WAS (ALT)(SHIFT).
- JZ KEY_RETURN ;IF SO, EMPTY THE BIOS BUFFER BY MOVING
- MOV DS:[BIOS_HEAD],BX ;THE HEAD POINTER TO THE TAIL.
- JMP KEY_RETURN ; ALL DONE FOR NOW.
- WAS_NEW_KEY: ;IF TAIL HAS MOVED, HAVE NEW KEY, SO
- MOV BX,[BX] ;GET CHARACTER NOW STORED IN OLD TAIL.
- CMP BX,DUP_CHAR ;COMPARE WITH PRIOR REPEAT CHARACTER AND
- MOV DUP_CHAR,BX ;STORE AS NEW REPEAT KEY. ASSUME OLD AND
- MOV BL,DUP_DELAY1 ;NEW CHARS DIFFERENT, SO WILL START SLOW.
- JNE SWITCH_ON ;OTHERWISE, THIS INTERRUPT WAS FROM STD
- MOV BL,DUP_DELAY2 ;TYPEMATIC ACTION, SO STAY AT HI RATE.
- SWITCH_ON:
- MOV DUP_CNT,BL ;SET REPETITION RATE FOR THE KEY AND
- MOV DUP_SWTCH,1 ;TURN TICK COUNTER BACK ON.
- KEY_RETURN:
- POP BX ;ALL DONE. KEY HAS BEEN PROCESSED BY
- POP DS ;ROM BIOS; REPEAT FLAG NOW RESET AND
- IRET ;TICK COUNT READY. RETURN TO USER.
- ;*****************************************************************************
- INT8: ;TIMER INTERRUPT PROCESSING
- ;*****************************************************************************
-
- CMP DUP_SWTCH,1 ;MOVE ON TO STANDARD TIMER PROCESSING, IF
- JNE MOVE_ON ;AUTOMATIC REPEAT FLAG IS NOT ON OR THE
- DEC DUP_CNT ;TIMER TICK COUNT IS NOT ZERO YET.
- JNZ MOVE_ON ;
- PUSH DS ;TIME TO REPEAT THE DUP_CHAR KEY, SO
- PUSH DI ; (1) SAVE ES,DI,BX,AND AX, SO CAN USE
- PUSH BX ; TO DO THE STORING.
- PUSH AX ;
- MOV BX,BIOS_SEG ; (2) ESTABLISH BIOS DATA SEGMENT
- MOV DS,BX ; ADDRESSABILITY.
- MOV BX,DS:[BIOS_TAIL] ; (3) GET CURRENT TAIL LOCATION INTO BX.
- MOV DI,BX ; (4) SAVE POINTER, SO CAN FILL, IF ROOM.
- ADD BX,2 ; (5) MOVE TAIL POINTER TO NEXT WORD IN
- CMP BX,BIOS_END ; ROM BUFFER.
- JNE FULL_CHECK ; (6) IF NEXT LOCATION IS PAST END OF
- MOV BX,BIOS_START ; BUFFER, WRAP AROUND TO START LOC.
- FULL_CHECK: ;
- CMP BX,DS:[BIOS_HEAD] ; (7) IF NEW TAIL IS SAME AS HEAD, THERE
- JNE HAVE_ROOM ; ISN'T ROOM FOR ANOTHER CHAR,
- MOV DUP_SWTCH,0 ; SO STOP REPEATING IT.
- JMP REG_RESTORE
- HAVE_ROOM:
- CLI
- MOV AX,DUP_CHAR ; (8) IF ROOM LEFT, MOVE THE REPEAT KEY
- MOV [DI],AX ; INTO THE BIOS KEYBOARD BUFFER AND
- MOV DS:[BIOS_TAIL],BX ; (9) UPDATE THE KEYBOARD TAIL POINTER.
- STI
- MOV AL,DUP_DELAY2 ; (10) FINALLY, SET TICK COUNTER FOR THE
- MOV DUP_CNT,AL ; THE HIGHER BETWEEN-KEY REPEAT RATE.
- REG_RESTORE:
- POP AX ; (11) RESTORE REGISTERS WE USED.
- POP BX
- POP DI
- POP DS
- MOVE_ON:
- JMP DWORD PTR ROM_INT8 ;GO DO STANDARD TIMER INTERRUPT WORK.
- ;*****************************************************************************
- INITIALIZE: ;INITIALIZE INTERRUPT VECTORS 8 AND 9.
- ;*****************************************************************************
- ASSUME DS:CSEG
- XOR AX,AX
- MOV ES,AX ;SET ES TO ABSOLUTE 0 (START OF VECTORS).
- MOV AX,ES:[8*4] ; AX=OFFSET ADDRESS TO CURRENT TIMER CODE.
- MOV BX,ES:[8*4+2] ; BX=SEGMENT ADDRESS OF CURRENT TIMER CODE
- MOV CX,ES:[9*4] ; CX=OFFSET ADDRESS TO ROM KEYSTROKE CODE.
- MOV DX,ES:[9*4+2] ; DX=SEGMENT ADDRESS OF ROM KEYSTROKE CODE
- MOV ROM_INT8,AX
- MOV ROM_INT8[2],BX ;SAVE CURRENT ADDRESSES FOR LATER USE.
- MOV ROM_INT9,CX
- MOV ROM_INT9[2],DX
- CLI
- LEA AX,INT8 ;AX=OFFSET TO OUR TIMER CODE.
- MOV ES:[8*4],AX ;RESET TIMER VECTOR TO POINT TO OUR
- MOV ES:[8*4+2],CS ;OFFSET AND CODE SEGMENT.
- LEA AX,INT9 ;AX=OFFSET TO OUR KEYSTROKE CODE.
- MOV ES:[9*4],AX ;RESET KEYSTROKE VECTOR TO POINT TO
- MOV ES:[9*4+2],CS ;OUR OFFSET AND CODE SEGMENT.
- STI
- LEA DX,INITIALIZE ;POINT TO END OF CODE WE NEED TO KEEP
- INT 27H ;AND TERMINATE SETUP OPERATION.
- CSEG ENDS
- END BEGIN