mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 05:40:01 -06:00
MMIO: Port the SW CP/PE MMIOs to the new interface.
Migration is now complete.
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "CoreTiming.h"
|
#include "CoreTiming.h"
|
||||||
#include "HW/Memmap.h"
|
#include "HW/Memmap.h"
|
||||||
|
#include "HW/MMIO.h"
|
||||||
#include "HW/ProcessorInterface.h"
|
#include "HW/ProcessorInterface.h"
|
||||||
|
|
||||||
#include "VideoBackend.h"
|
#include "VideoBackend.h"
|
||||||
@ -124,147 +125,77 @@ void RunGpu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Read16(u16& _rReturnValue, const u32 _Address)
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
u32 regAddr = (_Address & 0xFFF) >> 1;
|
// Directly map reads and writes to the cpreg structure.
|
||||||
|
for (size_t i = 0; i < sizeof (cpreg) / sizeof (u16); ++i)
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "(r): 0x%08x : 0x%08x", _Address, ((u16*)&cpreg)[regAddr]);
|
|
||||||
|
|
||||||
if (regAddr < 0x20)
|
|
||||||
_rReturnValue = ((u16*)&cpreg)[regAddr];
|
|
||||||
else
|
|
||||||
_rReturnValue = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Write16(const u16 _Value, const u32 _Address)
|
|
||||||
{
|
|
||||||
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
|
|
||||||
|
|
||||||
switch (_Address & 0xFFF)
|
|
||||||
{
|
{
|
||||||
case STATUS_REGISTER:
|
u16* ptr = ((u16*)&cpreg) + i;
|
||||||
{
|
mmio->Register(base | (i * 2),
|
||||||
ERROR_LOG(COMMANDPROCESSOR,"\t write to STATUS_REGISTER : %04x", _Value);
|
MMIO::DirectRead<u16>(ptr),
|
||||||
}
|
MMIO::DirectWrite<u16>(ptr)
|
||||||
break;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
case CTRL_REGISTER:
|
// Bleh. Apparently SWCommandProcessor does not know about regs 0x40 to
|
||||||
{
|
// 0x64...
|
||||||
cpreg.ctrl.Hex = _Value;
|
for (size_t i = 0x40; i < 0x64; ++i)
|
||||||
|
{
|
||||||
|
mmio->Register(base | i,
|
||||||
|
MMIO::Constant<u16>(0),
|
||||||
|
MMIO::Nop<u16>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value);
|
// The low part of MMIO regs for FIFO addresses needs to be aligned to 32
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | CPULINK %s | BP %s || BPIntEnable %s | OvF %s | UndF %s"
|
// bytes.
|
||||||
, cpreg.ctrl.GPReadEnable ? "ON" : "OFF"
|
u32 fifo_addr_lo_regs[] = {
|
||||||
, cpreg.ctrl.GPLinkEnable ? "ON" : "OFF"
|
FIFO_BASE_LO, FIFO_END_LO, FIFO_WRITE_POINTER_LO,
|
||||||
, cpreg.ctrl.BPEnable ? "ON" : "OFF"
|
FIFO_READ_POINTER_LO, FIFO_BP_LO, FIFO_RW_DISTANCE_LO,
|
||||||
, cpreg.ctrl.BreakPointIntEnable ? "ON" : "OFF"
|
};
|
||||||
, cpreg.ctrl.FifoOverflowIntEnable ? "ON" : "OFF"
|
for (u32 reg : fifo_addr_lo_regs)
|
||||||
, cpreg.ctrl.FifoUnderflowIntEnable ? "ON" : "OFF"
|
{
|
||||||
);
|
mmio->RegisterWrite(base | reg,
|
||||||
}
|
MMIO::DirectWrite<u16>(((u16*)&cpreg) + (reg / 2), 0xFFE0)
|
||||||
break;
|
);
|
||||||
|
}
|
||||||
|
|
||||||
case CLEAR_REGISTER:
|
// The clear register needs to perform some more complicated operations on
|
||||||
{
|
// writes.
|
||||||
UCPClearReg tmpClear(_Value);
|
mmio->RegisterWrite(base | CLEAR_REGISTER,
|
||||||
|
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
||||||
|
UCPClearReg tmpClear(val);
|
||||||
|
|
||||||
if (tmpClear.ClearFifoOverflow)
|
if (tmpClear.ClearFifoOverflow)
|
||||||
cpreg.status.OverflowHiWatermark = 0;
|
cpreg.status.OverflowHiWatermark = 0;
|
||||||
if (tmpClear.ClearFifoUnderflow)
|
if (tmpClear.ClearFifoUnderflow)
|
||||||
cpreg.status.UnderflowLoWatermark = 0;
|
cpreg.status.UnderflowLoWatermark = 0;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value);
|
void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
}
|
{
|
||||||
break;
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
|
Memory::mmio_mapping->Read(_Address, _rReturnValue);
|
||||||
|
}
|
||||||
|
|
||||||
// Fifo Registers
|
void Write16(const u16 _Value, const u32 _Address)
|
||||||
case FIFO_TOKEN_REGISTER:
|
{
|
||||||
cpreg.token = _Value;
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_TOKEN_REGISTER : %04x", _Value);
|
Memory::mmio_mapping->Write(_Address, _Value);
|
||||||
break;
|
|
||||||
|
|
||||||
case FIFO_BASE_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.fifobase, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO. FIFO base is : %08x", cpreg.fifobase);
|
|
||||||
break;
|
|
||||||
case FIFO_BASE_HI:
|
|
||||||
WriteHigh((u32 &)cpreg.fifobase, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_HI. FIFO base is : %08x", cpreg.fifobase);
|
|
||||||
break;
|
|
||||||
case FIFO_END_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.fifoend, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO. FIFO end is : %08x", cpreg.fifoend);
|
|
||||||
break;
|
|
||||||
case FIFO_END_HI:
|
|
||||||
WriteHigh((u32 &)cpreg.fifoend, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_HI. FIFO end is : %08x", cpreg.fifoend);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIFO_WRITE_POINTER_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.writeptr, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_LO. write ptr is : %08x", cpreg.writeptr);
|
|
||||||
break;
|
|
||||||
case FIFO_WRITE_POINTER_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.writeptr, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_HI. write ptr is : %08x", cpreg.writeptr);
|
|
||||||
break;
|
|
||||||
case FIFO_READ_POINTER_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.readptr, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_LO. read ptr is : %08x", cpreg.readptr);
|
|
||||||
break;
|
|
||||||
case FIFO_READ_POINTER_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.readptr, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_HI. read ptr is : %08x", cpreg.readptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIFO_HI_WATERMARK_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.hiwatermark, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_LO. hiwatermark is : %08x", cpreg.hiwatermark);
|
|
||||||
break;
|
|
||||||
case FIFO_HI_WATERMARK_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.hiwatermark, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI. hiwatermark is : %08x", cpreg.hiwatermark);
|
|
||||||
break;
|
|
||||||
case FIFO_LO_WATERMARK_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.lowatermark, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_LO. lowatermark is : %08x", cpreg.lowatermark);
|
|
||||||
break;
|
|
||||||
case FIFO_LO_WATERMARK_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.lowatermark, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_HI. lowatermark is : %08x", cpreg.lowatermark);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIFO_BP_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.breakpt, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_LO. breakpoint is : %08x", cpreg.breakpt);
|
|
||||||
break;
|
|
||||||
case FIFO_BP_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.breakpt, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_HI. breakpoint is : %08x", cpreg.breakpt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIFO_RW_DISTANCE_LO:
|
|
||||||
WriteLow ((u32 &)cpreg.rwdistance, _Value & 0xFFE0);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_LO. rwdistance is : %08x", cpreg.rwdistance);
|
|
||||||
break;
|
|
||||||
case FIFO_RW_DISTANCE_HI:
|
|
||||||
WriteHigh ((u32 &)cpreg.rwdistance, _Value);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_HI. rwdistance is : %08x", cpreg.rwdistance);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunGpu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Read32(u32& _rReturnValue, const u32 _Address)
|
void Read32(u32& _rReturnValue, const u32 _Address)
|
||||||
{
|
{
|
||||||
_rReturnValue = 0;
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
_dbg_assert_msg_(COMMANDPROCESSOR, 0, "Read32 from CommandProcessor at 0x%08x", _Address);
|
Memory::mmio_mapping->Read(_Address, _rReturnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write32(const u32 _Data, const u32 _Address)
|
void Write32(const u32 _Data, const u32 _Address)
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProcessor at 0x%08x", _Address);
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
|
Memory::mmio_mapping->Write(_Address, _Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STACKALIGN GatherPipeBursted()
|
void STACKALIGN GatherPipeBursted()
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
namespace MMIO { class Mapping; }
|
||||||
|
|
||||||
extern volatile bool g_bSkipCurrentFrame;
|
extern volatile bool g_bSkipCurrentFrame;
|
||||||
extern u8* g_pVideoData;
|
extern u8* g_pVideoData;
|
||||||
@ -123,6 +124,8 @@ namespace SWCommandProcessor
|
|||||||
void Shutdown();
|
void Shutdown();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
|
|
||||||
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
bool RunBuffer();
|
bool RunBuffer();
|
||||||
void RunGpu();
|
void RunGpu();
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "ChunkFile.h"
|
#include "ChunkFile.h"
|
||||||
#include "CoreTiming.h"
|
#include "CoreTiming.h"
|
||||||
#include "ConfigManager.h"
|
#include "ConfigManager.h"
|
||||||
|
#include "HW/MMIO.h"
|
||||||
#include "HW/ProcessorInterface.h"
|
#include "HW/ProcessorInterface.h"
|
||||||
|
|
||||||
#include "SWPixelEngine.h"
|
#include "SWPixelEngine.h"
|
||||||
@ -60,30 +61,22 @@ void Init()
|
|||||||
et_SetFinishOnMainThread = CoreTiming::RegisterEvent("SetFinish", SetFinish_OnMainThread);
|
et_SetFinishOnMainThread = CoreTiming::RegisterEvent("SetFinish", SetFinish_OnMainThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(PIXELENGINE, "(r16): 0x%08x", _iAddress);
|
// Directly map reads and writes to the pereg structure.
|
||||||
|
for (size_t i = 0; i < sizeof (pereg) / sizeof (u16); ++i)
|
||||||
u16 address = _iAddress & 0xFFF;
|
|
||||||
|
|
||||||
if (address <= 0x2e)
|
|
||||||
_uReturnValue = ((u16*)&pereg)[address >> 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Write32(const u32 _iValue, const u32 _iAddress)
|
|
||||||
{
|
|
||||||
WARN_LOG(PIXELENGINE, "(w32): 0x%08x @ 0x%08x",_iValue,_iAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Write16(const u16 _iValue, const u32 _iAddress)
|
|
||||||
{
|
|
||||||
u16 address = _iAddress & 0xFFF;
|
|
||||||
|
|
||||||
switch (address)
|
|
||||||
{
|
{
|
||||||
case PE_CTRL_REGISTER:
|
u16* ptr = (u16*)&pereg + i;
|
||||||
{
|
mmio->Register(base | (i * 2),
|
||||||
UPECtrlReg tmpCtrl(_iValue);
|
MMIO::DirectRead<u16>(ptr),
|
||||||
|
MMIO::DirectWrite<u16>(ptr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The control register has some more complex logic to perform on writes.
|
||||||
|
mmio->RegisterWrite(base | PE_CTRL_REGISTER,
|
||||||
|
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
||||||
|
UPECtrlReg tmpCtrl(val);
|
||||||
|
|
||||||
if (tmpCtrl.PEToken) g_bSignalTokenInterrupt = false;
|
if (tmpCtrl.PEToken) g_bSignalTokenInterrupt = false;
|
||||||
if (tmpCtrl.PEFinish) g_bSignalFinishInterrupt = false;
|
if (tmpCtrl.PEFinish) g_bSignalFinishInterrupt = false;
|
||||||
@ -93,15 +86,27 @@ void Write16(const u16 _iValue, const u32 _iAddress)
|
|||||||
pereg.ctrl.PEToken = 0; // this flag is write only
|
pereg.ctrl.PEToken = 0; // this flag is write only
|
||||||
pereg.ctrl.PEFinish = 0; // this flag is write only
|
pereg.ctrl.PEFinish = 0; // this flag is write only
|
||||||
|
|
||||||
DEBUG_LOG(PIXELENGINE, "(w16): PE_CTRL_REGISTER: 0x%04x", _iValue);
|
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
}
|
})
|
||||||
break;
|
);
|
||||||
default:
|
}
|
||||||
if (address <= 0x2e)
|
|
||||||
((u16*)&pereg)[address >> 1] = _iValue;
|
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
break;
|
{
|
||||||
}
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
|
Memory::mmio_mapping->Read(_iAddress, _uReturnValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
|
{
|
||||||
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
|
Memory::mmio_mapping->Write(_iAddress, _iValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write16(const u16 _iValue, const u32 _iAddress)
|
||||||
|
{
|
||||||
|
// HACK: Remove this function when the new MMIO interface is used.
|
||||||
|
Memory::mmio_mapping->Write(_iAddress, _iValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AllowIdleSkipping()
|
bool AllowIdleSkipping()
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
namespace MMIO { class Mapping; }
|
||||||
|
|
||||||
namespace SWPixelEngine
|
namespace SWPixelEngine
|
||||||
{
|
{
|
||||||
@ -200,6 +201,8 @@ namespace SWPixelEngine
|
|||||||
void Init();
|
void Init();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
|
|
||||||
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
void Read16(u16& _uReturnValue, const u32 _iAddress);
|
void Read16(u16& _uReturnValue, const u32 _iAddress);
|
||||||
|
|
||||||
|
@ -362,12 +362,12 @@ void VideoSoftware::Video_AbortFrame(void)
|
|||||||
|
|
||||||
void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
|
void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
// TODO
|
SWCommandProcessor::RegisterMMIO(mmio, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSoftware::RegisterPEMMIO(MMIO::Mapping* mmio, u32 base)
|
void VideoSoftware::RegisterPEMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
// TODO
|
SWPixelEngine::RegisterMMIO(mmio, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
readFn16 VideoSoftware::Video_CPRead16()
|
readFn16 VideoSoftware::Video_CPRead16()
|
||||||
|
Reference in New Issue
Block a user