mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
mb8421.cpp : Support variable size and data width, Use template for base device, Add notes (#5929)
* mb8421.cpp : Support variable size and data width, Reduce duplicate, Add notes twinkle.cpp, firebeat.cpp : Device-fied CY7C131 Dual port SRAM, Add notes esqmr.cpp : Add IDT7130 Dual port SRAM placeholder, Add notes * esqmr.cpp : Fix spacing * mb8421.cpp : Fix data width behavior * mb8421.cpp : Forgot this * mb8421.cpp : Fix spacing * mb8421.cpp : Use const in initializers, Fix class name related to support more similar DPRAMs in future , Add notes, Remove internal helpers * mb8421.cpp : Re-add masking * mb8421.cpp : Fix notes * mb8421.cpp : Fix manufacturer tags, Add notes * mb8421.cpp : Fix ram size argument behavior, Add notes * mb8421.cpp : Use template for base device, Fix build * mb8421.cpp : Use template and static constexprs for RAM defines * mb8421.cpp : Use extern template, Fix build, RAM size
This commit is contained in:
parent
fc0de7cfce
commit
ab67769285
@ -2,6 +2,8 @@
|
||||
// copyright-holders:hap,AJR
|
||||
/**********************************************************************
|
||||
|
||||
Dual port RAM with Mailbox emulation
|
||||
|
||||
Fujitsu MB8421/22/31/32-90/-90L/-90LL/-12/-12L/-12LL
|
||||
CMOS 16K-bit (2KB) dual-port SRAM
|
||||
|
||||
@ -10,192 +12,34 @@
|
||||
32-bit expansion. It makes sure there are no clashes with the _BUSY pin.
|
||||
|
||||
IDT71321 is function compatible, but not pin compatible with MB8421
|
||||
IDT7130 is 1KB variation of IDT71321
|
||||
CY7C131 is similar as IDT7130
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/mb8421.h"
|
||||
|
||||
template class dual_port_mailbox_ram_base<u8, 10, 8>;
|
||||
template class dual_port_mailbox_ram_base<u8, 11, 8>;
|
||||
template class dual_port_mailbox_ram_base<u16, 11, 16>;
|
||||
|
||||
DEFINE_DEVICE_TYPE(MB8421, mb8421_device, "mb8421", "MB8421 8-bit Dual-Port SRAM with Interrupts")
|
||||
DEFINE_DEVICE_TYPE(IDT71321, idt71321_device, "idt71321", "IDT71321 8-bit Dual-Port SRAM with Interrupts")
|
||||
DEFINE_DEVICE_TYPE(MB8421_MB8431_16BIT, mb8421_mb8431_16_device, "mb8421_mb8431_16", "MB8421/MB8431 16-bit Dual-Port SRAM with Interrupts")
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
constexpr Type dual_port_mailbox_ram_base<Type, AddrBits, DataBits>::DATA_MASK;
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
constexpr size_t dual_port_mailbox_ram_base<Type, AddrBits, DataBits>::RAM_SIZE;
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
constexpr offs_t dual_port_mailbox_ram_base<Type, AddrBits, DataBits>::ADDR_MASK;
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
constexpr offs_t dual_port_mailbox_ram_base<Type, AddrBits, DataBits>::INT_ADDR_LEFT;
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
constexpr offs_t dual_port_mailbox_ram_base<Type, AddrBits, DataBits>::INT_ADDR_RIGHT;
|
||||
|
||||
//-------------------------------------------------
|
||||
// mb8421_master_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mb8421_master_device::mb8421_master_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, m_intl_callback(*this)
|
||||
, m_intr_callback(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// mb8421_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mb8421_device::mb8421_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: mb8421_master_device(mconfig, MB8421, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
mb8421_device::mb8421_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||
: mb8421_master_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// idt71321_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
idt71321_device::idt71321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: mb8421_device(mconfig, IDT71321, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// mb8421_mb8431_16_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mb8421_mb8431_16_device::mb8421_mb8431_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: mb8421_master_device(mconfig, MB8421_MB8431_16BIT, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_resolve_objects - resolve objects that
|
||||
// may be needed for other devices to set
|
||||
// initial conditions at start time
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb8421_master_device::device_resolve_objects()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_intl_callback.resolve_safe();
|
||||
m_intr_callback.resolve_safe();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb8421_device::device_start()
|
||||
{
|
||||
m_ram = make_unique_clear<u8[]>(0x800);
|
||||
|
||||
// state save
|
||||
save_pointer(NAME(m_ram), 0x800);
|
||||
}
|
||||
|
||||
void mb8421_mb8431_16_device::device_start()
|
||||
{
|
||||
m_ram = make_unique_clear<u16[]>(0x800);
|
||||
|
||||
// state save
|
||||
save_pointer(NAME(m_ram), 0x800);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb8421_master_device::device_reset()
|
||||
{
|
||||
m_intl_callback(CLEAR_LINE);
|
||||
m_intr_callback(CLEAR_LINE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_intr - update interrupt lines upon
|
||||
// read or write accesses to special locations
|
||||
//-------------------------------------------------
|
||||
|
||||
template<read_or_write row, bool is_right>
|
||||
void mb8421_master_device::update_intr(offs_t offset)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
return;
|
||||
|
||||
if (row == read_or_write::WRITE && offset == (is_right ? 0x7fe : 0x7ff))
|
||||
(is_right ? m_intl_callback : m_intr_callback)(ASSERT_LINE);
|
||||
else if (row == read_or_write::READ && offset == (is_right ? 0x7ff : 0x7fe))
|
||||
(is_right ? m_intr_callback : m_intl_callback)(CLEAR_LINE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// left_w - write access for left-side bus
|
||||
// (write to 7FF asserts INTR)
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb8421_device::left_w(offs_t offset, u8 data)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
m_ram[offset] = data;
|
||||
update_intr<read_or_write::WRITE, false>(offset);
|
||||
}
|
||||
|
||||
void mb8421_mb8431_16_device::left_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
COMBINE_DATA(&m_ram[offset]);
|
||||
update_intr<read_or_write::WRITE, false>(offset);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// left_r - read access for left-side bus
|
||||
// (read from 7FE acknowledges INTL)
|
||||
//-------------------------------------------------
|
||||
|
||||
u8 mb8421_device::left_r(offs_t offset)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
update_intr<read_or_write::READ, false>(offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
u16 mb8421_mb8431_16_device::left_r(offs_t offset, u16 mem_mask)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
update_intr<read_or_write::READ, false>(offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// right_w - write access for right-side bus
|
||||
// (write to 7FE asserts INTL)
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb8421_device::right_w(offs_t offset, u8 data)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
m_ram[offset] = data;
|
||||
update_intr<read_or_write::WRITE, true>(offset);
|
||||
}
|
||||
|
||||
void mb8421_mb8431_16_device::right_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
COMBINE_DATA(&m_ram[offset]);
|
||||
update_intr<read_or_write::WRITE, true>(offset);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// right_r - read access for right-side bus
|
||||
// (read from 7FF acknowledges INTR)
|
||||
//-------------------------------------------------
|
||||
|
||||
u8 mb8421_device::right_r(offs_t offset)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
update_intr<read_or_write::READ, true>(offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
u16 mb8421_mb8431_16_device::right_r(offs_t offset, u16 mem_mask)
|
||||
{
|
||||
offset &= 0x7ff;
|
||||
update_intr<read_or_write::READ, true>(offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
// 1Kx8
|
||||
DEFINE_DEVICE_TYPE(CY7C131, cy7c131_device, "cy7c131", "Cypress CY7C131 8-bit Dual-Port SRAM with Interrupts")
|
||||
DEFINE_DEVICE_TYPE(IDT7130, idt7130_device, "idt7130", "IDT 7130 8-bit Dual-Port SRAM with Interrupts")
|
||||
// 2Kx8
|
||||
DEFINE_DEVICE_TYPE(IDT71321, idt71321_device, "idt71321", "IDT 71321 8-bit Dual-Port SRAM with Interrupts")
|
||||
DEFINE_DEVICE_TYPE(MB8421, mb8421_device, "mb8421", "Fujitsu MB8421 8-bit Dual-Port SRAM with Interrupts")
|
||||
// 2Kx16
|
||||
DEFINE_DEVICE_TYPE(MB8421_MB8431_16BIT, mb8421_mb8431_16_device, "mb8421_mb8431_16", "Fujitsu MB8421/MB8431 16-bit Dual-Port SRAM with Interrupts")
|
||||
|
@ -2,8 +2,13 @@
|
||||
// copyright-holders:hap,AJR
|
||||
/**********************************************************************
|
||||
|
||||
Dual port RAM with Mailbox emulation
|
||||
|
||||
Fujitsu MB8421/22/31/32-90/-90L/-90LL/-12/-12L/-12LL
|
||||
CMOS 16K-bit (2KB) dual-port SRAM
|
||||
CMOS 16K-bit (2KB) dual-port SRAM (pinouts : see below)
|
||||
IDT 71321 16K-bit (2Kx8) dual port SRAM
|
||||
IDT 7130 8K-bit (1Kx8) dual port SRAM
|
||||
Cypress CY7C131 8K-bit (1Kx8) dual port SRAM
|
||||
|
||||
***********************************************************************
|
||||
_____________
|
||||
@ -72,9 +77,17 @@
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> mb8421_device
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(CY7C131, cy7c131_device)
|
||||
DECLARE_DEVICE_TYPE(IDT7130, idt7130_device)
|
||||
DECLARE_DEVICE_TYPE(MB8421, mb8421_device)
|
||||
DECLARE_DEVICE_TYPE(IDT71321, idt71321_device)
|
||||
DECLARE_DEVICE_TYPE(MB8421_MB8431_16BIT, mb8421_mb8431_16_device)
|
||||
|
||||
class mb8421_master_device : public device_t
|
||||
// ======================> dual_port_mailbox_ram_base
|
||||
|
||||
template <typename Type, unsigned AddrBits, unsigned DataBits>
|
||||
class dual_port_mailbox_ram_base : public device_t
|
||||
{
|
||||
public:
|
||||
// note: INT pins are only available on MB84x1
|
||||
@ -82,80 +95,196 @@ public:
|
||||
auto intl_callback() { return m_intl_callback.bind(); }
|
||||
auto intr_callback() { return m_intr_callback.bind(); }
|
||||
|
||||
Type peek(offs_t offset) const { return m_ram[offset & ADDR_MASK]; }
|
||||
|
||||
//-------------------------------------------------
|
||||
// left_w - write access for left-side bus
|
||||
// (write to (max word size - 1) asserts INTR)
|
||||
//-------------------------------------------------
|
||||
|
||||
void left_w(offs_t offset, Type data, Type mem_mask = ~Type(0))
|
||||
{
|
||||
offset &= ADDR_MASK;
|
||||
data &= DATA_MASK;
|
||||
COMBINE_DATA(&m_ram[offset]);
|
||||
update_intr(read_or_write::WRITE, false, offset);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// left_r - read access for left-side bus
|
||||
// (read from (max word size - 2) acknowledges INTL)
|
||||
//-------------------------------------------------
|
||||
|
||||
Type left_r(offs_t offset)
|
||||
{
|
||||
offset &= ADDR_MASK;
|
||||
update_intr(read_or_write::READ, false, offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// right_w - write access for right-side bus
|
||||
// (write to (max word size - 2) asserts INTL)
|
||||
//-------------------------------------------------
|
||||
|
||||
void right_w(offs_t offset, Type data, Type mem_mask = ~Type(0))
|
||||
{
|
||||
offset &= ADDR_MASK;
|
||||
data &= DATA_MASK;
|
||||
COMBINE_DATA(&m_ram[offset]);
|
||||
update_intr(read_or_write::WRITE, true, offset);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// right_r - read access for right-side bus
|
||||
// (read from (max word size - 1) acknowledges INTR)
|
||||
//-------------------------------------------------
|
||||
|
||||
Type right_r(offs_t offset)
|
||||
{
|
||||
offset &= ADDR_MASK;
|
||||
update_intr(read_or_write::READ, true, offset);
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
DECLARE_READ_LINE_MEMBER(busy_r) { return 0; } // _BUSY pin - not emulated
|
||||
|
||||
protected:
|
||||
mb8421_master_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
dual_port_mailbox_ram_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, m_intl_callback(*this)
|
||||
, m_intr_callback(*this)
|
||||
, m_ram(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// internal helpers
|
||||
template<read_or_write row, bool is_right> void update_intr(offs_t offset);
|
||||
//-------------------------------------------------
|
||||
// device_resolve_objects - resolve objects that
|
||||
// may be needed for other devices to set
|
||||
// initial conditions at start time
|
||||
//-------------------------------------------------
|
||||
|
||||
virtual void device_resolve_objects() override
|
||||
{
|
||||
// resolve callbacks
|
||||
m_intl_callback.resolve_safe();
|
||||
m_intr_callback.resolve_safe();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
virtual void device_start() override
|
||||
{
|
||||
m_ram = make_unique_clear<Type[]>(RAM_SIZE);
|
||||
|
||||
// state save
|
||||
save_pointer(NAME(m_ram), RAM_SIZE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
virtual void device_reset() override
|
||||
{
|
||||
m_intl_callback(CLEAR_LINE);
|
||||
m_intr_callback(CLEAR_LINE);
|
||||
}
|
||||
|
||||
private:
|
||||
// internal helpers
|
||||
static constexpr Type DATA_MASK = make_bitmask<Type>(DataBits); // for DPRAMs with 9/18/36bit data buses
|
||||
static constexpr size_t RAM_SIZE = make_bitmask<size_t>(AddrBits) + 1; // max RAM word size
|
||||
static constexpr offs_t ADDR_MASK = RAM_SIZE - 1;
|
||||
static constexpr offs_t INT_ADDR_LEFT = ADDR_MASK - 1; // max RAM word size - 2
|
||||
static constexpr offs_t INT_ADDR_RIGHT = ADDR_MASK; // max RAM word size - 1
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_intr - update interrupt lines upon
|
||||
// read or write accesses to special locations
|
||||
//-------------------------------------------------
|
||||
|
||||
void update_intr(read_or_write row, bool is_right, offs_t offset)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
return;
|
||||
|
||||
if (row == read_or_write::WRITE && offset == (is_right ? INT_ADDR_LEFT : INT_ADDR_RIGHT))
|
||||
(is_right ? m_intl_callback : m_intr_callback)(ASSERT_LINE);
|
||||
else if (row == read_or_write::READ && offset == (is_right ? INT_ADDR_RIGHT : INT_ADDR_LEFT))
|
||||
(is_right ? m_intr_callback : m_intl_callback)(CLEAR_LINE);
|
||||
}
|
||||
|
||||
devcb_write_line m_intl_callback;
|
||||
devcb_write_line m_intr_callback;
|
||||
std::unique_ptr<Type[]> m_ram;
|
||||
};
|
||||
|
||||
// ======================> cy7c131_device
|
||||
|
||||
class cy7c131_device : public dual_port_mailbox_ram_base<u8, 10, 8>
|
||||
{
|
||||
public:
|
||||
cy7c131_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
|
||||
: dual_port_mailbox_ram_base<u8, 10, 8>(mconfig, CY7C131, tag, owner, clock) // 1kx8
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ======================> idt7130_device
|
||||
|
||||
class idt7130_device : public dual_port_mailbox_ram_base<u8, 10, 8>
|
||||
{
|
||||
public:
|
||||
idt7130_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
|
||||
: dual_port_mailbox_ram_base<u8, 10, 8>(mconfig, IDT7130, tag, owner, clock) // 1kx8
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ======================> idt71321_device
|
||||
|
||||
class idt71321_device : public dual_port_mailbox_ram_base<u8, 11, 8>
|
||||
{
|
||||
public:
|
||||
idt71321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
|
||||
: dual_port_mailbox_ram_base<u8, 11, 8>(mconfig, IDT71321, tag, owner, clock) // 2kx8
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ======================> mb8421_device
|
||||
|
||||
class mb8421_device : public mb8421_master_device
|
||||
class mb8421_device : public dual_port_mailbox_ram_base<u8, 11, 8>
|
||||
{
|
||||
public:
|
||||
mb8421_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
u8 peek(offs_t offset) const { return m_ram[offset & 0x7ff]; }
|
||||
|
||||
void left_w(offs_t offset, u8 data);
|
||||
u8 left_r(offs_t offset);
|
||||
void right_w(offs_t offset, u8 data);
|
||||
u8 right_r(offs_t offset);
|
||||
|
||||
protected:
|
||||
mb8421_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<u8[]> m_ram;
|
||||
};
|
||||
|
||||
// ======================> mb8421_device
|
||||
|
||||
class idt71321_device : public mb8421_device
|
||||
{
|
||||
public:
|
||||
idt71321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
mb8421_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
|
||||
: dual_port_mailbox_ram_base<u8, 11, 8>(mconfig, MB8421, tag, owner, clock) // 2kx8
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// ======================> mb8421_mb8431_16_device
|
||||
|
||||
class mb8421_mb8431_16_device : public mb8421_master_device
|
||||
class mb8421_mb8431_16_device : public dual_port_mailbox_ram_base<u16, 11, 16>
|
||||
{
|
||||
public:
|
||||
mb8421_mb8431_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
u16 peek(offs_t offset) const { return m_ram[offset & 0x7ff]; }
|
||||
|
||||
void left_w(offs_t offset, u16 data, u16 mem_mask = 0xffff);
|
||||
u16 left_r(offs_t offset, u16 mem_mask = 0xffff);
|
||||
void right_w(offs_t offset, u16 data, u16 mem_mask = 0xffff);
|
||||
u16 right_r(offs_t offset, u16 mem_mask = 0xffff);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<u16[]> m_ram;
|
||||
mb8421_mb8431_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0)
|
||||
: dual_port_mailbox_ram_base<u16, 11, 16>(mconfig, MB8421_MB8431_16BIT, tag, owner, clock) // 2kx16
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(MB8421, mb8421_device)
|
||||
DECLARE_DEVICE_TYPE(IDT71321, idt71321_device)
|
||||
DECLARE_DEVICE_TYPE(MB8421_MB8431_16BIT, mb8421_mb8431_16_device)
|
||||
//**************************************************************************
|
||||
// EXTERNAL TEMPLATE INSTANTIATIONS
|
||||
//**************************************************************************
|
||||
|
||||
extern template class dual_port_mailbox_ram_base<u8, 10, 8>;
|
||||
extern template class dual_port_mailbox_ram_base<u8, 11, 8>;
|
||||
extern template class dual_port_mailbox_ram_base<u16, 11, 16>;
|
||||
|
||||
#endif // MAME_MACHINE_MB8421_H
|
||||
|
@ -206,6 +206,7 @@
|
||||
#include "machine/68340ser.h"
|
||||
#include "sound/es5506.h"
|
||||
#include "machine/esqpanel.h"
|
||||
//#include "machine/mb8421.h"
|
||||
|
||||
#include "speaker.h"
|
||||
|
||||
@ -279,6 +280,8 @@ void esqmr_state::mr(machine_config &config)
|
||||
duart.a_tx_cb().set(FUNC(esqmr_state::duart_tx_a));
|
||||
duart.b_tx_cb().set(FUNC(esqmr_state::duart_tx_b));
|
||||
|
||||
//IDT7130(config, "dpram"); // present in PCB, but unknown purpose (mcu communication?)
|
||||
|
||||
ESQPANEL2X40_VFX(config, m_panel);
|
||||
m_panel->write_tx().set(duart, FUNC(mc68340_serial_module_device::rx_b_w));
|
||||
|
||||
|
@ -144,6 +144,7 @@ Keyboard Mania 2nd Mix - dongle, program CD, audio CD
|
||||
#include "cpu/powerpc/ppc.h"
|
||||
#include "machine/ins8250.h"
|
||||
#include "machine/intelfsh.h"
|
||||
#include "machine/mb8421.h"
|
||||
#include "machine/midikbd.h"
|
||||
#include "machine/rtc65271.h"
|
||||
#include "machine/timer.h"
|
||||
@ -172,7 +173,7 @@ struct IBUTTON
|
||||
};
|
||||
|
||||
|
||||
#define PRINT_SPU_MEM 0
|
||||
//#define PRINT_SPU_MEM 0
|
||||
|
||||
class firebeat_state : public driver_device
|
||||
{
|
||||
@ -187,6 +188,7 @@ public:
|
||||
m_kbd(*this, "kbd%u", 0),
|
||||
m_ata(*this, "ata"),
|
||||
m_gcu(*this, "gcu%u", 0),
|
||||
m_dpram(*this, "spuram"),
|
||||
m_spuata(*this, "spu_ata")
|
||||
{ }
|
||||
|
||||
@ -207,6 +209,7 @@ private:
|
||||
optional_device_array<midi_keyboard_device, 2> m_kbd;
|
||||
required_device<ata_interface_device> m_ata;
|
||||
optional_device_array<k057714_device, 2> m_gcu;
|
||||
optional_device<cy7c131_device> m_dpram;
|
||||
optional_device<ata_interface_device> m_spuata;
|
||||
|
||||
uint8_t m_extend_board_irq_enable;
|
||||
@ -216,7 +219,6 @@ private:
|
||||
int m_cab_data_ptr;
|
||||
const int * m_cur_cab_data;
|
||||
// int m_keyboard_state[2];
|
||||
uint8_t m_spu_shared_ram[0x400];
|
||||
IBUTTON m_ibutton;
|
||||
int m_ibutton_state;
|
||||
int m_ibutton_read_subkey_ptr;
|
||||
@ -250,14 +252,10 @@ private:
|
||||
DECLARE_WRITE32_MEMBER(lamp_output2_ppp_w);
|
||||
DECLARE_WRITE32_MEMBER(lamp_output3_w);
|
||||
DECLARE_WRITE32_MEMBER(lamp_output3_ppp_w);
|
||||
DECLARE_READ32_MEMBER(ppc_spu_share_r);
|
||||
DECLARE_WRITE32_MEMBER(ppc_spu_share_w);
|
||||
DECLARE_READ16_MEMBER(spu_unk_r);
|
||||
DECLARE_WRITE16_MEMBER(spu_irq_ack_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_220000_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_sdram_bank_w);
|
||||
DECLARE_READ16_MEMBER(m68k_spu_share_r);
|
||||
DECLARE_WRITE16_MEMBER(m68k_spu_share_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(spu_ata_interrupt);
|
||||
// TIMER_CALLBACK_MEMBER(keyboard_timer_callback);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(spu_timer_callback);
|
||||
@ -274,6 +272,7 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER(gcu1_interrupt);
|
||||
static void cdrom_config(device_t *device);
|
||||
void firebeat_map(address_map &map);
|
||||
void firebeat_spu_map(address_map &map);
|
||||
void firebeat2_map(address_map &map);
|
||||
void spu_map(address_map &map);
|
||||
void ymz280b_map(address_map &map);
|
||||
@ -765,76 +764,6 @@ WRITE32_MEMBER(firebeat_state::lamp_output3_ppp_w )
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
READ32_MEMBER(firebeat_state::ppc_spu_share_r)
|
||||
{
|
||||
uint32_t r = 0;
|
||||
|
||||
#if PRINT_SPU_MEM
|
||||
printf("ppc_spu_share_r: %08X, %08X at %08X\n", offset, mem_mask, m_maincpu->pc());
|
||||
#endif
|
||||
|
||||
if (ACCESSING_BITS_24_31)
|
||||
{
|
||||
r |= m_spu_shared_ram[(offset * 4) + 0] << 24;
|
||||
}
|
||||
if (ACCESSING_BITS_16_23)
|
||||
{
|
||||
r |= m_spu_shared_ram[(offset * 4) + 1] << 16;
|
||||
}
|
||||
if (ACCESSING_BITS_8_15)
|
||||
{
|
||||
r |= m_spu_shared_ram[(offset * 4) + 2] << 8;
|
||||
}
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
r |= m_spu_shared_ram[(offset * 4) + 3] << 0;
|
||||
|
||||
if (offset == 0xff) // address 0x3ff clears PPC interrupt
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ3, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(firebeat_state::ppc_spu_share_w)
|
||||
{
|
||||
#if PRINT_SPU_MEM
|
||||
printf("ppc_spu_share_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_maincpu->pc());
|
||||
#endif
|
||||
|
||||
if (ACCESSING_BITS_24_31)
|
||||
{
|
||||
m_spu_shared_ram[(offset * 4) + 0] = (data >> 24) & 0xff;
|
||||
}
|
||||
if (ACCESSING_BITS_16_23)
|
||||
{
|
||||
m_spu_shared_ram[(offset * 4) + 1] = (data >> 16) & 0xff;
|
||||
}
|
||||
if (ACCESSING_BITS_8_15)
|
||||
{
|
||||
m_spu_shared_ram[(offset * 4) + 2] = (data >> 8) & 0xff;
|
||||
|
||||
if (offset == 0xff) // address 0x3fe triggers M68K interrupt
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_IRQ4, ASSERT_LINE);
|
||||
|
||||
printf("SPU command %02X%02X\n", m_spu_shared_ram[0], m_spu_shared_ram[1]);
|
||||
|
||||
uint16_t cmd = ((uint16_t)(m_spu_shared_ram[0]) << 8) | m_spu_shared_ram[1];
|
||||
if (cmd == 0x1110)
|
||||
{
|
||||
printf(" [%02X %02X %02X %02X %02X]\n", m_spu_shared_ram[0x10], m_spu_shared_ram[0x11], m_spu_shared_ram[0x12], m_spu_shared_ram[0x13], m_spu_shared_ram[0x14]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
m_spu_shared_ram[(offset * 4) + 3] = (data >> 0) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* SPU board M68K IRQs
|
||||
|
||||
IRQ1: ?
|
||||
@ -847,41 +776,6 @@ WRITE32_MEMBER(firebeat_state::ppc_spu_share_w)
|
||||
IRQ6: ATA
|
||||
*/
|
||||
|
||||
READ16_MEMBER(firebeat_state::m68k_spu_share_r)
|
||||
{
|
||||
#if PRINT_SPU_MEM
|
||||
printf("m68k_spu_share_r: %08X, %08X\n", offset, mem_mask);
|
||||
#endif
|
||||
uint16_t r = 0;
|
||||
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
r |= m_spu_shared_ram[offset];
|
||||
|
||||
if (offset == 0x3fe) // address 0x3fe clears M68K interrupt
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_IRQ4, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(firebeat_state::m68k_spu_share_w)
|
||||
{
|
||||
#if PRINT_SPU_MEM
|
||||
printf("m68k_spu_share_w: %04X, %08X, %08X\n", data, offset, mem_mask);
|
||||
#endif
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
m_spu_shared_ram[offset] = data & 0xff;
|
||||
|
||||
if (offset == 0x3ff) // address 0x3ff triggers PPC interrupt
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ3, ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ16_MEMBER(firebeat_state::spu_unk_r)
|
||||
{
|
||||
// dipswitches?
|
||||
@ -943,7 +837,7 @@ void firebeat_state::firebeat_map(address_map &map)
|
||||
map(0x70006000, 0x70006003).w(FUNC(firebeat_state::extend_board_irq_w));
|
||||
map(0x70008000, 0x7000800f).r(FUNC(firebeat_state::keyboard_wheel_r));
|
||||
map(0x7000a000, 0x7000a003).r(FUNC(firebeat_state::extend_board_irq_r));
|
||||
map(0x74000000, 0x740003ff).rw(FUNC(firebeat_state::ppc_spu_share_r), FUNC(firebeat_state::ppc_spu_share_w)); // SPU shared RAM
|
||||
map(0x74000000, 0x740003ff).noprw(); // SPU shared RAM
|
||||
map(0x7d000200, 0x7d00021f).r(FUNC(firebeat_state::cabinet_r));
|
||||
map(0x7d000340, 0x7d000347).r(FUNC(firebeat_state::sensor_r));
|
||||
map(0x7d000400, 0x7d000401).rw("ymz", FUNC(ymz280b_device::read), FUNC(ymz280b_device::write));
|
||||
@ -960,6 +854,12 @@ void firebeat_state::firebeat_map(address_map &map)
|
||||
map(0x7ff80000, 0x7fffffff).rom().region("user1", 0); /* System BIOS */
|
||||
}
|
||||
|
||||
void firebeat_state::firebeat_spu_map(address_map &map)
|
||||
{
|
||||
firebeat_map(map);
|
||||
map(0x74000000, 0x740003ff).rw(m_dpram, FUNC(cy7c131_device::right_r), FUNC(cy7c131_device::right_w)); // SPU shared RAM
|
||||
}
|
||||
|
||||
void firebeat_state::firebeat2_map(address_map &map)
|
||||
{
|
||||
firebeat_map(map);
|
||||
@ -974,7 +874,7 @@ void firebeat_state::spu_map(address_map &map)
|
||||
map(0x220000, 0x220001).w(FUNC(firebeat_state::spu_220000_w));
|
||||
map(0x230000, 0x230001).w(FUNC(firebeat_state::spu_irq_ack_w));
|
||||
map(0x260000, 0x260001).w(FUNC(firebeat_state::spu_sdram_bank_w));
|
||||
map(0x280000, 0x2807ff).rw(FUNC(firebeat_state::m68k_spu_share_r), FUNC(firebeat_state::m68k_spu_share_w));
|
||||
map(0x280000, 0x2807ff).rw(m_dpram, FUNC(cy7c131_device::left_r), FUNC(cy7c131_device::left_w)).umask16(0x00ff);
|
||||
map(0x300000, 0x30000f).rw(m_spuata, FUNC(ata_interface_device::cs0_r), FUNC(ata_interface_device::cs0_w));
|
||||
map(0x340000, 0x34000f).rw(m_spuata, FUNC(ata_interface_device::cs1_r), FUNC(ata_interface_device::cs1_w));
|
||||
map(0x400000, 0x400fff).rw("rf5c400", FUNC(rf5c400_device::rf5c400_r), FUNC(rf5c400_device::rf5c400_w));
|
||||
@ -1306,9 +1206,15 @@ void firebeat_state::firebeat_spu(machine_config &config)
|
||||
firebeat(config);
|
||||
|
||||
/* basic machine hardware */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &firebeat_state::firebeat_spu_map);
|
||||
|
||||
M68000(config, m_audiocpu, 16000000);
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &firebeat_state::spu_map);
|
||||
|
||||
CY7C131(config, m_dpram);
|
||||
m_dpram->intl_callback().set_inputline(m_audiocpu, INPUT_LINE_IRQ4); // address 0x3fe triggers M68K interrupt
|
||||
m_dpram->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ3); // address 0x3ff triggers PPC interrupt
|
||||
|
||||
TIMER(config, "sputimer").configure_periodic(FUNC(firebeat_state::spu_timer_callback), attotime::from_hz(1000));
|
||||
|
||||
rf5c400_device &rf5c400(RF5C400(config, "rf5c400", XTAL(16'934'400)));
|
||||
|
@ -245,6 +245,7 @@ Notes:
|
||||
#include "machine/am53cf96.h"
|
||||
#include "machine/fdc37c665gt.h"
|
||||
#include "machine/i2cmem.h"
|
||||
#include "machine/mb8421.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/rtc65271.h"
|
||||
#include "machine/watchdog.h"
|
||||
@ -266,6 +267,7 @@ public:
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_am53cf96(*this, "am53cf96"),
|
||||
m_ata(*this, "ata"),
|
||||
m_dpram(*this, "dpram"),
|
||||
m_waveram(*this, "rfsnd"),
|
||||
m_led_displays(*this, "led%u", 0U),
|
||||
m_spotlights(*this, "spotlight%u", 0U),
|
||||
@ -291,15 +293,11 @@ private:
|
||||
DECLARE_WRITE16_MEMBER(led_w);
|
||||
DECLARE_WRITE16_MEMBER(key_led_w);
|
||||
DECLARE_WRITE16_MEMBER(serial_w);
|
||||
DECLARE_WRITE8_MEMBER(shared_psx_w);
|
||||
DECLARE_READ8_MEMBER(shared_psx_r);
|
||||
DECLARE_WRITE16_MEMBER(twinkle_spu_ctrl_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_ata_dma_low_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_ata_dma_high_w);
|
||||
DECLARE_READ16_MEMBER(twinkle_waveram_r);
|
||||
DECLARE_WRITE16_MEMBER(twinkle_waveram_w);
|
||||
DECLARE_READ16_MEMBER(shared_68k_r);
|
||||
DECLARE_WRITE16_MEMBER(shared_68k_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_led_w);
|
||||
DECLARE_WRITE16_MEMBER(spu_wavebank_w);
|
||||
DECLARE_READ16_MEMBER(unk_68k_r);
|
||||
@ -316,6 +314,7 @@ private:
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<am53cf96_device> m_am53cf96;
|
||||
required_device<ata_interface_device> m_ata;
|
||||
required_device<cy7c131_device> m_dpram;
|
||||
required_shared_ptr<uint16_t> m_waveram;
|
||||
|
||||
output_finder<9> m_led_displays;
|
||||
@ -325,7 +324,6 @@ private:
|
||||
output_finder<8> m_spu_leds;
|
||||
|
||||
uint16_t m_spu_ctrl; // SPU board control register
|
||||
uint8_t m_spu_shared[0x400]; // SPU/PSX shared dual-ported RAM
|
||||
uint32_t m_spu_ata_dma;
|
||||
int m_spu_ata_dmarq;
|
||||
uint32_t m_wave_bank;
|
||||
@ -520,7 +518,6 @@ void twinkle_state::machine_start()
|
||||
m_spu_leds.resolve();
|
||||
|
||||
save_item(NAME(m_spu_ctrl));
|
||||
save_item(NAME(m_spu_shared));
|
||||
save_item(NAME(m_spu_ata_dma));
|
||||
save_item(NAME(m_spu_ata_dmarq));
|
||||
save_item(NAME(m_wave_bank));
|
||||
@ -798,32 +795,9 @@ WRITE16_MEMBER(twinkle_state::serial_w)
|
||||
m_serial_clock = clock;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(twinkle_state::shared_psx_w)
|
||||
{
|
||||
// printf("shared_psx_w: %04x, %04x, %04x\n", offset, data, mem_mask);
|
||||
|
||||
m_spu_shared[offset] = data;
|
||||
|
||||
if (offset == 0x03fe && data == 0xff)
|
||||
{
|
||||
// printf("spu command %02x %02x\n", m_spu_shared[1], m_spu_shared[3]);
|
||||
|
||||
m_audiocpu->set_input_line(M68K_IRQ_4, HOLD_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(twinkle_state::shared_psx_r)
|
||||
{
|
||||
uint32_t result = m_spu_shared[offset];
|
||||
|
||||
//printf("shared_psx_r: %04x, %04x, %04x\n", offset, result, mem_mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void twinkle_state::main_map(address_map &map)
|
||||
{
|
||||
map(0x1f000000, 0x1f0007ff).rw(FUNC(twinkle_state::shared_psx_r), FUNC(twinkle_state::shared_psx_w)).umask32(0x00ff00ff);
|
||||
map(0x1f000000, 0x1f0007ff).rw(m_dpram, FUNC(cy7c131_device::right_r), FUNC(cy7c131_device::right_w)).umask32(0x00ff00ff);
|
||||
map(0x1f200000, 0x1f20001f).rw(m_am53cf96, FUNC(am53cf96_device::read), FUNC(am53cf96_device::write)).umask32(0x00ff00ff);
|
||||
map(0x1f20a01c, 0x1f20a01f).nopw(); /* scsi? */
|
||||
map(0x1f210000, 0x1f2107ff).rw("fdc37c665gt", FUNC(fdc37c665gt_device::read), FUNC(fdc37c665gt_device::write)).umask32(0x00ff00ff);
|
||||
@ -942,22 +916,6 @@ WRITE16_MEMBER(twinkle_state::twinkle_waveram_w)
|
||||
COMBINE_DATA(&m_waveram[offset+m_wave_bank]);
|
||||
}
|
||||
|
||||
READ16_MEMBER(twinkle_state::shared_68k_r)
|
||||
{
|
||||
uint16_t result = m_spu_shared[offset];
|
||||
|
||||
// printf("shared_68k_r: %04x, %04x, %04x\n", offset, result, mem_mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twinkle_state::shared_68k_w)
|
||||
{
|
||||
// printf("shared_68k_w: %04x, %04x, %04x\n", offset, data, mem_mask);
|
||||
|
||||
m_spu_shared[offset] = data & 0xff;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(twinkle_state::spu_led_w)
|
||||
{
|
||||
// upper 8 bits are occassionally written as all zeros
|
||||
@ -981,7 +939,7 @@ void twinkle_state::sound_map(address_map &map)
|
||||
map(0x240000, 0x240003).w(FUNC(twinkle_state::spu_ata_dma_low_w)).nopr();
|
||||
map(0x250000, 0x250003).w(FUNC(twinkle_state::spu_ata_dma_high_w)).nopr();
|
||||
map(0x260000, 0x260001).w(FUNC(twinkle_state::spu_wavebank_w)).nopr();
|
||||
map(0x280000, 0x280fff).rw(FUNC(twinkle_state::shared_68k_r), FUNC(twinkle_state::shared_68k_w));
|
||||
map(0x280000, 0x2807ff).rw(m_dpram, FUNC(cy7c131_device::left_r), FUNC(cy7c131_device::left_w)).umask16(0x00ff);
|
||||
map(0x300000, 0x30000f).rw(m_ata, FUNC(ata_interface_device::cs0_r), FUNC(ata_interface_device::cs0_w));
|
||||
// 34000E = ???
|
||||
map(0x34000e, 0x34000f).nopw();
|
||||
@ -1095,6 +1053,9 @@ void twinkle_state::twinkle(machine_config &config)
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog").set_time(attotime::from_msec(1200)); /* check TD pin on LTC1232 */
|
||||
|
||||
CY7C131(config, m_dpram); // or IDT7130 at some PCBs
|
||||
m_dpram->intl_callback().set_inputline(m_audiocpu, M68K_IRQ_4);
|
||||
|
||||
scsi_port_device &scsi(SCSI_PORT(config, "scsi", 0));
|
||||
scsi.set_slot_device(1, "cdrom", SCSICD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4));
|
||||
scsi.slot(1).set_option_machine_config("cdrom", cdrom_config);
|
||||
|
Loading…
Reference in New Issue
Block a user