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

This commit is contained in:
jpd002 2008-10-28 01:48:21 +00:00
parent f9d4017041
commit 8030863e21
6 changed files with 93 additions and 20 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
};
}

View File

@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(FrameworkRoot)\include&quot;;&quot;$(ProjectDir)\..\..\Source&quot;"
AdditionalIncludeDirectories="&quot;$(FrameworkRoot)\include&quot;;&quot;$(ProjectDir)\..\..\Source&quot;;&quot;$(ProjectDir)\Source&quot;"
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="&quot;$(FrameworkRoot)\include&quot;;&quot;$(ProjectDir)\..\..\Source&quot;"
AdditionalIncludeDirectories="&quot;$(FrameworkRoot)\include&quot;;&quot;$(ProjectDir)\..\..\Source&quot;;&quot;$(ProjectDir)\Source&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MSVC;_PSX"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"

View File

@ -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;
}