diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index ac123b07b46..467817c6086 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -736,7 +736,7 @@ void upd7810_device::upd7810_take_irq() int irqline = 0; /* global interrupt disable? */ - if (0 == IFF) + if (0 == IFF && !(IRR & INTNMI)) return; /* check the interrupts in priority sequence */ @@ -751,21 +751,22 @@ void upd7810_device::upd7810_take_irq() if ((IRR & INTFT0) && 0 == (MKL & 0x02)) { vector = 0x0008; - if (!((IRR & INTFT1) && 0 == (MKL & 0x04))) - IRR&=~INTFT0; + if (0 != (MKL & 0x04)) + IRR&=~INTFT0; } else if ((IRR & INTFT1) && 0 == (MKL & 0x04)) { vector = 0x0008; - IRR&=~INTFT1; + if (0 != (MKL & 0x02)) + IRR&=~INTFT1; } else if ((IRR & INTF1) && 0 == (MKL & 0x08)) { irqline = UPD7810_INTF1; vector = 0x0010; - if (!((IRR & INTF2) && 0 == (MKL & 0x10))) + if (0 != (MKL & 0x10)) IRR&=~INTF1; } else @@ -773,42 +774,50 @@ void upd7810_device::upd7810_take_irq() { irqline = UPD7810_INTF2; vector = 0x0010; - IRR&=~INTF2; + if (0 != (MKL & 0x08)) + IRR&=~INTF2; } else if ((IRR & INTFE0) && 0 == (MKL & 0x20)) { vector = 0x0018; - if (!((IRR & INTFE1) && 0 == (MKL & 0x40))) - IRR&=~INTFE0; + if (0 != (MKL & 0x40)) + IRR&=~INTFE0; } else if ((IRR & INTFE1) && 0 == (MKL & 0x40)) { vector = 0x0018; - IRR&=~INTFE1; + if (0 != (MKL & 0x20)) + IRR&=~INTFE1; } else if ((IRR & INTFEIN) && 0 == (MKL & 0x80)) { vector = 0x0020; + if (0 != (MKH & 0x01)) + IRR&=~INTFEIN; } else if ((IRR & INTFAD) && 0 == (MKH & 0x01)) { vector = 0x0020; + if (0 != (MKL & 0x80)) + IRR&=~INTFAD; } else if ((IRR & INTFSR) && 0 == (MKH & 0x02)) { vector = 0x0028; - IRR&=~INTFSR; + if (0 != (MKH & 0x04)) + IRR&=~INTFSR; } else if ((IRR & INTFST) && 0 == (MKH & 0x04)) { vector = 0x0028; - IRR&=~INTFST; + if (0 != (MKH & 0x02)) + IRR&=~INTFST; } if (vector) @@ -822,7 +831,7 @@ void upd7810_device::upd7810_take_irq() WM( SP, PCH ); SP--; WM( SP, PCL ); - IFF = 0; + IFF = m_iff_pending = 0; PSW &= ~(SK|L0|L1); PC = vector; } @@ -883,7 +892,7 @@ void upd7801_device::upd7810_take_irq() WM( SP, PCH ); SP--; WM( SP, PCL ); - IFF = 0; + IFF = m_iff_pending = 0; PSW &= ~(SK|L0|L1); PC = vector; } @@ -1186,6 +1195,12 @@ void upd7810_device::upd7810_sio_input() { if (SML & 0x03) /* asynchronous mode ? */ { + // start bit check + RXD = m_rxd_func(); + m_rxs = (m_rxs >> 1) | ((uint16_t)RXD << 15); + if ((m_rxs & 0xc000) != 0x4000) + return; + switch (SML & 0xfc) { case 0x48: /* 7bits, no parity, 1 stop bit */ @@ -1581,7 +1596,7 @@ void upd7810_device::base_device_start() m_co0_func.resolve_safe(); m_co1_func.resolve_safe(); m_txd_func.resolve_safe(); - m_rxd_func.resolve_safe(0); + m_rxd_func.resolve_safe(1); m_an0_func.resolve_safe(0); m_an1_func.resolve_safe(0); m_an2_func.resolve_safe(0); @@ -1614,6 +1629,7 @@ void upd7810_device::base_device_start() save_item(NAME(m_op)); save_item(NAME(m_op2)); save_item(NAME(m_iff)); + save_item(NAME(m_iff_pending)); save_item(NAME(m_ea.w.l)); save_item(NAME(m_va.w.l)); save_item(NAME(m_bc.w.l)); @@ -1800,6 +1816,7 @@ void upd7810_device::device_reset() m_op = 0; m_op2 = 0; m_iff = 0; + m_iff_pending = 0; m_psw = 0; m_ea.d = 0; m_va.d = 0; @@ -1976,7 +1993,7 @@ void upd7810_device::execute_run() } m_icount -= cc; upd7810_take_irq(); - + m_iff = m_iff_pending; } while (m_icount > 0); } diff --git a/src/devices/cpu/upd7810/upd7810.h b/src/devices/cpu/upd7810/upd7810.h index 5905b931af1..adb0fe88a8e 100644 --- a/src/devices/cpu/upd7810/upd7810.h +++ b/src/devices/cpu/upd7810/upd7810.h @@ -239,6 +239,7 @@ protected: uint8_t m_op; /* opcode */ uint8_t m_op2; /* opcode part 2 */ uint8_t m_iff; /* interrupt enable flip flop */ + uint8_t m_iff_pending; uint8_t m_psw; /* processor status word */ PAIR m_ea; /* extended accumulator */ PAIR m_va; /* accumulator + vector register */