void duart_base_device::update_interrupts() { /* update SR state and update interrupt ISR state for the following bits: SRn: bits 7-4: handled elsewhere. SRn: bit 3 (TxEMTn) (we can assume since we're not actually emulating the delay/timing of sending bits, that as long as TxRDYn is set, TxEMTn is also set since the transmit byte has 'already happened', therefore TxEMTn is always 1 assuming tx is enabled on channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined) SRn: bit 2 (TxRDYn) (we COULD assume since we're not emulating delay and timing output, that as long as tx is enabled on channel n, TxRDY is 1 for channel n and the MSR2n mode is 0 or 2; in mode 1 it is explicitly zeroed, and mode 3 is undefined; however, tx_ready is already nicely handled for us elsewhere, so we can use that instead for now, though we may need to retool that code as well) SRn: bit 1 (FFULLn) (this bit we actually emulate; if the receive fifo for channel n is full, this bit is 1, otherwise it is 0. the receive fifo should be three words long.) SRn: bit 0 (RxRDYn) (this bit we also emulate; the bit is always asserted if the receive fifo is not empty) ISR: bit 7: Input Port change; this should be handled elsewhere, on the input port handler ISR: bit 6: Delta Break B; this should be handled elsewhere, on the data receive handler ISR: bit 5: RxRDYB/FFULLB: this is handled here; depending on whether MSR1B bit 6 is 0 or 1, this bit holds the state of SRB bit 0 or bit 1 respectively ISR: bit 4: TxRDYB: this is handled here; it mirrors SRB bit 2 ISR: bit 3: Counter ready; this should be handled by the timer generator ISR: bit 2: Delta Break A; this should be handled elsewhere, on the data receive handler ISR: bit 1: RxRDYA/FFULLA: this is handled here; depending on whether MSR1A bit 6 is 0 or 1, this bit holds the state of SRA bit 0 or bit 1 respectively ISR: bit 0: TxRDYA: this is handled here; it mirrors SRA bit 2 */ if ((ISR & IMR) != 0) { LOG("68681: Interrupt line active (IMR & ISR = %02X)\n", (ISR & IMR)); write_irq(ASSERT_LINE); } else { LOG("68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR); write_irq(CLEAR_LINE); } if (OPCR & 0xf0) { if (BIT(OPCR, 4)) { if (BIT(ISR, 1)) OPR |= 0x10; else OPR &= ~0x10; } if (BIT(OPCR, 5)) { if (BIT(ISR, 5)) OPR |= 0x20; else OPR &= ~0x20; } if (BIT(OPCR, 6)) { if (BIT(ISR, 0)) OPR |= 0x40; else OPR &= ~0x40; } if (BIT(OPCR, 7)) { if (BIT(ISR, 4)) OPR |= 0x80; else OPR &= ~0x80; } write_outport(OPR ^ 0xff); } }
void duartn68681_device::device_reset() { ACR = 0; /* Interrupt Vector Register */ IVR = 0x0f; /* Interrupt Vector Register */ IMR = 0; /* Interrupt Mask Register */ ISR = 0; /* Interrupt Status Register */ OPCR = 0; /* Output Port Conf. Register */ OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ IP_last_state = 0; /* last state of IP bits */ // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" write_outport(OPR ^ 0xff); }
void duart_base_device::device_reset() { ACR = 0; /* Interrupt Vector Register */ IMR = 0; /* Interrupt Mask Register */ ISR = 0; /* Interrupt Status Register */ OPCR = 0; /* Output Port Conf. Register */ OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" IPCR = 0; write_irq(CLEAR_LINE); write_outport(OPR ^ 0xff); }