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