From df49d8de1eac36f04a5cf84d7b0c03ffceec91ba Mon Sep 17 00:00:00 2001 From: taoenwen <67533945+taoenwen@users.noreply.github.com> Date: Tue, 3 May 2022 20:59:41 +0800 Subject: [PATCH] neogeo update (#1015) [1-1] NON-PCB CMC-encrypted games now allow Sprite-ROM to be longer than 0x4000000; [1-2] The excess also applies to CMC encryption/decryption. [2-1] In the case of ips, the reserved length of P-ROM/C-ROM/V-ROM is increased. [2-2] ips extends the length of sprite-ROM, and in this mode, there is a judgment of the true length to ensure that CMC built-in TextRom can be correctly recognized. [2-3] When synchronizing ips cmc decrypts the length of the temporary memory, it avoids overflows caused by inconsistencies in the length of the two temporary memory. --- src/burn/drv/neogeo/d_neogeo.cpp | 55 ++++++++++++++++---------------- src/burn/drv/neogeo/neo_run.cpp | 35 ++++++++++++++++++-- src/burn/drv/neogeo/neogeo.cpp | 25 ++++++++++++++- 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/src/burn/drv/neogeo/d_neogeo.cpp b/src/burn/drv/neogeo/d_neogeo.cpp index fe803ea02b..2e57b6cf0d 100644 --- a/src/burn/drv/neogeo/d_neogeo.cpp +++ b/src/burn/drv/neogeo/d_neogeo.cpp @@ -18972,43 +18972,44 @@ struct BurnDriver BurnDrvkf2k2ps2 = { }; // The King of Fighters 2002 (PlayStation 2, Hack) -// Hack by Dream +// Hacked by Dream -static struct BurnRomInfo kf2k2ps2bRomDesc[] = { +static struct BurnRomInfo kof2002ps2RomDesc[] = { + /* Encrypted */ { "265-p1ps2.p1", 0x100000, 0x9da95b36, 1 | BRF_ESS | BRF_PRG }, // 0 68K code - { "265-p2ps2.sp2", 0x500000, 0x9846db3a, 1 | BRF_ESS | BRF_PRG }, // 1 - - { "265-s1ps2.s1", 0x020000, 0x714ade47, 2 | BRF_GRA }, // 2 Text layer tiles + { "265-p2ps2.sp2", 0x500000, 0x11419517, 1 | BRF_ESS | BRF_PRG }, // 1 - { "265-c1ps2.c1", 0x800000, 0x7efa6ef7, 3 | BRF_GRA }, // 3 Sprite data - { "265-c2ps2.c2", 0x800000, 0xaa82948b, 3 | BRF_GRA }, // 4 - { "265-c3ps2.c3", 0x800000, 0x959fad0b, 3 | BRF_GRA }, // 5 - { "265-c4ps2.c4", 0x800000, 0xefe6a468, 3 | BRF_GRA }, // 6 - { "265-c5ps2.c5", 0x800000, 0x74bba7c6, 3 | BRF_GRA }, // 7 - { "265-c6ps2.c6", 0x800000, 0xe20d2216, 3 | BRF_GRA }, // 8 - { "265-c7ps2.c7", 0x800000, 0xf0897b93, 3 | BRF_GRA }, // 9 - { "265-c8ps2.c8", 0x800000, 0x8d27a4a6, 3 | BRF_GRA }, // 10 - { "265-c9ps2.c9", 0x800000, 0x9939c08a, 3 | BRF_GRA }, // 11 - { "265-c10ps2.c10", 0x800000, 0xc724c069, 3 | BRF_GRA }, // 12 + /* The Encrypted Boards do not have an s1 rom, data for it comes from the Cx ROMs */ + /* Encrypted */ + { "265-c1ps2.c1", 0x800000, 0xa92b140e, 3 | BRF_GRA }, // 2 Sprite data + { "265-c2ps2.c2", 0x800000, 0x365e3945, 3 | BRF_GRA }, // 3 + { "265-c3ps2.c3", 0x800000, 0xe88beb81, 3 | BRF_GRA }, // 4 + { "265-c4ps2.c4", 0x800000, 0x06c374e8, 3 | BRF_GRA }, // 5 + { "265-c5ps2.c5", 0x800000, 0x4ffb0fdf, 3 | BRF_GRA }, // 6 + { "265-c6ps2.c6", 0x800000, 0xa33c38b9, 3 | BRF_GRA }, // 7 + { "265-c7ps2.c7", 0x800000, 0x186cd736, 3 | BRF_GRA }, // 8 + { "265-c8ps2.c8", 0x800000, 0xaf60bcf9, 3 | BRF_GRA }, // 9 + { "265-c9ps2.c9", 0x800000, 0xbbbd99e5, 3 | BRF_GRA }, // 10 + { "265-c10ps2.c10", 0x800000, 0x5d820e2e, 3 | BRF_GRA }, // 11 - { "265-m1ps2.m1", 0x020000, 0xab9d360e, 4 | BRF_ESS | BRF_PRG }, // 13 Z80 code + /* Encrypted */ + { "265-m1ps2.m1", 0x020000, 0x23961378, 4 | BRF_ESS | BRF_PRG }, // 12 Z80 code - { "265-v1sp2.v1", 0x400000, 0x13d98607, 5 | BRF_SND }, // 14 Sound data - { "265-v2sp2.v2", 0x400000, 0x9cf74677, 5 | BRF_SND }, // 15 - { "265-v3sp2.v3", 0x400000, 0x8e9448b5, 5 | BRF_SND }, // 16 - { "265-v4sp2.v4", 0x400000, 0x067271b5, 5 | BRF_SND }, // 17 + /* Encrypted */ + { "265-v1.v1", 0x800000, 0x15e8f3f5, 5 | BRF_SND }, // 11 Sound data + { "265-v2.v2", 0x800000, 0xda41d6f9, 5 | BRF_SND }, // 12 }; -STDROMPICKEXT(kf2k2ps2b, kf2k2ps2b, neogeo) -STD_ROM_FN(kf2k2ps2b) +STDROMPICKEXT(kof2002ps2, kof2002ps2, neogeo) +STD_ROM_FN(kof2002ps2) -struct BurnDriver BurnDrvkf2k2ps2b = { - "kf2k2ps2b", "kof2002", "neogeo", NULL, "2018", +struct BurnDriver BurnDrvkof2002ps2 = { + "kof2002ps2", "kof2002", "neogeo", NULL, "2018", "The King of Fighters 2002 (PlayStation 2, Hack)\0", "hack only enabled in AES mode", "Hack", "Neo Geo MVS", NULL, NULL, NULL, NULL, - BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_PREFIX_CARTRIDGE | HARDWARE_SNK_NEOGEO, GBF_VSFIGHT, FBF_KOF, - NULL, kf2k2ps2bRomInfo, kf2k2ps2bRomName, NULL, NULL, NULL, NULL, neogeoInputInfo, neoaesjapanDIPInfo, - NeoInit, NeoExit, NeoFrame, NeoRender, NeoScan, &NeoRecalcPalette, + BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_PREFIX_CARTRIDGE | HARDWARE_SNK_NEOGEO | HARDWARE_SNK_CMC50 | HARDWARE_SNK_ENCRYPTED_M1, GBF_VSFIGHT, FBF_KOF, + NULL, kof2002ps2RomInfo, kof2002ps2RomName, NULL, NULL, NULL, NULL, neogeoInputInfo, neoaesjapanDIPInfo, + kof2002Init, NeoExit, NeoFrame, NeoRender, NeoScan, &NeoRecalcPalette, 0x1000, 304, 224, 4, 3 }; diff --git a/src/burn/drv/neogeo/neo_run.cpp b/src/burn/drv/neogeo/neo_run.cpp index 1016ad00ae..05ad781b0c 100644 --- a/src/burn/drv/neogeo/neo_run.cpp +++ b/src/burn/drv/neogeo/neo_run.cpp @@ -569,6 +569,9 @@ static INT32 LoadRoms() } nCodeSize[nNeoActiveSlot] = (nCodeSize[nNeoActiveSlot] + 0x0FFFFF) & ~0x0FFFFF; + // Extend the length of[nCodeSize] to fit the ips of the hack games. + if (bDoIpsPatch) nCodeSize[nNeoActiveSlot] += (0x200000 << 1); + nSpriteSize[nNeoActiveSlot] = 0; if (BurnDrvGetHardwareCode() & HARDWARE_SNK_SWAPC) { @@ -605,6 +608,9 @@ static INT32 LoadRoms() nSpriteSize[nNeoActiveSlot] += ri.nLen * 2; } + // The [nSpriteSize] here corresponds to the setting of [nBuf1Len] in [neogeo.cpp]. + if (bDoIpsPatch) nSpriteSize[nNeoActiveSlot] += (0x800000 << 2); + { UINT32 nSize = nSpriteSize[nNeoActiveSlot]; // if (nSize > 0x4000000) { @@ -633,12 +639,13 @@ static INT32 LoadRoms() BurnDrvGetRomInfo(&ri, pInfo->nADPCMOffset + i); if (ri.nLen > nMaxSize) nMaxSize = ri.nLen; } - nYM2610ADPCMASize[nNeoActiveSlot] += nMaxSize * pInfo->nADPCMANum; + nYM2610ADPCMASize[nNeoActiveSlot] += bDoIpsPatch ? (nMaxSize << 1) * pInfo->nADPCMANum : nMaxSize * pInfo->nADPCMANum; for (INT32 i = 0; i < pInfo->nADPCMBNum; i++) { BurnDrvGetRomInfo(&ri, pInfo->nADPCMOffset + pInfo->nADPCMANum + i); nYM2610ADPCMBSize[nNeoActiveSlot] += ri.nLen; } + if (bDoIpsPatch) nYM2610ADPCMBSize[nNeoActiveSlot] *= 2; bprintf(0, _T("ADPCM-A Size:\t%x\n"), nYM2610ADPCMASize[nNeoActiveSlot]); bprintf(0, _T("ADPCM-B Size:\t%x\n"), nYM2610ADPCMBSize[nNeoActiveSlot]); @@ -692,9 +699,33 @@ static INT32 LoadRoms() // Load S ROM data BurnLoadRom(NeoTextROM[nNeoActiveSlot], pInfo->nTextOffset, 1); } else { + // With IPS, The true length of [nSpriteSize] will be obtained. + UINT32 nRealSpriteSize = nSpriteSize[nNeoActiveSlot]; + + if (bDoIpsPatch) { + + // If the expansion bytes of 0x800000 << 2 are all empty data, + // then [SpriteSize] will subtract the expansion part to ensure that [NeoTextROM] is obtained correctly. + for (INT32 i = 0, nIndex = 0; i < ((0x800000 << 2) / nNeoTextROMSize[nNeoActiveSlot]); i++, nIndex++) { + + // The last byte position segment to appear is the true Length of [nSpriteSize]. + // First move the pointer to the last data segment of the length of [nNeoTextROMSize]. + UINT8* pFind = NeoSpriteROM[nNeoActiveSlot] + nSpriteSize[nNeoActiveSlot] - ((i + 1) * nNeoTextROMSize[nNeoActiveSlot]); + + for (INT32 j = 0; j < (nNeoTextROMSize[nNeoActiveSlot] / sizeof(UINT32)); j += sizeof(UINT32)) { + // Data has been found + if (0 != *(UINT32*)&pFind[j]) { + i = ((0x800000 << 2) / nNeoTextROMSize[nNeoActiveSlot]); + break; + } + } + if (i != ((0x800000 << 2) / nNeoTextROMSize[nNeoActiveSlot])) + nRealSpriteSize -= nNeoTextROMSize[nNeoActiveSlot]; + } + } // Extract data from the end of C ROMS BurnUpdateProgress(0.0, _T("Decrypting text layer graphics...")/*, BST_DECRYPT_TXT*/, 0); - NeoCMCExtractSData(NeoSpriteROM[nNeoActiveSlot], NeoTextROM[nNeoActiveSlot], nSpriteSize[nNeoActiveSlot], nNeoTextROMSize[nNeoActiveSlot]); + NeoCMCExtractSData(NeoSpriteROM[nNeoActiveSlot], NeoTextROM[nNeoActiveSlot], nRealSpriteSize, nNeoTextROMSize[nNeoActiveSlot]); if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_DEDICATED_PCB) { for (INT32 i = 0; i < nNeoTextROMSize[nNeoActiveSlot]; i++) { diff --git a/src/burn/drv/neogeo/neogeo.cpp b/src/burn/drv/neogeo/neogeo.cpp index 360f5356b4..6a54c29d22 100644 --- a/src/burn/drv/neogeo/neogeo.cpp +++ b/src/burn/drv/neogeo/neogeo.cpp @@ -91,7 +91,12 @@ INT32 NeoLoadSprites(INT32 nOffset, INT32 nNum, UINT8* pDest, UINT32 nSpriteSize } } - pBuf1 = (UINT8*)BurnMalloc(nRomSize * 2); + // The length of the temporary memory corresponding to the CMC decryption. + // If the temporary memory length here is not set enough, a memory out-of-bounds error will occur during the [BurnExtLoadRom] process of [load.cpp]. + // The temporary memory length here corresponds to the setting of [neo_run.cpp] in the ips environment. + UINT32 nBuf1Len = bDoIpsPatch ? (nRomSize << 1) + (0x800000 << 2) : nRomSize << 1; + + pBuf1 = (UINT8*)BurnMalloc(nBuf1Len); if (pBuf1 == NULL) { return 1; } @@ -144,6 +149,13 @@ INT32 NeoLoadSprites(INT32 nOffset, INT32 nNum, UINT8* pDest, UINT32 nSpriteSize // BurnUpdateProgress(dProgress, NULL/*, 0*/, 0); NeoCMCDecrypt(nNeoProtectionXor, pDest, pBuf1 + j, i * (nRomSize * 2) + j, 0x400000, nSpriteSize); } + + // CMC decryption will not process data other than 0x4000000 in non PCB status. + // ips expansion data must be additionally loaded into reserved memory. + // In ips mode, the data segments that expand the capacity are not encrypted, otherwise CMC encryption will cause data redundancy. + if (bDoIpsPatch && i == (nNum >> 1) - 1) { + memcpy(pDest + (i + 1) * (nRomSize << 1), pBuf1 + (nRomSize << 1), nBuf1Len - (nRomSize << 1)); + } } else { // The kof2k3 PCB has 96MB of graphics ROM, however the last 16MB are unused, and the protection/decryption hardware does not see them if ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNK_DEDICATED_PCB) { @@ -154,6 +166,17 @@ INT32 NeoLoadSprites(INT32 nOffset, INT32 nNum, UINT8* pDest, UINT32 nSpriteSize // BurnUpdateProgress(dProgress, NULL, /*0,*/ 0); NeoCMCDecrypt(nNeoProtectionXor, pDest + 0x4000000, pBuf1 + j, j, 0x400000, 0x1000000); } + } else { + // Hack games that expands the capacity of Sprites. + // Additional processing of data after 0x4000000, loaded into memory. + // To prevent overflow, the data here should no longer be used to increase capacity ips. + memcpy(pDest + i * (nRomSize << 1), pBuf1, nRomSize << 1); + + for (UINT32 j = 0; j < nRomSize * 2; j += 0x400000) { + + // For CMC encryption in non-PCB state, the data after the 0x4000000 is also decrypted. + NeoCMCDecrypt(nNeoProtectionXor, pDest+ i * (nRomSize << 1), pBuf1 + j, j, 0x400000, nRomSize << 1); + } } } }