/*
* JR-IDE Project
* - (c) 2017 Alan Hightower
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "jride.h"
static int _iparse (const char *text, uint32_t *value_ptr)
{
int i, len, base, error = 0;
if (strncasecmp (text, "0x", 2) == 0)
{
base = 16;
text += 2;
}
else if (*text == '0')
base = 8;
else
base = 10;
*value_ptr = 0;
len = strlen (text);
for (i = 0; i < len; i++)
{
*value_ptr *= base;
switch (text[i])
{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
if (base != 16)
{
error = 1;
break;
}
*value_ptr += 10 + text[i] - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
if (base != 16)
{
error = 1;
break;
}
*value_ptr += 10 + text[i] - 'A';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
*value_ptr += text[i] - '0';
break;
default:
error = 1;
break;
}
}
return error;
}
static void _print_usage (const char *progname)
{
fprintf (stderr, "\nUsage: %s [/R|/D] [/P|/O] [/Q]\n\n"
"\t/R Set RTC from DOS time\n"
"\t/D Set DOS from RTC time\n"
"\t/P[=0xnn] Turn POST code and heartbeat display on\n"
"\t/O Turn POST code and heartbeat display off\n"
"\t/Q Quiet mode - no console output\n"
"\n", progname);
return;
}
int main (int argc, char *argv[])
{
const char *progname = basename(argv[0]);
struct dostime_t dos_time;
struct dosdate_t dos_date;
int rc = 0;
// switches
int quiet = 0,
update_dos = 0, update_rtc = 0,
post_on = 0, post_off = 0, post_code = -1;
argc--; argv++;
while (argc)
{
if (strcasecmp (argv[0], "/Q") == 0)
quiet = 1;
else if (strcasecmp (argv[0], "/D") == 0)
update_dos = 1;
else if (strcasecmp (argv[0], "/R") == 0)
update_rtc = 1;
else if (strncasecmp (argv[0], "/P", 2) == 0)
{
post_on = 1;
if (argv[0][2] == '=')
{
uint32_t value = 0;
if (_iparse (argv[0] + 3, &value))
{
fprintf (stderr, "\nERROR: Unknown value in '%s'\n", argv[0]);
_print_usage (progname);
return -1;
}
else
post_code = value & 0xff;
}
}
else if (strcasecmp (argv[0], "/O") == 0)
post_off = 1;
else
{
fprintf (stderr, "\nERROR: Unknown option '%s'\n", argv[0]);
_print_usage (progname);
return -1;
}
argc--; argv++;
}
if (update_dos && update_rtc)
{
fprintf (stderr, "\nERROR: Options /R and /D are exclusive\n");
_print_usage (progname);
return 0;
}
if (post_on && post_off)
{
fprintf (stderr, "\nERROR: Options /P and /O are exclusive\n");
_print_usage (progname);
return 0;
}
if (!quiet)
{
printf ("JR-IDE -");
if (update_dos)
printf (" Setting DOS Clock from RTC");
else if (update_rtc)
printf (" Setting RTC Clock from DOS");
if (post_on)
printf (" (POST On)");
else if (post_off)
printf (" (POST Off)");
printf ("\n");
}
if (update_rtc)
{
outp (JRIDE_RTC_ADDR_PORT, 0x0b); // control
outp (JRIDE_RTC_DATA_PORT, 0x87);
outp (JRIDE_RTC_DATA_PORT, 0x87); // yes 2x
outp (JRIDE_RTC_ADDR_PORT, 0x0a); // control
if (inp (JRIDE_RTC_DATA_PORT) != 0x20)
{
outp (JRIDE_RTC_ADDR_PORT, 0x0a);
outp (JRIDE_RTC_DATA_PORT, 0x20);
}
_dos_getdate (&dos_date);
_dos_gettime (&dos_time);
outp (JRIDE_RTC_ADDR_PORT, 0x00); // seconds
outp (JRIDE_RTC_DATA_PORT, dos_time.second);
outp (JRIDE_RTC_ADDR_PORT, 0x01); // seconds alarm
outp (JRIDE_RTC_DATA_PORT, 0x00);
outp (JRIDE_RTC_ADDR_PORT, 0x02); // minutes
outp (JRIDE_RTC_DATA_PORT, dos_time.minute);
outp (JRIDE_RTC_ADDR_PORT, 0x03); // minutes alarm
outp (JRIDE_RTC_DATA_PORT, 0x00);
outp (JRIDE_RTC_ADDR_PORT, 0x04); // hours
outp (JRIDE_RTC_DATA_PORT, dos_time.hour);
outp (JRIDE_RTC_ADDR_PORT, 0x05); // hours alarm
outp (JRIDE_RTC_DATA_PORT, 0x00);
outp (JRIDE_RTC_ADDR_PORT, 0x06); // day of week
outp (JRIDE_RTC_DATA_PORT, dos_date.dayofweek + 1);
outp (JRIDE_RTC_ADDR_PORT, 0x07); // date
outp (JRIDE_RTC_DATA_PORT, dos_date.day);
outp (JRIDE_RTC_ADDR_PORT, 0x08); // month
outp (JRIDE_RTC_DATA_PORT, dos_date.month);
outp (JRIDE_RTC_ADDR_PORT, 0x09); // year
outp (JRIDE_RTC_DATA_PORT, dos_date.year % 100);
outp (JRIDE_RTC_ADDR_PORT, 0x32); // century
outp (JRIDE_RTC_DATA_PORT, dos_date.year / 100);
outp (JRIDE_RTC_ADDR_PORT, 0x0b); // control
outp (JRIDE_RTC_DATA_PORT, 0x07);
}
if (update_dos)
{
outp (JRIDE_RTC_ADDR_PORT, 0x00); // seconds
dos_time.second = inp (JRIDE_RTC_DATA_PORT);
outp (JRIDE_RTC_ADDR_PORT, 0x02); // minutes
dos_time.minute = inp (JRIDE_RTC_DATA_PORT);
outp (JRIDE_RTC_ADDR_PORT, 0x04); // hours
dos_time.hour = inp (JRIDE_RTC_DATA_PORT);
dos_time.hsecond = 0;
if ((rc = _dos_settime (&dos_time)))
{
fprintf (stderr, "ERROR: Unable to update DOS time\n");
}
else
{
outp (JRIDE_RTC_ADDR_PORT, 0x06); // day of week
dos_date.dayofweek = inp (JRIDE_RTC_DATA_PORT) - 1;
outp (JRIDE_RTC_ADDR_PORT, 0x07); // date
dos_date.day = inp (JRIDE_RTC_DATA_PORT);
outp (JRIDE_RTC_ADDR_PORT, 0x08); // month
dos_date.month = inp (JRIDE_RTC_DATA_PORT);
outp (JRIDE_RTC_ADDR_PORT, 0x09); // year
dos_date.year = inp (JRIDE_RTC_DATA_PORT);
outp (JRIDE_RTC_ADDR_PORT, 0x32); // century
dos_date.year += inp (JRIDE_RTC_DATA_PORT) * 100L;
if ((rc = _dos_setdate (&dos_date)))
{
fprintf (stderr, "ERROR: Unable to update DOS date\n");
}
}
}
if (post_on)
{
uint8_t reg = inp (JRIDE_POST_CTRL_PORT) & 0xf8;
outp (JRIDE_POST_CTRL_PORT, reg);
if (post_code >= 0)
outp (JRIDE_POST_DATA_PORT, post_code);
}
if (post_off)
{
uint8_t reg = inp (JRIDE_POST_CTRL_PORT) | 0x07;
outp (JRIDE_POST_CTRL_PORT, reg);
}
if (!quiet && (update_rtc || update_dos))
{
printf (" %s %s %d, %d - ",
(dos_date.dayofweek == 0) ? "Sunday" :
(dos_date.dayofweek == 1) ? "Monday" :
(dos_date.dayofweek == 2) ? "Tuesday" :
(dos_date.dayofweek == 3) ? "Wednesday" :
(dos_date.dayofweek == 4) ? "Thursday" :
(dos_date.dayofweek == 5) ? "Friday" :
(dos_date.dayofweek == 6) ? "Saturday" : "Unknown",
(dos_date.month == 1) ? "January" :
(dos_date.month == 2) ? "February" :
(dos_date.month == 3) ? "March" :
(dos_date.month == 4) ? "April" :
(dos_date.month == 5) ? "May" :
(dos_date.month == 6) ? "June" :
(dos_date.month == 7) ? "July" :
(dos_date.month == 8) ? "August" :
(dos_date.month == 9) ? "September" :
(dos_date.month == 10) ? "October" :
(dos_date.month == 11) ? "November" :
(dos_date.month == 12) ? "December" : "Unknown",
dos_date.day, dos_date.year);
printf ("%d:%02d:%02d%c\n",
dos_time.hour ? (dos_time.hour % 12) : 12,
dos_time.minute, dos_time.second,
(dos_time.hour > 11) ? 'p' : 'a');
}
return 0;
}