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.