summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/68307.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/68307.cpp')
-rw-r--r--src/devices/machine/68307.cpp81
1 files changed, 53 insertions, 28 deletions
diff --git a/src/devices/machine/68307.cpp b/src/devices/machine/68307.cpp
index 91a85f10a90..421d5f06da2 100644
--- a/src/devices/machine/68307.cpp
+++ b/src/devices/machine/68307.cpp
@@ -66,6 +66,7 @@ m68307_cpu_device::m68307_cpu_device(const machine_config &mconfig, const char *
m_m68307_scrhigh = 0;
m_m68307_scrlow = 0;
m_m68307_currentcs = 0;
+ m_ipl = 0;
}
@@ -85,6 +86,7 @@ void m68307_cpu_device::device_reset()
m_m68307_scrhigh = 0x0007;
m_m68307_scrlow = 0xf010;
+ set_ipl(0);
}
@@ -147,55 +149,78 @@ uint16_t m68307_cpu_device::get_cs(offs_t address)
/* 68307 specifics - MOVE */
-void m68307_cpu_device::set_interrupt(int level, int vector)
+void m68307_cpu_device::set_ipl(int level)
{
- set_input_line_and_vector(level, HOLD_LINE, vector);
-}
-
-void m68307_cpu_device::timer0_interrupt()
-{
- int prioritylevel = (m_m68307SIM->m_picr & 0x7000)>>12;
- int vector = (m_m68307SIM->m_pivr & 0x00f0) | 0xa;
- set_interrupt(prioritylevel, vector);
+ if (level != m_ipl)
+ {
+ if (m_ipl != 0)
+ set_input_line(m_ipl, CLEAR_LINE);
+ m_ipl = level;
+ if (m_ipl != 0)
+ set_input_line(m_ipl, ASSERT_LINE);
+ }
}
-void m68307_cpu_device::timer1_interrupt()
+WRITE_LINE_MEMBER(m68307_cpu_device::timer0_interrupt)
{
- int prioritylevel = (m_m68307SIM->m_picr & 0x0700)>>8;
- int vector = (m_m68307SIM->m_pivr & 0x00f0) | 0xb;
- set_interrupt(prioritylevel, vector);
+ int prioritylevel = (m_m68307SIM->m_picr & 0x7000) >> 12;
+ if (state && m_ipl < prioritylevel)
+ set_ipl(prioritylevel);
+ else if (!state && m_ipl == prioritylevel)
+ set_ipl(m_m68307SIM->get_ipl(this));
}
-
-void m68307_cpu_device::serial_interrupt(int vector)
+WRITE_LINE_MEMBER(m68307_cpu_device::timer1_interrupt)
{
- int prioritylevel = (m_m68307SIM->m_picr & 0x0070)>>4;
- set_interrupt(prioritylevel, vector);
+ int prioritylevel = (m_m68307SIM->m_picr & 0x0700) >> 8;
+ if (state && m_ipl < prioritylevel)
+ set_ipl(prioritylevel);
+ else if (!state && m_ipl == prioritylevel)
+ set_ipl(m_m68307SIM->get_ipl(this));
}
WRITE_LINE_MEMBER(m68307_cpu_device::m68307_duart_irq_handler)
{
- if (state == ASSERT_LINE)
- {
- serial_interrupt(m_duart->get_irq_vector());
- }
+ int prioritylevel = (m_m68307SIM->m_picr & 0x0070) >> 4;
+ if (state && m_ipl < prioritylevel)
+ set_ipl(prioritylevel);
+ else if (!state && m_ipl == prioritylevel)
+ set_ipl(m_m68307SIM->get_ipl(this));
}
-void m68307_cpu_device::mbus_interrupt()
+WRITE_LINE_MEMBER(m68307_cpu_device::mbus_interrupt)
{
- int prioritylevel = (m_m68307SIM->m_picr & 0x0007)>>0;
- int vector = (m_m68307SIM->m_pivr & 0x00f0) | 0xd;
- set_interrupt(prioritylevel, vector);
+ int prioritylevel = (m_m68307SIM->m_picr & 0x0007) >> 0;
+ if (state && m_ipl < prioritylevel)
+ set_ipl(prioritylevel);
+ else if (!state && m_ipl == prioritylevel)
+ set_ipl(m_m68307SIM->get_ipl(this));
}
void m68307_cpu_device::licr2_interrupt()
{
- int prioritylevel = (m_m68307SIM->m_licr2 & 0x0007)>>0;
- int vector = (m_m68307SIM->m_pivr & 0x00f0) | 0x9;
m_m68307SIM->m_licr2 |= 0x8;
+ int prioritylevel = (m_m68307SIM->m_licr2 & 0x0007) >> 0;
+ if (m_ipl < prioritylevel)
+ set_ipl(prioritylevel);
+}
+
+IRQ_CALLBACK_MEMBER(m68307_cpu_device::int_ack)
+{
+ uint8_t type = m_m68307SIM->get_int_type(this, irqline);
+ logerror("Interrupt acknowledged: level %d, type %01X\n", irqline, type);
+
+ // UART provides its own vector
+ if (type == 0x0c)
+ return m_duart->get_irq_vector();
+ else
+ return (m_m68307SIM->m_pivr & 0xf0) | type;
+}
- set_interrupt(prioritylevel, vector);
+void m68307_cpu_device::device_config_complete()
+{
+ set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(m68307_cpu_device::int_ack), this));
}
void m68307_cpu_device::device_start()