mirror of
https://github.com/holub/mame
synced 2025-05-03 21:13:18 +03:00
(MESS) sms: added backward compatibility to SG-1000 Mark III, for SG-1000 games. [Fabio Priuli]
Only supported from fullpath for the moment
This commit is contained in:
parent
5ed2398162
commit
5b3ba478c9
@ -540,6 +540,17 @@ static const sn76496_config psg_intf =
|
|||||||
|
|
||||||
|
|
||||||
static SLOT_INTERFACE_START(sms_cart)
|
static SLOT_INTERFACE_START(sms_cart)
|
||||||
|
SLOT_INTERFACE_INTERNAL("rom", SEGA8_ROM_STD)
|
||||||
|
SLOT_INTERFACE_INTERNAL("codemasters", SEGA8_ROM_CODEMASTERS)
|
||||||
|
SLOT_INTERFACE_INTERNAL("4pak", SEGA8_ROM_4PAK)
|
||||||
|
SLOT_INTERFACE_INTERNAL("zemina", SEGA8_ROM_ZEMINA)
|
||||||
|
SLOT_INTERFACE_INTERNAL("nemesis", SEGA8_ROM_NEMESIS)
|
||||||
|
SLOT_INTERFACE_INTERNAL("janggun", SEGA8_ROM_JANGGUN)
|
||||||
|
SLOT_INTERFACE_INTERNAL("korean", SEGA8_ROM_KOREAN)
|
||||||
|
SLOT_INTERFACE_INTERNAL("korean_nb", SEGA8_ROM_KOREAN_NB)
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
|
static SLOT_INTERFACE_START(sg1000mk3_cart)
|
||||||
SLOT_INTERFACE_INTERNAL("rom", SEGA8_ROM_STD)
|
SLOT_INTERFACE_INTERNAL("rom", SEGA8_ROM_STD)
|
||||||
SLOT_INTERFACE_INTERNAL("terebi", SEGA8_ROM_TEREBI)
|
SLOT_INTERFACE_INTERNAL("terebi", SEGA8_ROM_TEREBI)
|
||||||
SLOT_INTERFACE_INTERNAL("codemasters", SEGA8_ROM_CODEMASTERS)
|
SLOT_INTERFACE_INTERNAL("codemasters", SEGA8_ROM_CODEMASTERS)
|
||||||
@ -549,6 +560,12 @@ static SLOT_INTERFACE_START(sms_cart)
|
|||||||
SLOT_INTERFACE_INTERNAL("janggun", SEGA8_ROM_JANGGUN)
|
SLOT_INTERFACE_INTERNAL("janggun", SEGA8_ROM_JANGGUN)
|
||||||
SLOT_INTERFACE_INTERNAL("korean", SEGA8_ROM_KOREAN)
|
SLOT_INTERFACE_INTERNAL("korean", SEGA8_ROM_KOREAN)
|
||||||
SLOT_INTERFACE_INTERNAL("korean_nb", SEGA8_ROM_KOREAN_NB)
|
SLOT_INTERFACE_INTERNAL("korean_nb", SEGA8_ROM_KOREAN_NB)
|
||||||
|
SLOT_INTERFACE_INTERNAL("castle", SEGA8_ROM_CASTLE)
|
||||||
|
SLOT_INTERFACE_INTERNAL("dahjee_typea", SEGA8_ROM_DAHJEE_TYPEA)
|
||||||
|
SLOT_INTERFACE_INTERNAL("dahjee_typeb", SEGA8_ROM_DAHJEE_TYPEB)
|
||||||
|
// are these SC-3000 carts below actually compatible or not? remove if not!
|
||||||
|
SLOT_INTERFACE_INTERNAL("level3", SEGA8_ROM_BASIC_L3)
|
||||||
|
SLOT_INTERFACE_INTERNAL("music_editor", SEGA8_ROM_MUSIC_EDITOR)
|
||||||
SLOT_INTERFACE_END
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
static SLOT_INTERFACE_START(gg_cart)
|
static SLOT_INTERFACE_START(gg_cart)
|
||||||
@ -793,7 +810,7 @@ static MACHINE_CONFIG_DERIVED( sg1000m3, sms_fm )
|
|||||||
MCFG_CPU_IO_MAP(sms_no3e3f_io)
|
MCFG_CPU_IO_MAP(sms_no3e3f_io)
|
||||||
|
|
||||||
MCFG_DEVICE_REMOVE("slot")
|
MCFG_DEVICE_REMOVE("slot")
|
||||||
MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sms_cart, NULL, NULL)
|
MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, NULL, NULL)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_DERIVED( sms2_fm, sms2_ntsc )
|
static MACHINE_CONFIG_DERIVED( sms2_fm, sms2_ntsc )
|
||||||
|
@ -15,9 +15,20 @@
|
|||||||
// constructors
|
// constructors
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
// Base cart type shared across SG-1000, SG-1000 Mark II, SG-1000 Mark III, SMS, GG
|
||||||
|
// even if in sg1000 rom banks are never changed and ram is never enabled
|
||||||
const device_type SEGA8_ROM_STD = &device_creator<sega8_rom_device>;
|
const device_type SEGA8_ROM_STD = &device_creator<sega8_rom_device>;
|
||||||
const device_type SEGA8_ROM_EEPROM = &device_creator<sega8_eeprom_device>;
|
|
||||||
|
// Specific SG-1000 MkI - MkII cart types
|
||||||
|
const device_type SEGA8_ROM_CASTLE = &device_creator<sega8_castle_device>;
|
||||||
|
const device_type SEGA8_ROM_BASIC_L3 = &device_creator<sega8_basic_l3_device>;
|
||||||
|
const device_type SEGA8_ROM_MUSIC_EDITOR = &device_creator<sega8_music_editor_device>;
|
||||||
const device_type SEGA8_ROM_TEREBI = &device_creator<sega8_terebi_device>;
|
const device_type SEGA8_ROM_TEREBI = &device_creator<sega8_terebi_device>;
|
||||||
|
const device_type SEGA8_ROM_DAHJEE_TYPEA = &device_creator<sega8_dahjee_typea_device>;
|
||||||
|
const device_type SEGA8_ROM_DAHJEE_TYPEB = &device_creator<sega8_dahjee_typeb_device>;
|
||||||
|
|
||||||
|
// Specific SG-1000 MkIII - SMS - GG cart types
|
||||||
|
const device_type SEGA8_ROM_EEPROM = &device_creator<sega8_eeprom_device>;
|
||||||
const device_type SEGA8_ROM_CODEMASTERS = &device_creator<sega8_codemasters_device>;
|
const device_type SEGA8_ROM_CODEMASTERS = &device_creator<sega8_codemasters_device>;
|
||||||
const device_type SEGA8_ROM_4PAK = &device_creator<sega8_4pak_device>;
|
const device_type SEGA8_ROM_4PAK = &device_creator<sega8_4pak_device>;
|
||||||
const device_type SEGA8_ROM_ZEMINA = &device_creator<sega8_zemina_device>;
|
const device_type SEGA8_ROM_ZEMINA = &device_creator<sega8_zemina_device>;
|
||||||
@ -27,6 +38,7 @@ const device_type SEGA8_ROM_KOREAN = &device_creator<sega8_korean_device>;
|
|||||||
const device_type SEGA8_ROM_KOREAN_NB = &device_creator<sega8_korean_nb_device>;
|
const device_type SEGA8_ROM_KOREAN_NB = &device_creator<sega8_korean_nb_device>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sega8_rom_device::sega8_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
sega8_rom_device::sega8_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||||
device_sega8_cart_interface( mconfig, *this )
|
device_sega8_cart_interface( mconfig, *this )
|
||||||
@ -34,22 +46,34 @@ sega8_rom_device::sega8_rom_device(const machine_config &mconfig, device_type ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
sega8_rom_device::sega8_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
sega8_rom_device::sega8_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: device_t(mconfig, SEGA8_ROM_STD, "SMS Carts", tag, owner, clock, "sega8_rom", __FILE__),
|
: device_t(mconfig, SEGA8_ROM_STD, "Mark III, SMS & GG Carts", tag, owner, clock, "sega8_rom", __FILE__),
|
||||||
device_sega8_cart_interface( mconfig, *this )
|
device_sega8_cart_interface( mconfig, *this )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sega8_eeprom_device::sega8_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
|
||||||
: device_t(mconfig, SEGA8_ROM_EEPROM, "SMS EEPROM Carts", tag, owner, clock, "sega8_eeprom", __FILE__),
|
|
||||||
device_sega8_cart_interface( mconfig, *this ),
|
sega8_castle_device::sega8_castle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
m_eeprom(*this, "eeprom")
|
: sega8_rom_device(mconfig, SEGA8_ROM_CASTLE, "SG-1000 The Castle Cart", tag, owner, clock, "sega8_castle", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sega8_basic_l3_device::sega8_basic_l3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: sega8_rom_device(mconfig, SEGA8_ROM_BASIC_L3, "SC-3000 BASIC Level III Cart", tag, owner, clock, "sega8_basicl3", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sega8_music_editor_device::sega8_music_editor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: sega8_rom_device(mconfig, SEGA8_ROM_MUSIC_EDITOR, "SC-3000 Music Editor Cart", tag, owner, clock, "sega8_music", __FILE__)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sega8_terebi_device::sega8_terebi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
sega8_terebi_device::sega8_terebi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: sega8_rom_device(mconfig, SEGA8_ROM_TEREBI, "SMS Terebi Oekaki Cart", tag, owner, clock, "sega8_terebi", __FILE__),
|
: sega8_rom_device(mconfig, SEGA8_ROM_TEREBI, "SG-1000 Terebi Oekaki Cart", tag, owner, clock, "sega8_terebi", __FILE__),
|
||||||
m_tvdraw_x(*this, "TVDRAW_X"),
|
m_tvdraw_x(*this, "TVDRAW_X"),
|
||||||
m_tvdraw_y(*this, "TVDRAW_Y"),
|
m_tvdraw_y(*this, "TVDRAW_Y"),
|
||||||
m_tvdraw_pen(*this, "TVDRAW_PEN")
|
m_tvdraw_pen(*this, "TVDRAW_PEN")
|
||||||
@ -57,8 +81,30 @@ sega8_terebi_device::sega8_terebi_device(const machine_config &mconfig, const ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sega8_dahjee_typea_device::sega8_dahjee_typea_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: sega8_rom_device(mconfig, SEGA8_ROM_DAHJEE_TYPEA, "SG-1000 Dahjee RAM expansion + Cart (Type A)", tag, owner, clock, "sega8_dahjeea", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sega8_dahjee_typeb_device::sega8_dahjee_typeb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: sega8_rom_device(mconfig, SEGA8_ROM_DAHJEE_TYPEB, "SG-1000 Dahjee RAM expansion + Cart (Type B)", tag, owner, clock, "sega8_dahjeeb", __FILE__)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sega8_eeprom_device::sega8_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, SEGA8_ROM_EEPROM, "GG Carts + EEPROM", tag, owner, clock, "sega8_eeprom", __FILE__),
|
||||||
|
device_sega8_cart_interface( mconfig, *this ),
|
||||||
|
m_eeprom(*this, "eeprom")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sega8_codemasters_device::sega8_codemasters_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
sega8_codemasters_device::sega8_codemasters_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: device_t(mconfig, SEGA8_ROM_CODEMASTERS, "SMS Codemasters Carts", tag, owner, clock, "sega8_codemasters", __FILE__),
|
: device_t(mconfig, SEGA8_ROM_CODEMASTERS, "Mark III, SMS & GG Codemasters Carts", tag, owner, clock, "sega8_codemasters", __FILE__),
|
||||||
device_sega8_cart_interface( mconfig, *this )
|
device_sega8_cart_interface( mconfig, *this )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -122,6 +168,21 @@ void sega8_rom_device::device_reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sega8_terebi_device::device_start()
|
||||||
|
{
|
||||||
|
save_item(NAME(m_rom_bank_base));
|
||||||
|
save_item(NAME(m_tvdraw_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sega8_terebi_device::device_reset()
|
||||||
|
{
|
||||||
|
m_tvdraw_data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sega8_eeprom_device::device_start()
|
void sega8_eeprom_device::device_start()
|
||||||
{
|
{
|
||||||
save_item(NAME(m_rom_bank_base));
|
save_item(NAME(m_rom_bank_base));
|
||||||
@ -136,17 +197,6 @@ void sega8_eeprom_device::device_reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sega8_terebi_device::device_start()
|
|
||||||
{
|
|
||||||
save_item(NAME(m_rom_bank_base));
|
|
||||||
save_item(NAME(m_tvdraw_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void sega8_terebi_device::device_reset()
|
|
||||||
{
|
|
||||||
m_tvdraw_data = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sega8_codemasters_device::device_start()
|
void sega8_codemasters_device::device_start()
|
||||||
{
|
{
|
||||||
save_item(NAME(m_rom_bank_base));
|
save_item(NAME(m_rom_bank_base));
|
||||||
@ -186,12 +236,6 @@ void sega8_zemina_device::device_reset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sega8_janggun_device::device_start()
|
|
||||||
{
|
|
||||||
save_item(NAME(m_rom_bank_base));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// initial bank setup needs to know how many 16K banks are available, so it needs to be called during cart loading...
|
// 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()
|
void sega8_rom_device::late_bank_setup()
|
||||||
@ -254,7 +298,6 @@ void sega8_korean_device::late_bank_setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
mapper specific handlers
|
mapper specific handlers
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
@ -262,6 +305,7 @@ void sega8_korean_device::late_bank_setup()
|
|||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
|
||||||
Base Sega 8bit carts, possibly with bankswitch
|
Base Sega 8bit carts, possibly with bankswitch
|
||||||
|
(only used by Mark III, SMS and GG games)
|
||||||
|
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
@ -312,6 +356,242 @@ WRITE8_MEMBER(sega8_rom_device::write_mapper)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
|
||||||
|
The Castle is a SG-1000 game featuring 8K of
|
||||||
|
oncart RAM, mapped at 0x8000-0x9fff
|
||||||
|
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_castle_device::read_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000 && offset < 0xa000)
|
||||||
|
return m_ram[offset & 0x1fff];
|
||||||
|
|
||||||
|
return m_rom[offset % m_rom_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_castle_device::write_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000 && offset < 0xa000)
|
||||||
|
m_ram[offset & 0x1fff] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
|
||||||
|
BASIC Level III cart featured 32K of
|
||||||
|
oncart RAM, mapped at 0x8000-0xffff?
|
||||||
|
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_basic_l3_device::read_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000)
|
||||||
|
return m_ram[offset & 0x3fff];
|
||||||
|
|
||||||
|
return m_rom[offset % m_rom_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_basic_l3_device::write_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000)
|
||||||
|
m_ram[offset & 0x3fff] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_basic_l3_device::read_ram)
|
||||||
|
{
|
||||||
|
return m_ram[0x4000 + (offset & 0x3fff)];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_basic_l3_device::write_ram)
|
||||||
|
{
|
||||||
|
m_ram[0x4000 + (offset & 0x3fff)] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
|
||||||
|
Music Editor cart featured 10K of oncart RAM, mapped
|
||||||
|
in 0x8000-0x9fff and 0xc000-0xffff
|
||||||
|
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_music_editor_device::read_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000 && offset < 0xa000)
|
||||||
|
return m_ram[offset & 0x1fff];
|
||||||
|
|
||||||
|
return m_rom[offset % m_rom_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_music_editor_device::write_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x8000-0x9fff
|
||||||
|
if (offset >= 0x8000 && offset < 0xa000)
|
||||||
|
m_ram[offset & 0x1fff] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_music_editor_device::read_ram)
|
||||||
|
{
|
||||||
|
// 2K more of RAM sits in 0xc000-0xc3ff (and mirrored up to 0xffff)
|
||||||
|
// or should it simply go to the 2K of SC3000 RAM???
|
||||||
|
return m_ram[0x2000 + (offset & 0x7ff)];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_music_editor_device::write_ram)
|
||||||
|
{
|
||||||
|
// 2K more of RAM sits in 0xc000-0xc3ff (and mirrored up to 0xffff)
|
||||||
|
// or should it simply go to the 2K of SC3000 RAM???
|
||||||
|
m_ram[0x2000 + (offset & 0x7ff)] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
|
||||||
|
SG-1000 Terebi Oekaki using a Tablet input device
|
||||||
|
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Terebi Oekaki (TV Draw)
|
||||||
|
|
||||||
|
Address Access Bits
|
||||||
|
7 6 5 4 3 2 1 0
|
||||||
|
$6000 W - - - - - - - AXIS
|
||||||
|
$8000 R BUSY - - - - - - PRESS
|
||||||
|
$A000 R/W DATA
|
||||||
|
|
||||||
|
AXIS: write 0 to select X axis, 1 to select Y axis.
|
||||||
|
BUSY: reads 1 when graphic board is busy sampling position, else 0.
|
||||||
|
PRESS: reads 0 when pen is touching graphic board, else 1.
|
||||||
|
DATA: when pen is touching graphic board, return 8-bit sample position for currently selected axis (X is in the 0-255 range, Y in the 0-191 range). Else, return 0.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_terebi_device::read_cart)
|
||||||
|
{
|
||||||
|
int bank = offset / 0x4000;
|
||||||
|
|
||||||
|
if (offset == 0x8000)
|
||||||
|
return m_tvdraw_pen->read();
|
||||||
|
if (offset == 0xa000)
|
||||||
|
return m_tvdraw_data;
|
||||||
|
|
||||||
|
return m_rom[m_rom_bank_base[bank] * 0x4000 + (offset & 0x3fff)];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_terebi_device::write_cart)
|
||||||
|
{
|
||||||
|
switch (offset)
|
||||||
|
{
|
||||||
|
case 0x6000:
|
||||||
|
if (data & 0x01)
|
||||||
|
{
|
||||||
|
m_tvdraw_data = m_tvdraw_x->read();
|
||||||
|
|
||||||
|
if (m_tvdraw_data < 4) m_tvdraw_data = 4;
|
||||||
|
if (m_tvdraw_data > 251) m_tvdraw_data = 251;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_tvdraw_data = m_tvdraw_y->read() + 0x20;
|
||||||
|
break;
|
||||||
|
case 0xa000:
|
||||||
|
// effect unknown
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INPUT_PORTS_START( tvdraw )
|
||||||
|
PORT_START("TVDRAW_X")
|
||||||
|
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Tablet - X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
||||||
|
|
||||||
|
PORT_START("TVDRAW_Y")
|
||||||
|
PORT_BIT( 0xff, 0x60, IPT_LIGHTGUN_Y ) PORT_NAME("Tablet - Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0, 191) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
||||||
|
|
||||||
|
PORT_START("TVDRAW_PEN")
|
||||||
|
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Tablet - Pen")
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
ioport_constructor sega8_terebi_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
return INPUT_PORTS_NAME( tvdraw );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
|
||||||
|
Dahjee carts were sold with a RAM expansion pass-through
|
||||||
|
cart (which we don't emulate separately for the
|
||||||
|
moment) which allowed to play on old SG1000 machines
|
||||||
|
some MSX conversions requiring more RAM than available
|
||||||
|
|
||||||
|
Two kind of expansion existed (for different games),
|
||||||
|
one with 9K of RAM (Type A) and one with 8K of
|
||||||
|
RAM (Type B).
|
||||||
|
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
// TYPE A
|
||||||
|
READ8_MEMBER(sega8_dahjee_typea_device::read_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x2000-0x3fff
|
||||||
|
if (offset >= 0x2000 && offset < 0x4000)
|
||||||
|
return m_ram[offset & 0x1fff];
|
||||||
|
|
||||||
|
return m_rom[offset % m_rom_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_dahjee_typea_device::write_cart)
|
||||||
|
{
|
||||||
|
// 8K of RAM sits in 0x2000-0x3fff
|
||||||
|
if (offset >= 0x2000 && offset < 0x4000)
|
||||||
|
m_ram[offset & 0x1fff] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_dahjee_typea_device::read_ram)
|
||||||
|
{
|
||||||
|
// 1K more of RAM sits in 0xc000-0xc3ff (and mirrored up to 0xffff
|
||||||
|
// or should it simply go to the 1K of SG1000 RAM???
|
||||||
|
return m_ram[0x2000 + (offset & 0x3ff)];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_dahjee_typea_device::write_ram)
|
||||||
|
{
|
||||||
|
// 1K more of RAM sits in 0xc000-0xc3ff (and mirrored up to 0xffff
|
||||||
|
// or should it simply go to the 1K of SG1000 RAM???
|
||||||
|
m_ram[0x2000 + (offset & 0x3ff)] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TYPE B
|
||||||
|
READ8_MEMBER(sega8_dahjee_typeb_device::read_cart)
|
||||||
|
{
|
||||||
|
return m_rom[offset % m_rom_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_dahjee_typeb_device::read_ram)
|
||||||
|
{
|
||||||
|
// 8K more of RAM sits in 0xc000-0xffff
|
||||||
|
return m_ram[offset & 0x1fff];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_dahjee_typeb_device::write_ram)
|
||||||
|
{
|
||||||
|
// 8K more of RAM sits in 0xc000-0xffff
|
||||||
|
m_ram[offset & 0x1fff] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
|
||||||
Sega carts + EEPROM, used for some GameGear baseball
|
Sega carts + EEPROM, used for some GameGear baseball
|
||||||
@ -381,63 +661,6 @@ machine_config_constructor sega8_eeprom_device::device_mconfig_additions() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
|
|
||||||
Sega 8-bit cart + Tablet input device, used for
|
|
||||||
SG-1000 Terebi Oekaki (compatible with Mark III)
|
|
||||||
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
READ8_MEMBER(sega8_terebi_device::read_cart)
|
|
||||||
{
|
|
||||||
int bank = offset / 0x4000;
|
|
||||||
|
|
||||||
if (offset == 0x8000)
|
|
||||||
return m_tvdraw_pen->read();
|
|
||||||
if (offset == 0xa000)
|
|
||||||
return m_tvdraw_data;
|
|
||||||
|
|
||||||
return m_rom[m_rom_bank_base[bank] * 0x4000 + (offset & 0x3fff)];
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITE8_MEMBER(sega8_terebi_device::write_cart)
|
|
||||||
{
|
|
||||||
switch (offset)
|
|
||||||
{
|
|
||||||
case 0x6000:
|
|
||||||
if (data & 0x01)
|
|
||||||
{
|
|
||||||
m_tvdraw_data = m_tvdraw_x->read();
|
|
||||||
|
|
||||||
if (m_tvdraw_data < 4) m_tvdraw_data = 4;
|
|
||||||
if (m_tvdraw_data > 251) m_tvdraw_data = 251;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_tvdraw_data = m_tvdraw_y->read() + 0x20;
|
|
||||||
break;
|
|
||||||
case 0xa000:
|
|
||||||
// effect unknown
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INPUT_PORTS_START( tvdraw )
|
|
||||||
PORT_START("TVDRAW_X")
|
|
||||||
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Tablet - X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
|
||||||
|
|
||||||
PORT_START("TVDRAW_Y")
|
|
||||||
PORT_BIT( 0xff, 0x60, IPT_LIGHTGUN_Y ) PORT_NAME("Tablet - Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0, 191) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
|
||||||
|
|
||||||
PORT_START("TVDRAW_PEN")
|
|
||||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Tablet - Pen")
|
|
||||||
INPUT_PORTS_END
|
|
||||||
|
|
||||||
ioport_constructor sega8_terebi_device::device_input_ports() const
|
|
||||||
{
|
|
||||||
return INPUT_PORTS_NAME( tvdraw );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
|
||||||
Codemasters carts, possibly having on cart RAM
|
Codemasters carts, possibly having on cart RAM
|
||||||
@ -639,3 +862,4 @@ WRITE8_MEMBER(sega8_korean_device::write_cart)
|
|||||||
if (offset == 0xa000)
|
if (offset == 0xa000)
|
||||||
m_rom_bank_base[2] = data % m_rom_page_count;
|
m_rom_bank_base[2] = data % m_rom_page_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,128 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_castle_device
|
||||||
|
|
||||||
|
class sega8_castle_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_castle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_basic_l3_device
|
||||||
|
|
||||||
|
class sega8_basic_l3_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_basic_l3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
|
||||||
|
// has internal RAM which overwrites the system one!
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_music_editor_device
|
||||||
|
|
||||||
|
class sega8_music_editor_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_music_editor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
|
||||||
|
// has internal RAM which overwrites the system one!
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_terebi_device
|
||||||
|
|
||||||
|
class sega8_terebi_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_terebi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual ioport_constructor device_input_ports() const;
|
||||||
|
virtual void device_reset();
|
||||||
|
|
||||||
|
required_ioport m_tvdraw_x;
|
||||||
|
required_ioport m_tvdraw_y;
|
||||||
|
required_ioport m_tvdraw_pen;
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UINT8 m_tvdraw_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_dahjee_typea_device
|
||||||
|
|
||||||
|
class sega8_dahjee_typea_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_dahjee_typea_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
|
||||||
|
// has internal RAM which overwrites the system one!
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> sega8_dahjee_typeb_device
|
||||||
|
|
||||||
|
class sega8_dahjee_typeb_device : public sega8_rom_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
sega8_dahjee_typeb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// reading and writing
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_cart) {}
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
|
||||||
|
// has internal RAM which overwrites the system one!
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ======================> sega8_eeprom_device
|
// ======================> sega8_eeprom_device
|
||||||
|
|
||||||
class sega8_eeprom_device : public device_t,
|
class sega8_eeprom_device : public device_t,
|
||||||
@ -62,32 +184,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ======================> sega8_terebi_device
|
|
||||||
|
|
||||||
class sega8_terebi_device : public sega8_rom_device
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// construction/destruction
|
|
||||||
sega8_terebi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
|
||||||
|
|
||||||
// device-level overrides
|
|
||||||
virtual void device_start();
|
|
||||||
virtual ioport_constructor device_input_ports() const;
|
|
||||||
virtual void device_reset();
|
|
||||||
|
|
||||||
required_ioport m_tvdraw_x;
|
|
||||||
required_ioport m_tvdraw_y;
|
|
||||||
required_ioport m_tvdraw_pen;
|
|
||||||
|
|
||||||
// reading and writing
|
|
||||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
|
||||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UINT8 m_tvdraw_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ======================> sega8_codemasters_device
|
// ======================> sega8_codemasters_device
|
||||||
|
|
||||||
class sega8_codemasters_device : public device_t,
|
class sega8_codemasters_device : public device_t,
|
||||||
@ -185,7 +281,7 @@ public:
|
|||||||
sega8_janggun_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
sega8_janggun_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start();
|
virtual void device_start() { save_item(NAME(m_rom_bank_base)); }
|
||||||
|
|
||||||
virtual void late_bank_setup();
|
virtual void late_bank_setup();
|
||||||
|
|
||||||
@ -228,8 +324,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
extern const device_type SEGA8_ROM_STD;
|
extern const device_type SEGA8_ROM_STD;
|
||||||
|
extern const device_type SEGA8_ROM_CASTLE;
|
||||||
|
extern const device_type SEGA8_ROM_BASIC_L3;
|
||||||
|
extern const device_type SEGA8_ROM_MUSIC_EDITOR;
|
||||||
|
extern const device_type SEGA8_ROM_DAHJEE_TYPEA;
|
||||||
|
extern const device_type SEGA8_ROM_DAHJEE_TYPEB;
|
||||||
extern const device_type SEGA8_ROM_EEPROM;
|
extern const device_type SEGA8_ROM_EEPROM;
|
||||||
extern const device_type SEGA8_ROM_TEREBI;
|
extern const device_type SEGA8_ROM_TEREBI;
|
||||||
extern const device_type SEGA8_ROM_CODEMASTERS;
|
extern const device_type SEGA8_ROM_CODEMASTERS;
|
||||||
|
@ -182,7 +182,12 @@ static const sega8_slot slot_list[] =
|
|||||||
{ SEGA8_NEMESIS, "nemesis" },
|
{ SEGA8_NEMESIS, "nemesis" },
|
||||||
{ SEGA8_JANGGUN, "janggun" },
|
{ SEGA8_JANGGUN, "janggun" },
|
||||||
{ SEGA8_KOREAN, "korean" },
|
{ SEGA8_KOREAN, "korean" },
|
||||||
{ SEGA8_KOREAN_NOBANK, "korean_nobank" }
|
{ SEGA8_KOREAN_NOBANK, "korean_nb" },
|
||||||
|
{ SEGA8_CASTLE, "castle" },
|
||||||
|
{ SEGA8_BASIC_L3, "level3" },
|
||||||
|
{ SEGA8_MUSIC_EDITOR, "music_editor" },
|
||||||
|
{ SEGA8_DAHJEE_TYPEA, "dahjee_typea" },
|
||||||
|
{ SEGA8_DAHJEE_TYPEB, "dahjee_typeb" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sega8_get_pcb_id(const char *slot)
|
static int sega8_get_pcb_id(const char *slot)
|
||||||
@ -272,19 +277,44 @@ void sega8_cart_slot_device::setup_ram()
|
|||||||
{
|
{
|
||||||
if (software_entry() == NULL)
|
if (software_entry() == NULL)
|
||||||
{
|
{
|
||||||
// from fullpath we have no way to know exactly if there was RAM, how much RAM was in the cart and if there was a battery
|
if (m_type == SEGA8_CASTLE)
|
||||||
// so we always alloc 32KB and we save its content only if the game enable the RAM (unless it's Codemasters mapper...)
|
|
||||||
|
|
||||||
if (m_type != SEGA8_CODEMASTERS)
|
|
||||||
{
|
{
|
||||||
m_cart->set_late_battery(TRUE);
|
m_cart->ram_alloc(machine(), 0x2000);
|
||||||
m_cart->ram_alloc(machine(), 0x08000);
|
m_cart->set_has_battery(FALSE);
|
||||||
|
}
|
||||||
|
else if (m_type == SEGA8_BASIC_L3)
|
||||||
|
{
|
||||||
|
m_cart->ram_alloc(machine(), 0x8000);
|
||||||
|
m_cart->set_has_battery(FALSE);
|
||||||
|
}
|
||||||
|
else if (m_type == SEGA8_MUSIC_EDITOR)
|
||||||
|
{
|
||||||
|
m_cart->ram_alloc(machine(), 0x2800);
|
||||||
|
m_cart->set_has_battery(FALSE);
|
||||||
|
}
|
||||||
|
else if (m_type == SEGA8_DAHJEE_TYPEA)
|
||||||
|
{
|
||||||
|
m_cart->ram_alloc(machine(), 0x2400);
|
||||||
|
m_cart->set_has_battery(FALSE);
|
||||||
|
}
|
||||||
|
else if (m_type == SEGA8_DAHJEE_TYPEB)
|
||||||
|
{
|
||||||
|
m_cart->ram_alloc(machine(), 0x2000);
|
||||||
|
m_cart->set_has_battery(FALSE);
|
||||||
|
}
|
||||||
|
else if (m_type == SEGA8_CODEMASTERS)
|
||||||
|
{
|
||||||
|
// Codemasters cart can have 64KB of RAM (Ernie Els Golf? or 8KB?) and no battery
|
||||||
|
m_cart->ram_alloc(machine(), 0x10000);
|
||||||
|
m_cart->set_has_battery(FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Codemasters cart can have 64KB of RAM (Ernie Els Golf) and no battery
|
// for generic carts loaded from fullpath we have no way to know exactly if there was RAM,
|
||||||
m_cart->ram_alloc(machine(), 0x10000);
|
// how much RAM was in the cart and if there was a battery so we always alloc 32KB and
|
||||||
m_cart->set_has_battery(FALSE);
|
// we save its content only if the game enable the RAM
|
||||||
|
m_cart->set_late_battery(TRUE);
|
||||||
|
m_cart->ram_alloc(machine(), 0x08000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -456,9 +486,8 @@ int sms_state::detect_korean_mapper( UINT8 *rom )
|
|||||||
int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
|
int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
|
||||||
{
|
{
|
||||||
int type = SEGA8_BASE_ROM;
|
int type = SEGA8_BASE_ROM;
|
||||||
static const UINT8 terebi_oekaki[7] = { 0x61, 0x6e, 0x6e, 0x61, 0x6b, 0x6d, 0x6e }; // "annakmn"
|
|
||||||
|
|
||||||
/* Check for special cartridge features (new routine, courtesy of Omar Cornut, from MEKA) */
|
// Check for special cartridge features (new routine, courtesy of Omar Cornut, from MEKA)
|
||||||
if (len >= 0x8000)
|
if (len >= 0x8000)
|
||||||
{
|
{
|
||||||
int _0002 = 0, _8000 = 0, _a000 = 0, _ffff = 0, _3ffe = 0, _4000 = 0, _6000 = 0;
|
int _0002 = 0, _8000 = 0, _a000 = 0, _ffff = 0, _3ffe = 0, _4000 = 0, _6000 = 0;
|
||||||
@ -506,10 +535,65 @@ int sega8_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
|
|||||||
type = SEGA8_JANGGUN;
|
type = SEGA8_JANGGUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terebi Oekaki (TV Draw) is a SG1000 game with special input device which is compatible with SG1000 Mark III
|
// Try to detect Dahjee RAM Expansions
|
||||||
if (!memcmp(&ROM[0x13b3], terebi_oekaki, 7))
|
if (len >= 0x8000)
|
||||||
|
{
|
||||||
|
int x2000_3000 = 0, xd000_e000_f000 = 0, x2000_ff = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 0x8000; i++)
|
||||||
|
{
|
||||||
|
if (ROM[i] == 0x32)
|
||||||
|
{
|
||||||
|
UINT16 addr = ROM[i + 1] | (ROM[i + 2] << 8);
|
||||||
|
|
||||||
|
switch (addr & 0xf000)
|
||||||
|
{
|
||||||
|
case 0x2000:
|
||||||
|
case 0x3000:
|
||||||
|
i += 2;
|
||||||
|
x2000_3000++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xd000:
|
||||||
|
case 0xe000:
|
||||||
|
case 0xf000:
|
||||||
|
i += 2;
|
||||||
|
xd000_e000_f000++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0x2000; i < 0x4000; i++)
|
||||||
|
{
|
||||||
|
if (ROM[i] == 0xff)
|
||||||
|
x2000_ff++;
|
||||||
|
}
|
||||||
|
if (x2000_ff == 0x2000 && (xd000_e000_f000 > 10 || x2000_3000 > 10))
|
||||||
|
{
|
||||||
|
if (xd000_e000_f000 > x2000_3000)
|
||||||
|
type = SEGA8_DAHJEE_TYPEB;
|
||||||
|
else
|
||||||
|
type = SEGA8_DAHJEE_TYPEA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terebi Oekaki (TV Draw)
|
||||||
|
if (!strncmp((const char *)&ROM[0x13b3], "annakmn", 7))
|
||||||
type = SEGA8_TEREBIOEKAKI;
|
type = SEGA8_TEREBIOEKAKI;
|
||||||
|
|
||||||
|
// The Castle (ROM+RAM)
|
||||||
|
if (!strncmp((const char *)&ROM[0x1cc3], "ASCII 1986", 10))
|
||||||
|
type = SEGA8_CASTLE;
|
||||||
|
|
||||||
|
// BASIC Level 3
|
||||||
|
if (!strncmp((const char *)&ROM[0x6a20], "SC-3000 BASIC Level 3 ver 1.0", 29))
|
||||||
|
type = SEGA8_BASIC_L3;
|
||||||
|
|
||||||
|
// Music Editor
|
||||||
|
if (!strncmp((const char *)&ROM[0x0841], "PIANO", 5))
|
||||||
|
type = SEGA8_MUSIC_EDITOR;
|
||||||
|
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
@ -557,6 +641,14 @@ READ8_MEMBER(sega8_cart_slot_device::read_cart)
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(sega8_cart_slot_device::read_ram)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
return m_cart->read_ram(space, offset);
|
||||||
|
else
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
write
|
write
|
||||||
@ -574,6 +666,12 @@ WRITE8_MEMBER(sega8_cart_slot_device::write_cart)
|
|||||||
m_cart->write_cart(space, offset, data);
|
m_cart->write_cart(space, offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(sega8_cart_slot_device::write_ram)
|
||||||
|
{
|
||||||
|
if (m_cart)
|
||||||
|
m_cart->write_ram(space, offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
Internal header logging
|
Internal header logging
|
||||||
|
@ -18,7 +18,12 @@ enum
|
|||||||
SEGA8_NEMESIS,
|
SEGA8_NEMESIS,
|
||||||
SEGA8_JANGGUN,
|
SEGA8_JANGGUN,
|
||||||
SEGA8_KOREAN,
|
SEGA8_KOREAN,
|
||||||
SEGA8_KOREAN_NOBANK
|
SEGA8_KOREAN_NOBANK,
|
||||||
|
SEGA8_CASTLE,
|
||||||
|
SEGA8_BASIC_L3,
|
||||||
|
SEGA8_MUSIC_EDITOR,
|
||||||
|
SEGA8_DAHJEE_TYPEA,
|
||||||
|
SEGA8_DAHJEE_TYPEB
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -39,6 +44,9 @@ public:
|
|||||||
virtual DECLARE_READ8_MEMBER(read_cart) { return 0xff; }
|
virtual DECLARE_READ8_MEMBER(read_cart) { return 0xff; }
|
||||||
virtual DECLARE_WRITE8_MEMBER(write_cart) {}
|
virtual DECLARE_WRITE8_MEMBER(write_cart) {}
|
||||||
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
virtual DECLARE_WRITE8_MEMBER(write_mapper) {}
|
||||||
|
// 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) {}
|
||||||
|
|
||||||
void rom_alloc(running_machine &machine, UINT32 size);
|
void rom_alloc(running_machine &machine, UINT32 size);
|
||||||
void ram_alloc(running_machine &machine, UINT32 size);
|
void ram_alloc(running_machine &machine, UINT32 size);
|
||||||
@ -132,6 +140,8 @@ public:
|
|||||||
virtual DECLARE_READ8_MEMBER(read_cart);
|
virtual DECLARE_READ8_MEMBER(read_cart);
|
||||||
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
virtual DECLARE_WRITE8_MEMBER(write_cart);
|
||||||
virtual DECLARE_WRITE8_MEMBER(write_mapper);
|
virtual DECLARE_WRITE8_MEMBER(write_mapper);
|
||||||
|
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||||
|
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||||
|
|
||||||
|
|
||||||
//protected:
|
//protected:
|
||||||
|
@ -1108,6 +1108,15 @@ MACHINE_START_MEMBER(sms_state,sms)
|
|||||||
m_cards[i] = machine().device<sega8_card_slot_device>(str);
|
m_cards[i] = machine().device<sega8_card_slot_device>(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a bunch of SG1000 carts (compatible with SG1000 Mark III) can access directly system RAM... let's install here the necessary handlers
|
||||||
|
// TODO: are BASIC and Music actually compatible with Mark III??
|
||||||
|
if (m_cartslot->get_type() == SEGA8_BASIC_L3 || m_cartslot->get_type() == SEGA8_MUSIC_EDITOR
|
||||||
|
|| m_cartslot->get_type() == SEGA8_DAHJEE_TYPEA || m_cartslot->get_type() == SEGA8_DAHJEE_TYPEB)
|
||||||
|
{
|
||||||
|
m_maincpu->space(AS_PROGRAM).install_read_handler(0xc000, 0xffff, 0, 0, read8_delegate(FUNC(sega8_cart_slot_device::read_ram),(sega8_cart_slot_device*)m_cartslot));
|
||||||
|
m_maincpu->space(AS_PROGRAM).install_write_handler(0xc000, 0xffff, 0, 0, write8_delegate(FUNC(sega8_cart_slot_device::write_ram),(sega8_cart_slot_device*)m_cartslot));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_RESET_MEMBER(sms_state,sms)
|
MACHINE_RESET_MEMBER(sms_state,sms)
|
||||||
|
Loading…
Reference in New Issue
Block a user