diff --git a/.gitattributes b/.gitattributes index 2e13e46de36..041be7d74f5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/src/mame/drivers/igs017.c b/src/mame/drivers/igs017.c index f6c8c111758..3fb6ee9f213 100644 --- a/src/mame/drivers/igs017.c +++ b/src/mame/drivers/igs017.c @@ -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 m_maincpu; @@ -70,9 +72,10 @@ public: optional_shared_ptr m_fg_videoram; optional_shared_ptr m_bg_videoram; required_device m_oki; - optional_device m_igs025_igs022; // Mj Shuang Long Qiang Zhu 2 + optional_device m_igs025; // Mj Shuang Long Qiang Zhu 2 + optional_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") diff --git a/src/mame/includes/pgm.h b/src/mame/includes/pgm.h index dbf4b7304a1..bf3df4b59cc 100644 --- a/src/mame/includes/pgm.h +++ b/src/mame/includes/pgm.h @@ -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 m_igs025_igs022; + void igs025_to_igs022_callback( void ); + + required_device m_igs025; + required_device m_igs022; }; /* for machine/pgmprot5.c type games */ diff --git a/src/mame/machine/igs025.c b/src/mame/machine/igs025.c new file mode 100644 index 00000000000..3e0b4d3a099 --- /dev/null +++ b/src/mame/machine/igs025.c @@ -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(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; + + + diff --git a/src/mame/machine/igs025_igs022.h b/src/mame/machine/igs025.h similarity index 59% rename from src/mame/machine/igs025_igs022.h rename to src/mame/machine/igs025.h index 79b0f27cab0..3d04426e6d5 100644 --- a/src/mame/machine/igs025_igs022.h +++ b/src/mame/machine/igs025.h @@ -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 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; diff --git a/src/mame/machine/igs025_igs022.c b/src/mame/machine/igs025_igs022.c deleted file mode 100644 index 1468a243dbe..00000000000 --- a/src/mame/machine/igs025_igs022.c +++ /dev/null @@ -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; - - - diff --git a/src/mame/machine/pgmprot_igs025_igs022.c b/src/mame/machine/pgmprot_igs025_igs022.c index 91d5de3ad69..6b1ba5868aa 100644 --- a/src/mame/machine/pgmprot_igs025_igs022.c +++ b/src/mame/machine/pgmprot_igs025_igs022.c @@ -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 diff --git a/src/mame/mame.mak b/src/mame/mame.mak index a57a56280f8..be913293f27 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -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 \