Registers change APIs.

This commit is contained in:
Vladimir Kononovich 2020-10-11 13:57:01 +03:00
parent 242dd77365
commit f514335bde
25 changed files with 511 additions and 15 deletions

View file

@ -117,3 +117,45 @@ void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
UpdateIrqNmiFlags(); UpdateIrqNmiFlags();
} }
#endif #endif
void Cpu::SetReg(CpuRegister reg, uint16_t value)
{
switch (reg) {
case CpuRegister::CpuRegA:
{
_state.A = value;
} break;
case CpuRegister::CpuRegX:
{
_state.X = value;
} break;
case CpuRegister::CpuRegY:
{
_state.Y = value;
} break;
case CpuRegister::CpuRegSP:
{
_state.SP = value;
} break;
case CpuRegister::CpuRegD:
{
_state.D = value;
} break;
case CpuRegister::CpuRegPC:
{
_state.PC = value;
} break;
case CpuRegister::CpuRegK:
{
_state.K = value & 0xFF;
} break;
case CpuRegister::CpuRegDBR:
{
_state.DBR = value & 0xFF;
} break;
case CpuRegister::CpuRegPS:
{
_state.PS = value & 0xFF;
} break;
}
}

View file

@ -7,6 +7,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "CpuTypes.h" #include "CpuTypes.h"
#include "DebugTypes.h"
#include "../Utilities/ISerializable.h" #include "../Utilities/ISerializable.h"
class MemoryMappings; class MemoryMappings;
@ -345,6 +346,8 @@ public:
// Inherited via ISerializable // Inherited via ISerializable
void Serialize(Serializer &s) override; void Serialize(Serializer &s) override;
void SetReg(CpuRegister reg, uint16_t value);
#ifdef DUMMYCPU #ifdef DUMMYCPU
private: private:
MemoryMappings* _memoryMappings; MemoryMappings* _memoryMappings;
@ -370,6 +373,8 @@ public:
#endif #endif
}; };
void SetReg(CpuRegister reg, uint16_t value);
template<uint64_t count> template<uint64_t count>
void Cpu::IncreaseCycleCount() void Cpu::IncreaseCycleCount()
{ {

View file

@ -478,4 +478,31 @@ uint32_t Cx4::DebugGetDataRamSize()
Cx4State Cx4::GetState() Cx4State Cx4::GetState()
{ {
return _state; return _state;
}
void Cx4::SetReg(Cx4Register reg, uint32_t value)
{
switch (reg)
{
case Cx4Register::Cx4RegPB:
{
_state.PB = value & 0xFFFF;
} break;
case Cx4Register::Cx4RegPC:
{
_state.PC = value & 0xFF;
} break;
case Cx4Register::Cx4RegA:
{
_state.A = value;
} break;
case Cx4Register::Cx4RegP:
{
_state.P = value & 0xFFFF;
} break;
case Cx4Register::Cx4RegSP:
{
_state.SP = value & 0xFF;
} break;
}
} }

View file

@ -129,4 +129,6 @@ public:
uint8_t* DebugGetDataRam(); uint8_t* DebugGetDataRam();
uint32_t DebugGetDataRamSize(); uint32_t DebugGetDataRamSize();
Cx4State GetState(); Cx4State GetState();
void SetReg(Cx4Register reg, uint32_t value);
}; };

View file

@ -284,3 +284,92 @@ enum class CpuType : uint8_t
Cx4, Cx4,
Gameboy Gameboy
}; };
enum class CpuRegister : uint8_t
{
CpuRegA,
CpuRegX,
CpuRegY,
CpuRegSP,
CpuRegD,
CpuRegPC,
CpuRegK,
CpuRegDBR,
CpuRegPS
};
enum class Cx4Register : uint8_t
{
Cx4RegPB,
Cx4RegPC,
Cx4RegA,
Cx4RegP,
Cx4RegSP
};
enum class GbRegister : uint8_t
{
GbRegPC,
GbRegSP,
GbRegA,
GbRegFlags,
GbRegB,
GbRegC,
GbRegD,
GbRegE,
GbRegH,
GbRegL
};
enum class GsuRegister : uint8_t
{
GsuReg0,
GsuReg1,
GsuReg2,
GsuReg3,
GsuReg4,
GsuReg5,
GsuReg6,
GsuReg7,
GsuReg8,
GsuReg9,
GsuRegA,
GsuRegB,
GsuRegC,
GsuRegD,
GsuRegE,
GsuRegF,
GsuRegSFR
};
enum class NecDspRegister : uint8_t
{
NecDspRegA,
NecDspRegFlagsA,
NecDspRegB,
NecDspRegFlagsB,
NecDspRegTR,
NecDspRegTRB,
NecDspRegPC,
NecDspRegRP,
NecDspRegDP,
NecDspRegDR,
NecDspRegSR,
NecDspRegK,
NecDspRegL,
NecDspRegM,
NecDspRegN,
NecDspRegSerialOut,
NecDspRegSerialIn,
NecDspRegSP
};
enum class SpcRegister : uint8_t
{
SpcRegPC,
SpcRegA,
SpcRegX,
SpcRegY,
SpcRegSP,
SpcRegPS
};

View file

@ -511,6 +511,41 @@ void Debugger::GetState(DebugState &state, bool partialPpuState)
} }
} }
void Debugger::SetCpuRegister(CpuRegister reg, uint16_t value)
{
_cpu->SetReg(reg, value);
}
void Debugger::SetCx4Register(Cx4Register reg, uint32_t value)
{
_cart->GetCx4()->SetReg(reg, value);
}
void Debugger::SetGameboyRegister(GbRegister reg, uint16_t value)
{
_cart->GetGameboy()->SetReg(reg, value);
}
void Debugger::SetGsuRegister(GsuRegister reg, uint16_t value)
{
_cart->GetGsu()->SetReg(reg, value);
}
void Debugger::SetNecDspRegister(NecDspRegister reg, uint16_t value)
{
_cart->GetDsp()->SetReg(reg, value);
}
void Debugger::SetSa1Register(CpuRegister reg, uint16_t value)
{
_cart->GetSa1()->SetReg(reg, value);
}
void Debugger::SetSpcRegister(SpcRegister reg, uint8_t value)
{
_spc->SetReg(reg, value);
}
AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress) AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress)
{ {
if(relAddress.Type == SnesMemoryType::CpuMemory) { if(relAddress.Type == SnesMemoryType::CpuMemory) {

View file

@ -127,7 +127,15 @@ public:
void ProcessBreakConditions(bool needBreak, BreakpointManager *bpManager, MemoryOperationInfo &operation, AddressInfo &addressInfo, BreakSource source = BreakSource::Unspecified); void ProcessBreakConditions(bool needBreak, BreakpointManager *bpManager, MemoryOperationInfo &operation, AddressInfo &addressInfo, BreakSource source = BreakSource::Unspecified);
void SleepUntilResume(BreakSource source, MemoryOperationInfo* operation = nullptr, int breakpointId = -1); void SleepUntilResume(BreakSource source, MemoryOperationInfo* operation = nullptr, int breakpointId = -1);
void GetState(DebugState &state, bool partialPpuState); void GetState(DebugState& state, bool partialPpuState);
void SetCpuRegister(CpuRegister reg, uint16_t value);
void SetCx4Register(Cx4Register reg, uint32_t value);
void SetGameboyRegister(GbRegister reg, uint16_t value);
void SetGsuRegister(GsuRegister reg, uint16_t value);
void SetNecDspRegister(NecDspRegister reg, uint16_t value);
void SetSa1Register(CpuRegister reg, uint16_t value);
void SetSpcRegister(SpcRegister reg, uint8_t value);
AddressInfo GetAbsoluteAddress(AddressInfo relAddress); AddressInfo GetAbsoluteAddress(AddressInfo relAddress);
AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType); AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType);

View file

@ -364,3 +364,8 @@ void Gameboy::Serialize(Serializer& s)
s.StreamArray(_spriteRam, Gameboy::SpriteRamSize); s.StreamArray(_spriteRam, Gameboy::SpriteRamSize);
s.StreamArray(_highRam, Gameboy::HighRamSize); s.StreamArray(_highRam, Gameboy::HighRamSize);
} }
void Gameboy::SetReg(GbRegister reg, uint16_t value)
{
_cpu->SetReg(reg, value);
}

View file

@ -92,4 +92,6 @@ public:
uint64_t GetApuCycleCount(); uint64_t GetApuCycleCount();
void Serialize(Serializer& s) override; void Serialize(Serializer& s) override;
void SetReg(GbRegister reg, uint16_t value);
}; };

View file

@ -1389,3 +1389,50 @@ void GbCpu::Serialize(Serializer& s)
_state.EiPending _state.EiPending
); );
} }
void GbCpu::SetReg(GbRegister reg, uint16_t value)
{
switch (reg)
{
case GbRegister::GbRegPC:
{
_state.PC = value;
} break;
case GbRegister::GbRegSP:
{
_state.SP = value;
} break;
case GbRegister::GbRegA:
{
_state.A = value & 0xFF;
} break;
case GbRegister::GbRegFlags:
{
_state.Flags = value & 0xFF;
} break;
case GbRegister::GbRegB:
{
_state.B = value & 0xFF;
} break;
case GbRegister::GbRegC:
{
_state.C = value & 0xFF;
} break;
case GbRegister::GbRegD:
{
_state.D = value & 0xFF;
} break;
case GbRegister::GbRegE:
{
_state.E = value & 0xFF;
} break;
case GbRegister::GbRegH:
{
_state.H = value & 0xFF;
} break;
case GbRegister::GbRegL:
{
_state.L = value & 0xFF;
} break;
}
}

View file

@ -150,4 +150,6 @@ public:
void Exec(); void Exec();
void Serialize(Serializer& s) override; void Serialize(Serializer& s) override;
void SetReg(GbRegister reg, uint16_t value);
}; };

View file

@ -651,3 +651,33 @@ uint32_t Gsu::DebugGetWorkRamSize()
{ {
return _gsuRamSize; return _gsuRamSize;
} }
void Gsu::SetReg(GsuRegister reg, uint16_t value)
{
switch (reg)
{
case GsuRegister::GsuReg0:
case GsuRegister::GsuReg1:
case GsuRegister::GsuReg2:
case GsuRegister::GsuReg3:
case GsuRegister::GsuReg4:
case GsuRegister::GsuReg5:
case GsuRegister::GsuReg6:
case GsuRegister::GsuReg7:
case GsuRegister::GsuReg8:
case GsuRegister::GsuReg9:
case GsuRegister::GsuRegA:
case GsuRegister::GsuRegB:
case GsuRegister::GsuRegC:
case GsuRegister::GsuRegD:
case GsuRegister::GsuRegE:
case GsuRegister::GsuRegF:
{
_state.R[static_cast<int>(reg) & 0xF] = value;
} break;
case GsuRegister::GsuRegSFR:
{
_state.SFR.SetFlags(value);
} break;
}
}

View file

@ -170,4 +170,6 @@ public:
MemoryMappings* GetMemoryMappings(); MemoryMappings* GetMemoryMappings();
uint8_t* DebugGetWorkRam(); uint8_t* DebugGetWorkRam();
uint32_t DebugGetWorkRamSize(); uint32_t DebugGetWorkRamSize();
void SetReg(GsuRegister reg, uint16_t value);
}; };

View file

@ -39,6 +39,27 @@ struct GsuFlags
(Irq << 7) (Irq << 7)
); );
} }
void SetFlags(uint16_t flags)
{
// 0 bit is clear
Zero = flags & (1 << 1);
Carry = flags & (1 << 2);
Sign = flags & (1 << 3);
Overflow = flags & (1 << 4);
Running = flags & (1 << 5);
RomReadPending = flags & (1 << 6);
// 7 bit is clear
Alt1 = flags & (1 << (8 + 0));
Alt2 = flags & (1 << (8 + 1));
ImmLow = flags & (1 << (8 + 2));
ImmHigh = flags & (1 << (8 + 3));
Prefix = flags & (1 << (8 + 4));
// 5 bit is clear
// 6 bit is clear
Irq = flags & (1 << (8 + 7));
}
}; };
struct GsuPixelCache struct GsuPixelCache

View file

@ -586,3 +586,82 @@ void NecDsp::Serialize(Serializer &s)
s.StreamArray<uint16_t>(_stack, _stackSize); s.StreamArray<uint16_t>(_stack, _stackSize);
} }
void NecDsp::SetReg(NecDspRegister reg, uint16_t value)
{
switch (reg)
{
case NecDspRegister::NecDspRegA:
{
_state.A = value;
} break;
case NecDspRegister::NecDspRegFlagsA:
{
_state.FlagsA.SetFlags(value & 0xFF);
} break;
case NecDspRegister::NecDspRegB:
{
_state.B = value;
} break;
case NecDspRegister::NecDspRegFlagsB:
{
_state.FlagsB.SetFlags(value & 0xFF);
} break;
case NecDspRegister::NecDspRegTR:
{
_state.TR = value;
} break;
case NecDspRegister::NecDspRegTRB:
{
_state.TRB = value;
} break;
case NecDspRegister::NecDspRegPC:
{
_state.PC = value;
} break;
case NecDspRegister::NecDspRegRP:
{
_state.RP = value;
} break;
case NecDspRegister::NecDspRegDP:
{
_state.DP = value;
} break;
case NecDspRegister::NecDspRegDR:
{
_state.DR = value;
} break;
case NecDspRegister::NecDspRegSR:
{
_state.SR = value;
} break;
case NecDspRegister::NecDspRegK:
{
_state.K = value;
} break;
case NecDspRegister::NecDspRegL:
{
_state.L = value;
} break;
case NecDspRegister::NecDspRegM:
{
_state.M = value;
} break;
case NecDspRegister::NecDspRegN:
{
_state.N = value;
} break;
case NecDspRegister::NecDspRegSerialOut:
{
_state.SerialOut = value;
} break;
case NecDspRegister::NecDspRegSerialIn:
{
_state.SerialIn = value;
} break;
case NecDspRegister::NecDspRegSP:
{
_state.SP = value & 0xFF;
} break;
}
}

View file

@ -82,4 +82,6 @@ public:
NecDspState GetState(); NecDspState GetState();
void Serialize(Serializer &s) override; void Serialize(Serializer &s) override;
void SetReg(NecDspRegister reg, uint16_t value);
}; };

View file

@ -9,6 +9,16 @@ struct NecDspAccFlags
bool Overflow1; bool Overflow1;
bool Sign0; bool Sign0;
bool Sign1; bool Sign1;
void SetFlags(uint8_t flags)
{
Carry = flags & (1 << 0);
Zero = flags & (1 << 1);
Overflow0 = flags & (1 << 2);
Overflow1 = flags & (1 << 3);
Sign0 = flags & (1 << 4);
Sign1 = flags & (1 << 5);
}
}; };
namespace NecDspStatusFlags namespace NecDspStatusFlags

View file

@ -949,7 +949,7 @@ void Ppu::RenderTilemap()
TileData* tileData = _layerData[layerIndex].Tiles; TileData* tileData = _layerData[layerIndex].Tiles;
uint8_t mosaicCounter = applyMosaic ? (_drawStartX % _state.MosaicSize) : 0; uint8_t mosaicCounter = applyMosaic ? _state.MosaicSize - (_drawStartX % _state.MosaicSize) : 0;
uint8_t lookupIndex; uint8_t lookupIndex;
uint8_t chrDataOffset; uint8_t chrDataOffset;
@ -988,7 +988,7 @@ void Ppu::RenderTilemap()
uint8_t priority = (tilemapData & 0x2000) ? highPriority : normalPriority; uint8_t priority = (tilemapData & 0x2000) ? highPriority : normalPriority;
if(applyMosaic) { if(applyMosaic) {
if(mosaicCounter == 0) { if(mosaicCounter == _state.MosaicSize) {
mosaicCounter = 1; mosaicCounter = 1;
if(hiResMode) { if(hiResMode) {
color = hiresSubColor; color = hiresSubColor;
@ -997,9 +997,6 @@ void Ppu::RenderTilemap()
_mosaicPriority[layerIndex] = priority; _mosaicPriority[layerIndex] = priority;
} else { } else {
mosaicCounter++; mosaicCounter++;
if(mosaicCounter == _state.MosaicSize) {
mosaicCounter = 0;
}
color = _mosaicColor[layerIndex] & 0xFF; color = _mosaicColor[layerIndex] & 0xFF;
paletteIndex = _mosaicColor[layerIndex] >> 8; paletteIndex = _mosaicColor[layerIndex] >> 8;
priority = _mosaicPriority[layerIndex]; priority = _mosaicPriority[layerIndex];
@ -1111,7 +1108,7 @@ void Ppu::RenderTilemapMode7()
//Keep the "scanline" to what it was at the start of this mosaic block //Keep the "scanline" to what it was at the start of this mosaic block
realY -= _state.MosaicSize - _mosaicScanlineCounter; realY -= _state.MosaicSize - _mosaicScanlineCounter;
} }
uint8_t mosaicCounter = applyMosaic ? (_drawStartX % _state.MosaicSize) : 0; uint8_t mosaicCounter = applyMosaic ? _state.MosaicSize - (_drawStartX % _state.MosaicSize) : 0;
int32_t xValue = ( int32_t xValue = (
((_state.Mode7.Matrix[0] * clip(hScroll - centerX)) & ~63) + ((_state.Mode7.Matrix[0] * clip(hScroll - centerX)) & ~63) +
@ -1178,15 +1175,12 @@ void Ppu::RenderTilemapMode7()
} }
if(applyMosaic) { if(applyMosaic) {
if(mosaicCounter == 0) { if(mosaicCounter == _state.MosaicSize) {
mosaicCounter = 1; mosaicCounter = 1;
_mosaicColor[layerIndex] = colorIndex; _mosaicColor[layerIndex] = colorIndex;
_mosaicPriority[layerIndex] = priority; _mosaicPriority[layerIndex] = priority;
} else { } else {
mosaicCounter++; mosaicCounter++;
if(mosaicCounter == _state.MosaicSize) {
mosaicCounter = 0;
}
colorIndex = _mosaicColor[layerIndex]; colorIndex = _mosaicColor[layerIndex];
priority = _mosaicPriority[layerIndex]; priority = _mosaicPriority[layerIndex];
} }

View file

@ -863,4 +863,9 @@ void Sa1::Serialize(Serializer &s)
UpdateSaveRamMappings(); UpdateSaveRamMappings();
ProcessInterrupts(); ProcessInterrupts();
} }
} }
void Sa1::SetReg(CpuRegister reg, uint16_t value)
{
_cpu->SetReg(reg, value);
}

View file

@ -95,4 +95,6 @@ public:
MemoryMappings* GetMemoryMappings(); MemoryMappings* GetMemoryMappings();
void LoadBattery() override; void LoadBattery() override;
void SaveBattery() override; void SaveBattery() override;
void SetReg(CpuRegister reg, uint16_t value);
}; };

View file

@ -142,4 +142,46 @@ uint16_t Sa1Cpu::GetResetVector()
void Sa1Cpu::IncreaseCycleCount(uint64_t cycleCount) void Sa1Cpu::IncreaseCycleCount(uint64_t cycleCount)
{ {
_state.CycleCount += cycleCount; _state.CycleCount += cycleCount;
} }
void Sa1Cpu::SetReg(CpuRegister reg, uint16_t value)
{
switch (reg) {
case CpuRegister::CpuRegA:
{
_state.A = value;
} break;
case CpuRegister::CpuRegX:
{
_state.X = value;
} break;
case CpuRegister::CpuRegY:
{
_state.Y = value;
} break;
case CpuRegister::CpuRegSP:
{
_state.SP = value;
} break;
case CpuRegister::CpuRegD:
{
_state.D = value;
} break;
case CpuRegister::CpuRegPC:
{
_state.PC = value;
} break;
case CpuRegister::CpuRegK:
{
_state.K = value & 0xFF;
} break;
case CpuRegister::CpuRegDBR:
{
_state.DBR = value & 0xFF;
} break;
case CpuRegister::CpuRegPS:
{
_state.PS = value & 0xFF;
} break;
}
}

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
#include "CpuTypes.h" #include "CpuTypes.h"
#include "DebugTypes.h"
#include "../Utilities/ISerializable.h" #include "../Utilities/ISerializable.h"
class Sa1; class Sa1;
@ -333,6 +334,8 @@ public:
// Inherited via ISerializable // Inherited via ISerializable
void Serialize(Serializer &s) override; void Serialize(Serializer &s) override;
void SetReg(CpuRegister reg, uint16_t value);
}; };
template<uint64_t count> template<uint64_t count>

View file

@ -582,4 +582,35 @@ void Spc::LoadSpcFile(SpcFileData* data)
_state.Timer0.SetOutput(data->TimerOutput[0]); _state.Timer0.SetOutput(data->TimerOutput[0]);
_state.Timer1.SetOutput(data->TimerOutput[0]); _state.Timer1.SetOutput(data->TimerOutput[0]);
_state.Timer2.SetOutput(data->TimerOutput[0]); _state.Timer2.SetOutput(data->TimerOutput[0]);
} }
void Spc::SetReg(SpcRegister reg, uint8_t value)
{
switch (reg)
{
case SpcRegister::SpcRegPC:
{
_state.PC = value;
} break;
case SpcRegister::SpcRegA:
{
_state.A = value;
} break;
case SpcRegister::SpcRegX:
{
_state.X = value;
} break;
case SpcRegister::SpcRegY:
{
_state.Y = value;
} break;
case SpcRegister::SpcRegSP:
{
_state.SP = value;
} break;
case SpcRegister::SpcRegPS:
{
_state.PS = value;
} break;
}
}

View file

@ -8,6 +8,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "SpcTypes.h" #include "SpcTypes.h"
#include "CpuTypes.h" #include "CpuTypes.h"
#include "DebugTypes.h"
#include "SpcTimer.h" #include "SpcTimer.h"
#include "../Utilities/ISerializable.h" #include "../Utilities/ISerializable.h"
@ -317,6 +318,8 @@ public:
void Serialize(Serializer &s) override; void Serialize(Serializer &s) override;
void SetReg(SpcRegister reg, uint8_t value);
#ifdef DUMMYSPC #ifdef DUMMYSPC
private: private:
uint32_t _writeCounter = 0; uint32_t _writeCounter = 0;

View file

@ -67,7 +67,15 @@ extern "C"
DllExport void __stdcall ResetProfiler(CpuType cpuType) { GetDebugger()->GetCallstackManager(cpuType)->GetProfiler()->Reset(); } DllExport void __stdcall ResetProfiler(CpuType cpuType) { GetDebugger()->GetCallstackManager(cpuType)->GetProfiler()->Reset(); }
DllExport void __stdcall GetState(DebugState& state) { GetDebugger()->GetState(state, false); } DllExport void __stdcall GetState(DebugState& state) { GetDebugger()->GetState(state, false); }
DllExport void __stdcall SetCpuRegister(CpuRegister reg, uint16_t value) { GetDebugger()->SetCpuRegister(reg, value); }
DllExport void __stdcall SetSpcRegister(SpcRegister reg, uint32_t value) { GetDebugger()->SetSpcRegister(reg, value); }
DllExport void __stdcall SetNecDspRegister(NecDspRegister reg, uint32_t value) { GetDebugger()->SetNecDspRegister(reg, value); }
DllExport void __stdcall SetSa1Register(CpuRegister reg, uint32_t value) { GetDebugger()->SetSa1Register(reg, value); }
DllExport void __stdcall SetGsuRegister(GsuRegister reg, uint32_t value) { GetDebugger()->SetGsuRegister(reg, value); }
DllExport void __stdcall SetCx4Register(Cx4Register reg, uint32_t value) { GetDebugger()->SetCx4Register(reg, value); }
DllExport void __stdcall SetGameboyRegister(GbRegister reg, uint32_t value) { GetDebugger()->SetGameboyRegister(reg, value); }
DllExport const char* __stdcall GetDebuggerLog() DllExport const char* __stdcall GetDebuggerLog()
{ {
_logString = GetDebugger()->GetLog(); _logString = GetDebugger()->GetLog();