nelson@sun.soe.clarkson.edu (Russ Nelson) (05/05/88)
This is a cheap 'n dirty keyboard buffer expander. It works by installing itself as the standard keyboard buffer in the bios. It can only do this if it is in the same segment as the bios, so you are well advised to install it as the first device driver. While it's installing itself into the bios, it also installs a device driver called KBUFFER. Anything written to KBUFFER ends up in the keyboard buffer. Written by Donald "Dj" Delorie: UUCP: uunet!unh!dgdhm!dj Internet: Delorie_D%DUR09.CEO.DG.COM@adam.DG.COM title buf160 ; History:63,1 ; 09-21-87 09:31:17 fix buf in force(). ; 09-16-87 16:07:46 added publics ; 09-16-87 16:01:41 comment out buffer tranfer code with equate ; DJ Delorie ; ; masm buf160; ; link buf160; ; exe2bin buf160.exe buf160.dvd ; ; DEVICE=buf160.dvd ( in config.sys) ; transfer equ 0 dqq struc ofs dw ? seg dw ? dqq ends wqq struc w dw ? wqq ends bqq struc b db ? bqq ends rqq struc len db ? unit db ? code db ? status dw ? q1 dd ? q2 dd ? mdesc db ? trans dd ? count dw ? rqq ends cseg segment byte assume cs:cseg,ds:cseg,es:cseg,ss:cseg org 0 success equ 0100h error equ 8100h busy equ 0300h public header header label near dd -1 dw 8000h dw strat dw intr db 'KBUFFER ' public req req dd ? dw 0 buffer_get equ 1ah buffer_put equ 1ch buffer_start equ 80h buffer_end equ 82h public queue_start,queue_end queue_start label word dw 160 dup (0) queue_end label word dw 0 public strat strat proc far mov cs:[req].ofs,bx mov cs:[req].seg,es ret strat endp public intr intr proc far push ds push es push ax push bx push cx push dx push di push si mov ax,cs mov ds,ax les bx,cs:req mov si,offset cmd_table mov cl,es:[bx].code mov ch,0 shl cx,1 add si,cx call [si].w les bx,cs:req mov es:[bx].status,ax pop si pop di pop dx pop cx pop bx pop ax pop es pop ds ret public cmd_table cmd_table: dw cmd_init dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_output dw cmd_output dw cmd_output_status dw cmd_none dw cmd_none public cmd_none cmd_none proc near mov ax,success ret cmd_none endp public cmd_output cmd_output proc near mov ax,40h mov ds,ax mov cx,es:[bx].count les bx,es:[bx].trans output_loop: mov al,es:[bx] inc bx call force jc output_error loop output_loop mov ax,success ret output_error: mov ax,error ret cmd_output endp public force force proc near cli mov di,ds:[buffer_put] call buf_wrap cmp di,ds:[buffer_get] ;is the buffer full? je buffer_full xchg ds:[buffer_put],di ;save the old, get the new. xor ah,ah mov ds:[di],ax clc sti ret buffer_full: stc sti ret force endp public buf_wrap buf_wrap proc near inc di inc di cmp di,ds:[buffer_end] jne no_wrap mov di,ds:[buffer_start] no_wrap: ret buf_wrap endp public cmd_output_status cmd_output_status proc near mov ax,40h mov ds,ax mov di,ds:[buffer_put] call buf_wrap cmp di,ds:[buffer_get] je buffer_busy mov ax,success ret buffer_busy: mov ax,busy ret cmd_output_status endp public last_code last_code label near public cmd_init cmd_init proc near mov ax,cs mov ds,ax cmp ax,0ff8h ja init_error mov ah,9 mov dx,offset banner int 21h mov cx,40h mov ds,cx if transfer public transfer_buffer transfer_buffer: mov si,ds:[buffer_get] mov di,ds:[buffer_put] mov bx,0 transfer_loop: cmp si,di je transfer_done mov ax,[si] mov cs:queue_start[bx],ax inc si inc si inc bx inc bx cmp si,ds:[buffer_end] jne transfer_loop mov si,ds:[buffer_start] jmp transfer_loop public transfer_done transfer_done: endif mov ax,cs sub ax,cx shl ax,1 shl ax,1 shl ax,1 shl ax,1 mov cx,ax add cx,offset queue_start mov ds:[buffer_start],cx mov ds:[buffer_get],cx add cx,bx mov ds:[buffer_put],cx add ax,offset queue_end mov ds:[buffer_end],ax les bx,cs:[req] mov es:[bx].trans.ofs,offset last_code mov es:[bx].trans.seg,cs mov ax,success ret public init_error init_error: mov dx,offset msg_err mov ah,9 int 21h if 0 ;not sure if it works. mov es:[bx].trans.ofs,0 else mov es:[bx].trans.ofs,offset last_code endif mov es:[bx].trans.seg,cs mov ax,success ret cmd_init endp public banner, msg_err banner db 'Buf160 has been loaded.',13,10,'$' msg_err db 'Buf160 too far from BIOS data area.',13,10,'$' intr endp cseg ends end begin 644 buf160.dvd M_____P"`6@%E`4M"549&15(@````````````````````````````````````B M````````````````````````````````````````````````````````````` M````````````````````````````````````````````````````````````` M````````````````````````````````````````````````````````````` M````````````````````````````````````````````````````````````` M````````````````````````````````````````````````````````````` M````````````````````````````````````````````````````````````` M`````````````````````````````````````````"Z)'A(`+HP&%`#+'@90Z M4U%25U:,R([8+L0>$@"^EP$FBD\"M0#1X0/Q_Q0NQ!X2`":)1P->7UI96U@') M'\L8`K$!L0&Q`;$!L0&Q`;$!M0&U`?X!L0&Q`;@``<.X0`".V":+3Q(FQ%\.T M)HH'0^@,`'(&XO6X``'#N`"!P_J+/AP`Z!0`.SX:`'0+ASX<`#+DB07X^\/Y6 M^\-'1SL^@@!U!(L^@`##N$``CMB+/AP`Z.?_.SX:`'0$N``!P[@``\.,R([8< M/?@/=T6T";I[`LTAN4``CMF,R"O!T>#1X-'@T>"+R('!&`")#H``B0X:``/+) MB0X<``58`:."`"[$'A(`)L='#A@")HQ/$+@``<.ZE0*T"<TA)L='#A@")HQ/: M$+@``<-"=68Q-C`@:&%S(&)E96X@;&]A9&5D+@T*)$)U9C$V,"!T;V\@9F%R' 8(&9R;VT@0DE/4R!D871A(&%R96$N#0HD] `` end