[comp.binaries.ibm.pc] buf160.sys

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