mirror of
https://github.com/holub/mame
synced 2025-05-03 13:06:47 +03:00
Merge pull request #2628 from JoakimLarsson/m68340_5
Improved 68340, 68681 and dbox support
This commit is contained in:
commit
3832af3948
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user