bus/gameboy: Added support for bootleg Telefang translations.

English and German versions of the Speed Version bootleg, passed off as
Pokémon Jade version, have been added to the software list.  Chinese and
Spanish translations, and translations of Power Version (Pokémon
Diamond) also exist.

New working software list additions (gbcolor.xml)
-----------------------------------
Pokémon Jade Version [taizou]
Pokémon Vision Jade [Sanqui, taizou]
This commit is contained in:
Vas Crabb 2022-11-12 06:36:29 +11:00
parent 6c0257b1a1
commit d75c4cc68e
10 changed files with 196 additions and 26 deletions

View File

@ -9993,9 +9993,9 @@ license:CC0
<description>Keitai Denjuu Telefang - Power Version (Japan)</description>
<year>2000</year>
<publisher>Natsume</publisher>
<info name="serial" value="DMG-BTXJ-JPN"/>
<info name="release" value="20001103"/>
<info name="alt_title" value="携帯電獣テレファング パワー・バージョン"/>
<info name="serial" value="DMG-BTXJ-JPN" />
<info name="release" value="20001103" />
<info name="alt_title" value="携帯電獣テレファング パワー・バージョン" />
<part name="cart" interface="gameboy_cart">
<feature name="pcb" value="DMG-KGDU-10" />
<feature name="u1" value="U1 PRG" />
@ -10005,11 +10005,10 @@ license:CC0
<feature name="battery" value="BT1 CR2025" />
<feature name="slot" value="rom_mbc3" />
<feature name="rtc" value="yes" />
<dataarea name="rom" size="2097152">
<rom name="dmg-btxj-0.u1" size="2097152" crc="8b61cfcc" sha1="baaf7fb9f9958ca22982ba0600bc0cb8a7fc4764"/>
</dataarea>
<dataarea name="nvram" size="32768">
<dataarea name="rom" size="0x200000">
<rom name="dmg-btxj-0.u1" size="0x200000" crc="8b61cfcc" sha1="baaf7fb9f9958ca22982ba0600bc0cb8a7fc4764" />
</dataarea>
<dataarea name="nvram" size="0x8000" />
</part>
</software>
@ -10017,17 +10016,47 @@ license:CC0
<description>Keitai Denjuu Telefang - Speed Version (Japan)</description>
<year>2000</year>
<publisher>Natsume</publisher>
<info name="serial" value="DMG-BTZJ-JPN"/>
<info name="release" value="20001103"/>
<info name="alt_title" value="携帯電獣テレファング スピード・バージョン"/>
<info name="serial" value="DMG-BTZJ-JPN" />
<info name="release" value="20001103" />
<info name="alt_title" value="携帯電獣テレファング スピード・バージョン" />
<part name="cart" interface="gameboy_cart">
<feature name="slot" value="rom_mbc3" />
<feature name="rtc" value="yes" />
<dataarea name="rom" size="2097152">
<rom name="keitai denjuu telefang - speed version (japan).bin" size="2097152" crc="fb528f66" sha1="1c273f9078c580e85e5c49e7114058f3e0fe5cca"/>
<dataarea name="rom" size="0x200000">
<rom name="keitai denjuu telefang - speed version (japan).bin" size="0x200000" crc="fb528f66" sha1="1c273f9078c580e85e5c49e7114058f3e0fe5cca" />
</dataarea>
<dataarea name="nvram" size="32768">
<dataarea name="nvram" size="0x8000" />
</part>
</software>
<!-- unlicensed English translation of Keitai Denjuu Telefang - Speed Version -->
<software name="pkmnjade" cloneof="telefngs">
<description>Pokémon Jade Version</description>
<year>200?</year>
<publisher>bootleg</publisher>
<info name="alt_title" value="Pokémon Jade" /> <!-- title screen doesn't say "version" -->
<part name="cart" interface="gameboy_cart">
<feature name="slot" value="rom_tfboot" />
<feature name="rtc" value="no" />
<dataarea name="rom" size="0x200000">
<rom name="pokemon jade version.bin" size="0x200000" crc="aa07f269" sha1="994a205d7c0b55f45715a65b23ec31258e43652f" />
</dataarea>
<dataarea name="nvram" size="0x8000" />
</part>
</software>
<!-- unlicensed German translation of Keitai Denjuu Telefang - Speed Version -->
<software name="pkmnjadede" cloneof="telefngs">
<description>Pokémon Vision Jade</description>
<year>200?</year>
<publisher>bootleg</publisher>
<part name="cart" interface="gameboy_cart">
<feature name="slot" value="rom_tfboot" /> <!-- doesn't actually use protection features - works with a regular MBC3 -->
<feature name="rtc" value="no" />
<dataarea name="rom" size="0x200000">
<rom name="pokemon vision jade.bin" size="0x200000" crc="2705ca20" sha1="72d5c6b8a570e67e7bce59070417cb89e985efb0" />
</dataarea>
<dataarea name="nvram" size="0x8000" />
</part>
</software>

View File

@ -51,6 +51,7 @@ char const *const GB_HUC1 = "rom_huc1";
char const *const GB_HUC3 = "rom_huc3";
char const *const GB_TAMA5 = "rom_tama5";
char const *const GB_CAMERA = "rom_camera";
char const *const GB_TFANGBOOT = "rom_tfboot";
char const *const GB_SINTAX = "rom_sintax";
char const *const GB_CHONGWU = "rom_chong";
char const *const GB_LICHENG = "rom_licheng";
@ -95,6 +96,7 @@ void gameboy_cartridges(device_slot_interface &device)
device.option_add_internal(slotoptions::GB_HUC1, GB_ROM_HUC1);
device.option_add_internal(slotoptions::GB_HUC3, GB_ROM_HUC3);
device.option_add_internal(slotoptions::GB_TAMA5, GB_ROM_TAMA5);
device.option_add_internal(slotoptions::GB_TFANGBOOT, GB_ROM_TFANGBOOT);
device.option_add_internal(slotoptions::GB_SINTAX, GB_ROM_SINTAX);
device.option_add_internal(slotoptions::GB_CHONGWU, GB_ROM_CHONGWU);
device.option_add_internal(slotoptions::GB_LICHENG, GB_ROM_LICHENG);

View File

@ -40,6 +40,7 @@ extern char const *const GB_CAMERA;
extern char const *const GB_HUC1;
extern char const *const GB_HUC3;
extern char const *const GB_TAMA5;
extern char const *const GB_TFANGBOOT;
extern char const *const GB_SINTAX;
extern char const *const GB_CHONGWU;
extern char const *const GB_LICHENG;

View File

@ -734,6 +734,9 @@ std::optional<char const *> probe_gbx_footer(std::string_view tag, util::random_
case gbxfile::TYPE_HUC3:
result = slotoptions::GB_HUC3;
break;
case gbxfile::TYPE_TFANGBOOT:
result = slotoptions::GB_TFANGBOOT;
break;
case gbxfile::TYPE_SINTAX:
result = slotoptions::GB_SINTAX;
break;

View File

@ -67,6 +67,7 @@ enum : u32
TYPE_MMM01 = 0x4d4d4d31, // 'MMM1'
TYPE_NEWGBCHK = 0x4e47484b, // 'NGHK'
TYPE_NTNEW = 0x4e544e00, // 'NTN\0'
TYPE_TFANGBOOT = 0x504b4a44, // 'PKJD'
TYPE_ROCKET = 0x524f434b, // 'ROCK'
TYPE_PLAIN = 0x524f4d00, // 'ROM\0'
TYPE_SACHEN1 = 0x53414d31, // 'SAM1'

View File

@ -114,7 +114,7 @@ void liebao_device::device_reset()
void liebao_device::enable_ram(offs_t offset, u8 data)
{
// TODO: how many bits are checked?
bool const enable = 0x0a == (data & 0x0f);
bool const enable(0x0a == (data & 0x0f));
LOG(
"%s: Cartridge RAM %s\n",
machine().describe_context(),

View File

@ -10,7 +10,6 @@
DECLARE_DEVICE_TYPE(GB_ROM_MBC1, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_MBC5, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_MMM01, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_SINTAX, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_CHONGWU, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_LICHENG, device_gb_cart_interface)

View File

@ -47,6 +47,17 @@
-X------ Set to halt real-time clock.
-------X Bit 8 of days.
Telefang bootlegs have three additional registers:
0x5 - Low value.
0x6 - High value.
0x7 - Command:
0x11 Decrement low value.
0x12 Decrement high value.
0x41 Add high value to low value.
0x42 Add low value to high value.
0x51 Increment low value.
0x52 Increment high value.
TODO:
* How are the static RAM bank outputs set when real-time clock registers
are selected?
@ -54,6 +65,8 @@
* How do invalid seconds, minutes and hours values roll over?
* Does MBC30 really have eight ROM bank outputs? The one game using it
only uses seven.
* Does the bootleg Keitai Denjuu Telefang controller actually include a
real-time clock? No oscillator crystal is present.
***************************************************************************/
@ -100,6 +113,13 @@ protected:
bool install_memory(std::string &message, unsigned highbits, unsigned lowbits) ATTR_COLD;
protected:
u8 const rtc_select() const { return BIT(m_rtc_select, 3); }
u8 const rtc_register() const { return m_rtc_select & 0x07; }
virtual u8 read_rtc(address_space &space);
virtual void write_rtc(u8 data);
private:
static inline constexpr u8 RTC_MASK[]{ 0x3f, 0x3f, 0x1f, 0xff, 0xc1 };
static inline constexpr u8 RTC_ROLLOVER[]{ 0x3c, 0x3c, 0x18, 0x00, 0x00 };
@ -110,8 +130,6 @@ private:
void bank_switch_fine(u8 data);
void select_ram_rtc(u8 data);
void latch_rtc(u8 data);
u8 read_rtc(address_space &space);
void write_rtc(u8 data);
u8 rtc_increment(unsigned index)
{
@ -153,6 +171,25 @@ public:
};
class tfboot_device : public mbc3_device_base
{
public:
tfboot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
virtual image_init_result load(std::string &message) override ATTR_COLD;
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual u8 read_rtc(address_space &space) override;
virtual void write_rtc(u8 data) override;
private:
u8 m_protection[2];
};
//**************************************************************************
// mbc3_device_base
@ -546,12 +583,12 @@ void mbc3_device_base::enable_ram_rtc(u8 data)
machine().describe_context());
m_view_ram.disable();
}
else if (BIT(m_rtc_select, 3))
else if (rtc_select())
{
LOG(
"%s: RTC register %u enabled\n",
machine().describe_context(),
m_rtc_select & 0x07);
rtc_register());
m_view_ram.select(1);
}
else
@ -611,7 +648,7 @@ void mbc3_device_base::latch_rtc(u8 data)
u8 mbc3_device_base::read_rtc(address_space &space)
{
u8 const reg(m_rtc_select & 0x07);
u8 const reg(rtc_register());
if (std::size(m_rtc_regs[1]) > reg)
{
LOG(
@ -634,7 +671,7 @@ u8 mbc3_device_base::read_rtc(address_space &space)
void mbc3_device_base::write_rtc(u8 data)
{
u8 const reg(m_rtc_select & 0x07);
u8 const reg(rtc_register());
if (std::size(m_rtc_regs[0]) > reg)
{
LOG(
@ -712,10 +749,107 @@ image_init_result mbc30_device::load(std::string &message)
return image_init_result::PASS;
}
//**************************************************************************
// tfboot_device
//**************************************************************************
tfboot_device::tfboot_device(
machine_config const &mconfig,
char const *tag,
device_t *owner,
u32 clock) :
mbc3_device_base(mconfig, GB_ROM_TFANGBOOT, tag, owner, clock),
m_protection{ 0U, 0U }
{
}
image_init_result tfboot_device::load(std::string &message)
{
if (!install_memory(message, 2, 7))
return image_init_result::FAIL;
else
return image_init_result::PASS;
}
void tfboot_device::device_start()
{
mbc3_device_base::device_start();
save_item(NAME(m_protection));
}
void tfboot_device::device_reset()
{
mbc3_device_base::device_reset();
m_protection[0] = 0U;
m_protection[1] = 0U;
}
u8 tfboot_device::read_rtc(address_space &space)
{
u8 const reg(rtc_register());
switch (reg)
{
case 0x05:
case 0x06:
return m_protection[BIT(reg, 0)];
case 0x07:
return 0U;
default:
return mbc3_device_base::read_rtc(space);
}
}
void tfboot_device::write_rtc(u8 data)
{
u8 const reg(rtc_register());
switch (reg)
{
case 0x05:
case 0x06:
m_protection[BIT(reg, 0)] = data;
break;
case 0x07:
LOG("%s: Protection command 0x%02X\n", machine().describe_context(), data);
switch (data)
{
case 0x11:
case 0x12:
--m_protection[BIT(data, 0)];
break;
case 0x41:
case 0x42:
m_protection[BIT(data, 0)] += m_protection[BIT(~data, 0)];
break;
case 0x51:
case 0x52:
++m_protection[BIT(data, 0)];
break;
default:
logerror(
"%s: Unknown protection command 0x%02X\n",
machine().describe_context(),
data);
}
break;
default:
mbc3_device_base::write_rtc(data);
}
}
} // anonymous namespace
} // namespace bus::gameboy
DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC3, device_gb_cart_interface, bus::gameboy::mbc3_device, "gb_rom_mbc3", "Game Boy MBC3 Cartridge")
DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC30, device_gb_cart_interface, bus::gameboy::mbc30_device, "gb_rom_mbc30", "Game Boy MBC30 Cartridge")
DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC3, device_gb_cart_interface, bus::gameboy::mbc3_device, "gb_rom_mbc3", "Game Boy MBC3 Cartridge")
DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC30, device_gb_cart_interface, bus::gameboy::mbc30_device, "gb_rom_mbc30", "Game Boy MBC30 Cartridge")
DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_TFANGBOOT, device_gb_cart_interface, bus::gameboy::tfboot_device, "gb_rom_tfboot", "Game Boy Telefang bootleg Cartridge")

View File

@ -13,7 +13,8 @@
#include "slot.h"
DECLARE_DEVICE_TYPE(GB_ROM_MBC3, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_MBC30, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_MBC3, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_MBC30, device_gb_cart_interface)
DECLARE_DEVICE_TYPE(GB_ROM_TFANGBOOT, device_gb_cart_interface)
#endif // MAME_BUS_GAMEBOY_MBC3_H

View File

@ -125,7 +125,7 @@ void ntnew_device::enable_ram(offs_t offset, u8 data)
}
// TODO: how many bits are checked?
bool const enable = 0x0a == (data & 0x0f);
bool const enable(0x0a == (data & 0x0f));
LOG(
"%s: Cartridge RAM %s\n",
machine().describe_context(),