git-svn-id: http://svn.purei.org/purei/trunk@423 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2008-11-25 02:00:42 +00:00
parent 10e676922a
commit 5c1036d110
6 changed files with 347 additions and 25 deletions

View File

@ -305,11 +305,11 @@ void CPS2OS::LoadELF(CStream& stream, const char* sExecName)
// memcpy(m_ram + 0x01000000, pELF->m_pData, pELF->m_nLenght);
// delete pELF;
for(int i = 0; i < 0x02000000 / 4; i++)
{
uint32 nVal = ((uint32*)m_ram)[i];
if((nVal & 0xFFFF) == 0x0180)
{
// for(int i = 0; i < 0x02000000 / 4; i++)
// {
// uint32 nVal = ((uint32*)m_ram)[i];
// if((nVal & 0xFFFF) == 0x0180)
// {
/*
for(unsigned int j = i; j < i + 0x30; j += 4)
{
@ -330,12 +330,12 @@ void CPS2OS::LoadELF(CStream& stream, const char* sExecName)
printf("Ballo: 0x%0.8X\r\n", i * 4);
}
*/
if((nVal & 0xFC000000) == 0x09 << 26)
{
printf("Allo: 0x%0.8X\r\n", i * 4);
}
}
}
// if((nVal & 0xFC000000) == 0x09 << 26)
// {
// printf("Allo: 0x%0.8X\r\n", i * 4);
// }
// }
// }
/*
int i;
@ -422,10 +422,10 @@ void CPS2OS::LoadExecutable()
void CPS2OS::UnloadExecutable()
{
m_OnExecutableUnloading();
if(m_pELF == NULL) return;
m_OnExecutableUnloading();
DELETEPTR(m_pELF);
SaveExecutableConfig();

View File

@ -4,6 +4,7 @@
#include "../ElfFile.h"
#include "PtrStream.h"
#include "Iop_Intc.h"
#include "lexical_cast_ex.h"
#ifdef _IOP_EMULATE_MODULES
#include "Iop_DbcMan320.h"
@ -30,14 +31,14 @@
using namespace std;
using namespace Framework;
CIopBios::CIopBios(uint32 baseAddress, uint32 clockFrequency, CMIPS& cpu, uint8* ram, uint32 ramSize, Iop::CSifMan* sifMan) :
CIopBios::CIopBios(uint32 baseAddress, uint32 clockFrequency, CMIPS& cpu, uint8* ram, uint32 ramSize) :
m_baseAddress(baseAddress),
m_cpu(cpu),
m_ram(ram),
m_ramSize(ramSize),
m_sifMan(sifMan),
m_nextThreadId(1),
m_nextSemaphoreId(1),
m_sifMan(NULL),
m_stdio(NULL),
m_sysmem(NULL),
m_ioman(NULL),
@ -52,10 +53,7 @@ m_threadFinishAddress(0),
m_clockFrequency(clockFrequency),
m_currentTime(0)
{
if(m_sifMan == NULL)
{
m_sifMan = new Iop::CSifManNull();
}
}
CIopBios::~CIopBios()
@ -67,7 +65,7 @@ CIopBios::~CIopBios()
DeleteModules();
}
void CIopBios::Reset()
void CIopBios::Reset(Iop::CSifMan* sifMan)
{
{
CMIPSAssembler assembler(reinterpret_cast<uint32*>(&m_ram[m_baseAddress]));
@ -83,6 +81,15 @@ void CIopBios::Reset()
DeleteModules();
if(sifMan == NULL)
{
m_sifMan = new Iop::CSifManNull();
}
else
{
m_sifMan = sifMan;
}
//Register built-in modules
{
m_stdio = new Iop::CStdio(m_ram);
@ -164,6 +171,8 @@ void CIopBios::Reset()
#ifndef _NULL_SIFMAN
m_sifMan->SetDmaBuffer(m_ram + sifDmaBufferPtr, sifDmaBufferSize);
#endif
Reschedule();
}
void CIopBios::LoadAndStartModule(const char* path, const char* args, unsigned int argsLength)
@ -181,8 +190,8 @@ void CIopBios::LoadAndStartModule(const char* path, const char* args, unsigned i
void CIopBios::LoadAndStartModule(uint32 modulePtr, const char* args, unsigned int argsLength)
{
// CELF module(m_ram + modulePtr);
// LoadAndStartModule(module, "", args, argsLength);
CELF module(m_ram + modulePtr);
LoadAndStartModule(module, "", args, argsLength);
}
void CIopBios::LoadAndStartModule(CELF& elf, const char* path, const char* args, unsigned int argsLength)
@ -857,6 +866,27 @@ const CIopBios::LOADEDMODULE& CIopBios::GetModuleAtAddress(uint32 address)
throw runtime_error("No module at specified address.");
}
#define TAGS_COLLECTION_FUNCTIONS ("functions")
#define TAGS_COLLECTION_COMMENTS ("comments")
#define TAGS_SECTION_MODULE ("module")
#define TAGS_SECTION_MODULE_BASEADDRESS ("baseAddress")
#define TAGS_SECTION_MODULE_GIVENNAME ("givenName")
#ifdef DEBUGGER_INCLUDED
void CIopBios::LoadDebugTags(Xml::CNode* root)
{
}
void CIopBios::SaveDebugTags(Xml::CNode* root)
{
SaveAllModulesTags(root, m_cpu.m_Functions, TAGS_COLLECTION_FUNCTIONS);
SaveAllModulesTags(root, m_cpu.m_Comments, TAGS_COLLECTION_COMMENTS);
}
#endif
void CIopBios::LoadModuleTags(const LOADEDMODULE& module, CMIPSTags& tags, const char* tagCollectionName)
{
CMIPSTags moduleTags;
@ -889,6 +919,32 @@ void CIopBios::SaveAllModulesTags(CMIPSTags& tags, const char* tagCollectionName
}
}
void CIopBios::SaveAllModulesTags(Framework::Xml::CNode* root, CMIPSTags& tags, const char* collectionName)
{
for(LoadedModuleListType::const_iterator moduleIterator(m_loadedModules.begin());
m_loadedModules.end() != moduleIterator; moduleIterator++)
{
const LOADEDMODULE& module(*moduleIterator);
CMIPSTags moduleTags;
for(CMIPSTags::TagIterator tag(tags.GetTagsBegin());
tag != tags.GetTagsEnd(); tag++)
{
uint32 tagAddress = tag->first;
if(tagAddress >= module.begin && tagAddress <= module.end)
{
moduleTags.InsertTag(tagAddress - module.begin, tag->second.c_str());
}
}
{
Xml::CNode* tagsNode = new Xml::CNode(TAGS_SECTION_MODULE, true);
tagsNode->InsertAttribute(TAGS_SECTION_MODULE_BASEADDRESS, lexical_cast_hex<string>(module.begin, 8).c_str());
tagsNode->InsertAttribute(TAGS_SECTION_MODULE_GIVENNAME, module.name.c_str());
moduleTags.Serialize(tagsNode);
root->InsertNode(tagsNode);
}
}
}
void CIopBios::DeleteModules()
{
while(m_modules.size() != 0)
@ -896,6 +952,17 @@ void CIopBios::DeleteModules()
delete m_modules.begin()->second;
m_modules.erase(m_modules.begin());
}
m_sifMan = NULL;
m_stdio = NULL;
m_ioman = NULL;
m_sysmem = NULL;
m_modload = NULL;
#ifdef _IOP_EMULATE_MODULES
m_dbcman = NULL;
m_padman = NULL;
m_cdvdfsv = NULL;
#endif
}
string CIopBios::ReadModuleName(uint32 address)

View File

@ -5,21 +5,23 @@
#include "../MIPSAssembler.h"
#include "../MIPS.h"
#include "../ELF.h"
#include "Iop_BiosBase.h"
#include "Iop_SifMan.h"
#include "Iop_Ioman.h"
#include "Iop_Stdio.h"
#include "Iop_Sysmem.h"
#include "Iop_Modload.h"
#include "xml/Node.h"
#ifdef _IOP_EMULATE_MODULES
#include "Iop_DbcMan.h"
#include "Iop_PadMan.h"
#include "Iop_Cdvdfsv.h"
#endif
class CIopBios
class CIopBios : public Iop::CBiosBase
{
public:
CIopBios(uint32, uint32, CMIPS&, uint8*, uint32, Iop::CSifMan*);
CIopBios(uint32, uint32, CMIPS&, uint8*, uint32);
virtual ~CIopBios();
void LoadAndStartModule(const char*, const char*, unsigned int);
@ -33,7 +35,11 @@ public:
uint64 MicroSecToClock(uint32);
uint64 ClockToMicroSec(uint64);
void Reset();
void Reset(Iop::CSifMan*);
#ifdef DEBUGGER_INCLUDED
void LoadDebugTags(Framework::Xml::CNode*);
void SaveDebugTags(Framework::Xml::CNode*);
#endif
Iop::CIoman* GetIoman();
#ifdef _IOP_EMULATE_MODULES
@ -145,6 +151,7 @@ private:
const LOADEDMODULE& GetModuleAtAddress(uint32);
void LoadModuleTags(const LOADEDMODULE&, CMIPSTags&, const char*);
void SaveAllModulesTags(CMIPSTags&, const char*);
void SaveAllModulesTags(Framework::Xml::CNode*, CMIPSTags&, const char*);
void DeleteModules();
uint32 Push(uint32&, const uint8*, uint32);

View File

@ -0,0 +1,194 @@
#include "Iop_SubSystem.h"
#include "../MA_MIPSIV.h"
#include "../Ps2Const.h"
#include "../Log.h"
using namespace Iop;
using namespace std::tr1;
using namespace std::tr1::placeholders;
using namespace PS2;
#define LOG_NAME ("iop_subsystem")
CSubSystem::CSubSystem() :
m_cpu(MEMORYMAP_ENDIAN_LSBF, 0, 0x1FFFFFFF),
m_executor(m_cpu),
m_bios(NULL),
m_ram(new uint8[IOP_RAM_SIZE]),
m_scratchPad(new uint8[IOP_SCRATCH_SIZE]),
m_spuRam(new uint8[SPU_RAM_SIZE]),
m_dmac(m_ram, m_intc),
m_counters(IOP_CLOCK_FREQ, m_intc),
m_spuCore0(m_spuRam, SPU_RAM_SIZE),
m_spuCore1(m_spuRam, SPU_RAM_SIZE),
m_spu(m_spuCore0),
m_spu2(m_spuCore0, m_spuCore1)
{
//Read memory map
m_cpu.m_pMemoryMap->InsertReadMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x01);
m_cpu.m_pMemoryMap->InsertReadMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x02);
m_cpu.m_pMemoryMap->InsertReadMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x03);
m_cpu.m_pMemoryMap->InsertReadMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x04);
m_cpu.m_pMemoryMap->InsertReadMap(0x1F800000, 0x1F8003FF, m_scratchPad, 0x05);
m_cpu.m_pMemoryMap->InsertReadMap(HW_REG_BEGIN, HW_REG_END, bind(&CSubSystem::ReadIoRegister, this, _1), 0x06);
//Write memory map
m_cpu.m_pMemoryMap->InsertWriteMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x01);
m_cpu.m_pMemoryMap->InsertWriteMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x02);
m_cpu.m_pMemoryMap->InsertWriteMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x03);
m_cpu.m_pMemoryMap->InsertWriteMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x04);
m_cpu.m_pMemoryMap->InsertWriteMap(0x1F800000, 0x1F8003FF, m_scratchPad, 0x05);
m_cpu.m_pMemoryMap->InsertWriteMap(HW_REG_BEGIN, HW_REG_END, bind(&CSubSystem::WriteIoRegister, this, _1, _2), 0x06);
//Instruction memory map
m_cpu.m_pMemoryMap->InsertInstructionMap((0 * IOP_RAM_SIZE), (0 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x01);
m_cpu.m_pMemoryMap->InsertInstructionMap((1 * IOP_RAM_SIZE), (1 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x02);
m_cpu.m_pMemoryMap->InsertInstructionMap((2 * IOP_RAM_SIZE), (2 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x03);
m_cpu.m_pMemoryMap->InsertInstructionMap((3 * IOP_RAM_SIZE), (3 * IOP_RAM_SIZE) + IOP_RAM_SIZE - 1, m_ram, 0x04);
m_cpu.m_pArch = &g_MAMIPSIV;
m_cpu.m_pAddrTranslator = &CMIPS::TranslateAddress64;
m_dmac.SetReceiveFunction(4, bind(&CSpuBase::ReceiveDma, &m_spuCore0, _1, _2, _3));
m_dmac.SetReceiveFunction(8, bind(&CSpuBase::ReceiveDma, &m_spuCore1, _1, _2, _3));
}
CSubSystem::~CSubSystem()
{
}
void CSubSystem::SetBios(CBiosBase* bios)
{
m_bios = bios;
}
void CSubSystem::Reset()
{
memset(m_ram, 0, IOP_RAM_SIZE);
memset(m_scratchPad, 0, IOP_SCRATCH_SIZE);
memset(m_spuRam, 0, SPU_RAM_SIZE);
m_executor.Clear();
m_cpu.Reset();
m_spuCore0.Reset();
m_spuCore1.Reset();
m_spu.Reset();
m_spu2.Reset();
m_counters.Reset();
m_dmac.Reset();
m_intc.Reset();
m_bios = NULL;
}
uint32 CSubSystem::ReadIoRegister(uint32 address)
{
if(address == 0x1F801814)
{
return 0x14802000;
}
else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
{
return m_spu.ReadRegister(address);
}
else if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
{
return m_dmac.ReadRegister(address);
}
else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
{
return m_dmac.ReadRegister(address);
}
else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
{
return m_intc.ReadRegister(address);
}
else if(address >= CRootCounters::ADDR_BEGIN && address <= CRootCounters::ADDR_END)
{
return m_counters.ReadRegister(address);
}
else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
{
return m_spu2.ReadRegister(address);
}
else
{
CLog::GetInstance().Print(LOG_NAME, "Reading an unknown hardware register (0x%0.8X).\r\n", address);
}
return 0;
}
uint32 CSubSystem::WriteIoRegister(uint32 address, uint32 value)
{
if(address >= CDmac::DMAC_ZONE1_START && address <= CDmac::DMAC_ZONE1_END)
{
m_dmac.WriteRegister(address, value);
}
else if(address >= CSpu::SPU_BEGIN && address <= CSpu::SPU_END)
{
m_spu.WriteRegister(address, static_cast<uint16>(value));
}
else if(address >= CDmac::DMAC_ZONE2_START && address <= CDmac::DMAC_ZONE2_END)
{
m_dmac.WriteRegister(address, value);
}
else if(address >= CIntc::ADDR_BEGIN && address <= CIntc::ADDR_END)
{
m_intc.WriteRegister(address, value);
}
else if(address >= CRootCounters::ADDR_BEGIN && address <= CRootCounters::ADDR_END)
{
m_counters.WriteRegister(address, value);
}
else if(address >= CSpu2::REGS_BEGIN && address <= CSpu2::REGS_END)
{
return m_spu2.WriteRegister(address, value);
}
else
{
CLog::GetInstance().Print(LOG_NAME, "Writing to an unknown hardware register (0x%0.8X, 0x%0.8X).\r\n", address, value);
}
return 0;
}
unsigned int CSubSystem::ExecuteCpu(bool singleStep)
{
int ticks = 0;
if(!m_cpu.m_State.nHasException)
{
if(m_intc.HasPendingInterrupt())
{
m_bios->HandleInterrupt();
}
}
if(!m_cpu.m_State.nHasException)
{
int quota = singleStep ? 1 : 500;
ticks = quota - m_executor.Execute(quota);
assert(ticks >= 0);
{
if(m_cpu.m_State.nPC == 0x1018)
{
ticks += (quota * 2);
}
else
{
CBasicBlock* nextBlock = m_executor.FindBlockAt(m_cpu.m_State.nPC);
if(nextBlock != NULL && nextBlock->GetSelfLoopCount() > 5000)
{
//Go a little bit faster if we're "stuck"
ticks += (quota * 2);
}
}
}
if(ticks > 0)
{
m_counters.Update(ticks);
m_bios->CountTicks(ticks);
}
}
if(m_cpu.m_State.nHasException)
{
m_bios->HandleException();
}
return ticks;
}

View File

@ -0,0 +1,53 @@
#ifndef _IOP_SUBSYSTEM_H_
#define _IOP_SUBSYSTEM_H_
#include "../MIPS.h"
#include "../MipsExecutor.h"
#include "Iop_SpuBase.h"
#include "Iop_Spu.h"
#include "Iop_Spu2.h"
#include "Iop_Dmac.h"
#include "Iop_Intc.h"
#include "Iop_RootCounters.h"
#include "Iop_BiosBase.h"
namespace Iop
{
class CSubSystem
{
public:
CSubSystem();
virtual ~CSubSystem();
void Reset();
unsigned int ExecuteCpu(bool);
void SetBios(CBiosBase*);
uint8* m_ram;
uint8* m_scratchPad;
uint8* m_spuRam;
CIntc m_intc;
CRootCounters m_counters;
CDmac m_dmac;
CSpuBase m_spuCore0;
CSpuBase m_spuCore1;
CSpu m_spu;
CSpu2 m_spu2;
CMIPS m_cpu;
CMipsExecutor m_executor;
CBiosBase* m_bios;
private:
enum
{
HW_REG_BEGIN = 0x1F801000,
HW_REG_END = 0x1F9FFFFF
};
uint32 ReadIoRegister(uint32);
uint32 WriteIoRegister(uint32, uint32);
};
}
#endif

View File

@ -9,6 +9,7 @@
#include <map>
#include <set>
#include <functional>
#include <memory>
#include <boost/signal.hpp>
#include <boost/lexical_cast.hpp>