diff options
Diffstat (limited to 'src/devices/cpu/m68000/mcf5206e.cpp')
| -rw-r--r-- | src/devices/cpu/m68000/mcf5206e.cpp | 144 |
1 files changed, 98 insertions, 46 deletions
diff --git a/src/devices/cpu/m68000/mcf5206e.cpp b/src/devices/cpu/m68000/mcf5206e.cpp index 80305b54c64..7e521b118ea 100644 --- a/src/devices/cpu/m68000/mcf5206e.cpp +++ b/src/devices/cpu/m68000/mcf5206e.cpp @@ -37,7 +37,7 @@ #define LOG_DRAM (1U << 7) #define LOG_SIM (1U << 8) #define LOG_DMA (1U << 9) -#define VERBOSE ( LOG_DEBUG | LOG_UART | LOG_SWDT | LOG_MBUS | LOG_DRAM | LOG_SIM | LOG_DMA ) +#define VERBOSE ( LOG_DEBUG | LOG_UART | LOG_SWDT | LOG_MBUS | LOG_DRAM | LOG_SIM | LOG_DMA | LOG_TIMER ) #include "logmacro.h" #define INT_LEVEL(N) ((N&0x1c) >> 2) @@ -220,8 +220,9 @@ void mcf5206e_device::coldfire_register_map(address_map &map) map(0xf0000240, 0xf000025f).m(m_dma[1], FUNC(coldfire_dma_device::dma_map)); } -void mcf5206e_device::coldfire_vector_map(address_map &map){ - map(0xfffffe0, 0xffffffc).r(m_sim, FUNC(coldfire_sim_device::interrupt_callback)); +void mcf5206e_device::coldfire_vector_map(address_map &map) +{ + map(0xfffffe0, 0xfffffff).r(m_sim, FUNC(coldfire_sim_device::interrupt_callback)); } /* @@ -343,7 +344,8 @@ void mcf5206e_device::ppddr_w(u8 data) { LOGMASKED(LOG_DEBUG, "%s: (Port A Data Direction Register) PPDDR_w %02x\n", this->machine().describe_context(), data); - if(m_ppddr != data){ + if(m_ppddr != data) + { // Updating the register updates the pins immediately u8 mask = 0; if(!BIT(m_sim->get_par(), 4)) mask |= 0x0f; // PP 0-3 / DDATA 0-3 @@ -414,7 +416,6 @@ void coldfire_sim_device::device_reset() m_simr = 0xc0; m_marb = 0x00; - m_ipr = 0x3ffe; m_sypcr = 0x00; m_swivr = 0x0f; m_imr = 0x3ffe; @@ -462,13 +463,15 @@ void coldfire_sim_device::sim_map(address_map &map) } // MBAR + 0x003: SIM Configuration Register - Not really applicable to MAME as there's no BDM port currently but hey. -void coldfire_sim_device::simr_w(u8 data){ +void coldfire_sim_device::simr_w(u8 data) +{ LOGMASKED(LOG_DEBUG, "%s: SIMR_w %02x\n", this->machine().describe_context(), data); m_simr = data; } // MBAR + 0x003: Bus Master Arbitration Control -void coldfire_sim_device::marb_w(u8 data){ +void coldfire_sim_device::marb_w(u8 data) +{ LOGMASKED(LOG_DEBUG, "%s: (Bus Master Arbitration Control) MARB_w %02x\n", this->machine().describe_context(), data); m_marb = data; } @@ -476,7 +479,8 @@ void coldfire_sim_device::marb_w(u8 data){ // MBAR + 0x014 -> 0x022: Interupt Control Registers u8 coldfire_sim_device::icr_r(offs_t offset) { - if(offset > 15){ + if(offset > 15) + { logerror("%s: Request to read invalid ICR offset received: %d\n", this->machine().describe_context(), offset); return 0; } @@ -551,29 +555,46 @@ void coldfire_sim_device::set_external_interrupt(int level, int state) } } +void mcf5206e_device::execute_set_input(int inputnum, int state) +{ + m68000_musashi_device::execute_set_input(inputnum, state); + // HACK: make it accept external interrupts + if (inputnum == 1 || inputnum == 4 || inputnum == 7) + m_sim->set_ipr(inputnum, state); + + if (BIT(m_sim->get_par(), 6)) + popmessage("mcf5206e: encoded interrupt priority!"); +} + // Return the vector for the highest priority and level interrupt u8 coldfire_sim_device::interrupt_callback(offs_t level) { u8 ipl = (level >> 1) & 7; // Should be 2 for coldFire, really + u8 highest_priority_icr = 0; u8 highest_priority_device = 0; - if(!this->machine().side_effects_disabled()) { + if(!this->machine().side_effects_disabled()) + { //logerror("%s: interrupt_callback(%u), ipl: %x, m_ipr: %x, m_imr: %x\n", this->machine().describe_context(), level, ipl, m_ipr, m_imr); m_maincpu->set_input_line(ipl, CLEAR_LINE); } - for (int i = 0; i < 15; i++) { + for (int i = 0; i < 15; i++) + { //if(!this->machine().side_effects_disabled()) logerror("i: %x, m_icr: %x, ipl: %x, ipr_bit: %x\n", i, INT_LEVEL(m_icr[i]), ipl, BIT(m_ipr, 1 + i)); - if (BIT(m_ipr, 1 +i) && (INT_LEVEL(m_icr[i]) == ipl)) { - if (highest_priority_device == 0 || INT_PRIORITY(m_icr[i]) > INT_PRIORITY(highest_priority_icr)) { + if (BIT(m_ipr, 1 + i) && (INT_LEVEL(m_icr[i]) == ipl)) + { + if (highest_priority_device == 0 || INT_PRIORITY(m_icr[i]) > INT_PRIORITY(highest_priority_icr)) + { highest_priority_icr = m_icr[i]; highest_priority_device = i + 1; } } } - if (highest_priority_device == 0) { + if (highest_priority_device == 0) + { if(!this->machine().side_effects_disabled()) logerror("%s: Spurious interrupt detected: %u\n", this->machine().describe_context(), ipl); return EXCEPTION_SPURIOUS_INTERRUPT; } @@ -583,11 +604,15 @@ u8 coldfire_sim_device::interrupt_callback(offs_t level) u8 vector = 0xff; // Check if ICR specifies to use autovectoring - if (BIT(highest_priority_icr, 7)) { + if (BIT(highest_priority_icr, 7)) + { vector = m68000_base_device::autovector(ipl); - } else { + } + else + { // Determine the correct vector to return - switch (highest_priority_device) { + switch (highest_priority_device) + { case EXTERNAL_IPL_1: case EXTERNAL_IPL_2: case EXTERNAL_IPL_3: @@ -595,27 +620,34 @@ u8 coldfire_sim_device::interrupt_callback(offs_t level) case EXTERNAL_IPL_5: case EXTERNAL_IPL_6: case EXTERNAL_IPL_7: - if (!BIT(highest_priority_icr, 7)) vector = irq_vector_cb(); + if (!BIT(highest_priority_icr, 7)) + vector = irq_vector_cb(); break; case WATCHDOG_IRQ: - if (!BIT(highest_priority_icr, 7)) vector = m_swivr; + if (!BIT(highest_priority_icr, 7)) + vector = m_swivr; break; case UART_1_IRQ: - if (!BIT(highest_priority_icr, 7)) vector = m_maincpu->m_uart[0]->get_irq_vector(); + if (!BIT(highest_priority_icr, 7)) + vector = m_maincpu->m_uart[0]->get_irq_vector(); break; case UART_2_IRQ: - if (!BIT(highest_priority_icr, 7)) vector = m_maincpu->m_uart[1]->get_irq_vector(); + if (!BIT(highest_priority_icr, 7)) + vector = m_maincpu->m_uart[1]->get_irq_vector(); break; case DMA_0_IRQ: - if (!BIT(highest_priority_icr, 7)) vector = m_maincpu->m_dma[0]->get_irq_vector(); + if (!BIT(highest_priority_icr, 7)) + vector = m_maincpu->m_dma[0]->get_irq_vector(); //m_maincpu->m_dma[0]->dma_int_callback(); break; case DMA_1_IRQ: - if (!BIT(highest_priority_icr, 7)) vector = m_maincpu->m_dma[1]->get_irq_vector(); + if (!BIT(highest_priority_icr, 7)) + vector = m_maincpu->m_dma[1]->get_irq_vector(); //m_maincpu->m_dma[1]->dma_int_callback(); break; default: - if(!this->machine().side_effects_disabled()) logerror("%s: Vector required for device that only supports autovectoring: %u, %u\n", + if(!this->machine().side_effects_disabled()) + logerror("%s: Vector required for device that only supports autovectoring: %u, %u\n", this->machine().describe_context(), ipl, highest_priority_device); vector = EXCEPTION_UNINITIALIZED_INTERRUPT; break; @@ -631,11 +663,16 @@ void coldfire_sim_device::set_interrupt(int interrupt, int state) //LOGMASKED(LOG_DEBUG, "%s: set_interrupt(%u, %u): %x, %d, %d\n", this->machine().describe_context(), interrupt, state, m_ipr, BIT(m_imr, interrupt), m_imr & interrupt); + //printf("%d %d -> %04x %04x\n", interrupt, state, m_imr, m_ipr); + // IMR enables interrupts when bit is 0 - if(state != CLEAR_LINE){ - if(!BIT(m_imr, interrupt)){ + if(state != CLEAR_LINE) + { + if(!BIT(m_imr, interrupt)) + { u8 icr = 0; - switch (interrupt){ + switch (interrupt) + { case EXTERNAL_IPL_1: icr = m_icr[ICR1]; break; case EXTERNAL_IPL_2: icr = m_icr[ICR2]; break; case EXTERNAL_IPL_3: icr = m_icr[ICR3]; break; @@ -673,7 +710,8 @@ void coldfire_sim_device::rsr_w(u8 data) // MBAR + 0x041 void coldfire_sim_device::sypcr_w(u8 data) { - if(!m_sypcr_locked){ + if(!m_sypcr_locked) + { // SYPCR is a write-once register, whatever is written first remains until system reset. LOGMASKED(LOG_SWDT, "%s: (System Protection Control) SYPCR_w %02x\n", this->machine().describe_context(), data); m_sypcr_locked = true; @@ -681,12 +719,17 @@ void coldfire_sim_device::sypcr_w(u8 data) // Bus monitoring is not supported (nor will it be?) - if(BIT(m_sypcr, 6)){ + if(BIT(m_sypcr, 6)) + { m_swdt->watchdog_enable(BIT(data, 7)); - } else { - // Set timer for interrupt } - } else { + else + { + // TODO: Set timer for interrupt + } + } + else + { LOG("%s: Write to SYPCR_w (%02x) when PCR is locked\n", this->machine().describe_context(), data); } } @@ -702,8 +745,10 @@ void coldfire_sim_device::swivr_w(u8 data) void coldfire_sim_device::swsr_w(u8 data) { LOGMASKED(LOG_SWDT, "%s: (Software Watchdog Service Routine) SWIVR_r %02x\n", this->machine().describe_context(), data); - if(data == swdt_reset_sequence[m_swdt_w_count]) m_swdt_w_count++; - if(m_swdt_w_count == 2) { + if(data == swdt_reset_sequence[m_swdt_w_count]) + m_swdt_w_count++; + if(m_swdt_w_count == 2) + { m_swdt->watchdog_reset(); m_swdt_w_count = 0; } @@ -719,8 +764,8 @@ TIMER_CALLBACK_MEMBER(coldfire_sim_device::swdt_callback) * Timer Module/s * Creates an MCF5206e compatible 16-bit timer */ -coldfire_timer_device::coldfire_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - device_t(mconfig, COLDFIRE_TIMER, tag, owner, clock) +coldfire_timer_device::coldfire_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, COLDFIRE_TIMER, tag, owner, clock) , write_irq(*this) { } @@ -746,7 +791,8 @@ void coldfire_timer_device::device_start() save_item(NAME(m_timer_start_time)); } -void coldfire_timer_device::device_reset(){ +void coldfire_timer_device::device_reset() +{ m_tmr = 0x0000; m_trr = 0xffff; m_tcn = 0x0000; @@ -759,19 +805,24 @@ void coldfire_timer_device::device_reset(){ TIMER_CALLBACK_MEMBER(coldfire_timer_device::timer_callback) { - if(m_tmr & T_FRR){ + if(m_tmr & T_FRR) + { // FRR resets counter to 0 m_tcn = 0; } m_ter |= T_EREF; - write_irq(ASSERT_LINE); + + // TODO: capture edge irq modes + if(BIT(m_tmr, 4)) + write_irq(ASSERT_LINE); } void coldfire_timer_device::tmr_w(u16 data) { u16 cmd = data; - if((m_tmr & T_RST) && !(cmd & T_RST)){ + if((m_tmr & T_RST) && !(cmd & T_RST)) + { // T_RST high to low resets the entire timer device_reset(); return; @@ -779,8 +830,9 @@ void coldfire_timer_device::tmr_w(u16 data) m_tmr = cmd; - if (m_tmr & T_RST){ - // todo: add tin pin support + if(m_tmr & T_RST) + { + // TODO: add tin pin support int div, start, interval; start = (m_trr - m_tcn); div = ((m_tmr & 0xff00) >> 8) + 1; // 1 -> 256 division scale @@ -867,8 +919,8 @@ void mcf5206e_device::init_regs(bool first_init) * Hosts I2C and Motorola extensions to the format. Can act as a device or host. */ -coldfire_mbus_device::coldfire_mbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - device_t(mconfig, COLDFIRE_MBUS, tag, owner, clock) +coldfire_mbus_device::coldfire_mbus_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, COLDFIRE_MBUS, tag, owner, clock) , write_sda(*this) , write_scl(*this) , write_irq(*this) @@ -922,7 +974,7 @@ void coldfire_mbus_device::mbus_map(address_map &map) TIMER_CALLBACK_MEMBER(coldfire_mbus_device::mbus_callback) { - // Do bit transfers etc + // TODO: Do bit transfers etc } void coldfire_mbus_device::madr_w(u8 data) @@ -978,8 +1030,8 @@ void coldfire_mbus_device::mbdr_w(u8 data) * */ -coldfire_dma_device::coldfire_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - device_t(mconfig, COLDFIRE_DMA, tag, owner, clock) +coldfire_dma_device::coldfire_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, COLDFIRE_DMA, tag, owner, clock) , write_irq(*this) { } |
