home *** CD-ROM | disk | FTP | other *** search
- ;
- ; --- Version 2.0 89-12-13 17:57 ---
- ;
- ; CTask - Keyboard handler module.
- ;
- ; Public Domain Software written by
- ; Thomas Wagner
- ; Patschkauer Weg 31
- ; D-1000 Berlin 33
- ; West Germany
- ;
- ; This module traps the keyboard interrupts to allow task switching
- ; on waiting for a character.
- ; To avoid problems with programs that access the keyboard buffer
- ; directly instead of going through INT 16, the logic has been changed
- ; in version 1.2. The keyboard characters are no longer placed into
- ; a pipe, instead the keyboard hardware interrupt just sets a flag
- ; to signal that there might be something in the buffer. The keyboard
- ; read routines wait on this flag if the original INT 16 status call
- ; indicates that no key is available.
- ;
- ; Note that there is a slight chance of this logic leading to busy
- ; waiting in the original INT 16. This could happen if the process
- ; is interrupted between the status check and the actual keyboard
- ; fetch, and the interrupting routine snatches away the keystroke.
- ; Since this is not very likely to occur, and would not be fatal
- ; anyway, it would be overkill to try to avoid this.
- ;
- ; If INT 16 is entered via CTask's t_read_key and t_wait_key,
- ; the stack is not switched.
- ;
- name tskkbd
- .model large,c
- ;
- public tsk_install_kbd
- public tsk_remove_kbd
- ;
- public t_read_key
- public t_wait_key
- public t_keyhit
- ;
- include tsk.mac
- ;
- ;
- extrn create_flag: far
- extrn delete_flag: far
- extrn set_flag: far
- extrn clear_flag: far
- extrn wait_flag_set: far
- ;
- extrn tsk_dgroup: word
- ;
- ;
- intseg segment at 0
- org 09h*4
- hwdoff dw ? ; keyboard hardware interrupt
- hwdseg dw ?
- org 16h*4
- kbdoff dw ? ; keyboard I/O interrupt
- kbdseg dw ?
- ;
- intseg ends
- ;
- ;----------------------------------------------------------------------------
- ;
- ; Variables
- ;
- .tsk_data
- ;
- IF TSK_NAMEPAR
- kbd_name db "KEYAVAIL",0
- ENDIF
- ;
- key_avail flag <>
- ;
- .tsk_edata
- .tsk_code
- ;
- extrn tsk_switch_stack: near
- ;
- ; Original Interrupt-Entries
- ;
- savhwd label dword ; original hardware int entry
- savhwdoff dw ?
- savhwdseg dw ?
- ;
- savkbd label dword ; original keyboard I/O entry
- savkbdoff dw ?
- savkbdseg dw ?
- ;
- ;---------------------------------------------------------------------------
- ;
- ; void tsk_install_kbd (void)
- ;
- ; Install keyboard handler
- ;
- tsk_install_kbd proc near uses ds
- ;
- mov ds,cs:tsk_dgroup
- ;
- IF TSK_NAMEPAR
- mov ax,offset kbd_name
- push ds
- push ax
- ENDIF
- mov ax,offset key_avail
- push ds
- push ax
- call create_flag
- IF TSK_NAMEPAR
- add sp,8
- ELSE
- add sp,4
- ENDIF
- ;
- ; Save old interrupt vectors
- ;
- push es
- xor ax,ax
- mov es,ax
- ;
- assume es:intseg
- ;
- mov ax,kbdoff
- mov savkbdoff,ax
- mov ax,kbdseg
- mov savkbdseg,ax
- ;
- mov ax,hwdoff
- mov savhwdoff,ax
- mov ax,hwdseg
- mov savhwdseg,ax
- ;
- ; Enter new Interrupt-Entries
- ;
- cli
- mov kbdoff,offset kbdentry
- mov kbdseg,cs
- mov hwdoff,offset hwdentry
- mov hwdseg,cs
- sti
- pop es
- ;
- ret
- ;
- assume es:nothing
- ;
- tsk_install_kbd endp
- ;
- ;
- ; void tsk_remove_kbd (void)
- ;
- ; Un-install keyboard handler
- ;
- tsk_remove_kbd proc near uses ds
- ;
- mov ds,cs:tsk_dgroup
- ;
- mov ax,offset key_avail
- push ds
- push ax
- call delete_flag
- add sp,4
- ;
- push es
- xor ax,ax
- mov es,ax
- ;
- assume es:intseg
- ;
- ; Restore interrupt entries
- ;
- cli
- ;
- mov ax,savkbdoff
- mov kbdoff,ax
- mov ax,savkbdseg
- mov kbdseg,ax
- ;
- mov ax,savhwdoff
- mov hwdoff,ax
- mov ax,savhwdseg
- mov hwdseg,ax
- ;
- sti
- ;
- pop es
- ret
- ;
- assume es:nothing
- ;
- tsk_remove_kbd endp
- ;
- ;
- ;---------------------------------------------------------------------------
- ;
- ; int t_read_key (void)
- ;
- ; Waits for key from keyboard. Returns char in lower byte,
- ; Scan-Code in upper byte.
- ;
- t_read_key proc
- ;
- mov ax,4112h
- int 16h
- ret
- ;
- t_read_key endp
- ;
- ;
- ; int t_wait_key (dword timeout)
- ;
- ; Waits for key from keyboard. Returns char in lower byte,
- ; Scan-Code in upper byte.
- ;
- t_wait_key proc tout: dword
- ;
- mov cx,word ptr (tout+2)
- mov dx,word ptr (tout)
- mov ax,4012h
- int 16h
- ret
- ;
- t_wait_key endp
- ;
- ;
- ; int t_keyhit (void)
- ;
- ; Checks if char is available. Returns -1 if not, else the
- ; character value. The character remains in the buffer.
- ;
- t_keyhit proc
- ;
- mov ah,1
- int 16h
- jnz t_kh_ok
- mov ax,-1
- t_kh_ok:
- ret
- ;
- t_keyhit endp
- ;
- ;---------------------------------------------------------------------------
- ;
- ; INT 9 - Keyboard hardware interrupt
- ;
- hwdentry proc far
- ;
- call tsk_switch_stack
- pushf
- cli
- call cs:savhwd ; process key
- ;
- mov ax,offset key_avail
- push ds
- push ax
- call set_flag
- add sp,4
- iret
- ;
- hwdentry endp
- ;
- ;---------------------------------------------------------------------------
- ;
- ; INT 16 - Keyboard I/O
- ;
- kbdentry proc far
- ;
- pushf
- or ah,ah
- jz kbd_read
- cmp ax,4012h
- jz kbd_read
- cmp ax,4112h
- jz kbd_read
- popf
- jmp cs:savkbd ; pass on functions != 0
- ;
- kbd_read:
- popf
- call tsk_switch_stack
- ;
- kbr_loop:
- mov ax,offset key_avail
- push ds
- push ax
- call clear_flag
- add sp,4
- mov ah,1
- pushf
- cli
- call cs:savkbd
- jnz kbr_get_key
- mov cx,save_cx[bp]
- mov dx,save_dx[bp]
- cmp byte ptr save_ax+1[bp],40h
- je tout_x
- xor cx,cx
- mov dx,cx
- tout_x:
- push cx
- push dx
- mov ax,offset key_avail
- push ds
- push ax
- call wait_flag_set
- add sp,8
- or ax,ax
- jz kbr_loop
- mov save_ax[bp],-1
- jmp short kbr_retn
- ;
- kbr_get_key:
- xor ah,ah
- pushf
- cli
- call cs:savkbd
- mov save_ax[bp],ax
- kbr_retn:
- iret
- ;
- kbdentry endp
- ;
- .tsk_ecode
- end
-
-