#define APPLE1_USE_WOZ_MONITOR 1 #define INPUT_LINE_PROMPT_CHAR '?' #include #include #include #include #include #include #include #include "..\..\lib\c64font.h" // const word ONE_TICK = 15996; // timer constant for 1/60 second calculated as 14318180/14*61/65/60 word ONE_TICK; void enable_timer_interrupt() { // install the interrupt handler install_interrupt((word) &time_interrupt_handler); *VIA_IER = 0b11000000; // enable T1 interrupts *VIA_ACR = 0b01000000; // T1 continous, PB7 disabled *VIA_T1CL = BYTE0(ONE_TICK); // programs the counter to 1/60 *VIA_T1CH = BYTE1(ONE_TICK); // and starts counting } void disable_timer_interrupt() { *VIA_IER = 0b01000000; // disable T1 interrupts *VIA_ACR = 0; // stop T1 (makes it one-shot) } byte last_min = 0xFF; byte last_sec = 0xFF; void print_digit_scanline(byte c, byte y) { word index = ((word) c-32) * 8 + (word) y; byte *ptr = FONT + index; byte mask = 128; for(byte t=0;t<8;t++) { if(*ptr & mask) woz_putc('@'); else woz_putc(' '); mask = mask >> 1; } } void print_clock() { byte c1,c2,c3,c4; if(last_min != _minutes) { last_min = _minutes; c1 = divr8u(_hours, 10, 0); c2 = rem8u; c3 = divr8u(_minutes, 10, 0); c4 = rem8u; for(byte t=0;t<24;t++) woz_putc('\r'); for(byte t=0;t<8;t++) { print_digit_scanline(c1+'0',t); print_digit_scanline(c2+'0',t); print_digit_scanline( ':',t); print_digit_scanline(c3+'0',t); print_digit_scanline(c4+'0',t); } for(byte t=0;t<4;t++) woz_putc('\r'); last_sec = 0; } if(last_sec < _seconds) { //if(last_sec > 20) woz_putc('>'); /* if(last_sec < 10) { woz_puts("...10 "); last_sec = 10; } else if(last_sec < 20) { woz_puts("...20 "); last_sec = 20; } else if(last_sec < 30) { woz_puts("...30 "); last_sec = 30; } else if(last_sec < 40) { woz_puts("...40 "); last_sec = 40; } else if(last_sec < 50) { woz_puts("...50 "); last_sec = 50; } */ c1 = divr8u(last_sec, 10, 0); c2 = rem8u; woz_putc(' '); woz_putc(c1+'0'); woz_putc(c2+'0'); woz_putc(' '); last_sec++; } } void bye() { disable_timer_interrupt(); woz_puts("BYE!\r"); woz_mon(); } void detect_machine_type() { // detect if VIA 6522 is present *VIA_DDRB = 0xA5; if(*VIA_DDRB != 0xA5) { woz_puts("\r\rSORRY, THIS PROGRAM NEEDS A VIA 6522 \rMAPPED AT ADDRESS $A000\r\r"); bye(); } // detect if genuine apple1 or replica-1 woz_puts("\r\rRUNNING ON "); const word *ptr1 = (word *) 0xF000; const word *ptr2 = (word *) 0xFF00; if(*ptr1 == *ptr2) { // genuine Apple1 ONE_TICK = 15996; // timer constant for 1/60 second calculated as 14318180/14*61/65/60 woz_puts("APPLE-1"); } else { // Replica-1 ONE_TICK = 16667; // timer constant for 1/60 second calculated as 5000000/5/60 woz_puts("REPLICA-1"); } woz_puts("\r\r"); } byte *const KEYBUF = (byte *) 0x0200; // use the same keyboard buffer as in WOZ monitor void main() { woz_puts("\r\r*** APPLE-1 CLOCK ***\r\r"); detect_machine_type(); woz_puts("\rWHAT TIME IS IT ?\r"); do { woz_puts("\r(HOURS ) "); apple1_input_line_prompt(KEYBUF, 2); _hours = (byte) atoi(KEYBUF); } while(_hours > 23); do { woz_puts("\r(MINUTES) "); apple1_input_line_prompt(KEYBUF, 2); _minutes = (byte) atoi(KEYBUF); } while(_minutes > 59); _seconds = 0; enable_timer_interrupt(); woz_putc('\r'); while(1) { byte k = apple1_readkey(); if(k=='X') break; print_clock(); } bye(); }