diff options
Diffstat (limited to 'src/mame/drivers/pgm2.cpp')
-rw-r--r-- | src/mame/drivers/pgm2.cpp | 212 |
1 files changed, 156 insertions, 56 deletions
diff --git a/src/mame/drivers/pgm2.cpp b/src/mame/drivers/pgm2.cpp index 794de03f295..bfddc66741a 100644 --- a/src/mame/drivers/pgm2.cpp +++ b/src/mame/drivers/pgm2.cpp @@ -46,11 +46,7 @@ Identify which regions each game was released in and either dump alt. internal ROMs for each region, or create them until that can be done. properly implement RTC (integrated into the CPU) - Memory Card system (there's an MCU on the motherboard that will need simulating or dumping somehow) Verify Sprite Zoom (check exactly which pixels are doubled / missed on hardware for flipped , non-flipped cases etc.) - Simplify IGS036 encryption based on tables in internal roms - Fix ARM? bug that means Oriental Legend 2 needs a patch (might also be that it needs the card reader, and is running a - codepath that would not exist in a real environment at the moment) Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests) Debug features (require DIP SW1:8 On and SW1:1 Off): @@ -72,6 +68,25 @@ Oriental Legend 2 (Oversea) - V21 Oriental Legend 2 (China) - A8 + GPU registers, located at 301200xx, 16bit access. + 00 - bg scroll x + 02 - bg scroll y + 04 - zoom something, 0F-7F, default 1F + 06 - zoom something, 0F-7F, default 1F + 08 - fg scroll x + 0a - fg scroll y + 0e - resolution, 0 - low (kof98), 1 - high (rest of games) + 10 - ? orleg2 - 0x13, kov2nl, kof - 0x14 at init (sprite related?) + 14 - sprite enable ? set to 0 before spriteram update, to 1 after + 16 - enable access to vrams/palettes/etc ? (bitmask) + 18 - vblank ack + 1a - ? 0 at init + 1c - ? orleg2 - 5, kov2nl, kof - 7 at init (sprite related?) + 1e - ? 2 at init (sprite related?) + 32 - shared RAM bank + 34, 36 - ? 0 at init, some unused xor feature ? + 38, 3a - sprite mask xor key + */ #include "includes/pgm2.h" @@ -105,7 +120,7 @@ WRITE32_MEMBER(pgm2_state::sprite_encryption_w) COMBINE_DATA(&m_spritekey); if (!m_sprite_predecrypted) - m_realspritekey = BITSWAP32(m_spritekey ^ 0x90055555, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); + m_realspritekey = bitswap<32>(m_spritekey ^ 0x90055555, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); } WRITE32_MEMBER(pgm2_state::encryption_do_w) @@ -121,7 +136,7 @@ WRITE32_MEMBER(pgm2_state::encryption_do_w) INTERRUPT_GEN_MEMBER(pgm2_state::igs_interrupt) { - m_arm_aic->set_irq(0x47); + m_arm_aic->set_irq(12, ASSERT_LINE); } WRITE16_MEMBER(pgm2_state::share_bank_w) @@ -141,7 +156,7 @@ WRITE8_MEMBER(pgm2_state::shareram_w) TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2) { - m_arm_aic->set_irq(0x46); + m_arm_aic->set_irq(3, ASSERT_LINE); } // "MPU" MCU HLE starts here @@ -172,7 +187,6 @@ void pgm2_state::mcu_command(address_space &space, bool is_command) case 0xe0: // command port test m_mcu_result0 = m_mcu_regs[0]; m_mcu_result1 = m_mcu_regs[1]; - delay = 30; // such quite long delay is needed for debug codes check routine break; case 0xe1: // shared ram access (unimplemented) { @@ -188,47 +202,86 @@ void pgm2_state::mcu_command(address_space &space, bool is_command) m_mcu_result1 = 0; } break; - // unknown / unimplemented, all C0-C9 commands is IC Card RW related - // (m_mcu_regs[0] >> 8) & 0xff - target RW unit (player) + // C0-C9 commands is IC Card RW comms case 0xc0: // insert card or/and check card presence. result: F7 - ok, F4 - no card - if (m_memcard_device[arg1 & 3]->present() == -1) + if (m_memcard[arg1 & 3]->present() == -1) status = 0xf4; m_mcu_result0 = cmd; break; case 0xc1: // check ready/busy ? + if (m_memcard[arg1 & 3]->present() == -1) + status = 0xf4; m_mcu_result0 = cmd; break; - case 0xc2: // read data to shared ram, args - offset, len + case 0xc2: // read data to shared ram for (int i = 0; i < arg3; i++) { - if (m_memcard_device[arg1 & 3]->present() != -1) - m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard_device[arg1 & 3]->read(space, arg2 + i); + if (m_memcard[arg1 & 3]->present() != -1) + m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard[arg1 & 3]->read(space, arg2 + i); + else + status = 0xf4; } - m_mcu_result0 = cmd; break; - case 0xc3: // save data from shared ram, args - offset, len + case 0xc3: // save data from shared ram for (int i = 0; i < arg3; i++) { - if (m_memcard_device[arg1 & 3]->present() != -1) - m_memcard_device[arg1 & 3]->write(space, arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]); + if (m_memcard[arg1 & 3]->present() != -1) + m_memcard[arg1 & 3]->write(space, arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]); + else + status = 0xf4; } m_mcu_result0 = cmd; break; - case 0xc7: // get card ID?, no args, result1 expected to be fixed value for new card - m_mcu_result1 = 0xf81f0000; + case 0xc4: // presumable read security mem (password only?) + if (m_memcard[arg1 & 3]->present() != -1) + { + m_mcu_result1 = m_memcard[arg1 & 3]->read_sec(space, 1) | + (m_memcard[arg1 & 3]->read_sec(space, 2) << 8) | + (m_memcard[arg1 & 3]->read_sec(space, 3) << 16); + } + else + status = 0xf4; m_mcu_result0 = cmd; break; - case 0xc8: // write byte, args - offset, data byte - if (m_memcard_device[arg1 & 3]->present() != -1) - m_memcard_device[arg1 & 3]->write(space, arg2, arg3); - + case 0xc5: // write security mem + if (m_memcard[arg1 & 3]->present() != -1) + m_memcard[arg1 & 3]->write_sec(space, arg2 & 3, arg3); + else + status = 0xf4; + m_mcu_result0 = cmd; + break; + case 0xc6: // presumable write protection mem + if (m_memcard[arg1 & 3]->present() != -1) + m_memcard[arg1 & 3]->write_prot(space, arg2 & 3, arg3); + else + status = 0xf4; + m_mcu_result0 = cmd; + break; + case 0xc7: // read protection mem + if (m_memcard[arg1 & 3]->present() != -1) + { + m_mcu_result1 = m_memcard[arg1 & 3]->read_prot(space, 0) | + (m_memcard[arg1 & 3]->read_prot(space, 1) << 8) | + (m_memcard[arg1 & 3]->read_prot(space, 2) << 16) | + (m_memcard[arg1 & 3]->read_prot(space, 3) << 24); + } + else + status = 0xf4; + m_mcu_result0 = cmd; + break; + case 0xc8: // write data mem + if (m_memcard[arg1 & 3]->present() != -1) + m_memcard[arg1 & 3]->write(space, arg2, arg3); + else + status = 0xf4; m_mcu_result0 = cmd; break; - case 0xc4: // not used - case 0xc5: // set new password?, args - offset, data byte (offs 0 - always 7, 1-3 password) - case 0xc6: // not used - case 0xc9: // card authentication, args - 3 byte password, ('I','G','S' for new cards) + case 0xc9: // card authentication + if (m_memcard[arg1 & 3]->present() != -1) + m_memcard[arg1 & 3]->auth(arg2, arg3, m_mcu_regs[1] & 0xff); + else + status = 0xf4; m_mcu_result0 = cmd; break; default: @@ -263,9 +316,32 @@ WRITE32_MEMBER(pgm2_state::mcu_w) if (reg == 2 && m_mcu_regs[2]) // irq to mcu mcu_command(space, true); if (reg == 5 && m_mcu_regs[5]) // ack to mcu (written at the end of irq handler routine) + { mcu_command(space, false); + m_arm_aic->set_irq(3, CLEAR_LINE); + } } +WRITE16_MEMBER(pgm2_state::vbl_ack_w) +{ + m_arm_aic->set_irq(12, CLEAR_LINE); +} + +WRITE16_MEMBER(pgm2_state::unk30120014_w) +{ + if (offset == 0) + { + // 0/1 toggles (maybe sprite dma triggers?) + } + else + { + // interesting data + //printf("unk30120014_w %d %04x\n", offset, data); + } +} + + + static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state ) AM_RANGE(0x00000000, 0x00003fff) AM_ROM //AM_REGION("user1", 0x00000) // internal ROM @@ -301,6 +377,10 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state ) AM_RANGE(0x30100000, 0x301000ff) AM_READWRITE8(shareram_r, shareram_w, 0x00ff00ff) AM_RANGE(0x30120000, 0x30120003) AM_RAM AM_SHARE("bgscroll") // scroll + AM_RANGE(0x30120008, 0x3012000b) AM_RAM AM_SHARE("fgscroll") + AM_RANGE(0x3012000c, 0x3012000f) AM_RAM AM_SHARE("vidmode") + AM_RANGE(0x30120014, 0x30120017) AM_WRITE16(unk30120014_w, 0xffffffff) + AM_RANGE(0x30120018, 0x3012001b) AM_WRITE16(vbl_ack_w, 0x0000ffff) AM_RANGE(0x30120030, 0x30120033) AM_WRITE16(share_bank_w, 0xffff0000) AM_RANGE(0x30120038, 0x3012003b) AM_WRITE(sprite_encryption_w) // there are other 0x301200xx regs @@ -318,7 +398,7 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state ) AM_RANGE(0xfffffd28, 0xfffffd2b) AM_READ(rtc_r) - AM_RANGE(0xfffffa08, 0xfffffa0b) AM_WRITE(encryption_do_w) // after uploading encryption? table might actually send it or enable external ROM? when read bits0-1 is ROM board status (0 if OK) + AM_RANGE(0xfffffa08, 0xfffffa0b) AM_WRITE(encryption_do_w) // after uploading encryption? table might actually send it or enable external ROM? when read bits0-1 called FUSE 0 and 1, must be 0 AM_RANGE(0xfffffa0c, 0xfffffa0f) AM_READ(unk_startup_r) ADDRESS_MAP_END @@ -427,11 +507,6 @@ void pgm2_state::machine_start() save_item(NAME(m_mcu_last_cmd)); save_item(NAME(m_shareram)); save_item(NAME(m_share_bank)); - - m_memcard_device[0] = m_memcard0; - m_memcard_device[1] = m_memcard1; - m_memcard_device[2] = m_memcard2; - m_memcard_device[3] = m_memcard3; } void pgm2_state::machine_reset() @@ -520,10 +595,15 @@ static MACHINE_CONFIG_START( pgm2 ) MCFG_PGM2_MEMCARD_ADD("memcard_p2") MCFG_PGM2_MEMCARD_ADD("memcard_p3") MCFG_PGM2_MEMCARD_ADD("memcard_p4") +MACHINE_CONFIG_END - +// not strictly needed as the video code supports changing on the fly, but makes recording easier etc. +static MACHINE_CONFIG_DERIVED( pgm2_lores, pgm2 ) + MCFG_SCREEN_MODIFY("screen") + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) MACHINE_CONFIG_END + /* using macros for the video / sound roms because the locations never change between sets, and we're going to have a LOT of clones to cover all the internal rom regions and external rom revision combinations, so it keeps things readable */ @@ -585,8 +665,8 @@ MACHINE_CONFIG_END #define ORLEG2_INTERNAL_CHINA \ ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_LOAD( "xyj2_cn.igs036", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) \ - ROM_REGION( 0x100, "default_card", 0 ) \ - ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x100, CRC(099156f0) SHA1(a621c9772a98719c657bba3a1bf235487eb78615) ) + ROM_REGION( 0x108, "default_card", 0 ) \ + ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x108, CRC(dc29556f) SHA1(2335cc7af25d4dd9763c6944d3f0eb50276de80a) ) #define ORLEG2_INTERNAL_OVERSEAS \ ROM_REGION( 0x04000, "maincpu", 0 ) \ @@ -667,8 +747,8 @@ ROM_END #define KOV2NL_INTERNAL_CHINA \ ROM_REGION( 0x04000, "maincpu", 0 ) \ ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) \ - ROM_REGION( 0x100, "default_card", 0 ) \ - ROM_LOAD( "blank_kov2nl_china_card.pg2", 0x000, 0x100, CRC(91786244) SHA1(ac0ce11b46c19ffe21f6b94bc83ef061f547b591) ) + ROM_REGION( 0x108, "default_card", 0 ) \ + ROM_LOAD( "blank_kov2nl_china_card.pg2", 0x000, 0x108, CRC(02842ae8) SHA1(a6cda633b09a706039a79b73db2c258094826f85) ) ROM_START( kov2nl ) @@ -752,6 +832,9 @@ ROM_START( kov3 ) ROM_REGION( 0x04000, "maincpu", 0 ) ROM_LOAD( "kov3_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) // CRC(c7d33764) SHA1(5cd48f876e637d60391d39ac6e40bf243300cc75) + ROM_REGION( 0x108, "default_card", 0 ) + ROM_LOAD( "blank_kov3_china_card.pg2", 0x000, 0x108, CRC(bd5a968f) SHA1(b9045eb70e02afda7810431c592208053d863980) ) + ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "kov3_v104cn_raw.bin", 0x00000000, 0x0800000, CRC(1b5cbd24) SHA1(6471d4842a08f404420dea2bd1c8b88798c80fd5) ) @@ -792,7 +875,7 @@ all others: SPANSION S99-50070 ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ ROM_LOAD( "ig-d3_text.u1", 0x00000000, 0x0200000, CRC(9a0ea82e) SHA1(7844fd7e46c3fbb2164060f160da528254fd177e) ) \ \ - ROM_REGION( 0x2000000, "bgtile", ROMREGION_ERASEFF ) \ + ROM_REGION( 0x2000000, "bgtile", ROMREGION_ERASE00 ) \ /* bgl/bgh unpopulated (no background tilemap) */ \ \ ROM_REGION( 0x08000000, "sprites_mask", 0 ) /* 1bpp sprite mask data */ \ @@ -809,11 +892,15 @@ all others: SPANSION S99-50070 \ ROM_REGION( 0x08000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ ROM_LOAD16_WORD_SWAP( "ig-d3_wave0.u12", 0x00000000, 0x4000000, CRC(edf2332d) SHA1(7e01c7e03e515814d7de117c265c3668d32842fa) ) \ - ROM_LOAD16_WORD_SWAP( "ig-d3_wave1.u11", 0x04000000, 0x4000000, CRC(62321b20) SHA1(a388c8a2489430fbe92fb26b3ef81c66ce97f318) ) + ROM_LOAD16_WORD_SWAP( "ig-d3_wave1.u11", 0x04000000, 0x4000000, CRC(62321b20) SHA1(a388c8a2489430fbe92fb26b3ef81c66ce97f318) ) \ + \ + ROM_REGION( 0x10000, "sram", 0 ) \ + ROM_LOAD( "kof98umh_sram", 0x00000000, 0x10000, CRC(60460ed9) SHA1(55cd8de37cee04ff7ad940fb52f8fb8db042c26e) ) + ROM_START( kof98umh ) ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "kof98uhm_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) // CRC(3ed2e50f) SHA1(35310045d375d9dda36c325e35257123a7b5b8c7) + ROM_LOAD( "kof98umh_internal_rom.bin", 0x00000000, 0x0004000, CRC(3ed2e50f) SHA1(35310045d375d9dda36c325e35257123a7b5b8c7) ) ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "kof98umh_v100cn.u4", 0x00000000, 0x1000000, CRC(2ea91e3b) SHA1(5a586bb99cc4f1b02e0db462d5aff721512e0640) ) @@ -842,7 +929,7 @@ static void iga_u16_decode(uint16_t *rom, int len, int ixor) if ( (i>>1) & 0x000400) x ^= 0x8000; rom[i] ^= x; - rom[i] = BITSWAP16(rom[i], 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); + rom[i] = bitswap<16>(rom[i], 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); } } @@ -867,7 +954,7 @@ static void iga_u12_decode(uint16_t* rom, int len, int ixor) if ( (i>>1) & 0x000400) x ^= 0x0000; rom[i] ^= x; - rom[i] = BITSWAP16(rom[i], 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); + rom[i] = bitswap<16>(rom[i], 8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7); } } @@ -877,7 +964,7 @@ static void sprite_colour_decode(uint16_t* rom, int len) for (i = 0; i < len / 2; i++) { - rom[i] = BITSWAP16(rom[i], 15, 14, /* unused - 6bpp */ + rom[i] = bitswap<16>(rom[i], 15, 14, /* unused - 6bpp */ 13, 12, 11, 5, 4, 3, 7, 6, /* unused - 6bpp */ @@ -921,6 +1008,25 @@ READ32_MEMBER(pgm2_state::kov2nl_speedup_r) return m_mainram[0x20470 / 4]; } +READ32_MEMBER(pgm2_state::kof98umh_speedup_r) +{ + int pc = space.device().safe_pc(); + + if (pc == 0x100028f6) + { + if ((m_mainram[0x00060 / 4] == 0x00) && (m_mainram[0x00064 / 4] == 0x00)) + space.device().execute().spin_until_interrupt(); + } + /* + else + { + printf("pc is %08x\n", pc); + } + */ + + return m_mainram[0x00060 / 4]; +} + // for games with the internal ROMs fully dumped that provide the sprite key and program rom key at runtime void pgm2_state::common_encryption_init() @@ -1014,19 +1120,13 @@ DRIVER_INIT_MEMBER(pgm2_state, kov3_100) DRIVER_INIT_MEMBER(pgm2_state,kof98umh) { - uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); + common_encryption_init(); + machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x20000060, 0x20000063, read32_delegate(FUNC(pgm2_state::kof98umh_speedup_r),this)); +} + - iga_u12_decode(src, 0x08000000, 0x21df); - iga_u16_decode(src, 0x08000000, 0x8692); - m_sprite_predecrypted = 1; - src = (uint16_t *)memregion("sprites_colour")->base(); - sprite_colour_decode(src, 0x20000000); - igs036_decryptor decrypter(kof98umh_key); - decrypter.decrypter_rom(memregion("user1")); - m_has_decrypted = 1; -} /* PGM2 */ @@ -1053,7 +1153,7 @@ GAME( 2011, kov3_102, kov3, pgm2, pgm2, pgm2_state, kov3_102, ROT0, GAME( 2011, kov3_100, kov3, pgm2, pgm2, pgm2_state, kov3_100, ROT0, "IGS", "Knights of Valour 3 (V100, China)", MACHINE_NOT_WORKING ) // King of Fighters '98: Ultimate Match Hero -GAME( 2009, kof98umh, 0, pgm2, pgm2, pgm2_state, kof98umh, ROT0, "IGS / SNK Playmore / NewChannel", "The King of Fighters '98: Ultimate Match HERO (China, V100, 09-08-23)", MACHINE_NOT_WORKING ) +GAME( 2009, kof98umh, 0, pgm2_lores, pgm2, pgm2_state, kof98umh, ROT0, "IGS / SNK Playmore / New Channel", "The King of Fighters '98: Ultimate Match HERO (China, V100, 09-08-23)", 0 ) // Jigsaw World Arena |