1 ; **************************************************************************** 2 ; clock386.s (Retro Unix 386 v1) - 'clock' prints current date & time 3 ; ---------------------------------------------------------------------------- 4 ; 5 ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix) 6 ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013) 7 ; 8 ; Retro UNIX 8086 v1 - 'clock.asm' file 9 ; 10 ; Derived from 'Retro UNIX 8086 v1' source code by Erdogan Tan 11 ; (v0.1 - Beginning: 11/07/2012) 12 ; 13 ; [ Last Modification: 26/02/2022 ] 14 ; 15 ; Derived from UNIX Operating System (v1.0 for PDP-11) 16 ; (Original) Source Code by Ken Thompson (Bell Laboratories, 1971-1972) 17 ; **************************************************************************** 18 ; clock1.s (21/02/2022, Retro UNIX 386 v1&v1.1&v1.2) 19 ; clock0.s (17/10/2015-18/11/2015, Retro UNIX 386 v1, NASM 2.11, 32 bit) 20 ; CLOCK.ASM, 12/12/2013 - 17/01/2014 (Retro UNIX 8086 v1, MASM 6.11) 21 ; 17/10/2015 22 23 ; UNIX v1 system calls 24 _rele equ 0 25 _exit equ 1 26 _fork equ 2 27 _read equ 3 28 _write equ 4 29 _open equ 5 30 _close equ 6 31 _wait equ 7 32 _creat equ 8 33 _link equ 9 34 _unlink equ 10 35 _exec equ 11 36 _chdir equ 12 37 _time equ 13 38 _mkdir equ 14 39 _chmod equ 15 40 _chown equ 16 41 _break equ 17 42 _stat equ 18 43 _seek equ 19 44 _tell equ 20 45 _mount equ 21 46 _umount equ 22 47 _setuid equ 23 48 _getuid equ 24 49 _stime equ 25 50 _quit equ 26 51 _intr equ 27 52 _fstat equ 28 53 _emt equ 29 54 _mdate equ 30 55 _stty equ 31 56 _gtty equ 32 57 _ilgins equ 33 58 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 59 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 60 61 %macro sys 1-4 62 ; 03/09/2015 63 ; 13/04/2015 64 ; Retro UNIX 386 v1 system call. 65 %if %0 >= 2 66 mov ebx, %2 67 %if %0 >= 3 68 mov ecx, %3 69 %if %0 = 4 70 mov edx, %4 71 %endif 72 %endif 73 %endif 74 mov eax, %1 75 int 30h 76 %endmacro 77 78 ; Retro UNIX 386 v1 system call format: 79 ; sys systemcall (eax) , , 80 81 [BITS 32] ; We need 32-bit intructions for protected mode 82 83 [ORG 0] 84 85 START_CODE: 86 sys _write, 1, b_dt_txt, dt_size+1 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 00000000 BB01000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 00000005 B9[E1020000] <1> mov ecx, %3 69 <1> %if %0 = 4 70 0000000A BA19000000 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 0000000F B804000000 <1> mov eax, %1 75 00000014 CD30 <1> int 30h 87 ;jc short terminate 88 sys _gtty, 0, 1 ; get console tty, cursor position 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 00000016 BB00000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 0000001B B901000000 <1> mov ecx, %3 69 <1> %if %0 = 4 70 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 00000020 B820000000 <1> mov eax, %1 75 00000025 CD30 <1> int 30h 89 ;jc short terminate 90 00000027 A2[FB020000] mov [ttynum], al 91 0000002C 3C07 cmp al, 7 92 0000002E 7609 jna short x1 93 ;mov word [dt_txt], 0D07h 94 00000030 C605[E3020000]07 mov byte [dt_txt+1], 07h ; 21/02/2022 95 00000037 EB09 jmp short clk0 96 x1: 97 00000039 66891D[DF020000] mov [cursor_pos], bx ; cursor position 98 00000040 31D2 xor edx, edx ; 0 99 clk0: 100 sys _time 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 <1> mov ecx, %3 69 <1> %if %0 = 4 70 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 00000042 B80D000000 <1> mov eax, %1 75 00000047 CD30 <1> int 30h 101 ; EAX = Unix epoch time 102 00000049 39D0 cmp eax, edx 103 ;je clk4 104 ; 21/02/2022 105 0000004B 750A jne short clk1 106 clk4: 107 0000004D 90 nop 108 0000004E 90 nop 109 0000004F 90 nop 110 00000050 90 nop 111 ; 21/02/2022 112 00000051 31C0 xor eax, eax 113 00000053 40 inc eax 114 00000054 48 dec eax 115 00000055 EBEB jmp short clk0 116 clk1: 117 00000057 50 push eax ; current time 118 00000058 E890000000 call ctime 119 ;sys _write, 1, cbuf, 25 120 ; 25/02/2022 121 sys _write, 1, cbuf, 26 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 0000005D BB01000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 00000062 B9[C4020000] <1> mov ecx, %3 69 <1> %if %0 = 4 70 00000067 BA1A000000 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 0000006C B804000000 <1> mov eax, %1 75 00000071 CD30 <1> int 30h 122 sys _gtty, 0, 0 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 00000073 BB00000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 00000078 B900000000 <1> mov ecx, %3 69 <1> %if %0 = 4 70 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 0000007D B820000000 <1> mov eax, %1 75 00000082 CD30 <1> int 30h 123 ;or bx, bx 124 00000084 09DB or ebx, ebx ; 21/02/2022 125 00000086 741F jz short clk2 126 sys _read, 0, chr, 1 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 00000088 BB00000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 0000008D B9[FA020000] <1> mov ecx, %3 69 <1> %if %0 = 4 70 00000092 BA01000000 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 00000097 B803000000 <1> mov eax, %1 75 0000009C CD30 <1> int 30h 127 0000009E 803D[FA020000]1B cmp byte [chr], 1Bh ; ESC key 128 000000A5 7439 je short clk3 ; exit 129 clk2: 130 000000A7 803D[FB020000]08 cmp byte [ttynum], 8 131 000000AE 7218 jb short clk_pt 132 sys _write, 1, dt_txt, dt_size 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 000000B0 BB01000000 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 000000B5 B9[E2020000] <1> mov ecx, %3 69 <1> %if %0 = 4 70 000000BA BA18000000 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 000000BF B804000000 <1> mov eax, %1 75 000000C4 CD30 <1> int 30h 133 000000C6 EB12 jmp short x2 134 clk_pt: 135 000000C8 668B15[DF020000] mov dx, [cursor_pos] 136 000000CF 66B9FFFF mov cx, 0FFFFh ; set cursor position only 137 ; 26/02/2022 (ebx = 0) 138 ;;xor bx, bx ; set for console tty 139 ;xor ebx, ebx ; 21/02/2022 140 sys _stty 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 <1> mov ecx, %3 69 <1> %if %0 = 4 70 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 000000D3 B81F000000 <1> mov eax, %1 75 000000D8 CD30 <1> int 30h 141 x2: 142 000000DA 5A pop edx ; current time -> previous time 143 000000DB E962FFFFFF jmp clk0 144 clk3: 145 000000E0 58 pop eax 146 terminate: 147 sys _exit 62 <1> 63 <1> 64 <1> 65 <1> %if %0 >= 2 66 <1> mov ebx, %2 67 <1> %if %0 >= 3 68 <1> mov ecx, %3 69 <1> %if %0 = 4 70 <1> mov edx, %4 71 <1> %endif 72 <1> %endif 73 <1> %endif 74 000000E1 B801000000 <1> mov eax, %1 75 000000E6 CD30 <1> int 30h 148 ; 21/02/2022 149 ;clk4: 150 ; nop 151 ; nop 152 ; nop 153 ; nop 154 ; jmp clk0 155 ; 21/02/2022 156 000000E8 E960FFFFFF jmp clk4 157 158 ;%include 'ctime386.inc' 159 %include 'ctime386.s' ; 21/02/2022 160 <1> ; **************************************************************************** 161 <1> ; ctime386.inc (Retro Unix 386 v1 - /bin/ls - list file or directory) 162 <1> ; ---------------------------------------------------------------------------- 163 <1> ; RETRO UNIX 386 (Retro Unix == Turkish Rational Unix) 164 <1> ; Operating System Project (v0.2) by ERDOGAN TAN (Beginning: 24/12/2013) 165 <1> ; 166 <1> ; [ Last Modification: 25/02/2022 ] 167 <1> ; 168 <1> ; Derived from 'CTIME.INC' source code file of 'Retro UNIX 8086 v1' 169 <1> ; operating system project, /bin/ls source code by Erdogan Tan 170 <1> ; (28/11/2013) 171 <1> ; 172 <1> ; Derived from 'ctime.c' file of original UNIX v5 (usr/source/s3/ctime.c) 173 <1> ; 174 <1> ; ls386.s (ls0.s) 23/09/2015 - 06/10/2015 175 <1> ; include ctime386.inc 176 <1> ; 177 <1> ; **************************************************************************** 178 <1> ; ctime386.s (06/10/2015 - 21/02/2022) 179 <1> 180 <1> ; Assembler: NASM 2.11 (NASM 2.15, 2022) 181 <1> 182 <1> ;timezone equ 5*60*60 183 <1> 184 <1> ctime: ; ctime(at) 185 <1> ; int *at; 186 <1> ; { 187 <1> ; return(asctime(localtime(at))); 188 <1> ; } 189 <1> 190 <1> ; EAX = unix epoch time (in seconds) 191 <1> 192 <1> ;call localtime 193 <1> ;call asctime 194 <1> 195 <1> ;retn 196 <1> 197 <1> localtime: 198 <1> ; localtime(tim) 199 <1> ; int tim[]; 200 <1> ; { 201 <1> ; register int *t, *ct, dayno; 202 <1> ; int daylbegin, daylend; 203 <1> ; int copyt[2]; 204 <1> ; t = copyt; 205 <1> ; t[0] = tim[0]; 206 <1> ; t[1] = tim[1]; 207 <1> ; dpadd(t, -timezone); 208 <1> ; ct = gmtime(t); 209 <1> ; dayno = ct[YDAY]; 210 <1> ; if (nixonflg && (ct[YEAR]>74 || ct[YEAR]==74 && (dayno > 5 || 211 <1> ; dayno==5 && ct[HOUR]>=2))) { 212 <1> ; daylight =| 1; 213 <1> ; daylbegin = -1; 214 <1> ; daylend = 367; 215 <1> ; } else { 216 <1> ; daylbegin = sunday(ct, 119); /* last Sun in Apr */ 217 <1> ; daylend = sunday(ct, 303); /* last Sun in Oct */ 218 <1> ; } 219 <1> ; if (daylight && 220 <1> ; (dayno>daylbegin || (dayno==daylbegin && ct[HOUR]>=2)) && 221 <1> ; (dayno ; dpadd(t, 1*60*60); 223 <1> ; ct = gmtime(t); 224 <1> ; ct[ISDAY]++; 225 <1> ; } 226 <1> ; return(ct); 227 <1> ; } 228 <1> 229 <1> ;sub eax, timezone 230 <1> 231 <1> ;push eax 232 <1> 233 000000ED E882000000 <1> call gmtime 234 <1> ; if (nixonflg && (ct[YEAR]>74 || ct[YEAR]==74 && (dayno > 5 || 235 <1> ; dayno==5 && ct[HOUR]>=2))) { 236 <1> ;cmp byte [nixonflg], 0 237 <1> ;jna short lt1 238 <1> ;cmp word [year], 1974 239 <1> ;jb short lt1 240 <1> ;ja short lt0 241 <1> ;cmp word [yday], 5 242 <1> ;jb short lt1 243 <1> ;ja short lt0 244 <1> ;cmp word [hour], 2 245 <1> ;jb short lt1 246 <1> ; nixonflag > 0 247 <1> ;lt0: 248 <1> ;mov word [daylight], 1 249 <1> ;mov word [daylbegin], -1 250 <1> ;mov word [daylend], 367 251 <1> ; ;jmp short lt2 252 <1> 253 <1> ; } else { 254 <1> ;lt1: 255 <1> ; mov cx, 119 256 <1> ; call sunday ; sunday(ct, 119); /* last Sun in Apr */ 257 <1> ; mov [daylbegin], cx 258 <1> ; mov cx, 303 259 <1> ; call sunday ; sunday(ct, 303); /* last Sun in Oct */ 260 <1> ; mov [daylend], cx 261 <1> ;lt2: 262 <1> ; if (daylight && 263 <1> ; (dayno>daylbegin || (dayno==daylbegin && ct[HOUR]>=2)) && 264 <1> ; (dayno 266 <1> ; pop eax 267 <1> 268 <1> ;cmp byte [daylight], 0 269 <1> ;jna short lt5 270 <1> 271 <1> ;mov cx, [yday] 272 <1> 273 <1> ;cmp cx, [daylbegin] 274 <1> ;jb short lt5 275 <1> ;ja short lt3 276 <1> ;cmp word [hour], 2 277 <1> ;jb short lt5 278 <1> ;jmp short lt4 279 <1> ;lt3: 280 <1> ;cmp cx, [daylend] 281 <1> ;jb short lt4 282 <1> ;ja short lt5 283 <1> ;cmp word [hour], 1 284 <1> ;jnb short lt5 285 <1> ;lt4: 286 <1> ;add eax, 1*60*60 287 <1> ;call gmtime 288 <1> ;inc word [isday] 289 <1> ;lt5: 290 <1> ; } 291 <1> ; return(ct); 292 <1> ; } 293 <1> 294 <1> ;retn 295 <1> 296 <1> ; 21/02/2022 (Retro UNIX 386 v1&v1.1&v1.2) 297 <1> asctime: 298 <1> ; asctime(t) 299 <1> ;int *t; 300 <1> ;{ 301 <1> ; register char *cp, *ncp; 302 <1> ; register int *tp; 303 <1> ; 304 <1> ; cp = cbuf; 305 <1> ; for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); 306 <1> ; ncp = &"SunMonTueWedThuFriSat"[3*t[6]]; 307 <1> ; cp = cbuf; 308 <1> ; *cp++ = *ncp++; 309 <1> ; *cp++ = *ncp++; 310 <1> ; *cp++ = *ncp++; 311 <1> ; cp++; 312 <1> ; tp = &t[4]; 313 <1> ; ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; 314 <1> ; *cp++ = *ncp++; 315 <1> ; *cp++ = *ncp++; 316 <1> ; *cp++ = *ncp++; 317 <1> ; cp = numb(cp, *--tp); 318 <1> ; cp = numb(cp, *--tp+100); 319 <1> ; cp = numb(cp, *--tp+100); 320 <1> ; cp = numb(cp, *--tp+100); 321 <1> ; cp =+ 2; 322 <1> ; cp = numb(cp, t[YEAR]); 323 <1> ; return(cbuf); 324 <1> ;} 325 <1> 326 <1> ;;mov edi, cbuf 327 <1> ;;mov esi, ncp0 328 <1> ;;mov ecx, 13 329 <1> ;;movsw 330 <1> ; 331 000000F2 BF[C4020000] <1> mov edi, cbuf 332 <1> ;movzx esi, word [wday] 333 <1> ;shl si, 2 334 <1> ;add esi, ncp1 335 <1> ;movsd 336 000000F7 0FB735[5A020000] <1> movzx esi, word [month] 337 <1> ;shl si, 2 338 000000FE C1E602 <1> shl esi, 2 ; 21/02/2022 339 00000101 81C6[90020000] <1> add esi, ncp2 - 4 340 00000107 A5 <1> movsd 341 <1> ;movzx eax, word [day] 342 00000108 66A1[58020000] <1> mov ax, [day] 343 <1> ;mov cx, 10 344 0000010E B10A <1> mov cl, 10 345 00000110 E824010000 <1> call numb 346 00000115 B020 <1> mov al, 20h 347 00000117 AA <1> stosb 348 <1> ; 349 00000118 66A1[5C020000] <1> mov ax, [year] 350 0000011E B564 <1> mov ch, 100 351 00000120 F6F5 <1> div ch 352 <1> ;push ax ; 353 <1> ; 21/02/2022 354 00000122 50 <1> push eax 355 00000123 6698 <1> cbw ; century (19, 20) 356 00000125 E80F010000 <1> call numb 357 <1> ;pop ax 358 <1> ; 21/02/2022 359 0000012A 58 <1> pop eax 360 0000012B 88E0 <1> mov al, ah 361 0000012D 6698 <1> cbw ; year (0 to 99) 362 0000012F E805010000 <1> call numb 363 00000134 B020 <1> mov al, 20h 364 00000136 AA <1> stosb 365 <1> ; 366 <1> ;movzx esi, word [wday] 367 <1> ; 21/02/2022 368 00000137 668B35[5E020000] <1> mov si, [wday] 369 <1> ;shl si, 2 370 0000013E C1E602 <1> shl esi, 2 ; 21/02/2022 371 00000141 81C6[78020000] <1> add esi, ncp1 372 00000147 A5 <1> movsd 373 <1> ; 374 00000148 66A1[56020000] <1> mov ax, [hour] 375 0000014E E8E6000000 <1> call numb 376 00000153 B03A <1> mov al, ':' 377 00000155 AA <1> stosb 378 00000156 66A1[54020000] <1> mov ax, [minute] 379 0000015C E8D8000000 <1> call numb 380 00000161 B03A <1> mov al, ':' 381 00000163 AA <1> stosb 382 00000164 66A1[52020000] <1> mov ax, [second] 383 0000016A E8CA000000 <1> call numb 384 0000016F B020 <1> mov al, 20h 385 00000171 AA <1> stosb 386 <1> ;mov ax, [year] 387 <1> ;mov ch, 100 388 <1> ;div ch 389 <1> ;push ax ; 390 <1> ;cbw ; century (19, 20) 391 <1> ;call numb 392 <1> ;pop ax 393 <1> ;mov al, ah 394 <1> ;cbw ; year (0 to 99) 395 <1> ;call numb 396 <1> ;mov al, 20h 397 <1> ;stosb 398 <1> ;xor al, al 399 <1> ;stosb 400 <1> 401 <1> ; 25/02/2022 402 00000172 AA <1> stosb 403 <1> 404 00000173 C3 <1> retn 405 <1> 406 <1> gmtime: 407 <1> ; 21/02/2022 (Retro UNIX 386 v1&v1.1&v1.2) 408 <1> ; 24/11/2013 (yday, wday) 409 <1> ; Retro UNIX 8086 v1 - UNIX.ASM (20/06/2013) 410 <1> ; Retro UNIX 8086 v1 feature/procedure only! 411 <1> ; 'convert_from_epoch' procedure prototype: 412 <1> ; UNIXCOPY.ASM, 10/03/2013 413 <1> ; 30/11/2012 414 <1> ; Derived from DALLAS Semiconductor 415 <1> ; Application Note 31 (DS1602/DS1603) 416 <1> ; 6 May 1998 417 <1> ; 418 <1> ; INPUT: 419 <1> ; DX:AX = Unix (Epoch) Time 420 <1> ; 421 <1> ; ((Modified registers: AX, DX, CX, BX)) 422 <1> ; 423 00000174 31D2 <1> xor edx, edx 424 <1> ;mov ecx, 60 425 <1> ; 21/02/2022 426 00000176 31C9 <1> xor ecx, ecx 427 00000178 B13C <1> mov cl, 60 428 0000017A F7F1 <1> div ecx 429 <1> ;mov [imin], eax ; whole minutes 430 <1> ; since 1/1/1970 431 0000017C 668915[52020000] <1> mov [second], dx ; leftover seconds 432 <1> ;mov ecx, 60 433 00000183 29D2 <1> sub edx, edx 434 00000185 F7F1 <1> div ecx 435 <1> ;mov [ihrs], eax ; whole hours 436 <1> ; since 1/1/1970 437 00000187 668915[54020000] <1> mov [minute], dx ; leftover minutes 438 <1> ;mov ecx, 24 439 0000018E 31D2 <1> xor edx, edx 440 00000190 B118 <1> mov cl, 24 441 00000192 F7F1 <1> div ecx 442 <1> ;mov [iday], ax ; whole days 443 <1> ; since 1/1/1970 444 00000194 66A3[5E020000] <1> mov [wday], ax ; 24/11/2013 445 0000019A 668915[56020000] <1> mov [hour], dx ; leftover hours 446 000001A1 05DB020000 <1> add eax, 365+366 ; whole day since 447 <1> ; 1/1/1968 448 <1> ;mov [iday], ax 449 000001A6 50 <1> push eax 450 000001A7 66B9B505 <1> mov cx, (4*365)+1 ; 4 years = 1461 days 451 000001AB 29D2 <1> sub edx, edx 452 000001AD F7F1 <1> div ecx 453 000001AF 59 <1> pop ecx 454 <1> ;mov [lday], ax ; count of quadyrs (4 years) 455 000001B0 52 <1> push edx 456 <1> ;mov [qday], dx ; days since quadyr began 457 000001B1 6683FA3C <1> cmp dx, 31+29 ; if past feb 29 then 458 000001B5 F5 <1> cmc ; add this quadyr's leap day 459 000001B6 83D000 <1> adc eax, 0 ; to # of qadyrs (leap days) 460 <1> ;mov [lday], ax ; since 1968 461 <1> ;mov cx, [iday] 462 000001B9 91 <1> xchg ecx, eax ; CX = lday, AX = iday 463 000001BA 29C8 <1> sub eax, ecx ; iday - lday 464 <1> ;mov ecx, 365 465 000001BC 66B96D01 <1> mov cx, 365 466 000001C0 31D2 <1> xor edx, edx ; DX = 0 467 <1> ; EAX = iday-lday 468 000001C2 F7F1 <1> div ecx 469 <1> ;mov [iyrs], ax ; whole years since 1968 470 <1> ; jday = iday - (iyrs*365) - lday 471 <1> ;mov [jday], dx ; days since 1/1 of current year 472 <1> ;add eax, 1968 ; compute year 473 000001C4 05B0070000 <1> add eax, 1968 474 000001C9 66A3[5C020000] <1> mov [year], ax 475 000001CF 89C3 <1> mov ebx, eax 476 <1> ;mov ax, [qday] 477 000001D1 58 <1> pop eax 478 000001D2 663D6D01 <1> cmp ax, 365 ; if qday <= 365 and qday >= 60 479 000001D6 7709 <1> ja short L1 ; jday = jday +1 480 000001D8 6683F83C <1> cmp ax, 60 ; if past 2/29 and leap year then 481 000001DC F5 <1> cmc ; add a leap day to the # of whole 482 000001DD 6683D200 <1> adc dx, 0 ; days since 1/1 of current year 483 <1> L1: 484 <1> ;mov [jday], dx 485 <1> ;mov [yday], dx ; 24/11/2013 486 <1> ;mov cx, 12 ; estimate month 487 <1> ;xchg cx, dx ; CX = jday, DX = month 488 <1> ; 21/02/2022 489 000001E1 30ED <1> xor ch, ch 490 000001E3 B10C <1> mov cl, 12 491 000001E5 87CA <1> xchg ecx, edx 492 000001E7 66B86E01 <1> mov ax, 366 ; mday, max. days since 1/1 is 365 493 000001EB 6683E303 <1> and bx, 11b ; year mod 4 (and bx, 3) 494 <1> L2: ; Month calculation ; 0 to 11 (11 to 0) 495 <1> ;cmp cx, ax ; mday = # of days passed from 1/1 496 <1> ; 21/02/2022 497 000001EF 39C1 <1> cmp ecx, eax 498 000001F1 7319 <1> jnb short L3 499 <1> ;dec dx ; month = month - 1 500 <1> ; 21/02/2022 501 000001F3 4A <1> dec edx 502 <1> ;shl dx, 1 503 000001F4 D1E2 <1> shl edx, 1 ; 21/02/2022 504 000001F6 668B82[60020000] <1> mov ax, [edx+DMonth] ; # elapsed days at 1st of month 505 <1> ;shr dx, 1 ; dx = month - 1 (0 to 11) 506 000001FD D1EA <1> shr edx, 1 ; 21/02/2022 507 000001FF 6683FA01 <1> cmp dx, 1 ; if month > 2 and year mod 4 = 0 508 00000203 76EA <1> jna short L2 ; then mday = mday + 1 509 00000205 08DB <1> or bl, bl ; if past 2/29 and leap year then 510 00000207 75E6 <1> jnz short L2 ; add leap day (to mday) 511 <1> ;inc ax ; mday = mday + 1 512 <1> ; 21/02/2022 513 00000209 40 <1> inc eax 514 0000020A EBE3 <1> jmp short L2 515 <1> L3: 516 <1> ;inc dx ; -> dx = month, 1 to 12 517 <1> ; 21/02/2022 518 0000020C 42 <1> inc edx 519 0000020D 668915[5A020000] <1> mov [month], dx 520 <1> ;sub cx, ax ; day = jday - mday + 1 521 <1> ;inc cx 522 <1> ; 21/02/2022 523 00000214 29C1 <1> sub ecx, eax 524 00000216 41 <1> inc ecx 525 00000217 66890D[58020000] <1> mov [day], cx 526 <1> 527 <1> ; eax, ebx, ecx, edx are changed at return 528 <1> ; output -> 529 <1> ; [year], [month], [day], [hour], [minute], [second] 530 <1> ; [yday] -> 24/11/2013 531 <1> ; [wday] -> 24/11/2013 532 <1> ; 533 <1> ; 24/11/2013 534 0000021E 66A1[5E020000] <1> mov ax, [wday] ; [iday] 535 <1> ;xor dx, dx 536 00000224 31D2 <1> xor edx, edx ; 21/02/2022 537 00000226 6683C004 <1> add ax, 4 538 <1> ; NOTE: January 1, 1970 was THURSDAY 539 <1> ; ch = 0 540 0000022A B107 <1> mov cl, 7 541 0000022C 66F7F1 <1> div cx 542 0000022F 668915[5E020000] <1> mov [wday], dx ; week of the day, 0 to 6 543 <1> ; 0 = sunday ... 6 = saturday 544 <1> ;mov word [isday], 0 545 <1> 546 00000236 C3 <1> retn 547 <1> 548 <1> ;sunday: 549 <1> ; sunday(at, ad) 550 <1> ; int *at; 551 <1> ; { 552 <1> ; register int *t, d; 553 <1> ; t = at; 554 <1> ; d = ad; 555 <1> ; d = ad + dysize(t[YEAR]) - 365; 556 <1> ; return(d - (d - t[YDAY] + t[WDAY] + 700) % 7); 557 <1> ; } 558 <1> 559 <1> ;mov dx, [year] 560 <1> ;call dysize 561 <1> ;sub ax, 365 562 <1> ; add cx, ax 563 <1> ; test word [year], 11b 564 <1> ; jnz short sunday1 565 <1> ; CX = 119 (77h) or CX = 303 (12Fh) 566 <1> ;inc cx 567 <1> ; inc cl 568 <1> ;sunday1: 569 <1> ; mov ax, cx 570 <1> ; add ax, [wday] 571 <1> ;adc ax, 700 572 <1> ; add ax, 700 573 <1> ; sub ax, [yday] 574 <1> ;xor dx, dx 575 <1> ; mov bx, 7 576 <1> ;div bx 577 <1> ; div bl 578 <1> ; sub cx, bx 579 <1> ; retn 580 <1> 581 <1> ;dysize: 582 <1> ; dysize(y) 583 <1> ; { 584 <1> ; if((y%4) == 0) 585 <1> ; return(366); 586 <1> ; return(365); 587 <1> ; } 588 <1> 589 <1> ; mov ax, 365 590 <1> ; test dx, 11b 591 <1> ; jnz short dysize1 592 <1> ; ;inc ax 593 00000237 FEC0 <1> inc al 594 <1> ;dysize1: 595 <1> ; retn 596 <1> 597 <1> numb: ; AX = 0 to 99 598 <1> ; 599 <1> ; numb(acp, n) 600 <1> ; { 601 <1> ; register char *cp; 602 <1> ; 603 <1> ; cp = acp; 604 <1> ; cp++; 605 <1> ; if (n>=10) 606 <1> ; *cp++ = (n/10)%10 + '0'; 607 <1> ; else 608 <1> ; *cp++ = ' '; 609 <1> ; *cp++ = n%10 + '0'; 610 <1> ; return(cp); 611 <1> ; } 612 <1> ; 613 <1> ;mov cl, 10 614 00000239 6683F80A <1> cmp ax, 10 615 0000023D 7306 <1> jnb short nb1 616 0000023F 88C4 <1> mov ah, al 617 00000241 30C0 <1> xor al, al ; 0 618 00000243 EB04 <1> jmp short nb2 619 <1> nb1: 620 00000245 F6F1 <1> div cl 621 00000247 88E2 <1> mov dl, ah 622 <1> 623 <1> nb2: 624 00000249 0430 <1> add al, '0' 625 0000024B AA <1> stosb ; digit 1 626 0000024C 88E0 <1> mov al, ah 627 0000024E 0430 <1> add al, '0' 628 00000250 AA <1> stosb ; digit 2 629 00000251 C3 <1> retn 630 <1> 631 <1> ;;; DATA 632 <1> 633 <1> ;daylight: db 1 ; int daylight 1; /* Allow daylight conversion */ 634 <1> ;nixonflg: db 0 ; int nixonflg 0; /* Daylight time all year around */ 635 <1> ;daylbegin: dw 0 636 <1> ;daylend: dw 0 637 <1> 638 <1> ct: 639 <1> ; 24/11/2013 (re-order) 640 <1> ; 641 <1> ; Retro UNIX 8086 v1 - UNIX.ASM 642 <1> ; 09/04/2013 epoch variables 643 <1> ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013 644 <1> ; 645 <1> 646 00000252 0000 <1> second: dw 0 647 00000254 0000 <1> minute: dw 0 648 00000256 0000 <1> hour: dw 0 649 00000258 0100 <1> day: dw 1 650 0000025A 0100 <1> month: dw 1 651 0000025C B207 <1> year: dw 1970 652 0000025E 0000 <1> wday: dw 0 ; 24/11/2013 653 <1> ;yday: dw 0 ; 24/11/2013 654 <1> ;isday: dw 0 ; 24/11/2013 655 <1> 656 <1> DMonth: 657 00000260 0000 <1> dw 0 658 00000262 1F00 <1> dw 31 659 00000264 3B00 <1> dw 59 660 00000266 5A00 <1> dw 90 661 00000268 7800 <1> dw 120 662 0000026A 9700 <1> dw 151 663 0000026C B500 <1> dw 181 664 0000026E D400 <1> dw 212 665 00000270 F300 <1> dw 243 666 00000272 1101 <1> dw 273 667 00000274 3001 <1> dw 304 668 00000276 4E01 <1> dw 334 669 <1> 670 <1> ;ncp0: db "Day Mon 00 00:00:00 1970", 0, 0 671 00000278 53756E204D6F6E2054- <1> ncp1: db "Sun Mon Tue Wed Thu Fri Sat " 671 00000281 756520576564205468- <1> 671 0000028A 752046726920536174- <1> 671 00000293 20 <1> 672 00000294 4A616E20466562204D- <1> ncp2: db "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec " 672 0000029D 617220417072204D61- <1> 672 000002A6 79204A756E204A756C- <1> 672 000002AF 204175672053657020- <1> 672 000002B8 4F6374204E6F762044- <1> 672 000002C1 656320 <1> 673 <1> 674 <1> cbuf: ; char cbuf[26] 675 <1> ;times 26 db 0 676 <1> ; 25/02/2022 677 000002C4 00 <1> times 27 db 0 678 <1> 679 <1> ;; ctime.c (Unix v5) 680 <1> ; 681 <1> ;# 682 <1> ;/* 683 <1> ; * This routine converts time as follows. 684 <1> ; * The epoch is 0000 Jan 1 1970 GMT. 685 <1> ; * The argument time is in seconds since then. 686 <1> ; * The localtime(t) entry returns a pointer to an array 687 <1> ; * containing 688 <1> ; * seconds (0-59) 689 <1> ; * minutes (0-59) 690 <1> ; * hours (0-23) 691 <1> ; * day of month (1-31) 692 <1> ; * month (0-11) 693 <1> ; * year-1970 694 <1> ; * weekday (0-6, Sun is 0) 695 <1> ; * day of the year 696 <1> ; * daylight savings flag 697 <1> ; * 698 <1> ; * The routine corrects for daylight saving 699 <1> ; * time and will work in any time zone provided 700 <1> ; * "timezone" is adjusted to the difference between 701 <1> ; * Greenwich and local standard time (measured in seconds). 702 <1> ; * In places like Michigan "daylight" must 703 <1> ; * be initialized to 0 to prevent the conversion 704 <1> ; * to daylight time. 705 <1> ; * 706 <1> ; * "nixonflg,", if set to 1, will 707 <1> ; * cause daylight savings time all year around 708 <1> ; * independently of "daylight". 709 <1> ; * 710 <1> ; * The routine does not work 711 <1> ; * in Saudi Arabia which runs on Solar time. 712 <1> ; * 713 <1> ; * asctime(tvec)) 714 <1> ; * where tvec is produced by localtime 715 <1> ; * returns a ptr to a character string 716 <1> ; * that has the ascii time in the form 717 <1> ; * Thu Jan 01 00:00:00 1970n0\; * 01234567890123456789012345 719 <1> ; * 0 1 2 720 <1> ; * 721 <1> ; * ctime(t) just calls localtime, then asctime. 722 <1> ; */ 723 <1> ;char cbuf[26]; 724 <1> ;int dmsize[12] 725 <1> ;{ 726 <1> ; 31, 727 <1> ; 28, 728 <1> ; 31, 729 <1> ; 30, 730 <1> ; 31, 731 <1> ; 30, 732 <1> ; 31, 733 <1> ; 31, 734 <1> ; 30, 735 <1> ; 31, 736 <1> ; 30, 737 <1> ; 31 738 <1> ;}; 739 <1> ; 740 <1> ;int timezone 5*60*60; 741 <1> ;int tzname[] 742 <1> ;{ 743 <1> ; "EST", 744 <1> ; "EDT", 745 <1> ;}; 746 <1> ;int daylight 1; /* Allow daylight conversion */ 747 <1> ;int nixonflg 0; /* Daylight time all year around */ 748 <1> ; 749 <1> ;#define SEC 0 750 <1> ;#define MIN 1 751 <1> ;#define HOUR 2 752 <1> ;#define MDAY 3 753 <1> ;#define MON 4 754 <1> ;#define YEAR 5 755 <1> ;#define WDAY 6 756 <1> ;#define YDAY 7 757 <1> ;#define ISDAY 8 758 <1> ; 759 <1> ;ctime(at) 760 <1> ;int *at; 761 <1> ;{ 762 <1> ; return(asctime(localtime(at))); 763 <1> ;} 764 <1> ; 765 <1> ;localtime(tim) 766 <1> ;int tim[]; 767 <1> ;{ 768 <1> ; register int *t, *ct, dayno; 769 <1> ; int daylbegin, daylend; 770 <1> ; int copyt[2]; 771 <1> ; 772 <1> ; t = copyt; 773 <1> ; t[0] = tim[0]; 774 <1> ; t[1] = tim[1]; 775 <1> ; dpadd(t, -timezone); 776 <1> ; ct = gmtime(t); 777 <1> ; dayno = ct[YDAY]; 778 <1> ; if (nixonflg && (ct[YEAR]>74 || ct[YEAR]==74 && (dayno > 5 || 779 <1> ; dayno==5 && ct[HOUR]>=2))) { 780 <1> ; daylight =| 1; 781 <1> ; daylbegin = -1; 782 <1> ; daylend = 367; 783 <1> ; } else { 784 <1> ; daylbegin = sunday(ct, 119); /* last Sun in Apr */ 785 <1> ; daylend = sunday(ct, 303); /* last Sun in Oct */ 786 <1> ; } 787 <1> ; if (daylight && 788 <1> ; (dayno>daylbegin || (dayno==daylbegin && ct[HOUR]>=2)) && 789 <1> ; (dayno ; dpadd(t, 1*60*60); 791 <1> ; ct = gmtime(t); 792 <1> ; ct[ISDAY]++; 793 <1> ; } 794 <1> ; return(ct); 795 <1> ;} 796 <1> ; 797 <1> ;sunday(at, ad) 798 <1> ;int *at; 799 <1> ;{ 800 <1> ; register int *t, d; 801 <1> ; 802 <1> ; t = at; 803 <1> ; d = ad; 804 <1> ; d = ad + dysize(t[YEAR]) - 365; 805 <1> ; return(d - (d - t[YDAY] + t[WDAY] + 700) % 7); 806 <1> ;} 807 <1> ; 808 <1> ;gmtime(tim) 809 <1> ;int tim[]; 810 <1> ;{ 811 <1> ; register int d0, d1; 812 <1> ; register *tp; 813 <1> ; static xtime[9]; 814 <1> ; extern int ldivr; 815 <1> ; 816 <1> ; /* 817 <1> ; * break initial number into 818 <1> ; * multiples of 8 hours. 819 <1> ; * (28800 = 60*60*8) 820 <1> ; */ 821 <1> ; 822 <1> ; d0 = ldiv(tim[0], tim[1], 28800); 823 <1> ; d1 = ldivr; 824 <1> ; tp = &xtime[0]; 825 <1> ; 826 <1> ; /* 827 <1> ; * generate hours:minutes:seconds 828 <1> ; */ 829 <1> ; 830 <1> ; *tp++ = d1%60; 831 <1> ; d1 =/ 60; 832 <1> ; *tp++ = d1%60; 833 <1> ; d1 =/ 60; 834 <1> ; d1 =+ (d0%3)*8; 835 <1> ; d0 =/ 3; 836 <1> ; *tp++ = d1; 837 <1> ; 838 <1> ; /* 839 <1> ; * d0 is the day number. 840 <1> ; * generate day of the week. 841 <1> ; */ 842 <1> ; 843 <1> ; xtime[WDAY] = (d0+4)%7; 844 <1> ; 845 <1> ; /* 846 <1> ; * year number 847 <1> ; */ 848 <1> ; for(d1=70; d0 >= dysize(d1); d1++) 849 <1> ; d0 =- dysize(d1); 850 <1> ; xtime[YEAR] = d1; 851 <1> ; xtime[YDAY] = d0; 852 <1> ; 853 <1> ; /* 854 <1> ; * generate month 855 <1> ; */ 856 <1> ; 857 <1> ; if (dysize(d1)==366) 858 <1> ; dmsize[1] = 29; 859 <1> ; for(d1=0; d0 >= dmsize[d1]; d1++) 860 <1> ; d0 =- dmsize[d1]; 861 <1> ; dmsize[1] = 28; 862 <1> ; *tp++ = d0+1; 863 <1> ; *tp++ = d1; 864 <1> ; xtime[ISDAY] = 0; 865 <1> ; return(xtime); 866 <1> ;} 867 <1> ; 868 <1> ;asctime(t) 869 <1> ;int *t; 870 <1> ;{ 871 <1> ; register char *cp, *ncp; 872 <1> ; register int *tp; 873 <1> ; 874 <1> ; cp = cbuf; 875 <1> ; for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); 876 <1> ; ncp = &"SunMonTueWedThuFriSat"[3*t[6]]; 877 <1> ; cp = cbuf; 878 <1> ; *cp++ = *ncp++; 879 <1> ; *cp++ = *ncp++; 880 <1> ; *cp++ = *ncp++; 881 <1> ; cp++; 882 <1> ; tp = &t[4]; 883 <1> ; ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; 884 <1> ; *cp++ = *ncp++; 885 <1> ; *cp++ = *ncp++; 886 <1> ; *cp++ = *ncp++; 887 <1> ; cp = numb(cp, *--tp); 888 <1> ; cp = numb(cp, *--tp+100); 889 <1> ; cp = numb(cp, *--tp+100); 890 <1> ; cp = numb(cp, *--tp+100); 891 <1> ; cp =+ 2; 892 <1> ; cp = numb(cp, t[YEAR]); 893 <1> ; return(cbuf); 894 <1> ;} 895 <1> ; 896 <1> ;dysize(y) 897 <1> ;{ 898 <1> ; if((y%4) == 0) 899 <1> ; return(366); 900 <1> ; return(365); 901 <1> ;} 902 <1> ; 903 <1> ; 904 <1> ;numb: 905 <1> ; 906 <1> ; 907 <1> ;numb(acp, n) 908 <1> ;{ 909 <1> ; register char *cp; 910 <1> ; cp = acp; 911 <1> ; cp++; 912 <1> ; if (n>=10) 913 <1> ; *cp++ = (n/10)%10 + '0'; 914 <1> ; else 915 <1> ; *cp++ = ' '; 916 <1> ; *cp++ = n%10 + '0'; 917 <1> ; return(cp); 918 <1> ;} 919 <1> ; 160 161 000002DF 0000 cursor_pos: dw 0 162 163 b_dt_txt: 164 000002E1 07 db 07h 165 dt_txt: 166 000002E2 0D db 0Dh 167 000002E3 0A db 0Ah 168 000002E4 43757272656E742044- db 'Current Date & Time : ' 168 000002ED 61746520262054696D- 168 000002F6 65203A20 169 dt_size equ $ - dt_txt 170 000002FA 00 chr: db 0 171 000002FB 00 ttynum: db 0