bfirsh / bfirsh/jsnes

MMC3: IRQ counter has multiple correctness issues

Open
#595 0 comments 0 reactions 0 assignees View on GitHub
accuracy bug component: mapper difficulty: hard priority: critical
Dominant language
JavaScript
Stars
6.4k
Forks
857
PR merge metrics
No merged PRs in 30d

Description

## Summary

The MMC3 scanline IRQ counter has several fundamental issues that affect split-screen effects in games like Super Mario Bros. 3, Kirby's Adventure, and many others.

### Issue 1: \$C000/\$C001 register roles are swapped

Per nesdev, \`\$C000\` sets the **latch** (reload value) and \`\$C001\` triggers a **reload**. The code has them backwards:

\`\`\`javascript
case 0xc000:
this.irqCounter = value; // WRONG: should set irqLatchValue
break;
case 0xc001:
this.irqLatchValue = value; // WRONG: should set irqReload flag
break;
\`\`\`

### Issue 2: Counter logic is fundamentally wrong

Current (\`mapper4.js:221-231\`):
\`\`\`javascript
clockIrqCounter() {
if (this.irqEnable === 1) {
this.irqCounter--;
if (this.irqCounter < 0) {
this.nes.cpu.requestIrq(this.nes.cpu.IRQ_NORMAL);
this.irqCounter = this.irqLatchValue;
}
}
}
\`\`\`

Problems:
1. Always decrements instead of reloading from latch when counter=0 or reload flag is set
2. No reload flag tracked at all
3. IRQ fires on **underflow** (<0) instead of when counter **reaches** 0
4. Counter logic skipped entirely when IRQ is disabled (should still clock)

### Issue 3: \$E000 doesn't acknowledge pending IRQ

Writing to \`\$E000\` should both disable IRQs AND acknowledge any pending IRQ. Current code only disables.

### Correct behavior

Per [nesdev MMC3 wiki](https://www.nesdev.org/wiki/MMC3), when the IRQ counter is clocked:
1. If counter is 0 OR reload flag is set → reload counter from latch, clear reload flag
2. Otherwise → decrement counter
3. If counter is 0 AND IRQs enabled → trigger IRQ

## References

- [MMC3 wiki](https://www.nesdev.org/wiki/MMC3)
- [MMC3 IRQ behavior](https://forums.nesdev.org/viewtopic.php?t=19413)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.