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