home *** CD-ROM | disk | FTP | other *** search
- ;
- ; 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