Talk:CMOS
Usage of GCC inline assembler instead of VC?
Technically the code could be converted to code that would compile in GCC, Considering a majority of code examples here are in Assembly or C in a syntax compatible with GCC. --Brynet-Inc 17:17, 14 January 2007 (CST)
The goal is to get the point across. To that extent intel assembly is easier to read than AT&T syntax. Besides, this is 16-bit stuff which fits in neither GCC nor MSVC. - Combuster 17:13, 15 January 2007 (CST)
Reading and sanitizing the RTC
I use the following code to read and sanitize the RTC:
char time[10];
void out_byte(int port, int value);
int in_byte(int port);
enum {
cmos_address = 0x70,
cmos_data = 0x71
};
int cmos_ready() {
out_byte(cmos_address, 10);
return (in_byte(cmos_data) & 0x80);
}
void read_rtc() {
while (cmos_ready());
out_byte(cmos_address, 0x00); time[0] = in_byte(cmos_data);
out_byte(cmos_address, 0x02); time[1] = in_byte(cmos_data);
out_byte(cmos_address, 0x04); time[2] = in_byte(cmos_data);
out_byte(cmos_address, 0x06); time[3] = in_byte(cmos_data);
out_byte(cmos_address, 0x07); time[4] = in_byte(cmos_data);
out_byte(cmos_address, 0x08); time[5] = in_byte(cmos_data) - 1;
out_byte(cmos_address, 0x09); time[6] = in_byte(cmos_data);
out_byte(cmos_address, 0x32); time[7] = in_byte(cmos_data);
out_byte(cmos_address, 0x0a); time[8] = in_byte(cmos_data);
out_byte(cmos_address, 0x0b); time[9] = in_byte(cmos_data);
// 12 hour clock
if (!(time[9] & 2) && (time[2] & 0x80)) {
time[2] = ((time[2] & 0x80) + 12) % 24;
}
// decimal stuff
if (!(time[9] & 4)) {
time[0] = (time[0] & 0xf) + ((time[0] / 16) * 10);
time[1] = (time[1] & 0xf) + ((time[1] / 16) * 10);
time[2] = (time[2] & 0xf) + ((time[2] / 16) * 10);
time[5] = (time[5] & 0xf) + ((time[5] / 16) * 10);
}
time[3] = (time[3] + 5) % 7;
}
This produces a much saner version of the CMOS bytes for the RTC; weeks start on Mondays (international standard, used pretty much everywhere but the US) with Monday = 0, Sunday = 6. January = 0 (not 1), December = 11, hour is always [0..23] and minutes/seconds is always [0..59] (no hexing). Naturally, I can't say that the "century" is a correct representation of the century.
The code assumes that interrupts are disabled before calling it.
I hope this is helpful. (Posted 2011-12-13 by Clearer, edited by Solar.)