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