UNIF: Added support for SSS-NROM-256 board (Famicombox Menu cartridge) - incomplete, but boots properly
This commit is contained in:
parent
9f643f256b
commit
b5d460ffb3
14 changed files with 440 additions and 58 deletions
|
@ -9,6 +9,7 @@
|
|||
#include "Debugger.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "BatteryManager.h"
|
||||
#include "IMemoryManager.h"
|
||||
|
||||
void BaseMapper::WriteRegister(uint16_t addr, uint8_t value) { }
|
||||
uint8_t BaseMapper::ReadRegister(uint16_t addr) { return 0; }
|
||||
|
@ -655,6 +656,11 @@ void BaseMapper::GetMemoryRanges(MemoryRanges &ranges)
|
|||
}
|
||||
}
|
||||
|
||||
void BaseMapper::SetMemoryManager(IMemoryManager* memoryManager)
|
||||
{
|
||||
_memoryManager = memoryManager;
|
||||
}
|
||||
|
||||
void BaseMapper::SetDefaultNametables(uint8_t* nametableA, uint8_t* nametableB)
|
||||
{
|
||||
_nesNametableRam[0] = nametableA;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "IBattery.h"
|
||||
|
||||
class BaseControlDevice;
|
||||
class IMemoryManager;
|
||||
|
||||
class BaseMapper : public IMemoryHandler, public Snapshotable, public INotificationListener, public IBattery
|
||||
{
|
||||
|
@ -55,6 +56,7 @@ private:
|
|||
|
||||
protected:
|
||||
shared_ptr<BaseControlDevice> _mapperControlDevice;
|
||||
IMemoryManager *_memoryManager;
|
||||
|
||||
NESHeader _nesHeader;
|
||||
GameInfo _databaseInfo;
|
||||
|
@ -171,6 +173,7 @@ public:
|
|||
|
||||
virtual void SaveBattery() override;
|
||||
|
||||
void SetMemoryManager(IMemoryManager* memoryManager);
|
||||
virtual void SetDefaultNametables(uint8_t* nametableA, uint8_t* nametableB);
|
||||
|
||||
shared_ptr<BaseControlDevice> GetMapperControlDevice();
|
||||
|
|
|
@ -535,6 +535,8 @@
|
|||
<ClInclude Include="IBattery.h" />
|
||||
<ClInclude Include="IInputProvider.h" />
|
||||
<ClInclude Include="IInputRecorder.h" />
|
||||
<ClInclude Include="IMemoryManager.h" />
|
||||
<ClInclude Include="InternalRamHandler.h" />
|
||||
<ClInclude Include="Kaiser7017.h" />
|
||||
<ClInclude Include="Kaiser7031.h" />
|
||||
<ClInclude Include="KeyManager.h" />
|
||||
|
@ -544,9 +546,11 @@
|
|||
<ClInclude Include="MMC3_224.h" />
|
||||
<ClInclude Include="MovieRecorder.h" />
|
||||
<ClInclude Include="AsciiTurboFile.h" />
|
||||
<ClInclude Include="OpenBusHandler.h" />
|
||||
<ClInclude Include="RawVideoFilter.h" />
|
||||
<ClInclude Include="Sachen9602.h" />
|
||||
<ClInclude Include="ServerInformationMessage.h" />
|
||||
<ClInclude Include="FamicomBox.h" />
|
||||
<ClInclude Include="SystemActionManager.h" />
|
||||
<ClInclude Include="DatachBarcodeReader.h" />
|
||||
<ClInclude Include="DebugHud.h" />
|
||||
|
@ -966,6 +970,7 @@
|
|||
<ClCompile Include="MovieRecorder.cpp" />
|
||||
<ClCompile Include="OggMixer.cpp" />
|
||||
<ClCompile Include="OggReader.cpp" />
|
||||
<ClCompile Include="OpenBusHandler.cpp" />
|
||||
<ClCompile Include="RawVideoFilter.cpp" />
|
||||
<ClCompile Include="RecordedRomTest.cpp" />
|
||||
<ClCompile Include="AutoSaveManager.cpp" />
|
||||
|
|
|
@ -113,6 +113,9 @@
|
|||
<Filter Include="Nes\Input\Controllers">
|
||||
<UniqueIdentifier>{7b42e684-9487-4031-a769-a05934998777}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Nes\MemoryManager">
|
||||
<UniqueIdentifier>{13af8497-e820-43f1-9888-85797a29b551}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="IAudioDevice.h">
|
||||
|
@ -283,9 +286,6 @@
|
|||
<ClInclude Include="CheatManager.h">
|
||||
<Filter>Nes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MemoryManager.h">
|
||||
<Filter>Nes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PPU.h">
|
||||
<Filter>Nes</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1438,6 +1438,21 @@
|
|||
<ClInclude Include="MMC3_224.h">
|
||||
<Filter>Nes\Mappers\MMC</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FamicomBox.h">
|
||||
<Filter>Nes\Mappers\Unif</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MemoryManager.h">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InternalRamHandler.h">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OpenBusHandler.h">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IMemoryManager.h">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -1503,9 +1518,6 @@
|
|||
<ClCompile Include="ControlManager.cpp">
|
||||
<Filter>Nes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MemoryManager.cpp">
|
||||
<Filter>Nes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PPU.cpp">
|
||||
<Filter>Nes</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1707,5 +1719,11 @@
|
|||
<ClCompile Include="BaseSoundManager.cpp">
|
||||
<Filter>Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MemoryManager.cpp">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OpenBusHandler.cpp">
|
||||
<Filter>Nes\MemoryManager</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
287
Core/FamicomBox.h
Normal file
287
Core/FamicomBox.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "BaseMapper.h"
|
||||
#include "InternalRamHandler.h"
|
||||
#include "IMemoryManager.h"
|
||||
|
||||
//SSS-NROM-256 (Famicom box menu board)
|
||||
//Info from here: http://kevtris.org/mappers/famicombox/index6.html
|
||||
class FamicomBox : public BaseMapper
|
||||
{
|
||||
private:
|
||||
uint8_t _regs[8];
|
||||
uint8_t _dipSwitches;
|
||||
uint8_t _extInternalRam[0x2000];
|
||||
InternalRamHandler<0x1FFF> _extendedRamHandler;
|
||||
|
||||
protected:
|
||||
uint16_t RegisterStartAddress() override { return 0x5000; }
|
||||
uint16_t RegisterEndAddress() override { return 0x5FFF; }
|
||||
uint16_t GetPRGPageSize() override { return 0x4000; }
|
||||
uint16_t GetCHRPageSize() override { return 0x2000; }
|
||||
bool AllowRegisterRead() override { return true; }
|
||||
|
||||
void InitMapper() override
|
||||
{
|
||||
_regs[7] = 0xFF;
|
||||
_dipSwitches = 0xC0;
|
||||
|
||||
SelectPRGPage(0, 0);
|
||||
SelectPRGPage(1, 1);
|
||||
|
||||
SelectCHRPage(0, 0);
|
||||
|
||||
_extendedRamHandler.SetInternalRam(_extInternalRam);
|
||||
}
|
||||
|
||||
void StreamState(bool saving) override
|
||||
{
|
||||
BaseMapper::StreamState(saving);
|
||||
ArrayInfo<uint8_t> regs { _regs, 8 };
|
||||
ArrayInfo<uint8_t> extRam { _extInternalRam, 0x2000 };
|
||||
Stream(_dipSwitches, regs, extRam);
|
||||
}
|
||||
|
||||
void Reset(bool softReset) override
|
||||
{
|
||||
for(int i = 0; i < 6; i++) {
|
||||
_regs[i] = 0;
|
||||
}
|
||||
_memoryManager->RegisterIODevice(&_extendedRamHandler);
|
||||
}
|
||||
|
||||
uint8_t ReadRegister(uint16_t addr) override
|
||||
{
|
||||
switch(addr & 7) {
|
||||
case 0:
|
||||
/*
|
||||
5000R: Device which caused an exception (0 = this device caused the exception)
|
||||
-----
|
||||
0 - 6.82Hz interrupt source hit
|
||||
1 - 8 bit timer expired @ 5003W
|
||||
2 - controller(s) were read
|
||||
3 - keyswitch was rotated
|
||||
4 - money was inserted
|
||||
5 - reset button was pressed
|
||||
6 - watchdog timer expired (reading either controller resets this timer)
|
||||
7 - Pin 4 of "CATV connector" went high/open
|
||||
*/
|
||||
_regs[0] = 0xFF; // clear all exceptions
|
||||
return _regs[0];
|
||||
|
||||
case 1:
|
||||
//5001R (not implemented)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
5002R Dip switch register
|
||||
DIP Switches Info:
|
||||
0x01 - Self Test. When on, unit will continuously self-test
|
||||
0x02 - Coin timeout period. off = 10 minutes, on = 20 minutes
|
||||
0x04 - not used
|
||||
0x08 - Famicombox menu time. off = 7 sec, on = 12 sec
|
||||
|
||||
0x10 - attract time
|
||||
0x20 - attract time
|
||||
00: 12 seconds
|
||||
01: 17 seconds
|
||||
10: 23 seconds
|
||||
11: 7 seconds
|
||||
|
||||
0x40 - Mode
|
||||
0x80 - Mode
|
||||
00: Key Mode
|
||||
01: CATV Mode
|
||||
10: Coin Mode
|
||||
11: Free Play
|
||||
*/
|
||||
return _dipSwitches;
|
||||
|
||||
case 3:
|
||||
/*5003R
|
||||
0 - key position 0 (1 = in this position)
|
||||
1 - key position 1
|
||||
2 - key position 2
|
||||
3 - key position 3
|
||||
4 - key position 4
|
||||
5 - key position 6
|
||||
6 - money system enabled (pin 9 of 3199)
|
||||
7 - pin 10 of 3199
|
||||
*/
|
||||
return 0x00; // 0, 1 - attract
|
||||
// 2
|
||||
// 4 - menu
|
||||
// 8 - self check and game casette check
|
||||
// 10 - lock?
|
||||
// 20 - game title & count display
|
||||
case 4:
|
||||
//5004R - DB-25 pins
|
||||
return 0;
|
||||
|
||||
case 5:
|
||||
//5005R: The enable for this runs to pin 28 of the expansion connector.
|
||||
return 0;
|
||||
|
||||
case 6:
|
||||
//5006R: The enable for this runs to pin 27 of the expansion connector.
|
||||
return 0;
|
||||
|
||||
case 7:
|
||||
/*
|
||||
0 - TV type selection (1 = game, 0 = TV)
|
||||
1 - keyswitch turned (1 = in middle of positions)
|
||||
2 - 0 = zapper grounded
|
||||
3 - pin 21 of exp. conn. (inverted)
|
||||
4 - state of pin 8 of "CATV" connector, 0 = low, 1 = high
|
||||
5 - relay position. 0 = position A, 1 = position B
|
||||
6 - pin 22 of exp. conn. (inverted)
|
||||
7 - 5005.5W (inverted)
|
||||
*/
|
||||
return 0x22; // TV type, key not turned, relay B
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WriteRegister(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
//None of this is implemented
|
||||
switch(addr & 0x07) {
|
||||
case 0:
|
||||
/*
|
||||
5000W: Exception Trap enable register (reset to 00h on powerup only)
|
||||
-----
|
||||
0 - 6.82Hz interrupt source (0 = enable)
|
||||
1 - 8 bit timer expiration @ 5003W (1 = enable)
|
||||
2 - controller reads (1 = enable)
|
||||
3 - keyswitch rotation (1 = enable)
|
||||
4 - money insertion (1 = enable)
|
||||
5 - reset button (1 = enable)
|
||||
6 - not used
|
||||
7 - "CATV connector" pin 4 detection (1 = enable)
|
||||
*/
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/*
|
||||
5001W Money handling register (reset to 00h on power up only)
|
||||
-----
|
||||
0 - pin 1 of 2D(3199)
|
||||
1 - pin 2 of 2D(3199)
|
||||
2 - pin 3 of 2D(3199)
|
||||
3 - pin 4 of 2D(3199)
|
||||
4 - pin 12 of 2D(3199)
|
||||
5 - pin 14 of 2D(3199)
|
||||
6 - enable pin 7 of "CATV" connector, 1 = enable.when in TV mode, output goes low. else output stays high
|
||||
7 - inverter->pin 8 of "CATV" connector
|
||||
*/
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
5002W LED & memory protect register (reset to 00h when CPU is reset)
|
||||
-----
|
||||
|
||||
0 - LED sel 0
|
||||
1 - LED sel 1
|
||||
2 - LED sel 2
|
||||
3 - LED sel 3
|
||||
4 - Mem Protect 0
|
||||
5 - Mem protect 1
|
||||
6 - Mem protect 2
|
||||
7 - LED flash- high = flash, low = steady
|
||||
|
||||
LED sel: 01-0fh selects one of the LEDs on the front, 0 = no LEDs
|
||||
|
||||
Mem protect:
|
||||
|
||||
0 - no RAM is writable
|
||||
1 - 0000-07ffh is writable
|
||||
2 - 0000-0fffh is writable
|
||||
3 - 0000-17ffh is writable
|
||||
4-7 - 0000-1fffh is writable
|
||||
*/
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/*
|
||||
5003W 8 bit down counter, for attract mode timing
|
||||
-----
|
||||
|
||||
Writing to this location loads the counter with the 8 bit value written .
|
||||
It is clocked at a 6.8274Hz rate. When the timer wraps from 00h to ffh
|
||||
it triggers an exception, if it is enabled. (See 5000W and 5000R)
|
||||
This timer is used for the "attract" mode. It lets the game run for
|
||||
several seconds before it brings the menu back.
|
||||
*/
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/*
|
||||
5004W Cart control register (reset to 00h when CPU is reset)
|
||||
-----
|
||||
|
||||
0 - cart 0
|
||||
1 - cart 1
|
||||
2 - cart 2
|
||||
3 - cart 3
|
||||
4 - row select 0
|
||||
5 - row select 1
|
||||
6 - Lock. writing a 1 here unmaps all hardware
|
||||
7 - NC
|
||||
|
||||
cart: These 4 bits select which cartridge is active. Cartridge 0 is the
|
||||
menu cart inside the unit, carts 01-0fh are the carts on the front.
|
||||
|
||||
row select: These bits select which row of carts is active.
|
||||
|
||||
0 - only the internal menu cart is selected.
|
||||
1 - carts 1-5 are selected
|
||||
2 - carts 6-10 are selected
|
||||
3 - carts 11-15 are selected
|
||||
|
||||
Proper cart selection requires setting up BOTH the desired cart # (00-0fh), AND
|
||||
the proper row. The menu software uses a small table to do this.
|
||||
*/
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/*
|
||||
5005W CATV and joypad control (reset to 00h on power up only)
|
||||
-----
|
||||
0 - 1 = flip latching relay to position A (coil on pins 1 & 10)
|
||||
1 - connects to 3199
|
||||
2 - turn zapper on. 1 = turn on
|
||||
3 - enable 40% input of modulator. 1 = enable, 0 = disable
|
||||
4 - NC
|
||||
5 - maps to 5007R.7
|
||||
6 - joypad enable- 1 = disable, 0 = enable
|
||||
7 - joypad swap. 1 = normal, 0 = swap swapping only swaps D0 and CLK
|
||||
*/
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/*
|
||||
5006W (not reset, unknown contents at powerup)
|
||||
-----
|
||||
0 - DB-25 pin 6
|
||||
1 - DB-25 pin 15
|
||||
2 - DB-25 pin 7
|
||||
3 - DB-25 pin 16
|
||||
4 - DB-25 pin 8
|
||||
5 - DB-25 pin 17
|
||||
6 - DB-25 pin 9
|
||||
7 - DB-25 pin 18
|
||||
*/
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/*
|
||||
5007W (not implemented)
|
||||
-----
|
||||
The enable for this runs to pin 26 of the expansion connector.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
9
Core/IMemoryManager.h
Normal file
9
Core/IMemoryManager.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
#include "IMemoryHandler.h"
|
||||
|
||||
class IMemoryManager
|
||||
{
|
||||
public:
|
||||
virtual void RegisterIODevice(IMemoryHandler *handler) = 0;
|
||||
virtual void UnregisterIODevice(IMemoryHandler *handler) = 0;
|
||||
};
|
32
Core/InternalRamHandler.h
Normal file
32
Core/InternalRamHandler.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
|
||||
template<size_t Mask>
|
||||
class InternalRamHandler : public IMemoryHandler
|
||||
{
|
||||
private:
|
||||
uint8_t *_internalRam;
|
||||
|
||||
public:
|
||||
void SetInternalRam(uint8_t* internalRam)
|
||||
{
|
||||
_internalRam = internalRam;
|
||||
}
|
||||
|
||||
void GetMemoryRanges(MemoryRanges &ranges) override
|
||||
{
|
||||
ranges.SetAllowOverride();
|
||||
ranges.AddHandler(MemoryOperation::Any, 0, 0x1FFF);
|
||||
}
|
||||
|
||||
uint8_t ReadRAM(uint16_t addr) override
|
||||
{
|
||||
return _internalRam[addr & Mask];
|
||||
}
|
||||
|
||||
void WriteRAM(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
_internalRam[addr & Mask] = value;
|
||||
}
|
||||
};
|
|
@ -32,6 +32,7 @@
|
|||
#include "Bmc8in1.h"
|
||||
#include "BmcG146.h"
|
||||
#include "BmcGn45.h"
|
||||
#include "BmcHpxx.h"
|
||||
#include "BmcNtd03.h"
|
||||
#include "BnRom.h"
|
||||
#include "Bs5.h"
|
||||
|
@ -49,6 +50,7 @@
|
|||
#include "DreamTech01.h"
|
||||
#include "Edu2000.h"
|
||||
#include "Eh8813A.h"
|
||||
#include "FamicomBox.h"
|
||||
#include "FDS.h"
|
||||
#include "FrontFareast.h"
|
||||
#include "Ghostbusters63in1.h"
|
||||
|
@ -59,7 +61,6 @@
|
|||
#include "Henggedianzi177.h"
|
||||
#include "Henggedianzi179.h"
|
||||
#include "Hp898f.h"
|
||||
#include "BmcHpxx.h"
|
||||
#include "IremG101.h"
|
||||
#include "IremH3001.h"
|
||||
#include "IremLrog017.h"
|
||||
|
@ -583,6 +584,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData)
|
|||
case UnifBoards::Rt01: return new Rt01();
|
||||
case UnifBoards::Sachen9602: return new Sachen9602();
|
||||
case UnifBoards::Smb2j: return new Smb2j();
|
||||
case UnifBoards::SssNrom256: return new FamicomBox();
|
||||
case UnifBoards::StreetHeroes: return new MMC3_StreetHeroes();
|
||||
case UnifBoards::Super24in1Sc03: return new MMC3_Super24in1Sc03();
|
||||
case UnifBoards::Super40in1Ws: return new Super40in1Ws();
|
||||
|
|
|
@ -4,27 +4,30 @@
|
|||
#include "Debugger.h"
|
||||
#include "CheatManager.h"
|
||||
|
||||
//Used for open bus
|
||||
uint8_t MemoryManager::_lastReadValue = 0;
|
||||
|
||||
MemoryManager::MemoryManager(shared_ptr<BaseMapper> mapper)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_lastReadValue = 0;
|
||||
|
||||
_internalRAM = new uint8_t[InternalRAMSize];
|
||||
_internalRamHandler.SetInternalRam(_internalRAM);
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
_nametableRAM[i] = new uint8_t[NameTableScreenSize];
|
||||
BaseMapper::InitializeRam(_nametableRAM[i], NameTableScreenSize);
|
||||
}
|
||||
|
||||
_mapper->SetMemoryManager(this);
|
||||
_mapper->SetDefaultNametables(_nametableRAM[0], _nametableRAM[1]);
|
||||
|
||||
_ramReadHandlers = new IMemoryHandler*[RAMSize];
|
||||
_ramWriteHandlers = new IMemoryHandler*[RAMSize];
|
||||
|
||||
memset(_ramReadHandlers, 0, RAMSize * sizeof(IMemoryHandler*));
|
||||
memset(_ramWriteHandlers, 0, RAMSize * sizeof(IMemoryHandler*));
|
||||
for(int i = 0; i < RAMSize; i++) {
|
||||
_ramReadHandlers[i] = &_openBusHandler;
|
||||
_ramWriteHandlers[i] = &_openBusHandler;
|
||||
}
|
||||
|
||||
RegisterIODevice(&_internalRamHandler);
|
||||
}
|
||||
|
||||
MemoryManager::~MemoryManager()
|
||||
|
@ -47,26 +50,10 @@ void MemoryManager::Reset(bool softReset)
|
|||
_mapper->Reset(softReset);
|
||||
}
|
||||
|
||||
uint8_t MemoryManager::ReadRegister(uint16_t addr)
|
||||
{
|
||||
if(_ramReadHandlers[addr]) {
|
||||
return _ramReadHandlers[addr]->ReadRAM(addr);
|
||||
} else {
|
||||
return GetOpenBus();
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::WriteRegister(uint16_t addr, uint8_t value)
|
||||
{
|
||||
if(_ramWriteHandlers[addr]) {
|
||||
_ramWriteHandlers[addr]->WriteRAM(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::InitializeMemoryHandlers(IMemoryHandler** memoryHandlers, IMemoryHandler* handler, vector<uint16_t> *addresses, bool allowOverride)
|
||||
{
|
||||
for(uint16_t address : *addresses) {
|
||||
if(!allowOverride && memoryHandlers[address] != nullptr && memoryHandlers[address] != handler) {
|
||||
if(!allowOverride && memoryHandlers[address] != &_openBusHandler && memoryHandlers[address] != handler) {
|
||||
throw std::runtime_error("Not supported");
|
||||
}
|
||||
memoryHandlers[address] = handler;
|
||||
|
@ -88,11 +75,11 @@ void MemoryManager::UnregisterIODevice(IMemoryHandler *handler)
|
|||
handler->GetMemoryRanges(ranges);
|
||||
|
||||
for(uint16_t address : *ranges.GetRAMReadAddresses()) {
|
||||
_ramReadHandlers[address] = nullptr;
|
||||
_ramReadHandlers[address] = &_openBusHandler;
|
||||
}
|
||||
|
||||
for(uint16_t address : *ranges.GetRAMWriteAddresses()) {
|
||||
_ramWriteHandlers[address] = nullptr;
|
||||
_ramWriteHandlers[address] = &_openBusHandler;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +92,7 @@ uint8_t MemoryManager::DebugRead(uint16_t addr, bool disableSideEffects)
|
|||
{
|
||||
uint8_t value = 0x00;
|
||||
if(addr <= 0x1FFF) {
|
||||
value = _internalRAM[addr & 0x07FF];
|
||||
value = _ramReadHandlers[addr]->ReadRAM(addr);
|
||||
} else {
|
||||
IMemoryHandler* handler = _ramReadHandlers[addr];
|
||||
if(handler) {
|
||||
|
@ -140,18 +127,11 @@ void MemoryManager::ProcessCpuClock()
|
|||
|
||||
uint8_t MemoryManager::Read(uint16_t addr, MemoryOperationType operationType)
|
||||
{
|
||||
uint8_t value;
|
||||
if(addr <= 0x1FFF) {
|
||||
value = _internalRAM[addr & 0x07FF];
|
||||
} else {
|
||||
value = ReadRegister(addr);
|
||||
}
|
||||
|
||||
uint8_t value = _ramReadHandlers[addr]->ReadRAM(addr);
|
||||
CheatManager::ApplyRamCodes(addr, value);
|
||||
|
||||
Debugger::ProcessRamOperation(operationType, addr, value);
|
||||
|
||||
_lastReadValue = value;
|
||||
OpenBusHandler::SetOpenBus(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -159,18 +139,14 @@ uint8_t MemoryManager::Read(uint16_t addr, MemoryOperationType operationType)
|
|||
void MemoryManager::Write(uint16_t addr, uint8_t value)
|
||||
{
|
||||
if(Debugger::ProcessRamOperation(MemoryOperationType::Write, addr, value)) {
|
||||
if(addr <= 0x1FFF) {
|
||||
_internalRAM[addr & 0x07FF] = value;
|
||||
} else {
|
||||
WriteRegister(addr, value);
|
||||
}
|
||||
_ramWriteHandlers[addr]->WriteRAM(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::DebugWrite(uint16_t addr, uint8_t value, bool disableSideEffects)
|
||||
{
|
||||
if(addr <= 0x1FFF) {
|
||||
_internalRAM[addr & 0x07FF] = value;
|
||||
_ramWriteHandlers[addr]->WriteRAM(addr, value);
|
||||
} else {
|
||||
IMemoryHandler* handler = _ramReadHandlers[addr];
|
||||
if(handler) {
|
||||
|
@ -201,5 +177,5 @@ void MemoryManager::StreamState(bool saving)
|
|||
|
||||
uint8_t MemoryManager::GetOpenBus(uint8_t mask)
|
||||
{
|
||||
return _lastReadValue & mask;
|
||||
return OpenBusHandler::GetOpenBus() & mask;
|
||||
}
|
|
@ -3,28 +3,29 @@
|
|||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
#include "Snapshotable.h"
|
||||
#include "OpenBusHandler.h"
|
||||
#include "InternalRamHandler.h"
|
||||
#include "IMemoryManager.h"
|
||||
|
||||
class BaseMapper;
|
||||
|
||||
class MemoryManager: public Snapshotable
|
||||
class MemoryManager: public IMemoryManager, public Snapshotable
|
||||
{
|
||||
private:
|
||||
static const int RAMSize = 0x10000;
|
||||
static const int VRAMSize = 0x4000;
|
||||
static const int NameTableScreenSize = 0x400;
|
||||
|
||||
static uint8_t _lastReadValue;
|
||||
|
||||
shared_ptr<BaseMapper> _mapper;
|
||||
|
||||
uint8_t *_internalRAM;
|
||||
uint8_t *_nametableRAM[2];
|
||||
|
||||
OpenBusHandler _openBusHandler;
|
||||
InternalRamHandler<0x7FF> _internalRamHandler;
|
||||
IMemoryHandler** _ramReadHandlers;
|
||||
IMemoryHandler** _ramWriteHandlers;
|
||||
|
||||
uint8_t ReadRegister(uint16_t addr);
|
||||
void WriteRegister(uint16_t addr, uint8_t value);
|
||||
|
||||
void InitializeMemoryHandlers(IMemoryHandler** memoryHandlers, IMemoryHandler* handler, vector<uint16_t> *addresses, bool allowOverride);
|
||||
|
||||
protected:
|
||||
|
@ -37,8 +38,8 @@ class MemoryManager: public Snapshotable
|
|||
~MemoryManager();
|
||||
|
||||
void Reset(bool softReset);
|
||||
void RegisterIODevice(IMemoryHandler *handler);
|
||||
void UnregisterIODevice(IMemoryHandler *handler);
|
||||
void RegisterIODevice(IMemoryHandler *handler) override;
|
||||
void UnregisterIODevice(IMemoryHandler *handler) override;
|
||||
|
||||
uint8_t DebugRead(uint16_t addr, bool disableSideEffects = true);
|
||||
uint16_t DebugReadWord(uint16_t addr);
|
||||
|
|
4
Core/OpenBusHandler.cpp
Normal file
4
Core/OpenBusHandler.cpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include "stdafx.h"
|
||||
#include "OpenBusHandler.h"
|
||||
|
||||
uint8_t OpenBusHandler::_lastReadValue = 0;
|
38
Core/OpenBusHandler.h
Normal file
38
Core/OpenBusHandler.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
|
||||
class OpenBusHandler : public IMemoryHandler
|
||||
{
|
||||
private:
|
||||
static uint8_t _lastReadValue;
|
||||
|
||||
public:
|
||||
OpenBusHandler()
|
||||
{
|
||||
_lastReadValue = 0;
|
||||
}
|
||||
|
||||
uint8_t ReadRAM(uint16_t addr) override
|
||||
{
|
||||
return _lastReadValue;
|
||||
}
|
||||
|
||||
__forceinline static uint8_t GetOpenBus()
|
||||
{
|
||||
return _lastReadValue;
|
||||
}
|
||||
|
||||
__forceinline static void SetOpenBus(uint8_t value)
|
||||
{
|
||||
_lastReadValue = value;
|
||||
}
|
||||
|
||||
void GetMemoryRanges(MemoryRanges & ranges) override
|
||||
{
|
||||
}
|
||||
|
||||
void WriteRAM(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
}
|
||||
};
|
|
@ -71,5 +71,6 @@ namespace UnifBoards {
|
|||
DragonFighter,
|
||||
BmcGn45,
|
||||
UnlDripGame,
|
||||
SssNrom256,
|
||||
};
|
||||
}
|
|
@ -108,7 +108,7 @@ std::unordered_map<string, int> UnifLoader::_boardMappings = std::unordered_map<
|
|||
{ "SMB2J", UnifBoards::Smb2j },
|
||||
{ "SNROM", 1 },
|
||||
{ "SOROM", 1 },
|
||||
{ "SSS-NROM-256", UnifBoards::UnknownBoard },
|
||||
{ "SSS-NROM-256", UnifBoards::SssNrom256 },
|
||||
{ "SUNSOFT_UNROM", 93 },
|
||||
{ "Sachen-74LS374N", 150 },
|
||||
{ "Sachen-74LS374NA", 243 },
|
||||
|
|
Loading…
Add table
Reference in a new issue