static void rtc_write(const uint16_t pio, const uint8_t byte) { uint16_t index = pio & 0xFF; uint8_t bit_offset = (index & 3) << 3; switch (index) { case 0x10: rtc.alarmSec = byte; break; case 0x14: rtc.alarmMin = byte; break; case 0x18: rtc.alarmHour = byte; break; case 0x20: rtc.control = byte; if (rtc.control & 1) { event_set(SCHED_RTC, 0); } else { event_clear(SCHED_RTC); } if (rtc.control & 64) { /* (Bit 6) -- Load time */ rtc.readSec = rtc.writeSec; rtc.readMin = rtc.writeMin; rtc.readHour = rtc.writeHour; rtc.readDay = rtc.writeDay; rtc.control &= ~64; rtc.interrupt |= 32; /* Load operation complete */ intrpt_set(INT_RTC, (rtc.interrupt & rtc.control & 15) ? true : false); } if (!(rtc.control & 128)) { hold_read(); } break; case 0x24: rtc.writeSec = byte; break; case 0x28: rtc.writeMin = byte; break; case 0x2C: rtc.writeHour = byte; break; case 0x30: case 0x31: write8(rtc.writeDay, bit_offset, byte); break; case 0x34: rtc.interrupt &= ~byte; intrpt_set(INT_RTC, (rtc.interrupt & rtc.control & 15) ? true : false); break; default: break; } }
static void rtc_event(int index) { /* Update exactly once a second */ event_repeat(index, 32768); if (rtc.control & 1) { rtc.interrupt |= 1; } rtc.readSec++; if (rtc.readSec > 59) { rtc.readSec = 0; if (rtc.control & 2) { rtc.interrupt |= 2; intrpt_set(INT_RTC, true); } rtc.readMin++; if (rtc.readMin > 59) { rtc.readMin = 0; if (rtc.control & 4) { rtc.interrupt |= 4; intrpt_set(INT_RTC, true); } rtc.readHour++; if (rtc.readHour > 23) { rtc.readHour = 0; if (rtc.control & 8) { rtc.interrupt |= 8; intrpt_set(INT_RTC, true); } rtc.readDay++; } } } if ((rtc.control & 16) && (rtc.readSec == rtc.alarmSec) && (rtc.readMin == rtc.alarmMin) && (rtc.readHour == rtc.alarmHour)) { rtc.interrupt |= 16; intrpt_set(INT_RTC, true); } }
static void rtc_write(const uint16_t pio, const uint8_t byte, bool poke) { uint16_t index = pio & 0xFF; uint8_t bit_offset = (index & 3) << 3; (void)poke; switch (index) { case 0x10: rtc.alarmSec = byte; break; case 0x14: rtc.alarmMin = byte; break; case 0x18: rtc.alarmHour = byte; break; case 0x20: rtc.control = byte; if (rtc.control & 1) { sched_set(SCHED_RTC, 0); } else { sched_clear(SCHED_RTC); } if (!(rtc.control & 128)) { hold_read(); } break; case 0x24: rtc.writeSec = byte; break; case 0x28: rtc.writeMin = byte; break; case 0x2C: rtc.writeHour = byte; break; case 0x30: case 0x31: write8(rtc.writeDay, bit_offset, byte); break; case 0x34: rtc.interrupt &= ~byte; intrpt_set(INT_RTC, rtc.interrupt & rtc.control & 15); break; default: break; } }
void keypad_key_event(unsigned int row, unsigned int col, bool press) { if (row == 2 && col == 0) { intrpt_set(INT_ON, press); if (press && control.ports[0] & 0x40) { control.readBatteryStatus = ~1; intrpt_pulse(19); } } else { if (press) { keypad.key_map[row] |= 1 << col; if (keypad.mode == 1) { keypad.status |= 4; keypad_intrpt_check(); } } else { keypad.key_map[row] &= ~(1 << col); } } }
static void rtc_event(enum sched_item_id id) { /* Update exactly once a second */ sched_repeat(id, 1); if (rtc.control & 64) { /* (Bit 6) -- Load time */ rtc.readSec = rtc.writeSec; rtc.readMin = rtc.writeMin; rtc.readHour = rtc.writeHour; rtc.readDay = rtc.writeDay; rtc.control &= ~64; rtc.interrupt |= 32; /* Load operation complete */ intrpt_set(INT_RTC, true); } rtc.readSec++; if (rtc.control & 2) { rtc.interrupt |= 1; intrpt_set(INT_RTC, true); } if (rtc.readSec > 59) { rtc.readSec = 0; if (rtc.control & 4) { rtc.interrupt |= 2; intrpt_set(INT_RTC, true); } rtc.readMin++; if (rtc.readMin > 59) { rtc.readMin = 0; if (rtc.control & 8) { rtc.interrupt |= 4; intrpt_set(INT_RTC, true); } rtc.readHour++; if (rtc.readHour > 23) { rtc.readHour = 0; if (rtc.control & 16) { rtc.interrupt |= 8; intrpt_set(INT_RTC, true); } rtc.readDay++; } } } if ((rtc.control & 32) && (rtc.readSec == rtc.alarmSec) && (rtc.readMin == rtc.alarmMin) && (rtc.readHour == rtc.alarmHour)) { rtc.interrupt |= 16; intrpt_set(INT_RTC, true); } }
void EMSCRIPTEN_KEEPALIVE keypad_key_event(unsigned int row, unsigned int col, bool press) { if (row == 2 && col == 0) { intrpt_set(INT_ON, press); if (press && calc_is_off()) { asic.ship_mode_enabled = false; control.readBatteryStatus = ~1; intrpt_pulse(19); } } else { if (press) { keypad.key_map[row] |= 1 << col; if (keypad.mode == 1) { keypad.status |= 4; keypad_intrpt_check(); } } else { keypad.data[row] = keypad.key_map[row] &= ~(1 << col); keypad.status |= 2; keypad_intrpt_check(); } } }
void keypad_intrpt_check() { intrpt_set(INT_KEYPAD, (keypad.status & keypad.enable) | (keypad.gpio_status & keypad.gpio_enable)); }
void intrpt_pulse(uint32_t int_num) { intrpt_set(int_num, true); intrpt_set(int_num, false); }