pic8259: priority and sfnm [Carl}

This commit is contained in:
cracyc 2014-10-31 16:32:53 -05:00
parent 133642df6c
commit 015dddb02d

View File

@ -14,8 +14,6 @@
#include "emu.h" #include "emu.h"
#include "machine/pic8259.h" #include "machine/pic8259.h"
#define IRQ_COUNT 8
#define LOG_ICW 0 #define LOG_ICW 0
#define LOG_OCW 0 #define LOG_OCW 0
#define LOG_GENERAL 0 #define LOG_GENERAL 0
@ -24,20 +22,17 @@ ALLOW_SAVE_TYPE(pic8259_device::pic8259_state_t); // allow save_item on a non-fu
void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{ {
int irq;
UINT8 mask;
/* check the various IRQs */ /* check the various IRQs */
for (irq = 0; irq < IRQ_COUNT; irq++) for (int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
{ {
mask = 1 << irq; UINT8 mask = 1 << irq;
/* is this IRQ in service? */ /* is this IRQ in service and not cascading and sfnm? */
if (m_isr & mask) if ((m_isr & mask) && !(m_master && m_cascade && m_nested && (m_slave & mask)))
{ {
if (LOG_GENERAL) if (LOG_GENERAL)
{ {
logerror("pic8259_timerproc(): PIC IRQ #%d still in service\n", irq); logerror("pic8259_timerproc() %s: PIC IRQ #%d still in service\n", tag(), irq);
} }
break; break;
} }
@ -47,7 +42,7 @@ void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int para
{ {
if (LOG_GENERAL) if (LOG_GENERAL)
{ {
logerror("pic8259_timerproc(): PIC triggering IRQ #%d\n", irq); logerror("pic8259_timerproc() %s: PIC triggering IRQ #%d\n", tag(), irq);
} }
if (!BIT(m_ocw3, 2)) if (!BIT(m_ocw3, 2))
{ {
@ -55,6 +50,9 @@ void pic8259_device::device_timer(emu_timer &timer, device_timer_id id, int para
} }
return; return;
} }
// if sfnm and in-service don't continue
if((m_isr & mask) && m_master && m_cascade && m_nested && (m_slave & mask))
break;
} }
if (!BIT(m_ocw3, 2)) if (!BIT(m_ocw3, 2))
{ {
@ -71,7 +69,7 @@ void pic8259_device::set_irq_line(int irq, int state)
{ {
/* setting IRQ line */ /* setting IRQ line */
if (LOG_GENERAL) if (LOG_GENERAL)
logerror("pic8259_set_irq_line(): PIC set IRQ line #%d\n", irq); logerror("pic8259_set_irq_line() %s: PIC set IRQ line #%d\n", tag(), irq);
if(m_level_trig_mode || (!m_level_trig_mode && !(m_irq_lines & mask))) if(m_level_trig_mode || (!m_level_trig_mode && !(m_irq_lines & mask)))
{ {
@ -84,7 +82,7 @@ void pic8259_device::set_irq_line(int irq, int state)
/* clearing IRQ line */ /* clearing IRQ line */
if (LOG_GENERAL) if (LOG_GENERAL)
{ {
logerror("pic8259_device::set_irq_line(): PIC cleared IRQ line #%d\n", irq); logerror("pic8259_device::set_irq_line() %s: PIC cleared IRQ line #%d\n", tag(), irq);
} }
m_irq_lines &= ~mask; m_irq_lines &= ~mask;
@ -96,19 +94,16 @@ void pic8259_device::set_irq_line(int irq, int state)
UINT32 pic8259_device::acknowledge() UINT32 pic8259_device::acknowledge()
{ {
UINT8 mask; for (int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
int irq;
for (irq = 0; irq < IRQ_COUNT; irq++)
{ {
mask = 1 << irq; UINT8 mask = 1 << irq;
/* is this IRQ pending and enabled? */ /* is this IRQ pending and enabled? */
if ((m_irr & mask) && !(m_imr & mask)) if ((m_irr & mask) && !(m_imr & mask))
{ {
if (LOG_GENERAL) if (LOG_GENERAL)
{ {
logerror("pic8259_acknowledge(): PIC acknowledge IRQ #%d\n", irq); logerror("pic8259_acknowledge() %s: PIC acknowledge IRQ #%d\n", tag(), irq);
} }
if (!m_level_trig_mode) if (!m_level_trig_mode)
{ {
@ -170,8 +165,8 @@ READ8_MEMBER( pic8259_device::read )
if ( m_irr & ~m_imr ) if ( m_irr & ~m_imr )
{ {
int irq; /* check the various IRQs */
for ( irq = 0; irq < IRQ_COUNT; irq++ ) for (int n = 0, irq = m_prio; n < 8; n++, irq = (irq + 1) & 7)
{ {
if ( ( 1 << irq ) & m_irr & ~m_imr ) if ( ( 1 << irq ) & m_irr & ~m_imr )
{ {
@ -216,7 +211,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write ICW1 - this pretty much resets the chip */ /* write ICW1 - this pretty much resets the chip */
if (LOG_ICW) if (LOG_ICW)
{ {
logerror("pic8259_device::write(): ICW1; data=0x%02X\n", data); logerror("pic8259_device::write() %s: ICW1; data=0x%02X\n", tag(), data);
} }
m_imr = 0x00; m_imr = 0x00;
@ -237,7 +232,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write OCW3 */ /* write OCW3 */
if (LOG_OCW) if (LOG_OCW)
{ {
logerror("pic8259_device::write(): OCW3; data=0x%02X\n", data); logerror("pic8259_device::write() %s: OCW3; data=0x%02X\n", tag(), data);
} }
m_ocw3 = data; m_ocw3 = data;
@ -250,7 +245,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write OCW2 */ /* write OCW2 */
if (LOG_OCW) if (LOG_OCW)
{ {
logerror("pic8259_device::write(): OCW2; data=0x%02X\n", data); logerror("pic8259_device::write() %s: OCW2; data=0x%02X\n", tag(), data);
} }
switch (data & 0xe0) switch (data & 0xe0)
@ -291,13 +286,13 @@ WRITE8_MEMBER( pic8259_device::write )
} }
break; break;
case 0xc0: case 0xc0:
m_prio = n & 7; m_prio = (n + 1) & 7;
break; break;
case 0xe0: case 0xe0:
if( m_isr & mask ) if( m_isr & mask )
{ {
m_isr &= ~mask; m_isr &= ~mask;
m_prio = (m_prio + 1) & 7; m_prio = (n + 1) & 7;
} }
break; break;
} }
@ -315,7 +310,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write ICW2 */ /* write ICW2 */
if (LOG_ICW) if (LOG_ICW)
{ {
logerror("pic8259_device::write(): ICW2; data=0x%02X\n", data); logerror("pic8259_device::write() %s: ICW2; data=0x%02X\n", tag(), data);
} }
m_base = data & 0xf8; m_base = data & 0xf8;
@ -334,7 +329,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write ICW3 */ /* write ICW3 */
if (LOG_ICW) if (LOG_ICW)
{ {
logerror("pic8259_device::write(): ICW3; data=0x%02X\n", data); logerror("pic8259_device::write() %s: ICW3; data=0x%02X\n", tag(), data);
} }
m_slave = data; m_slave = data;
@ -345,7 +340,7 @@ WRITE8_MEMBER( pic8259_device::write )
/* write ICW4 */ /* write ICW4 */
if (LOG_ICW) if (LOG_ICW)
{ {
logerror("pic8259_device::write(): ICW4; data=0x%02X\n", data); logerror("pic8259_device::write() %s: ICW4; data=0x%02X\n", tag(), data);
} }
m_nested = (data & 0x10) ? 1 : 0; m_nested = (data & 0x10) ? 1 : 0;