diff options
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 |
commit | 6e43812f6032b779d5732e166b09e630cd115efc (patch) | |
tree | cad06591dadf186ca081cdf69d81d28b9daa7f48 /src/devices/bus/gba | |
parent | df5c8faa8594fbbab71a2f31ce6636b996d44c41 (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.cpp | 9 | ||||
-rw-r--r-- | src/devices/bus/gba/gba_slot.h | 10 | ||||
-rw-r--r-- | src/devices/bus/gba/rom.cpp | 75 | ||||
-rw-r--r-- | src/devices/bus/gba/rom.h | 21 |
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; |