diff --git a/tools/PsfPlayer2/Source/AppDef.h b/tools/PsfPlayer2/Source/AppDef.h index b5c67aaa..5c48a7dd 100644 --- a/tools/PsfPlayer2/Source/AppDef.h +++ b/tools/PsfPlayer2/Source/AppDef.h @@ -2,7 +2,7 @@ #define _APPDEF_H_ #define APP_NAME _T("PsfPlayer") -#define APP_VERSION (14) -#define APP_VERSIONSTR _T("0.14") +#define APP_VERSION (15) +#define APP_VERSIONSTR _T("0.15") #endif diff --git a/tools/PsfPlayer2/Source/PsxBios.cpp b/tools/PsfPlayer2/Source/PsxBios.cpp index cfa730f1..0636ec27 100644 --- a/tools/PsfPlayer2/Source/PsxBios.cpp +++ b/tools/PsfPlayer2/Source/PsxBios.cpp @@ -94,7 +94,8 @@ void CPsxBios::AssembleEventChecker() unsigned int currentEvent = CMIPS::S0; unsigned int eventMax = CMIPS::S1; unsigned int eventToCheck = CMIPS::S2; - int stackAlloc = 4 * 4; + unsigned int needClearInt = CMIPS::S3; + int stackAlloc = 5 * 4; //prolog assembler.ADDIU(CMIPS::SP, CMIPS::SP, -stackAlloc); @@ -102,10 +103,12 @@ void CPsxBios::AssembleEventChecker() assembler.SW(CMIPS::S0, 0x04, CMIPS::SP); assembler.SW(CMIPS::S1, 0x08, CMIPS::SP); assembler.SW(CMIPS::S2, 0x0C, CMIPS::SP); + assembler.SW(CMIPS::S3, 0x10, CMIPS::SP); assembler.LI(currentEvent, EVENTS_BEGIN); assembler.LI(eventMax, EVENTS_BEGIN + EVENTS_SIZE); assembler.MOV(eventToCheck, CMIPS::A0); + assembler.ADDU(needClearInt, CMIPS::R0, CMIPS::R0); //checkEvent { @@ -116,16 +119,19 @@ void CPsxBios::AssembleEventChecker() assembler.BEQ(CMIPS::T0, CMIPS::R0, doneEventLabel); assembler.NOP(); - //check if enabled - assembler.LW(CMIPS::T0, offsetof(EVENT, enabled), currentEvent); - assembler.BEQ(CMIPS::T0, CMIPS::R0, doneEventLabel); - assembler.NOP(); - //check if good event class assembler.LW(CMIPS::T0, offsetof(EVENT, classId), currentEvent); assembler.BNE(CMIPS::T0, eventToCheck, doneEventLabel); assembler.NOP(); + //Tell that we need to clear interrupt later (experimental) + assembler.ADDIU(needClearInt, CMIPS::R0, 1); + + //check if enabled + assembler.LW(CMIPS::T0, offsetof(EVENT, enabled), currentEvent); + assembler.BEQ(CMIPS::T0, CMIPS::R0, doneEventLabel); + assembler.NOP(); + //Start handler if present assembler.LW(CMIPS::T0, offsetof(EVENT, func), currentEvent); assembler.BEQ(CMIPS::T0, CMIPS::R0, doneEventLabel); @@ -141,11 +147,15 @@ void CPsxBios::AssembleEventChecker() assembler.BNE(currentEvent, eventMax, checkEventLabel); assembler.NOP(); + //Result + assembler.ADDU(CMIPS::V0, needClearInt, CMIPS::R0); + //epilog assembler.LW(CMIPS::RA, 0x00, CMIPS::SP); assembler.LW(CMIPS::S0, 0x04, CMIPS::SP); assembler.LW(CMIPS::S1, 0x08, CMIPS::SP); assembler.LW(CMIPS::S2, 0x0C, CMIPS::SP); + assembler.LW(CMIPS::S3, 0x10, CMIPS::SP); assembler.ADDIU(CMIPS::SP, CMIPS::SP, stackAlloc); assembler.JR(CMIPS::RA); @@ -176,7 +186,8 @@ void CPsxBios::AssembleInterruptHandler() assembler.JAL(EVENT_CHECKER); assembler.NOP(); - assembler.MarkLabel(skipRootCounter2EventLabel); + assembler.BEQ(CMIPS::V0, CMIPS::R0, skipRootCounter2EventLabel); + assembler.NOP(); //Clear cause assembler.LI(CMIPS::T0, CIntc::STATUS); @@ -184,6 +195,8 @@ void CPsxBios::AssembleInterruptHandler() assembler.LI(CMIPS::T1, ~0x40); assembler.SW(CMIPS::T1, 0, CMIPS::T0); + assembler.MarkLabel(skipRootCounter2EventLabel); + //checkIntHook assembler.LI(CMIPS::T0, LONGJMP_BUFFER); assembler.LW(CMIPS::T0, 0, CMIPS::T0); @@ -348,11 +361,22 @@ void CPsxBios::DisassembleSyscall(uint32 searchAddress) m_cpu.m_State.nGPR[SC_PARAM0].nV0, m_cpu.m_State.nGPR[SC_PARAM1].nV0); break; + case 0x19: + CLog::GetInstance().Print(LOG_NAME, "strcpy(dst = 0x%0.8X, src = 0x%0.8X);\r\n", + m_cpu.m_State.nGPR[SC_PARAM0].nV0, + m_cpu.m_State.nGPR[SC_PARAM1].nV0); + break; case 0x28: CLog::GetInstance().Print(LOG_NAME, "bzero(address = 0x%0.8X, length = 0x%x);\r\n", m_cpu.m_State.nGPR[SC_PARAM0].nV0, m_cpu.m_State.nGPR[SC_PARAM1].nV0); break; + case 0x2B: + CLog::GetInstance().Print(LOG_NAME, "memset(address = 0x%0.8X, value = 0x%x, length = 0x%x);\r\n", + m_cpu.m_State.nGPR[SC_PARAM0].nV0, + m_cpu.m_State.nGPR[SC_PARAM1].nV0, + m_cpu.m_State.nGPR[SC_PARAM2].nV0); + break; case 0x39: CLog::GetInstance().Print(LOG_NAME, "InitHeap(block = 0x%0.8X, n = 0x%0.8X);\r\n", m_cpu.m_State.nGPR[SC_PARAM0].nV0, @@ -405,6 +429,10 @@ void CPsxBios::DisassembleSyscall(uint32 searchAddress) CLog::GetInstance().Print(LOG_NAME, "WaitEvent(event = 0x%X);\r\n", m_cpu.m_State.nGPR[SC_PARAM0].nV0); break; + case 0x0B: + CLog::GetInstance().Print(LOG_NAME, "TestEvent(event = 0x%X);\r\n", + m_cpu.m_State.nGPR[SC_PARAM0].nV0); + break; case 0x0C: CLog::GetInstance().Print(LOG_NAME, "EnableEvent(event = 0x%X);\r\n", m_cpu.m_State.nGPR[SC_PARAM0].nV0); @@ -413,6 +441,9 @@ void CPsxBios::DisassembleSyscall(uint32 searchAddress) CLog::GetInstance().Print(LOG_NAME, "DisableEvent(event = 0x%X);\r\n", m_cpu.m_State.nGPR[SC_PARAM0].nV0); break; + case 0x16: + CLog::GetInstance().Print(LOG_NAME, "PAD_dr();\r\n"); + break; case 0x17: CLog::GetInstance().Print(LOG_NAME, "ReturnFromException();\r\n"); break; @@ -509,6 +540,20 @@ void CPsxBios::sc_longjmp() LongJump(buffer, value); } +//A0 - 19 +void CPsxBios::sc_strcpy() +{ + uint32 dst = m_cpu.m_pAddrTranslator(&m_cpu, 0, m_cpu.m_State.nGPR[SC_PARAM0].nV0); + uint32 src = m_cpu.m_pAddrTranslator(&m_cpu, 0, m_cpu.m_State.nGPR[SC_PARAM1].nV0); + + strcpy( + reinterpret_cast(m_ram + dst), + reinterpret_cast(m_ram + src) + ); + + m_cpu.m_State.nGPR[SC_RETURN].nV0 = dst; +} + //A0 - 28 void CPsxBios::sc_bzero() { @@ -521,6 +566,21 @@ void CPsxBios::sc_bzero() memset(m_ram + address, 0, length); } +//A0 - 2B +void CPsxBios::sc_memset() +{ + uint32 address = m_cpu.m_pAddrTranslator(&m_cpu, 0, m_cpu.m_State.nGPR[SC_PARAM0].nV0); + uint8 value = static_cast(m_cpu.m_State.nGPR[SC_PARAM1].nV0); + uint32 length = m_cpu.m_State.nGPR[SC_PARAM2].nV0; + if((address + length) > CPsxVm::RAMSIZE) + { + throw exception(); + } + memset(m_ram + address, value, length); + + m_cpu.m_State.nGPR[SC_RETURN].nV0 = address; +} + //A0 - 39 void CPsxBios::sc_InitHeap() { @@ -651,6 +711,12 @@ void CPsxBios::sc_DisableEvent() } } +//B0 - 16 +void CPsxBios::sc_PAD_dr() +{ + +} + //B0 - 17 void CPsxBios::sc_ReturnFromException() { @@ -737,7 +803,9 @@ void CPsxBios::sc_ExitCriticalSection() void CPsxBios::sc_Illegal() { +#ifdef _DEBUG throw runtime_error("Illegal system call."); +#endif } CPsxBios::SyscallHandler CPsxBios::m_handlerA0[MAX_HANDLER_A0] = @@ -749,11 +817,11 @@ CPsxBios::SyscallHandler CPsxBios::m_handlerA0[MAX_HANDLER_A0] = //0x10 &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_setjmp, &sc_longjmp, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x18 - &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, + &sc_Illegal, &sc_strcpy, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x20 &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x28 - &sc_bzero, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, + &sc_bzero, &sc_Illegal, &sc_Illegal, &sc_memset, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x30 &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x38 @@ -815,7 +883,7 @@ CPsxBios::SyscallHandler CPsxBios::m_handlerB0[MAX_HANDLER_B0] = //0x08 &sc_OpenEvent, &sc_Illegal, &sc_WaitEvent, &sc_TestEvent, &sc_EnableEvent, &sc_DisableEvent, &sc_Illegal, &sc_Illegal, //0x10 - &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_ReturnFromException, + &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_PAD_dr, &sc_ReturnFromException, //0x18 &sc_Illegal, &sc_HookEntryInt, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, &sc_Illegal, //0x20 diff --git a/tools/PsfPlayer2/Source/PsxBios.h b/tools/PsfPlayer2/Source/PsxBios.h index ac5ce8a9..0dd61683 100644 --- a/tools/PsfPlayer2/Source/PsxBios.h +++ b/tools/PsfPlayer2/Source/PsxBios.h @@ -113,7 +113,9 @@ private: //A0 void sc_setjmp(); void sc_longjmp(); + void sc_strcpy(); void sc_bzero(); + void sc_memset(); void sc_InitHeap(); void sc_printf(); void sc_FlushCache(); @@ -129,6 +131,7 @@ private: void sc_TestEvent(); void sc_EnableEvent(); void sc_DisableEvent(); + void sc_PAD_dr(); void sc_ReturnFromException(); void sc_HookEntryInt(); void sc_InitCARD(); diff --git a/tools/PsfPlayer2/Source/PsxVm.cpp b/tools/PsfPlayer2/Source/PsxVm.cpp index a7bf6300..0a5bb09f 100644 --- a/tools/PsfPlayer2/Source/PsxVm.cpp +++ b/tools/PsfPlayer2/Source/PsxVm.cpp @@ -23,6 +23,7 @@ m_bios(m_cpu, m_ram), m_status(PAUSED), m_singleStep(false), m_ram(new uint8[RAMSIZE]), +m_scratchPad(new uint8[SCRATCHSIZE]), m_dmac(m_ram, m_intc), m_counters(CLOCK_FREQ, m_intc), m_thread(bind(&CPsxVm::ThreadProc, this)) @@ -32,14 +33,16 @@ m_thread(bind(&CPsxVm::ThreadProc, this)) m_cpu.m_pMemoryMap->InsertReadMap((1 * RAMSIZE), (1 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x02); m_cpu.m_pMemoryMap->InsertReadMap((2 * RAMSIZE), (2 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x03); m_cpu.m_pMemoryMap->InsertReadMap((3 * RAMSIZE), (3 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x04); - m_cpu.m_pMemoryMap->InsertReadMap(HW_REG_BEGIN, HW_REG_END, bind(&CPsxVm::ReadIoRegister, this, _1), 0x05); + m_cpu.m_pMemoryMap->InsertReadMap(0x1F800000, 0x1F8003FF, m_scratchPad, 0x05); + m_cpu.m_pMemoryMap->InsertReadMap(HW_REG_BEGIN, HW_REG_END, bind(&CPsxVm::ReadIoRegister, this, _1), 0x06); //Write memory map m_cpu.m_pMemoryMap->InsertWriteMap((0 * RAMSIZE), (0 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x01); m_cpu.m_pMemoryMap->InsertWriteMap((1 * RAMSIZE), (1 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x02); m_cpu.m_pMemoryMap->InsertWriteMap((2 * RAMSIZE), (2 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x03); m_cpu.m_pMemoryMap->InsertWriteMap((3 * RAMSIZE), (3 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x04); - m_cpu.m_pMemoryMap->InsertWriteMap(HW_REG_BEGIN, HW_REG_END, bind(&CPsxVm::WriteIoRegister, this, _1, _2), 0x05); + m_cpu.m_pMemoryMap->InsertWriteMap(0x1F800000, 0x1F8003FF, m_scratchPad, 0x05); + m_cpu.m_pMemoryMap->InsertWriteMap(HW_REG_BEGIN, HW_REG_END, bind(&CPsxVm::WriteIoRegister, this, _1, _2), 0x06); //Instruction memory map m_cpu.m_pMemoryMap->InsertInstructionMap((0 * RAMSIZE), (0 * RAMSIZE) + RAMSIZE - 1, m_ram, 0x01); @@ -65,11 +68,13 @@ CPsxVm::~CPsxVm() m_cpu.m_Comments.Serialize("rawr.comments"); #endif delete [] m_ram; + delete [] m_scratchPad; } void CPsxVm::Reset() { memset(m_ram, 0, RAMSIZE); + memset(m_scratchPad, 0, SCRATCHSIZE); m_executor.Clear(); m_cpu.Reset(); m_bios.Reset(); diff --git a/tools/PsfPlayer2/Source/PsxVm.h b/tools/PsfPlayer2/Source/PsxVm.h index 1922929c..1288ad47 100644 --- a/tools/PsfPlayer2/Source/PsxVm.h +++ b/tools/PsfPlayer2/Source/PsxVm.h @@ -23,6 +23,11 @@ public: RAMSIZE = 0x00200000 }; + enum SCRATCHSIZE + { + SCRATCHSIZE = 0x00000400, + }; + CPsxVm(); virtual ~CPsxVm(); @@ -78,6 +83,7 @@ private: STATUS m_status; uint8* m_ram; + uint8* m_scratchPad; Psx::CIntc m_intc; CSpu m_spu; Psx::CRootCounters m_counters;