;--------------------- KEYBOARD BUFFER EXTENDER -------- EN#1.0SRW02R ---[] ; By - Titas Raha (27/11/93) System Research Work # 2 (Resident program) : ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ : ; Extends the keyboard buffer length by passing the additional keys through : ; a generated que. Must be converted into a .COM file : ;--------------------------------------------------------------------------[] MAXKEYS EQU 128 ; Added Keyboard buffer length BIOSSEG EQU 40h ; Dada segment of the BIOS GETKBD EQU 3509h ; Get INT Vector Keyboard 9 SETKBD EQU 2509h ; Set INT Vector Keyboard 9 GETTIM EQU 351Ch ; Get INT Vector Timer 1C SETTIM EQU 251Ch ; Set INT Vector Timer 1C GETBRK EQU 351Bh ; Get INT Vector Break 1B SETBRK EQU 251Bh ; Set INT Vector Break 1B KBD_CTL EQU 61h ; Keyboard control port address EOI EQU 20h ; End of int No. SPKCYOFF EQU 28h ; Iterations at off position SPKCYON EQU 68h ; Iterations at on position SPKCYCLES EQU 80h ; No. of speaker cycles code SEGMENT ASSUME cs:code,ds:code ORG 1Ah buffhead LABEL WORD ; Keyboard buffer head ORG 1Ch bufftail LABEL WORD ; Keyboard buffer tail ORG 80h buffstart LABEL WORD ; Location of the Keyboard buffer ORG 82h buffend LABEL WORD ; Pointer to the end of buffer ORG 100h ; In anticipation of .COM file RESIDENT_LEN EQU ((OFFSET RB - OFFSET RT+100h) SHR 4)+1 ; Length of the resident program RT LABEL WORD ; Top of the resident program start: jmp newloc ; Jump away from ; the resident data area org_kbd dw 0,0 ; Original Keyboard handler INT 9 org_tim dw 0,0 ; Original Timer INT 1C handler org_brk dw 0,0 ; Original Break INT 1B handler que_head dw QUE_START ; Initial Head pointer of the que que_tail dw QUE_START ; Initial Tail pointer of the que QUE_START EQU OFFSET qs ; Start of the que QUE_END EQU OFFSET qe ; End of the que qs LABEL WORD ; Que's physical start address que dw MAXKEYS DUP('U'*256+'Q') ; Que for storing additional keys qe LABEL WORD ; Que's physical end address newbrk PROC FAR ; New break procedure ;Clears the que with every invocation of the break interrupt mov cs:que_head,QUE_START ; Make que head equal to mov cs:que_tail,QUE_START ; que tail. jmp dword ptr cs:[org_brk] ; Original Break interrupt newbrk ENDP newkbd PROC FAR ; The new rerouted keyboard INT 9 ; Gets the extra keys from the keyboard buffer and saves it in a que. push ax ; Save registers to use push ds pushf ; Will be restored by the handler mov ax,BIOSSEG mov ds,ax ; Set to BIOS's data segment mov ax,bufftail ; Save the old tail pointer value call dword ptr cs:[org_kbd] ; Call the original handler push bx ; Save registers to use push si mov bx,ax ; Save tail pointer value to bx mov ax,bufftail ; Get the new buffer position mov si,ax ; Save in SI inc ax ; Go to next buffer position inc ax ; Inc 2 since it is of word length cmp ax,buffend ; Is it end of the buffer ? jne bptrok ; No, jump mov ax,buffstart ; Yes, set to start of buffer bptrok: cmp ax,buffhead ; Tail touched the head ? je branch ; If yes, jump cmp si,bx ; Is the buffer changed by handler je kbdone ; No, nothing to do, leave mov ax,cs:que_tail ; Get tail ptr of the extra buffer cmp ax,cs:que_head ; Is it equal to the head ? je kbdone ; Yes, X buffer empty no probs attach: mov si,[bx] ; Get the char that just came in mov bufftail,bx ; as if no change in the buffer mov ax,cs ; set DS to the programs DATA mov ds,ax ; segment. mov ax,que_tail ; Get the X buffer tail ptr mov bx,ax ; Save it inc ax ; Goto next X buffer position inc ax cmp ax,QUE_END ; Is it at the end of the que ? jne qptrok ; No, jump mov ax,QUE_START ; Yes, set it to start of the que qptrok: cmp ax,que_head ; Que head touched the tail ? je beep ; Yes, buffer full beep mov que_tail,ax ; No, advance the X buffer tail mov [bx],si ; Save the char in X buffer. kbdone: pop si ; Restore the stack and registers pop bx pop ds pop ax iret ; Interrupt return beep: push cx ; Save CX mov al,EOI ; End of interrupt command out 20h,al ; Send command to INT control port mov bx,SPKCYCLES ; No of cycle in al,KBD_CTL ; Get control information push ax ; Save information atoffstate: and al,0FCh ; Turn off timer gate and speaker out KBD_CTL,al ; Output to control mov cx,SPKCYOFF ; No. of empty iterations itr1: loop itr1 ; Speaker off or al,2 ; Turn on speaker bit out KBD_CTL,al ; Output to control mov cx,SPKCYON ; Again set up count itr2: loop itr2 ; With speaker at on position dec bx ; Total time count jnz atoffstate ; Do another cycle pop ax ; Recover control out KBD_CTL,al ; output the control pop cx ; Recover CX jmp kbdone branch: cmp si,buffstart ; Current tail ptr = buffer start? jne posfound ; No jump mov si,buffend ; Yes, make it at end posfound: dec si ; Get the previous position dec si mov bx,si ; save it in bx jmp attach ; jump to the mainstreem newkbd ENDP newtim PROC FAR ; New rerouted INT 1C ; Tryies to restore the keys from the que to the keyboard buffer. push ax ; Save registers to use push si push dx push ds mov ax,cs ; Make DATA segment as CODE mov ds,ax mov si,que_head ; Get the que head ptr cmp si,que_tail ; Is it equal to the tail je timdone ; Yes, no keys present, jump mov ax,[si] ; Get the character from the que mov dx,BIOSSEG ; Set DS to BIOS data mov ds,dx mov si,bufftail ; Get the kyb buffer tail mov [si],ax ; Store the char to the kyb buffer mov ax,buffend ; get the end of the buffer inc si ; Get the next of the tail ptr inc si cmp si,ax ; Is it equal to the end of buffer jne atbend1 ; Jump if not mov si,buffstart ; Yes, Set to the start atbend1: mov dx,si ; save next of the tail ptr cmp si,buffhead ; Is it equal to the head ? je timdone ; Yes, Buffer full quit inc si ; No, get next to next of tail inc si ; pointer cmp si,ax ; Is it equal to the end of buffer jne atbend2 ; Jump if not mov si,buffstart ; Yes, Set to the start atbend2: cmp si,buffhead ; Is it equal to the head ? je timdone ; Yes, space left for 1 char, quit mov bufftail,dx ; Increment the tail pointer ; ( character already saved ) mov ax,cs ; Again set DS as CS mov ds,ax mov ax,que_head ; Get the que head pointer inc ax ; get the next position inc ax cmp ax,QUE_END ; Is it equal to the end ? jne atbend3 ; No, jump mov ax,QUE_START ; Yes, Set to start of the que atbend3: mov que_head,ax ; Set the new que head position timdone: pop ds ; restore the registers pop dx pop si pop ax jmp dword ptr cs:[org_tim] ; Call the old timer INT 1C newtim ENDP RB LABEL WORD ; End of the resident program newloc: mov ah,9 ; Display line mov dx,OFFSET heading ; Get Heading position int 21h ; Dos function does it mov ax,GETKBD ; Get the Keyboard interrupt int 21h ; Dos function 21h does it mov ax,es ; Get the segment of Kyb handler cmp ax,0D000h ; Is it above 0D000h ? ja kybnotset ; Yes, Keyboard not re-routed mov ah,9 ; Dos function no. to print a line mov dx,OFFSET msgfail ; Get the failure message to print int 21h ; Call Dos int 20h ; Terminate as normal program kybnotset: mov org_kbd,bx ; Save the value OFFSET mov org_kbd+2,es ; Save the value SEGMENT mov ax,GETTIM ; Get the Timer interrupt in ES:BX int 21h ; Function to get it mov org_tim,bx ; Save the OFFSET mov org_tim+2,es ; Save the SEGMENT mov ax,GETBRK ; Get the Break interrupt int 21h mov org_brk,bx ; Save offset mov org_brk+2,es ; Save segment mov ax,SETKBD ; Set the new keyboard interrupt mov dx,OFFSET newkbd ; OFFSET of the keyboard routine int 21h ; Dos function 21h does it mov ax,SETTIM ; Set the new timer interrupt mov dx,OFFSET newtim ; OFFSET of it int 21h ; Function to set it mov ax,SETBRK ; Set new break interrupt handler mov dx,OFFSET newbrk ; Address of it int 21h mov ah,9 ; Dos. function No. to print mov dx,OFFSET msgsucc ; Get the success message int 21h mov ax,3100h ; Get ready to be resident mov dx,RESIDENT_LEN ; No. of para to be resident int 21h ; Initiate residency msgfail db 'Keyboard interrupt vector re-routed',13,10 db 'Cannot load the resident part',13,10 db 'Terminating as a normal program.',13,10 db 10,'$' heading db 13,10 db 10 db '<<<<<<-- KEYBOARD BUFFER EXTENDER -->>>>>>',9,9,9,'EN#1.0SRW02R',13,10 db 10 db 'A self taught product from :',13,10 db 'Titas Raha,',13,10 db '17, Uttar Palli, Sodepur',13,10 db 'Dist. 24 Parganas (N)',13,10 db 'WEST BENGAL - 743178',13,10 db '--------------------',13,10 db 10 db 'This is a resident program which handles the keys typed in when the',13,10 db 'keyboard buffer gets filled by storing those keys in another place,',13,10 db 'and transfering it back as soon as the keyboard buffer is in a',13,10 db 'position to accept it. It extends the buffer from normally 15 Keys',13,10 db 'to 15+127=142 Keys. Reroutes the 1C,1B and 9 interrupt vectors.',13,10 db 10,'$' msgsucc db 'Resident portion loaded.',13,10 db 10,'$' code ends end start