From 7498b7058c732239bae89ff76e4d35dec498d030 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Mon, 29 Jun 2020 23:19:23 +0200 Subject: pgmprot_igs027a_type1.cpp: simulated Photo Y2K2 sprite offset decode [iq_132] --- src/mame/drivers/pgm.cpp | 4 +- src/mame/machine/pgmprot_igs027a_type1.cpp | 102 ++++++++++++++++++++++++----- src/mame/machine/pgmprot_igs027a_type1.h | 4 ++ 3 files changed, 93 insertions(+), 17 deletions(-) diff --git a/src/mame/drivers/pgm.cpp b/src/mame/drivers/pgm.cpp index c27cf59e00a..fde3aece16b 100644 --- a/src/mame/drivers/pgm.cpp +++ b/src/mame/drivers/pgm.cpp @@ -5090,8 +5090,8 @@ GAME( 1999, puzlstar, pgm, pgm_arm_type1_sim, pstar, pgm_arm_ //超級比一比2/Chāojí bǐ yī bǐ 2 (Taiwan) //大家来找碴2/Dàjiā lái zhǎo chá 2/Daai6gaa1 Loi4 Zaau2 Caa4 2 (China, Hong Kong) //リアルアンドフェイク 2 Photo Y2K/Riaruandofeiku(Real and Fake) 2 Photo Y2K (Japan) -GAME( 2001, py2k2, pgm, pgm_arm_type1_sim, py2k2, pgm_arm_type1_state, init_py2k2, ROT0, "IGS", "Photo Y2K 2 / Chaoji Bi Yi Bi 2 / Dajia Lai Zhao Cha 2 / Real and Fake 2 Photo Y2K (M101XX 05/25/01 11:02:54)", MACHINE_NOT_WORKING ) /* need internal rom of IGS027A */ -GAME( 2000, py2k2100, py2k2, pgm_arm_type1_sim, py2k2, pgm_arm_type1_state, init_py2k2, ROT0, "IGS", "Photo Y2K 2 / Chaoji Bi Yi Bi 2 / Dajia Lai Zhao Cha 2 / Real and Fake 2 Photo Y2K (ver. 100, Japanese Board)", MACHINE_NOT_WORKING ) /* need internal rom of IGS027A */ +GAME( 2001, py2k2, pgm, pgm_arm_type1_sim, py2k2, pgm_arm_type1_state, init_py2k2, ROT0, "IGS", "Photo Y2K 2 / Chaoji Bi Yi Bi 2 / Dajia Lai Zhao Cha 2 / Real and Fake 2 Photo Y2K (M101XX 05/25/01 11:02:54)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) /* need internal rom of IGS027A */ +GAME( 2000, py2k2100, py2k2, pgm_arm_type1_sim, py2k2, pgm_arm_type1_state, init_py2k2, ROT0, "IGS", "Photo Y2K 2 / Chaoji Bi Yi Bi 2 / Dajia Lai Zhao Cha 2 / Real and Fake 2 Photo Y2K (ver. 100, Japanese Board)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) /* need internal rom of IGS027A */ //閃亮三合一/Shǎn liàng sān hé yī (Taiwan, Hong Kong, Oversea) //闪亮三合一/Shǎn liàng sān hé yī (China) diff --git a/src/mame/machine/pgmprot_igs027a_type1.cpp b/src/mame/machine/pgmprot_igs027a_type1.cpp index 7f98480d1d8..2602e2338d6 100644 --- a/src/mame/machine/pgmprot_igs027a_type1.cpp +++ b/src/mame/machine/pgmprot_igs027a_type1.cpp @@ -1020,39 +1020,104 @@ void pgm_arm_type1_state::command_handler_puzzli2(int pc) } } +static u32 py2k2_sprite_offset(u16 base, u16 pos) +{ + u16 ret = 0; + u16 offset = (base * 16) + (pos & 0xf); + + switch (base & ~0x3f) + { + case 0x000: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break; + case 0x040: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break; + case 0x080: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break; + case 0x0c0: ret = bitswap<16>(offset ^ 0x0001, 15, 14, 13, 12, 11, 10, 6, 5, 4, 3, 2, 1, 9, 8, 7, 0); break; + case 0x100: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break; + case 0x140: ret = bitswap<16>(offset ^ 0x01c0, 15, 14, 13, 12, 11, 10, 2, 8, 7, 6, 4, 3, 5, 9, 0, 1); break; + case 0x180: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break; + case 0x1c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break; + case 0x200: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break; + case 0x240: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4); break; + case 0x280: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break; + case 0x2c0: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break; + case 0x300: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break; + case 0x340: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break; + case 0x380: ret = bitswap<16>(offset ^ 0x0001, 15, 14, 13, 12, 11, 10, 6, 5, 4, 3, 2, 1, 9, 8, 7, 0); break; + case 0x3c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break; + case 0x400: ret = bitswap<16>(offset ^ 0x02a1, 15, 14, 13, 12, 11, 10, 9, 1, 7, 8, 5, 6, 2, 4, 3, 0); break; + case 0x440: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break; + case 0x480: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break; + case 0x4c0: ret = bitswap<16>(offset ^ 0x01c0, 15, 14, 13, 12, 11, 10, 2, 8, 7, 6, 4, 3, 5, 9, 0, 1); break; + case 0x500: ret = bitswap<16>(offset ^ 0x0141, 15, 14, 13, 12, 11, 10, 4, 8, 2, 6, 1, 7, 9, 5, 3, 0); break; + case 0x540: ret = bitswap<16>(offset ^ 0x0030, 15, 14, 13, 12, 11, 10, 0, 2, 3, 9, 5, 4, 8, 7, 6, 1); break; + case 0x580: ret = bitswap<16>(offset ^ 0x03c0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 1, 2, 0, 5, 3, 4); break; + case 0x5c0: ret = bitswap<16>(offset ^ 0x0090, 15, 14, 13, 12, 11, 10, 5, 3, 7, 2, 1, 4, 0, 9, 8, 6); break; + case 0x600: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 0, 3, 4, 6, 8, 7, 5, 9, 2, 1); break; + case 0x640: ret = bitswap<16>(offset ^ 0x0000, 15, 14, 13, 12, 11, 10, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5); break; + } + + if (offset >= 0xce80/2 && offset <= 0xceff/2) ret -= 0x0100; + if (offset >= 0xcf00/2 && offset <= 0xcf7f/2) ret += 0x0100; + + return ret; +} + /* preliminary */ void pgm_arm_type1_state::command_handler_py2k2(int pc) { switch (m_ddp3lastcommand) { - default: - puzzli2_printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0); - m_valueresponse = 0x880000; - break; - + case 0x30: + m_valueresponse = py2k2_sprite_offset(m_py2k2_sprite_base, m_py2k2_sprite_pos++); + break; + case 0x32: + m_py2k2_sprite_base = m_value0; + m_py2k2_sprite_pos = 0; + m_valueresponse = py2k2_sprite_offset(m_py2k2_sprite_base, m_py2k2_sprite_pos++); + break; + case 0xba: + m_valueresponse = m_py2k2_prev_base; + m_py2k2_prev_base = m_value0; + break; + case 0x99: // reset? + m_py2k2_prev_base = m_value0; + m_simregion = m_region->read(); + m_valuekey = 0x100; + m_valueresponse = 0x00880000 | m_simregion<<8; + break; case 0xc0: puzzli2_printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0); m_valueresponse = 0x880000; break; - + case 0xc3: + m_valueresponse = 0x904000 + ((m_extra_ram[0xc0] + (m_value0 * 0x40)) * 4); + break; + case 0xd0: + m_valueresponse = 0xa01000 + (m_value0 * 0x20); + break; + case 0xdc: + m_valueresponse = 0xa00800 + (m_value0 * 0x40); + break; + case 0xe0: + m_valueresponse = 0xa00000 + ((m_value0 & 0x1f) * 0x40); + break; case 0xcb: // Background layer 'x' select (pgm3in1, same as kov) m_valueresponse = 0x880000; - m_kov_cb_value = m_value0; break; - case 0xcc: // Background layer offset (pgm3in1, same as kov) { int y = m_value0; if (y & 0x400) y = -(0x400 - (y & 0x3ff)); - m_valueresponse = 0x900000 + ((m_kov_cb_value + (y * 0x40)) * 4); + m_valueresponse = 0x900000 + ((m_extra_ram[0xcb] + (y * 0x40)) * 4); } break; - - case 0x99: // reset? - m_simregion = m_region->read(); - m_valuekey = 0x100; - m_valueresponse = 0x00880000 | m_simregion<<8; - + case 0x33: + case 0x34: + case 0x35: + case 0x37: + case 0x38: + default: + puzzli2_printf("%06x command %02x | %04x\n", pc, m_ddp3lastcommand, m_value0); + m_valueresponse = 0x880000; break; } } @@ -2221,6 +2286,13 @@ void pgm_arm_type1_state::init_py2k2() arm_sim_handler = &pgm_arm_type1_state::command_handler_py2k2; m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x500000, 0x500005, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_r)), write16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_w))); m_maincpu->space(AS_PROGRAM).install_read_handler(0x4f0000, 0x4f003f, read16sm_delegate(*this, FUNC(pgm_arm_type1_state::arm7_type1_sim_protram_r))); + + m_py2k2_sprite_pos = 0; + m_py2k2_sprite_base = 0; + m_py2k2_prev_base = 0; + save_item(NAME(m_py2k2_sprite_pos)); + save_item(NAME(m_py2k2_sprite_base)); + save_item(NAME(m_py2k2_prev_base)); } void pgm_arm_type1_state::init_pgm3in1() diff --git a/src/mame/machine/pgmprot_igs027a_type1.h b/src/mame/machine/pgmprot_igs027a_type1.h index 6e7abe406e2..c5c1ec78192 100644 --- a/src/mame/machine/pgmprot_igs027a_type1.h +++ b/src/mame/machine/pgmprot_igs027a_type1.h @@ -128,6 +128,10 @@ private: int command_31_write_type; + // py2k2 protection related + u16 m_py2k2_sprite_pos; + u16 m_py2k2_sprite_base; + u16 m_py2k2_prev_base; // the maximum level size returned or read by the device appears to be this size u16 level_structure[8][10]; -- cgit v1.2.3