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:
987123879113 2023-04-18 23:49:56 +09:00 committed by GitHub
parent 87dc49048b
commit fd4f515024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1990 additions and 895 deletions

View File

@ -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()

View File

@ -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];

View File

@ -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 */

View File

@ -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

View 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;
}

View 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

View File

@ -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];
}

View File

@ -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