/* * 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; }