1 #include <com32.h>
2 #include <string.h>
3 #include "ctime.h"
4
frombcd(uint8_t v)5 static uint8_t frombcd(uint8_t v)
6 {
7 uint8_t a = v & 0x0f;
8 uint8_t b = v >> 4;
9
10 return a + b*10;
11 }
12
posix_time(void)13 uint32_t posix_time(void)
14 {
15 /* Days from March 1 for a specific month, starting in March */
16 static const unsigned int yday[12] =
17 { 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
18 com32sys_t ir, d0, d1, t0;
19 unsigned int c, y, mo, d, h, m, s;
20 uint32_t t;
21
22 memset(&ir, 0, sizeof ir);
23
24 ir.eax.b[1] = 0x04;
25 __intcall(0x1A, &ir, &d0);
26
27 memset(&ir, 0, sizeof ir);
28 ir.eax.b[1] = 0x02;
29 __intcall(0x1A, &ir, &t0);
30
31 memset(&ir, 0, sizeof ir);
32 ir.eax.b[1] = 0x04;
33 __intcall(0x1A, &ir, &d1);
34
35 if (t0.ecx.b[1] < 0x12)
36 d0 = d1;
37
38 c = frombcd(d0.ecx.b[1]);
39 y = frombcd(d0.ecx.b[0]);
40 mo = frombcd(d0.edx.b[1]);
41 d = frombcd(d0.edx.b[0]);
42
43 h = frombcd(t0.ecx.b[1]);
44 m = frombcd(t0.ecx.b[0]);
45 s = frombcd(t0.edx.b[1]);
46
47 /* We of course have no idea about the timezone, so ignore it */
48
49 /*
50 * Look for impossible dates... this code was written in 2010, so
51 * assume any century less than 20 is just broken.
52 */
53 if (c < 20)
54 c = 20;
55 y += c*100;
56
57 /* Consider Jan and Feb as the last months of the previous year */
58 if (mo < 3) {
59 y--;
60 mo += 12;
61 }
62
63 /*
64 * Just in case: if the month is nonsense, don't read off the end
65 * of the table...
66 */
67 if (mo-3 > 11)
68 return 0;
69
70 t = y*365 + y/4 - y/100 + y/400 + yday[mo-3] + d - 719469;
71 t *= 24;
72 t += h;
73 t *= 60;
74 t += m;
75 t *= 60;
76 t += s;
77
78 return t;
79 }
80