From abd73e6db4c7e354beb0ad7ef6a7d82c179c7d9c Mon Sep 17 00:00:00 2001 From: Wilbert Pol Date: Sun, 17 Jan 2021 16:19:28 +0100 Subject: [PATCH] Software list items promoted to working --------------------------------------- gamegear: X-Terminator v2.1 for Game Gear (USA, Euro) X-Terminator v2.1J for Game Gear (Jpn) [Wilbert Pol] --- hash/gamegear.xml | 10 +- src/devices/bus/sega8/rom.cpp | 145 +++++++++++++++++++++++++++ src/devices/bus/sega8/rom.h | 28 ++++++ src/devices/bus/sega8/sega8_slot.cpp | 12 ++- src/devices/bus/sega8/sega8_slot.h | 3 +- 5 files changed, 194 insertions(+), 4 deletions(-) diff --git a/hash/gamegear.xml b/hash/gamegear.xml index bd7f6fe57ac..51b0c7cd0d8 100644 --- a/hash/gamegear.xml +++ b/hash/gamegear.xml @@ -10069,25 +10069,31 @@ a certain item) --> - + X-Terminator v2.1 for Game Gear (USA, Euro) 19?? <unknown> + + + - + X-Terminator v2.1J for Game Gear (Jpn) 19?? <unknown> + + + diff --git a/src/devices/bus/sega8/rom.cpp b/src/devices/bus/sega8/rom.cpp index edcbc910740..1cc25a476cf 100644 --- a/src/devices/bus/sega8/rom.cpp +++ b/src/devices/bus/sega8/rom.cpp @@ -41,6 +41,7 @@ DEFINE_DEVICE_TYPE(SEGA8_ROM_HICOM, sega8_hicom_device, "sega8_hic DEFINE_DEVICE_TYPE(SEGA8_ROM_KOREAN, sega8_korean_device, "sega8_korean", "SMS Korean Carts") DEFINE_DEVICE_TYPE(SEGA8_ROM_KOREAN_NB, sega8_korean_nb_device, "sega8_korean_nb", "SMS Korean No-Bank Mapper Carts") DEFINE_DEVICE_TYPE(SEGA8_ROM_SEOJIN, sega8_seojin_device, "sega8_seojin", "SMS Seo Jin Multi-cart") +DEFINE_DEVICE_TYPE(SEGA8_ROM_X_TERMINATOR, sega8_x_terminator_device, "sega8_x_terminator", "GG X-Terminator") // Specific SC-3000 cart types DEFINE_DEVICE_TYPE(SEGA8_ROM_MULTICART, sega8_multicart_device, "sega8_multicart", "SC-3000 MkII Multicart Cart") @@ -1135,3 +1136,147 @@ void sega8_megacart_device::write_io(offs_t offset, uint8_t data) if ((offset & 0xe0) == 0xe0) m_block = (data & 0x1f) | (data & 0xc0) >> 1; } + + +/*------------------------------------------------- + +GG X-Terminator + +The cartridge has a switch to choose NORMAL or ACTION mode +and a RESET button. + +The X-Terminator has logic to switch between the X-Terminator's +ROM and game ROM when $0038 is read. +When starting up the X-Terminator's ROM is active. In NORMAL +mode any read of $38 switches to game ROM. In ACTION mode any +read of $38 switches between game ROM and X-Terminator ROM (this +allows the X-Terminator to inject cheat codes during IRQs). + +While running a game the RESET button is used to get back +into the X-Terminator to search for cheat codes. + + -------------------------------------------------*/ + +sega8_x_terminator_device::sega8_x_terminator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : sega8_rom_device(mconfig, SEGA8_ROM_X_TERMINATOR, tag, owner, clock) + , m_subslot(*this, "subslot") + , m_switch(*this, "SWITCH") + , m_reset(*this, "RESET") + , m_active(true) +{ +} + +static INPUT_PORTS_START( x_terminator ) + PORT_START("SWITCH") + PORT_DIPNAME( 0x01, 0x00, "NORMAL/ACTION" ) + PORT_DIPSETTING( 0x00, "NORMAL" ) + PORT_DIPSETTING( 0x01, "ACTION" ) + + PORT_START("RESET") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Reset") +INPUT_PORTS_END + +ioport_constructor sega8_x_terminator_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( x_terminator ); +} + +void sega8_x_terminator_device::device_add_mconfig(machine_config &config) +{ + GAMEGEAR_CART_SLOT(config, "subslot", gg_cart, nullptr); + SOFTWARE_LIST(config, "cart_list").set_original("gamegear"); +} + +void sega8_x_terminator_device::device_start() +{ + save_item(NAME(m_active)); +} + +void sega8_x_terminator_device::device_reset() +{ + m_active = true; +} + +uint8_t sega8_x_terminator_device::read_cart(offs_t offset) +{ + if (offset == 0x38 && !machine().side_effects_disabled()) + { + if (BIT(m_switch->read(), 0)) + { + // ACTION + m_active = !m_active; + } + else if (!BIT(m_reset->read(), 0)) + { + // RESET button pressed + m_active = true; + } + else + { + // NORMAL + m_active = false; + } + } + if (m_active) + { + // RAM at 0x2000-0x3fff + if (offset >= 0x2000 && offset < 0x4000) + return m_ram[offset & 0x1fff]; + + // Check RESET button + if (offset == 0x0007) + return m_reset->read(); + + return m_rom[offset % m_rom_size]; + } + else + { + // Pass-through to inserted game cartridge + return m_subslot->read_cart(offset); + } +} + +void sega8_x_terminator_device::write_cart(offs_t offset, uint8_t data) +{ + if (m_active) + { + // RAM at 0x2000-0x23fff + if (offset >= 0x2000 && offset < 0x4000) + m_ram[offset & 0x1fff] = data; + } + else + { + // Pass-through to inserted game cartridge + m_subslot->write_cart(offset, data); + } +} + +void sega8_x_terminator_device::write_mapper(offs_t offset, uint8_t data) +{ + // Pass-through to inserted game cartridge + m_subslot->write_mapper(offset, data); +} + +uint8_t sega8_x_terminator_device::read_ram(offs_t offset) +{ + // Pass-through to inserted game cartridge + return m_subslot->read_ram(offset); +} + +void sega8_x_terminator_device::write_ram(offs_t offset, uint8_t data) +{ + // Pass-through to inserted game cartridge + m_subslot->write_ram(offset, data); +} + +uint8_t sega8_x_terminator_device::read_io(offs_t offset) +{ + // Pass-through to inserted game cartridge + return m_subslot->read_io(offset); +} + +void sega8_x_terminator_device::write_io(offs_t offset, uint8_t data) +{ + // Pass-through to inserted game cartridge + m_subslot->write_io(offset, data); +} diff --git a/src/devices/bus/sega8/rom.h b/src/devices/bus/sega8/rom.h index de4272a4253..1af8cdb1c5b 100644 --- a/src/devices/bus/sega8/rom.h +++ b/src/devices/bus/sega8/rom.h @@ -450,6 +450,33 @@ private: uint8_t m_block; }; +class sega8_x_terminator_device : public sega8_rom_device +{ +public: + sega8_x_terminator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual ioport_constructor device_input_ports() const override; + + // reading and writing + virtual uint8_t read_cart(offs_t offset) override; + virtual void write_cart(offs_t offset, uint8_t data) override; + virtual void write_mapper(offs_t offset, uint8_t data) override; + virtual uint8_t read_ram(offs_t offset) override; + virtual void write_ram(offs_t offset, uint8_t data) override; + virtual uint8_t read_io(offs_t offset) override; + virtual void write_io(offs_t offset, uint8_t data) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + required_device m_subslot; + required_ioport m_switch; + required_ioport m_reset; + bool m_active; +}; // device type definition DECLARE_DEVICE_TYPE(SEGA8_ROM_STD, sega8_rom_device) @@ -472,5 +499,6 @@ DECLARE_DEVICE_TYPE(SEGA8_ROM_KOREAN_NB, sega8_korean_nb_device) DECLARE_DEVICE_TYPE(SEGA8_ROM_SEOJIN, sega8_seojin_device) DECLARE_DEVICE_TYPE(SEGA8_ROM_MULTICART, sega8_multicart_device) DECLARE_DEVICE_TYPE(SEGA8_ROM_MEGACART, sega8_megacart_device) +DECLARE_DEVICE_TYPE(SEGA8_ROM_X_TERMINATOR, sega8_x_terminator_device) #endif // MAME_BUS_SEGA8_ROM_H diff --git a/src/devices/bus/sega8/sega8_slot.cpp b/src/devices/bus/sega8/sega8_slot.cpp index 02bcd1213af..8330fc68915 100644 --- a/src/devices/bus/sega8/sega8_slot.cpp +++ b/src/devices/bus/sega8/sega8_slot.cpp @@ -232,7 +232,8 @@ static const sega8_slot slot_list[] = { SEGA8_DAHJEE_TYPEB, "dahjee_typeb" }, { SEGA8_SEOJIN, "seojin" }, { SEGA8_MULTICART, "multicart" }, - { SEGA8_MEGACART, "megacart" } + { SEGA8_MEGACART, "megacart" }, + { SEGA8_X_TERMINATOR, "xterminator" } }; static int sega8_get_pcb_id(const char *slot) @@ -357,6 +358,12 @@ void sega8_cart_slot_device::setup_ram() m_cart->ram_alloc(0x10000); m_cart->set_has_battery(false); } + else if (m_type == SEGA8_X_TERMINATOR) + { + // X-Terminator seems to have 8192 bytes of RAM + // Unknown if the RAM is battery backed + m_cart->ram_alloc(0x2000); + } else { // for generic carts loaded from fullpath we have no way to know exactly if there was RAM, @@ -646,6 +653,8 @@ int sega8_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len) cons if (len == 0x400000) type = SEGA8_MEGACART; + if (len == 0x2000) + type = SEGA8_X_TERMINATOR; return type; } @@ -938,4 +947,5 @@ void gg_cart(device_slot_interface &device) device.option_add_internal("eeprom", SEGA8_ROM_EEPROM); device.option_add_internal("codemasters", SEGA8_ROM_CODEMASTERS); device.option_add_internal("mgear", SEGA8_ROM_MGEAR); + device.option_add_internal("xterminator", SEGA8_ROM_X_TERMINATOR); } diff --git a/src/devices/bus/sega8/sega8_slot.h b/src/devices/bus/sega8/sega8_slot.h index 9cca56c3ccf..05502dad7d8 100644 --- a/src/devices/bus/sega8/sega8_slot.h +++ b/src/devices/bus/sega8/sega8_slot.h @@ -34,7 +34,8 @@ enum SEGA8_DAHJEE_TYPEB, SEGA8_SEOJIN, SEGA8_MULTICART, - SEGA8_MEGACART + SEGA8_MEGACART, + SEGA8_X_TERMINATOR };