Skip to content

Commit

Permalink
megadrive, fix determinism (re-recording, etc)
Browse files Browse the repository at this point in the history
  • Loading branch information
dinkc64 committed Dec 25, 2024
1 parent 95c4eea commit 73e8c30
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 55 deletions.
63 changes: 21 additions & 42 deletions src/burn/drv/megadrive/megadrive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,16 @@ static void SekRunM68k(INT32 cyc)
m68k_ICount = 0;
}

static UINT64 z80_cycle_cnt, z80_cycle_aim, last_z80_sync;
static UINT64 z80_cycle_cnt;

#define z80CyclesReset() { last_z80_sync = z80_cycle_cnt = z80_cycle_aim = 0; }
#define cycles_68k_to_z80(x) ( (x)*957 >> 11 )
#define z80CyclesReset() { z80_cycle_cnt = 0; }
#define cycles_68k_to_z80(x) ((UINT64) (x)*957 >> 11 )

/* sync z80 to 68k */
static void z80CyclesSync(INT32 bRun)
{
INT64 m68k_cycles_done = SekCyclesDone();

INT32 m68k_cnt = m68k_cycles_done - last_z80_sync;
z80_cycle_aim += cycles_68k_to_z80(m68k_cnt);
INT32 cnt = z80_cycle_aim - z80_cycle_cnt;
last_z80_sync = m68k_cycles_done;
INT64 z80_total = cycles_68k_to_z80(SekCyclesDone());
INT32 cnt = z80_total - z80_cycle_cnt;

if (cnt > 0) {
if (bRun) {
Expand Down Expand Up @@ -261,21 +257,17 @@ static UINT32 RomNum = 0;
static UINT32 RomSize = 0;
static UINT32 SRamSize = 0;

static INT32 SpriteBlocks;

static INT32 Scanline = 0;

static INT32 Z80HasBus = 0;
static INT32 MegadriveZ80Reset = 0;
static INT32 RomNoByteswap;

static INT32 dma_xfers = 0; // vdp dma
//static INT32 rendstatus = 0; // status of vdp renderer

static INT32 BlankedLine = 0;
static INT32 interlacemode2 = 0;

static UINT8 Hardware;
static UINT8 DrvSECAM = 0; // NTSC
static UINT8 bNoDebug = 0;
static INT32 bForce3Button = 0;
INT32 psolarmode = 0; // pier solar
Expand Down Expand Up @@ -727,12 +719,6 @@ static UINT32 CheckDMA(void)
return burn;
}

static INT32 DMABURN() { // add cycles to the 68k cpu
if (dma_xfers) {
return CheckDMA();
} else return 0;
}

static void DmaSlow(INT32 len)
{
UINT16 *pd=0, *pdend, *r;
Expand All @@ -750,12 +736,12 @@ static void DmaSlow(INT32 len)

dma_xfers += len;

INT32 dmab = CheckDMA();
// INT32 dmab = CheckDMA();

#ifdef CYCDBUG
// bprintf(0, _T("dma @ ln %d cyc %d, burnt: %d.\n"), Scanline, SekCyclesLine(), dmab);
#endif
SekCyclesBurnRun(dmab);
SekCyclesBurnRun(CheckDMA());

if ((source & 0xe00000) == 0xe00000) { // RAM
pd = (UINT16 *)(Ram68K + (source & 0xfffe));
Expand Down Expand Up @@ -1199,6 +1185,8 @@ static void __fastcall MegadriveVideoWriteWord(UINT32 sekAddress, UINT16 wordVal
UINT8 oldreg = RamVReg->reg[num];
RamVReg->reg[num] = wordValue & 0xff;

// if (num < 2) bprintf(0, _T("sl %d, reg[%02x] %02x\n"),Scanline, num, wordValue&0xff);

// update IRQ level (Lemmings, Wiz 'n' Liz intro, ... )
// may break if done improperly:
// International Superstar Soccer Deluxe (crash), Street Racer (logos), Burning Force (gfx), Fatal Rewind (hang), Sesame Street Counting Cafe
Expand Down Expand Up @@ -3362,7 +3350,6 @@ INT32 MegadriveInit()
BurnSetRefreshRate(60.0);

bNoDebug = 0;
DrvSECAM = 0;
BurnMD2612Init(1, 0, MegadriveSynchroniseStream, 1);
BurnMD2612SetRoute(0, BURN_SND_MD2612_MD2612_ROUTE_1, 0.75, BURN_SND_ROUTE_LEFT);
BurnMD2612SetRoute(0, BURN_SND_MD2612_MD2612_ROUTE_2, 0.75, BURN_SND_ROUTE_RIGHT);
Expand Down Expand Up @@ -3409,7 +3396,6 @@ INT32 MegadriveExit()
}

MegadriveCallback = NULL;
RomNoByteswap = 0;
MegadriveReset = 0;
RomSize = 0;
RomNum = 0;
Expand All @@ -3418,7 +3404,6 @@ INT32 MegadriveExit()
Z80HasBus = 0;
MegadriveZ80Reset = 0;
Hardware = 0;
DrvSECAM = 0;
HighCol = NULL;
bNoDebug = 0;
bForce3Button = 0;
Expand Down Expand Up @@ -4718,9 +4703,7 @@ static void SetHighCol(INT32 line)

static void PicoFrameStart()
{
// rendstatus = 0x80 >> 5; // accurate sprites
RamVReg->status &= ~0x0020; // mask collision bit
// if((RamVReg->reg[12]&6) == 6) rendstatus |= 8; // interlace mode

// prepare to do this frame
RamVReg->rendstatus = 0;
Expand Down Expand Up @@ -5024,13 +5007,17 @@ INT32 MegadriveFrame()

line_base_cycles = SekCyclesDone();
// there must be a gap between H and V ints, also after vblank bit set (Mazin Saga, Bram Stoker's Dracula)
#if 0
#ifdef CYCDBUG
burny = DMABURN();
SekCyclesBurn(burny);
if (burny) {bprintf(0, _T("[%d] v-burny %d, cyclesdone %d. "), Scanline, burny, SekCyclesLine()); }
#else
SekCyclesBurn(DMABURN());
#endif
#endif
SekCyclesBurnRun(CheckDMA());

SekRunM68k(CYCLES_M68K_VINT_LAG);

if(RamVReg->reg[1] & 0x20) {
Expand Down Expand Up @@ -5073,20 +5060,11 @@ INT32 MegadriveFrame()
SekRunM68k(CYCLES_M68K_LINE - CYCLES_M68K_VINT_LAG - CYCLES_M68K_ASD);
} else {
line_base_cycles = SekCyclesDone();
#if 0
#ifdef CYCDBUG
burny = DMABURN();
SekCyclesBurn(burny);
if (burny) {bprintf(0, _T("[%d] burny %d, cyclesdone %d. "), Scanline, burny, SekCyclesLine()); }
#else
SekCyclesBurn(DMABURN());
#endif
#endif

if (y < lines_vis) {
do_timing_hacks_as(vdp_slots);
} else {
SekCyclesBurn(DMABURN());
SekCyclesBurnRun(CheckDMA());
}
SekRunM68k(CYCLES_M68K_LINE);
}
Expand All @@ -5101,15 +5079,20 @@ INT32 MegadriveFrame()

if (pBurnDraw) MegadriveDraw();

#if 0
// this makes no sense
if (Z80HasBus && !MegadriveZ80Reset) {
z80CyclesSync(1);
}
#endif

if (pBurnSoundOut) {
SN76496Update(0, pBurnSoundOut, nBurnSoundLen);
BurnMD2612Update(pBurnSoundOut, nBurnSoundLen);
}

// ym2612 needs to be updated even if pBurnSoundOut is NULL.
BurnMD2612Update(pBurnSoundOut, nBurnSoundLen);

SekClose();
ZetClose();

Expand Down Expand Up @@ -5145,15 +5128,11 @@ INT32 MegadriveScan(INT32 nAction, INT32 *pnMin)
SCAN_VAR(Scanline);
SCAN_VAR(Z80HasBus);
SCAN_VAR(MegadriveZ80Reset);
SCAN_VAR(SpriteBlocks);
// SCAN_VAR(rendstatus);
SCAN_VAR(SekCycleCnt);
SCAN_VAR(SekCycleAim);
SCAN_VAR(dma_xfers);

SCAN_VAR(z80_cycle_cnt);
SCAN_VAR(z80_cycle_aim);
SCAN_VAR(last_z80_sync);

BurnRandomScan(nAction);
}
Expand Down
24 changes: 11 additions & 13 deletions src/burn/snd/burn_md2612.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void MD2612Render(INT32 nSegmentLength)
if (!DebugSnd_YM2612Initted) bprintf(PRINT_ERROR, _T("MD2612Render called without init\n"));
#endif

if (nMD2612Position >= nSegmentLength || !pBurnSoundOut) {
if (nMD2612Position >= nSegmentLength) {
return;
}

Expand Down Expand Up @@ -106,12 +106,14 @@ static void MD2612UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd)
nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample * MD2612Volumes[BURN_SND_MD2612_MD2612_ROUTE_1]);
nTotalRightSample = BURN_SND_CLIP(nTotalRightSample * MD2612Volumes[BURN_SND_MD2612_MD2612_ROUTE_2]);

if (bMD2612AddSignal) {
pSoundBuf[i + 0] = BURN_SND_CLIP(pSoundBuf[i + 0] + nTotalLeftSample);
pSoundBuf[i + 1] = BURN_SND_CLIP(pSoundBuf[i + 1] + nTotalRightSample);
} else {
pSoundBuf[i + 0] = nTotalLeftSample;
pSoundBuf[i + 1] = nTotalRightSample;
if (pSoundBuf) {
if (bMD2612AddSignal) {
pSoundBuf[i + 0] = BURN_SND_CLIP(pSoundBuf[i + 0] + nTotalLeftSample);
pSoundBuf[i + 1] = BURN_SND_CLIP(pSoundBuf[i + 1] + nTotalRightSample);
} else {
pSoundBuf[i + 0] = nTotalLeftSample;
pSoundBuf[i + 1] = nTotalRightSample;
}
}
}

Expand Down Expand Up @@ -232,15 +234,11 @@ void BurnMD2612Scan(INT32 nAction, INT32* pnMin)

if (nAction & ACB_DRIVER_DATA) {
SCAN_VAR(nMD2612Position);
// ym2612 core has internal timers, we need to scan this to keep determinism
SCAN_VAR(nFractionalPosition);

if (nAction & ACB_WRITE) {
MDYM2612LoadContext();

if (~nAction & ACB_RUNAHEAD) {
nMD2612Position = 0;
nFractionalPosition = 0;
memset(pBuffer, 0, 4096 * 2 * 1 * sizeof(INT16));
}
} else {
MDYM2612SaveContext();
}
Expand Down
5 changes: 5 additions & 0 deletions src/burn/snd/ym2612.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,11 @@ static void scan_ym2612_internal()
SCAN_VAR(ym2612.dacout);
SCAN_VAR(ym2612.OPN);

SCAN_VAR(m2);
SCAN_VAR(c1);
SCAN_VAR(c2);
SCAN_VAR(mem);

for (i = 0; i < 6; i++) {
SCAN_VAR(ym2612.CH[i].ALGO);
SCAN_VAR(ym2612.CH[i].FB);
Expand Down
7 changes: 7 additions & 0 deletions src/burner/win32/media.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ int MediaInit()
nBurnSoundLen = nAudSegLen;
}

if (nBurnSoundRate == 0) {
// Sound disabled, but fake these numbers for sound cores which must
// stay synched (f.ex. burn_md2612)
nBurnSoundRate = 44100;
nBurnSoundLen = (nBurnSoundRate * 100 + (nBurnFPS >> 1)) / nBurnFPS;
}

if (!bVidOkay) {

// Reinit the video plugin
Expand Down

0 comments on commit 73e8c30

Please sign in to comment.