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