- Reverse-engineered Space Lords security FPGA and implemented decryption code [Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen]
New games added or promoted from NOT_WORKING status Space Lords [Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen]
This commit is contained in:
parent
777be34dfe
commit
e6d92ba43c
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
driver by Aaron Giles
|
driver by Aaron Giles
|
||||||
|
|
||||||
Moto Frenzy protection reverse engineered by:
|
Moto Frenzy and Space Lords protection reverse engineered by:
|
||||||
Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen
|
Morten Shearman Kirkegaard, Samuel Neves, Peter Wilhelmsen
|
||||||
|
|
||||||
Games supported:
|
Games supported:
|
||||||
@ -15,7 +15,7 @@
|
|||||||
* Road Riot's Revenge Rally (1993)
|
* Road Riot's Revenge Rally (1993)
|
||||||
|
|
||||||
Known bugs:
|
Known bugs:
|
||||||
* Unemulated protection for Space Lords and Road Riot's Revenge
|
* Unemulated protection for Road Riot's Revenge
|
||||||
|
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
|
||||||
@ -76,13 +76,16 @@ READ32_MEMBER(atarigx2_state::special_port3_r)
|
|||||||
|
|
||||||
READ32_MEMBER(atarigx2_state::a2d_data_r)
|
READ32_MEMBER(atarigx2_state::a2d_data_r)
|
||||||
{
|
{
|
||||||
/* otherwise, assume it's hydra */
|
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return (ioport("A2D0")->read() << 24) | (ioport("A2D1")->read() << 8);
|
return (ioport("A2D0")->read() << 24) | (ioport("A2D1")->read() << 8);
|
||||||
case 1:
|
case 1:
|
||||||
return (ioport("A2D2")->read() << 24) | (ioport("A2D3")->read() << 8);
|
return (ioport("A2D2")->read() << 24) | (ioport("A2D3")->read() << 8);
|
||||||
|
case 2:
|
||||||
|
return (ioport("A2D4")->read() << 24) | (ioport("A2D5")->read() << 8);
|
||||||
|
case 3:
|
||||||
|
return (ioport("A2D6")->read() << 24) | (ioport("A2D7")->read() << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1264,20 +1267,28 @@ static INPUT_PORTS_START( spclords )
|
|||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
PORT_START("A2D0") /* A2D @ 0xD00000 */
|
PORT_START("A2D0") /* A2D @ 0xD00000 */
|
||||||
PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
|
||||||
PORT_START("A2D1") /* A2D @ 0xD00002 */
|
PORT_START("A2D1") /* A2D @ 0xD00002 */
|
||||||
PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
PORT_BIT ( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1) // Pilot L/R
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
|
||||||
PORT_START("A2D2") /* A2D @ 0xD00004 */
|
PORT_START("A2D2") /* A2D @ 0xD00004 */
|
||||||
PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2)
|
PORT_BIT ( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1) // Pilot U/D
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
|
||||||
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
||||||
PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2)
|
PORT_BIT ( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2) // Gunner L/R
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
PORT_START("A2D4") /* A2D @ 0xD00008 */
|
||||||
|
PORT_BIT ( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2) // Gunner U/D
|
||||||
|
|
||||||
|
PORT_START("A2D5") /* A2D @ 0xD0000A */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D6") /* A2D @ 0xD0000C */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D7") /* A2D @ 0xD0000E */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
@ -1320,6 +1331,18 @@ static INPUT_PORTS_START( motofren )
|
|||||||
|
|
||||||
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
||||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D4") /* A2D @ 0xD00008 */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D5") /* A2D @ 0xD0000A */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D6") /* A2D @ 0xD0000C */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D7") /* A2D @ 0xD0000E */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
@ -1356,18 +1379,28 @@ static INPUT_PORTS_START( rrreveng )
|
|||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
PORT_START("A2D0") /* A2D @ 0xD00000 */
|
PORT_START("A2D0") /* A2D @ 0xD00000 */
|
||||||
PORT_BIT ( 0x00ff, 0x0010, IPT_PEDAL ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
PORT_BIT ( 0xff, 0x10, IPT_PEDAL ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
|
||||||
PORT_START("A2D1") /* A2D @ 0xD00002 */
|
PORT_START("A2D1") /* A2D @ 0xD00002 */
|
||||||
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
PORT_START("A2D2") /* A2D @ 0xD00004 */
|
PORT_START("A2D2") /* A2D @ 0xD00004 */
|
||||||
PORT_BIT ( 0x00ff, 0x0080, IPT_PADDLE ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
PORT_BIT ( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
|
||||||
PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
|
|
||||||
|
|
||||||
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
PORT_START("A2D3") /* A2D @ 0xD00006 */
|
||||||
PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D4") /* A2D @ 0xD00008 */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D5") /* A2D @ 0xD0000A */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D6") /* A2D @ 0xD0000C */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
|
|
||||||
|
PORT_START("A2D7") /* A2D @ 0xD0000E */
|
||||||
|
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
@ -1468,8 +1501,6 @@ static MACHINE_CONFIG_START( atarigx2, atarigx2_state )
|
|||||||
|
|
||||||
MCFG_MACHINE_RESET_OVERRIDE(atarigx2_state,atarigx2)
|
MCFG_MACHINE_RESET_OVERRIDE(atarigx2_state,atarigx2)
|
||||||
|
|
||||||
MCFG_DEVICE_ADD("xga", ATARI_XGA, 0);
|
|
||||||
|
|
||||||
MCFG_ATARI_EEPROM_2816_ADD("eeprom")
|
MCFG_ATARI_EEPROM_2816_ADD("eeprom")
|
||||||
|
|
||||||
/* video hardware */
|
/* video hardware */
|
||||||
@ -1501,10 +1532,12 @@ MACHINE_CONFIG_END
|
|||||||
|
|
||||||
|
|
||||||
static MACHINE_CONFIG_DERIVED( atarigx2_0x200, atarigx2 )
|
static MACHINE_CONFIG_DERIVED( atarigx2_0x200, atarigx2 )
|
||||||
|
MCFG_DEVICE_ADD("xga", ATARI_136094_0072, 0)
|
||||||
MCFG_ATARIRLE_ADD("rle", modesc_0x200)
|
MCFG_ATARIRLE_ADD("rle", modesc_0x200)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_DERIVED( atarigx2_0x400, atarigx2 )
|
static MACHINE_CONFIG_DERIVED( atarigx2_0x400, atarigx2 )
|
||||||
|
MCFG_DEVICE_ADD("xga", ATARI_136095_0072, 0)
|
||||||
MCFG_ATARIRLE_ADD("rle", modesc_0x400)
|
MCFG_ATARIRLE_ADD("rle", modesc_0x400)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
@ -2220,7 +2253,9 @@ ROM_END
|
|||||||
DRIVER_INIT_MEMBER(atarigx2_state,spclords)
|
DRIVER_INIT_MEMBER(atarigx2_state,spclords)
|
||||||
{
|
{
|
||||||
m_playfield_base = 0x000;
|
m_playfield_base = 0x000;
|
||||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xca0000, 0xca0fff, read32_delegate(FUNC(atarigx2_state::atarigx2_protection_r),this), write32_delegate(FUNC(atarigx2_state::atarigx2_protection_w),this));
|
|
||||||
|
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xc80f00, 0xc80fff, read32_delegate(FUNC(atari_136095_0072_device::polylsb_read),(atari_136095_0072_device*)&(*m_xga)), write32_delegate(FUNC(atari_136095_0072_device::polylsb_write),(atari_136095_0072_device*)&(*m_xga)));
|
||||||
|
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xca0000, 0xca0fff, read32_delegate(FUNC(atari_xga_device::read),&(*m_xga)), write32_delegate(FUNC(atari_xga_device::write),&(*m_xga)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2267,10 +2302,10 @@ DRIVER_INIT_MEMBER(atarigx2_state,rrreveng)
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
GAME( 1992, spclords, 0, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev C)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING )
|
GAME( 1992, spclords, 0, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev C)", 0 )
|
||||||
GAME( 1992, spclordsb, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev B)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING )
|
GAME( 1992, spclordsb, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev B)", 0 )
|
||||||
GAME( 1992, spclordsg, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev A, German)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING )
|
GAME( 1992, spclordsg, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev A, German)", 0 )
|
||||||
GAME( 1992, spclordsa, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev A)", MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING )
|
GAME( 1992, spclordsa, spclords, atarigx2_0x400, spclords, atarigx2_state, spclords, ROT0, "Atari Games", "Space Lords (rev A)", 0 )
|
||||||
|
|
||||||
GAME( 1992, motofren, 0, atarigx2_0x200, motofren, atarigx2_state, motofren, ROT0, "Atari Games", "Moto Frenzy", 0 )
|
GAME( 1992, motofren, 0, atarigx2_0x200, motofren, atarigx2_state, motofren, ROT0, "Atari Games", "Moto Frenzy", 0 )
|
||||||
GAME( 1992, motofrenmd, motofren, atarigx2_0x200, motofren, atarigx2_state, motofren, ROT0, "Atari Games", "Moto Frenzy (Mini Deluxe)", 0 )
|
GAME( 1992, motofrenmd, motofren, atarigx2_0x200, motofren, atarigx2_state, motofren, ROT0, "Atari Games", "Moto Frenzy (Mini Deluxe)", 0 )
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
uint16_t m_playfield_base;
|
uint16_t m_playfield_base;
|
||||||
|
|
||||||
required_device<atari_jsa_iiis_device> m_jsa;
|
required_device<atari_jsa_iiis_device> m_jsa;
|
||||||
required_device<atari_xga_device> m_xga;
|
optional_device<atari_xga_device> m_xga;
|
||||||
|
|
||||||
required_shared_ptr<uint32_t> m_mo_command;
|
required_shared_ptr<uint32_t> m_mo_command;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
atarixga.cpp
|
atarixga.cpp
|
||||||
|
|
||||||
Atari XGA encryption FPGA
|
Atari XGA encryption FPGAs
|
||||||
|
|
||||||
**************************************************************************
|
**************************************************************************
|
||||||
|
|
||||||
@ -22,74 +22,6 @@
|
|||||||
#include "atarixga.h"
|
#include "atarixga.h"
|
||||||
|
|
||||||
|
|
||||||
extern const device_type ATARI_XGA = &device_creator<atari_xga_device>;
|
|
||||||
|
|
||||||
atari_xga_device::atari_xga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
|
||||||
: device_t(mconfig, ATARI_XGA, "Atari XGA", tag, owner, clock, "xga", __FILE__),
|
|
||||||
m_mode(FPGA_RESET),
|
|
||||||
m_address(0),
|
|
||||||
m_ciphertext(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
* Initialization
|
|
||||||
*
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
void atari_xga_device::device_start()
|
|
||||||
{
|
|
||||||
m_ram = std::make_unique<uint16_t[]>(RAM_WORDS);
|
|
||||||
|
|
||||||
save_pointer(NAME(m_ram.get()), RAM_WORDS * sizeof(uint16_t));
|
|
||||||
save_item(NAME(m_address));
|
|
||||||
save_item(NAME(m_ciphertext));
|
|
||||||
}
|
|
||||||
|
|
||||||
void atari_xga_device::device_reset()
|
|
||||||
{
|
|
||||||
memset(m_ram.get(), 0, RAM_WORDS * sizeof(uint16_t));
|
|
||||||
m_mode = FPGA_RESET;
|
|
||||||
m_address = 0;
|
|
||||||
m_ciphertext = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
* Definitions
|
|
||||||
*
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
// TODO: Add definitions for other games
|
|
||||||
// Moto Frenzy
|
|
||||||
|
|
||||||
/* key 0x10 is special, it has 15 "identical twins". */
|
|
||||||
static const uint8_t kmap[128] =
|
|
||||||
{
|
|
||||||
0x6B,0x11,0x1B,0x19,0x4B,0x50,0x17,0x09,
|
|
||||||
0x5D,0x69,0x43,0x33,0x0F,0x0C,0x28,0x3F,
|
|
||||||
0x00,0x20,0x15,0x3C,0x57,0x38,0x00,0x07,
|
|
||||||
0x49,0x25,0x61,0x2F,0x2B,0x4E,0x64,0x00,
|
|
||||||
0x45,0x41,0x6D,0x52,0x31,0x66,0x22,0x59,
|
|
||||||
0x00,0x70,0x6F,0x5B,0x46,0x6E,0x67,0x5A,
|
|
||||||
0x26,0x30,0x2C,0x65,0x21,0x3D,0x58,0x00,
|
|
||||||
0x5E,0x44,0x0D,0x40,0x6C,0x1C,0x51,0x0A,
|
|
||||||
0x35,0x2A,0x13,0x4D,0x63,0x00,0x00,0x3A,
|
|
||||||
0x00,0x48,0x54,0x24,0x60,0x1E,0x2E,0x01,
|
|
||||||
0x56,0x03,0x37,0x00,0x04,0x00,0x05,0x06,
|
|
||||||
0x00,0x55,0x1F,0x02,0x36,0x14,0x00,0x3B,
|
|
||||||
0x5F,0x0E,0x1D,0x0B,0x27,0x2D,0x3E,0x00,
|
|
||||||
0x00,0x5C,0x47,0x68,0x42,0x53,0x32,0x23,
|
|
||||||
0x4A,0x62,0x4F,0x00,0x00,0x16,0x39,0x08,
|
|
||||||
0x6A,0x34,0x10,0x29,0x12,0x1A,0x4C,0x18
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
@ -97,7 +29,7 @@ static const uint8_t kmap[128] =
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
uint16_t atari_xga_device::ctz(uint16_t x)
|
static uint16_t ctz(uint16_t x)
|
||||||
{
|
{
|
||||||
uint16_t n = 0;
|
uint16_t n = 0;
|
||||||
if (x == 0) return 16;
|
if (x == 0) return 16;
|
||||||
@ -108,7 +40,7 @@ uint16_t atari_xga_device::ctz(uint16_t x)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t atari_xga_device::popcount(uint16_t x)
|
static size_t popcount(uint16_t x)
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
while (x != 0)
|
while (x != 0)
|
||||||
@ -119,31 +51,64 @@ size_t atari_xga_device::popcount(uint16_t x)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t atari_xga_device::parity(uint16_t x)
|
static uint16_t parity(uint16_t x)
|
||||||
{
|
{
|
||||||
return popcount(x) & 1;
|
return popcount(x) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t atari_xga_device::lfsr1(uint16_t x)
|
|
||||||
|
/*************************************
|
||||||
|
*
|
||||||
|
* 136094-0072 (Moto Frenzy)
|
||||||
|
*
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
extern const device_type ATARI_136094_0072 = &device_creator<atari_136094_0072_device>;
|
||||||
|
|
||||||
|
atari_136094_0072_device::atari_136094_0072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: atari_xga_device(mconfig, ATARI_136094_0072, tag, owner, clock, "Atari 136094-0072 XGA", "136094-0072")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void atari_136094_0072_device::device_start()
|
||||||
|
{
|
||||||
|
m_ram = std::make_unique<uint16_t[]>(RAM_WORDS);
|
||||||
|
|
||||||
|
save_pointer(NAME(m_ram.get()), RAM_WORDS * sizeof(uint16_t));
|
||||||
|
save_item(NAME(m_address));
|
||||||
|
save_item(NAME(m_ciphertext));
|
||||||
|
}
|
||||||
|
|
||||||
|
void atari_136094_0072_device::device_reset()
|
||||||
|
{
|
||||||
|
memset(m_ram.get(), 0, RAM_WORDS * sizeof(uint16_t));
|
||||||
|
m_mode = FPGA_RESET;
|
||||||
|
m_address = 0;
|
||||||
|
m_ciphertext = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t atari_136094_0072_device::lfsr1(uint16_t x)
|
||||||
{
|
{
|
||||||
const uint16_t bit = parity(x & 0x8016);
|
const uint16_t bit = parity(x & 0x8016);
|
||||||
return (x << 1) | bit;
|
return (x << 1) | bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t atari_xga_device::lfsr2(uint16_t x)
|
uint16_t atari_136094_0072_device::lfsr2(uint16_t x)
|
||||||
{
|
{
|
||||||
uint16_t bit = parity(x & 0x002D);
|
uint16_t bit = parity(x & 0x002D);
|
||||||
return (x >> 1) | (bit << 15);
|
return (x >> 1) | (bit << 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t atari_xga_device::powers2(uint8_t k, uint16_t x)
|
uint16_t atari_136094_0072_device::powers2(uint8_t k, uint16_t x)
|
||||||
{
|
{
|
||||||
static const uint16_t L[16] = {
|
static const uint16_t L[16] =
|
||||||
0x5E85,0xBD0B,0x2493,0x17A3,
|
{
|
||||||
0x2F47,0x0005,0x000B,0x0017,
|
0x5E85,0xBD0B,0x2493,0x17A3,
|
||||||
0x002F,0x005E,0x00BD,0x017A,
|
0x2F47,0x0005,0x000B,0x0017,
|
||||||
0x02F4,0x05E8,0x0BD0,0x17A1
|
0x002F,0x005E,0x00BD,0x017A,
|
||||||
};
|
0x02F4,0x05E8,0x0BD0,0x17A1
|
||||||
|
};
|
||||||
|
|
||||||
uint16_t t = (x == 16) ? (L[4] ^ L[5]) : L[x];
|
uint16_t t = (x == 16) ? (L[4] ^ L[5]) : L[x];
|
||||||
|
|
||||||
@ -153,8 +118,29 @@ uint16_t atari_xga_device::powers2(uint8_t k, uint16_t x)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t atari_xga_device::decipher(uint8_t k, uint16_t c)
|
uint16_t atari_136094_0072_device::decipher(uint8_t k, uint16_t c)
|
||||||
{
|
{
|
||||||
|
/* key 0x10 is special, it has 15 "identical twins". */
|
||||||
|
static const uint8_t kmap[128] =
|
||||||
|
{
|
||||||
|
0x6B,0x11,0x1B,0x19,0x4B,0x50,0x17,0x09,
|
||||||
|
0x5D,0x69,0x43,0x33,0x0F,0x0C,0x28,0x3F,
|
||||||
|
0x00,0x20,0x15,0x3C,0x57,0x38,0x00,0x07,
|
||||||
|
0x49,0x25,0x61,0x2F,0x2B,0x4E,0x64,0x00,
|
||||||
|
0x45,0x41,0x6D,0x52,0x31,0x66,0x22,0x59,
|
||||||
|
0x00,0x70,0x6F,0x5B,0x46,0x6E,0x67,0x5A,
|
||||||
|
0x26,0x30,0x2C,0x65,0x21,0x3D,0x58,0x00,
|
||||||
|
0x5E,0x44,0x0D,0x40,0x6C,0x1C,0x51,0x0A,
|
||||||
|
0x35,0x2A,0x13,0x4D,0x63,0x00,0x00,0x3A,
|
||||||
|
0x00,0x48,0x54,0x24,0x60,0x1E,0x2E,0x01,
|
||||||
|
0x56,0x03,0x37,0x00,0x04,0x00,0x05,0x06,
|
||||||
|
0x00,0x55,0x1F,0x02,0x36,0x14,0x00,0x3B,
|
||||||
|
0x5F,0x0E,0x1D,0x0B,0x27,0x2D,0x3E,0x00,
|
||||||
|
0x00,0x5C,0x47,0x68,0x42,0x53,0x32,0x23,
|
||||||
|
0x4A,0x62,0x4F,0x00,0x00,0x16,0x39,0x08,
|
||||||
|
0x6A,0x34,0x10,0x29,0x12,0x1A,0x4C,0x18
|
||||||
|
};
|
||||||
|
|
||||||
uint16_t p = 0;
|
uint16_t p = 0;
|
||||||
|
|
||||||
/* Only 128 keys internally, if high bit set,
|
/* Only 128 keys internally, if high bit set,
|
||||||
@ -197,57 +183,57 @@ uint16_t atari_xga_device::decipher(uint8_t k, uint16_t c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
* Write/Read access
|
* Write/Read access
|
||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
WRITE32_MEMBER(atari_xga_device::write)
|
WRITE32_MEMBER(atari_136094_0072_device::write)
|
||||||
{
|
{
|
||||||
switch (m_mode)
|
switch (m_mode)
|
||||||
{
|
{
|
||||||
case FPGA_RESET:
|
case FPGA_RESET:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FPGA_SETKEY:
|
|
||||||
/* Write table to FPGA SRAM. */
|
|
||||||
if (ACCESSING_BITS_16_31)
|
|
||||||
m_ram[offset << 1] = uint16_t (data >> 16);
|
|
||||||
if (ACCESSING_BITS_0_15)
|
|
||||||
m_ram[(offset << 1) + 1] = uint16_t(data & 0xFFFF);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPGA_DECIPHER:
|
case FPGA_SETKEY:
|
||||||
/* Send Ciphertext to FPGA for decryption. */
|
/* Write table to FPGA SRAM. */
|
||||||
if (ACCESSING_BITS_16_31)
|
if (ACCESSING_BITS_16_31)
|
||||||
{
|
m_ram[offset << 1] = uint16_t (data >> 16);
|
||||||
m_address = offset << 2;
|
if (ACCESSING_BITS_0_15)
|
||||||
m_ciphertext = uint16_t(data >> 16);
|
m_ram[(offset << 1) + 1] = uint16_t(data & 0xFFFF);
|
||||||
}
|
break;
|
||||||
if (ACCESSING_BITS_0_15)
|
|
||||||
{
|
case FPGA_DECIPHER:
|
||||||
m_address = (offset << 2) + 2;
|
/* Send Ciphertext to FPGA for decryption. */
|
||||||
m_ciphertext = uint16_t(data & 0xFFFF);
|
if (ACCESSING_BITS_16_31)
|
||||||
}
|
{
|
||||||
break;
|
m_address = offset << 2;
|
||||||
|
m_ciphertext = uint16_t(data >> 16);
|
||||||
|
}
|
||||||
|
if (ACCESSING_BITS_0_15)
|
||||||
|
{
|
||||||
|
m_address = (offset << 2) + 2;
|
||||||
|
m_ciphertext = uint16_t(data & 0xFFFF);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
READ32_MEMBER(atari_xga_device::read)
|
READ32_MEMBER(atari_136094_0072_device::read)
|
||||||
{
|
{
|
||||||
switch (offset << 2)
|
switch (offset << 2)
|
||||||
{
|
{
|
||||||
case 0x0FC0:
|
case 0x0FC0:
|
||||||
m_mode = FPGA_RESET;
|
m_mode = FPGA_RESET;
|
||||||
break;
|
break;
|
||||||
case 0x0010:
|
case 0x0010:
|
||||||
m_mode = FPGA_SETKEY;
|
m_mode = FPGA_SETKEY;
|
||||||
break;
|
break;
|
||||||
case 0x0020:
|
case 0x0020:
|
||||||
m_mode = FPGA_DECIPHER;
|
m_mode = FPGA_DECIPHER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_mode == FPGA_RESET)
|
if (m_mode == FPGA_RESET)
|
||||||
@ -289,3 +275,234 @@ READ32_MEMBER(atari_xga_device::read)
|
|||||||
|
|
||||||
return plaintext;
|
return plaintext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
*
|
||||||
|
* 136095-0072 (Space Lords)
|
||||||
|
*
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
extern const device_type ATARI_136095_0072 = &device_creator<atari_136095_0072_device>;
|
||||||
|
|
||||||
|
atari_136095_0072_device::atari_136095_0072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
|
: atari_xga_device(mconfig, ATARI_136095_0072, tag, owner, clock, "Atari 136095-0072 XGA", "136095-0072")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void atari_136095_0072_device::device_start()
|
||||||
|
{
|
||||||
|
m_ram = std::make_unique<uint16_t[]>(RAM_WORDS);
|
||||||
|
save_pointer(NAME(m_ram.get()), RAM_WORDS * sizeof(uint16_t));
|
||||||
|
|
||||||
|
save_item(NAME(m_update.addr));
|
||||||
|
save_item(NAME(m_update.data));
|
||||||
|
save_item(NAME(m_poly_lsb));
|
||||||
|
save_item(NAME(m_reply));
|
||||||
|
}
|
||||||
|
|
||||||
|
void atari_136095_0072_device::device_reset()
|
||||||
|
{
|
||||||
|
memset(m_ram.get(), 0, RAM_WORDS * sizeof(uint16_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t atari_136095_0072_device::lfsr1(uint16_t x)
|
||||||
|
{
|
||||||
|
uint16_t bit = parity(x & (0xC100 | m_poly_lsb));
|
||||||
|
return (x << 1) | bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t atari_136095_0072_device::lfsr2(uint16_t x)
|
||||||
|
{
|
||||||
|
uint16_t bit = parity(x & (0x8201 | (m_poly_lsb << 1)));
|
||||||
|
return (x >> 1) | (bit << 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t atari_136095_0072_device::powers2(uint8_t k, uint16_t x)
|
||||||
|
{
|
||||||
|
size_t i, n;
|
||||||
|
uint16_t t = 1 << (x % 16);
|
||||||
|
|
||||||
|
if ((x == 15) || (x == 16))
|
||||||
|
n = k + 13;
|
||||||
|
else
|
||||||
|
n = k + 14;
|
||||||
|
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t = lfsr1(t);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t atari_136095_0072_device::decipher(uint8_t k, uint16_t c)
|
||||||
|
{
|
||||||
|
uint16_t i, p = 0;
|
||||||
|
|
||||||
|
/* key 0x00 is special, it has 15 "identical twins". */
|
||||||
|
static const uint8_t kmap[128] =
|
||||||
|
{
|
||||||
|
0x00,0x3C,0x0D,0x0B,0x5E,0x09,0x2A,0x31,
|
||||||
|
0x00,0x56,0x11,0x4D,0x14,0x34,0x3A,0x44,
|
||||||
|
0x24,0x41,0x51,0x28,0x1E,0x2F,0x68,0x00,
|
||||||
|
0x5C,0x49,0x18,0x04,0x37,0x00,0x07,0x6B,
|
||||||
|
0x58,0x46,0x0F,0x60,0x4B,0x6D,0x53,0x20,
|
||||||
|
0x00,0x70,0x62,0x6F,0x59,0x61,0x6E,0x54,
|
||||||
|
0x4A,0x19,0x38,0x6C,0x42,0x52,0x1F,0x01,
|
||||||
|
0x57,0x12,0x15,0x45,0x3D,0x0E,0x5F,0x32,
|
||||||
|
0x4F,0x36,0x00,0x2C,0x06,0x00,0x26,0x6A,
|
||||||
|
0x64,0x5B,0x48,0x22,0x17,0x3F,0x1B,0x03,
|
||||||
|
0x66,0x1D,0x2E,0x00,0x67,0x00,0x00,0x00,
|
||||||
|
0x65,0x23,0x40,0x1C,0x50,0x2D,0x00,0x27,
|
||||||
|
0x13,0x16,0x3E,0x33,0x1A,0x39,0x43,0x02,
|
||||||
|
0x00,0x63,0x5A,0x55,0x47,0x10,0x4C,0x21,
|
||||||
|
0x5D,0x05,0x00,0x08,0x25,0x29,0x30,0x69,
|
||||||
|
0x00,0x4E,0x35,0x3B,0x00,0x0C,0x0A,0x2B,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Only 128 keys internally, if high bit set,
|
||||||
|
then find the 7-bit "twin" by xor 0xA8. */
|
||||||
|
if (k & 0x80) k ^= 0xA8;
|
||||||
|
|
||||||
|
k = kmap[k];
|
||||||
|
|
||||||
|
if ((c & (c - 1)) == 0) {
|
||||||
|
return powers2(k, ctz(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 15; ++i) {
|
||||||
|
if (1 & (c >> i)) {
|
||||||
|
p ^= powers2(k, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c & 0x8000) {
|
||||||
|
p ^= powers2(k, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t x = 0xC000;
|
||||||
|
for (i = 0; i < k + 13; ++i)
|
||||||
|
{
|
||||||
|
if (x == c)
|
||||||
|
return (p == 1) ? 0 : lfsr2(p);
|
||||||
|
|
||||||
|
x = lfsr2(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(atari_136095_0072_device::polylsb_write)
|
||||||
|
{
|
||||||
|
m_update.addr = offset;
|
||||||
|
m_update.data[offset] = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(atari_136095_0072_device::polylsb_read)
|
||||||
|
{
|
||||||
|
if (m_update.addr == offset)
|
||||||
|
{
|
||||||
|
if (ACCESSING_BITS_16_31)
|
||||||
|
{
|
||||||
|
m_poly_lsb = (m_update.data[offset] >> 16) & 0xFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_poly_lsb = m_update.data[offset] & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m_update.data[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE32_MEMBER(atari_136095_0072_device::write)
|
||||||
|
{
|
||||||
|
uint16_t address, value = 0;
|
||||||
|
|
||||||
|
address = offset << 2;
|
||||||
|
if (ACCESSING_BITS_16_31)
|
||||||
|
{
|
||||||
|
value = uint16_t (data >> 16);
|
||||||
|
}
|
||||||
|
if (ACCESSING_BITS_0_15)
|
||||||
|
{
|
||||||
|
address += 2;
|
||||||
|
value = uint16_t (data & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_mode)
|
||||||
|
{
|
||||||
|
case FPGA_SETKEY:
|
||||||
|
/* Write table to FPGA SRAM. */
|
||||||
|
if (ACCESSING_BITS_16_31)
|
||||||
|
{
|
||||||
|
m_ram[offset << 1] = value;
|
||||||
|
}
|
||||||
|
if (ACCESSING_BITS_0_15)
|
||||||
|
{
|
||||||
|
m_ram[(offset << 1) + 1] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Send Ciphertext to FPGA for decryption. */
|
||||||
|
case FPGA_DECIPHER:
|
||||||
|
uint16_t key_offset, key_byte;
|
||||||
|
|
||||||
|
/* Algorithm to select key byte based on offset. */
|
||||||
|
key_offset = ((((address >> 8) & 1) ^ 1) << 0)
|
||||||
|
| ((((address >> 2) & 1) ^ 1) << 1)
|
||||||
|
| ((((address >> 7) & 1) ^ 0) << 2)
|
||||||
|
| ((((address >> 1) & 1) ^ 0) << 3)
|
||||||
|
| ((((address >> 4) & 1) ^ 1) << 4)
|
||||||
|
| ((((address >> 5) & 1) ^ 1) << 5)
|
||||||
|
| ((((address >> 3) & 1) ^ 0) << 6)
|
||||||
|
| ((((address >> 6) & 1) ^ 1) << 7)
|
||||||
|
| ((((address >> 9) & 1) ^ 0) << 8)
|
||||||
|
| ((((address >> 10) & 1) ^ 0) << 9)
|
||||||
|
| ((((address >> 11) & 1) ^ 0) << 10)
|
||||||
|
| ((((address >> 12) & 1) ^ 0) << 11);
|
||||||
|
key_byte = m_ram[key_offset];
|
||||||
|
m_reply = decipher(key_byte, value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FPGA_PROCESS:
|
||||||
|
case FPGA_RESULT:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ32_MEMBER(atari_136095_0072_device::read)
|
||||||
|
{
|
||||||
|
uint16_t address;
|
||||||
|
uint32_t reply = 0;
|
||||||
|
|
||||||
|
address = offset << 2;
|
||||||
|
|
||||||
|
if (ACCESSING_BITS_0_15)
|
||||||
|
address += 2;
|
||||||
|
|
||||||
|
switch (address)
|
||||||
|
{
|
||||||
|
case 0x0020:
|
||||||
|
m_mode = FPGA_SETKEY;
|
||||||
|
break;
|
||||||
|
case 0x0042:
|
||||||
|
m_mode = FPGA_DECIPHER;
|
||||||
|
break;
|
||||||
|
case 0x0C00:
|
||||||
|
m_mode = FPGA_PROCESS;
|
||||||
|
reply = -1;
|
||||||
|
break;
|
||||||
|
case 0x0FC0:
|
||||||
|
m_mode = FPGA_RESULT;
|
||||||
|
reply = m_reply << 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
@ -4,30 +4,54 @@
|
|||||||
|
|
||||||
atarixga.h
|
atarixga.h
|
||||||
|
|
||||||
Atari XGA encryption FPGA
|
Atari XGA encryption FPGAs
|
||||||
|
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#ifndef __MACHINE_ATARIXGA__
|
#ifndef __MACHINE_ATARIXGA__
|
||||||
#define __MACHINE_ATARIXGA__
|
#define __MACHINE_ATARIXGA__
|
||||||
|
|
||||||
extern const device_type ATARI_XGA;
|
extern const device_type ATARI_136094_0072;
|
||||||
|
extern const device_type ATARI_136095_0072;
|
||||||
|
|
||||||
class atari_xga_device : public device_t
|
class atari_xga_device : public device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
atari_xga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
atari_xga_device(const machine_config &mconfig, device_type type, const char *tag,
|
||||||
|
device_t *owner, uint32_t clock, const char *name, const char *shortname)
|
||||||
|
: device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
|
||||||
|
{}
|
||||||
|
|
||||||
DECLARE_WRITE32_MEMBER(write);
|
virtual DECLARE_WRITE32_MEMBER(write) = 0;
|
||||||
DECLARE_READ32_MEMBER(read);
|
virtual DECLARE_READ32_MEMBER(read) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void device_start() = 0;
|
||||||
|
virtual void device_reset() = 0;
|
||||||
|
|
||||||
|
std::unique_ptr<uint16_t[]> m_ram; // CY7C185-45PC, only 16-Kbit used
|
||||||
|
};
|
||||||
|
|
||||||
|
class atari_136094_0072_device : public atari_xga_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
atari_136094_0072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
virtual DECLARE_WRITE32_MEMBER(write) override;
|
||||||
|
virtual DECLARE_READ32_MEMBER(read) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const size_t RAM_WORDS = 2048;
|
static const size_t RAM_WORDS = 2048;
|
||||||
|
|
||||||
|
uint16_t powers2(uint8_t k, uint16_t x);
|
||||||
|
uint16_t lfsr2(uint16_t x);
|
||||||
|
uint16_t lfsr1(uint16_t x);
|
||||||
|
uint16_t decipher(uint8_t k, uint16_t c);
|
||||||
|
|
||||||
enum fpga_mode
|
enum fpga_mode
|
||||||
{
|
{
|
||||||
@ -35,19 +59,52 @@ private:
|
|||||||
FPGA_SETKEY,
|
FPGA_SETKEY,
|
||||||
FPGA_DECIPHER
|
FPGA_DECIPHER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fpga_mode m_mode;
|
||||||
|
uint16_t m_address; // last written address
|
||||||
|
uint16_t m_ciphertext; // last written ciphertext
|
||||||
|
};
|
||||||
|
|
||||||
|
class atari_136095_0072_device : public atari_xga_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
atari_136095_0072_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
DECLARE_WRITE32_MEMBER(polylsb_write);
|
||||||
|
DECLARE_READ32_MEMBER(polylsb_read);
|
||||||
|
|
||||||
|
virtual DECLARE_WRITE32_MEMBER(write) override;
|
||||||
|
virtual DECLARE_READ32_MEMBER(read) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const size_t RAM_WORDS = 4096;
|
||||||
|
|
||||||
uint16_t powers2(uint8_t k, uint16_t x);
|
uint16_t powers2(uint8_t k, uint16_t x);
|
||||||
uint16_t lfsr2(uint16_t x);
|
uint16_t lfsr2(uint16_t x);
|
||||||
uint16_t lfsr1(uint16_t x);
|
uint16_t lfsr1(uint16_t x);
|
||||||
uint16_t parity(uint16_t x);
|
|
||||||
size_t popcount(uint16_t x);
|
|
||||||
uint16_t ctz(uint16_t x);
|
|
||||||
uint16_t decipher(uint8_t k, uint16_t c);
|
uint16_t decipher(uint8_t k, uint16_t c);
|
||||||
|
|
||||||
|
enum fpga_mode
|
||||||
|
{
|
||||||
|
FPGA_SETKEY,
|
||||||
|
FPGA_DECIPHER,
|
||||||
|
FPGA_PROCESS,
|
||||||
|
FPGA_RESULT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t addr;
|
||||||
|
uint32_t data[64];
|
||||||
|
} m_update;
|
||||||
|
|
||||||
fpga_mode m_mode;
|
fpga_mode m_mode;
|
||||||
uint16_t m_address; // last written address
|
uint8_t m_poly_lsb;
|
||||||
uint16_t m_ciphertext; // last written ciphertext
|
uint16_t m_reply;
|
||||||
std::unique_ptr<uint16_t[]> m_ram; // CY7C185-45PC, only 16-Kbit used
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user