660 lines
20 KiB
C
660 lines
20 KiB
C
/*
|
|
* Project 64 - A Nintendo 64 emulator.
|
|
*
|
|
* (c) Copyright 2001 zilmar (zilmar@emulation64.com) and
|
|
* Jabo (jabo@emulation64.com).
|
|
*
|
|
* pj64 homepage: www.pj64.net
|
|
*
|
|
* Permission to use, copy, modify and distribute Project64 in both binary and
|
|
* source form, for non-commercial purposes, is hereby granted without fee,
|
|
* providing that this license information and copyright notice appear with
|
|
* all copies and any derived work.
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event shall the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
*
|
|
* Project64 is freeware for PERSONAL USE only. Commercial users should
|
|
* seek permission of the copyright holders first. Commercial use includes
|
|
* charging money for Project64 or software derived from Project64.
|
|
*
|
|
* The copyright holders request that bug fixes and improvements to the code
|
|
* should be forwarded to them so if they want them.
|
|
*
|
|
*/
|
|
#ifdef todelete
|
|
|
|
#include <Windows.h>
|
|
#include <stdio.h>
|
|
#include "main.h"
|
|
#include "cpu.h"
|
|
#include "debugger.h"
|
|
#include "plugin.h"
|
|
|
|
#define MaxMemory 2000
|
|
|
|
void StartErrorLog ( void );
|
|
void StopErrorLog ( void );
|
|
void WriteSyncMemoryLineDump ( char * Label, BYTE * Memory );
|
|
|
|
DWORD CurrentBlock, *TLB_SyncReadMap, *TLB_SyncWriteMap, * MemAddrUsed[2] = { NULL,NULL };
|
|
int SyncNextInstruction, SyncJumpToLocation;
|
|
HANDLE hErrorLogFile = NULL;
|
|
N64_REGISTERS SyncRegisters;
|
|
int MemAddrUsedCount[2];
|
|
BYTE * SyncMemory;
|
|
|
|
#ifdef toremove
|
|
//TLB
|
|
//FASTTLB SyncFastTlb[64];
|
|
//TLB SyncTlb[32];
|
|
#endif
|
|
|
|
int Sync_MemoryFilter( DWORD dwExptCode, LPEXCEPTION_POINTERS lpEP);
|
|
|
|
void AllocateSyncMemory ( void ) {
|
|
DWORD * TempReadMap, *TempWriteMap;
|
|
BYTE * TempMemPtr;
|
|
FreeSyncMemory();
|
|
|
|
if(SyncMemory==NULL) {
|
|
DisplayError(GS(MSG_MEM_ALLOC_ERROR));
|
|
ExitThread(0);
|
|
}
|
|
|
|
if(VirtualAlloc(SyncMemory, RdramSize, MEM_COMMIT, PAGE_READWRITE)==NULL) {
|
|
DisplayError(GS(MSG_MEM_ALLOC_ERROR));
|
|
ExitThread(0);
|
|
}
|
|
|
|
if(VirtualAlloc(SyncMemory + 0x04000000, 0x2000, MEM_COMMIT, PAGE_READWRITE)==NULL) {
|
|
DisplayError(GS(MSG_MEM_ALLOC_ERROR));
|
|
ExitThread(0);
|
|
}
|
|
|
|
TLB_SyncReadMap = (DWORD *)VirtualAlloc(NULL,0xFFFFF * sizeof(DWORD),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
|
if (TLB_SyncReadMap == NULL) {
|
|
DisplayError(GS(MSG_MEM_ALLOC_ERROR));
|
|
ExitThread(0);
|
|
}
|
|
|
|
TLB_SyncWriteMap = (DWORD *)VirtualAlloc(NULL,0xFFFFF * sizeof(DWORD),MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
|
|
if (TLB_SyncWriteMap == NULL) {
|
|
DisplayError(GS(MSG_MEM_ALLOC_ERROR));
|
|
ExitThread(0);
|
|
}
|
|
|
|
MemAddrUsed[0] = (DWORD *)malloc(MaxMemory * sizeof(DWORD *));
|
|
MemAddrUsed[1] = (DWORD *)malloc(MaxMemory * sizeof(DWORD *));
|
|
|
|
TempReadMap = TLB_ReadMap;
|
|
TLB_ReadMap = TLB_SyncReadMap;
|
|
TLB_SyncReadMap = TempReadMap;
|
|
|
|
TempWriteMap = TLB_WriteMap;
|
|
TLB_WriteMap = TLB_SyncWriteMap;
|
|
TLB_SyncWriteMap = TempWriteMap;
|
|
|
|
TempMemPtr = N64MEM;
|
|
N64MEM = SyncMemory;
|
|
RDRAM = (unsigned char *)(N64MEM);
|
|
DMEM = (unsigned char *)(N64MEM+0x04000000);
|
|
IMEM = (unsigned char *)(N64MEM+0x04001000);
|
|
SyncMemory = TempMemPtr;
|
|
|
|
InitilizeTLB();
|
|
memcpy(SyncFastTlb,FastTlb,sizeof(FastTlb));
|
|
memcpy(SyncTlb,tlb,sizeof(tlb));
|
|
}
|
|
|
|
void __cdecl Error_Message (char * Message, ...) {
|
|
DWORD dwWritten;
|
|
char Msg[400];
|
|
va_list ap;
|
|
|
|
if (hErrorLogFile == NULL) { StartErrorLog(); }
|
|
va_start( ap, Message );
|
|
vsprintf( Msg, Message, ap );
|
|
va_end( ap );
|
|
|
|
strcat(Msg,"\r\n");
|
|
|
|
WriteFile( hErrorLogFile,Msg,strlen(Msg),&dwWritten,NULL );
|
|
}
|
|
|
|
void FreeSyncMemory (void) {
|
|
if (TLB_SyncReadMap) {
|
|
VirtualFree( TLB_SyncReadMap, 0 , MEM_RELEASE);
|
|
TLB_SyncReadMap = NULL;
|
|
}
|
|
if (TLB_SyncWriteMap) {
|
|
VirtualFree( TLB_SyncWriteMap, 0 , MEM_RELEASE);
|
|
TLB_SyncWriteMap = NULL;
|
|
}
|
|
if (MemAddrUsed[0]) { free(MemAddrUsed[0]); }
|
|
MemAddrUsed[0] = NULL;
|
|
if (MemAddrUsed[1]) { free(MemAddrUsed[1]); }
|
|
MemAddrUsed[1] = NULL;
|
|
}
|
|
|
|
void ProtectMemory (void) {
|
|
DWORD OldProtect;
|
|
|
|
VirtualProtect(N64MEM,RdramSize,PAGE_READONLY,&OldProtect);
|
|
VirtualProtect(N64MEM + 0x04000000,0x2000,PAGE_READONLY,&OldProtect);
|
|
}
|
|
|
|
void ReInitializeRSP (void) {
|
|
#ifdef hhhh
|
|
RSP_INFO_1_0 RspInfo10;
|
|
RSP_INFO_1_1 RspInfo11;
|
|
|
|
RspInfo10.CheckInterrupts = CheckInterrupts;
|
|
RspInfo11.CheckInterrupts = CheckInterrupts;
|
|
RspInfo10.ProcessDlist = ProcessDList;
|
|
RspInfo11.ProcessDlist = ProcessDList;
|
|
RspInfo10.ProcessAlist = ProcessAList;
|
|
RspInfo11.ProcessAlist = ProcessAList;
|
|
RspInfo10.ProcessRdpList = ProcessRDPList;
|
|
RspInfo11.ProcessRdpList = ProcessRDPList;
|
|
RspInfo11.ShowCFB = ShowCFB;
|
|
|
|
RspInfo10.hInst = hInst;
|
|
RspInfo11.hInst = hInst;
|
|
RspInfo10.RDRAM = N64MEM;
|
|
RspInfo11.RDRAM = N64MEM;
|
|
RspInfo10.DMEM = DMEM;
|
|
RspInfo11.DMEM = DMEM;
|
|
RspInfo10.IMEM = IMEM;
|
|
RspInfo11.IMEM = IMEM;
|
|
RspInfo10.MemoryBswaped = FALSE;
|
|
RspInfo11.MemoryBswaped = FALSE;
|
|
|
|
RspInfo10.MI__INTR_REG = &MI_INTR_REG;
|
|
RspInfo11.MI__INTR_REG = &MI_INTR_REG;
|
|
|
|
RspInfo10.SP__MEM_ADDR_REG = &SP_MEM_ADDR_REG;
|
|
RspInfo11.SP__MEM_ADDR_REG = &SP_MEM_ADDR_REG;
|
|
RspInfo10.SP__DRAM_ADDR_REG = &SP_DRAM_ADDR_REG;
|
|
RspInfo11.SP__DRAM_ADDR_REG = &SP_DRAM_ADDR_REG;
|
|
RspInfo10.SP__RD_LEN_REG = &SP_RD_LEN_REG;
|
|
RspInfo11.SP__RD_LEN_REG = &SP_RD_LEN_REG;
|
|
RspInfo10.SP__WR_LEN_REG = &SP_WR_LEN_REG;
|
|
RspInfo11.SP__WR_LEN_REG = &SP_WR_LEN_REG;
|
|
RspInfo10.SP__STATUS_REG = &SP_STATUS_REG;
|
|
RspInfo11.SP__STATUS_REG = &SP_STATUS_REG;
|
|
RspInfo10.SP__DMA_FULL_REG = &SP_DMA_FULL_REG;
|
|
RspInfo11.SP__DMA_FULL_REG = &SP_DMA_FULL_REG;
|
|
RspInfo10.SP__DMA_BUSY_REG = &SP_DMA_BUSY_REG;
|
|
RspInfo11.SP__DMA_BUSY_REG = &SP_DMA_BUSY_REG;
|
|
RspInfo10.SP__PC_REG = &SP_PC_REG;
|
|
RspInfo11.SP__PC_REG = &SP_PC_REG;
|
|
RspInfo10.SP__SEMAPHORE_REG = &SP_SEMAPHORE_REG;
|
|
RspInfo11.SP__SEMAPHORE_REG = &SP_SEMAPHORE_REG;
|
|
|
|
RspInfo10.DPC__START_REG = &DPC_START_REG;
|
|
RspInfo11.DPC__START_REG = &DPC_START_REG;
|
|
RspInfo10.DPC__END_REG = &DPC_END_REG;
|
|
RspInfo11.DPC__END_REG = &DPC_END_REG;
|
|
RspInfo10.DPC__CURRENT_REG = &DPC_CURRENT_REG;
|
|
RspInfo11.DPC__CURRENT_REG = &DPC_CURRENT_REG;
|
|
RspInfo10.DPC__STATUS_REG = &DPC_STATUS_REG;
|
|
RspInfo11.DPC__STATUS_REG = &DPC_STATUS_REG;
|
|
RspInfo10.DPC__CLOCK_REG = &DPC_CLOCK_REG;
|
|
RspInfo11.DPC__CLOCK_REG = &DPC_CLOCK_REG;
|
|
RspInfo10.DPC__BUFBUSY_REG = &DPC_BUFBUSY_REG;
|
|
RspInfo11.DPC__BUFBUSY_REG = &DPC_BUFBUSY_REG;
|
|
RspInfo10.DPC__PIPEBUSY_REG = &DPC_PIPEBUSY_REG;
|
|
RspInfo11.DPC__PIPEBUSY_REG = &DPC_PIPEBUSY_REG;
|
|
RspInfo10.DPC__TMEM_REG = &DPC_TMEM_REG;
|
|
RspInfo11.DPC__TMEM_REG = &DPC_TMEM_REG;
|
|
|
|
if (RSPVersion == 0x0100) { InitiateRSP_1_0(RspInfo10, &RspTaskValue); }
|
|
if (RSPVersion == 0x0101) { InitiateRSP_1_1(RspInfo11, &RspTaskValue); }
|
|
#else
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}
|
|
|
|
void StartErrorLog (void) {
|
|
#ifdef ggg
|
|
char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR];
|
|
char fname[_MAX_FNAME],ext[_MAX_EXT], LogFileName[_MAX_PATH];
|
|
|
|
GetModuleFileName(NULL,path_buffer,sizeof(path_buffer));
|
|
_splitpath( path_buffer, drive, dir, fname, ext );
|
|
_makepath( LogFileName, drive, dir, "CPU Error", "log" );
|
|
|
|
hErrorLogFile = CreateFile(LogFileName,GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
|
|
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
|
SetFilePointer(hErrorLogFile,0,NULL,FILE_BEGIN);
|
|
|
|
Error_Message("=== Error Has occured !?! ===");
|
|
Error_Message("Block Address: 0x%X",CurrentBlock);
|
|
if (PROGRAM_COUNTER != Registers.PROGRAM_COUNTER) {
|
|
Error_Message("interp PC: 0x%08X",PROGRAM_COUNTER);
|
|
Error_Message("Recomp PC: 0x%08X",Registers.PROGRAM_COUNTER);
|
|
} else {
|
|
Error_Message("PC: 0x%08X",PROGRAM_COUNTER);
|
|
}
|
|
Error_Message("");
|
|
#else
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}
|
|
|
|
#ifdef todelete
|
|
void StartSyncCPU (void ) {
|
|
#ifdef hhh
|
|
DWORD Addr;
|
|
BYTE * Block;
|
|
#ifdef Log_x86Code
|
|
Start_x86_Log();
|
|
#endif
|
|
|
|
ResetRecompCode();
|
|
AllocateSyncMemory();
|
|
Registers.PROGRAM_COUNTER = PROGRAM_COUNTER;
|
|
Registers.HI.DW = HI.DW;
|
|
Registers.LO.DW = LO.DW;
|
|
Registers.DMAUsed = DMAUsed;
|
|
memcpy(&SyncRegisters,&Registers,sizeof(Registers));
|
|
memcpy(N64MEM,SyncMemory,RdramSize);
|
|
memcpy(N64MEM + 0x04000000,SyncMemory + 0x04000000,0x2000);
|
|
ProtectMemory();
|
|
SyncNextInstruction = NORMAL;
|
|
SyncJumpToLocation = -1;
|
|
__try {
|
|
for (;;) {
|
|
Addr = PROGRAM_COUNTER;
|
|
if (UseTlb) {
|
|
if (!TranslateVaddr(&Addr)) {
|
|
DoTLBMiss(NextInstruction == DELAY_SLOT,PROGRAM_COUNTER);
|
|
NextInstruction = NORMAL;
|
|
Addr = PROGRAM_COUNTER;
|
|
if (!TranslateVaddr(&Addr)) {
|
|
DisplayError("Failed to tranlate PC to a PAddr: %X\n\nEmulation stopped",PROGRAM_COUNTER);
|
|
ExitThread(0);
|
|
}
|
|
}
|
|
} else {
|
|
Addr &= 0x1FFFFFFF;
|
|
}
|
|
if (NextInstruction == DELAY_SLOT) {
|
|
__try {
|
|
Block = *(DelaySlotTable + (Addr >> 12));
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DisplayError("Executing Delay Slot from non maped space");
|
|
ExitThread(0);
|
|
}
|
|
if (Block == NULL) {
|
|
Block = CompileDelaySlot();
|
|
*(DelaySlotTable + (Addr >> 12)) = Block;
|
|
NextInstruction = NORMAL;
|
|
}
|
|
_asm {
|
|
pushad
|
|
call Block
|
|
popad
|
|
}
|
|
continue;
|
|
}
|
|
__try {
|
|
Block = *(JumpTable + (Addr >> 2));
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DisplayError(GS(MSG_NONMAPPED_SPACE));
|
|
ExitThread(0);
|
|
}
|
|
if (Block == NULL) {
|
|
__try {
|
|
Block = Compiler4300iBlock();
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
DisplayError("Reset Recompiler Code");
|
|
//ResetRecompCode();
|
|
//Block = Compiler4300iBlock();
|
|
}
|
|
*(JumpTable + (Addr >> 2)) = Block;
|
|
NextInstruction = NORMAL;
|
|
}
|
|
_asm {
|
|
pushad
|
|
call Block
|
|
popad
|
|
}
|
|
}
|
|
} __except( Sync_MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) {
|
|
DisplayError(GS(MSG_UNKNOWN_MEM_ACTION));
|
|
ExitThread(0);
|
|
}
|
|
#else
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
void StopErrorLog (void) {
|
|
if (hErrorLogFile) {
|
|
CloseHandle(hErrorLogFile);
|
|
hErrorLogFile = NULL;
|
|
}
|
|
}
|
|
|
|
void SwitchSyncRegisters (void) {
|
|
_Notify->BreakPoint(__FILE__,__LINE__);
|
|
#ifdef tofix
|
|
FASTTLB TempFastTlb[64];
|
|
TLB Temptlb[32];
|
|
BYTE * TempMemPtr;
|
|
DWORD * Temp;
|
|
|
|
if (GPR == Registers.GPR) {
|
|
Registers.PROGRAM_COUNTER = PROGRAM_COUNTER;
|
|
Registers.HI.DW = HI.DW;
|
|
Registers.LO.DW = LO.DW;
|
|
Registers.DMAUsed = DMAUsed;
|
|
SetupRegisters(&SyncRegisters);
|
|
} else {
|
|
SyncRegisters.PROGRAM_COUNTER = PROGRAM_COUNTER;
|
|
SyncRegisters.HI.DW = HI.DW;
|
|
SyncRegisters.LO.DW = LO.DW;
|
|
SyncRegisters.DMAUsed = DMAUsed;
|
|
SetupRegisters(&Registers);
|
|
}
|
|
|
|
Temp = MemAddrUsed[1];
|
|
MemAddrUsed[1] = MemAddrUsed[0];
|
|
MemAddrUsed[0] = Temp;
|
|
MemAddrUsedCount[1] = MemAddrUsedCount[0];
|
|
MemAddrUsedCount[0] = 0;
|
|
|
|
memcpy(TempFastTlb,FastTlb,sizeof(FastTlb));
|
|
memcpy(FastTlb,SyncFastTlb,sizeof(FastTlb));
|
|
memcpy(SyncFastTlb,TempFastTlb,sizeof(FastTlb));
|
|
|
|
memcpy(Temptlb,tlb,sizeof(tlb));
|
|
memcpy(tlb,SyncTlb,sizeof(tlb));
|
|
memcpy(SyncTlb,Temptlb,sizeof(tlb));
|
|
|
|
Temp = TLB_ReadMap;
|
|
TLB_ReadMap = TLB_SyncReadMap;
|
|
TLB_SyncReadMap = Temp;
|
|
|
|
Temp = TLB_WriteMap;
|
|
TLB_WriteMap = TLB_SyncWriteMap;
|
|
TLB_SyncWriteMap = Temp;
|
|
|
|
TempMemPtr = N64MEM;
|
|
N64MEM = SyncMemory;
|
|
RDRAM = (unsigned char *)(N64MEM);
|
|
DMEM = (unsigned char *)(N64MEM+0x04000000);
|
|
IMEM = (unsigned char *)(N64MEM+0x04001000);
|
|
SyncMemory = TempMemPtr;
|
|
ReInitializeRSP();
|
|
ProtectMemory();
|
|
#else
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}
|
|
|
|
/*void SyncSystem (void) {
|
|
#ifdef hhhh
|
|
int count, i, error;
|
|
|
|
error = FALSE;
|
|
if (PROGRAM_COUNTER != Registers.PROGRAM_COUNTER) {
|
|
error = TRUE;
|
|
Error_Message("*** Program counter is not equal!!!");
|
|
Error_Message("");
|
|
}
|
|
|
|
//GPR
|
|
for (count = 0; count < 32; count ++) {
|
|
if (Registers.GPR[count].DW != SyncRegisters.GPR[count].DW) {
|
|
error = TRUE;
|
|
Error_Message("*** %s (GPR %d) is not equal!!!",GPR_Name[count],count);
|
|
Error_Message("interp value: 0x%08X%08X",SyncRegisters.GPR[count].UW[1],SyncRegisters.GPR[count].UW[0]);
|
|
Error_Message("Recomp value: 0x%08X%08X",Registers.GPR[count].UW[1],Registers.GPR[count].UW[0]);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
//COP0
|
|
FixRandomReg();
|
|
for (count = 0; count < 33; count ++) {
|
|
if (Registers.CP0[count] != SyncRegisters.CP0[count]) {
|
|
error = TRUE;
|
|
Error_Message("*** %s (CP0 %d) is not equal!!!",count == 32?"Fake cause":Cop0_Name[count],count);
|
|
Error_Message("interp value: 0x%08X",SyncRegisters.CP0[count]);
|
|
Error_Message("Recomp value: 0x%08X",Registers.CP0[count]);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
//FPU
|
|
for (count = 0; count < 32; count ++) {
|
|
if (Registers.FPR[count].DW != SyncRegisters.FPR[count].DW) {
|
|
error = TRUE;
|
|
Error_Message("*** %s (FPR %d) is not equal!!!",FPR_Name[count],count);
|
|
Error_Message("interp value: 0x%08X%08X",SyncRegisters.FPR[count].UW[1],SyncRegisters.FPR[count].UW[0]);
|
|
Error_Message("Recomp value: 0x%08X%08X",Registers.FPR[count].UW[1],Registers.FPR[count].UW[0]);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
if (Registers.FPCR[31] != SyncRegisters.FPCR[31]) {
|
|
error = TRUE;
|
|
Error_Message("*** %s is not equal!!!",FPR_Ctrl_Name[31]);
|
|
Error_Message("interp value: 0x%08X",SyncRegisters.FPCR[31]);
|
|
Error_Message("Recomp value: 0x%08X",Registers.FPCR[31]);
|
|
Error_Message("");
|
|
}
|
|
//HI
|
|
if (Registers.HI.DW != HI.DW) {
|
|
error = TRUE;
|
|
Error_Message("*** HI register is not equal!!!");
|
|
Error_Message("interp value: 0x%08X",HI.DW);
|
|
Error_Message("Recomp value: 0x%08X",Registers.HI.DW);
|
|
Error_Message("");
|
|
}
|
|
|
|
//LO
|
|
if (Registers.LO.DW != LO.DW) {
|
|
error = TRUE;
|
|
Error_Message("*** LO register is not equal!!!");
|
|
Error_Message("interp value: 0x%08X",LO.DW);
|
|
Error_Message("Recomp value: 0x%08X",Registers.LO.DW);
|
|
Error_Message("");
|
|
}
|
|
|
|
//TLB
|
|
for (count = 0; count < 32; count ++) {
|
|
if (tlb[count].PageMask.Value != SyncTlb[count].PageMask.Value) {
|
|
error = TRUE;
|
|
Error_Message("*** tlb[%d].PageMask is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncTlb[count].PageMask.Value);
|
|
Error_Message("Recomp value: 0x%08X",tlb[count].PageMask.Value );
|
|
Error_Message("");
|
|
}
|
|
if (tlb[count].EntryHi.Value != SyncTlb[count].EntryHi.Value) {
|
|
error = TRUE;
|
|
Error_Message("*** tlb[%d].EntryHi is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncTlb[count].EntryHi.Value);
|
|
Error_Message("Recomp value: 0x%08X",tlb[count].EntryHi.Value );
|
|
Error_Message("");
|
|
}
|
|
if (tlb[count].EntryLo0.Value != SyncTlb[count].EntryLo0.Value) {
|
|
error = TRUE;
|
|
Error_Message("*** tlb[%d].PageMask is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncTlb[count].EntryLo0.Value);
|
|
Error_Message("Recomp value: 0x%08X",tlb[count].EntryLo0.Value );
|
|
Error_Message("");
|
|
}
|
|
if (tlb[count].EntryLo1.Value != SyncTlb[count].EntryLo1.Value) {
|
|
error = TRUE;
|
|
Error_Message("*** tlb[%d].PageMask is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncTlb[count].EntryLo1.Value);
|
|
Error_Message("Recomp value: 0x%08X",tlb[count].EntryLo1.Value );
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
//Mips Interface
|
|
for (count = 0; count < 4; count ++) {
|
|
if (Registers.MI[count] != SyncRegisters.MI[count]) {
|
|
error = TRUE;
|
|
Error_Message("*** MI %d is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncRegisters.MI[count]);
|
|
Error_Message("Recomp value: 0x%08X",Registers.MI[count]);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
//PI Interface
|
|
for (count = 0; count < 12; count ++) {
|
|
if (Registers.PI[count] != SyncRegisters.PI[count]) {
|
|
error = TRUE;
|
|
Error_Message("*** PI %d is not equal!!!",count);
|
|
Error_Message("interp value: 0x%08X",SyncRegisters.PI[count]);
|
|
Error_Message("Recomp value: 0x%08X",Registers.PI[count]);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
|
|
//Memory
|
|
for (count = 0; count < MemAddrUsedCount[0]; count ++) {
|
|
int count2;
|
|
|
|
for (count2 = 0; count2 < MemAddrUsedCount[1]; count2 ++) {
|
|
if (MemAddrUsed[0][count] == MemAddrUsed[1][count2]) {
|
|
MemAddrUsed[1][count2] = (DWORD)-1;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < 2; i++) {
|
|
for (count = 0; count < MemAddrUsedCount[i]; count ++) {
|
|
DWORD count2;
|
|
|
|
if (MemAddrUsed[i][count] == (DWORD)-1) { continue; }
|
|
if (memcmp(N64MEM + MemAddrUsed[i][count], SyncMemory + MemAddrUsed[i][count],0xFFF) == 0) {
|
|
continue;
|
|
}
|
|
error = TRUE;
|
|
for (count2 = MemAddrUsed[i][count]; count2 < (MemAddrUsed[i][count] + 0x1000); count2 += 0x10) {
|
|
if (memcmp(N64MEM + count2, SyncMemory + count2,0x10) == 0) { continue; }
|
|
Error_Message("*** Memory (Address: %X) is not equal!!!",count2);
|
|
WriteSyncMemoryLineDump("Interp",N64MEM + count2);
|
|
WriteSyncMemoryLineDump("Recomp",SyncMemory + count2);
|
|
Error_Message("");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (error) {
|
|
SwitchSyncRegisters();
|
|
DisplayError("Sync Error has occured see log for details\n\nEmulation Has stoped");
|
|
ExitThread(0);
|
|
}
|
|
#else
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}*/
|
|
|
|
void SyncToPC (void) {
|
|
FixRandomReg();
|
|
SyncSystem ();
|
|
return;
|
|
#ifdef toremove
|
|
|
|
{
|
|
int RecNextInstruction, RecJumpToLocation;
|
|
|
|
//LogMessage("Recompiler (PC: %X count: %X)",PROGRAM_COUNTER,CP0[9]);
|
|
RecNextInstruction = NextInstruction;
|
|
RecJumpToLocation = JumpToLocation;
|
|
NextInstruction = SyncNextInstruction;
|
|
JumpToLocation = SyncJumpToLocation;
|
|
|
|
SwitchSyncRegisters();
|
|
/*if ((DWORD)RecompPos > 0x609844D8) {
|
|
while (PROGRAM_COUNTER != Registers.PROGRAM_COUNTER) {
|
|
ExecuteInterpreterOpCode();
|
|
}
|
|
} else {
|
|
while (CP0[9] != Registers.CP0[9]) {
|
|
ExecuteInterpreterOpCode();
|
|
}
|
|
}*/
|
|
while (CP0[9] != Registers.CP0[9]) {
|
|
ExecuteInterpreterOpCode();
|
|
}
|
|
SyncRegisters.MI[2] = Registers.MI[2]; //MI_INTR_REG
|
|
SyncRegisters.CP0[32] = Registers.CP0[32]; //FAKE_CAUSE_REGISTER
|
|
SyncSystem ();
|
|
SwitchSyncRegisters();
|
|
|
|
SyncNextInstruction = NextInstruction;
|
|
SyncJumpToLocation = JumpToLocation;
|
|
NextInstruction = RecNextInstruction;
|
|
JumpToLocation = RecJumpToLocation;
|
|
|
|
MemAddrUsedCount[0] = 0;
|
|
MemAddrUsedCount[1] = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
int Sync_MemoryFilter( DWORD dwExptCode, LPEXCEPTION_POINTERS lpEP) {
|
|
DWORD MemAddress = (char *)lpEP->ExceptionRecord->ExceptionInformation[1] - (char *)N64MEM;
|
|
EXCEPTION_RECORD exRec;
|
|
|
|
if (dwExptCode != EXCEPTION_ACCESS_VIOLATION) {
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
exRec = *lpEP->ExceptionRecord;
|
|
|
|
if ((int)((char *)lpEP->ExceptionRecord->ExceptionInformation[1] - N64MEM) < 0) {
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
if ((int)((char *)lpEP->ExceptionRecord->ExceptionInformation[1] - N64MEM) > 0x1FFFFFFF) {
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
if (MemAddress < RdramSize || (MemAddress >= 0x4000000 && MemAddress < 0x4002000)) {
|
|
DWORD OldProtect;
|
|
|
|
VirtualProtect(N64MEM+(MemAddress & 0xFFFFF000),0xFFF,PAGE_READWRITE,&OldProtect);
|
|
MemAddrUsed[0][MemAddrUsedCount[0]] = (MemAddress & 0xFFFFF000);
|
|
MemAddrUsedCount[0] += 1;
|
|
if (MemAddrUsedCount[0] == MaxMemory) {
|
|
DisplayError("Used up all sync blocks ????");
|
|
ExitThread(0);
|
|
}
|
|
if (CPU_Type != ModCode_ProtectedMemory) { return EXCEPTION_CONTINUE_EXECUTION; }
|
|
}
|
|
return r4300i_CPU_MemoryFilter(dwExptCode,lpEP);
|
|
}
|
|
|
|
void WriteSyncMemoryLineDump (char * Label, BYTE * Memory) {
|
|
char Hex[100], Ascii[30];
|
|
DWORD count;
|
|
|
|
memset(&Hex,0,sizeof(Hex));
|
|
memset(&Ascii,0,sizeof(Ascii));
|
|
|
|
for (count = 0; count < 0x10; count ++ ) {
|
|
if ((count % 4) != 0 || count == 0) {
|
|
sprintf(Hex,"%s %02X",Hex,Memory[count]);
|
|
} else {
|
|
sprintf(Hex,"%s - %02X",Hex,Memory[count]);
|
|
}
|
|
if (Memory[count] < 30 || Memory[count] > 127) {
|
|
strcat(Ascii,".");
|
|
} else {
|
|
sprintf(Ascii,"%s%c",Ascii,Memory[count]);
|
|
}
|
|
}
|
|
Error_Message("%s:%s %s",Label,Hex,Ascii);
|
|
}
|
|
|
|
#endif |