diff --git a/src/emu/machine/n68681.c b/src/emu/machine/n68681.c index 51bf2a34d59..37b4f39cbac 100644 --- a/src/emu/machine/n68681.c +++ b/src/emu/machine/n68681.c @@ -130,6 +130,7 @@ void duartn68681_device::device_reset() OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ IP_last_state = 0; /* last state of IP bits */ + m_read_vector = false; // "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); @@ -166,6 +167,7 @@ void duartn68681_device::update_interrupts() { LOG(( "68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR)); write_irq(CLEAR_LINE); + m_read_vector = false; // clear IACK too } }; @@ -314,6 +316,18 @@ READ8_MEMBER( duartn68681_device::read ) { r = IP_last_state; } + + r |= 0x80; // bit 7 is always set + + // bit 6 is /IACK (note the active-low) + if (m_read_vector) + { + r &= ~0x40; + } + else + { + r |= 0x40; + } break; case 0x0e: /* Start counter command */ @@ -523,14 +537,14 @@ WRITE_LINE_MEMBER( duartn68681_device::ip3_w ) WRITE_LINE_MEMBER( duartn68681_device::ip4_w ) { UINT8 newIP = (IP_last_state & ~0x10) | (state == ASSERT_LINE) ? 0x10 : 0; -// TODO: special mode for ip4 +// TODO: special mode for ip4 (Ch. A Rx clock) IP_last_state = newIP; } WRITE_LINE_MEMBER( duartn68681_device::ip5_w ) { UINT8 newIP = (IP_last_state & ~0x20) | (state == ASSERT_LINE) ? 0x20 : 0; -// TODO: special mode for ip5 +// TODO: special mode for ip5 (Ch. B Tx clock) IP_last_state = newIP; } diff --git a/src/emu/machine/n68681.h b/src/emu/machine/n68681.h index 35ea05efdca..c0e6b358466 100644 --- a/src/emu/machine/n68681.h +++ b/src/emu/machine/n68681.h @@ -109,7 +109,7 @@ public: // API DECLARE_READ8_HANDLER(read); DECLARE_WRITE8_HANDLER(write); - UINT8 get_irq_vector() { return IVR; } + UINT8 get_irq_vector() { m_read_vector = true; return IVR; } DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((UINT8)state); } DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((UINT8)state); } @@ -152,6 +152,8 @@ private: PAIR CTR; /* Counter/Timer Preset Value */ UINT8 IPCR; /* Input Port Control Register */ + bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK + /* state */ UINT8 IP_last_state; /* last state of IP bits */