diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/TIME.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to '')
| -rw-r--r-- | v4.0/src/DOS/TIME.ASM | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/v4.0/src/DOS/TIME.ASM b/v4.0/src/DOS/TIME.ASM new file mode 100644 index 0000000..0d3895c --- /dev/null +++ b/v4.0/src/DOS/TIME.ASM | |||
| @@ -0,0 +1,380 @@ | |||
| 1 | ; SCCSID = @(#)time.asm 1.1 85/04/10 | ||
| 2 | TITLE TIME - time and date functions | ||
| 3 | NAME TIME | ||
| 4 | ; | ||
| 5 | ; System Calls and low level routines for DATE and TIME | ||
| 6 | ; | ||
| 7 | ; $GET_DATE | ||
| 8 | ; $SET_DATE | ||
| 9 | ; $GET_TIME | ||
| 10 | ; $SET_TIME | ||
| 11 | ; DATE16 | ||
| 12 | ; READTIME | ||
| 13 | ; DSLIDE | ||
| 14 | ; SETYEAR | ||
| 15 | ; DODATE | ||
| 16 | ; DSUM | ||
| 17 | ; | ||
| 18 | ; Modification history: | ||
| 19 | ; | ||
| 20 | ; Created: ARR 30 March 1983 | ||
| 21 | ; | ||
| 22 | |||
| 23 | .xlist | ||
| 24 | ; | ||
| 25 | ; get the appropriate segment definitions | ||
| 26 | ; | ||
| 27 | include dosseg.asm | ||
| 28 | |||
| 29 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 30 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 31 | |||
| 32 | .xcref | ||
| 33 | INCLUDE DOSSYM.INC | ||
| 34 | INCLUDE DEVSYM.INC | ||
| 35 | .cref | ||
| 36 | .list | ||
| 37 | |||
| 38 | |||
| 39 | i_need DAY,BYTE | ||
| 40 | i_need MONTH,BYTE | ||
| 41 | i_need YEAR,WORD | ||
| 42 | i_need WEEKDAY,BYTE | ||
| 43 | i_need TIMEBUF,6 | ||
| 44 | i_need BCLOCK,DWORD | ||
| 45 | i_need DAYCNT,WORD | ||
| 46 | i_need YRTAB,8 | ||
| 47 | i_need MONTAB,12 | ||
| 48 | i_need DATE_FLAG,WORD | ||
| 49 | |||
| 50 | FOURYEARS = 3*365 + 366 | ||
| 51 | |||
| 52 | SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45 | ||
| 53 | PAGE | ||
| 54 | procedure $GET_DATE,NEAR | ||
| 55 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 56 | |||
| 57 | ; Inputs: | ||
| 58 | ; None | ||
| 59 | ; Function: | ||
| 60 | ; Return current date | ||
| 61 | ; Returns: | ||
| 62 | ; Date in CX:DX | ||
| 63 | |||
| 64 | Context DS | ||
| 65 | CALL READTIME ;Check for rollover to next day | ||
| 66 | MOV AX,[YEAR] | ||
| 67 | ; | ||
| 68 | ; WARNING!!!! DAY and MONTH must be adjacently allocated! | ||
| 69 | ; | ||
| 70 | MOV BX,WORD PTR [DAY] ; fetch both day and month | ||
| 71 | invoke get_user_stack ;Get pointer to user registers | ||
| 72 | ASSUME DS:NOTHING | ||
| 73 | MOV [SI.user_DX],BX ;DH=month, DL=day | ||
| 74 | ADD AX,1980 ;Put bias back | ||
| 75 | MOV [SI.user_CX],AX ;CX=year | ||
| 76 | MOV AL,BYTE PTR [WEEKDAY] | ||
| 77 | return | ||
| 78 | EndProc $GET_DATE | ||
| 79 | |||
| 80 | procedure $SET_DATE,NEAR ;System call 43 | ||
| 81 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 82 | |||
| 83 | ; Inputs: | ||
| 84 | ; CX:DX valid date | ||
| 85 | ; Function: | ||
| 86 | ; Set current date | ||
| 87 | ; Returns: | ||
| 88 | ; AL = -1 date bad, = 0 OK | ||
| 89 | |||
| 90 | MOV AL,-1 ;Be ready to flag error | ||
| 91 | SUB CX,1980 ;Fix bias in year | ||
| 92 | retc ;Error if not big enough | ||
| 93 | CMP CX,119 ;Year must be less than 2100 | ||
| 94 | JA RET24 | ||
| 95 | OR DH,DH | ||
| 96 | retz | ||
| 97 | OR DL,DL | ||
| 98 | retz ;Error if either month or day is 0 | ||
| 99 | CMP DH,12 ;Check against max. month | ||
| 100 | JA RET24 | ||
| 101 | Context DS | ||
| 102 | invoke DODATE | ||
| 103 | RET24: return | ||
| 104 | EndProc $SET_DATE | ||
| 105 | |||
| 106 | procedure $GET_TIME,NEAR ;System call 44 | ||
| 107 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 108 | |||
| 109 | ; Inputs: | ||
| 110 | ; None | ||
| 111 | ; Function: | ||
| 112 | ; Get current time | ||
| 113 | ; Returns: | ||
| 114 | ; Time in CX:DX | ||
| 115 | |||
| 116 | Context DS | ||
| 117 | CALL READTIME | ||
| 118 | invoke get_user_stack ;Get pointer to user registers | ||
| 119 | MOV [SI.user_DX],DX | ||
| 120 | MOV [SI.user_CX],CX | ||
| 121 | XOR AL,AL | ||
| 122 | RET26: return | ||
| 123 | EndProc $GET_TIME | ||
| 124 | |||
| 125 | procedure $SET_TIME,NEAR ;System call 45 | ||
| 126 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 127 | |||
| 128 | ; Inputs: | ||
| 129 | ; CX:DX = Time | ||
| 130 | ; Function: | ||
| 131 | ; Set time | ||
| 132 | ; Returns: | ||
| 133 | ; AL = -1 time bad, = 0 OK | ||
| 134 | |||
| 135 | MOV AL,-1 ;Flag in case of error | ||
| 136 | CMP CH,24 ;Check hours | ||
| 137 | JAE RET26 | ||
| 138 | CMP CL,60 ;Check minutes | ||
| 139 | JAE RET26 | ||
| 140 | CMP DH,60 ;Check seconds | ||
| 141 | JAE RET26 | ||
| 142 | CMP DL,100 ;Check 1/100's | ||
| 143 | JAE RET26 | ||
| 144 | PUSH CX | ||
| 145 | PUSH DX | ||
| 146 | Context DS | ||
| 147 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 148 | MOV CX,6 | ||
| 149 | XOR DX,DX | ||
| 150 | MOV AX,DX | ||
| 151 | PUSH BX | ||
| 152 | invoke SETREAD | ||
| 153 | DOSAssume CS,<ES>,"TIME/SetRead" | ||
| 154 | PUSH DS | ||
| 155 | LDS SI,[BCLOCK] | ||
| 156 | ASSUME DS:NOTHING | ||
| 157 | invoke DEVIOCALL2 ;Get correct day count | ||
| 158 | POP DS | ||
| 159 | DOSAssume CS,<DS>,"TIME/DevIOCall2" | ||
| 160 | POP BX | ||
| 161 | invoke SETWRITE | ||
| 162 | POP WORD PTR [TIMEBUF+4] | ||
| 163 | POP WORD PTR [TIMEBUF+2] | ||
| 164 | LDS SI,[BCLOCK] | ||
| 165 | ASSUME DS:NOTHING | ||
| 166 | invoke DEVIOCALL2 ;Set the time | ||
| 167 | XOR AL,AL | ||
| 168 | return | ||
| 169 | EndProc $SET_TIME | ||
| 170 | |||
| 171 | SUBTTL DATE16, READTIME, DODATE -- GUTS OF TIME AND DATE | ||
| 172 | PAGE | ||
| 173 | |||
| 174 | ; | ||
| 175 | ; Date16 returns the current date in AX, current time in DX | ||
| 176 | ; AX - YYYYYYYMMMMDDDDD years months days | ||
| 177 | ; DX - HHHHHMMMMMMSSSSS hours minutes seconds/2 | ||
| 178 | ; | ||
| 179 | ; DS = DOSGROUP on output | ||
| 180 | |||
| 181 | procedure DATE16,NEAR | ||
| 182 | Context DS | ||
| 183 | ASSUME ES:NOTHING | ||
| 184 | PUSH CX | ||
| 185 | PUSH ES | ||
| 186 | CALL READTIME | ||
| 187 | POP ES | ||
| 188 | SHL CL,1 ;Minutes to left part of byte | ||
| 189 | SHL CL,1 | ||
| 190 | SHL CX,1 ;Push hours and minutes to left end | ||
| 191 | SHL CX,1 | ||
| 192 | SHL CX,1 | ||
| 193 | SHR DH,1 ;Count every two seconds | ||
| 194 | OR CL,DH ;Combine seconds with hours and minutes | ||
| 195 | MOV DX,CX | ||
| 196 | ; | ||
| 197 | ; WARNING! MONTH and YEAR must be adjacently allocated | ||
| 198 | ; | ||
| 199 | MOV AX,WORD PTR [MONTH] ;Fetch month and year | ||
| 200 | MOV CL,4 | ||
| 201 | SHL AL,CL ;Push month to left to make room for day | ||
| 202 | SHL AX,1 | ||
| 203 | POP CX | ||
| 204 | OR AL,[DAY] | ||
| 205 | return | ||
| 206 | EndProc DATE16 | ||
| 207 | |||
| 208 | ;Gets time in CX:DX. Figures new date if it has changed. | ||
| 209 | ;Uses AX, CX, DX. | ||
| 210 | |||
| 211 | procedure READTIME,NEAR | ||
| 212 | DOSAssume CS,<DS>,"ReadTime" | ||
| 213 | ASSUME ES:NOTHING | ||
| 214 | |||
| 215 | MOV [DATE_FLAG],0 ; reset date flag for CPMIO | ||
| 216 | PUSH SI | ||
| 217 | PUSH BX | ||
| 218 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 219 | MOV CX,6 | ||
| 220 | XOR DX,DX | ||
| 221 | MOV AX,DX | ||
| 222 | invoke SETREAD | ||
| 223 | PUSH DS | ||
| 224 | LDS SI,[BCLOCK] | ||
| 225 | ASSUME DS:NOTHING | ||
| 226 | invoke DEVIOCALL2 ;Get correct date and time | ||
| 227 | POP DS | ||
| 228 | DOSAssume CS,<DS>,"ReadTime/DevIOCall2" | ||
| 229 | POP BX | ||
| 230 | POP SI | ||
| 231 | MOV AX,WORD PTR [TIMEBUF] | ||
| 232 | MOV CX,WORD PTR [TIMEBUF+2] | ||
| 233 | MOV DX,WORD PTR [TIMEBUF+4] | ||
| 234 | CMP AX,[DAYCNT] ;See if day count is the same | ||
| 235 | retz | ||
| 236 | CMP AX,FOURYEARS*30 ;Number of days in 120 years | ||
| 237 | JAE RET22 ;Ignore if too large | ||
| 238 | MOV [DAYCNT],AX | ||
| 239 | PUSH SI | ||
| 240 | PUSH CX | ||
| 241 | PUSH DX ;Save time | ||
| 242 | XOR DX,DX | ||
| 243 | MOV CX,FOURYEARS ;Number of days in 4 years | ||
| 244 | DIV CX ;Compute number of 4-year units | ||
| 245 | SHL AX,1 | ||
| 246 | SHL AX,1 | ||
| 247 | SHL AX,1 ;Multiply by 8 (no. of half-years) | ||
| 248 | MOV CX,AX ;<240 implies AH=0 | ||
| 249 | MOV SI,OFFSET DOSGROUP:YRTAB;Table of days in each year | ||
| 250 | CALL DSLIDE ;Find out which of four years we're in | ||
| 251 | SHR CX,1 ;Convert half-years to whole years | ||
| 252 | JNC SK ;Extra half-year? | ||
| 253 | ADD DX,200 | ||
| 254 | SK: | ||
| 255 | CALL SETYEAR | ||
| 256 | MOV CL,1 ;At least at first month in year | ||
| 257 | MOV SI,OFFSET DOSGROUP:MONTAB ;Table of days in each month | ||
| 258 | CALL DSLIDE ;Find out which month we're in | ||
| 259 | MOV [MONTH],CL | ||
| 260 | INC DX ;Remainder is day of month (start with one) | ||
| 261 | MOV [DAY],DL | ||
| 262 | CALL WKDAY ;Set day of week | ||
| 263 | POP DX | ||
| 264 | POP CX | ||
| 265 | POP SI | ||
| 266 | RET22: return | ||
| 267 | EndProc READTIME | ||
| 268 | |||
| 269 | procedure DSLIDE,NEAR | ||
| 270 | MOV AH,0 | ||
| 271 | DSLIDE1: | ||
| 272 | LODSB ;Get count of days | ||
| 273 | CMP DX,AX ;See if it will fit | ||
| 274 | retc ;If not, done | ||
| 275 | SUB DX,AX | ||
| 276 | INC CX ;Count one more month/year | ||
| 277 | JMP SHORT DSLIDE1 | ||
| 278 | EndProc DSLIDE | ||
| 279 | |||
| 280 | procedure SETYEAR,NEAR | ||
| 281 | ;Set year with value in CX. Adjust length of February for this year. | ||
| 282 | MOV BYTE PTR [YEAR],CL | ||
| 283 | |||
| 284 | CHKYR: | ||
| 285 | TEST CL,3 ;Check for leap year | ||
| 286 | MOV AL,28 | ||
| 287 | JNZ SAVFEB ;28 days if no leap year | ||
| 288 | INC AL ;Add leap day | ||
| 289 | SAVFEB: | ||
| 290 | MOV [MONTAB+1],AL ;Store for February | ||
| 291 | RET23: return | ||
| 292 | EndProc SETYEAR | ||
| 293 | |||
| 294 | procedure DODATE,NEAR | ||
| 295 | DOSAssume CS,<DS>,"DoDate" | ||
| 296 | ASSUME ES:NOTHING | ||
| 297 | CALL CHKYR ;Set Feb. up for new year | ||
| 298 | MOV AL,DH | ||
| 299 | MOV BX,OFFSET DOSGROUP:MONTAB-1 | ||
| 300 | XLAT ;Look up days in month | ||
| 301 | CMP AL,DL | ||
| 302 | MOV AL,-1 ;Restore error flag, just in case | ||
| 303 | retc ;Error if too many days | ||
| 304 | CALL SETYEAR | ||
| 305 | ; | ||
| 306 | ; WARNING! DAY and MONTH must be adjacently allocated | ||
| 307 | ; | ||
| 308 | MOV WORD PTR [DAY],DX ;Set both day and month | ||
| 309 | SHR CX,1 | ||
| 310 | SHR CX,1 | ||
| 311 | MOV AX,FOURYEARS | ||
| 312 | MOV BX,DX | ||
| 313 | MUL CX | ||
| 314 | MOV CL,BYTE PTR [YEAR] | ||
| 315 | AND CL,3 | ||
| 316 | MOV SI,OFFSET DOSGROUP:YRTAB | ||
| 317 | MOV DX,AX | ||
| 318 | SHL CX,1 ;Two entries per year, so double count | ||
| 319 | CALL DSUM ;Add up the days in each year | ||
| 320 | MOV CL,BH ;Month of year | ||
| 321 | MOV SI,OFFSET DOSGROUP:MONTAB | ||
| 322 | DEC CX ;Account for months starting with one | ||
| 323 | CALL DSUM ;Add up days in each month | ||
| 324 | MOV CL,BL ;Day of month | ||
| 325 | DEC CX ;Account for days starting with one | ||
| 326 | ADD DX,CX ;Add in to day total | ||
| 327 | XCHG AX,DX ;Get day count in AX | ||
| 328 | MOV [DAYCNT],AX | ||
| 329 | PUSH SI | ||
| 330 | PUSH BX | ||
| 331 | PUSH AX | ||
| 332 | MOV BX,OFFSET DOSGROUP:TIMEBUF | ||
| 333 | MOV CX,6 | ||
| 334 | XOR DX,DX | ||
| 335 | MOV AX,DX | ||
| 336 | PUSH BX | ||
| 337 | invoke SETREAD | ||
| 338 | DOSAssume CS,<ES>,"DoDate/SetRead" | ||
| 339 | PUSH DS | ||
| 340 | LDS SI,[BCLOCK] | ||
| 341 | ASSUME DS:NOTHING | ||
| 342 | invoke DEVIOCALL2 ;Get correct date and time | ||
| 343 | POP DS | ||
| 344 | POP BX | ||
| 345 | DOSAssume CS,<DS>,"DoDate/DevIOCall2" | ||
| 346 | invoke SETWRITE | ||
| 347 | POP WORD PTR [TIMEBUF] | ||
| 348 | PUSH DS | ||
| 349 | LDS SI,[BCLOCK] | ||
| 350 | ASSUME DS:NOTHING | ||
| 351 | invoke DEVIOCALL2 ;Set the date | ||
| 352 | POP DS | ||
| 353 | DOSAssume CS,<DS>,"DoDate/DevIOCall2(second)" | ||
| 354 | POP BX | ||
| 355 | POP SI | ||
| 356 | WKDAY: | ||
| 357 | MOV AX,[DAYCNT] | ||
| 358 | XOR DX,DX | ||
| 359 | MOV CX,7 | ||
| 360 | INC AX | ||
| 361 | INC AX ;First day was Tuesday | ||
| 362 | DIV CX ;Compute day of week | ||
| 363 | MOV [WEEKDAY],DL | ||
| 364 | XOR AL,AL ;Flag OK | ||
| 365 | Ret25: return | ||
| 366 | EndProc DODATE | ||
| 367 | |||
| 368 | procedure DSUM,NEAR | ||
| 369 | MOV AH,0 | ||
| 370 | JCXZ RET25 | ||
| 371 | DSUM1: | ||
| 372 | LODSB | ||
| 373 | ADD DX,AX | ||
| 374 | LOOP DSUM1 | ||
| 375 | return | ||
| 376 | EndProc DSUM | ||
| 377 | |||
| 378 | CODE ENDS | ||
| 379 | END | ||
| 380 | \ No newline at end of file | ||