mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
upd7810: Interrupt-related fixes
- Prevent NMI from being masked out - Make EI take effect only after the following instruction - Inhibit clearing of interrupt flag upon acknowledgment when another interrupt with the same priority is also enabled - Add a crude start bit check to asynchronous serial mode
This commit is contained in:
parent
ef8a18e63a
commit
9cd1748fd1
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user