[e16e8f2] | 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 | } |
---|