summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/gba
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 /src/devices/bus/gba
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]
Diffstat (limited to 'src/devices/bus/gba')
-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
4 files changed, 114 insertions, 1 deletions
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;