Skip to content

Commit

Permalink
neogeo update (libretro#1015)
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
taoenwen authored May 3, 2022
1 parent 078599a commit df49d8d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 30 deletions.
55 changes: 28 additions & 27 deletions src/burn/drv/neogeo/d_neogeo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down
35 changes: 33 additions & 2 deletions src/burn/drv/neogeo/neo_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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++) {
Expand Down
25 changes: 24 additions & 1 deletion src/burn/drv/neogeo/neogeo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}
}
}
Expand Down

0 comments on commit df49d8d

Please sign in to comment.