project64/Source/Project64/N64 System/C Core/C Memory.cpp

404 lines
14 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 toremove
#include <windows.h>
#include <stdio.h>
#include "main.h"
#include "cpu.h"
#include "x86.h"
#include "plugin.h"
#include "debugger.h"
void ** JumpTable, ** DelaySlotTable;
BYTE *RecompPos;
BOOL WrittenToRom;
DWORD WroteToRom;
DWORD TempValue;
int r4300i_Command_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)((BYTE *)lpEP->ExceptionRecord->ExceptionInformation[1] - N64MEM) < 0) {
return EXCEPTION_CONTINUE_SEARCH;
}
if ((int)((BYTE *)lpEP->ExceptionRecord->ExceptionInformation[1] - N64MEM) > 0x1FFFFFFF) {
return EXCEPTION_CONTINUE_SEARCH;
}
switch(*(unsigned char *)lpEP->ContextRecord->Eip) {
case 0x8B:
switch(*(unsigned char *)(lpEP->ContextRecord->Eip + 1)) {
case 0x04:
lpEP->ContextRecord->Eip += 3;
r4300i_LW_NonMemory((char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
&lpEP->ContextRecord->Eax);
return EXCEPTION_CONTINUE_EXECUTION;
break;
case 0x0C:
lpEP->ContextRecord->Eip += 3;
r4300i_LW_NonMemory((char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
&lpEP->ContextRecord->Ecx);
return EXCEPTION_CONTINUE_EXECUTION;
break;
default:
DisplayError("Unknown x86 opcode %X\nlocation %X\nN64mem loc: %X",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)N64MEM);
//return EXCEPTION_EXECUTE_HANDLER;
return EXCEPTION_CONTINUE_SEARCH;
}
break;
default:
DisplayError("Unknown x86 opcode %X\nlocation %X\nloc: %X\n2",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
//return EXCEPTION_EXECUTE_HANDLER;
return EXCEPTION_CONTINUE_SEARCH;
}
DisplayError("Unknown x86 opcode %X\nlocation %X\nN64mem loc: %X\nAddress: %X",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)N64MEM,
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
DisplayError("r4300i: CPU Memory Filter\n\nWTF");
return EXCEPTION_CONTINUE_SEARCH;
}
int r4300i_CPU_MemoryFilter( DWORD dwExptCode, LPEXCEPTION_POINTERS lpEP) {
DWORD MemAddress = (char *)lpEP->ExceptionRecord->ExceptionInformation[1] - (char *)N64MEM;
EXCEPTION_RECORD exRec;
BYTE * ReadPos, *TypePos;
DWORD * Reg;
if (dwExptCode != EXCEPTION_ACCESS_VIOLATION) {
return EXCEPTION_CONTINUE_SEARCH;
}
TypePos = (unsigned char *)lpEP->ContextRecord->Eip;
exRec = *lpEP->ExceptionRecord;
if ((int)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF) { return EXCEPTION_CONTINUE_SEARCH; }
if (*TypePos == 0xF3 && *(TypePos + 1) == 0xA5) {
DWORD Start, End, count, OldProtect;
Start = (lpEP->ContextRecord->Edi - (DWORD)N64MEM);
End = (Start + (lpEP->ContextRecord->Ecx << 2) - 1);
if ((int)Start < 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("hmmm.... where does this dma start ?");
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
#ifdef CFB_READ
if (Start >= CFBStart && End < CFBEnd) {
for ( count = Start; count < End; count += 0x1000 ) {
VirtualProtect(N64MEM+count,4,PAGE_READONLY, &OldProtect);
if (FrameBufferRead) { FrameBufferRead(count & ~0xFFF); }
}
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif
if ((int)End < RdramSize) {
for ( count = Start; count < End; count += 0x1000 ) {
BreakPoint(__FILE__,__LINE__);
if (N64_Blocks.NoOfRDRamBlocks[(count >> 12)] > 0) {
N64_Blocks.NoOfRDRamBlocks[(count >> 12)] = 0;
memset(JumpTable + ((count & 0x00FFFFF0) >> 2),0,0x1000);
*(DelaySlotTable + count) = NULL;
if (VirtualProtect(N64MEM + count, 4, PAGE_READWRITE, &OldProtect) == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Failed to unprotect %X\n1", count);
#endif
}
}
}
return EXCEPTION_CONTINUE_EXECUTION;
}
if (Start >= 0x04000000 && End < 0x04001000) {
BreakPoint(__FILE__,__LINE__);
N64_Blocks.NoOfDMEMBlocks = 0;
memset(JumpTable + (0x04000000 >> 2),0,0x1000);
*(DelaySlotTable + (0x04000000 >> 12)) = NULL;
if (VirtualProtect(N64MEM + 0x04000000, 4, PAGE_READWRITE, &OldProtect) == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Failed to unprotect %X\n7", 0x04000000);
#endif
}
return EXCEPTION_CONTINUE_EXECUTION;
}
if (Start >= 0x04001000 && End < 0x04002000) {
BreakPoint(__FILE__,__LINE__);
N64_Blocks.NoOfIMEMBlocks = 0;
memset(JumpTable + (0x04001000 >> 2),0,0x1000);
*(DelaySlotTable + (0x04001000 >> 12)) = NULL;
if (VirtualProtect(N64MEM + 0x04001000, 4, PAGE_READWRITE, &OldProtect) == 0) {
#ifndef EXTERNAL_RELEASE
DisplayError("Failed to unprotect %X\n6", 0x04001000);
#endif
}
return EXCEPTION_CONTINUE_EXECUTION;
}
#ifndef EXTERNAL_RELEASE
DisplayError("hmmm.... where does this dma End ?\nstart: %X\nend:%X\nlocation %X",
Start,End,lpEP->ContextRecord->Eip);
#endif
return EXCEPTION_CONTINUE_SEARCH;
}
if (*TypePos == 0x0F && *(TypePos + 1) == 0xB6) {
ReadPos = TypePos + 2;
} else if (*TypePos == 0x0F && *(TypePos + 1) == 0xB7) {
ReadPos = TypePos + 2;
} else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBE) {
ReadPos = TypePos + 2;
} else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBF) {
ReadPos = TypePos + 2;
} else if (*TypePos == 0x66) {
ReadPos = TypePos + 2;
} else {
ReadPos = TypePos + 1;
}
switch ((*ReadPos & 0x38)) {
case 0x00: Reg = &lpEP->ContextRecord->Eax; break;
case 0x08: Reg = &lpEP->ContextRecord->Ecx; break;
case 0x10: Reg = &lpEP->ContextRecord->Edx; break;
case 0x18: Reg = &lpEP->ContextRecord->Ebx; break;
case 0x20: Reg = &lpEP->ContextRecord->Esp; break;
case 0x28: Reg = &lpEP->ContextRecord->Ebp; break;
case 0x30: Reg = &lpEP->ContextRecord->Esi; break;
case 0x38: Reg = &lpEP->ContextRecord->Edi; break;
}
switch ((*ReadPos & 0xC7)) {
case 0: ReadPos += 1; break;
case 1: ReadPos += 1; break;
case 2: ReadPos += 1; break;
case 3: ReadPos += 1; break;
case 4:
ReadPos += 1;
switch ((*ReadPos & 0xC7)) {
case 0: ReadPos += 1; break;
case 1: ReadPos += 1; break;
case 2: ReadPos += 1; break;
case 3: ReadPos += 1; break;
case 6: ReadPos += 1; break;
case 7: ReadPos += 1; break;
default:
BreakPoint(__FILE__,__LINE__);
}
break;
case 5: ReadPos += 5; break;
case 6: ReadPos += 1; break;
case 7: ReadPos += 1; break;
case 0x40: ReadPos += 2; break;
case 0x41: ReadPos += 2; break;
case 0x42: ReadPos += 2; break;
case 0x43: ReadPos += 2; break;
case 0x46: ReadPos += 2; break;
case 0x47: ReadPos += 2; break;
case 0x80: ReadPos += 5; break;
case 0x81: ReadPos += 5; break;
case 0x82: ReadPos += 5; break;
case 0x83: ReadPos += 5; break;
case 0x86: ReadPos += 5; break;
case 0x87: ReadPos += 5; break;
default:
DisplayError("Unknown x86 opcode %X\nlocation %X\nloc: %X\nfgh2",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
return EXCEPTION_CONTINUE_SEARCH;
}
switch(*TypePos) {
case 0x0F:
switch(*(TypePos + 1)) {
case 0xB6:
if (!r4300i_LB_NonMemory(MemAddress,(DWORD *)Reg,FALSE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load byte\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0xB7:
if (!r4300i_LH_NonMemory(MemAddress,(DWORD *)Reg,FALSE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load half word\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0xBE:
if (!r4300i_LB_NonMemory(MemAddress,Reg,TRUE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load byte\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0xBF:
if (!r4300i_LH_NonMemory(MemAddress,Reg,TRUE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load half word\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
default:
DisplayError("Unkown x86 opcode %X\nlocation %X\nloc: %X\nfhfgh2",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
return EXCEPTION_CONTINUE_SEARCH;
}
break;
case 0x66:
switch(*(TypePos + 1)) {
case 0x8B:
if (!r4300i_LH_NonMemory(MemAddress,Reg,FALSE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to half word\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0x89:
if (!r4300i_SH_NonMemory(MemAddress,*(WORD *)Reg)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store half word\n\nMIPS Address: %X\nX86 Address",MemAddress,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0xC7:
if (Reg != &lpEP->ContextRecord->Eax) { return EXCEPTION_CONTINUE_SEARCH; }
if (!r4300i_SH_NonMemory(MemAddress,*(WORD *)ReadPos)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store half word\n\nMIPS Address: %X\nX86 Address",MemAddress,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)(ReadPos + 2);
return EXCEPTION_CONTINUE_EXECUTION;
default:
DisplayError("Unkown x86 opcode %X\nlocation %X\nloc: %X\nfhfgh2",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
return EXCEPTION_CONTINUE_SEARCH;
}
break;
case 0x88:
if (!r4300i_SB_NonMemory(MemAddress,*(BYTE *)Reg)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store byte\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0x8A:
if (!r4300i_LB_NonMemory(MemAddress,Reg,FALSE)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load byte\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0x8B:
if (!r4300i_LW_NonMemory(MemAddress,Reg)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to load word\n\nMIPS Address: %X\nX86 Address",
(char *)exRec.ExceptionInformation[1] - (char *)N64MEM,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0x89:
if (!r4300i_SW_NonMemory(MemAddress,*(DWORD *)Reg)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store word\n\nMIPS Address: %X\nX86 Address",MemAddress,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)ReadPos;
return EXCEPTION_CONTINUE_EXECUTION;
case 0xC6:
if (Reg != &lpEP->ContextRecord->Eax) { return EXCEPTION_CONTINUE_SEARCH; }
if (!r4300i_SB_NonMemory(MemAddress,*(BYTE *)ReadPos)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store byte\n\nMIPS Address: %X\nX86 Address",MemAddress,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)(ReadPos + 1);
return EXCEPTION_CONTINUE_EXECUTION;
case 0xC7:
if (Reg != &lpEP->ContextRecord->Eax) { return EXCEPTION_CONTINUE_SEARCH; }
if (!r4300i_SW_NonMemory(MemAddress,*(DWORD *)ReadPos)) {
if (ShowUnhandledMemory) {
DisplayError("Failed to store word\n\nMIPS Address: %X\nX86 Address",MemAddress,
*(unsigned char *)lpEP->ContextRecord->Eip);
}
}
lpEP->ContextRecord->Eip = (DWORD)(ReadPos + 4);
return EXCEPTION_CONTINUE_EXECUTION;
default:
DisplayError("Unkown x86 opcode %X\nlocation %X\nloc: %X\nfhfgh2",
*(unsigned char *)lpEP->ContextRecord->Eip, lpEP->ContextRecord->Eip, (char *)exRec.ExceptionInformation[1] - (char *)N64MEM);
return EXCEPTION_CONTINUE_SEARCH;
}
}
void r4300i_LW_PAddr ( DWORD PAddr, DWORD * Value ) {
*Value = *(DWORD *)(N64MEM+PAddr);
if (LookUpMode == FuncFind_ChangeMemory)
{
BreakPoint(__FILE__,__LINE__);
// if ( (Command.Hex >> 16) == 0x7C7C) {
// Command.Hex = OrigMem[(Command.Hex & 0xFFFF)].OriginalValue;
// }
}
}
#endif