mirror of
https://github.com/libretro/Play-.git
synced 2025-03-03 00:46:50 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@393 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
f9d4017041
commit
8030863e21
@ -3,6 +3,7 @@
|
||||
#include "../Log.h"
|
||||
#include "../ElfFile.h"
|
||||
#include "PtrStream.h"
|
||||
#include "Iop_Intc.h"
|
||||
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
#include "Iop_DbcMan320.h"
|
||||
@ -74,6 +75,10 @@ void CIopBios::Reset()
|
||||
m_threadFinishAddress = AssembleThreadFinish(assembler);
|
||||
}
|
||||
|
||||
m_cpu.m_State.nCOP0[CCOP_SCU::STATUS] |= CMIPS::STATUS_INT;
|
||||
|
||||
m_intrHandlers.clear();
|
||||
|
||||
DeleteModules();
|
||||
|
||||
//Register built-in modules
|
||||
@ -112,7 +117,7 @@ void CIopBios::Reset()
|
||||
RegisterModule(new Iop::CTimrman());
|
||||
}
|
||||
{
|
||||
RegisterModule(new Iop::CIntrman(m_ram));
|
||||
RegisterModule(new Iop::CIntrman(*this, m_ram));
|
||||
}
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
{
|
||||
@ -601,6 +606,25 @@ Iop::CPadMan* CIopBios::GetPadman()
|
||||
|
||||
#endif
|
||||
|
||||
bool CIopBios::RegisterIntrHandler(uint32 line, uint32 mode, uint32 handler, uint32 arg)
|
||||
{
|
||||
INTRHANDLER intrHandler;
|
||||
intrHandler.line = line;
|
||||
intrHandler.mode = mode;
|
||||
intrHandler.handler = handler;
|
||||
intrHandler.arg = arg;
|
||||
m_intrHandlers[line] = intrHandler;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CIopBios::ReleaseIntrHandler(uint32 line)
|
||||
{
|
||||
IntrHandlerMapType::iterator handlerIterator(m_intrHandlers.find(line));
|
||||
if(handlerIterator == m_intrHandlers.end()) return false;
|
||||
m_intrHandlers.erase(handlerIterator);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 CIopBios::AssembleThreadFinish(CMIPSAssembler& assembler)
|
||||
{
|
||||
uint32 address = m_baseAddress + assembler.GetProgramSize();
|
||||
@ -609,7 +633,7 @@ uint32 CIopBios::AssembleThreadFinish(CMIPSAssembler& assembler)
|
||||
return address;
|
||||
}
|
||||
|
||||
void CIopBios::SysCallHandler()
|
||||
void CIopBios::HandleException()
|
||||
{
|
||||
uint32 searchAddress = m_cpu.m_State.nCOP0[CCOP_SCU::EPC];
|
||||
uint32 callInstruction = m_cpu.m_pMemoryMap->GetWord(searchAddress);
|
||||
@ -656,6 +680,36 @@ void CIopBios::SysCallHandler()
|
||||
m_cpu.m_State.nHasException = 0;
|
||||
}
|
||||
|
||||
void CIopBios::HandleInterrupt()
|
||||
{
|
||||
if(m_cpu.GenerateInterrupt(0xBFC00000))
|
||||
{
|
||||
//Find first concerned interrupt
|
||||
unsigned int line = -1;
|
||||
UNION64_32 status;
|
||||
for(unsigned int i = 0; i < 0x40; i++)
|
||||
{
|
||||
|
||||
}
|
||||
// SaveCpuState();
|
||||
// m_cpu.m_State.nGPR[CMIPS::K1].nV0 = m_cpu.m_State.nCOP0[CCOP_SCU::EPC];
|
||||
// uint32 status = m_cpu.m_pMemoryMap->GetWord(CIntc::STATUS);
|
||||
// uint32 mask = m_cpu.m_pMemoryMap->GetWord(CIntc::MASK);
|
||||
// uint32 cause = status & mask;
|
||||
// for(unsigned int i = 1; i <= MAX_EVENT; i++)
|
||||
// {
|
||||
// EVENT* eventPtr = m_events[i];
|
||||
// if(eventPtr == NULL) continue;
|
||||
// if(cause & 0x08 && eventPtr->classId == 0xF0000009)
|
||||
// {
|
||||
// eventPtr->fired = 1;
|
||||
// }
|
||||
// }
|
||||
// m_cpu.m_State.nPC = INTR_HANDLER;
|
||||
// m_cpu.m_pMemoryMap->SetWord(CIntc::STATUS, ~0x40);
|
||||
}
|
||||
}
|
||||
|
||||
string CIopBios::GetModuleNameFromPath(const std::string& path)
|
||||
{
|
||||
string::size_type slashPosition;
|
||||
|
@ -24,7 +24,8 @@ public:
|
||||
|
||||
void LoadAndStartModule(const char*, const char*, unsigned int);
|
||||
void LoadAndStartModule(uint32, const char*, unsigned int);
|
||||
void SysCallHandler();
|
||||
void HandleException();
|
||||
void HandleInterrupt();
|
||||
|
||||
void Reset();
|
||||
|
||||
@ -46,6 +47,9 @@ public:
|
||||
uint32 SignalSemaphore(uint32);
|
||||
uint32 WaitSemaphore(uint32);
|
||||
|
||||
bool RegisterIntrHandler(uint32, uint32, uint32, uint32);
|
||||
bool ReleaseIntrHandler(uint32);
|
||||
|
||||
private:
|
||||
enum DEFAULT_STACKSIZE
|
||||
{
|
||||
@ -83,6 +87,14 @@ private:
|
||||
uint32 waitCount;
|
||||
};
|
||||
|
||||
struct INTRHANDLER
|
||||
{
|
||||
uint32 line;
|
||||
uint32 mode;
|
||||
uint32 handler;
|
||||
uint32 arg;
|
||||
};
|
||||
|
||||
struct LOADEDMODULE
|
||||
{
|
||||
std::string name;
|
||||
@ -102,6 +114,7 @@ private:
|
||||
typedef std::multimap<uint32, THREAD, std::greater<uint32> > ThreadMapType;
|
||||
typedef std::map<std::string, Iop::CModule*> IopModuleMapType;
|
||||
typedef std::map<uint32, SEMAPHORE> SemaphoreMapType;
|
||||
typedef std::map<uint32, INTRHANDLER> IntrHandlerMapType;
|
||||
typedef std::list<LOADEDMODULE> LoadedModuleListType;
|
||||
typedef std::pair<uint32, uint32> ExecutableRange;
|
||||
|
||||
@ -143,6 +156,7 @@ private:
|
||||
bool m_rescheduleNeeded;
|
||||
ThreadMapType m_threads;
|
||||
SemaphoreMapType m_semaphores;
|
||||
IntrHandlerMapType m_intrHandlers;
|
||||
IopModuleMapType m_modules;
|
||||
LoadedModuleListType m_loadedModules;
|
||||
Iop::CSifMan* m_sifMan;
|
||||
|
@ -2,13 +2,15 @@
|
||||
#include "../Log.h"
|
||||
#include "../COP_SCU.h"
|
||||
#include "Iop_Intc.h"
|
||||
#include "IopBios.h"
|
||||
|
||||
#define LOGNAME "iop_intrman"
|
||||
|
||||
using namespace Iop;
|
||||
using namespace std;
|
||||
|
||||
CIntrman::CIntrman(uint8* ram) :
|
||||
CIntrman::CIntrman(CIopBios& bios, uint8* ram) :
|
||||
m_bios(bios),
|
||||
m_ram(ram)
|
||||
{
|
||||
|
||||
@ -88,7 +90,7 @@ uint32 CIntrman::RegisterIntrHandler(uint32 line, uint32 mode, uint32 handler, u
|
||||
CLog::GetInstance().Print(LOGNAME, "RegisterIntrHandler(line = %d, mode = %d, handler = 0x%0.8X, arg = 0x%0.8X);\r\n",
|
||||
line, mode, handler, arg);
|
||||
#endif
|
||||
return 0;
|
||||
return m_bios.RegisterIntrHandler(line, mode, handler, arg) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32 CIntrman::ReleaseIntrHandler(uint32 line)
|
||||
@ -97,7 +99,7 @@ uint32 CIntrman::ReleaseIntrHandler(uint32 line)
|
||||
CLog::GetInstance().Print(LOGNAME, "ReleaseIntrHandler(line = %d);\r\n",
|
||||
line);
|
||||
#endif
|
||||
return 0;
|
||||
return m_bios.ReleaseIntrHandler(line) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32 CIntrman::EnableIntrLine(CMIPS& context, uint32 line)
|
||||
@ -137,7 +139,7 @@ uint32 CIntrman::EnableInterrupts(CMIPS& context)
|
||||
#endif
|
||||
|
||||
uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS];
|
||||
statusRegister |= 1;
|
||||
statusRegister |= CMIPS::STATUS_INT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,8 +149,8 @@ uint32 CIntrman::SuspendInterrupts(CMIPS& context, uint32* state)
|
||||
CLog::GetInstance().Print(LOGNAME, "SuspendInterrupts();\r\n");
|
||||
#endif
|
||||
uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS];
|
||||
(*state) = statusRegister & 1;
|
||||
statusRegister &= ~1;
|
||||
(*state) = statusRegister & CMIPS::STATUS_INT;
|
||||
statusRegister &= ~CMIPS::STATUS_INT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -160,11 +162,11 @@ uint32 CIntrman::ResumeInterrupts(CMIPS& context, uint32 state)
|
||||
uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS];
|
||||
if(state)
|
||||
{
|
||||
statusRegister |= 1;
|
||||
statusRegister |= CMIPS::STATUS_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusRegister &= ~1;
|
||||
statusRegister &= ~CMIPS::STATUS_INT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -175,5 +177,5 @@ uint32 CIntrman::QueryIntrContext(CMIPS& context)
|
||||
CLog::GetInstance().Print(LOGNAME, "QueryIntrContext();\r\n");
|
||||
#endif
|
||||
uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS];
|
||||
return (statusRegister & 0x02 ? 1 : 0);
|
||||
return (statusRegister & CMIPS::STATUS_EXL ? 1 : 0);
|
||||
}
|
||||
|
@ -3,12 +3,14 @@
|
||||
|
||||
#include "Iop_Module.h"
|
||||
|
||||
class CIopBios;
|
||||
|
||||
namespace Iop
|
||||
{
|
||||
class CIntrman : public CModule
|
||||
{
|
||||
public:
|
||||
CIntrman(uint8*);
|
||||
CIntrman(CIopBios&, uint8*);
|
||||
virtual ~CIntrman();
|
||||
|
||||
std::string GetId() const;
|
||||
@ -24,6 +26,7 @@ namespace Iop
|
||||
uint32 ResumeInterrupts(CMIPS&, uint32);
|
||||
uint32 QueryIntrContext(CMIPS&);
|
||||
uint8* m_ram;
|
||||
CIopBios& m_bios;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(FrameworkRoot)\include";"$(ProjectDir)\..\..\Source""
|
||||
AdditionalIncludeDirectories=""$(FrameworkRoot)\include";"$(ProjectDir)\..\..\Source";"$(ProjectDir)\Source""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MSVC;_CRT_SECURE_NO_WARNINGS;_PSX;_NULL_SIFMAN;DEBUGGER_INCLUDED"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@ -116,7 +116,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""$(FrameworkRoot)\include";"$(ProjectDir)\..\..\Source""
|
||||
AdditionalIncludeDirectories=""$(FrameworkRoot)\include";"$(ProjectDir)\..\..\Source";"$(ProjectDir)\Source""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MSVC;_PSX"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
|
@ -109,10 +109,10 @@ unsigned int CPsfVm::ExecuteCpu(bool singleStep)
|
||||
int ticks = 0;
|
||||
if(!m_cpu.m_State.nHasException)
|
||||
{
|
||||
// if(m_intc.IsInterruptPending())
|
||||
// {
|
||||
// m_bios.HandleInterrupt();
|
||||
// }
|
||||
if(m_intc.HasPendingInterrupt())
|
||||
{
|
||||
m_bios.HandleInterrupt();
|
||||
}
|
||||
}
|
||||
if(!m_cpu.m_State.nHasException)
|
||||
{
|
||||
@ -134,7 +134,7 @@ unsigned int CPsfVm::ExecuteCpu(bool singleStep)
|
||||
}
|
||||
if(m_cpu.m_State.nHasException)
|
||||
{
|
||||
m_bios.SysCallHandler();
|
||||
m_bios.HandleException();
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user