⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdevio.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
					; 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 + -