/* * CoCo "flashy" clock example using Dunfield Micro-C * * Copyright 2013 by John W. Linville */ #include <6809io.h> #include #define SYNC() asm " sync" struct pia { struct { unsigned char data; unsigned char ctrl; } piaport[2]; }; struct pia *pia0 = 0xff00; #define CURPOS ((unsigned int *)0x0088) #define TXTBASE ((char *)0x0400) #define TXTWIDTH 32 #define TXTLINES 16 #define TXTSIZE ((unsigned int)TXTWIDTH*TXTLINES) #define TXTEND (TXTBASE+TXTSIZE) void cls(unsigned char color) { unsigned char *pos, val; if (color == 0) val = 0x80; else val = 0x8f | ((color - 1) << 4); for (pos = TXTBASE; pos < TXTEND; pos++) *pos = val; } void curpos(unsigned int val) { if (val > TXTSIZE) abort("INVALID CURPOS!"); *CURPOS = TXTBASE + val; } char hour, minute, second, ampm, tick; void timeset(void) { char tmp; second = 0; putstr("CURRENT TIME\n\n"); do { putstr("HOUR? "); tmp = getchr(); putch(tmp); if ((tmp < '0') || (tmp > '2')) { hour = -1; putch('\n'); continue; } hour = 10 * (tmp - '0'); tmp = getchr(); putch(tmp); putch('\n'); if ((tmp < '0') || (tmp > '9')) { hour = -1; continue; } hour += (tmp - '0'); } while ((hour < 1) || (hour > 23)); do { putstr("MINUTE? "); tmp = getchr(); putch(tmp); if ((tmp < '0') || (tmp > '5')) { minute = -1; putch('\n'); continue; } minute = 10 * (tmp - '0'); tmp = getchr(); putch(tmp); putch('\n'); if ((tmp < '0') || (tmp > '9')) { minute = -1; continue; } minute += (tmp - '0'); } while (minute < 0); if (hour > 12) { ampm = 1; hour -= 12; } else do { putstr("AM/PM? "); tmp = getchr(); putch(tmp); putch('\n'); if (tmp == 'A') ampm = 0; else if (tmp == 'P') ampm = 1; else ampm = -1; } while (ampm < 0); } INTERRUPT(timer) { /* clear Vsync interrupt */ pia0->piaport[1].data; /* dummy read */ if (++tick < 60) return; tick = 0; if (++second < 60) return; second = 0; if (++minute < 60) return; minute = 0; if (++hour > 12) hour = 1; else if (hour == 12) ampm ^= 1; } void timestart(void) { disable(); /* Enable Vsync interrupt */ pia0->piaport[1].ctrl |= 0x05; pia0->piaport[1].data; /* dummy read */ tick = 0; SETIRQ(timer); enable(); } const char steps[] = { 10, 10, 20, 10, 10 }; void main(void) { char *cursor; char color, curval, mode, step; char output[9]; mode = step = color = 0; curval = 0x8f; timeset(); cls(0); output[2] = output[5] = ':'; output[8] = '\0'; curpos(272); putch('M'); cursor = TXTBASE + 16; timestart(); SYNC(); for (;;) { curpos(236); output[0] = '0' + (hour / 10); output[1] = '0' + (hour % 10); output[3] = '0' + (minute / 10); output[4] = '0' + (minute % 10); output[6] = '0' + (second / 10); output[7] = '0' + (second % 10); putstr(output); curpos(271); putch(ampm ? 'P' : 'A'); switch(mode) { case 0: *cursor++ = curval; if (!(step & 1)) *cursor++ = curval; break; case 1: *cursor = curval; cursor += 32; if (!(step & 1)) { *cursor = curval; cursor += 32; } break; case 2: *cursor-- = curval; if (step & 1) *cursor-- = curval; break; case 3: *cursor = curval; cursor -= 32; if (!(step & 1)) { *cursor = curval; cursor -= 32; } break; case 4: *cursor++ = curval; if (step & 1) *cursor++ = curval; break; default: /* should not happen! */ abort("unknown mode"); } if (++step == steps[mode]) { step = 0; if (++mode == sizeof(steps)) { mode = 0; color++; curval = 0x8f | ((color & 7) << 4); } } SYNC(); } }