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:
cam900 2019-11-21 00:59:18 +09:00 committed by Vas Crabb
parent fc0de7cfce
commit ab67769285
5 changed files with 238 additions and 395 deletions

View File

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

View File

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

View File

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

View File

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

View File

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