diff --git a/src/mame/drivers/igs017.cpp b/src/mame/drivers/igs017.cpp index 89a89de4a45..ac643d6d7c8 100644 --- a/src/mame/drivers/igs017.cpp +++ b/src/mame/drivers/igs017.cpp @@ -18,7 +18,7 @@ Year + Game PCB CPU Sound Custom 97 Mj Super Da Man Guan II NO-0147-6 68000 M6295 IGS031 8255 Battery 97 Mj Tian Jiang Shen Bing NO-0157-2 Z180 M6295 YM2413 IGS017 IGS025 Battery 97 Mj Man Guan Daheng NO-0252 68000 M6295 IGS031 IGS025 IGS???* Battery -98? Genius 6 NO-0131-4 Z180 M6295 YM2413 IGS017 8255 Battery +98 Genius 6 NO-0131-4 Z180 M6295 YM2413 IGS017 IGS003c Battery 98 Mj Long Hu Zhengba 2 NO-0206 68000 M6295 IGS031 IGS025 IGS022* Battery 98 Mj Shuang Long Qiang Zhu 2 NO-0207 68000 M6295 IGS031 IGS025 IGS022 Battery 98 Mj Man Guan Caishen NO-0192-1 68000 M6295 IGS017 IGS025 IGS029 Battery @@ -30,14 +30,14 @@ Year + Game PCB CPU Sound Custom * not present in one set To Do: -- Protection emulation, instead of patching the roms. +- Protection emulation in some games, instead of patching the roms. - NVRAM. -- iqblockf: protection. - mgcs: implement joystick inputs. Finish IGS029 protection simulation. Notes: -- iqblocka: keep start or test pressed during boot to enter test mode A or B. +- iqblocka: keep start pressed during boot for DSWs & input test. Keep test (F2) pressed for book-keeping / setup [pass: press Play (2)] +- iqblockf/genius6: for gambling, press service1 (9) then press Play (2) eight times. Then test (F2) enters book-keeping / setup - lhzb2, mgcs, tjsb: press service + stats during test mode for sound test. - mgdh: press A + B during test mode for sound test (B1+B2+B3 when using a joystick). - mgdh: test mode is accessed by keeping test pressed during boot (as usual), but pressing F2+F3 in MAME @@ -61,13 +61,437 @@ Notes: #include "screen.h" #include "speaker.h" +// Similar protection to that found in igs011.cpp: + +/*************************************************************************** + + ---- IGS Parametric Bitswaps Protection ---- + + The protection involves an internal 16-bit value (val), two mode registers + (mode_f = 0..f, mode_3 = 0..3) and 8 x 16-bit registers (word). + + The two modes affect the bitswap, and are set by loading the (same) mode-specific value + to all the word registers, and then writing to the mode_f or mode_3 trigger register. + + The bitswap of the internal value is then performed writing to one of 8 trigger registers, + according to the modes, trigger register and value written. + + The result is read through a fixed bitswap of the internal value. + +***************************************************************************/ + +class igs_bitswap_device : public device_t +{ +public: + igs_bitswap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template devcb_base &set_in_pa_callback(Object &&cb) { return m_in_pa_cb.set_callback(std::forward(cb)); } + template devcb_base &set_in_pb_callback(Object &&cb) { return m_in_pb_cb.set_callback(std::forward(cb)); } + template devcb_base &set_in_pc_callback(Object &&cb) { return m_in_pc_cb.set_callback(std::forward(cb)); } + + template devcb_base &set_out_pa_callback(Object &&cb) { return m_out_pa_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_pb_callback(Object &&cb) { return m_out_pb_cb.set_callback(std::forward(cb)); } + template devcb_base &set_out_pc_callback(Object &&cb) { return m_out_pc_cb.set_callback(std::forward(cb)); } + + DECLARE_WRITE8_MEMBER( address_w ); + DECLARE_WRITE8_MEMBER( data_w ); + DECLARE_READ8_MEMBER( data_r ); + + void set_m3_bits(int m3, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3); + void set_mf_bits(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3); + void set_val_xor(uint16_t val_xor); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + devcb_read8 m_in_pa_cb; + devcb_read8 m_in_pb_cb; + devcb_read8 m_in_pc_cb; + + devcb_write8 m_out_pa_cb; + devcb_write8 m_out_pb_cb; + devcb_write8 m_out_pc_cb; + + uint8_t m_address, m_m3, m_mf; + uint16_t m_val, m_word; + + uint8_t m_m3_bits[4][4]; + uint8_t m_mf_bits[4]; + uint16_t m_val_xor; +}; + +void igs_bitswap_device::set_m3_bits(int m3, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) +{ + m_m3_bits[m3][0] = b0; + m_m3_bits[m3][1] = b1; + m_m3_bits[m3][2] = b2; + m_m3_bits[m3][3] = b3; + +#if 0 + printf("igs_bitswap: INIT m3_bits[%x] =", m3); + for (int i = 0; i < 4; ++i) + { + uint8_t bit = m_m3_bits[m3][i]; + printf(" %c%d", (bit & 0x80) ? '~' : ' ', (bit & 0x80) ? (bit ^ 0xff) : bit); + } + printf("\n"); +#endif +} + +void igs_bitswap_device::set_mf_bits(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) +{ + m_mf_bits[0] = b0; + m_mf_bits[1] = b1; + m_mf_bits[2] = b2; + m_mf_bits[3] = b3; + +#if 0 + printf("igs_bitswap: INIT mf_bits = %d %d %d %d\n", m_mf_bits[0], m_mf_bits[1], m_mf_bits[2], m_mf_bits[3]); +#endif +} + +void igs_bitswap_device::set_val_xor(uint16_t val_xor) +{ + m_val_xor = val_xor; + +#if 0 + printf("igs_bitswap: INIT val_xor = %04x\n", m_val_xor); +#endif +} + +#define MCFG_IGS_BITSWAP_IN_PORTA_CB(_devcb) \ + devcb = &downcast(*device).set_in_pa_callback(DEVCB_##_devcb); + +#define MCFG_IGS_BITSWAP_IN_PORTB_CB(_devcb) \ + devcb = &downcast(*device).set_in_pb_callback(DEVCB_##_devcb); + +#define MCFG_IGS_BITSWAP_IN_PORTC_CB(_devcb) \ + devcb = &downcast(*device).set_in_pc_callback(DEVCB_##_devcb); + +#define MCFG_IGS_BITSWAP_OUT_PORTA_CB(_devcb) \ + devcb = &downcast(*device).set_out_pa_callback(DEVCB_##_devcb); + +#define MCFG_IGS_BITSWAP_OUT_PORTB_CB(_devcb) \ + devcb = &downcast(*device).set_out_pb_callback(DEVCB_##_devcb); + +#define MCFG_IGS_BITSWAP_OUT_PORTC_CB(_devcb) \ + devcb = &downcast(*device).set_out_pc_callback(DEVCB_##_devcb); + +// note: b3 seems fixed to ~15, it may go away in the future +#define MCFG_IGS_BITSWAP_M3_0_BITS(_b0, _b1, _b2, _b3) \ + downcast(*device).set_m3_bits(0, _b0, _b1, _b2, _b3); + +#define MCFG_IGS_BITSWAP_M3_1_BITS(_b0, _b1, _b2, _b3) \ + downcast(*device).set_m3_bits(1, _b0, _b1, _b2, _b3); + +#define MCFG_IGS_BITSWAP_M3_2_BITS(_b0, _b1, _b2, _b3) \ + downcast(*device).set_m3_bits(2, _b0, _b1, _b2, _b3); + +#define MCFG_IGS_BITSWAP_M3_3_BITS(_b0, _b1, _b2, _b3) \ + downcast(*device).set_m3_bits(3, _b0, _b1, _b2, _b3); + +#define MCFG_IGS_BITSWAP_MF_BITS(_b0, _b1, _b2, _b3) \ + downcast(*device).set_mf_bits(_b0, _b1, _b2, _b3); + +#define MCFG_IGS_BITSWAP_VAL_XOR(_val_xor) \ + downcast(*device).set_val_xor(_val_xor); + +DEFINE_DEVICE_TYPE(IGS_BITSWAP, igs_bitswap_device, "igs_bitswap", "IGS Bitswap Protection") + +igs_bitswap_device::igs_bitswap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, IGS_BITSWAP, tag, owner, clock), + m_in_pa_cb(*this), + m_in_pb_cb(*this), + m_in_pc_cb(*this), + m_out_pa_cb(*this), + m_out_pb_cb(*this), + m_out_pc_cb(*this) +{ +} + +void igs_bitswap_device::device_start() +{ + // resolve callbacks + m_in_pa_cb.resolve(); + m_in_pb_cb.resolve(); + m_in_pc_cb.resolve(); + m_out_pa_cb.resolve(); + m_out_pb_cb.resolve(); + m_out_pc_cb.resolve(); + + // register for save states + save_item(NAME(m_address)); + save_item(NAME(m_m3)); + save_item(NAME(m_mf)); + save_item(NAME(m_val)); + save_item(NAME(m_word)); +} + +void igs_bitswap_device::device_reset() +{ + m_address = m_m3 = m_mf = 0; + m_val = m_word = 0; +} + +WRITE8_MEMBER(igs_bitswap_device::address_w) +{ + m_address = data; +} + +WRITE8_MEMBER(igs_bitswap_device::data_w) +{ + switch (m_address) + { + case 0x00: + if (!m_out_pa_cb.isnull()) + { + m_out_pa_cb((offs_t)0, data); + return; + } + break; + case 0x01: + if (!m_out_pb_cb.isnull()) + { + m_out_pb_cb((offs_t)0, data); + return; + } + break; + case 0x02: + if (!m_out_pc_cb.isnull()) + { + m_out_pc_cb((offs_t)0, data); + return; + } + break; + + case 0x40: // word + { + m_word = (m_word << 8) | data; + logerror("%s: word = %02x\n", machine().describe_context(), m_word); + return; + } + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // same value as address 0x40 + return; + + case 0x48: // mode_f + { + m_mf = 0; + if ((m_word & 0x0f00) != 0x0a00) m_mf |= 0x08; + if ((m_word & 0xf000) != 0x9000) m_mf |= 0x04; + if ((m_word & 0x000f) != 0x0006) m_mf |= 0x02; + if ((m_word & 0x00f0) != 0x0090) m_mf |= 0x01; + + logerror("%s: mode_f = %x (word = %04x)\n", machine().describe_context(), m_mf, m_word); + return; + } + + case 0x50: // mode_3 + { + m_m3 = 0; + if ((m_word & 0x000f) != 0x0003) m_m3 |= 0x02; + if ((m_word & 0x00f0) != 0x0050) m_m3 |= 0x01; + + logerror("%s: mode_3 = %x (word = %04x)\n", machine().describe_context(), m_m3, m_word); + return; + } + + case 0x80: // do bitswap + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + { + uint16_t x = m_val; + + // bits 1-15 come from inverting some bits, xor-ing 4 bits (they change per game) with the mf bits, then shifting to the left + m_val ^= m_val_xor; + for (int i = 0; i < 4; ++i) + m_val ^= BIT(m_mf, i) << m_mf_bits[i]; + m_val <<= 1; + + // bit 0 is the xor of 4 bits from val (some inverted). The 4 bits are picked based on m3 (and they change per game) + uint16_t bit0 = 0; + for (int i = 0; i < 4; ++i) + { + uint8_t bit = m_m3_bits[m_m3][i]; + bit0 ^= (bit & 0x80) ? (BIT(x, bit ^ 0xff) ^ 1) : BIT(x, bit); + } + + // bit 0 is further xor'd with bit x of the data written to this address (8x) + uint16_t xor0 = BIT(data, m_address & 7); + m_val |= bit0 ^ xor0; + + logerror("%s: exec bitswap on port %02x = %02x - mode_3 %02x, mode_f %02x, bit0 %x, xor0 %x, val %04x -> %04x\n", machine().describe_context(), m_address, data, m_m3, m_mf, bit0, xor0, x, m_val); + return; + } + + case 0xa0: // reset + { + logerror("%s: reset bitswap - val %04x -> 0\n", machine().describe_context(), m_val); + m_val = 0; + return; + } + } + + logerror("%s: warning, writing to address %02x = %02x\n", machine().describe_context(), m_address, data); +} + +READ8_MEMBER(igs_bitswap_device::data_r) +{ + switch (m_address) + { + case 0x00: + if (!m_in_pa_cb.isnull()) + return m_in_pa_cb(0); + break; + case 0x01: + if (!m_in_pb_cb.isnull()) + return m_in_pb_cb(0); + break; + case 0x02: + if (!m_in_pc_cb.isnull()) + return m_in_pc_cb(0); + break; + + case 0x03: // result + { + uint8_t res = bitswap<16>(m_val, 0,0,0,0,0,0,0,0, 5,2,9,7,10,13,12,15) & 0xff; + logerror("%s: read bitswap - val %04x -> %02x\n", machine().describe_context(), m_val, res); + return res; + } + + case 0x20: return 0x49; // 'I' + case 0x21: return 0x47; // 'G' + case 0x22: return 0x53; // 'S' + + case 0x24: return 0x41; + case 0x25: return 0x41; + case 0x26: return 0x7f; + case 0x27: return 0x41; + case 0x28: return 0x41; + + case 0x2a: return 0x3e; + case 0x2b: return 0x41; + case 0x2c: return 0x49; + case 0x2d: return 0xf9; + case 0x2e: return 0x0a; + + case 0x30: return 0x26; + case 0x31: return 0x49; + case 0x32: return 0x49; + case 0x33: return 0x49; + case 0x34: return 0x32; + } + + logerror("%s: warning, reading with address = %02x\n", machine().describe_context(), m_address); + return 0xff; +} + + +/*************************************************************************** + + ---- IGS Inc/Dec Protection ---- + + The chip holds an internal 8-bit (or less) value. It is manipulated by issuing commands, + where each command is assigned a specific address range, and is triggered + by writing to that range. Possible commands: + + - INC: increment value + - DEC: decrement value + - RESET: value = 0 + + The protection value is read from an additional address range: + + - READ: read bitswap(value). Only 4 bits are checked. + +***************************************************************************/ + +class igs_incdec_device : public device_t +{ +public: + igs_incdec_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE8_MEMBER( reset_w ); + DECLARE_WRITE8_MEMBER( inc_w ); + DECLARE_WRITE8_MEMBER( dec_w ); + DECLARE_READ8_MEMBER( val_r ); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + uint8_t m_val; +}; + +WRITE8_MEMBER(igs_incdec_device::reset_w) +{ + m_val = 0x00; + logerror("%s: reset -> %02x\n", machine().describe_context(), m_val); +} + +WRITE8_MEMBER(igs_incdec_device::inc_w) +{ + m_val++; + logerror("%s: inc -> %02x\n", machine().describe_context(), m_val); +} + +WRITE8_MEMBER(igs_incdec_device::dec_w) +{ + m_val--; + logerror("%s: dec -> %02x\n", machine().describe_context(), m_val); +} + +READ8_MEMBER(igs_incdec_device::val_r) +{ + uint8_t res = (BIT(m_val, 0) << 7) | + (BIT(m_val, 3) << 5) | + (BIT(m_val, 2) << 4) | + (BIT(m_val, 1) << 2) ; + + logerror("%s: value read, %02x -> %02x\n", machine().describe_context(), m_val, res); + return res; +} + +DEFINE_DEVICE_TYPE(IGS_INCDEC, igs_incdec_device, "igs_incdec", "IGS Inc/Dec Protection") + +igs_incdec_device::igs_incdec_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, IGS_INCDEC, tag, owner, clock) +{ +} + +void igs_incdec_device::device_start() +{ + // register for save states + save_item(NAME(m_val)); +} + +void igs_incdec_device::device_reset() +{ + m_val = 0; +} + + +// igs017_state class igs017_state : public driver_device { public: igs017_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_input_addr(-1), + m_remap_addr(-1), m_maincpu(*this, "maincpu"), m_oki(*this, "oki"), m_hopperdev(*this, "hopper"), @@ -76,7 +500,9 @@ public: m_screen(*this, "screen"), m_palette(*this, "palette"), m_decrypted_opcodes(*this, "decrypted_opcodes"), - m_igs017_igs031(*this, "igs017_igs031") + m_igs017_igs031(*this, "igs017_igs031"), + m_igs_bitswap(*this, "igs_bitswap"), + m_igs_incdec(*this, "igs_incdec") { } void mgcs(machine_config &config); @@ -85,6 +511,8 @@ public: void lhzb2a(machine_config &config); void slqz2(machine_config &config); void iqblocka(machine_config &config); + void iqblockf(machine_config &config); + void genius6(machine_config &config); void lhzb2(machine_config &config); void starzan(machine_config &config); void spkrform(machine_config &config); @@ -98,7 +526,6 @@ public: DECLARE_DRIVER_INIT(mgcs); DECLARE_DRIVER_INIT(tjsb); DECLARE_DRIVER_INIT(spkrform); - DECLARE_DRIVER_INIT(iqblockf); DECLARE_DRIVER_INIT(sdmg2); DECLARE_DRIVER_INIT(tarzan); DECLARE_DRIVER_INIT(tarzana); @@ -110,7 +537,7 @@ protected: virtual void machine_reset() override; private: - int m_input_addr; + int m_remap_addr; required_device m_maincpu; required_device m_oki; @@ -121,6 +548,8 @@ private: required_device m_palette; optional_shared_ptr m_decrypted_opcodes; required_device m_igs017_igs031; + optional_device m_igs_bitswap; + optional_device m_igs_incdec; void igs025_to_igs022_callback( void ); @@ -131,10 +560,6 @@ private: uint8_t m_dsw_select; - // lhzb2a protection: - uint16_t m_prot_regs[2], m_prot_val, m_prot_word, m_prot_m3, m_prot_mf; - uint8_t m_prot2; - // IGS029 protection (communication) uint8_t m_igs029_send_data, m_igs029_recv_data; uint8_t m_igs029_send_buf[256], m_igs029_recv_buf[256]; @@ -142,9 +567,12 @@ private: // IGS029 protection (mgcs) uint32_t m_igs029_mgcs_long; - DECLARE_WRITE8_MEMBER(input_select_w); - DECLARE_READ8_MEMBER(input_r); + + DECLARE_WRITE8_MEMBER(iqblocka_keyin_w); + DECLARE_WRITE8_MEMBER(iqblockf_keyout_w); + DECLARE_WRITE8_MEMBER(iqblocka_remap_addr_w); + DECLARE_WRITE16_MEMBER(mgcs_magic_w); DECLARE_READ16_MEMBER(mgcs_magic_r); @@ -164,17 +592,9 @@ private: DECLARE_READ8_MEMBER(tjsb_input_r); DECLARE_READ8_MEMBER(spkrform_input_r); - DECLARE_READ16_MEMBER(lhzb2a_input_r); - DECLARE_WRITE16_MEMBER(lhzb2a_input_addr_w); DECLARE_WRITE16_MEMBER(lhzb2a_input_select_w); - - DECLARE_WRITE16_MEMBER(lhzb2a_prot_w); - DECLARE_READ16_MEMBER(lhzb2a_prot_r); - - DECLARE_WRITE16_MEMBER(lhzb2a_prot2_reset_w); - DECLARE_WRITE16_MEMBER(lhzb2a_prot2_inc_w); - DECLARE_WRITE16_MEMBER(lhzb2a_prot2_dec_w); - DECLARE_READ16_MEMBER(lhzb2a_prot2_r); + DECLARE_READ16_MEMBER(lhzb2a_input_r); + DECLARE_WRITE16_MEMBER(lhzb2a_remap_addr_w); DECLARE_WRITE16_MEMBER(lhzb2_magic_w); DECLARE_READ16_MEMBER(lhzb2_magic_r); @@ -191,10 +611,7 @@ private: TIMER_DEVICE_CALLBACK_MEMBER(mgcs_interrupt); TIMER_DEVICE_CALLBACK_MEMBER(mgdh_interrupt); - void decrypt_program_rom(int mask, int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0); - void iqblocka_patch_rom(); - void iqblockf_patch_rom(); void tjsb_decrypt_sprites(); void mgcs_decrypt_program_rom(); void mgcs_decrypt_tiles(); @@ -236,7 +653,6 @@ void igs017_state::machine_reset() Video Hardware ***************************************************************************/ - void igs017_state::video_start() { m_igs017_igs031->video_start(); @@ -275,7 +691,6 @@ uint16_t igs017_state::slqz2_palette_bitswap(uint16_t bgr) - /*************************************************************************** Decryption ***************************************************************************/ @@ -337,63 +752,13 @@ void igs017_state::decrypt_program_rom(int mask, int a7, int a6, int a5, int a4, } -// iqblocka - -void igs017_state::iqblocka_patch_rom() -{ - uint8_t *rom = memregion("maincpu")->base(); - -// rom[0x7b64] = 0xc9; - - rom[0x010c7] = 0x18; - - // CBEF bank 0a - rom[0x16bef] = 0x18; - - // C1BD bank 24 - rom[0x301bd] = 0x18; - - // C21B bank 2e - rom[0x3a21b] = 0x18; - - // DCA9 bank 2e - rom[0x3bca9] = 0x18; - - // maybe -// rom[0x18893] = 0x18; -// rom[0x385b1] = 0x18; -} +// iqblocka, iqblockf, genius6 DRIVER_INIT_MEMBER(igs017_state,iqblocka) { decrypt_program_rom(0x11, 7, 6, 5, 4, 3, 2, 1, 0); - iqblocka_patch_rom(); } -// iqblockf - -void igs017_state::iqblockf_patch_rom() // very preliminary -{ - uint8_t *rom = memregion("maincpu")->base(); - - rom[0x010d7] = 0x18; - - rom[0x1182c] = 0x18; - - rom[0x16887] = 0x18; - - rom[0x181bd] = 0x18; - - rom[0x2221b] = 0x18; - - rom[0x23c90] = 0x18; -} - -DRIVER_INIT_MEMBER(igs017_state,iqblockf) -{ - decrypt_program_rom(0x11, 7, 6, 5, 4, 3, 2, 1, 0); - iqblockf_patch_rom(); -} // tjsb @@ -614,6 +979,7 @@ DRIVER_INIT_MEMBER(igs017_state,tarzana) // tarzana_decrypt_tiles(); // to do } + // starzan // decryption is incomplete: data decryption is correct but opcodes are encrypted differently. @@ -787,7 +1153,6 @@ DRIVER_INIT_MEMBER(igs017_state,mgdh) // lhzb2 - void igs017_state::lhzb2_patch_rom() { uint16_t *rom = (uint16_t *)memregion("maincpu")->base(); @@ -845,8 +1210,6 @@ void igs017_state::igs025_to_igs022_callback( void ) m_igs022->IGS022_handle_command(); } - - DRIVER_INIT_MEMBER(igs017_state,lhzb2) { int i; @@ -946,7 +1309,7 @@ DRIVER_INIT_MEMBER(igs017_state,lhzb2) } -//lhzb2a +// lhzb2a DRIVER_INIT_MEMBER(igs017_state,lhzb2a) { @@ -1011,7 +1374,7 @@ DRIVER_INIT_MEMBER(igs017_state,lhzb2a) } -//slqz2 +// slqz2 void igs017_state::slqz2_patch_rom() { @@ -1127,6 +1490,7 @@ DRIVER_INIT_MEMBER(igs017_state,slqz2) // m_igs025->m_kb_game_id = 0x00060000; } + // spkrform void igs017_state::spkrform_decrypt_sprites() @@ -1156,13 +1520,12 @@ DRIVER_INIT_MEMBER(igs017_state,spkrform) spkrform_decrypt_sprites(); } + /*************************************************************************** Memory Maps ***************************************************************************/ - -// iqblocka - +// iqblocka, iqblockf, genius6 void igs017_state::iqblocka_map(address_map &map) { @@ -1177,48 +1540,57 @@ void igs017_state::decrypted_opcodes_map(address_map &map) map(0x00000, 0x3ffff).rom().share("decrypted_opcodes"); } - - WRITE8_MEMBER(igs017_state::input_select_w) { m_input_select = data; } -READ8_MEMBER(igs017_state::input_r) +WRITE8_MEMBER(igs017_state::iqblocka_keyin_w) { - switch (m_input_select) + machine().bookkeeping().coin_counter_w(0, data & 0x80); // key in (in gambling mode) +// popmessage("PORT0 %02X", data); + if ( data & ~0x80 ) + logerror("%s: warning, unknown bits written in keyin_w = %02x\n", machine().describe_context(), data); +} + +WRITE8_MEMBER(igs017_state::iqblockf_keyout_w) +{ + machine().bookkeeping().coin_counter_w(1, data & 0x80); // key out (in gambling mode, only iqblockf/genius6) +// popmessage("PORT1 %02X", data); + if ( data & ~0x80 ) + logerror("%s: warning, unknown bits written in keyout_w = %02x\n", machine().describe_context(), data); +} + +WRITE8_MEMBER(igs017_state::iqblocka_remap_addr_w) +{ + if (offset == 0) { - case 0x00: return ioport("PLAYER1")->read(); - case 0x01: return ioport("PLAYER2")->read(); - case 0x02: return ioport("COINS")->read(); + // Unmap previous address ranges + if (m_remap_addr != -1) + { + address_space &prg_space = m_maincpu->space(AS_PROGRAM); + prg_space.unmap_write ( m_remap_addr + 0x0, m_remap_addr + 0x0 ); + prg_space.unmap_write ( m_remap_addr + 0x1, m_remap_addr + 0x1 ); + prg_space.unmap_write ( m_remap_addr + 0x3, m_remap_addr + 0x3 ); + prg_space.unmap_read ( m_remap_addr + 0x5, m_remap_addr + 0x5 ); - case 0x03: return 01; + logerror("%s: incdec protection unmapped from %04x\n", machine().describe_context(), m_remap_addr); + } - case 0x20: return 0x49; - case 0x21: return 0x47; - case 0x22: return 0x53; + m_remap_addr = (m_remap_addr & 0xff00) | data; + } + else + { + m_remap_addr = (m_remap_addr & 0x00ff) | (data << 8); - case 0x24: return 0x41; - case 0x25: return 0x41; - case 0x26: return 0x7f; - case 0x27: return 0x41; - case 0x28: return 0x41; + // Add new memory ranges + address_space &prg_space = m_maincpu->space(AS_PROGRAM); + prg_space.install_write_handler ( m_remap_addr + 0x0, m_remap_addr + 0x0, write8_delegate(FUNC(igs_incdec_device::reset_w), &(*m_igs_incdec)) ); + prg_space.install_write_handler ( m_remap_addr + 0x1, m_remap_addr + 0x1, write8_delegate(FUNC(igs_incdec_device::dec_w), &(*m_igs_incdec)) ); + prg_space.install_write_handler ( m_remap_addr + 0x3, m_remap_addr + 0x3, write8_delegate(FUNC(igs_incdec_device::inc_w), &(*m_igs_incdec)) ); + prg_space.install_read_handler ( m_remap_addr + 0x5, m_remap_addr + 0x5, read8_delegate (FUNC(igs_incdec_device::val_r), &(*m_igs_incdec)) ); - case 0x2a: return 0x3e; - case 0x2b: return 0x41; - case 0x2c: return 0x49; - case 0x2d: return 0xf9; - case 0x2e: return 0x0a; - - case 0x30: return 0x26; - case 0x31: return 0x49; - case 0x32: return 0x49; - case 0x33: return 0x49; - case 0x34: return 0x32; - - default: - logerror("%s: input %02x read\n", machine().describe_context(), m_input_select); - return 0xff; + logerror("%s: incdec protection remapped at %04x\n", machine().describe_context(), m_remap_addr); } } @@ -1228,8 +1600,10 @@ void igs017_state::iqblocka_io(address_map &map) map(0x0000, 0x003f).ram(); // internal regs - map(0x8000, 0x8000).w(this, FUNC(igs017_state::input_select_w)); - map(0x8001, 0x8001).r(this, FUNC(igs017_state::input_r)); + map(0x2010, 0x2011).w(this, FUNC(igs017_state::iqblocka_remap_addr_w)); + + map(0x8000, 0x8000).w ("igs_bitswap", FUNC(igs_bitswap_device::address_w)); + map(0x8001, 0x8001).rw("igs_bitswap", FUNC(igs_bitswap_device::data_r), FUNC(igs_bitswap_device::data_w)); map(0x9000, 0x9000).rw(m_oki, FUNC(okim6295_device::read), FUNC(okim6295_device::write)); @@ -1494,8 +1868,6 @@ READ8_MEMBER(igs017_state::mgcs_keys_r) return 0xff; } - - void igs017_state::mgcs(address_map &map) { map(0x000000, 0x07ffff).rom(); @@ -1594,7 +1966,6 @@ void igs017_state::sdmg2(address_map &map) // mgdh, mgdha - READ8_MEMBER(igs017_state::mgdh_keys_r) { if (~m_input_select & 0x04) return ioport("KEY0")->read(); @@ -1708,7 +2079,6 @@ void igs017_state::mgdha_map(address_map &map) // tjsb - WRITE8_MEMBER(igs017_state::tjsb_output_w) { switch(m_input_select) @@ -1783,7 +2153,6 @@ void igs017_state::tjsb_io(address_map &map) // spkrform - void igs017_state::spkrform_map(address_map &map) { map(0x00000, 0x0dfff).rom(); @@ -1831,7 +2200,6 @@ void igs017_state::spkrform_io(address_map &map) // lhzb2 - WRITE16_MEMBER(igs017_state::lhzb2_magic_w) { COMBINE_DATA(&m_igs_magic[offset]); @@ -1906,236 +2274,6 @@ void igs017_state::lhzb2(address_map &map) // lhzb2a // To do: what devices are on this PCB? -/*************************************************************************** - - LHZB2A Protection (similar to that found in igs011.c) - - ---- Protection 1 (parametric bitswaps) ---- - - An address base register (xx = F0 at reset) determines where this protection device, - as well as game inputs and the address base register itself are mapped in memory: - inputs are mapped at xx8000, protection at xx4000 and base register at xxc000. - - The protection involves an internal 16-bit value (val), two mode registers - (mode_f = 0..f, mode_3 = 0..3) and 8 x 16-bit registers (word). - - The two modes affect the bitswap, and are set by loading the (same) mode-specific value - to all the word registers, and then writing to the mode_f or mode_3 trigger register. - - The bitswap of the internal value is then performed writing to one of 8 trigger registers, - according to the modes, trigger register and value written. - - The result is read through a fixed bitswap of the internal value. - - ---- Protection 2 (simple inc,dec + bitswapped read) ---- - - The chip holds an internal 8-bit value. It is manipulated by issuing commands, - where each command is assigned a specific address range, and is triggered - by writing FF to that range. Possible commands: - - - INC: increment value - - DEC: decrement value - - RESET: value = 0 - - The protection value is read from an additional address range: - - - READ: read bitswap(value). Only 4 bits are checked. - -***************************************************************************/ - -// Bitswap protection - -WRITE16_MEMBER(igs017_state::lhzb2a_prot_w) -{ - COMBINE_DATA(&m_prot_regs[offset]); - - if (offset == 0) - return; - - switch(m_prot_regs[0]) - { - case 0x40: // prot_word - { - m_prot_word = (m_prot_word << 8) | (m_prot_regs[1] & 0xff); - break; - } - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - // same value as reg 0x40 - break; - - case 0x48: // mode_f - { - switch (m_prot_word) - { - case 0x9a96: m_prot_mf = 0x0; break; - case 0x9a06: m_prot_mf = 0x1; break; - case 0x9a90: m_prot_mf = 0x2; break; - case 0x9a00: m_prot_mf = 0x3; break; - case 0x0a96: m_prot_mf = 0x4; break; - case 0x0a06: m_prot_mf = 0x5; break; - case 0x0a90: m_prot_mf = 0x6; break; - case 0x0a00: m_prot_mf = 0x7; break; - case 0x9096: m_prot_mf = 0x8; break; - case 0x9006: m_prot_mf = 0x9; break; - case 0x9090: m_prot_mf = 0xa; break; - case 0x9000: m_prot_mf = 0xb; break; - case 0x0096: m_prot_mf = 0xc; break; - case 0x0006: m_prot_mf = 0xd; break; - case 0x0090: m_prot_mf = 0xe; break; - case 0x0000: m_prot_mf = 0xf; break; - default: - m_prot_mf = 0; - logerror("%s: warning, setting mode_f with unknown prot_word = %02x\n", machine().describe_context(), m_prot_word); - return; - } - - logerror("%s: mode_f = %02x\n", machine().describe_context(), m_prot_mf); - break; - } - - case 0x50: // mode_3 - { - switch (m_prot_word & 0xff) - { - case 0x53: m_prot_m3 = 0x0; break; - case 0x03: m_prot_m3 = 0x1; break; - case 0x50: m_prot_m3 = 0x2; break; - case 0x00: m_prot_m3 = 0x3; break; - default: - m_prot_m3 = 0; - logerror("%s: warning, setting mode_3 with unknown prot_word = %02x\n", machine().describe_context(), m_prot_word); - return; - } - - logerror("%s: mode_3 = %02x\n", machine().describe_context(), m_prot_m3); - break; - } - - case 0x80: // do bitswap - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - { - uint16_t x = m_prot_val; - uint16_t mf = m_prot_mf; - - uint16_t bit0 = 0; - switch (m_prot_m3) - { - case 0: bit0 = BIT(~x,12) ^ BIT(~x,15) ^ BIT( x, 8) ^ BIT(~x, 3); break; - case 1: bit0 = BIT(~x, 6) ^ BIT(~x,15) ^ BIT(~x, 3) ^ BIT(~x, 9); break; - case 2: bit0 = BIT(~x, 3) ^ BIT(~x,15) ^ BIT(~x, 5) ^ BIT( x, 4); break; - case 3: bit0 = BIT(~x,15) ^ BIT(~x, 9) ^ BIT( x,12) ^ BIT(~x,11); break; - } - - uint16_t xor0 = BIT(m_prot_regs[1], m_prot_regs[0] - 0x80); - bit0 ^= xor0; - - m_prot_val = ( BIT( x,14) << 15 ) | - ( (BIT(~x,13) ^ BIT(mf,3)) << 14 ) | - ( BIT( x,12) << 13 ) | - ( BIT(~x,11) << 12 ) | - ( (BIT( x,10) ^ BIT(mf,2)) << 11 ) | - ( BIT( x, 9) << 10 ) | - ( BIT( x, 8) << 9 ) | - ( (BIT(~x, 7) ^ BIT(mf,1)) << 8 ) | - ( BIT( x, 6) << 7 ) | - ( BIT( x, 5) << 6 ) | - ( (BIT(~x, 4) ^ BIT(mf,0)) << 5 ) | - ( BIT(~x, 3) << 4 ) | - ( BIT( x, 2) << 3 ) | - ( BIT(~x, 1) << 2 ) | - ( BIT( x, 0) << 1 ) | - ( bit0 << 0 ) ; - - logerror("%s: exec bitswap - mode_3 %02x, mode_f %02x, xor0 %x, val %04x -> %04x\n", machine().describe_context(), m_prot_m3, m_prot_mf, xor0, x, m_prot_val); - - break; - } - - case 0xa0: // reset - { - m_prot_val = 0; - break; - } - - default: - logerror("%s: warning, writing to prot_reg %02x = %02x\n", machine().describe_context(), m_prot_regs[0], m_prot_regs[1]); - } -} - -READ16_MEMBER(igs017_state::lhzb2a_prot_r) -{ - switch(m_prot_regs[0]) - { - case 0x03: // result - { - uint16_t x = m_prot_val; - uint16_t res = (BIT(x, 5) << 7) | - (BIT(x, 2) << 6) | - (BIT(x, 9) << 5) | - (BIT(x, 7) << 4) | - (BIT(x,10) << 3) | - (BIT(x,13) << 2) | - (BIT(x,12) << 1) | - (BIT(x,15) << 0) ; - - logerror("%s: read bitswap - val %04x -> %02x\n", machine().describe_context(), m_prot_val, res); - return res; - } - - default: - logerror("%s: warning, reading with prot_reg = %02x\n", machine().describe_context(), m_prot_regs[0]); - break; - } - - return 0xffff; -} - -// Protection 2 - -WRITE16_MEMBER(igs017_state::lhzb2a_prot2_reset_w) -{ - m_prot2 = 0x00; - logerror("%s: prot2 reset -> %02x\n", machine().describe_context(), m_prot2); -} - -WRITE16_MEMBER(igs017_state::lhzb2a_prot2_inc_w) -{ - m_prot2++; - logerror("%s: prot2 inc -> %02x\n", machine().describe_context(), m_prot2); -} - -WRITE16_MEMBER(igs017_state::lhzb2a_prot2_dec_w) -{ - m_prot2--; - logerror("%s: prot2 dec -> %02x\n", machine().describe_context(), m_prot2); -} - -READ16_MEMBER(igs017_state::lhzb2a_prot2_r) -{ - uint8_t x = m_prot2; - uint8_t res = (BIT(x, 0) << 7) | - (BIT(x, 3) << 5) | - (BIT(x, 2) << 4) | - (BIT(x, 1) << 2) ; - - logerror("%s: prot2 read, %02x -> %02x\n", machine().describe_context(), m_prot2, res); - return res; -} - - - READ16_MEMBER(igs017_state::lhzb2a_input_r) { switch (offset*2) @@ -2165,24 +2303,36 @@ READ16_MEMBER(igs017_state::lhzb2a_input_r) return 0xffff; } -WRITE16_MEMBER(igs017_state::lhzb2a_input_addr_w) +/*************************************************************************** + + An address base register (xx = F0 at reset) determines where the bitswap protection device, + as well as game inputs and the address base register itself are mapped in memory: + inputs are mapped at xx8000, protection at xx4000 and base register at xxc000. + +***************************************************************************/ + +WRITE16_MEMBER(igs017_state::lhzb2a_remap_addr_w) { // Unmap previous address ranges - if (m_input_addr != -1) + if (m_remap_addr != -1) { - space.unmap_readwrite(m_input_addr * 0x10000 + 0x4000, m_input_addr * 0x10000 + 0x4003); - space.unmap_read (m_input_addr * 0x10000 + 0x8000, m_input_addr * 0x10000 + 0x8005); - space.unmap_write (m_input_addr * 0x10000 + 0xc000, m_input_addr * 0x10000 + 0xc001); + space.unmap_write ( m_remap_addr * 0x10000 + 0x4000, m_remap_addr * 0x10000 + 0x4001 ); + space.unmap_readwrite ( m_remap_addr * 0x10000 + 0x4002, m_remap_addr * 0x10000 + 0x4003 ); + + space.unmap_read ( m_remap_addr * 0x10000 + 0x8000, m_remap_addr * 0x10000 + 0x8005 ); + space.unmap_write ( m_remap_addr * 0x10000 + 0xc000, m_remap_addr * 0x10000 + 0xc001 ); } - m_input_addr = data & 0xff; + m_remap_addr = data & 0xff; // Add new memory ranges - space.install_readwrite_handler (m_input_addr * 0x10000 + 0x4000, m_input_addr * 0x10000 + 0x4003, read16_delegate (FUNC(igs017_state::lhzb2a_prot_r), this), write16_delegate (FUNC(igs017_state::lhzb2a_prot_w), this)); - space.install_read_handler (m_input_addr * 0x10000 + 0x8000, m_input_addr * 0x10000 + 0x8005, read16_delegate (FUNC(igs017_state::lhzb2a_input_r), this)); - space.install_write_handler (m_input_addr * 0x10000 + 0xc000, m_input_addr * 0x10000 + 0xc001, write16_delegate(FUNC(igs017_state::lhzb2a_input_addr_w), this)); + space.install_write_handler ( m_remap_addr * 0x10000 + 0x4001, m_remap_addr * 0x10000 + 0x4001, write8_delegate(FUNC(igs_bitswap_device::address_w), &(*m_igs_bitswap)) ); + space.install_readwrite_handler ( m_remap_addr * 0x10000 + 0x4003, m_remap_addr * 0x10000 + 0x4003, read8_delegate (FUNC(igs_bitswap_device::data_r), &(*m_igs_bitswap)), write8_delegate(FUNC(igs_bitswap_device::data_w), &(*m_igs_bitswap)) ); - logerror("%s: inputs and protection remapped at %02xxxxx\n", machine().describe_context(), m_input_addr); + space.install_read_handler ( m_remap_addr * 0x10000 + 0x8000, m_remap_addr * 0x10000 + 0x8005, read16_delegate (FUNC(igs017_state::lhzb2a_input_r), this) ); + space.install_write_handler ( m_remap_addr * 0x10000 + 0xc000, m_remap_addr * 0x10000 + 0xc001, write16_delegate(FUNC(igs017_state::lhzb2a_remap_addr_w), this) ); + + logerror("%s: inputs and protection remapped at %02xxxxx\n", machine().describe_context(), m_remap_addr); } WRITE16_MEMBER(igs017_state::lhzb2a_input_select_w) @@ -2207,11 +2357,11 @@ void igs017_state::lhzb2a(address_map &map) { map(0x000000, 0x07ffff).rom(); - // prot2 - map(0x003200, 0x003201).w(this, FUNC(igs017_state::lhzb2a_prot2_reset_w)); - map(0x003202, 0x003203).w(this, FUNC(igs017_state::lhzb2a_prot2_dec_w)); - map(0x003206, 0x003207).w(this, FUNC(igs017_state::lhzb2a_prot2_inc_w)); - map(0x00320a, 0x00320b).r(this, FUNC(igs017_state::lhzb2a_prot2_r)); + // incdec protection + map(0x003200, 0x003201).w(m_igs_incdec, FUNC(igs_incdec_device::reset_w)); + map(0x003202, 0x003203).w(m_igs_incdec, FUNC(igs_incdec_device::dec_w)); + map(0x003206, 0x003207).w(m_igs_incdec, FUNC(igs_incdec_device::inc_w)); + map(0x00320a, 0x00320b).r(m_igs_incdec, FUNC(igs_incdec_device::val_r)); map(0x500000, 0x503fff).ram(); // AM_RANGE(0x910000, 0x910003) accesses appear to be from leftover code where the final checks were disabled @@ -2220,13 +2370,13 @@ void igs017_state::lhzb2a(address_map &map) map(0xb10001, 0xb10001).rw(m_oki, FUNC(okim6295_device::read), FUNC(okim6295_device::write)); map(0xb12000, 0xb12001).w(this, FUNC(igs017_state::lhzb2a_input_select_w)); -// Inputs dynamically mapped at xx8000, protection at xx4000 (xx = f0 initially). xx written to xxc000 + + // Inputs dynamically mapped at xx8000, protection at xx4000 (xx = f0 initially). xx written to xxc000 } // slqz2 - WRITE16_MEMBER(igs017_state::slqz2_magic_w) { COMBINE_DATA(&m_igs_magic[offset]); @@ -2283,7 +2433,6 @@ void igs017_state::slqz2(address_map &map) map(0x900000, 0x90ffff).rw(m_igs017_igs031, FUNC(igs017_igs031_device::read), FUNC(igs017_igs031_device::write)).umask16(0x00ff); - map(0x910001, 0x910001).rw(m_oki, FUNC(okim6295_device::read), FUNC(okim6295_device::write)); } @@ -2293,7 +2442,6 @@ void igs017_state::slqz2(address_map &map) ***************************************************************************/ static INPUT_PORTS_START( iqblocka ) - PORT_START("DSW1") PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) @@ -2335,7 +2483,7 @@ static INPUT_PORTS_START( iqblocka ) PORT_DIPNAME( 0x10, 0x10, "Open Mode" ) PORT_DIPSETTING( 0x10, "Gaming" ) PORT_DIPSETTING( 0x00, "Amuse" ) - PORT_DIPNAME( 0x20, 0x20, "Demo Game" ) + PORT_DIPNAME( 0x20, 0x00, "Demo Game" ) PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0xc0, 0xc0, "Bonus Base" ) @@ -2361,7 +2509,7 @@ static INPUT_PORTS_START( iqblocka ) PORT_DIPNAME( 0x20, 0x20, "Title Name" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x40, "Double" ) + PORT_DIPNAME( 0x40, 0x40, "Double Up" ) PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x40, DEF_STR( On ) ) PORT_DIPNAME( 0x80, 0x80, "CG Select" ) @@ -2369,49 +2517,182 @@ static INPUT_PORTS_START( iqblocka ) PORT_DIPSETTING( 0x00, DEF_STR( High ) ) PORT_START("PLAYER1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME( "Start / Test" ) // keep pressed while booting + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME( "Start" ) // start, in videogame mode (keep pressed while booting for DSW and inputs test) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_NAME( "Down / Collect Win" ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Help / Big" ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Hold 1 / Big / Help" ) // help = next tile becomes a wildcard (in videogame mode) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Hold 2 / Double Up" ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("PLAYER2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME( "Bet" ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME( "Play / Last Bet" ) // play current bet or, if null, bet as last time (2P C in test mode) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) // unused? shown in test mode + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) // "" + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) // "" + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) // "" + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME( "Hold 4 / Half Double" ) // (2P A in test mode) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME( "Hold 5 / Tile in Double Up?" ) // (2P B in test mode) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("COINS") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_SERVICE_NO_TOGGLE( 0x40, IP_ACTIVE_LOW ) // keep pressed while booting - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE1 ) // this seems to toggle between videogame and gambling + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(5) // impulse prevents coin error in gambling mode + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_SERVICE_NO_TOGGLE( 0x40, IP_ACTIVE_LOW ) // keep pressed while booting + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME( "Toggle Gambling" ) // this toggles between videogame and gambling PORT_START("BUTTONS") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Small" ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_IMPULSE(2) // coin error - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME( "Score -> Time" ) // converts score into time - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Hold 3 / Small" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(5) // no coin. Hopper sensor? impulse prevents coin error in gambling mode (1P D in test mode) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) // unused? (1P E in test mode) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START3 ) PORT_NAME( "Bet" ) // Bet 1 credit (2P C in test mode) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) // unused? (2P D in test mode) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) // unused? (2P E in test mode) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) +INPUT_PORTS_END +static INPUT_PORTS_START( iqblockf ) + PORT_INCLUDE( iqblocka ) + + PORT_MODIFY("DSW1") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, "Hold Mode" ) + PORT_DIPSETTING( 0x02, "In Win" ) + PORT_DIPSETTING( 0x00, "Always" ) + PORT_DIPNAME( 0x0c, 0x0c, "Coin In" ) + PORT_DIPSETTING( 0x0c, "1" ) + PORT_DIPSETTING( 0x08, "5" ) + PORT_DIPSETTING( 0x04, "10" ) + PORT_DIPSETTING( 0x00, "20" ) + PORT_DIPNAME( 0x30, 0x30, "Key In" ) + PORT_DIPSETTING( 0x30, "10" ) + PORT_DIPSETTING( 0x20, "100" ) + PORT_DIPSETTING( 0x10, "200" ) + PORT_DIPSETTING( 0x00, "500" ) + PORT_DIPNAME( 0xc0, 0xc0, "Min Bet" ) + PORT_DIPSETTING( 0xc0, "1" ) + PORT_DIPSETTING( 0x80, "2" ) + PORT_DIPSETTING( 0x40, "5" ) + PORT_DIPSETTING( 0x00, "10" ) + + PORT_MODIFY("DSW2") + PORT_DIPNAME( 0x03, 0x03, "Max Bet" ) + PORT_DIPSETTING( 0x03, "5" ) + PORT_DIPSETTING( 0x02, "10" ) + PORT_DIPSETTING( 0x01, "20" ) + PORT_DIPSETTING( 0x00, "50" ) + PORT_DIPNAME( 0x04, 0x04, "Register" ) + PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x08, 0x08, "Key Out Base" ) + PORT_DIPSETTING( 0x08, "1" ) + PORT_DIPSETTING( 0x00, "10" ) + PORT_DIPNAME( 0x10, 0x10, "Open Mode" ) + PORT_DIPSETTING( 0x10, "Gaming" ) + PORT_DIPSETTING( 0x00, "Amuse" ) + PORT_DIPNAME( 0x20, 0x00, "Demo Game" ) + PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPUNUSED( 0x40, 0x40 ) + PORT_DIPUNUSED( 0x80, 0x80 ) + + PORT_MODIFY("DSW3") + PORT_DIPUNUSED( 0x01, 0x01 ) + PORT_DIPUNUSED( 0x02, 0x02 ) + PORT_DIPUNUSED( 0x04, 0x04 ) + PORT_DIPUNUSED( 0x08, 0x08 ) + PORT_DIPNAME( 0x10, 0x10, "Cards" ) + PORT_DIPSETTING( 0x10, "A,J,Q,K" ) + PORT_DIPSETTING( 0x00, "Number" ) + PORT_DIPUNUSED( 0x20, 0x20 ) + PORT_DIPUNUSED( 0x40, 0x40 ) + PORT_DIPNAME( 0x80, 0x80, "CG Select" ) + PORT_DIPSETTING( 0x80, DEF_STR( Low ) ) + PORT_DIPSETTING( 0x00, DEF_STR( High ) ) + + PORT_MODIFY("PLAYER2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME( "Play / Last Bet / Toggle Gambling (8 Times)" ) // play current bet or, if null, bet as last time (2P C in test mode) + + PORT_MODIFY("COINS") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(5) // impulse prevents coin error in gambling mode + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) + // + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME( "Start Gambling Toggle" ) // this starts toggling between videogame and gambling + + PORT_MODIFY("BUTTONS") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) // (2P E in test mode) +INPUT_PORTS_END + +static INPUT_PORTS_START( genius6 ) + PORT_INCLUDE( iqblockf ) + + PORT_MODIFY("DSW1") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Demo_Sounds ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, "Auto Hold" ) + PORT_DIPSETTING( 0x02, DEF_STR( No ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x0c, 0x0c, "Coin In" ) + PORT_DIPSETTING( 0x0c, "1" ) + PORT_DIPSETTING( 0x08, "10" ) + PORT_DIPSETTING( 0x04, "20" ) + PORT_DIPSETTING( 0x00, "50" ) + PORT_DIPNAME( 0x30, 0x30, "Key In" ) + PORT_DIPSETTING( 0x30, "10" ) + PORT_DIPSETTING( 0x20, "100" ) + PORT_DIPSETTING( 0x10, "200" ) + PORT_DIPSETTING( 0x00, "500" ) + PORT_DIPNAME( 0xc0, 0xc0, "Min Bet" ) + PORT_DIPSETTING( 0xc0, "1" ) + PORT_DIPSETTING( 0x80, "2" ) + PORT_DIPSETTING( 0x40, "5" ) + PORT_DIPSETTING( 0x00, "10" ) + + PORT_MODIFY("DSW2") + PORT_DIPNAME( 0x03, 0x03, "Max Bet" ) + PORT_DIPSETTING( 0x03, "5" ) + PORT_DIPSETTING( 0x02, "10" ) + PORT_DIPSETTING( 0x01, "20" ) + PORT_DIPSETTING( 0x00, "50" ) + PORT_DIPUNUSED( 0x04, 0x04 ) + PORT_DIPNAME( 0x08, 0x08, "Key Out" ) + PORT_DIPSETTING( 0x08, "1" ) + PORT_DIPSETTING( 0x00, "10" ) + PORT_DIPNAME( 0x10, 0x10, "Open Mode" ) + PORT_DIPSETTING( 0x10, "Gaming" ) + PORT_DIPSETTING( 0x00, "Amuse" ) + PORT_DIPNAME( 0x20, 0x00, "Demo Game" ) + PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPUNUSED( 0x40, 0x40 ) + PORT_DIPUNUSED( 0x80, 0x80 ) + + PORT_MODIFY("DSW3") + PORT_DIPUNUSED( 0x01, 0x01 ) + PORT_DIPUNUSED( 0x02, 0x02 ) + PORT_DIPUNUSED( 0x04, 0x04 ) + PORT_DIPUNUSED( 0x08, 0x08 ) + PORT_DIPNAME( 0x10, 0x10, "Cards" ) + PORT_DIPSETTING( 0x10, "A,J,Q,K" ) + PORT_DIPSETTING( 0x00, "Number" ) + PORT_DIPUNUSED( 0x20, 0x20 ) + PORT_DIPUNUSED( 0x40, 0x40 ) + PORT_DIPUNUSED( 0x80, 0x80 ) + + PORT_MODIFY("PLAYER2") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME( "Hold 5" ) // (2P B in test mode) INPUT_PORTS_END static INPUT_PORTS_START( lhzb2 ) - PORT_START("DSW1") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) @@ -2519,11 +2800,9 @@ static INPUT_PORTS_START( lhzb2 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - INPUT_PORTS_END static INPUT_PORTS_START( lhzb2a ) - PORT_START("DSW1") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) @@ -2577,7 +2856,7 @@ static INPUT_PORTS_START( lhzb2a ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_CUSTOM ) // hopper switch PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) // keep pressed while booting PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Statistics") // press with the above for sound test - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(5) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Pay Out") PORT_CODE(KEYCODE_O) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE3 ) // shown in test mode PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -2631,11 +2910,9 @@ static INPUT_PORTS_START( lhzb2a ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - INPUT_PORTS_END static INPUT_PORTS_START( mgcs ) - // DSWs are read through a protection device (IGS029). See code at 1CF16 PORT_START("DSW1") // $3009e2 @@ -2745,11 +3022,9 @@ static INPUT_PORTS_START( mgcs ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - INPUT_PORTS_END static INPUT_PORTS_START( sdmg2 ) - PORT_START("DSW1") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) @@ -2872,11 +3147,9 @@ static INPUT_PORTS_START( sdmg2 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - INPUT_PORTS_END static INPUT_PORTS_START( mgdh ) - PORT_START("DSW1") PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) @@ -3005,11 +3278,9 @@ static INPUT_PORTS_START( mgdh ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) - INPUT_PORTS_END static INPUT_PORTS_START( slqz2 ) - PORT_START("DSW1") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) @@ -3097,11 +3368,9 @@ static INPUT_PORTS_START( slqz2 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("0") PORT_CODE(KEYCODE_6_PAD) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("0") PORT_CODE(KEYCODE_7_PAD) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("0") PORT_CODE(KEYCODE_8_PAD) - INPUT_PORTS_END static INPUT_PORTS_START( tjsb ) - PORT_START("DSW1") PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coinage ) ) PORT_DIPSETTING( 0x03, DEF_STR( 1C_1C ) ) @@ -3194,12 +3463,10 @@ static INPUT_PORTS_START( tjsb ) PORT_BIT( 0x20, IP_ACTIVE_HIGH,IPT_CUSTOM ) // hopper switch PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - INPUT_PORTS_END // to do: static INPUT_PORTS_START( spkrform ) - PORT_START("DSW1") PORT_DIPUNKNOWN( 0x01, 0x01 ) PORT_DIPUNKNOWN( 0x02, 0x02 ) @@ -3282,11 +3549,9 @@ static INPUT_PORTS_START( spkrform ) PORT_DIPNAME( 0xff, 0xff, "A001" ) PORT_DIPSETTING( 0xff, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - INPUT_PORTS_END - /*************************************************************************** Machine Drivers ***************************************************************************/ @@ -3302,7 +3567,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(igs017_state::iqblocka_interrupt) m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); } - MACHINE_RESET_MEMBER(igs017_state,iqblocka) { m_input_select = 0; @@ -3314,14 +3578,30 @@ MACHINE_CONFIG_START(igs017_state::iqblocka) MCFG_CPU_IO_MAP(iqblocka_io) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", igs017_state, iqblocka_interrupt, "screen", 0, 1) + MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) + + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW2")) MCFG_I8255_IN_PORTC_CB(IOPORT("DSW3")) - MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) + // protection + MCFG_DEVICE_ADD("igs_bitswap", IGS_BITSWAP, 0) + MCFG_IGS_BITSWAP_IN_PORTA_CB(IOPORT("PLAYER1")) + MCFG_IGS_BITSWAP_IN_PORTB_CB(IOPORT("PLAYER2")) + MCFG_IGS_BITSWAP_IN_PORTC_CB(IOPORT("COINS")) + MCFG_IGS_BITSWAP_OUT_PORTA_CB(WRITE8(igs017_state, iqblocka_keyin_w)) + MCFG_IGS_BITSWAP_VAL_XOR(0x15d6) + MCFG_IGS_BITSWAP_MF_BITS(3, 5, 9, 11) + MCFG_IGS_BITSWAP_M3_0_BITS(~5, 8, ~10, ~15) + MCFG_IGS_BITSWAP_M3_1_BITS( 3, ~8, ~12, ~15) + MCFG_IGS_BITSWAP_M3_2_BITS( 2, ~6, ~11, ~15) + MCFG_IGS_BITSWAP_M3_3_BITS( 0, ~1, ~3, ~15) - /* video hardware */ + MCFG_DEVICE_ADD("igs_incdec", IGS_INCDEC, 0) + + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3333,11 +3613,10 @@ MACHINE_CONFIG_START(igs017_state::iqblocka) MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) - MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) MCFG_GFX_PALETTE("palette") - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ymsnd", YM2413, XTAL(3'579'545)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) @@ -3346,6 +3625,23 @@ MACHINE_CONFIG_START(igs017_state::iqblocka) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END +MACHINE_CONFIG_START(igs017_state::iqblockf) + iqblocka(config); + MCFG_DEVICE_MODIFY("igs_bitswap") // tweaked protection bitswap + MCFG_IGS_BITSWAP_OUT_PORTB_CB(WRITE8(igs017_state, iqblockf_keyout_w)) + MCFG_IGS_BITSWAP_MF_BITS(0, 5, 9, 13) +MACHINE_CONFIG_END + +MACHINE_CONFIG_START(igs017_state::genius6) + iqblockf(config); + MCFG_DEVICE_MODIFY("igs_bitswap") // tweaked protection bitswap + MCFG_IGS_BITSWAP_MF_BITS(2, 7, 9, 13) + MCFG_IGS_BITSWAP_M3_0_BITS(~5, 6, ~7, ~15) + MCFG_IGS_BITSWAP_M3_1_BITS( 1, ~6, ~9, ~15) + MCFG_IGS_BITSWAP_M3_2_BITS( 4, ~8, ~12, ~15) + MCFG_IGS_BITSWAP_M3_3_BITS( 3, ~5, ~6, ~15) +MACHINE_CONFIG_END + MACHINE_CONFIG_START(igs017_state::starzan) iqblocka(config); MCFG_DEVICE_MODIFY("maincpu") @@ -3381,13 +3677,14 @@ MACHINE_CONFIG_START(igs017_state::mgcs) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,mgcs) + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("COINS")) MCFG_I8255_IN_PORTB_CB(READ8(igs017_state, mgcs_keys_r)) MCFG_TICKET_DISPENSER_ADD("hopper", attotime::from_msec(50), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_LOW ) - /* video hardware */ + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3400,17 +3697,16 @@ MACHINE_CONFIG_START(igs017_state::mgcs) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( igs017_state, mgcs_palette_bitswap ) MCFG_GFX_PALETTE("palette") - MCFG_PALETTE_SCRAMBLE_CB( igs017_state, mgcs_palette_bitswap ) - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(8'000'000) / 8, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END - // lhzb2 MACHINE_CONFIG_START(igs017_state::lhzb2) @@ -3420,12 +3716,19 @@ MACHINE_CONFIG_START(igs017_state::lhzb2) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,mgcs) + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("COINS")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTC_CB(IOPORT("DSW2")) - /* video hardware */ + // protection + MCFG_DEVICE_ADD("igs025", IGS025, 0) + MCFG_IGS025_SET_EXTERNAL_EXECUTE( igs017_state, igs025_to_igs022_callback ) + + MCFG_DEVICE_ADD("igs022", IGS022, 0) + + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3434,35 +3737,26 @@ MACHINE_CONFIG_START(igs017_state::lhzb2) MCFG_SCREEN_UPDATE_DRIVER(igs017_state, screen_update_igs017) MCFG_SCREEN_PALETTE("palette") - MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( igs017_state, lhzb2a_palette_bitswap ) MCFG_GFX_PALETTE("palette") - MCFG_PALETTE_SCRAMBLE_CB( igs017_state, lhzb2a_palette_bitswap ) - // protection - 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 */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(8'000'000) / 8, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END - // lhzb2a MACHINE_RESET_MEMBER(igs017_state,lhzb2a) { MACHINE_RESET_CALL_MEMBER( mgcs ); - lhzb2a_input_addr_w(m_maincpu->space(AS_PROGRAM), 0, 0xf0); + lhzb2a_remap_addr_w(m_maincpu->space(AS_PROGRAM), 0, 0xf0); } MACHINE_CONFIG_START(igs017_state::lhzb2a) @@ -3472,9 +3766,21 @@ MACHINE_CONFIG_START(igs017_state::lhzb2a) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,lhzb2a) -// MCFG_I8255A_ADD( "ppi8255", sdmg2_ppi8255_intf ) + // i/o +// MCFG_DEVICE_ADD("ppi8255", I8255A, 0) - /* video hardware */ + // protection + MCFG_DEVICE_ADD("igs_bitswap", IGS_BITSWAP, 0) + MCFG_IGS_BITSWAP_VAL_XOR(0x289a) + MCFG_IGS_BITSWAP_MF_BITS(4, 7, 10, 13) + MCFG_IGS_BITSWAP_M3_0_BITS(~3, 8, ~12, ~15) + MCFG_IGS_BITSWAP_M3_1_BITS(~3, ~6, ~9, ~15) + MCFG_IGS_BITSWAP_M3_2_BITS(~3, 4, ~5, ~15) + MCFG_IGS_BITSWAP_M3_3_BITS(~9, ~11, 12, ~15) + + MCFG_DEVICE_ADD("igs_incdec", IGS_INCDEC, 0) + + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) // VSync 60Hz, HSync 15.3kHz MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3483,23 +3789,20 @@ MACHINE_CONFIG_START(igs017_state::lhzb2a) MCFG_SCREEN_UPDATE_DRIVER(igs017_state, screen_update_igs017) MCFG_SCREEN_PALETTE("palette") - MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) - MCFG_GFX_PALETTE("palette") - MCFG_PALETTE_SCRAMBLE_CB( igs017_state, lhzb2a_palette_bitswap ) - - MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) + MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( igs017_state, lhzb2a_palette_bitswap ) + MCFG_GFX_PALETTE("palette") - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(22'000'000) / 22, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END - // slqz2 MACHINE_CONFIG_START(igs017_state::slqz2) @@ -3509,12 +3812,19 @@ MACHINE_CONFIG_START(igs017_state::slqz2) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,mgcs) + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("COINS")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTC_CB(IOPORT("DSW2")) - /* video hardware */ + // protection + MCFG_DEVICE_ADD("igs025", IGS025, 0) + MCFG_IGS025_SET_EXTERNAL_EXECUTE( igs017_state, igs025_to_igs022_callback ) + + MCFG_DEVICE_ADD("igs022", IGS022, 0) + + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3527,23 +3837,16 @@ MACHINE_CONFIG_START(igs017_state::slqz2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( igs017_state, slqz2_palette_bitswap ) MCFG_GFX_PALETTE("palette") - MCFG_PALETTE_SCRAMBLE_CB( igs017_state, slqz2_palette_bitswap ) - // protection - 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 */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(8'000'000) / 8, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END - // sdmg2 MACHINE_CONFIG_START(igs017_state::sdmg2) @@ -3553,11 +3856,12 @@ MACHINE_CONFIG_START(igs017_state::sdmg2) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,mgcs) + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW2")) - /* video hardware */ + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) // VSync 60Hz, HSync 15.3kHz MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3566,15 +3870,13 @@ MACHINE_CONFIG_START(igs017_state::sdmg2) MCFG_SCREEN_UPDATE_DRIVER(igs017_state, screen_update_igs017) MCFG_SCREEN_PALETTE("palette") - MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) - MCFG_GFX_PALETTE("palette") - - MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) + MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_GFX_PALETTE("palette") - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(22'000'000) / 22, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) @@ -3601,10 +3903,11 @@ MACHINE_CONFIG_START(igs017_state::mgdha) MCFG_MACHINE_RESET_OVERRIDE(igs017_state,mgcs) + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1")) - /* video hardware */ + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3613,15 +3916,13 @@ MACHINE_CONFIG_START(igs017_state::mgdha) MCFG_SCREEN_UPDATE_DRIVER(igs017_state, screen_update_igs017) MCFG_SCREEN_PALETTE("palette") - MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) - MCFG_GFX_PALETTE("palette") - - MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) + MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_GFX_PALETTE("palette") - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_OKIM6295_ADD("oki", XTAL(22'000'000) / 22, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) @@ -3636,14 +3937,15 @@ MACHINE_CONFIG_START(igs017_state::tjsb) MCFG_CPU_IO_MAP(tjsb_io) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", igs017_state, iqblocka_interrupt, "screen", 0, 1) + MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) + + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW2")) MCFG_I8255_IN_PORTC_CB(IOPORT("DSW3")) - MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) - - /* video hardware */ + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3652,16 +3954,14 @@ MACHINE_CONFIG_START(igs017_state::tjsb) MCFG_SCREEN_UPDATE_DRIVER(igs017_state, screen_update_igs017) MCFG_SCREEN_PALETTE("palette") - MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) - MCFG_GFX_PALETTE("palette") - MCFG_PALETTE_SCRAMBLE_CB( igs017_state, tjsb_palette_bitswap ) - - MCFG_PALETTE_ADD("palette", 0x100*2) MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB) + MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( igs017_state, tjsb_palette_bitswap ) + MCFG_GFX_PALETTE("palette") - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ymsnd", YM2413, XTAL(3'579'545)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) @@ -3679,14 +3979,15 @@ MACHINE_CONFIG_START(igs017_state::spkrform) MCFG_CPU_IO_MAP(spkrform_io) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", igs017_state, iqblocka_interrupt, "screen", 0, 1) + MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) + + // i/o MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1")) MCFG_I8255_IN_PORTB_CB(IOPORT("DSW2")) MCFG_I8255_IN_PORTC_CB(IOPORT("DSW3")) - MCFG_MACHINE_RESET_OVERRIDE(igs017_state,iqblocka) - - /* video hardware */ + // video MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) @@ -3701,8 +4002,7 @@ MACHINE_CONFIG_START(igs017_state::spkrform) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) MCFG_GFX_PALETTE("palette") - - /* sound hardware */ + // sound MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ymsnd", YM2413, XTAL(3'579'545)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) @@ -3716,10 +4016,11 @@ MACHINE_CONFIG_END ROMs Loading ***************************************************************************/ +// These are newer versions of IQ-Block (see iqblock.cpp) with added gambling + /*************************************************************************** -IQ Block (alt hardware) -數字樂園 (Shùzì Lèyuán) +數字樂園 (Shùzì Lèyuán, V127M) IGS, 1996 PCB Layout @@ -3775,6 +4076,8 @@ ROM_START( iqblocka ) ROM_LOAD( "speech.u17", 0x00000, 0x40000, CRC(d9e3d39f) SHA1(bec85d1ac2dfca77453cbca0e7dd53fee8fb438b) ) ROM_END +// English title (IQ Block) and year 1997: + ROM_START( iqblockf ) ROM_REGION( 0x40000, "maincpu", 0 ) ROM_LOAD( "v113fr.u18", 0x00000, 0x40000, CRC(346c68af) SHA1(ceae4c0143c288dc9c1dd1e8a51f1e3371ffa439) ) @@ -3789,6 +4092,38 @@ ROM_START( iqblockf ) ROM_LOAD( "sp.u17", 0x00000, 0x40000, CRC(71357845) SHA1(25f4f7aebdcc0706018f041d3696322df569b0a3) ) ROM_END +/*************************************************************************** + +Genius 6 +IGS, 1998 + +IGS PCB N0- 0131-4 +|---------------------------------------| +|uPD1242H VOL U3567 3.579545MHz| +| K668 | +| Z8018008PSC | +| 16MHz BATTERY| +| | +| SPEECH.U17 | +| | +|J 6264 | +|A | +|M IGS003c V-110F.U18 | +|M | +|A | +| | +| | +| |-------| | +| | | | +| CG.U7 |IGS017 | | +| | | | +| TEXT.U8 |-------| PAL | +| 22MHz 61256 | +| DSW1 DSW2 DSW3 | +|---------------------------------------| + +***************************************************************************/ + ROM_START( genius6 ) ROM_REGION( 0x40000, "maincpu", 0 ) ROM_LOAD( "genius6_v110f.u18", 0x00000, 0x40000, CRC(2630ad44) SHA1(37002fa913ad60c59145f5a7692eef8862b9d6eb) ) @@ -3872,13 +4207,12 @@ Mahjong Man Guan Caishen 满贯财神 (Mǎn Guàn Cáishén) IGS, 1998 - PCB Layout ---------- IGS PCB NO-0192-1 |---------------------------------------| -| JAMMA UPC1242 | +| JAMMA uPC1242 | | | | S1502.U10 | | K668 VOL | @@ -3930,13 +4264,12 @@ ROM_END Mahjong Super Da Man Guan 2 IGS, 1997 - PCB Layout ---------- IGS PCB NO-0147-6 |---------------------------------------| -| UPC1242H S0903.U15 BATTERY | +| uPC1242H S0903.U15 BATTERY | | VOL SPDT_SW | | | | K668 6264 | @@ -4227,7 +4560,7 @@ IGS PCB NO-0248-1 |0 DSW3 | |W BATT | |A VOL LM7805 RES_SW| -|Y UPC1242 M6295 U14 | +|Y uPC1242 M6295 U14 | |------------------------------| Notes: IGS025 - custom IGS chip labelled 'TARZAN 1' @@ -4405,13 +4738,13 @@ ROM_START( spkrform ) ROM_END -GAME( 1996, iqblocka, iqblock, iqblocka, iqblocka, igs017_state, iqblocka, ROT0, "IGS", "Shuzi Leyuan (V127M)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // hangs at game over -GAME( 1997, iqblockf, iqblock, iqblocka, iqblocka, igs017_state, iqblockf, ROT0, "IGS", "Shuzi Leyuan (V113FR)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // hangs at game over -GAME( 1997, mgdh, 0, mgdha, mgdh, igs017_state, mgdh, ROT0, "IGS", "Mahjong Man Guan Daheng (Taiwan, V125T1)", 0 ) +GAME( 1996, iqblocka, iqblock, iqblocka, iqblocka, igs017_state, iqblocka, ROT0, "IGS", "Shuzi Leyuan (V127M, Gambling)", 0 ) +GAME( 1997, iqblockf, iqblock, iqblockf, iqblockf, igs017_state, iqblocka, ROT0, "IGS", "IQ Block (V113FR, Gambling)", 0 ) +GAME( 1997, mgdh, 0, mgdha, mgdh, igs017_state, mgdh, ROT0, "IGS", "Mahjong Man Guan Daheng (Taiwan, V125T1)", MACHINE_IMPERFECT_COLORS ) // wrong colors in betting screen GAME( 1997, mgdha, mgdh, mgdha, mgdh , igs017_state, mgdha, ROT0, "IGS", "Mahjong Man Guan Daheng (Taiwan, V123T1)", 0 ) GAME( 1997, sdmg2, 0, sdmg2, sdmg2, igs017_state, sdmg2, ROT0, "IGS", "Mahjong Super Da Man Guan II (China, V754C)", 0 ) GAME( 1997, tjsb, 0, tjsb, tjsb, igs017_state, tjsb, ROT0, "IGS", "Mahjong Tian Jiang Shen Bing (V137C)", MACHINE_UNEMULATED_PROTECTION ) -GAME( 1998, genius6, 0, iqblocka, iqblocka, igs017_state, iqblocka, ROT0, "IGS", "Genius 6 (V110F)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1998, genius6, 0, genius6, genius6, igs017_state, iqblocka, ROT0, "IGS", "Genius 6 (V110F)", 0 ) GAME( 1998, mgcs, 0, mgcs, mgcs, igs017_state, mgcs, ROT0, "IGS", "Mahjong Man Guan Caishen (V103CS)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_SOUND ) GAME( 1998, lhzb2, 0, lhzb2, lhzb2, igs017_state, lhzb2, ROT0, "IGS", "Mahjong Long Hu Zhengba 2 (set 1)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) GAME( 1998, lhzb2a, lhzb2, lhzb2a, lhzb2a, igs017_state, lhzb2a, ROT0, "IGS", "Mahjong Long Hu Zhengba 2 (VS221M)", 0 ) @@ -4421,5 +4754,5 @@ GAME( 1999, tarzan, tarzanc, iqblocka, iqblocka, igs017_state, tarzan, ROT GAME( 1999, tarzana, tarzanc, iqblocka, iqblocka, igs017_state, tarzana, ROT0, "IGS", "Tarzan (V107)", MACHINE_NOT_WORKING ) GAME( 2000?, starzan, 0, starzan, iqblocka, igs017_state, starzan, ROT0, "IGS (G.F. Gioca license)", "Super Tarzan (Italy, V100I)", MACHINE_NOT_WORKING ) -/* Parent spk306us in driver spoker.cpp. Move this set to that driver? */ -GAME( ????, spkrform, spk306us, spkrform, spkrform, igs017_state, spkrform, ROT0, "IGS", "Super Poker (v100xD03) / Formosa", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) +// Parent spk306us in driver spoker.cpp. Move this set to that driver? +GAME( ????, spkrform, spk306us, spkrform, spkrform, igs017_state, spkrform, ROT0, "IGS", "Super Poker (v100xD03) / Formosa", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) diff --git a/src/mame/drivers/igs_m027.cpp b/src/mame/drivers/igs_m027.cpp index 5cdb25a5a99..2a00ecafd97 100644 --- a/src/mame/drivers/igs_m027.cpp +++ b/src/mame/drivers/igs_m027.cpp @@ -346,8 +346,8 @@ MACHINE_CONFIG_START(igs_m027_state::igs_majhong) // MCFG_PALETTE_FORMAT(xGGGGGRRRRRBBBBB) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_REVERSE_TEXT_BITS MCFG_GFX_PALETTE("palette") - MCFG_REVERSE_TEXT_BITS // 82C55? (accessed through igs017/igs031 area like igs017.c?) @@ -380,8 +380,8 @@ MACHINE_CONFIG_START(igs_m027_state::amazonia) // MCFG_PALETTE_FORMAT(xGGGGGRRRRRBBBBB) MCFG_DEVICE_ADD("igs017_igs031", IGS017_IGS031, 0) + MCFG_IGS017_IGS031_REVERSE_TEXT_BITS MCFG_GFX_PALETTE("palette") - MCFG_REVERSE_TEXT_BITS // 82C55? (accessed through igs017/igs031 area like igs017.c?) diff --git a/src/mame/drivers/iqblock.cpp b/src/mame/drivers/iqblock.cpp index 8cd41c1a8d9..7f051136f22 100644 --- a/src/mame/drivers/iqblock.cpp +++ b/src/mame/drivers/iqblock.cpp @@ -9,8 +9,6 @@ Driver by Nicola Salmoria and Ernesto Corvi TODO: - Who generates IRQ and NMI? How many should there be per frame? -- Sound chip is a UM3567. Is this compatible to something already in MAME? yes, YM2413 - - Coin 2 doesn't work? DIP switch setting? - Protection: @@ -271,19 +269,19 @@ static INPUT_PORTS_START( grndtour ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // in Level test mode the following select the start level, do they have any effect during normal gameplay? - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x02, 0x02, "Level Test +1" ) PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x04, 0x04, "Level Test +2" ) PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x08, 0x08, "Level Test +4" ) PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x10, 0x10, "Level Test +8" ) PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x20, 0x20, "Level Test +16" ) PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0xc0, 0xc0, "Test Mode" ) @@ -384,45 +382,23 @@ MACHINE_CONFIG_END ***************************************************************************/ /* -IQ Block -IGS, 1996 +IQ-Block +IGS 1993 -PCB Layout ----------- +PCB 0036-5 + SW1 SW2 -IGS PCB N0- 0131-4 -|---------------------------------------| -|uPD1242H VOL U3567 3.579545MHz| -| AR17961 | -| HD64180RP8 | -| 16MHz BATTERY| -| | -| SPEECH.U17 | -| | -|J 6264 | -|A | -|M 8255 V.U18 | -|M | -|A | -| | -| | -| |-------| | -| | | | -| CG.U7 |IGS017 | | -| | | | -| TEXT.U8 |-------| PAL | -| 22MHz 61256 | -| DSW1 DSW2 DSW3 | -|---------------------------------------| -Notes: - HD64180RP8 - Hitachi HD64180 CPU. Clocks 16MHz (pins 2 & 3), 8MHz (pin 64) - 61256 - 32k x8 SRAM (DIP28) - 6264 - 8k x8 SRAM (DIP28) - IGS017 - Custom IGS IC (QFP208) - AR17961 - == Oki M6295 (QFP44). Clock 1.000MHz [16/16]. pin 7 = high - U3567 - == YM2413. Clock 3.579545MHz - VSync - 60Hz - HSync - 15.31kHz + 12MHz W2466 8255 + + IGS002 U24.5 + U25.4 AMT001 6116-45 + 6116-45 + Z80 U26.3 + U27.2 + U7.V5 U28.1 + U8.6 + W2466 + UMC UM3567 */ ROM_START( iqblock ) @@ -538,5 +514,5 @@ DRIVER_INIT_MEMBER(iqblock_state,grndtour) -GAME( 1993, iqblock, 0, iqblock, iqblock, iqblock_state, iqblock, ROT0, "IGS", "IQ-Block", MACHINE_SUPPORTS_SAVE ) -GAME( 1993, grndtour, 0, iqblock, grndtour,iqblock_state, grndtour, ROT0, "IGS", "Grand Tour", MACHINE_SUPPORTS_SAVE ) +GAME( 1993, iqblock, 0, iqblock, iqblock, iqblock_state, iqblock, ROT0, "IGS", "IQ-Block (V100U)", MACHINE_SUPPORTS_SAVE ) +GAME( 1993, grndtour, 0, iqblock, grndtour,iqblock_state, grndtour, ROT0, "IGS", "Grand Tour (V100U)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/video/igs017_igs031.cpp b/src/mame/video/igs017_igs031.cpp index e38bd6becd7..863150c417f 100644 --- a/src/mame/video/igs017_igs031.cpp +++ b/src/mame/video/igs017_igs031.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli, Luca Elia - -/* IGS017 / IGS031 video device */ - /* +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 @@ -12,13 +11,9 @@ providing the interface to the 8255, or is it coincidence? */ - - #include "emu.h" #include "igs017_igs031.h" - - void igs017_igs031_device::map(address_map &map) { map(0x1000, 0x17ff).ram().share("spriteram"); @@ -42,8 +37,7 @@ READ8_MEMBER(igs017_igs031_device::i8255_r) if (m_i8255) return m_i8255->read(space, offset); - logerror("igs017_igs031_device::i8255_r with no 8255 device %02x\n", offset); - + logerror("igs017_igs031_device::i8255_r(%02x) with no 8255 device\n", offset); return 0; } @@ -60,7 +54,7 @@ static const gfx_layout layout_8x8x4 = }; GFXDECODE_MEMBER( igs017_igs031_device::gfxinfo ) - GFXDECODE_DEVICE( "^tilemaps", 0, layout_8x8x4, 0, 16 ) + GFXDECODE_DEVICE( "^tilemaps", 0, layout_8x8x4, 0, 16 ) // GFXDECODE_DEVICE( DEVICE_SELF, 0, spritelayout, 0, 0x1000 ) GFXDECODE_END @@ -80,7 +74,7 @@ igs017_igs031_device::igs017_igs031_device(const machine_config &mconfig, const m_i8255(*this, "^ppi8255"), m_palette(*this, "^palette") { - m_palette_scramble_cb = igs017_igs031_palette_scramble_delegate(FUNC(igs017_igs031_device::palette_callback_straight), this); + m_palette_scramble_cb = igs017_igs031_palette_scramble_delegate(FUNC(igs017_igs031_device::palette_callback_straight), this); m_revbits = 0; } @@ -96,15 +90,12 @@ uint16_t igs017_igs031_device::palette_callback_straight(uint16_t bgr) return bgr; } - void igs017_igs031_device::device_start() { m_palette_scramble_cb.bind_relative_to(*owner()); - m_fg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(igs017_igs031_device::get_fg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,32); - m_bg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(igs017_igs031_device::get_bg_tile_info),this),TILEMAP_SCAN_ROWS,8,8,64,32); - - + m_fg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(igs017_igs031_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8,8, 64,32); + m_bg_tilemap = &machine().tilemap().create(*this, tilemap_get_info_delegate(FUNC(igs017_igs031_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8,8, 64,32); m_fg_tilemap->set_transparent_pen(0xf); m_bg_tilemap->set_transparent_pen(0xf); @@ -112,22 +103,19 @@ void igs017_igs031_device::device_start() m_toggle = 0; m_debug_addr = 0; m_debug_width = 512; - - } void igs017_igs031_device::video_start() { - // make sure thie happens AFTER driver init, or things won't work + // make sure this happens AFTER driver init, or things won't work expand_sprites(); if (m_revbits) { uint8_t *rom = memregion("^tilemaps")->base(); - int size = memregion("^tilemaps")->bytes(); - int i; + int size = memregion("^tilemaps")->bytes(); - for (i = 0; i < size ; i++) + for (int i = 0; i < size ; i++) { rom[i] = bitswap<8>(rom[i], 0, 1, 2, 3, 4, 5, 6, 7); // rom[i^1] = bitswap<8>(rom[i], 0, 1, 2, 3, 4, 5, 6, 7); @@ -135,7 +123,6 @@ void igs017_igs031_device::video_start() } } - void igs017_igs031_device::device_reset() { m_video_disable = 0; @@ -153,7 +140,6 @@ WRITE8_MEMBER(igs017_igs031_device::write) space_w(offset, data); } - void igs017_igs031_device::space_w(int offset, uint8_t data) { space().write_byte(offset, data); @@ -217,20 +203,17 @@ WRITE8_MEMBER(igs017_igs031_device::bg_w) } - - // Eeach 16 bit word in the sprites gfx roms contains three 5 bit pens: x-22222-11111-00000 (little endian!). // This routine expands each word into three bytes. void igs017_igs031_device::expand_sprites() { uint8_t *rom = memregion("^sprites")->base(); - int size = memregion("^sprites")->bytes(); - int i; + int size = memregion("^sprites")->bytes(); m_sprites_gfx_size = size / 2 * 3; m_sprites_gfx = std::make_unique(m_sprites_gfx_size); - for (i = 0; i < size / 2 ; i++) + for (int i = 0; i < size / 2 ; i++) { uint16_t pens = (rom[i*2+1] << 8) | rom[i*2]; @@ -240,7 +223,6 @@ void igs017_igs031_device::expand_sprites() } } - /*************************************************************************** Sprites Format @@ -399,36 +381,16 @@ uint32_t igs017_igs031_device::screen_update_igs017(screen_device &screen, bitma return 0; } -#if 0 -WRITE16_MEMBER(igs017_igs031_device::irq_enable_w) -{ - if (ACCESSING_BITS_0_7) - m_irq_enable = data & 1; - - if (data != 0 && data != 1 && data != 0xff) - logerror("%s: irq_enable = %04x\n", machine().describe_context(), data); -} - -WRITE16_MEMBER(igs017_igs031_device::nmi_enable_w) -{ - if (ACCESSING_BITS_0_7) - m_nmi_enable = data & 1; - - if (data != 0 && data != 1 && data != 0xff) - logerror("%s: nmi_enable = %04x\n", machine().describe_context(), data); -} -#endif - WRITE8_MEMBER(igs017_igs031_device::nmi_enable_w) { m_nmi_enable = data & 1; - if (data & (~1)) + if (data != 0 && data != 1 && data != 0xff) logerror("%s: nmi_enable = %02x\n", machine().describe_context(), data); } WRITE8_MEMBER(igs017_igs031_device::irq_enable_w) { m_irq_enable = data & 1; - if (data & (~1)) + if (data != 0 && data != 1 && data != 0xff) logerror("%s: irq_enable = %02x\n", machine().describe_context(), data); } diff --git a/src/mame/video/igs017_igs031.h b/src/mame/video/igs017_igs031.h index be6ef235c85..73830c66fd6 100644 --- a/src/mame/video/igs017_igs031.h +++ b/src/mame/video/igs017_igs031.h @@ -9,10 +9,10 @@ typedef device_delegate igs017_igs031_palette_scramble_delegate; -#define MCFG_PALETTE_SCRAMBLE_CB( _class, _method) \ +#define MCFG_IGS017_IGS031_PALETTE_SCRAMBLE_CB( _class, _method) \ downcast(*device).set_palette_scramble_cb(igs017_igs031_palette_scramble_delegate(&_class::_method, #_class "::" #_method, nullptr, (_class *)nullptr)); -#define MCFG_REVERSE_TEXT_BITS \ +#define MCFG_IGS017_IGS031_REVERSE_TEXT_BITS \ downcast(*device).set_text_reverse_bits(); class igs017_igs031_device : public device_t, @@ -23,7 +23,6 @@ class igs017_igs031_device : public device_t, public: igs017_igs031_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template void set_palette_scramble_cb(Object &&cb) { m_palette_scramble_cb = std::forward(cb); } void set_text_reverse_bits()