mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
namco/namcos10.cpp: More dumps/redumps, new decryption devices, and more I/O emulation. (#11114)
* Implemented the basics of the MEM(P3) memory/I/O board. * Added controls for more games. * Marked Pacman BALL as a bad dump. * Marked all games as MACHINE_IMPERFECT_SOUND in anticipation of complaints. * cpu/tlcs900/tmp95c061.cpp: Added basic ADC support (based on TMP95C063). * namco/namcos10_exio.cpp: Added System 10 I/O expander board (EXIO) emulation. * namco/ns10crypt.cpp: Moved per-game decryption setup to client configuration. * Added decryption setups for GAHAHA Ippatsudou, Golgo 13: Juusei no Requiem, Sekai Kaseki Hakken, Pacman BALL, Medal no Tatsujin, Medal no Tatsujin 2 and Sugorotic JAPAN. [Samuel Neves, Peter Wilhelmsen] Systems promoted to working ---------------------------- GAHAHA Ippatsudou (World, GID2 Ver.A) [Samuel Neves, Peter Wilhelmsen, Windy Fairy] GAHAHA Ippatsudou 2 (Japan, GIS1 Ver.A) [Samuel Neves, Peter Wilhelmsen, Windy Fairy] Golgo 13: Juusei no Requiem (Japan, GLT1 VER.A) [Samuel Neves, Peter Wilhelmsen, Windy Fairy] Kotoba no Puzzle Mojipittan (Japan, KPM1 Ver.A) [Brizzo, Smitdogg, The Dumping Union, Windy Fairy] New systems marked not working -------------------------------- Sugorotic JAPAN (STJ1 Ver.C) [Brizzo, Smitdogg, The Dumping Union] Tsukkomi Yousei Gips Nice Tsukkomi (NTK1 Ver.A) [Guru]
This commit is contained in:
parent
87dc49048b
commit
fd4f515024
@ -30,6 +30,7 @@ tmp95c061_device::tmp95c061_device(const machine_config &mconfig, const char *ta
|
||||
m_porta_write(*this),
|
||||
m_portb_read(*this),
|
||||
m_portb_write(*this),
|
||||
m_an_read(*this),
|
||||
m_port_latch{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
m_port_control{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
m_port_function{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
@ -206,6 +207,7 @@ void tmp95c061_device::device_start()
|
||||
m_porta_write.resolve_safe();
|
||||
m_portb_read.resolve_safe(0);
|
||||
m_portb_write.resolve_safe();
|
||||
m_an_read.resolve_all_safe(0);
|
||||
}
|
||||
|
||||
void tmp95c061_device::device_reset()
|
||||
@ -550,15 +552,29 @@ void tmp95c061_device::tlcs900_handle_ad()
|
||||
if ( m_ad_cycles_left <= 0 )
|
||||
{
|
||||
/* Store A/D converted value */
|
||||
switch( m_ad_mode & 0x03 )
|
||||
if ( ( m_ad_mode & 0x10 ) == 0 )
|
||||
{
|
||||
case 0x00: /* AN0 */
|
||||
m_ad_result[0] = 0x3ff;
|
||||
break;
|
||||
case 0x01: /* AN1 */
|
||||
case 0x02: /* AN2 */
|
||||
case 0x03: /* AN3 */
|
||||
break;
|
||||
/* conversion channel fixed */
|
||||
m_ad_result[m_ad_mode & 0x03] = m_an_read[m_ad_mode & 0x03](0) & 0x3ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* conversion channel sweep */
|
||||
switch( m_ad_mode & 0x03 )
|
||||
{
|
||||
case 0x03: /* AN3 */
|
||||
m_ad_result[3] = m_an_read[3](0) & 0x3ff;
|
||||
[[fallthrough]];
|
||||
case 0x02: /* AN2 */
|
||||
m_ad_result[2] = m_an_read[2](0) & 0x3ff;
|
||||
[[fallthrough]];
|
||||
case 0x01: /* AN1 */
|
||||
m_ad_result[1] = m_an_read[1](0) & 0x3ff;
|
||||
[[fallthrough]];
|
||||
case 0x00: /* AN0 */
|
||||
m_ad_result[0] = m_an_read[0](0) & 0x3ff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear BUSY flag, set END flag */
|
||||
@ -1355,10 +1371,15 @@ void tmp95c061_device::ode_w(uint8_t data)
|
||||
|
||||
uint8_t tmp95c061_device::adreg_r(offs_t offset)
|
||||
{
|
||||
// ADMOD EOCF is cleared to 0 when reading any ADREG0..3
|
||||
m_ad_mode &= ~0x80;
|
||||
|
||||
if (BIT(offset, 0))
|
||||
return m_ad_result[offset >> 1] >> 2;
|
||||
else
|
||||
return m_ad_result[offset >> 1] << 6 | 0x3f;
|
||||
|
||||
// Reading data from the upper 8 bits clears INTE0AD IADC
|
||||
m_int_reg[TMP95C061_INTE0AD] &= ~0x80;
|
||||
return m_ad_result[offset >> 1] << 6 | 0x3f;
|
||||
}
|
||||
|
||||
uint8_t tmp95c061_device::admod_r()
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
auto porta_write() { return m_porta_write.bind(); }
|
||||
auto portb_read() { return m_portb_read.bind(); }
|
||||
auto portb_write() { return m_portb_write.bind(); }
|
||||
template <size_t Bit> auto an_read() { return m_an_read[Bit].bind(); }
|
||||
|
||||
protected:
|
||||
virtual void device_config_complete() override;
|
||||
@ -183,6 +184,9 @@ private:
|
||||
devcb_read8 m_portb_read;
|
||||
devcb_write8 m_portb_write;
|
||||
|
||||
// analogue inputs, sampled at 10 bits
|
||||
devcb_read16::array<4> m_an_read;
|
||||
|
||||
// I/O Port Control
|
||||
uint8_t m_port_latch[0xc];
|
||||
uint8_t m_port_control[0xc];
|
||||
|
@ -241,6 +241,7 @@ const double XTAL::known_xtals[] = {
|
||||
14'742'800, /* 14.7428_MHz_XTAL ADM 23 */
|
||||
14'745'000, /* 14.745_MHz_XTAL Synertek KTM-3 */
|
||||
14'745'600, /* 14.7456_MHz_XTAL Namco System 12 & System Super 22/23 for JVS */
|
||||
14'746'000, /* 14.746_MHz_XTAL Namco System 10 MGEXIO */
|
||||
14'784'000, /* 14.784_MHz_XTAL Zenith Z-29 */
|
||||
14'916'000, /* 14.916_MHz_XTAL ADDS Viewpoint 122 */
|
||||
14'976'000, /* 14.976_MHz_XTAL CIT-101 80-column display clock */
|
||||
|
@ -32409,37 +32409,39 @@ valkyrie // (c) 1989 (Japan)
|
||||
@source:namco/namcos10.cpp
|
||||
ballpom // 2005.02 Ball Pom Line
|
||||
chocovdr // 2002.10 Uchuu Daisakusen : Chocovader Contactee
|
||||
g13jnc // 2001.?? Golgo 13: Juusei no Chinkonka (Japan, GLT1 VER.A)
|
||||
gahaha // 2000.?? GAHAHA Ippatsudou (World, GID2 Ver.A)
|
||||
gahaha2 // 2001.?? GAHAHA Ippatsudou 2 (Japan, GIS1 Ver.A)
|
||||
g13jnr // 2001.07 Golgo 13: Juusei no Requiem (Japan, GLT1 VER.A)
|
||||
gahaha // 2000.03 GAHAHA Ippatsudou (World, GID2 Ver.A)
|
||||
gahaha2 // 2001.09 GAHAHA Ippatsudou 2 (Japan, GIS1 Ver.A)
|
||||
gamshara // 2002.08 Gamshara (10021 Ver.A)
|
||||
gamsharaj // 2002.08 Gamshara (10021 Ver.A)
|
||||
gegemdb // 2007.?? Gegege no Kitarō Yōkai Yokochō Matsuri De Batoru Ja (GYM1 Ver.A)
|
||||
gegemdb // 2007.12 Gegege no Kitarō Yōkai Yokochō Matsuri De Batoru Ja (GYM1 Ver.A)
|
||||
gjspace // 2001.12 Gekitoride-Jong Space (10011 Ver.A)
|
||||
gunbalina // 2000.12 Gunbalina (GNN1 Ver.A)
|
||||
kd2001 // 2001.1? Knock Down 2001 (KD11 Ver.B)
|
||||
keroro // 2006.?? Keroro Gunso Chikyu Shinryaku Shirei Dearimasu! (KRG1 Ver.A)
|
||||
kd2001 // 2001.11 Knock Down 2001 (KD11 Ver.B)
|
||||
keroro // 2006.08 Keroro Gunso Chikyu Shinryaku Shirei Dearimasu! (KRG1 Ver.A)
|
||||
knpuzzle // 2001.12 Kotoba no Puzzle Mojipittan (KPM1 Ver.A)
|
||||
konotako // 2003.?? Kono e Tako (10021 Ver.A)
|
||||
konotako // 2003.11 Kono e Tako (10021 Ver.A)
|
||||
medalnt // 2005.04 Medal No Tatsujin Doki! Ooatari-Darake No Sugoroku Matsuri (MTL1 SPR0B)
|
||||
medalnt2 // 2007.02 Medal no Tatsujin 2 Atsumare! Go! Go! Sugoroku Sentai Don Ranger Five (MTA1 STMPR0A)
|
||||
mrdrilr2 // 2000.?? Mr Driller 2 (DR22 Ver.A)
|
||||
mrdrilr2 // 2000.07 Mr Driller 2 (DR22 Ver.A)
|
||||
mrdrilr2j // 2000.07 Mr Driller 2 (DR21 Ver.A)
|
||||
mrdrilr2u // 2000.?? Mr Driller 2 (DR23 Ver.A)
|
||||
mrdrilr2u // 2000.07 Mr Driller 2 (DR23 Ver.A)
|
||||
mrdrilrg // 2001.03 Mr. Driller G (DRG1 Ver.A)
|
||||
nflclsfb // 2003.?? NFL Classic Football
|
||||
nicetsuk // 2002.07 Tsukkomi Yousei Gips Nice Tsukkomi (NTK1 Ver.A)
|
||||
pacmball // 2003.?? Pacman Ball
|
||||
panikuru // 2002.03 Panicuru Panekuru
|
||||
ptblank3 // 2000.12 Point Blank 3 (GNN2 Ver.A)
|
||||
puzzball // 2002.02 Puzz Ball (Japan, PZB1 Ver.A)
|
||||
sekaikh // 2004.0? Sekai Kaseki Hakken (Japan, SKH1 Ver.B)
|
||||
sekaikha // 2004.04 Sekai Kaseki Hakken (Japan, SKH1 Ver.A)
|
||||
sekaikh // 2004.03 Sekai Kaseki Hakken (Japan, SKH1 Ver.B)
|
||||
sekaikha // 2004.03 Sekai Kaseki Hakken (Japan, SKH1 Ver.A)
|
||||
startrgn // 2002.07 Star Trigon (STT1 Ver.A)
|
||||
sugorotic // 2002.02 Sugorotic JAPAN (STJ1 Ver.C)
|
||||
taiko2 // 2001.08 Taiko no Tatsujin 2 (Japan, TK21 Ver.C)
|
||||
taiko3 // 2002.03 Taiko no Tatsujin 3 (Japan, TK31 Ver.A)
|
||||
taiko4 // 2002.12 Taiko no Tatsujin 4 (Japan, TK41 Ver.A)
|
||||
taiko5 // 2003.10 Taiko no Tatsujin 5 (Japan, TK51 Ver.A)
|
||||
taiko6 // 2004.07 Taiko no Tatsujin 6 (Japan, TK61 Ver.A)
|
||||
unks10md // 200?.?? unknown Namco System 10 medal game (MTL1 SPRB0)
|
||||
|
||||
@source:namco/namcos11.cpp
|
||||
danceyes // 1996.09 Dancing Eyes (World, DC2/VER.B)
|
||||
|
File diff suppressed because it is too large
Load Diff
300
src/mame/namco/namcos10_exio.cpp
Normal file
300
src/mame/namco/namcos10_exio.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:windyfairy
|
||||
#include "emu.h"
|
||||
#include "namcos10_exio.h"
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(NAMCOS10_EXIO, namcos10_exio_device, "namcos10_exio", "Namco System 10 EXIO")
|
||||
DEFINE_DEVICE_TYPE(NAMCOS10_EXIO_BASE, namcos10_exio_base_device, "namcos10_exio_g", "Namco System 10 EXIO(G)")
|
||||
DEFINE_DEVICE_TYPE(NAMCOS10_MGEXIO, namcos10_mgexio_device, "namcos10_mgexio", "Namco System 10 MGEXIO")
|
||||
|
||||
// EXIO(G) has the bare minimum: CPLD, audio output jacks, gun I/O, and a card edge connector for additional I/O
|
||||
namcos10_exio_base_device::namcos10_exio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t ident_code) :
|
||||
device_t(mconfig, type, tag, owner, clock), m_ident_code(ident_code)
|
||||
{
|
||||
}
|
||||
|
||||
namcos10_exio_base_device::namcos10_exio_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
namcos10_exio_base_device(mconfig, NAMCOS10_EXIO_BASE, tag, owner, clock, 0x32)
|
||||
{
|
||||
}
|
||||
|
||||
void namcos10_exio_base_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
namcos10_exio_device::namcos10_exio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
namcos10_exio_base_device(mconfig, NAMCOS10_EXIO, tag, owner, clock, 0x30),
|
||||
m_maincpu(*this, "exio_mcu"),
|
||||
m_ram(*this, "exio_ram"),
|
||||
m_analog_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void namcos10_exio_device::device_start()
|
||||
{
|
||||
namcos10_exio_base_device::device_start();
|
||||
|
||||
m_analog_cb.resolve_safe(0);
|
||||
|
||||
save_item(NAME(m_is_active));
|
||||
save_item(NAME(m_analog_idx));
|
||||
}
|
||||
|
||||
void namcos10_exio_device::device_reset_after_children()
|
||||
{
|
||||
namcos10_exio_base_device::device_reset_after_children();
|
||||
|
||||
m_maincpu->suspend(SUSPEND_REASON_HALT, 1);
|
||||
m_is_active = false;
|
||||
m_analog_idx = 0;
|
||||
}
|
||||
|
||||
void namcos10_exio_device::map(address_map &map)
|
||||
{
|
||||
map(0x000100, 0x002fff).ram(); // TODO: Stack and such is stored here, how large should this really be?
|
||||
map(0x003000, 0x007fff).ram().mirror(0xff8000).share(m_ram);
|
||||
}
|
||||
|
||||
void namcos10_exio_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
// TODO: tmp95c061 doesn't have a serial implementation yet so JVS communication won't work for now
|
||||
TMP95C061(config, m_maincpu, XTAL(22'118'400));
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &namcos10_exio_device::map);
|
||||
|
||||
m_maincpu->port1_read().set(FUNC(namcos10_exio_device::port_read<1>));
|
||||
m_maincpu->port5_read().set(FUNC(namcos10_exio_device::port_read<5>));
|
||||
m_maincpu->port7_read().set(FUNC(namcos10_exio_device::port_read<7>));
|
||||
m_maincpu->port8_read().set(FUNC(namcos10_exio_device::port_read<8>));
|
||||
m_maincpu->port9_read().set(FUNC(namcos10_exio_device::port_read<9>));
|
||||
m_maincpu->porta_read().set(FUNC(namcos10_exio_device::port_read<10>));
|
||||
m_maincpu->portb_read().set(FUNC(namcos10_exio_device::port_read<11>));
|
||||
m_maincpu->port1_write().set(FUNC(namcos10_exio_device::port_write<1>));
|
||||
m_maincpu->port2_write().set(FUNC(namcos10_exio_device::port_write<2>));
|
||||
m_maincpu->port5_write().set(FUNC(namcos10_exio_device::port_write<5>));
|
||||
m_maincpu->port6_write().set(FUNC(namcos10_exio_device::port_write<6>));
|
||||
m_maincpu->port8_write().set(FUNC(namcos10_exio_device::port_write<8>));
|
||||
m_maincpu->porta_write().set(FUNC(namcos10_exio_device::port_write<10>));
|
||||
m_maincpu->portb_write().set(FUNC(namcos10_exio_device::port_write<11>));
|
||||
|
||||
m_maincpu->port7_write().set([this] (uint8_t data) {
|
||||
// The common EXIO program uploaded seems to write what analog value it wants to read here.
|
||||
// Going to the CPLD?
|
||||
m_analog_idx = data;
|
||||
});
|
||||
m_maincpu->an_read<0>().set([this] () {
|
||||
return m_analog_cb((m_analog_idx & 3) * 2);
|
||||
});
|
||||
m_maincpu->an_read<1>().set([this] () {
|
||||
return m_analog_cb((m_analog_idx & 3) * 2 + 1);
|
||||
});
|
||||
}
|
||||
|
||||
uint16_t namcos10_exio_device::cpu_status_r()
|
||||
{
|
||||
uint16_t r = m_is_active ? 1 : 0;
|
||||
return (r << 8) | r;
|
||||
}
|
||||
|
||||
void namcos10_exio_device::ctrl_w(uint16_t data)
|
||||
{
|
||||
logerror("%s: exio_ctrl_w %04x\n", machine().describe_context(), data);
|
||||
|
||||
if (data == 3) {
|
||||
m_maincpu->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void namcos10_exio_device::ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
if (BIT(offset, 0))
|
||||
m_ram[offset / 2] = ((data & 0xff) << 8) | (m_ram[offset / 2] & 0xff);
|
||||
else
|
||||
m_ram[offset / 2] = (m_ram[offset / 2] & 0xff00) | (data & 0xff);
|
||||
}
|
||||
|
||||
uint16_t namcos10_exio_device::ram_r(offs_t offset)
|
||||
{
|
||||
if (BIT(offset, 0))
|
||||
return BIT(m_ram[offset / 2], 8, 8);
|
||||
|
||||
return BIT(m_ram[offset / 2], 0, 8);
|
||||
}
|
||||
|
||||
template <int Port>
|
||||
void namcos10_exio_device::port_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
// logerror("%s: exio_port%d_write %02x\n", machine().describe_context(), Port, data);
|
||||
|
||||
if (Port == 8) {
|
||||
// HACK: Simple check to just know when the CPU is alive
|
||||
m_is_active |= data != 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <int Port>
|
||||
uint8_t namcos10_exio_device::port_read(offs_t offset)
|
||||
{
|
||||
// logerror("%s: exio_port%d_read\n", machine().describe_context(), Port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
|
||||
namcos10_mgexio_device::namcos10_mgexio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
namcos10_exio_base_device(mconfig, NAMCOS10_MGEXIO, tag, owner, clock, 0x33),
|
||||
m_maincpu(*this, "exio_mcu"),
|
||||
m_ram(*this, "exio_ram"),
|
||||
m_nvram(*this, "nvram"),
|
||||
m_port_read(*this),
|
||||
m_port_write(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_is_active));
|
||||
save_item(NAME(m_bus_req));
|
||||
save_item(NAME(m_ctrl));
|
||||
|
||||
m_port_read.resolve_all_safe(0);
|
||||
m_port_write.resolve_all_safe();
|
||||
|
||||
m_cpu_reset_timer = timer_alloc(FUNC(namcos10_mgexio_device::cpu_reset_timeout), this);
|
||||
|
||||
m_nvram->set_base(m_ram, 0x8000);
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::device_reset_after_children()
|
||||
{
|
||||
namcos10_exio_base_device::device_reset_after_children();
|
||||
|
||||
m_maincpu->suspend(SUSPEND_REASON_HALT, 1);
|
||||
m_is_active = false;
|
||||
m_bus_req = 0;
|
||||
m_ctrl = 0;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(namcos10_mgexio_device::cpu_reset_timeout)
|
||||
{
|
||||
m_maincpu->reset();
|
||||
m_is_active = true;
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::map(address_map &map)
|
||||
{
|
||||
map(0x00000, 0x7ffff).ram().share(m_ram);
|
||||
}
|
||||
|
||||
template <int Port>
|
||||
uint16_t namcos10_mgexio_device::port_r()
|
||||
{
|
||||
return m_port_read[Port](0);
|
||||
}
|
||||
|
||||
template <int Port>
|
||||
void namcos10_mgexio_device::port_w(uint16_t data)
|
||||
{
|
||||
m_port_write[Port](data);
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::io_map(address_map &map)
|
||||
{
|
||||
map(h8_device::PORT_4, h8_device::PORT_4).rw(FUNC(namcos10_mgexio_device::port_r<0>), FUNC(namcos10_mgexio_device::port_w<0>));
|
||||
map(h8_device::PORT_6, h8_device::PORT_6).rw(FUNC(namcos10_mgexio_device::port_r<1>), FUNC(namcos10_mgexio_device::port_w<1>));
|
||||
map(h8_device::PORT_7, h8_device::PORT_7).rw(FUNC(namcos10_mgexio_device::port_r<2>), FUNC(namcos10_mgexio_device::port_w<2>));
|
||||
map(h8_device::PORT_8, h8_device::PORT_8).rw(FUNC(namcos10_mgexio_device::port_r<3>), FUNC(namcos10_mgexio_device::port_w<3>));
|
||||
map(h8_device::PORT_9, h8_device::PORT_9).rw(FUNC(namcos10_mgexio_device::port_r<4>), FUNC(namcos10_mgexio_device::port_w<4>));
|
||||
map(h8_device::PORT_A, h8_device::PORT_A).rw(FUNC(namcos10_mgexio_device::port_r<5>), FUNC(namcos10_mgexio_device::port_w<5>));
|
||||
map(h8_device::PORT_B, h8_device::PORT_B).rw(FUNC(namcos10_mgexio_device::port_r<6>), FUNC(namcos10_mgexio_device::port_w<6>));
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
H83007(config, m_maincpu, 14.746_MHz_XTAL);
|
||||
m_maincpu->set_mode_a20();
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &namcos10_mgexio_device::map);
|
||||
m_maincpu->set_addrmap(AS_IO, &namcos10_mgexio_device::io_map);
|
||||
|
||||
NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
|
||||
}
|
||||
|
||||
uint16_t namcos10_mgexio_device::cpu_status_r()
|
||||
{
|
||||
// pacmball's code call bit 1 the "sub_cpu_enable_flag"
|
||||
return m_is_active ? 2 : 0;
|
||||
}
|
||||
|
||||
uint16_t namcos10_mgexio_device::ctrl_r()
|
||||
{
|
||||
// bit 0 being 1 makes some games check for sensor responses on the H8's ports (sekaikh, ballpom)
|
||||
// pacmball doesn't seem to care about bit 0
|
||||
// Possibly those games only want to check I/O when the CPU is known to be active?
|
||||
return m_ctrl;
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::ctrl_w(uint16_t data)
|
||||
{
|
||||
logerror("%s: exio_ctrl_w %04x %04x\n", machine().describe_context(), data, m_ctrl ^ data);
|
||||
|
||||
// sekaikh and ballpom only write 3 here and that's all
|
||||
// pacmball will write 3 at the start when the CPU is to be started
|
||||
// and then flip bit 1 at the end of the main loop so it might be I/O related
|
||||
if ((data & 1) && !(m_ctrl & 1)) {
|
||||
// Timed such that there's enough delay before starting but also
|
||||
// so it doesn't wait too long into the timeout before starting.
|
||||
// So far only pacmball relies on timings to be correct to boot.
|
||||
//
|
||||
// TODO: Should this really be restarted every time or just the first time?
|
||||
// Even pacmball only wants to see the timings correct the first time
|
||||
// so it might actually just use standby mode after the initial boot.
|
||||
m_cpu_reset_timer->adjust(attotime::from_msec(40));
|
||||
} else if (!(data & 1) && (m_ctrl & 1)) {
|
||||
// Stop the CPU when bit 0 is flipped from 1 to 0
|
||||
// This happens when a sub CPU-related error occurs
|
||||
m_maincpu->suspend(SUSPEND_REASON_HALT, 1);
|
||||
}
|
||||
|
||||
m_ctrl = data;
|
||||
}
|
||||
|
||||
uint16_t namcos10_mgexio_device::bus_req_r()
|
||||
{
|
||||
// Should have bit 1 set when the CPU is requested
|
||||
return m_bus_req == 1 ? 2 : 0;
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::bus_req_w(uint16_t data)
|
||||
{
|
||||
// Usage before using RAM:
|
||||
// Write 0 to bus_req_w
|
||||
// Check if unk_r has bit 0 set
|
||||
// If set, loop until bus_req_r bit 1 is 0
|
||||
// If bus_req_r bit 1 does not return 0 within 500 polls, "BREQ time out" and "BUS-ACK" is raised
|
||||
// (do RAM things)
|
||||
// Write 1 to bus_req_w
|
||||
//
|
||||
// bus_req_r bit 1 must be 1 for the CPU check
|
||||
|
||||
// logerror("%s: bus_req_w %04x\n", machine().describe_context(), data);
|
||||
m_bus_req = data;
|
||||
}
|
||||
|
||||
void namcos10_mgexio_device::ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
if (BIT(offset, 0) == 1)
|
||||
m_ram[offset / 2] = (m_ram[offset / 2] & 0xff00) | data;
|
||||
else
|
||||
m_ram[offset / 2] = (data << 8) | (m_ram[offset / 2] & 0xff);
|
||||
}
|
||||
|
||||
uint16_t namcos10_mgexio_device::ram_r(offs_t offset)
|
||||
{
|
||||
if (BIT(offset, 0) == 1)
|
||||
return m_ram[offset / 2] & 0xff;
|
||||
else
|
||||
return (m_ram[offset / 2] >> 8) & 0xff;
|
||||
}
|
132
src/mame/namco/namcos10_exio.h
Normal file
132
src/mame/namco/namcos10_exio.h
Normal file
@ -0,0 +1,132 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:windyfairy
|
||||
#ifndef MAME_NAMCO_NAMCOS10_EXIO_H
|
||||
#define MAME_NAMCO_NAMCOS10_EXIO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/h8/h83006.h"
|
||||
#include "cpu/tlcs900/tmp95c061.h"
|
||||
#include "machine/nvram.h"
|
||||
|
||||
class namcos10_exio_base_device : public device_t
|
||||
{
|
||||
public:
|
||||
namcos10_exio_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
uint8_t ident_code() { return m_ident_code; }
|
||||
|
||||
virtual void ctrl_w(uint16_t data) {}
|
||||
|
||||
virtual uint16_t cpu_status_r() { return 0; }
|
||||
|
||||
virtual uint16_t ram_r(offs_t offset) { return 0xff; }
|
||||
virtual void ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) {}
|
||||
|
||||
protected:
|
||||
namcos10_exio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t ident_code);
|
||||
|
||||
virtual void device_start() override;
|
||||
|
||||
const uint8_t m_ident_code;
|
||||
};
|
||||
|
||||
class namcos10_exio_device : public namcos10_exio_base_device
|
||||
{
|
||||
public:
|
||||
namcos10_exio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto analog_callback() { return m_analog_cb.bind(); }
|
||||
|
||||
virtual void ctrl_w(uint16_t data) override;
|
||||
|
||||
virtual uint16_t cpu_status_r() override;
|
||||
|
||||
virtual uint16_t ram_r(offs_t offset) override;
|
||||
virtual void ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset_after_children() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
private:
|
||||
void map(address_map &map);
|
||||
|
||||
template <int Port> uint8_t port_read(offs_t offset);
|
||||
template <int Port> void port_write(offs_t offset, uint8_t data);
|
||||
|
||||
required_device<tmp95c061_device> m_maincpu;
|
||||
required_shared_ptr<uint16_t> m_ram;
|
||||
|
||||
devcb_read16 m_analog_cb;
|
||||
|
||||
bool m_is_active;
|
||||
uint32_t m_analog_idx;
|
||||
};
|
||||
|
||||
class namcos10_mgexio_device : public namcos10_exio_base_device
|
||||
{
|
||||
public:
|
||||
namcos10_mgexio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto port4_read_callback() { return m_port_read[0].bind(); }
|
||||
auto port6_read_callback() { return m_port_read[1].bind(); }
|
||||
auto port7_read_callback() { return m_port_read[2].bind(); }
|
||||
auto port8_read_callback() { return m_port_read[3].bind(); }
|
||||
auto port9_read_callback() { return m_port_read[4].bind(); }
|
||||
auto porta_read_callback() { return m_port_read[5].bind(); }
|
||||
auto portb_read_callback() { return m_port_read[6].bind(); }
|
||||
|
||||
auto port4_write_callback() { return m_port_write[0].bind(); }
|
||||
auto port6_write_callback() { return m_port_write[1].bind(); }
|
||||
auto port7_write_callback() { return m_port_write[2].bind(); }
|
||||
auto port8_write_callback() { return m_port_write[3].bind(); }
|
||||
auto port9_write_callback() { return m_port_write[4].bind(); }
|
||||
auto porta_write_callback() { return m_port_write[5].bind(); }
|
||||
auto portb_write_callback() { return m_port_write[6].bind(); }
|
||||
|
||||
virtual uint16_t ctrl_r();
|
||||
virtual void ctrl_w(uint16_t data) override;
|
||||
|
||||
virtual uint16_t bus_req_r();
|
||||
virtual void bus_req_w(uint16_t data);
|
||||
|
||||
virtual uint16_t cpu_status_r() override;
|
||||
|
||||
virtual uint16_t ram_r(offs_t offset) override;
|
||||
virtual void ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset_after_children() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
private:
|
||||
void map(address_map &map);
|
||||
void io_map(address_map &map);
|
||||
|
||||
template <int Port> uint16_t port_r();
|
||||
template <int Port> void port_w(uint16_t data);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(cpu_reset_timeout);
|
||||
|
||||
required_device<h83007_device> m_maincpu;
|
||||
required_shared_ptr<uint16_t> m_ram;
|
||||
required_device<nvram_device> m_nvram;
|
||||
|
||||
devcb_read16::array<7> m_port_read;
|
||||
devcb_write16::array<7> m_port_write;
|
||||
|
||||
emu_timer *m_cpu_reset_timer;
|
||||
|
||||
bool m_is_active;
|
||||
uint16_t m_bus_req;
|
||||
uint16_t m_ctrl;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(NAMCOS10_EXIO, namcos10_exio_device)
|
||||
DECLARE_DEVICE_TYPE(NAMCOS10_EXIO_BASE, namcos10_exio_base_device)
|
||||
DECLARE_DEVICE_TYPE(NAMCOS10_MGEXIO, namcos10_mgexio_device)
|
||||
|
||||
#endif // MAME_NAMCO_NAMCOS10_EXIO_H
|
@ -118,14 +118,9 @@ really exist.
|
||||
#include "emu.h"
|
||||
#include "ns10crypt.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(CHOCOVDR_DECRYPTER, chocovdr_decrypter_device, "chocovdr_decrypter", "Chocovader Contactee decrypter")
|
||||
DEFINE_DEVICE_TYPE(GAMSHARA_DECRYPTER, gamshara_decrypter_device, "gamshara_decrypter", "Gamshara decrypter")
|
||||
DEFINE_DEVICE_TYPE(GJSPACE_DECRYPTER, gjspace_decrypter_device, "gjspace_decrypter", "Gekitorider-Jong Space decrypter")
|
||||
DEFINE_DEVICE_TYPE(KNPUZZLE_DECRYPTER, knpuzzle_decrypter_device, "knpuzzle_decrypter", "Kotoba no Puzzle Mojipittan decrypter")
|
||||
DEFINE_DEVICE_TYPE(KONOTAKO_DECRYPTER, konotako_decrypter_device, "konotako_decrypter", "Kono Tako decrypter")
|
||||
DEFINE_DEVICE_TYPE(MRDRILR2_DECRYPTER, mrdrilr2_decrypter_device, "mrdrilr2_decrypter", "Mr Driller 2 decrypter")
|
||||
DEFINE_DEVICE_TYPE(NFLCLSFB_DECRYPTER, nflclsfb_decrypter_device, "nflclsfg_decrypter", "NFL Classic Football decrypter")
|
||||
DEFINE_DEVICE_TYPE(STARTRGN_DECRYPTER, startrgn_decrypter_device, "startrgn_decrypter", "Star Trigon decrypter")
|
||||
|
||||
DEFINE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER, ns10_type2_decrypter_device, "ns10_type2_decrypter", "Namco System 10 Type 2 decrypter")
|
||||
|
||||
// base class
|
||||
|
||||
@ -146,7 +141,7 @@ void ns10_decrypter_device::deactivate()
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
bool ns10_decrypter_device::is_active()const
|
||||
bool ns10_decrypter_device::is_active() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
@ -155,13 +150,12 @@ ns10_decrypter_device::~ns10_decrypter_device()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// type-1 decrypter
|
||||
|
||||
constexpr int UNKNOWN {16};
|
||||
constexpr int U {UNKNOWN};
|
||||
constexpr int UNKNOWN{16};
|
||||
constexpr int U{UNKNOWN};
|
||||
// this could perfectly be part of the per-game logic but, with only one known type-1 game, we cannot say anything definitive
|
||||
const int ns10_type1_decrypter_device::initSbox[16] {U,U,U,0,4,9,U,U,U,8,U,1,U,9,U,5};
|
||||
const int ns10_type1_decrypter_device::initSbox[16]{U, U, U, 0, 4, 9, U, U, U, 8, U, 1, U, 9, U, 5};
|
||||
|
||||
ns10_type1_decrypter_device::ns10_type1_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(mconfig, type, tag, owner, clock)
|
||||
@ -170,27 +164,24 @@ ns10_type1_decrypter_device::ns10_type1_decrypter_device(const machine_config &m
|
||||
|
||||
uint16_t ns10_type1_decrypter_device::decrypt(uint16_t cipherword)
|
||||
{
|
||||
uint16_t plainword = m_mask ^ bitswap(cipherword,9,13,15,7,14,8,6,10,11,12,3,5,0,1,4,2);
|
||||
uint16_t plainword = m_mask ^ bitswap(cipherword, 9, 13, 15, 7, 14, 8, 6, 10, 11, 12, 3, 5, 0, 1, 4, 2);
|
||||
|
||||
uint16_t nbs =
|
||||
((BIT(m_counter, 4) ) << 15) ^
|
||||
((BIT(cipherword, 2) ^ BIT(cipherword, 5) ) << 14) ^
|
||||
((BIT(cipherword, 0) ) << 13) ^
|
||||
((BIT(m_counter, 4)) << 15) ^
|
||||
((BIT(cipherword, 2) ^ BIT(cipherword, 5)) << 14) ^
|
||||
((BIT(cipherword, 0)) << 13) ^
|
||||
(((BIT(cipherword, 4) | BIT(cipherword, 5))) << 12) ^ // this is the only nonlinear term not involving the counter
|
||||
((BIT(m_counter, 0) ) << 11) ^
|
||||
((BIT(cipherword, 6) ) << 10) ^
|
||||
(((BIT(cipherword, 4) & BIT(m_counter, 1)) ) << 8) ^
|
||||
((BIT(m_counter, 3) ) << 6) ^
|
||||
(((BIT(cipherword, 3) | BIT(m_counter, 7)) ) << 5) ^
|
||||
((BIT(cipherword, 2) ^ BIT(m_counter, 3) ) << 4) ^
|
||||
((BIT(m_counter, 2) ) << 3) ^
|
||||
(((BIT(cipherword, 7) & BIT(m_counter, 7)) ) << 2) ^
|
||||
((BIT(m_counter, 5) ) << 1) ^
|
||||
(((BIT(cipherword, 7) | BIT(m_counter, 1)) ) << 0);
|
||||
m_mask = nbs
|
||||
^ bitswap(cipherword, 6,11, 3, 1,13, 5,15,10, 2, 9, 8, 4, 0,12, 7,14)
|
||||
^ bitswap(plainword , 9, 7, 5, 2,14, 4,13, 8, 0,15,10, 1, 3, 6,12,11)
|
||||
^ 0xecbe;
|
||||
((BIT(m_counter, 0)) << 11) ^
|
||||
((BIT(cipherword, 6)) << 10) ^
|
||||
(((BIT(cipherword, 4) & BIT(m_counter, 1))) << 8) ^
|
||||
((BIT(m_counter, 3)) << 6) ^
|
||||
(((BIT(cipherword, 3) | BIT(m_counter, 7))) << 5) ^
|
||||
((BIT(cipherword, 2) ^ BIT(m_counter, 3)) << 4) ^
|
||||
((BIT(m_counter, 2)) << 3) ^
|
||||
(((BIT(cipherword, 7) & BIT(m_counter, 7))) << 2) ^
|
||||
((BIT(m_counter, 5)) << 1) ^
|
||||
(((BIT(cipherword, 7) | BIT(m_counter, 1))) << 0);
|
||||
m_mask = nbs ^ bitswap(cipherword, 6, 11, 3, 1, 13, 5, 15, 10, 2, 9, 8, 4, 0, 12, 7, 14) ^ bitswap(plainword, 9, 7, 5, 2, 14, 4, 13, 8, 0, 15, 10, 1, 3, 6, 12, 11) ^ 0xecbe;
|
||||
++m_counter;
|
||||
|
||||
return plainword;
|
||||
@ -207,26 +198,35 @@ void ns10_type1_decrypter_device::device_start()
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
mrdrilr2_decrypter_device::mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type1_decrypter_device(mconfig, MRDRILR2_DECRYPTER, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
// type-2 decrypter
|
||||
|
||||
// this could perfectly be part of the per-game logic; by now, only gamshara seems to use it, so we keep it global
|
||||
const int ns10_type2_decrypter_device::initSbox[16] {0,12,13,6,2,4,9,8,11,1,7,15,10,5,14,3};
|
||||
const int ns10_type2_decrypter_device::initSbox[16]{0, 12, 13, 6, 2, 4, 9, 8, 11, 1, 7, 15, 10, 5, 14, 3};
|
||||
|
||||
ns10_type2_decrypter_device::ns10_type2_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const ns10_type2_decrypter_device::ns10_crypto_logic &logic)
|
||||
: ns10_decrypter_device(mconfig, type, tag, owner, clock)
|
||||
, m_logic(logic)
|
||||
ns10_type2_decrypter_device::ns10_type2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_decrypter_device(mconfig, NS10_TYPE2_DECRYPTER, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
ns10_type2_decrypter_device::ns10_type2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const ns10_type2_decrypter_device::ns10_crypto_logic logic)
|
||||
: ns10_decrypter_device(mconfig, NS10_TYPE2_DECRYPTER, tag, owner, clock), m_logic(logic)
|
||||
{
|
||||
m_logic_initialized = true;
|
||||
}
|
||||
|
||||
uint16_t ns10_type2_decrypter_device::decrypt(uint16_t cipherword)
|
||||
{
|
||||
uint16_t plainword = cipherword ^ m_mask;
|
||||
|
||||
m_previous_cipherwords <<= 16;
|
||||
m_previous_cipherwords ^= cipherword;
|
||||
m_previous_plainwords <<= 16;
|
||||
m_previous_plainwords ^= plainword;
|
||||
m_previous_cipherwords ^= cipherword;
|
||||
m_previous_plainwords <<= 16;
|
||||
m_previous_plainwords ^= plainword;
|
||||
|
||||
m_mask = 0;
|
||||
for (int j = 15; j >= 0; --j)
|
||||
@ -245,18 +245,20 @@ void ns10_type2_decrypter_device::init(int iv)
|
||||
{
|
||||
// by now, only gamshara requires non-trivial initialization code; data
|
||||
// should be moved to the per-game logic in case any other game do it differently
|
||||
m_previous_cipherwords = bitswap(initSbox[iv],3,16,16,2,1,16,16,0,16,16,16,16,16,16,16,16);
|
||||
m_previous_plainwords = 0;
|
||||
m_mask = 0;
|
||||
m_previous_cipherwords = bitswap(initSbox[iv], 3, 16, 16, 2, 1, 16, 16, 0, 16, 16, 16, 16, 16, 16, 16, 16);
|
||||
m_previous_plainwords = 0;
|
||||
m_mask = 0;
|
||||
}
|
||||
|
||||
void ns10_type2_decrypter_device::device_start()
|
||||
{
|
||||
// If the logic isn't initialized then this will just fail
|
||||
assert(m_logic_initialized == true);
|
||||
|
||||
m_active = false;
|
||||
m_reducer = std::make_unique<gf2_reducer>();
|
||||
}
|
||||
|
||||
|
||||
ns10_type2_decrypter_device::gf2_reducer::gf2_reducer()
|
||||
{
|
||||
int reduction;
|
||||
@ -274,222 +276,10 @@ ns10_type2_decrypter_device::gf2_reducer::gf2_reducer()
|
||||
}
|
||||
}
|
||||
|
||||
int ns10_type2_decrypter_device::gf2_reducer::gf2_reduce(uint64_t num)const
|
||||
{
|
||||
return
|
||||
m_gf2Reduction[num & 0xffff] ^
|
||||
m_gf2Reduction[(num >> 16) & 0xffff] ^
|
||||
m_gf2Reduction[(num >> 32) & 0xffff] ^
|
||||
m_gf2Reduction[num >> 48];
|
||||
}
|
||||
|
||||
|
||||
// game-specific logic
|
||||
|
||||
// static uint16_t mrdrilrg_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
// {
|
||||
// uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
// return (reducer.gf2_reduce(0x00000a00a305c826ull & previous_masks) & reducer.gf2_reduce(0x0000011800020000ull & previous_masks)) * 0x0011;
|
||||
// }
|
||||
|
||||
// static uint16_t panikuru_nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
// {
|
||||
// return ((reducer.gf2_reduce(0x0000000088300281ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000004600281ull & previous_plainwords))
|
||||
// & (reducer.gf2_reduce(0x0000a13140090000ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000806240090000ull & previous_plainwords))) << 2;
|
||||
// }
|
||||
|
||||
uint16_t chocovdr_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 9) & (reducer.gf2_reduce(0x0000000010065810ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000021005810ull & previous_plainwords)) & 1) << 10;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic chocovdr_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x00005239351ec1daull, 0x0000000000008090ull, 0x0000000048264808ull, 0x0000000000004820ull,
|
||||
0x0000000000000500ull, 0x0000000058ff5a54ull, 0x00000000d8220208ull, 0x00005239351e91d3ull,
|
||||
0x000000009a1dfaffull, 0x0000000090040001ull, 0x0000000000000100ull, 0x0000000000001408ull,
|
||||
0x0000000032efd3f1ull, 0x00000000000000d0ull, 0x0000000032efd2d7ull, 0x0000000000000840ull,
|
||||
}, {
|
||||
0x00002000410485daull, 0x0000000000008081ull, 0x0000000008044088ull, 0x0000000000004802ull,
|
||||
0x0000000000000500ull, 0x00000000430cda54ull, 0x0000000010000028ull, 0x00002000410491dbull,
|
||||
0x000000001100fafeull, 0x0000000018040001ull, 0x0000000000000010ull, 0x0000000000000508ull,
|
||||
0x000000006800d3f5ull, 0x0000000000000058ull, 0x000000006800d2d5ull, 0x0000000000001840ull,
|
||||
},
|
||||
0x5b22,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t gamshara_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 7) & (previous_masks >> 13) & 1) << 2;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic gamshara_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x0000000000000028ull, 0x0000cae83f389fd9ull, 0x0000000000001000ull, 0x0000000042823402ull,
|
||||
0x0000cae8736a0592ull, 0x0000cae8736a8596ull, 0x000000008b4095b9ull, 0x0000000000002100ull,
|
||||
0x0000000004018228ull, 0x0000000000000042ull, 0x0000000000000818ull, 0x0000000000004010ull,
|
||||
0x000000008b4099f1ull, 0x00000000044bce08ull, 0x00000000000000c1ull, 0x0000000042823002ull,
|
||||
}, {
|
||||
0x0000000000000028ull, 0x00000904c2048dd9ull, 0x0000000000008000ull, 0x0000000054021002ull,
|
||||
0x00000904e0078592ull, 0x00000904e00785b2ull, 0x00000000440097f9ull, 0x0000000000002104ull,
|
||||
0x0000000029018308ull, 0x0000000000000042ull, 0x0000000000000850ull, 0x0000000000004012ull,
|
||||
0x000000004400d1f1ull, 0x000000006001ce08ull, 0x00000000000000c8ull, 0x0000000054023002ull,
|
||||
},
|
||||
0x25ab,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t gjspace_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic gjspace_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x0000000000000240ull, 0x0000d617eb0f1ab1ull, 0x00000000451111c0ull, 0x00000000013b1f44ull,
|
||||
0x0000aab0b356abceull, 0x00007ca76b89602aull, 0x0000000000001800ull, 0x00000000031d1303ull,
|
||||
0x0000000000000801ull, 0x0000000030111160ull, 0x0000000001ab3978ull, 0x00000000c131b160ull,
|
||||
0x0000000000001110ull, 0x0000000000008002ull, 0x00000000e1113540ull, 0x0000d617fdce8bfcull,
|
||||
}, {
|
||||
0x0000000000008240ull, 0x000000002f301ab1ull, 0x00000000050011c0ull, 0x00000000412817c4ull,
|
||||
0x00000004c338abc6ull, 0x000000046108602aull, 0x0000000000005800ull, 0x00000000c3081347ull,
|
||||
0x0000000000000801ull, 0x0000000061001160ull, 0x0000000061183978ull, 0x00000000e520b142ull,
|
||||
0x0000000000001101ull, 0x000000000000a002ull, 0x0000000029001740ull, 0x00000000a4309bfcull,
|
||||
},
|
||||
0x2e7f,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t knpuzzle_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 0x13) & (reducer.gf2_reduce(0x0000000014001290ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000000021290ull & previous_plainwords)) & 1) << 1;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic knpuzzle_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x00000000c0a4208cull, 0x00000000204100a8ull, 0x000000000c0306a0ull, 0x000000000819e944ull,
|
||||
0x0000000000001400ull, 0x0000000000000061ull, 0x000000000141401cull, 0x0000000000000020ull,
|
||||
0x0000000001418010ull, 0x00008d6a1eb690cfull, 0x00008d6a4d3b90ceull, 0x0000000000004201ull,
|
||||
0x00000000012c00a2ull, 0x000000000c0304a4ull, 0x0000000000000500ull, 0x0000000000000980ull,
|
||||
}, {
|
||||
0x000000002a22608cull, 0x00000000002300a8ull, 0x0000000000390ea0ull, 0x000000000100a9c4ull,
|
||||
0x0000000000001400ull, 0x0000000000000041ull, 0x0000000003014014ull, 0x0000000000000022ull,
|
||||
0x0000000003010110ull, 0x00000800031a80cfull, 0x00000800003398deull, 0x0000000000004200ull,
|
||||
0x00000000012a04a2ull, 0x00000000003984a4ull, 0x0000000000000700ull, 0x0000000000000882ull,
|
||||
},
|
||||
0x01e2,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t konotako_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 7) & (previous_masks >> 15) & 1) << 15;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic konotako_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x000000000000004cull, 0x00000000d39e3d3dull, 0x0000000000001110ull, 0x0000000000002200ull,
|
||||
0x000000003680c008ull, 0x0000000000000281ull, 0x0000000000005002ull, 0x00002a7371895a47ull,
|
||||
0x0000000000000003ull, 0x00002a7371897a4eull, 0x00002a73aea17a41ull, 0x00002a73fd895a4full,
|
||||
0x000000005328200aull, 0x0000000000000010ull, 0x0000000000000040ull, 0x0000000000000200ull,
|
||||
}, {
|
||||
0x000000000000008cull, 0x0000000053003d25ull, 0x0000000000001120ull, 0x0000000000002200ull,
|
||||
0x0000000037004008ull, 0x0000000000000282ull, 0x0000000000006002ull, 0x0000060035005a47ull,
|
||||
0x0000000000000003ull, 0x0000060035001a4eull, 0x0000060025007a41ull, 0x00000600b5005a2full,
|
||||
0x000000009000200bull, 0x0000000000000310ull, 0x0000000000001840ull, 0x0000000000000400ull,
|
||||
},
|
||||
0x0748,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t nflclsfb_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer& reducer)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 1) & (reducer.gf2_reduce(0x0000000040de8fb3ull & previous_cipherwords) ^ reducer.gf2_reduce(0x0000000088008fb3ull & previous_plainwords)) & 1) << 2;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic nflclsfb_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x000034886e281880ull, 0x0000000012c5e7baull, 0x0000000000000200ull, 0x000000002900002aull,
|
||||
0x00000000000004c0ull, 0x0000000012c5e6baull, 0x00000000e0df8bbbull, 0x000000002011532aull,
|
||||
0x0000000000009040ull, 0x0000000000006004ull, 0x000000000000a001ull, 0x000034886e2818e1ull,
|
||||
0x0000000000004404ull, 0x0000000000004200ull, 0x0000000000009100ull, 0x0000000020115712ull,
|
||||
}, {
|
||||
0x00000e00060819c0ull, 0x000000000e08e7baull, 0x0000000000000800ull, 0x000000000100002aull,
|
||||
0x00000000000010c0ull, 0x000000000e08cebaull, 0x0000000088018bbbull, 0x000000008c005302ull,
|
||||
0x000000000000c040ull, 0x0000000000006010ull, 0x0000000000000001ull, 0x00000e00060818e3ull,
|
||||
0x0000000000000404ull, 0x0000000000004201ull, 0x0000000000001100ull, 0x000000008c0057b2ull,
|
||||
},
|
||||
0xbe32,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
uint16_t startrgn_decrypter_device::nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer&)
|
||||
{
|
||||
uint64_t previous_masks = previous_cipherwords ^ previous_plainwords;
|
||||
return ((previous_masks >> 12) & (previous_masks >> 14) & 1) << 4;
|
||||
}
|
||||
|
||||
const ns10_type2_decrypter_device::ns10_crypto_logic startrgn_decrypter_device::crypto_logic = {
|
||||
{
|
||||
0x00003e4bfe92c6a9ull, 0x000000000000010cull, 0x00003e4b7bd6c4aaull, 0x0000b1a904b8fab8ull,
|
||||
0x0000000000000080ull, 0x0000000000008c00ull, 0x0000b1a9b2f0b4cdull, 0x000000006c100828ull,
|
||||
0x000000006c100838ull, 0x0000b1a9d3913fcdull, 0x000000006161aa00ull, 0x0000000000006040ull,
|
||||
0x0000000000000420ull, 0x0000000000001801ull, 0x00003e4b7bd6deabull, 0x0000000000000105ull,
|
||||
}, {
|
||||
0x000012021f00c6a8ull, 0x0000000000000008ull, 0x000012020b1046aaull, 0x000012001502fea8ull,
|
||||
0x0000000000002000ull, 0x0000000000008800ull, 0x000012001e02b4cdull, 0x000000002c0008aaull,
|
||||
0x000000002c00083aull, 0x000012003f027ecdull, 0x0000000021008a00ull, 0x0000000000002040ull,
|
||||
0x0000000000000428ull, 0x0000000000001001ull, 0x000012020b10ceabull, 0x0000000000000144ull,
|
||||
},
|
||||
0x8c46,
|
||||
&nonlinear_calc
|
||||
};
|
||||
|
||||
|
||||
// game-specific devices
|
||||
|
||||
mrdrilr2_decrypter_device::mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type1_decrypter_device(mconfig, MRDRILR2_DECRYPTER, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
chocovdr_decrypter_device::chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, CHOCOVDR_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
gamshara_decrypter_device::gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, GAMSHARA_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
gjspace_decrypter_device::gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, GJSPACE_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
knpuzzle_decrypter_device::knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, KNPUZZLE_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
konotako_decrypter_device::konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, KONOTAKO_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
nflclsfb_decrypter_device::nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, NFLCLSFB_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
{
|
||||
}
|
||||
|
||||
startrgn_decrypter_device::startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ns10_type2_decrypter_device(mconfig, STARTRGN_DECRYPTER, tag, owner, clock, crypto_logic)
|
||||
int ns10_type2_decrypter_device::gf2_reducer::gf2_reduce(uint64_t num) const
|
||||
{
|
||||
return m_gf2Reduction[num & 0xffff] ^
|
||||
m_gf2Reduction[(num >> 16) & 0xffff] ^
|
||||
m_gf2Reduction[(num >> 32) & 0xffff] ^
|
||||
m_gf2Reduction[num >> 48];
|
||||
}
|
||||
|
@ -11,16 +11,16 @@ class ns10_decrypter_device : public device_t
|
||||
public:
|
||||
void activate(int iv);
|
||||
void deactivate();
|
||||
bool is_active()const;
|
||||
bool is_active() const;
|
||||
|
||||
virtual uint16_t decrypt(uint16_t cipherword)=0;
|
||||
virtual uint16_t decrypt(uint16_t cipherword) = 0;
|
||||
virtual ~ns10_decrypter_device();
|
||||
|
||||
protected:
|
||||
ns10_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual void init(int iv)=0;
|
||||
virtual void device_start()override=0;
|
||||
virtual void init(int iv) = 0;
|
||||
virtual void device_start() override = 0;
|
||||
|
||||
bool m_active;
|
||||
};
|
||||
@ -30,7 +30,7 @@ class ns10_type1_decrypter_device : public ns10_decrypter_device
|
||||
public:
|
||||
// with just only type-1 game known, we cannot say which parts of the crypto_logic is common, if any,
|
||||
// and which is game-specific. In practice, this class is just an alias for the decrypter device of mrdrilr2
|
||||
uint16_t decrypt(uint16_t cipherword)override;
|
||||
uint16_t decrypt(uint16_t cipherword) override;
|
||||
|
||||
protected:
|
||||
ns10_type1_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -40,22 +40,19 @@ private:
|
||||
uint8_t m_counter = 0;
|
||||
static const int initSbox[16];
|
||||
|
||||
void init(int iv)override;
|
||||
void device_start()override;
|
||||
void init(int iv) override;
|
||||
void device_start() override;
|
||||
};
|
||||
|
||||
|
||||
class ns10_type2_decrypter_device : public ns10_decrypter_device
|
||||
{
|
||||
public:
|
||||
uint16_t decrypt(uint16_t cipherword)override;
|
||||
|
||||
protected:
|
||||
class gf2_reducer // helper class
|
||||
class gf2_reducer // helper class
|
||||
{
|
||||
public:
|
||||
gf2_reducer();
|
||||
int gf2_reduce(uint64_t num)const;
|
||||
int gf2_reduce(uint64_t num) const;
|
||||
|
||||
private:
|
||||
int m_gf2Reduction[0x10000]{};
|
||||
};
|
||||
@ -67,104 +64,36 @@ protected:
|
||||
uint64_t eMask[16]{};
|
||||
uint64_t dMask[16]{};
|
||||
uint16_t xMask = 0;
|
||||
uint16_t(*nonlinear_calculation)(uint64_t, uint64_t, const gf2_reducer&); // preliminary encoding; need research
|
||||
std::function<uint16_t(uint64_t, uint64_t, const gf2_reducer &)> nonlinear_calculation; // preliminary encoding; need research
|
||||
};
|
||||
|
||||
ns10_type2_decrypter_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const ns10_crypto_logic &logic);
|
||||
ns10_type2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
ns10_type2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const ns10_crypto_logic logic);
|
||||
|
||||
uint16_t decrypt(uint16_t cipherword) override;
|
||||
|
||||
private:
|
||||
uint16_t m_mask = 0;
|
||||
uint64_t m_previous_cipherwords = 0;
|
||||
uint64_t m_previous_plainwords = 0;
|
||||
const ns10_crypto_logic& m_logic;
|
||||
std::unique_ptr<const gf2_reducer>m_reducer;
|
||||
const ns10_crypto_logic m_logic;
|
||||
static const int initSbox[16];
|
||||
|
||||
void init(int iv)override;
|
||||
void device_start()override;
|
||||
void init(int iv) override;
|
||||
void device_start() override;
|
||||
|
||||
std::unique_ptr<const gf2_reducer> m_reducer;
|
||||
|
||||
bool m_logic_initialized;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// game-specific devices
|
||||
|
||||
class mrdrilr2_decrypter_device : public ns10_type1_decrypter_device
|
||||
{
|
||||
public:
|
||||
mrdrilr2_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class chocovdr_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
chocovdr_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class gamshara_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
gamshara_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class gjspace_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
gjspace_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class knpuzzle_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
knpuzzle_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class konotako_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
konotako_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class nflclsfb_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
nflclsfb_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
class startrgn_decrypter_device : public ns10_type2_decrypter_device
|
||||
{
|
||||
public:
|
||||
startrgn_decrypter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
static uint16_t nonlinear_calc(uint64_t previous_cipherwords, uint64_t previous_plainwords, const gf2_reducer &reducer);
|
||||
static const ns10_crypto_logic crypto_logic;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(CHOCOVDR_DECRYPTER, chocovdr_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(GAMSHARA_DECRYPTER, gamshara_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(GJSPACE_DECRYPTER, gjspace_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(KNPUZZLE_DECRYPTER, knpuzzle_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(KONOTAKO_DECRYPTER, konotako_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(MRDRILR2_DECRYPTER, mrdrilr2_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(NFLCLSFB_DECRYPTER, nflclsfb_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(STARTRGN_DECRYPTER, startrgn_decrypter_device)
|
||||
DECLARE_DEVICE_TYPE(MRDRILR2_DECRYPTER, mrdrilr2_decrypter_device) // Type 1
|
||||
DECLARE_DEVICE_TYPE(NS10_TYPE2_DECRYPTER, ns10_type2_decrypter_device)
|
||||
|
||||
#endif // MAME_NAMCO_NS10CRYPT_H
|
||||
|
Loading…
Reference in New Issue
Block a user