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

📄 misc.a86

📁 与MS-DOS兼容的DOS操作系统
💻 A86
📖 第 1 页 / 共 4 页
字号:
	mov	reg_BX[bp],TRUE_VERSION	; return version number
	mov	ax,patch_version
	mov	reg_DX[bp],ax		; return revision+HMA
	ret
endif


;
;	*****************************
;	***    DOS Function 25    ***
;	***  Set Interrupt Vector ***
;	*****************************
;

; WARNING - use no stack as device drivers have called us re-entrantly

	Public	func25
func25:
	mov	bx,es			; is really dos_DS - save for later
	xor	di,di			; replace with the values in dos_DS:DX
	mov	es,di			; es -> zero segment
	xor	ah,ah			; the interrupt number
	mov	di,ax			; 0:di -> vector
	shl di,1 ! shl di,1		; 4 bytes per vector

	cli
	xchg	ax,dx			; Get New Offset
	stosw				; and Save
	xchg	ax,bx			; Get New Segment
	stosw				; and Save
	sti
	xchg	ax,dx			; recover entry AL to (preserve it)
	ret

;	*****************************
;	***    DOS Function 35    ***
;	***  Get Interrupt Vector ***
;	*****************************

; WARNING - use no stack as device drivers have called us re-entrantly

	Public	func35
func35:
	xor	bx,bx
	mov	ds,bx			; DS:0 -> vector table
	mov	bl,al			; BX = the interrupt number
	shl bx,1 ! shl bx,1		; 4 bytes per vector
	lds	bx,ds:dword ptr [bx]	; DS:BX -> vector
	les	di,ss:int21regs_ptr
	mov	es:reg_BX[di],bx
	mov	es:reg_ES[di],ds
	jmp	get_dseg		; restore DS for return

;PC-DOS	Verify and Break Flags Support
;
;	*****************************
;	***    DOS Function 2E    ***
;	***    Set/Reset Verify   ***
;	*****************************
	Public	func2E
func2E:
	and	al,1			; only use bottom bit
	mov	verify_flag,al		; store for use later
	ret

;	*****************************
;	***    DOS Function 54    ***
;	***  Get Verify Setting   ***
;	*****************************
	Public	func54
func54:
	mov	al,verify_flag		; return verify flag
	ret

;	*****************************
;	***    DOS Function 63    ***
;	***  Get Lead Byte Table  ***
;	*****************************
;


	Public	func63
func63:
	cmp	al, 1			; subfunction #?
	 jb	f63_get_tbl		; subfunction 0
	 je	f63_set_flg		; subfunction 1
	cmp	al, 2			; subfunction 2?
	 je	f63_get_flg		;  yes

	mov	ax, ED_FUNCTION		; invalid subfunction number
	jmp	error_exit		; so quit


f63_get_flg:
; Get the current state of the DOS interim character console flag.
; If this flag is set int 21h functions 07h, 08h, 0Bh, 0Ch are supposed
; to return "interim character information" which I assume is incomplete
; characters. (In languages like Korean a given double byte character
; may be built by the user entering several keystrokes which form
; incomplete characters.)
	mov	es, current_psp
	mov	dl, PSP_RIC		; Return Interim Character flag
	jmp	return_DX		; flag returned in dl


f63_set_flg:
; Set the current state of the DOS interim character console flag.
; dos_DL = 0 - clear flag, dos_DL = 1 - set flag
	mov	es, current_psp
	mov	PSP_RIC, dl		; record flag
	ret


f63_get_tbl:
; Get the current DBCS table address.
	mov	si,offset DBCS_tbl+2; skip the table size entry
;	jmp	return_DSSI

return_DSSI:
;-----------
; On Entry:
;	DS:SI to be returned to caller
; On Exit:
;	AX preserved
;
	les	di,ss:int21regs_ptr
	mov	es:reg_DS[di],ds
	mov	es:reg_SI[di],si
	ret

;
;	*****************************
;	***    DOS Function 29    ***
;	***     Parse String      ***
;	*****************************
	Public	func29
func29:
;
; Entry:
;    DS:SI  ->	line to parse
;    ES:DI  ->	resulting fcb
; Exit:
;    DS:SI  ->	terminating delimeter past parsed filename
;    ES:DI  ->	filled in fcb (Affects 16 bytes:  DnnnnnnnnTTT0000)
;
	push	ds
	push	es
	call	reload_ES
	pop	ds
	call	parse
	call	return_DSSI		; return result of parse
	pop	ds
	mov	al,dh			; return result in AL
	ret

;-----
parse:	; parse DOS filename delimited by TAB,SPACE,or .,+:;=|"/\[]<> or ctrl
;-----
; Entry:
;    DS:SI  ->	line to parse
;    ES:DI  ->	fcb to parse into
;	AL  ==	bit options:
;		Bit 0 == 1:  scan off leading delimiters
;		Bit 1 == 1:  change drive only if specified
;		Bit 2 == 1:  change name   "	"     "
;		Bit 3 == 1:  change type   "	"     "
; Exit:
;    DS:SI  ->	terminating delimeter past parsed filename
;    ES:DI  ->	filled in fcb (Affects 16 bytes:  DnnnnnnnnTTT0000)
;	DH  ==	1 if wild, 0FFh if the drive is invalid, 0 otherwise
;
	push	di			; (<--keep DI last on stack)

	cld				; ChSh
	xor	dx,dx			; DH = default return value (0)
	xchg	al,dl			; put flags into DL, AL = 0

	mov	cx,1
	test	dl,0010b		; should we initialize drive?
	call	nz_store_al		; do conditional store

	mov	al,' '			; use spaces for filename & typ

	mov	cl,8
	test	dl,0100b		; should we initialize the name?
	call	nz_store_al

	mov	cl,3
	test	dl,1000b		; should we initialize the typ?
	call	nz_store_al

	xor	ax,ax			; zero-out the 4 post-typ bytes
	stos	ax
	stos	ax

	pop di ! push di		; restore DI to start of FCB

deblank_loop:
	lods	al			; grab char
	cmp	al,' '			; is it a blank?
	 je	deblank_loop		;  Y: keep looping
	cmp	al,'I'-'@'		; is it a tab?
	 je	deblank_loop		;  Y: keep looping

	test	dl,0001b		; skip-delimiter-bit set?
	 jz	parse_drive		;  N: go start parsing

skip_delim_loop:
	call	check_delimiters	; check AL for delimiterness
	 jb	parse_dec_ret		; found terminator, dec SI & leave
	mov	dl,dh			; flag no-more-delimiter-skip (DL = 0)
	 je 	deblank_loop		; found separator, go deblank after it

parse_drive:
	dec	si
	cmp	byte ptr 1[si],':'	; is the drive specified?
	 jne	parse_name
	lods	ax			; get drive, junk colon
	and	al,01011111b		; upper case it
	sub	al,'@'			; AL = 1-relative drive #
	push ax ! push ds		; Save the drive code and call
	call	get_dseg		; Restore our Data Segment
	call	valid_drive		; routine to validate drive ZR == OK
	pop ds ! pop ax			; Restore drive code and User DS
	 jz	parse_d10
	dec	dh			; flag drive error (0FFh)
parse_d10:
	mov	es:[di],al		; insert drive in fcb

parse_name:
	inc	di			; DI -> fname
	mov	cx,8
	call	parse_item		; parse an up-to 8 char filename
	cmp	dl,'.'			; was the delimeter a '.'?
	 jne	parse_dec_ret		;  N:  the parse is complete

	mov	cl,3
	call	parse_item		; parse an up-to 3 char filetype
parse_dec_ret:
	dec	si			; bump SI back to point to delimeter

parse_ret:
	pop	di
	ret


;-----------
nz_store_al:
;-----------
; Entry:
;	DI  ->	destination to conditionally initialize
;	CX  ==	length of destination
;	AL  ==	byte to initialize with
;	ZF set: do not initialize destination
; Exit:
;	DI  ->	past destination (initial DI+CX)
; Changed:
;	CX,DI
;
	 jnz	skip_store		; should we initialize?
	rep	stosb			;  Y: store them bytes
skip_store:
	add	di,cx			; bump DI to post-dest position
	ret


;==========
parse_item:		; Parses item into fcb if item is specified
;==========
;
; Entry:
;	SI  ->	item to parse (name or type)
;	DI  ->	fcb area to parse it into
;	CX  ==	length of item
;	DH  ==	parse_return
; Exit:
;	SI  ->	past ending delimeter
;	DI  ->	past fcb area (initial DI + CX)
;	CH  ==	If zero on enter zero on exit else 0-255
;	DH  ==	updated parse_return w/possible wild bit set
;	DL  ==	character delimiter @(SI-1)
; Changed:
;	AX,CX,DX,SI,DI
;

	mov	ah,FALSE		; specified item flag
parse_item_loop:
	lods	al			; get char
	call	check_delimiters	; is it a delimiter?
	jbe	pi_pad_ret		;  Y:  the parse is complete
	jcxz	parse_item_loop		; if the name is full, skip the char
	mov	ah,al			; flag name as present
	cmp	al,'?'			; is it a single wild char?
	je	pi_set_wild		;  Y: set wild flag
	cmp	al,'*'			; is it a multi-char wild card?
	jne	pi_store		;  N: store it
	mov	al,'?'			;  Y: fill with '?' to end of name
	rep	stosb
pi_set_wild:
	or	dh,1			; set wild flag
	jcxz	parse_item_loop		; skip store if name is now filled
pi_store:
	dec	cx			; another char done
	call	dbcs_lead		; is it the 1st byte of kanji ?
	 jne	pi_store10
	inc	si			; skip 2nd byte
	 jcxz	parse_item_loop		; can I copy both ?
	dec	cx			; yes, do so
	stosb
	dec	si			; point at second byte
	lodsb				;  so we can copy it too..
pi_store10:
	stos	al			; put the char in the fcb
	jmps	parse_item_loop
pi_pad_ret:
	mov	dl,al			; DL = ending delimeter
	or	ah,ah			; the the item specified?
	 jz	pi_ret			;  N: skip padding
	mov	al,' '			;  Y: pad to end with spaces
	rep	stosb
pi_ret:
	add	di,cx			; bump DI out to end
	ret


;----------------
check_delimiters:
;----------------
;
; Entry:
;	AL  ==	char to check in list of delimiters
; Exit:
;	AL  ==	char changed to uppercase
;	CF set if it is one of the terminators:  |"/\[]<>  & ctrl chars != TAB
;	ZF set if it is one of the separators:   .,+:;=    SPACE & TAB
;	       OR one of the non-ctrl terminators
;

	cmp	al,'a'			; check for lower case
	jb	not_lower
	cmp	al,'z'
	ja	not_lower
	and	al,01011111b		; uppercase it, CF clear, ZF clear
	ret
not_lower:
	push	cx ! push di ! push es
	push	cs ! pop  es		; ES = Code segment
	mov	di,offset parse_separators
	mov	cx,length parse_separators
	repne	scasb			; is AL a separator?
	je	cpd_pop_ret		;  Y: return ZF set
	mov	cl,length parse_terminators
	repne	scasb			; is AL a terminator?
	 stc				;  (set CF if true)
	je	cpd_pop_ret		;  Y: return CF & ZF set
	cmp	al,' '			; (AL == ' ') ZF set, (AL < ' ') CF set
cpd_pop_ret:
	pop	es ! pop  di ! pop  cx
	ret

;
;	*****************************
;	***    DOS Function 2A    ***
;	***  Get Current Date     ***
;	*****************************
	Public	func2A
func2A:
;
;	entry:	None
;
;	exit:	cx = year (1980-2099)
;		dh = month (1-12)
;		dl = day (1-31)
;		al = DOS returns day of week here
;
	call	ReadTimeAndDate		; Get the current Time and Date
	mov	cx,1980
	add	cx,yearsSince1980
;	mov	dl,dayOfMonth
;	mov	ah,month
	mov	dx,word ptr dayOfMonth
	mov	al,dayOfWeek
	jmps	f2C_10			; exit via common routine

;	*****************************
;	***    DOS Function 2C    ***
;	***  Get Current Time     ***
;	*****************************
	Public	func2C
func2C:
;
;	entry:	None
;
;	exit:	ch = hours (0-23)
;		cl = minutes (0-59)
;		dh = seconds (0-59)
;		dl = Hunredths seconds (0-99)
;		al = 0
;
	call	ReadTimeAndDate		; Get the current Time and Date
	mov	cx,biosDate+2		; Get the Hour and Minute
	mov	dx,biosDate+4		; Get the Seconds and Hundredths
	xor	ax,ax			; return AL = 0
f2C_10:
	call	return_CX		; and return to caller
	jmp	return_DX



;	*****************************
;	***    DOS Function 2B    ***
;	***  Set Current Date     ***
;	*****************************
	Public	func2B
func2B:
;
;	entry:	cx = year (1980-2099)
;		dh = month (1-12)
;		dl = day (1-31)
;
;	exit:	al = 00H success
;		   = FFH failure
;
	call	ConvertDate		; Convert to BIOS date
	 jc	f2B_20			; Abort on Error
	push	cx			; save the converted date
	call	ReadTimeAndDate		; Get the current Time and Date
	pop	biosDate		; new date, existing time
f2B_10:					; Set the current Time and Date
	call	rw_clock_common		; make sure clock is there/setup regs
	call	device_write		; Update the Date and Time
	xor	ax,ax
	ret

f2B_20:
	mov	al,0FFh			; return FAILURE
	ret

;	*****************************
;	***    DOS Function 2D    ***
;	***  Set Current Time     ***
;	*****************************
	Public	func2D
func2D:
;
;	entry:	ch = hours (0-23)
;		cl = minutes (0-59)
;		dh = seconds (0-59)
;		dl = hundredth seconds (0-99)
;
;	exit:	al = 00H success
;		   = FFH failure
;
	cmp	ch,23			; Range check hours
	 ja	f2B_20
	cmp	cl,59			; Range check minutes
	 ja	f2B_20
	cmp	dh,59			; Range check seconds

⌨️ 快捷键说明

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