mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 21:57:57 +03:00
Save and load some basic IPU state.
This commit is contained in:
parent
85ff0350da
commit
f65f6f240b
5 changed files with 138 additions and 0 deletions
|
@ -501,6 +501,7 @@ set(COMMON_SRC_FILES
|
||||||
states/MemoryStateFile.h
|
states/MemoryStateFile.h
|
||||||
states/RegisterState.cpp
|
states/RegisterState.cpp
|
||||||
states/RegisterState.h
|
states/RegisterState.h
|
||||||
|
states/RegisterStateUtils.h
|
||||||
states/RegisterStateCollectionFile.cpp
|
states/RegisterStateCollectionFile.cpp
|
||||||
states/RegisterStateCollectionFile.h
|
states/RegisterStateCollectionFile.h
|
||||||
states/RegisterStateFile.cpp
|
states/RegisterStateFile.cpp
|
||||||
|
|
|
@ -379,6 +379,7 @@ void CSubSystem::SaveState(Framework::CZipArchiveWriter& archive)
|
||||||
m_vpu1->SaveState(archive);
|
m_vpu1->SaveState(archive);
|
||||||
m_timer.SaveState(archive);
|
m_timer.SaveState(archive);
|
||||||
m_gif.SaveState(archive);
|
m_gif.SaveState(archive);
|
||||||
|
m_ipu.SaveState(archive);
|
||||||
m_os->GetLibMc2().SaveState(archive);
|
m_os->GetLibMc2().SaveState(archive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +406,7 @@ void CSubSystem::LoadState(Framework::CZipArchiveReader& archive)
|
||||||
m_vpu1->LoadState(archive);
|
m_vpu1->LoadState(archive);
|
||||||
m_timer.LoadState(archive);
|
m_timer.LoadState(archive);
|
||||||
m_gif.LoadState(archive);
|
m_gif.LoadState(archive);
|
||||||
|
m_ipu.LoadState(archive);
|
||||||
m_os->GetLibMc2().LoadState(archive);
|
m_os->GetLibMc2().LoadState(archive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,38 @@
|
||||||
#include "DMAC.h"
|
#include "DMAC.h"
|
||||||
#include "INTC.h"
|
#include "INTC.h"
|
||||||
#include "Ps2Const.h"
|
#include "Ps2Const.h"
|
||||||
|
#include "../states/RegisterStateFile.h"
|
||||||
|
#include "../states/RegisterStateUtils.h"
|
||||||
|
#include "../states/MemoryStateFile.h"
|
||||||
|
|
||||||
#define LOG_NAME ("ee_ipu")
|
#define LOG_NAME ("ee_ipu")
|
||||||
|
|
||||||
//#define _DECODE_LOGGING
|
//#define _DECODE_LOGGING
|
||||||
#define DECODE_LOG_NAME ("ipu_decode")
|
#define DECODE_LOG_NAME ("ipu_decode")
|
||||||
|
|
||||||
|
#define STATE_REGS_XML ("ipu/regs.xml")
|
||||||
|
#define STATE_INFIFO_REGS_XML ("ipu/infifo.xml")
|
||||||
|
#define STATE_OUTFIFO ("ipu/outfifo")
|
||||||
|
#define STATE_INTRAIQ ("ipu/intraiq")
|
||||||
|
#define STATE_NONINTRAIQ ("ipu/nonintraiq")
|
||||||
|
#define STATE_VQCLUT ("ipu/vqclut")
|
||||||
|
|
||||||
|
#define STATE_REGS_CTRL ("CTRL")
|
||||||
|
#define STATE_REGS_CMD0 ("CMD0")
|
||||||
|
#define STATE_REGS_CMD1 ("CMD1")
|
||||||
|
#define STATE_REGS_TH0 ("TH0")
|
||||||
|
#define STATE_REGS_TH1 ("TH1")
|
||||||
|
#define STATE_REGS_CURRENTCMDID ("currentCmdId")
|
||||||
|
#define STATE_REGS_LASTCMDID ("lastCmdId")
|
||||||
|
#define STATE_REGS_ISBUSY ("isBusy")
|
||||||
|
#define STATE_REGS_DCPRED0 ("dcPredictor0")
|
||||||
|
#define STATE_REGS_DCPRED1 ("dcPredictor1")
|
||||||
|
#define STATE_REGS_DCPRED2 ("dcPredictor2")
|
||||||
|
|
||||||
|
#define STATE_INFIFO_REGS_SIZE ("size")
|
||||||
|
#define STATE_INFIFO_REGS_BITPOSITION ("bitPosition")
|
||||||
|
#define STATE_INFIFO_REGS_BUFFER_FORMAT ("Buffer%d")
|
||||||
|
|
||||||
using namespace IPU;
|
using namespace IPU;
|
||||||
using namespace MPEG2;
|
using namespace MPEG2;
|
||||||
|
|
||||||
|
@ -268,6 +294,59 @@ void CIPU::SetRegister(uint32 nAddress, uint32 nValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIPU::SaveState(Framework::CZipArchiveWriter& archive)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto registerFile = std::make_unique<CRegisterStateFile>(STATE_REGS_XML);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_CTRL, m_IPU_CTRL);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_CMD0, m_IPU_CMD[0]);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_CMD1, m_IPU_CMD[1]);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_TH0, m_nTH0);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_TH1, m_nTH1);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_CURRENTCMDID, m_currentCmdId);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_LASTCMDID, m_lastCmdId);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_ISBUSY, m_isBusy ? 1 : 0);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_DCPRED0, m_nDcPredictor[0]);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_DCPRED1, m_nDcPredictor[1]);
|
||||||
|
registerFile->SetRegister32(STATE_REGS_DCPRED2, m_nDcPredictor[2]);
|
||||||
|
archive.InsertFile(std::move(registerFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_IN_FIFO.SaveState(STATE_INFIFO_REGS_XML, archive);
|
||||||
|
|
||||||
|
archive.InsertFile(std::make_unique<CMemoryStateFile>(STATE_INTRAIQ, m_nIntraIQ, sizeof(m_nIntraIQ)));
|
||||||
|
archive.InsertFile(std::make_unique<CMemoryStateFile>(STATE_NONINTRAIQ, m_nNonIntraIQ, sizeof(m_nNonIntraIQ)));
|
||||||
|
archive.InsertFile(std::make_unique<CMemoryStateFile>(STATE_VQCLUT, m_nVQCLUT, sizeof(m_nVQCLUT)));
|
||||||
|
|
||||||
|
assert(m_currentCmdId == IPU_INVALID_CMDID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIPU::LoadState(Framework::CZipArchiveReader& archive)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto registerFile = CRegisterStateFile(*archive.BeginReadFile(STATE_REGS_XML));
|
||||||
|
m_IPU_CTRL = registerFile.GetRegister32(STATE_REGS_CTRL);
|
||||||
|
m_IPU_CMD[0] = registerFile.GetRegister32(STATE_REGS_CMD0);
|
||||||
|
m_IPU_CMD[1] = registerFile.GetRegister32(STATE_REGS_CMD1);
|
||||||
|
m_nTH0 = registerFile.GetRegister32(STATE_REGS_TH0);
|
||||||
|
m_nTH1 = registerFile.GetRegister32(STATE_REGS_TH1);
|
||||||
|
m_currentCmdId = registerFile.GetRegister32(STATE_REGS_CURRENTCMDID);
|
||||||
|
m_lastCmdId = registerFile.GetRegister32(STATE_REGS_LASTCMDID);
|
||||||
|
m_isBusy = registerFile.GetRegister32(STATE_REGS_ISBUSY) != 0;
|
||||||
|
m_nDcPredictor[0] = registerFile.GetRegister32(STATE_REGS_DCPRED0);
|
||||||
|
m_nDcPredictor[1] = registerFile.GetRegister32(STATE_REGS_DCPRED1);
|
||||||
|
m_nDcPredictor[2] = registerFile.GetRegister32(STATE_REGS_DCPRED2);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_IN_FIFO.LoadState(STATE_INFIFO_REGS_XML, archive);
|
||||||
|
|
||||||
|
archive.BeginReadFile(STATE_INTRAIQ)->Read(m_nIntraIQ, sizeof(m_nIntraIQ));
|
||||||
|
archive.BeginReadFile(STATE_NONINTRAIQ)->Read(m_nNonIntraIQ, sizeof(m_nNonIntraIQ));
|
||||||
|
archive.BeginReadFile(STATE_VQCLUT)->Read(m_nVQCLUT, sizeof(m_nVQCLUT));
|
||||||
|
|
||||||
|
assert(m_currentCmdId == IPU_INVALID_CMDID);
|
||||||
|
}
|
||||||
|
|
||||||
void CIPU::CountTicks(uint32 ticks)
|
void CIPU::CountTicks(uint32 ticks)
|
||||||
{
|
{
|
||||||
if(m_currentCmdId != IPU_INVALID_CMDID)
|
if(m_currentCmdId != IPU_INVALID_CMDID)
|
||||||
|
@ -897,6 +976,23 @@ void CIPU::CINFIFO::Reset()
|
||||||
m_lookupBitsDirty = false;
|
m_lookupBitsDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIPU::CINFIFO::SaveState(const char* regsFileName, Framework::CZipArchiveWriter& archive)
|
||||||
|
{
|
||||||
|
auto registerFile = std::make_unique<CRegisterStateFile>(regsFileName);
|
||||||
|
registerFile->SetRegister32(STATE_INFIFO_REGS_SIZE, m_size);
|
||||||
|
registerFile->SetRegister32(STATE_INFIFO_REGS_BITPOSITION, m_bitPosition);
|
||||||
|
RegisterStateUtils::WriteArray(*registerFile.get(), m_buffer, STATE_INFIFO_REGS_BUFFER_FORMAT);
|
||||||
|
archive.InsertFile(std::move(registerFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIPU::CINFIFO::LoadState(const char* regsFileName, Framework::CZipArchiveReader& archive)
|
||||||
|
{
|
||||||
|
auto registerFile = CRegisterStateFile(*archive.BeginReadFile(regsFileName));
|
||||||
|
m_size = registerFile.GetRegister32(STATE_INFIFO_REGS_SIZE);
|
||||||
|
m_bitPosition = registerFile.GetRegister32(STATE_INFIFO_REGS_BITPOSITION);
|
||||||
|
RegisterStateUtils::ReadArray(registerFile, m_buffer, STATE_INFIFO_REGS_BUFFER_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
void CIPU::CINFIFO::SyncLookupBits()
|
void CIPU::CINFIFO::SyncLookupBits()
|
||||||
{
|
{
|
||||||
unsigned int lookupPosition = (m_bitPosition & ~0x1F) / 8;
|
unsigned int lookupPosition = (m_bitPosition & ~0x1F) / 8;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "mpeg2/DctCoefficientTable.h"
|
#include "mpeg2/DctCoefficientTable.h"
|
||||||
#include "../MailBox.h"
|
#include "../MailBox.h"
|
||||||
#include "Convertible.h"
|
#include "Convertible.h"
|
||||||
|
#include "zip/ZipArchiveWriter.h"
|
||||||
|
#include "zip/ZipArchiveReader.h"
|
||||||
|
|
||||||
class CINTC;
|
class CINTC;
|
||||||
|
|
||||||
|
@ -33,6 +35,10 @@ public:
|
||||||
void Reset();
|
void Reset();
|
||||||
uint32 GetRegister(uint32);
|
uint32 GetRegister(uint32);
|
||||||
void SetRegister(uint32, uint32);
|
void SetRegister(uint32, uint32);
|
||||||
|
|
||||||
|
void SaveState(Framework::CZipArchiveWriter&);
|
||||||
|
void LoadState(Framework::CZipArchiveReader&);
|
||||||
|
|
||||||
void SetDMA3ReceiveHandler(const Dma3ReceiveHandler&);
|
void SetDMA3ReceiveHandler(const Dma3ReceiveHandler&);
|
||||||
uint32 ReceiveDMA4(uint32, uint32, bool, uint8*, uint8*);
|
uint32 ReceiveDMA4(uint32, uint32, bool, uint8*, uint8*);
|
||||||
|
|
||||||
|
@ -166,7 +172,10 @@ private:
|
||||||
void SetBitPosition(unsigned int);
|
void SetBitPosition(unsigned int);
|
||||||
unsigned int GetSize() const;
|
unsigned int GetSize() const;
|
||||||
unsigned int GetAvailableBits() const;
|
unsigned int GetAvailableBits() const;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
void SaveState(const char*, Framework::CZipArchiveWriter&);
|
||||||
|
void LoadState(const char*, Framework::CZipArchiveReader&);
|
||||||
|
|
||||||
enum BUFFERSIZE
|
enum BUFFERSIZE
|
||||||
{
|
{
|
||||||
|
|
30
Source/states/RegisterStateUtils.h
Normal file
30
Source/states/RegisterStateUtils.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "string_format.h"
|
||||||
|
|
||||||
|
namespace RegisterStateUtils
|
||||||
|
{
|
||||||
|
template <typename RegisterStateType, typename ArrayType, std::size_t ArraySize>
|
||||||
|
void ReadArray(const RegisterStateType& registerState, ArrayType (&array)[ArraySize], const char* format)
|
||||||
|
{
|
||||||
|
static_assert((sizeof(array) & 0x0F) == 0);
|
||||||
|
static const size_t regCount = sizeof(array) / (sizeof(uint128));
|
||||||
|
for(size_t i = 0; i < regCount; i++)
|
||||||
|
{
|
||||||
|
auto registerName = string_format(format, i);
|
||||||
|
reinterpret_cast<uint128*>(array)[i] = registerState.GetRegister128(registerName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RegisterStateType, typename ArrayType, std::size_t ArraySize>
|
||||||
|
void WriteArray(RegisterStateType& registerState, const ArrayType (&array)[ArraySize], const char* format)
|
||||||
|
{
|
||||||
|
static_assert((sizeof(array) & 0x0F) == 0);
|
||||||
|
static const size_t regCount = sizeof(array) / (sizeof(uint128));
|
||||||
|
for(size_t i = 0; i < regCount; i++)
|
||||||
|
{
|
||||||
|
auto registerName = string_format(format, i);
|
||||||
|
registerState.SetRegister128(registerName.c_str(), reinterpret_cast<const uint128*>(array)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue