summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2017-09-05 16:49:58 -0400
committer GitHub <noreply@github.com>2017-09-05 16:49:58 -0400
commit3832af3948948ea3da1e0b18fc6f99d8c624755c (patch)
treee9955e9286a84ea8d8d84f7172c4808cdff4cb76
parent6523a1566ebd28c4e01ab52af9744b7f9badc972 (diff)
parent9d4df844ba6333b1a4400f4f845b7956df435dfe (diff)
Merge pull request #2628 from JoakimLarsson/m68340_5
Improved 68340, 68681 and dbox support
-rw-r--r--src/devices/machine/68340.cpp43
-rw-r--r--src/devices/machine/68340.h8
-rw-r--r--src/devices/machine/68340ser.cpp166
-rw-r--r--src/devices/machine/68340ser.h50
-rw-r--r--src/devices/machine/68340sim.cpp25
-rw-r--r--src/devices/machine/68340tmu.cpp4
-rw-r--r--src/devices/machine/68340tmu.h2
-rw-r--r--src/devices/machine/mc68681.cpp82
-rw-r--r--src/devices/machine/mc68681.h25
-rw-r--r--src/mame/drivers/dbox.cpp2
10 files changed, 354 insertions, 53 deletions
diff --git a/src/devices/machine/68340.cpp b/src/devices/machine/68340.cpp
index 1aaa6ee78dd..68f1db3134c 100644
--- a/src/devices/machine/68340.cpp
+++ b/src/devices/machine/68340.cpp
@@ -1,6 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
-/* 68340 */
+/* 68340
+ * TODO: - convert all modules to devices
+ */
#include "emu.h"
#include "68340.h"
@@ -78,23 +80,23 @@ WRITE32_MEMBER( m68340_cpu_device::m68340_internal_base_w )
int base = m68340_base & 0xfffff000;
internal->install_readwrite_handler(base + 0x000, base + 0x03f,
- read16_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_r),this),
- write16_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_w),this),0xffffffff);
+ read16_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_r),this),
+ write16_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_w),this),0xffffffff);
internal->install_readwrite_handler(base + 0x010, base + 0x01f, // Intentionally punches a hole in previous address mapping
- read8_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_ports_r),this),
- write8_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_ports_w),this),0xffffffff);
+ read8_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_ports_r),this),
+ write8_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_ports_w),this),0xffffffff);
internal->install_readwrite_handler(base + 0x040, base + 0x05f,
- read32_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_cs_r),this),
- write32_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_cs_w),this));
+ read32_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_cs_r),this),
+ write32_delegate(FUNC(m68340_cpu_device::m68340_internal_sim_cs_w),this));
internal->install_readwrite_handler(base + 0x600, base + 0x67f,
- read16_delegate(FUNC(m68340_cpu_device::m68340_internal_timer_r),this),
- write16_delegate(FUNC(m68340_cpu_device::m68340_internal_timer_w),this),0xffffffff);
+ read16_delegate(FUNC(m68340_cpu_device::m68340_internal_timer_r),this),
+ write16_delegate(FUNC(m68340_cpu_device::m68340_internal_timer_w),this),0xffffffff);
internal->install_readwrite_handler(base + 0x700, base + 0x723,
- read32_delegate(FUNC(m68340_cpu_device::m68340_internal_serial_r),this),
- write32_delegate(FUNC(m68340_cpu_device::m68340_internal_serial_w),this));
+ READ8_DEVICE_DELEGATE(m_serial, m68340_serial, read),
+ WRITE8_DEVICE_DELEGATE(m_serial, m68340_serial, write),0xffffffff);
internal->install_readwrite_handler(base + 0x780, base + 0x7bf,
- read32_delegate(FUNC(m68340_cpu_device::m68340_internal_dma_r),this),
- write32_delegate(FUNC(m68340_cpu_device::m68340_internal_dma_w),this));
+ read32_delegate(FUNC(m68340_cpu_device::m68340_internal_dma_r),this),
+ write32_delegate(FUNC(m68340_cpu_device::m68340_internal_dma_w),this));
}
@@ -108,17 +110,27 @@ WRITE32_MEMBER( m68340_cpu_device::m68340_internal_base_w )
}
-
static ADDRESS_MAP_START( m68340_internal_map, AS_PROGRAM, 32, m68340_cpu_device )
AM_RANGE(0x0003ff00, 0x0003ff03) AM_READWRITE( m68340_internal_base_r, m68340_internal_base_w)
ADDRESS_MAP_END
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+MACHINE_CONFIG_MEMBER( m68340_cpu_device::device_add_mconfig )
+ MCFG_DEVICE_ADD("serial", M68340_SERIAL_MODULE, 0)
+ MCFG_MC68681_IRQ_CALLBACK(DEVWRITELINE("serial", m68340_serial, irq_w))
+MACHINE_CONFIG_END
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
m68340_cpu_device::m68340_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: fscpu32_device(mconfig, tag, owner, clock, M68340, 32,32, ADDRESS_MAP_NAME(m68340_internal_map))
+ , m_serial(*this, "serial")
, m_clock_mode(0)
, m_crystal(0)
, m_extal(0)
@@ -135,7 +147,6 @@ m68340_cpu_device::m68340_cpu_device(const machine_config &mconfig, const char *
{
m68340SIM = nullptr;
m68340DMA = nullptr;
- m68340SERIAL = nullptr;
m68340TIMER = nullptr;
m68340_base = 0;
}
@@ -165,12 +176,10 @@ void m68340_cpu_device::device_start()
m68340SIM = new m68340_sim();
m68340DMA = new m68340_dma();
- m68340SERIAL = new m68340_serial();
m68340TIMER = new m68340_timer();
m68340SIM->reset();
m68340DMA->reset();
- m68340SERIAL->reset();
m68340TIMER->reset();
start_68340_sim();
diff --git a/src/devices/machine/68340.h b/src/devices/machine/68340.h
index cd29ad091fa..22ea42cbabc 100644
--- a/src/devices/machine/68340.h
+++ b/src/devices/machine/68340.h
@@ -51,6 +51,8 @@
class m68340_cpu_device : public fscpu32_device
{
+ friend class m68340_serial;
+
public:
m68340_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@@ -80,8 +82,6 @@ public:
WRITE32_MEMBER( m68340_internal_base_w );
READ32_MEMBER( m68340_internal_dma_r );
WRITE32_MEMBER( m68340_internal_dma_w );
- READ32_MEMBER( m68340_internal_serial_r );
- WRITE32_MEMBER( m68340_internal_serial_w );
READ16_MEMBER( m68340_internal_sim_r );
READ8_MEMBER( m68340_internal_sim_ports_r );
READ32_MEMBER( m68340_internal_sim_cs_r );
@@ -104,6 +104,9 @@ public:
protected:
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ required_device<m68340_serial> m_serial;
TIMER_CALLBACK_MEMBER(periodic_interrupt_timer_callback);
TIMER_CALLBACK_MEMBER(timer1_callback);
@@ -127,7 +130,6 @@ protected:
/* 68340 peripheral modules */
m68340_sim* m68340SIM;
m68340_dma* m68340DMA;
- m68340_serial* m68340SERIAL;
m68340_timer* m68340TIMER;
uint32_t m68340_base;
diff --git a/src/devices/machine/68340ser.cpp b/src/devices/machine/68340ser.cpp
index 8a26975cd87..e3b2a382cd3 100644
--- a/src/devices/machine/68340ser.cpp
+++ b/src/devices/machine/68340ser.cpp
@@ -1,31 +1,171 @@
// license:BSD-3-Clause
-// copyright-holders:David Haywood
+// copyright-holders:David Haywood, Joakim Larsson Edstrom
/* 68340 SERIAL module */
#include "emu.h"
#include "68340.h"
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
-READ32_MEMBER( m68340_cpu_device::m68340_internal_serial_r )
+//#define LOG_GENERAL (1U << 0) // Already defined in logmacro.h
+#define LOG_SETUP (1U << 1)
+#define LOG_READ (1U << 2)
+#define LOG_SERIAL (1U << 3)
+#define LOG_INT (1U << 4)
+
+//#define VERBOSE (LOG_SETUP|LOG_READ|LOG_SERIAL|LOG_INT)
+#define LOG_OUTPUT_FUNC printf // Needs always to be enabled as the default value 'logerror' is not available here
+
+#include "logmacro.h"
+
+//#define LOG(...) LOGMASKED(LOG_GENERAL, __VA_ARGS__) // Already defined in logmacro.h
+#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
+#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__)
+#define LOGSERIAL(...) LOGMASKED(LOG_SERIAL, __VA_ARGS__)
+#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#endif
+
+void m68340_serial::device_start()
{
- assert(m68340SERIAL);
- //m68340_serial &serial = *m68340SERIAL;
+ m_cpu = downcast<m68340_cpu_device *>(owner());
+ m68340_serial_device::device_start();
+}
+
+READ8_MEMBER( m68340_serial::read )
+{
+ LOG("%s\n", FUNCNAME);
+ int val = 0;
+
+ LOGR("%08x %s %08x, (%08x)\n", space.device().safe_pc(), FUNCNAME, offset, mem_mask);
- int pc = space.device().safe_pc();
- logerror("%08x m68340_internal_serial_r %08x, (%08x)\n", pc, offset*4,mem_mask);
+ /*Setting the STP bit stops all clocks within the serial module (including the crystal
+ or external clock and SCLK), except for the clock from the IMB. The clock from the IMB
+ remains active to allow CPU32 access to the MCR. The clock stops on the low phase of the
+ clock and remains stopped until the STP bit is cleared by the CPU32 or a hardware reset.
+ Accesses to serial module registers while in stop mode produce a bus error. */
+ if ( (m_mcrh & REG_MCRH_STP) && offset != REG_MCRH && offset != REG_MCRL)
+ {
+ logerror("Attempt to access timer registers while timer clocks are stopped, STP bit in MCR is set!");
+ return val; // TODO: Should cause BUSERROR
+ }
- return 0x00000000;
+ switch (offset)
+ {
+ case REG_MCRH:
+ val = m_mcrh;
+ LOGSERIAL("- %08x %s %04x, %04x (%04x) (MCRH - Module Configuration Register High byte)\n", space.device().safe_pc(), FUNCNAME, offset, val, mem_mask);
+ break;
+ case REG_MCRL:
+ val = m_mcrl;
+ LOGSERIAL("- %08x %s %04x, %04x (%04x) (MCRL - Module Configuration Register Low byte)\n", space.device().safe_pc(), FUNCNAME, offset, val, mem_mask);
+ break;
+ case REG_ILR:
+ val = m_ilr;
+ LOGSERIAL("- %08x %s %04x, %04x (%04x) (ILR - Interrupt Level Register)\n", space.device().safe_pc(), FUNCNAME, offset, val, mem_mask);
+ break;
+ case REG_IVR:
+ val = m_ivr;
+ LOGSERIAL("- %08x %s %04x, %04x (%04x) (IVR - Interrupt Vector Register)\n", space.device().safe_pc(), FUNCNAME, offset, val, mem_mask);
+ break;
+ }
+
+
+ LOGR(" * Reg %02x -> %02x - %s\n", offset, val,
+ (offset > 0x21) ? "Error - should not happen" :
+ std::array<char const *, 0x22>
+ {{
+ "MCRH", "MCRL", "n/a", "n/a", "ILR", "IVR", "hole", "hole", // 0x00 - 0x07
+ "hole", "hole", "hole", "hole", "hole", "hole", "hole", "hole", // 0x08 - 0x0f
+ "MR1A", "SRA", "n/a", "RBA", "IPCR", "ISR", "n/a", "n/a", // 0x10 - 0x17
+ "MR1B", "SRB", "n/a", "RBB", "n/a", "IP", "n/a", "n/a", // 0x18 - 0x1f
+ "MR2A", "MR2B" }}[offset]); // 0x20 - 0x21
+
+ return offset >= 0x10 && offset < 0x22 ? m68340_serial_device::read(space, offset - 0x10, mem_mask) : val;
}
-WRITE32_MEMBER( m68340_cpu_device::m68340_internal_serial_w )
+WRITE8_MEMBER( m68340_serial::write )
{
- assert(m68340SERIAL);
- //m68340_serial &serial = *m68340SERIAL;
+ LOG("\n%s\n", FUNCNAME);
+ LOGSETUP(" * Reg %02x <- %02x - %s\n", offset, data,
+ (offset > 0x21) ? "Error - should not happen" :
+ std::array<char const *, 0x22>
+ {{
+ "MCRH", "MCRL", "n/a", "n/a", "ILR", "IVR", "hole", "hole", // 0x00 - 0x07
+ "hole", "hole", "hole", "hole", "hole", "hole", "hole", "hole", // 0x08 - 0x0f
+ "MR1A", "CSRA", "CRA", "TBA", "ACR", "IER", "n/a", "n/a", // 0x10 - 0x17
+ "MR1B", "CSRB", "CRB", "TBB", "n/a", "OPCR", "OPS", "OPR", // 0x18 - 0x1f
+ "MR2A", "MR2B" }}[offset]); // 0x20 - 0x21
+
+ /*Setting the STP bit stops all clocks within the serial module (including the crystal
+ or external clock and SCLK), except for the clock from the IMB. The clock from the IMB
+ remains active to allow CPU32 access to the MCR. The clock stops on the low phase of the
+ clock and remains stopped until the STP bit is cleared by the CPU32 or a hardware reset.
+ Accesses to serial module registers while in stop mode produce a bus error. */
+ if ( (m_mcrh & REG_MCRH_STP) && offset != REG_MCRH && offset != REG_MCRL)
+ {
+ logerror("Attempt to access timer registers while timer clocks are stopped, STP bit in MCR is set!");
+ return; // TODO: Should cause BUSERROR
+ }
+
+ switch (offset)
+ {
+ case REG_MCRH:
+ m_mcrh = data;
+ LOGSERIAL("PC: %08x %s %04x, %04x (%04x) (MCRH - Module Configuration Register High byte)\n", space.device().safe_pc(), FUNCNAME, offset, data, mem_mask);
+ LOGSERIAL("- Clocks are %s\n", data & REG_MCRH_STP ? "stopped" : "running");
+ LOGSERIAL("- Freeze signal %s - not implemented\n", data & REG_MCRH_FRZ1 ? "stops at character boundary" : "is ignored");
+ LOGSERIAL("- CTS capture clock: %s - not implemented\n", data & REG_MCRH_ICCS ? "SCLK" : "Crystal");
+ break;
+ case REG_MCRL:
+ m_mcrl = data;
+ LOGSERIAL("PC: %08x %s %04x, %04x (%04x) (MCRL - Module Configuration Register Low byte)\n", space.device().safe_pc(), FUNCNAME, offset, data, mem_mask);
+ LOGSERIAL("- Supervisor registers %s - not implemented\n", data & REG_MCRL_SUPV ? "requries supervisor privileges" : "can be accessed by user privileged software");
+ LOGSERIAL("- Interrupt Arbitration level: %02x - not implemented\n", data & REG_MCRL_ARBLV);
+ break;
+ case REG_ILR:
+ m_ilr = data;
+ LOGSERIAL("PC: %08x %s %04x, %04x (%04x) (ILR - Interrupt Level Register)\n", space.device().safe_pc(), FUNCNAME, offset, data, mem_mask);
+ LOGSERIAL("- Interrupt Level: %02x\n", data & REG_ILR_MASK);
+ break;
+ case REG_IVR:
+ m_ivr = data;
+ LOGSERIAL("PC: %08x %s %04x, %04x (%04x) (IVR - Interrupt Vector Register)\n", space.device().safe_pc(), FUNCNAME, offset, data, mem_mask);
+ LOGSERIAL("- Interrupt Vector: %02x\n", data);
+ break;
+ default:
+ if (offset >= 0x10 && offset < 0x22) m68340_serial_device::write(space, offset - 0x10, data, mem_mask);
+ }
- int pc = space.device().safe_pc();
- logerror("%08x m68340_internal_serial_w %08x, %08x (%08x)\n", pc, offset*4,data,mem_mask);
}
-void m68340_serial::reset()
+WRITE_LINE_MEMBER( m68340_serial::irq_w )
{
+ LOGINT("IRQ!\n%s\n", FUNCNAME);
+ if (m_ilr > 0)
+ {
+ if (((m_cpu->m68340SIM->m_avr_rsr >> (8 + m_ilr)) & 1) != 0) // use autovector ?
+ {
+ LOGINT("- Autovector level %d\n", m_ilr);
+ m_cpu->set_input_line(m_ilr, HOLD_LINE);
+ }
+ else // otherwise not...
+ {
+ LOGINT("- Vector %02x level %d\n", m_ivr, m_ilr);
+ m_cpu->set_input_line_and_vector(m_ilr, HOLD_LINE, m_ivr);
+ }
+ }
}
+
+m68340_serial::m68340_serial(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : m68340_serial_device(mconfig, "serial", owner, clock)
+{
+}
+
+DEFINE_DEVICE_TYPE(M68340_SERIAL_MODULE, m68340_serial, "m68340 serial module", "Motorola 68340 Serial Module")
diff --git a/src/devices/machine/68340ser.h b/src/devices/machine/68340ser.h
index c5fcd028bdd..271b26dafcd 100644
--- a/src/devices/machine/68340ser.h
+++ b/src/devices/machine/68340ser.h
@@ -5,11 +5,57 @@
#pragma once
+#include "machine/mc68681.h"
-class m68340_serial
+class m68340_cpu_device;
+
+class m68340_serial : public m68340_serial_device
{
+ friend class m68340_cpu_device;
+
public:
- void reset();
+ m68340_serial(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+
+ READ8_MEMBER( read ) override;
+ WRITE8_MEMBER( write ) override;
+ DECLARE_WRITE_LINE_MEMBER(irq_w);
+
+protected:
+ m68340_cpu_device *m_cpu;
+
+ // Module registers not in the DUART part
+ uint8_t m_mcrh;
+ uint8_t m_mcrl;
+ uint8_t m_ilr;
+ uint8_t m_ivr;
+
+ enum {
+ REG_MCRH = 0,
+ REG_MCRL = 1,
+ REG_ILR = 4,
+ REG_IVR = 5,
+ };
+
+ enum {
+ REG_MCRH_STP = 0x80,
+ REG_MCRH_FRZ1 = 0x40,
+ REG_MCRH_FRZ2 = 0x20,
+ REG_MCRH_ICCS = 0x10,
+ };
+
+ enum {
+ REG_MCRL_SUPV = 0x80,
+ REG_MCRL_ARBLV = 0x0f,
+ };
+
+ enum {
+ REG_ILR_MASK = 0x07
+ };
};
+DECLARE_DEVICE_TYPE(M68340_SERIAL_MODULE, m68340_serial)
+
#endif // MAME_MACHINE_68340SER_H
diff --git a/src/devices/machine/68340sim.cpp b/src/devices/machine/68340sim.cpp
index 701369269f8..ddc7516b237 100644
--- a/src/devices/machine/68340sim.cpp
+++ b/src/devices/machine/68340sim.cpp
@@ -18,8 +18,9 @@
#define LOG_DATA (1U << 6)
#define LOG_INT (1U << 7)
#define LOG_PIT (1U << 8)
+#define LOG_CS (1U << 9)
-//#define VERBOSE (LOG_SETUP)
+//#define VERBOSE (LOG_CS)
#define LOG_OUTPUT_FUNC printf // Needs always to be enabled as the default value 'logerror' is not available here
#include "logmacro.h"
@@ -33,6 +34,7 @@
#define LOGDATA(...) LOGMASKED(LOG_DATA, __VA_ARGS__)
#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
#define LOGPIT(...) LOGMASKED(LOG_PIT, __VA_ARGS__)
+#define LOGCS(...) LOGMASKED(LOG_CS, __VA_ARGS__)
#ifdef _MSC_VER
#define FUNCNAME __func__
@@ -45,7 +47,7 @@ READ16_MEMBER( m68340_cpu_device::m68340_internal_sim_r )
LOGR("%s\n", FUNCNAME);
assert(m68340SIM);
m68340_sim &sim = *m68340SIM;
- int val = space.machine().rand();
+ int val = 0;
int pc = space.device().safe_pc();
switch (offset * 2)
@@ -86,14 +88,15 @@ READ16_MEMBER( m68340_cpu_device::m68340_internal_sim_r )
break;
default:
- LOGSIM("- %08x %s %04x, (%04x)\n", pc, FUNCNAME, offset * 2, mem_mask);
+ logerror("- %08x %s %04x, (%04x) (unsupported register)\n", pc, FUNCNAME, offset * 2, mem_mask);
+ LOGSIM("- %08x %s %04x, (%04x) (unsupported register)\n", pc, FUNCNAME, offset * 2, mem_mask);
}
LOGR(" * Reg %02x -> %02x - %s\n", offset * 2, val,
((offset * 2) >= 0x10 && (offset * 2) < 0x20) || (offset * 2) >= 0x60 ? "Error - should not happen" :
std::array<char const *, 8> {{"MCR", "reserved", "SYNCR", "AVR/RSR", "SWIV/SYPCR", "PICR", "PITR", "SWSR"}}[(offset * 2) <= m68340_sim::REG_AVR_RSR ? offset : offset - 0x10 + 0x04]);
- return 0x0000;
+ return val;
}
WRITE16_MEMBER( m68340_cpu_device::m68340_internal_sim_w )
@@ -376,14 +379,24 @@ WRITE32_MEMBER( m68340_cpu_device::m68340_internal_sim_cs_w )
{
LOG("%s\n", FUNCNAME);
offset += m68340_sim::REG_AM_CS0>>2;
- LOGSETUP("- %08x %s %08x, %08x (%08x) - not implemented\n", pc, FUNCNAME, offset*4,data,mem_mask);
+
+ if (offset & 1)
+ {
+ LOGCS("%08x Base address CS%d %08x, %08x (%08x) ", pc, (offset - 0x10) / 2, offset * 4, data, mem_mask);
+ LOGCS("- Base: %08x BFC:%02x WP:%d FTE:%d NCS:%d Valid: %s\n", data & 0xffffff00, (data & 0xf0) >> 4, data & 0x08 ? 1 : 0, data & 0x04 ? 1 : 0, data & 0x02 ? 1 : 0, data & 0x01 ? "Yes" : "No");
+ }
+ else
+ {
+ LOGCS("%08x Address mask CS%d %08x, %08x (%08x) ", pc, (offset - 0x10) / 2, offset * 4, data, mem_mask);
+ LOGCS("- Mask: %08x FCM:%02x DD:%d PS: %s\n", data & 0xffffff00, (data & 0xf0) >> 4, (data >> 2) & 0x03, std::array<char const *, 4>{{"Reserved", "16-Bit", "8-bit", "External DSACK response"}}[data & 0x03]);
+ }
assert(m68340SIM);
m68340_sim &sim = *m68340SIM;
int pc = space.device().safe_pc();
- switch (offset<<2)
+ switch (offset << 2)
{
case m68340_sim::REG_AM_CS0:
COMBINE_DATA(&sim.m_am[0]);
diff --git a/src/devices/machine/68340tmu.cpp b/src/devices/machine/68340tmu.cpp
index ab4443fa818..0fb359dbddf 100644
--- a/src/devices/machine/68340tmu.cpp
+++ b/src/devices/machine/68340tmu.cpp
@@ -47,7 +47,7 @@ READ16_MEMBER( m68340_cpu_device::m68340_internal_timer_r )
int val = 0;
int pc = space.device().safe_pc();
- logerror("%08x m68340_internal_timer_r %08x, (%08x)\n", pc, offset * 2, mem_mask);
+ LOGR("%08x m68340_internal_timer_r %08x, (%08x)\n", pc, offset * 2, mem_mask);
int id = (offset * 2) < 0x40 ? 0 : 1; // Timer1 or Timer2
@@ -257,7 +257,7 @@ WRITE16_MEMBER( m68340_cpu_device::m68340_internal_timer_w )
}
int pc = space.device().safe_pc();
- logerror("%08x m68340_internal_timer_w %08x, %08x (%08x)\n", pc, offset * 2, data, mem_mask);
+ LOG("%08x m68340_internal_timer_w %08x, %08x (%08x)\n", pc, offset * 2, data, mem_mask);
}
void m68340_timer::reset()
diff --git a/src/devices/machine/68340tmu.h b/src/devices/machine/68340tmu.h
index 3bcbd844184..8e49914a436 100644
--- a/src/devices/machine/68340tmu.h
+++ b/src/devices/machine/68340tmu.h
@@ -41,7 +41,7 @@ public:
REG_MCR_STP = 0x8000,
REG_MCR_FRZ1 = 0x4000,
REG_MCR_FRZ2 = 0x2000,
- REG_MCR_SUPV = 0x0800,
+ REG_MCR_SUPV = 0x0080,
REG_MCR_ARBLV = 0x000f,
};
diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp
index 956dbe2071b..0659dc3dc29 100644
--- a/src/devices/machine/mc68681.cpp
+++ b/src/devices/machine/mc68681.cpp
@@ -4,17 +4,20 @@
2681 DUART
68681 DUART
28C94 QUART
+ 68340 serial module
Written by Mariusz Wojcieszek
Updated by Jonathan Gevaryahu AKA Lord Nightmare
Improved interrupt handling by R. Belmont
Rewrite and modernization in progress by R. Belmont
+ Addition of 68340 serial module support by Edstrom
*/
#include "emu.h"
#include "mc68681.h"
//#define VERBOSE 1
+//#define LOG_OUTPUT_FUNC printf
#include "logmacro.h"
@@ -59,6 +62,7 @@ static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000,
// device type definition
DEFINE_DEVICE_TYPE(MC68681, mc68681_device, "mc68681", "MC68681 DUART")
DEFINE_DEVICE_TYPE(SC28C94, sc28c94_device, "sc28c94", "SC28C94 QUART")
+DEFINE_DEVICE_TYPE(M68340SERIAL, m68340_serial_device, "m68340ser", "M68340 SERIAL MODULE")
DEFINE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel, "mc68681_channel", "MC68681 DUART channel")
@@ -99,6 +103,18 @@ sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, d
{
}
+//--------------------------------------------------------------------------------------------------------------------
+// The read and write methods are meant to catch all differences in the register model between 68681 and 68340
+// serial module. Eg some registers are (re)moved into the 68340 like the vector register. There are also no counter
+// in the 68340. The CSR clock register is also different for the external clock modes. The implementation assumes
+// that the code knows all of this and will not warn if those registers are accessed as it could be ported code.
+// TODO: A lot of subtle differences and also detect misuse of unavailable registers as they should be ignored
+//--------------------------------------------------------------------------------------------------------------------
+m68340_serial_device::m68340_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68681_base_device(mconfig, M68340SERIAL, tag, owner, clock)
+{
+}
+
//-------------------------------------------------
// static_set_clocks - configuration helper to set
// the external clocks
@@ -171,6 +187,11 @@ MACHINE_CONFIG_MEMBER( sc28c94_device::device_add_mconfig )
MCFG_DEVICE_ADD(CHAND_TAG, MC68681_CHANNEL, 0)
MACHINE_CONFIG_END
+MACHINE_CONFIG_MEMBER( m68340_serial_device::device_add_mconfig )
+ MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
+MACHINE_CONFIG_END
+
void mc68681_base_device::update_interrupts()
{
/* update SR state and update interrupt ISR state for the following bits:
@@ -345,6 +366,30 @@ TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback )
}
+READ8_MEMBER( m68340_serial_device::read )
+{
+ uint8_t r = 0;
+
+ switch (offset)
+ {
+ case 0x00: /* MR1A - does not share register address with MR2A */
+ r = m_chanA->read_MR1();
+ break;
+ case 0x08: /* MR1B - does not share register address with MR2B */
+ r = m_chanB->read_MR1();
+ break;
+ case 0x10: /* MR2A - does not share register address with MR1A */
+ r = m_chanA->read_MR2();
+ break;
+ case 0x11: /* MR2B - does not share register address with MR1B */
+ r = m_chanB->read_MR2();
+ break;
+ default:
+ r = mc68681_base_device::read(space, offset, mem_mask);
+ }
+ return r;
+}
+
READ8_MEMBER( sc28c94_device::read )
{
uint8_t r = 0;
@@ -477,6 +522,29 @@ READ8_MEMBER( mc68681_base_device::read )
return r;
}
+WRITE8_MEMBER( m68340_serial_device::write )
+{
+ //printf("Duart write %02x -> %02x\n", data, offset);
+
+ switch(offset)
+ {
+ case 0x00: /* MR1A - does not share register address with MR2A */
+ m_chanA->write_MR1(data);
+ break;
+ case 0x08: /* MR1B - does not share register address with MR2B */
+ m_chanB->write_MR1(data);
+ break;
+ case 0x10: /* MR2A - does not share register address with MR1A */
+ m_chanA->write_MR2(data);
+ break;
+ case 0x11: /* MR2B - does not share register address with MR1B */
+ m_chanB->write_MR2(data);
+ break;
+ default:
+ mc68681_base_device::write(space, offset, data, mem_mask);
+ }
+}
+
WRITE8_MEMBER( sc28c94_device::write )
{
offset &= 0x1f;
@@ -810,7 +878,7 @@ void mc68681_channel::rcv_complete()
{
receive_register_extract();
-// printf("%s ch %d rcv complete\n", tag(), m_ch);
+ //printf("%s ch %d rcv complete\n", tag(), m_ch);
if ( rx_enabled )
{
@@ -832,7 +900,7 @@ void mc68681_channel::rcv_complete()
void mc68681_channel::tra_complete()
{
-// printf("%s ch %d Tx complete\n", tag(), m_ch);
+ //printf("%s ch %d Tx complete\n", tag(), m_ch);
tx_ready = 1;
SR |= STATUS_TRANSMITTER_READY;
@@ -996,7 +1064,7 @@ uint8_t mc68681_channel::read_rx_fifo()
{
uint8_t rv;
-// printf("read_rx_fifo: rx_fifo_num %d\n", rx_fifo_num);
+ //printf("read_rx_fifo: rx_fifo_num %d\n", rx_fifo_num);
if ( rx_fifo_num == 0 )
{
@@ -1014,7 +1082,7 @@ uint8_t mc68681_channel::read_rx_fifo()
rx_fifo_num--;
update_interrupts();
-// printf("Rx read %02x\n", rv);
+ //printf("Rx read %02x\n", rv);
return rv;
}
@@ -1064,7 +1132,7 @@ void mc68681_channel::write_chan_reg(int reg, uint8_t data)
CSR = data;
tx_baud_rate = m_uart->calc_baud(m_ch, data & 0xf);
rx_baud_rate = m_uart->calc_baud(m_ch, (data>>4) & 0xf);
-// printf("%s ch %d CSR %02x Tx baud %d Rx baud %d\n", tag(), m_ch, data, tx_baud_rate, rx_baud_rate);
+ //printf("%s ch %d CSR %02x Tx baud %d Rx baud %d\n", tag(), m_ch, data, tx_baud_rate, rx_baud_rate);
set_rcv_rate(rx_baud_rate);
set_tra_rate(tx_baud_rate);
break;
@@ -1149,7 +1217,7 @@ void mc68681_channel::recalc_framing()
break;
}
-// printf("%s ch %d MR1 %02x MR2 %02x => %d bits / char, %d stop bits, parity %d\n", tag(), m_ch, MR1, MR2, (MR1 & 3)+5, stopbits, parity);
+ //printf("%s ch %d MR1 %02x MR2 %02x => %d bits / char, %d stop bits, parity %d\n", tag(), m_ch, MR1, MR2, (MR1 & 3)+5, stopbits, parity);
set_data_frame(1, (MR1 & 3)+5, parity, stopbits);
}
@@ -1241,7 +1309,7 @@ void mc68681_channel::write_TX(uint8_t data)
printf("Write %02x to TX when TX not ready!\n", data);
}*/
- //printf("%s ch %d Tx %02x\n", tag(), m_ch, data);
+ //printf("%s ch %d Tx %c [%02x]\n", tag(), m_ch, isprint(data) ? data : ' ', data);
tx_ready = 0;
SR &= ~STATUS_TRANSMITTER_READY;
diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h
index d1f9d3c96d6..47e15e3c318 100644
--- a/src/devices/machine/mc68681.h
+++ b/src/devices/machine/mc68681.h
@@ -41,6 +41,10 @@
#define MCFG_SC28C94_D_TX_CALLBACK(_cb) \
devcb = &sc28c94_device::set_d_tx_cb(*device, DEVCB_##_cb);
+// M68340SERIAL specific callbacks
+#define MCFG_M68340SERIAL_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD(_tag, M68340SERIAL, _clock)
+
#define MC68681_RX_FIFO_SIZE 3
// forward declaration
@@ -71,6 +75,12 @@ public:
uint8_t get_chan_CSR();
+ // Access methods needed for 68340 serial module register model
+ uint8_t read_MR1(){ return MR1; }
+ uint8_t read_MR2(){ return MR2; }
+ void write_MR1(uint8_t data){ MR1 = data; }
+ void write_MR2(uint8_t data){ MR2 = data; }
+
private:
/* Registers */
uint8_t CR; /* Command register */
@@ -230,8 +240,23 @@ protected:
private:
};
+class m68340_serial_device : public mc68681_base_device
+{
+public:
+ m68340_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual DECLARE_READ8_MEMBER(read) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+};
+
DECLARE_DEVICE_TYPE(MC68681, mc68681_device)
DECLARE_DEVICE_TYPE(SC28C94, sc28c94_device)
+DECLARE_DEVICE_TYPE(M68340SERIAL, m68340_serial_device)
DECLARE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel)
#endif // MAME_MACHINE_MC68681_H
diff --git a/src/mame/drivers/dbox.cpp b/src/mame/drivers/dbox.cpp
index 62966abc959..2ed325e9f89 100644
--- a/src/mame/drivers/dbox.cpp
+++ b/src/mame/drivers/dbox.cpp
@@ -621,7 +621,6 @@ static MACHINE_CONFIG_START( dbox )
//MCFG_MC68340_TOUT2_OUTPUT_CB(DEVWRITELINE("dcs", descrambler_device, txd_receiver))
//MCFG_MC68340_TGATE2_INPUT_CB(DEVREADLINE("dsc", descrambler_device, rxd_receiver))
-#if 0
/* Configure the serial ports */
#define CHA ":rs232"
#define CHB ":modem"
@@ -632,7 +631,6 @@ static MACHINE_CONFIG_START( dbox )
MCFG_RS232_RXD_HANDLER (DEVWRITELINE (":maincpu:serial", m68340_serial, rx_a_w))
MCFG_RS232_PORT_ADD (CHB, default_rs232_devices, "terminal")
MCFG_RS232_RXD_HANDLER (DEVWRITELINE (":maincpu:serial", m68340_serial, rx_b_w))
-#endif
/* Add the boot flash */
MCFG_AMD_29F800B_16BIT_ADD("flash")