diff options
Diffstat (limited to 'src/devices/machine/68307.cpp')
-rw-r--r-- | src/devices/machine/68307.cpp | 81 |
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() |