Emulate sound in sf2mdt, captcommb2 and knightsb4, all use a Z80 to drive a YM2151 and 2 x MSM5205
This commit is contained in:
parent
5381fc93d6
commit
7f964103c8
|
@ -238,11 +238,15 @@ extern UINT8* CpsEncZRom;
|
|||
INT32 CpsRwInit();
|
||||
INT32 CpsRwExit();
|
||||
INT32 CpsRwGetInp();
|
||||
void CpsWritePort(const UINT32 ia, UINT8 d);
|
||||
UINT8 __fastcall CpsReadByte(UINT32 a);
|
||||
void __fastcall CpsWriteByte(UINT32 a, UINT8 d);
|
||||
UINT16 __fastcall CpsReadWord(UINT32 a);
|
||||
void __fastcall CpsWriteWord(UINT32 a, UINT16 d);
|
||||
|
||||
typedef void (*CpsRWSoundCommandCallback)(UINT16);
|
||||
extern CpsRWSoundCommandCallback CpsRWSoundCommandCallbackFunction;
|
||||
|
||||
// cps_draw.cpp
|
||||
extern UINT8 CpsRecalcPal; // Flag - If it is 1, recalc the whole palette
|
||||
extern INT32 nCpsLcReg; // Address of layer controller register
|
||||
|
@ -423,9 +427,17 @@ void slammast_decode();
|
|||
void cps2_decrypt_game_data();
|
||||
|
||||
// fcrash_snd.cpp
|
||||
void FrcashSoundCommand(UINT16 d);
|
||||
void FcrashSoundCommand(UINT16 d);
|
||||
INT32 FcrashSoundInit();
|
||||
INT32 FcrashSoundReset();
|
||||
INT32 FcrashSoundExit();
|
||||
void FcrashSoundFrameStart();
|
||||
void FcrashSoundFrameEnd();
|
||||
|
||||
// sf2mdt_snd.cpp
|
||||
void Sf2mdtSoundCommand(UINT16 d);
|
||||
INT32 Sf2mdtSoundInit();
|
||||
INT32 Sf2mdtSoundReset();
|
||||
INT32 Sf2mdtSoundExit();
|
||||
void Sf2mdtSoundFrameStart();
|
||||
void Sf2mdtSoundFrameEnd();
|
||||
|
|
|
@ -34,6 +34,8 @@ INT32 Ssf2tb = 0;
|
|||
INT32 Dinohunt = 0;
|
||||
INT32 Port6SoundWrite = 0;
|
||||
|
||||
CpsRWSoundCommandCallback CpsRWSoundCommandCallbackFunction = NULL;
|
||||
|
||||
static INT32 nCalc[2] = {0, 0};
|
||||
|
||||
static const bool nCPSExtraNVRAM = false;
|
||||
|
@ -281,7 +283,7 @@ static UINT8 CpsReadPort(const UINT32 ia)
|
|||
}
|
||||
|
||||
// Write output port 0x000-0x1ff
|
||||
static void CpsWritePort(const UINT32 ia, UINT8 d)
|
||||
void CpsWritePort(const UINT32 ia, UINT8 d)
|
||||
{
|
||||
if ((Cps & 1) && Cps1Qs == 0) {
|
||||
if (!Cps1DisablePSnd) {
|
||||
|
@ -300,6 +302,12 @@ static void CpsWritePort(const UINT32 ia, UINT8 d)
|
|||
PsndFade = d;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (ia == 0x181 || (Port6SoundWrite && (ia == 0x006 || ia == 0x007))) {
|
||||
if (CpsRWSoundCommandCallbackFunction) {
|
||||
CpsRWSoundCommandCallbackFunction(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ia == 0x041) {
|
||||
|
@ -487,6 +495,7 @@ INT32 CpsRwInit()
|
|||
INT32 CpsRwExit()
|
||||
{
|
||||
InpBlank();
|
||||
CpsRWSoundCommandCallbackFunction = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10883,6 +10883,12 @@ static INT32 CaptcommbInit()
|
|||
static INT32 Captcommb2Init()
|
||||
{
|
||||
Cps1DisablePSnd = 1;
|
||||
CpsRunInitCallbackFunction = Sf2mdtSoundInit;
|
||||
CpsRunResetCallbackFunction = Sf2mdtSoundReset;
|
||||
CpsRunExitCallbackFunction = Sf2mdtSoundExit;
|
||||
CpsRunFrameStartCallbackFunction = Sf2mdtSoundFrameStart;
|
||||
CpsRunFrameEndCallbackFunction = Sf2mdtSoundFrameEnd;
|
||||
CpsRWSoundCommandCallbackFunction = Sf2mdtSoundCommand;
|
||||
|
||||
return DrvInit();
|
||||
}
|
||||
|
@ -10926,7 +10932,7 @@ void __fastcall CawingblInputWrite(UINT32 a, UINT8 d)
|
|||
{
|
||||
switch (a) {
|
||||
case 0x882006: {
|
||||
FrcashSoundCommand(d);
|
||||
FcrashSoundCommand(d);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -11194,7 +11200,7 @@ void __fastcall FcrashInputWriteWord(UINT32 a, UINT16 d)
|
|||
{
|
||||
switch (a) {
|
||||
case 0x880006: {
|
||||
FrcashSoundCommand(d);
|
||||
FcrashSoundCommand(d);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -11539,9 +11545,16 @@ static INT32 Knightsb4Init()
|
|||
Cps1DisablePSnd = 1;
|
||||
bCpsUpdatePalEveryFrame = 1;
|
||||
Cps1OverrideLayers = 1;
|
||||
Port6SoundWrite = 1;
|
||||
|
||||
Cps1ObjGetCallbackFunction = DinopicObjGet;
|
||||
Cps1ObjDrawCallbackFunction = FcrashObjDraw;
|
||||
CpsRunInitCallbackFunction = Sf2mdtSoundInit;
|
||||
CpsRunResetCallbackFunction = Sf2mdtSoundReset;
|
||||
CpsRunExitCallbackFunction = Sf2mdtSoundExit;
|
||||
CpsRunFrameStartCallbackFunction = Sf2mdtSoundFrameStart;
|
||||
CpsRunFrameEndCallbackFunction = Sf2mdtSoundFrameEnd;
|
||||
CpsRWSoundCommandCallbackFunction = Sf2mdtSoundCommand;
|
||||
|
||||
INT32 nRet = DrvInit();
|
||||
|
||||
|
@ -11998,15 +12011,15 @@ UINT8 __fastcall Sf2mdtReadByte(UINT32 a)
|
|||
{
|
||||
switch (a) {
|
||||
case 0x70c01a: {
|
||||
return 0xff;
|
||||
return ~Cpi01A;
|
||||
}
|
||||
|
||||
case 0x70c01c: {
|
||||
return 0xff;
|
||||
return ~Cpi01C;
|
||||
}
|
||||
|
||||
case 0x70c01e: {
|
||||
return 0xff;
|
||||
return ~Cpi01E;
|
||||
}
|
||||
|
||||
default: {
|
||||
|
@ -12033,6 +12046,12 @@ static INT32 Sf2mdtInit()
|
|||
Cps1GfxLoadCallbackFunction = CpsLoadTilesSf2mdt;
|
||||
|
||||
Cps1DisablePSnd = 1;
|
||||
CpsRunInitCallbackFunction = Sf2mdtSoundInit;
|
||||
CpsRunResetCallbackFunction = Sf2mdtSoundReset;
|
||||
CpsRunExitCallbackFunction = Sf2mdtSoundExit;
|
||||
CpsRunFrameStartCallbackFunction = Sf2mdtSoundFrameStart;
|
||||
CpsRunFrameEndCallbackFunction = Sf2mdtSoundFrameEnd;
|
||||
CpsRWSoundCommandCallbackFunction = Sf2mdtSoundCommand;
|
||||
|
||||
INT32 nRet = Sf2ceInit();
|
||||
|
||||
|
@ -13109,7 +13128,7 @@ struct BurnDriver BurnDrvCpsCaptcommb = {
|
|||
|
||||
struct BurnDriver BurnDrvCpsCaptcommb2 = {
|
||||
"captcommb2", "captcomm", NULL, NULL, "1991",
|
||||
"Captain Commando (bootleg, set 2)\0", "No sound", "bootleg", "CPS1",
|
||||
"Captain Commando (bootleg, set 2)\0", NULL, "bootleg", "CPS1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_GAME_WORKING | BDF_CLONE | BDF_BOOTLEG, 4, HARDWARE_CAPCOM_CPS1, GBF_SCRFIGHT, 0,
|
||||
NULL, Captcommb2RomInfo, Captcommb2RomName, NULL, NULL, CaptcommInputInfo, CaptcommDIPInfo,
|
||||
|
@ -13619,7 +13638,7 @@ struct BurnDriver BurnDrvCpsKnightsb3 = {
|
|||
|
||||
struct BurnDriver BurnDrvCpsKnightsb4 = {
|
||||
"knightsb4", "knights", NULL, NULL, "1991",
|
||||
"Knights of the Round (911127 etc bootleg set 4)\0", "No sound", "bootleg", "CPS1",
|
||||
"Knights of the Round (911127 etc bootleg set 4)\0", NULL, "bootleg", "CPS1",
|
||||
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,
|
||||
|
@ -14459,7 +14478,7 @@ struct BurnDriver BurnDrvCpsSf2koryu2 = {
|
|||
|
||||
struct BurnDriverD BurnDrvCpsSf2mdt = {
|
||||
"sf2mdt", "sf2ce", NULL, NULL, "1992",
|
||||
"Street Fighter II' - Magic Delta Turbo (bootleg)\0", "No sound, incorrect graphics", "Capcom", "CPS1",
|
||||
"Street Fighter II' - Magic Delta Turbo (bootleg)\0", "Incorrect graphics", "Capcom", "CPS1",
|
||||
NULL, NULL, NULL, NULL,
|
||||
BDF_CLONE | BDF_BOOTLEG, 2, HARDWARE_CAPCOM_CPS1, GBF_VSFIGHT, FBF_SF,
|
||||
NULL, Sf2mdtRomInfo, Sf2mdtRomName, NULL, NULL, Sf2InputInfo, Sf2DIPInfo,
|
||||
|
|
|
@ -17,7 +17,7 @@ static INT32 FcrashSampleSelect2 = 0;
|
|||
static INT32 FcrashSoundPos = 0;
|
||||
static INT32 FcrashCyclesPerSegment = 0;
|
||||
|
||||
void FrcashSoundCommand(UINT16 d)
|
||||
void FcrashSoundCommand(UINT16 d)
|
||||
{
|
||||
if (d & 0xff) {
|
||||
INT32 nCyclesToDo = ((INT64)SekTotalCycles() * nCpsZ80Cycles / nCpsCycles) - ZetTotalCycles();
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
#include "cps.h"
|
||||
#include "burn_ym2151.h"
|
||||
#include "msm5205.h"
|
||||
|
||||
// sf2mdt_snd.cpp
|
||||
// Sound support for games using similar sound to Street Fighter 2: Magic Delta Turbo
|
||||
// 1 x YM2151 and 2 x MSM5205
|
||||
|
||||
static UINT8 *Sf2mdtZ80Ram = NULL;
|
||||
static INT32 Sf2mdtZ80BankAddress = 0;
|
||||
static INT32 Sf2mdtSoundLatch = 0;
|
||||
static INT32 Sf2mdtMSM5205Interleave = 0;
|
||||
static INT32 Sf2mdtSampleBuffer1 = 0;
|
||||
static INT32 Sf2mdtSampleBuffer2 = 0;
|
||||
static INT32 Sf2mdtSampleSelect1 = 0;
|
||||
static INT32 Sf2mdtSampleSelect2 = 0;
|
||||
static INT32 Sf2mdtSoundPos = 0;
|
||||
static INT32 Sf2mdtCyclesPerSegment = 0;
|
||||
static INT32 Sf2NumZ80Banks = 0;
|
||||
|
||||
void Sf2mdtSoundCommand(UINT16 d)
|
||||
{
|
||||
if (d & 0xff) {
|
||||
INT32 nCyclesToDo = ((INT64)SekTotalCycles() * nCpsZ80Cycles / nCpsCycles) - ZetTotalCycles();
|
||||
INT32 nEnd = Sf2mdtSoundPos + (INT64)Sf2mdtMSM5205Interleave * nCyclesToDo / nCpsZ80Cycles;
|
||||
|
||||
for (INT32 i = Sf2mdtSoundPos; i < nEnd; i++) {
|
||||
ZetRun(Sf2mdtCyclesPerSegment);
|
||||
MSM5205Update();
|
||||
Sf2mdtSoundPos = i;
|
||||
}
|
||||
|
||||
Sf2mdtSoundLatch = d & 0xff;
|
||||
ZetSetIRQLine(0, ZET_IRQSTATUS_ACK);
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 __fastcall Sf2mdtZ80Read(UINT16 a)
|
||||
{
|
||||
switch (a) {
|
||||
case 0xd801: {
|
||||
return BurnYM2151ReadStatus();
|
||||
}
|
||||
|
||||
case 0xdc00: {
|
||||
ZetSetIRQLine(0, ZET_IRQSTATUS_NONE);
|
||||
return Sf2mdtSoundLatch;
|
||||
}
|
||||
|
||||
default: {
|
||||
bprintf(PRINT_NORMAL, _T("Z80 #1 Read => %04X\n"), a);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __fastcall Sf2mdtZ80Write(UINT16 a, UINT8 d)
|
||||
{
|
||||
switch (a) {
|
||||
case 0xd800: {
|
||||
BurnYM2151SelectRegister(d);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0xd801: {
|
||||
BurnYM2151WriteRegister(d);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0xe000: {
|
||||
MSM5205SetVolume(0, (d & 0x20) ? 0 : 20);
|
||||
MSM5205SetVolume(1, (d & 0x10) ? 0 : 20);
|
||||
|
||||
Sf2mdtZ80BankAddress = (d & Sf2NumZ80Banks) * 0x4000;
|
||||
ZetMapArea(0x8000, 0xbfff, 0, CpsZRom + Sf2mdtZ80BankAddress);
|
||||
ZetMapArea(0x8000, 0xbfff, 2, CpsZRom + Sf2mdtZ80BankAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
case 0xe400: {
|
||||
Sf2mdtSampleBuffer1 = d;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0xe800: {
|
||||
Sf2mdtSampleBuffer2 = d;
|
||||
return;
|
||||
}
|
||||
|
||||
default: {
|
||||
bprintf(PRINT_NORMAL, _T("Z80 #1 Write => %04X, %02X\n"), a, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline static INT32 Sf2mdtSynchroniseStream(INT32 nSoundRate)
|
||||
{
|
||||
return (INT64)(ZetTotalCycles() * nSoundRate / 3579540);
|
||||
}
|
||||
|
||||
static void Sf2mdtMSM5205Vck0()
|
||||
{
|
||||
MSM5205DataWrite(0, Sf2mdtSampleBuffer1 & 0x0f);
|
||||
Sf2mdtSampleBuffer1 >>= 4;
|
||||
Sf2mdtSampleSelect1 ^= 1;
|
||||
if (Sf2mdtSampleSelect1 == 0) {
|
||||
ZetNmi();
|
||||
}
|
||||
}
|
||||
|
||||
static void Sf2mdtMSM5205Vck1()
|
||||
{
|
||||
MSM5205DataWrite(1, Sf2mdtSampleBuffer2 & 0x0f);
|
||||
Sf2mdtSampleBuffer2 >>= 4;
|
||||
Sf2mdtSampleSelect2 ^= 1;
|
||||
}
|
||||
|
||||
INT32 Sf2mdtSoundInit()
|
||||
{
|
||||
Sf2mdtZ80Ram = (UINT8*)BurnMalloc(0x800);
|
||||
|
||||
ZetInit(0);
|
||||
ZetOpen(0);
|
||||
ZetSetReadHandler(Sf2mdtZ80Read);
|
||||
ZetSetWriteHandler(Sf2mdtZ80Write);
|
||||
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, Sf2mdtZ80Ram );
|
||||
ZetMapArea(0xd000, 0xd7ff, 1, Sf2mdtZ80Ram );
|
||||
ZetMapArea(0xd000, 0xd7ff, 2, Sf2mdtZ80Ram );
|
||||
ZetMemEnd();
|
||||
ZetClose();
|
||||
|
||||
BurnYM2151Init(3579540, 50.0);
|
||||
|
||||
MSM5205Init(0, Sf2mdtSynchroniseStream, 24000000 / 64, Sf2mdtMSM5205Vck0, MSM5205_S96_4B, 20, 1);
|
||||
MSM5205Init(1, Sf2mdtSynchroniseStream, 24000000 / 64, Sf2mdtMSM5205Vck1, MSM5205_S96_4B, 20, 1);
|
||||
|
||||
nCpsZ80Cycles = 3579540 * 100 / nBurnFPS;
|
||||
|
||||
Sf2NumZ80Banks = (nCpsZRomLen / 0x4000) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 Sf2mdtSoundReset()
|
||||
{
|
||||
ZetOpen(0);
|
||||
ZetReset();
|
||||
BurnYM2151Reset();
|
||||
MSM5205Reset();
|
||||
Sf2mdtZ80BankAddress = 2;
|
||||
ZetMapArea(0x8000, 0xbfff, 0, CpsZRom + Sf2mdtZ80BankAddress);
|
||||
ZetMapArea(0x8000, 0xbfff, 2, CpsZRom + Sf2mdtZ80BankAddress);
|
||||
ZetClose();
|
||||
|
||||
Sf2mdtSoundLatch = 0;
|
||||
Sf2mdtSampleBuffer1 = 0;
|
||||
Sf2mdtSampleBuffer2 = 0;
|
||||
Sf2mdtSampleSelect1 = 0;
|
||||
Sf2mdtSampleSelect2 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 Sf2mdtSoundExit()
|
||||
{
|
||||
ZetExit();
|
||||
BurnYM2151Exit();
|
||||
MSM5205Exit();
|
||||
|
||||
BurnFree(Sf2mdtZ80Ram);
|
||||
|
||||
Sf2mdtZ80BankAddress = 0;
|
||||
Sf2mdtSoundLatch = 0;
|
||||
Sf2mdtMSM5205Interleave = 0;
|
||||
Sf2mdtSampleBuffer1 = 0;
|
||||
Sf2mdtSampleBuffer2 = 0;
|
||||
Sf2mdtSampleSelect1 = 0;
|
||||
Sf2mdtSampleSelect2 = 0;
|
||||
Sf2mdtCyclesPerSegment = 0;
|
||||
Sf2NumZ80Banks = 0;
|
||||
|
||||
nCpsZ80Cycles = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Sf2mdtSoundFrameStart()
|
||||
{
|
||||
Sf2mdtMSM5205Interleave = MSM5205CalcInterleave(0, 3579540);
|
||||
Sf2mdtSoundPos = 0;
|
||||
Sf2mdtCyclesPerSegment = (INT64)nCpsZ80Cycles / Sf2mdtMSM5205Interleave;
|
||||
|
||||
ZetNewFrame();
|
||||
ZetOpen(0);
|
||||
}
|
||||
|
||||
void Sf2mdtSoundFrameEnd()
|
||||
{
|
||||
for (INT32 i = Sf2mdtSoundPos; i < Sf2mdtMSM5205Interleave; i++) {
|
||||
ZetRun(Sf2mdtCyclesPerSegment);
|
||||
MSM5205Update();
|
||||
Sf2mdtSoundPos = i;
|
||||
}
|
||||
ZetRun(nCpsZ80Cycles - ZetTotalCycles());
|
||||
|
||||
if (pBurnSoundOut) {
|
||||
BurnYM2151Render(pBurnSoundOut, nBurnSoundLen);
|
||||
MSM5205Render(0, pBurnSoundOut, nBurnSoundLen);
|
||||
MSM5205Render(1, pBurnSoundOut, nBurnSoundLen);
|
||||
}
|
||||
ZetClose();
|
||||
}
|
Loading…
Reference in New Issue