home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
assemblr
/
03
/
quickeys.asm
< prev
next >
Wrap
Assembly Source File
|
1985-12-11
|
9KB
|
144 lines
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