mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-29 09:05:46 +00:00
231 lines
6.9 KiB
NASM
231 lines
6.9 KiB
NASM
|
;
|
|||
|
; Time and date functions for MSDOS
|
|||
|
;
|
|||
|
|
|||
|
INCLUDE DOSSEG.ASM
|
|||
|
|
|||
|
CODE SEGMENT BYTE PUBLIC 'CODE'
|
|||
|
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
|||
|
|
|||
|
.xlist
|
|||
|
.xcref
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
INCLUDE DEVSYM.ASM
|
|||
|
.cref
|
|||
|
.list
|
|||
|
|
|||
|
TITLE TIME - time and date functions
|
|||
|
NAME TIME
|
|||
|
|
|||
|
|
|||
|
i_need DAY,BYTE
|
|||
|
i_need MONTH,BYTE
|
|||
|
i_need YEAR,WORD
|
|||
|
i_need WEEKDAY,BYTE
|
|||
|
i_need TIMEBUF,6
|
|||
|
i_need BCLOCK,DWORD
|
|||
|
i_need DAYCNT,WORD
|
|||
|
i_need YRTAB,8
|
|||
|
i_need MONTAB,12
|
|||
|
|
|||
|
FOURYEARS = 3*365 + 366
|
|||
|
|
|||
|
SUBTTL DATE16, READTIME, DODATE -- GUTS OF TIME AND DATE
|
|||
|
PAGE
|
|||
|
;
|
|||
|
; Date16 returns the current date in AX, current time in DX
|
|||
|
; AX - YYYYYYYMMMMDDDDD years months days
|
|||
|
; DX - HHHHHMMMMMMSSSSS hours minutes seconds/2
|
|||
|
;
|
|||
|
procedure DATE16,NEAR
|
|||
|
ASSUME DS:DOSGROUP,ES:NOTHING
|
|||
|
PUSH CX
|
|||
|
PUSH ES
|
|||
|
CALL READTIME
|
|||
|
POP ES
|
|||
|
SHL CL,1 ;Minutes to left part of byte
|
|||
|
SHL CL,1
|
|||
|
SHL CX,1 ;Push hours and minutes to left end
|
|||
|
SHL CX,1
|
|||
|
SHL CX,1
|
|||
|
SHR DH,1 ;Count every two seconds
|
|||
|
OR CL,DH ;Combine seconds with hours and minutes
|
|||
|
MOV DX,CX
|
|||
|
MOV AX,WORD PTR [MONTH] ;Fetch month and year
|
|||
|
MOV CL,4
|
|||
|
SHL AL,CL ;Push month to left to make room for day
|
|||
|
SHL AX,1
|
|||
|
POP CX
|
|||
|
OR AL,[DAY]
|
|||
|
RET
|
|||
|
DATE16 ENDP
|
|||
|
|
|||
|
procedure READTIME,NEAR
|
|||
|
|
|||
|
ASSUME DS:DOSGROUP,ES:NOTHING
|
|||
|
;Gets time in CX:DX. Figures new date if it has changed.
|
|||
|
;Uses AX, CX, DX.
|
|||
|
|
|||
|
PUSH SI
|
|||
|
PUSH BX
|
|||
|
MOV BX,OFFSET DOSGROUP:TIMEBUF
|
|||
|
MOV CX,6
|
|||
|
XOR DX,DX
|
|||
|
MOV AX,DX
|
|||
|
invoke SETREAD
|
|||
|
PUSH DS
|
|||
|
LDS SI,[BCLOCK]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
invoke DEVIOCALL2 ;Get correct date and time
|
|||
|
POP DS
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
POP BX
|
|||
|
POP SI
|
|||
|
MOV AX,WORD PTR [TIMEBUF]
|
|||
|
MOV CX,WORD PTR [TIMEBUF+2]
|
|||
|
MOV DX,WORD PTR [TIMEBUF+4]
|
|||
|
CMP AX,[DAYCNT] ;See if day count is the same
|
|||
|
JZ RET22
|
|||
|
CMP AX,FOURYEARS*30 ;Number of days in 120 years
|
|||
|
JAE RET22 ;Ignore if too large
|
|||
|
MOV [DAYCNT],AX
|
|||
|
PUSH SI
|
|||
|
PUSH CX
|
|||
|
PUSH DX ;Save time
|
|||
|
XOR DX,DX
|
|||
|
MOV CX,FOURYEARS ;Number of days in 4 years
|
|||
|
DIV CX ;Compute number of 4-year units
|
|||
|
SHL AX,1
|
|||
|
SHL AX,1
|
|||
|
SHL AX,1 ;Multiply by 8 (no. of half-years)
|
|||
|
MOV CX,AX ;<240 implies AH=0
|
|||
|
MOV SI,OFFSET DOSGROUP:YRTAB ;Table of days in each year
|
|||
|
CALL DSLIDE ;Find out which of four years we're in
|
|||
|
SHR CX,1 ;Convert half-years to whole years
|
|||
|
JNC SK ;Extra half-year?
|
|||
|
ADD DX,200
|
|||
|
SK:
|
|||
|
CALL SETYEAR
|
|||
|
MOV CL,1 ;At least at first month in year
|
|||
|
MOV SI,OFFSET DOSGROUP:MONTAB ;Table of days in each month
|
|||
|
CALL DSLIDE ;Find out which month we're in
|
|||
|
MOV [MONTH],CL
|
|||
|
INC DX ;Remainder is day of month (start with one)
|
|||
|
MOV [DAY],DL
|
|||
|
CALL WKDAY ;Set day of week
|
|||
|
POP DX
|
|||
|
POP CX
|
|||
|
POP SI
|
|||
|
RET22: RET
|
|||
|
READTIME ENDP
|
|||
|
|
|||
|
procedure DSLIDE,NEAR
|
|||
|
MOV AH,0
|
|||
|
DSLIDE1:
|
|||
|
LODSB ;Get count of days
|
|||
|
CMP DX,AX ;See if it will fit
|
|||
|
JB RET23 ;If not, done
|
|||
|
SUB DX,AX
|
|||
|
INC CX ;Count one more month/year
|
|||
|
JMP SHORT DSLIDE1
|
|||
|
DSLIDE ENDP
|
|||
|
|
|||
|
procedure SETYEAR,NEAR
|
|||
|
;Set year with value in CX. Adjust length of February for this year.
|
|||
|
MOV BYTE PTR [YEAR],CL
|
|||
|
|
|||
|
CHKYR:
|
|||
|
TEST CL,3 ;Check for leap year
|
|||
|
MOV AL,28
|
|||
|
JNZ SAVFEB ;28 days if no leap year
|
|||
|
INC AL ;Add leap day
|
|||
|
SAVFEB:
|
|||
|
MOV [MONTAB+1],AL ;Store for February
|
|||
|
RET23: RET
|
|||
|
SETYEAR ENDP
|
|||
|
|
|||
|
procedure DODATE,NEAR
|
|||
|
ASSUME DS:DOSGROUP,ES:NOTHING
|
|||
|
CALL CHKYR ;Set Feb. up for new year
|
|||
|
MOV AL,DH
|
|||
|
MOV BX,OFFSET DOSGROUP:MONTAB-1
|
|||
|
XLAT ;Look up days in month
|
|||
|
CMP AL,DL
|
|||
|
MOV AL,-1 ;Restore error flag, just in case
|
|||
|
JB RET25 ;Error if too many days
|
|||
|
CALL SETYEAR
|
|||
|
MOV WORD PTR [DAY],DX ;Set both day and month
|
|||
|
SHR CX,1
|
|||
|
SHR CX,1
|
|||
|
MOV AX,FOURYEARS
|
|||
|
MOV BX,DX
|
|||
|
MUL CX
|
|||
|
MOV CL,BYTE PTR [YEAR]
|
|||
|
AND CL,3
|
|||
|
MOV SI,OFFSET DOSGROUP:YRTAB
|
|||
|
MOV DX,AX
|
|||
|
SHL CX,1 ;Two entries per year, so double count
|
|||
|
CALL DSUM ;Add up the days in each year
|
|||
|
MOV CL,BH ;Month of year
|
|||
|
MOV SI,OFFSET DOSGROUP:MONTAB
|
|||
|
DEC CX ;Account for months starting with one
|
|||
|
CALL DSUM ;Add up days in each month
|
|||
|
MOV CL,BL ;Day of month
|
|||
|
DEC CX ;Account for days starting with one
|
|||
|
ADD DX,CX ;Add in to day total
|
|||
|
XCHG AX,DX ;Get day count in AX
|
|||
|
MOV [DAYCNT],AX
|
|||
|
PUSH SI
|
|||
|
PUSH BX
|
|||
|
PUSH AX
|
|||
|
MOV BX,OFFSET DOSGROUP:TIMEBUF
|
|||
|
MOV CX,6
|
|||
|
XOR DX,DX
|
|||
|
MOV AX,DX
|
|||
|
PUSH BX
|
|||
|
invoke SETREAD
|
|||
|
ASSUME ES:DOSGROUP
|
|||
|
PUSH DS
|
|||
|
LDS SI,[BCLOCK]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
invoke DEVIOCALL2 ;Get correct date and time
|
|||
|
POP DS
|
|||
|
POP BX
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
invoke SETWRITE
|
|||
|
POP WORD PTR [TIMEBUF]
|
|||
|
PUSH DS
|
|||
|
LDS SI,[BCLOCK]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
invoke DEVIOCALL2 ;Set the date
|
|||
|
POP DS
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
POP BX
|
|||
|
POP SI
|
|||
|
WKDAY:
|
|||
|
MOV AX,[DAYCNT]
|
|||
|
XOR DX,DX
|
|||
|
MOV CX,7
|
|||
|
INC AX
|
|||
|
INC AX ;First day was Tuesday
|
|||
|
DIV CX ;Compute day of week
|
|||
|
MOV [WEEKDAY],DL
|
|||
|
XOR AL,AL ;Flag OK
|
|||
|
RET25: RET
|
|||
|
DODATE ENDP
|
|||
|
|
|||
|
procedure DSUM,NEAR
|
|||
|
MOV AH,0
|
|||
|
JCXZ RET25
|
|||
|
DSUM1:
|
|||
|
LODSB
|
|||
|
ADD DX,AX
|
|||
|
LOOP DSUM1
|
|||
|
RET
|
|||
|
DSUM ENDP
|
|||
|
|
|||
|
do_ext
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END
|
|||
|
|