This repository has been archived by the owner. It is now read-only.
Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
232 lines (214 sloc)
6.88 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; | |
| ; 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 | |