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
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class DefaultMapper : public BaseMapper
|
|
|
|
{
|
2014-06-14 18:20:56 -04:00
|
|
|
vector<MemoryBank*> _mappedRomBanks;
|
2014-06-15 21:45:36 -04:00
|
|
|
MemoryBank *_mappedVromBank;
|
2014-06-14 11:27:55 -04:00
|
|
|
private:
|
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
|
|
|
|
|
|
|
_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
|
|
|
};
|
|
|
|
|
|
|
|
class MapperFactory
|
|
|
|
{
|
|
|
|
public:
|
2014-06-14 18:20:56 -04:00
|
|
|
static shared_ptr<BaseMapper> InitializeFromFile(string filename)
|
2014-06-14 11:27:55 -04:00
|
|
|
{
|
|
|
|
ROMLoader loader(filename);
|
|
|
|
|
|
|
|
NESHeader header = loader.GetHeader();
|
|
|
|
|
|
|
|
uint8_t mapperID = header.GetMapperID();
|
|
|
|
shared_ptr<BaseMapper> mapper = nullptr;
|
|
|
|
switch(mapperID) {
|
|
|
|
case 0: mapper = shared_ptr<BaseMapper>(new DefaultMapper()); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!mapper) {
|
|
|
|
throw std::exception("Unsupported mapper");
|
|
|
|
}
|
|
|
|
|
|
|
|
mapper->Initialize(header, loader.GetROMBanks(), loader.GetVROMBanks());
|
|
|
|
return mapper;
|
|
|
|
}
|
|
|
|
};
|