diff options
author | Olivier Galibert <galibert@pobox.com> | 2022-07-01 17:44:25 +0200 |
---|---|---|
committer | Olivier Galibert <galibert@pobox.com> | 2022-07-01 17:44:39 +0200 |
commit | 96e24fc56bb9cd0b15aa8d0ce17c4915ae2b2043 (patch) | |
tree | cbdbedef0a22d40263a4bafbb4b4817b19fe44f1 /src/devices | |
parent | 7942dd4e9efed59663c73d6101169000c66fdd47 (diff) |
There is only one Sega
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/machine/segacrp2_device.cpp | 451 | ||||
-rw-r--r-- | src/devices/machine/segacrp2_device.h | 126 | ||||
-rw-r--r-- | src/devices/machine/segacrpt_device.cpp | 1055 | ||||
-rw-r--r-- | src/devices/machine/segacrpt_device.h | 279 |
4 files changed, 1911 insertions, 0 deletions
diff --git a/src/devices/machine/segacrp2_device.cpp b/src/devices/machine/segacrp2_device.cpp new file mode 100644 index 00000000000..1a2676bd631 --- /dev/null +++ b/src/devices/machine/segacrp2_device.cpp @@ -0,0 +1,451 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, David Haywood +/****************************************************************************** + + Sega encryption emulation by Nicola Salmoria + + + This encryption is an evolution of the one implemented in segacrpt.cpp. + It works on more data and address bits but apart from that it's essentially + the same. + + The encryption affects D0, D2, D4, and D6, and depends on M1, A0, A3, A6, A9, + A12, and A14. + + The encryption consists of a permutation of the four data bits, which can also + be inverted. Therefore there are 4! * 2^4 = 384 different possible encryptions. + + An interesting peculiarity is that four games in the list below use an almost + identical key, just offset by one or more bytes. This leads to believe that + keys were generated using a PRNG like in other Sega encryptions (MC8123 etc.) + and the CPU part# used to skip the first N bytes. + + + List of encrypted games currently known: + + CPU Part # Game Comments + 315-5136 New Lucky 8 Lines (set 7, W-4, encrypted) + 315-5162 4D Warriors & used I'm Sorry for k.p.a. + Rafflesia & + Wonder Boy (set 4) + 315-5176 Wonder Boy (system 2 hardware, set 2) + 315-5177 Astro Flash & + Wonder Boy (set 1) + 315-5178 Wonder Boy (set 2) unencrypted version available + 315-5179 Robo-Wrestle 2001 + 317-5000 Fantasy Zone (Sound CPU) same key as 315-5177 + + The following games seem to use the same algorithm as the above ones, but + using a key which almost doesn't change + + 317-0004 Calorie Kun unencrypted bootleg available + 317-0005 Space Position + 317-0006 Gardia (set 1) + 317-0007 Gardia (set 2) + +******************************************************************************/ + +#include "emu.h" +#include "segacrp2_device.h" + + +static void decode(uint8_t *rom, uint8_t *decrypted, const uint8_t xor_table[128], const int swap_table[128]) +{ + static const uint8_t swaptable[24][4] = { + { 6,4,2,0 }, { 4,6,2,0 }, { 2,4,6,0 }, { 0,4,2,6 }, + { 6,2,4,0 }, { 6,0,2,4 }, { 6,4,0,2 }, { 2,6,4,0 }, + { 4,2,6,0 }, { 4,6,0,2 }, { 6,0,4,2 }, { 0,6,4,2 }, + { 4,0,6,2 }, { 0,4,6,2 }, { 6,2,0,4 }, { 2,6,0,4 }, + { 0,6,2,4 }, { 2,0,6,4 }, { 0,2,6,4 }, { 4,2,0,6 }, + { 2,4,0,6 }, { 4,0,2,6 }, { 2,0,4,6 }, { 0,2,4,6 } }; + + for (int a = 0x0000; a < 0x8000; a++) + { + const uint8_t *tbl; + + const uint8_t src = rom[a]; + + // pick the translation table from bits 0, 3, 6, 9, 12 and 14 of the address + const int row = bitswap<6>(a, 14, 12, 9, 6, 3, 0); + + // decode the opcodes + tbl = swaptable[swap_table[2 * row]]; + decrypted[a] = bitswap<8>(src, 7, tbl[0], 5, tbl[1], 3, tbl[2], 1, tbl[3]) ^ xor_table[2 * row]; + + // decode the data + tbl = swaptable[swap_table[2 * row + 1]]; + rom[a] = bitswap<8>(src, 7, tbl[0], 5, tbl[1], 3, tbl[2], 1, tbl[3]) ^ xor_table[2 * row + 1]; + } +} + + +DEFINE_DEVICE_TYPE(NEC_315_5136, nec_315_5136_device, "nec_315_5136", "Nec 315-5136") +DEFINE_DEVICE_TYPE(SEGA_315_5179, sega_315_5179_device, "sega_315_5179", "Sega 315-5179") +DEFINE_DEVICE_TYPE(SEGA_315_5178, sega_315_5178_device, "sega_315_5178", "Sega 315-5178") +DEFINE_DEVICE_TYPE(SEGA_315_5177, sega_315_5177_device, "sega_315_5177", "Sega 315-5177") // also seen as 317-5000 +DEFINE_DEVICE_TYPE(SEGA_315_5176, sega_315_5176_device, "sega_315_5176", "Sega 315-5176") +DEFINE_DEVICE_TYPE(SEGA_315_5162, sega_315_5162_device, "sega_315_5162", "Sega 315-5162") + +DEFINE_DEVICE_TYPE(SEGA_317_0004, sega_317_0004_device, "sega_317_0004", "Sega 317-0004") +DEFINE_DEVICE_TYPE(SEGA_317_0005, sega_317_0005_device, "sega_317_0005", "Sega 317-0005") +DEFINE_DEVICE_TYPE(SEGA_317_0006, sega_317_0006_device, "sega_317_0006", "Sega 317-0006") +DEFINE_DEVICE_TYPE(SEGA_317_0007, sega_317_0007_device, "sega_317_0007", "Sega 317-0007") + + +segacrp2_z80_device::segacrp2_z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + z80_device(mconfig, type, tag, owner, clock), + m_decrypted(*this, finder_base::DUMMY_TAG) +{ +} + +void segacrp2_z80_device::device_start() +{ + z80_device::device_start(); + decrypt(); +} + +nec_315_5136_device::nec_315_5136_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, NEC_315_5136, tag, owner, clock) +{ +} + +void nec_315_5136_device::decrypt() +{ + // 315-5136 + static const uint8_t xor_table[128] = { + 0x00,0x40, 0x10,0x50, 0x04,0x44, 0x14,0x54, 0x01,0x41, 0x11,0x51, 0x05,0x45, 0x15,0x55, + 0x00,0x40, 0x10,0x50, 0x04,0x44, 0x14,0x54, 0x01,0x41, 0x11,0x51, 0x05,0x45, 0x15,0x55, + 0x00,0x40, 0x10,0x50, 0x04,0x44, 0x14,0x54, 0x01,0x41, 0x11,0x51, 0x05,0x45, 0x15,0x55, + 0x00,0x40, 0x10,0x50, 0x04,0x44, 0x14,0x54, 0x01,0x41, 0x11,0x51, 0x05,0x45, 0x15,0x55, + + 0x50,0x10, 0x44,0x04, 0x54,0x14, 0x41,0x01, 0x51,0x11, 0x45,0x05, 0x55,0x15, 0x40,0x00, + 0x50,0x10, 0x44,0x04, 0x54,0x14, 0x41,0x01, 0x51,0x11, 0x45,0x05, 0x55,0x15, 0x40,0x00, + 0x50,0x10, 0x44,0x04, 0x54,0x14, 0x41,0x01, 0x51,0x11, 0x45,0x05, 0x55,0x15, 0x40,0x00, + 0x50,0x10, 0x44,0x04, 0x54,0x14, 0x41,0x01, 0x51,0x11, 0x45,0x05, 0x55,0x15, 0x40,0x00 }; + + static const int swap_table[128] = { + 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, + 0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, + 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, + 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, + 0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04 }; + + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + +sega_315_5177_device::sega_315_5177_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_315_5177, tag, owner, clock) +{ +} + +void sega_315_5177_device::decrypt() +{ + // 315-5177 + static const uint8_t xor_table[128] = { + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14,0x41,0x45,0x00,0x50,0x54,0x11,0x45,0x40, + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14,0x41,0x45,0x00,0x50,0x54,0x11,0x45,0x40, + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14, + + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14,0x41,0x45,0x00,0x50,0x54,0x11,0x45,0x40, + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14,0x41,0x45,0x00,0x50,0x54,0x11,0x45,0x40, + 0x04,0x54,0x51,0x15,0x40,0x44,0x01,0x51,0x55,0x10,0x44,0x41, + 0x05,0x55,0x50,0x14 }; + + static const int swap_table[128] = { + 0,0,0,0, + 1,1,1,1,1, + 2,2,2,2,2, + 3,3,3,3, + 4,4,4,4,4, + 5,5,5,5,5, + 6,6,6,6,6, + 7,7,7,7,7, + 8,8,8,8, + 9,9,9,9,9, + 10,10,10,10,10, + 11,11,11,11,11, + 12,12,12,12,12, + 13,13, + + 8,8,8,8, + 9,9,9,9,9, + 10,10,10,10,10, + 11,11,11,11, + 12,12,12,12,12, + 13,13,13,13,13, + 14,14,14,14,14, + 15,15,15,15,15, + 16,16,16,16, + 17,17,17,17,17, + 18,18,18,18,18, + 19,19,19,19,19, + 20,20,20,20,20, + 21,21 }; + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + +sega_315_5176_device::sega_315_5176_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_315_5176, tag, owner, clock) +{ +} + +void sega_315_5176_device::decrypt() +{ + static const uint8_t xor_table[128] = { + 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, + 0x41, 0x05, 0x55, 0x10, 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, + 0x45, 0x00, 0x50, 0x14, 0x41, 0x05, 0x55, 0x10, 0x44, 0x01, 0x51, 0x15, + 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, 0x41, 0x05, 0x55, 0x10, + 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, + 0x41, 0x05, 0x55, 0x10, + + 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, + 0x41, 0x05, 0x55, 0x10, 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, + 0x45, 0x00, 0x50, 0x14, 0x41, 0x05, 0x55, 0x10, 0x44, 0x01, 0x51, 0x15, + 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, 0x41, 0x05, 0x55, 0x10, + 0x44, 0x01, 0x51, 0x15, 0x40, 0x04, 0x54, 0x11, 0x45, 0x00, 0x50, 0x14, + 0x41, 0x05, 0x55, 0x10 }; + + static const int swap_table[128] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, + + 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, + 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14 }; + + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + +sega_315_5162_device::sega_315_5162_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_315_5162, tag, owner, clock) +{ +} + +void sega_315_5162_device::decrypt() +{ + // 315-5162 + static const uint8_t xor_table[128] = { + 0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00,0x40,0x10,0x50,0x04,0x44,0x14,0x54,0x01,0x41,0x11,0x51,0x05,0x45,0x15,0x55, + 0x00 }; + + static const int swap_table[128] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, + 12 }; + + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + + +sega_315_5178_device::sega_315_5178_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_315_5178, tag, owner, clock) +{ +} + +void sega_315_5178_device::decrypt() +{ // 315-5178 + static const uint8_t xor_table[128] = { + 0x00,0x55,0x45,0x05,0x11,0x41,0x01,0x14,0x44,0x50,0x10, + 0x00,0x55,0x15,0x05,0x51,0x41,0x01,0x14,0x44,0x04,0x10, + 0x40,0x55,0x15,0x05,0x51,0x11, + 0x01,0x54,0x44,0x04,0x10,0x40,0x00,0x15,0x45,0x51,0x11, + 0x01,0x54,0x14,0x04,0x50,0x40,0x00,0x15,0x45,0x05,0x11, + 0x41,0x54,0x14,0x04,0x50,0x10, + 0x00,0x55,0x45,0x05,0x11,0x41,0x01,0x14, + + 0x00,0x55,0x45,0x05,0x11,0x41,0x01,0x14,0x44,0x50,0x10, + 0x00,0x55,0x15,0x05,0x51,0x41,0x01,0x14,0x44,0x04,0x10, + 0x40,0x55,0x15,0x05,0x51,0x11, + 0x01,0x54,0x44,0x04,0x10,0x40,0x00,0x15,0x45,0x51,0x11, + 0x01,0x54,0x14,0x04,0x50,0x40,0x00,0x15,0x45,0x05,0x11, + 0x41,0x54,0x14,0x04,0x50,0x10, + 0x00,0x55,0x45,0x05,0x11,0x41,0x01,0x14 }; + + static const int swap_table[128] = { + 2, + 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, + 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, + 5, 7, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, + 4, 6, 0, 2, 4, 6, 0, 2, 4, 6, + 8, + 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, + 6, 0, 2, 4, 6, 0, 2, + + 10, + 11,13,15, 9,11,13,15, 9,11,13,15, + 8,10,12,14, 8,10,12,14, 8,10,12, + 13,15, 9,11,13,15, 9,11,13,15, 9,11, + 12,14, 8,10,12,14, 8,10,12,14, + 16, + 9,11,13,15, 9,11,13,15, 9,11,13, + 14, 8,10,12,14, 8,10 }; + + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + +sega_315_5179_device::sega_315_5179_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_315_5179, tag, owner, clock) +{ +} + +void sega_315_5179_device::decrypt() +{ // 315-5179 + static const uint8_t xor_table[128] = { + 0x00,0x45,0x41,0x14,0x10,0x55,0x51,0x01,0x04,0x40,0x45,0x11,0x14,0x50, + 0x00,0x05,0x41,0x44,0x10,0x15,0x51,0x54,0x04, + 0x00,0x45,0x41,0x14,0x10,0x55,0x05,0x01,0x44,0x40,0x15,0x11,0x54,0x50, + 0x00,0x05,0x41,0x44,0x10,0x15,0x51,0x01,0x04, + 0x40,0x45,0x11,0x14,0x50,0x55,0x05,0x01,0x44,0x40,0x15,0x11,0x54,0x04, + 0x00,0x45,0x41,0x14,0x50, + 0x00,0x05,0x41,0x44,0x10,0x15,0x51,0x54,0x04, + 0x00,0x45,0x41,0x14,0x50,0x55,0x05,0x01,0x44,0x40,0x15,0x11,0x54,0x50, + 0x00,0x05,0x41,0x44,0x10,0x55,0x51,0x01,0x04, + 0x40,0x45,0x11,0x14,0x50,0x55,0x05,0x01,0x44,0x40,0x15,0x51,0x54,0x04, + 0x00,0x45,0x41,0x14,0x10,0x55,0x51,0x01,0x04, + 0x40,0x45,0x11,0x54,0x50,0x00,0x05,0x41 }; + + static const int swap_table[128] = { + 8, 9,11,13,15, 0, 2, 4, 6, + 8, 9,11,13,15, 1, 2, 4, 6, + 8, 9,11,13,15, 1, 2, 4, 6, + 8, 9,11,13,15, 1, 2, 4, 6, + 8,10,11,13,15, 1, 2, 4, 6, + 8,10,11,13,15, 1, 2, 4, 6, + 8,10,11,13,15, 1, 3, 4, 6, + 8, + 7, 1, 2, 4, 6, 0, 1, 3, 5, + 7, 1, 2, 4, 6, 0, 1, 3, 5, + 7, 1, 2, 4, 6, 0, 2, 3, 5, + 7, 1, 2, 4, 6, 0, 2, 3, 5, + 7, 1, 2, 4, 6, 0, 2, 3, 5, + 7, 1, 3, 4, 6, 0, 2, 3, 5, + 7, 1, 3, 4, 6, 0, 2, 4, 5, + 7 }; + + decode(memregion(tag())->base(), m_decrypted, xor_table, swap_table); +} + + +/****************************************************************************** + + These games (all 317-000x CPUs) use the same algorithm, but the key doesn't + change much - just a shift in the table. + +******************************************************************************/ + +static void sega_decode_317(uint8_t *rom, uint8_t *decrypted, int shift) +{ + static const uint8_t xor_table[128 + 3] = { + 0x04,0x54,0x44,0x14,0x15,0x15,0x51,0x41,0x41,0x14,0x10,0x50,0x15,0x55,0x54,0x05, + 0x04,0x41,0x51,0x01,0x05,0x10,0x55,0x51,0x05,0x05,0x54,0x11,0x45,0x05,0x04,0x14, + 0x10,0x55,0x01,0x41,0x51,0x05,0x55,0x04,0x45,0x41,0x55,0x14,0x45,0x10,0x04,0x45, + 0x55,0x50,0x40,0x00,0x11,0x45,0x15,0x00,0x01,0x00,0x40,0x00,0x01,0x45,0x11,0x00, + 0x45,0x00,0x44,0x54,0x40,0x04,0x05,0x15,0x15,0x10,0x15,0x04,0x01,0x05,0x50,0x11, + 0x00,0x44,0x44,0x04,0x04,0x01,0x50,0x05,0x51,0x00,0x45,0x44,0x50,0x15,0x54,0x40, + 0x41,0x45,0x40,0x10,0x14,0x15,0x40,0x51,0x50,0x50,0x45,0x00,0x10,0x15,0x05,0x51, + 0x50,0x44,0x01,0x15,0x40,0x04,0x01,0x44,0x50,0x44,0x50,0x50,0x50,0x10,0x44,0x04, + 0x40,0x04,0x10 }; + + static const int swap_table[128 + 3] = { + 7, 7,12, 1,18,11, 8,23,21,17, 0,23,22, 0,21,15, + 13,19,21,20,20,12,13,10,20, 0,14,18, 6,18, 3, 5, + 5,20,20,13, 8, 0,20,18, 4,14, 8, 5,17, 6,22,10, + 0,21, 0, 1, 6,11,17, 9,17, 3, 9,21, 0, 4,16, 1, + 13,17,21, 5, 3, 7, 2,16,18,13, 6,19,11,23, 3,20, + 3, 2,18,10,18,23,19,23, 3,15, 0,10, 5,12, 0, 0, + 11,22, 8,14, 8, 6, 1,15, 7,11, 2,17,10,15, 8,21, + 10, 0, 2, 6, 1, 1, 3, 1,12,18,16, 5, 0,15,17,15, + 10,20, 1 }; + + decode(rom, decrypted, xor_table + shift, swap_table + shift); +} + + +sega_317_0004_device::sega_317_0004_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_317_0004, tag, owner, clock) +{ +} + +void sega_317_0004_device::decrypt() +{ // 317-0004 + sega_decode_317(memregion(tag())->base(), m_decrypted, 0); +} + + +sega_317_0005_device::sega_317_0005_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_317_0005, tag, owner, clock) +{ +} + +void sega_317_0005_device::decrypt() +{ // 317-0005 + sega_decode_317(memregion(tag())->base(), m_decrypted, 1); +} + + +sega_317_0006_device::sega_317_0006_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_317_0006, tag, owner, clock) +{ +} + +void sega_317_0006_device::decrypt() +{ // 317-0006 + sega_decode_317(memregion(tag())->base(), m_decrypted, 2); +} + + +sega_317_0007_device::sega_317_0007_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + segacrp2_z80_device(mconfig, SEGA_317_0007, tag, owner, clock) +{ +} + +void sega_317_0007_device::decrypt() +{ // 317-0006 + sega_decode_317(memregion(tag())->base(), m_decrypted, 3); +} diff --git a/src/devices/machine/segacrp2_device.h b/src/devices/machine/segacrp2_device.h new file mode 100644 index 00000000000..a64f3fa5fe0 --- /dev/null +++ b/src/devices/machine/segacrp2_device.h @@ -0,0 +1,126 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +#ifndef MAME_MACHINE_SEGACRP2_DEVICE_H +#define MAME_MACHINE_SEGACRP2_DEVICE_H + +#pragma once + + +#include "cpu/z80/z80.h" + +// base class +class segacrp2_z80_device : public z80_device +{ +public: + template <typename T> void set_decrypted_tag(T &&decrypted_tag) { m_decrypted.set_tag(std::forward<T>(decrypted_tag)); } + +protected: + segacrp2_z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void decrypt() = 0; + + required_shared_ptr<uint8_t> m_decrypted; +}; + + + +// actual encrypted CPUs +class nec_315_5136_device : public segacrp2_z80_device +{ +public: + nec_315_5136_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5179_device : public segacrp2_z80_device +{ +public: + sega_315_5179_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_315_5178_device : public segacrp2_z80_device +{ +public: + sega_315_5178_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5177_device : public segacrp2_z80_device +{ +public: + sega_315_5177_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5176_device : public segacrp2_z80_device +{ +public: + sega_315_5176_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5162_device : public segacrp2_z80_device +{ +public: + sega_315_5162_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_317_0004_device : public segacrp2_z80_device +{ +public: + sega_317_0004_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_317_0005_device : public segacrp2_z80_device +{ +public: + sega_317_0005_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_317_0006_device : public segacrp2_z80_device +{ +public: + sega_317_0006_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_317_0007_device : public segacrp2_z80_device +{ +public: + sega_317_0007_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +DECLARE_DEVICE_TYPE(NEC_315_5136, nec_315_5136_device) +DECLARE_DEVICE_TYPE(SEGA_315_5179, sega_315_5179_device) +DECLARE_DEVICE_TYPE(SEGA_315_5178, sega_315_5178_device) +DECLARE_DEVICE_TYPE(SEGA_315_5177, sega_315_5177_device) +DECLARE_DEVICE_TYPE(SEGA_315_5176, sega_315_5176_device) +DECLARE_DEVICE_TYPE(SEGA_315_5162, sega_315_5162_device) + +DECLARE_DEVICE_TYPE(SEGA_317_0004, sega_317_0004_device) +DECLARE_DEVICE_TYPE(SEGA_317_0005, sega_317_0005_device) +DECLARE_DEVICE_TYPE(SEGA_317_0006, sega_317_0006_device) +DECLARE_DEVICE_TYPE(SEGA_317_0007, sega_317_0007_device) + + +#endif // MAME_MACHINE_SEGACRP2_DEVICE_H diff --git a/src/devices/machine/segacrpt_device.cpp b/src/devices/machine/segacrpt_device.cpp new file mode 100644 index 00000000000..2ba57904e60 --- /dev/null +++ b/src/devices/machine/segacrpt_device.cpp @@ -0,0 +1,1055 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, David Haywood +/****************************************************************************** + + Sega encryption emulation by Nicola Salmoria + + + Several Sega Z80 games have program ROMs encrypted using a common algorithm + (but with a different key). + The hardware used to implement this encryption is either a custom CPU, or an + epoxy block which probably contains a standard Z80 + PALs. + + The encryption affects D3, D5, and D7, and depends on M1, A0, A4, A8 and A12. + D0, D1, D2, D4 and D6 are always unaffected. + + The encryption consists of a permutation of the three bits, which can also be + inverted. Therefore there are 3! * 2^3 = 48 different possible encryptions. + + For simplicity, the decryption is implemented using conversion tables. + We need 32 of these tables, one for every possible combination of M1, A0, A4, + A8 and A12. However, all the games currently known are full of repetitions + and only use 6 different tables, the only exceptions being Pengo, Yamato and + Spatter which have 7 (but one of them is the identity: { 0x00, 0x08, 0x20, 0x28 } ). + This is most likely a limitation of the hardware. + Some of the early games are even weaker: of the 6 different tables, they use + 3 for opcodes and 3 for data, and always coupled in the same way. + + In all games currently known, only bytes in the memory range 0x0000-0x7fff + (A15 = 0) are encrypted. My guess is that this was done to allow games to + copy code to RAM (in the memory range 0x8000-0xffff) and execute it from + there without the CPU trying to decrypt it and messing everything up. + However Zaxxon has RAM at 0x6000, and the CPU doesn't seem to interfere with + it; but it doesn't execute code from there, so it's possible that the CPU is + encrypting the data while writing it and decrypting it while reading (that + would seem kind of strange though). Video and sprite RAM and memory mapped + ports are all placed above 0x8000. + + Given its strict limitations, this encryption is reasonably easy to break, + and very vulnerable to known plaintext attacks. + + + + Ninja Princess: + + there is a (bootleg?) board which has a standard Z80 + 2 bipolar PROMs + instead of the custom CPU. The encryption table is different from the + original Ninja Princess; it is actually the same as Flicky. + + The first PROM is 32x8 and contains the number (0..5) of the table to + use depending on M1, A0, A4, A8, A12: + + 00: 11 00 33 22 00 44 44 00 11 33 33 22 44 44 44 22 + 10: 11 55 55 33 44 22 55 22 11 33 55 33 44 44 11 22 + + The second PROM is 256x4 and contains the 6 different XOR tables: + + A D B C C B D A + 00: 09 09 0A 0A 0A 0A 09 09 + 08: 0E 08 0B 0D 0D 0B 08 0E + 10: 0A 0C 0A 0C 0C 0A 0C 0A + 18: 0B 0E 0E 0B 0B 0E 0E 0B + 20: 0C 0C 0F 0F 0F 0F 0C 0C + 28: 08 0D 0B 0E 0E 0B 0D 08 + [the remaining bytes are all 0F] + bit 3 is not used. + bits 0-2 is the XOR code inverted (0 = 0xa8, 1 = 0xa0 ... 6 = 0x08 7 = 0x00) + + Here is a diagram showing how it works: + + data to XOR + decode value + A --- + D7 --------------- 0| | + D3 --------------- 1| | + D5 --------------- 2| P |D + A --- D | R |0 ---|>--- D3 + M1 --- 0| P |0 --- 3| O |1 ---|>--- D5 + A0 --- 1| R |1 --- 4| M |2 ---|>--- D7 + A4 --- 2| O |2 --- 5| 2 |3 --- + A8 --- 3| M |3 --- 6| | + A12 --- 4| 1 |4 --- 7| | + --- --- + + + My Hero: + + the bootleg does the decryption using a single 256x4 PROM, mapped in the + obvious way: + + data to XOR + decode value + A --- + D3 --- 0| | + D5 --- 1| |D + D7 --- 2| P |0 --- D3 + A0 --- 3| R |1 --- D5 + A4 --- 4| O |2 --- D7 + A8 --- 5| M |3 --- + A12 --- 6| | + M1 --- 7| | + --- + + + + List of encrypted games currently known: + + CPU Part # Game Comments + 315-5010 Pengo unencrypted version available + 315-5013 Super Zaxxon used Zaxxon for known plaintext attack + 315-5014 Buck Rogers / Zoom 909 unencrypted version available + 315-5015 Super Locomotive + 315-5018 Yamato + ???-???? Top Roller same key as Yamato + 315-5028 Sindbad Mystery + 315-5030 Up'n Down unencrypted version available + ???-???? M120 Razzmatazz same key as Up'n Down + 315-5033 Regulus unencrypted version available + 315-5041 M140 Mister Viking + 315-5048 SWAT used Bull Fight for k.p.a. + 315-5051 Flicky & + Ninja Princess (bootleg) + 315-5061 Future Spy + 315-5064 Water Match used Mister Viking for k.p.a. + 315-5065 Bull Fight + 315-5069 Star Force game by Tehkan; same key as Super Locomotive + ???-???? Spatter same encryption scheme is used by the Falcon 03155096 CPU (Z80) + 315-5084 Jongkyo TABLE INCOMPLETE game by Kiwako; also has a simple bitswap on top + 315-5093 Pitfall II + 315-5098 Ninja Princess unencrypted version available; same key as Up'n Down + 315-5102 Sega Ninja unencrypted version available + 315-5110 I'm Sorry used My Hero for k.p.a. + 315-5114 Champion Pro Wrestling same key as Regulus + 315-5115 TeddyBoy Blues + 315-5128 Pinball Action game by Tehkan; also has a simple bitswap on top + 315-5132 My Hero + 315-5135 Heavy Metal & + Wonder Boy (set 1a & 3; bootlegs?) + + + Some text found in the ROMs: + + Buck Rogers SECULITY BY MASATOSHI,MIZUNAGA + Super Locomotive SEGA FUKUMURA MIZUNAGA + Yamato SECULITY BY M,MIZUNAGA + Regulus SECULITY BY SYUICHI,KATAGI + Up'n Down 19/SEP 1983 MASATOSHI,MIZUNAGA + Mister Viking SECURITY BY S.KATAGI CONTROL CHIP M140 + SWAT SECURITY BY S.KATAGI + Flicky SECURITY BY S.KATAGI + Water Match PROGRAMED BY KAWAHARA&NAKAGAWA + Star Force STAR FORCE TEHKAN. SECURITY BY SEGA ENTERPRISESE + +******************************************************************************/ + +#include "emu.h" +#include "segacrpt_device.h" + + +#if 0 +static void lfkp(int mask) +{ + int A; + uint8_t *RAM = machine.root_device().memregion("maincpu")->base(); + + + for (A = 0x0000;A < 0x8000-14;A++) + { + static const char text[] = "INSERT COIN"; + int i; + + + if ( (RAM[A+0] & mask) == (0x21 & mask) && /* LD HL,$xxxx */ + (RAM[A+3] & mask) == (0x11 & mask) && /* LD DE,$xxxx */ + (RAM[A+6] & mask) == (0x01 & mask)) /* LD BC,$xxxx */ + { + if ( (RAM[A+ 9] & mask) == (0x36 & mask) && /* LD (HL),$xx */ + (RAM[A+11] & mask) == (0xed & mask) && + (RAM[A+12] & mask) == (0xb0 & mask)) /* LDIR */ + logerror("%04x: hl de bc (hl),xx ldir\n",A); + + if ( (RAM[A+ 9] & mask) == (0x77 & mask) && /* LD (HL),A */ + (RAM[A+10] & mask) == (0xed & mask) && + (RAM[A+11] & mask) == (0xb0 & mask)) /* LDIR */ + logerror("%04x: hl de bc (hl),a ldir\n",A); + + if ( (RAM[A+ 9] & mask) == (0xed & mask) && + (RAM[A+10] & mask) == (0xb0 & mask)) /* LDIR */ + logerror("%04x: hl de bc ldir\n",A); + } + + /* the following can also be PUSH IX, PUSH IY - need better checking */ + if ( (RAM[A+0] & mask) == (0xf5 & mask) && /* PUSH AF */ + (RAM[A+1] & mask) == (0xc5 & mask) && /* PUSH BC */ + (RAM[A+2] & mask) == (0xd5 & mask) && /* PUSH DE */ + (RAM[A+3] & mask) == (0xe5 & mask)) /* PUSH HL */ + logerror("%04x: push af bc de hl\n",A); + + if ( (RAM[A+0] & mask) == (0xe1 & mask) && /* POP HL */ + (RAM[A+1] & mask) == (0xd1 & mask) && /* POP DE */ + (RAM[A+2] & mask) == (0xc1 & mask) && /* POP BC */ + (RAM[A+3] & mask) == (0xf1 & mask)) /* POP AF */ + logerror("%04x: pop hl de bc af\n",A); + + for (i = 0;i < strlen(text);i++) + if ((RAM[A+i] & mask) != (text[i] & mask)) break; + if (i == strlen(text)) + logerror("%04x: INSERT COIN\n",A); + } +} + +static void look_for_known_plaintext(void) +{ + lfkp(0x57); +} +#endif + +static void decode(uint8_t *data, uint8_t *opcodes, int size, const uint8_t convtable[32][4], int bank_count, int bank_size) +{ + for (int A = 0x0000;A < size + bank_count*bank_size;A++) + { + int xorval = 0; + + uint8_t src = data[A]; + int adr; + if(A < size || !bank_count) + adr = A; + else + adr = size + ((A - size) % bank_size); + + /* pick the translation table from bits 0, 4, 8 and 12 of the address */ + int row = (adr & 1) + (((adr >> 4) & 1) << 1) + (((adr >> 8) & 1) << 2) + (((adr >> 12) & 1) << 3); + + /* pick the offset in the table from bits 3 and 5 of the source data */ + int col = ((src >> 3) & 1) + (((src >> 5) & 1) << 1); + /* the bottom half of the translation table is the mirror image of the top */ + if (src & 0x80) + { + col = 3 - col; + xorval = 0xa8; + } + + /* decode the opcodes */ + opcodes[A] = (src & ~0xa8) | (convtable[2*row][col] ^ xorval); + + /* decode the data */ + data[A] = (src & ~0xa8) | (convtable[2*row+1][col] ^ xorval); + + if (convtable[2*row][col] == 0xff) /* table incomplete! (for development) */ + opcodes[A] = 0xee; + if (convtable[2*row+1][col] == 0xff) /* table incomplete! (for development) */ + data[A] = 0xee; + } +} + + + + +DEFINE_DEVICE_TYPE(SEGA_315_5132, sega_315_5132_device, "sega_315_5132", "Sega 315-5132") +DEFINE_DEVICE_TYPE(SEGA_315_5155, sega_315_5155_device, "sega_315_5155", "Sega 315-5155") +DEFINE_DEVICE_TYPE(SEGA_315_5110, sega_315_5110_device, "sega_315_5110", "Sega 315-5110") +DEFINE_DEVICE_TYPE(SEGA_315_5135, sega_315_5135_device, "sega_315_5135", "Sega 315-5135") +DEFINE_DEVICE_TYPE(SEGA_315_5051, sega_315_5051_device, "sega_315_5051", "Sega 315-5051") +DEFINE_DEVICE_TYPE(SEGA_315_5098, sega_315_5098_device, "sega_315_5098", "Sega 315-5098") // also 315-5030 ? +DEFINE_DEVICE_TYPE(SEGA_315_5102, sega_315_5102_device, "sega_315_5102", "Sega 315-5102") +DEFINE_DEVICE_TYPE(SEGA_315_5065, sega_315_5065_device, "sega_315_5065", "Sega 315-5065") +DEFINE_DEVICE_TYPE(SEGA_315_5064, sega_315_5064_device, "sega_315_5064", "Sega 315-5064") +DEFINE_DEVICE_TYPE(SEGA_315_5033, sega_315_5033_device, "sega_315_5033", "Sega 315-5033") +DEFINE_DEVICE_TYPE(SEGA_315_5041, sega_315_5041_device, "sega_315_5041", "Sega 315-5041") +DEFINE_DEVICE_TYPE(SEGA_315_5048, sega_315_5048_device, "sega_315_5048", "Sega 315-5048") +DEFINE_DEVICE_TYPE(SEGA_315_5093, sega_315_5093_device, "sega_315_5093", "Sega 315-5093") +DEFINE_DEVICE_TYPE(SEGA_315_5099, sega_315_5099_device, "sega_315_5099", "Sega 315-5099") +DEFINE_DEVICE_TYPE(SEGA_315_5015, sega_315_5015_device, "sega_315_5015", "Sega 315-5015") +DEFINE_DEVICE_TYPE(SEGA_315_5133, sega_315_5133_device, "sega_315_5133", "Sega 315-5133") // exactly the same as Sega 315-5048? +DEFINE_DEVICE_TYPE(SEGA_315_5061, sega_315_5061_device, "sega_315_5061", "Sega 315-5061") +DEFINE_DEVICE_TYPE(SEGA_315_5028, sega_315_5028_device, "sega_315_5028", "Sega 315-5028") +DEFINE_DEVICE_TYPE(SEGA_315_5084, sega_315_5084_device, "sega_315_5084", "Sega 315-5084") +DEFINE_DEVICE_TYPE(SEGA_315_5013, sega_315_5013_device, "sega_315_5013", "Sega 315-5013") +DEFINE_DEVICE_TYPE(SEGA_315_5014, sega_315_5014_device, "sega_315_5014", "Sega 315-5014") +DEFINE_DEVICE_TYPE(SEGA_315_5018, sega_315_5018_device, "sega_315_5018", "Sega 315-5018") +DEFINE_DEVICE_TYPE(SEGA_315_5010, sega_315_5010_device, "sega_315_5010", "Sega 315-5010") +DEFINE_DEVICE_TYPE(SEGA_315_SPAT, sega_315_spat_device, "sega_315_spat", "Sega 315-5xxx (Spatter)") // unknown part number +DEFINE_DEVICE_TYPE(SEGA_315_5128, sega_315_5128_device, "sega_315_5128", "Sega 315-5128") + + + + +segacrpt_z80_device::segacrpt_z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + z80_device(mconfig, type, tag, owner, clock), + m_decrypted_ptr(nullptr), + m_region_ptr(nullptr), + m_decode_size(0x8000), + m_numbanks(0), + m_banksize(0), + m_decryption_done(false) +{ +} + +void segacrpt_z80_device::device_start() +{ + z80_device::device_start(); +} + +void segacrpt_z80_device::device_reset() +{ + // decrypt on reset, makes sure DRIVER_INIT stuff happens first (for myherok) + // actual CPU would be decrypting in realtime anyway + if (m_decrypted_ptr == nullptr) + { + m_decrypted_ptr = (uint8_t*)memshare(m_decrypted_tag)->ptr(); + } + + if (m_region_ptr == nullptr) + { + m_region_ptr = (uint8_t*)memregion(tag())->base(); + } + + if (m_decryption_done == false) + { + decrypt(); + m_decryption_done = true; + } + z80_device::device_reset(); +} + +void segacrpt_z80_device::set_region_p(uint8_t* ptr) +{ + m_region_ptr = ptr; +} + +void segacrpt_z80_device::set_decrypted_p(uint8_t* ptr) +{ + m_decrypted_ptr = ptr; +} + + + + +sega_315_5132_device::sega_315_5132_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5132, tag, owner, clock) {} +void sega_315_5132_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x20,0x00,0xa0,0x80 }, { 0x80,0xa0,0x88,0xa8 }, /* ...0...0...0...0 */ + { 0x20,0x00,0xa0,0x80 }, { 0x80,0xa0,0x88,0xa8 }, /* ...0...0...0...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...1...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x80,0xa0,0x88,0xa8 }, /* ...0...0...1...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...1...0...0 */ + { 0x20,0x00,0xa0,0x80 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...0...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...1...1...0 */ + { 0x08,0x88,0x00,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0x20,0x00,0xa0,0x80 }, /* ...1...0...0...0 */ + { 0x80,0xa0,0x88,0xa8 }, { 0x20,0x00,0xa0,0x80 }, /* ...1...0...0...1 */ + { 0x80,0xa0,0x88,0xa8 }, { 0x80,0xa0,0x88,0xa8 }, /* ...1...0...1...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x80,0xa0,0x88,0xa8 }, /* ...1...0...1...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...0...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x08,0x88,0x00,0x80 }, /* ...1...1...0...1 */ + { 0x88,0x80,0x08,0x00 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...1...1...0 */ + { 0x88,0x80,0x08,0x00 }, { 0xa8,0xa0,0x88,0x80 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_5155_device::sega_315_5155_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5155, tag, owner, clock) {} +void sega_315_5155_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x20,0x28,0x00,0x08 }, { 0x80,0x00,0xa0,0x20 }, /* ...0...0...0...0 */ + { 0x20,0x28,0x00,0x08 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...0...0...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...1 */ + { 0x20,0x28,0x00,0x08 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...0...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...1...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0x80,0x00,0xa0,0x20 }, /* ...1...0...0...0 */ + { 0xa0,0x20,0xa8,0x28 }, { 0xa0,0xa8,0x20,0x28 }, /* ...1...0...0...1 */ + { 0xa0,0x20,0xa8,0x28 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...1...0 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...1...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0x20,0x28,0x00,0x08 }, /* ...1...1...0...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0x20,0xa8,0x28 }, /* ...1...1...0...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...1...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0x20,0xa8,0x28 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_5110_device::sega_315_5110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5110, tag, owner, clock) {} +void sega_315_5110_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0x08,0x80,0x00 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...0...0...0 */ + { 0x00,0x20,0x80,0xa0 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...0...1 */ + { 0x88,0x08,0xa8,0x28 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...0...1...0 */ + { 0x00,0x20,0x80,0xa0 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...0...1...1 */ + { 0x00,0x20,0x80,0xa0 }, { 0x08,0x00,0x88,0x80 }, /* ...0...1...0...0 */ + { 0x00,0x20,0x80,0xa0 }, { 0x20,0x28,0xa0,0xa8 }, /* ...0...1...0...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...1...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...1...1...1 */ + { 0x88,0x08,0x80,0x00 }, { 0x08,0x00,0x88,0x80 }, /* ...1...0...0...0 */ + { 0x08,0x00,0x88,0x80 }, { 0x88,0x08,0x80,0x00 }, /* ...1...0...0...1 */ + { 0x08,0x28,0x00,0x20 }, { 0x08,0x28,0x00,0x20 }, /* ...1...0...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x08,0x28,0x00,0x20 }, /* ...1...0...1...1 */ + { 0x08,0x28,0x00,0x20 }, { 0x08,0x00,0x88,0x80 }, /* ...1...1...0...0 */ + { 0x08,0x28,0x00,0x20 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...1...0...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x08,0x28,0x00,0x20 }, /* ...1...1...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x08,0x28,0x00,0x20 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5135_device::sega_315_5135_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5135, tag, owner, clock) {} +void sega_315_5135_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...1...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...1...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...1...1 */ + { 0xa0,0x20,0xa8,0x28 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...0...0 */ + { 0xa0,0x20,0xa8,0x28 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...0...1 */ + { 0xa0,0x20,0xa8,0x28 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa0,0x20,0xa8,0x28 }, /* ...1...1...0...0 */ + { 0xa0,0x20,0xa8,0x28 }, { 0x28,0xa8,0x08,0x88 }, /* ...1...1...0...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa0,0x20,0xa8,0x28 }, /* ...1...1...1...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0xa8,0x08,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_5051_device::sega_315_5051_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5051, tag, owner, clock) {} +void sega_315_5051_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x08,0x88,0x00,0x80 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0x08,0x20,0x00 }, /* ...0...0...1...0 */ + { 0x28,0x08,0x20,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...1 */ + { 0x08,0x88,0x00,0x80 }, { 0x80,0x00,0xa0,0x20 }, /* ...0...1...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...1 */ + { 0x28,0x08,0x20,0x00 }, { 0x28,0x08,0x20,0x00 }, /* ...0...1...1...0 */ + { 0x28,0x08,0x20,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...1...1 */ + { 0x08,0x88,0x00,0x80 }, { 0xa8,0x88,0x28,0x08 }, /* ...1...0...0...0 */ + { 0xa8,0x88,0x28,0x08 }, { 0x80,0x00,0xa0,0x20 }, /* ...1...0...0...1 */ + { 0x28,0x08,0x20,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...1...0 */ + { 0xa8,0x88,0x28,0x08 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...1...1 */ + { 0x08,0x88,0x00,0x80 }, { 0x80,0x00,0xa0,0x20 }, /* ...1...1...0...0 */ + { 0xa8,0x88,0x28,0x08 }, { 0x80,0x00,0xa0,0x20 }, /* ...1...1...0...1 */ + { 0x28,0x08,0x20,0x00 }, { 0x28,0x08,0x20,0x00 }, /* ...1...1...1...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x88,0x80,0x08,0x00 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5098_device::sega_315_5098_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5098, tag, owner, clock) {} +void sega_315_5098_device::decrypt() +{ + // also 315-5030 ? + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x08,0x88,0x00,0x80 }, { 0xa0,0x20,0x80,0x00 }, /* ...0...0...0...0 */ + { 0xa8,0xa0,0x28,0x20 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...0...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...0...1...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x20,0x80,0x00 }, /* ...0...1...0...0 */ + { 0xa8,0xa0,0x28,0x20 }, { 0xa8,0xa0,0x28,0x20 }, /* ...0...1...0...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...1...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...1...1...1 */ + { 0xa0,0x20,0x80,0x00 }, { 0xa0,0x20,0x80,0x00 }, /* ...1...0...0...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...0...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...1...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...1...0...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...1...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x28,0x08,0xa8,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_5102_device::sega_315_5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5102, tag, owner, clock) {} +void sega_315_5102_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...0...0...1 */ + { 0xa8,0xa0,0x28,0x20 }, { 0xa8,0xa0,0x28,0x20 }, /* ...0...0...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...0...1...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x08,0x80,0x00 }, /* ...0...1...0...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x28,0x20 }, /* ...0...1...1...1 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...0...0 */ + { 0xa0,0xa8,0x80,0x88 }, { 0x28,0xa8,0x08,0x88 }, /* ...1...0...0...1 */ + { 0xa8,0xa0,0x28,0x20 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...1...0 */ + { 0xa8,0xa0,0x28,0x20 }, { 0x28,0xa8,0x08,0x88 }, /* ...1...0...1...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...1...0...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...1...0...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...1...1...0 */ + { 0xa8,0xa0,0x28,0x20 }, { 0x28,0x08,0xa8,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5065_device::sega_315_5065_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5065, tag, owner, clock) {} +void sega_315_5065_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0xa0,0xa8,0x20,0x28 }, { 0x80,0xa0,0x00,0x20 }, /* ...0...0...0...0 */ + { 0x20,0x28,0x00,0x08 }, { 0x20,0x28,0x00,0x08 }, /* ...0...0...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x08,0x28,0x00,0x20 }, /* ...0...0...1...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...0...1...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x20,0x28,0x00,0x08 }, /* ...0...1...0...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x20,0x28,0x00,0x08 }, /* ...0...1...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x08,0x28,0x00,0x20 }, /* ...0...1...1...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x20,0xa0 }, { 0xa0,0xa8,0x20,0x28 }, /* ...1...0...0...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...0...1 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x08,0x28,0x00,0x20 }, /* ...1...0...1...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...1...1 */ + { 0x20,0x28,0x00,0x08 }, { 0x20,0x28,0x00,0x08 }, /* ...1...1...0...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x20,0x28,0x00,0x08 }, /* ...1...1...0...1 */ + { 0x08,0x28,0x00,0x20 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...1...1...0 */ + { 0x08,0x28,0x00,0x20 }, { 0x88,0x08,0xa8,0x28 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5064_device::sega_315_5064_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5064, tag, owner, clock) {} +void sega_315_5064_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...0...0...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...0...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0x20,0x28,0xa0,0xa8 }, /* ...0...0...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...0...1...1 */ + { 0xa8,0x28,0x88,0x08 }, { 0xa8,0x28,0x88,0x08 }, /* ...0...1...0...0 */ + { 0x08,0x88,0x00,0x80 }, { 0xa8,0x28,0x88,0x08 }, /* ...0...1...0...1 */ + { 0xa8,0x28,0x88,0x08 }, { 0x20,0x28,0xa0,0xa8 }, /* ...0...1...1...0 */ + { 0xa8,0x28,0x88,0x08 }, { 0xa8,0x28,0x88,0x08 }, /* ...0...1...1...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...0...0...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...0...1...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...1...0...0 */ + { 0xa8,0x28,0x88,0x08 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...1...1...0 */ + { 0xa8,0x28,0x88,0x08 }, { 0xa8,0x28,0x88,0x08 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5033_device::sega_315_5033_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5033, tag, owner, clock) {} +void sega_315_5033_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x28,0x08,0xa8,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...0...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...1...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...1 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...0...1...1...0 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...1...1...1 */ + { 0x80,0xa0,0x00,0x20 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...0...1 */ + { 0x80,0xa0,0x00,0x20 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...1...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...1...0...0 */ + { 0x80,0xa0,0x00,0x20 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...1...1...0 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5041_device::sega_315_5041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5041, tag, owner, clock) {} +void sega_315_5041_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...1...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...0...1...1...0 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...1...1...1 */ + { 0x88,0x80,0x08,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...0...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...1...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...1...0...1...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...1...1...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0xa8,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5048_device::sega_315_5048_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5048, tag, owner, clock) {} +sega_315_5048_device::sega_315_5048_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, type, tag, owner, clock) {} +void sega_315_5048_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...0...0...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...1...0 */ + { 0xa0,0xa8,0x80,0x88 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...1...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...1...1...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa0,0xa8,0x80,0x88 }, /* ...0...1...1...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...0...0 */ + { 0xa0,0x20,0x80,0x00 }, { 0x88,0xa8,0x80,0xa0 }, /* ...1...0...0...1 */ + { 0xa0,0x20,0x80,0x00 }, { 0xa0,0x20,0x80,0x00 }, /* ...1...0...1...0 */ + { 0xa0,0x20,0x80,0x00 }, { 0xa0,0x20,0x80,0x00 }, /* ...1...0...1...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...1...0...1 */ + { 0xa0,0xa8,0x80,0x88 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...1...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa0,0xa8,0x80,0x88 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5093_device::sega_315_5093_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5093, tag, owner, clock) {} +void sega_315_5093_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...0...0 */ + { 0x08,0x88,0x28,0xa8 }, { 0x28,0xa8,0x20,0xa0 }, /* ...0...0...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...0...1...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0x20,0x00,0xa0,0x80 }, /* ...0...1...0...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x20,0x00,0xa0,0x80 }, /* ...0...1...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...1...1...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...1...1...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...0...0...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...0...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...1...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x28,0xa8,0x20,0xa0 }, /* ...1...0...1...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...1...0...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x20,0x00,0xa0,0x80 }, /* ...1...1...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...1...1...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x28,0xa8,0x20,0xa0 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5099_device::sega_315_5099_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5099, tag, owner, clock) {} +void sega_315_5099_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0xa0,0xa8,0x20,0x28 }, { 0x80,0xa0,0x00,0x20 }, /* ...0...0...0...0 */ + { 0x20,0x28,0x00,0x08 }, { 0x20,0x28,0x00,0x08 }, /* ...0...0...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x08,0x28,0x00,0x20 }, /* ...0...0...1...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...0...1...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x20,0x28,0x00,0x08 }, /* ...0...1...0...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x20,0x28,0x00,0x08 }, /* ...0...1...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x08,0x28,0x00,0x20 }, /* ...0...1...1...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x88,0x08,0xa8,0x28 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x20,0xa0 }, { 0xa0,0xa8,0x20,0x28 }, /* ...1...0...0...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...0...1 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x08,0x28,0x00,0x20 }, /* ...1...0...1...0 */ + { 0x28,0xa8,0x20,0xa0 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...0...1...1 */ + { 0x20,0x28,0x00,0x08 }, { 0x20,0x28,0x00,0x08 }, /* ...1...1...0...0 */ + { 0x88,0x08,0xa8,0x28 }, { 0x20,0x28,0x00,0x08 }, /* ...1...1...0...1 */ + { 0x08,0x28,0x00,0x20 }, { 0x80,0xa0,0x00,0x20 }, /* ...1...1...1...0 */ + { 0x08,0x28,0x00,0x20 }, { 0x88,0x08,0xa8,0x28 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_spat_device::sega_315_spat_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_SPAT, tag, owner, clock) {} +void sega_315_spat_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0x08,0x80,0x00 }, { 0x00,0x08,0x20,0x28 }, /* ...0...0...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...0...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...0...0...1...1 */ + { 0x00,0x08,0x20,0x28 }, { 0x88,0x08,0x80,0x00 }, /* ...0...1...0...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0x80,0x88,0x00,0x08 }, /* ...0...1...0...1 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...1...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0x80,0x88,0x00,0x08 }, /* ...1...0...0...0 */ + { 0x80,0x88,0x00,0x08 }, { 0x00,0x08,0x20,0x28 }, /* ...1...0...0...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x28,0xa8,0x08,0x88 }, /* ...1...0...1...0 */ + { 0x00,0x08,0x20,0x28 }, { 0x80,0xa0,0x88,0xa8 }, /* ...1...0...1...1 */ + { 0x80,0x88,0x00,0x08 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...0 */ + { 0x80,0xa0,0x88,0xa8 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0x80,0xa0,0x88,0xa8 }, /* ...1...1...1...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x00,0x08,0x20,0x28 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + +sega_315_5015_device::sega_315_5015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5015, tag, owner, clock) {} +void sega_315_5015_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...0...0 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...0...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...1 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...1...0...0 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...1...0...1 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...1...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...1...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...0...0...0 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...0...1 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...1...0 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...0...1...1 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...1...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...0...1 */ + { 0x20,0x00,0xa0,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...1...1...0 */ + { 0x88,0x08,0x80,0x00 }, { 0xa0,0x80,0xa8,0x88 } /* ...1...1...1...1 */ + }; + + /* decrypt program ROMs */ + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5133_device::sega_315_5133_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : sega_315_5048_device(mconfig, SEGA_315_5133, tag, owner, clock) {} +// == sega_315_5048_device + + +sega_315_5014_device::sega_315_5014_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5014, tag, owner, clock) {} +void sega_315_5014_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...0...0...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...1...0 */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...1...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...1...0...0 */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...0...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...1...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...0...0...0 */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...0...1 */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...1...1 */ + { 0x80,0x00,0x88,0x08 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...0...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...1...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa8,0xa0,0x88,0x80 } /* ...1...1...1...1 */ + }; + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5013_device::sega_315_5013_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5013, tag, owner, clock) {} +void sega_315_5013_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...0...0 */ + { 0x08,0x28,0x88,0xa8 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...1 */ + { 0xa8,0x28,0xa0,0x20 }, { 0x20,0xa0,0x00,0x80 }, /* ...0...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...1...1 */ + { 0x08,0x28,0x88,0xa8 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...0...1 */ + { 0xa8,0x28,0xa0,0x20 }, { 0x20,0xa0,0x00,0x80 }, /* ...0...1...1...0 */ + { 0x08,0x28,0x88,0xa8 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...1...1 */ + { 0x08,0x28,0x88,0xa8 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...0...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...1...0 */ + { 0xa8,0x28,0xa0,0x20 }, { 0x20,0xa0,0x00,0x80 }, /* ...1...0...1...1 */ + { 0xa8,0x28,0xa0,0x20 }, { 0x20,0xa0,0x00,0x80 }, /* ...1...1...0...0 */ + { 0xa8,0x28,0xa0,0x20 }, { 0x20,0xa0,0x00,0x80 }, /* ...1...1...0...1 */ + { 0x08,0x28,0x88,0xa8 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x28,0x20,0xa8,0xa0 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5061_device::sega_315_5061_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5061, tag, owner, clock) {} +void sega_315_5061_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x28,0x08,0x20,0x00 }, { 0x28,0x08,0x20,0x00 }, /* ...0...0...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x08,0x88,0x00,0x80 }, /* ...0...0...0...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0x08,0x88,0x00,0x80 }, /* ...0...0...1...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0x20,0x28,0xa0,0xa8 }, /* ...0...0...1...1 */ + { 0x28,0x08,0x20,0x00 }, { 0x88,0x80,0xa8,0xa0 }, /* ...0...1...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...0...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0x20,0x28,0xa0,0xa8 }, /* ...0...1...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...1...1 */ + { 0x88,0x80,0xa8,0xa0 }, { 0x28,0x08,0x20,0x00 }, /* ...1...0...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...0...1 */ + { 0x20,0x28,0xa0,0xa8 }, { 0x08,0x88,0x00,0x80 }, /* ...1...0...1...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x20,0x28,0xa0,0xa8 }, /* ...1...0...1...1 */ + { 0x88,0x80,0xa8,0xa0 }, { 0x88,0x80,0xa8,0xa0 }, /* ...1...1...0...0 */ + { 0x80,0x00,0xa0,0x20 }, { 0x08,0x88,0x00,0x80 }, /* ...1...1...0...1 */ + { 0x80,0x00,0xa0,0x20 }, { 0x28,0x08,0x20,0x00 }, /* ...1...1...1...0 */ + { 0x20,0x28,0xa0,0xa8 }, { 0xa0,0x80,0x20,0x00 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + +sega_315_5018_device::sega_315_5018_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5018, tag, owner, clock) {} +void sega_315_5018_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x88,0xa8,0x08,0x28 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...0...0 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...0...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...0...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x20,0xa0,0x28,0xa8 }, /* ...0...0...1...1 */ + { 0x88,0xa8,0x08,0x28 }, { 0x88,0xa8,0x08,0x28 }, /* ...0...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...1...0...1 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x20,0xa0,0x28,0xa8 }, /* ...0...1...1...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x88,0xa8,0x80,0xa0 }, /* ...0...1...1...1 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x88,0xa8,0x08,0x28 }, /* ...1...0...0...0 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...0...1 */ + { 0xa0,0x20,0x80,0x00 }, { 0x20,0xa0,0x28,0xa8 }, /* ...1...0...1...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x20,0xa0,0x28,0xa8 }, /* ...1...0...1...1 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x88,0xa8,0x08,0x28 }, /* ...1...1...0...0 */ + { 0x88,0xa8,0x08,0x28 }, { 0x88,0xa8,0x08,0x28 }, /* ...1...1...0...1 */ + { 0xa0,0x20,0x80,0x00 }, { 0x88,0x08,0x80,0x00 }, /* ...1...1...1...0 */ + { 0x20,0xa0,0x28,0xa8 }, { 0x00,0x08,0x20,0x28 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); + +} + + +sega_315_5010_device::sega_315_5010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5010, tag, owner, clock) {} +void sega_315_5010_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0xa0,0x80,0xa8,0x88 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...0...1...0 */ + { 0x08,0x28,0x88,0xa8 }, { 0xa0,0x80,0xa8,0x88 }, /* ...0...0...1...1 */ + { 0x08,0x00,0x88,0x80 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...1...0...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0x08,0x00,0x88,0x80 }, /* ...0...1...0...1 */ + { 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...0...1...1...0 */ + { 0xa0,0x80,0x20,0x00 }, { 0x00,0x08,0x20,0x28 }, /* ...0...1...1...1 */ + { 0x88,0x80,0x08,0x00 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...0...0 */ + { 0x88,0x80,0x08,0x00 }, { 0x00,0x08,0x20,0x28 }, /* ...1...0...0...1 */ + { 0x08,0x28,0x88,0xa8 }, { 0x08,0x28,0x88,0xa8 }, /* ...1...0...1...0 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0x20,0x00 }, /* ...1...0...1...1 */ + { 0x08,0x00,0x88,0x80 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...0...0 */ + { 0x00,0x08,0x20,0x28 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...0...1 */ + { 0x08,0x28,0x88,0xa8 }, { 0x08,0x28,0x88,0xa8 }, /* ...1...1...1...0 */ + { 0x08,0x00,0x88,0x80 }, { 0xa0,0x80,0x20,0x00 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + + + +sega_315_5128_device::sega_315_5128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5128, tag, owner, clock) {} +void sega_315_5128_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0xa8,0xa0,0x88,0x80 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...0...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...0...0...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x28,0xa8,0x08,0x88 }, /* ...0...0...1...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...0...1...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0xa8,0xa0,0x88,0x80 }, /* ...0...1...0...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...0...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...1...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x28,0x20,0xa8,0xa0 }, /* ...0...1...1...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x28,0x20,0xa8,0xa0 }, /* ...1...0...0...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...0...0...1 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa0,0x80,0xa8,0x88 }, /* ...1...0...1...0 */ + { 0x28,0x08,0xa8,0x88 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...0...1...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...1...0...0 */ + { 0x28,0x20,0xa8,0xa0 }, { 0xa8,0x28,0xa0,0x20 }, /* ...1...1...0...1 */ + { 0xa0,0x80,0xa8,0x88 }, { 0xa8,0xa0,0x88,0x80 }, /* ...1...1...1...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0xa8,0x28,0xa0,0x20 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5028_device::sega_315_5028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5028, tag, owner, clock) {} +void sega_315_5028_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...0...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...0...0...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...0...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...0...1...1 */ + { 0xa8,0x88,0xa0,0x80 }, { 0xa0,0x20,0xa8,0x28 }, /* ...0...1...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...0...1...0...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...1...1...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...0...1...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...0...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...1...0...0...1 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...1...0...1...0 */ + { 0xa8,0xa0,0x88,0x80 }, { 0x00,0x20,0x80,0xa0 }, /* ...1...0...1...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...0...0 */ + { 0xa8,0x88,0xa0,0x80 }, { 0xa0,0x20,0xa8,0x28 }, /* ...1...1...0...1 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 }, /* ...1...1...1...0 */ + { 0x28,0xa8,0x08,0x88 }, { 0x88,0x80,0x08,0x00 } /* ...1...1...1...1 */ + }; + + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} + + +sega_315_5084_device::sega_315_5084_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segacrpt_z80_device(mconfig, SEGA_315_5084, tag, owner, clock) {} +void sega_315_5084_device::decrypt() +{ + static const uint8_t convtable[32][4] = + { + /* opcode data address */ + /* A B C D A B C D */ + { 0x28,0x08,0xa8,0x88 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...0...0...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0xa0,0xa8,0x20,0x28 }, /* ...0...0...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x20,0xa0,0x00,0x80 }, /* ...0...0...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x80,0x88,0xa0,0xa8 }, /* ...0...0...1...1 */ + { 0x08,0x88,0x00,0x80 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...0...0 */ + { 0x88,0xa8,0x80,0xa0 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...0...1 */ + { 0x20,0xa0,0x00,0x80 }, { 0x20,0xa0,0x00,0x80 }, /* ...0...1...1...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x08,0x88,0x00,0x80 }, /* ...0...1...1...1 */ + { 0x88,0xa8,0x80,0xa0 }, { 0xa0,0xa8,0x20,0x28 }, /* ...1...0...0...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...0...0...1 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x20,0xa0,0x00,0x80 }, /* ...1...0...1...0 */ + { 0xa0,0xa8,0x20,0x28 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...0...1...1 */ + { 0x08,0x88,0x00,0x80 }, { 0x28,0x08,0xa8,0x88 }, /* ...1...1...0...0 */ + { 0x08,0x88,0x00,0x80 }, { 0x80,0x88,0xa0,0xa8 }, /* ...1...1...0...1 */ + { 0x28,0x08,0xa8,0x88 }, { 0x20,0xa0,0x00,0x80 }, /* ...1...1...1...0 */ + { 0x80,0x88,0xa0,0xa8 }, { 0x08,0x88,0x00,0x80 } /* ...1...1...1...1 */ + }; + decode(m_region_ptr, m_decrypted_ptr, m_decode_size, convtable, m_numbanks, m_banksize); +} diff --git a/src/devices/machine/segacrpt_device.h b/src/devices/machine/segacrpt_device.h new file mode 100644 index 00000000000..63b50bde2d0 --- /dev/null +++ b/src/devices/machine/segacrpt_device.h @@ -0,0 +1,279 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_MACHINE_SEGACRYPT_DEVICE_H +#define MAME_MACHINE_SEGACRYPT_DEVICE_H + +#pragma once + +#include "cpu/z80/z80.h" + + +// base class +class segacrpt_z80_device : public z80_device +{ +public: + void set_decrypted_tag(const char* decrypted_tag) { m_decrypted_tag = decrypted_tag; } + void set_size(int size) { m_decode_size = size; } + void set_numbanks(int numbanks) { m_numbanks = numbanks; } + void set_banksize(int banksize) { m_banksize = banksize; } + + void set_decrypted_p(uint8_t* ptr); + void set_region_p(uint8_t* ptr); + +protected: + segacrpt_z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_reset() override; + virtual void decrypt() = 0; + + const char* m_decrypted_tag = nullptr; + uint8_t* m_decrypted_ptr; + uint8_t* m_region_ptr; + int m_decode_size; + int m_numbanks; + int m_banksize; + +private: + bool m_decryption_done; +}; + + +// actual encrypted CPUs +class sega_315_5132_device : public segacrpt_z80_device +{ +public: + sega_315_5132_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5155_device : public segacrpt_z80_device +{ +public: + sega_315_5155_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5110_device : public segacrpt_z80_device +{ +public: + sega_315_5110_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5135_device : public segacrpt_z80_device +{ +public: + sega_315_5135_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5051_device : public segacrpt_z80_device +{ +public: + sega_315_5051_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5098_device : public segacrpt_z80_device +{ +public: + sega_315_5098_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5102_device : public segacrpt_z80_device +{ +public: + sega_315_5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5065_device : public segacrpt_z80_device +{ +public: + sega_315_5065_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_315_5064_device : public segacrpt_z80_device +{ +public: + sega_315_5064_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_315_5033_device : public segacrpt_z80_device +{ +public: + sega_315_5033_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5041_device : public segacrpt_z80_device +{ +public: + sega_315_5041_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5048_device : public segacrpt_z80_device +{ +public: + sega_315_5048_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); + sega_315_5048_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void decrypt() override; +}; + +class sega_315_5093_device : public segacrpt_z80_device +{ +public: + sega_315_5093_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5099_device : public segacrpt_z80_device +{ +public: + sega_315_5099_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_spat_device : public segacrpt_z80_device +{ +public: + sega_315_spat_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5015_device : public segacrpt_z80_device +{ +public: + sega_315_5015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +class sega_315_5133_device : public sega_315_5048_device +{ +public: + sega_315_5133_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +}; + +class sega_315_5014_device : public segacrpt_z80_device +{ +public: + sega_315_5014_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5013_device : public segacrpt_z80_device +{ +public: + sega_315_5013_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5061_device : public segacrpt_z80_device +{ +public: + sega_315_5061_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + + +class sega_315_5018_device : public segacrpt_z80_device +{ +public: + sega_315_5018_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5010_device : public segacrpt_z80_device +{ +public: + sega_315_5010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + + +class sega_315_5128_device : public segacrpt_z80_device +{ +public: + sega_315_5128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5028_device : public segacrpt_z80_device +{ +public: + sega_315_5028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + +class sega_315_5084_device : public segacrpt_z80_device +{ +public: + sega_315_5084_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t); +protected: + virtual void decrypt() override; +}; + + +DECLARE_DEVICE_TYPE(SEGA_315_5132, sega_315_5132_device) +DECLARE_DEVICE_TYPE(SEGA_315_5155, sega_315_5155_device) +DECLARE_DEVICE_TYPE(SEGA_315_5110, sega_315_5110_device) +DECLARE_DEVICE_TYPE(SEGA_315_5135, sega_315_5135_device) +DECLARE_DEVICE_TYPE(SEGA_315_5051, sega_315_5051_device) +DECLARE_DEVICE_TYPE(SEGA_315_5098, sega_315_5098_device) +DECLARE_DEVICE_TYPE(SEGA_315_5102, sega_315_5102_device) +DECLARE_DEVICE_TYPE(SEGA_315_5065, sega_315_5065_device) +DECLARE_DEVICE_TYPE(SEGA_315_5064, sega_315_5064_device) +DECLARE_DEVICE_TYPE(SEGA_315_5033, sega_315_5033_device) +DECLARE_DEVICE_TYPE(SEGA_315_5041, sega_315_5041_device) +DECLARE_DEVICE_TYPE(SEGA_315_5048, sega_315_5048_device) +DECLARE_DEVICE_TYPE(SEGA_315_5093, sega_315_5093_device) +DECLARE_DEVICE_TYPE(SEGA_315_5099, sega_315_5099_device) +DECLARE_DEVICE_TYPE(SEGA_315_SPAT, sega_315_spat_device) +DECLARE_DEVICE_TYPE(SEGA_315_5015, sega_315_5015_device) +DECLARE_DEVICE_TYPE(SEGA_315_5133, sega_315_5133_device) +DECLARE_DEVICE_TYPE(SEGA_315_5014, sega_315_5014_device) +DECLARE_DEVICE_TYPE(SEGA_315_5013, sega_315_5013_device) +DECLARE_DEVICE_TYPE(SEGA_315_5061, sega_315_5061_device) +DECLARE_DEVICE_TYPE(SEGA_315_5018, sega_315_5018_device) +DECLARE_DEVICE_TYPE(SEGA_315_5010, sega_315_5010_device) +DECLARE_DEVICE_TYPE(SEGA_315_5128, sega_315_5128_device) +DECLARE_DEVICE_TYPE(SEGA_315_5028, sega_315_5028_device) +DECLARE_DEVICE_TYPE(SEGA_315_5084, sega_315_5084_device) + + +#endif // MAME_MACHINE_SEGACRYPT_DEVICE_H |