Complementary Metal–Oxide–Semiconductor (CMOS)
Complementary Metal–Oxide–Semiconductor (CMOS) is a chip on the motherboard which is always running even if the computer is off.It is powered by a battary and it consumes very little amount of power.This CMOS chip is used for storing BIOS Setup information and Date, Time,etc.The Real Time Clock is a part of the CMOS chip which holds and updates the time and eventually the date also.The CMOS(Also the RTC) chip can be accessed through the 0x70 and x071 port.
The CMOS Registers:
#define CMOS_ADDREG 0x70
#define CMOS_DATAREG 0x71
These are the two ports of the CMOS Chip, the Address Port and the Data Port
-------------------------------------------------------------------------------------------------------------------------------
Reading Data from the CMOS:
This extermly simple, we need to send the address number to 0x70(Address Port) port.Here,Address means data you want to read from the chip.After the sending the address number, the CMOS will keep the data ready to be read at 0x71(Data Port).
NOTE:Sometimes the data read from the CMOS comes in BCD Format.To convert it to a binary value use the following formula:
#define BCD2BIN(bcd) ((((bcd)&15) + ((bcd)>>4)*10))
Example Code:
unsigned char read_cmos(unsigned char address)
{
unsigned char data;
outportb(CMOS_ADDREG,address);
data = inportb(CMOS_DATAREG);
return data;
}
This 'outportb' function sends the address to the CMOS chip then collect the data by "inportb" function through the data port and returns the data.
-------------------------------------------------------------------------------------------------------------------------------
Writing Data to the CMOS:
This is exactly same but we will replace inportb with outportb of the previous example.In simple words, instead of read the data we will write data.But while we write to the CMOS Address register 0x70, we may also change the NMI bit as NMI are enabled\disabled.NMI are signals sent to the processor when a fatal error takes place or some hardware panic.The 8th bit is the NMI enable\disable bit.And only 7 bits are used for transmitting the address.
void write_cmos(unsigned char address, unsigned int value)
{
outportb(CMOS_ADDREG, address);
outportb(CMOS_DATAREG,NMI_disable_bit << 7 | data);
}
The first 'outportb' function tells the CMOS to set the data ready at the data register.The the next 'outportb' will overwrite the existing data.That's how you can change the data.
NOTE:Dont mess to much with this or else you may overwrite valuable BIOS Setup information, then you will have trouble reconfiguring the BIOS.
-------------------------------------------------------------------------------------------------------------------------------
Using the CMOS
Here are few self-explanatory C code examples which use read_cmos function and get some data from the chip.
-------------------------------------------------------------------------------------------------------------------------------
1. Example code to get the total memory.
unsigned short get_memory_size()
{
unsigned short memory;
unsigned char low, high;
low =read_cmos(0x30);
high=read_cmos(0x31);
memory = low | high << 8;
return memory;
}
-------------------------------------------------------------------------------------------------------------------------------
2. Getting time is as simple as ABC
unsigned int seconds;
seconds = read_cmos(0x0);
seconds = BCD2BIN(seconds);
To get all the data of the Real Time Clock ,view the RTC Article
===============================================================================================
Links:
Real Time Clock
Detecting Floppy Drives using the data provided by the CMOS (External)
The CMOS Registers:
#define CMOS_ADDREG 0x70
#define CMOS_DATAREG 0x71
These are the two ports of the CMOS Chip, the Address Port and the Data Port
-------------------------------------------------------------------------------------------------------------------------------
Reading Data from the CMOS:
This extermly simple, we need to send the address number to 0x70(Address Port) port.Here,Address means data you want to read from the chip.After the sending the address number, the CMOS will keep the data ready to be read at 0x71(Data Port).
NOTE:Sometimes the data read from the CMOS comes in BCD Format.To convert it to a binary value use the following formula:
#define BCD2BIN(bcd) ((((bcd)&15) + ((bcd)>>4)*10))
Example Code:
unsigned char read_cmos(unsigned char address)
{
unsigned char data;
outportb(CMOS_ADDREG,address);
data = inportb(CMOS_DATAREG);
return data;
}
This 'outportb' function sends the address to the CMOS chip then collect the data by "inportb" function through the data port and returns the data.
-------------------------------------------------------------------------------------------------------------------------------
Writing Data to the CMOS:
This is exactly same but we will replace inportb with outportb of the previous example.In simple words, instead of read the data we will write data.But while we write to the CMOS Address register 0x70, we may also change the NMI bit as NMI are enabled\disabled.NMI are signals sent to the processor when a fatal error takes place or some hardware panic.The 8th bit is the NMI enable\disable bit.And only 7 bits are used for transmitting the address.
void write_cmos(unsigned char address, unsigned int value)
{
outportb(CMOS_ADDREG, address);
outportb(CMOS_DATAREG,NMI_disable_bit << 7 | data);
}
The first 'outportb' function tells the CMOS to set the data ready at the data register.The the next 'outportb' will overwrite the existing data.That's how you can change the data.
NOTE:Dont mess to much with this or else you may overwrite valuable BIOS Setup information, then you will have trouble reconfiguring the BIOS.
-------------------------------------------------------------------------------------------------------------------------------
Using the CMOS
Here are few self-explanatory C code examples which use read_cmos function and get some data from the chip.
-------------------------------------------------------------------------------------------------------------------------------
1. Example code to get the total memory.
unsigned short get_memory_size()
{
unsigned short memory;
unsigned char low, high;
low =read_cmos(0x30);
high=read_cmos(0x31);
memory = low | high << 8;
return memory;
}
-------------------------------------------------------------------------------------------------------------------------------
2. Getting time is as simple as ABC
unsigned int seconds;
seconds = read_cmos(0x0);
seconds = BCD2BIN(seconds);
To get all the data of the Real Time Clock ,view the RTC Article
===============================================================================================
Links:
Real Time Clock
Detecting Floppy Drives using the data provided by the CMOS (External)