Académique Documents
Professionnel Documents
Culture Documents
Cs609@vu.edu.pk
Lecture # 18
Clock Status Registers
Status Register B
7 6 5 4 3 2 1 0
0 = Daylight
Update time saving time
The status register B is the main control register. It is used to specify the date time
formats and is also used to enable interrupt on various events like alarm time and time
up-dation. Another feature of RTC is periodic interrupt which occur with a frequency
specified in the A register.
Status Register C
7 6 5 4 3 2 1 0
Status register is used to identify the reason of interrupt generation as described in the
slide above.
Virtual University of Pakistan 151
System Programming Course Code: CS609
Cs609@vu.edu.pk
Status Register D
7 6 5 4 3 2 1 0
0 = Battery Dead
Only the most significant byte in status register D is important which on being 0 indicates
that the battery is dead.
Sample Program.
void main ()
{
unsigned int hours, months, seconds;
_AH =2;
geninterrupt(0x1a);
hours = _CH;
minutes = _CL;
seconds = _DH;
hours = hours <<4;
*((unsigned char *)(& hours)) =
(*((unsigned char *) (& hours))) >>4;
hours = hours + 0x3030;
The above program uses the service int 1Ah/02H to read the time from the real time
clock. It reads the time and converts the packed BCD values into unpacked BCD values.
These values are then converted into ASCII and displayed using the printf() statement.
#include <bios.h>
#include <dos.h>
void main ()
{
int hrs,mins,secs;
char temp;
do {
outportb(0x70,0x0a);
temp=inportb(0x71);
}while ((temp & 0x80) == 0);
outportb(0x70,0);
secs=inport(0x71);
outportb(0x70,2);
mins=inport(0x71);
outportb(0x70,4);
hrs=inport(0x71);
printf("%c%c:%c%c:%c%c",
*(((unsigned char*)(&hrs))+1),
*((unsigned char*)(&hrs)),
*(((unsigned char*)(&mins))+1),
*((unsigned char*)(&mins)),
*(((unsigned char*)(&secs))+1),
*((unsigned char*)(&secs)));
getch();
}
The time units are similarly read and converted to ASCII and displayed.
#include <bios.h>
#include <dos.h>
unsigned char ASCIItoBCD(char hi, char lo)
{
hi = hi - 0x30;
lo = lo - 0x30;
hi = hi << 4;
hi = hi | lo;
return hi;
}
void main ()
{
unsigned char hrs,mins,secs;
char ch1, ch2;
puts("\nEnter the hours to update: ");
ch1=getche();
ch2=getch();
hrs = ASCIItoBCD(ch1, ch2);
*tm = 0;
_CH = hrs;
_CL=mins;
_DH= secs;
_DL=0;
_AH =3;
geninterrupt(0x1a);
puts("Time Updated");
}
The above listing of the program inputs the time from the user which is in ASCII format.
It converts the ASCII in packed BCD and uses BIOS services to update the time. In DOS
or windows this time change may not remain effective after the completion of the
program as the DOS or windows device drivers will revert the time to original even if it
has been changed using this method.
Sample Program
#include <bios.h>
#include <dos.h>
unsigned char ASCIItoBCD (unsigned
char hi, unsigned char lo)
{
hi = hi - 0x30;
lo = lo - 0x30;
hi = hi << 4;
hi = hi | lo;
return hi;
}
void main ()
{
unsigned int hrs,mins,secs;
char ch1, ch2;
int temp;
outportb(0x70,0x0b);
temp = inport(0x71);
outport (0x70,0);
outport (0x71,secs);
outport (0x70,2);
outport (0x71,mins);
outport (0x70,4);
outport (0x71,hrs);
outportb(0x70,0x0b);
temp = inport(0x71);
temp = temp & 0x7f;
outportb(0x70,0x0b);
outportb(0x71,temp);
delay (30000);
do {
outportb(0x70,0x0a);
temp=inportb(0x71);
}while ((temp & 0x80) == 0);
outportb(0x70,0);
secs=inport(0x71);
outportb(0x70,2);
mins=inport(0x71);
outportb(0x70,4);
hrs=inport(0x71);
hrs = hrs <<4;
*((unsigned char *)(&hrs)) =
(*((unsigned char *)(&hrs))) >>4;
hrs = hrs + 0x3030;
To elaborate more on the problem posed by the OS device drivers here is another
program. This program first updates the time accessing the 64 byte RAM directly and
taking the new time as input from the user. After updating the program produces a delay
of 30 seconds and then reads time to display it. A difference of 30 seconds will be noticed
in the time entered and the time displayed. This shows that during the execution of the
program the time was successfully changed and was being updated accordingly.