3 #include "routix/time.h"
4 #include "routix/8254.h"
5 #include <routix/kstdio.h>
8 #include "routix/system.h"
12 static char dias_por_mes
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
13 enum { ENERO
, FEBRERO
, MARZO
, ABRIL
, MAYO
, JUNIO
, JULIO
, AGOSTO
, SEPTIEMBRE
, OCTUBRE
, NOVIEMBRE
, DICIEMBRE
};
14 static time_t reloj
=0;
17 byte
get_value(word registro
)
19 outportb_p(CMOS_C
, registro
);
20 return(inportb_p(CMOS_V
));
23 void set_value(word registro
, byte valor
)
25 outportb_p(CMOS_C
, registro
);
26 outportb_p(CMOS_V
, valor
);
35 int year
= get_year();
36 year
= ( year
>= 1970 ) ? 1900+year
: 2000+year
;
39 tm
.tm_sec
= get_sec();
40 tm
.tm_min
= get_min();
41 tm
.tm_hour
= get_hour();
42 tm
.tm_mday
= get_dayofmonth();
43 tm
.tm_mon
= get_month() - 1;
45 tm
.tm_wday
= get_dayofweek();
46 tm
.tm_yday
= day_of_year(tm
.tm_year
, tm
.tm_mon
, tm
.tm_mday
);
47 tm
.tm_isdst
= 0; // Cero por ahora
50 // Seteamos el valor del reloj
51 reloj
= mktime( &tm
);
52 kprintf("Seteando reloj: %d\n",reloj
);
57 inline void actualizar_reloj()
63 struct tm
*localtime(const time_t *clock
)
68 // Valores del momento actual
70 kprintf("localtime: null tod, seteando tod=reloj (%d ticks)\n",reloj
);
74 // Hay un tod especificado
76 kprintf("localtime: tod especificado, tod=*clock (%d ticks)\n",*clock
);
81 for ( tm
.tm_year
=ANIO_INICIO
; (tod
-= SEC_PER_YEAR(1900+tm
.tm_year
)) > 0; tm
.tm_year
++ ) ;
82 // Corregimos por el error en la última resta del for
83 tod
+= SEC_PER_YEAR(1900+tm
.tm_year
);
86 for ( tm
.tm_mon
=MES_INICIO
; (tod
-= SEC_PER_MONTH(tm
.tm_year
,tm
.tm_mon
)) > 0; tm
.tm_mon
++ ) ;
87 // Corregimos por el error en la última resta del for
88 tod
+= SEC_PER_MONTH(tm
.tm_year
,tm
.tm_mon
);
91 tm
.tm_mday
= (time_t) (tod
/ SEC_PER_DAY
);
92 tod
-= (tm
.tm_mday
* SEC_PER_DAY
);
95 tm
.tm_hour
= (time_t) (tod
/ SEC_PER_HOUR
);
96 tod
-= (tm
.tm_hour
* SEC_PER_HOUR
);
98 tm
.tm_min
= (time_t) (tod
/ SEC_PER_MIN
);
99 tm
.tm_sec
= tod
- (tm
.tm_min
* SEC_PER_MIN
);
106 int day_of_year(int anio
, int mes
, int dia
)
111 // Recorremos los meses
112 for ( tmp
=0; tmp
< mes
; tmp
++)
113 dias
+= dias_por_mes
[tmp
];
115 // Correcion por año bisiesto
116 if ( (mes
> FEBRERO
) && es_bisiesto(1900+anio
) ) dias
++;
124 // el tod representa la cantidad de segundos transcurridos desde un momento hasta el
125 // 1 de enero de 1970.
126 // Para entender la forma de calcularlo veamos un ejemplo:
127 // queremos calcular el tod de la fecha: 25/09/1979 07:49:15
129 // bien, primero que todo:
131 // 1979 - 1970 = 9 años transcurridos
132 // 70-71 -- 71-72 -- 72-73 -- 73-74 -- 74-75 -- 75-76 -- 76-77 -- 77-78 -- 78-79
133 // o sea que la cantidad de segundos hasta el inicio del 79 son:
135 // tod += 9 * 365 * 24 * 60 * 60
137 // bien, no olvidemos los años bisiestos, que desde el 70 al 78 son 1972 - 1976
138 // con lo que ajustando el tod anterior tenemos:
140 // tod += 2 * 1 * 24 * 60 * 60 dos días de ajuste
142 // Bien, ahora debemos calcular la cantidad de segundos desde el Enero de 1979 hasta Septiembre de 1979
143 // tod += dias_por_mes[ENERO] * 24 * 60 * 60 + dias_por_mes[FEB] * 24 * 60 * 60 + ... + dias_por_mes[AGOS] * 24 * 60 * 60
144 // como antes, si el año es bisiesto y SI PASAMOS POR FEBRERO debemos corregir:
145 // tod += 1 * 24 * 60 * 60
147 // Ahora, la cantidad de segundos desde el 1ero de Septiembre al 25 de Septiembre
148 // tod += 24 * 24 * 60 * 60
151 // Ahora la cantidad de segundos desde las 00:00 del 25 de Septiembre a las 07:00 del mismo
152 // tod += 7 * 60 * 60
154 // Ahora la cantidad de segundos desde los 0 minutos hasta los 49 minutos
157 // Finalmente sumamos la cantidad de segundos:
160 // y obtuvimos el tod buscado.
161 time_t mktime(struct tm
*tm
)
166 for ( tmp
=ANIO_INICIO
; tmp
< tm
->tm_year
; tmp
++ )
167 tod
+= SEC_PER_YEAR(1900+tmp
);
169 for ( tmp
=MES_INICIO
; tmp
< tm
->tm_mon
; tmp
++ )
170 tod
+= SEC_PER_MONTH(tm
->tm_year
,tmp
);
172 tod
+= (tm
->tm_mday
- 1) * SEC_PER_DAY
+ tm
->tm_hour
* SEC_PER_HOUR
+ tm
->tm_min
* SEC_PER_MIN
+ tm
->tm_sec
;
181 // Los años bisiestos son todos los divisibles por 4 suprimiendo los divisibles por 100
182 // y no divisibles por 400 ( la regla de calculo es válida desde 1582 ).
183 int es_bisiesto(int year
)
185 if ( (!(year
%4)) && (year
%100) ) { return 1; }
186 else if ( !(year
%400) ) { return 1; }
190 char *dias
[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
191 char *mes
[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
194 char *asctime(const struct tm
*tm
)
197 static char string
[26];
199 //kprintf("%s %s %d %d:%d:%d %d\n", dias[tm->tm_wday], mes[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (1900 + tm->tm_year) );
200 kprintf("%s %s %d %d:%d:%d %d\n", dias
[0], mes
[tm
->tm_mon
], tm
->tm_mday
, tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, (1900 + tm
->tm_year
) );