Fix APU IRQ inhibit flag $4017 and dmc

This commit is contained in:
retro-wertz
2018-12-08 11:35:04 +08:00
parent 68c5289726
commit 3b2511a8fe

View File

@@ -289,17 +289,17 @@ static DECLFW(Write_DMCRegs) {
break; break;
case 0x01: DoPCM(); case 0x01: DoPCM();
RawDALatch = V & 0x7F; RawDALatch = V & 0x7F;
if (RawDALatch) if (RawDALatch)
DMC_7bit = 1; DMC_7bit = 1;
break; break;
case 0x02: case 0x02:
DMCAddressLatch = V; DMCAddressLatch = V;
if (V) if (V)
DMC_7bit = 0; DMC_7bit = 0;
break; break;
case 0x03: case 0x03:
DMCSizeLatch = V; DMCSizeLatch = V;
if (V) if (V)
DMC_7bit = 0; DMC_7bit = 0;
break; break;
} }
@@ -314,6 +314,7 @@ static DECLFW(StatusWrite) {
DoTriangle(); DoTriangle();
DoNoise(); DoNoise();
DoPCM(); DoPCM();
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++)
if (!(V & (1 << x))) lengthcount[x] = 0; /* Force length counters to 0. */ if (!(V & (1 << x))) lengthcount[x] = 0; /* Force length counters to 0. */
@@ -337,9 +338,9 @@ static DECLFR(StatusRead) {
for (x = 0; x < 4; x++) ret |= lengthcount[x] ? (1 << x) : 0; for (x = 0; x < 4; x++) ret |= lengthcount[x] ? (1 << x) : 0;
if (DMCSize) ret |= 0x10; if (DMCSize) ret |= 0x10;
#ifdef FCEUDEF_DEBUGGER #ifdef FCEUDEF_DEBUGGER
if (!fceuindbg) if (!fceuindbg)
#endif #endif
{ {
SIRQStat &= ~0x40; SIRQStat &= ~0x40;
X6502_IRQEnd(FCEU_IQFCOUNT); X6502_IRQEnd(FCEU_IQFCOUNT);
@@ -429,19 +430,21 @@ void FrameSoundUpdate(void) {
* Length counter: Bit 4-7 of $4003, $4007, $400b, $400f * Length counter: Bit 4-7 of $4003, $4007, $400b, $400f
*/ */
if (!fcnt && !(IRQFrameMode & 0x3)) {
SIRQStat |= 0x40;
X6502_IRQBegin(FCEU_IQFCOUNT);
}
if (fcnt == 3) { if (fcnt == 3) {
if (IRQFrameMode & 0x2) if (IRQFrameMode & 0x2)
fhcnt += fhinc; fhcnt += fhinc;
} }
FrameSoundStuff(fcnt); FrameSoundStuff(fcnt);
fcnt = (fcnt + 1) & 3; fcnt = (fcnt + 1) & 3;
}
/* has to be moved here to fix Dragon Warrior 4
* after irq inhibit fix for $4017 */
if (!fcnt && !(IRQFrameMode & 0x3)) {
SIRQStat |= 0x40;
X6502_IRQBegin(FCEU_IQFCOUNT);
}
}
static INLINE void tester(void) { static INLINE void tester(void) {
if (DMCBitCount == 0) { if (DMCBitCount == 0) {
@@ -468,9 +471,10 @@ static INLINE void DMCDMA(void) {
if (DMCFormat & 0x40) if (DMCFormat & 0x40)
PrepDPCM(); PrepDPCM();
else { else {
SIRQStat |= 0x80; if (DMCFormat & 0x80) {
if (DMCFormat & 0x80) SIRQStat |= 0x80;
X6502_IRQBegin(FCEU_IQDPCM); X6502_IRQBegin(FCEU_IQDPCM);
}
} }
} }
} }
@@ -853,7 +857,6 @@ static void RDoTriangleNoisePCMLQ(void) {
} }
} }
static void RDoNoise(void) { static void RDoNoise(void) {
uint32 V; uint32 V;
int32 outo; int32 outo;
@@ -924,10 +927,12 @@ DECLFW(Write_IRQFM) {
fcnt = 0; fcnt = 0;
if (V & 2) if (V & 2)
FrameSoundUpdate(); FrameSoundUpdate();
fcnt = 1; /* fcnt = 1; */
fhcnt = fhinc; fhcnt = fhinc;
X6502_IRQEnd(FCEU_IQFCOUNT); if (V & 1) {
SIRQStat &= ~0x40; X6502_IRQEnd(FCEU_IQFCOUNT);
SIRQStat &= ~0x40;
}
IRQFrameMode = V; IRQFrameMode = V;
} }