Merge pull request #2628 from JoakimLarsson/m68340_5

Improved 68340, 68681 and dbox support
This commit is contained in:
R. Belmont 2017-09-05 16:49:58 -04:00 committed by GitHub
commit 3832af3948
10 changed files with 356 additions and 55 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;
int pc = space.device().safe_pc();
logerror("%08x m68340_internal_serial_r %08x, (%08x)\n", pc, offset*4,mem_mask);
return 0x00000000;
m_cpu = downcast<m68340_cpu_device *>(owner());
m68340_serial_device::device_start();
}
WRITE32_MEMBER( m68340_cpu_device::m68340_internal_serial_w )
READ8_MEMBER( m68340_serial::read )
{
assert(m68340SERIAL);
//m68340_serial &serial = *m68340SERIAL;
LOG("%s\n", FUNCNAME);
int val = 0;
int pc = space.device().safe_pc();
logerror("%08x m68340_internal_serial_w %08x, %08x (%08x)\n", pc, offset*4,data,mem_mask);
LOGR("%08x %s %08x, (%08x)\n", space.device().safe_pc(), FUNCNAME, offset, 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
}
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;
}
void m68340_serial::reset()
WRITE8_MEMBER( m68340_serial::write )
{
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);
}
}
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")

View File

@ -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

View File

@ -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]);

View File

@ -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()

View File

@ -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,
};

View File

@ -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;

View File

@ -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

View File

@ -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")