AXROM support (Mapper 7) - Battletoads doesn't work (sprite 0 timing issue)

This commit is contained in:
Souryo 2014-06-26 23:13:02 -04:00
parent 060eb67421
commit 616546ae5b
5 changed files with 75 additions and 53 deletions

24
Core/AXROM.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include "stdafx.h"
#include "BaseMapper.h"
class AXROM : public BaseMapper
{
protected:
virtual uint32_t GetPRGPageSize() { return 0x8000; }
virtual uint32_t GetCHRPageSize() { return 0x2000; }
void InitMapper()
{
SelectPRGPage(0, 0);
SelectCHRPage(0, 0);
}
public:
void WriteRAM(uint16_t addr, uint8_t value)
{
SelectPRGPage(0, value & 0x07);
_mirroringType = ((value & 0x10) == 0x10) ? MirroringType::ScreenBOnly : MirroringType::ScreenAOnly;
}
};

View File

@ -88,6 +88,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="APU.h" />
<ClInclude Include="AXROM.h" />
<ClInclude Include="BaseMapper.h" />
<ClInclude Include="CNROM.h" />
<ClInclude Include="ControlManager.h" />

View File

@ -120,6 +120,9 @@
<ClInclude Include="Snapshotable.h">
<Filter>Header Files\Interfaces</Filter>
</ClInclude>
<ClInclude Include="AXROM.h">
<Filter>Header Files\Mappers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CPU.cpp">

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "ROMLoader.h"
#include "AXROM.h"
#include "CNROM.h"
#include "MMC1.h"
#include "MMC3.h"
@ -8,6 +9,22 @@
class MapperFactory
{
private:
static BaseMapper* GetMapperFromID(uint8_t mapperID)
{
switch(mapperID) {
case 0: return new NROM();
case 1: return new MMC1();
case 2: return new UNROM();
case 3: return new CNROM();
case 4: return new MMC3();
case 7: return new AXROM();
}
throw std::exception("Unsupported mapper");
return nullptr;
}
public:
static shared_ptr<BaseMapper> InitializeFromFile(wstring filename)
{
@ -15,19 +32,7 @@ class MapperFactory
uint8_t mapperID = loader.GetMapperID();
BaseMapper* mapper = nullptr;
switch(mapperID) {
case 0: mapper = new NROM(); break;
case 1: mapper = new MMC1(); break;
case 2: mapper = new UNROM(); break;
case 3: mapper = new CNROM(); break;
case 4: mapper = new MMC3(); break;
}
if(!mapper) {
throw std::exception("Unsupported mapper");
}
BaseMapper* mapper = GetMapperFromID(mapperID);
mapper->Initialize(loader);
return shared_ptr<BaseMapper>(mapper);
}

View File

@ -147,7 +147,21 @@ uint8_t MemoryManager::ReadVRAM(uint16_t addr)
if(addr >= 0x3000) {
addr -= 0x1000;
}
return _videoRAM[addr & 0x3FFF];
switch(_mapper->GetMirroringType()) {
case MirroringType::Vertical:
case MirroringType::Horizontal:
case MirroringType::FourScreens:
default:
return _videoRAM[addr & 0x3FFF];
case MirroringType::ScreenAOnly:
return _videoRAM[addr & 0x33FF];
case MirroringType::ScreenBOnly:
return _videoRAM[addr & 0x33FF | 0x400];
}
}
}
@ -163,52 +177,27 @@ void MemoryManager::WriteVRAM(uint16_t addr, uint8_t value)
addr -= 0x1000;
}
_videoRAM[addr] = value;
switch(_mapper->GetMirroringType()) {
case MirroringType::Vertical:
if(addr >= 0x2000 && addr < 0x2400) {
_videoRAM[addr + 0x800] = value;
} else if(addr >= 0x2400 && addr < 0x2800) {
_videoRAM[addr + 0x800] = value;
} else if(addr >= 0x2800 && addr < 0x2C00) {
_videoRAM[addr - 0x800] = value;
} else if(addr >= 0x2C00 && addr < 0x3000) {
_videoRAM[addr - 0x800] = value;
}
_videoRAM[addr] = value;
_videoRAM[addr ^ 0x800] = value;
break;
case MirroringType::Horizontal:
if(addr >= 0x2000 && addr < 0x2400) {
_videoRAM[addr + 0x400] = value;
} else if(addr >= 0x2400 && addr < 0x2800) {
_videoRAM[addr - 0x400] = value;
} else if(addr >= 0x2800 && addr < 0x2C00) {
_videoRAM[addr + 0x400] = value;
} else if(addr >= 0x2C00 && addr < 0x3000) {
_videoRAM[addr - 0x400] = value;
}
_videoRAM[addr] = value;
_videoRAM[addr ^ 0x400] = value;
break;
case MirroringType::ScreenAOnly:
case MirroringType::ScreenBOnly:
if(addr >= 0x2000 && addr < 0x2400) {
_videoRAM[addr + 0x400] = value;
_videoRAM[addr + 0x800] = value;
_videoRAM[addr + 0xC00] = value;
} else if(addr >= 0x2400 && addr < 0x2800) {
_videoRAM[addr - 0x400] = value;
_videoRAM[addr + 0x400] = value;
_videoRAM[addr + 0x800] = value;
} else if(addr >= 0x2800 && addr < 0x2C00) {
_videoRAM[addr + 0x400] = value;
_videoRAM[addr - 0x400] = value;
_videoRAM[addr - 0x800] = value;
} else if(addr >= 0x2C00 && addr < 0x3000) {
_videoRAM[addr - 0x400] = value;
_videoRAM[addr - 0x800] = value;
_videoRAM[addr - 0xC00] = value;
}
case MirroringType::ScreenAOnly: //Always write to 0x2000
_videoRAM[addr & ~0xC00] = value;
break;
case MirroringType::ScreenBOnly: //Always write to 0x2400
_videoRAM[addr & ~0x800 | 0x400] = value;
break;
case MirroringType::FourScreens:
_videoRAM[addr] = value;
break;
default: