Vous êtes sur la page 1sur 9

System Programming Course Code: CS609

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

Call pe riodic 24/12 – hour counter


interrupt 0 = 12 hour format
1 = 24 hour format
Call Alarm interrupt
Call interrupt on
Time & date format
time update
0 = BCD
Block generator 1 = Binary

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

1 = Time update complete

1 = Alarm time reached

1 = Periodic interrupt call

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;

seconds = seconds <<4;


*((unsigned char *)(& seconds)) =
(*((unsigned char *)(& seconds))) >>4;
seconds = seconds + 0x3030;

Virtual University of Pakistan 152


System Programming Course Code: CS609
Cs609@vu.edu.pk

minutes = minutes <<4;


*((unsigned char *)(& minutes)) =
(*((unsigned char *)(& minutes))) >>4;
minutes = minutes + 0x3030;
clrscr();
printf("%c%c-%c%c-%c%c%c%c",
*(((unsigned char*)(&hours))+1),
*((unsigned char*)(&hours)),
*(((unsigned char*)(&minutes))+1),
*((unsigned char*)(&minutes)),
*(((unsigned char*)(&seconds))+1),
*((unsigned char*)(&seconds)),
getch();
}

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.

Virtual University of Pakistan 153


System Programming Course Code: CS609
Cs609@vu.edu.pk

Read time from RTC (Sample Program)


This sample program directly accesses the 64 byte RAM to access the units of time.
Before reading the time it makes sure by checking the value of Status register A and
checking its most significant bit for time update completion. If the updation is complete
time can be read from the respective registers in the 64 byte RAM.

#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);

hrs = hrs <<4;


*((unsigned char *)(&hrs)) =
(*((unsigned char *)(&hrs))) >>4;
hrs = hrs + 0x3030;

mins = mins <<4;


*((unsigned char *)(&mins)) =
(*((unsigned char *)(&mins))) >>4;
mins = mins + 0x3030;

secs = secs <<4;


*((unsigned char *)(&secs)) =
(*((unsigned char *)(&secs))) >>4;
secs = secs + 0x3030;
clrscr();

Virtual University of Pakistan 154


System Programming Course Code: CS609
Cs609@vu.edu.pk

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.

Write the Time on RTC

#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;
}

unsigned long int far *tm =


(unsigned long int far *)0x0040006c;

Virtual University of Pakistan 155


System Programming Course Code: CS609
Cs609@vu.edu.pk

void main ()
{
unsigned char hrs,mins,secs;
char ch1, ch2;
puts("\nEnter the hours to update: ");
ch1=getche();
ch2=getch();
hrs = ASCIItoBCD(ch1, ch2);

puts("\nEnter the minutes to update: ");


ch1=getche();
ch2=getch();
mins = ASCIItoBCD(ch1, ch2);

puts("\nEnter the seconds to update: ");


ch1=getche();
ch2=getch();
secs = 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.

Virtual University of Pakistan 156


System Programming Course Code: CS609
Cs609@vu.edu.pk

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;

puts("\nEnter the hours to update: ");


ch1=getche();
ch2=getche();
hrs = ASCIItoBCD(ch1, ch2);

puts("\nEnter the minutes to update: ");


ch1=getche();
ch2=getche();
mins = ASCIItoBCD(ch1, ch2);

puts("\nEnter the seconds to update: ");


ch1=getche();
ch2=getche();
secs = ASCIItoBCD(ch1, ch2);

outportb(0x70,0x0b);
temp = inport(0x71);

Virtual University of Pakistan 157


System Programming Course Code: CS609
Cs609@vu.edu.pk

temp = temp | 0x80;


outportb(0x70,0x0b);
outportb(0x71,temp);

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.

Virtual University of Pakistan 158


System Programming Course Code: CS609
Cs609@vu.edu.pk

mins = mins <<4;


*((unsigned char *)(&mins)) =
(*((unsigned char *)(&mins))) >>4;
mins = mins + 0x3030;
secs = secs <<4;
*((unsigned char *)(&secs)) =
(*((unsigned char *)(&secs))) >>4;
secs = secs + 0x3030;
printf("\nUpdated time is = %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();
}

Virtual University of Pakistan 159

Vous aimerez peut-être aussi