(MESS) pce.c: converted carts to use slot devices [Fabio Priuli]

This commit is contained in:
Fabio Priuli 2013-05-27 15:27:03 +00:00
parent b7fc03f9ce
commit 620187abe1
11 changed files with 770 additions and 207 deletions

4
.gitattributes vendored
View File

@ -7610,6 +7610,10 @@ src/mess/machine/pc_lpt.h svneol=native#text/plain
src/mess/machine/pce.c svneol=native#text/plain
src/mess/machine/pce220_ser.c svneol=native#text/plain
src/mess/machine/pce220_ser.h svneol=native#text/plain
src/mess/machine/pce_rom.c svneol=native#text/plain
src/mess/machine/pce_rom.h svneol=native#text/plain
src/mess/machine/pce_slot.c svneol=native#text/plain
src/mess/machine/pce_slot.h svneol=native#text/plain
src/mess/machine/pecom.c svneol=native#text/plain
src/mess/machine/pet_64k.c svneol=native#text/plain
src/mess/machine/pet_64k.h svneol=native#text/plain

View File

@ -2892,6 +2892,7 @@
<info name="release" value="19910405"/>
<info name="alt_title" value="ポピュラス"/>
<part name="cart" interface="pce_cart">
<feature name="slot" value="populous" />
<dataarea name="rom" size="524288">
<rom name="populous (japan).pce" size="524288" crc="083c956a" sha1="4912ccc31bdd45ef9483ea345bbe4c4ff2d70779" offset="000000" />
</dataarea>
@ -2906,6 +2907,7 @@
<info name="release" value="19910405"/>
<info name="alt_title" value="ポピュラス"/>
<part name="cart" interface="pce_cart">
<feature name="slot" value="populous" />
<dataarea name="rom" size="524288">
<rom name="populous (japan) [a].pce" size="524288" crc="0a9ade99" sha1="8e021703241c20ebd2a40ee55788c3a5fc4b8592" offset="000000" />
</dataarea>
@ -3666,6 +3668,7 @@
<info name="release" value="19930612"/>
<info name="alt_title" value="ストリートファイターIIダッシュ"/>
<part name="cart" interface="pce_cart">
<feature name="slot" value="sf2" />
<dataarea name="rom" size="2621440">
<rom name="street fighter ii' - champion edition (japan).pce" size="2621440" crc="d15cb6bb" sha1="e757ecdf857803cb46cdf37ecf4596f6eaccdd76" offset="000000" />
</dataarea>
@ -4442,6 +4445,7 @@
<year>19??</year>
<publisher>Hudson</publisher>
<part name="cart" interface="pce_cart">
<feature name="slot" value="cdsys3j" />
<dataarea name="rom" size="262144">
<rom name="[cd] super cd-rom system (japan) (v3.0).pce" size="262144" crc="6d9a73ef" sha1="79f5ff55dd10187c7fd7b8daab0b3ffbd1f56a2c" offset="000000" />
</dataarea>

View File

@ -1042,6 +1042,7 @@
<year>19??</year>
<publisher>NEC</publisher>
<part name="cart" interface="tg16_cart">
<feature name="slot" value="cdsys3u" />
<dataarea name="rom" size="262144">
<rom name="[cd] turbografx cd super system card (usa) (v3.0).pce" size="262144" crc="2b5b75fe" sha1="d02611d99921986147c753df14c7349b31d71950" offset="000000" />
</dataarea>

View File

@ -57,8 +57,8 @@ Super System Card:
#include "emu.h"
#include "cpu/h6280/h6280.h"
#include "includes/pce.h"
#include "imagedev/cartslot.h"
#include "imagedev/chd_cd.h"
#include "machine/pce_rom.h"
#include "sound/c6280.h"
#include "sound/cdda.h"
#include "sound/msm5205.h"
@ -237,16 +237,6 @@ static INPUT_PORTS_START( pce )
INPUT_PORTS_END
static void pce_partialhash(hash_collection &dest, const unsigned char *data,
unsigned long length, const char *functions)
{
if ( ( length <= PCE_HEADER_SIZE ) || ( length & PCE_HEADER_SIZE ) ) {
dest.compute(&data[PCE_HEADER_SIZE], length - PCE_HEADER_SIZE, functions);
} else {
dest.compute(data, length, functions);
}
}
static const c6280_interface c6280_config =
{
"maincpu"
@ -264,41 +254,9 @@ static MACHINE_CONFIG_FRAGMENT( pce_cdslot )
MCFG_SOFTWARE_LIST_ADD("cd_list","pcecd")
MACHINE_CONFIG_END
static MACHINE_CONFIG_FRAGMENT( pce_cartslot )
MCFG_CARTSLOT_ADD("cart")
MCFG_CARTSLOT_EXTENSION_LIST("pce,bin")
MCFG_CARTSLOT_MANDATORY
MCFG_CARTSLOT_INTERFACE("pce_cart")
MCFG_CARTSLOT_LOAD(pce_state,pce_cart)
MCFG_CARTSLOT_PARTIALHASH(pce_partialhash)
MCFG_SOFTWARE_LIST_ADD("cart_list","pce")
MACHINE_CONFIG_END
static MACHINE_CONFIG_FRAGMENT( tg16_cartslot )
MCFG_CARTSLOT_ADD("cart")
MCFG_CARTSLOT_EXTENSION_LIST("pce,bin")
MCFG_CARTSLOT_MANDATORY
MCFG_CARTSLOT_INTERFACE("tg16_cart")
MCFG_CARTSLOT_LOAD(pce_state,pce_cart)
MCFG_CARTSLOT_PARTIALHASH(pce_partialhash)
MCFG_SOFTWARE_LIST_ADD("cart_list","tg16")
MACHINE_CONFIG_END
static MACHINE_CONFIG_FRAGMENT( sgx_cartslot )
MCFG_CARTSLOT_ADD("cart")
MCFG_CARTSLOT_EXTENSION_LIST("pce,bin")
MCFG_CARTSLOT_MANDATORY
MCFG_CARTSLOT_INTERFACE("pce_cart")
MCFG_CARTSLOT_LOAD(pce_state,pce_cart)
MCFG_CARTSLOT_PARTIALHASH(pce_partialhash)
MCFG_SOFTWARE_LIST_ADD("cart_list","sgx")
MACHINE_CONFIG_END
static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, pce_state )
AM_RANGE( 0x000000, 0x07FFFF) AM_ROMBANK("bank1")
AM_RANGE( 0x080000, 0x087FFF) AM_ROMBANK("bank2")
AM_RANGE( 0x088000, 0x0CFFFF) AM_ROMBANK("bank3")
AM_RANGE( 0x0D0000, 0x0FFFFF) AM_ROMBANK("bank4")
AM_RANGE( 0x000000, 0x0FFFFF) AM_DEVREADWRITE("cartslot", pce_cart_slot_device, read_cart, write_cart)
AM_RANGE( 0x100000, 0x10FFFF) AM_RAM AM_SHARE("cd_ram")
AM_RANGE( 0x110000, 0x1EDFFF) AM_NOP
AM_RANGE( 0x1EE000, 0x1EE7FF) AM_ROMBANK("bank10") AM_WRITE(pce_cd_bram_w )
@ -319,10 +277,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( sgx_mem , AS_PROGRAM, 8, pce_state )
AM_RANGE( 0x000000, 0x07FFFF) AM_ROMBANK("bank1")
AM_RANGE( 0x080000, 0x087FFF) AM_ROMBANK("bank2")
AM_RANGE( 0x088000, 0x0CFFFF) AM_ROMBANK("bank3")
AM_RANGE( 0x0D0000, 0x0FFFFF) AM_ROMBANK("bank4")
AM_RANGE( 0x000000, 0x0FFFFF) AM_DEVREADWRITE("cartslot", pce_cart_slot_device, read_cart, write_cart)
AM_RANGE( 0x100000, 0x10FFFF) AM_RAM AM_SHARE("cd_ram")
AM_RANGE( 0x110000, 0x1EDFFF) AM_NOP
AM_RANGE( 0x1EE000, 0x1EE7FF) AM_ROMBANK("bank10") AM_WRITE(pce_cd_bram_w )
@ -415,6 +370,14 @@ static const huc6260_interface sgx_huc6260_config =
DEVCB_DEVICE_LINE_MEMBER( "huc6202", huc6202_device, hsync_changed )
};
static SLOT_INTERFACE_START(pce_cart)
SLOT_INTERFACE_INTERNAL("rom", PCE_ROM_STD)
SLOT_INTERFACE_INTERNAL("cdsys3u", PCE_ROM_CDSYS3)
SLOT_INTERFACE_INTERNAL("cdsys3j", PCE_ROM_CDSYS3)
SLOT_INTERFACE_INTERNAL("populous", PCE_ROM_POPULOUS)
SLOT_INTERFACE_INTERNAL("sf2", PCE_ROM_SF2)
SLOT_INTERFACE_END
static MACHINE_CONFIG_START( pce_common, pce_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", H6280, MAIN_CLOCK/3)
@ -456,13 +419,17 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( pce, pce_common )
MCFG_FRAGMENT_ADD( pce_cartslot )
MCFG_PCE_CARTRIDGE_ADD("cartslot", pce_cart, NULL, NULL)
MCFG_SOFTWARE_LIST_ADD("cart_list","pce")
MCFG_FRAGMENT_ADD( pce_cdslot )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( tg16, pce_common )
MCFG_FRAGMENT_ADD( tg16_cartslot )
MCFG_TG16_CARTRIDGE_ADD("cartslot", pce_cart, NULL, NULL)
MCFG_SOFTWARE_LIST_ADD("cart_list","tg16")
MCFG_FRAGMENT_ADD( pce_cdslot )
MACHINE_CONFIG_END
@ -507,7 +474,10 @@ static MACHINE_CONFIG_START( sgx, pce_state )
MCFG_SOUND_ROUTE( 0, "lspeaker", 1.00 )
MCFG_SOUND_ROUTE( 1, "rspeaker", 1.00 )
MCFG_FRAGMENT_ADD( sgx_cartslot )
MCFG_PCE_CARTRIDGE_ADD("cartslot", pce_cart, NULL, NULL)
MCFG_SOFTWARE_LIST_ADD("cart_list","sgx")
MCFG_SOFTWARE_LIST_COMPATIBLE_ADD("pce_list","pce")
MCFG_FRAGMENT_ADD( pce_cdslot )
MACHINE_CONFIG_END
@ -518,7 +488,7 @@ MACHINE_CONFIG_END
***************************************************************************/
ROM_START( pce )
ROM_REGION( PCE_ROM_MAXSIZE, "user1", ROMREGION_ERASEFF ) /* Cartridge ROM area */
ROM_REGION( 0x100000, "maincpu", ROMREGION_ERASEFF )
ROM_END
#define rom_tg16 rom_pce

View File

@ -13,6 +13,7 @@
#include "cpu/h6280/h6280.h"
#include "sound/msm5205.h"
#include "machine/nvram.h"
#include "machine/pce_slot.h"
#include "video/huc6260.h"
#define C6280_TAG "c6280"
@ -20,8 +21,6 @@
#define MAIN_CLOCK 21477270
#define PCE_CD_CLOCK 9216000
#define PCE_HEADER_SIZE 512
#define TG_16_JOY_SIG 0x00
#define PCE_JOY_SIG 0x40
#define NO_CD_SIG 0x80
@ -29,8 +28,6 @@
/* these might be used to indicate something, but they always seem to return 1 */
#define CONST_SIG 0x30
/* the largest possible cartridge image (street fighter 2 - 2.5MB) */
#define PCE_ROM_MAXSIZE 0x280000
struct pce_cd_t
{
@ -114,7 +111,8 @@ public:
m_cd_ram(*this, "cd_ram"),
m_user_ram(*this, "user_ram"),
m_huc6260(*this, "huc6260"),
m_msm5205(*this, "msm5205")
m_msm5205(*this, "msm5205"),
m_cartslot(*this, "cartslot")
{ }
required_device<h6280_device> m_maincpu;
@ -122,16 +120,15 @@ public:
required_shared_ptr<UINT8> m_user_ram;
optional_device<huc6260_device> m_huc6260;
optional_device<msm5205_device> m_msm5205;
required_device<pce_cart_slot_device> m_cartslot;
UINT8 m_io_port_options;
UINT8 m_sys3_card;
UINT8 m_acard;
pce_cd_t m_cd;
UINT8 *m_cartridge_ram;
int m_joystick_port_select;
int m_joystick_data_select;
UINT8 m_joy_6b_packet[5];
DECLARE_WRITE8_MEMBER(pce_sf2_banking_w);
DECLARE_WRITE8_MEMBER(pce_cartridge_ram_w);
DECLARE_WRITE8_MEMBER(mess_pce_joystick_w);
DECLARE_READ8_MEMBER(mess_pce_joystick_r);
DECLARE_WRITE8_MEMBER(pce_cd_bram_w);
@ -155,7 +152,6 @@ public:
TIMER_CALLBACK_MEMBER(pce_cd_clear_ack);
TIMER_CALLBACK_MEMBER(pce_cd_adpcm_dma_timer_callback);
DECLARE_WRITE_LINE_MEMBER(pce_irq_changed);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(pce_cart);
};

View File

@ -118,150 +118,6 @@ static void pce_cd_init( running_machine &machine );
static void pce_cd_set_irq_line( running_machine &machine, int num, int state );
WRITE8_MEMBER(pce_state::pce_sf2_banking_w)
{
membank( "bank2" )->set_base( memregion("user1")->base() + offset * 0x080000 + 0x080000 );
membank( "bank3" )->set_base( memregion("user1")->base() + offset * 0x080000 + 0x088000 );
membank( "bank4" )->set_base( memregion("user1")->base() + offset * 0x080000 + 0x0D0000 );
}
WRITE8_MEMBER(pce_state::pce_cartridge_ram_w)
{
m_cartridge_ram[offset] = data;
}
DEVICE_IMAGE_LOAD_MEMBER(pce_state,pce_cart)
{
UINT32 size;
int split_rom = 0, offset = 0;
const char *extrainfo = NULL;
unsigned char *ROM;
logerror("*** DEVICE_IMAGE_LOAD(pce_cart) : %s\n", image.filename());
/* open file to get size */
ROM = memregion("user1")->base();
if (image.software_entry() == NULL)
size = image.length();
else
size = image.get_software_region_length("rom");
/* handle header accordingly */
if ((size / 512) & 1)
{
logerror("*** DEVICE_IMAGE_LOAD(pce_cart) : Header present\n");
size -= 512;
offset = 512;
}
if (size > PCE_ROM_MAXSIZE)
size = PCE_ROM_MAXSIZE;
if (image.software_entry() == NULL)
{
image.fseek(offset, SEEK_SET);
image.fread( ROM, size);
}
else
memcpy(ROM, image.get_software_region("rom") + offset, size);
if (extrainfo)
{
logerror("extrainfo: %s\n", extrainfo);
if (strstr(extrainfo, "ROM_SPLIT"))
split_rom = 1;
}
if (ROM[0x1fff] < 0xe0)
{
int i;
UINT8 decrypted[256];
logerror( "*** DEVICE_IMAGE_LOAD(pce_cart) : ROM image seems encrypted, decrypting...\n" );
/* Initialize decryption table */
for (i = 0; i < 256; i++)
decrypted[i] = ((i & 0x01) << 7) | ((i & 0x02) << 5) | ((i & 0x04) << 3) | ((i & 0x08) << 1) | ((i & 0x10) >> 1) | ((i & 0x20 ) >> 3) | ((i & 0x40) >> 5) | ((i & 0x80) >> 7);
/* Decrypt ROM image */
for (i = 0; i < size; i++)
ROM[i] = decrypted[ROM[i]];
}
/* check if we're dealing with a split rom image */
if (size == 384 * 1024)
{
split_rom = 1;
/* Mirror the upper 128KB part of the image */
memcpy(ROM + 0x060000, ROM + 0x040000, 0x020000); /* Set up 060000 - 07FFFF mirror */
}
/* set up the memory for a split rom image */
if (split_rom)
{
logerror("Split rom detected, setting up memory accordingly\n");
/* Set up ROM address space as follows: */
/* 000000 - 03FFFF : ROM data 000000 - 03FFFF */
/* 040000 - 07FFFF : ROM data 000000 - 03FFFF */
/* 080000 - 0BFFFF : ROM data 040000 - 07FFFF */
/* 0C0000 - 0FFFFF : ROM data 040000 - 07FFFF */
memcpy(ROM + 0x080000, ROM + 0x040000, 0x040000); /* Set up 080000 - 0BFFFF region */
memcpy(ROM + 0x0C0000, ROM + 0x040000, 0x040000); /* Set up 0C0000 - 0FFFFF region */
memcpy(ROM + 0x040000, ROM, 0x040000); /* Set up 040000 - 07FFFF region */
}
else
{
/* mirror 256KB rom data */
if (size <= 0x040000)
memcpy(ROM + 0x040000, ROM, 0x040000);
/* mirror 512KB rom data */
if (size <= 0x080000)
memcpy(ROM + 0x080000, ROM, 0x080000);
}
membank("bank1")->set_base(ROM);
membank("bank2")->set_base(ROM + 0x080000);
membank("bank3")->set_base(ROM + 0x088000);
membank("bank4")->set_base(ROM + 0x0d0000);
/* Check for Street fighter 2 */
if (size == PCE_ROM_MAXSIZE)
{
m_maincpu->space(AS_PROGRAM).install_write_handler(0x01ff0, 0x01ff3, write8_delegate(FUNC(pce_state::pce_sf2_banking_w),this));
}
/* Check for Populous */
if (!memcmp(ROM + 0x1F26, "POPULOUS", 8))
{
m_cartridge_ram = auto_alloc_array(machine(), UINT8, 0x8000);
membank("bank2")->set_base(m_cartridge_ram);
m_maincpu->space(AS_PROGRAM).install_write_handler(0x080000, 0x087FFF, write8_delegate(FUNC(pce_state::pce_cartridge_ram_w),this));
}
/* Check for CD system card */
m_sys3_card = 0;
if (!memcmp(ROM + 0x3FFB6, "PC Engine CD-ROM SYSTEM", 23))
{
/* Check if 192KB additional system card ram should be used */
if(!memcmp(ROM + 0x29D1, "VER. 3.", 7)) { m_sys3_card = 1; } // JP version
else if(!memcmp(ROM + 0x29C4, "VER. 3.", 7 )) { m_sys3_card = 3; } // US version
if(m_sys3_card)
{
m_cartridge_ram = auto_alloc_array(machine(), UINT8, 0x30000);
membank("bank4")->set_base(m_cartridge_ram);
m_maincpu->space(AS_PROGRAM).install_write_handler(0x0D0000, 0x0FFFFF, write8_delegate(FUNC(pce_state::pce_cartridge_ram_w),this));
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x080000, 0x087FFF, read8_delegate(FUNC(pce_state::pce_cd_acard_wram_r),this),write8_delegate(FUNC(pce_state::pce_cd_acard_wram_w),this));
}
}
return 0;
}
DRIVER_INIT_MEMBER(pce_state,mess_pce)
{
m_io_port_options = PCE_JOY_SIG | CONST_SIG;
@ -282,9 +138,8 @@ MACHINE_START_MEMBER(pce_state,pce)
pce_cd_init( machine() );
machine().device<nvram_device>("nvram")->set_base(m_cd.bram, PCE_BRAM_SIZE);
// *partial* saving (no cd items, no cart-specific items)
// *partial* saving (no cd items)
save_item(NAME(m_io_port_options));
save_item(NAME(m_sys3_card));
save_item(NAME(m_acard));
save_item(NAME(m_joystick_port_select));
save_item(NAME(m_joystick_data_select));
@ -314,6 +169,18 @@ MACHINE_RESET_MEMBER(pce_state,mess_pce)
/* Note: Arcade Card BIOS contents are the same as System 3, only internal HW differs.
We use a category to select between modes (some games can be run in either S-CD or A-CD modes) */
m_acard = ioport("A_CARD")->read() & 1;
if (m_cartslot->get_type() == PCE_CDSYS3J)
{
m_sys3_card = 1;
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x080000, 0x087fff, read8_delegate(FUNC(pce_state::pce_cd_acard_wram_r),this),write8_delegate(FUNC(pce_state::pce_cd_acard_wram_w),this));
}
if (m_cartslot->get_type() == PCE_CDSYS3U)
{
m_sys3_card = 3;
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x080000, 0x087fff, read8_delegate(FUNC(pce_state::pce_cd_acard_wram_r),this),write8_delegate(FUNC(pce_state::pce_cd_acard_wram_w),this));
}
}
/* todo: how many input ports does the PCE have? */

125
src/mess/machine/pce_rom.c Normal file
View File

@ -0,0 +1,125 @@
/***********************************************************************************************************
PC-Engine & Turbografx-16 cart emulation
***********************************************************************************************************/
#include "emu.h"
#include "machine/pce_rom.h"
//-------------------------------------------------
// pce_rom_device - constructor
//-------------------------------------------------
const device_type PCE_ROM_STD = &device_creator<pce_rom_device>;
const device_type PCE_ROM_CDSYS3 = &device_creator<pce_cdsys3_device>;
const device_type PCE_ROM_POPULOUS = &device_creator<pce_populous_device>;
const device_type PCE_ROM_SF2 = &device_creator<pce_sf2_device>;
pce_rom_device::pce_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_pce_cart_interface( mconfig, *this )
{
}
pce_rom_device::pce_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, PCE_ROM_STD, "PCE & TG16 Carts", tag, owner, clock, "pce_rom", __FILE__),
device_pce_cart_interface( mconfig, *this )
{
}
pce_cdsys3_device::pce_cdsys3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pce_rom_device(mconfig, PCE_ROM_CDSYS3, "PCE & TG16 CD-System Cart v3.00", tag, owner, clock, "pce_cdsys3", __FILE__)
{
}
pce_populous_device::pce_populous_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pce_rom_device(mconfig, PCE_ROM_POPULOUS, "PCE Populous Cart", tag, owner, clock, "pce_populous", __FILE__)
{
}
pce_sf2_device::pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pce_rom_device(mconfig, PCE_ROM_SF2, "PCE Street Fighters 2 Cart", tag, owner, clock, "pce_sf2", __FILE__)
{
}
//-------------------------------------------------
// mapper specific start/reset
//-------------------------------------------------
void pce_sf2_device::device_start()
{
save_item(NAME(m_bank_base));
}
void pce_sf2_device::device_reset()
{
m_bank_base = 0;
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
READ8_MEMBER(pce_rom_device::read_cart)
{
int bank = offset / 0x20000;
return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
}
READ8_MEMBER(pce_cdsys3_device::read_cart)
{
int bank = offset / 0x20000;
if (m_ram && offset >= 0xd0000)
return m_ram[offset];
return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
}
WRITE8_MEMBER(pce_cdsys3_device::write_cart)
{
if (m_ram && offset >= 0xd0000)
m_ram[offset] = data;
}
READ8_MEMBER(pce_populous_device::read_cart)
{
int bank = offset / 0x20000;
if (m_ram && offset >= 0x80000 && offset < 0x88000)
return m_ram[offset];
return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
}
WRITE8_MEMBER(pce_populous_device::write_cart)
{
if (m_ram && offset >= 0x80000 && offset < 0x88000)
m_ram[offset] = data;
}
READ8_MEMBER(pce_sf2_device::read_cart)
{
if (offset < 0x80000)
return m_rom[offset];
else
return m_rom[0x80000 + m_bank_base * 0x80000 + (offset & 0x7ffff)];
}
WRITE8_MEMBER(pce_sf2_device::write_cart)
{
if (offset >= 0x1ff0 && offset < 0x1ff4)
m_bank_base = offset & 3;
}

View File

@ -0,0 +1,83 @@
#ifndef __PCE_ROM_H
#define __PCE_ROM_H
#include "machine/pce_slot.h"
// ======================> pce_rom_device
class pce_rom_device : public device_t,
public device_pce_cart_interface
{
public:
// construction/destruction
pce_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);
pce_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start() {}
virtual void device_reset() {}
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart);
};
// ======================> pce_cdsys3_device
class pce_cdsys3_device : public pce_rom_device
{
public:
// construction/destruction
pce_cdsys3_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);
};
// ======================> pce_populous_device
class pce_populous_device : public pce_rom_device
{
public:
// construction/destruction
pce_populous_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);
};
// ======================> pce_sf2_device
class pce_sf2_device : public pce_rom_device
{
public:
// construction/destruction
pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start();
virtual void device_reset();
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart);
virtual DECLARE_WRITE8_MEMBER(write_cart);
private:
UINT8 m_bank_base;
};
// device type definition
extern const device_type PCE_ROM_STD;
extern const device_type PCE_ROM_CDSYS3;
extern const device_type PCE_ROM_POPULOUS;
extern const device_type PCE_ROM_SF2;
#endif

385
src/mess/machine/pce_slot.c Normal file
View File

@ -0,0 +1,385 @@
/***********************************************************************************************************
PC-Engine / Turbografx-16 cart emulation
(through slot devices)
***********************************************************************************************************/
#include "emu.h"
#include "machine/pce_slot.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type PCE_CART_SLOT = &device_creator<pce_cart_slot_device>;
//**************************************************************************
// PCE cartridges Interface
//**************************************************************************
//-------------------------------------------------
// device_pce_cart_interface - constructor
//-------------------------------------------------
device_pce_cart_interface::device_pce_cart_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device),
m_rom(NULL),
m_ram(NULL),
m_rom_size(0),
m_ram_size(0)
{
}
//-------------------------------------------------
// ~device_pce_cart_interface - destructor
//-------------------------------------------------
device_pce_cart_interface::~device_pce_cart_interface()
{
}
//-------------------------------------------------
// rom_alloc - alloc the space for the cart
//-------------------------------------------------
void device_pce_cart_interface::rom_alloc(running_machine &machine, UINT32 size)
{
if (m_rom == NULL)
{
m_rom = auto_alloc_array_clear(machine, UINT8, size);
m_rom_size = size;
}
}
//-------------------------------------------------
// ram_alloc - alloc the space for the ram
//-------------------------------------------------
void device_pce_cart_interface::ram_alloc(running_machine &machine, UINT32 size)
{
if (m_ram == NULL)
{
m_ram = auto_alloc_array_clear(machine, UINT8, size);
m_ram_size = size;
state_save_register_item_pointer(machine, "PCE_CART", this->device().tag(), 0, m_ram, m_ram_size);
}
}
//-------------------------------------------------
// rom_map_setup - setup map of rom banks in 128K
// blocks, so to simplify ROM access to mirror
//-------------------------------------------------
void device_pce_cart_interface::rom_map_setup(UINT32 size)
{
int i;
if (size == 0x60000)
{
// HuCard 384K are mapped with mirrored pieces
rom_bank_map[0] = 0;
rom_bank_map[1] = 1;
rom_bank_map[2] = 0;
rom_bank_map[3] = 1;
rom_bank_map[4] = 2;
rom_bank_map[5] = 2;
rom_bank_map[6] = 2;
rom_bank_map[7] = 2;
}
else
{
// setup the rom_bank_map array to faster ROM read
for (i = 0; i < size / 0x20000; i++)
rom_bank_map[i] = i;
// fill up remaining blocks with mirrors
while (i % 8)
{
int j = 0, repeat_banks;
while ((i % (8 >> j)) && j < 3)
j++;
repeat_banks = i % (8 >> (j - 1));
for (int k = 0; k < repeat_banks; k++)
rom_bank_map[i + k] = rom_bank_map[i + k - repeat_banks];
i += repeat_banks;
}
}
// check bank map!
// for (i = 0; i < 8; i++)
// {
// printf("bank %3d = %3d\t", i, rom_bank_map[i]);
// }
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// pce_cart_slot_device - constructor
//-------------------------------------------------
pce_cart_slot_device::pce_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, PCE_CART_SLOT, "PCE & TG16 Cartridge Slot", tag, owner, clock),
device_image_interface(mconfig, *this),
device_slot_interface(mconfig, *this),
m_interface("pce_cart"),
m_type(PCE_STD)
{
}
//-------------------------------------------------
// pce_cart_slot_device - destructor
//-------------------------------------------------
pce_cart_slot_device::~pce_cart_slot_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void pce_cart_slot_device::device_start()
{
m_cart = dynamic_cast<device_pce_cart_interface *>(get_card_device());
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void pce_cart_slot_device::device_config_complete()
{
// set brief and instance name
update_names();
}
//-------------------------------------------------
// PCE PCB
//-------------------------------------------------
struct pce_slot
{
int pcb_id;
const char *slot_option;
};
// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
static const pce_slot slot_list[] =
{
{ PCE_STD, "rom" },
{ PCE_CDSYS3U, "cdsys3u" },
{ PCE_CDSYS3J, "cdsys3j" },
{ PCE_POPULOUS, "populous" },
{ PCE_SF2, "sf2" },
};
static int pce_get_pcb_id(const char *slot)
{
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
{
if (!mame_stricmp(slot_list[i].slot_option, slot))
return slot_list[i].pcb_id;
}
return 0;
}
static const char *pce_get_slot(int type)
{
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
{
if (slot_list[i].pcb_id == type)
return slot_list[i].slot_option;
}
return "rom";
}
/*-------------------------------------------------
call load
-------------------------------------------------*/
bool pce_cart_slot_device::call_load()
{
if (m_cart)
{
UINT32 offset = 0;
UINT32 len = (software_entry() == NULL) ? length() : get_software_region_length("rom");
UINT8 *ROM;
// From fullpath, check for presence of a header and skip it
if (software_entry() == NULL && (len % 0x4000) == 512)
{
logerror("Rom-header found, skipping\n");
offset = 512;
len -= offset;
fseek(offset, SEEK_SET);
}
m_cart->rom_alloc(machine(), len);
ROM = m_cart->get_rom_base();
if (software_entry() == NULL)
fread(ROM, len);
else
memcpy(ROM, get_software_region("rom"), len);
// check for encryption (US carts)
if (ROM[0x1fff] < 0xe0)
{
UINT8 decrypted[256];
/* Initialize decryption table */
for (int i = 0; i < 256; i++)
decrypted[i] = ((i & 0x01) << 7) | ((i & 0x02) << 5) | ((i & 0x04) << 3) | ((i & 0x08) << 1) | ((i & 0x10) >> 1) | ((i & 0x20 ) >> 3) | ((i & 0x40) >> 5) | ((i & 0x80) >> 7);
/* Decrypt ROM image */
for (int i = 0; i < len; i++)
ROM[i] = decrypted[ROM[i]];
}
m_cart->rom_map_setup(len);
if (software_entry() == NULL)
m_type = get_cart_type(ROM, len);
else
{
const char *pcb_name = get_feature("slot");
if (pcb_name)
m_type = pce_get_pcb_id(pcb_name);
}
//printf("Type: %s\n", pce_get_slot(m_type));
if (m_type == PCE_POPULOUS)
m_cart->ram_alloc(machine(), 0x8000);
if (m_type == PCE_CDSYS3J || m_type == PCE_CDSYS3U)
m_cart->ram_alloc(machine(), 0x30000);
return IMAGE_INIT_PASS;
}
return IMAGE_INIT_PASS;
}
/*-------------------------------------------------
call_unload
-------------------------------------------------*/
void pce_cart_slot_device::call_unload()
{
}
/*-------------------------------------------------
call softlist load
-------------------------------------------------*/
bool pce_cart_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
{
load_software_part_region(this, swlist, swname, start_entry );
return TRUE;
}
/*-------------------------------------------------
get_cart_type - code to detect NVRAM type from
fullpath
-------------------------------------------------*/
int pce_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
{
int type = PCE_STD;
/* Check for Street fighter 2 */
if (len == 0x280000)
type = PCE_SF2;
/* Check for Populous */
if (len >= 0x1f26 + 8 && !memcmp(ROM + 0x1f26, "POPULOUS", 8))
type = PCE_POPULOUS;
// Check for CD system card v3 which adds on-cart RAM to the system
if (!memcmp(ROM + 0x3FFB6, "PC Engine CD-ROM SYSTEM", 23))
{
/* Check if 192KB additional system card ram should be used */
if(!memcmp(ROM + 0x29D1, "VER. 3.", 7)) { type = PCE_CDSYS3J; } // JP version
else if(!memcmp(ROM + 0x29C4, "VER. 3.", 7 )) { type = PCE_CDSYS3U; } // US version
}
return type;
}
/*-------------------------------------------------
get default card software
-------------------------------------------------*/
const char * pce_cart_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
{
if (open_image_file(options))
{
const char *slot_string = "rom";
UINT32 len = core_fsize(m_file);
UINT8 *ROM = global_alloc_array(UINT8, len);
int type;
core_fread(m_file, ROM, len);
type = get_cart_type(ROM, len);
slot_string = pce_get_slot(type);
//printf("type: %s\n", slot_string);
global_free(ROM);
clear();
return slot_string;
}
return software_get_default_slot(config, options, this, "rom");
}
/*-------------------------------------------------
read
-------------------------------------------------*/
READ8_MEMBER(pce_cart_slot_device::read_cart)
{
if (m_cart)
return m_cart->read_cart(space, offset);
else
return 0xff;
}
/*-------------------------------------------------
write
-------------------------------------------------*/
WRITE8_MEMBER(pce_cart_slot_device::write_cart)
{
if (m_cart)
m_cart->write_cart(space, offset, data);
}
/*-------------------------------------------------
Internal header logging
-------------------------------------------------*/
void pce_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len)
{
}

126
src/mess/machine/pce_slot.h Normal file
View File

@ -0,0 +1,126 @@
#ifndef __PCE_SLOT_H
#define __PCE_SLOT_H
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
/* PCB */
enum
{
PCE_STD = 0,
PCE_CDSYS3J,
PCE_CDSYS3U,
PCE_POPULOUS,
PCE_SF2
};
// ======================> device_pce_cart_interface
class device_pce_cart_interface : public device_slot_card_interface
{
public:
// construction/destruction
device_pce_cart_interface(const machine_config &mconfig, device_t &device);
virtual ~device_pce_cart_interface();
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart) { return 0xff; }
virtual DECLARE_WRITE8_MEMBER(write_cart) {};
void rom_alloc(running_machine &machine, UINT32 size);
void ram_alloc(running_machine &machine, UINT32 size);
UINT8* get_rom_base() { return m_rom; }
UINT8* get_ram_base() { return m_ram; }
UINT32 get_rom_size() { return m_rom_size; }
UINT32 get_ram_size() { return m_ram_size; }
// internal state
UINT8 *m_rom;
UINT8 *m_ram;
UINT32 m_rom_size;
UINT32 m_ram_size;
void rom_map_setup(UINT32 size);
UINT8 rom_bank_map[8]; // 128K chunks of rom
};
// ======================> pce_cart_slot_device
class pce_cart_slot_device : public device_t,
public device_image_interface,
public device_slot_interface
{
public:
// construction/destruction
pce_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~pce_cart_slot_device();
// device-level overrides
virtual void device_start();
virtual void device_config_complete();
// image-level overrides
virtual bool call_load();
virtual void call_unload();
virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
int get_type() { return m_type; }
int get_cart_type(UINT8 *ROM, UINT32 len);
void setup_ram(UINT8 banks);
void internal_header_logging(UINT8 *ROM, UINT32 len);
void set_intf(const char * interface) { m_interface = interface; }
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
virtual bool is_readable() const { return 1; }
virtual bool is_writeable() const { return 0; }
virtual bool is_creatable() const { return 0; }
virtual bool must_be_loaded() const { return 1; }
virtual bool is_reset_on_load() const { return 1; }
virtual const option_guide *create_option_guide() const { return NULL; }
virtual const char *image_interface() const { return m_interface; }
virtual const char *file_extensions() const { return "pce,bin"; }
// slot interface overrides
virtual const char * get_default_card_software(const machine_config &config, emu_options &options);
// reading and writing
virtual DECLARE_READ8_MEMBER(read_cart);
virtual DECLARE_WRITE8_MEMBER(write_cart);
protected:
const char *m_interface;
int m_type;
device_pce_cart_interface* m_cart;
};
// device type definition
extern const device_type PCE_CART_SLOT;
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MCFG_PCE_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
MCFG_DEVICE_ADD(_tag, PCE_CART_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) \
static_cast<pce_cart_slot_device *>(device)->set_intf("pce_cart");
#define MCFG_TG16_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot,_def_inp) \
MCFG_DEVICE_ADD(_tag, PCE_CART_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _def_inp, false) \
static_cast<pce_cart_slot_device *>(device)->set_intf("tg16_cart");
#endif

View File

@ -1381,6 +1381,8 @@ $(MESSOBJ)/ne.a: \
$(MESSOBJ)/nec.a: \
$(MESS_DRIVERS)/apc.o \
$(MESS_MACHINE)/pce.o \
$(MESS_MACHINE)/pce_slot.o \
$(MESS_MACHINE)/pce_rom.o \
$(MESS_DRIVERS)/pce.o \
$(MESS_DRIVERS)/pcfx.o \
$(MESS_DRIVERS)/pc6001.o \