gba.cpp: Added preliminary support for the 3D Matrix Memory

Controller used by 64MB video cartridges. Disney Collection 2
works, while other dumps still fail (possibly due to reason
unrelated to the mapper emulation...) [Fabio Priuli]
This commit is contained in:
etabeta78 2016-05-17 12:35:54 +02:00
parent df5c8faa85
commit 6e43812f60
6 changed files with 130 additions and 8 deletions

View File

@ -15503,13 +15503,13 @@ Note: In the AGB-E05-XX and AGB-E06-XX pcbs, the chip name is hidden under the b
</part>
</software>
<!-- This uses an unemulated mapper -->
<software name="v_dccol2" supported="no">
<software name="v_dccol2">
<description>Game Boy Advance Video - Disney Channel Collection - Volume 2 (USA)</description>
<year>2004?</year>
<publisher>Majesco</publisher>
<info name="serial" value="AGB-MDSE-USA"/>
<part name="cart" interface="gba_cart">
<feature name="slot" value="gba_3dmatrix" />
<dataarea name="rom" size="67108864">
<rom name="disney channel collection - volume 2 (agb-mdse-usa).bin" size="67108864" crc="60dfd79c" sha1="864ce0db324b1252df923804f8c6e812d5ebcbba" offset="0" />
</dataarea>
@ -15612,52 +15612,52 @@ Note: In the AGB-E05-XX and AGB-E06-XX pcbs, the chip name is hidden under the b
</part>
</software>
<!-- This uses an unemulated mapper -->
<software name="v_shrek" supported="no">
<description>Game Boy Advance Video - Shrek (USA)</description>
<year>2004?</year>
<publisher>Nintendo</publisher>
<info name="serial" value="AGB-MSKE-USA"/>
<part name="cart" interface="gba_cart">
<feature name="slot" value="gba_3dmatrix" />
<dataarea name="rom" size="67108864">
<rom name="shrek-mske.bin" size="67108864" crc="690176e5" sha1="2dedea86ec289a0e31089299613d9f74cca03609" offset="000000" />
</dataarea>
</part>
</software>
<!-- This uses an unemulated mapper -->
<software name="v_shrek2" supported="no">
<description>Game Boy Advance Video - Shrek 2 (USA)</description>
<year>2004?</year>
<publisher>Nintendo</publisher>
<info name="serial" value="AGB-M2SE-USA"/>
<part name="cart" interface="gba_cart">
<feature name="slot" value="gba_3dmatrix" />
<dataarea name="rom" size="67108864">
<rom name="shrek2-m2se.bin" size="67108864" crc="0d353654" sha1="5cd627e205020297b25d707131883be5850515fe" offset="000000" />
</dataarea>
</part>
</software>
<!-- This uses an unemulated mapper -->
<software name="v_sharkt" supported="no">
<description>Game Boy Advance Video - Shark Tale (USA, Rev. 6)</description>
<year>2004?</year>
<publisher>Nintendo</publisher>
<info name="serial" value="AGB-MSAE-USA"/>
<part name="cart" interface="gba_cart">
<feature name="slot" value="gba_3dmatrix" />
<dataarea name="rom" size="67108864">
<rom name="sharkstale-msae.bin" size="67108864" crc="d2cf417a" sha1="9bc5b60793b8a6de3b80eb2c213cd125e1fa468e" offset="000000" />
</dataarea>
</part>
</software>
<!-- This uses an unemulated mapper -->
<software name="v_sharkta" cloneof="v_sharkt" supported="no">
<description>Game Boy Advance Video - Shark Tale (USA, Rev. 5)</description>
<year>2004?</year>
<publisher>Nintendo</publisher>
<info name="serial" value="AGB-MSAE-USA"/>
<part name="cart" interface="gba_cart">
<feature name="slot" value="gba_3dmatrix" />
<dataarea name="rom" size="67108864">
<rom name="shark tale (agb-msae-usa).bin" size="67108864" crc="01468820" sha1="6128a476edb10e6839ac5bd2697e83b9b7a9b234" offset="0" />
</dataarea>

View File

@ -54,7 +54,10 @@ void device_gba_cart_interface::rom_alloc(UINT32 size, const char *tag)
// we always alloc 32MB of rom region!
m_rom = (UINT32 *)device().machine().memory().region_alloc(std::string(tag).append(GBASLOT_ROM_REGION_TAG).c_str(), 0x2000000, 4, ENDIANNESS_LITTLE)->base();
else
{
m_rom = (UINT32 *)device().machine().memory().region_alloc(std::string(tag).append(GBASLOT_ROM_REGION_TAG).c_str(), 0x4000000, 4, ENDIANNESS_LITTLE)->base();
m_romhlp = (UINT32 *)device().machine().memory().region_alloc(std::string(tag).append(GBAHELP_ROM_REGION_TAG).c_str(), 0x2000000, 4, ENDIANNESS_LITTLE)->base();
}
m_rom_size = size;
}
}
@ -137,6 +140,7 @@ static const gba_slot slot_list[] =
{ GBA_FLASH, "gba_flash" },
{ GBA_FLASH512, "gba_flash_512" },
{ GBA_FLASH1M, "gba_flash_1m" },
{ GBA_3DMATRIX, "gba_3dmatrix" },
};
static int gba_get_pcb_id(const char *slot)
@ -219,6 +223,8 @@ bool gba_cart_slot_device::call_load()
memcpy(ROM + 0x1000000, ROM, 0x1000000);
break;
}
if (size == 0x4000000)
memcpy((UINT8 *)m_cart->get_romhlp_base(), ROM, 0x2000000);
if (m_cart->get_nvram_size())
battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0x00);
@ -397,6 +403,9 @@ int gba_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
break;
}
if (len == 0x4000000)
type = GBA_3DMATRIX;
return type;
}
/*-------------------------------------------------

View File

@ -18,7 +18,8 @@ enum
GBA_EEPROM64,
GBA_FLASH,
GBA_FLASH512,
GBA_FLASH1M
GBA_FLASH1M,
GBA_3DMATRIX
};
@ -35,12 +36,15 @@ public:
virtual DECLARE_READ32_MEMBER(read_rom) { return 0xffffffff; }
virtual DECLARE_READ32_MEMBER(read_ram) { return 0xffffffff; }
virtual DECLARE_WRITE32_MEMBER(write_ram) {};
virtual DECLARE_WRITE32_MEMBER(write_mapper) {};
void rom_alloc(UINT32 size, const char *tag);
void nvram_alloc(UINT32 size);
UINT32* get_rom_base() { return m_rom; }
UINT32* get_romhlp_base() { return m_romhlp; }
UINT32* get_nvram_base() { return &m_nvram[0]; }
UINT32 get_rom_size() { return m_rom_size; }
UINT32 get_romhlp_size() { return m_romhlp_size; }
UINT32 get_nvram_size() { return m_nvram.size()*sizeof(UINT32); }
void set_rom_size(UINT32 val) { m_rom_size = val; }
@ -49,6 +53,8 @@ public:
// internal state
UINT32 *m_rom; // this points to the cart rom region
UINT32 m_rom_size; // this is the actual game size, not the rom region size!
UINT32 *m_romhlp;
UINT32 m_romhlp_size;
std::vector<UINT32> m_nvram;
};
@ -98,6 +104,7 @@ public:
virtual DECLARE_READ32_MEMBER(read_rom);
virtual DECLARE_READ32_MEMBER(read_ram);
virtual DECLARE_WRITE32_MEMBER(write_ram);
virtual DECLARE_WRITE32_MEMBER(write_mapper) { if (m_cart) return m_cart->write_mapper(space, offset, data, mem_mask); };
protected:
@ -117,6 +124,7 @@ extern const device_type GBA_CART_SLOT;
***************************************************************************/
#define GBASLOT_ROM_REGION_TAG ":cart:rom"
#define GBAHELP_ROM_REGION_TAG ":cart:romhlp"
#define MCFG_GBA_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
MCFG_DEVICE_ADD(_tag, GBA_CART_SLOT, 0) \

View File

@ -27,6 +27,7 @@ const device_type GBA_ROM_EEPROM = &device_creator<gba_rom_eeprom_device>;
const device_type GBA_ROM_EEPROM64 = &device_creator<gba_rom_eeprom64_device>;
const device_type GBA_ROM_FLASH = &device_creator<gba_rom_flash_device>;
const device_type GBA_ROM_FLASH1M = &device_creator<gba_rom_flash1m_device>;
const device_type GBA_ROM_3DMATRIX = &device_creator<gba_rom_3dmatrix_device>;
gba_rom_device::gba_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)
@ -68,6 +69,11 @@ gba_rom_flash1m_device::gba_rom_flash1m_device(const machine_config &mconfig, co
{
}
gba_rom_3dmatrix_device::gba_rom_3dmatrix_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: gba_rom_device(mconfig, GBA_ROM_3DMATRIX, "GBA Carts + 3D Matrix Memory Mapper", tag, owner, clock, "gba_3dmatrix", __FILE__)
{
}
//-------------------------------------------------
// mapper specific start/reset
@ -106,6 +112,20 @@ void gba_rom_eeprom64_device::device_start()
m_eeprom = std::make_unique<gba_eeprom_device>(machine(), (UINT8*)get_nvram_base(), get_nvram_size(), 14);
}
void gba_rom_3dmatrix_device::device_start()
{
save_item(NAME(m_src));
save_item(NAME(m_dst));
save_item(NAME(m_nblock));
}
void gba_rom_3dmatrix_device::device_reset()
{
m_src = 0;
m_dst = 0;
m_nblock = 0;
}
/*-------------------------------------------------
mapper specific handlers
@ -436,3 +456,58 @@ WRITE32_MEMBER(gba_rom_eeprom64_device::write_ram)
m_eeprom->write(data);
}
/*-------------------------------------------------
Carts with 3D Matrix Memory controller
Used by Video carts with 64MB ROM chips
Emulation based on the reverse engineering efforts
by endrift
The Memory controller basically behaves like a DMA
chip by writing first source and destination address,
then the number of 512K blocks to copy and finally
by issuing the transfer command.
Disney Collection 2 carts uses command 0x01 to start
the transfer, other carts might use 0x11 but currently
they die before getting to the mapper communication
(CPU emulation issue? cart mapping issue? still unknown)
To investigate:
- why the other carts fail
- which addresses might be used by the mapper
(Disney Collection 2 uses 0x08800180-0x0880018f
but it might well be possible to issue commands
in an extended range...)
- which bus addresses can be used by the mapper
(currently we restrict the mapping in the range
0x08000000-0x09ffffff but maybe also the rest of
the cart "range" is accessible...)
-------------------------------------------------*/
WRITE32_MEMBER(gba_rom_3dmatrix_device::write_mapper)
{
//printf("mapper write 0x%.8X - 0x%X\n", offset, data);
switch (offset & 3)
{
case 0:
if (data == 0x1) // transfer data
memcpy((UINT8 *)m_romhlp + m_dst, (UINT8 *)m_rom + m_src, m_nblock * 0x200);
else
printf("Unknown mapper command 0x%X\n", data);
break;
case 1:
m_src = data;
break;
case 2:
if (data >= 0xa000000)
printf("Unknown transfer destination 0x%X\n", data);
m_dst = (data & 0x1ffffff);
break;
case 3:
default:
m_nblock = data;
break;
}
}

View File

@ -161,6 +161,26 @@ private:
};
// ======================> gba_rom_3dmatrix_device
class gba_rom_3dmatrix_device : public gba_rom_device
{
public:
// construction/destruction
gba_rom_3dmatrix_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// reading and writing
virtual DECLARE_WRITE32_MEMBER(write_mapper) override;
private:
UINT32 m_src, m_dst, m_nblock;
};
// device type definition
extern const device_type GBA_ROM_STD;
extern const device_type GBA_ROM_SRAM;
@ -168,6 +188,7 @@ extern const device_type GBA_ROM_EEPROM;
extern const device_type GBA_ROM_EEPROM64;
extern const device_type GBA_ROM_FLASH;
extern const device_type GBA_ROM_FLASH1M;
extern const device_type GBA_ROM_3DMATRIX;

View File

@ -2109,7 +2109,7 @@ void gba_state::machine_start()
m_maincpu->space(AS_PROGRAM).install_read_bank(0x08000000, 0x09ffffff, 0, 0, "rom1");
m_maincpu->space(AS_PROGRAM).install_read_bank(0x0a000000, 0x0bffffff, 0, 0, "rom2");
m_maincpu->space(AS_PROGRAM).install_read_bank(0x0c000000, 0x0cffffff, 0, 0, "rom3");
std::string region_tag;
memory_region *cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GBASLOT_ROM_REGION_TAG).c_str());
@ -2118,6 +2118,7 @@ void gba_state::machine_start()
membank("rom2")->set_base(cart_rom->base());
membank("rom3")->set_base(cart_rom->base());
// add nvram to save state
m_cart->save_nvram();
@ -2144,6 +2145,13 @@ void gba_state::machine_start()
m_maincpu->space(AS_PROGRAM).install_read_handler(0xe000000, 0xe01ffff, read32_delegate(FUNC(gba_cart_slot_device::read_ram),(gba_cart_slot_device*)m_cart));
m_maincpu->space(AS_PROGRAM).install_write_handler(0xe000000, 0xe01ffff, write32_delegate(FUNC(gba_cart_slot_device::write_ram),(gba_cart_slot_device*)m_cart));
}
if (m_cart->get_type() == GBA_3DMATRIX)
{
m_maincpu->space(AS_PROGRAM).install_write_handler(0x08800000, 0x088001ff, write32_delegate(FUNC(gba_cart_slot_device::write_mapper),(gba_cart_slot_device*)m_cart));
memory_region *cart_romhlp = memregion(region_tag.assign(m_cart->tag()).append(GBAHELP_ROM_REGION_TAG).c_str());
membank("rom1")->set_base(cart_romhlp->base());
}
}
save_item(NAME(m_DISPSTAT));
@ -2245,6 +2253,7 @@ static SLOT_INTERFACE_START(gba_cart)
SLOT_INTERFACE_INTERNAL("gba_flash", GBA_ROM_FLASH) // Panasonic
SLOT_INTERFACE_INTERNAL("gba_flash_512", GBA_ROM_FLASH) // Panasonic
SLOT_INTERFACE_INTERNAL("gba_flash_1m", GBA_ROM_FLASH1M) // Sanyo
SLOT_INTERFACE_INTERNAL("gba_3dmatrix", GBA_ROM_3DMATRIX)
SLOT_INTERFACE_END