summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine
diff options
context:
space:
mode:
author Luca Elia <lucaelia@mamedev.org>2022-06-11 19:08:01 +0200
committer GitHub <noreply@github.com>2022-06-12 03:08:01 +1000
commit219d63bada37a4d2e9f4b00d12371b96dc070b05 (patch)
treeba75175bd2f76a33ca38117cf7a5a2e4173be9a3 /src/mame/machine
parente22c74806140472ee5622a7b54c0b9da0d6d0091 (diff)
igs017.cpp, igs022.cpp: Improved protection and decryption; ,oved protection data to external files. (#9890)
* igs017.cpp: Improved protection and decryption [Luca Elia] - Implemented "magic" i/o as a memory map (IGS_MUX) for added flexibility - Hooked up IGS_INCDEC protection to cpoker2, tarzanc, spkrform, starzan - Implemented specific IGS_INC protection in cpoker2 - Hooked up improved IGS022 protection to lhzb2, sqlz2 - Added IGS025 string protection to lhzb2, lhzb2a, mgcs, spkrform, slqz2, starzan, tarzanc, tjsb - Palette scramble and tweaked tiles decryption in tarzanc (used also by starzan, happyskl, cpoker2) - Decrypted sprites in tarzanc and starzan (used also by happyskl) - Lamps and layout for starzan, happyskl, cpoker2 - Cleaned up/finished hopper emulation, added diplocations - Joystick inputs in mgcs - Finished inputs in spkrform. Allow hiding gambling (switching to Formosa and back) - Moved protection data to external files * igs022.cpp: Fixes for igs017.cpp games [Luca Elia, RockyWall] - Fixed initial auto-DMA mode - Enlarged internal RAM. Added stack - Fixed command 12: Copy -> Stack Push - Added command 45: Stack Pop - Fixed command 6d opcode 1: Add Imm -> Sub Values - Added command 6d opcode 0: Add Values - Extended logging Machines promoted to working ---------------------------- Tarzan Chuang Tian Guan (China, V109C, set 1) [Luca Elia, iq_132, Ivan Vangelista, Guru, Dyq, bnathan] Super Tarzan (Italy, V100I) [Luca Elia, iq_132, Ivan Vangelista, f205v, Mirko Buffoni] Happy Skill (Italy, V611IT) [Luca Elia, Ivan Vangelista, Caius, The Dumping Union] Champion Poker 2 (V100A) [Luca Elia, Ivan Vangelista, Jorge Silva, Fernando Oliveira] Long Hu Zhengba 2 (China, set 1) [Luca Elia, RockyWall, David Haywood, iq_132, Pierpaolo Prazzoli, XingXing] Shuang Long Qiang Zhu 2 VS (China, VS203J) [Luca Elia, RockyWall, David Haywood, iq_132, Pierpaolo Prazzoli, XingXing] Clones promoted to working -------------------------- Super Poker (V100xD03) / Formosa [Luca Elia, ANY]
Diffstat (limited to 'src/mame/machine')
-rw-r--r--src/mame/machine/igs022.cpp440
-rw-r--r--src/mame/machine/igs022.h27
-rw-r--r--src/mame/machine/pgmprot_igs025_igs022.cpp21
3 files changed, 317 insertions, 171 deletions
diff --git a/src/mame/machine/igs022.cpp b/src/mame/machine/igs022.cpp
index 0fabcd00383..d6adb617ea8 100644
--- a/src/mame/machine/igs022.cpp
+++ b/src/mame/machine/igs022.cpp
@@ -1,17 +1,23 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, ElSemi
-/*
+/************************************************************************************************************
- IGS022 is an encrypted DMA device, most likely an MCU of some sort
- it can safely be swapped between games so doesn't appear to have
- any kind of game specific programming
+ IGS022 is an encrypted DMA device, most likely an MCU of some sort.
+ It can safely be swapped between games, so doesn't appear to have any kind of game specific programming.
-*/
+************************************************************************************************************/
#include "emu.h"
#include "igs022.h"
+#include <sstream>
-#include <algorithm>
+#define LOG_DMA (1U << 1)
+#define LOG_STACK (1U << 2)
+#define LOG_CMD_6D (1U << 3)
+
+//#define VERBOSE (LOG_GENERAL | LOG_DMA | LOG_STACK | LOG_CMD_6D)
+#define VERBOSE (0)
+#include "logmacro.h"
igs022_device::igs022_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, IGS022, tag, owner, clock)
@@ -22,76 +28,105 @@ igs022_device::igs022_device(const machine_config &mconfig, const char *tag, dev
void igs022_device::device_start()
{
- // Reset stuff
- std::fill(std::begin(m_kb_regs), std::end(m_kb_regs), 0);
-
- save_item(NAME(m_kb_regs));
+ save_item(NAME(m_regs));
+ save_item(NAME(m_stack));
+ save_item(NAME(m_stack_ptr));
}
void igs022_device::device_reset()
{
- //printf("igs022_device::device_reset()");
-
if (!m_sharedprotram)
- {
- logerror("m_sharedprotram was not set\n");
- return;
- }
- IGS022_reset();
+ fatalerror("%s: IGS022 sharedprotram was not set!\n", machine().describe_context());
- std::fill(std::begin(m_kb_regs), std::end(m_kb_regs), 0);
-}
+ // the internal MCU boot code automatically does this DMA
+ // and puts the version # of the data rom in ram
+ // reset regs and stack
+ std::fill(std::begin(m_regs), std::end(m_regs), 0);
+ std::fill(std::begin(m_stack), std::end(m_stack), 0);
+ m_stack_ptr = 0;
-void igs022_device::IGS022_do_dma(u16 src, u16 dst, u16 size, u16 mode)
-{
- //printf("igs022_device::IGS022_do_dma\n");
+ // fill ram with 0xa55a pattern
+ for (int i = 0; i < 0x4000 / 2; i++)
+ m_sharedprotram[i] = 0xa55a;
- /*
- P_SRC =0x300290 (offset from prot rom base)
- P_DST =0x300292 (words from 0x300000)
- P_SIZE=0x300294 (words)
- P_MODE=0x300296
+ // the initial auto-DMA
+ const u16 * const PROTROM = (u16 *)m_rom->base();
+
+ u16 src = PROTROM[0x100 / 2];
+ const u32 dst = PROTROM[0x102 / 2];
+ const u16 size = PROTROM[0x104 / 2];
+ u16 mode = PROTROM[0x106 / 2];
- Mode 5 direct
- Mode 6 swap nibbles and bytes
+ mode = (mode >> 8) | (mode << 8);
+
+ src >>= 1;
- 1,2,3 table based ops
+ do_dma(src, dst, size, mode);
+
+ // there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied..
+ // Dragon World 3 checks it
+ // Setting 0x3002a0 to #3 causes Dragon World 3 to skip this check
+ m_sharedprotram[0x2a2 / 2] = PROTROM[0x114 / 2];
+}
+
+// From IGS022 ROM to shared protection RAM
+void igs022_device::do_dma(u16 src, u16 dst, u16 size, u16 mode)
+{
+ LOGMASKED(LOG_DMA, "%s: IGS022 DMA src %04x, dst %04x, size %04x, mode %04x\n", machine().describe_context(), src, dst, size, mode);
+
+ /*
+ P_SRC = 0x300290 (offset from prot rom base)
+ P_DST = 0x300292 (words from 0x300000)
+ P_SIZE = 0x300294 (words)
+ P_MODE = 0x300296
+
+ Mode 0 plain copy
+ Mode 1,2,3 rom table based ops
+ Mode 4 fixed data ('IGS ') based ops
+ Mode 5 swap bytes
+ Mode 6 swap nibbles
*/
const u16 param = mode >> 8;
- // the initial DMA on kilbld has 0x10 set, drgw3 has 0x18 set, not sure how they affect the operation.
- if (mode & 0x00f8) printf("IGS022_do_dma mode bits %04x set\n", mode & 0x00f8);
+ // the initial auto-DMA on killbld/slqz2/lhzb2 has 0x10 set, drgw3 has 0x18 set, not sure how they affect the operation.
+ if (mode & 0x00f8)
+ logerror("%s: IGS022 unknown DMA mode bits %04x set\n", machine().describe_context(), mode & 0x00f8);
- mode &= 0x7; // what are the other bits?
+ mode &= 0x7; // what are the other bits?
- if ((mode == 0) || (mode == 1) || (mode == 2) || (mode == 3) || (mode == 4))
- {
- /* mode3 applies a xor from a 0x100 byte table to the data being
- transferred
+ const u16 * const PROTROM = (u16 *)m_rom->base();
- the table is stored at the start of the protection rom.
+ switch (mode)
+ {
+ case 0: case 1: case 2: case 3: case 4:
+ /*
+ modes 1-3 modify the data being transferred using a 0x100 byte table stored at the start of the protection rom.
- the param used with the mode gives a start offset into the table
+ The param used with the mode gives a start offset into the table.
- odd offsets cause an overflow
+ Odd offsets cause an overflow.
*/
-
- const u16 *PROTROM = (u16*)m_rom->base();
-
for (int x = 0; x < size; x++)
{
- u16 dat2 = PROTROM[src + x];
+ u16 dat = PROTROM[src + x];
+
+ const u8 extraoffset = param & 0xff;
+ const u8 * const dectable = (u8 *)m_rom->base(); // the basic decryption table is at the start of the mcu data rom!
+ const u8 taboff = ((x * 2) + extraoffset) & 0xff; // must allow for overflow in instances of odd offsets
- const u8 extraoffset = param & 0xff;
- const u8* dectable = (u8*)m_rom->base(); // the basic decryption table is at the start of the mcu data rom!
- const u8 taboff = ((x * 2) + extraoffset) & 0xff; // must allow for overflow in instances of odd offsets
- u16 extraxor = ((dectable[taboff + 1]) << 8) | (dectable[taboff + 0] << 0);
+ u16 extraxor = ((dectable[taboff + 1]) << 8) | (dectable[taboff + 0] << 0);
- if (mode == 4)
+ switch (mode)
{
+// case 0: plain copy
+ case 1: dat -= extraxor; break;
+ case 2: dat += extraxor; break;
+ case 3: dat ^= extraxor; break;
+ case 4:
extraxor = 0;
+
if ((x & 0x003) == 0x000) extraxor |= 0x0049; // 'I'
if ((x & 0x003) == 0x001) extraxor |= 0x0047; // 'G'
if ((x & 0x003) == 0x002) extraxor |= 0x0053; // 'S'
@@ -101,166 +136,273 @@ void igs022_device::IGS022_do_dma(u16 src, u16 dst, u16 size, u16 mode)
if ((x & 0x300) == 0x100) extraxor |= 0x4700; // 'G'
if ((x & 0x300) == 0x200) extraxor |= 0x5300; // 'S'
if ((x & 0x300) == 0x300) extraxor |= 0x2000; // ' '
- }
-
- // mode == 0 plain
- if (mode == 3) dat2 ^= extraxor;
- if (mode == 2) dat2 += extraxor;
- if (mode == 1) dat2 -= extraxor;
- if (mode == 4)
- {
- //printf("%06x | %04x (%04x)\n", (dst+x)*2, dat2, (u16)(dat2-extraxor));
+ LOGMASKED(LOG_DMA, "%s: IGS022 DMA mode 4 -> %06x | %04x (%04x)\n", machine().describe_context(), (dst + x) * 2, dat, (u16)(dat - extraxor));
- dat2 -= extraxor;
+ dat -= extraxor;
+ break;
}
- m_sharedprotram[dst + x] = dat2;
+ m_sharedprotram[dst + x] = dat;
}
- }
- else if (mode == 5)
- {
- /* mode 5 seems to be a byteswapped copy */
- const u16 *PROTROM = (u16*)m_rom->base();
+ break;
+
+ case 5: // byteswapped copy
for (int x = 0; x < size; x++)
{
u16 dat = PROTROM[src + x];
+
dat = ((dat &0x00ff) << 8) | ((dat &0xff00) >> 8);
m_sharedprotram[dst + x] = dat;
}
- }
- else if (mode == 6)
- {
- /* mode 6 seems to be a nibble swapped copy */
- const u16 *PROTROM = (u16*)m_rom->base();
+ break;
+
+ case 6: // nibble swapped copy
for (int x = 0; x < size; x++)
{
u16 dat = PROTROM[src + x];
- dat = ((dat & 0xf0f0) >> 4)|
- ((dat & 0x0f0f) << 4);
+ dat = ((dat & 0xf0f0) >> 4) | ((dat & 0x0f0f) << 4);
m_sharedprotram[dst + x] = dat;
}
+ break;
+
+ case 7:
+ logerror("%s: IGS022 DMA unhandled copy mode %04x!\n", machine().describe_context(), mode);
+ // not used by killbld
+ // weird mode, the params get left in memory? - maybe it's a NOP?
+ break;
+
+ default:
+ logerror("%s: IGS022 DMA unhandled copy mode!: %d, src: %04x, dst: %04x, size: %04x, param: %02x\n", machine().describe_context(), mode, src, dst, size, param);
+ // not used by killbld
+ // invalid?
+ }
+}
+
+void igs022_device::push_stack(u32 data)
+{
+ if (m_stack_ptr < STACK_SIZE - 1)
+ ++m_stack_ptr;
+
+ m_stack[m_stack_ptr] = data;
+}
+
+u32 igs022_device::pop_stack()
+{
+ const u32 data = m_stack[m_stack_ptr];
+
+ if (m_stack_ptr > 0)
+ --m_stack_ptr;
+
+ return data;
+}
+
+std::string igs022_device::stack_as_string() const
+{
+ std::ostringstream stream;
+ stream << "stack:";
+
+ for (int i = 0; i <= m_stack_ptr; ++i)
+ util::stream_format(stream, " %08x", m_stack[i]);
+
+ return std::move(stream).str();
+}
+
+u32 igs022_device::read_reg(u16 offset)
+{
+ if (offset < NUM_REGS)
+ {
+ return m_regs[offset];
}
- else if (mode == 7)
+ else if (offset == 0x400)
{
- printf("unhandled copy mode %04x!\n", mode);
- // not used by killing blade
- /* weird mode, the params get left in memory? - maybe it's a NOP? */
+ return pop_stack();
}
else
{
- osd_printf_debug("unhandled copy mode %04x!\n", mode);
- printf ("DMA MODE: %d, src: %4.4x, dst: %4.4x, size: %4.4x, param: %2.2x\n", mode, src, dst, size, param);
- // not used by killing blade
- /* invalid? */
+ return 0; // Invalid!
}
}
-// the internal MCU boot code automatically does this DMA
-// and puts the version # of the data rom in ram
-void igs022_device::IGS022_reset()
+void igs022_device::write_reg(u16 offset, u32 data)
{
- const u16 *PROTROM = (u16*)m_rom->base();
+ if (offset < NUM_REGS)
+ {
+ m_regs[offset] = data;
+ }
+ else if (offset == 0x300)
+ {
+ push_stack(data);
+ }
+ else
+ {
+ // Invalid!
+ }
+}
- // fill ram with A5 patern
- for (int i = 0; i < 0x4000/2; i++)
- m_sharedprotram[i] = 0xa55a;
+// What does this do? write the completion byte for now...
+void igs022_device::handle_incomplete_command(u16 cmd, u16 res)
+{
+ logerror("%s: IGS022 command %04x: INCOMPLETE (NOP)\n", machine().describe_context(), cmd);
+ m_sharedprotram[0x202 / 2] = res;
+}
- // the auto-dma
- u16 src = PROTROM[0x100 / 2];
- const u32 dst = PROTROM[0x102 / 2];
- const u16 size = PROTROM[0x104 / 2];
- u16 mode = PROTROM[0x106 / 2];
+void igs022_device::handle_command()
+{
+ const u16 cmd = m_sharedprotram[0x200 / 2];
- mode &= 0xff;
+ switch (cmd)
+ {
+ case 0x12: // Push
+ {
+ const u32 data = (m_sharedprotram[0x288 / 2] << 16) + m_sharedprotram[0x28a / 2];
- src >>= 1;
+ push_stack(data);
- IGS022_do_dma(src,dst,size,mode);
+ LOGMASKED(LOG_STACK, "%s: IGS022 command %04x: PUSH {288, 28a} (%08x) %s\n", machine().describe_context(), cmd, data, stack_as_string());
- // there is also a version ID? (or is it some kind of checksum) that is stored in the data rom, and gets copied..
- // Dragon World 3 checks it
- // Setting $3002a0 to #3 causes Dragon World 3 to skip this check
- m_sharedprotram[0x2a2/2] = PROTROM[0x114/2];
-}
+ m_sharedprotram[0x202 / 2] = 0x23; // this mode complete?
+ break;
+ }
-void igs022_device::IGS022_handle_command()
-{
- //printf("igs022_device::IGS022_handle_command\n");
+ case 0x2d: handle_incomplete_command(cmd, 0x3c); break; // killbld
- const u16 cmd = m_sharedprotram[0x200/2];
+// case 0x42: break; // killbld
- if (cmd == 0x6d) // Store values to asic ram
- {
- const u32 p1 = (m_sharedprotram[0x298/2] << 16) | m_sharedprotram[0x29a/2];
- const u32 p2 = (m_sharedprotram[0x29c/2] << 16) | m_sharedprotram[0x29e/2];
+ case 0x45: // Pop
+ {
+ const u32 data = pop_stack();
+
+ m_sharedprotram[0x28c / 2] = (data >> 16) & 0xffff;
+ m_sharedprotram[0x28e / 2] = data & 0xffff;
+
+ LOGMASKED(LOG_STACK, "%s: IGS022 command %04x: POP {28c, 28e} (%08x) %s\n", machine().describe_context(), cmd, data, stack_as_string());
+
+ m_sharedprotram[0x202 / 2] = 0x56; // this mode complete?
+ break;
+ }
- if ((p2 & 0xffff) == 0x9) // Set value
+// case 0x47: // NOP? slqz2/lhzb2
+// break;
+
+ case 0x4f: // DMA from protection ROM (memcpy with encryption / scrambling)
{
- const int reg = (p2 >> 16) & 0xffff;
+ LOGMASKED(LOG_DMA, "%s: IGS022 command %04x: DMA\n", machine().describe_context(), cmd);
- if (reg & 0x300) { // 300?? killbld expects 0x200, drgw3 expects 0x100?
- m_kb_regs[reg & 0xff] = p1;
- }
+ const u16 src = m_sharedprotram[0x290 / 2] >> 1; // External mcu data is 8 bit and addressed as such
+ const u32 dst = m_sharedprotram[0x292 / 2];
+ const u16 size = m_sharedprotram[0x294 / 2];
+ const u16 mode = m_sharedprotram[0x296 / 2];
+
+ do_dma(src, dst, size, mode);
+
+ m_sharedprotram[0x202 / 2] = 0x5e; // this mode complete?
+ break;
}
- if ((p2 & 0xffff) == 0x6) // Add value
+ case 0x5a: handle_incomplete_command(cmd, 0x4b); break; // killbld, uses {284} as input
+
+ case 0x6d: // Set/Get values to/from ASIC RAM, arithmetic operations on them
+ handle_command_6d();
+ break;
+
+ default:
+ logerror("%s: IGS022 command %04x: UNKNOWN!\n", machine().describe_context(), cmd);
+ }
+}
+
+// Set/Get values to/from ASIC RAM, arithmetic operations on them
+void igs022_device::handle_command_6d()
+{
+ const u32 p1 = (m_sharedprotram[0x298 / 2] << 16) | m_sharedprotram[0x29a / 2];
+ const u32 p2 = (m_sharedprotram[0x29c / 2] << 16) | m_sharedprotram[0x29e / 2];
+
+ std::ostringstream stream;
+ util::stream_format(stream, "%s: IGS022 command 006d: ASIC RAM %04x %04x %04x %04x ~ ", machine().describe_context(),
+ (p1 >> 16) & 0xffff, (p1 >> 0) & 0xffff, (p2 >> 16) & 0xffff, (p2 >> 0) & 0xffff
+ );
+
+ switch (p2 & 0xffff)
+ {
+ case 0x0: // Add values
{
- const int src1 = (p1 >> 16) & 0xff;
- const int src2 = (p1 >> 0) & 0xff;
- const int dst = (p2 >> 16) & 0xff;
+ const u16 src1 = p1 >> 16;
+ const u16 src2 = p1 >> 0;
+ const u16 dst = p2 >> 16;
+
+ const u32 data1 = read_reg(src1);
+ const u32 data2 = read_reg(src2);
+ const u32 res = data1 + data2;
+
+ write_reg(dst, res);
- m_kb_regs[dst] = m_kb_regs[src2] - m_kb_regs[src1];
+ util::stream_format(stream, "ADD [%04x] = [%04x] + [%04x] (%08x)\n", dst, src1, src2, res);
+ break;
}
- if ((p2 & 0xffff) == 0x1) // Add Imm?
+ case 0x1: // Sub values (src1 - src2)
{
- const int reg = (p2 >> 16) & 0xff;
- const int imm = (p1 >> 0) & 0xffff;
+ const u16 src1 = p1 >> 16;
+ const u16 src2 = p1 >> 0;
+ const u16 dst = p2 >> 16;
- m_kb_regs[reg] += imm;
+ const u32 data1 = read_reg(src1);
+ const u32 data2 = read_reg(src2);
+ const u32 res = data1 - data2;
+
+ write_reg(dst, res);
+
+ util::stream_format(stream, "SUB1 [%04x] = [%04x] - [%04x] (%08x)\n", dst, src1, src2, res);
+ break;
}
- if ((p2 & 0xffff) == 0xa) // Get value
+ case 0x6: // Sub values (src2 - src1)
{
- const int reg = (p1 >> 16) & 0xFF;
+ const u16 src1 = p1 >> 16;
+ const u16 src2 = p1 >> 0;
+ const u16 dst = p2 >> 16;
+
+ const u32 data1 = read_reg(src1);
+ const u32 data2 = read_reg(src2);
+ const u32 res = data2 - data1;
+
+ write_reg(dst, res);
- m_sharedprotram[0x29c/2] = (m_kb_regs[reg] >> 16) & 0xffff;
- m_sharedprotram[0x29e/2] = m_kb_regs[reg] & 0xffff;
+ util::stream_format(stream, "SUB2 [%04x] = [%04x] - [%04x] (%08x)\n", dst, src2, src1, res);
+ break;
}
- m_sharedprotram[0x202 / 2] = 0x7c; // this mode complete?
- }
+ case 0x9: // Set value (Shared Protection RAM -> ASIC RAM)
+ {
+ const u16 dst = p2 >> 16;
- // Is this actually what this is suppose to do? Complete guess.
- if (cmd == 0x12) // copy??
- {
- m_sharedprotram[0x28c / 2] = m_sharedprotram[0x288 / 2];
- m_sharedprotram[0x28e / 2] = m_sharedprotram[0x28a / 2];
+ const u32 data = p1;
- m_sharedprotram[0x202 / 2] = 0x23; // this mode complete?
- }
+ write_reg(dst, data);
- // what do these do? write the completion byte for now...
- if (cmd == 0x45) m_sharedprotram[0x202 / 2] = 0x56;
- if (cmd == 0x5a) m_sharedprotram[0x202 / 2] = 0x4b;
- if (cmd == 0x2d) m_sharedprotram[0x202 / 2] = 0x3c;
+ util::stream_format(stream, "SET [%04x] = {298, 29a} (%08x)\n", dst, data);
+ break;
+ }
- if (cmd == 0x4f) // memcpy with encryption / scrambling
- {
- const u16 src = m_sharedprotram[0x290 / 2] >> 1; // External mcu data is 8 bit and addressed as such
- const u32 dst = m_sharedprotram[0x292 / 2];
- const u16 size = m_sharedprotram[0x294 / 2];
- const u16 mode = m_sharedprotram[0x296 / 2];
+ case 0xa: // Get value (ASIC RAM -> Shared Protection RAM)
+ {
+ const u16 src = p1 >> 16;
+
+ const u32 data = m_regs[src];
- IGS022_do_dma(src,dst,size,mode);
+ m_sharedprotram[0x29c / 2] = (data >> 16) & 0xffff;
+ m_sharedprotram[0x29e / 2] = data & 0xffff;
- m_sharedprotram[0x202 / 2] = 0x5e; // this mode complete?
+ util::stream_format(stream, "GET {29c, 29e} = [%04x] (%08x)\n", src, data);
+ break;
+ }
}
-}
+ LOGMASKED(LOG_CMD_6D, "%s", stream.str());
+ m_sharedprotram[0x202 / 2] = 0x7c; // this mode complete?
+}
-DEFINE_DEVICE_TYPE(IGS022, igs022_device, "igs022", "IGS022")
+DEFINE_DEVICE_TYPE(IGS022, igs022_device, "igs022", "IGS022 encrypted DMA device")
diff --git a/src/mame/machine/igs022.h b/src/mame/machine/igs022.h
index 619b7a0fc86..5fb2bd9115c 100644
--- a/src/mame/machine/igs022.h
+++ b/src/mame/machine/igs022.h
@@ -1,33 +1,42 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood, ElSemi
-/* IGS022 */
#ifndef MAME_MACHINE_IGS022_H
#define MAME_MACHINE_IGS022_H
#pragma once
-
class igs022_device : public device_t
{
public:
igs022_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- void IGS022_handle_command();
+ void handle_command();
protected:
virtual void device_start() override;
virtual void device_reset() override;
- u32 m_kb_regs[0x100];
-
- void IGS022_do_dma(u16 src, u16 dst, u16 size, u16 mode);
- void IGS022_reset();
-
private:
+ static constexpr u16 NUM_REGS = 0x300, STACK_SIZE = 0x100;
+ u32 m_regs[NUM_REGS];
+ u32 m_stack[STACK_SIZE];
+ u8 m_stack_ptr;
+
optional_shared_ptr<u16> m_sharedprotram;
required_memory_region m_rom;
-};
+ u32 read_reg(u16 offset);
+ void write_reg(u16 offset, u32 data);
+
+ void push_stack(u32 data);
+ u32 pop_stack();
+ std::string stack_as_string() const;
+
+ void do_dma(u16 src, u16 dst, u16 size, u16 mode);
+
+ void handle_command_6d();
+ void handle_incomplete_command(u16 cmd, u16 res);
+};
DECLARE_DEVICE_TYPE(IGS022, igs022_device)
diff --git a/src/mame/machine/pgmprot_igs025_igs022.cpp b/src/mame/machine/pgmprot_igs025_igs022.cpp
index 29bc98c34a4..0bba9402785 100644
--- a/src/mame/machine/pgmprot_igs025_igs022.cpp
+++ b/src/mame/machine/pgmprot_igs025_igs022.cpp
@@ -4,25 +4,22 @@
PGM 022 + 025 PGM protection emulation
this file contains the game / pgm specifc hookups for the IGS022/IGS025
- protection chips, actual simulation is in igs025_igs022.c
+ protection chips, actual simulation is in igs022.cpp/igs025.cpp
- sed by
+ Used by:
The Killing Blade
Dragon World 3
Dragon World 3 EX
- ----
-
-
-
- ***********************************************************************/
+************************************************************************/
#include "emu.h"
#include "includes/pgm.h"
#include "machine/pgmprot_igs025_igs022.h"
-/* The IGS022 is an MCU which performs encrypted DMA used by
+/*
+ The IGS022 is an MCU which performs encrypted DMA used by:
- The Killing Blade
- Dragon World 3
- Dragon World 3 Ex
@@ -32,7 +29,7 @@
*/
-/* NON-device stuff, game specific, keep here */
+// NON-device stuff, game specific, keep here
void pgm_022_025_state::pgm_dw3_decrypt()
{
@@ -337,7 +334,7 @@ MACHINE_RESET_MEMBER(pgm_022_025_state, dw3)
void pgm_022_025_state::igs025_to_igs022_callback( void )
{
// printf("igs025_to_igs022_callback\n");
- m_igs022->IGS022_handle_command();
+ m_igs022->handle_command();
}
@@ -380,7 +377,6 @@ void pgm_022_025_state::pgm_022_025(machine_config &config)
m_igs025->set_external_cb(FUNC(pgm_022_025_state::igs025_to_igs022_callback));
IGS022(config, m_igs022, 0);
-
}
void pgm_022_025_state::pgm_022_025_dw3(machine_config &config)
@@ -415,6 +411,7 @@ INPUT_PORTS_START( killbld )
PORT_DIPSETTING( 0x0021, DEF_STR( World ) )
INPUT_PORTS_END
+
INPUT_PORTS_START( dw3 )
PORT_INCLUDE ( pgm )
@@ -428,7 +425,6 @@ INPUT_PORTS_START( dw3 )
PORT_CONFSETTING( 0x0005, DEF_STR( China ) )
PORT_CONFSETTING( 0x0006, DEF_STR( World ) )
PORT_CONFSETTING( 0x0007, "Singapore" )
-
INPUT_PORTS_END
@@ -445,5 +441,4 @@ INPUT_PORTS_START( dw3j ) // for dw3100 set
// PORT_CONFSETTING( 0x0005, DEF_STR( China ) )
// PORT_CONFSETTING( 0x0006, DEF_STR( World ) )
// PORT_CONFSETTING( 0x0007, "Singapore" )
-
INPUT_PORTS_END