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

📄 cio.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 3 页
字号:
	pop	bx
cooked_o20:
	test	ah,CIO_RAW		; is it a cooked console ?
	 jnz	cooked_o30		; skip check if not
	call	cooked_status		; look for keyboard input
	mov	char_count,CHECK_EVERY	; look again in a while
cooked_o30:
	pop	si
	pop	cx
	pop	ax
	pop	es
	ret

eject
;	IDLE_DEV is called when the PCMODE is waiting for a character.
;	This routine must determine if the request is for a device or not
;	and call the IDLE interface for device requests to the system can be
;	put to sleep until a character is ready.
;
;	On Entry:-	BX Handle Number
;	
idle_dev:
	push	bx			; preserve handle
	mov	ax,8400h
	int	2ah			; Server hook for idle
	dec	clock_count
	 jnz	idle_dev10		; Zero if NO skip delay and execute
	call	ReadTimeAndDate		; for PC BIOS's who must read every day
idle_dev10:
if IDLE_DETECT
	test	idle_flags,IDLE_DISABLE	; Has Idle Checking been enabled
	 jnz	idle_dev40		; Skip if NO
	push es ! push si
	call	is_device		; The requested handle a file or device
	 jc	idle_dev30		; File Access skip IDLE
	mov	ax,PROC_KEYIN		; Assume this is the REAL Console
	test	es:DH_ATTRIB[si],DA_ISCIN; Test Attribute Bits
	 jnz	idle_dev20		; Yes this is Default Console Device
	mov	ax,PROC_DEVIN		; Input from Another Device
idle_dev20:
	callf	idle_vec		; Call the IDLE Handler
idle_dev30:
	pop si ! pop es
idle_dev40:
endif
	pop	bx			; recover handle
	ret

eject
;	The following routine reads CX bytes from the device whose address 
;	is held in the DWORD pointer passed by DS:SI. A Request Header 
;	is built on the stack and the command is executed.
;
;	On Entry:
;		ES:SI		DWORD Pointer to Device Header
;		SS:DX		Buffer Address
;		CX		Character Count
;
;	On Exit:
;		AX		Request Header Status
;		Zero		No Error
;
	Public	device_read
device_read:
	mov	al,CMD_INPUT		; we want input
	jmps	device_common		; now use common code

eject
;	The following routine writes CX bytes to the device whose address 
;	is held in the DWORD pointer passed by DS:SI. A Request Header 
;	is built on the stack and the command is executed.
;
;	On Entry:
;		ES:SI		DWORD Pointer to Device Header
;		SS:DX		Buffer Address
;		CX		Character Count
;
;	On Exit:
;		AX		Request Header Status
;		Zero		No Error
;
	Public	device_write
device_write:
	mov	al,CMD_OUTPUT		; we want output
device_common:
	push	bx
	sub	sp,RH4_LEN		; reserve space on the stack
	mov	bx,sp			; request header offset
	mov	ss:RH_LEN,RH4_LEN	; request header length
	mov	ss:RH4_BUFOFF,dx	; buffer offset
	mov	ss:RH4_BUFSEG,ss	; buffer segment
device_common10:
	mov	ss:RH4_COUNT,cx		; character count
	call	device_req		; execute command
	 jns	device_common20		; if no errors return to the caller
	sub	cx,ss:RH4_COUNT		; CX = chars remaining
	push	ax			; save the error code
	call	char_error		; ask int 24 what to do
	cmp	al,ERR_RETRY		; should we retry the operation ?
	pop	ax			; recover the error code
	 ja	device_common20		; Fail/Abort return error
	mov	al,ss:RH_CMD		; reload the command
	 je	device_common10		; Retry, re-issue the device request
	mov	ax,RHS_DONE		; Ignore, pretend no errors
device_common20:
	add	sp,RH4_LEN		; restore the stack to its normal
	test	ax,RHS_ERROR		;  state and return the status.	
	pop	bx
	ret


char_check:
; On Entry:
;	BX = handle to check
; On Exit:
;	ZF set if character ready
;	AL = character (if device handle)
;	AH = RIC status
;
	push	bx			; Save the current handle status
if IDLE_DETECT
	test	idle_flags,IDLE_DISABLE	; Has Idle Checking been enabled
	 jnz	char_check10		; Skip if NO
	dec	int28_delay		; Has the INT28 Loop count reached
	 jnz	char_check10		; Zero if NO skip delay and execute
	mov	ax,int28_reload		; INT28. Otherwise DELAY/DISPATCH
	mov	int28_delay,ax
	mov	ax,PROC_INT28		; Process is IDLE
	callf	idle_vec		; Call the IDLE Handler
char_check10:
endif
	cmp	indos_flag,1		; Only execute an INT 28
	 jnz	char_check20		; when the INDOS flag is 1
	cmp	int28_flag,TRUE		; Only generate INT 28s for the
	 jnz	char_check20		; selected functions
	
	push	remote_call
	push	machine_id
	mov	es,current_psp		; Get the PSP
	push	PSP_USERSP		; Save the SS:SP pointer to 
	push	PSP_USERSS		; the register image

if IDLE_DETECT				; Set IDLE_INT28 so $IDLE$ knows
	or	idle_flags,IDLE_INT28	; that we are nolonger inside DOS
endif
	int	28h			; Execute an INT 28 for SideKick and
					; the PRINT utility. INDOS flag is 1

if IDLE_DETECT				; Reset IDLE_INT28 so $IDLE$ knows
	and	idle_flags,not IDLE_INT28; that we are back DOS
endif
	mov	int28_flag,TRUE		; Restore INT28_FLAG
	mov	es,current_psp		; Get the PSP
	pop	PSP_USERSS		; Restore the SS:SP pointer to 
	pop	PSP_USERSP		; the register image
	pop	machine_id
	pop	remote_call
char_check20:
	pop	bx
;	jmp	hndl_instat		; Check Input Status. ZERO == Ready

;
;
hndl_instat:
	call	is_device		; Does this handle refer to a device
	 jnc	device_instat
	mov	ax,(MS_X_IOCTL shl 8)+6	; Get the file status
	call	dos_entry		; for the specified handle
	cmp	al,0FFh			; and return ZERO until the EOF
	ret

;	The following routine executes the Non Destructive Input
;	command to the device whose address passed in ES:SI.
;
;	On Entry:
;		ES:SI		DWORD Pointer to Device Header
;
;	On Exit:
;		Zero		Character Ready
;		AH		Top Byte Request Header Status
;		AL		Next Character if ZERO
;

device_instat:
	push	bx
	sub	sp,RH5_LEN		; Reserve Space on the Stack
	mov	bx,sp			; Request Header Offset
	mov	ss:RH_LEN,RH5_LEN	; Set Request Header Length
	mov	al,CMD_INPUT_NOWAIT	; Command Number
	call	device_req		; Execute the Command
	mov	al,ss:RH5_CHAR		; Assume a character is ready
	add	sp,RH5_LEN		; Restore the Stack to its normal
	test	ax,RHS_BUSY		; state and return the status.	
	pop	bx			; Zero if a Character is ready
	ret

;	The following routine handles the low level device interface to
;	the character device drivers. All the generic Request Header 
;	initialization is carried out here.
;
;	On Entry:
;		AL		Command
;		ES:SI		Device Header
;		SS:BX		Current Request Header
;
;	On Exit:
;		AX		Request Header Status
;

device_req:
;----------
	mov	ss:RH_CMD,al		; save the command
	push	ds
	push	es
	push es ! pop ds		; DS:SI -> device driver
	mov	es,ss:current_psp	; es = current PSP
	mov	al,es:PSP_RIC		; al = Return Interim Character flag
	mov	ss:RH4_RIC,al		; Return Interim Char flag
	push ss ! pop es		; ES:BX -> RH_
	call	device_driver
	pop	es
	pop	ds
	ret

eject
;
;	IS_DEVICE checks the internal handle structures to determine
;	if the handle referenced in BX is a file or device. Invalid
;	handles all map to the default console device.
;
; On Entry:
;	BX	Handle Number
;
; On Exit:
;	CY set if handle is for a file
;	CY clear if handle is for device at ES:SI
;
is_device:
	push	ax
	push	bx			; Convert the Standard Handle number
	mov	ax,bx			; get XFN in AL
;	mov	cx,current_psp		; into an internal handle number
;	 jcxz	is_dev10		; no PSP, we have IFN already
;	mov	es,cx
	test	byte ptr remote_call+1,DHM_FCB/100h; if FCB initiated access
	 jnz	is_dev10		; we have IFN already
	mov	es,current_psp
	cmp	bx,es:PSP_XFNMAX	; Check if the handle is in range for
	 jae	is_dev_bad		; this PSP.
	les	si,es:PSP_XFTPTR
	mov	al,es:byte ptr [bx+si]	; AL = Internal File Handle
is_dev10:
	call	ifn2dhndl		; ES:BX -> DHNDL_
	 jc	is_dev_bad
	mov	ax,es:DHNDL_WATTR[bx]	; get file attributes
	and	ax,DHAT_REMOTE+DHAT_DEV
	cmp	ax,DHAT_DEV		; is it a local device ?
	stc				; assume it's a file
	 jne	is_dev30
	les	si,es:DHNDL_DEVPTR[bx]	; its a device
is_dev20:
	clc
is_dev30:
	pop	bx
	pop	ax
	ret

is_dev_bad:
	les	si,con_device		; bad handles map to console
	jmps	is_dev20

open_or_close_prn:
;-----------------
; called when CIO_CTLP toggled - call prn device with Open or Close as appropriate
;
	push ds ! push ax ! push bx
	mov	ax,CTLP
	push	ax			; ^P on stack
	mov	cx,current_psp		; look in PSP
	 jcxz	oc_prn30		; no PSP, forget it
	mov	es,cx
	cmp	bx,PSP_XFNMAX		; Check if the handle is in range for
	 jae	oc_prn30		; this PSP. 
	les	si,es:PSP_XFTPTR	; for the internal handle number
	mov	al,es:byte ptr STDPRN[si]
	cmp	al,0FFh			; AL = Internal File Handle
	 je 	oc_prn30		;  skip if invalid Handle Number
	call	ifn2dhndl		; ES:BX -> doshndl
	 jc	oc_prn30
	test	es:DHNDL_WATTR[bx],DHAT_NETPRN
	 jz	oc_prn10
	mov	ax,I2F_CTLP		; turn on the network printer
	int	2fh			; with a magic INT 2F call
	 jnc	oc_prn10
	and	cio_state,not CIO_CTLP	; make sure Printer Echo is off
	mov	ax,I2F_CTLP_ERR
	int	2fh
	jmps	oc_prn30
oc_prn10:
	mov	ax,es:DHNDL_WATTR[bx]	; get file attributes
	and	ax,DHAT_REMOTE+DHAT_DEV
	cmp	ax,DHAT_DEV		; is it a local device ?
	 jne	oc_prn30
	mov	al,CMD_DEVICE_OPEN	; assume we've just opened
	test	cio_state,CIO_CTLP	; Check for Printer Echo
	 jnz	oc_prn20		; yes, skip next bit
	mov	al,CMD_DEVICE_CLOSE	; no, we must close
oc_prn20:
	les	si,es:DHNDL_DEVPTR[bx]	; get the device driver address
	test	es:DH_ATTRIB[si],DA_REMOVE
	 jz	oc_prn30		; no, skip call if not supported
	sub	sp,RH13_LEN		; Reserve Space on the Stack
	mov	bx,sp			; and point to it
	mov	ss:RH_LEN,RH13_LEN	; Set Request Header Length
	mov	ss:RH_CMD,al		; Command Number
	call	device_driver		; issue the command
	add	sp,RH13_LEN		; Restore the Stack to its normal
oc_prn30:
	pop	ax			; discard ^P from stack
	pop bx ! pop ax ! pop ds
	ret
	
	
PCM_RODATA	CSEG	WORD

cntrl_c_msg	db	'^C', CR, LF	; Control-Break Message

GLOBAL_DATA	dseg

clock_count	db	0

PCMODE_DATA	DSEG	WORD

	extrn	break_sp:word		; For Control-Break handler
	extrn	char_count:byte
	extrn	cio_state:byte		; Character I/O State
	extrn	column:byte		; Console Cursor Location
	extrn	con_device:dword	; Current Console Device
	extrn	current_psp:word	; Current PSP Address
	extrn	exit_type:byte
	extrn	last_key_ext:byte
	extrn	indos_flag:byte		; INDOS Count
	extrn	int21regs_ptr:dword	; pointer to callers registers
	extrn	machine_id:word
	extrn	remote_call:word
if IDLE_DETECT
	extrn	idle_flags:word		; IDLE State Flags
	extrn	idle_vec:dword		; IDLE routine Vector
	extrn	int28_delay:word
	extrn	int28_reload:word
	extrn	int28_flag:byte
endif

	end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -