custom frame for gprider - ack the irq`s a little longer than usual to get past a hang @ game start, this breaks other xboard games, which is why it has been separated. also fix out of bounds access to iochip_custom_read - see case 0x04 iochip_r\(\)

This commit is contained in:
dinkc64 2014-12-20 20:55:35 +00:00
parent 72a95e4b0c
commit 9d0e7d6082
3 changed files with 106 additions and 6 deletions

View File

@ -1698,10 +1698,10 @@ Memory Handlers
====================================================*/
typedef UINT8 (*io_custom_read)(UINT8);
static io_custom_read iochip_custom_read[2][4];
static io_custom_read iochip_custom_read[2][5];
typedef void (*io_custom_write)(UINT8);
static io_custom_write iochip_custom_write[2][4];
static io_custom_write iochip_custom_write[2][5];
static UINT8 iochip_regs[2][8];
@ -2675,7 +2675,7 @@ static INT32 XBoardExit()
{
memset(iochip_regs, 0, sizeof(iochip_regs));
for (INT32 i = 0; i < 4; i++) {
for (INT32 i = 0; i <= 4; i++) {
iochip_custom_read[0][i] = NULL;
iochip_custom_read[1][i] = NULL;
iochip_custom_write[0][i] = NULL;
@ -2763,7 +2763,7 @@ struct BurnDriver BurnDrvGprider = {
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING, 2, HARDWARE_SEGA_SYSTEMX | HARDWARE_SEGA_SPRITE_LOAD32 | HARDWARE_SEGA_FD1094_ENC, GBF_RACING, 0,
NULL, GpriderRomInfo, GpriderRomName, NULL, NULL, GpriderInputInfo, GpriderDIPInfo,
GpriderInit, XBoardExit, XBoardFrame, NULL, XBoardScan,
GpriderInit, XBoardExit, XBoardFrameGPRider, NULL, XBoardScan,
NULL, 0x6000, 320, 224, 4, 3
};
@ -2773,7 +2773,7 @@ struct BurnDriver BurnDrvGpriderj = {
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_SEGA_SYSTEMX | HARDWARE_SEGA_SPRITE_LOAD32 | HARDWARE_SEGA_FD1094_ENC, GBF_RACING, 0,
NULL, GpriderjRomInfo, GpriderjRomName, NULL, NULL, GpriderInputInfo, GpriderDIPInfo,
GpriderInit, XBoardExit, XBoardFrame, NULL, XBoardScan,
GpriderInit, XBoardExit, XBoardFrameGPRider, NULL, XBoardScan,
NULL, 0x6000, 320, 224, 4, 3
};
@ -2783,7 +2783,7 @@ struct BurnDriver BurnDrvGprideru = {
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE, 2, HARDWARE_SEGA_SYSTEMX | HARDWARE_SEGA_SPRITE_LOAD32 | HARDWARE_SEGA_FD1094_ENC, GBF_RACING, 0,
NULL, GprideruRomInfo, GprideruRomName, NULL, NULL, GpriderInputInfo, GpriderDIPInfo,
GpriderInit, XBoardExit, XBoardFrame, NULL, XBoardScan,
GpriderInit, XBoardExit, XBoardFrameGPRider, NULL, XBoardScan,
NULL, 0x6000, 320, 224, 4, 3
};

View File

@ -158,6 +158,7 @@ INT32 HangonFrame();
INT32 HangonYM2203Frame();
INT32 OutrunFrame();
INT32 XBoardFrame();
INT32 XBoardFrameGPRider();
INT32 YBoardFrame();
INT32 System16Scan(INT32 nAction, INT32 *pnMin);

View File

@ -3225,6 +3225,105 @@ INT32 XBoardFrame()
return 0;
}
INT32 XBoardFrameGPRider()
{
INT32 nInterleave = 100, i;
if (System16Reset) System16DoReset();
System16MakeInputs();
if (nBurnGunNumPlayers) System16GunMakeInputs();
nCyclesTotal[0] = (INT32)((INT64)(50000000 / 4) * nBurnCPUSpeedAdjust / (0x0100 * 60));
nCyclesTotal[1] = (INT32)((INT64)(50000000 / 4) * nBurnCPUSpeedAdjust / (0x0100 * 60));
nCyclesTotal[2] = (16000000 / 4) / 60;
nCyclesTotal[3] = (16000000 / 4) / 60;
nSystem16CyclesDone[0] = nSystem16CyclesDone[1] = nSystem16CyclesDone[2] = nSystem16CyclesDone[3] = 0;
INT32 nSoundBufferPos = 0;
SekNewFrame();
ZetNewFrame();
for (i = 0; i < nInterleave; i++) {
INT32 nCurrentCPU, nNext;
// Run 68000 #1
nCurrentCPU = 0;
SekOpen(nCurrentCPU);
nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
nCyclesSegment = nNext - nSystem16CyclesDone[nCurrentCPU];
nSystem16CyclesDone[nCurrentCPU] += SekRun(nCyclesSegment);
// ACK for 1 interleave cycle to make gprider happy
if (i == 20 || i == 40 || i == 60 || i == 80) SekSetIRQLine(2, SEK_IRQSTATUS_ACK);
if (i == 21 || i == 41 || i == 61 || i == 81) SekSetIRQLine(2, SEK_IRQSTATUS_NONE);
if (i == 98) SekSetIRQLine(4, SEK_IRQSTATUS_ACK);
if (i == 99) SekSetIRQLine(4, SEK_IRQSTATUS_NONE);
SekClose();
// Run 68000 #2
nCurrentCPU = 1;
SekOpen(nCurrentCPU);
nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
nCyclesSegment = nNext - nSystem16CyclesDone[nCurrentCPU];
nCyclesSegment = SekRun(nCyclesSegment);
nSystem16CyclesDone[nCurrentCPU] += nCyclesSegment;
if (i == 99) SekSetIRQLine(4, SEK_IRQSTATUS_AUTO);
SekClose();
// Run Z80
nCurrentCPU = 2;
ZetOpen(0);
nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
nCyclesSegment = nNext - nSystem16CyclesDone[nCurrentCPU];
nCyclesSegment = ZetRun(nCyclesSegment);
nSystem16CyclesDone[nCurrentCPU] += nCyclesSegment;
ZetClose();
// Run Z80 #2
if (System16Z80Rom2Num) {
nCurrentCPU = 3;
ZetOpen(1);
nNext = (i + 1) * nCyclesTotal[nCurrentCPU] / nInterleave;
nCyclesSegment = nNext - nSystem16CyclesDone[nCurrentCPU];
nCyclesSegment = ZetRun(nCyclesSegment);
nSystem16CyclesDone[nCurrentCPU] += nCyclesSegment;
ZetClose();
}
if (pBurnSoundOut) {
INT32 nSegmentLength = nBurnSoundLen / nInterleave;
INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
ZetOpen(0);
BurnYM2151Render(pSoundBuf, nSegmentLength);
ZetClose();
if (System16PCMDataSize) SegaPCMUpdate(pSoundBuf, nSegmentLength);
nSoundBufferPos += nSegmentLength;
}
}
// Make sure the buffer is entirely filled.
if (pBurnSoundOut) {
INT32 nSegmentLength = nBurnSoundLen - nSoundBufferPos;
INT16* pSoundBuf = pBurnSoundOut + (nSoundBufferPos << 1);
if (nSegmentLength) {
ZetOpen(0);
BurnYM2151Render(pSoundBuf, nSegmentLength);
ZetClose();
if (System16PCMDataSize) SegaPCMUpdate(pSoundBuf, nSegmentLength);
}
}
if (pBurnDraw) {
XBoardRender();
}
return 0;
}
INT32 YBoardFrame()
{
INT32 nInterleave = 262, i;