From 0169416ae394fd203a455ac3c9711a2b2fc2529e Mon Sep 17 00:00:00 2001 From: etabeta78 Date: Mon, 6 Jun 2016 18:31:27 +0200 Subject: [PATCH] =?UTF-8?q?gba.cpp:=20several=20improvements=20[Fabio=20Pr?= =?UTF-8?q?iuli]=20=20=20-=20Implemented=20emulation=20of=20the=20=20"Gene?= =?UTF-8?q?ral=20Purpose=20I/O"=20=20=20=20=20=20port=20(GPIO)=20of=20GBA.?= =?UTF-8?q?=20=20=20-=20Hooked=20up=20S-3511=20RTC=20emulation=20through?= =?UTF-8?q?=20the=20GPIO=20=20=20=20=20port.=20This=20allows=20to=20avoid?= =?UTF-8?q?=20the=20"Internal=20battery=20has=20run=20=20=20=20=20dry=20[.?= =?UTF-8?q?..]=20clock-based=20events=20will=20no=20longer=20occur"=20=20?= =?UTF-8?q?=20=20=20messages=20in=20Pok=C3=A9mon=20Emerald=20/=20Ruby=20/?= =?UTF-8?q?=20Sapphire.=20This=20=20=20=20=20also=20promotes=20Sennen=20Ka?= =?UTF-8?q?zoku=20to=20working=20state.=20=20=20-=20Hooked=20up=20Boktai?= =?UTF-8?q?=20Light=20Sensor=20emulation=20through=20the=20=20=20=20=20GPI?= =?UTF-8?q?O=20port.=20This=20allows=20to=20avoid=20the=20"Solar=20Sensor?= =?UTF-8?q?=20is=20broken"=20=20=20=20=20message=20in=20Boktai=20/=20Bokur?= =?UTF-8?q?a=20no=20Taiyou,=20which=20is=20now=20=20=20=20=20playable=20an?= =?UTF-8?q?d=20to=20recharge=20your=20weapons=20in=20all=20three=20games?= =?UTF-8?q?=20=20=20=20=20of=20the=20series.=20Light=20level=20has=20to=20?= =?UTF-8?q?be=20chosen=20via=20the=20"Machine=20=20=20=20=20Configuration"?= =?UTF-8?q?=20menu,=20until=20we=20get=20some=20kind=20of=20camera=20=20?= =?UTF-8?q?=20=20=20input.=20=20=20-=20Hooked=20up=20Warioware=20Twist=20G?= =?UTF-8?q?yroscope=20emulation=20=20=20=20=20through=20the=20GPIO=20port.?= =?UTF-8?q?=20This=20allows=20to=20play=20the=20minigames,=20=20=20=20=20e?= =?UTF-8?q?ven=20if=20in=20some=20case=20the=20input=20sensibility=20might?= =?UTF-8?q?=20need=20a=20=20=20=20=20few=20tweaks.=20=20=20-=20Hooked=20up?= =?UTF-8?q?=20Warioware=20Twist=20&=20Drill=20Dozer=20Rumble=20=20=20=20?= =?UTF-8?q?=20emulation=20through=20the=20GPIO=20port.=20MAME=20will=20now?= =?UTF-8?q?=20output=20=20=20=20=20a=20"Rumble"=20output=20bit=20(0=20for?= =?UTF-8?q?=20Rumble=3DOFF=20and=201=20for=20=20=20=20=20Rumble=3DON)=20wh?= =?UTF-8?q?enever=20the=20games=20try=20to=20access=20the=20Rumble=20=20?= =?UTF-8?q?=20=20=20component=E2=80=A6=20third=20party=20applications=20ca?= =?UTF-8?q?n=20now=20listen=20to=20the=20=20=20=20=20output=20and=20redire?= =?UTF-8?q?ct=20it=20to=20some=20hardware=20that=20can=20"rumble"=20=20=20?= =?UTF-8?q?=20=20in=20sync=20with=20the=20gameplay.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gba.cpp: implemented emulation of the Tilt sensor used by Yoshi’s Universal Gravitation / Yoshi Topsy-Turvy / Yoshi no Banyuuinryoku (and by Koro Koro Puzzle). Note that the calibration can seem a bit tricky at first, because the emulated screen does not turn as the GBA would... In order to properly calibrate the sensor, just keep pressed right for a few seconds when requested to calibrate right inclination (first calibration screen in Yoshi Universal Gravitation) so to get the full right range; then keep pressed for left for a few seconds when requested to calibrate left inclination (second calibration screen in Yoshi Universal Gravitation) so to get the full left range. [Fabio Priuli] --- hash/gba.xml | 110 ++-- src/devices/bus/gba/gba_slot.cpp | 47 +- src/devices/bus/gba/gba_slot.h | 29 +- src/devices/bus/gba/rom.cpp | 892 +++++++++++++++++++++++++------ src/devices/bus/gba/rom.h | 321 ++++++++--- src/mame/drivers/gba.cpp | 43 +- 6 files changed, 1142 insertions(+), 300 deletions(-) diff --git a/hash/gba.xml b/hash/gba.xml index 8d66d4da16a..e17a0abcbb0 100644 --- a/hash/gba.xml +++ b/hash/gba.xml @@ -3221,7 +3221,7 @@ - + @@ -3233,7 +3233,7 @@ 2003 Konami - + @@ -3246,7 +3246,7 @@ Konami - + @@ -3259,7 +3259,7 @@ Konami - + @@ -3272,7 +3272,7 @@ Konami - + @@ -3339,7 +3339,7 @@ - + @@ -8504,7 +8504,7 @@ Nintendo - + @@ -17557,7 +17557,7 @@ - + @@ -20131,7 +20131,7 @@ - + @@ -25144,7 +25144,7 @@ - + @@ -25222,7 +25222,7 @@ - + @@ -25242,7 +25242,7 @@ - + @@ -25319,7 +25319,7 @@ - + @@ -25331,7 +25331,7 @@ 2004 Nintendo - + @@ -25343,7 +25343,7 @@ 2004 Nintendo - + @@ -25355,7 +25355,7 @@ 2004 Nintendo - + @@ -25373,7 +25373,7 @@ - + @@ -25546,7 +25546,7 @@ Nintendo - + @@ -25564,7 +25564,7 @@ - + @@ -25577,7 +25577,7 @@ Nintendo - + @@ -25589,7 +25589,7 @@ 2003 Nintendo - + @@ -25601,7 +25601,7 @@ 2003 Nintendo - + @@ -25613,7 +25613,7 @@ 2003 Nintendo - + @@ -25625,7 +25625,7 @@ 2003 Nintendo - + @@ -25643,7 +25643,7 @@ - + @@ -25655,7 +25655,7 @@ 2003 Nintendo - + @@ -25667,7 +25667,7 @@ 2003 Nintendo - + @@ -25679,7 +25679,7 @@ 2003 Nintendo - + @@ -25691,7 +25691,7 @@ 2003 Nintendo - + @@ -25704,7 +25704,7 @@ Nintendo - + @@ -25722,7 +25722,7 @@ - + @@ -25735,7 +25735,7 @@ Nintendo - + @@ -25747,7 +25747,7 @@ 2003 Nintendo - + @@ -25759,7 +25759,7 @@ 2003 Nintendo - + @@ -25771,7 +25771,7 @@ 2003 Nintendo - + @@ -25783,7 +25783,7 @@ 2003 Nintendo - + @@ -25795,7 +25795,7 @@ 2003 Nintendo - + @@ -25807,7 +25807,7 @@ 2003 Nintendo - + @@ -25819,7 +25819,7 @@ 2003 Nintendo - + @@ -25831,7 +25831,7 @@ 2003 Nintendo - + @@ -27789,7 +27789,7 @@ - + @@ -28594,7 +28594,7 @@ - + @@ -28824,7 +28824,7 @@ - + Sennen Kazoku (Jpn) 2005 Nintendo @@ -28837,7 +28837,7 @@ - + @@ -29181,7 +29181,7 @@ - + Shin Bokura no Taiyou - Gyakushuu no Sabata (Jpn) 2005 Konami @@ -29189,7 +29189,7 @@ - + @@ -36155,7 +36155,7 @@ The cart also contained a non-empty SRAM save which we currently include in the - + @@ -37054,20 +37054,20 @@ The cart also contained a non-empty SRAM save which we currently include in the - + Yoshi - Topsy-Turvy (USA) 2005 Nintendo - + - + Yoshi no Banyuuinryoku (Jpn) 2004 Nintendo @@ -37075,14 +37075,14 @@ The cart also contained a non-empty SRAM save which we currently include in the - + - + Yoshi's Universal Gravitation (Euro) 2005 Nintendo @@ -37094,7 +37094,7 @@ The cart also contained a non-empty SRAM save which we currently include in the - + @@ -37972,7 +37972,7 @@ The cart also contained a non-empty SRAM save which we currently include in the - + @@ -37986,7 +37986,7 @@ The cart also contained a non-empty SRAM save which we currently include in the - + diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp index 5ed54717275..01c0194f67e 100644 --- a/src/devices/bus/gba/gba_slot.cpp +++ b/src/devices/bus/gba/gba_slot.cpp @@ -134,12 +134,18 @@ static const gba_slot slot_list[] = { { GBA_STD, "gba_rom" }, { GBA_SRAM, "gba_sram" }, + { GBA_DRILLDOZ, "gba_drilldoz" }, + { GBA_WARIOTWS, "gba_wariotws" }, { GBA_EEPROM, "gba_eeprom" }, { GBA_EEPROM4, "gba_eeprom_4k" }, + { GBA_YOSHIUG, "gba_yoshiug" }, { GBA_EEPROM64, "gba_eeprom_64k" }, + { GBA_BOKTAI, "gba_boktai" }, { GBA_FLASH, "gba_flash" }, + { GBA_FLASH_RTC, "gba_flash_rtc" }, { GBA_FLASH512, "gba_flash_512" }, { GBA_FLASH1M, "gba_flash_1m" }, + { GBA_FLASH1M_RTC, "gba_flash_1m_rtc" }, { GBA_3DMATRIX, "gba_3dmatrix" }, }; @@ -204,7 +210,7 @@ bool gba_cart_slot_device::call_load() osd_printf_info("GBA: Detected (XML) %s\n", pcb_name ? pcb_name : "NONE"); } - if (m_type == GBA_SRAM) + if (m_type == GBA_SRAM || m_type == GBA_DRILLDOZ || m_type == GBA_WARIOTWS) m_cart->nvram_alloc(0x10000); // mirror the ROM @@ -300,6 +306,8 @@ int gba_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) { UINT32 chip = 0; int type = GBA_STD; + bool has_rtc = false; + bool has_rumble = false; // first detect nvram type based on strings inside the file for (int i = 0; i < len; i++) @@ -359,19 +367,30 @@ int gba_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) for (auto & elem : gba_chip_fix_eeprom_list) { - const gba_chip_fix_eeprom_item *item = &elem; + const gba_chip_fix_item *item = &elem; if (!strcmp(game_code, item->game_code)) { chip = (chip & ~GBA_CHIP_EEPROM) | GBA_CHIP_EEPROM_64K; break; } } + + for (auto & elem : gba_chip_fix_rumble_list) + { + const gba_chip_fix_item *item = &elem; + if (!strcmp(game_code, item->game_code)) + { + has_rumble = true; + break; + } + } } if (chip & GBA_CHIP_RTC) { - osd_printf_info("game has RTC - not emulated at the moment\n"); + //osd_printf_info("game has RTC - not emulated at the moment\n"); chip &= ~GBA_CHIP_RTC; + has_rtc = true; } osd_printf_info("GBA: Emulate %s\n", gba_chip_string(chip).c_str()); @@ -383,21 +402,29 @@ int gba_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len) break; case GBA_CHIP_EEPROM: type = GBA_EEPROM; + if (has_rumble) + type = GBA_YOSHIUG; break; case GBA_CHIP_EEPROM_4K: type = GBA_EEPROM4; break; case GBA_CHIP_EEPROM_64K: type = GBA_EEPROM64; + if (has_rtc) + type = GBA_BOKTAI; break; case GBA_CHIP_FLASH: type = GBA_FLASH; + if (has_rtc) + type = GBA_FLASH_RTC; break; case GBA_CHIP_FLASH_512: type = GBA_FLASH512; break; case GBA_CHIP_FLASH_1M: type = GBA_FLASH1M; + if (has_rtc) + type = GBA_FLASH1M_RTC; break; default: break; @@ -455,6 +482,14 @@ READ32_MEMBER(gba_cart_slot_device::read_ram) return 0xffffffff; } +READ32_MEMBER(gba_cart_slot_device::read_gpio) +{ + if (m_cart) + return m_cart->read_gpio(space, offset, mem_mask); + else + return 0xffffffff; +} + /*------------------------------------------------- write @@ -466,6 +501,12 @@ WRITE32_MEMBER(gba_cart_slot_device::write_ram) m_cart->write_ram(space, offset, data, mem_mask); } +WRITE32_MEMBER(gba_cart_slot_device::write_gpio) +{ + if (m_cart) + m_cart->write_gpio(space, offset, data, mem_mask); +} + /*------------------------------------------------- Internal header logging diff --git a/src/devices/bus/gba/gba_slot.h b/src/devices/bus/gba/gba_slot.h index a3908730180..03b9ca4f653 100644 --- a/src/devices/bus/gba/gba_slot.h +++ b/src/devices/bus/gba/gba_slot.h @@ -13,12 +13,18 @@ enum { GBA_STD = 0, GBA_SRAM, + GBA_DRILLDOZ, + GBA_WARIOTWS, GBA_EEPROM, GBA_EEPROM4, + GBA_YOSHIUG, GBA_EEPROM64, + GBA_BOKTAI, GBA_FLASH, + GBA_FLASH_RTC, GBA_FLASH512, GBA_FLASH1M, + GBA_FLASH1M_RTC, GBA_3DMATRIX }; @@ -35,7 +41,11 @@ public: // reading and writing virtual DECLARE_READ32_MEMBER(read_rom) { return 0xffffffff; } virtual DECLARE_READ32_MEMBER(read_ram) { return 0xffffffff; } + virtual DECLARE_READ32_MEMBER(read_gpio) { return 0; } + virtual DECLARE_READ32_MEMBER(read_tilt) { return 0xffffffff; } virtual DECLARE_WRITE32_MEMBER(write_ram) {}; + virtual DECLARE_WRITE32_MEMBER(write_gpio) {}; + virtual DECLARE_WRITE32_MEMBER(write_tilt) {}; virtual DECLARE_WRITE32_MEMBER(write_mapper) {}; void rom_alloc(UINT32 size, const char *tag); @@ -103,8 +113,12 @@ public: // reading and writing virtual DECLARE_READ32_MEMBER(read_rom); virtual DECLARE_READ32_MEMBER(read_ram); + virtual DECLARE_READ32_MEMBER(read_gpio); + virtual DECLARE_READ32_MEMBER(read_tilt) { if (m_cart) return m_cart->read_tilt(space, offset, mem_mask); else return 0xffffffff; } 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); }; + virtual DECLARE_WRITE32_MEMBER(write_gpio); + virtual DECLARE_WRITE32_MEMBER(write_tilt) { if (m_cart) m_cart->write_tilt(space, offset, data, mem_mask); } + virtual DECLARE_WRITE32_MEMBER(write_mapper) { if (m_cart) m_cart->write_mapper(space, offset, data, mem_mask); } protected: @@ -193,12 +207,12 @@ static const gba_chip_fix_conflict_item gba_chip_fix_conflict_list[] = { "BYUJ", GBA_CHIP_EEPROM_64K }, // 2322 - Yggdra Union (JPN) }; -struct gba_chip_fix_eeprom_item +struct gba_chip_fix_item { char game_code[5]; }; -static const gba_chip_fix_eeprom_item gba_chip_fix_eeprom_list[] = +static const gba_chip_fix_item gba_chip_fix_eeprom_list[] = { // gba scan no. 7 { "AKTJ" }, // 0145 - Hello Kitty Collection - Miracle Fashion Maker (JPN) @@ -588,4 +602,13 @@ static const gba_chip_fix_eeprom_item gba_chip_fix_eeprom_list[] = { "A3IJ" }, // bokura no taiyou - taiyou action rpg - kabunushi go-yuutai ban (japan) (demo) }; +static const gba_chip_fix_item gba_chip_fix_rumble_list[] = +{ + { "KYGP" }, // Yoshi's Universal Gravitation (EUR) + { "KYGE" }, // Yoshi - Topsy-Turvy (USA) + { "KYGJ" }, // Yoshi no Banyuuinryoku (JPN) + { "KHPJ" } // Koro Koro Puzzle - Happy Panechu! (JPN) +}; + + #endif diff --git a/src/devices/bus/gba/rom.cpp b/src/devices/bus/gba/rom.cpp index 4aadc54b884..c99f15cd6c8 100644 --- a/src/devices/bus/gba/rom.cpp +++ b/src/devices/bus/gba/rom.cpp @@ -23,10 +23,16 @@ const device_type GBA_ROM_STD = &device_creator; const device_type GBA_ROM_SRAM = &device_creator; +const device_type GBA_ROM_DRILLDOZ = &device_creator; +const device_type GBA_ROM_WARIOTWS = &device_creator; const device_type GBA_ROM_EEPROM = &device_creator; +const device_type GBA_ROM_YOSHIUG = &device_creator; const device_type GBA_ROM_EEPROM64 = &device_creator; +const device_type GBA_ROM_BOKTAI = &device_creator; const device_type GBA_ROM_FLASH = &device_creator; +const device_type GBA_ROM_FLASH_RTC = &device_creator; const device_type GBA_ROM_FLASH1M = &device_creator; +const device_type GBA_ROM_FLASH1M_RTC = &device_creator; const device_type GBA_ROM_3DMATRIX = &device_creator; @@ -42,33 +48,98 @@ gba_rom_device::gba_rom_device(const machine_config &mconfig, const char *tag, d { } +gba_rom_sram_device::gba_rom_sram_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) + : gba_rom_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + gba_rom_sram_device::gba_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : gba_rom_device(mconfig, GBA_ROM_SRAM, "GBA Carts + SRAM", tag, owner, clock, "gba_sram", __FILE__) { } +gba_rom_drilldoz_device::gba_rom_drilldoz_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_sram_device(mconfig, GBA_ROM_DRILLDOZ, "GBA Carts + SRAM + Rumble", tag, owner, clock, "gba_drilldoz", __FILE__) +{ +} + +gba_rom_wariotws_device::gba_rom_wariotws_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_sram_device(mconfig, GBA_ROM_WARIOTWS, "GBA Carts + SRAM + Rumble + Gyroscope", tag, owner, clock, "gba_wariotws", __FILE__), + m_gyro_z(*this, "GYROZ") +{ +} + +gba_rom_eeprom_device::gba_rom_eeprom_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) + : gba_rom_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + gba_rom_eeprom_device::gba_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : gba_rom_device(mconfig, GBA_ROM_EEPROM, "GBA Carts + EEPROM", tag, owner, clock, "gba_eeprom", __FILE__) { } +gba_rom_yoshiug_device::gba_rom_yoshiug_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_eeprom_device(mconfig, GBA_ROM_YOSHIUG, "GBA Carts + EEPROM + Tilt Sensor", tag, owner, clock, "gba_yoshiug", __FILE__), + m_tilt_x(*this, "TILTX"), + m_tilt_y(*this, "TILTY") +{ +} + +gba_rom_eeprom64_device::gba_rom_eeprom64_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) + : gba_rom_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + gba_rom_eeprom64_device::gba_rom_eeprom64_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : gba_rom_device(mconfig, GBA_ROM_EEPROM64, "GBA Carts + EEPROM 64K", tag, owner, clock, "gba_eeprom64", __FILE__) { } +gba_rom_boktai_device::gba_rom_boktai_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_eeprom64_device(mconfig, GBA_ROM_BOKTAI, "GBA Carts + EEPROM 64K + RTC", tag, owner, clock, "gba_boktai", __FILE__), + m_sensor(*this, "LIGHTSENSE") +{ +} + +gba_rom_flash_device::gba_rom_flash_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) + : gba_rom_device(mconfig, type, name, tag, owner, clock, shortname, source), + m_flash_mask(0), + m_flash(*this, "flash") +{ +} + gba_rom_flash_device::gba_rom_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gba_rom_device(mconfig, GBA_ROM_FLASH, "GBA Carts + Panasonic Flash", tag, owner, clock, "gba_flash", __FILE__), m_flash_mask(0), + : gba_rom_device(mconfig, GBA_ROM_FLASH, "GBA Carts + Panasonic Flash", tag, owner, clock, "gba_flash", __FILE__), + m_flash_mask(0), + m_flash(*this, "flash") +{ +} + +gba_rom_flash_rtc_device::gba_rom_flash_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_flash_device(mconfig, GBA_ROM_FLASH_RTC, "GBA Carts + Panasonic Flash + RTC", tag, owner, clock, "gba_flash_rtc", __FILE__) +{ +} + +gba_rom_flash1m_device::gba_rom_flash1m_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) + : gba_rom_device(mconfig, type, name, tag, owner, clock, shortname, source), + m_flash_mask(0), m_flash(*this, "flash") { } gba_rom_flash1m_device::gba_rom_flash1m_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : gba_rom_device(mconfig, GBA_ROM_FLASH1M, "GBA Carts + Sanyo Flash", tag, owner, clock, "gba_flash1m", __FILE__), m_flash_mask(0), + : gba_rom_device(mconfig, GBA_ROM_FLASH1M, "GBA Carts + Sanyo Flash", tag, owner, clock, "gba_flash1m", __FILE__), + m_flash_mask(0), m_flash(*this, "flash") { } +gba_rom_flash1m_rtc_device::gba_rom_flash1m_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : gba_rom_flash1m_device(mconfig, GBA_ROM_FLASH1M_RTC, "GBA Carts + Sanyo Flash + RTC", tag, owner, clock, "gba_flash1m_rtc", __FILE__) +{ +} + 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__) { @@ -81,10 +152,31 @@ gba_rom_3dmatrix_device::gba_rom_3dmatrix_device(const machine_config &mconfig, void gba_rom_device::device_start() { + save_item(NAME(m_gpio_regs)); + save_item(NAME(m_gpio_write_only)); + save_item(NAME(m_gpio_dirs)); } void gba_rom_device::device_reset() { + m_gpio_regs[0] = 0; + m_gpio_regs[1] = 0; + m_gpio_regs[2] = 0; + m_gpio_regs[3] = 0; + m_gpio_write_only = 0; + m_gpio_dirs = 0; +} + +void gba_rom_wariotws_device::device_start() +{ + save_item(NAME(m_last_val)); + save_item(NAME(m_counter)); +} + +void gba_rom_wariotws_device::device_reset() +{ + m_last_val = 0; + m_counter = 0; } void gba_rom_flash_device::device_reset() @@ -105,6 +197,22 @@ void gba_rom_eeprom_device::device_start() m_eeprom = std::make_unique(machine(), (UINT8*)get_nvram_base(), get_nvram_size(), 6); } +void gba_rom_yoshiug_device::device_start() +{ + gba_rom_eeprom_device::device_start(); + save_item(NAME(m_tilt_ready)); + save_item(NAME(m_xpos)); + save_item(NAME(m_ypos)); +} + +void gba_rom_yoshiug_device::device_reset() +{ + m_tilt_ready = 0; + m_xpos = 0; + m_ypos = 0; +} + + void gba_rom_eeprom64_device::device_start() { // for the moment we use a custom eeprom implementation, so we alloc/save it as nvram @@ -112,6 +220,31 @@ void gba_rom_eeprom64_device::device_start() m_eeprom = std::make_unique(machine(), (UINT8*)get_nvram_base(), get_nvram_size(), 14); } +void gba_rom_boktai_device::device_start() +{ + gba_rom_eeprom64_device::device_start(); + m_rtc = std::make_unique(machine()); + + save_item(NAME(m_last_val)); + save_item(NAME(m_counter)); +} + +void gba_rom_boktai_device::device_reset() +{ + m_last_val = 0; + m_counter = 0; +} + +void gba_rom_flash_rtc_device::device_start() +{ + m_rtc = std::make_unique(machine()); +} + +void gba_rom_flash1m_rtc_device::device_start() +{ + m_rtc = std::make_unique(machine()); +} + void gba_rom_3dmatrix_device::device_start() { save_item(NAME(m_src)); @@ -131,6 +264,75 @@ void gba_rom_3dmatrix_device::device_reset() mapper specific handlers -------------------------------------------------*/ +/*------------------------------------------------- + This is a preliminary implementation of the + General Purpose I/O Port embedded in the GBA PCBs + as described at : http://problemkaputt.de/gbatek.htm#gbacartioportgpio + + Functions read_gpio/write_gpio only give the + I/O interface while the actual on-cart devices + are read and written through gpio_dev_read/gpio_dev_write + which are virtual methods defined in the specific + cart types. + -------------------------------------------------*/ + +READ32_MEMBER(gba_rom_device::read_gpio) +{ + logerror("read GPIO offs %X\n", offset); + if (!m_gpio_write_only) + { + switch (offset) + { + case 0: + default: + if (ACCESSING_BITS_0_15) + { + UINT16 ret = gpio_dev_read(m_gpio_dirs); + return ret; + } + if (ACCESSING_BITS_16_31) + return m_gpio_regs[1] << 16; + case 1: + if (ACCESSING_BITS_0_15) + return m_gpio_regs[2]; + if (ACCESSING_BITS_16_31) + return m_gpio_regs[3] << 16; + } + return 0; + } + else + return m_rom[offset + 0xc4/4]; +} + +WRITE32_MEMBER(gba_rom_device::write_gpio) +{ + logerror("write GPIO offs %X data %X\n", offset, data); + switch (offset) + { + case 0: + default: + if (ACCESSING_BITS_0_15) + { + gpio_dev_write(data & 0xffff, m_gpio_dirs); + } + if (ACCESSING_BITS_16_31) + { + m_gpio_dirs = (data >> 16) & 0x0f; + m_gpio_regs[1] = (data >> 16) & 0xffff; + } + break; + case 1: + if (ACCESSING_BITS_0_15) + { + m_gpio_write_only = BIT(data, 0) ? 0 : 1; + m_gpio_regs[2] = data & 0xffff; + } + if (ACCESSING_BITS_16_31) + m_gpio_regs[3] = (data >> 16) & 0xffff; + break; + } +} + /*------------------------------------------------- Carts with SRAM @@ -151,6 +353,60 @@ WRITE32_MEMBER(gba_rom_sram_device::write_ram) } +// SRAM cart variant with additional Rumble motor (used by Drill Dozer) + +void gba_rom_drilldoz_device::gpio_dev_write(UINT16 data, int gpio_dirs) +{ + if ((gpio_dirs & 0x08)) + { + // send impulse to Rumble sensor + machine().output().set_value("Rumble", BIT(data, 3)); + } +} + + +// SRAM cart variant with additional Rumble motor + Gyroscope (used by Warioware Twist) + +static INPUT_PORTS_START( wariotws_gyroscope ) + PORT_START("GYROZ") + PORT_BIT( 0xfff, 0x6c0, IPT_AD_STICK_Z ) PORT_MINMAX(0x354,0x9e3) PORT_SENSITIVITY(0x10) PORT_KEYDELTA(0x50) +INPUT_PORTS_END + +ioport_constructor gba_rom_wariotws_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( wariotws_gyroscope ); +} + +UINT16 gba_rom_wariotws_device::gpio_dev_read(int gpio_dirs) +{ + int gyro = 0; + if (gpio_dirs == 0x0b) + gyro = BIT(m_gyro_z->read(), m_counter); + return (gyro << 2); +} + +void gba_rom_wariotws_device::gpio_dev_write(UINT16 data, int gpio_dirs) +{ + if ((gpio_dirs & 0x08)) + { + // send impulse to Rumble sensor + machine().output().set_value("Rumble", BIT(data, 3)); + } + + if (gpio_dirs == 0x0b) + { + if ((data & 2) && (m_counter > 0)) + m_counter--; + + if (data & 1) + m_counter = 15; + + m_last_val = data & 0x0b; + } +} + + + /*------------------------------------------------- Carts with Flash RAM -------------------------------------------------*/ @@ -257,164 +513,34 @@ WRITE32_MEMBER(gba_rom_flash1m_device::write_ram) } } +// cart variants with additional S3511 RTC + +UINT16 gba_rom_flash_rtc_device::gpio_dev_read(int gpio_dirs) +{ + return 5 | (m_rtc->read_line() << 1); +} + +void gba_rom_flash_rtc_device::gpio_dev_write(UINT16 data, int gpio_dirs) +{ + m_rtc->write(data, gpio_dirs); +} + + +UINT16 gba_rom_flash1m_rtc_device::gpio_dev_read(int gpio_dirs) +{ + return 5 | (m_rtc->read_line() << 1); +} + +void gba_rom_flash1m_rtc_device::gpio_dev_write(UINT16 data, int gpio_dirs) +{ + m_rtc->write(data, gpio_dirs); +} + /*------------------------------------------------- Carts with EEPROM - - TODO: can this sketchy EEPROM device be merged - with the core implementation? -------------------------------------------------*/ -// GBA EEPROM Device - -gba_eeprom_device::gba_eeprom_device(running_machine &machine, UINT8 *eeprom, UINT32 size, int addr_bits) : - m_state(EEP_IDLE), - m_machine(machine) -{ - m_data = eeprom; - m_data_size = size; - m_addr_bits = addr_bits; - - m_machine.save().save_item(m_state, "GBA_EEPROM/m_state"); - m_machine.save().save_item(m_command, "GBA_EEPROM/m_command"); - m_machine.save().save_item(m_count, "GBA_EEPROM/m_count"); - m_machine.save().save_item(m_addr, "GBA_EEPROM/m_addr"); - m_machine.save().save_item(m_bits, "GBA_EEPROM/m_bits"); - m_machine.save().save_item(m_eep_data, "GBA_EEPROM/m_eep_data"); -} - -UINT32 gba_eeprom_device::read() -{ - UINT32 out; - - switch (m_state) - { - case EEP_IDLE: -// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %d\n", offset, ~mem_mask, m_state, activecpu_get_pc(), 1); - return 0x00010001; // "ready" - - case EEP_READFIRST: - m_count--; - - if (!m_count) - { - m_count = 64; - m_bits = 0; - m_eep_data = 0; - m_state = EEP_READ; - } - break; - case EEP_READ: - if ((m_bits == 0) && (m_count)) - { - if (m_addr >= m_data_size) - { - fatalerror("eeprom: invalid address (%x)\n", m_addr); - } - m_eep_data = m_data[m_addr]; - //printf("EEPROM read @ %x = %x (%x)\n", m_addr, m_eep_data, (m_eep_data & 0x80) ? 1 : 0); - m_addr++; - m_bits = 8; - } - - out = (m_eep_data & 0x80) ? 1 : 0; - out |= (out<<16); - m_eep_data <<= 1; - - m_bits--; - m_count--; - - if (!m_count) - { - m_state = EEP_IDLE; - } - -// printf("out = %08x\n", out); -// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %08x\n", offset, ~mem_mask, m_state, activecpu_get_pc(), out); - return out; - } -// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %d\n", offset, ~mem_mask, m_state, space.device().safe_pc(), 0); - return 0; -} - -void gba_eeprom_device::write(UINT32 data) -{ -// printf("eeprom_w: %x @ %x (state %d) (PC=%x)\n", data, offset, m_state, space.device().safe_pc()); - switch (m_state) - { - case EEP_IDLE: - if (data == 1) - m_state++; - break; - - case EEP_COMMAND: - if (data == 1) - m_command = EEP_READFIRST; - else - m_command = EEP_WRITE; - m_state = EEP_ADDR; - m_count = m_addr_bits; - m_addr = 0; - break; - - case EEP_ADDR: - m_addr <<= 1; - m_addr |= (data & 1); - m_count--; - if (!m_count) - { - m_addr *= 8; // each address points to 8 bytes - if (m_command == EEP_READFIRST) - m_state = EEP_AFTERADDR; - else - { - m_count = 64; - m_bits = 8; - m_state = EEP_WRITE; - m_eep_data = 0; - } - } - break; - - case EEP_AFTERADDR: - m_state = m_command; - m_count = 64; - m_bits = 0; - m_eep_data = 0; - if (m_state == EEP_READFIRST) - m_count = 4; - break; - - case EEP_WRITE: - m_eep_data <<= 1; - m_eep_data |= (data & 1); - m_bits--; - m_count--; - - if (m_bits == 0) - { - osd_printf_verbose("%08x: EEPROM: %02x to %x\n", machine().device("maincpu")->safe_pc(), m_eep_data, m_addr); - if (m_addr >= m_data_size) - fatalerror("eeprom: invalid address (%x)\n", m_addr); - - m_data[m_addr] = m_eep_data; - m_addr++; - m_eep_data = 0; - m_bits = 8; - } - - if (!m_count) - m_state = EEP_AFTERWRITE; - break; - - case EEP_AFTERWRITE: - m_state = EEP_IDLE; - break; - } -} - - - READ32_MEMBER(gba_rom_eeprom_device::read_ram) { // Larger games have smaller access to EERPOM content @@ -458,6 +584,137 @@ WRITE32_MEMBER(gba_rom_eeprom64_device::write_ram) } +/*------------------------------------------------- + Carts with EEPROM + Tilt Sensor + + Note about the calibration: this can seem a bit + tricky at first, because the emulated screen + does not turn as the GBA would... + In order to properly calibrate the sensor, just + keep pressed right for a few seconds when requested + to calibrate right inclination (first calibration + screen in Yoshi Universal Gravitation) so to get the + full right range; then keep pressed for left for a + few seconds when requested to calibrate left + inclination (second calibration screen in Yoshi + Universal Gravitation) so to get the full left range + + -------------------------------------------------*/ + +static INPUT_PORTS_START( yoshiug_tilt ) + PORT_START("TILTX") + PORT_BIT( 0xfff, 0x3a0, IPT_AD_STICK_X ) PORT_MINMAX(0x2af,0x477) PORT_SENSITIVITY(0x30) PORT_KEYDELTA(0x50) + PORT_START("TILTY") + PORT_BIT( 0xfff, 0x3a0, IPT_AD_STICK_Y ) PORT_MINMAX(0x2c3,0x480) PORT_SENSITIVITY(0x30) PORT_KEYDELTA(0x50) +INPUT_PORTS_END + +ioport_constructor gba_rom_yoshiug_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( yoshiug_tilt ); +} + + +READ32_MEMBER(gba_rom_yoshiug_device::read_tilt) +{ + switch (offset) + { + case 0x200/4: + if (ACCESSING_BITS_0_15) + return (m_xpos & 0xff); + break; + case 0x300/4: + if (ACCESSING_BITS_0_15) + return ((m_xpos >> 8) & 0x0f) | 0x80; + break; + case 0x400/4: + if (ACCESSING_BITS_0_15) + return (m_ypos & 0xff); + break; + case 0x500/4: + if (ACCESSING_BITS_0_15) + return ((m_ypos >> 8) & 0x0f); + break; + default: + break; + } + return 0xffffffff; +} + +WRITE32_MEMBER(gba_rom_yoshiug_device::write_tilt) +{ + switch (offset) + { + case 0x000/4: + if (data == 0x55) m_tilt_ready = 1; + break; + case 0x100/4: + if (data == 0xaa) + { + m_xpos = m_tilt_x->read(); + m_ypos = m_tilt_y->read(); + m_tilt_ready = 0; + } + break; + default: + break; + } +} + + +/*------------------------------------------------- + Carts with EEPROM + S3511 RTC + Light Sensor + -------------------------------------------------*/ + +static INPUT_PORTS_START( boktai_sensor ) + PORT_START("LIGHTSENSE") + PORT_CONFNAME( 0xff, 0xe8, "Light Sensor" ) + PORT_CONFSETTING( 0xe8, "Complete Darkness" ) + PORT_CONFSETTING( 0xe4, "10%" ) + PORT_CONFSETTING( 0xdc, "20%" ) + PORT_CONFSETTING( 0xd4, "30%" ) + PORT_CONFSETTING( 0xc8, "40%" ) + PORT_CONFSETTING( 0xb8, "50%" ) + PORT_CONFSETTING( 0xa8, "60%" ) + PORT_CONFSETTING( 0x98, "70%" ) + PORT_CONFSETTING( 0x88, "80%" ) + PORT_CONFSETTING( 0x68, "90%" ) + PORT_CONFSETTING( 0x48, "Very Bright" ) +INPUT_PORTS_END + + +ioport_constructor gba_rom_boktai_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( boktai_sensor ); +} + +UINT16 gba_rom_boktai_device::gpio_dev_read(int gpio_dirs) +{ + int light = (gpio_dirs == 7 && m_counter >= m_sensor->read()) ? 1 : 0; + return 5 | (m_rtc->read_line() << 1) | (light << 3); +} + +void gba_rom_boktai_device::gpio_dev_write(UINT16 data, int gpio_dirs) +{ + m_rtc->write(data, gpio_dirs); + if (gpio_dirs == 7) + { + if (data & 2) + m_counter = 0; + + if ((data & 1) && !(m_last_val & 1)) + { + m_counter++; + if (m_counter == 0x100) + m_counter = 0; + } + + m_last_val = data & 7; + } +} + + + + /*------------------------------------------------- Carts with 3D Matrix Memory controller @@ -511,3 +768,328 @@ WRITE32_MEMBER(gba_rom_3dmatrix_device::write_mapper) break; } } + + + +// Additional devices, to be moved to separate source files at a later stage + +/*------------------------------------------------- + Seiko S-3511 RTC implementation + + TODO: transform this into a separate device, using + also dirtc.cpp! + -------------------------------------------------*/ + +gba_s3511_device::gba_s3511_device(running_machine &machine) : + m_phase(S3511_RTC_IDLE), + m_machine(machine) +{ + m_last_val = 0; + m_bits = 0; + m_command = 0; + m_data_len = 1; + m_data[0] = 0; + + m_machine.save().save_item(m_phase, "GBA_RTC/m_phase"); + m_machine.save().save_item(m_data, "GBA_RTC/m_data"); + m_machine.save().save_item(m_last_val, "GBA_RTC/m_last_val"); + m_machine.save().save_item(m_bits, "GBA_RTC/m_bits"); + m_machine.save().save_item(m_command, "GBA_RTC/m_command"); + m_machine.save().save_item(m_data_len, "GBA_RTC/m_data_len"); +} + + +UINT8 gba_s3511_device::convert_to_bcd(int val) +{ + return (((val % 100) / 10) << 4) | (val % 10); +} + +void gba_s3511_device::update_time(int len) +{ + system_time curtime; + m_machine.current_datetime(curtime); + + if (len == 7) + { + m_data[0] = convert_to_bcd(curtime.local_time.year); + m_data[1] = convert_to_bcd(curtime.local_time.month + 1); + m_data[2] = convert_to_bcd(curtime.local_time.mday); + m_data[3] = convert_to_bcd(curtime.local_time.weekday); + m_data[4] = convert_to_bcd(curtime.local_time.hour); + m_data[5] = convert_to_bcd(curtime.local_time.minute); + m_data[6] = convert_to_bcd(curtime.local_time.second); + } + else if (len == 3) + { + m_data[0] = convert_to_bcd(curtime.local_time.hour); + m_data[1] = convert_to_bcd(curtime.local_time.minute); + m_data[2] = convert_to_bcd(curtime.local_time.second); + } +} + + +int gba_s3511_device::read_line() +{ + int pin = 0; + switch (m_phase) + { + case S3511_RTC_DATAOUT: + //printf("mmm %d - %X - %d - %d\n", m_bits, m_data[m_bits >> 3], m_bits >> 3, BIT(m_data[m_bits >> 3], (m_bits & 7))); + pin = BIT(m_data[m_bits >> 3], (m_bits & 7)); + m_bits++; + if (m_bits == 8 * m_data_len) + { + //for (int i = 0; i < m_data_len; i++) + // printf("RTC DATA OUT COMPLETE %X (reg %d) \n", m_data[i], i); + m_bits = 0; + m_phase = S3511_RTC_IDLE; + } + break; + } + return pin; +} + + +void gba_s3511_device::write(UINT16 data, int gpio_dirs) +{ +// printf("gpio_dev_write data %X\n", data); + if (m_phase == S3511_RTC_IDLE && (m_last_val & 5) == 1 && (data & 5) == 5) + { + m_phase = S3511_RTC_COMMAND; + m_bits = 0; + m_command = 0; + } + else + { +// if (m_phase == 3) +// printf("RTC command OK\n"); + if (!(m_last_val & 1) & (data & 1)) + { + // bit transfer + m_last_val = data & 0xff; + switch (m_phase) + { + case S3511_RTC_DATAIN: + if (!BIT(gpio_dirs, 1)) + { + m_data[m_bits >> 3] = (m_data[m_bits >> 3] >> 1) | ((data << 6) & 0x80); + m_bits++; + if (m_bits == 8 * m_data_len) + { + //for (int i = 0; i < m_data_len; i++) + // printf("RTC DATA IN COMPLETE %X (reg %d) \n", m_data[i], i); + m_bits = 0; + m_phase = S3511_RTC_IDLE; + } + } + break; + case S3511_RTC_DATAOUT: + break; + case S3511_RTC_COMMAND: + m_command |= (BIT(data, 1) << (7 - m_bits)); + m_bits++; + if (m_bits == 8) + { + m_bits = 0; + //printf("RTC command %X ENTERED!!!\n", m_command); + switch (m_command) + { + case 0x60: + // reset? + m_phase = S3511_RTC_IDLE; + m_bits = 0; + break; + case 0x62: + m_phase = S3511_RTC_DATAIN; + m_data_len = 1; + break; + case 0x63: + m_data_len = 1; + m_data[0] = 0x40; + m_phase = S3511_RTC_DATAOUT; + break; + case 0x64: + break; + case 0x65: + m_data_len = 7; + update_time(m_data_len); + m_phase = S3511_RTC_DATAOUT; + break; + case 0x67: + m_data_len = 3; + update_time(m_data_len); + m_phase = S3511_RTC_DATAOUT; + break; + default: + printf("Unknown RTC command %02X\n", m_command); + m_phase = S3511_RTC_IDLE; + break; + } + } + break; + case S3511_RTC_IDLE: + default: + break; + } + } + else + m_last_val = data & 0xff; + } +} + + +/*------------------------------------------------- + GBA EEPROM Device + + TODO: can this sketchy EEPROM device be merged + with the core implementation? + -------------------------------------------------*/ + +// + +gba_eeprom_device::gba_eeprom_device(running_machine &machine, UINT8 *eeprom, UINT32 size, int addr_bits) : + m_state(EEP_IDLE), + m_machine(machine) +{ + m_data = eeprom; + m_data_size = size; + m_addr_bits = addr_bits; + + m_machine.save().save_item(m_state, "GBA_EEPROM/m_state"); + m_machine.save().save_item(m_command, "GBA_EEPROM/m_command"); + m_machine.save().save_item(m_count, "GBA_EEPROM/m_count"); + m_machine.save().save_item(m_addr, "GBA_EEPROM/m_addr"); + m_machine.save().save_item(m_bits, "GBA_EEPROM/m_bits"); + m_machine.save().save_item(m_eep_data, "GBA_EEPROM/m_eep_data"); +} + +UINT32 gba_eeprom_device::read() +{ + UINT32 out; + + switch (m_state) + { + case EEP_IDLE: +// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %d\n", offset, ~mem_mask, m_state, activecpu_get_pc(), 1); + return 0x00010001; // "ready" + + case EEP_READFIRST: + m_count--; + + if (!m_count) + { + m_count = 64; + m_bits = 0; + m_eep_data = 0; + m_state = EEP_READ; + } + break; + case EEP_READ: + if ((m_bits == 0) && (m_count)) + { + if (m_addr >= m_data_size) + { + fatalerror("eeprom: invalid address (%x)\n", m_addr); + } + m_eep_data = m_data[m_addr]; + //printf("EEPROM read @ %x = %x (%x)\n", m_addr, m_eep_data, (m_eep_data & 0x80) ? 1 : 0); + m_addr++; + m_bits = 8; + } + + out = (m_eep_data & 0x80) ? 1 : 0; + out |= (out<<16); + m_eep_data <<= 1; + + m_bits--; + m_count--; + + if (!m_count) + { + m_state = EEP_IDLE; + } + +// printf("out = %08x\n", out); +// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %08x\n", offset, ~mem_mask, m_state, activecpu_get_pc(), out); + return out; + } +// printf("eeprom_r: @ %x, mask %08x (state %d) (PC=%x) = %d\n", offset, ~mem_mask, m_state, space.device().safe_pc(), 0); + return 0; +} + +void gba_eeprom_device::write(UINT32 data) +{ +// printf("eeprom_w: %x @ %x (state %d) (PC=%x)\n", data, offset, m_state, space.device().safe_pc()); + switch (m_state) + { + case EEP_IDLE: + if (data == 1) + m_state++; + break; + + case EEP_COMMAND: + if (data == 1) + m_command = EEP_READFIRST; + else + m_command = EEP_WRITE; + m_state = EEP_ADDR; + m_count = m_addr_bits; + m_addr = 0; + break; + + case EEP_ADDR: + m_addr <<= 1; + m_addr |= (data & 1); + m_count--; + if (!m_count) + { + m_addr *= 8; // each address points to 8 bytes + if (m_command == EEP_READFIRST) + m_state = EEP_AFTERADDR; + else + { + m_count = 64; + m_bits = 8; + m_state = EEP_WRITE; + m_eep_data = 0; + } + } + break; + + case EEP_AFTERADDR: + m_state = m_command; + m_count = 64; + m_bits = 0; + m_eep_data = 0; + if (m_state == EEP_READFIRST) + m_count = 4; + break; + + case EEP_WRITE: + m_eep_data <<= 1; + m_eep_data |= (data & 1); + m_bits--; + m_count--; + + if (m_bits == 0) + { + osd_printf_verbose("%08x: EEPROM: %02x to %x\n", machine().device("maincpu")->safe_pc(), m_eep_data, m_addr); + if (m_addr >= m_data_size) + fatalerror("eeprom: invalid address (%x)\n", m_addr); + + m_data[m_addr] = m_eep_data; + m_addr++; + m_eep_data = 0; + m_bits = 8; + } + + if (!m_count) + m_state = EEP_AFTERWRITE; + break; + + case EEP_AFTERWRITE: + m_state = EEP_IDLE; + break; + } +} + diff --git a/src/devices/bus/gba/rom.h b/src/devices/bus/gba/rom.h index e13f6c623ac..4a1850c5fa2 100644 --- a/src/devices/bus/gba/rom.h +++ b/src/devices/bus/gba/rom.h @@ -6,81 +6,37 @@ #include "gba_slot.h" #include "machine/intelfsh.h" +// GBA RTC device -// ======================> gba_rom_device - -class gba_rom_device : public device_t, - public device_gba_cart_interface -{ -public: - // construction/destruction - 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); - gba_rom_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_READ32_MEMBER(read_rom) override { return m_rom[offset]; } +enum { + S3511_RTC_IDLE = 0, + S3511_RTC_DATAOUT, + S3511_RTC_DATAIN, + S3511_RTC_COMMAND }; -// ======================> gba_rom_sram_device - -class gba_rom_sram_device : public gba_rom_device +class gba_s3511_device { public: - // construction/destruction - gba_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // reading and writing - virtual DECLARE_READ32_MEMBER(read_ram) override; - virtual DECLARE_WRITE32_MEMBER(write_ram) override; + gba_s3511_device(running_machine &machine); + running_machine &machine() const { return m_machine; } + + void update_time(int len); + UINT8 convert_to_bcd(int val); + + int read_line(); + void write(UINT16 data, int gpio_dirs); + +protected: + int m_phase; + UINT8 m_last_val, m_bits, m_command; + int m_data_len; + UINT8 m_data[7]; + + running_machine& m_machine; }; -// ======================> gba_rom_flash_device -class gba_rom_flash_device : public gba_rom_device -{ -public: - // construction/destruction - gba_rom_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual machine_config_constructor device_mconfig_additions() const override; - virtual void device_reset() override; - - // reading and writing - virtual DECLARE_READ32_MEMBER(read_ram) override; - virtual DECLARE_WRITE32_MEMBER(write_ram) override; - -private: - //UINT32 m_flash_size; - UINT32 m_flash_mask; - required_device m_flash; -}; - -// ======================> gba_rom_flash1m_device - -class gba_rom_flash1m_device : public gba_rom_device -{ -public: - // construction/destruction - gba_rom_flash1m_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // device-level overrides - virtual machine_config_constructor device_mconfig_additions() const override; - virtual void device_reset() override; - - // reading and writing - virtual DECLARE_READ32_MEMBER(read_ram) override; - virtual DECLARE_WRITE32_MEMBER(write_ram) override; - -private: - //UINT32 m_flash_size; - UINT32 m_flash_mask; - required_device m_flash; -}; // GBA EEPROM device // TODO: is it possible to merge this with the standard EEPROM devices in the core? @@ -102,10 +58,10 @@ class gba_eeprom_device public: gba_eeprom_device(running_machine &machine, UINT8 *eeprom, UINT32 size, int addr_bits); running_machine &machine() const { return m_machine; } - + UINT32 read(); void write(UINT32 data); - + protected: UINT8 *m_data; UINT32 m_data_size; @@ -116,17 +72,184 @@ protected: int m_bits; int m_addr_bits; UINT8 m_eep_data; - + running_machine& m_machine; }; + +// ======================> gba_rom_device + +class gba_rom_device : public device_t, + public device_gba_cart_interface +{ +public: + // construction/destruction + 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); + gba_rom_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_READ32_MEMBER(read_rom) override { return m_rom[offset]; } + + virtual DECLARE_READ32_MEMBER(read_gpio) override; + virtual DECLARE_WRITE32_MEMBER(write_gpio) override; + + virtual UINT16 gpio_dev_read(int gpio_dirs) { return 0; } + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) {} + +private: + UINT16 m_gpio_regs[4]; + UINT8 m_gpio_write_only, m_gpio_dirs; +}; + + +// ======================> gba_rom_sram_device + +class gba_rom_sram_device : public gba_rom_device +{ +public: + // construction/destruction + gba_rom_sram_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); + gba_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // reading and writing + virtual DECLARE_READ32_MEMBER(read_ram) override; + virtual DECLARE_WRITE32_MEMBER(write_ram) override; +}; + + +// ======================> gba_rom_drilldoz_device + +class gba_rom_drilldoz_device : public gba_rom_sram_device +{ +public: + // construction/destruction + gba_rom_drilldoz_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) override; +}; + + +// ======================> gba_rom_wariotws_device + +class gba_rom_wariotws_device : public gba_rom_sram_device +{ +public: + // construction/destruction + gba_rom_wariotws_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const override; + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + virtual UINT16 gpio_dev_read(int gpio_dirs) override; + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) override; + +private: + UINT8 m_last_val; + int m_counter; + required_ioport m_gyro_z; +}; + + +// ======================> gba_rom_flash_device + +class gba_rom_flash_device : public gba_rom_device +{ +public: + // construction/destruction + gba_rom_flash_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); + gba_rom_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual machine_config_constructor device_mconfig_additions() const override; + virtual void device_reset() override; + + // reading and writing + virtual DECLARE_READ32_MEMBER(read_ram) override; + virtual DECLARE_WRITE32_MEMBER(write_ram) override; + +protected: + //UINT32 m_flash_size; + UINT32 m_flash_mask; + required_device m_flash; +}; + + +// ======================> gba_rom_flash_rtc_device + +class gba_rom_flash_rtc_device : public gba_rom_flash_device +{ +public: + // construction/destruction + gba_rom_flash_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start() override; + virtual UINT16 gpio_dev_read(int gpio_dirs) override; + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) override; + +private: + std::unique_ptr m_rtc; +}; + + +// ======================> gba_rom_flash1m_device + +class gba_rom_flash1m_device : public gba_rom_device +{ +public: + // construction/destruction + gba_rom_flash1m_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); + gba_rom_flash1m_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual machine_config_constructor device_mconfig_additions() const override; + virtual void device_reset() override; + + // reading and writing + virtual DECLARE_READ32_MEMBER(read_ram) override; + virtual DECLARE_WRITE32_MEMBER(write_ram) override; + +protected: + //UINT32 m_flash_size; + UINT32 m_flash_mask; + required_device m_flash; +}; + + +// ======================> gba_rom_flash1m_rtc_device + +class gba_rom_flash1m_rtc_device : public gba_rom_flash1m_device +{ +public: + // construction/destruction + gba_rom_flash1m_rtc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start() override; + virtual UINT16 gpio_dev_read(int gpio_dirs) override; + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) override; + +private: + std::unique_ptr m_rtc; +}; + + // ======================> gba_rom_eeprom_device class gba_rom_eeprom_device : public gba_rom_device { public: // construction/destruction + gba_rom_eeprom_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); gba_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // device-level overrides @@ -141,12 +264,38 @@ private: }; +// ======================> gba_rom_yoshiug_device + +class gba_rom_yoshiug_device : public gba_rom_eeprom_device +{ +public: + // construction/destruction + gba_rom_yoshiug_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; + virtual ioport_constructor device_input_ports() const override; + + // reading and writing + virtual DECLARE_READ32_MEMBER(read_tilt) override; + virtual DECLARE_WRITE32_MEMBER(write_tilt) override; + +private: + int m_tilt_ready; + UINT16 m_xpos, m_ypos; + required_ioport m_tilt_x; + required_ioport m_tilt_y; +}; + + // ======================> gba_rom_eeprom64_device class gba_rom_eeprom64_device : public gba_rom_device { public: // construction/destruction + gba_rom_eeprom64_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); gba_rom_eeprom64_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // device-level overrides @@ -156,11 +305,35 @@ public: virtual DECLARE_READ32_MEMBER(read_ram) override; virtual DECLARE_WRITE32_MEMBER(write_ram) override; -private: +protected: std::unique_ptr m_eeprom; }; +// ======================> gba_rom_boktai_device + +class gba_rom_boktai_device : public gba_rom_eeprom64_device +{ +public: + // construction/destruction + gba_rom_boktai_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; + virtual ioport_constructor device_input_ports() const override; + + virtual UINT16 gpio_dev_read(int gpio_dirs) override; + virtual void gpio_dev_write(UINT16 data, int gpio_dirs) override; + +private: + std::unique_ptr m_rtc; + required_ioport m_sensor; + UINT8 m_last_val; + int m_counter; +}; + + // ======================> gba_rom_3dmatrix_device class gba_rom_3dmatrix_device : public gba_rom_device @@ -184,10 +357,16 @@ private: // device type definition extern const device_type GBA_ROM_STD; extern const device_type GBA_ROM_SRAM; +extern const device_type GBA_ROM_DRILLDOZ; +extern const device_type GBA_ROM_WARIOTWS; extern const device_type GBA_ROM_EEPROM; +extern const device_type GBA_ROM_YOSHIUG; extern const device_type GBA_ROM_EEPROM64; +extern const device_type GBA_ROM_BOKTAI; extern const device_type GBA_ROM_FLASH; +extern const device_type GBA_ROM_FLASH_RTC; extern const device_type GBA_ROM_FLASH1M; +extern const device_type GBA_ROM_FLASH1M_RTC; extern const device_type GBA_ROM_3DMATRIX; diff --git a/src/mame/drivers/gba.cpp b/src/mame/drivers/gba.cpp index 4a8cae101e5..9270c520b43 100644 --- a/src/mame/drivers/gba.cpp +++ b/src/mame/drivers/gba.cpp @@ -2118,29 +2118,40 @@ void gba_state::machine_start() membank("rom2")->set_base(cart_rom->base()); membank("rom3")->set_base(cart_rom->base()); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x80000c4, 0x80000cb, read32_delegate(FUNC(gba_cart_slot_device::read_gpio),(gba_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x80000c4, 0x80000cb, write32_delegate(FUNC(gba_cart_slot_device::write_gpio),(gba_cart_slot_device*)m_cart)); // add nvram to save state m_cart->save_nvram(); // install the cart NVRAM handlers if necessary - if (m_cart->get_type() == GBA_SRAM) + if (m_cart->get_type() == GBA_SRAM || m_cart->get_type() == GBA_DRILLDOZ || m_cart->get_type() == GBA_WARIOTWS) { m_maincpu->space(AS_PROGRAM).install_read_handler(0xe000000, 0xe00ffff, read32_delegate(FUNC(gba_cart_slot_device::read_ram),(gba_cart_slot_device*)m_cart)); m_maincpu->space(AS_PROGRAM).install_write_handler(0xe000000, 0xe00ffff, write32_delegate(FUNC(gba_cart_slot_device::write_ram),(gba_cart_slot_device*)m_cart)); } - if (m_cart->get_type() == GBA_EEPROM || m_cart->get_type() == GBA_EEPROM4 || m_cart->get_type() == GBA_EEPROM64) + if (m_cart->get_type() == GBA_EEPROM || m_cart->get_type() == GBA_EEPROM4 || m_cart->get_type() == GBA_EEPROM64 || m_cart->get_type() == GBA_BOKTAI) { // for games larger than 16MB the actual range is smaller but read_ram/write_ram handles that! m_maincpu->space(AS_PROGRAM).install_read_handler(0xd000000, 0xdffffff, read32_delegate(FUNC(gba_cart_slot_device::read_ram),(gba_cart_slot_device*)m_cart)); m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000000, 0xdffffff, write32_delegate(FUNC(gba_cart_slot_device::write_ram),(gba_cart_slot_device*)m_cart)); } + if (m_cart->get_type() == GBA_YOSHIUG) + { + // EEPROM + m_maincpu->space(AS_PROGRAM).install_read_handler(0xd000000, 0xdffffff, read32_delegate(FUNC(gba_cart_slot_device::read_ram),(gba_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0xd000000, 0xdffffff, write32_delegate(FUNC(gba_cart_slot_device::write_ram),(gba_cart_slot_device*)m_cart)); + // Tilt Sensor + m_maincpu->space(AS_PROGRAM).install_read_handler(0xe008000, 0xe0085ff, read32_delegate(FUNC(gba_cart_slot_device::read_tilt),(gba_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0xe008000, 0xe0085ff, write32_delegate(FUNC(gba_cart_slot_device::write_tilt),(gba_cart_slot_device*)m_cart)); + } // merge the two flash and mask accesses in read_ram?!? - if (m_cart->get_type() == GBA_FLASH || m_cart->get_type() == GBA_FLASH512) + if (m_cart->get_type() == GBA_FLASH || m_cart->get_type() == GBA_FLASH512 || m_cart->get_type() == GBA_FLASH_RTC) { m_maincpu->space(AS_PROGRAM).install_read_handler(0xe000000, 0xe00ffff, read32_delegate(FUNC(gba_cart_slot_device::read_ram),(gba_cart_slot_device*)m_cart)); m_maincpu->space(AS_PROGRAM).install_write_handler(0xe000000, 0xe00ffff, write32_delegate(FUNC(gba_cart_slot_device::write_ram),(gba_cart_slot_device*)m_cart)); } - if (m_cart->get_type() == GBA_FLASH1M) + if (m_cart->get_type() == GBA_FLASH1M || m_cart->get_type() == GBA_FLASH1M_RTC) { 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)); @@ -2245,15 +2256,21 @@ void gba_state::machine_start() static SLOT_INTERFACE_START(gba_cart) - SLOT_INTERFACE_INTERNAL("gba_rom", GBA_ROM_STD) - SLOT_INTERFACE_INTERNAL("gba_sram", GBA_ROM_SRAM) - SLOT_INTERFACE_INTERNAL("gba_eeprom", GBA_ROM_EEPROM) - SLOT_INTERFACE_INTERNAL("gba_eeprom_4k", GBA_ROM_EEPROM) - SLOT_INTERFACE_INTERNAL("gba_eeprom_64k", GBA_ROM_EEPROM64) - 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_INTERNAL("gba_rom", GBA_ROM_STD) + SLOT_INTERFACE_INTERNAL("gba_sram", GBA_ROM_SRAM) + SLOT_INTERFACE_INTERNAL("gba_drilldoz", GBA_ROM_DRILLDOZ) // Rumble output unemulated + SLOT_INTERFACE_INTERNAL("gba_wariotws", GBA_ROM_WARIOTWS) // Rumble output unemulated + SLOT_INTERFACE_INTERNAL("gba_eeprom", GBA_ROM_EEPROM) + SLOT_INTERFACE_INTERNAL("gba_eeprom_4k", GBA_ROM_EEPROM) + SLOT_INTERFACE_INTERNAL("gba_yoshiug", GBA_ROM_YOSHIUG) + SLOT_INTERFACE_INTERNAL("gba_eeprom_64k", GBA_ROM_EEPROM64) + SLOT_INTERFACE_INTERNAL("gba_boktai", GBA_ROM_BOKTAI) + SLOT_INTERFACE_INTERNAL("gba_flash", GBA_ROM_FLASH) // Panasonic + SLOT_INTERFACE_INTERNAL("gba_flash_rtc", GBA_ROM_FLASH_RTC) // 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_flash_1m_rtc", GBA_ROM_FLASH1M_RTC) // Sanyo + SLOT_INTERFACE_INTERNAL("gba_3dmatrix", GBA_ROM_3DMATRIX) SLOT_INTERFACE_END