From 8030863e21428f33869126fd430291a70c8669df Mon Sep 17 00:00:00 2001 From: jpd002 Date: Tue, 28 Oct 2008 01:48:21 +0000 Subject: [PATCH] git-svn-id: http://svn.purei.org/purei/trunk@393 b36208d7-6611-0410-8bec-b1987f11c4a2 --- Source/iop/IopBios.cpp | 58 ++++++++++++++++++++++++++- Source/iop/IopBios.h | 16 +++++++- Source/iop/Iop_Intrman.cpp | 20 ++++----- Source/iop/Iop_Intrman.h | 5 ++- tools/PsfPlayer2/PsfPlayer.vcproj | 4 +- tools/PsfPlayer2/Source/ps2/PsfVm.cpp | 10 ++--- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/Source/iop/IopBios.cpp b/Source/iop/IopBios.cpp index 23cfe329..2a62d1e2 100644 --- a/Source/iop/IopBios.cpp +++ b/Source/iop/IopBios.cpp @@ -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; diff --git a/Source/iop/IopBios.h b/Source/iop/IopBios.h index e5c5aa38..6c942a3a 100644 --- a/Source/iop/IopBios.h +++ b/Source/iop/IopBios.h @@ -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 > ThreadMapType; typedef std::map IopModuleMapType; typedef std::map SemaphoreMapType; + typedef std::map IntrHandlerMapType; typedef std::list LoadedModuleListType; typedef std::pair 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; diff --git a/Source/iop/Iop_Intrman.cpp b/Source/iop/Iop_Intrman.cpp index ae70060f..3de5ccfa 100644 --- a/Source/iop/Iop_Intrman.cpp +++ b/Source/iop/Iop_Intrman.cpp @@ -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); } diff --git a/Source/iop/Iop_Intrman.h b/Source/iop/Iop_Intrman.h index 889f4323..8b3cc9a9 100644 --- a/Source/iop/Iop_Intrman.h +++ b/Source/iop/Iop_Intrman.h @@ -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; }; } diff --git a/tools/PsfPlayer2/PsfPlayer.vcproj b/tools/PsfPlayer2/PsfPlayer.vcproj index 8d32602b..382e08a7 100644 --- a/tools/PsfPlayer2/PsfPlayer.vcproj +++ b/tools/PsfPlayer2/PsfPlayer.vcproj @@ -41,7 +41,7 @@