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

📄 cio.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 3 页
字号:
func0B:
;
; Entry:
;	AH  ==	0Bh
; Exit:
;	AL  ==	0FFh if char available
;	    ==	 00h otherwise
;
	mov	bx,STDIN
	call	cooked_status		; Get the current handle status
	mov 	al,0FFh			; Assume that the handle is ready
	 jz	f0B_exit		; and return 0FFh in AL
	mov	al,00			; Not Ready
f0B_exit:
	jmps	funcICexit		; exit thru incomplete char support



;	*****************************
;	***    DOS Function 0C    ***
;	***    Flush and Execute  ***
;	*****************************
;
	Public	func0C
func0C:
;
; Entry:
;	AH  ==	0Ch
;	AL  ==  function to execute:  1,6,7,8 or A
; Exit:
;	AL = 0 if function in AL is invalid
;
	push	ax			; save sub-function
	mov	bx,STDIN		; Is this Standard Input Handle a
	call	is_device		;  file or device. Do not flush the 
	 jc	f0C_20			;  buffer contents for a FILE
f0C_10:
	call	hndl_instat		; check if any characters are left
	 jnz	f0C_20			;  and quit when buffer empty
	call	raw_read		; read the character
	jmps	f0C_10			; loop till the buffer is empty

f0C_20:
	pop	ax
	cmp al,01h ! je	al_ok		; is legal for this command
	cmp al,0ah ! je	al_ok
	cmp al,06h ! jb	al_nogo
	cmp al,08h ! ja	al_nogo

al_ok:					; Valid function so now execute
	call	reload_registers	; all register reloaded as per entry
	mov	ah,al			; Get the requested sub-function in AH
	jmp	int21_func		; execute the function

al_nogo:				; Illegal command to execute
	xor	ax,ax			; from this function so return error
	ret

eject
;
;	BREAK_CHECK checks for a CNTRL-C and is called by functions 01h to 
;	0Ch. Or by the entry code if the break flag is non zero.
;
	Public	break_check
break_check:
	cmp	indos_flag,01		; Skip the check if we are
	 jnz	break_c15		; already in the emulator
	push	ax
	push	es
	push	si
	les	si,con_device
	call	device_instat		; get the input status
	pop	si
	pop	es
	 jnz	break_c10		; No Character Ready
	cmp	al,CTLC			; Is the character a Control-C
	 jz	break_c20		; Yes
break_c10:
	pop	ax
break_c15:
	ret

break_c20:				; The User has Typed Control-C so flush
	mov	bx,0FFFFh		;  input buffer (FFFF=con_device)
	call	char_get
go_int23:
	push cs ! pop es		; ES:DX -> Character Buffer
	mov	si,offset cntrl_c_msg	; Message Offset
	mov	cx,length cntrl_c_msg	; Message Length
	call	stdout_cooked_write	; write the ^C String to console
;
;	Prepare to execute an Interrupt 23 (Break Check) and process
;	the return values. If the called routine returns with an IRET
;	or with a RETF and the carry flag reset continue the function
;	otherwise Abort.
;
	mov	es,current_psp		; Get the Entry SS and SP
	mov	ax,PSP_USERSP		; Get the Users Stack Pointer
	add	ax,18 - 2		; Compensate for the User Registers
	mov	break_sp,ax		; and save for RETF check
	cli
	dec	indos_flag		; Exit the PCDOS emulator
	mov	ss,PSP_USERSS		; Switch to the Users Stack
	mov	sp,PSP_USERSP		; and Restore the registers

	POP$DOS				; Update the registers then
					; set the flags and return
					; to the user
	clc				; Default to continue function
	int	23h			; Call the Break Handler
	cli				; Check the Flag State
	 jnc	do23_10			; If CARRY then Abort this process
	call	get_dseg		; Get our data segment
	mov	exit_type,TERM_BREAK	; Force EXIT_TYPE to TERM_BREAK
	mov	ax,4C00h		; "Good-Bye Cruel World" 
    jmps    do23_20
    do23_10:
	push	ds			; Otherwise restart the aborted func
	call	get_dseg
	cmp	sp,break_sp
	pop	ds			; Restore the the USER DS correct
	 jz	do23_30			; Did we Use a RETF or Not
do23_20:
	add	sp,2			; Yes so correct the stack pointer
do23_30:				; and restart the aborted function
	jmp	int21_entry		; re-start the function call



eject
;
; cooked_status is called on input or output and looks for live keys ^C,^P,^S.
; If any of these are found they are dealt with.
; If ^P is encountered it is swallowed.
; If ^C is encountered we always do an Int23.
; If ^S is pressed we swallow it, and the next character (checking for ^C, but
; not for ^P), then say a character is ready.
; Note that this can lead to status calls (func0B) hanging inside the OS,
; or the return of ^S characters from input calls (func01), but this is
; intentional.
;

cooked_status:
;-------------
; check input
; On Entry:
;	BX = handle to check
; On Exit:
;	ZF set if character available
;	AL = character
;	AH = RHS_IC
;
	call	break_check		; check for a ^C on console
	call	char_check		; is there a character ready
	 jnz	cooked_s50		;  no so keep scanning

	cmp	last_key_ext,0		; was last char an zero ?
	mov	last_key_ext,0		; (clear flag for next time)
	 jne	cooked_s40		; skip ^P,^S,^C checks if so
	
	cmp	al,CTLP			; has the user typed ^P
	 jne	cooked_s10		;  flush the buffer and
	xor	cio_state,CIO_CTLP	;  toggle ^P flag
	call	char_get		;  flush the character from buffer
	call	open_or_close_prn	;  open/close printer device
	test	ax,ax			; ZF clear, ie. no char available
	jmps	cooked_s50

cooked_s10:
	cmp	al,CTLC
	 jnz	cooked_s30		; has the user typed ^C
	call	char_get		; so get the RAW character
cooked_s20:
	jmp	go_int23		; and terminate the function

cooked_s30:
	cmp	al,CTLS			; pause if the user has typed
	 jnz	cooked_s40		;  a ^S
	call	char_get		; remove ^S and resume when
	call	raw_read_wait		; the next character is typed
	cmp	al,CTLC
	 je	cooked_s20		; has the user typed ^C
cooked_s40:
	cmp	al,0
	 jne	cooked_s45
	mov	last_key_ext,1
cooked_s45:
	cmp	ax,ax			; ZF set, ie. char available
cooked_s50:
	ret
	
eject
;
;	The COOKED, CMDLINE and RAW Read functions are basically the same
;	except in their treatment of 'live' characters ^C,^P, and ^S.
;	COOKED will look for and act upon all three live characters.
;	CMDLINE will look for and act upon ^C and ^P, but ^S will be returned
;	so we can use it as a line editing key.
;	RAW will not check for any live keys.
;
	public	cmdline_read, raw_read	; for CMDLINE.PCM

cmdline_read_wait:			; Waiting for a device to become
	call	idle_dev		; ready. So call IDLE routines to
					; put the processor to sleep.
cmdline_read:
	call	break_check		; check for a ^C on console
	call	char_check		; is there a character ready
	 jnz	cmdline_read_wait	;  no so keep scanning
	cmp	al,CTLS			; if the user has typed ^S
	 jne	cooked_read		;  we have to do a raw read
;	jmps	raw_read		;  else we do a cooked read

raw_read_wait:				; Waiting for a device to become
	call	idle_dev		; ready. So call IDLE routines to
					; put the processor to sleep.
raw_read:
	call	char_check		; Is there a character Ready
	 jnz	raw_read_wait		; loop until character available
	jmps	char_get

cooked_read_wait:			; Waiting for a device to become
	call	idle_dev		; ready. So call IDLE routines to
					; put the processor to sleep.
cooked_read:
	call	break_check		; check for a ^C on console
	call	cooked_status		; check for a ^S,^P,^C on handle BX
	 jnz	cooked_read_wait	; wait until char is available
;	jmps	char_get		;  else get the character

char_get:
	push es ! push ax		; Input one character and
	mov	dx,sp			;  return it in AL
	call	is_device		; Does this handle refer to a device
	mov	cx,1
	 jc	char_get30		; if it's a device then
	call	device_read		;  use device_read
char_get20:
	pop ax ! pop es
	ret

char_get30:
; We are redirected, so call to the FDOS to get a character
	push ss ! pop es		; EX:DX -> character to read
	mov	ah,MS_X_READ		; call the FDOS to do all
	call	dos_entry		;  the hard work
	jmps	char_get20

eject

stdout_cooked_write:
	mov	bx,STDOUT		; output to the console device
;	jmp	cooked_write

;
;	The COOKED_WRITE routine will expand TABS etc in the string
;	passed passed by the calling routine. 
;
;	On Entry:
;		ES:SI		Buffer Address
;		CX		Character Count
;		BX		Output Handle
;	On Exit:
;		AL = last char written
;
	Public cooked_write
cooked_write:
	push	es
	push	bx
	mov	ah,cio_state		; get CIO_CTLP status
	or	ah,CIO_RAW+CIO_HANDLE	; assume we will want raw handle output
	mov	al,bl
	test	byte ptr remote_call+1,DHM_FCB/100h
	 jnz	cook_w03
	mov	es,current_psp		; get our PSP
	cmp	bx,PSP_XFNMAX		; range check our handle
	 jae	cook_w05
	les	di,PSP_XFTPTR
	mov	al,es:byte ptr [bx+di]	; AL = Internal File Handle
cook_w03:
	call	ifn2dhndl		; ES:BX -> DHNDL_
	 jc	cook_w05		; skip if bad handle
	mov	dx,es:DHNDL_WATTR[bx]	; get handle attributes
	and	dx,DHAT_DEV+DHAT_CIN+DHAT_COT+DHAT_BIN+DHAT_REMOTE
	cmp	dx,DHAT_DEV+DHAT_CIN+DHAT_COT+DHAT_BIN
	 je	cook_w04		; accept binary console device
	cmp	dx,DHAT_DEV+DHAT_CIN+DHAT_COT
	 jne	cook_w05		; skip if not cooked console device
	and	ah,not CIO_RAW		; we want cooked output
cook_w04:
	les	bx,es:DHNDL_DEVPTR[bx]	; its the console - but is it FAST ?
	test	es:DH_ATTRIB[bx],DA_SPECIAL
	 jz	cook_w05		; skip if not
	and	ah,not CIO_HANDLE	; don't use handle functions
cook_w05:
	pop	bx
	pop	es
     jcxz   cook_w80        
cook_w10:
	lods	es:al			; Read the next character
	cmp al,DEL ! je cook_w60	; DEL is a NON Printing Character
	cmp al,' ' ! jae cook_w50	; Space and Above are Normal
	cmp al,LF  ! je cook_w60	; Just print LineFeeds
	cmp al,ESC ! je cook_w60	; Just print Escape
	cmp al,BELL! je cook_w60	; Just ring the Bell
	cmp al,CR  ! jne cook_w20	; CR zeros the column number
	mov	column,0
	mov	char_count,1		; check for ^S etc NOW
	jmps	cook_w60
cook_w20:
	cmp al,CTLH ! jne cook_w30	; BackSpace decrements the
	dec	column			; column count by one
	jmps	cook_w60
cook_w30:
	cmp al,TAB ! jne cook_w60	; is it a TAB ?
cook_w40:
	mov	al,' '			;  spaces
	call	cooked_out		; output a space char
	inc	column
	test	column,7		; are we at a TAB stop yet ?
	 jnz	cook_w40
	jmps	cook_w70
cook_w50:
	inc	column			; Update the column count and
cook_w60:
	call	cooked_out		;  output the character
cook_w70:
	loop	cook_w10		; onto the next character
cook_w80:
	ret

cooked_out:
; On Entry:
;	AH = handle status
;	AL = character
;	BX = handle
; On Exit:
;	AX, BX, CX, ES:SI preserved
;
	dec	char_count		; time to check keyboard input ?
	 jz	cooked_o10		;  no, skip status check
	test	ah,CIO_HANDLE+CIO_CTLP	; is it complicated ?
	 jnz	cooked_o10
	int	29h			; This device supports FAST console
	ret

cooked_o10:
	push	es
	push	ax
	push	cx
	push	si
	call	hndl_write		; display the character
	test	ah,CIO_CTLP		; Check for Printer Echo
	 jz	cooked_o20		; Off so No Echo
	push	bx			; Save Output Handle
	mov	bx,STDPRN		; and output the same data to the
	call	hndl_write		; to the Printer Handle

⌨️ 快捷键说明

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