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

📄 misc.a86

📁 与MS-DOS兼容的DOS操作系统
💻 A86
📖 第 1 页 / 共 4 页
字号:
	 ja	f2B_20
	cmp	dl,99			; Range check hundredths
	 ja	f2B_20
	push	cx			; save hours/mins
	push	dx			; save secs/hundredths
	call	ReadTimeAndDate		; Get the current Time and Date
	pop	biosDate+4		; leave the date alone
	pop	biosDate+2		;  but update the time
	jmps	f2B_10			; Update the Date and Time	


	Public	ReadTimeAndDate
	
ReadTimeAndDate:			; Get the current Time and Date
	call	rw_clock_common		; make sure clock is there/setup regs
	call	device_read		; read the Date and Time
	mov	ax,biosDate		; get the BIOS date and convert
	cmp	ax,daysSince1980	; (but only if necessary)
	 jne	NewDate
	ret

NewDate:
	mov	daysSince1980,ax	; so we won't have to convert next time
	inc	ax			; Day number starting 1 Jan 1980
	mov	cx,ax			; save day count
	inc	ax			; convert to a sunday as 1/1/80 is tues
	xor	dx,dx
	mov	bx,7
	div	bx
	mov	dayOfWeek,dl		; save day of week

	xor	dx,dx
	mov	ax,cx			; recover day count

	xor	di,di			; assume zero leap days
	sub	ax,60			; less than 60 days
	 jc	no_leap_days		; means no leap days to subtract
	mov	bx,1461			; 1461 = days in four years
	div	bx			; get number of leap years since 1980
	inc	ax			; include 1980
	sub	cx,ax			; normalize years to 365 days
	mov	di,ax			; save proper leap day count
no_leap_days:

	xor	dx,dx
	xchg	ax,cx			; DX:AX = years since 1980 * 365
	mov	bx,365
	div	bx			; get number of years since 1980
	or	dx,dx			; check for zero days left
	 jnz	days_left
	dec	ax			; dec year count
	mov	dx,365			; set day count to last day of last year
days_left:

	mov	yearsSince1980,ax	; save the year
	xchg	ax,si			; save in SI

	xor	bx,bx
	mov	cx,12
get_month:				; find the appropriate month
	cmp	dx,totaldays[bx]
	 jbe	got_month
	inc bx ! inc bx
	loop	get_month
got_month:
	shr	bx,1			; BX = month
	mov	month,bl
	
	dec	bx
	shl	bx,1			; BX = index to previous months
	sub	dx,totaldays[bx]	; get days into this month

	cmp	bx,2			; if it's FEB 29th we've lost a day
	 jne	not_leap_yr		; check it's FEB
	test	si,3
	 jnz	not_leap_yr		; but is it a leap year ?
	shr si,1 ! shr si,1		; divide years by 4
	inc	si			; include this year
	cmp	si,di			; compare against leap day adjustment
	 jne	not_leap_yr
	inc	dx			; put 29th feb back again
not_leap_yr:
	mov	dayOfMonth,dl		; save the day of the month
	ret


ConvertDate:
    sub cx,1980         ; Base year is 1980
	jc	xset_date_error
	cmp	cx,2100-1980		; Year in valid range ?
	jnc	xset_date_error
	mov	bl,dh			; Month to BL
	xor	bh,bh
	dec	bx			; Adjust month to 0-11
	cmp	bl,12			; Month in valid range ?
	jnc	xset_date_error
	mov	al,dl			; Day of month
	cbw
	test	cl,3			; Leap year ?
	jnz	not_leap_year		; Jump if not
	cmp	dh,3			; After February ?
	cmc
	adc	al,ah			; Increment days in current year if so
	cmp	dl,29			; Day of month 29 ?
	jz	day_valid		; Valid if so

not_leap_year:
	dec	dx
	cmp	dl,monthdays[bx]	; Day of month within range for non-leap
					; year ?
	jnc	xset_date_error

day_valid:
	shl	bx,1
	add	ax,totaldays[bx]	; Get total days in current year

	push	ax

	mov	ax,365
	mul	cx			; Convert year to days since 1-1-1980
	mov	cx,ax

;	if total (ax) >= 60 (Feb 29 1980) then
;	  leap$days = (total - 60) / (365 * 4) + 1

	sub	ax,60			; Before first leap year date
	jc	noleap			; Jump if so
	mov	bx,365*4		; 4 years worth of days (365 * 4)
	sub	dx,dx
	div	bx			; Get number of leap years - 1
	inc	ax
	add	cx,ax			; CX now has total days including leap
					; days

noleap:
	dec	cx

	pop	ax

	add	cx,ax			; Get total days since 1-1-1980
	clc
	ret

xset_date_error:
	stc
	ret

rw_clock_common:
	mov	cx,6			; read/write 6 characters
	mov	dx,offset biosDate	; DX -> 6 byte buffer
	les	si,clk_device		; Get the address of the Clock Device
	cmp	si,-1			; Has a valid device been selected
	 jne	rw_clock_common10
	add	sp,WORD			; discard near return address
rw_clock_common10:
	ret


;	*****************************
;	***    DOS Function 38    ***
;	*** Get/Set Country Data  ***
;	*****************************
	Public	func38
func38:
	xor	ah,ah			; Generate 16 Bit country
	cmp	al,0FFh			; FF means country code in BX
	 jne	f38_10
	xchg	ax,bx			; AX = real country code
f38_10:
	xchg	ax,dx			; DX = country
	test	dx,dx			; dos_AL = 0 get the current country
     jz f38_get         
	inc	ax			; now check for dos_DX = FFFF
	 jz	f38_set			;  which means set country code
	dec	ax			; no, return buffer to normal
f38_get:
	test	dx,dx			; Get current?
	 jnz	f38_g10			; Yes
	mov	dx,cur_country		; use current country
f38_g10:
; look for (and if neccessary load) type 1 info into buffer
	xchg	ax,di			; ES:DI -> buffer
	mov	bx,cur_cp		; bx=codepage
	call	f38_get_info		; get info in current codepage
	 jnc	f38_g20
	push ss ! pop ds
	xor	bx,bx			; now try any codepage
	call	f38_get_info		; if none for current codepage
	 jc	f38_error		; No Match Found
f38_g20:
	lea	si,EXCI_CI_DATAOFF[si]	; point at CI_, not EXCI_ data
	mov	bx,CI_CODE[si]		; Return the selected country code
	mov	cx,CI_STATICLEN/2
	rep	movsw
	
if NLSFUNC
	push	ss
	pop	ds
;	call	get_dseg		; DS back to PCMODE
endif
	call	return_BX		; return country code in BX
	xchg	ax,bx
	jmp	return_AX_CLC		; and in AX

f38_get_info:
	push es ! push di ! push dx	; save pointer to buffer
	mov	al,1			; Get data list seperators etc...
	call	f65_get_info		; DS:SI -> extended country info buffer
	pop dx ! pop di ! pop es	; ES:DI -> users buffer
	ret

f38_set:
	mov	bx,cur_cp		; bx=codepage
	and	bx,f38_flag		; force CP to zero if 1st time here
	call	f38_set_country		; Update the Internal Data Structures
	 jc	f38_error
f38_s20:
	mov	f38_flag,0FFFFh		; Country Code Set Successfully
	mov	ax,cur_country		; and return the current country
	jmp	return_AX_CLC		;  to the user


f38_error:

if NLSFUNC
	push	ss
	pop	ds
;	call	get_dseg		; DS back to PCMODE
endif
	mov	ax,ED_FILE		; This is the Error to return 
    jmp error_exit      


f38_set_country:
; On Entry:
;	BX = codepage
;	DX = country
; On Exit:
;	AX = error code
; preserve codepage/country info if there is an error (ie do type 1 last!)
;
	mov	al,2			; Get uppercase & filename table
	mov	di,offset Ucasetbl
	mov	cx,info2_len
	call	f38_update
	 jc	f38_seterr
	mov	al,4			; Get uppercase & filename table
	mov	di,offset FileUcasetbl
	mov	cx,info4_len
	call	f38_update
	 jc	f38_seterr
	mov	al,5			; Get Legal file characters
	mov	di,offset FileCharstbl
	mov	cx,info5_len
	call	f38_update
	 jc	f38_seterr
	mov	al,6			; Get Collating table
	mov	di,offset Collatingtbl
	mov	cx,info6_len
	call	f38_update
	 jc	f38_seterr
	mov	al,7			; Get double byte character set table
	mov	di,offset DBCS_tbl
	mov	cx,info7_len
	call	f38_update
	 jc	f38_seterr
	mov	al,1			; Get data list seperators etc...
	mov	di,offset country_data	; do last since this updates
	mov	cx,info1_len		; cur_country/cur_cp
	call	f38_update
;	 jc	f38_seterr
;	clc
	ret
f38_seterr:
	mov	ax,ED_FILE		; return file not found error
	ret

f38_update:
	push	ds			; save important registers
	push	bx			; codepage
	push	cx			; count for move
	push	dx			; country
	push	di			; destination offset for move
	push	ds			; destination segment
	call	f65_get_info		; DS:SI -> buffer with country info
	pop	es			; destination seg in ES
	pop	di			; ES:DI -> destination of move
	pop	dx			; country
	pop	cx			; bytes to move
	pop	bx			; codepage back again
	 jc	f38_update10		; any problems ?
	rep	movsb			; no, copy the data
f38_update10:
	pop	ds			; DS back to PCMDSEG
	ret

;	*****************************
;	***    DOS Function 65    ***
;	*** Extended Country Data ***
;	*****************************
;
;CODEPAGE	equ	437			; Return Standard Code Page
;
;	Get Extended Country Code Sub-Functions
;
func65_dt	dw	0FFFFh			; 00 Illegal Sub-Function
		dw	offset country_data	; 01 Extended Country Info
		dw	offset Ucasetbl		; 02 UpperCase Table
		dw	0FFFFh			; 03 Invalid Subfunction
		dw	offset FileUcasetbl	; 04 FileName Upper Case Table
		dw	offset FileCharstbl	; 05 Valid Filename Characters
		dw	offset Collatingtbl	; 06 Collating Sequence
		dw	offset DBCS_tbl		; 07 DBCS Environment Vector 
func65_dtl	equ	(offset $ - offset func65_dt)/2

	Public	func65
func65:
	cmp	al,func65_dtl		; is sub-function 0-7 ?
	 jb	func65_read_table
	sub	al,20h			; now check for 20-22
	 jb	f65_invalid
	 je	func6520		; it's upper case character
	sub	al,2
	 je	func6522
	 jb	func6521
	sub	al,1			; how about 6523 ?
	 jnz	f65_invalid
;	jmp	func6523

func6523:
;--------
; On Entry:
;	DX = character to check
; On Exit:
;	AX = 0, No
;	AX = 1, Yes
;	AX = 2, neither
;
	push	ds
	pop	es
	mov	di,offset NoYesChars	; 'NnYy'
	cbw				; assume No (AX=0)	
	xchg	ax,dx			; AX = char, DX = answer
	call	dbcs_lead		; is it 1st of a DBCS pair
	 jne	func6523_10
	scasw				; check 'N'
	 je	func6523_30
	inc	dx			; assume Yes (DX=1)
	scasw				; check 'Y'
	jmps	func6523_20
func6523_10:
	scasb				; check 'N'
	 je	func6523_30
	scasb				; check 'n'
	 je	func6523_30
	inc	dx			; assume Yes (DX=1)
	scasb				; check 'Y'
	 je	func6523_30
	scasb				; check 'y'
func6523_20:
	 je	func6523_30
	inc	dx			; it's neither (DX=2)
func6523_30:
	xchg	ax,dx			; return result in AX
	jmp	return_AX_CLC		; Return the Code Page

func6522:
;--------
; Upper case ASCIIZ string at ES:DX
	mov	cx,0FFFFh		; calculate the length
	mov	di,dx			;  of the string
;	mov	al,0
	repne	scasb
	not	cx			; CX = length, including 0
;	jmp	func6521		; now use upper case CX bytes

func6521:
;--------
; Upper case string of CX bytes at ES:DX
	mov	si,dx
	mov	di,dx			; point SI & DI at string
f6521_10:
	lods	es:al			; read a character
	call	dbcs_lead		; is it 1st of a DBCS pair
	 jne	f6521_20
	stosb				; store 1st byte of this pair
	movs	es:byte ptr [di],es:byte ptr [si]
					; copy 2nd byte
	dec	cx			; 1st byte of pair
	loopnz	f6521_10		; go around for another one
	ret				; time to go...
f6521_20:
	call	toupper			; upper case the character
	stosb				; 
	loop	f6521_10		; go and do another one
	ret

func6520:
;--------
; Upper case character DL
	xchg	ax,dx			; character in AX
	call	toupper			; upper case it
	mov	dl,al			; return in AL and DL
	jmp	return_DX		; set return code

f65_invalid:
;-----------
; short jump to invalid function
	jmp	invalid_function


func65_read_table:
;-----------------
	cmp	cx,5			; Check for valid buffer size
	 jb	f65_invalid
	cbw				; Get the request sub-function
	mov	si,ax			; into SI
	shl	si,1
	mov	si,func65_dt[si]
	inc	si			; is SI = 0FFFFh
	 jz	f65_invalid		; if so it's an invalid function
	dec	si

	cmp	dx,0ffffh
	 jne	f65_21			; FFFF means
	mov	dx,cur_country		;  use default country
f65_21:
	cmp	bx,0ffffh
	 jne	f65_22			; FFFF means
	mov	bx,cur_cp		;  use default codepage
f65_22:
	call	f65_get_info		; DS:SI -> extended info for this pair
	mov	ax,ED_FILE		; On Error return File Not Found
	 jnc	f65_23			; for any error
	push ss ! pop ds
	jmp	error_exit		; so Quit
f65_23:
	les	bx,ss:int21regs_ptr	; point to callers registers
	mov	ax,es:reg_AX[bx]	; get the subfunction number
	mov	cx,es:reg_CX[bx]	; this much data is requested
	mov	di,es:reg_DI[bx]	; Get the Parameter Block Offset
	mov	es,es:reg_ES[bx]	; and Segment
	stosb				; fill in Info ID
	cmp	al,1			; 1 is special - the rest
	 jne	f65_30			;  want a DWORD ptr
	cmp	cx,EXCI_MAXLEN		; Check CX against the sub-function 1
	 jbe	f65_25			; maximum and force CX to this value
	mov	cx,EXCI_MAXLEN		; if it is greater
f65_25:
	call	return_CX		; Return the number of bytes transfered
	sub	cx,EXI_DATA_LEN		; Adjust count for 3 byte header 
	mov ax,cx ! stosw		; fill in EXCI_LENGTH
	push	cx			; Save the count and copy as much
	cmp	cx,EXCI_STATLEN		; valid data a possible. IE at most
	 jbe f65_27			; EXCI_STATLEN bytes	
	mov	cx,EXCI_STATLEN
f65_27:
	rep	movsb			; just copy the data

⌨️ 快捷键说明

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