MMIO: Port the VideoCommon CP MMIOs to the new interface (and provide framework for other video related mappings).

This commit is contained in:
Pierre Bourdon 2014-02-02 14:16:43 +01:00
parent bdedaa24a9
commit 4129b30494
9 changed files with 222 additions and 289 deletions

View File

@ -310,6 +310,7 @@ void InitHWMemFuncsWii()
void InitMMIO(MMIO::Mapping* mmio)
{
g_video_backend->RegisterCPMMIO(mmio, 0xCC000000);
VideoInterface::RegisterMMIO(mmio, 0xCC002000);
ProcessorInterface::RegisterMMIO(mmio, 0xCC003000);
MemoryInterface::RegisterMMIO(mmio, 0xCC004000);

View File

@ -360,6 +360,16 @@ void VideoSoftware::Video_AbortFrame(void)
{
}
void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
{
// TODO
}
void VideoSoftware::RegisterPEMMIO(MMIO::Mapping* mmio, u32 base)
{
// TODO
}
readFn16 VideoSoftware::Video_CPRead16()
{
return SWCommandProcessor::Read16;

View File

@ -2,6 +2,8 @@
#include "VideoBackendBase.h"
namespace MMIO { class Mapping; }
namespace SW
{
@ -44,6 +46,9 @@ class VideoSoftware : public VideoBackend
bool Video_IsPossibleWaitingSetDrawDone() override;
void Video_AbortFrame() override;
void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;
void RegisterPEMMIO(MMIO::Mapping* mmio, u32 base) override;
readFn16 Video_CPRead16() override;
writeFn16 Video_CPWrite16() override;
readFn16 Video_PERead16() override;

View File

@ -19,6 +19,7 @@
#include "HW/Memmap.h"
#include "HW/SystemTimers.h"
#include "Core.h"
#include "HW/MMIO.h"
namespace CommandProcessor
{
@ -33,10 +34,10 @@ UCPStatusReg m_CPStatusReg;
UCPCtrlReg m_CPCtrlReg;
UCPClearReg m_CPClearReg;
int m_bboxleft;
int m_bboxtop;
int m_bboxright;
int m_bboxbottom;
u16 m_bboxleft;
u16 m_bboxtop;
u16 m_bboxright;
u16 m_bboxbottom;
u16 m_tokenReg;
static bool bProcessFifoToLoWatermark = false;
@ -131,307 +132,192 @@ void Init()
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
}
void Read16(u16& _rReturnValue, const u32 _Address)
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{
INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address);
switch (_Address & 0xFFF)
struct {
u32 addr;
u16* ptr;
bool readonly;
bool writes_align_to_32_bytes;
} directly_mapped_vars[] = {
{ FIFO_TOKEN_REGISTER, &m_tokenReg },
// Bounding box registers are read only.
{ FIFO_BOUNDING_BOX_LEFT, &m_bboxleft, true },
{ FIFO_BOUNDING_BOX_RIGHT, &m_bboxright, true },
{ FIFO_BOUNDING_BOX_TOP, &m_bboxtop, true },
{ FIFO_BOUNDING_BOX_BOTTOM, &m_bboxbottom, true },
// Some FIFO addresses need to be aligned on 32 bytes on write - only
// the high part can be written directly without a mask.
{ FIFO_BASE_LO, MMIO::Utils::LowPart(&fifo.CPBase), false, true },
{ FIFO_BASE_HI, MMIO::Utils::HighPart(&fifo.CPBase) },
{ FIFO_END_LO, MMIO::Utils::LowPart(&fifo.CPEnd), false, true },
{ FIFO_END_HI, MMIO::Utils::HighPart(&fifo.CPEnd) },
{ FIFO_HI_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPHiWatermark) },
{ FIFO_HI_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPHiWatermark) },
{ FIFO_LO_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPLoWatermark) },
{ FIFO_LO_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPLoWatermark) },
// FIFO_RW_DISTANCE has some complex read code different for
// single/dual core.
{ FIFO_WRITE_POINTER_LO, MMIO::Utils::LowPart(&fifo.CPWritePointer), false, true },
{ FIFO_WRITE_POINTER_HI, MMIO::Utils::HighPart(&fifo.CPWritePointer) },
// FIFO_READ_POINTER has different code for single/dual core.
{ FIFO_BP_LO, MMIO::Utils::LowPart(&fifo.CPBreakpoint), false, true },
{ FIFO_BP_HI, MMIO::Utils::HighPart(&fifo.CPBreakpoint) },
};
for (auto& mapped_var : directly_mapped_vars)
{
case STATUS_REGISTER:
SetCpStatusRegister();
_rReturnValue = m_CPStatusReg.Hex;
return;
case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return;
case CLEAR_REGISTER:
_rReturnValue = m_CPClearReg.Hex;
PanicAlert("CommandProcessor:: CPU reads from CLEAR_REGISTER!");
ERROR_LOG(COMMANDPROCESSOR, "(r) clear: 0x%04x", _rReturnValue);
return;
case FIFO_TOKEN_REGISTER: _rReturnValue = m_tokenReg; return;
case FIFO_BOUNDING_BOX_LEFT: _rReturnValue = m_bboxleft; return;
case FIFO_BOUNDING_BOX_RIGHT: _rReturnValue = m_bboxright; return;
case FIFO_BOUNDING_BOX_TOP: _rReturnValue = m_bboxtop; return;
case FIFO_BOUNDING_BOX_BOTTOM: _rReturnValue = m_bboxbottom; return;
case FIFO_BASE_LO: _rReturnValue = ReadLow (fifo.CPBase); return;
case FIFO_BASE_HI: _rReturnValue = ReadHigh(fifo.CPBase); return;
case FIFO_END_LO: _rReturnValue = ReadLow (fifo.CPEnd); return;
case FIFO_END_HI: _rReturnValue = ReadHigh(fifo.CPEnd); return;
case FIFO_HI_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPHiWatermark); return;
case FIFO_HI_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPHiWatermark); return;
case FIFO_LO_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPLoWatermark); return;
case FIFO_LO_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPLoWatermark); return;
case FIFO_RW_DISTANCE_LO:
if (IsOnThread())
{
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
}
else
{
_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
}
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
return;
case FIFO_RW_DISTANCE_HI:
if (IsOnThread())
{
if(fifo.CPWritePointer >= fifo.SafeCPReadPointer)
_rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
_rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
}
else
{
_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
}
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
return;
case FIFO_WRITE_POINTER_LO:
_rReturnValue = ReadLow (fifo.CPWritePointer);
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_WRITE_POINTER_LO : %04x", _rReturnValue);
return;
case FIFO_WRITE_POINTER_HI:
_rReturnValue = ReadHigh(fifo.CPWritePointer);
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_WRITE_POINTER_HI : %04x", _rReturnValue);
return;
case FIFO_READ_POINTER_LO:
if (IsOnThread())
_rReturnValue = ReadLow (fifo.SafeCPReadPointer);
else
_rReturnValue = ReadLow (fifo.CPReadPointer);
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_READ_POINTER_LO : %04x", _rReturnValue);
return;
case FIFO_READ_POINTER_HI:
if (IsOnThread())
_rReturnValue = ReadHigh (fifo.SafeCPReadPointer);
else
_rReturnValue = ReadHigh (fifo.CPReadPointer);
DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_READ_POINTER_HI : %04x", _rReturnValue);
return;
case FIFO_BP_LO: _rReturnValue = ReadLow (fifo.CPBreakpoint); return;
case FIFO_BP_HI: _rReturnValue = ReadHigh(fifo.CPBreakpoint); return;
case XF_RASBUSY_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_L: %04x", _rReturnValue);
return;
case XF_RASBUSY_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_H: %04x", _rReturnValue);
return;
case XF_CLKS_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_L: %04x", _rReturnValue);
return;
case XF_CLKS_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_H: %04x", _rReturnValue);
return;
case XF_WAIT_IN_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_L: %04x", _rReturnValue);
return;
case XF_WAIT_IN_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_H: %04x", _rReturnValue);
return;
case XF_WAIT_OUT_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_L: %04x", _rReturnValue);
return;
case XF_WAIT_OUT_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_H: %04x", _rReturnValue);
return;
case VCACHE_METRIC_CHECK_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_L: %04x", _rReturnValue);
return;
case VCACHE_METRIC_CHECK_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_H: %04x", _rReturnValue);
return;
case VCACHE_METRIC_MISS_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_L: %04x", _rReturnValue);
return;
case VCACHE_METRIC_MISS_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_H: %04x", _rReturnValue);
return;
case VCACHE_METRIC_STALL_L:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_L: %04x", _rReturnValue);
return;
case VCACHE_METRIC_STALL_H:
_rReturnValue = 0; // TODO: Figure out the true value
DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_H: %04x", _rReturnValue);
return;
case CLKS_PER_VTX_OUT:
_rReturnValue = 4; //Number of clocks per vertex.. TODO: Calculate properly
DEBUG_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue);
return;
default:
_rReturnValue = 0;
WARN_LOG(COMMANDPROCESSOR, "(r16) unknown CP reg @ %08x", _Address);
return;
u16 wmask = mapped_var.writes_align_to_32_bytes ? 0xFFE0 : 0xFFFF;
mmio->Register(base | mapped_var.addr,
MMIO::DirectRead<u16>(mapped_var.ptr),
mapped_var.readonly
? MMIO::InvalidWrite<u16>()
: MMIO::DirectWrite<u16>(mapped_var.ptr, wmask)
);
}
return;
// Timing and metrics MMIOs are stubbed with fixed values.
struct {
u32 addr;
u16 value;
} metrics_mmios[] = {
{ XF_RASBUSY_L, 0 },
{ XF_RASBUSY_H, 0 },
{ XF_CLKS_L, 0 },
{ XF_CLKS_H, 0 },
{ XF_WAIT_IN_L, 0 },
{ XF_WAIT_IN_H, 0 },
{ XF_WAIT_OUT_L, 0 },
{ XF_WAIT_OUT_H, 0 },
{ VCACHE_METRIC_CHECK_L, 0 },
{ VCACHE_METRIC_CHECK_H, 0 },
{ VCACHE_METRIC_MISS_L, 0 },
{ VCACHE_METRIC_MISS_H, 0 },
{ VCACHE_METRIC_STALL_L, 0 },
{ VCACHE_METRIC_STALL_H, 0 },
{ CLKS_PER_VTX_OUT, 4 },
};
for (auto& metrics_mmio : metrics_mmios)
{
mmio->Register(base | metrics_mmio.addr,
MMIO::Constant<u16>(metrics_mmio.value),
MMIO::InvalidWrite<u16>()
);
}
mmio->Register(base | STATUS_REGISTER,
MMIO::ComplexRead<u16>([](u32) {
SetCpStatusRegister();
return m_CPStatusReg.Hex;
}),
MMIO::InvalidWrite<u16>()
);
mmio->Register(base | CTRL_REGISTER,
MMIO::DirectRead<u16>(&m_CPCtrlReg.Hex),
MMIO::ComplexWrite<u16>([](u32, u16 val) {
UCPCtrlReg tmp(val);
m_CPCtrlReg.Hex = tmp.Hex;
SetCpControlRegister();
if (!IsOnThread())
RunGpu();
})
);
mmio->Register(base | CLEAR_REGISTER,
MMIO::DirectRead<u16>(&m_CPClearReg.Hex),
MMIO::ComplexWrite<u16>([](u32, u16 val) {
UCPClearReg tmp(val);
m_CPClearReg.Hex = tmp.Hex;
SetCpClearRegister();
if (!IsOnThread())
RunGpu();
})
);
mmio->Register(base | PERF_SELECT,
MMIO::InvalidRead<u16>(),
MMIO::Nop<u16>()
);
// Some MMIOs have different handlers for single core vs. dual core mode.
mmio->Register(base | FIFO_RW_DISTANCE_LO,
IsOnThread()
? MMIO::ComplexRead<u16>([](u32) {
if (fifo.CPWritePointer >= fifo.SafeCPReadPointer)
return ReadLow(fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
return ReadLow(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
})
: MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)),
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance), 0xFFE0)
);
mmio->Register(base | FIFO_RW_DISTANCE_HI,
IsOnThread()
? MMIO::ComplexRead<u16>([](u32) {
if (fifo.CPWritePointer >= fifo.SafeCPReadPointer)
return ReadHigh(fifo.CPWritePointer - fifo.SafeCPReadPointer);
else
return ReadHigh(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32);
})
: MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)),
MMIO::ComplexWrite<u16>([](u32, u16 val) {
WriteHigh(fifo.CPReadWriteDistance, val);
if (fifo.CPReadWriteDistance == 0)
{
GPFifo::ResetGatherPipe();
ResetVideoBuffer();
}
else
{
ResetVideoBuffer();
}
if (!IsOnThread())
RunGpu();
})
);
mmio->Register(base | FIFO_READ_POINTER_LO,
IsOnThread()
? MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.SafeCPReadPointer))
: MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer)),
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer), 0xFFE0)
);
mmio->Register(base | FIFO_READ_POINTER_HI,
IsOnThread()
? MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.SafeCPReadPointer))
: MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer)),
IsOnThread()
? MMIO::ComplexWrite<u16>([](u32, u16 val) {
WriteHigh(fifo.CPReadPointer, val);
fifo.SafeCPReadPointer = fifo.CPReadPointer;
})
: MMIO::DirectWrite<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer))
);
}
void Read16(u16& _rReturnValue, const u32 _Address)
{
// HACK: Remove this function when the new MMIO interface is used.
Memory::mmio_mapping->Read(_Address, _rReturnValue);
}
void Write16(const u16 _Value, const u32 _Address)
{
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
switch (_Address & 0xFFF)
{
case STATUS_REGISTER:
{
// This should be Read-Only
ERROR_LOG(COMMANDPROCESSOR,"\t write to STATUS_REGISTER : %04x", _Value);
PanicAlert("CommandProcessor:: CPU writes to STATUS_REGISTER!");
}
break;
case CTRL_REGISTER:
{
UCPCtrlReg tmpCtrl(_Value);
m_CPCtrlReg.Hex = tmpCtrl.Hex;
INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value);
SetCpControlRegister();
}
break;
case CLEAR_REGISTER:
{
UCPClearReg tmpCtrl(_Value);
m_CPClearReg.Hex = tmpCtrl.Hex;
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to CLEAR_REGISTER : %04x", _Value);
SetCpClearRegister();
}
break;
case PERF_SELECT:
// Seems to select which set of perf registers should be exposed.
DEBUG_LOG(COMMANDPROCESSOR, "Write to PERF_SELECT: %04x", _Value);
break;
// Fifo Registers
case FIFO_TOKEN_REGISTER:
m_tokenReg = _Value;
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_TOKEN_REGISTER : %04x", _Value);
break;
case FIFO_BASE_LO:
WriteLow ((u32 &)fifo.CPBase, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_BASE_LO : %04x", _Value);
break;
case FIFO_BASE_HI:
WriteHigh((u32 &)fifo.CPBase, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_BASE_HI : %04x", _Value);
break;
case FIFO_END_LO:
WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_LO : %04x", _Value);
break;
case FIFO_END_HI:
WriteHigh((u32 &)fifo.CPEnd, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_HI : %04x", _Value);
break;
case FIFO_WRITE_POINTER_LO:
WriteLow ((u32 &)fifo.CPWritePointer, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_LO : %04x", _Value);
break;
case FIFO_WRITE_POINTER_HI:
WriteHigh((u32 &)fifo.CPWritePointer, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_HI : %04x", _Value);
break;
case FIFO_READ_POINTER_LO:
WriteLow ((u32 &)fifo.CPReadPointer, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_LO : %04x", _Value);
break;
case FIFO_READ_POINTER_HI:
WriteHigh((u32 &)fifo.CPReadPointer, _Value);
fifo.SafeCPReadPointer = fifo.CPReadPointer;
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_HI : %04x", _Value);
break;
case FIFO_HI_WATERMARK_LO:
WriteLow ((u32 &)fifo.CPHiWatermark, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_LO : %04x", _Value);
break;
case FIFO_HI_WATERMARK_HI:
WriteHigh((u32 &)fifo.CPHiWatermark, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_HI : %04x", _Value);
break;
case FIFO_LO_WATERMARK_LO:
WriteLow ((u32 &)fifo.CPLoWatermark, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_LO : %04x", _Value);
break;
case FIFO_LO_WATERMARK_HI:
WriteHigh((u32 &)fifo.CPLoWatermark, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_HI : %04x", _Value);
break;
case FIFO_BP_LO:
WriteLow ((u32 &)fifo.CPBreakpoint, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"Write to FIFO_BP_LO : %04x", _Value);
break;
case FIFO_BP_HI:
WriteHigh((u32 &)fifo.CPBreakpoint, _Value);
DEBUG_LOG(COMMANDPROCESSOR,"Write to FIFO_BP_HI : %04x", _Value);
break;
case FIFO_RW_DISTANCE_HI:
WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value);
if (fifo.CPReadWriteDistance == 0)
{
GPFifo::ResetGatherPipe();
ResetVideoBuffer();
}
else
{
ResetVideoBuffer();
}
DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_HI : %04x", _Value);
break;
case FIFO_RW_DISTANCE_LO:
WriteLow((u32 &)fifo.CPReadWriteDistance, _Value & 0xFFE0);
DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_LO : %04x", _Value);
break;
default:
WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address);
}
if (!IsOnThread())
RunGpu();
// HACK: Remove this function when the new MMIO interface is used.
Memory::mmio_mapping->Write(_Address, _Value);
}
void Read32(u32& _rReturnValue, const u32 _Address)
{
_rReturnValue = 0;
_dbg_assert_msg_(COMMANDPROCESSOR, 0, "Read32 from CommandProccessor at 0x%08x", _Address);
// HACK: Remove this function when the new MMIO interface is used.
Memory::mmio_mapping->Read(_Address, _rReturnValue);
}
void Write32(const u32 _Data, const u32 _Address)
{
_dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProccessor at 0x%08x", _Address);
// HACK: Remove this function when the new MMIO interface is used.
Memory::mmio_mapping->Write(_Address, _Data);
}
void STACKALIGN GatherPipeBursted()

View File

@ -8,6 +8,7 @@
#include "VideoBackendBase.h"
class PointerWrap;
namespace MMIO { class Mapping; }
extern bool MT;
@ -134,6 +135,8 @@ void Init();
void Shutdown();
void DoState(PointerWrap &p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
// Read
void Read16(u16& _rReturnValue, const u32 _Address);
void Write16(const u16 _Data, const u32 _Address);

View File

@ -311,6 +311,16 @@ void VideoBackendHardware::Video_AbortFrame()
CommandProcessor::AbortFrame();
}
void VideoBackendHardware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
{
CommandProcessor::RegisterMMIO(mmio, base);
}
void VideoBackendHardware::RegisterPEMMIO(MMIO::Mapping* mmio, u32 base)
{
PixelEngine::RegisterMMIO(mmio, base);
}
readFn16 VideoBackendHardware::Video_CPRead16()
{
return CommandProcessor::Read16;

View File

@ -133,6 +133,11 @@ void DoState(PointerWrap &p)
p.Do(bbox_active);
}
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
{
// TODO
}
void UpdateInterrupts();
void UpdateTokenInterrupt(bool active);
void UpdateFinishInterrupt(bool active);

View File

@ -6,6 +6,7 @@
#include "CommonTypes.h"
class PointerWrap;
namespace MMIO { class Mapping; }
// internal hardware addresses
enum
@ -55,6 +56,8 @@ union UPEAlphaReadReg
void Init();
void DoState(PointerWrap &p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
// Read
void Read16(u16& _uReturnValue, const u32 _iAddress);

View File

@ -10,6 +10,8 @@
#include "ChunkFile.h"
#include "../VideoCommon/PerfQueryBase.h"
namespace MMIO { class Mapping; }
typedef void (*writeFn16)(const u16,const u32);
typedef void (*writeFn32)(const u32,const u32);
typedef void (*readFn16)(u16&, const u32);
@ -110,6 +112,11 @@ public:
virtual bool Video_IsHiWatermarkActive() = 0;
virtual void Video_AbortFrame() = 0;
// Registers MMIO handlers for the CommandProcessor registers.
virtual void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) = 0;
virtual void RegisterPEMMIO(MMIO::Mapping* mmio, u32 base) = 0;
// HACK: Remove these functions when the new MMIO interface is used.
virtual readFn16 Video_CPRead16() = 0;
virtual writeFn16 Video_CPWrite16() = 0;
virtual readFn16 Video_PERead16() = 0;
@ -162,6 +169,9 @@ class VideoBackendHardware : public VideoBackend
bool Video_IsHiWatermarkActive();
void Video_AbortFrame();
void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;
void RegisterPEMMIO(MMIO::Mapping* mmio, u32 base) override;
readFn16 Video_CPRead16();
writeFn16 Video_CPWrite16();
readFn16 Video_PERead16();