Skip to content

Commit 94e3bcb

Browse files
authored
Merge pull request #1426 from fwsGonzo/dev
x86: Use CMOS century register to calculate year correctly
2 parents f566fa0 + d522911 commit 94e3bcb

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

api/hw/cmos.hpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace hw
4545
static const reg_t r_day = 0x7;
4646
static const reg_t r_month = 0x8;
4747
static const reg_t r_year = 0x9;
48-
static const reg_t r_cent = 0x48;
48+
//static const reg_t r_cent = 0x48;
4949

5050
// RTC Alarm registers
5151
static const reg_t r_alarm_sec = 0x1;
@@ -153,8 +153,7 @@ namespace hw
153153
* (For initialization. Recommended practice by CG I.24)
154154
**/
155155
struct Fields {
156-
uint8_t century = 0;
157-
uint8_t year = 0;
156+
int year = 0;
158157
uint8_t month = 0;
159158
uint8_t day_of_month = 0;
160159
uint8_t day_of_week = 0;
@@ -163,8 +162,7 @@ namespace hw
163162
uint8_t second = 0;
164163
};
165164

166-
uint8_t century() { return f.century; }
167-
uint16_t year() { return (f.century + 20) * 100 + f.year; }
165+
uint16_t year() { return f.year; }
168166
uint8_t month() { return f.month; }
169167
uint8_t day_of_month() { return f.day_of_month; }
170168
uint8_t day_of_week() { return f.day_of_week; }

src/hw/cmos.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <hw/cmos.hpp>
22
#include <statman>
3+
#include "../platform/x86_pc/acpi.hpp"
34

45
using namespace hw;
56
uint8_t CMOS::reg_b_value = 0;
@@ -18,6 +19,8 @@ void CMOS::init()
1819
CMOS::Time& CMOS::Time::hw_update() {
1920
// We're supposed to check this before every read
2021
while (update_in_progress());
22+
const reg_t r_cent = x86::ACPI::get().cmos_century();
23+
int century = 0;
2124

2225
if (CMOS::mode_binary()) {
2326
f.second = get(r_sec);
@@ -27,7 +30,7 @@ CMOS::Time& CMOS::Time::hw_update() {
2730
f.day_of_month = get(r_day);
2831
f.month = get(r_month);
2932
f.year = get(r_year);
30-
f.century = get(r_cent);
33+
if (r_cent) century = get(r_cent);
3134
} else {
3235
f.second = bcd_to_binary(get(r_sec));
3336
f.minute = bcd_to_binary(get(r_min));
@@ -36,7 +39,16 @@ CMOS::Time& CMOS::Time::hw_update() {
3639
f.day_of_month = bcd_to_binary(get(r_day));
3740
f.month = bcd_to_binary(get(r_month));
3841
f.year = bcd_to_binary(get(r_year));
39-
f.century = get(r_cent);
42+
if (r_cent) century = bcd_to_binary(get(r_cent));
43+
}
44+
45+
// Insanity
46+
#define CURRENT_YEAR 2017 // Change this each year!
47+
if (r_cent != 0) {
48+
f.year += century * 100;
49+
} else {
50+
f.year += (CURRENT_YEAR / 100) * 100;
51+
if (f.year < CURRENT_YEAR) f.year += 100;
4052
}
4153

4254
// Convert to 24-hour clock if necessary
@@ -51,9 +63,7 @@ CMOS::Time& CMOS::Time::hw_update() {
5163
std::string CMOS::Time::to_string(){
5264
std::array<char,20> str;
5365
sprintf(str.data(), "%.2i-%.2i-%iT%.2i:%.2i:%.2iZ",
54-
(f.century + 20) * 100 + f.year,
55-
f.month,
56-
f.day_of_month,
66+
f.year, f.month, f.day_of_month,
5767
f.hour, f.minute, f.second);
5868
return std::string(str.data(), str.size());
5969
}

0 commit comments

Comments
 (0)