2014-06-14 15:27:55 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
2014-06-26 01:52:37 +00:00
|
|
|
#include "Snapshotable.h"
|
2014-06-14 15:27:55 +00:00
|
|
|
#include "IMemoryHandler.h"
|
2015-07-05 23:05:33 +00:00
|
|
|
#include "MessageManager.h"
|
2016-01-29 01:47:16 +00:00
|
|
|
#include "RomLoader.h"
|
2016-07-09 14:23:07 +00:00
|
|
|
#include "EmulationSettings.h"
|
2016-11-23 03:38:14 +00:00
|
|
|
#include "DebuggerTypes.h"
|
2017-04-01 02:14:16 +00:00
|
|
|
#include "Debugger.h"
|
|
|
|
#include "Types.h"
|
2017-11-20 04:08:23 +00:00
|
|
|
#include "IBattery.h"
|
2016-09-04 22:08:16 +00:00
|
|
|
|
2017-11-20 04:08:23 +00:00
|
|
|
class BaseControlDevice;
|
|
|
|
|
|
|
|
class BaseMapper : public IMemoryHandler, public Snapshotable, public INotificationListener, public IBattery
|
2014-06-14 15:27:55 +00:00
|
|
|
{
|
2016-01-24 16:18:50 +00:00
|
|
|
private:
|
|
|
|
MirroringType _mirroringType;
|
|
|
|
string _batteryFilename;
|
|
|
|
|
|
|
|
uint16_t InternalGetPrgPageSize();
|
2016-08-19 03:41:58 +00:00
|
|
|
uint16_t InternalGetSaveRamPageSize();
|
|
|
|
uint16_t InternalGetWorkRamPageSize();
|
2016-01-24 16:18:50 +00:00
|
|
|
uint16_t InternalGetChrPageSize();
|
2016-08-19 03:41:58 +00:00
|
|
|
uint16_t InternalGetChrRamPageSize();
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
uint8_t *_nesNametableRam[2];
|
|
|
|
uint8_t *_cartNametableRam[10];
|
|
|
|
uint8_t _nametableIndexes[4];
|
|
|
|
|
|
|
|
bool _onlyChrRam = false;
|
|
|
|
bool _hasBusConflicts = false;
|
2016-06-18 00:53:05 +00:00
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
string _romFilename;
|
2016-06-18 00:53:05 +00:00
|
|
|
string _romName;
|
2017-03-05 03:24:41 +00:00
|
|
|
RomFormat _romFormat;
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
bool _allowRegisterRead = false;
|
2016-06-11 17:18:47 +00:00
|
|
|
uint8_t _isReadRegisterAddr[0x10000];
|
|
|
|
uint8_t _isWriteRegisterAddr[0x10000];
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2017-04-01 02:14:16 +00:00
|
|
|
uint8_t* _prgPages[0x100];
|
|
|
|
uint8_t* _chrPages[0x100];
|
|
|
|
uint8_t _prgPageAccessType[0x100];
|
|
|
|
uint8_t _chrPageAccessType[0x100];
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
uint32_t _prgPageNumbers[64];
|
|
|
|
uint32_t _chrPageNumbers[64];
|
2016-01-29 01:47:16 +00:00
|
|
|
|
2017-04-24 22:28:50 +00:00
|
|
|
HashInfo _hashInfo;
|
2016-01-29 01:47:16 +00:00
|
|
|
|
|
|
|
vector<uint8_t> _originalPrgRom;
|
2017-08-12 20:52:45 +00:00
|
|
|
vector<uint8_t> _originalChrRom;
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
protected:
|
2017-11-20 04:08:23 +00:00
|
|
|
shared_ptr<BaseControlDevice> _mapperControlDevice;
|
|
|
|
|
2016-06-18 22:16:25 +00:00
|
|
|
NESHeader _nesHeader;
|
2016-07-26 23:19:28 +00:00
|
|
|
GameInfo _databaseInfo;
|
|
|
|
|
2016-06-11 17:18:47 +00:00
|
|
|
uint16_t _mapperID;
|
2016-06-03 23:16:31 +00:00
|
|
|
uint8_t _subMapperID;
|
2016-07-10 13:05:41 +00:00
|
|
|
GameSystem _gameSystem;
|
2016-06-03 23:16:31 +00:00
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
uint8_t* _prgRom = nullptr;
|
|
|
|
uint8_t* _chrRom = nullptr;
|
|
|
|
uint8_t* _chrRam = nullptr;
|
|
|
|
uint32_t _prgSize = 0;
|
|
|
|
uint32_t _chrRomSize = 0;
|
|
|
|
uint32_t _chrRamSize = 0;
|
|
|
|
|
|
|
|
uint8_t* _saveRam = nullptr;
|
|
|
|
uint32_t _saveRamSize = 0;
|
2016-07-26 23:19:28 +00:00
|
|
|
uint32_t _workRamSize = 0;
|
2016-01-24 16:18:50 +00:00
|
|
|
uint8_t* _workRam = nullptr;
|
|
|
|
bool _hasBattery = false;
|
2016-07-29 21:28:01 +00:00
|
|
|
bool _hasChrBattery = false;
|
2017-05-26 00:04:49 +00:00
|
|
|
int16_t _vramOpenBusValue = -1;
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
virtual void InitMapper() = 0;
|
2016-06-03 03:56:11 +00:00
|
|
|
virtual void InitMapper(RomData &romData);
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual uint16_t GetPRGPageSize() = 0;
|
|
|
|
virtual uint16_t GetCHRPageSize() = 0;
|
|
|
|
|
2016-07-26 23:19:28 +00:00
|
|
|
bool IsNes20();
|
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual uint16_t GetChrRamPageSize() { return 0x2000; }
|
|
|
|
|
|
|
|
//Save ram is battery backed and saved to disk
|
2016-08-19 03:59:38 +00:00
|
|
|
virtual uint32_t GetSaveRamSize() { return HasBattery() ? 0x2000 : 0; }
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual uint32_t GetSaveRamPageSize() { return 0x2000; }
|
|
|
|
virtual bool ForceBattery() { return false; }
|
2016-07-29 21:28:01 +00:00
|
|
|
virtual bool ForceChrBattery() { return false; }
|
2016-08-27 01:57:32 +00:00
|
|
|
|
|
|
|
virtual bool ForceSaveRamSize() { return false; }
|
|
|
|
virtual bool ForceWorkRamSize() { return false; }
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2016-07-23 13:21:43 +00:00
|
|
|
virtual uint32_t GetChrRamSize() { return 0x0000; }
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
//Work ram is NOT saved - aka Expansion ram, etc.
|
2016-08-27 01:50:52 +00:00
|
|
|
virtual uint32_t GetWorkRamSize() { return HasBattery() ? 0 : 0x2000; }
|
|
|
|
virtual uint32_t GetWorkRamPageSize() { return 0x2000; }
|
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual uint16_t RegisterStartAddress() { return 0x8000; }
|
|
|
|
virtual uint16_t RegisterEndAddress() { return 0xFFFF; }
|
|
|
|
virtual bool AllowRegisterRead() { return false; }
|
|
|
|
|
|
|
|
virtual bool HasBusConflicts() { return false; }
|
|
|
|
|
|
|
|
uint8_t InternalReadRam(uint16_t addr);
|
|
|
|
|
2016-06-03 03:56:11 +00:00
|
|
|
virtual void WriteRegister(uint16_t addr, uint8_t value);
|
|
|
|
virtual uint8_t ReadRegister(uint16_t addr);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2016-01-24 19:20:35 +00:00
|
|
|
void SelectPrgPage4x(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom);
|
|
|
|
void SelectPrgPage2x(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom);
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual void SelectPRGPage(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom);
|
|
|
|
void SetCpuMemoryMapping(uint16_t startAddr, uint16_t endAddr, int16_t pageNumber, PrgMemoryType type, int8_t accessType = -1);
|
2016-06-26 00:46:54 +00:00
|
|
|
void SetCpuMemoryMapping(uint16_t startAddr, uint16_t endAddr, uint8_t *source, int8_t accessType = -1);
|
2016-07-21 01:06:36 +00:00
|
|
|
void RemoveCpuMemoryMapping(uint16_t startAddr, uint16_t endAddr);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
virtual void SelectChrPage8x(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default);
|
|
|
|
virtual void SelectChrPage4x(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default);
|
|
|
|
virtual void SelectChrPage2x(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default);
|
|
|
|
virtual void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default);
|
|
|
|
void SetPpuMemoryMapping(uint16_t startAddr, uint16_t endAddr, uint16_t pageNumber, ChrMemoryType type = ChrMemoryType::Default, int8_t accessType = -1);
|
|
|
|
void SetPpuMemoryMapping(uint16_t startAddr, uint16_t endAddr, uint8_t* sourceMemory, int8_t accessType = -1);
|
|
|
|
void RemovePpuMemoryMapping(uint16_t startAddr, uint16_t endAddr);
|
|
|
|
|
|
|
|
bool HasBattery();
|
|
|
|
void LoadBattery();
|
|
|
|
string GetBatteryFilename();
|
|
|
|
|
|
|
|
uint32_t GetPRGPageCount();
|
|
|
|
uint32_t GetCHRPageCount();
|
|
|
|
|
|
|
|
void RestoreOriginalPrgRam();
|
2016-06-12 17:53:41 +00:00
|
|
|
void InitializeChrRam(int32_t chrRamSize = -1);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2016-06-11 17:18:47 +00:00
|
|
|
void AddRegisterRange(uint16_t startAddr, uint16_t endAddr, MemoryOperation operation = MemoryOperation::Any);
|
|
|
|
void RemoveRegisterRange(uint16_t startAddr, uint16_t endAddr, MemoryOperation operation = MemoryOperation::Any);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2016-12-18 04:14:47 +00:00
|
|
|
virtual void StreamState(bool saving) override;
|
2016-01-24 16:18:50 +00:00
|
|
|
|
|
|
|
uint8_t* GetNametable(uint8_t index);
|
|
|
|
void AddNametable(uint8_t index, uint8_t *nametable);
|
|
|
|
void SetNametable(uint8_t index, uint8_t nametableIndex);
|
|
|
|
void SetNametables(uint8_t nametable1Index, uint8_t nametable2Index, uint8_t nametable3Index, uint8_t nametable4Index);
|
|
|
|
void SetMirroringType(MirroringType type);
|
|
|
|
MirroringType GetMirroringType();
|
|
|
|
|
|
|
|
public:
|
2016-01-29 01:47:16 +00:00
|
|
|
void Initialize(RomData &romData);
|
2016-07-26 23:19:28 +00:00
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual ~BaseMapper();
|
2016-06-03 03:56:11 +00:00
|
|
|
virtual void Reset(bool softReset);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2017-11-20 04:08:23 +00:00
|
|
|
virtual ConsoleFeatures GetAvailableFeatures();
|
|
|
|
|
2016-07-09 14:23:07 +00:00
|
|
|
virtual void SetNesModel(NesModel model) { }
|
2016-01-24 16:18:50 +00:00
|
|
|
virtual void ProcessCpuClock() { }
|
|
|
|
virtual void NotifyVRAMAddressChange(uint16_t addr);
|
2016-12-18 04:14:47 +00:00
|
|
|
void ProcessNotification(ConsoleNotificationType type, void* parameter) override;
|
|
|
|
virtual void GetMemoryRanges(MemoryRanges &ranges) override;
|
2015-07-30 02:10:34 +00:00
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
void ApplyCheats();
|
2017-11-20 04:08:23 +00:00
|
|
|
|
|
|
|
virtual void SaveBattery() override;
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2016-06-18 22:16:25 +00:00
|
|
|
virtual void SetDefaultNametables(uint8_t* nametableA, uint8_t* nametableB);
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2017-11-20 04:08:23 +00:00
|
|
|
shared_ptr<BaseControlDevice> GetMapperControlDevice();
|
2016-06-16 01:59:34 +00:00
|
|
|
GameSystem GetGameSystem();
|
2017-04-22 17:19:21 +00:00
|
|
|
HashInfo GetHashInfo();
|
2016-06-18 00:53:05 +00:00
|
|
|
string GetRomName();
|
2017-03-05 03:24:41 +00:00
|
|
|
RomFormat GetRomFormat();
|
2016-01-24 16:18:50 +00:00
|
|
|
|
2017-04-01 02:14:16 +00:00
|
|
|
__forceinline uint8_t ReadRAM(uint16_t addr) override;
|
2017-08-30 22:31:27 +00:00
|
|
|
uint8_t DebugReadRAM(uint16_t addr);
|
2016-12-18 04:14:47 +00:00
|
|
|
virtual void WriteRAM(uint16_t addr, uint8_t value) override;
|
2017-08-30 22:31:27 +00:00
|
|
|
void DebugWriteRAM(uint16_t addr, uint8_t value);
|
2016-01-24 16:18:50 +00:00
|
|
|
void WritePrgRam(uint16_t addr, uint8_t value);
|
|
|
|
|
2017-04-01 02:14:16 +00:00
|
|
|
__forceinline uint8_t InternalReadVRAM(uint16_t addr);
|
|
|
|
__forceinline virtual uint8_t MapperReadVRAM(uint16_t addr, MemoryOperationType operationType);
|
|
|
|
|
|
|
|
__forceinline uint8_t ReadVRAM(uint16_t addr, MemoryOperationType type = MemoryOperationType::PpuRenderingRead)
|
|
|
|
{
|
|
|
|
ProcessVramAccess(addr);
|
|
|
|
NotifyVRAMAddressChange(addr);
|
|
|
|
|
|
|
|
uint8_t value = MapperReadVRAM(addr, type);
|
2017-08-05 21:18:09 +00:00
|
|
|
Debugger::ProcessVramReadOperation(type, addr, value);
|
2017-04-01 02:14:16 +00:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2017-10-07 17:31:28 +00:00
|
|
|
void DebugWriteVRAM(uint16_t addr, uint8_t value, bool disableSideEffects = true);
|
2016-01-24 16:18:50 +00:00
|
|
|
void WriteVRAM(uint16_t addr, uint8_t value);
|
|
|
|
|
2017-04-01 02:14:16 +00:00
|
|
|
__forceinline void ProcessVramAccess(uint16_t &addr);
|
2017-10-07 17:31:28 +00:00
|
|
|
uint8_t DebugReadVRAM(uint16_t addr, bool disableSideEffects = true);
|
2017-04-01 02:14:16 +00:00
|
|
|
|
2017-02-24 01:01:48 +00:00
|
|
|
static void InitializeRam(void* data, uint32_t length);
|
2016-08-25 00:48:14 +00:00
|
|
|
|
2017-12-19 01:02:25 +00:00
|
|
|
void CopyChrRamTile(uint32_t address, uint8_t *dest);
|
|
|
|
|
2016-01-24 16:18:50 +00:00
|
|
|
//Debugger Helper Functions
|
2017-06-28 23:00:08 +00:00
|
|
|
bool HasChrRam();
|
|
|
|
bool HasChrRom();
|
|
|
|
|
2016-09-04 22:08:16 +00:00
|
|
|
CartridgeState GetState();
|
2016-02-14 03:19:42 +00:00
|
|
|
uint8_t* GetPrgRom();
|
|
|
|
uint8_t* GetWorkRam();
|
2017-03-15 23:19:41 +00:00
|
|
|
uint8_t* GetSaveRam();
|
2016-12-02 00:38:48 +00:00
|
|
|
|
2017-03-05 02:50:19 +00:00
|
|
|
uint8_t GetMemoryValue(DebugMemoryType memoryType, uint32_t address);
|
2017-02-27 01:47:39 +00:00
|
|
|
void SetMemoryValue(DebugMemoryType memoryType, uint32_t address, uint8_t value);
|
2016-12-02 00:38:48 +00:00
|
|
|
uint32_t GetMemorySize(DebugMemoryType type);
|
|
|
|
|
2016-09-05 13:05:34 +00:00
|
|
|
uint32_t CopyMemory(DebugMemoryType type, uint8_t* buffer);
|
|
|
|
void WriteMemory(DebugMemoryType type, uint8_t* buffer);
|
2016-01-24 16:18:50 +00:00
|
|
|
int32_t ToAbsoluteAddress(uint16_t addr);
|
2016-11-23 03:38:14 +00:00
|
|
|
int32_t ToAbsoluteSaveRamAddress(uint16_t addr);
|
|
|
|
int32_t ToAbsoluteWorkRamAddress(uint16_t addr);
|
2016-01-24 16:18:50 +00:00
|
|
|
int32_t ToAbsoluteChrAddress(uint16_t addr);
|
2016-11-23 03:38:14 +00:00
|
|
|
int32_t FromAbsoluteAddress(uint32_t addr, AddressType type = AddressType::PrgRom);
|
2017-03-05 03:24:41 +00:00
|
|
|
|
2017-08-12 20:52:45 +00:00
|
|
|
NESHeader GetNesHeader();
|
2017-08-19 23:40:02 +00:00
|
|
|
void SaveRomToDisk(string filename, bool saveAsIps, uint8_t* header);
|
2017-08-22 03:11:14 +00:00
|
|
|
void RevertPrgChrChanges();
|
|
|
|
bool HasPrgChrChanges();
|
2014-06-24 06:47:32 +00:00
|
|
|
};
|