📄 cdevio.a86
字号:
; return the result
rddev1:
test ah,DHAT_READY ; previous EOF ?
jnz rddev2 ; yes we return now
mov di,2[bp] ; DI -> parameter block
mov ds:word ptr 8[di],0 ; zero bytes xfered
ret
rddev2:
mov cl,CMD_INPUT
inst_io:
; ES:BX = DHNDL_, CL = command
sub sp,RH4_CDEV_LEN ; make RH_ on stack
mov di,bx ; save address DHNDL_ in DI
mov bx,sp ; SS:BX -> request header
mov ds:RH_CMD[bx],cl
mov ds:RH_LEN[bx],RH4_CDEV_LEN
mov ds:RH_STATUS[bx],0 ; status OK in case of zero chars
mov si,2[bp] ; DS:SI -> parameter block
lea si,4[si] ; point at buffer offset
lodsw ; get buffer offset
; Normalising the address has been unnecessary so far
; push ax
; and ax,15 ; normalise the address
; pop cx
; shr cx,1 ! shr cx,1
; shr cx,1 ! shr cx,1
mov ds:RH4_BUFOFF[bx],ax ; set buffer offset in request header
lodsw ; get buffer segment
; add ax,cx ; add in normalised offset/16
mov ds:RH4_BUFSEG[bx],ax ; get buffer segment in request header
lodsw ; get byte count
xchg ax,cx ; byte count in CX
; Parameter block created on stack at SS:BX and initialised for xfer
; ES:DI -> DHNDL_, CX = total number of bytes to xfer
inst_io20:
mov ds:RH4_COUNT[bx],cx ; try and do this many
test es:DHNDL_ATTR[di],DHAT_BIN+DHAT_NUL
; are we in binary mode ?
jcxz inst_io30 ; return on zero length xfer
jnz inst_io25 ; binary, skip calling PCMODE
mov ds:RH4_COUNT[bx],1 ; do one char at a time
call break_check ; call the break check routine
cmp ds:RH_CMD[bx],CMD_OUTPUT ; which way are we going
jne inst_io25
call inst_io_getchar ; AL = 1st char in the buffer
cmp al,1Ah ; EOF - don't send it or anything after
je inst_io30 ; and exit without xfering any
inst_io25:
push ds ! push es ! push di ! push cx
lds si,es:DHNDL_DEVPTR[di] ; DS:SI -> device driver
push ss ! pop es ; ES:BX -> RH_
call device_driver ; execute the command
pop cx ! pop di ! pop es ! pop ds
jns inst_io_continue ; if no errors carry on
push es
les si,es:DHNDL_DEVPTR[di] ; ES:SI -> device driver
call char_error ; this will handle the Int 24
pop es
cmp al,ERR_RETRY ; what should we do ?
je inst_io20 ; retry the operation
ja inst_io30 ; fail - return error
mov ds:RH_STATUS[bx],RHS_DONE
jmps inst_io_ignore ; ignore - fiddle status and
inst_io_continue: ; say we did it all
mov dx,ds:RH4_COUNT[bx] ; how many did we xfer ?
test dx,dx ; if we haven't done any
jz inst_io30 ; we are stuck so exit now
inst_io_ignore:
call inst_io_getchar ; AL = 1st char in the buffer
add ds:RH4_BUFOFF[bx],dx ; it may not enough so adjust offset
sub cx,dx ; and number still to do
cmp ds:RH_CMD[bx],CMD_INPUT ; which way are we going - if input
jne inst_io20 ; we need to check for CR/EOF
test es:DHNDL_ATTR[di],DHAT_BIN+DHAT_NUL
jnz inst_io30 ; if BIN then exit now
cmp al,13 ; is it a CR character ?
je inst_io30 ; yes, we stop now
cmp al,1Ah ; is it the EOF character ?
jne inst_io20 ; yes, we aren't ready
and es:DHNDL_ATTR[di],not DHAT_READY
inst_io30:
mov di,2[bp] ; DI -> parameter block
sub ds:8[di],cx ; subtract # not xfered from byte count
mov ax,ds:RH_STATUS[bx] ; get result for later
sub bx,bx ; assume no errors
test ax,ax ; test error bit (8000h)
jns rddev_no_err ; skip if ERROR set
mov bl,al ; AL is error code
neg bx ; make it negative code
add bx,ED_PROTECT ; normalize for extended errors
rddev_no_err:
add sp,RH4_CDEV_LEN ; free up RH_ on stack
ret ; return BX
inst_io_getchar:
push ds
lds si,ds:RH4_BUFFER[bx] ; point to the users buffer
lodsb ; get 1st char in the buffer
pop ds
ret
read_con: ; handle read from cooked console
;--------
; entry: AH = DHNDL_ATTR
; ES:BX -> DHNDL_
; 2[BP] -> F_DOS parameter block
; exit: BX = return value
xor cx,cx ; assume we've already had EOF
test ah,DHAT_READY ; now see if we have
jnz con_dev_not_eof
jmp con_dev_exit ; yes, just return zero chars read
con_dev_not_eof:
push es
push bx ; save DHNDL_
con_dev_loop:
mov bx,word ptr fdos_buf ; get # of bytes already used
xor ax,ax
xchg al,bh ; get # bytes in the buffer
inc ax ! inc ax ; also count the CR/LF
sub ax,bx ; have we any bytes left in the buffer?
ja con_dev_cont ; yes, return them
; no, we need a fresh input line
mov fdos_buf,128 ; read up to 128 characters
mov si,2[bp] ; SI -> parameter block
mov bx,ds:2[si] ; BX = input handle
push ds ! pop es
mov dx,offset fdos_buf ; ES:DX -> console buffer
mov cx,bx ; output to same handle as input
push bx
push bp
call read_line ; read edited line
pop bp
mov bl,fdos_buf+1 ; # byte we have read
mov bh,0 ; BX = # of characters read
mov word ptr fdos_buf+2[bx],0A0Dh; append carriage return/line feed
mov fdos_buf,0 ; start reading at beginning
lea si,fdos_buf+3[bx] ; Echo the LF character to the
pop bx ; Same Output handle
mov cx,1 ; Only One Character
call cooked_write
jmps con_dev_loop
con_dev_cont: ; BX = buffer offset
mov di,2[bp] ; DI -> parameter block
mov cx,ds:8[di] ; CX = # of bytes to read
cmp cx,ax ; reading more than available?
jbe con_dev_ok ; no, read as much as you want
mov cx,ax ; else take all that there is
con_dev_ok:
add fdos_buf,cl ; update buffer index for next time
les di,ds:4[di] ; ES:DI -> buffer to read into
lea si,fdos_buf+2[bx] ; DS:SI -> function 10 buffer
push cx ; save count
rep movsb ; read all the data
pop cx ; restore count
mov al,1Ah ; now we look for EOF mark...
push ds ! pop es
lea di,fdos_buf+2[bx] ; ES:DI -> function 10 buffer
mov si,cx ; keep count safe
repne scasb
xchg cx,si ; restore count
pop bx ; recover DHNDL_
pop es
jne con_dev_exit ; if no EOF, skip to exit
sub cx,si ; subtract any after EOF mark
dec cx ; and the EOF mark itself
and es:DHNDL_ATTR[bx],not DHAT_READY
con_dev_exit:
mov di,2[bp] ; DI -> parameter block
mov ds:8[di],cx ; set # of characters read
sub bx,bx ; good return code
ret
eject
first_dev: ; F_DOS FIRST call on device performed
;--------- ; Called with MXDisk
; On Entry:
; ES:BX -> device header
; On Exit:
; dma_buffer initialised with device name
;
mov dx,es ; DX:BX -> device header
call les_di_dmaptr ; ES:DI -> DMA buffer
mov al,0FFh ; invalidate search state for NEXT
mov cx,21
rep stosb
mov al,40h ; mark it as a device
stosb
sub ax,ax
mov cx,4
rep stosw ; zero time, date, file size
lea si,10[bx]
push ds
mov ds,dx ; DS:SI -> name in device header
mov cx,4
rep movsw ; copy device name across
pop ds
mov cx,8
frstdev1: ; scan off trailing spaces
cmp es:byte ptr 0-1[di],' '
jne frstdev2
dec di
loop frstdev1
frstdev2:
mov al,0
stosb ; add a trailing NUL
ret
eject
ioc6_dev: ; IOCTL(6) - input status for device
;--------
; entry: ES:BX -> DHNDL_
mov al,CMD_INPUT_NOWAIT
jmps ioc67d ; call the device driver
ioc7_dev: ; IOCTL(7) - output status for device
;--------
; entry: ES:BX -> DHNDL_
mov al,CMD_OUTPUT_STATUS ; OUTPUT STATUS
ioc67d: ; common code for I/O STATUS
push ds
sub sp,RH5_LEN-2*word ; allocate request header on stack
push ax ; RH_CMD = AL
mov ax,RH5_LEN
push ax ; RH_LEN = RH5_LEN
lds si,es:DHNDL_DEVPTR[bx] ; DS:SI -> device driver
push ss ! pop es
mov bx,sp ; ES:BX -> RH_
mov es:RH5_CHAR[bx],0 ; zero the char
call device_driver ; do the CALLF's to the device driver
xor dl,dl ; assume not ready
mov dh,es:RH5_CHAR[bx] ; possible peeked character
add sp,RH5_LEN ; recover stack space
pop ds
test ax,RHS_ERROR+RHS_BUSY ; test if BUSY bit set in status
jnz ioc67d_ret ; device not ready if error or busy
dec dl ; return ready DL = FF
ioc67d_ret:
mov si,2[bp] ; SI -> user's parameter block
mov ds:6[si],dx ; update returned status
sub bx,bx ; no error occurred
ret ; for now
end ; of CDEVIO.A86
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -