diff --git a/src/burn/drv/capcom/cps.h b/src/burn/drv/capcom/cps.h index 5c995b55a..ca9b41d97 100644 --- a/src/burn/drv/capcom/cps.h +++ b/src/burn/drv/capcom/cps.h @@ -169,6 +169,16 @@ INT32 CpsRunInit(); INT32 CpsRunExit(); INT32 Cps1Frame(); INT32 Cps2Frame(); +typedef INT32 (*CpsRunInitCallback)(); +extern CpsRunInitCallback CpsRunInitCallbackFunction; +typedef INT32 (*CpsRunExitCallback)(); +extern CpsRunExitCallback CpsRunExitCallbackFunction; +typedef INT32 (*CpsRunResetCallback)(); +extern CpsRunResetCallback CpsRunResetCallbackFunction; +typedef void (*CpsRunFrameStartCallback)(); +extern CpsRunFrameStartCallback CpsRunFrameStartCallbackFunction; +typedef void (*CpsRunFrameEndCallback)(); +extern CpsRunFrameEndCallback CpsRunFrameEndCallbackFunction; inline static UINT8* CpsFindGfxRam(INT32 nAddr,INT32 nLen) { @@ -411,3 +421,11 @@ void slammast_decode(); // cps2_crypt.cpp void cps2_decrypt_game_data(); + +// fcrash_snd.cpp +void FrcashSoundCommand(UINT16 d); +INT32 FcrashSoundInit(); +INT32 FcrashSoundReset(); +INT32 FcrashSoundExit(); +void FcrashSoundFrameStart(); +void FcrashSoundFrameEnd(); diff --git a/src/burn/drv/capcom/cps_run.cpp b/src/burn/drv/capcom/cps_run.cpp index 68d21ccb6..a927cf93c 100644 --- a/src/burn/drv/capcom/cps_run.cpp +++ b/src/burn/drv/capcom/cps_run.cpp @@ -19,6 +19,12 @@ INT32 nIrqLine50, nIrqLine52; INT32 nCpsNumScanlines = 259; +CpsRunInitCallback CpsRunInitCallbackFunction = NULL; +CpsRunInitCallback CpsRunExitCallbackFunction = NULL; +CpsRunResetCallback CpsRunResetCallbackFunction = NULL; +CpsRunFrameStartCallback CpsRunFrameStartCallbackFunction = NULL; +CpsRunFrameEndCallback CpsRunFrameEndCallbackFunction = NULL; + static void CpsQSoundCheatSearchCallback() { // Q-Sound Shared RAM ranges - not useful for cheat searching, and runs the Z80 @@ -65,6 +71,10 @@ static INT32 DrvReset() QsndReset(); } + if (CpsRunResetCallbackFunction) { + CpsRunResetCallbackFunction(); + } + HiscoreReset(); return 0; @@ -134,6 +144,11 @@ INT32 CpsRunInit() } if (Cps == 2 || PangEEP || Cps1Qs == 1) EEPROMReset(); + + if (CpsRunInitCallbackFunction) { + CpsRunInitCallbackFunction(); + } + DrvReset(); //Init Draw Function @@ -168,6 +183,15 @@ INT32 CpsRunExit() CpsMemExit(); SekExit(); + + if (CpsRunExitCallbackFunction) { + CpsRunExitCallbackFunction(); + CpsRunExitCallbackFunction = NULL; + } + CpsRunInitCallbackFunction = NULL; + CpsRunResetCallbackFunction = NULL; + CpsRunFrameStartCallbackFunction = NULL; + CpsRunFrameEndCallbackFunction = NULL; return 0; } @@ -269,6 +293,10 @@ INT32 Cps1Frame() PsndNewFrame(); } } + + if (CpsRunFrameStartCallbackFunction) { + CpsRunFrameStartCallbackFunction(); + } nCpsCycles = (INT32)((INT64)nCPS68KClockspeed * nBurnCPUSpeedAdjust >> 8); @@ -315,6 +343,10 @@ INT32 Cps1Frame() ZetClose(); } } + + if (CpsRunFrameEndCallbackFunction) { + CpsRunFrameEndCallbackFunction(); + } nCpsCyclesExtra = SekTotalCycles() - nCpsCycles; diff --git a/src/burn/drv/capcom/d_cps1.cpp b/src/burn/drv/capcom/d_cps1.cpp index 9fdb5a636..741e7fe83 100644 --- a/src/burn/drv/capcom/d_cps1.cpp +++ b/src/burn/drv/capcom/d_cps1.cpp @@ -10925,6 +10925,11 @@ UINT8 __fastcall CawingblInputRead(UINT32 a) void __fastcall CawingblInputWrite(UINT32 a, UINT8 d) { switch (a) { + case 0x882006: { + FrcashSoundCommand(d); + return; + } + default: { bprintf(PRINT_NORMAL, _T("Input Write Byte %x, %x\n"), a, d); } @@ -10935,11 +10940,18 @@ static INT32 CawingblInit() { INT32 nRet = 0; + Cps1DisablePSnd = 1; + CpsLayer1XOffs = 0xffc0; // CpsLayer2XOffs = 0xffc0; // CpsLayer3XOffs = 0xffc0; Cps1GfxLoadCallbackFunction = CpsLoadTilesCawingbl; + CpsRunInitCallbackFunction = FcrashSoundInit; + CpsRunResetCallbackFunction = FcrashSoundReset; + CpsRunExitCallbackFunction = FcrashSoundExit; + CpsRunFrameStartCallbackFunction = FcrashSoundFrameStart; + CpsRunFrameEndCallbackFunction = FcrashSoundFrameEnd; nRet = DrvInit(); @@ -11181,6 +11193,16 @@ void __fastcall FcrashInputWriteByte(UINT32 a, UINT8 d) void __fastcall FcrashInputWriteWord(UINT32 a, UINT16 d) { switch (a) { + case 0x880006: { + FrcashSoundCommand(d); + return; + } + + case 0x890000: { + // ??? + return; + } + default: { bprintf(PRINT_NORMAL, _T("Input Write word %x, %x\n"), a, d); } @@ -11198,6 +11220,11 @@ static INT32 FcrashInit() Cps1GfxLoadCallbackFunction = CpsLoadTilesFcrash; Cps1ObjGetCallbackFunction = FcrashObjGet; Cps1ObjDrawCallbackFunction = FcrashObjDraw; + CpsRunInitCallbackFunction = FcrashSoundInit; + CpsRunResetCallbackFunction = FcrashSoundReset; + CpsRunExitCallbackFunction = FcrashSoundExit; + CpsRunFrameStartCallbackFunction = FcrashSoundFrameStart; + CpsRunFrameEndCallbackFunction = FcrashSoundFrameEnd; INT32 nRet = DrvInit(); @@ -11479,9 +11506,9 @@ void __fastcall Knightsb98WriteWord(UINT32 a, UINT16 d) static INT32 KnightsbInit() { - Cps1DisablePSnd = 1; bCpsUpdatePalEveryFrame = 1; Cps1OverrideLayers = 1; + Port6SoundWrite = 1; Cps1ObjGetCallbackFunction = DinopicObjGet; Cps1ObjDrawCallbackFunction = FcrashObjDraw; @@ -11507,6 +11534,28 @@ static INT32 Knightsb2Init() return DrvInit(); } +static INT32 Knightsb4Init() +{ + Cps1DisablePSnd = 1; + bCpsUpdatePalEveryFrame = 1; + Cps1OverrideLayers = 1; + + Cps1ObjGetCallbackFunction = DinopicObjGet; + Cps1ObjDrawCallbackFunction = FcrashObjDraw; + + INT32 nRet = DrvInit(); + + CpsBootlegSpriteRam = (UINT8*)BurnMalloc(0x2000); + + SekOpen(0); + SekMapMemory(CpsBootlegSpriteRam, 0x990000, 0x991FFF, SM_RAM); + SekMapHandler(1, 0x980000, 0x98ffff, SM_WRITE); + SekSetWriteWordHandler(1, Knightsb98WriteWord); + SekClose(); + + return nRet; +} + static INT32 KodbInit() { INT32 nRet = 0; @@ -13380,7 +13429,7 @@ struct BurnDriver BurnDrvCpsFfightjh = { struct BurnDriver BurnDrvCpsFcrash = { "fcrash", "ffight", NULL, NULL, "1990", - "Final Crash (bootleg)\0", "No sound, some sprite priority issues", "Playmark", "CPS1", + "Final Crash (bootleg)\0", NULL, "Playmark", "CPS1", NULL, NULL, NULL, NULL, BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_CAPCOM_CPS1, GBF_SCRFIGHT, 0, NULL, FcrashRomInfo, FcrashRomName, NULL, NULL, FfightInputInfo, FfightDIPInfo, @@ -13540,7 +13589,7 @@ struct BurnDriver BurnDrvCpsKnightsja = { struct BurnDriver BurnDrvCpsKnightsb = { "knightsb", "knights", NULL, NULL, "1991", - "Knights of the Round (911127 etc bootleg set 1)\0", "No sound", "bootleg", "CPS1", + "Knights of the Round (911127 etc bootleg set 1)\0", NULL, "bootleg", "CPS1", NULL, NULL, NULL, NULL, BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 3, HARDWARE_CAPCOM_CPS1, GBF_SCRFIGHT, 0, NULL, KnightsbRomInfo, KnightsbRomName, NULL, NULL, KnightsInputInfo, KnightsDIPInfo, @@ -13574,7 +13623,7 @@ struct BurnDriver BurnDrvCpsKnightsb4 = { NULL, NULL, NULL, NULL, BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 3, HARDWARE_CAPCOM_CPS1, GBF_SCRFIGHT, 0, NULL, Knightsb4RomInfo, Knightsb4RomName, NULL, NULL, KnightsInputInfo, KnightsDIPInfo, - KnightsbInit, DrvExit, Cps1Frame, CpsRedraw, CpsAreaScan, + Knightsb4Init, DrvExit, Cps1Frame, CpsRedraw, CpsAreaScan, &CpsRecalcPal, 0x1000, 384, 224, 4, 3 }; diff --git a/src/burn/drv/capcom/fcrash_snd.cpp b/src/burn/drv/capcom/fcrash_snd.cpp new file mode 100644 index 000000000..264cbe7ff --- /dev/null +++ b/src/burn/drv/capcom/fcrash_snd.cpp @@ -0,0 +1,236 @@ +#include "cps.h" +#include "burn_ym2203.h" +#include "msm5205.h" + +static UINT8 *FcrashZ80Ram = NULL; +static INT32 FcrashZ80BankAddress = 0; +static INT32 FcrashSoundLatch = 0; +static INT32 FcrashMSM5205Interleave = 0; +static INT32 FcrashSampleBuffer1 = 0; +static INT32 FcrashSampleBuffer2 = 0; +static INT32 FcrashSampleSelect1 = 0; +static INT32 FcrashSampleSelect2 = 0; + +void FrcashSoundCommand(UINT16 d) +{ + if (d & 0xff) { + INT32 nCyclesToDo = (INT64)SekTotalCycles() * nCpsZ80Cycles / nCpsCycles; + INT32 nFramePortion = (INT64)FcrashMSM5205Interleave * nCyclesToDo / nCpsZ80Cycles; + INT32 nCyclesPerPortion = nCyclesToDo / nFramePortion; + + for (INT32 i = 0; i < nFramePortion; i++) { + BurnTimerUpdate((i + 1) * nCyclesPerPortion); + MSM5205Update(); + } + + FcrashSoundLatch = d & 0xff; + ZetSetIRQLine(0, ZET_IRQSTATUS_ACK); + } +} + +UINT8 __fastcall FcrashZ80Read(UINT16 a) +{ + switch (a) { + case 0xd800: { + return BurnYM2203Read(0, 0); + } + + case 0xdc00: { + return BurnYM2203Read(1, 0); + } + + case 0xe400: { + ZetSetIRQLine(0, ZET_IRQSTATUS_NONE); + return FcrashSoundLatch; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Read => %04X\n"), a); + } + } + + return 0; +} + +void __fastcall FcrashZ80Write(UINT16 a, UINT8 d) +{ + switch (a) { + case 0xd800: { + BurnYM2203Write(0, 0, d); + return; + } + + case 0xd801: { + BurnYM2203Write(0, 1, d); + return; + } + + case 0xdc00: { + BurnYM2203Write(1, 0, d); + return; + } + + case 0xdc01: { + BurnYM2203Write(1, 1, d); + return; + } + + case 0xe000: { + MSM5205SetVolume(0, (d & 0x08) ? 0 : 30); + MSM5205SetVolume(1, (d & 0x10) ? 0 : 30); + + FcrashZ80BankAddress = (d & 0x07) * 0x4000; + ZetMapArea(0x8000, 0xbfff, 0, CpsZRom + FcrashZ80BankAddress); + ZetMapArea(0x8000, 0xbfff, 2, CpsZRom + FcrashZ80BankAddress); + return; + } + + case 0xe800: { + FcrashSampleBuffer1 = d; + return; + } + + case 0xec00: { + FcrashSampleBuffer2 = d; + return; + } + + case 0xf002: + case 0xf004: + case 0xf006: { + // ??? + return; + } + + default: { + bprintf(PRINT_NORMAL, _T("Z80 #1 Write => %04X, %02X\n"), a, d); + } + } +} + +inline static INT32 FcrashSynchroniseStream(INT32 nSoundRate) +{ + return (INT64)(ZetTotalCycles() * nSoundRate / (24000000 / 6)); +} + +inline static double FcrashGetTime() +{ + return (double)ZetTotalCycles() / (24000000 / 6); +} + +static void FcrashMSM5205Vck0() +{ + MSM5205DataWrite(0, FcrashSampleBuffer1 & 0x0f); + FcrashSampleBuffer1 >>= 4; + FcrashSampleSelect1 ^= 1; + if (FcrashSampleSelect1 == 0) { + ZetNmi(); + } +} + +static void FcrashMSM5205Vck1() +{ + MSM5205DataWrite(1, FcrashSampleBuffer2 & 0x0f); + FcrashSampleBuffer2 >>= 4; + FcrashSampleSelect2 ^= 1; +} + +INT32 FcrashSoundInit() +{ + FcrashZ80Ram = (UINT8*)BurnMalloc(0x800); + + ZetInit(0); + ZetOpen(0); + ZetSetReadHandler(FcrashZ80Read); + ZetSetWriteHandler(FcrashZ80Write); + ZetMapArea(0x0000, 0x7fff, 0, CpsZRom + 0x00000); + ZetMapArea(0x0000, 0x7fff, 2, CpsZRom + 0x00000); + ZetMapArea(0x8000, 0xbfff, 0, CpsZRom + 0x08000); + ZetMapArea(0x8000, 0xbfff, 2, CpsZRom + 0x08000); + ZetMapArea(0xd000, 0xd7ff, 0, FcrashZ80Ram ); + ZetMapArea(0xd000, 0xd7ff, 1, FcrashZ80Ram ); + ZetMapArea(0xd000, 0xd7ff, 2, FcrashZ80Ram ); + ZetMemEnd(); + ZetClose(); + + BurnYM2203Init(2, 24000000 / 6, NULL, FcrashSynchroniseStream, FcrashGetTime, 0); + BurnTimerAttachZet(24000000 / 6); + BurnYM2203SetVolumeShift(2); + + MSM5205Init(0, FcrashSynchroniseStream, 24000000 / 64, FcrashMSM5205Vck0, MSM5205_S96_4B, 30, 1); + MSM5205Init(1, FcrashSynchroniseStream, 24000000 / 64, FcrashMSM5205Vck1, MSM5205_S96_4B, 30, 1); + + nCpsZ80Cycles = (24000000 / 6) * 100 / nBurnFPS; + + return 0; +} + +INT32 FcrashSoundReset() +{ + ZetOpen(0); + ZetReset(); + BurnYM2203Reset(); + MSM5205Reset(); + FcrashZ80BankAddress = 2; + ZetMapArea(0x8000, 0xbfff, 0, CpsZRom + FcrashZ80BankAddress); + ZetMapArea(0x8000, 0xbfff, 2, CpsZRom + FcrashZ80BankAddress); + ZetClose(); + + FcrashSoundLatch = 0; + FcrashSampleBuffer1 = 0; + FcrashSampleBuffer2 = 0; + FcrashSampleSelect1 = 0; + FcrashSampleSelect2 = 0; + + return 0; +} + +INT32 FcrashSoundExit() +{ + ZetExit(); + BurnYM2203Exit(); + MSM5205Exit(); + + BurnFree(FcrashZ80Ram); + + FcrashZ80BankAddress = 0; + FcrashSoundLatch = 0; + FcrashMSM5205Interleave = 0; + FcrashSampleBuffer1 = 0; + FcrashSampleBuffer2 = 0; + FcrashSampleSelect1 = 0; + FcrashSampleSelect2 = 0; + + nCpsZ80Cycles = 0; + + return 0; +} + +void FcrashSoundFrameStart() +{ + FcrashMSM5205Interleave = MSM5205CalcInterleave(0, 24000000 / 6); + + ZetNewFrame(); + ZetOpen(0); +} + +void FcrashSoundFrameEnd() +{ + INT32 nStartCycles = ZetTotalCycles(); + INT32 nCyclesToDo = nCpsZ80Cycles - nStartCycles; + INT32 nFramePortion = (INT64)FcrashMSM5205Interleave * nCyclesToDo / nCpsZ80Cycles; + INT32 nCyclesPerPortion = nCyclesToDo / nFramePortion; + + for (INT32 i = 0; i < nFramePortion; i++) { + BurnTimerUpdate(nStartCycles + ((i + 1) * nCyclesPerPortion)); + MSM5205Update(); + } + BurnTimerEndFrame(nCpsZ80Cycles); + + if (pBurnSoundOut) { + BurnYM2203Update(pBurnSoundOut, nBurnSoundLen); + MSM5205Render(0, pBurnSoundOut, nBurnSoundLen); + MSM5205Render(1, pBurnSoundOut, nBurnSoundLen); + } + ZetClose(); +}