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