void MAIN::write_signal(int id, uint32 data, uint32 mask) { switch(id) { case SIG_MAIN_INTS: case SIG_MAIN_INTA: case SIG_MAIN_INTB: case SIG_MAIN_INTC: case SIG_MAIN_INTD: if(data & mask) { if(!(intr_req & priority[id])) { intr_req |= priority[id]; update_intr(); } } else { if(intr_req & priority[id]) { intr_req &= ~priority[id]; update_intr(); } } break; case SIG_MAIN_COMM: comm_data = data & 0xff; break; } }
void RTC::event_callback(int event_id, int err) { if(event_id == EVENT_1HZ) { // update calendar if(cur_time.initialized) { cur_time.increment(); } else { get_host_time(&cur_time); // resync cur_time.initialized = true; } read_from_cur_time(); // 1sec interrupt rtdsr |= 4; update_intr(); } else if(event_id == EVENT_32HZ) { // update tcnt regs[TCNT]++; } else if(event_id == EVENT_DONE) { int ch = (rtadr >> 1) & 0x3f; if(rtadr & 1) { // invalid address } else if(rtadr & 0x80) { // write if(ch <= 6) { regs[ch] = (uint8_t)rtobr; write_to_cur_time(); } else if(ch == POWON) { regs[ch] = (regs[ch] & 0xe0) | (rtobr & 0x1f); if((rtobr & 0xe0) == 0xc0) { // reipl regs[ch] = (regs[ch] & 0x1f) | 0xc0; vm->reset(); } else if((rtobr & 0xe0) == 0xe0) { // power off emu->power_off(); } update_checksum(); } else if(7 <= ch && ch < 32) { regs[ch] = (uint8_t)rtobr; update_checksum(); } } else { // read if(ch < 40) { rtibr = regs[ch]; } } // update flags rtdsr &= ~1; rtdsr |= 2; update_intr(); }
void SERIAL::write_io8(uint32 addr, uint32 data) { switch(addr & 0xffff) { case 0x0a: sioctrl[0].baud = data; break; case 0x0b: sioctrl[0].ctrl = data; d_kb->write_signal(SIG_I8251_LOOPBACK, data, 8); update_intr(0); break; case 0x12: sioctrl[1].baud = data; break; case 0x13: sioctrl[1].ctrl = data; d_sub->write_signal(SIG_I8251_LOOPBACK, data, 8); update_intr(1); break; case 0x62: sioctrl[2].baud = data; break; case 0x63: sioctrl[2].ctrl = data; d_ch1->write_signal(SIG_I8251_LOOPBACK, data, 8); update_intr(2); break; case 0x64: sioctrl[2].intmask = data; break; case 0x65: sioctrl[2].intstat &= ~data; break; case 0x72: sioctrl[3].baud = data; break; case 0x73: sioctrl[3].ctrl = data; d_ch2->write_signal(SIG_I8251_LOOPBACK, data, 8); update_intr(3); break; case 0x74: sioctrl[3].intmask = data; break; case 0x75: sioctrl[3].intstat &= ~data; break; } }
void FLOPPY::write_signal(int id, uint32_t data, uint32_t mask) { if(id == SIG_FLOPPY_IRQ) { irq = ((data & mask) != 0); update_intr(); } }
void FLOPPY::write_io8(uint32_t addr, uint32_t data) { switch(addr & 0xffff) { case 0x34: // drive control register fdcr = data; update_intr(); // d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x18); d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4); break; case 0x35: // drive select register fdsl = data; if(drvsel != (data & 3)) { d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = data & 3, 3); fdst = changed[drvsel] ? 1 : 0; changed[drvsel] = false; } d_fdc->write_signal(SIG_MB8877_MOTOR, 1, 1); break; case 0x36: // echo clear if(data & 1) { fdst &= ~1; } break; } }
void FLOPPY::write_io8(uint32_t addr, uint32_t data) { int nextdrv = drvsel; switch(addr & 0xffff) { case 0x208: // drive control register irqmsk = ((data & 1) != 0); update_intr(); d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10); d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4); break; case 0x20c: // drive select register if(data & 1) { nextdrv = 0; } else if(data & 2) { nextdrv = 1; } else if(data & 4) { nextdrv = 2; } else if(data & 8) { nextdrv = 3; } if(drvsel != nextdrv) { d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3); } drvreg = data; break; } }
void SERIAL::write_signal(int id, uint32 data, uint32 mask) { switch(id) { case SIG_SERIAL_RXRDY_KB: case SIG_SERIAL_RXRDY_SUB: case SIG_SERIAL_RXRDY_CH1: case SIG_SERIAL_RXRDY_CH2: sioctrl[id & 3].rxrdy = ((data & mask) != 0); update_intr(id & 3); break; case SIG_SERIAL_TXRDY_KB: case SIG_SERIAL_TXRDY_SUB: case SIG_SERIAL_TXRDY_CH1: case SIG_SERIAL_TXRDY_CH2: sioctrl[id & 3].txrdy = ((data & mask) != 0); update_intr(id & 3); break; } }
void MAIN::write_io8(uint32 addr, uint32 data) { switch(addr & 0xffe0) { case 0xff00: case 0xff20: case 0xff40: case 0xff60: slot_sel = (slot_sel & 1) | ((data << 1) & 6); break; case 0xff80: if((intr_mask & 0x80) != (data & 0x80)) { intr_mask = (intr_mask & (~0x80)) | (data & 0x80); d_sub->write_signal(SIG_SUB_INT2, data, 0x80); } if((intr_mask & 0x1f) != (data & 0x1f)) { intr_mask = (intr_mask & (~0x1f)) | (data & 0x1f); update_intr(); } break; case 0xffa0: if(data & 2) { SET_BANK(0x0000, 0x8fff, ram, ram); } else { SET_BANK(0x0000, 0x8fff, ram, rom); } slot_sel = (slot_sel & 6) | (data & 1); break; case 0xffc0: d_sub->write_signal(SIG_SUB_COMM, data, 0xff); break; case 0xffe0: break; default: d_slot[slot_sel & 7]->write_io8(addr, data); break; } }
void RTC::write_io16(uint32_t addr, uint32_t data) { switch(addr) { case 0: rtcmr = data; break; case 2: // echo reset rtdsr &= ~(data & 0xe); update_intr(); break; case 4: if(!(rtdsr & 1)) { rtadr = data; rtdsr |= 1; // register event register_event(this, EVENT_DONE, 100, false, NULL); } break; case 6: rtobr = data; break; } }