1 | #include <com32.h> |
---|
2 | #include <string.h> |
---|
3 | #include "ctime.h" |
---|
4 | |
---|
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 | |
---|
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 | } |
---|