Saturday 26 June 2010

Real-time clock program


Downloaded DJGPP 32bit C compiler GNU, used RHIDE old fashioned text mode IDE to update a program to show an on screen clock. It pokes the time into direct screen memory, keeping it simple, so it doesn't conflict with system stuff.

Nice hot Saturday!


//Simple Example of chaining interrupt handlers

//Adopted from Matthew Mastracci's code
//Lyndon Smith added poking screen memory with clock time

#include
#include
#include
#include
#include
#include

//macros by Shawn Hargreaves from the Allegro library for locking
//functions and variables.
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void *)&x,(long)sizeof(x));
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x,(long)sizeof(x));

//timer interrupt 8 is generated every 18.2 ms
#define TIMER 8
#define NORMAL 7
#define CLOCKOFFSET (80*3)+52

//global counter
int counter = 0;
int hour=0,minute=0,second =0,tens=0,units=0;
int CLOCKATTR=3,showclock=1;

char *daiclock = "lyndon smith testing clock interrupt";


//the new ISR, will be called automatically every 18.2 ms once installed


void TickHandler(void)
{
counter++;
if(counter==18)
{
counter=0;
if(showclock==1)
{
second++;
if(second==60) {minute++;second=0;}
tens=second/10;
units=second-(tens*10);
_farpokeb(_dos_ds, 0xB800*16+12+CLOCKOFFSET,'0'+tens);
_farpokeb(_dos_ds, 0xB800*16+12+CLOCKOFFSET+1,CLOCKATTR);
_farpokeb(_dos_ds, 0xB800*16+14+CLOCKOFFSET,'0'+units);
_farpokeb(_dos_ds, 0xB800*16+14+CLOCKOFFSET+1,CLOCKATTR);
_farpokeb(_dos_ds, 0xB800*16+10+CLOCKOFFSET,':');
_farpokeb(_dos_ds, 0xB800*16+10+CLOCKOFFSET+1,CLOCKATTR);
if(minute==60) {hour++;minute=0;}
tens=minute/10;
units=minute-(tens*10);
_farpokeb(_dos_ds, 0xB800*16+6+CLOCKOFFSET,'0'+tens);
_farpokeb(_dos_ds, 0xB800*16+6+CLOCKOFFSET+1,CLOCKATTR);
_farpokeb(_dos_ds, 0xB800*16+8+CLOCKOFFSET,'0'+units);
_farpokeb(_dos_ds, 0xB800*16+8+CLOCKOFFSET+1,CLOCKATTR);
_farpokeb(_dos_ds, 0xB800*16+4+CLOCKOFFSET,':');
_farpokeb(_dos_ds, 0xB800*16+4+CLOCKOFFSET+1,CLOCKATTR);
if(hour==99) hour=0;
tens=hour/10;
units=hour-(tens*10);
_farpokeb(_dos_ds, 0xB800*16+0+CLOCKOFFSET,'0'+tens);
_farpokeb(_dos_ds, 0xB800*16+0+CLOCKOFFSET+1,CLOCKATTR);
_farpokeb(_dos_ds, 0xB800*16+2+CLOCKOFFSET,'0'+units);
_farpokeb(_dos_ds, 0xB800*16+2+CLOCKOFFSET+1,CLOCKATTR);
}
}
}

void junk(void)
{
}


int main(void)
{
//structures to hold selector:offset info for the ISRs
_go32_dpmi_seginfo OldISR, NewISR;
int i,j,limit;

//lock the functions and variables
LOCK_FUNCTION(TickHandler);
LOCK_VARIABLE(counter);
LOCK_VARIABLE(second);
LOCK_VARIABLE(minute);
LOCK_VARIABLE(hour);
LOCK_VARIABLE(tens);
LOCK_VARIABLE(units);
LOCK_VARIABLE(CLOCKATTR);
LOCK_VARIABLE(showclock);

//load the address of the old timer ISR into the OldISR structure
_go32_dpmi_get_protected_mode_interrupt_vector(TIMER, &OldISR);

//point NewISR to the proper selector:offset for handler
//function
NewISR.pm_offset = (int)TickHandler;
NewISR.pm_selector = _go32_my_cs();

//chain the new ISR onto the old one so that first the old
//timer ISR
//will be called, then the new timer ISR
_go32_dpmi_chain_protected_mode_interrupt_vector(TIMER,&NewISR);

//notice no changes to counter in this loop- the interrupt changes it
clrscr();
gotoxy(13,7);printf("Lyndon's interrupt clock routine for DJGPP 32bit C");
i=9;
srand(time(0));
while (!kbhit())
{
i++;
if (i>20) i=9;
gotoxy(10,i);limit=1+rand() % 60;
for(j=0;j }

printf("Removing new ISR from the timer ISR chain\n");

//load the old timer ISR back without the new ISR chained on
_go32_dpmi_set_protected_mode_interrupt_vector(TIMER,&OldISR);

return 0;
}

No comments: