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)

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]
This commit is contained in:
Luca Elia 2022-04-09 17:27:16 +02:00
parent 1d19337feb
commit ec3cd170e7
7 changed files with 2959 additions and 2028 deletions

File diff suppressed because it is too large Load Diff

132
src/mame/layout/igsslot.lay Normal file
View File

@ -0,0 +1,132 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<element name="L1" defstate="1">
<rect state="1">
<color red="0.0" green="1.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.0" green="0.2" blue="0.0" />
</rect>
<text string="TAKE">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="STOP1">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<element name="L2" defstate="1">
<rect state="1">
<color red="0.0" green="1.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.0" green="0.2" blue="0.0" />
</rect>
<text string="HIGH">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="STOP2">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<element name="L3" defstate="1">
<rect state="1">
<color red="0.0" green="1.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.0" green="0.2" blue="0.0" />
</rect>
<text string="LOW">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="STOP3">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<element name="L4" defstate="1">
<rect state="1">
<color red="0.0" green="1.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.0" green="0.2" blue="0.0" />
</rect>
<text string="W-UP">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="STOP4">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<element name="L5" defstate="1">
<rect state="1">
<color red="0.0" green="1.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.0" green="0.2" blue="0.0" />
</rect>
<text string="BET / 2W-UP">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="STOP ALL">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<element name="L6" defstate="1">
<rect state="1">
<color red="1.0" green="0.0" blue="0.0" />
</rect>
<rect state="0">
<color red="0.3" green="0.0" blue="0.0" />
</rect>
<text string="HW-UP">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.1" width="1" height="0.4" />
</text>
<text string="START">
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0" y="0.5" width="1" height="0.4" />
</text>
</element>
<view name="Button Lamps">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
<element name="lamp1" ref="L1">
<bounds x="0.5" y="3.13" width="0.40" height="0.24" />
</element>
<element name="lamp2" ref="L2">
<bounds x="1.0" y="3.13" width="0.40" height="0.24" />
</element>
<element name="lamp3" ref="L3">
<bounds x="1.5" y="3.13" width="0.40" height="0.24" />
</element>
<element name="lamp4" ref="L4">
<bounds x="2.0" y="3.13" width="0.40" height="0.24" />
</element>
<element name="lamp5" ref="L5">
<bounds x="2.5" y="3.13" width="0.40" height="0.24" />
</element>
<element name="lamp6" ref="L6">
<bounds x="3.0" y="3.13" width="0.40" height="0.24" />
</element>
</view>
</mamelayout>

View File

@ -1,17 +1,15 @@
// 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 <algorithm>
#include <sstream>
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 +20,86 @@ 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);
std::fill(std::begin(m_regs), std::end(m_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()");
logerror("%s: IGS022 Reset\n", machine().describe_context());
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;
if (!m_sharedprotram)
{
logerror("m_sharedprotram was not set\n");
logerror("%s: IGS022 m_sharedprotram was not set!\n", machine().describe_context());
return;
}
IGS022_reset();
std::fill(std::begin(m_kb_regs), std::end(m_kb_regs), 0);
reset();
}
void igs022_device::IGS022_do_dma(u16 src, u16 dst, u16 size, u16 mode)
// From IGS022 ROM to shared protection RAM
void igs022_device::do_dma(u16 src, u16 dst, u16 size, u16 mode)
{
//printf("igs022_device::IGS022_do_dma\n");
logerror("%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
P_SRC = 0x300290 (offset from prot rom base)
P_DST = 0x300292 (words from 0x300000)
P_SIZE = 0x300294 (words)
P_MODE = 0x300296
Mode 5 direct
Mode 6 swap nibbles and bytes
1,2,3 table based ops
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 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))
const u16 * const PROTROM = (u16 *)m_rom->base();
switch (mode)
{
/* mode3 applies a xor from a 0x100 byte table to the data being
transferred
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 table is 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* 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);
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
if (mode == 4)
u16 extraxor = ((dectable[taboff + 1]) << 8) | (dectable[taboff + 0] << 0);
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 +109,301 @@ 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; // ' '
logerror("%s: IGS022 DMA mode 4 -> %06x | %04x (%04x)\n", machine().describe_context(), (dst + x) * 2, dat, (u16)(dat - extraxor));
dat -= extraxor;
break;
}
// 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));
dat2 -= extraxor;
}
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;
}
}
else if (mode == 7)
{
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? */
}
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? */
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?
}
}
// 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::reset()
{
const u16 *PROTROM = (u16*)m_rom->base();
const u16 * const PROTROM = (u16 *)m_rom->base();
// fill ram with A5 patern
for (int i = 0; i < 0x4000/2; i++)
// fill ram with A55A pattern
for (int i = 0; i < 0x4000 / 2; i++)
m_sharedprotram[i] = 0xa55a;
// the auto-dma
// the initial auto-DMA
u16 src = PROTROM[0x100 / 2];
const u32 dst = PROTROM[0x102 / 2];
const u16 size = PROTROM[0x104 / 2];
u16 mode = PROTROM[0x106 / 2];
mode &= 0xff;
mode = (mode >> 8) | (mode << 8);
src >>= 1;
IGS022_do_dma(src,dst,size,mode);
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 $3002a0 to #3 causes Dragon World 3 to skip this check
m_sharedprotram[0x2a2/2] = PROTROM[0x114/2];
m_sharedprotram[0x2a2 / 2] = PROTROM[0x114 / 2];
}
void igs022_device::IGS022_handle_command()
void igs022_device::push_stack(u32 data)
{
//printf("igs022_device::IGS022_handle_command\n");
if (m_stack_ptr < STACK_SIZE - 1)
++m_stack_ptr;
const u16 cmd = m_sharedprotram[0x200/2];
m_stack[m_stack_ptr] = data;
}
if (cmd == 0x6d) // Store values to asic ram
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::stringstream stream;
stream << "stack:";
for (int i = 0; i <= m_stack_ptr; ++i)
util::stream_format(stream, " %08x", m_stack[i]);
return stream.str();
}
u32 igs022_device::read_reg(u16 offset)
{
if (offset < NUM_REGS)
{
const u32 p1 = (m_sharedprotram[0x298/2] << 16) | m_sharedprotram[0x29a/2];
const u32 p2 = (m_sharedprotram[0x29c/2] << 16) | m_sharedprotram[0x29e/2];
if ((p2 & 0xffff) == 0x9) // Set value
{
const int reg = (p2 >> 16) & 0xffff;
if (reg & 0x300) { // 300?? killbld expects 0x200, drgw3 expects 0x100?
m_kb_regs[reg & 0xff] = p1;
}
}
if ((p2 & 0xffff) == 0x6) // Add value
{
const int src1 = (p1 >> 16) & 0xff;
const int src2 = (p1 >> 0) & 0xff;
const int dst = (p2 >> 16) & 0xff;
m_kb_regs[dst] = m_kb_regs[src2] - m_kb_regs[src1];
}
if ((p2 & 0xffff) == 0x1) // Add Imm?
{
const int reg = (p2 >> 16) & 0xff;
const int imm = (p1 >> 0) & 0xffff;
m_kb_regs[reg] += imm;
}
if ((p2 & 0xffff) == 0xa) // Get value
{
const int reg = (p1 >> 16) & 0xFF;
m_sharedprotram[0x29c/2] = (m_kb_regs[reg] >> 16) & 0xffff;
m_sharedprotram[0x29e/2] = m_kb_regs[reg] & 0xffff;
}
m_sharedprotram[0x202 / 2] = 0x7c; // this mode complete?
return m_regs[offset];
}
// Is this actually what this is suppose to do? Complete guess.
if (cmd == 0x12) // copy??
else if (offset == 0x400)
{
m_sharedprotram[0x28c / 2] = m_sharedprotram[0x288 / 2];
m_sharedprotram[0x28e / 2] = m_sharedprotram[0x28a / 2];
m_sharedprotram[0x202 / 2] = 0x23; // this mode complete?
return pop_stack();
}
// 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;
if (cmd == 0x4f) // memcpy with encryption / scrambling
else
{
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];
IGS022_do_dma(src,dst,size,mode);
m_sharedprotram[0x202 / 2] = 0x5e; // this mode complete?
return 0; // Invalid!
}
}
void igs022_device::write_reg(u16 offset, u32 data)
{
if (offset < NUM_REGS)
{
m_regs[offset] = data;
}
else if (offset == 0x300)
{
push_stack(data);
}
else
{
// Invalid!
}
}
DEFINE_DEVICE_TYPE(IGS022, igs022_device, "igs022", "IGS022")
// 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;
}
void igs022_device::handle_command()
{
const u16 cmd = m_sharedprotram[0x200 / 2];
switch (cmd)
{
case 0x12: // Push
{
const u32 data = (m_sharedprotram[0x288 / 2] << 16) + m_sharedprotram[0x28a / 2];
push_stack(data);
logerror("%s: IGS022 command %04x: PUSH {288, 28a} (%08x) %s\n", machine().describe_context(), cmd, data, stack_as_string());
m_sharedprotram[0x202 / 2] = 0x23; // this mode complete?
break;
}
case 0x2d: handle_incomplete_command(cmd, 0x3c); break; // killbld
// case 0x42: break; // killbld
case 0x45: // Pop
{
const u32 data = pop_stack();
m_sharedprotram[0x28c / 2] = (data >> 16) & 0xffff;
m_sharedprotram[0x28e / 2] = data & 0xffff;
logerror("%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;
}
// case 0x47: // NOP? slqz2/lhzb2
// break;
case 0x4f: // DMA from protection ROM (memcpy with encryption / scrambling)
{
logerror("%s: IGS022 command %04x: DMA\n", machine().describe_context(), cmd);
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;
}
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::stringstream 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 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);
util::stream_format(stream, "ADD [%04x] = [%04x] + [%04x] (%08x)\n", dst, src1, src2, res);
break;
}
case 0x1: // Sub values (src1 - src2)
{
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);
util::stream_format(stream, "SUB1 [%04x] = [%04x] - [%04x] (%08x)\n", dst, src1, src2, res);
break;
}
case 0x6: // Sub values (src2 - src1)
{
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);
util::stream_format(stream, "SUB2 [%04x] = [%04x] - [%04x] (%08x)\n", dst, src2, src1, res);
break;
}
case 0x9: // Set value (Shared Protection RAM -> ASIC RAM)
{
const u16 dst = p2 >> 16;
const u32 data = p1;
write_reg(dst, data);
util::stream_format(stream, "SET [%04x] = {298, 29a} (%08x)\n", dst, data);
break;
}
case 0xa: // Get value (ASIC RAM -> Shared Protection RAM)
{
const u16 src = p1 >> 16;
const u32 data = m_regs[src];
m_sharedprotram[0x29c / 2] = (data >> 16) & 0xffff;
m_sharedprotram[0x29e / 2] = data & 0xffff;
util::stream_format(stream, "GET {29c, 29e} = [%04x] (%08x)\n", src, data);
break;
}
}
logerror("%s", stream.str());
m_sharedprotram[0x202 / 2] = 0x7c; // this mode complete?
}
DEFINE_DEVICE_TYPE(IGS022, igs022_device, "igs022", "IGS022 encrypted DMA device")

View File

@ -1,33 +1,44 @@
// 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 reset();
void handle_command_6d();
void handle_incomplete_command(u16 cmd, u16 res);
};
DECLARE_DEVICE_TYPE(IGS022, igs022_device)

View File

@ -337,7 +337,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();
}

View File

@ -17268,10 +17268,11 @@ wlcc // (c) 1996
xymg // (c) 1996
@source:igs017.cpp
cpoker2 // (c) 2000?
genius6 // (c) 1998
genius6a // (c) 1997
genius6b // (c) 1997
happyskl // (c) 2001?
happyskl // (c) 2000?
iqblocka // (c) 1996
iqblockf // (c) 1996
lhzb2 // (c) 1998
@ -17281,13 +17282,12 @@ mgdh // (c) 1997
mgdha // (c) 1997
sdmg2 // (c) 1997
slqz2 // (c) 1998
spkrform // (c) ????
spkrform // (c) 2000?
starzan // (c) 2000?
tarzan // (c) 1999
tarzana // (c) 1999
tarzanc // (c) 1999
tjsb // (c) 1997
unkigs // (c) 2001?
@source:igspc.cpp
eztouch // (c) 200?

View File

@ -6,7 +6,7 @@ IGS017 / IGS031 video device
what's the difference between IGS017 and IGS031? encryption?
all the known IGS017 / IGS031 games use same memory map, is the IGS017 / IGS031
all the known IGS017 / IGS031 games use the same memory map, is the IGS017 / IGS031
providing the interface to the 8255, or is it coincidence?
*/
@ -17,7 +17,6 @@ providing the interface to the 8255, or is it coincidence?
void igs017_igs031_device::map(address_map &map)
{
map(0x1000, 0x17ff).ram().share("spriteram");
// map(0x1800, 0x1bff).ram() //.w("palette", FUNC(palette_device::write).share("palette");
map(0x1800, 0x1bff).ram().w(FUNC(igs017_igs031_device::palram_w)).share("palram");
map(0x1c00, 0x1fff).ram();
@ -29,7 +28,6 @@ void igs017_igs031_device::map(address_map &map)
map(0x4000, 0x5fff).ram().w(FUNC(igs017_igs031_device::fg_w)).share("fg_videoram");
map(0x6000, 0x7fff).ram().w(FUNC(igs017_igs031_device::bg_w)).share("bg_videoram");
}
u8 igs017_igs031_device::i8255_r(offs_t offset)
@ -260,7 +258,7 @@ void igs017_igs031_device::draw_sprite(bitmap_ind16 &bitmap, const rectangle &cl
if (addr + dimx * dimy >= m_sprites_gfx_size)
return;
/* Start drawing */
// Start drawing
const u16 pal = 0x100 + (color << 5);
const u8 *source_base = &m_sprites_gfx[addr];
const u8 transparent_color = 0x1f;
@ -389,7 +387,7 @@ int igs017_igs031_device::debug_viewer(bitmap_ind16 &bitmap,const rectangle &cli
popmessage("a: %08X w: %03X p: %02x-%02x-%02x",a,w,m_sprites_gfx[a/3*3+0],m_sprites_gfx[a/3*3+1],m_sprites_gfx[a/3*3+2]);
m_debug_addr = a;
m_debug_width = w;
osd_sleep(osd_ticks_per_second() / 1000 * 200);
osd_sleep(osd_ticks_per_second() / 1000 * 200 / 4);
return 1;
}
#endif