AST SETDATE on VENIX/86
Mike Umansky
misha at daisy.UUCP
Thu Mar 21 05:41:09 AEST 1985
To all who have IBM PC or XT (maybe AT) with an AST SixPak expansion
card with onboard clock/calendar and running VENIX/86 (TM VenturCom)
operating system:
The following program will free you from setting date and time
manually everytime you boot the system. Just follow the
directions below on how to use it and you are off and running.
NOTE: No matter which hardware your system is running on, make sure
that the AST port addresses on your card are the same as in
the defines below, if not then it is easy to modify the defines.
My next project will be a change to VENIX boot record so that by
typing "dos" to the ampersand (&) prompt at boot time, the PC-DOS
will be booted from its partition on the C disk (if there is any).
So far by setting the dos partition active has not worked and I don't
know of any other way of booting dos from the hard disk partition;
does anybody??? Another project I would love to do is to provide
access to PC-DOS files on the hard disk C partition, but this is tricky.
As far as running PC-DOS programs under VENIX, I would suggest looking
at VenturCom's CONNECTOR. Thats All Folks! Enjoy the program!!
Mike Umansky
PS: It is not in any special format, just cut at the dashed line
below and that is it.
----------------------------CUT HERE-------------------------------------
/************************************************************************
* *
* Copyright (c) 1985, Michael Umansky *
* 94 Cassia Court, Hayward CA 94544 *
* (415) 886-4805 *
* All Rights Reserved *
* *
* This software and/or documentation is released into the *
* public domain for personal, non-commercial use only. *
* Limited rights to use, modify, and redistribute are hereby *
* granted for non-commercial purposes, provided that all *
* copyright notices remain intact and all changes are clearly *
* documented. The author makes no warranty of any kind with *
* respect to this product and explicitly disclaims any implied *
* warranties of merchantability or fitness for any particular *
* purpose. (ala other software creators) *
* *
************************************************************************/
/*******************************************************************************
*
* SETDATE/GETDATE
* Utility to set and get date and time from
* an AST SixPak expansion board on an IBM PC
* or XT or compatibles (maybe even AT) running
* VENIX (TM Venturcom) operating system.
*
* TO USE:
* In my "/etc/rc" file the last line reads:
*
* date `getdate`
*
* which automatically sets UNIX date in utmp file
* by getting the date and time from the AST board
* via the GETDATE command.
*
* NOTE:
* Actually the real compiled file is SETDATE and
* GETDATE is a link to SETDATE. SETDATE looks at
* how it was invoked to provide different functions.
* BEWARE: SETDATE and GETDATE expect different arguments
* (see usage() or help() routines for descriptions).
* This routine sets and reads date and time from/to
* AST board in the same way as the PC-DOS commands,
* ASTCLOCK and SETCLOCK, so that both operating systems
* can use the same clock. The ram buckets used by the
* clock can even be used to pass some information
* between the two operating systems or can even be used
* to store some information that could be used for
* certain setups. This is just a sugestion for you,
* I have not and probably will not do that.
*
* AUTHOR:
* Michael Umansky, Daisy Systems Corporation
* 700B Middlefield Road, Mountain View CA 94039
* (415) 960-7166
* uucp - ucbvax!menlo70!nsc!daisy!misha
*
*******************************************************************************/
#include <stdio.h>
/*
The following are definitions for port addresses
on the AST SixPak card. The names are self-explanatory.
*/
#define THOUSANDTHS (int)0x02c0
#define HUNDREDTHS (int)0x02c1
#define SECONDS (int)0x02c2
#define MINUTES (int)0x02c3
#define HOURS (int)0x02c4
#define WEEKDAY (int)0x02c5
#define DAY (int)0x02c6
#define MONTH (int)0x02c7
#define RAMTHOUSANDTHS (int)0x02c8
#define RAMHUNDREDTHS (int)0x02c9
#define RAMSECONDS (int)0x02ca
#define RAMMINUTES (int)0x02cb
#define RAMHOURS (int)0x02cc
#define RAMWEEKDAY (int)0x02cd
#define RAMDAY (int)0x02ce
#define RAMMONTH (int)0x02cf
#define INTSTATUS (int)0x02d0
#define INTCONTROL (int)0x02d1
#define COUNTRESET (int)0x02d2
#define RAMRESET (int)0x02d3
#define STATUS (int)0x02d4
#define GO (int)0x02d5
#define INTSTANDBY (int)0x02d6
#define TEST (int)0x02df
/*
The following are redefinitions of three of the above
ports to match MSDOS ASTCLOCK routine's usage of ports.
The redefinitions are only in name for clarity.
*/
#define LASTMONTH (int)0x02c9
#define YEAR (int)0x02ca
#define SPECIAL (int)0x02cb
/*
The following define two special codes as used
by AST software on the PC-DOS side.
INIT tells whether there has ever been access
to the AST card. If the location for INIT
(called SPECIAL - see above) has any other value
it means that a total reset has been applied to
the board, or battery has been changed, or this
is a first access ever to the board.
ALL is a byte with 8 bit-flags and is used to
tell the clock chip on AST board how to reset
its internal counters and/or ram buckets.
See AST documentation for more.
*/
#define INIT (unsigned char)0xde
#define ALL (unsigned char)0xff
#define CENTURY 1900
char *week[8] =
{
"WEEK-ERROR",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
char *month[13] =
{
"MONTH-ERROR",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
char getport();
main(argc,argv)
int argc;
char *argv[];
{
if (!strcmp(argv[0],"setdate"))
exit (setdate(argc,argv));
exit (getdate(argc,argv));
}
setdate(argc,argv)
int argc;
char *argv[];
{
register int i = 0, len, fy = 0, fm = 0, fd = 0, fh = 0, fn = 0, fs = 0;
register int yy = 0, mm = 0, dd = 0, hh = 0, nn = 0, ss = 0, ram = 0;
register int ww = 0, wy = 0, wm = 0, wd = 0;
register char t[3];
if (argc > 1)
{
if (argv[1][0] == '-')
{
if (argv[1][1] == 'r')
{
argv++;
ram = 1;
}
else
return (usage(argv));
}
}
else
return (usage(argv));
len = strlen(argv[1]);
if (getuid() != 0)
{
printf("Must be root to set date\n");
return (0);
}
if ((len > 13) || (len < 1))
return (usage(argv));
switch (len)
{
case 4: /* just hours and minutes */
fh = fn = 1;
break;
case 6: /* just year, month and day */
fy = fm = fd = 1;
break;
case 10: /* all except seconds */
fy = fm = fd = fh = fn = 1;
break;
case 13: /* all */
fy = fm = fd = fh = fn = fs = 1;
break;
default: /* invalid parameters specified */
return (usage(argv));
}
if ((i = getport(SPECIAL) & 0x00ff) != INIT)
{
if (!fy)
{
printf("Clock calendar is now reset - ");
printf("specify full date and time\n\n");
return (usage(argv));
}
putport(ALL,COUNTRESET);
putport(ALL,RAMRESET);
putport(INIT,SPECIAL);
}
if (fy)
{
t[0] = argv[1][0];
t[1] = argv[1][1];
t[2] = '\0';
if (((yy = atoi(t)) < 80) || (yy > 99))
{
printf("year must be between 80 and 99\n");
return (usage(argv));
}
wy = yy + CENTURY;
yy -= 80;
i = (yy % 10) & 0x000f;
i |= (((yy / 10) & 0x000f) << 4);
putport((char)(i & 0x00ff),YEAR);
}
if (fm)
{
t[0] = argv[1][2];
t[1] = argv[1][3];
t[2] = '\0';
if (((mm = atoi(t)) < 1) || (mm > 12))
{
printf("month must be between 01 and 12\n");
return (usage(argv));
}
wm = mm;
i = (mm % 10) & 0x000f;
i |= (((mm / 10) & 0x0001) << 4);
putport((char)(i & 0x00ff),MONTH);
if (ram)
putport((char)(i & 0x00ff),RAMMONTH);
if (mm-- < 1)
mm = 12;
i = (mm % 10) & 0x000f;
i |= (((mm / 10) & 0x0001) << 4);
putport((char)(i & 0x00ff),LASTMONTH);
}
if (fd)
{
t[0] = argv[1][4];
t[1] = argv[1][5];
t[2] = '\0';
if (((dd = atoi(t)) < 1) || (dd > 31))
{
printf("day must be between 01 and 31\n");
return (usage(argv));
}
wd = dd;
i = (dd % 10) & 0x000f;
i |= (((dd / 10) & 0x0003) << 4);
putport((char)(i & 0x00ff),DAY);
if (ram)
putport((char)(i & 0x00ff),RAMDAY);
}
if (fy)
{
ww = day(wm, wd, wy);
if (ww == 0) /* adjust SUNDAY to AST format */
ww = 7;
putport((char)(ww & 0x0007),WEEKDAY);
if (ram)
putport((char)(ww & 0x0007),RAMWEEKDAY);
}
if (fh)
{
if (fy)
{
t[0] = argv[1][6];
t[1] = argv[1][7];
}
else
{
t[0] = argv[1][0];
t[1] = argv[1][1];
}
t[2] = '\0';
if (((hh = atoi(t)) < 0) || (hh > 23))
{
printf("hours must be between 00 and 23\n");
return (usage(argv));
}
i = (hh % 10) & 0x000f;
i |= (((hh / 10) & 0x0003) << 4);
putport((char)(i & 0x00ff),HOURS);
if (ram)
putport((char)(i & 0x00ff),RAMHOURS);
}
if (fn)
{
if (fy)
{
t[0] = argv[1][8];
t[1] = argv[1][9];
}
else
{
t[0] = argv[1][2];
t[1] = argv[1][3];
}
t[2] = '\0';
if (((nn = atoi(t)) < 0) || (nn > 59))
{
printf("minutes must be between 00 and 59\n");
return (usage(argv));
}
i = (nn % 10) & 0x000f;
i |= (((nn / 10) & 0x0007) << 4);
putport((char)(i & 0x00ff),MINUTES);
}
if (fs)
{
t[0] = argv[1][11];
t[1] = argv[1][12];
t[2] = '\0';
if (((ss = atoi(t)) < 0) || (ss > 59))
{
printf("seconds must be between 00 and 59\n");
return (usage(argv));
}
i = (ss % 10) & 0x000f;
i |= (((ss / 10) & 0x0007) << 4);
putport((char)(i & 0x00ff),SECONDS);
}
putport((char)0,HUNDREDTHS);
putport((char)0,THOUSANDTHS);
putport((char)0,RAMTHOUSANDTHS);
putport((char)0,INTCONTROL);
return (1);
}
getdate(argc,argv)
int argc;
char *argv[];
{
argc--, argv++;
while (argc > 0 && **argv == '-')
{
(*argv)++;
while (**argv)
{
switch (*(*argv)++)
{
case 'T': /* time for date */
return (time());
case 'D': /* date for date */
return (date());
case 't': /* time for user */
return (utime());
case 'd': /* date for user */
return (udate());
case 'a': /* date and time for user */
return (udatetime());
case 'A': /* for debugging */
return (dumpall());
case '-': /* for help */
case '?': /* for help */
case 'h': /* for help */
return (help());
}
}
argc--, argv++;
}
return (datetime()); /* date and time for date */
}
time()
{
register unsigned int c, hh, mm;
c = getport(HOURS);
hh = c & 0x000f;
hh += ((c >> 4) & 0x0003) * 10;
c = getport(MINUTES);
mm = c & 0x000f;
mm += ((c >> 4) & 0x0007) * 10;
printf("%02d%02d",hh,mm);
return (1);
}
date()
{
register unsigned int c, dd, mm, yy;
c = getport(DAY);
dd = c & 0x000f;
dd += ((c >> 4) & 0x0003) * 10;
c = getport(MONTH);
mm = c & 0x000f;
mm += ((c >> 4) & 0x0001) * 10;
c = getport(YEAR);
yy = c & 0x000f;
yy += ((c >> 4) & 0x000f) * 10;
printf("%02d%02d%02d",(yy + 80),mm,dd);
return (1);
}
datetime()
{
date();
time();
return (1);
}
utime()
{
register unsigned int c, hh, mm, ss, am;
c = getport(HOURS);
hh = c & 0x000f;
hh += ((c >> 4) & 0x0003) * 10;
if (hh < 12)
am = 1;
else
am = 0;
if ((hh %= 12) == 0)
hh = 12;
c = getport(MINUTES);
mm = c & 0x000f;
mm += ((c >> 4) & 0x0007) * 10;
c = getport(SECONDS);
ss = c & 0x000f;
ss += ((c >> 4) & 0x0007) * 10;
printf("The time is: %d:%02d:%02d %s\n",hh,mm,ss,(am ? "AM" : "PM"));
return (1);
}
udate()
{
register unsigned int c, dd, mm, yy, ww;
c = getport(DAY);
dd = c & 0x000f;
dd += ((c >> 4) & 0x0003) * 10;
c = getport(MONTH);
mm = c & 0x000f;
mm += ((c >> 4) & 0x0001) * 10;
c = getport(YEAR);
yy = c & 0x000f;
yy += ((c >> 4) & 0x000f) * 10;
c = getport(WEEKDAY);
ww = c & 0x0007;
printf("The date is: %s - %s %d, 19%d PDT\n",
week[ww],month[mm],dd,(yy + 80));
return (1);
}
udatetime()
{
udate();
utime();
return (1);
}
dumpall()
{
register unsigned int c, i;
c = getport(THOUSANDTHS);
i = ((c >> 4) & 0x000f) * 10;
printf("ten thousandth of a second = %d\n",i);
c = getport(HUNDREDTHS);
i = c & 0x000f;
i += ((c >> 4) & 0x000f) * 10;
printf("hundredth of a second = %d\n",i);
c = getport(SECONDS);
i = c & 0x000f;
i += ((c >> 4) & 0x0007) * 10;
printf("seconds = %d\n",i);
c = getport(MINUTES);
i = c & 0x000f;
i += ((c >> 4) & 0x0007) * 10;
printf("minutes = %d\n",i);
c = getport(HOURS);
i = c & 0x000f;
i += ((c >> 4) & 0x0003) * 10;
printf("hours = %d\n",i);
c = getport(WEEKDAY);
i = c & 0x0007;
printf("weekday = %d %s\n",i,week[i]);
c = getport(DAY);
i = c & 0x000f;
i += ((c >> 4) & 0x0003) * 10;
printf("day = %d\n",i);
c = getport(MONTH);
i = c & 0x000f;
i += ((c >> 4) & 0x0001) * 10;
printf("month = %d %s\n",i,month[i]);
c = getport(RAMTHOUSANDTHS);
i = ((c >> 4) & 0x000f) * 10;
printf("upper - ram thousandths = %d c = 0x%x %o\n",i,c,c);
c = getport(RAMHUNDREDTHS);
i = c & 0x000f;
i += ((c >> 4) & 0x000f) * 10;
printf("last month - ram hundredths = %d %s c = 0x%x %o\n",
i,month[i],c,c);
c = getport(RAMSECONDS);
i = c & 0x000f;
i += ((c >> 4) & 0x000f) * 10;
printf("year - ram seconds = 19%d c = 0x%x %o\n",(i + 80),c,c);
c = getport(RAMMINUTES);
i = c & 0x000f;
i += ((c >> 4) & 0x0007) * 10;
printf("special - ram minutes = %d c = 0x%x %o\n",i,c,c);
c = getport(RAMHOURS);
i = c & 0x000f;
i += ((c >> 4) & 0x0003) * 10;
printf("ram - hours = %d\n",i);
c = getport(RAMWEEKDAY);
i = c & 0x0007;
printf("ram - weekday = %d\n",i);
c = getport(RAMDAY);
i = c & 0x000f;
i += ((c >> 4) & 0x0003) * 10;
printf("ram - day = %d\n",i);
c = getport(RAMMONTH);
i = c & 0x000f;
i += ((c >> 4) & 0x0001) * 10;
printf("ram - month = %d\n",i);
c = getport(INTSTATUS);
printf("interrupt status = %d\n",c);
c = getport(INTCONTROL);
printf("interrupt control = %d\n",c);
c = getport(COUNTRESET);
printf("count reset = %d\n",c);
c = getport(RAMRESET);
printf("ram reset = %d\n",c);
c = getport(STATUS);
printf("status = %d\n",c);
c = getport(GO);
printf("go = %d\n",c);
c = getport(INTSTANDBY);
printf("interrupt standby = %d\n",c);
c = getport(TEST);
printf("test = %d\n",c);
return (1);
}
usage()
{
printf("usage: setdate [-r] yymmddhhmm.ss\n");
printf(" -r - set rams in addition to counters\n");
printf(" yy - year\n");
printf(" mm - month\n");
printf(" dd - day\n");
printf(" hh - hours\n");
printf(" mm - minutes\n");
printf(" . - necessary to indicate seconds\n");
printf(" ss - seconds (optional: default = 0)\n");
return (0);
}
help()
{
printf("usage: getdate [-T | -D | -t | -d | -a | -A | -h | -? | --]\n");
printf("no options - returns 'yymmddhhmm' for date command\n");
printf(" -T - returns 'hhmm' for date command\n");
printf(" -D - returns 'yymmdd' for date command\n");
printf(" -t - return time in user readable format\n");
printf(" -d - return date in user readable format\n");
printf(" -a - return date and time in user readable format\n");
printf(" -A - dump all counters of the calendar clock\n");
printf(" -- - print this options list\n");
printf(" -? - print this options list\n");
printf(" -h - print this options list\n");
return (0);
}
/*
The following routine returns an integer 0 thru 6 for
day of week ( 0 = Sunday and 6 = Saturday ).
It was borrowed from the net (I forget the name of writer)
so it is not of my creation.
*/
day(m, d, y)
int m, d, y;
{
int y0, y1, y2, m1, dbuf;
m1 = ((m + 9) % 12) + 1;
y0 = (m <= 2) ? (y - 1) : y;
y1 = y0 / 100;
y2 = y0 % 100;
dbuf = ((26 * m1 - 2) / 10 + d + y2 + y2 / 4 + y1 / 4 - 2 * y1) % 7;
if (dbuf < 0)
dbuf += 7;
return (dbuf);
}
/*
The following routines go directly to the hardware
ports bypassing all the bios and everything else.
You can use them to poke and peek any other port.
They are highly optimized (as fas as I know) and
very sensitive about additions to them as far as
parameters and/or additional lines of code.
SO, LEAVE THEM ALONE FOR YOUR PROTECTION.
*/
char
getport(p)
{
asm(" mov dx,4(bp)");
asm(" in");
asm(" mov ah,#0");
}
putport(c,p)
{
asm(" mov dx,6(bp)");
asm(" mov ax,*4(bp)");
asm(" out");
}
/*-----------------------------------THE END-----------------------------*/
More information about the Comp.sources.unix
mailing list