dos_compilers/DeSmet C88 v24/BUF128.A

159 lines
3.4 KiB
Plaintext
Raw Normal View History

2024-06-30 23:24:37 +02:00
;
; buf128: a 128 character type-ahead buffer for the IBM-PC
;
; This program works by intercepting the calls to the BIOS
; interrupt routines at 9 for the keystroke interrupts and
; 16H for the program requests
; Everything is kept in CS.
;
; Caution: buf128 must be linked with the -A option, e.g.
; BIND B:BUF128 -A
cseg
public main_,key_int,request,buffer,head,tail
KEYINT: equ 24H ; int 9 vector offset
REQINT: equ 58H ; int 16H vector offset
B_HEAD: equ 1AH ; offset to BUFFER_HEAD
B_TAIL: equ 1CH ; offset to BUFFER_TAIL
KB_FLAG: equ 17H ; offset to KB_FLAG
main_: jmp init_code
;
buffer: dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
head: dw buffer
tail: dw buffer
;
; the keystroke interrupt routine. Interrcept the key interrupt, run
; it through the standard key input routine, and remove it from the buffer.
;
key_int:
cli
pushf ; simulate an interrupt
;
; long call to F000:E987
;
db 9AH
dw 0E987H
dw 0F000H
;
push bx
push es
mov bx,40H ; BIOS data segment
mov es,bx
mov bx, es:[B_HEAD] ; pointer to datum
cmp bx, es:[B_TAIL] ; test for character
je k_esbx
mov es:[B_TAIL], bx ; clear the buffer
mov bx, es:[bx]
push si
mov si, cs:tail
push si ; save tail value
add si,2 ; test for full
cmp si, offset buffer+256
jb k_over1
mov si, offset buffer
k_over1:
cmp si, cs:head
pop si
je k_siesbx ; jump if buffer full
mov cs:[si], bx ; store the character
add si,2
cmp si, offset buffer+256
jb k_over2
mov si, offset buffer
k_over2:
mov cs:tail, si
k_siesbx:
pop si
k_esbx:
pop es ; no character, return
pop bx
iret
;
; The request interrupt routine.
;
; simulate the BIOS routine
; ah = 0 read next char
; ah = 1 set Z flag on character status, ZF=1 if no char
; ZF=0 and AX = char if char ready
; ah = 2 shift status
request:
sti
or ah,ah
jz do_read
dec ah
jz do_stat
dec ah
jz do_shift
iret
do_read: ; return the next character
sti
nop
cli
mov ax,cs:head
cmp ax,cs:tail
je do_read ; loop until a character
push bx
mov bx,ax
mov ax, cs:[bx] ; ax gets the character
add bx,2
cmp bx, offset buffer+256
jb r_over
mov bx, offset buffer
r_over:
cmp bx, cs:tail
mov cs:head, bx ; new head
pop bx
iret
do_stat: ; return key status
cli
push bx
mov bx,cs:head
cmp bx,cs:tail
mov ax,cs:[bx]
pop bx
sti
lret 2 ; throw out the flags
do_shift:
push es
mov ax,40H ; BIOS data segment
mov es,ax
mov al, es:[KB_FLAG]
pop es
iret
init_code: cli ; turn off interrupts for now
mov ax,0
mov es,ax ; segment base for vectors
mov es:[KEYINT], offset key_int
mov es:[KEYINT+2], cs
mov es:[REQINT], offset request
mov es:[REQINT+2], cs
mov cs:head, offset buffer
mov cs:tail, offset buffer
sti
mov ds:byte[1], 27H ; change PCB terminate to resident
push ds
mov dx,0
push dx
mov dx, offset init_code+100H
lret ; long return to the int 27H
end