Talk:CMOS

From OSDev Wiki
Jump to navigation Jump to search

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.)