mirror of
https://github.com/libretro/Mesen.git
synced 2024-12-01 04:50:23 +00:00
MMC3: Implemented submapper 3 (MM-ACC) - fixes Incredible Crash Dummies
-Also fixed a bug in NES 2.0 mapper ID code
This commit is contained in:
parent
4a784ff87a
commit
53f1808f73
44
Core/MMC3.h
44
Core/MMC3.h
@ -21,6 +21,8 @@ class MMC3 : public BaseMapper
|
||||
RegE001 = 0xE001
|
||||
};
|
||||
|
||||
uint8_t _subMapperID;
|
||||
|
||||
uint8_t _currentRegister;
|
||||
uint8_t _chrMode;
|
||||
uint8_t _prgMode;
|
||||
@ -36,6 +38,8 @@ class MMC3 : public BaseMapper
|
||||
bool _wramEnabled;
|
||||
bool _wramWriteProtected;
|
||||
|
||||
bool _needIrq;
|
||||
|
||||
struct {
|
||||
uint8_t Reg8000;
|
||||
uint8_t RegA000;
|
||||
@ -61,6 +65,8 @@ class MMC3 : public BaseMapper
|
||||
|
||||
_wramEnabled = false;
|
||||
_wramWriteProtected = false;
|
||||
|
||||
_needIrq = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -145,7 +151,7 @@ class MMC3 : public BaseMapper
|
||||
BaseMapper::StreamState(saving);
|
||||
Stream(_state.Reg8000, _state.RegA000, _state.RegA001, _currentRegister, _chrMode, _prgMode,
|
||||
_irqReloadValue, _irqCounter, _irqReload, _irqEnabled, _lastCycle, _cyclesDown,
|
||||
_wramEnabled, _wramWriteProtected, ArrayInfo<uint8_t>{_registers, 8});
|
||||
_wramEnabled, _wramWriteProtected, ArrayInfo<uint8_t>{_registers, 8}, _needIrq);
|
||||
}
|
||||
|
||||
virtual uint16_t GetPRGPageSize() { return 0x2000; }
|
||||
@ -208,12 +214,41 @@ class MMC3 : public BaseMapper
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerIrq()
|
||||
{
|
||||
if(_subMapperID != 3) {
|
||||
CPU::SetIRQSource(IRQSource::External);
|
||||
} else {
|
||||
//MM-ACC (Acclaim copy of the MMC3)
|
||||
//IRQ will be triggered on the next falling edge of A12 instead of on the rising edge like normal MMC3 behavior
|
||||
//This adds a 4 ppu cycle delay (until the PPU fetches the next garbage NT tile between sprites)
|
||||
_needIrq = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
MMC3(uint8_t subMapperID)
|
||||
{
|
||||
_subMapperID = subMapperID;
|
||||
}
|
||||
|
||||
MMC3()
|
||||
{
|
||||
_subMapperID = 0;
|
||||
}
|
||||
|
||||
virtual void NotifyVRAMAddressChange(uint16_t addr)
|
||||
{
|
||||
uint32_t cycle = PPU::GetFrameCycle();
|
||||
|
||||
if((addr & 0x1000) == 0) {
|
||||
if(_needIrq) {
|
||||
//Used by MM-ACC (Acclaim copy of the MMC3), see TriggerIrq above
|
||||
CPU::SetIRQSource(IRQSource::External);
|
||||
_needIrq = false;
|
||||
}
|
||||
|
||||
if(_cyclesDown == 0) {
|
||||
_cyclesDown = 1;
|
||||
} else {
|
||||
@ -233,14 +268,15 @@ class MMC3 : public BaseMapper
|
||||
_irqCounter--;
|
||||
}
|
||||
|
||||
if(ForceMmc3RevAIrqs() || EmulationSettings::CheckFlag(EmulationFlags::Mmc3IrqAltBehavior)) {
|
||||
//SubMapper 2 = MM-ACC (Acclaim MMC3 clone)
|
||||
if(_subMapperID != 2 && (ForceMmc3RevAIrqs() || EmulationSettings::CheckFlag(EmulationFlags::Mmc3IrqAltBehavior))) {
|
||||
//MMC3 Revision A behavior
|
||||
if((count > 0 || _irqReload) && _irqCounter == 0 && _irqEnabled) {
|
||||
CPU::SetIRQSource(IRQSource::External);
|
||||
TriggerIrq();
|
||||
}
|
||||
} else {
|
||||
if(_irqCounter == 0 && _irqEnabled) {
|
||||
CPU::SetIRQSource(IRQSource::External);
|
||||
TriggerIrq();
|
||||
}
|
||||
}
|
||||
_irqReload = false;
|
||||
|
@ -104,7 +104,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData)
|
||||
case 1: return new MMC1();
|
||||
case 2: return new UNROM();
|
||||
case 3: return new CNROM(false);
|
||||
case 4: return new MMC3();
|
||||
case 4: return new MMC3(romData.SubMapperID);
|
||||
case 5: return new MMC5();
|
||||
case 7: return new AXROM();
|
||||
case 9: return new MMC2();
|
||||
|
@ -644,8 +644,12 @@ void PPU::ProcessPreVBlankScanline()
|
||||
if((_cycle - 260) % 8 == 0) {
|
||||
//Cycle 260, 268, etc. This is an approximation (each tile is actually loaded in 8 steps (e.g from 257 to 264))
|
||||
LoadSpriteTileInfo();
|
||||
} else if(_cycle == 257) {
|
||||
_spriteIndex = 0;
|
||||
} else if((_cycle - 257) % 8 == 0) {
|
||||
//Garbage NT sprite fetch (257, 265, 273, etc.) - Required for proper MC-ACC IRQs (MMC3 clone)
|
||||
_memoryManager->ReadVRAM(GetNameTableAddr());
|
||||
if(_cycle == 257) {
|
||||
_spriteIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(_cycle == 321 && IsRenderingEnabled()) {
|
||||
|
@ -71,7 +71,7 @@ struct NESHeader
|
||||
{
|
||||
switch(GetRomHeaderVersion()) {
|
||||
case RomHeaderVersion::Nes2_0:
|
||||
return (Byte8 & 0x0F << 4) | (Byte7 & 0xF0) | (Byte6 >> 4);
|
||||
return ((Byte8 & 0x0F) << 4) | (Byte7 & 0xF0) | (Byte6 >> 4);
|
||||
default:
|
||||
case RomHeaderVersion::iNes:
|
||||
return (Byte7 & 0xF0) | (Byte6 >> 4);
|
||||
|
Loading…
Reference in New Issue
Block a user