Mesen-X/Core/BaseMapper.h

127 lines
2.6 KiB
C
Raw Normal View History

2014-06-14 11:27:55 -04:00
#pragma once
#include "stdafx.h"
#include "ROMLoader.h"
#include "IMemoryHandler.h"
class BaseMapper : public IMemoryHandler
{
protected:
NESHeader _header;
vector<MemoryBank> _romBanks;
vector<MemoryBank> _vromBanks;
2014-06-14 18:20:56 -04:00
virtual void InitMapper() = 0;
2014-06-14 11:27:55 -04:00
public:
void Initialize(NESHeader header, vector<MemoryBank> romBanks, vector<MemoryBank> vromBanks)
{
_header = header;
_romBanks = romBanks;
_vromBanks = vromBanks;
2014-06-14 18:20:56 -04:00
InitMapper();
2014-06-14 11:27:55 -04:00
}
const NESHeader GetHeader()
{
return _header;
}
2014-06-14 11:27:55 -04:00
};
class DefaultMapper : public BaseMapper
{
2014-06-21 19:26:17 -04:00
protected:
vector<MemoryBank*> _mappedRomBanks;
MemoryBank *_mappedVromBank;
2014-06-14 18:20:56 -04:00
void InitMapper()
{
if(_romBanks.size() == 1) {
_mappedRomBanks = { &_romBanks[0], &_romBanks[0] };
} else {
_mappedRomBanks = { &_romBanks[0], &_romBanks[1] };
}
2014-06-15 21:45:36 -04:00
if(_vromBanks.size() == 0) {
uint8_t *buffer = new uint8_t[ROMLoader::VROMBankSize];
_vromBanks.push_back(MemoryBank(buffer, buffer + ROMLoader::VROMBankSize));
}
2014-06-15 21:45:36 -04:00
_mappedVromBank = &_vromBanks[0];
2014-06-14 18:20:56 -04:00
}
2014-06-14 11:27:55 -04:00
public:
2014-06-15 21:45:36 -04:00
vector<std::array<uint16_t, 2>> GetRAMAddresses()
{
return { { { 0x8000, 0xFFFF } } };
}
vector<std::array<uint16_t, 2>> GetVRAMAddresses()
2014-06-14 11:27:55 -04:00
{
2014-06-15 21:45:36 -04:00
return { { { 0x0000, 0x1FFF } } };
2014-06-14 11:27:55 -04:00
}
2014-06-15 21:45:36 -04:00
uint8_t ReadRAM(uint16_t addr)
2014-06-14 11:27:55 -04:00
{
2014-06-14 18:20:56 -04:00
return (*_mappedRomBanks[(addr >> 14) & 0x01])[addr & 0x3FFF];
2014-06-14 11:27:55 -04:00
}
2014-06-15 21:45:36 -04:00
void WriteRAM(uint16_t addr, uint8_t value)
2014-06-14 11:27:55 -04:00
{
2014-06-14 18:20:56 -04:00
(*_mappedRomBanks[(addr >> 14) & 0x01])[addr & 0x3FFF] = value;
2014-06-14 11:27:55 -04:00
}
2014-06-15 21:45:36 -04:00
uint8_t ReadVRAM(uint16_t addr)
{
return (*_mappedVromBank)[addr & 0x1FFF];
}
void WriteVRAM(uint16_t addr, uint8_t value)
{
(*_mappedVromBank)[addr & 0x1FFF] = value;
}
2014-06-14 11:27:55 -04:00
};
2014-06-21 19:26:17 -04:00
class Mapper2 : public DefaultMapper
{
private:
void InitMapper()
{
DefaultMapper::InitMapper();
_mappedRomBanks[1] = &_romBanks[_romBanks.size() - 1];
}
public:
void WriteRAM(uint16_t addr, uint8_t value)
{
_mappedRomBanks[0] = &_romBanks[value];
//(*_mappedRomBanks[(addr >> 14) & 0x01])[addr & 0x3FFF] = value;
}
};
2014-06-14 11:27:55 -04:00
class MapperFactory
{
public:
static unique_ptr<BaseMapper> InitializeFromFile(wstring filename)
2014-06-14 11:27:55 -04:00
{
ROMLoader loader(filename);
NESHeader header = loader.GetHeader();
uint8_t mapperID = header.GetMapperID();
2014-06-21 19:26:17 -04:00
BaseMapper* mapper = nullptr;
2014-06-14 11:27:55 -04:00
switch(mapperID) {
2014-06-21 19:26:17 -04:00
case 0: mapper = new DefaultMapper(); break;
case 2: mapper = new Mapper2(); break;
2014-06-14 11:27:55 -04:00
}
if(!mapper) {
throw std::exception("Unsupported mapper");
}
mapper->Initialize(header, loader.GetROMBanks(), loader.GetVROMBanks());
2014-06-21 19:26:17 -04:00
return unique_ptr<BaseMapper>(mapper);
2014-06-14 11:27:55 -04:00
}
};