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

📄 genercfg.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 5 页
字号:
	 jae	func_return20		; no, cannot RETURN
	pop	cfg_seekhi
	pop	cfg_seeklo		; restore position in file
	mov	cfg_tail,0		; force a read
	push	bx
	call	atoi			; returning a value ?
	pop	bx
	 jnc	func_return10		; default to 0
	xor	ax,ax
func_return10:
	mov	error_level,ax		; return result in error level
func_return20:
	push	bx			; save return address
	ret				;  and return to it

func_goto:		; GOTO="label"
;---------
	mov	di,offset dev_name	; Copy the label into a 
	mov	byte ptr [di],0		; local buffer and zero terminate
	call	copy_file
	 jc	func_goto10		; ignore if any problems

	mov	cfg_seeklo,0		; Seek to start of file
	mov	cfg_seekhi,0
	mov	cfg_tail,0		; force a re-read

func_goto5:
	call	readline		; read in a line
	 jc	func_goto10		; stop if end of file
	call	strupr			; upper case possible label
	mov	bx,offset cfg_buffer
	cmp	ds:byte ptr [bx],':'		; is it a label ?
	 jne	func_goto5		; no, try next line
	mov	si,offset dev_name
func_goto6:
	inc	bx			; next char in possible label
	lodsb				; get a character
	test	al,al			; end of label ?
	 je	func_goto10		; we have a match !
	cmp	al,ds:byte ptr [bx]	; does it match
	 jne	func_goto5		; no, try next line
	jmps	func_goto6		; yes, look at next character
func_goto10:
	ret

func_exit:
; Stop processing CONFIG.SYS
	call	readline		; read in a line
	 jnc	func_exit		;  until we can read no more..
	ret

func_cls:
; CLEAR SCREEN
; This is PC specific - sorry
	mov	ah,15			; get current
	int	10h			; screen mode
	mov	ah,0
	int	10h			; reset it to clear screen
	ret

func_cpos:
; Set cursor position
	call	atoi			; AX = row
	 jnc	func_cpos10		; check for error
	xor	ax,ax			; default to top left
	jmps	func_cpos40
func_cpos10:
	push	ax			; save row
	call	separator		; look for ','
	 jc	func_cpos20		; no col specified
	call	atoi			; get col
	 jnc	func_cpos30
func_cpos20:
	mov	ax,1			; default to left
func_cpos30:
	pop	dx
	mov	ah,dl			; AH = row, AL = col
	sub	ax,0101h		; compensate for being one based
func_cpos40:
	xchg	ax,dx			; DH = row, DL = col
	xor	bx,bx			; page zero
	mov	ah,2			; set cursor position
	int	10h			; Eeeek!! call the ROS
	ret

func_timeout:
; set TIMEOUT for keyboard input
	call	atoi			; AX = # timeout count
	 jnc	func_timeout10		; check for error
	xor	ax,ax			; bad values mean no timeout
func_timeout10:
	mov	keyb_timeout,ax		; save timeout count
	call	separator		; look for ','
	 jc	func_timeout20
	lodsb				; get default query char
	cmp al,LF ! je func_timeout20
	cmp al,CR ! je func_timeout20
	mov	default_query_char,al
	call	separator		; look for ','
	 jc	func_timeout20
	lodsb				; get default switch char
	cmp al,CR ! je func_timeout20
	cmp al,LF ! je func_timeout20
	mov	default_switch_char,al
func_timeout20:
	ret

func_error:
; ERROR='n'
	call	atoi			; AX = error count to match
	 jc	func_error10
	mov	error_level,ax		; set error level
func_error10:
	ret

func_onerror:
; ONERROR='n' optional command
;
	call	whitespace		; Scan off all white space
	xor	bx,bx			; index relationship = 1st item
	xor	dx,dx			; DX is bit to set
func_onerror10:
	or	bx,dx			; set reationship bit
	lodsb				; now process a character
	mov	dx,2
	cmp	al,'='			; if '=' set bit 1
	 je	func_onerror10
	mov	dx,4
	cmp	al,'<'			; if '<' set bit 2
	 je	func_onerror10
	mov	dx,8
	cmp	al,'>'			; if '>' set bit 3
	 je	func_onerror10
	dec	si			; point at char
	push	bx			; save relationship
	call	atoi			; AX = error count to match
	pop	bx			; recover relationship
	 jc	func_onerror20
	cmp	error_level,ax		; is it the error level we want ?
	jmp	func_onerror_tbl[bx]	; jump to handler
func_onerror20:
	ret

func_onerror_tbl:
	dw	func_onerror_eq		; . . .
	dw	func_onerror_eq		; . . =
	dw	func_onerror_lt		; . < .
	dw	func_onerror_le		; . < =
	dw	func_onerror_gt		; > . .
	dw	func_onerror_ge		; > . =
	dw	func_onerror_ne		; > < .
	dw	func_onerror_take	; > < =
	
func_onerror_eq:
	 je	func_onerror_take
	ret

func_onerror_ne:
	 jne	func_onerror_take
	ret

func_onerror_lt:
	 jb	func_onerror_take
	ret

func_onerror_le:
	 jbe	func_onerror_take
	ret

func_onerror_gt:
	 ja	func_onerror_take
	ret

func_onerror_ge:
	 jae	func_onerror_take
	ret

func_onerror_take:
	pop	ax			; discard return address
	xor	ax,ax			; boot key options = none
	jmp	cfg_continue		; and execute this command



func_query:
; ?optional command
	cmp	boot_options,F5KEY	; if F5 has been pressed then
	 je	func_query50		;  do nothing
	call	whitespace		; discard any following whitespace
	lodsb				; get a character	
	cmp	al,'?'			; is it another '?', is so swallow it
	 je	func_query		;  and go round again
	dec	si			; it wasn't a '?', forget we looked
	push	si			; save current position
	lodsb				; get next real char
	xor	cx,cx			; assume no prompt string
	cmp	al,'"'			; '?"user prompt"' - keep silent as
	 jne	func_query10		; user has supplied prompt
	xchg	ax,cx			; CL = " if user prompt
	lodsb
func_query10:
	cmp	al,cl			; is this the user prompt char ?
	 je	func_query20		;  then stop now
	xchg	ax,dx			; DL= character
	mov	ah,MS_C_WRITE
	int	DOS_INT			; output the character
	lodsb
	cmp	al,CR			; is it the end of the line ?
	 jne	func_query10		;  no, do another character
	mov	ah,MS_C_WRITESTR	; Output msg of form " (Y/N) ? "
	mov	dx,offset confirm_msg1
	int	DOS_INT			; do " ("
	mov	ah,MS_C_WRITE
	mov	dl,yes_char
	int	DOS_INT			; do "Y"
	mov	dl,'/'
	int	DOS_INT			; do "/"
	mov	dl,no_char
	int	DOS_INT			; do "N"
	mov	ah,MS_C_WRITESTR
	mov	dx,offset confirm_msg2
	int	DOS_INT			; do ") ? "
func_query20:
	 jcxz	func_query30		; if no user supplied prompt
	pop	ax			; don't discard original starting
	push	si			;  position
func_query30:
	call	wait_for_key		; wait until a key is pressed
	mov	al,default_query_char	; if we timeout default
	 jc	func_query40
	mov	ah,MS_C_RAWIN
	int	DOS_INT			; read a char
	test	al,al			; is it a function key ?
	 jnz	func_query40
	mov	ah,MS_C_RAWIN
	int	DOS_INT			; throw away function keys
    jmps    func_query30
func_query40:
	push	ax			; save response
	mov	ah,MS_C_WRITE
	mov	dl,al
	int	DOS_INT			; echo the char
	mov	ah,MS_C_WRITESTR
	mov	dx,offset confirm_msg3
	int	DOS_INT			; now do CR/LF to tidy up
	pop	ax
	call	toupper			; make response upper case
	pop	si			; recover starting position
	cmp	al,yes_char
	 jne	func_query50
	pop	ax			; Discard Return Address
	xor	ax,ax			; boot key options = none
	jmp	cfg_continue		; Execute the command
func_query50:
	ret				; Return without Executing Command



func_getkey:				; GETKEY
	call	wait_for_key		; wait until a key is pressed
	mov	ax,CONFIG_ERRLVL	; assume we have timed out
	 jc	func_getkey10		; ignore if timeout
	mov	ah,MS_C_RAWIN
	int	DOS_INT			; read a char
	xor	ah,ah			; convert to word
func_getkey10:
	mov	error_level,ax
	ret
	
	
;	CONFIG_ERROR is the global error handler for the CONFIG.SYS
;	commands. It is called with SI pointing to the CR/LF terminated string
;	that caused the error and with DX pointing to an "informative" error
;	message.
;
;	On Entry:- 	AL	Terminating Character
;			DX	Offset of Error Message
;			SI	0000 No Message to display
;				Offset of AL terminated string
;
config_error:

if ADDDRV
	mov	error_flag,1
endif

	push	ax
	mov	ah,MS_C_WRITESTR	; Print the Error Message
	int	DOS_INT			; passed in DX
	pop	ax

	mov	ah,al			; AH = terminating character
	test	si,si			; display the failing string ?
	 jz	cfg_e20			;  YES then scan for terminator
cfg_e10:
	lodsb				; get char to display
	cmp	al,ah			; have we reached the terminator ?
	 je	cfg_e20
	xchg	ax,dx			; DL = character to display
	mov	ah,MS_C_WRITE		; print a character at a time
	int	DOS_INT
	xchg	ax,dx			; terminator back in AH
	jmps	cfg_e10
cfg_e20:
;;	jmp	crlf			; Terminate with a CRLF

	Public	crlf
crlf:
	push	dx
	mov	dx,offset msg_crlf	; Print a CR LF
	mov	ah,MS_C_WRITESTR
	int	DOS_INT
	pop	dx
	ret

;
;	Scan the command table for a match with the first entry in the
;	CR/LF terminated string passed in SI
scan:
	call	whitespace		; scan off all white space
	push	bx			; save the CONFIG Handle
	mov	bx,offset cfg_table - CFG_SIZE

scan_10:
	add	bx,CFG_SIZE		; bx -> next entry in table
	mov	di,CFG_NAME[bx]		; es:di -> next entry name
	test	di,di			; end of table ?
	stc				; assume so
	 jz	scan_exit		; Yes Exit with the Carry Flag Set
	push	si			; Save the String Offset
	call	compare
	pop	ax			; Remove String Address
	 jnc	scan_20			; String Matched
	xchg	ax,si			; Restore the original String Address
	jmps	scan_10			; and test the next entry

scan_20:
	and	CFG_FLAGS[bx],not CF_QUERY
	test	CFG_FLAGS[bx],CF_LC	; should we upper case line ?
	 jnz	scan_50			;  skip if not
	xchg	ax,si
	call	strupr			; upper case the command line
	xchg	ax,si
scan_30:
	call	whitespace		; Scan off all white space before and
	lodsb				;  after the option '=' character
	cmp	al,'?'			; are we querying things ?
	 jne	scan_40
	or	CFG_FLAGS[bx],CF_QUERY	; remember the query, now go and
	jmps	scan_30			;  remove any other whitespace
scan_40:
	cmp	al,'='			; '=' character.
	 je	scan_30
	dec	si
scan_50:
	mov	di,bx			; Save the Table Entry
	xor	ax,ax			; and exit with the Carry Flag Reset
scan_exit:
	pop	bx
	ret

; Compare two strings in case insensitive manner
; On Entry:
;	ds:si -> String 1 (upper/lower case, length determined by string 2)
;	es:di -> String 2 (uppercase, null terminated)
; On Exit:
;	Carry clear:	strings are the same
;	ds:si -> character immediately following end of string 1
;	es:di -> character immediately following end on string 2
;
;	Carry set:	strings different
;	ds:si -> As on entry
;	es:di -> undefined
;
compare:
;-------
	push	bx
	push	si			; save starting position
compare10:
	mov	al,es:[di]		; al = next character 
	inc	di
	test	al,al			; end of string 2 yet ?
	 jz	compare40		; yes, strings must be equal
	call	dbcs_lead		; DBCS lead byte?
	 jnz	compare20		;  no
	mov	ah,al
	lodsb				; is 1st byte of pair the same ?
	cmp	al,ah
	 jne	compare30
	cmpsb				; is 2nd byte of pair equal ?
	 jne	compare30
	jmps	compare10
compare20:
	call	toupper			; just uppercase this byte
	xchg	ax,bx			; BL = string2 character
	lodsb				; al = next char in string 1
	call	toupper			; (can't be KANJI if it matches)
	cmp	al,bl			; check the characters are
	 je	compare10		;  identical stop the compare 
compare30:
	stc				; on a mismatch and set CY
compare40:
	pop	bx			; recover starting position
	 jnc	compare50
	mov	si,bx			; SI = original start
compare50:
	pop	bx
	ret


separator:
;---------
; On Entry:
;	DS:SI -> string
; On Exit:
;	DS:SI -> next option
;	CY set if end of line
;
; Strips off all whitespace, and the optional ','
; CY set at end of line
	call	whitespace			; deblank string and
	lodsb					;  check for ',' separator
	cmp	al,','				;  discarding if found
	 je	separator10
	cmp	al,CR				; end of the line ?
	stc					; assume so
	 je	separator10
	dec	si				; something else, leave alone
	clc					; not end of line
separator10:
	ret

separator20:
	call	whitespace			; strip of following spaces
	clc					; not end of line
	ret


strupr:
;------
; Uppercase a null terminated string.
; Entry
;	ds:si ->	null terminated string
; Exit
;	none		(string is uppercased)
; Lost
;	no registers changed


	push	si
	push	ax

spr_loop:
	mov	al, [si]		; al = next byte from string
	test	al, al			; end of string?
	jz	spr_done		;  yes - exit
	
;	cmp	al,' '			; BAP. End at first space
;	je	spr_done		; or comma or slash
;	cmp	al,','			; so that parameters
;	je	spr_done		; are not uppercased
;	cmp	al,'/'			; Took out again cos it caused
;	je	spr_done		; problems with labels (I think).

	call	dbcs_lead		; DBCS lead byte?
	jnz	spr_not_dbcs		;  no
	inc	si			;  yes - skip first and second bytes of
	inc	si			;  pair as they cannot be uppercased
	jmp	spr_loop		; loop round
spr_not_dbcs:

	call	toupper			; just uppercase this byte
	mov	[si], al		; return the result to the string
	inc	si
	jmp	spr_loop		; continue

spr_done:
	pop	ax
	pop	si
	ret


dbcs_lead:
;---------
; Return true if given byte is the first of a double byte character.
; Entry
;	al 	= byte to be tested
; Exit
;	Z Flag	= 1 - byte is a DBCS lead
;		  0 - byte is not a DBCS lead
; Lost
;	no registers changed


	push	ds

⌨️ 快捷键说明

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