summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author etabeta78 <doge.fabio@gmail.com>2016-05-17 12:35:54 +0200
committer etabeta78 <doge.fabio@gmail.com>2016-05-17 12:35:54 +0200
commit6e43812f6032b779d5732e166b09e630cd115efc (patch)
treecad06591dadf186ca081cdf69d81d28b9daa7f48
parentdf5c8faa8594fbbab71a2f31ce6636b996d44c41 (diff)
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]
-rw-r--r--hash/gba.xml12
-rw-r--r--src/devices/bus/gba/gba_slot.cpp9
-rw-r--r--src/devices/bus/gba/gba_slot.h10
-rw-r--r--src/devices/bus/gba/rom.cpp75
-rw-r--r--src/devices/bus/gba/rom.h21
-rw-r--r--src/mame/drivers/gba.cpp11
6 files changed, 130 insertions, 8 deletions
diff --git a/hash/gba.xml b/hash/gba.xml
index 516975a1b92..bb0e67d0abc 100644
--- a/hash/gba.xml
+++ b/hash/gba.xml
@@ -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>
diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp
index b32c6c21af4..5ed54717275 100644
--- a/src/devices/bus/gba/gba_slot.cpp
+++ b/src/devices/bus/gba/gba_slot.cpp
@@ -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;
}
/*-------------------------------------------------
diff --git a/src/devices/bus/gba/gba_slot.h b/src/devices/bus/gba/gba_slot.h
index 11810ecd960..a3908730180 100644
--- a/src/devices/bus/gba/gba_slot.h
+++ b/src/devices/bus/gba/gba_slot.h
@@ -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) \
diff --git a/src/devices/bus/gba/rom.cpp b/src/devices/bus/gba/rom.cpp
index 8e857dfe004..b4b2899024f 100644
--- a/src/devices/bus/gba/rom.cpp
+++ b/src/devices/bus/gba/rom.cpp
@@ -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;
+ }
+}
diff --git a/src/devices/bus/gba/rom.h b/src/devices/bus/gba/rom.h
index f9a3c16cb2e..b43875af862 100644
--- a/src/devices/bus/gba/rom.h
+++ b/src/devices/bus/gba/rom.h
@@ -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;
diff --git a/src/mame/drivers/gba.cpp b/src/mame/drivers/gba.cpp
index 5998a83d2c2..64620d1f156 100644
--- a/src/mame/drivers/gba.cpp
+++ b/src/mame/drivers/gba.cpp
@@ -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