mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
68340: deskeletonized the serial module as a device derived from the duart device defined in mc68681.cpp
This commit is contained in:
parent
1e4b7bea34
commit
5f7f9c4933
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user