• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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