summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/mcf5206e.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/mcf5206e.cpp')
-rw-r--r--src/devices/cpu/m68000/mcf5206e.cpp204
1 files changed, 102 insertions, 102 deletions
diff --git a/src/devices/cpu/m68000/mcf5206e.cpp b/src/devices/cpu/m68000/mcf5206e.cpp
index 1ed5d1d5945..109230824fb 100644
--- a/src/devices/cpu/m68000/mcf5206e.cpp
+++ b/src/devices/cpu/m68000/mcf5206e.cpp
@@ -2,26 +2,26 @@
// copyright-holders: Karl Stenerud, NaokiS
/*
- Notes:
- Chip Select Module:
- * Not currently implemented, quite possible it doesn't need to be added for any functional reason aside from completeness/debugging
- System Integration Module:
- * MBAR: should be set up in m68000_musashi_device::x4e7a_movec_l_c() to move the ColdFire IO register map according to the contents of MBAR
- could store m_mbar in m68000_musashi_device and move the address_space_map to the given offset?
- * SIMR: Logged and stored, but not used as there is no BDM interface present
- * MARB: Logged and stored, but not used, not required?
- DRAM Controller Module:
- * All functions just log and store the registers, again, possibly not required for any functional reasons.
- UART Modules:
- * Uses the MC68681 device driver as a base as effectively it is an integrated one. The difference however is both UART modules are entirely
- independant of the other, so there is two command registers e.t.c. They also only have a single channel each.
- * In this implementation, the driver uses two MC68681s at the appropriate offsets to emulate this, with the MC68681 driver having an
- entry for the MCF5206E which changes the mapping a little bit. A more appropriate solution would be to have a single UART module and load
- two of them.
- Timer Modules:
- * Slow, could be improved.
-
- * Some of these modules can probably be split back into the /devices/machine device, namely the MBUS and timer modules, possibly SIM too.
+ Notes:
+ Chip Select Module:
+ * Not currently implemented, quite possible it doesn't need to be added for any functional reason aside from completeness/debugging
+ System Integration Module:
+ * MBAR: should be set up in m68000_musashi_device::x4e7a_movec_l_c() to move the ColdFire IO register map according to the contents of MBAR
+ could store m_mbar in m68000_musashi_device and move the address_space_map to the given offset?
+ * SIMR: Logged and stored, but not used as there is no BDM interface present
+ * MARB: Logged and stored, but not used, not required?
+ DRAM Controller Module:
+ * All functions just log and store the registers, again, possibly not required for any functional reasons.
+ UART Modules:
+ * Uses the MC68681 device driver as a base as effectively it is an integrated one. The difference however is both UART modules are entirely
+ independant of the other, so there is two command registers e.t.c. They also only have a single channel each.
+ * In this implementation, the driver uses two MC68681s at the appropriate offsets to emulate this, with the MC68681 driver having an
+ entry for the MCF5206E which changes the mapping a little bit. A more appropriate solution would be to have a single UART module and load
+ two of them.
+ Timer Modules:
+ * Slow, could be improved.
+
+ * Some of these modules can probably be split back into the /devices/machine device, namely the MBUS and timer modules, possibly SIM too.
*/
#include "emu.h"
@@ -31,27 +31,27 @@
#define LOG_DEBUG (1U << 1)
#define LOG_INVALID (1U << 2)
#define LOG_TIMER (1U << 3)
-#define LOG_UART (1U << 4)
-#define LOG_SWDT (1U << 5)
-#define LOG_MBUS (1U << 6)
-#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 LOG_UART (1U << 4)
+#define LOG_SWDT (1U << 5)
+#define LOG_MBUS (1U << 6)
+#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 )
#include "logmacro.h"
-#define INT_LEVEL(N) ((N&0x1c) >> 2)
-#define INT_PRIORITY(N) (N&0x03)
-#define ICR_USE_AUTOVEC(N) ((N & 0x80) != 0)
+#define INT_LEVEL(N) ((N&0x1c) >> 2)
+#define INT_PRIORITY(N) (N&0x03)
+#define ICR_USE_AUTOVEC(N) ((N & 0x80) != 0)
static constexpr int EXCEPTION_BUS_ERROR = 2;
static constexpr int EXCEPTION_UNINITIALIZED_INTERRUPT = 15;
static constexpr int EXCEPTION_SPURIOUS_INTERRUPT = 24;
template <typename T, typename U>
-inline void BITWRITE(T &var, U bit_number, bool state)
+inline void BITWRITE(T &var, U bit_number, bool state)
{
- var = (var & ~(static_cast<T>(1) << bit_number)) | (static_cast<T>(state) << bit_number);
+ var = (var & ~(static_cast<T>(1) << bit_number)) | (static_cast<T>(state) << bit_number);
}
DEFINE_DEVICE_TYPE(MCF5206E, mcf5206e_device, "mcf5206e", "Freescale MCF5206E")
@@ -224,7 +224,7 @@ void mcf5206e_device::coldfire_vector_map(address_map &map){
map(0xfffffe0, 0xffffffc).r(m_sim, FUNC(coldfire_sim_device::interrupt_callback));
}
-/*
+/*
* DRAM Controller
* Handles the DRAM refresh and access control circuits
*/
@@ -276,8 +276,8 @@ void mcf5206e_device::dccr1_w(u8 data)
m_dccr1 = data;
}
-/*
- * Chip Select Module
+/*
+ * Chip Select Module
* Controls what address spaces that the configurable chip select pins will be assigned to.
*/
@@ -306,7 +306,7 @@ void mcf5206e_device::csmr_x_w(offs_t offset, u32 data)
}
u8 mcf5206e_device::cscr_x_r(offs_t offset)
-{
+{
LOGMASKED(LOG_DEBUG, "%s: (Chip Select Control Register) CSCR%d_r\n", this->machine().describe_context(), offset);
return m_cscr[offset];
}
@@ -324,8 +324,8 @@ void mcf5206e_device::dmcr_w(u16 data)
}
-/*
- * Parallel port
+/*
+ * Parallel port
* Just a 8 bit GPIO. Nothing to see here
*/
@@ -346,8 +346,8 @@ void mcf5206e_device::ppddr_w(u8 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
- if(!BIT(m_sim->get_par(), 5)) mask |= 0xf0; // PP 4-7 / PST 0-3
+ if(!BIT(m_sim->get_par(), 4)) mask |= 0x0f; // PP 0-3 / DDATA 0-3
+ if(!BIT(m_sim->get_par(), 5)) mask |= 0xf0; // PP 4-7 / PST 0-3
// GPIO pins will physically be set to the current input and output state, and masked according to PAR
m_gpio_w_cb(((m_ppdat_out & m_ppddr) | (m_ppdat_in & ~m_ppddr)) & mask);
@@ -362,19 +362,19 @@ void mcf5206e_device::ppdat_w(u8 data)
m_ppdat_out = data;
u8 mask = 0;
- if(!BIT(m_sim->get_par(), 4)) mask |= 0x0f; // PP 0-3 / DDATA 0-3
- if(!BIT(m_sim->get_par(), 5)) mask |= 0xf0; // PP 4-7 / PST 0-3
+ if(!BIT(m_sim->get_par(), 4)) mask |= 0x0f; // PP 0-3 / DDATA 0-3
+ if(!BIT(m_sim->get_par(), 5)) mask |= 0xf0; // PP 4-7 / PST 0-3
m_gpio_w_cb(((m_ppdat_out & m_ppddr) | (m_ppdat_in & ~m_ppddr)) & mask);
}
-/*
+/*
* System Integration Module
* Handles the interrupt system and bus
*/
-coldfire_sim_device::coldfire_sim_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+coldfire_sim_device::coldfire_sim_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, COLDFIRE_SIM, tag, owner, clock)
, irq_vector_cb(*this, (u8)EXCEPTION_BUS_ERROR)
, m_maincpu(*this, finder_base::DUMMY_TAG)
@@ -390,8 +390,8 @@ void coldfire_sim_device::device_add_mconfig(machine_config &config)
void coldfire_sim_device::device_start()
{
m_swdt->watchdog_enable(0);
- m_timer_swdt = timer_alloc( FUNC( coldfire_sim_device::swdt_callback ), this ); // For interrupt version
-
+ m_timer_swdt = timer_alloc( FUNC( coldfire_sim_device::swdt_callback ), this ); // For interrupt version
+
save_item(NAME(m_simr));
save_item(NAME(m_marb));
@@ -409,13 +409,13 @@ void coldfire_sim_device::device_start()
void coldfire_sim_device::device_reset()
{
- if(!(m_rsr & 0x20)) m_rsr = 0x00; // don't clear if watchdog triggered
+ if(!(m_rsr & 0x20)) m_rsr = 0x00; // don't clear if watchdog triggered
else m_rsr = 0x70;
m_simr = 0xc0;
m_marb = 0x00;
m_ipr = 0x3ffe;
- m_sypcr = 0x00;
+ m_sypcr = 0x00;
m_swivr = 0x0f;
m_imr = 0x3ffe;
m_ipr = 0x0000;
@@ -494,10 +494,10 @@ void coldfire_sim_device::icr_w(offs_t offset, u8 data)
case 4: m_icr[offset] = (data & 0x83) + (5 << 2); break;
case 5: m_icr[offset] = (data & 0x83) + (6 << 2); break;
case 6: m_icr[offset] = (data & 0x83) + (7 << 2); break;
- case 7: m_icr[offset] = (data & 0x03) + (7 << 2); break; // IPL7 and SWDT share same level, also you cannot use autovector on SWT.
- case 8: m_icr[offset] = (data & 0x1f) + 0x80; break; // Timer 1 *must* use autovector
- case 9: m_icr[offset] = (data & 0x1f) + 0x80; break; // Timer 2 *must* use autovector
- case 10: m_icr[offset] = (data & 0x1f) + 0x80; break; // MBUS *must* use autovector
+ case 7: m_icr[offset] = (data & 0x03) + (7 << 2); break; // IPL7 and SWDT share same level, also you cannot use autovector on SWT.
+ case 8: m_icr[offset] = (data & 0x1f) + 0x80; break; // Timer 1 *must* use autovector
+ case 9: m_icr[offset] = (data & 0x1f) + 0x80; break; // Timer 2 *must* use autovector
+ case 10: m_icr[offset] = (data & 0x1f) + 0x80; break; // MBUS *must* use autovector
case 11: m_icr[offset] = (data & 0x9f); break;
case 12: m_icr[offset] = (data & 0x9f); break;
case 13: m_icr[offset] = (data & 0x9f); break;
@@ -548,38 +548,38 @@ void coldfire_sim_device::set_external_interrupt(int level, int state)
// 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 ipl = (level >> 1) & 7; // Should be 2 for coldFire, really
u8 highest_priority_icr = 0;
- u8 highest_priority_device = 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)) {
- highest_priority_icr = m_icr[i];
- highest_priority_device = i + 1;
- }
- }
- }
-
- 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;
- }
+ 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(!this->machine().side_effects_disabled()) logerror("%s: Spurious interrupt detected: %u\n", this->machine().describe_context(), ipl);
+ return EXCEPTION_SPURIOUS_INTERRUPT;
+ }
BITWRITE(m_ipr, ipl, 0);
u8 vector = 0xff;
- // Check if ICR specifies to use autovectoring
- if (BIT(highest_priority_icr, 7)) {
- vector = m68000_base_device::autovector(ipl);
- } else {
+ // Check if ICR specifies to use autovectoring
+ if (BIT(highest_priority_icr, 7)) {
+ vector = m68000_base_device::autovector(ipl);
+ } else {
// Determine the correct vector to return
switch (highest_priority_device) {
case EXTERNAL_IPL_1:
@@ -609,13 +609,13 @@ u8 coldfire_sim_device::interrupt_callback(offs_t level)
//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;
}
}
-
+
return vector;
}
@@ -637,15 +637,15 @@ void coldfire_sim_device::set_interrupt(int interrupt, int state)
case EXTERNAL_IPL_5: icr = m_icr[ICR5]; break;
case EXTERNAL_IPL_6: icr = m_icr[ICR6]; break;
case EXTERNAL_IPL_7: icr = m_icr[ICR7]; break;
- case WATCHDOG_IRQ: icr = m_icr[ICR_SWDT]; break;
- case TIMER_1_IRQ: icr = m_icr[ICR_TMR1]; break; // Always autovector
- case TIMER_2_IRQ: icr = m_icr[ICR_TMR2]; break; // Always autovector
- case MBUS_IRQ: icr = m_icr[ICR_MBUS]; break; // Always autovector
- case UART_1_IRQ: icr = m_icr[ICR_UART1]; break;
- case UART_2_IRQ: icr = m_icr[ICR_UART2]; break;
- case DMA_0_IRQ: icr = m_icr[ICR_DMA0]; break;
- case DMA_1_IRQ: icr = m_icr[ICR_DMA1]; break;
- default:
+ case WATCHDOG_IRQ: icr = m_icr[ICR_SWDT]; break;
+ case TIMER_1_IRQ: icr = m_icr[ICR_TMR1]; break; // Always autovector
+ case TIMER_2_IRQ: icr = m_icr[ICR_TMR2]; break; // Always autovector
+ case MBUS_IRQ: icr = m_icr[ICR_MBUS]; break; // Always autovector
+ case UART_1_IRQ: icr = m_icr[ICR_UART1]; break;
+ case UART_2_IRQ: icr = m_icr[ICR_UART2]; break;
+ case DMA_0_IRQ: icr = m_icr[ICR_DMA0]; break;
+ case DMA_1_IRQ: icr = m_icr[ICR_DMA1]; break;
+ default:
logerror("%s: Unknown device trying to set interrupt level: %u\n", this->machine().describe_context(), interrupt);
return;
}
@@ -709,11 +709,11 @@ TIMER_CALLBACK_MEMBER(coldfire_sim_device::swdt_callback)
//set_interrupt(WDINT);
}
-/*
- * Timer Module/s
+/*
+ * 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) :
+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)
{
@@ -723,7 +723,7 @@ void coldfire_timer_device::timer_map(address_map &map)
{
map(0x00, 0x01).rw(FUNC(coldfire_timer_device::tmr_r), FUNC(coldfire_timer_device::tmr_w));
map(0x04, 0x05).rw(FUNC(coldfire_timer_device::trr_r), FUNC(coldfire_timer_device::trr_w));
- map(0x08, 0x09).r(FUNC(coldfire_timer_device::tcr_r)); // TCR is r/only
+ map(0x08, 0x09).r(FUNC(coldfire_timer_device::tcr_r)); // TCR is r/only
map(0x0c, 0x0d).rw(FUNC(coldfire_timer_device::tcn_r), FUNC(coldfire_timer_device::tcn_w));
map(0x11, 0x11).rw(FUNC(coldfire_timer_device::ter_r), FUNC(coldfire_timer_device::ter_w));
}
@@ -777,10 +777,10 @@ void coldfire_timer_device::tmr_w(u16 data)
// todo: add tin pin support
int div, start, interval;
start = (m_trr - m_tcn);
- div = ((m_tmr & 0xff00) >> 8) + 1; // 1 -> 256 division scale
- if ((m_tmr & T_CL1) && !(m_tmr & T_CL0)) div = div * 16; // input clock / 16
- if (!(m_tmr & T_FRR)) interval = (0xffff * div); // don't reset tcn to 0
- else interval = start; // else tcn is reset to 0
+ div = ((m_tmr & 0xff00) >> 8) + 1; // 1 -> 256 division scale
+ if ((m_tmr & T_CL1) && !(m_tmr & T_CL0)) div = div * 16; // input clock / 16
+ if (!(m_tmr & T_FRR)) interval = (0xffff * div); // don't reset tcn to 0
+ else interval = start; // else tcn is reset to 0
m_timer_start_time = machine().time();
m_timer->adjust(clocks_to_attotime(start * div), 0, clocks_to_attotime(interval * div));
}
@@ -798,7 +798,7 @@ void coldfire_timer_device::trr_w(u16 data)
u16 coldfire_timer_device::tcn_r()
{
m_tcn = (attotime_to_clocks(machine().time() - m_timer_start_time) & 0xffff);
- return m_tcn;
+ return m_tcn;
}
void coldfire_timer_device::tcn_w(u16 data)
@@ -826,7 +826,7 @@ void coldfire_timer_device::ter_w(u8 data)
void mcf5206e_device::init_regs(bool first_init)
{
m_dcrr = 0x0000;
- m_dctr = 0x0000;
+ m_dctr = 0x0000;
m_dcar0 = UNINIT;
m_dcmr0 = UNINIT;
m_dccr0 = 0x00;
@@ -861,7 +861,7 @@ 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) :
+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)
@@ -948,7 +948,7 @@ u8 coldfire_mbus_device::mbsr_r()
void coldfire_mbus_device::mbsr_w(u8 data)
{
- m_mbsr = (data & 0x14); // MAL & MIF
+ m_mbsr = (data & 0x14); // MAL & MIF
LOGMASKED(LOG_MBUS, "%s: (M-Bus Status Register) mbsr_w: %02x\n", this->machine().describe_context(), data);
}
@@ -969,10 +969,10 @@ void coldfire_mbus_device::mbdr_w(u8 data)
/*
* DMA Module
- *
+ *
*/
-coldfire_dma_device::coldfire_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 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)
{
@@ -995,10 +995,10 @@ void coldfire_dma_device::device_reset()
{
m_sar = 0x00000000;
m_dar = 0x00000000;
- m_dcr = 0x0000;
- m_bcr = 0x0000;
- m_dsr = 0x00;
- m_divr = 0x0F;
+ m_dcr = 0x0000;
+ m_bcr = 0x0000;
+ m_dsr = 0x00;
+ m_divr = 0x0F;
//m_timer_dma->adjust(attotime::never);
}
@@ -1040,7 +1040,7 @@ void coldfire_dma_device::bcr_w(u16 data)
void coldfire_dma_device::dsr_w(u8 data)
{
- BITWRITE(m_dsr, 0, BIT(data, 0)); // Manual states only writes to bit 0 has any effect on the register
+ BITWRITE(m_dsr, 0, BIT(data, 0)); // Manual states only writes to bit 0 has any effect on the register
LOGMASKED(LOG_DMA, "%s: (DMA Status Register) dsr_w: %02x\n", this->machine().describe_context(), data);
}