📄 cdevio.a86
字号:
title 'F_DOS Character device I/O'
; File : $CDEVIO.A86$
;
; Description :
;
; Original Author : DIGITAL RESEARCH
;
; Last Edited By : $CALDERA$
;
;-----------------------------------------------------------------------;
; Copyright Work of Caldera, Inc. All Rights Reserved.
;
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
; CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
; $Log: $
; CDEVIO.A86 1.18 94/12/21 11:16:29
; Changed dev_dup to refuse from duplicating remote devices rather
; than refuse from duplicating FCBs
; Made open_dev return IFN rather than XFN for FCB opens
; Made open_dev put the current time/date into DHNDL_TIME/DHNDL_DATE
; CDEVIO.A86 1.16 94/10/07 09:00:18
; Added patch 004 as source fix. Changed request header length for character
; device to 16h. Used RH4_CDEV_LEN instead of RH4_LEN.
; CDEVIO.A86 1.15 93/12/10 00:09:17
; Move non-inherited bit to correct place in file handle
; CDEVIO.A86 1.14 93/11/26 16:17:14
; Update char_error so ES:SI -> device driver header itself;
; ENDLOG
eject ! include i:psp.def
eject ! include i:modfunc.def
eject ! include i:fdos.equ
eject ! include i:mserror.equ
eject ! include i:doshndl.def
eject ! include i:driver.equ
eject ! include rh.equ
BDOS_DATA dseg
extrn fdos_buf:byte ; caveat: in PCMODE data segment
extrn fdos_pb:word
extrn fdos_ret:word
;
; Critical Error responses from the default INT 24 handler and
; the DO_INT24 routine.
;
ERR_IGNORE equ 0 ; Ignore Error
ERR_RETRY equ 1 ; Retry the Operation
ERR_ABORT equ 2 ; Terminate the Process
ERR_FAIL equ 3 ; Fail Function
BDOS_CODE cseg
public open_dev
public close_dev
public dup_dev
public read_dev
public write_dev
public first_dev
public ioc6_dev
public ioc7_dev
extrn cooked_write:near ; write to cooked console
extrn read_line:near ; read edited line
extrn break_check:near ; look for CTRL C
extrn char_error:near ; generate Int 24
extrn current_dsk2al:near ; get default drive in AL
extrn device_driver:near
extrn alloc_dhndl:near ; find free DHNDL_ structure
extrn alloc_xfn:near
extrn les_di_dmaptr:near
extrn release_handle:near
extrn get_xftptr:near
extrn timestamp_dhndl:near
; Character device functions
; ==========================
open_dev:
;--------
; Entry: ES:BX -> character device header
; Note: We own the MXdisk here, fdos_pb -> parameter data
push es ! push bx ; save device driver address
call alloc_xfn ; DI = XFN
push di ; save XFN
call alloc_dhndl ; ES:BX -> DHNDL, AX = IFN
pop dx ; DX = XFN
xchg ax,si ; SI = IFN
xor ax,ax
lea di,DHNDL_DATRB[bx] ; point at start of area to fill
mov cx,DHNDL_UID-DHNDL_DATRB
rep stosb
mov es:DHNDL_SHARE[bx],ax ; also zap share word
pop es:DHNDL_DEVOFF[bx]
pop es:DHNDL_DEVSEG[bx] ; save device driver address
push si ! push dx ; save IFN/XFN
mov es:DHNDL_COUNT[bx],1
push ds
mov ax,fdos_pb+6 ; AX = open mode
mov cx,DHAT_DEV+DHAT_CLEAN+DHAT_TIMEOK
lds si,es:DHNDL_DEVPTR[bx] ; DS:SI -> device driver
or cl,ds:byte ptr DH_ATTRIB[si]
; get attrib from device driver
test al,DHM_LOCAL ; is it private ?
jz open_dev10
and al,not DHM_LOCAL ; clear inherit bit
or ch,DHAT_LOCAL/256 ; rememmber it's local
open_dev10:
mov es:DHNDL_MODE[bx],ax
mov es:DHNDL_WATTR[bx],cx
lea si,DH_NAME[si] ; copy the device name
lea di,DHNDL_NAME[bx] ; from the device header
mov cx,8/WORD
rep movsw
mov al,' '
mov cl,3 ; space the file extension
rep stosb
pop ds
pop dx ! pop ax ; AX = IFN, DX = XFN
push es
call get_xftptr ; ES:DI -> PSP_XFTPTR for current_psp
jc open_dev20 ; no PSP, skip updating XFN
add di,dx ; ES:DI -> entry in PSP
stosb ; update entry in PSP
xchg ax,dx
open_dev20:
pop es
mov fdos_ret,ax ; save XFN (IFN for FCB open) to return
call timestamp_dhndl
or es:DHNDL_ATTR[bx],DHAT_READY
; jmp open_dup_dev
open_dup_dev:
;------------
; On Entry:
; ES:BX = DHNDL_
; On Exit:
; None
;
mov al,CMD_DEVICE_OPEN
; jmp open_close_dev ; call device open routine
open_close_dev:
;--------------
; entry: ES:BX = DHNDL_
; AL = cmd_type (CMD_DEVICE_OPEN/CMD_DEVICE_CLOSE)
;
push ds ! push es
push bx ! push si
lds si,es:DHNDL_DEVPTR[bx] ; DS:SI -> device driver
test ds:DH_ATTRIB[si],DA_REMOVE
jz ocdev1 ; does the device support OPEN/CLOSE/RM
sub sp,RH13_LEN-2*word ; make space on stack for RH_
push ax ; RH_CMD = AL
mov ax,RH13_LEN
push ax ; RH_LEN = RH13_LEN
push ss ! pop es
mov bx,sp ; ES:BX -> RH_
call device_driver ; call the device driver
add sp,RH13_LEN ; recover stack space
ocdev1:
pop si ! pop bx
pop es ! pop ds
ret
dup_dev:
;-------
; On Entry:
; ES:BX -> DHNDL_
; On Exit:
; None
; AX trashed
;
mov ax,es:DHNDL_WATTR[bx]
test al,DHAT_DEV
jz dup_dev10 ; skip if disk file
test ax,DHAT_REMOTE ; or remote
jz open_dup_dev
dup_dev10:
ret
close_dev: ; close character device handle
;---------
; entry: FDOS_PB+2 = user file handle
; ES:BX = file handle
; NOTE: This is called with the MXdisk owned
mov al,CMD_DEVICE_CLOSE
call open_close_dev ; call device close routine
call release_handle ; release the XFN
dec es:DHNDL_COUNT[bx] ; one less XFN refers to this IFN
ret
write_dev: ; write to character device handle
;---------
; entry: ES:BX -> DHNDL_ structure
;
mov cl,CMD_OUTPUT ; OUTPUT driver function
or es:DHNDL_ATTR[bx],DHAT_READY
mov al,es:DHNDL_ATTR[bx] ; get file info
and al,DHAT_BIN+DHAT_NUL+DHAT_CIN+DHAT_COT
cmp al,DHAT_CIN+DHAT_COT ; is it cooked console?
jne inst_io ; no, device driver i/o
mov si,2[bp] ; SI -> parameter block
mov cx,ds:8[si] ; CX = string length
jcxz write_dev20 ; exit if nothing to write
les di,ds:4[si] ; ES:DI -> string to print
mov al,'Z'-40h ; we have to stop at ^Z
repne scasb ; scan for ^Z character
jne write_dev10 ; skip if ^Z not found
inc cx ; include ^Z in count of chars to skip
sub ds:8[si],cx ; subtract from total count
write_dev10:
mov bx,ds:2[si] ; BX = handle number
mov cx,ds:8[si] ; CX = string length
mov si,ds:4[si] ; ES:SI -> string to print
call cooked_write ; write w/ tab expansion & ^C checking
write_dev20:
sub bx,bx ; no errors
ret ; return the result
read_dev: ; read to character device handle
;--------
; entry: ES:BX -> DHNDL_ structure
mov al,es:DHNDL_ATTR[bx] ; get the file info
mov ah,al ; save ioctl info
and al,DHAT_BIN+DHAT_CIN+DHAT_COT
cmp al,DHAT_CIN+DHAT_COT ; is it cooked console?
jne rddev1 ; skip if binary or not console
jmp read_con ; read from console handle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -