ESC1332%ESOC.BITNET@wiscvm.wisc.edu (K.Keyte) (08/27/87)
The following contains two files:
ldclock.c For loading the clock
ports.s For port I/O
Compile ldclock.c and load it with ports.s (under MINIX this is done
with 'cc -o ldclock ldclock.c ports.s')
Split the two programs at the cuts.
Please send me any comments!
Karl (ESC1332@ESOC.BITNET)
**------------------------ CUT HERE ----------------------**
/**************************************************************************
* *
* A procedure to load the MINIX software clock from the battery backed *
* real-time clock of the PC-AT computer. The data is taken from some of *
* the 64 bytes of CMOS RAM and addressed using: *
* *
* Port 0x70 : CMOS RAM index port - Write Only *
* 0x71 : CMOS RAM data port - Read/Write *
* *
* Written by Karl Keyte (ESC1332@ESOC.BITNET) *
* Date : 20th July 1987 *
* *
**************************************************************************/
#define cmos_index 0x70
#define cmos_data 0x71
#define SECONDS 0x00
#define MINUTES 0x02
#define HOURS 0x04
#define DATE 0x07
#define MONTH 0x08
#define YEAR 0x09
int days[] = {0,31,59,90,120,151,181,212,243,273,304,334,
0,31,60,91,121,152,182,213,244,274,305,335};
main()
{
unsigned long ct;
int dt, hrs, mins, mnth, secs, year;
short extra, leap;
get_value(&secs, SECONDS);
get_value(&mins, MINUTES);
get_value(&hrs, HOURS);
get_value(&dt, DATE);
get_value(&mnth, MONTH);
get_value(&year, YEAR);
if (year<80) year += 100;
leap = (mnth>2 && year%4 == 0) ? 1 : 0;
extra = leap + (year-69)/4;
ct = secs;
ct += mins*60;
ct += (long) hrs*3600;
ct += (long) (days[leap*12+mnth-1]+dt-1+extra)*86400;
ct += (long) (year-70)*365*86400;
if (stime(&ct))
printf("Permission denied\n");
}
/*------------------------------------------------------------------------*/
get_value(storage, port_offset)
unsigned int *storage,
port_offset;
{
int temp = 0;
*storage = 0xff;
while (*storage == 0xff || *storage != temp) {
port_out(cmos_index,port_offset);
port_in(cmos_data,storage);
port_out(cmos_index,port_offset);
port_in(cmos_data,&temp);
}
*storage = 10*(*storage>>4)+(*storage & 0x0f);
}
**------------------------- CUT HERE ---------------------**
|*===========================================================================*
|* port_out *
|*===========================================================================*
| port_out(port, value) writes 'value' on the I/O port 'port'.
_port_out:
push bx | save bx
mov bx,sp | index off bx
push ax | save ax
push dx | save dx
mov dx,4(bx) | dx = port
mov ax,6(bx) | ax = value
out | output 1 byte
pop dx | restore dx
pop ax | restore ax
pop bx | restore bx
ret | return to caller
|*===========================================================================*
|* port_in *
|*===========================================================================*
| port_in(port, &value) reads from port 'port' and puts the result in 'value'.
_port_in:
push bx | save bx
mov bx,sp | index off bx
push ax | save ax
push dx | save dx
mov dx,4(bx) | dx = port
in | input 1 byte
xorb ah,ah | clear ah
mov bx,6(bx) | fetch address where byte is to go
mov (bx),ax | return byte to caller in param
pop dx | restore dx
pop ax | restore ax
pop bx | restore bx
ret | return to caller