sc3000: Added support for the SC-3000 Survivors Multicart and Megacart cartridges.

This commit is contained in:
Nigel Barnes 2019-01-20 11:24:51 +00:00
parent 49a2eb1c86
commit d47d3ca4f7
5 changed files with 207 additions and 4 deletions

View File

@ -42,6 +42,9 @@ DEFINE_DEVICE_TYPE(SEGA8_ROM_KOREAN, sega8_korean_device, "sega8_kor
DEFINE_DEVICE_TYPE(SEGA8_ROM_KOREAN_NB, sega8_korean_nb_device, "sega8_korean_nb", "SMS Korean No-Bank Mapper Carts")
DEFINE_DEVICE_TYPE(SEGA8_ROM_SEOJIN, sega8_seojin_device, "sega8_seojin", "SMS Seo Jin Multi-cart")
// Specific SC-3000 cart types
DEFINE_DEVICE_TYPE(SEGA8_ROM_MULTICART, sega8_multicart_device, "sega8_multicart", "SC-3000 MkII Multicart Cart")
DEFINE_DEVICE_TYPE(SEGA8_ROM_MEGACART, sega8_megacart_device, "sega8_megacart", "SC-3000 Megacart Cart")
sega8_rom_device::sega8_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
@ -185,6 +188,18 @@ sega8_seojin_device::sega8_seojin_device(const machine_config &mconfig, const ch
}
sega8_multicart_device::sega8_multicart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sega8_rom_device(mconfig, SEGA8_ROM_MULTICART, tag, owner, clock)
{
}
sega8_megacart_device::sega8_megacart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sega8_rom_device(mconfig, SEGA8_ROM_MEGACART, tag, owner, clock)
{
}
void sega8_rom_device::device_start()
{
save_item(NAME(m_rom_bank_base));
@ -268,6 +283,28 @@ void sega8_zemina_device::device_reset()
}
void sega8_multicart_device::device_start()
{
save_item(NAME(m_block));
}
void sega8_multicart_device::device_reset()
{
m_block = 0xff;
}
void sega8_megacart_device::device_start()
{
save_item(NAME(m_block));
}
void sega8_megacart_device::device_reset()
{
m_block = 0xff;
}
// initial bank setup needs to know how many 16K banks are available, so it needs to be called during cart loading...
void sega8_rom_device::late_bank_setup()
@ -1023,3 +1060,78 @@ READ8_MEMBER(sega8_seojin_device::read_ram)
return m_ram[offset & 0x3fff];
}
/*-------------------------------------------------
SC-3000 Survivors MkII Multicart
-------------------------------------------------*/
READ8_MEMBER(sega8_multicart_device::read_cart)
{
// 16K of RAM sits in 0x8000-0xbfff
if (offset >= 0x8000)
return m_ram[offset & 0x3fff];
return m_rom[(offset & 0x7fff) | (m_block << 15) % m_rom_size];
}
WRITE8_MEMBER(sega8_multicart_device::write_cart)
{
// 16K of RAM sits in 0x8000-0xbfff
if (offset >= 0x8000)
m_ram[offset & 0x3fff] = data;
}
READ8_MEMBER(sega8_multicart_device::read_ram)
{
return m_ram[0x4000 + (offset & 0x3fff)];
}
WRITE8_MEMBER(sega8_multicart_device::write_ram)
{
m_ram[0x4000 + (offset & 0x3fff)] = data;
}
WRITE8_MEMBER(sega8_multicart_device::write_io)
{
if ((offset & 0xe0) == 0xe0)
m_block = (data & 0x80) ? ((data & 0x1f) | ((data & 0x40) ? 0x20 : 0x00)) : 0x3f;
}
/*-------------------------------------------------
SC-3000 Survivors Megacart
-------------------------------------------------*/
READ8_MEMBER(sega8_megacart_device::read_cart)
{
// 16K of RAM sits in 0x8000-0xbfff
if (offset >= 0x8000)
return m_ram[offset & 0x3fff];
return m_rom[(offset & 0x7fff) | (m_block << 15) % m_rom_size];
}
WRITE8_MEMBER(sega8_megacart_device::write_cart)
{
// 16K of RAM sits in 0x8000-0xbfff
if (offset >= 0x8000)
m_ram[offset & 0x3fff] = data;
}
READ8_MEMBER(sega8_megacart_device::read_ram)
{
return m_ram[0x4000 + (offset & 0x3fff)];
}
WRITE8_MEMBER(sega8_megacart_device::write_ram)
{
m_ram[0x4000 + (offset & 0x3fff)] = data;
}
WRITE8_MEMBER(sega8_megacart_device::write_io)
{
if ((offset & 0xe0) == 0xe0)
m_block = (data & 0x1f) | (data & 0xc0) >> 1;
}

View File

@ -397,6 +397,60 @@ protected:
};
// ======================> sega8_multicart_device
class sega8_multicart_device : public sega8_rom_device
{
public:
// construction/destruction
sega8_multicart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart) override;
virtual DECLARE_WRITE8_MEMBER(write_cart) override;
virtual DECLARE_WRITE8_MEMBER(write_io) override;
// has internal RAM which overwrites the system one!
virtual DECLARE_READ8_MEMBER(read_ram) override;
virtual DECLARE_WRITE8_MEMBER(write_ram) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
uint8_t m_block;
};
// ======================> sega8_megacart_device
class sega8_megacart_device : public sega8_rom_device
{
public:
// construction/destruction
sega8_megacart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart) override;
virtual DECLARE_WRITE8_MEMBER(write_cart) override;
virtual DECLARE_WRITE8_MEMBER(write_io) override;
// has internal RAM which overwrites the system one!
virtual DECLARE_READ8_MEMBER(read_ram) override;
virtual DECLARE_WRITE8_MEMBER(write_ram) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
uint8_t m_block;
};
// device type definition
DECLARE_DEVICE_TYPE(SEGA8_ROM_STD, sega8_rom_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_OTHELLO, sega8_othello_device)
@ -416,5 +470,7 @@ DECLARE_DEVICE_TYPE(SEGA8_ROM_HICOM, sega8_hicom_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_KOREAN, sega8_korean_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_KOREAN_NB, sega8_korean_nb_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_SEOJIN, sega8_seojin_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_MULTICART, sega8_multicart_device)
DECLARE_DEVICE_TYPE(SEGA8_ROM_MEGACART, sega8_megacart_device)
#endif // MAME_BUS_SEGA8_ROM_H

View File

@ -178,7 +178,9 @@ static const sega8_slot slot_list[] =
{ SEGA8_MUSIC_EDITOR, "music_editor" },
{ SEGA8_DAHJEE_TYPEA, "dahjee_typea" },
{ SEGA8_DAHJEE_TYPEB, "dahjee_typeb" },
{ SEGA8_SEOJIN, "seojin" }
{ SEGA8_SEOJIN, "seojin" },
{ SEGA8_MULTICART, "multicart" },
{ SEGA8_MEGACART, "megacart" }
};
static int sega8_get_pcb_id(const char *slot)
@ -277,7 +279,7 @@ void sega8_cart_slot_device::setup_ram()
m_cart->ram_alloc(0x800);
m_cart->set_has_battery(false);
}
else if (m_type == SEGA8_BASIC_L3)
else if (m_type == SEGA8_BASIC_L3 || m_type == SEGA8_MULTICART || m_type == SEGA8_MEGACART)
{
m_cart->ram_alloc(0x8000);
m_cart->set_has_battery(false);
@ -584,6 +586,14 @@ int sega8_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len) cons
type = SEGA8_MUSIC_EDITOR;
}
// SC-3000 Survivors Multicart
if (len == 0x200000)
type = SEGA8_MULTICART;
// SC-3000 Survivors Megacart
if (len == 0x400000)
type = SEGA8_MEGACART;
return type;
}
@ -638,6 +648,14 @@ READ8_MEMBER(sega8_cart_slot_device::read_ram)
return 0xff;
}
READ8_MEMBER(sega8_cart_slot_device::read_io)
{
if (m_cart)
return m_cart->read_io(space, offset);
else
return 0xff;
}
/*-------------------------------------------------
write
@ -661,6 +679,12 @@ WRITE8_MEMBER(sega8_cart_slot_device::write_ram)
m_cart->write_ram(space, offset, data);
}
WRITE8_MEMBER(sega8_cart_slot_device::write_io)
{
if (m_cart)
m_cart->write_io(space, offset, data);
}
/*-------------------------------------------------
Internal header logging
@ -817,6 +841,8 @@ void sg1000_cart(device_slot_interface &device)
device.option_add_internal("dahjee_typea", SEGA8_ROM_DAHJEE_TYPEA);
device.option_add_internal("dahjee_typeb", SEGA8_ROM_DAHJEE_TYPEB);
device.option_add_internal("cardcatcher", SEGA8_ROM_CARDCATCH);
device.option_add_internal("multicart", SEGA8_ROM_MULTICART);
device.option_add_internal("megacart", SEGA8_ROM_MEGACART);
}
void sg1000mk3_cart(device_slot_interface &device)

View File

@ -32,7 +32,9 @@ enum
SEGA8_MUSIC_EDITOR,
SEGA8_DAHJEE_TYPEA,
SEGA8_DAHJEE_TYPEB,
SEGA8_SEOJIN
SEGA8_SEOJIN,
SEGA8_MULTICART,
SEGA8_MEGACART
};
@ -56,6 +58,9 @@ public:
// a few carts (for SG1000) acts as a RAM expansion, taking control of the system RAM in 0xc000-0xffff
virtual DECLARE_READ8_MEMBER(read_ram) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(write_ram) { }
// the SC3000 has I/OR, I/OW lines connected
virtual DECLARE_READ8_MEMBER(read_io) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(write_io) { }
void rom_alloc(uint32_t size, const char *tag);
void ram_alloc(uint32_t size);
@ -148,6 +153,8 @@ public:
virtual DECLARE_WRITE8_MEMBER(write_mapper);
virtual DECLARE_READ8_MEMBER(read_ram);
virtual DECLARE_WRITE8_MEMBER(write_ram);
virtual DECLARE_READ8_MEMBER(read_io);
virtual DECLARE_WRITE8_MEMBER(write_io);
int get_lphaser_xoffs() { return m_cart ? m_cart->get_lphaser_xoffs() : -1; }
int get_sms_mode() { return m_cart->get_sms_mode(); }

View File

@ -187,6 +187,7 @@ void sg1000_state::sc3000_map(address_map &map)
void sg1000_state::sc3000_io_map(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0xff).rw(CARTSLOT_TAG, FUNC(sega8_cart_slot_device::read_io), FUNC(sega8_cart_slot_device::write_io));
map(0x7f, 0x7f).w(SN76489AN_TAG, FUNC(sn76489a_device::command_w));
map(0xbe, 0xbe).rw(TMS9918A_TAG, FUNC(tms9918a_device::vram_r), FUNC(tms9918a_device::vram_w));
map(0xbf, 0xbf).rw(TMS9918A_TAG, FUNC(tms9918a_device::register_r), FUNC(tms9918a_device::register_w));
@ -485,7 +486,8 @@ void sc3000_state::machine_start()
timer_set(attotime::zero, TIMER_LIGHTGUN_TICK);
if (m_cart && m_cart->exists() && (m_cart->get_type() == SEGA8_BASIC_L3 || m_cart->get_type() == SEGA8_MUSIC_EDITOR
|| m_cart->get_type() == SEGA8_DAHJEE_TYPEA || m_cart->get_type() == SEGA8_DAHJEE_TYPEB))
|| m_cart->get_type() == SEGA8_DAHJEE_TYPEA || m_cart->get_type() == SEGA8_DAHJEE_TYPEB
|| m_cart->get_type() == SEGA8_MULTICART || m_cart->get_type() == SEGA8_MEGACART))
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0xc000, 0xffff, read8_delegate(FUNC(sega8_cart_slot_device::read_ram),(sega8_cart_slot_device*)m_cart));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xc000, 0xffff, write8_delegate(FUNC(sega8_cart_slot_device::write_ram),(sega8_cart_slot_device*)m_cart));