bunda@cs.utexas.edu (John Bunda) (07/13/88)
Since I couldn't find one in the archives, here is code
to set minix date and time from the clock-calendar on a
Quadram Quadboard. It is a rather transparent conversion
of a wretched basic program, but it works...
The port_io.s file is lifted from klib88.s. No makefile is
included, just compile with:
cc -o qclk qclk.c port_io.s
and chmem to 2k or so.
then change the date line in /etc/rc to:
qclk | date -q >/dev/null
to set the date and time when you boot. This is a minix shell
archive.
----------------cut here------------------------
echo x - qclk.c
gres '^X' '' > qclk.c << '/'
X/* qclk.c
X
X Read current time and date from battery clock
X on Quadram or compatable clock, and place on
X standard output as MMDDYYhhmmss.
X
X the clock chip is the OKI MSM5832, interfaced through
X an Intel 8255 or similar. This was adapted from a BASIC
X program provided with the Quadboard.
X
X this is how the clock vector maps to time/date:
X
X index 10 9 | 8 7 | 12 11 | 5 4 | 3 2 | 1 0
X digit MM | DD | YY | HH | MM | SS
X
X (c) 1988 John Bunda, Austin, TX. Permission granted
X to copy and distribute non-commercially. User assumes
X all risks in the use of this software; no warranty.
X */
X/* possible values to be output to ctl_port */
X
X#define HOLD 0x90 /* stop clock (to read) */
X#define READ 0xb0 /* set data bus to output */
X#define WRITE 0xd0 /* set data bus to input */
X
X/* direction of 8255 A port (sent to dir_port) */
X
X#define DATA_IN 0x90
X#define DATA_OUT 0x80
X
Xint data_port,select_port,ctl_port,dir_port;
Xstatic char q[14];
Xstatic int ord[13] = {10, 9, 8, 7, 12, 11, 5, 4, 3, 2, 1, 0};
X
X
Xmain()
X{
X int i,t;
X char d;
X set_ports(); /* enable and set access ports */
X adjust_clock(); /* do correction adjustments */
X
X /* read current time and date from clock */
X
X port_out (dir_port, DATA_IN);
X port_out (ctl_port, READ);
X for ( i = 0 ; i < 12; i++)
X {
X port_out (select_port , ord[i]);
X port_in (data_port, &t);
X d = 48 + (t & (ord[i]==5 || ord[i]==8 ? 3 : 15));
X printf("%c",d);
X }
X printf("\n");
X}
X
Xset_ports()
X{
X int t;
X port_out(0x313,0x90);
X port_out(0x311,97);
X port_in (0x311, &t);
X data_port = (t == 97 ? 0x310 : 0x210);
X select_port = data_port + 1;
X ctl_port = data_port + 2;
X dir_port = data_port + 3;
X}
X
X
X
Xadjust_clock()
X /* various necessary adjustments for leap year, etc. */
X{
X int t,x,i,th,leap;
X port_out (dir_port, DATA_IN);
X port_out (select_port, 5);
X port_out (ctl_port, READ);
X port_in (data_port, &th);
X port_out (dir_port, DATA_OUT);
X port_out (select_port, 5);
X port_out (ctl_port, HOLD);
X port_out (data_port, th & 3 | 8);
X port_out (ctl_port, WRITE);
X
X /* adjust for leap year */
X
X port_out (dir_port, DATA_IN);
X port_out (ctl_port, READ);
X
X for (i = 9; i <= 12 ; i++)
X {
X port_out (select_port, i);
X port_in (data_port, &t);
X q[i] = t;
X }
X leap = 10 * q[10] + q[9] > 2 & 1;
X leap = 4 & (leap + 10 * q[12] + q[11] & 3) == 0;
X port_out (dir_port, DATA_IN);
X port_out (select_port, 8);
X port_out (ctl_port, READ);
X port_in (data_port, &x);
X port_out (dir_port, DATA_OUT);
X port_out (select_port, 8);
X port_out (ctl_port, HOLD);
X port_out (data_port, x & 3 | leap);
X port_out (ctl_port, WRITE);
X}
/
echo x - port_io.s
gres '^X' '' > port_io.s << '/'
X| this file was grafted from klib88.s
X
X.globl _port_out, _port_in
X
X
X
X|*===========================================================================*
X|* port_out *
X|*===========================================================================*
X| port_out(port, value) writes 'value' on the I/O port 'port'.
X
X_port_out:
X push bx | save bx
X mov bx,sp | index off bx
X push ax | save ax
X push dx | save dx
X mov dx,4(bx) | dx = port
X mov ax,6(bx) | ax = value
X out | output 1 byte
X pop dx | restore dx
X pop ax | restore ax
X pop bx | restore bx
X ret | return to caller
X
X
X|*===========================================================================*
X|* port_in *
X|*===========================================================================*
X| port_in(port, &value) reads from port 'port' and puts the result in 'value'.
X_port_in:
X push bx | save bx
X mov bx,sp | index off bx
X push ax | save ax
X push dx | save dx
X mov dx,4(bx) | dx = port
X in | input 1 byte
X xorb ah,ah | clear ah
X mov bx,6(bx) | fetch address where byte is to go
X mov (bx),ax | return byte to caller in param
X pop dx | restore dx
X pop ax | restore ax
X pop bx | restore bx
X ret | return to caller
/
--
................................................................
John Bunda UT CS Dept. The proof is trivial, and
bunda@cs.utexas.edu Austin, Texas left as an exercise.