(MESS) sms.c: added support for the card slot to Master System I console; use the -card switch

to load Sega Card/MyCard dumps in the emulated system. [Fabio Priuli]


The support is still preliminary, in the sense that at the moment you can load any SMS dump <= 32K 
in the card slot. Eventually the support will be restricted (at least from softlist) to games which were 
really available as cards.
This commit is contained in:
Fabio Priuli 2013-05-23 06:42:07 +00:00
parent a0ec59c8ac
commit 9784c1b3c7
5 changed files with 76 additions and 29 deletions

View File

@ -628,6 +628,10 @@ static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base )
MCFG_VIDEO_START_OVERRIDE(sms_state,sms1)
MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_ntsc_intf)
// cardslot, not present in Master System II
MCFG_SMS_CARD_ADD("mycard", sms_cart, NULL, NULL)
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( sms_sdisp, smssdisp_state )
@ -756,6 +760,9 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base )
MCFG_VIDEO_START_OVERRIDE(sms_state,sms1)
MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_pal_intf)
// cardslot, not present in Master System II
MCFG_SMS_CARD_ADD("mycard", sms_cart, NULL, NULL)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( sms_fm, sms1_ntsc )

View File

@ -30,6 +30,7 @@ public:
m_main_scr(*this, "screen"),
m_mainram(*this, "mainram"),
m_cartslot(*this, "slot"),
m_card(*this, "mycard"),
m_region_maincpu(*this, "maincpu"),
m_port_dd(*this, "PORT_DD"),
m_port_dc(*this, "PORT_DC"),
@ -66,6 +67,7 @@ public:
required_device<screen_device> m_main_scr;
required_shared_ptr<UINT8> m_mainram;
required_device<sega8_cart_slot_device> m_cartslot;
optional_device<sega8_card_slot_device> m_card;
required_memory_region m_region_maincpu;
required_ioport m_port_dd;
required_ioport m_port_dc;

View File

@ -14,10 +14,12 @@
* write_mapper : to write to range [fffc-ffff] (called by the handler accessing those
same addresses in sms.c)
Note about Sega Card / MyCard: the data contained in these matches the data in carts, it's only
the connector to be different. We emulate this with a variant of the slot having different media
switch and different interface (the latter not implemented yet)
TODO:
- investigate SG-1000 carts so to reduce duplicated code and to add full .sg support to sg1000m3
- add support for sms card slot (using the same code, since the access are basically the same as
the cart ones)
***********************************************************************************************************/
@ -34,6 +36,7 @@
//**************************************************************************
const device_type SEGA8_CART_SLOT = &device_creator<sega8_cart_slot_device>;
const device_type SEGA8_CARD_SLOT = &device_creator<sega8_card_slot_device>;
//**************************************************************************
@ -94,7 +97,7 @@ void device_sega8_cart_interface::ram_alloc(running_machine &machine, UINT32 siz
{
m_ram = auto_alloc_array_clear(machine, UINT8, size);
m_ram_size = size;
state_save_register_item_pointer(machine, "SEGA8_CART", NULL, 0, m_ram, m_ram_size);
state_save_register_item_pointer(machine, "SEGA8_CART", this->device().tag(), 0, m_ram, m_ram_size);
}
}
@ -108,14 +111,32 @@ void device_sega8_cart_interface::ram_alloc(running_machine &machine, UINT32 siz
// sega8_cart_slot_device - constructor
//-------------------------------------------------
sega8_cart_slot_device::sega8_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, SEGA8_CART_SLOT, "Sega Master System / Game Gear / SG1000 Cartridge Slot", tag, owner, clock),
sega8_cart_slot_device::sega8_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool is_card) :
device_t(mconfig, type, name, tag, owner, clock),
device_image_interface(mconfig, *this),
device_slot_interface(mconfig, *this),
m_type(SEGA8_BASE_ROM),
m_must_be_loaded(FALSE),
m_interface("sms_cart"),
m_extensions("bin")
{
m_is_card = is_card;
}
sega8_cart_slot_device::sega8_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, SEGA8_CART_SLOT, "Sega Master System / Game Gear / SG1000 Cartridge Slot", tag, owner, clock),
device_image_interface(mconfig, *this),
device_slot_interface(mconfig, *this),
m_type(SEGA8_BASE_ROM),
m_must_be_loaded(FALSE),
m_is_card(FALSE),
m_interface("sms_cart"),
m_extensions("bin")
{
}
sega8_card_slot_device::sega8_card_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
sega8_cart_slot_device(mconfig, SEGA8_CARD_SLOT, "Sega Master System / Game Gear / SG1000 Card Slot", tag, owner, clock, TRUE)
{
}
@ -137,19 +158,6 @@ void sega8_cart_slot_device::device_start()
m_cart = dynamic_cast<device_sega8_cart_interface *>(get_card_device());
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void sega8_cart_slot_device::device_config_complete()
{
// set brief and instance name
update_names();
}
//-------------------------------------------------
// SMS PCB
//-------------------------------------------------
@ -267,7 +275,13 @@ bool sega8_cart_slot_device::call_load()
UINT32 len = (software_entry() == NULL) ? length() : get_software_region_length("rom");
UINT32 offset = 0;
UINT8 *ROM;
if (m_is_card && len > 0x8000)
{
seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a card larger than 32KB");
return IMAGE_INIT_FAIL;
}
// check for header
if ((len % 0x4000) == 512)
{

View File

@ -22,6 +22,10 @@ enum
};
extern const device_type SEGA8_CART_SLOT;
extern const device_type SEGA8_CARD_SLOT;
// ======================> device_sega8_cart_interface
class device_sega8_cart_interface : public device_slot_card_interface
@ -79,12 +83,13 @@ class sega8_cart_slot_device : public device_t,
{
public:
// construction/destruction
sega8_cart_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool is_card);
sega8_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~sega8_cart_slot_device();
// device-level overrides
virtual void device_start();
virtual void device_config_complete();
virtual void device_config_complete() { update_names(SEGA8_CART_SLOT, "cartridge", "cart"); }
// image-level overrides
virtual bool call_load();
@ -123,14 +128,23 @@ public:
//protected:
int m_type;
bool m_must_be_loaded;
bool m_must_be_loaded, m_is_card;
const char *m_interface;
const char *m_extensions;
device_sega8_cart_interface* m_cart;
};
// ======================> sega8_card_slot_device
class sega8_card_slot_device : public sega8_cart_slot_device
{
public:
// construction/destruction
sega8_card_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual void device_config_complete() { update_names(SEGA8_CARD_SLOT, "card", "card"); }
};
extern const device_type SEGA8_CART_SLOT;
/***************************************************************************
DEVICE CONFIGURATION MACROS
@ -143,13 +157,6 @@ extern const device_type SEGA8_CART_SLOT;
static_cast<sega8_cart_slot_device *>(device)->set_intf("sms_cart"); \
static_cast<sega8_cart_slot_device *>(device)->set_ext("bin,sms");
#define MCFG_SMS_CARD_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
MCFG_DEVICE_ADD(_tag, SEGA8_CART_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) \
static_cast<sega8_cart_slot_device *>(device)->set_mandatory(FALSE); \
static_cast<sega8_cart_slot_device *>(device)->set_intf("sms_card"); \
static_cast<sega8_cart_slot_device *>(device)->set_ext("bin,sc");
#define MCFG_GG_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
MCFG_DEVICE_ADD(_tag, SEGA8_CART_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) \
@ -165,4 +172,13 @@ extern const device_type SEGA8_CART_SLOT;
static_cast<sega8_cart_slot_device *>(device)->set_ext("bin,sms,sg");
#define MCFG_SMS_CARD_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
MCFG_DEVICE_ADD(_tag, SEGA8_CARD_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) \
static_cast<sega8_card_slot_device *>(device)->set_mandatory(FALSE); \
static_cast<sega8_card_slot_device *>(device)->set_intf("sms_cart"); \
static_cast<sega8_card_slot_device *>(device)->set_ext("bin,sms"); \
#endif

View File

@ -741,6 +741,8 @@ READ8_MEMBER(sms_state::read_0000)
}
if (m_bank_enabled[3] == ENABLE_CART)
return m_cartslot->read_cart(space, offset);
if (m_card && m_bank_enabled[3] == ENABLE_CARD)
return m_card->read_cart(space, offset);
}
else
{
@ -751,6 +753,8 @@ READ8_MEMBER(sms_state::read_0000)
}
if (m_bank_enabled[0] == ENABLE_CART)
return m_cartslot->read_cart(space, offset);
if (m_card && m_bank_enabled[0] == ENABLE_CARD)
return m_card->read_cart(space, offset);
}
return m_region_maincpu->base()[offset];
}
@ -765,6 +769,8 @@ READ8_MEMBER(sms_state::read_4000)
if (m_bank_enabled[1] == ENABLE_CART)
return m_cartslot->read_cart(space, offset + 0x4000);
if (m_card && m_bank_enabled[1] == ENABLE_CARD)
return m_card->read_cart(space, offset + 0x4000);
return m_region_maincpu->base()[offset];
}
@ -779,6 +785,8 @@ READ8_MEMBER(sms_state::read_8000)
if (m_bank_enabled[2] == ENABLE_CART)
return m_cartslot->read_cart(space, offset + 0x8000);
if (m_card && m_bank_enabled[2] == ENABLE_CARD)
return m_card->read_cart(space, offset + 0x8000);
return m_region_maincpu->base()[offset];
}