further refactoring (nw)

This commit is contained in:
David Haywood 2013-10-07 19:20:45 +00:00
parent ffb7377f8f
commit 39d91b12eb
8 changed files with 312 additions and 484 deletions

4
.gitattributes vendored
View File

@ -5096,8 +5096,8 @@ src/mame/machine/gdrom.h svneol=native#text/plain
src/mame/machine/genpin.c svneol=native#text/plain
src/mame/machine/genpin.h svneol=native#text/plain
src/mame/machine/harddriv.c svneol=native#text/plain
src/mame/machine/igs025_igs022.c svneol=native#text/plain
src/mame/machine/igs025_igs022.h svneol=native#text/plain
src/mame/machine/igs025.c svneol=native#text/plain
src/mame/machine/igs025.h svneol=native#text/plain
src/mame/machine/irem_cpu.c svneol=native#text/plain
src/mame/machine/irem_cpu.h svneol=native#text/plain
src/mame/machine/irobot.c svneol=native#text/plain

View File

@ -48,7 +48,8 @@ Notes:
#include "machine/i8255.h"
#include "sound/2413intf.h"
#include "sound/okim6295.h"
#include "machine/igs025_igs022.h"
#include "machine/igs025.h"
#include "machine/igs022.h"
class igs017_state : public driver_device
{
@ -61,8 +62,9 @@ public:
m_fg_videoram(*this, "fg_videoram", 0),
m_bg_videoram(*this, "bg_videoram", 0),
m_oki(*this, "oki"),
m_igs025_igs022(*this,"igs022igs025")
{ }
m_igs025(*this,"igs025"),
m_igs022(*this,"igs022")
{ }
int m_input_addr;
required_device<cpu_device> m_maincpu;
@ -70,9 +72,10 @@ public:
optional_shared_ptr<UINT8> m_fg_videoram;
optional_shared_ptr<UINT8> m_bg_videoram;
required_device<okim6295_device> m_oki;
optional_device<igs_025_022_device> m_igs025_igs022; // Mj Shuang Long Qiang Zhu 2
optional_device<igs025_device> m_igs025; // Mj Shuang Long Qiang Zhu 2
optional_device<igs022_device> m_igs022; // Mj Shuang Long Qiang Zhu 2
void igs025_to_igs022_callback( void );
int m_toggle;
int m_debug_addr;
@ -997,6 +1000,13 @@ void igs017_state::lhzb2_decrypt_sprites()
}
}
void igs017_state::igs025_to_igs022_callback( void )
{
m_igs022->IGS022_handle_command();
}
DRIVER_INIT_MEMBER(igs017_state,lhzb2)
{
int i;
@ -1088,11 +1098,11 @@ DRIVER_INIT_MEMBER(igs017_state,lhzb2)
lhzb2_patch_rom();
// install and configure protection device(s)
// m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_r), (igs_025_022_device*)m_igs025_igs022), write16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_w), (igs_025_022_device*)m_igs025_igs022));
// m_igs025_igs022->m_sharedprotram = m_sharedprotram;
// m_igs025_igs022->m_kb_source_data = dw3_source_data;
// m_igs025_igs022->m_kb_source_data_offset = 0;
// m_igs025_igs022->m_kb_game_id = 0x00060000;
// m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs025_device::killbld_igs025_prot_r), (igs025_device*)m_igs025), write16_delegate(FUNC(igs025_device::killbld_igs025_prot_w), (igs025_device*)m_igs025));
// m_igs022->m_sharedprotram = m_sharedprotram;
// m_igs025->m_kb_source_data = dw3_source_data;
// m_igs025->m_kb_source_data_offset = 0;
// m_igs025->m_kb_game_id = 0x00060000;
}
@ -1272,11 +1282,11 @@ DRIVER_INIT_MEMBER(igs017_state,slqz2)
slqz2_patch_rom();
// install and configure protection device(s)
// m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_r), (igs_025_022_device*)m_igs025_igs022), write16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_w), (igs_025_022_device*)m_igs025_igs022));
// m_igs025_igs022->m_sharedprotram = m_sharedprotram;
// m_igs025_igs022->m_kb_source_data = dw3_source_data;
// m_igs025_igs022->m_kb_source_data_offset = 0;
// m_igs025_igs022->m_kb_game_id = 0x00060000;
// m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs025_device::killbld_igs025_prot_r), (igs025_device*)m_igs025), write16_delegate(FUNC(igs025_device::killbld_igs025_prot_w), (igs025_device*)m_igs025));
// m_igs022->m_sharedprotram = m_sharedprotram;
// m_igs025->m_kb_source_data = dw3_source_data;
// m_igs025->m_kb_source_data_offset = 0;
// m_igs025->m_kb_game_id = 0x00060000;
}
// spkrform
@ -3595,7 +3605,11 @@ static MACHINE_CONFIG_START( lhzb2, igs017_state )
MCFG_PALETTE_LENGTH(0x100*2)
// protection
MCFG_DEVICE_ADD("igs022igs025", IGS025022, 0)
MCFG_DEVICE_ADD("igs025", IGS025, 0)
MCFG_IGS025_SET_EXTERNAL_EXECUTE( igs017_state, igs025_to_igs022_callback )
MCFG_DEVICE_ADD("igs022", IGS022, 0)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -3665,7 +3679,10 @@ static MACHINE_CONFIG_START( slqz2, igs017_state )
MCFG_PALETTE_LENGTH(0x100*2)
// protection
MCFG_DEVICE_ADD("igs022igs025", IGS025022, 0)
MCFG_DEVICE_ADD("igs025", IGS025, 0)
MCFG_IGS025_SET_EXTERNAL_EXECUTE( igs017_state, igs025_to_igs022_callback )
MCFG_DEVICE_ADD("igs022", IGS022, 0)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -8,7 +8,8 @@
#include "machine/nvram.h"
#include "machine/pgmcrypt.h"
#include "machine/igs025_igs022.h"
#include "machine/igs025.h"
#include "machine/igs022.h"
#define PGMARM7LOGERROR 0
@ -387,7 +388,9 @@ public:
pgm_022_025_state(const machine_config &mconfig, device_type type, const char *tag)
: pgm_state(mconfig, type, tag),
m_sharedprotram(*this, "sharedprotram"),
m_igs025_igs022(*this,"igs022igs025")
m_igs025(*this,"igs025"),
m_igs022(*this,"igs022")
{ }
void pgm_dw3_decrypt();
@ -399,7 +402,10 @@ public:
DECLARE_DRIVER_INIT(drgw3);
DECLARE_MACHINE_RESET(killbld);
required_device<igs_025_022_device> m_igs025_igs022;
void igs025_to_igs022_callback( void );
required_device<igs025_device> m_igs025;
required_device<igs022_device> m_igs022;
};
/* for machine/pgmprot5.c type games */

228
src/mame/machine/igs025.c Normal file
View File

@ -0,0 +1,228 @@
/*
IGS025 is some kind of state machine / logic device which the game
uses for various security checks, and to determine the region of the
game based on string sequences.
The IGS025 can _NOT_ be swapped between games, so contains at least
some game specific configuration / programming even if there is a
large amount of common behavior between games.
*/
#include "emu.h"
#include "igs025.h"
igs025_device::igs025_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, IGS025, "IGS025", tag, owner, clock, "igs_025_022", __FILE__)
{
m_execute_external = igs025_execute_external(FUNC(igs025_device::no_callback_setup), this);
}
void igs025_device::device_config_complete()
{
}
void igs025_device::device_validity_check(validity_checker &valid) const
{
}
void igs025_device::no_callback_setup()
{
printf("igs025 trigger external callback with no external callback setup\n");
}
void igs025_device::set_external_cb(device_t &device,igs025_execute_external newcb)
{
//printf("set_external_cb\n");
igs025_device &dev = downcast<igs025_device &>(device);
dev.m_execute_external = newcb;
}
void igs025_device::device_start()
{
// Reset IGS025 stuff
m_kb_prot_hold = 0;
m_kb_prot_hilo = 0;
m_kb_prot_hilo_select = 0;
m_kb_cmd = 0;
m_kb_reg = 0;
m_kb_ptr = 0;
m_kb_swap = 0;
m_execute_external.bind_relative_to(*owner());
save_item(NAME(m_kb_prot_hold));
save_item(NAME(m_kb_prot_hilo));
save_item(NAME(m_kb_prot_hilo_select));
save_item(NAME(m_kb_cmd));
save_item(NAME(m_kb_reg));
save_item(NAME(m_kb_ptr));
}
void igs025_device::device_reset()
{
// Reset IGS025 stuff
m_kb_prot_hold = 0;
m_kb_prot_hilo = 0;
m_kb_prot_hilo_select = 0;
m_kb_cmd = 0;
m_kb_reg = 0;
m_kb_ptr = 0;
m_kb_swap = 0;
}
void igs025_device::killbld_protection_calculate_hold(int y, int z)
{
unsigned short old = m_kb_prot_hold;
m_kb_prot_hold = ((old << 1) | (old >> 15));
m_kb_prot_hold ^= 0x2bad;
m_kb_prot_hold ^= BIT(z, y);
m_kb_prot_hold ^= BIT( old, 7) << 0;
m_kb_prot_hold ^= BIT(~old, 13) << 4;
m_kb_prot_hold ^= BIT( old, 3) << 11;
m_kb_prot_hold ^= (m_kb_prot_hilo & ~0x0408) << 1;
}
void igs025_device::killbld_protection_calculate_hilo()
{
UINT8 source;
m_kb_prot_hilo_select++;
if (m_kb_prot_hilo_select > 0xeb) {
m_kb_prot_hilo_select = 0;
}
source = m_kb_source_data[(ioport(":Region")->read() - m_kb_source_data_offset)][m_kb_prot_hilo_select];
if (m_kb_prot_hilo_select & 1)
{
m_kb_prot_hilo = (m_kb_prot_hilo & 0x00ff) | (source << 8);
}
else
{
m_kb_prot_hilo = (m_kb_prot_hilo & 0xff00) | (source << 0);
}
}
WRITE16_MEMBER(igs025_device::killbld_igs025_prot_w )
{
if (offset == 0)
{
m_kb_cmd = data;
}
else
{
switch (m_kb_cmd)
{
case 0x00:
m_kb_reg = data;
break;
case 0x01: // drgw3
{
if (data == 0x0002) { // Execute command
//printf("execute\n");
m_execute_external();
}
}
break;
case 0x02: // killbld
{
if (data == 0x0001) { // Execute command
//printf("execute\n");
m_execute_external();
m_kb_reg++;
}
}
break;
case 0x03:
m_kb_swap = data;
break;
case 0x04:
// m_kb_ptr = data; // Suspect. Not good for drgw3
break;
case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
m_kb_ptr++;
killbld_protection_calculate_hold(m_kb_cmd & 0x0f, data & 0xff);
break;
// default:
// logerror("%06X: ASIC25 W CMD %X VAL %X\n", space.device().safe_pc(), m_kb_cmd, data);
}
}
}
READ16_MEMBER(igs025_device::killbld_igs025_prot_r )
{
if (offset)
{
switch (m_kb_cmd)
{
case 0x00:
return BITSWAP8((m_kb_swap+1) & 0x7f, 0,1,2,3,4,5,6,7); // drgw3
case 0x01:
return m_kb_reg & 0x7f;
case 0x05:
{
switch (m_kb_ptr)
{
case 1:
return 0x3f00 | ioport(":Region")->read();
case 2:
return 0x3f00 | ((m_kb_game_id >> 8) & 0xff);
case 3:
return 0x3f00 | ((m_kb_game_id >> 16) & 0xff);
case 4:
return 0x3f00 | ((m_kb_game_id >> 24) & 0xff);
default: // >= 5
return 0x3f00 | BITSWAP8(m_kb_prot_hold, 5,2,9,7,10,13,12,15);
}
return 0;
}
case 0x40:
killbld_protection_calculate_hilo();
return 0; // Read and then discarded
// default:
// logerror("%06X: ASIC25 R CMD %X\n", space.device().safe_pc(), m_kb_cmd);
}
}
return 0;
}
const device_type IGS025 = &device_creator<igs025_device>;

View File

@ -1,9 +1,17 @@
/* Common device stuff for IGS025 / IGS022, should be split into devices for each chip once we know where what part does what */
class igs_025_022_device : public device_t
// used to connect the 022
typedef device_delegate<void (void)> igs025_execute_external;
#define MCFG_IGS025_SET_EXTERNAL_EXECUTE( _class, _method) \
igs025_device::set_external_cb(*device, igs025_execute_external(&_class::_method, #_class "::" #_method, NULL, (_class *)0));
class igs025_device : public device_t
{
public:
igs_025_022_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
igs025_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_WRITE16_MEMBER( killbld_igs025_prot_w );
DECLARE_READ16_MEMBER( killbld_igs025_prot_r );
@ -11,7 +19,9 @@ public:
const UINT8 (*m_kb_source_data)[0xec];
INT32 m_kb_source_data_offset;
UINT32 m_kb_game_id;
UINT16* m_sharedprotram;
igs025_execute_external m_execute_external;
static void set_external_cb(device_t &device,igs025_execute_external newcb);
protected:
virtual void device_config_complete();
@ -28,19 +38,13 @@ protected:
int m_kb_reg;
int m_kb_ptr;
UINT8 m_kb_swap;
UINT32 m_kb_regs[0x100];
void killbld_protection_calculate_hilo();
void killbld_protection_calculate_hold(int y, int z);
void IGS022_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode);
void IGS022_reset();
void IGS022_handle_command();
void no_callback_setup(void);
};
extern const device_type IGS025022;
extern const device_type IGS025;

View File

@ -1,439 +0,0 @@
/*
IGS022 is an encrypted DMA device, most likely an MCU of some sort
IGS025 is some kind of state machine / logic device which the game
uses for various securit checks, and to determine the region of the
game based on string sequences.
*/
#include "emu.h"
#include "igs025_igs022.h"
igs_025_022_device::igs_025_022_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, IGS025022, "IGS025022", tag, owner, clock, "igs_025_022", __FILE__)
{
}
void igs_025_022_device::device_config_complete()
{
}
void igs_025_022_device::device_validity_check(validity_checker &valid) const
{
}
void igs_025_022_device::device_start()
{
// Reset IGS025 stuff
m_kb_prot_hold = 0;
m_kb_prot_hilo = 0;
m_kb_prot_hilo_select = 0;
m_kb_cmd = 0;
m_kb_reg = 0;
m_kb_ptr = 0;
m_kb_swap = 0;
memset(m_kb_regs, 0, 0x100 * sizeof(UINT32));
m_sharedprotram = 0;
save_item(NAME(m_kb_prot_hold));
save_item(NAME(m_kb_prot_hilo));
save_item(NAME(m_kb_prot_hilo_select));
save_item(NAME(m_kb_cmd));
save_item(NAME(m_kb_reg));
save_item(NAME(m_kb_ptr));
save_item(NAME(m_kb_regs));
}
void igs_025_022_device::device_reset()
{
if (!m_sharedprotram)
{
logerror("m_sharedprotram was not set\n");
return;
}
IGS022_reset();
// Reset IGS025 stuff
m_kb_prot_hold = 0;
m_kb_prot_hilo = 0;
m_kb_prot_hilo_select = 0;
m_kb_cmd = 0;
m_kb_reg = 0;
m_kb_ptr = 0;
m_kb_swap = 0;
memset(m_kb_regs, 0, 0x100 * sizeof(UINT32));
}
void igs_025_022_device::IGS022_do_dma(UINT16 src, UINT16 dst, UINT16 size, UINT16 mode)
{
UINT16 param;
/*
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
*/
param = mode >> 8;
mode &=0xf; // 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
the table is stored at the start of the protection rom.
the param used with the mode gives a start offset into the table
odd offsets cause an overflow
*/
int x;
UINT16 *PROTROM = (UINT16*)memregion(":igs022data")->base();
for (x = 0; x < size; x++)
{
UINT16 dat2 = PROTROM[src + x];
UINT8 extraoffset = param&0xff;
UINT8* dectable = (UINT8*)memregion(":igs022data")->base(); // the basic decryption table is at the start of the mcu data rom!
UINT8 taboff = ((x*2)+extraoffset) & 0xff; // must allow for overflow in instances of odd offsets
UINT16 extraxor = ((dectable[taboff+1]) << 8) | (dectable[taboff+0] << 0);
if (mode==4)
{
extraxor = 0;
if ((x & 0x003) == 0x000) extraxor |= 0x0049; // 'I'
if ((x & 0x003) == 0x001) extraxor |= 0x0047; // 'G'
if ((x & 0x003) == 0x002) extraxor |= 0x0053; // 'S'
if ((x & 0x003) == 0x003) extraxor |= 0x0020; // ' '
if ((x & 0x300) == 0x000) extraxor |= 0x4900; // 'I'
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, (UINT16)(dat2-extraxor));
dat2 -= extraxor;
}
m_sharedprotram[dst + x] = dat2;
}
}
else if (mode == 5)
{
/* mode 5 seems to be a straight copy, byteswap */
int x;
UINT16 *PROTROM = (UINT16*)memregion(":igs022data")->base();
for (x = 0; x < size; x++)
{
UINT16 dat = PROTROM[src + x];
m_sharedprotram[dst + x] = (dat << 8) | (dat >> 8);
}
}
else if (mode == 6)
{
/* mode 6 seems to swap bytes and nibbles */
int x;
UINT16 *PROTROM = (UINT16*)memregion(":igs022data")->base();
for (x = 0; x < size; x++)
{
UINT16 dat = PROTROM[src + x];
dat = ((dat & 0xf000) >> 12)|
((dat & 0x0f00) >> 4)|
((dat & 0x00f0) << 4)|
((dat & 0x000f) << 12);
m_sharedprotram[dst + x] = dat;
}
}
else if (mode == 7)
{
mame_printf_debug("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
{
mame_printf_debug("unhandled copy mode %04x!\n", mode);
logerror ("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? */
}
}
// the internal MCU boot code automatically does this DMA
// and puts the version # of the data rom in ram
void igs_025_022_device::IGS022_reset()
{
int i;
UINT16 *PROTROM = (UINT16*)memregion(":igs022data")->base();
// fill ram with A5 patern
for (i = 0; i < 0x4000/2; i++)
m_sharedprotram[i] = 0xa55a;
// the auto-dma
UINT16 src = PROTROM[0x100 / 2];
UINT32 dst = PROTROM[0x102 / 2];
UINT16 size = PROTROM[0x104 / 2];
UINT16 mode = PROTROM[0x106 / 2];
mode &= 0xff;
src >>= 1;
IGS022_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];
}
void igs_025_022_device::IGS022_handle_command()
{
UINT16 cmd = m_sharedprotram[0x200/2];
if (cmd == 0x6d) // Store values to asic ram
{
UINT32 p1 = (m_sharedprotram[0x298/2] << 16) | m_sharedprotram[0x29a/2];
UINT32 p2 = (m_sharedprotram[0x29c/2] << 16) | m_sharedprotram[0x29e/2];
if ((p2 & 0xffff) == 0x9) // Set value
{
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
{
int src1 = (p1 >> 16) & 0xff;
int src2 = (p1 >> 0) & 0xff;
int dst = (p2 >> 16) & 0xff;
m_kb_regs[dst] = m_kb_regs[src2] - m_kb_regs[src1];
}
if ((p2 & 0xffff) == 0x1) // Add Imm?
{
int reg = (p2 >> 16) & 0xff;
int imm = (p1 >> 0) & 0xffff;
m_kb_regs[reg] += imm;
}
if ((p2 & 0xffff) == 0xa) // Get value
{
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?
}
// 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];
m_sharedprotram[0x202 / 2] = 0x23; // this mode complete?
}
// 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
{
UINT16 src = m_sharedprotram[0x290 / 2] >> 1; // External mcu data is 8 bit and addressed as such
UINT32 dst = m_sharedprotram[0x292 / 2];
UINT16 size = m_sharedprotram[0x294 / 2];
UINT16 mode = m_sharedprotram[0x296 / 2];
IGS022_do_dma(src,dst,size,mode);
m_sharedprotram[0x202 / 2] = 0x5e; // this mode complete?
}
}
void igs_025_022_device::killbld_protection_calculate_hold(int y, int z)
{
unsigned short old = m_kb_prot_hold;
m_kb_prot_hold = ((old << 1) | (old >> 15));
m_kb_prot_hold ^= 0x2bad;
m_kb_prot_hold ^= BIT(z, y);
m_kb_prot_hold ^= BIT( old, 7) << 0;
m_kb_prot_hold ^= BIT(~old, 13) << 4;
m_kb_prot_hold ^= BIT( old, 3) << 11;
m_kb_prot_hold ^= (m_kb_prot_hilo & ~0x0408) << 1;
}
void igs_025_022_device::killbld_protection_calculate_hilo()
{
UINT8 source;
m_kb_prot_hilo_select++;
if (m_kb_prot_hilo_select > 0xeb) {
m_kb_prot_hilo_select = 0;
}
source = m_kb_source_data[(ioport(":Region")->read() - m_kb_source_data_offset)][m_kb_prot_hilo_select];
if (m_kb_prot_hilo_select & 1)
{
m_kb_prot_hilo = (m_kb_prot_hilo & 0x00ff) | (source << 8);
}
else
{
m_kb_prot_hilo = (m_kb_prot_hilo & 0xff00) | (source << 0);
}
}
WRITE16_MEMBER(igs_025_022_device::killbld_igs025_prot_w )
{
if (offset == 0)
{
m_kb_cmd = data;
}
else
{
switch (m_kb_cmd)
{
case 0x00:
m_kb_reg = data;
break;
case 0x01: // drgw3
{
if (data == 0x0002) { // Execute command
IGS022_handle_command();
}
}
break;
case 0x02: // killbld
{
if (data == 0x0001) { // Execute command
IGS022_handle_command();
m_kb_reg++;
}
}
break;
case 0x03:
m_kb_swap = data;
break;
case 0x04:
// m_kb_ptr = data; // Suspect. Not good for drgw3
break;
case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
m_kb_ptr++;
killbld_protection_calculate_hold(m_kb_cmd & 0x0f, data & 0xff);
break;
// default:
// logerror("%06X: ASIC25 W CMD %X VAL %X\n", space.device().safe_pc(), m_kb_cmd, data);
}
}
}
READ16_MEMBER(igs_025_022_device::killbld_igs025_prot_r )
{
if (offset)
{
switch (m_kb_cmd)
{
case 0x00:
return BITSWAP8((m_kb_swap+1) & 0x7f, 0,1,2,3,4,5,6,7); // drgw3
case 0x01:
return m_kb_reg & 0x7f;
case 0x05:
{
switch (m_kb_ptr)
{
case 1:
return 0x3f00 | ioport(":Region")->read();
case 2:
return 0x3f00 | ((m_kb_game_id >> 8) & 0xff);
case 3:
return 0x3f00 | ((m_kb_game_id >> 16) & 0xff);
case 4:
return 0x3f00 | ((m_kb_game_id >> 24) & 0xff);
default: // >= 5
return 0x3f00 | BITSWAP8(m_kb_prot_hold, 5,2,9,7,10,13,12,15);
}
return 0;
}
case 0x40:
killbld_protection_calculate_hilo();
return 0; // Read and then discarded
// default:
// logerror("%06X: ASIC25 R CMD %X\n", space.device().safe_pc(), m_kb_cmd);
}
}
return 0;
}
const device_type IGS025022 = &device_creator<igs_025_022_device>;

View File

@ -315,17 +315,25 @@ MACHINE_RESET_MEMBER(pgm_022_025_state,killbld)
MACHINE_RESET_CALL_MEMBER(pgm);
}
void pgm_022_025_state::igs025_to_igs022_callback( void )
{
// printf("igs025_to_igs022_callback\n");
m_igs022->IGS022_handle_command();
}
DRIVER_INIT_MEMBER(pgm_022_025_state,killbld)
{
pgm_basic_init();
pgm_killbld_decrypt();
// install and configure protection device(s)
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xd40000, 0xd40003, read16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_r), (igs_025_022_device*)m_igs025_igs022), write16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_w), (igs_025_022_device*)m_igs025_igs022));
m_igs025_igs022->m_sharedprotram = m_sharedprotram;
m_igs025_igs022->m_kb_source_data = killbld_source_data;
m_igs025_igs022->m_kb_source_data_offset = 0x16;
m_igs025_igs022->m_kb_game_id = 0x89911400;
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xd40000, 0xd40003, read16_delegate(FUNC(igs025_device::killbld_igs025_prot_r), (igs025_device*)m_igs025), write16_delegate(FUNC(igs025_device::killbld_igs025_prot_w), (igs025_device*)m_igs025));
m_igs022->m_sharedprotram = m_sharedprotram;
m_igs025->m_kb_source_data = killbld_source_data;
m_igs025->m_kb_source_data_offset = 0x16;
m_igs025->m_kb_game_id = 0x89911400;
}
DRIVER_INIT_MEMBER(pgm_022_025_state,drgw3)
@ -334,11 +342,11 @@ DRIVER_INIT_MEMBER(pgm_022_025_state,drgw3)
pgm_dw3_decrypt();
// install and configure protection device(s)
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_r), (igs_025_022_device*)m_igs025_igs022), write16_delegate(FUNC(igs_025_022_device::killbld_igs025_prot_w), (igs_025_022_device*)m_igs025_igs022));
m_igs025_igs022->m_sharedprotram = m_sharedprotram;
m_igs025_igs022->m_kb_source_data = dw3_source_data;
m_igs025_igs022->m_kb_source_data_offset = 0;
m_igs025_igs022->m_kb_game_id = 0x00060000;
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xda5610, 0xda5613, read16_delegate(FUNC(igs025_device::killbld_igs025_prot_r), (igs025_device*)m_igs025), write16_delegate(FUNC(igs025_device::killbld_igs025_prot_w), (igs025_device*)m_igs025));
m_igs022->m_sharedprotram = m_sharedprotram;
m_igs025->m_kb_source_data = dw3_source_data;
m_igs025->m_kb_source_data_offset = 0;
m_igs025->m_kb_game_id = 0x00060000;
}
@ -355,7 +363,10 @@ MACHINE_CONFIG_START( pgm_022_025, pgm_022_025_state )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(killbld_mem)
MCFG_DEVICE_ADD("igs022igs025", IGS025022, 0)
MCFG_DEVICE_ADD("igs025", IGS025, 0)
MCFG_IGS025_SET_EXTERNAL_EXECUTE( pgm_022_025_state, igs025_to_igs022_callback )
MCFG_DEVICE_ADD("igs022", IGS022, 0)
MCFG_MACHINE_RESET_OVERRIDE(pgm_022_025_state,killbld)
MACHINE_CONFIG_END

View File

@ -1047,7 +1047,8 @@ $(MAMEOBJ)/igs.a: \
$(MACHINE)/pgmprot_igs025_igs012.o \
$(MACHINE)/pgmprot_igs025_igs022.o \
$(MACHINE)/pgmprot_igs025_igs028.o \
$(MACHINE)/igs025_igs022.o \
$(MACHINE)/igs025.o \
$(MACHINE)/igs022.o \
$(MAMEOBJ)/irem.a: \
$(DRIVERS)/m10.o $(VIDEO)/m10.o \