mirror of
https://github.com/holub/mame
synced 2025-06-11 07:14:07 +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;
|
int irqline = 0;
|
||||||
|
|
||||||
/* global interrupt disable? */
|
/* global interrupt disable? */
|
||||||
if (0 == IFF)
|
if (0 == IFF && !(IRR & INTNMI))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* check the interrupts in priority sequence */
|
/* check the interrupts in priority sequence */
|
||||||
@ -751,13 +751,14 @@ void upd7810_device::upd7810_take_irq()
|
|||||||
if ((IRR & INTFT0) && 0 == (MKL & 0x02))
|
if ((IRR & INTFT0) && 0 == (MKL & 0x02))
|
||||||
{
|
{
|
||||||
vector = 0x0008;
|
vector = 0x0008;
|
||||||
if (!((IRR & INTFT1) && 0 == (MKL & 0x04)))
|
if (0 != (MKL & 0x04))
|
||||||
IRR&=~INTFT0;
|
IRR&=~INTFT0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFT1) && 0 == (MKL & 0x04))
|
if ((IRR & INTFT1) && 0 == (MKL & 0x04))
|
||||||
{
|
{
|
||||||
vector = 0x0008;
|
vector = 0x0008;
|
||||||
|
if (0 != (MKL & 0x02))
|
||||||
IRR&=~INTFT1;
|
IRR&=~INTFT1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -765,7 +766,7 @@ void upd7810_device::upd7810_take_irq()
|
|||||||
{
|
{
|
||||||
irqline = UPD7810_INTF1;
|
irqline = UPD7810_INTF1;
|
||||||
vector = 0x0010;
|
vector = 0x0010;
|
||||||
if (!((IRR & INTF2) && 0 == (MKL & 0x10)))
|
if (0 != (MKL & 0x10))
|
||||||
IRR&=~INTF1;
|
IRR&=~INTF1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -773,41 +774,49 @@ void upd7810_device::upd7810_take_irq()
|
|||||||
{
|
{
|
||||||
irqline = UPD7810_INTF2;
|
irqline = UPD7810_INTF2;
|
||||||
vector = 0x0010;
|
vector = 0x0010;
|
||||||
|
if (0 != (MKL & 0x08))
|
||||||
IRR&=~INTF2;
|
IRR&=~INTF2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFE0) && 0 == (MKL & 0x20))
|
if ((IRR & INTFE0) && 0 == (MKL & 0x20))
|
||||||
{
|
{
|
||||||
vector = 0x0018;
|
vector = 0x0018;
|
||||||
if (!((IRR & INTFE1) && 0 == (MKL & 0x40)))
|
if (0 != (MKL & 0x40))
|
||||||
IRR&=~INTFE0;
|
IRR&=~INTFE0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFE1) && 0 == (MKL & 0x40))
|
if ((IRR & INTFE1) && 0 == (MKL & 0x40))
|
||||||
{
|
{
|
||||||
vector = 0x0018;
|
vector = 0x0018;
|
||||||
|
if (0 != (MKL & 0x20))
|
||||||
IRR&=~INTFE1;
|
IRR&=~INTFE1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFEIN) && 0 == (MKL & 0x80))
|
if ((IRR & INTFEIN) && 0 == (MKL & 0x80))
|
||||||
{
|
{
|
||||||
vector = 0x0020;
|
vector = 0x0020;
|
||||||
|
if (0 != (MKH & 0x01))
|
||||||
|
IRR&=~INTFEIN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFAD) && 0 == (MKH & 0x01))
|
if ((IRR & INTFAD) && 0 == (MKH & 0x01))
|
||||||
{
|
{
|
||||||
vector = 0x0020;
|
vector = 0x0020;
|
||||||
|
if (0 != (MKL & 0x80))
|
||||||
|
IRR&=~INTFAD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFSR) && 0 == (MKH & 0x02))
|
if ((IRR & INTFSR) && 0 == (MKH & 0x02))
|
||||||
{
|
{
|
||||||
vector = 0x0028;
|
vector = 0x0028;
|
||||||
|
if (0 != (MKH & 0x04))
|
||||||
IRR&=~INTFSR;
|
IRR&=~INTFSR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ((IRR & INTFST) && 0 == (MKH & 0x04))
|
if ((IRR & INTFST) && 0 == (MKH & 0x04))
|
||||||
{
|
{
|
||||||
vector = 0x0028;
|
vector = 0x0028;
|
||||||
|
if (0 != (MKH & 0x02))
|
||||||
IRR&=~INTFST;
|
IRR&=~INTFST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,7 +831,7 @@ void upd7810_device::upd7810_take_irq()
|
|||||||
WM( SP, PCH );
|
WM( SP, PCH );
|
||||||
SP--;
|
SP--;
|
||||||
WM( SP, PCL );
|
WM( SP, PCL );
|
||||||
IFF = 0;
|
IFF = m_iff_pending = 0;
|
||||||
PSW &= ~(SK|L0|L1);
|
PSW &= ~(SK|L0|L1);
|
||||||
PC = vector;
|
PC = vector;
|
||||||
}
|
}
|
||||||
@ -883,7 +892,7 @@ void upd7801_device::upd7810_take_irq()
|
|||||||
WM( SP, PCH );
|
WM( SP, PCH );
|
||||||
SP--;
|
SP--;
|
||||||
WM( SP, PCL );
|
WM( SP, PCL );
|
||||||
IFF = 0;
|
IFF = m_iff_pending = 0;
|
||||||
PSW &= ~(SK|L0|L1);
|
PSW &= ~(SK|L0|L1);
|
||||||
PC = vector;
|
PC = vector;
|
||||||
}
|
}
|
||||||
@ -1186,6 +1195,12 @@ void upd7810_device::upd7810_sio_input()
|
|||||||
{
|
{
|
||||||
if (SML & 0x03) /* asynchronous mode ? */
|
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)
|
switch (SML & 0xfc)
|
||||||
{
|
{
|
||||||
case 0x48: /* 7bits, no parity, 1 stop bit */
|
case 0x48: /* 7bits, no parity, 1 stop bit */
|
||||||
@ -1581,7 +1596,7 @@ void upd7810_device::base_device_start()
|
|||||||
m_co0_func.resolve_safe();
|
m_co0_func.resolve_safe();
|
||||||
m_co1_func.resolve_safe();
|
m_co1_func.resolve_safe();
|
||||||
m_txd_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_an0_func.resolve_safe(0);
|
||||||
m_an1_func.resolve_safe(0);
|
m_an1_func.resolve_safe(0);
|
||||||
m_an2_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_op));
|
||||||
save_item(NAME(m_op2));
|
save_item(NAME(m_op2));
|
||||||
save_item(NAME(m_iff));
|
save_item(NAME(m_iff));
|
||||||
|
save_item(NAME(m_iff_pending));
|
||||||
save_item(NAME(m_ea.w.l));
|
save_item(NAME(m_ea.w.l));
|
||||||
save_item(NAME(m_va.w.l));
|
save_item(NAME(m_va.w.l));
|
||||||
save_item(NAME(m_bc.w.l));
|
save_item(NAME(m_bc.w.l));
|
||||||
@ -1800,6 +1816,7 @@ void upd7810_device::device_reset()
|
|||||||
m_op = 0;
|
m_op = 0;
|
||||||
m_op2 = 0;
|
m_op2 = 0;
|
||||||
m_iff = 0;
|
m_iff = 0;
|
||||||
|
m_iff_pending = 0;
|
||||||
m_psw = 0;
|
m_psw = 0;
|
||||||
m_ea.d = 0;
|
m_ea.d = 0;
|
||||||
m_va.d = 0;
|
m_va.d = 0;
|
||||||
@ -1976,7 +1993,7 @@ void upd7810_device::execute_run()
|
|||||||
}
|
}
|
||||||
m_icount -= cc;
|
m_icount -= cc;
|
||||||
upd7810_take_irq();
|
upd7810_take_irq();
|
||||||
|
m_iff = m_iff_pending;
|
||||||
} while (m_icount > 0);
|
} while (m_icount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +239,7 @@ protected:
|
|||||||
uint8_t m_op; /* opcode */
|
uint8_t m_op; /* opcode */
|
||||||
uint8_t m_op2; /* opcode part 2 */
|
uint8_t m_op2; /* opcode part 2 */
|
||||||
uint8_t m_iff; /* interrupt enable flip flop */
|
uint8_t m_iff; /* interrupt enable flip flop */
|
||||||
|
uint8_t m_iff_pending;
|
||||||
uint8_t m_psw; /* processor status word */
|
uint8_t m_psw; /* processor status word */
|
||||||
PAIR m_ea; /* extended accumulator */
|
PAIR m_ea; /* extended accumulator */
|
||||||
PAIR m_va; /* accumulator + vector register */
|
PAIR m_va; /* accumulator + vector register */
|
||||||
|
Loading…
Reference in New Issue
Block a user