dos_compilers/DeSmet C88 v24/BUF128.A
2024-06-30 14:24:37 -07:00

159 lines
3.4 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; 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