git-svn-id: https://localhost/svn/Project64/trunk@3 111125ac-702d-7242-af9c-5ba8ae61c1ef

This commit is contained in:
zilmar 2008-11-14 20:47:53 +00:00
parent 28c5a7e77c
commit c99c1d6a6f
73 changed files with 21882 additions and 13 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -110,7 +110,7 @@ private:
fInsertSpaces(WritePos,Newlen - OldLen); fInsertSpaces(WritePos,Newlen - OldLen);
BytesMoved = Newlen - OldLen; BytesMoved = Newlen - OldLen;
} }
}
m_File.Seek(WritePos,CFileStorage::begin); m_File.Seek(WritePos,CFileStorage::begin);
stdstr_f NewData(_T("%s=%s%s"),lpKeyName,lpString,m_LineFeed); stdstr_f NewData(_T("%s=%s%s"),lpKeyName,lpString,m_LineFeed);
@ -121,7 +121,6 @@ private:
{ {
m_File.Flush(); m_File.Flush();
} }
}
if (Input) { delete [] Input; Input = NULL; } if (Input) { delete [] Input; Input = NULL; }
if (Data) { delete [] Data; Data = NULL; } if (Data) { delete [] Data; Data = NULL; }
return true; return true;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -119,6 +119,16 @@ CPath::CPath(LPCTSTR lpszPath)
cleanPathString(m_strPath); cleanPathString(m_strPath);
} }
//-------------------------------------------------------------
// Task : Constructs a path and points it 2 strPath
//-------------------------------------------------------------
CPath::CPath(LPCTSTR strPath, LPCTSTR NameExten )
{
Init();
SetDriveDirectory(strPath);
SetNameExtension(NameExten);
}
//------------------------------------------------------------- //-------------------------------------------------------------
// Task : Constructs a path and points it 2 strPath // Task : Constructs a path and points it 2 strPath
//------------------------------------------------------------- //-------------------------------------------------------------

263
Source/RSP/Cpu.c Normal file
View File

@ -0,0 +1,263 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "RSP.h"
#include "Cpu.h"
#include "RSP registers.h"
#include "RSP Command.h"
#include "Recompiler CPU.h"
#include "memory.h"
#include "opcode.h"
#include "log.h"
#include "Profiling.h"
#include "breakpoint.h"
#include "x86.h"
UDWORD EleSpec[32], Indx[32];
OPCODE RSPOpC;
DWORD *PrgCount, NextInstruction, RSP_Running;
void * RSP_Opcode[64];
void * RSP_RegImm[32];
void * RSP_Special[64];
void * RSP_Cop0[32];
void * RSP_Cop2[32];
void * RSP_Vector[64];
void * RSP_Lc2[32];
void * RSP_Sc2[32];
void BuildInterpreterCPU(void);
void BuildRecompilerCPU(void);
extern HANDLE hMutex;
void SetCPU(DWORD core) {
WaitForSingleObjectEx(hMutex, 1000 * 100, FALSE);
CPUCore = core;
switch (core) {
case RecompilerCPU:
BuildRecompilerCPU();
break;
case InterpreterCPU:
BuildInterpreterCPU();
break;
}
ReleaseMutex(hMutex);
}
void Build_RSP ( void ) {
int i;
extern UWORD32 Recp, RecpResult, SQroot, SQrootResult;
Recp.UW = 0;
RecpResult.UW = 0;
SQroot.UW = 0;
SQrootResult.UW = 0;
SetCPU(CPUCore);
ResetTimerList();
EleSpec[ 0].DW = 0;
EleSpec[ 1].DW = 0;
EleSpec[ 2].DW = 0;
EleSpec[ 3].DW = 0;
EleSpec[ 4].DW = 0;
EleSpec[ 5].DW = 0;
EleSpec[ 6].DW = 0;
EleSpec[ 7].DW = 0;
EleSpec[ 8].DW = 0;
EleSpec[ 9].DW = 0;
EleSpec[10].DW = 0;
EleSpec[11].DW = 0;
EleSpec[12].DW = 0;
EleSpec[13].DW = 0;
EleSpec[14].DW = 0;
EleSpec[15].DW = 0;
EleSpec[16].DW = 0x0001020304050607; /* None */
EleSpec[17].DW = 0x0001020304050607; /* None */
EleSpec[18].DW = 0x0000020204040606; /* 0q */
EleSpec[19].DW = 0x0101030305050707; /* 1q */
EleSpec[20].DW = 0x0000000004040404; /* 0h */
EleSpec[21].DW = 0x0101010105050505; /* 1h */
EleSpec[22].DW = 0x0202020206060606; /* 2h */
EleSpec[23].DW = 0x0303030307070707; /* 3h */
EleSpec[24].DW = 0x0000000000000000; /* 0 */
EleSpec[25].DW = 0x0101010101010101; /* 1 */
EleSpec[26].DW = 0x0202020202020202; /* 2 */
EleSpec[27].DW = 0x0303030303030303; /* 3 */
EleSpec[28].DW = 0x0404040404040404; /* 4 */
EleSpec[29].DW = 0x0505050505050505; /* 5 */
EleSpec[30].DW = 0x0606060606060606; /* 6 */
EleSpec[31].DW = 0x0707070707070707; /* 7 */
Indx[ 0].DW = 0;
Indx[ 1].DW = 0;
Indx[ 2].DW = 0;
Indx[ 3].DW = 0;
Indx[ 4].DW = 0;
Indx[ 5].DW = 0;
Indx[ 6].DW = 0;
Indx[ 7].DW = 0;
Indx[ 8].DW = 0;
Indx[ 9].DW = 0;
Indx[10].DW = 0;
Indx[11].DW = 0;
Indx[12].DW = 0;
Indx[13].DW = 0;
Indx[14].DW = 0;
Indx[15].DW = 0;
Indx[16].DW = 0x0001020304050607; /* None */
Indx[17].DW = 0x0001020304050607; /* None */
Indx[18].DW = 0x0103050700020406; /* 0q */
Indx[19].DW = 0x0002040601030507; /* 1q */
Indx[20].DW = 0x0102030506070004; /* 0h */
Indx[21].DW = 0x0002030406070105; /* 1h */
Indx[22].DW = 0x0001030405070206; /* 2h */
Indx[23].DW = 0x0001020405060307; /* 3h */
Indx[24].DW = 0x0102030405060700; /* 0 */
Indx[25].DW = 0x0002030405060701; /* 1 */
Indx[26].DW = 0x0001030405060702; /* 2 */
Indx[27].DW = 0x0001020405060703; /* 3 */
Indx[28].DW = 0x0001020305060704; /* 4 */
Indx[29].DW = 0x0001020304060705; /* 5 */
Indx[30].DW = 0x0001020304050706; /* 6 */
Indx[31].DW = 0x0001020304050607; /* 7 */
for (i = 16; i < 32; i ++) {
int count;
for (count = 0; count < 8; count ++) {
Indx[i].B[count] = 7 - Indx[i].B[count];
EleSpec[i].B[count] = 7 - EleSpec[i].B[count];
}
for (count = 0; count < 4; count ++) {
BYTE Temp;
Temp = Indx[i].B[count];
Indx[i].B[count] = Indx[i].B[7 - count];
Indx[i].B[7 - count] = Temp;
}
}
PrgCount = RSPInfo.SP_PC_REG;
}
/******************************************************************
Function: DoRspCycles
Purpose: This function is to allow the RSP to run in parrel with
the r4300 switching control back to the r4300 once the
function ends.
input: The number of cylces that is meant to be executed
output: The number of cycles that was executed. This value can
be greater than the number of cycles that the RSP
should have performed.
(this value is ignored if the RSP is stoped)
*******************************************************************/
DWORD RunInterpreterCPU(DWORD Cycles);
DWORD RunRecompilerCPU ( DWORD Cycles );
#define MI_INTR_SP 0x01 /* Bit 0: SP intr */
__declspec(dllexport) DWORD DoRspCycles ( DWORD Cycles ) {
extern BOOL AudioHle, GraphicsHle;
DWORD TaskType = *(DWORD*)(RSPInfo.DMEM + 0xFC0);
/* if (*RSPInfo.SP_STATUS_REG & SP_STATUS_SIG0) {
*RSPInfo.SP_STATUS_REG &= ~SP_STATUS_SIG0;
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
return Cycles;
}
*/
if (TaskType == 1 && GraphicsHle && *(DWORD*)(RSPInfo.DMEM + 0x0ff0) != 0) {
if (RSPInfo.ProcessDList != NULL) {
RSPInfo.ProcessDList();
}
*RSPInfo.SP_STATUS_REG |= (0x0203 );
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
*RSPInfo.MI_INTR_REG |= R4300i_SP_Intr;
RSPInfo.CheckInterrupts();
}
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
return Cycles;
} else if (TaskType == 2 && AudioHle) {
if (RSPInfo.ProcessAList != NULL) {
RSPInfo.ProcessAList();
}
*RSPInfo.SP_STATUS_REG |= (0x0203 );
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
*RSPInfo.MI_INTR_REG |= R4300i_SP_Intr;
RSPInfo.CheckInterrupts();
}
return Cycles;
} else if (TaskType == 7) {
RSPInfo.ShowCFB();
}
Compiler.bAudioUcode = (TaskType == 2) ? TRUE : FALSE;
/*
*RSPInfo.SP_STATUS_REG |= (0x0203 );
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
*RSPInfo.MI_INTR_REG |= R4300i_SP_Intr;
RSPInfo.CheckInterrupts();
}
//return Cycles;
*/
if (Profiling && !IndvidualBlock) {
StartTimer(Timer_RSP_Running);
}
WaitForSingleObjectEx(hMutex, 1000 * 100, FALSE);
if (BreakOnStart)
{
Enter_RSP_Commands_Window();
}
switch (CPUCore) {
case RecompilerCPU:
RunRecompilerCPU(Cycles);
break;
case InterpreterCPU:
RunInterpreterCPU(Cycles);
break;
}
ReleaseMutex(hMutex);
if (Profiling && !IndvidualBlock) {
StartTimer(Timer_R4300_Running);
}
return Cycles;
}

43
Source/RSP/Cpu.h Normal file
View File

@ -0,0 +1,43 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include "opcode.h"
extern UDWORD EleSpec[32], Indx[32];
extern void * RSP_Opcode[64];
extern void * RSP_RegImm[32];
extern void * RSP_Special[64];
extern void * RSP_Cop0[32];
extern void * RSP_Cop2[32];
extern void * RSP_Vector[64];
extern void * RSP_Lc2[32];
extern void * RSP_Sc2[32];
extern DWORD * PrgCount, RSP_Running;
extern OPCODE RSPOpC;
void SetCPU(DWORD core);
void Build_RSP (void);

View File

@ -0,0 +1,466 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "breakpoint.h"
#include "RSP.h"
#include "Cpu.h"
#include "Interpreter Ops.h"
#include "Interpreter CPU.h"
#include "RSP registers.h"
#include "RSP Command.h"
#include "memory.h"
#include "opcode.h"
#include "log.h"
DWORD RSP_NextInstruction, RSP_JumpTo;
void BuildInterpreterCPU(void) {
RSP_Opcode[ 0] = RSP_Opcode_SPECIAL;
RSP_Opcode[ 1] = RSP_Opcode_REGIMM;
RSP_Opcode[ 2] = RSP_Opcode_J;
RSP_Opcode[ 3] = RSP_Opcode_JAL;
RSP_Opcode[ 4] = RSP_Opcode_BEQ;
RSP_Opcode[ 5] = RSP_Opcode_BNE;
RSP_Opcode[ 6] = RSP_Opcode_BLEZ;
RSP_Opcode[ 7] = RSP_Opcode_BGTZ;
RSP_Opcode[ 8] = RSP_Opcode_ADDI;
RSP_Opcode[ 9] = RSP_Opcode_ADDIU;
RSP_Opcode[10] = RSP_Opcode_SLTI;
RSP_Opcode[11] = RSP_Opcode_SLTIU;
RSP_Opcode[12] = RSP_Opcode_ANDI;
RSP_Opcode[13] = RSP_Opcode_ORI;
RSP_Opcode[14] = RSP_Opcode_XORI;
RSP_Opcode[15] = RSP_Opcode_LUI;
RSP_Opcode[16] = RSP_Opcode_COP0;
RSP_Opcode[17] = rsp_UnknownOpcode;
RSP_Opcode[18] = RSP_Opcode_COP2;
RSP_Opcode[19] = rsp_UnknownOpcode;
RSP_Opcode[20] = rsp_UnknownOpcode;
RSP_Opcode[21] = rsp_UnknownOpcode;
RSP_Opcode[22] = rsp_UnknownOpcode;
RSP_Opcode[23] = rsp_UnknownOpcode;
RSP_Opcode[24] = rsp_UnknownOpcode;
RSP_Opcode[25] = rsp_UnknownOpcode;
RSP_Opcode[26] = rsp_UnknownOpcode;
RSP_Opcode[27] = rsp_UnknownOpcode;
RSP_Opcode[28] = rsp_UnknownOpcode;
RSP_Opcode[29] = rsp_UnknownOpcode;
RSP_Opcode[30] = rsp_UnknownOpcode;
RSP_Opcode[31] = rsp_UnknownOpcode;
RSP_Opcode[32] = RSP_Opcode_LB;
RSP_Opcode[33] = RSP_Opcode_LH;
RSP_Opcode[34] = rsp_UnknownOpcode;
RSP_Opcode[35] = RSP_Opcode_LW;
RSP_Opcode[36] = RSP_Opcode_LBU;
RSP_Opcode[37] = RSP_Opcode_LHU;
RSP_Opcode[38] = rsp_UnknownOpcode;
RSP_Opcode[39] = rsp_UnknownOpcode;
RSP_Opcode[40] = RSP_Opcode_SB;
RSP_Opcode[41] = RSP_Opcode_SH;
RSP_Opcode[42] = rsp_UnknownOpcode;
RSP_Opcode[43] = RSP_Opcode_SW;
RSP_Opcode[44] = rsp_UnknownOpcode;
RSP_Opcode[45] = rsp_UnknownOpcode;
RSP_Opcode[46] = rsp_UnknownOpcode;
RSP_Opcode[47] = rsp_UnknownOpcode;
RSP_Opcode[48] = rsp_UnknownOpcode;
RSP_Opcode[49] = rsp_UnknownOpcode;
RSP_Opcode[50] = RSP_Opcode_LC2;
RSP_Opcode[51] = rsp_UnknownOpcode;
RSP_Opcode[52] = rsp_UnknownOpcode;
RSP_Opcode[53] = rsp_UnknownOpcode;
RSP_Opcode[54] = rsp_UnknownOpcode;
RSP_Opcode[55] = rsp_UnknownOpcode;
RSP_Opcode[56] = rsp_UnknownOpcode;
RSP_Opcode[57] = rsp_UnknownOpcode;
RSP_Opcode[58] = RSP_Opcode_SC2;
RSP_Opcode[59] = rsp_UnknownOpcode;
RSP_Opcode[60] = rsp_UnknownOpcode;
RSP_Opcode[61] = rsp_UnknownOpcode;
RSP_Opcode[62] = rsp_UnknownOpcode;
RSP_Opcode[63] = rsp_UnknownOpcode;
RSP_Special[ 0] = RSP_Special_SLL;
RSP_Special[ 1] = rsp_UnknownOpcode;
RSP_Special[ 2] = RSP_Special_SRL;
RSP_Special[ 3] = RSP_Special_SRA;
RSP_Special[ 4] = RSP_Special_SLLV;
RSP_Special[ 5] = rsp_UnknownOpcode;
RSP_Special[ 6] = RSP_Special_SRLV;
RSP_Special[ 7] = RSP_Special_SRAV;
RSP_Special[ 8] = RSP_Special_JR;
RSP_Special[ 9] = RSP_Special_JALR;
RSP_Special[10] = rsp_UnknownOpcode;
RSP_Special[11] = rsp_UnknownOpcode;
RSP_Special[12] = rsp_UnknownOpcode;
RSP_Special[13] = RSP_Special_BREAK;
RSP_Special[14] = rsp_UnknownOpcode;
RSP_Special[15] = rsp_UnknownOpcode;
RSP_Special[16] = rsp_UnknownOpcode;
RSP_Special[17] = rsp_UnknownOpcode;
RSP_Special[18] = rsp_UnknownOpcode;
RSP_Special[19] = rsp_UnknownOpcode;
RSP_Special[20] = rsp_UnknownOpcode;
RSP_Special[21] = rsp_UnknownOpcode;
RSP_Special[22] = rsp_UnknownOpcode;
RSP_Special[23] = rsp_UnknownOpcode;
RSP_Special[24] = rsp_UnknownOpcode;
RSP_Special[25] = rsp_UnknownOpcode;
RSP_Special[26] = rsp_UnknownOpcode;
RSP_Special[27] = rsp_UnknownOpcode;
RSP_Special[28] = rsp_UnknownOpcode;
RSP_Special[29] = rsp_UnknownOpcode;
RSP_Special[30] = rsp_UnknownOpcode;
RSP_Special[31] = rsp_UnknownOpcode;
RSP_Special[32] = RSP_Special_ADD;
RSP_Special[33] = RSP_Special_ADDU;
RSP_Special[34] = RSP_Special_SUB;
RSP_Special[35] = RSP_Special_SUBU;
RSP_Special[36] = RSP_Special_AND;
RSP_Special[37] = RSP_Special_OR;
RSP_Special[38] = RSP_Special_XOR;
RSP_Special[39] = RSP_Special_NOR;
RSP_Special[40] = rsp_UnknownOpcode;
RSP_Special[41] = rsp_UnknownOpcode;
RSP_Special[42] = RSP_Special_SLT;
RSP_Special[43] = RSP_Special_SLTU;
RSP_Special[44] = rsp_UnknownOpcode;
RSP_Special[45] = rsp_UnknownOpcode;
RSP_Special[46] = rsp_UnknownOpcode;
RSP_Special[47] = rsp_UnknownOpcode;
RSP_Special[48] = rsp_UnknownOpcode;
RSP_Special[49] = rsp_UnknownOpcode;
RSP_Special[50] = rsp_UnknownOpcode;
RSP_Special[51] = rsp_UnknownOpcode;
RSP_Special[52] = rsp_UnknownOpcode;
RSP_Special[53] = rsp_UnknownOpcode;
RSP_Special[54] = rsp_UnknownOpcode;
RSP_Special[55] = rsp_UnknownOpcode;
RSP_Special[56] = rsp_UnknownOpcode;
RSP_Special[57] = rsp_UnknownOpcode;
RSP_Special[58] = rsp_UnknownOpcode;
RSP_Special[59] = rsp_UnknownOpcode;
RSP_Special[60] = rsp_UnknownOpcode;
RSP_Special[61] = rsp_UnknownOpcode;
RSP_Special[62] = rsp_UnknownOpcode;
RSP_Special[63] = rsp_UnknownOpcode;
RSP_RegImm[ 0] = RSP_Opcode_BLTZ;
RSP_RegImm[ 1] = RSP_Opcode_BGEZ;
RSP_RegImm[ 2] = rsp_UnknownOpcode;
RSP_RegImm[ 3] = rsp_UnknownOpcode;
RSP_RegImm[ 4] = rsp_UnknownOpcode;
RSP_RegImm[ 5] = rsp_UnknownOpcode;
RSP_RegImm[ 6] = rsp_UnknownOpcode;
RSP_RegImm[ 7] = rsp_UnknownOpcode;
RSP_RegImm[ 8] = rsp_UnknownOpcode;
RSP_RegImm[ 9] = rsp_UnknownOpcode;
RSP_RegImm[10] = rsp_UnknownOpcode;
RSP_RegImm[11] = rsp_UnknownOpcode;
RSP_RegImm[12] = rsp_UnknownOpcode;
RSP_RegImm[13] = rsp_UnknownOpcode;
RSP_RegImm[14] = rsp_UnknownOpcode;
RSP_RegImm[15] = rsp_UnknownOpcode;
RSP_RegImm[16] = RSP_Opcode_BLTZAL;
RSP_RegImm[17] = RSP_Opcode_BGEZAL;
RSP_RegImm[18] = rsp_UnknownOpcode;
RSP_RegImm[19] = rsp_UnknownOpcode;
RSP_RegImm[20] = rsp_UnknownOpcode;
RSP_RegImm[21] = rsp_UnknownOpcode;
RSP_RegImm[22] = rsp_UnknownOpcode;
RSP_RegImm[23] = rsp_UnknownOpcode;
RSP_RegImm[24] = rsp_UnknownOpcode;
RSP_RegImm[25] = rsp_UnknownOpcode;
RSP_RegImm[26] = rsp_UnknownOpcode;
RSP_RegImm[27] = rsp_UnknownOpcode;
RSP_RegImm[28] = rsp_UnknownOpcode;
RSP_RegImm[29] = rsp_UnknownOpcode;
RSP_RegImm[30] = rsp_UnknownOpcode;
RSP_RegImm[31] = rsp_UnknownOpcode;
RSP_Cop0[ 0] = RSP_Cop0_MF;
RSP_Cop0[ 1] = rsp_UnknownOpcode;
RSP_Cop0[ 2] = rsp_UnknownOpcode;
RSP_Cop0[ 3] = rsp_UnknownOpcode;
RSP_Cop0[ 4] = RSP_Cop0_MT;
RSP_Cop0[ 5] = rsp_UnknownOpcode;
RSP_Cop0[ 6] = rsp_UnknownOpcode;
RSP_Cop0[ 7] = rsp_UnknownOpcode;
RSP_Cop0[ 8] = rsp_UnknownOpcode;
RSP_Cop0[ 9] = rsp_UnknownOpcode;
RSP_Cop0[10] = rsp_UnknownOpcode;
RSP_Cop0[11] = rsp_UnknownOpcode;
RSP_Cop0[12] = rsp_UnknownOpcode;
RSP_Cop0[13] = rsp_UnknownOpcode;
RSP_Cop0[14] = rsp_UnknownOpcode;
RSP_Cop0[15] = rsp_UnknownOpcode;
RSP_Cop0[16] = rsp_UnknownOpcode;
RSP_Cop0[17] = rsp_UnknownOpcode;
RSP_Cop0[18] = rsp_UnknownOpcode;
RSP_Cop0[19] = rsp_UnknownOpcode;
RSP_Cop0[20] = rsp_UnknownOpcode;
RSP_Cop0[21] = rsp_UnknownOpcode;
RSP_Cop0[22] = rsp_UnknownOpcode;
RSP_Cop0[23] = rsp_UnknownOpcode;
RSP_Cop0[24] = rsp_UnknownOpcode;
RSP_Cop0[25] = rsp_UnknownOpcode;
RSP_Cop0[26] = rsp_UnknownOpcode;
RSP_Cop0[27] = rsp_UnknownOpcode;
RSP_Cop0[28] = rsp_UnknownOpcode;
RSP_Cop0[29] = rsp_UnknownOpcode;
RSP_Cop0[30] = rsp_UnknownOpcode;
RSP_Cop0[31] = rsp_UnknownOpcode;
RSP_Cop2[ 0] = RSP_Cop2_MF;
RSP_Cop2[ 1] = rsp_UnknownOpcode;
RSP_Cop2[ 2] = RSP_Cop2_CF;
RSP_Cop2[ 3] = rsp_UnknownOpcode;
RSP_Cop2[ 4] = RSP_Cop2_MT;
RSP_Cop2[ 5] = rsp_UnknownOpcode;
RSP_Cop2[ 6] = RSP_Cop2_CT;
RSP_Cop2[ 7] = rsp_UnknownOpcode;
RSP_Cop2[ 8] = rsp_UnknownOpcode;
RSP_Cop2[ 9] = rsp_UnknownOpcode;
RSP_Cop2[10] = rsp_UnknownOpcode;
RSP_Cop2[11] = rsp_UnknownOpcode;
RSP_Cop2[12] = rsp_UnknownOpcode;
RSP_Cop2[13] = rsp_UnknownOpcode;
RSP_Cop2[14] = rsp_UnknownOpcode;
RSP_Cop2[15] = rsp_UnknownOpcode;
RSP_Cop2[16] = RSP_COP2_VECTOR;
RSP_Cop2[17] = RSP_COP2_VECTOR;
RSP_Cop2[18] = RSP_COP2_VECTOR;
RSP_Cop2[19] = RSP_COP2_VECTOR;
RSP_Cop2[20] = RSP_COP2_VECTOR;
RSP_Cop2[21] = RSP_COP2_VECTOR;
RSP_Cop2[22] = RSP_COP2_VECTOR;
RSP_Cop2[23] = RSP_COP2_VECTOR;
RSP_Cop2[24] = RSP_COP2_VECTOR;
RSP_Cop2[25] = RSP_COP2_VECTOR;
RSP_Cop2[26] = RSP_COP2_VECTOR;
RSP_Cop2[27] = RSP_COP2_VECTOR;
RSP_Cop2[28] = RSP_COP2_VECTOR;
RSP_Cop2[29] = RSP_COP2_VECTOR;
RSP_Cop2[30] = RSP_COP2_VECTOR;
RSP_Cop2[31] = RSP_COP2_VECTOR;
RSP_Vector[ 0] = RSP_Vector_VMULF;
RSP_Vector[ 1] = RSP_Vector_VMULU;
RSP_Vector[ 2] = rsp_UnknownOpcode;
RSP_Vector[ 3] = rsp_UnknownOpcode;
RSP_Vector[ 4] = RSP_Vector_VMUDL;
RSP_Vector[ 5] = RSP_Vector_VMUDM;
RSP_Vector[ 6] = RSP_Vector_VMUDN;
RSP_Vector[ 7] = RSP_Vector_VMUDH;
RSP_Vector[ 8] = RSP_Vector_VMACF;
RSP_Vector[ 9] = RSP_Vector_VMACU;
RSP_Vector[10] = rsp_UnknownOpcode;
RSP_Vector[11] = RSP_Vector_VMACQ;
RSP_Vector[12] = RSP_Vector_VMADL;
RSP_Vector[13] = RSP_Vector_VMADM;
RSP_Vector[14] = RSP_Vector_VMADN;
RSP_Vector[15] = RSP_Vector_VMADH;
RSP_Vector[16] = RSP_Vector_VADD;
RSP_Vector[17] = RSP_Vector_VSUB;
RSP_Vector[18] = rsp_UnknownOpcode;
RSP_Vector[19] = RSP_Vector_VABS;
RSP_Vector[20] = RSP_Vector_VADDC;
RSP_Vector[21] = RSP_Vector_VSUBC;
RSP_Vector[22] = rsp_UnknownOpcode;
RSP_Vector[23] = rsp_UnknownOpcode;
RSP_Vector[24] = rsp_UnknownOpcode;
RSP_Vector[25] = rsp_UnknownOpcode;
RSP_Vector[26] = rsp_UnknownOpcode;
RSP_Vector[27] = rsp_UnknownOpcode;
RSP_Vector[28] = rsp_UnknownOpcode;
RSP_Vector[29] = RSP_Vector_VSAW;
RSP_Vector[30] = rsp_UnknownOpcode;
RSP_Vector[31] = rsp_UnknownOpcode;
RSP_Vector[32] = RSP_Vector_VLT;
RSP_Vector[33] = RSP_Vector_VEQ;
RSP_Vector[34] = RSP_Vector_VNE;
RSP_Vector[35] = RSP_Vector_VGE;
RSP_Vector[36] = RSP_Vector_VCL;
RSP_Vector[37] = RSP_Vector_VCH;
RSP_Vector[38] = RSP_Vector_VCR;
RSP_Vector[39] = RSP_Vector_VMRG;
RSP_Vector[40] = RSP_Vector_VAND;
RSP_Vector[41] = RSP_Vector_VNAND;
RSP_Vector[42] = RSP_Vector_VOR;
RSP_Vector[43] = RSP_Vector_VNOR;
RSP_Vector[44] = RSP_Vector_VXOR;
RSP_Vector[45] = RSP_Vector_VNXOR;
RSP_Vector[46] = rsp_UnknownOpcode;
RSP_Vector[47] = rsp_UnknownOpcode;
RSP_Vector[48] = RSP_Vector_VRCP;
RSP_Vector[49] = RSP_Vector_VRCPL;
RSP_Vector[50] = RSP_Vector_VRCPH;
RSP_Vector[51] = RSP_Vector_VMOV;
RSP_Vector[52] = RSP_Vector_VRSQ;
RSP_Vector[53] = RSP_Vector_VRSQL;
RSP_Vector[54] = RSP_Vector_VRSQH;
RSP_Vector[55] = RSP_Vector_VNOOP;
RSP_Vector[56] = rsp_UnknownOpcode;
RSP_Vector[57] = rsp_UnknownOpcode;
RSP_Vector[58] = rsp_UnknownOpcode;
RSP_Vector[59] = rsp_UnknownOpcode;
RSP_Vector[60] = rsp_UnknownOpcode;
RSP_Vector[61] = rsp_UnknownOpcode;
RSP_Vector[62] = rsp_UnknownOpcode;
RSP_Vector[63] = rsp_UnknownOpcode;
RSP_Lc2[ 0] = RSP_Opcode_LBV;
RSP_Lc2[ 1] = RSP_Opcode_LSV;
RSP_Lc2[ 2] = RSP_Opcode_LLV;
RSP_Lc2[ 3] = RSP_Opcode_LDV;
RSP_Lc2[ 4] = RSP_Opcode_LQV;
RSP_Lc2[ 5] = RSP_Opcode_LRV;
RSP_Lc2[ 6] = RSP_Opcode_LPV;
RSP_Lc2[ 7] = RSP_Opcode_LUV;
RSP_Lc2[ 8] = RSP_Opcode_LHV;
RSP_Lc2[ 9] = RSP_Opcode_LFV;
RSP_Lc2[10] = rsp_UnknownOpcode;
RSP_Lc2[11] = RSP_Opcode_LTV;
RSP_Lc2[12] = rsp_UnknownOpcode;
RSP_Lc2[13] = rsp_UnknownOpcode;
RSP_Lc2[14] = rsp_UnknownOpcode;
RSP_Lc2[15] = rsp_UnknownOpcode;
RSP_Lc2[16] = rsp_UnknownOpcode;
RSP_Lc2[17] = rsp_UnknownOpcode;
RSP_Lc2[18] = rsp_UnknownOpcode;
RSP_Lc2[19] = rsp_UnknownOpcode;
RSP_Lc2[20] = rsp_UnknownOpcode;
RSP_Lc2[21] = rsp_UnknownOpcode;
RSP_Lc2[22] = rsp_UnknownOpcode;
RSP_Lc2[23] = rsp_UnknownOpcode;
RSP_Lc2[24] = rsp_UnknownOpcode;
RSP_Lc2[25] = rsp_UnknownOpcode;
RSP_Lc2[26] = rsp_UnknownOpcode;
RSP_Lc2[27] = rsp_UnknownOpcode;
RSP_Lc2[28] = rsp_UnknownOpcode;
RSP_Lc2[29] = rsp_UnknownOpcode;
RSP_Lc2[30] = rsp_UnknownOpcode;
RSP_Lc2[31] = rsp_UnknownOpcode;
RSP_Sc2[ 0] = RSP_Opcode_SBV;
RSP_Sc2[ 1] = RSP_Opcode_SSV;
RSP_Sc2[ 2] = RSP_Opcode_SLV;
RSP_Sc2[ 3] = RSP_Opcode_SDV;
RSP_Sc2[ 4] = RSP_Opcode_SQV;
RSP_Sc2[ 5] = RSP_Opcode_SRV;
RSP_Sc2[ 6] = RSP_Opcode_SPV;
RSP_Sc2[ 7] = RSP_Opcode_SUV;
RSP_Sc2[ 8] = RSP_Opcode_SHV;
RSP_Sc2[ 9] = RSP_Opcode_SFV;
RSP_Sc2[10] = RSP_Opcode_SWV;
RSP_Sc2[11] = RSP_Opcode_STV;
RSP_Sc2[12] = rsp_UnknownOpcode;
RSP_Sc2[13] = rsp_UnknownOpcode;
RSP_Sc2[14] = rsp_UnknownOpcode;
RSP_Sc2[15] = rsp_UnknownOpcode;
RSP_Sc2[16] = rsp_UnknownOpcode;
RSP_Sc2[17] = rsp_UnknownOpcode;
RSP_Sc2[18] = rsp_UnknownOpcode;
RSP_Sc2[19] = rsp_UnknownOpcode;
RSP_Sc2[20] = rsp_UnknownOpcode;
RSP_Sc2[21] = rsp_UnknownOpcode;
RSP_Sc2[22] = rsp_UnknownOpcode;
RSP_Sc2[23] = rsp_UnknownOpcode;
RSP_Sc2[24] = rsp_UnknownOpcode;
RSP_Sc2[25] = rsp_UnknownOpcode;
RSP_Sc2[26] = rsp_UnknownOpcode;
RSP_Sc2[27] = rsp_UnknownOpcode;
RSP_Sc2[28] = rsp_UnknownOpcode;
RSP_Sc2[29] = rsp_UnknownOpcode;
RSP_Sc2[30] = rsp_UnknownOpcode;
RSP_Sc2[31] = rsp_UnknownOpcode;
}
DWORD RunInterpreterCPU(DWORD Cycles) {
DWORD CycleCount;
RSP_Running = TRUE;
Enable_RSP_Commands_Window();
CycleCount = 0;
while (RSP_Running) {
if (NoOfBpoints != 0) {
if (CheckForRSPBPoint(*PrgCount)) {
if (InRSPCommandsWindow) {
Enter_RSP_Commands_Window();
if (Stepping_Commands) {
DisplayError ( "Encounted a R4300i Breakpoint" );
} else {
DisplayError ( "Encounted a R4300i Breakpoint\n\nNow Stepping" );
SetRSPCommandViewto( *PrgCount );
SetRSPCommandToStepping();
}
} else {
DisplayError ( "Encounted a RSP Breakpoint\n\nEntering Command Window" );
Enter_RSP_Commands_Window();
}
}
}
if (Stepping_Commands) {
WaitingForStep = TRUE;
SetRSPCommandViewto( *PrgCount );
UpdateRSPRegistersScreen();
while ( WaitingForStep == TRUE ){
Sleep(20);
if (!Stepping_Commands) {
WaitingForStep = FALSE;
}
}
}
RDP_LogLoc(*PrgCount);
RSP_LW_IMEM(*PrgCount, &RSPOpC.Hex);
((void (*)()) RSP_Opcode[ RSPOpC.op ])();
switch (RSP_NextInstruction) {
case NORMAL:
*PrgCount = (*PrgCount + 4) & 0xFFC;
break;
case DELAY_SLOT:
RSP_NextInstruction = JUMP;
*PrgCount = (*PrgCount + 4) & 0xFFC;
break;
case JUMP:
RSP_NextInstruction = NORMAL;
*PrgCount = RSP_JumpTo;
break;
}
}
*PrgCount -= 4;
return Cycles;
}

View File

@ -0,0 +1,34 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#define NORMAL 0
#define DELAY_SLOT 1
#define JUMP 2
extern DWORD RSP_NextInstruction, RSP_JumpTo;
void BuildInterpreterCPU(void);
DWORD RunInterpreterCPU(DWORD Cycles);

1902
Source/RSP/Interpreter Ops.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
/************************* OpCode functions *************************/
void RSP_Opcode_SPECIAL ( void );
void RSP_Opcode_REGIMM ( void );
void RSP_Opcode_J ( void );
void RSP_Opcode_JAL ( void );
void RSP_Opcode_BEQ ( void );
void RSP_Opcode_BNE ( void );
void RSP_Opcode_BLEZ ( void );
void RSP_Opcode_BGTZ ( void );
void RSP_Opcode_ADDI ( void );
void RSP_Opcode_ADDIU ( void );
void RSP_Opcode_SLTI ( void );
void RSP_Opcode_SLTIU ( void );
void RSP_Opcode_ANDI ( void );
void RSP_Opcode_ORI ( void );
void RSP_Opcode_XORI ( void );
void RSP_Opcode_LUI ( void );
void RSP_Opcode_COP0 ( void );
void RSP_Opcode_COP2 ( void );
void RSP_Opcode_LB ( void );
void RSP_Opcode_LH ( void );
void RSP_Opcode_LW ( void );
void RSP_Opcode_LBU ( void );
void RSP_Opcode_LHU ( void );
void RSP_Opcode_SB ( void );
void RSP_Opcode_SH ( void );
void RSP_Opcode_SW ( void );
void RSP_Opcode_LC2 ( void );
void RSP_Opcode_SC2 ( void );
/********************** R4300i OpCodes: Special **********************/
void RSP_Special_SLL ( void );
void RSP_Special_SRL ( void );
void RSP_Special_SRA ( void );
void RSP_Special_SLLV ( void );
void RSP_Special_SRLV ( void );
void RSP_Special_SRAV ( void );
void RSP_Special_JR ( void );
void RSP_Special_JALR ( void );
void RSP_Special_BREAK ( void );
void RSP_Special_ADD ( void );
void RSP_Special_ADDU ( void );
void RSP_Special_SUB ( void );
void RSP_Special_SUBU ( void );
void RSP_Special_AND ( void );
void RSP_Special_OR ( void );
void RSP_Special_XOR ( void );
void RSP_Special_NOR ( void );
void RSP_Special_SLT ( void );
void RSP_Special_SLTU ( void );
/********************** R4300i OpCodes: RegImm **********************/
void RSP_Opcode_BLTZ ( void );
void RSP_Opcode_BGEZ ( void );
void RSP_Opcode_BLTZAL ( void );
void RSP_Opcode_BGEZAL ( void );
/************************** Cop0 functions *************************/
void RSP_Cop0_MF ( void );
void RSP_Cop0_MT ( void );
/************************** Cop2 functions *************************/
void RSP_Cop2_MF ( void );
void RSP_Cop2_CF ( void );
void RSP_Cop2_MT ( void );
void RSP_Cop2_CT ( void );
void RSP_COP2_VECTOR ( void );
/************************** Vect functions **************************/
void RSP_Vector_VMULF ( void );
void RSP_Vector_VMULU ( void );
void RSP_Vector_VMUDL ( void );
void RSP_Vector_VMUDM ( void );
void RSP_Vector_VMUDN ( void );
void RSP_Vector_VMUDH ( void );
void RSP_Vector_VMACF ( void );
void RSP_Vector_VMACU ( void );
void RSP_Vector_VMACQ ( void );
void RSP_Vector_VMADL ( void );
void RSP_Vector_VMADM ( void );
void RSP_Vector_VMADN ( void );
void RSP_Vector_VMADH ( void );
void RSP_Vector_VADD ( void );
void RSP_Vector_VSUB ( void );
void RSP_Vector_VABS ( void );
void RSP_Vector_VADDC ( void );
void RSP_Vector_VSUBC ( void );
void RSP_Vector_VSAW ( void );
void RSP_Vector_VLT ( void );
void RSP_Vector_VEQ ( void );
void RSP_Vector_VNE ( void );
void RSP_Vector_VGE ( void );
void RSP_Vector_VCL ( void );
void RSP_Vector_VCH ( void );
void RSP_Vector_VCR ( void );
void RSP_Vector_VMRG ( void );
void RSP_Vector_VAND ( void );
void RSP_Vector_VNAND ( void );
void RSP_Vector_VOR ( void );
void RSP_Vector_VNOR ( void );
void RSP_Vector_VXOR ( void );
void RSP_Vector_VNXOR ( void );
void RSP_Vector_VRCP ( void );
void RSP_Vector_VRCPL ( void );
void RSP_Vector_VRCPH ( void );
void RSP_Vector_VMOV ( void );
void RSP_Vector_VRSQ ( void );
void RSP_Vector_VRSQL ( void );
void RSP_Vector_VRSQH ( void );
void RSP_Vector_VNOOP ( void );
/************************** lc2 functions **************************/
void RSP_Opcode_LBV ( void );
void RSP_Opcode_LSV ( void );
void RSP_Opcode_LLV ( void );
void RSP_Opcode_LDV ( void );
void RSP_Opcode_LQV ( void );
void RSP_Opcode_LRV ( void );
void RSP_Opcode_LPV ( void );
void RSP_Opcode_LUV ( void );
void RSP_Opcode_LHV ( void );
void RSP_Opcode_LFV ( void );
void RSP_Opcode_LTV ( void );
/************************** lc2 functions **************************/
void RSP_Opcode_SBV ( void );
void RSP_Opcode_SSV ( void );
void RSP_Opcode_SLV ( void );
void RSP_Opcode_SDV ( void );
void RSP_Opcode_SQV ( void );
void RSP_Opcode_SRV ( void );
void RSP_Opcode_SPV ( void );
void RSP_Opcode_SUV ( void );
void RSP_Opcode_SHV ( void );
void RSP_Opcode_SFV ( void );
void RSP_Opcode_STV ( void );
void RSP_Opcode_SWV ( void );
/************************** Other functions **************************/
void rsp_UnknownOpcode ( void );

718
Source/RSP/Main.cpp Normal file
View File

@ -0,0 +1,718 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <Windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <common/std string.h>
#include <common/Version.h>
#include "../Settings/Settings.h"
extern "C" {
#include "Rsp.h"
#include "CPU.h"
#include "Recompiler CPU.h"
#include "Rsp Command.h"
#include "Rsp Registers.h"
#include "memory.h"
#include "breakpoint.h"
#include "profiling.h"
#include "log.h"
#include "resource.h"
void ClearAllx86Code(void);
void ProcessMenuItem(int ID);
BOOL CALLBACK CompilerDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL GraphicsHle = TRUE, AudioHle, ConditionalMove;
BOOL DebuggingEnabled = FALSE,
Profiling,
IndvidualBlock,
ShowErrors,
BreakOnStart = FALSE,
LogRDP = FALSE,
LogX86Code = FALSE;
DWORD CPUCore = RecompilerCPU;
HANDLE hMutex = NULL;
DEBUG_INFO DebugInfo;
RSP_INFO RSPInfo;
HINSTANCE hinstDLL;
HMENU hRSPMenu = NULL;
extern BYTE * pLastSecondary;
}
enum {
Set_BreakOnStart, Set_CPUCore, Set_LogRDP, Set_LogX86Code, Set_Profiling, Set_IndvidualBlock,
Set_AudioHle, Set_GraphicsHle, Set_ShowErrors,
//Compiler settings
Set_CheckDest, Set_Accum, Set_Mmx, Set_Mmx2, Set_Sse, Set_Sections,
Set_ReOrdering, Set_GPRConstants, Set_Flags, Set_AlignVector,
};
/************ DLL info **************/
const char * AppName ( void )
{
static stdstr_f Name("RSP %s",VersionInfo(VERSION_PRODUCT_VERSION,hinstDLL));
return Name.c_str();
}
const char * AboutMsg ( void )
{
static stdstr_f Msg("RSP emulation Plugin\nMade for Project64 (c)\nVersion %s\n\nby Jabo & Zilmar",VersionInfo(VERSION_PRODUCT_VERSION,hinstDLL));
return Msg.c_str();
}
/************ Functions ***********/
DWORD AsciiToHex (char * HexValue) {
DWORD Count, Finish, Value = 0;
Finish = strlen(HexValue);
if (Finish > 8 ) { Finish = 8; }
for (Count = 0; Count < Finish; Count++){
Value = (Value << 4);
switch( HexValue[Count] ) {
case '0': break;
case '1': Value += 1; break;
case '2': Value += 2; break;
case '3': Value += 3; break;
case '4': Value += 4; break;
case '5': Value += 5; break;
case '6': Value += 6; break;
case '7': Value += 7; break;
case '8': Value += 8; break;
case '9': Value += 9; break;
case 'A': Value += 10; break;
case 'a': Value += 10; break;
case 'B': Value += 11; break;
case 'b': Value += 11; break;
case 'C': Value += 12; break;
case 'c': Value += 12; break;
case 'D': Value += 13; break;
case 'd': Value += 13; break;
case 'E': Value += 14; break;
case 'e': Value += 14; break;
case 'F': Value += 15; break;
case 'f': Value += 15; break;
default:
Value = (Value >> 4);
Count = Finish;
}
}
return Value;
}
void DisplayError (char * Message, ...) {
char Msg[400];
va_list ap;
va_start( ap, Message );
vsprintf( Msg, Message, ap );
va_end( ap );
MessageBox(NULL,Msg,"Error",MB_OK|MB_ICONERROR);
}
/******************************************************************
Function: CloseDLL
Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise.
input: none
output: none
*******************************************************************/
__declspec(dllexport) void CloseDLL (void) {
FreeMemory();
}
/******************************************************************
Function: DllAbout
Purpose: This function is optional function that is provided
to give further information about the DLL.
input: a handle to the window that calls this function
output: none
*******************************************************************/
__declspec(dllexport) void DllAbout ( HWND hParent ) {
MessageBox(hParent,AboutMsg(),"About",MB_OK | MB_ICONINFORMATION );
}
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved ){
hinstDLL = hinst;
if (strcmp(VersionInfo(VERSION_INTERNAL_NAME).c_str(),"Project64") != 0)
{
return FALSE;
}
return TRUE;
}
/******************************************************************
Function: GetDllInfo
Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be
filled by the function. (see def above)
output: none
*******************************************************************/
__declspec(dllexport) void GetDllInfo ( PLUGIN_INFO * PluginInfo ) {
PluginInfo->Version = 0x0102;
PluginInfo->Type = PLUGIN_TYPE_RSP;
sprintf(PluginInfo->Name,"RSP Plugin %s",VersionInfo(VERSION_PRODUCT_VERSION,hinstDLL));
PluginInfo->NormalMemory = FALSE;
PluginInfo->MemoryBswaped = TRUE;
}
/******************************************************************
Function: GetRspDebugInfo
Purpose: This function allows the emulator to gather information
about the debug capabilities of the dll by filling in
the DebugInfo structure.
input: a pointer to a RSPDEBUG_INFO stucture that needs to be
filled by the function. (see def above)
output: none
*******************************************************************/
#if !defined(EXTERNAL_RELEASE)
void FixMenuState (void)
{
EnableMenuItem(hRSPMenu,ID_RSPCOMMANDS,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu,ID_RSPREGISTERS,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu,ID_PROFILING_RESETSTATS,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu,ID_PROFILING_GENERATELOG,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu,ID_DUMP_RSPCODE,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu,ID_DUMP_DMEM,MF_BYCOMMAND| (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
CheckMenuItem( hRSPMenu, ID_CPUMETHOD_RECOMPILER, MF_BYCOMMAND | (CPUCore == RecompilerCPU ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | (CPUCore == InterpreterCPU ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | (LogRDP ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | (Profiling ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | (Profiling ? MFS_UNCHECKED : MF_CHECKED ));
CheckMenuItem( hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | (IndvidualBlock ? MFS_CHECKED : MF_UNCHECKED ));
CheckMenuItem( hRSPMenu, ID_SHOWCOMPILERERRORS,MF_BYCOMMAND | (ShowErrors ? MFS_CHECKED : MF_UNCHECKED ));
}
__declspec(dllexport) void GetRspDebugInfo ( RSPDEBUG_INFO * DebugInfo )
{
if (hRSPMenu == NULL)
{
hRSPMenu = LoadMenu(hinstDLL,MAKEINTRESOURCE(RspMenu));
FixMenuState();
}
DebugInfo->hRSPMenu = hRSPMenu;
DebugInfo->ProcessMenuItem = ProcessMenuItem;
DebugInfo->UseBPoints = TRUE;
sprintf(DebugInfo->BPPanelName," RSP ");
DebugInfo->Add_BPoint = Add_BPoint;
DebugInfo->CreateBPPanel = CreateBPPanel;
DebugInfo->HideBPPanel = HideBPPanel;
DebugInfo->PaintBPPanel = PaintBPPanel;
DebugInfo->RefreshBpoints = RefreshBpoints;
DebugInfo->RemoveAllBpoint = RemoveAllBpoint;
DebugInfo->RemoveBpoint = RemoveBpoint;
DebugInfo->ShowBPPanel = ShowBPPanel;
DebugInfo->Enter_RSP_Commands_Window = Enter_RSP_Commands_Window;
}
#endif
/******************************************************************
Function: InitiateRSP
Purpose: This function is called when the DLL is started to give
information from the emulator that the n64 RSP
interface needs
input: Rsp_Info is passed to this function which is defined
above.
CycleCount is the number of cycles between switching
control between teh RSP and r4300i core.
output: none
*******************************************************************/
RSP_COMPILER Compiler;
void DetectCpuSpecs(void) {
DWORD Intel_Features = 0;
DWORD AMD_Features = 0;
__try {
_asm {
/* Intel features */
mov eax, 1
cpuid
mov [Intel_Features], edx
/* AMD features */
mov eax, 80000001h
cpuid
or [AMD_Features], edx
}
} __except ( EXCEPTION_EXECUTE_HANDLER) {
AMD_Features = Intel_Features = 0;
}
if (Intel_Features & 0x02000000) {
Compiler.mmx2 = TRUE;
Compiler.sse = TRUE;
}
if (Intel_Features & 0x00800000) {
Compiler.mmx = TRUE;
}
if (AMD_Features & 0x40000000) {
Compiler.mmx2 = TRUE;
}
if (Intel_Features & 0x00008000) {
ConditionalMove = TRUE;
} else {
ConditionalMove = FALSE;
}
}
__declspec(dllexport) void InitiateRSP ( RSP_INFO Rsp_Info, DWORD * CycleCount) {
RSPInfo = Rsp_Info;
AudioHle = GetSetting(Set_AudioHle);
GraphicsHle = GetSetting(Set_GraphicsHle);
*CycleCount = 0;
AllocateMemory();
InitilizeRSPRegisters();
Build_RSP();
#ifdef GenerateLog
Start_Log();
#endif
}
/******************************************************************
Function: InitiateRSPDebugger
Purpose: This function is called when the DLL is started to give
information from the emulator that the n64 RSP
interface needs to intergrate the debugger with the
rest of the emulator.
input: DebugInfo is passed to this function which is defined
above.
output: none
*******************************************************************/
#if !defined(EXTERNAL_RELEASE)
__declspec(dllexport) void InitiateRSPDebugger ( DEBUG_INFO Debug_Info) {
DebugInfo = Debug_Info;
}
void ProcessMenuItem(int ID) {
UINT uState;
switch (ID) {
case ID_RSPCOMMANDS: Enter_RSP_Commands_Window(); break;
case ID_RSPREGISTERS: Enter_RSP_Register_Window(); break;
case ID_DUMP_RSPCODE: DumpRSPCode(); break;
case ID_DUMP_DMEM: DumpRSPData(); break;
case ID_PROFILING_ON:
case ID_PROFILING_OFF:
{
uState = GetMenuState(hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | MFS_UNCHECKED );
CheckMenuItem( hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_Profiling,FALSE);
if (DebuggingEnabled) { Profiling = FALSE; }
} else {
CheckMenuItem( hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | MFS_CHECKED );
CheckMenuItem( hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_Profiling,TRUE);
if (DebuggingEnabled) { Profiling = TRUE; }
}
}
break;
case ID_PROFILING_RESETSTATS: ResetTimerList(); break;
case ID_PROFILING_GENERATELOG: GenerateTimerResults(); break;
case ID_PROFILING_LOGINDIVIDUALBLOCKS:
{
uState = GetMenuState(hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_IndvidualBlock,FALSE);
if (DebuggingEnabled) { IndvidualBlock = FALSE; }
} else {
CheckMenuItem( hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_IndvidualBlock,TRUE);
if (DebuggingEnabled) { IndvidualBlock = TRUE; }
}
}
break;
case ID_SHOWCOMPILERERRORS:
{
uState = GetMenuState(hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_ShowErrors,FALSE);
if (DebuggingEnabled) { ShowErrors = FALSE; }
} else {
CheckMenuItem( hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_ShowErrors,TRUE);
if (DebuggingEnabled) { ShowErrors = TRUE; }
}
}
break;
case ID_COMPILER:
DialogBox(hinstDLL, "RSPCOMPILER", HWND_DESKTOP, CompilerDlgProc);
break;
case ID_BREAKONSTARTOFTASK:
{
uState = GetMenuState(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_BreakOnStart,FALSE);
if (DebuggingEnabled) { BreakOnStart = FALSE; }
} else {
CheckMenuItem( hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_BreakOnStart,TRUE);
if (DebuggingEnabled) { BreakOnStart = TRUE; }
}
}
break;
case ID_LOGRDPCOMMANDS:
{
uState = GetMenuState(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_LogRDP,FALSE);
if (DebuggingEnabled)
{
LogRDP = FALSE;
StopRDPLog();
}
} else {
CheckMenuItem( hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_LogRDP,TRUE);
if (DebuggingEnabled)
{
LogRDP = TRUE;
StartRDPLog();
}
}
}
break;
case ID_SETTINGS_LOGX86CODE:
{
uState = GetMenuState(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND);
if (uState & MFS_CHECKED) {
CheckMenuItem( hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_LogX86Code,FALSE);
if (DebuggingEnabled)
{
LogX86Code = FALSE;
StopCPULog();
}
} else {
CheckMenuItem( hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_LogX86Code,TRUE);
if (DebuggingEnabled)
{
LogX86Code = TRUE;
StartCPULog();
}
}
}
break;
case ID_CPUMETHOD_RECOMPILER:
{
SetSetting(Set_CPUCore,RecompilerCPU);
CPUCore = RecompilerCPU;
FixMenuState();
SetCPU(RecompilerCPU);
}
break;
case ID_CPUMETHOD_INTERPT:
{
SetSetting(Set_CPUCore,InterpreterCPU);
CPUCore = InterpreterCPU;
FixMenuState();
SetCPU(InterpreterCPU);
}
break;
}
}
#endif
/******************************************************************
Function: RomClosed
Purpose: This function is called when a rom is closed.
input: none
output: none
*******************************************************************/
__declspec(dllexport) void RomClosed (void) {
if (Profiling) {
StopTimer();
GenerateTimerResults();
}
InitilizeRSPRegisters();
ClearAllx86Code();
StopRDPLog();
StopCPULog();
#ifdef GenerateLog
Stop_Log();
#endif
}
static BOOL GetBooleanCheck(HWND hDlg, DWORD DialogID) {
return (IsDlgButtonChecked(hDlg, DialogID) == BST_CHECKED) ? TRUE : FALSE;
}
#if !defined(EXTERNAL_RELEASE)
BOOL CALLBACK CompilerDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
char Buffer[256];
switch (uMsg) {
case WM_INITDIALOG:
if (Compiler.bDest == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_DEST, BST_CHECKED);
if (Compiler.mmx == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_MMX, BST_CHECKED);
if (Compiler.mmx2 == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_MMX2, BST_CHECKED);
if (Compiler.sse == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_SSE, BST_CHECKED);
if (Compiler.bAlignVector == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_ALIGNVEC, BST_CHECKED);
if (Compiler.bSections == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_SECTIONS, BST_CHECKED);
if (Compiler.bGPRConstants == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_GPRCONSTANTS, BST_CHECKED);
if (Compiler.bReOrdering == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_REORDER, BST_CHECKED);
if (Compiler.bFlags == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_FLAGS, BST_CHECKED);
if (Compiler.bAccum == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_ACCUM, BST_CHECKED);
SetTimer(hDlg, 1, 250, NULL);
break;
case WM_TIMER:
sprintf(Buffer, "x86: %2.2f KB / %2.2f KB", (float)(RecompPos - RecompCode) / 1024.0F,
pLastSecondary?(float)((pLastSecondary - RecompCodeSecondary) / 1024.0F):0);
SetDlgItemText(hDlg, IDC_COMPILER_BUFFERS, Buffer);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
Compiler.bDest = GetBooleanCheck(hDlg, IDC_COMPILER_DEST);
Compiler.bAccum = GetBooleanCheck(hDlg, IDC_COMPILER_ACCUM);
Compiler.mmx = GetBooleanCheck(hDlg, IDC_CHECK_MMX);
Compiler.mmx2 = GetBooleanCheck(hDlg, IDC_CHECK_MMX2);
Compiler.sse = GetBooleanCheck(hDlg, IDC_CHECK_SSE);
Compiler.bSections = GetBooleanCheck(hDlg, IDC_COMPILER_SECTIONS);
Compiler.bReOrdering = GetBooleanCheck(hDlg, IDC_COMPILER_REORDER);
Compiler.bGPRConstants = GetBooleanCheck(hDlg, IDC_COMPILER_GPRCONSTANTS);
Compiler.bFlags = GetBooleanCheck(hDlg, IDC_COMPILER_FLAGS);
Compiler.bAlignVector = GetBooleanCheck(hDlg, IDC_COMPILER_ALIGNVEC);
SetSetting(Set_CheckDest,Compiler.bDest);
SetSetting(Set_Accum,Compiler.bAccum);
SetSetting(Set_Mmx,Compiler.mmx);
SetSetting(Set_Mmx2,Compiler.mmx2);
SetSetting(Set_Sse,Compiler.sse);
SetSetting(Set_Sections,Compiler.bSections);
SetSetting(Set_ReOrdering,Compiler.bReOrdering);
SetSetting(Set_GPRConstants,Compiler.bGPRConstants);
SetSetting(Set_Flags,Compiler.bFlags);
SetSetting(Set_AlignVector,Compiler.bAlignVector);
KillTimer(hDlg, 1);
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
KillTimer(hDlg, 1);
EndDialog(hDlg, TRUE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
#endif
BOOL CALLBACK ConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
HWND hWndItem;
DWORD value;
switch (uMsg) {
case WM_INITDIALOG:
if (AudioHle == TRUE) {
CheckDlgButton(hDlg, IDC_AUDIOHLE, BST_CHECKED);
}
if (GraphicsHle == TRUE) {
CheckDlgButton(hDlg, IDC_GRAPHICSHLE, BST_CHECKED);
}
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
ComboBox_AddString(hWndItem, "Interpreter");
ComboBox_AddString(hWndItem, "Recompiler");
ComboBox_SetCurSel(hWndItem, CPUCore);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
value = ComboBox_GetCurSel(hWndItem);
SetCPU(value);
AudioHle = GetBooleanCheck(hDlg, IDC_AUDIOHLE);
GraphicsHle = GetBooleanCheck(hDlg, IDC_GRAPHICSHLE);
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
/*__declspec(dllexport) void DllConfig (HWND hWnd) {
// DialogBox(hinstDLL, "RSPCONFIG", hWnd, ConfigDlgProc);
DialogBox(hinstDLL, "RSPCONFIG", GetForegroundWindow(), ConfigDlgProc);
}*/
__declspec(dllexport) void EnableDebugging (BOOL Enabled) {
DebuggingEnabled = Enabled;
if (DebuggingEnabled)
{
BreakOnStart = GetSetting(Set_BreakOnStart);
CPUCore = GetSetting(Set_CPUCore);
LogRDP = GetSetting(Set_LogRDP);
LogX86Code = GetSetting(Set_LogX86Code);
Profiling = GetSetting(Set_Profiling);
IndvidualBlock = GetSetting(Set_IndvidualBlock);
ShowErrors = GetSetting(Set_ShowErrors);
Compiler.bDest = GetSetting(Set_CheckDest);
Compiler.bAccum = GetSetting(Set_Accum);
Compiler.mmx = GetSetting(Set_Mmx);
Compiler.mmx2 = GetSetting(Set_Mmx2);
Compiler.sse = GetSetting(Set_Sse);
Compiler.bSections = GetSetting(Set_Sections);
Compiler.bReOrdering = GetSetting(Set_ReOrdering);
Compiler.bGPRConstants = GetSetting(Set_GPRConstants);
Compiler.bFlags = GetSetting(Set_Flags);
Compiler.bAlignVector = GetSetting(Set_AlignVector);
SetCPU(CPUCore);
}
FixMenuState();
if (LogRDP)
{
StartRDPLog();
}
if (LogX86Code)
{
StartCPULog();
}
}
__declspec(dllexport) void PluginLoaded (void)
{
BreakOnStart = false;
CPUCore = RecompilerCPU;
LogRDP = FALSE;
LogX86Code = FALSE;
Profiling = FALSE;
IndvidualBlock = FALSE;
ShowErrors = FALSE;
memset(&Compiler, 0, sizeof(Compiler));
Compiler.bDest = TRUE;
Compiler.bAlignVector = FALSE;
Compiler.bFlags = TRUE;
Compiler.bReOrdering = TRUE;
Compiler.bSections = TRUE;
Compiler.bAccum = TRUE;
Compiler.bGPRConstants = TRUE;
DetectCpuSpecs();
SetModuleName("RSP");
RegisterSetting(Set_BreakOnStart, Data_DWORD_General,"Break on Start", NULL,BreakOnStart,NULL);
RegisterSetting(Set_CPUCore, Data_DWORD_General,"CPU Method", NULL,CPUCore,NULL);
RegisterSetting(Set_LogRDP, Data_DWORD_General,"Log RDP", NULL,LogRDP,NULL);
RegisterSetting(Set_LogX86Code, Data_DWORD_General,"Log X86 Code", NULL,LogX86Code,NULL);
RegisterSetting(Set_Profiling, Data_DWORD_General,"Profiling", NULL,Profiling,NULL);
RegisterSetting(Set_IndvidualBlock, Data_DWORD_General,"Indvidual Block",NULL,IndvidualBlock,NULL);
RegisterSetting(Set_AudioHle, Data_DWORD_General,"HLE Audio", NULL,FALSE,NULL);
RegisterSetting(Set_GraphicsHle, Data_DWORD_General,"HLE GFX", NULL,TRUE,NULL);
RegisterSetting(Set_ShowErrors, Data_DWORD_General,"Show Errors", NULL,ShowErrors,NULL);
//Compiler settings
RegisterSetting(Set_CheckDest, Data_DWORD_General,"Check Dest Vector", NULL,Compiler.bDest,NULL);
RegisterSetting(Set_Accum, Data_DWORD_General,"Check Dest Accum", NULL,Compiler.bAccum,NULL);
RegisterSetting(Set_Mmx, Data_DWORD_General,"Use MMX", NULL,Compiler.mmx,NULL);
RegisterSetting(Set_Mmx2, Data_DWORD_General,"Use MMX2", NULL,Compiler.mmx2,NULL);
RegisterSetting(Set_Sse, Data_DWORD_General,"Use SSE", NULL,Compiler.sse,NULL);
RegisterSetting(Set_Sections, Data_DWORD_General,"Use precompiled sections", NULL,Compiler.bSections,NULL);
RegisterSetting(Set_ReOrdering, Data_DWORD_General,"Reorder opcodes", NULL,Compiler.bReOrdering,NULL);
RegisterSetting(Set_GPRConstants, Data_DWORD_General,"Detect GPR Constants", NULL,Compiler.bGPRConstants,NULL);
RegisterSetting(Set_Flags, Data_DWORD_General,"Check Flag Usage", NULL,Compiler.bFlags,NULL);
RegisterSetting(Set_AlignVector, Data_DWORD_General,"Assume Vector loads align", NULL,Compiler.bAlignVector,NULL);
AudioHle = GetSetting(Set_AudioHle);
GraphicsHle = GetSetting(Set_GraphicsHle);
hMutex = CreateMutex(NULL, FALSE, NULL);
SetCPU(CPUCore);
}
void UseUnregisteredSetting (int SettingID)
{
_asm int 3
}

737
Source/RSP/Mmx.c Normal file
View File

@ -0,0 +1,737 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include "rsp.h"
#include "x86.h"
#include "memory.h"
#include "RSP registers.h"
#include "log.h"
#define PUTDST8(dest,value) (*((BYTE *)(dest))=(BYTE)(value)); dest += 1;
#define PUTDST16(dest,value) (*((WORD *)(dest))=(WORD)(value)); dest += 2;
#define PUTDST32(dest,value) (*((DWORD *)(dest))=(DWORD)(value)); dest += 4;
char * mmx_Strings[8] = {
"mm0", "mm1", "mm2", "mm3",
"mm4", "mm5", "mm6", "mm7"
};
#define mmx_Name(Reg) (mmx_Strings[(Reg)])
void MmxEmptyMultimediaState(void) {
CPU_Message(" emms");
PUTDST16(RecompPos,0x770f);
}
void MmxMoveRegToReg(int Dest, int Source) {
BYTE x86Command = 0;
CPU_Message(" movq %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0; break;
case x86_MM1: x86Command = 1; break;
case x86_MM2: x86Command = 2; break;
case x86_MM3: x86Command = 3; break;
case x86_MM4: x86Command = 4; break;
case x86_MM5: x86Command = 5; break;
case x86_MM6: x86Command = 6; break;
case x86_MM7: x86Command = 7; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0 << 3; break;
case x86_MM1: x86Command |= 1 << 3; break;
case x86_MM2: x86Command |= 2 << 3; break;
case x86_MM3: x86Command |= 3 << 3; break;
case x86_MM4: x86Command |= 4 << 3; break;
case x86_MM5: x86Command |= 5 << 3; break;
case x86_MM6: x86Command |= 6 << 3; break;
case x86_MM7: x86Command |= 7 << 3; break;
}
PUTDST16(RecompPos,0x7f0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxMoveQwordVariableToReg(int Dest, void *Variable, char *VariableName) {
BYTE x86Command;
CPU_Message(" movq %s, qword ptr [%s]",mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x6f0f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void MmxMoveQwordRegToVariable(int Dest, void *Variable, char *VariableName) {
BYTE x86Command;
CPU_Message(" movq qword ptr [%s], %s", VariableName, mmx_Name(Dest));
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x7f0f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void MmxPorRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" por %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xeb0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPorVariableToReg(void * Variable, char * VariableName, int Dest) {
BYTE x86Command;
CPU_Message(" por %s, qword ptr [%s]",mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xeb0f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void MmxPandRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pand %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xdb0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPandVariableToReg(void * Variable, char * VariableName, int Dest) {
BYTE x86Command;
CPU_Message(" pand %s, qword ptr [%s]",mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xdb0f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void MmxPandnRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pandn %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xdf0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxXorRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pxor %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0x00; break;
case x86_MM1: x86Command = 0x08; break;
case x86_MM2: x86Command = 0x10; break;
case x86_MM3: x86Command = 0x18; break;
case x86_MM4: x86Command = 0x20; break;
case x86_MM5: x86Command = 0x28; break;
case x86_MM6: x86Command = 0x30; break;
case x86_MM7: x86Command = 0x38; break;
}
switch (Source) {
case x86_MM0: x86Command += 0x00; break;
case x86_MM1: x86Command += 0x01; break;
case x86_MM2: x86Command += 0x02; break;
case x86_MM3: x86Command += 0x03; break;
case x86_MM4: x86Command += 0x04; break;
case x86_MM5: x86Command += 0x05; break;
case x86_MM6: x86Command += 0x06; break;
case x86_MM7: x86Command += 0x07; break;
}
PUTDST16(RecompPos,0xef0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxShuffleMemoryToReg(int Dest, void * Variable, char * VariableName, BYTE Immed) {
BYTE x86Command;
CPU_Message(" pshufw %s, [%s], %02X", mmx_Name(Dest), VariableName, Immed);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x700f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
PUTDST8(RecompPos, Immed);
}
void MmxPmullwRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pmullw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xd50f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPmullwVariableToReg(int Dest, void * Variable, char * VariableName) {
BYTE x86Command;
CPU_Message(" pmullw %s, [%s]", mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xd50f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos, Variable);
}
void MmxPmulhuwRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pmulhuw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xe40f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPmulhwRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pmulhw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xe50f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPmulhwRegToVariable(int Dest, void * Variable, char * VariableName) {
BYTE x86Command;
CPU_Message(" pmulhw %s, [%s]", mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xe50f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos, Variable);
}
void MmxPsrlwImmed(int Dest, BYTE Immed) {
BYTE x86Command;
CPU_Message(" psrlw %s, %i", mmx_Name(Dest), Immed);
switch (Dest) {
case x86_MM0: x86Command = 0xD0; break;
case x86_MM1: x86Command = 0xD1; break;
case x86_MM2: x86Command = 0xD2; break;
case x86_MM3: x86Command = 0xD3; break;
case x86_MM4: x86Command = 0xD4; break;
case x86_MM5: x86Command = 0xD5; break;
case x86_MM6: x86Command = 0xD6; break;
case x86_MM7: x86Command = 0xD7; break;
}
PUTDST16(RecompPos,0x710f);
PUTDST8(RecompPos, x86Command);
PUTDST8(RecompPos, Immed);
}
void MmxPsrawImmed(int Dest, BYTE Immed) {
BYTE x86Command;
CPU_Message(" psraw %s, %i", mmx_Name(Dest), Immed);
switch (Dest) {
case x86_MM0: x86Command = 0xE0; break;
case x86_MM1: x86Command = 0xE1; break;
case x86_MM2: x86Command = 0xE2; break;
case x86_MM3: x86Command = 0xE3; break;
case x86_MM4: x86Command = 0xE4; break;
case x86_MM5: x86Command = 0xE5; break;
case x86_MM6: x86Command = 0xE6; break;
case x86_MM7: x86Command = 0xE7; break;
}
PUTDST16(RecompPos,0x710f);
PUTDST8(RecompPos, x86Command);
PUTDST8(RecompPos, Immed);
}
void MmxPsllwImmed(int Dest, BYTE Immed) {
BYTE x86Command;
CPU_Message(" psllw %s, %i", mmx_Name(Dest), Immed);
switch (Dest) {
case x86_MM0: x86Command = 0xF0; break;
case x86_MM1: x86Command = 0xF1; break;
case x86_MM2: x86Command = 0xF2; break;
case x86_MM3: x86Command = 0xF3; break;
case x86_MM4: x86Command = 0xF4; break;
case x86_MM5: x86Command = 0xF5; break;
case x86_MM6: x86Command = 0xF6; break;
case x86_MM7: x86Command = 0xF7; break;
}
PUTDST16(RecompPos,0x710f);
PUTDST8(RecompPos, x86Command);
PUTDST8(RecompPos, Immed);
}
void MmxPaddswRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" paddsw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xed0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPsubswRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" psubsw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xe90f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPaddswVariableToReg(int Dest, void * Variable, char * VariableName) {
BYTE x86Command;
CPU_Message(" paddsw %s, [%s]", mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xed0f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos, Variable);
}
void MmxPsubswVariableToReg(int Dest, void * Variable, char * VariableName) {
BYTE x86Command;
CPU_Message(" psubsw %s, [%s]", mmx_Name(Dest), VariableName);
switch (Dest) {
case x86_MM0: x86Command = 0x05; break;
case x86_MM1: x86Command = 0x0D; break;
case x86_MM2: x86Command = 0x15; break;
case x86_MM3: x86Command = 0x1D; break;
case x86_MM4: x86Command = 0x25; break;
case x86_MM5: x86Command = 0x2D; break;
case x86_MM6: x86Command = 0x35; break;
case x86_MM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0xe90f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos, Variable);
}
void MmxPaddwRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" paddw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0xfd0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPackSignedDwords(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" packssdw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0x6b0f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxUnpackLowWord(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" punpcklwd %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0x610f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxUnpackHighWord(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" punpckhwd %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0x690f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxCompareGreaterWordRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" pcmpgtw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos,0x650f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}

204
Source/RSP/OpCode.h Normal file
View File

@ -0,0 +1,204 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#ifndef __OpCode
#define __OpCode
#include "Types.h"
typedef struct tagOPCODE {
union {
unsigned long Hex;
unsigned char Ascii[4];
struct {
unsigned offset : 16;
unsigned rt : 5;
unsigned rs : 5;
unsigned op : 6;
};
struct {
unsigned immediate : 16;
unsigned : 5;
unsigned base : 5;
unsigned : 6;
};
struct {
unsigned target : 26;
unsigned : 6;
};
struct {
unsigned funct : 6;
unsigned sa : 5;
unsigned rd : 5;
unsigned : 5;
unsigned : 5;
unsigned : 6;
};
struct {
signed voffset : 7;
unsigned del : 4;
unsigned : 5;
unsigned dest : 5;
unsigned : 5;
unsigned : 6;
};
};
} OPCODE;
//RSP OpCodes
#define RSP_SPECIAL 0
#define RSP_REGIMM 1
#define RSP_J 2
#define RSP_JAL 3
#define RSP_BEQ 4
#define RSP_BNE 5
#define RSP_BLEZ 6
#define RSP_BGTZ 7
#define RSP_ADDI 8
#define RSP_ADDIU 9
#define RSP_SLTI 10
#define RSP_SLTIU 11
#define RSP_ANDI 12
#define RSP_ORI 13
#define RSP_XORI 14
#define RSP_LUI 15
#define RSP_CP0 16
#define RSP_CP2 18
#define RSP_LB 32
#define RSP_LH 33
#define RSP_LW 35
#define RSP_LBU 36
#define RSP_LHU 37
#define RSP_SB 40
#define RSP_SH 41
#define RSP_SW 43
#define RSP_LC2 50
#define RSP_SC2 58
/* RSP Special opcodes */
#define RSP_SPECIAL_SLL 0
#define RSP_SPECIAL_SRL 2
#define RSP_SPECIAL_SRA 3
#define RSP_SPECIAL_SLLV 4
#define RSP_SPECIAL_SRLV 6
#define RSP_SPECIAL_SRAV 7
#define RSP_SPECIAL_JR 8
#define RSP_SPECIAL_JALR 9
#define RSP_SPECIAL_BREAK 13
#define RSP_SPECIAL_ADD 32
#define RSP_SPECIAL_ADDU 33
#define RSP_SPECIAL_SUB 34
#define RSP_SPECIAL_SUBU 35
#define RSP_SPECIAL_AND 36
#define RSP_SPECIAL_OR 37
#define RSP_SPECIAL_XOR 38
#define RSP_SPECIAL_NOR 39
#define RSP_SPECIAL_SLT 42
#define RSP_SPECIAL_SLTU 43
/* RSP RegImm opcodes */
#define RSP_REGIMM_BLTZ 0
#define RSP_REGIMM_BGEZ 1
#define RSP_REGIMM_BLTZAL 16
#define RSP_REGIMM_BGEZAL 17
/* RSP COP0 opcodes */
#define RSP_COP0_MF 0
#define RSP_COP0_MT 4
/* RSP COP2 opcodes */
#define RSP_COP2_MF 0
#define RSP_COP2_CF 2
#define RSP_COP2_MT 4
#define RSP_COP2_CT 6
/* RSP Vector opcodes */
#define RSP_VECTOR_VMULF 0
#define RSP_VECTOR_VMULU 1
#define RSP_VECTOR_VRNDP 2
#define RSP_VECTOR_VMULQ 3
#define RSP_VECTOR_VMUDL 4
#define RSP_VECTOR_VMUDM 5
#define RSP_VECTOR_VMUDN 6
#define RSP_VECTOR_VMUDH 7
#define RSP_VECTOR_VMACF 8
#define RSP_VECTOR_VMACU 9
#define RSP_VECTOR_VRNDN 10
#define RSP_VECTOR_VMACQ 11
#define RSP_VECTOR_VMADL 12
#define RSP_VECTOR_VMADM 13
#define RSP_VECTOR_VMADN 14
#define RSP_VECTOR_VMADH 15
#define RSP_VECTOR_VADD 16
#define RSP_VECTOR_VSUB 17
#define RSP_VECTOR_VABS 19
#define RSP_VECTOR_VADDC 20
#define RSP_VECTOR_VSUBC 21
#define RSP_VECTOR_VSAW 29
#define RSP_VECTOR_VLT 32
#define RSP_VECTOR_VEQ 33
#define RSP_VECTOR_VNE 34
#define RSP_VECTOR_VGE 35
#define RSP_VECTOR_VCL 36
#define RSP_VECTOR_VCH 37
#define RSP_VECTOR_VCR 38
#define RSP_VECTOR_VMRG 39
#define RSP_VECTOR_VAND 40
#define RSP_VECTOR_VNAND 41
#define RSP_VECTOR_VOR 42
#define RSP_VECTOR_VNOR 43
#define RSP_VECTOR_VXOR 44
#define RSP_VECTOR_VNXOR 45
#define RSP_VECTOR_VRCP 48
#define RSP_VECTOR_VRCPL 49
#define RSP_VECTOR_VRCPH 50
#define RSP_VECTOR_VMOV 51
#define RSP_VECTOR_VRSQ 52
#define RSP_VECTOR_VRSQL 53
#define RSP_VECTOR_VRSQH 54
#define RSP_VECTOR_VNOOP 55
/* RSP LSC2 opcodes */
#define RSP_LSC2_BV 0
#define RSP_LSC2_SV 1
#define RSP_LSC2_LV 2
#define RSP_LSC2_DV 3
#define RSP_LSC2_QV 4
#define RSP_LSC2_RV 5
#define RSP_LSC2_PV 6
#define RSP_LSC2_UV 7
#define RSP_LSC2_HV 8
#define RSP_LSC2_FV 9
#define RSP_LSC2_WV 10
#define RSP_LSC2_TV 11
#endif

307
Source/RSP/Profiling.cpp Normal file
View File

@ -0,0 +1,307 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
extern "C" {
#include "profiling.h"
}
#pragma warning(disable:4786)
#include <common/std string.h>
#include <common/Log Class.h>
#include <map>
#include <vector>
class CProfiling {
typedef std::map<DWORD, __int64 > PROFILE_ENRTIES;
typedef PROFILE_ENRTIES::iterator PROFILE_ENRTY;
typedef PROFILE_ENRTIES::value_type PROFILE_VALUE;
typedef struct { SPECIAL_TIMERS Timer; char * Name; } TIMER_NAME;
DWORD m_CurrentTimerAddr, CurrentDisplayCount;
DWORD m_StartTimeHi, m_StartTimeLo; //The Current Timer start time
PROFILE_ENRTIES m_Entries;
public:
CProfiling ()
{
m_CurrentTimerAddr = Timer_None;
}
//recording timing against current timer, returns the address of the timer stoped
DWORD StartTimer ( DWORD Address )
{
DWORD OldTimerAddr = StopTimer();
m_CurrentTimerAddr = Address;
DWORD HiValue, LoValue;
_asm {
pushad
rdtsc
mov HiValue, edx
mov LoValue, eax
popad
}
m_StartTimeHi = HiValue;
m_StartTimeLo = LoValue;
return OldTimerAddr;
}
DWORD StopTimer ( void )
{
DWORD HiValue, LoValue;
if (m_CurrentTimerAddr == Timer_None) { return m_CurrentTimerAddr; }
_asm {
pushad
rdtsc
mov HiValue, edx
mov LoValue, eax
popad
}
__int64 StopTime = ((unsigned __int64)HiValue << 32) + (unsigned __int64)LoValue;
__int64 StartTime = ((unsigned __int64)m_StartTimeHi << 32) + (unsigned __int64)m_StartTimeLo;
__int64 TimeTaken = StopTime - StartTime;
PROFILE_ENRTY Entry = m_Entries.find(m_CurrentTimerAddr);
if (Entry != m_Entries.end()) {
Entry->second += TimeTaken;
} else {
m_Entries.insert(PROFILE_ENRTIES::value_type(m_CurrentTimerAddr,TimeTaken));
}
DWORD OldTimerAddr = m_CurrentTimerAddr;
m_CurrentTimerAddr = Timer_None;
return OldTimerAddr;
}
//Reset all the counters back to 0
void ResetCounters ( void )
{
m_Entries.clear();
}
//Generate a log file with the current results, this will also reset the counters
void GenerateLog ( void )
{
stdstr LogFileName;
{
CLog Log;
Log.Open("RSP Profiling.txt");
LogFileName = Log.FileName();
//Get the total time
__int64 TotalTime = 0;
for (PROFILE_ENRTY itemTime = m_Entries.begin(); itemTime != m_Entries.end(); itemTime++ ) {
TotalTime += itemTime->second;
}
//Create a sortable list of items
std::vector<PROFILE_VALUE *> ItemList;
for (PROFILE_ENRTY Entry = m_Entries.begin(); Entry != m_Entries.end(); Entry++ ) {
ItemList.push_back(&(*Entry));
}
//sort the list with a basic bubble sort
if (ItemList.size() > 0)
{
for (int OuterPass = 0; OuterPass < (ItemList.size() - 1); OuterPass++ ) {
for (int InnerPass = 0; InnerPass < (ItemList.size() - 1); InnerPass++ ) {
if (ItemList[InnerPass]->second < ItemList[InnerPass + 1]->second) {
PROFILE_VALUE * TempPtr = ItemList[InnerPass];
ItemList[InnerPass] = ItemList[InnerPass + 1];
ItemList[InnerPass + 1] = TempPtr;
}
}
}
}
TIMER_NAME TimerNames[] = {
{Timer_Compiling, "RSP: Compiling"},
{Timer_RSP_Running, "RSP: Running"},
{Timer_R4300_Running, "R4300: Running"},
{Timer_RDP_Running, "RDP: Running"},
};
for (int count =0; count < ItemList.size(); count++ ) {
char Buffer[255];
float CpuUsage = ((double)ItemList[count]->second / (double)TotalTime) * 100;
if (CpuUsage <= 0.2) { continue; }
sprintf(Buffer,"Func 0x%08X",ItemList[count]->first);
for (int NameID = 0; NameID < (sizeof(TimerNames) / sizeof(TIMER_NAME)); NameID++) {
if (ItemList[count]->first == TimerNames[NameID].Timer) {
strcpy(Buffer,TimerNames[NameID].Name);
break;
}
}
Log.LogF("%s\t%2.2f",Buffer, CpuUsage);
}
}
ShellExecute(NULL,"open",LogFileName.c_str(),NULL,NULL,SW_SHOW);
ResetCounters();
}
};
CProfiling& GetProfiler ( void )
{
static CProfiling Profile;
return Profile;
}
void ResetTimerList (void) {
GetProfiler().ResetCounters();
}
DWORD StartTimer (DWORD Address) {
return GetProfiler().StartTimer(Address);
}
void StopTimer (void) {
GetProfiler().StopTimer();
}
void GenerateTimerResults (void) {
GetProfiler().GenerateLog();
}
#ifdef todelete
#include <windows.h>
#include <stdio.h>
typedef struct {
char Label[100];
_int64 TimeTotal;
} TIME_STAMP_ENTRY;
DWORD StartTimeHi, StartTimeLo, StopTimeHi, StopTimeLo, TSE_Count, TSE_Max;
TIME_STAMP_ENTRY * TS_Entries = NULL;
char LastLabel[100];
void ResetTimerList (void) {
if (TS_Entries) { free(TS_Entries); }
TS_Entries = NULL;
TSE_Count = 0;
TSE_Max = 0;
}
void StartTimer (char * Label) {
strcpy(LastLabel,Label);
_asm {
pushad
rdtsc
mov StartTimeHi, edx
mov StartTimeLo, eax
popad
}
}
void StopTimer (void) {
_asm {
pushad
rdtsc
mov StopTimeHi, edx
mov StopTimeLo, eax
popad
}
if (strlen(LastLabel) == 0) { return; }
{
DWORD count;
for (count = 0; count < TSE_Count; count ++) {
if (strcmp(LastLabel,TS_Entries[count].Label) == 0) {
_int64 Time = ((unsigned _int64)StopTimeHi << 32) + (unsigned _int64)StopTimeLo;
Time -= ((unsigned _int64)StartTimeHi << 32) + (unsigned _int64)StartTimeLo;
TS_Entries[count].TimeTotal += Time;
return;
}
}
}
if (TSE_Count == 0) {
TS_Entries = (TIME_STAMP_ENTRY *)malloc(sizeof(TIME_STAMP_ENTRY) * 100);
if (TS_Entries == NULL) {
MessageBox(NULL,"TIME_STAMP_ENTRY == NULL ??","ERROR",MB_OK|MB_ICONERROR|MB_SETFOREGROUND);
}
TSE_Max = 100;
} else if (TSE_Count == TSE_Max) {
TSE_Max += 100;
TS_Entries = (TIME_STAMP_ENTRY *)realloc(TS_Entries,sizeof(TIME_STAMP_ENTRY) * TSE_Max);
if (TS_Entries == NULL) {
MessageBox(NULL,"TIME_STAMP_ENTRY == NULL ??","ERROR",MB_OK|MB_ICONERROR|MB_SETFOREGROUND);
}
}
strcpy(TS_Entries[TSE_Count].Label,LastLabel);
TS_Entries[TSE_Count].TimeTotal = ((unsigned _int64)StopTimeHi << 32) + (unsigned _int64)StopTimeLo;
TS_Entries[TSE_Count].TimeTotal -= ((unsigned _int64)StartTimeHi << 32) + (unsigned _int64)StartTimeLo;
TSE_Count +=1;
}
void GenerateTimerResults (void) {
char buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR];
char fname[_MAX_FNAME],ext[_MAX_EXT], LogFileName[_MAX_PATH];
DWORD dwWritten, count, count2;
HANDLE hLogFile = NULL;
_int64 TotalTime;
StopTimer();
GetModuleFileName(NULL,buffer,sizeof(buffer));
_splitpath( buffer, drive, dir, fname, ext );
_makepath( LogFileName, drive, dir, "RSP Profiling", "log" );
hLogFile = CreateFile(LogFileName,GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
SetFilePointer(hLogFile,0,NULL,FILE_BEGIN);
for (count = 0; count < TSE_Count; count ++) {
for (count2 = 0; count2 < (TSE_Count - 1); count2 ++) {
if (TS_Entries[count2].TimeTotal < TS_Entries[count2 + 1].TimeTotal) {
TIME_STAMP_ENTRY Temp;
memcpy(&Temp,&TS_Entries[count2],sizeof(TIME_STAMP_ENTRY));
memcpy(&TS_Entries[count2],&TS_Entries[count2 + 1],sizeof(TIME_STAMP_ENTRY));
memcpy(&TS_Entries[count2 + 1],&Temp,sizeof(TIME_STAMP_ENTRY));
}
}
}
TotalTime = 0;
for (count = 0; count < TSE_Count; count ++) {
TotalTime += TS_Entries[count].TimeTotal;
}
for (count = 0; count < (TSE_Count < 50?TSE_Count:50); count ++) {
sprintf(buffer,"%s - %0.2f%c\r\n",
TS_Entries[count].Label,
(((double)TS_Entries[count].TimeTotal / (double)TotalTime) * 100),'%'
);
WriteFile( hLogFile,buffer,strlen(buffer),&dwWritten,NULL );
}
CloseHandle(hLogFile);
ResetTimerList();
}
#endif

37
Source/RSP/Profiling.h Normal file
View File

@ -0,0 +1,37 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
enum SPECIAL_TIMERS {
Timer_None = 0, Timer_Compiling = -1, Timer_RSP_Running = -2,
Timer_R4300_Running = -3, Timer_RDP_Running = -5, Timer_RefreshScreen = -6,
Timer_UpdateScreen = -7, Timer_UpdateFPS = -9, Timer_Idel = -10,
Timer_FuncLookup = -11,Timer_Done = -13,
};
void ResetTimerList ( void );
DWORD StartTimer ( DWORD Address );
void StopTimer ( void );
void GenerateTimerResults ( void );

1337
Source/RSP/RSP Command.c Normal file

File diff suppressed because it is too large Load Diff

40
Source/RSP/RSP Command.h Normal file
View File

@ -0,0 +1,40 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
char * RSPOpcodeName ( DWORD OpCode, DWORD PC );
void DumpRSPCode (void);
void DumpRSPData (void);
void Disable_RSP_Commands_Window ( void );
void Enable_RSP_Commands_Window ( void );
void Enter_RSP_Commands_Window ( void );
void RefreshRSPCommands ( void );
void SetRSPCommandToRunning ( void );
void SetRSPCommandToStepping ( void );
void SetRSPCommandViewto ( UINT NewLocation );
extern DWORD Stepping_Commands, WaitingForStep;
extern BOOL InRSPCommandsWindow;

667
Source/RSP/RSP Register.c Normal file
View File

@ -0,0 +1,667 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "rsp.h"
#include "types.h"
#define GeneralPurpose 1
#define ControlProcessor0 2
#define HiddenRegisters 3
#define Vector1 4
#define Vector2 5
#define IDC_TAB_CONTROL 1000
void Create_RSP_Register_Window ( int );
void HideRSP_RegisterPanel ( int );
void PaintRSP_HiddenPanel ( HWND );
void PaintRSP_CP0Panel ( HWND );
void PaintRSP_GPRPanel ( HWND );
void PaintRSP_Vector1_Panel ( HWND );
void PaintRSP_Vector2_Panel ( HWND );
void ShowRSP_RegisterPanel ( int );
void SetupRSP_HiddenPanel ( HWND );
void SetupRSP_CP0Panel ( HWND );
void SetupRSP_GPRPanel ( HWND );
void SetupRSP_RegistersMain ( HWND );
void SetupRSP_Vect1Panel ( HWND );
void SetupRSP_Vect2Panel ( HWND );
void UpdateRSPRegistersScreen ( void );
LRESULT CALLBACK RefreshRSP_RegProc ( HWND, UINT, WPARAM, LPARAM );
LRESULT CALLBACK RSP_Registers_Proc ( HWND, UINT, WPARAM, LPARAM );
HWND RSP_Registers_hDlg, hTab, hStatic, hGPR[32], hCP0[16], hHIDDEN[12],
hVECT1[16], hVECT2[16];
int InRSPRegisterWindow = FALSE;
FARPROC RefreshProc;
/*** RSP Registers ***/
UWORD32 RSP_GPR[32], RSP_Flags[4];
UDWORD RSP_ACCUM[8];
VECTOR RSP_Vect[32];
char * GPR_Strings[32] = {
"R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3",
"T0", "T1", "T2", "T3", "T4", "T5", "T6", "T7",
"S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7",
"T8", "T9", "K0", "K1", "GP", "SP", "S8", "RA"
};
void Create_RSP_Register_Window ( int Child ) {
DWORD ThreadID;
if ( Child ) {
InRSPRegisterWindow = TRUE;
DialogBox( hinstDLL, "RSPREGISTERS", NULL,(DLGPROC) RSP_Registers_Proc );
InRSPRegisterWindow = FALSE;
} else {
if (!InRSPRegisterWindow) {
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Create_RSP_Register_Window,
(LPVOID)TRUE,0, &ThreadID);
} else {
SetForegroundWindow(RSP_Registers_hDlg);
}
}
}
void Enter_RSP_Register_Window ( void ) {
Create_RSP_Register_Window ( FALSE );
}
void HideRSP_RegisterPanel ( int Panel) {
int count;
switch( Panel ) {
case GeneralPurpose:
for (count = 0; count < 32;count ++) { ShowWindow(hGPR[count], FALSE ); }
break;
case ControlProcessor0:
for (count = 0; count < 16;count ++) { ShowWindow(hCP0[count], FALSE ); }
break;
case HiddenRegisters:
for (count = 0; count < 12;count ++) { ShowWindow(hHIDDEN[count], FALSE ); }
break;
case Vector1:
for (count = 0; count < 16;count ++) { ShowWindow(hVECT1[count], FALSE ); }
break;
case Vector2:
for (count = 0; count < 16;count ++) { ShowWindow(hVECT2[count], FALSE ); }
break;
}
}
void InitilizeRSPRegisters (void) {
memset(RSP_GPR,0,sizeof(RSP_GPR));
memset(RSP_Vect,0,sizeof(RSP_Vect));
}
void PaintRSP_HiddenPanel (HWND hWnd) {
PAINTSTRUCT ps;
RECT rcBox;
HFONT hOldFont;
int OldBkMode;
BeginPaint( hWnd, &ps );
rcBox.left = 66; rcBox.top = 39;
rcBox.right = 320; rcBox.bottom = 265;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
rcBox.left = 350; rcBox.top = 39;
rcBox.right = 510; rcBox.bottom = 265;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
rcBox.left = 75; rcBox.top = 35;
rcBox.right = 150; rcBox.bottom = 50;
FillRect( ps.hdc, &rcBox,(HBRUSH)COLOR_WINDOW);
rcBox.left = 365; rcBox.top = 35;
rcBox.right = 425; rcBox.bottom = 50;
FillRect( ps.hdc, &rcBox,(HBRUSH)COLOR_WINDOW);
hOldFont = SelectObject( ps.hdc,
GetStockObject(DEFAULT_GUI_FONT) );
OldBkMode = SetBkMode( ps.hdc, TRANSPARENT );
TextOut( ps.hdc, 80,34,"Accumulators",12);
TextOut( ps.hdc, 80,56,"Accumulator 0:",14);
TextOut( ps.hdc, 80,81,"Accumulator 1:",14);
TextOut( ps.hdc, 80,106,"Accumulator 2:",14);
TextOut( ps.hdc, 80,131,"Accumulator 3:",14);
TextOut( ps.hdc, 80,156,"Accumulator 4:",14);
TextOut( ps.hdc, 80,181,"Accumulator 5:",14);
TextOut( ps.hdc, 80,206,"Accumulator 6:",14);
TextOut( ps.hdc, 80,231,"Accumulator 7:",14);
TextOut( ps.hdc, 371,34,"RSP Flags",9);
TextOut( ps.hdc, 375,86,"Flag 0:",7);
TextOut( ps.hdc, 375,116,"Flag 2:",7);
TextOut( ps.hdc, 375,146,"Flag 3:",7);
TextOut( ps.hdc, 375,176,"Flag 4:",7);
SelectObject( ps.hdc,hOldFont );
SetBkMode( ps.hdc, OldBkMode );
EndPaint( hWnd, &ps );
}
void PaintRSP_CP0Panel (HWND hWnd) {
PAINTSTRUCT ps;
RECT rcBox;
HFONT hOldFont;
int OldBkMode;
BeginPaint( hWnd, &ps );
rcBox.left = 41;
rcBox.top = 29;
rcBox.right = 573;
rcBox.bottom = 275;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
hOldFont = SelectObject( ps.hdc,
GetStockObject(DEFAULT_GUI_FONT) );
OldBkMode = SetBkMode( ps.hdc, TRANSPARENT );
TextOut( ps.hdc, 53,48,"Reg 0 - SP memory address:",26);
TextOut( ps.hdc, 53,76,"Reg 1 - SP DRAM DMA address:",28);
TextOut( ps.hdc, 53,104,"Reg 2 - SP read DMA length:",27);
TextOut( ps.hdc, 53,132,"Reg 3 - SP write DMA length:",28);
TextOut( ps.hdc, 53,160,"Reg 4 - SP status:",18);
TextOut( ps.hdc, 53,188,"Reg 5 - SP DMA full:",20);
TextOut( ps.hdc, 53,216,"Reg 6 - SP DMA busy:",20);
TextOut( ps.hdc, 53,244,"Reg 7 - SP semaphore:",21);
TextOut( ps.hdc, 313,48,"Reg 8 - DP CMD DMA start:",25);
TextOut( ps.hdc, 313,76,"Reg 9 - DP CMD DMA end:",23);
TextOut( ps.hdc, 313,104,"Reg 10 - DP CMD DMA current:",28);
TextOut( ps.hdc, 313,132,"Reg 11 - DP CMD status:",23);
TextOut( ps.hdc, 313,160,"Reg 12 - DP clock counter:",26);
TextOut( ps.hdc, 313,188,"Reg 13 - DP buffer busy counter:",32);
TextOut( ps.hdc, 313,216,"Reg 14 - DP pipe busy counter:",30);
TextOut( ps.hdc, 313,244,"Reg 15 - DP TMEM load counter:",30);
SelectObject( ps.hdc,hOldFont );
SetBkMode( ps.hdc, OldBkMode );
EndPaint( hWnd, &ps );
}
void PaintRSP_GPRPanel (HWND hWnd) {
PAINTSTRUCT ps;
RECT rcBox;
HFONT hOldFont;
int OldBkMode;
BeginPaint( hWnd, &ps );
rcBox.left = 41;
rcBox.top = 29;
rcBox.right = 573;
rcBox.bottom = 275;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
hOldFont = SelectObject( ps.hdc,
GetStockObject(DEFAULT_GUI_FONT) );
OldBkMode = SetBkMode( ps.hdc, TRANSPARENT );
TextOut( ps.hdc, 53,46,"R0 - Reg 0:",11);
TextOut( ps.hdc, 53,66,"AT - Reg 1:",11);
TextOut( ps.hdc, 53,86,"V0 - Reg 2:",11);
TextOut( ps.hdc, 53,106,"V1 - Reg 3:",11);
TextOut( ps.hdc, 53,126,"A0 - Reg 4:",11);
TextOut( ps.hdc, 53,146,"A1 - Reg 5:",11);
TextOut( ps.hdc, 53,166,"A2 - Reg 6:",11);
TextOut( ps.hdc, 53,186,"A3 - Reg 7:",11);
TextOut( ps.hdc, 53,206,"T0 - Reg 8:",11);
TextOut( ps.hdc, 53,226,"T1 - Reg 9:",11);
TextOut( ps.hdc, 53,246,"T2 - Reg 10:",12);
TextOut( ps.hdc, 228,46,"T3 - Reg 11:",12);
TextOut( ps.hdc, 228,66,"T4 - Reg 12:",12);
TextOut( ps.hdc, 228,86,"T5 - Reg 13:",12);
TextOut( ps.hdc, 228,106,"T6 - Reg 14:",12);
TextOut( ps.hdc, 228,126,"T7 - Reg 15:",12);
TextOut( ps.hdc, 228,146,"S0 - Reg 16:",12);
TextOut( ps.hdc, 228,166,"S1 - Reg 17:",12);
TextOut( ps.hdc, 228,186,"S2 - Reg 18:",12);
TextOut( ps.hdc, 228,206,"S3 - Reg 19:",12);
TextOut( ps.hdc, 228,226,"S4 - Reg 20:",12);
TextOut( ps.hdc, 228,246,"S5 - Reg 21:",12);
TextOut( ps.hdc, 408,46,"S6 - Reg 22:",12);
TextOut( ps.hdc, 408,66,"S7 - Reg 23:",12);
TextOut( ps.hdc, 408,86,"T8 - Reg 24:",12);
TextOut( ps.hdc, 408,106,"T9 - Reg 25:",12);
TextOut( ps.hdc, 408,126,"K0 - Reg 26:",12);
TextOut( ps.hdc, 408,146,"K1 - Reg 27:",12);
TextOut( ps.hdc, 408,166,"GP - Reg 28:",12);
TextOut( ps.hdc, 408,186,"SP - Reg 29:",12);
TextOut( ps.hdc, 408,206,"S8 - Reg 30:",12);
TextOut( ps.hdc, 408,226,"RA - Reg 31:",12);
SelectObject( ps.hdc,hOldFont );
SetBkMode( ps.hdc, OldBkMode );
EndPaint( hWnd, &ps );
}
void PaintRSP_Vector1_Panel (HWND hWnd) {
PAINTSTRUCT ps;
RECT rcBox;
HFONT hOldFont;
int OldBkMode;
BeginPaint( hWnd, &ps );
rcBox.left = 10;
rcBox.top = 29;
rcBox.right = 606;
rcBox.bottom = 275;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
hOldFont = SelectObject( ps.hdc,
GetStockObject(DEFAULT_GUI_FONT) );
OldBkMode = SetBkMode( ps.hdc, TRANSPARENT );
TextOut( ps.hdc, 20,48,"$v0:",4);
TextOut( ps.hdc, 20,76,"$v1:",4);
TextOut( ps.hdc, 20,104,"$v2:",4);
TextOut( ps.hdc, 20,132,"$v3:",4);
TextOut( ps.hdc, 20,160,"$v4:",4);
TextOut( ps.hdc, 20,188,"$v5:",4);
TextOut( ps.hdc, 20,216,"$v6:",4);
TextOut( ps.hdc, 20,244,"$v7:",4);
TextOut( ps.hdc, 310,48,"$v8:",4);
TextOut( ps.hdc, 310,76,"$v9:",4);
TextOut( ps.hdc, 310,104,"$v10:",5);
TextOut( ps.hdc, 310,132,"$v11:",5);
TextOut( ps.hdc, 310,160,"$v12:",5);
TextOut( ps.hdc, 310,188,"$v13:",5);
TextOut( ps.hdc, 310,216,"$v14:",5);
TextOut( ps.hdc, 310,244,"$v15:",5);
SelectObject( ps.hdc,hOldFont );
SetBkMode( ps.hdc, OldBkMode );
EndPaint( hWnd, &ps );
}
void PaintRSP_Vector2_Panel (HWND hWnd) {
PAINTSTRUCT ps;
RECT rcBox;
HFONT hOldFont;
int OldBkMode;
BeginPaint( hWnd, &ps );
rcBox.left = 10;
rcBox.top = 29;
rcBox.right = 606;
rcBox.bottom = 275;
DrawEdge( ps.hdc, &rcBox, EDGE_ETCHED, BF_RECT );
hOldFont = SelectObject( ps.hdc,
GetStockObject(DEFAULT_GUI_FONT) );
OldBkMode = SetBkMode( ps.hdc, TRANSPARENT );
TextOut( ps.hdc, 20,48,"$v16:",5);
TextOut( ps.hdc, 20,76,"$v17:",5);
TextOut( ps.hdc, 20,104,"$v18:",5);
TextOut( ps.hdc, 20,132,"$v19:",5);
TextOut( ps.hdc, 20,160,"$v20:",5);
TextOut( ps.hdc, 20,188,"$v21:",5);
TextOut( ps.hdc, 20,216,"$v22:",5);
TextOut( ps.hdc, 20,244,"$v23:",5);
TextOut( ps.hdc, 310,48,"$v24:",5);
TextOut( ps.hdc, 310,76,"$v25:",5);
TextOut( ps.hdc, 310,104,"$v26:",5);
TextOut( ps.hdc, 310,132,"$v27:",5);
TextOut( ps.hdc, 310,160,"$v28:",5);
TextOut( ps.hdc, 310,188,"$v29:",5);
TextOut( ps.hdc, 310,216,"$v30:",5);
TextOut( ps.hdc, 310,244,"$v31:",5);
SelectObject( ps.hdc,hOldFont );
SetBkMode( ps.hdc, OldBkMode );
EndPaint( hWnd, &ps );
}
LRESULT CALLBACK RefreshRSP_RegProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
int nSel;
TC_ITEM item;
switch( uMsg ) {
case WM_PAINT:
nSel = TabCtrl_GetCurSel( hTab );
if ( nSel > -1 ) {
item.mask = TCIF_PARAM;
TabCtrl_GetItem( hTab, nSel, &item );
switch( item.lParam ) {
case GeneralPurpose:
PaintRSP_GPRPanel (hWnd);
break;
case ControlProcessor0:
PaintRSP_CP0Panel (hWnd);
break;
case HiddenRegisters:
PaintRSP_HiddenPanel (hWnd);
break;
case Vector1:
PaintRSP_Vector1_Panel (hWnd);
break;
case Vector2:
PaintRSP_Vector2_Panel (hWnd);
break;
}
}
break;
default:
return( (*RefreshProc)(hWnd, uMsg, wParam, lParam) );
}
return( FALSE );
}
LRESULT CALLBACK RSP_Registers_Proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static RECT rcDisp;
static int CurrentPanel = GeneralPurpose;
TC_ITEM item;
switch (uMsg) {
case WM_INITDIALOG:
RSP_Registers_hDlg = hDlg;
SetupRSP_RegistersMain( hDlg );
break;
case WM_MOVE:
//StoreCurrentWinPos("RSP Registers",hDlg);
break;
case WM_SIZE:
GetClientRect( hDlg, &rcDisp);
TabCtrl_AdjustRect( hTab, FALSE, &rcDisp );
break;
case WM_NOTIFY:
switch (((NMHDR *)lParam)->code) {
case TCN_SELCHANGE:
InvalidateRect( hTab, &rcDisp, TRUE );
HideRSP_RegisterPanel (CurrentPanel);
item.mask = TCIF_PARAM;
TabCtrl_GetItem( hTab, TabCtrl_GetCurSel( hTab ), &item );
CurrentPanel = item.lParam;
InvalidateRect( hStatic, NULL, FALSE );
UpdateRSPRegistersScreen();
ShowRSP_RegisterPanel ( CurrentPanel );
break;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDCANCEL:
CurrentPanel = GeneralPurpose;
EndDialog( hDlg, IDCANCEL );
break;
}
default:
return FALSE;
}
return TRUE;
}
void SetupRSP_HiddenPanel (HWND hDlg) {
int count;
for (count = 0; count < 8;count ++) {
hHIDDEN[count] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,170,(count*25) + 60,140,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hHIDDEN[count],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 4;count ++) {
hHIDDEN[count + 8] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,425,(count*30) + 90,55,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hHIDDEN[count + 8],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
}
void SetupRSP_CP0Panel (HWND hDlg) {
int count;
for (count = 0; count < 8;count ++) {
hCP0[count] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,225,(count*28) + 53,75,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hCP0[count],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 8;count ++) {
hCP0[count + 8] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,485,(count*28) + 53,75,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hCP0[ count + 8 ],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
}
void SetupRSP_GPRPanel (HWND hDlg) {
int count;
for (count = 0; count < 11;count ++) {
hGPR[count] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,135,(count*20) + 50,75,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hGPR[count],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 11;count ++) {
hGPR[count + 11] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,315,(count*20) + 50,75,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hGPR[ count + 11 ],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 10;count ++) {
hGPR[count + 22] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,485,(count*20) + 50,75,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hGPR[ count + 22 ],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
}
void SetupRSP_RegistersMain (HWND hDlg) {
#define WindowWidth 630
#define WindowHeight 325
DWORD X, Y;
hTab = CreateWindowEx(0,WC_TABCONTROL,"", WS_TABSTOP | WS_CHILD | WS_VISIBLE,5,6,616,290,
hDlg,(HMENU)IDC_TAB_CONTROL,hinstDLL,NULL );
if ( hTab ) {
TC_ITEM item;
SendMessage(hTab, WM_SETFONT, (WPARAM)GetStockObject( DEFAULT_GUI_FONT ), 0);
item.mask = TCIF_TEXT | TCIF_PARAM;
item.pszText = " General Purpose ";
item.lParam = GeneralPurpose;
TabCtrl_InsertItem( hTab,0, &item);
item.lParam = ControlProcessor0;
item.pszText = " Control Processor 0 ";
TabCtrl_InsertItem( hTab,1, &item);
item.lParam = HiddenRegisters;
item.pszText = " Hidden Registers ";
TabCtrl_InsertItem( hTab,2, &item);
item.lParam = Vector1;
item.pszText = " RSP Vectors $v0 - $v15 ";
TabCtrl_InsertItem( hTab,3, &item);
item.lParam = Vector2;
item.pszText = " RSP Vectors $v16 - $v31 ";
TabCtrl_InsertItem( hTab,4, &item);
}
SetupRSP_HiddenPanel ( hDlg );
SetupRSP_CP0Panel ( hDlg );
SetupRSP_GPRPanel ( hDlg );
SetupRSP_Vect1Panel ( hDlg );
SetupRSP_Vect2Panel ( hDlg );
hStatic = CreateWindowEx(0,"STATIC","", WS_CHILD|WS_VISIBLE, 5,6,616,290,hDlg,0,hinstDLL,NULL );
RefreshProc = (FARPROC)SetWindowLong( hStatic,GWL_WNDPROC,(long)RefreshRSP_RegProc);
UpdateRSPRegistersScreen ();
ShowRSP_RegisterPanel ( GeneralPurpose );
SetWindowText(hDlg," RSP Registers");
//if ( !GetStoredWinPos( "RSP Registers", &X, &Y ) ) {
X = (GetSystemMetrics( SM_CXSCREEN ) - WindowWidth) / 2;
Y = (GetSystemMetrics( SM_CYSCREEN ) - WindowHeight) / 2;
//}
SetWindowPos(hDlg,NULL,X,Y,WindowWidth,WindowHeight, SWP_NOZORDER | SWP_SHOWWINDOW);
}
void SetupRSP_Vect1Panel (HWND hDlg) {
int count;
for (count = 0; count < 8;count ++) {
hVECT1[count] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,55,(count*28) + 52,254,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hVECT1[count],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 8;count ++) {
hVECT1[count + 8] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,345,(count*28) + 52,254,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hVECT1[count + 8],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
}
void SetupRSP_Vect2Panel (HWND hDlg) {
int count;
for (count = 0; count < 8;count ++) {
hVECT2[count] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,55,(count*28) + 52,254,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hVECT2[count],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
for (count = 0; count < 8;count ++) {
hVECT2[count + 8] = CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","", WS_CHILD |
ES_READONLY | WS_BORDER | WS_TABSTOP,345,(count*28) + 52,254,19,
hDlg,0,hinstDLL, NULL );
SendMessage(hVECT2[count + 8],WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
}
}
void ShowRSP_RegisterPanel ( int Panel) {
int count;
switch( Panel ) {
case GeneralPurpose:
for (count = 0; count < 32;count ++) { ShowWindow(hGPR[count], TRUE ); }
break;
case ControlProcessor0:
for (count = 0; count < 16;count ++) { ShowWindow(hCP0[count], TRUE ); }
break;
case HiddenRegisters:
for (count = 0; count < 12;count ++) { ShowWindow(hHIDDEN[count], TRUE ); }
break;
case Vector1:
for (count = 0; count < 16;count ++) { ShowWindow(hVECT1[count], TRUE ); }
break;
case Vector2:
for (count = 0; count < 16;count ++) { ShowWindow(hVECT2[count], TRUE ); }
break;
}
}
void UpdateRSPRegistersScreen ( void ) {
char RegisterValue[100];
int count, nSel;
TC_ITEM item;
if (!InRSPRegisterWindow) { return; }
nSel = TabCtrl_GetCurSel( hTab );
if ( nSel > -1 ) {
item.mask = TCIF_PARAM;
TabCtrl_GetItem( hTab, nSel, &item );
switch( item.lParam ) {
case GeneralPurpose:
for (count = 0; count < 32;count ++) {
sprintf(RegisterValue," 0x%08X",RSP_GPR[count].UW);
SetWindowText(hGPR[count],RegisterValue);
}
break;
case ControlProcessor0:
if (RSPInfo.SP_MEM_ADDR_REG)
{
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_MEM_ADDR_REG);
SetWindowText(hCP0[0],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_DRAM_ADDR_REG);
SetWindowText(hCP0[1],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_RD_LEN_REG);
SetWindowText(hCP0[2],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_WR_LEN_REG);
SetWindowText(hCP0[3],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_STATUS_REG);
SetWindowText(hCP0[4],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_DMA_FULL_REG);
SetWindowText(hCP0[5],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_DMA_BUSY_REG);
SetWindowText(hCP0[6],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.SP_SEMAPHORE_REG);
SetWindowText(hCP0[7],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_START_REG);
SetWindowText(hCP0[8],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_END_REG);
SetWindowText(hCP0[9],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_CURRENT_REG);
SetWindowText(hCP0[10],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_STATUS_REG);
SetWindowText(hCP0[11],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_CLOCK_REG);
SetWindowText(hCP0[12],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_BUFBUSY_REG);
SetWindowText(hCP0[13],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_PIPEBUSY_REG);
SetWindowText(hCP0[14],RegisterValue);
sprintf(RegisterValue," 0x%08X",*RSPInfo.DPC_TMEM_REG);
SetWindowText(hCP0[15],RegisterValue);
}
break;
case HiddenRegisters:
for (count = 0; count < 8;count ++) {
sprintf(RegisterValue," 0x%08X - %08X",RSP_ACCUM[count].W[1], RSP_ACCUM[count].W[0]);
SetWindowText(hHIDDEN[count],RegisterValue);
}
for (count = 0; count < 3;count ++) {
sprintf(RegisterValue," 0x%04X",RSP_Flags[count].UHW[0]);
SetWindowText(hHIDDEN[count + 8],RegisterValue);
}
sprintf(RegisterValue," 0x%04X",RSP_Flags[2].UHW[0]);
SetWindowText(hHIDDEN[11],RegisterValue);
break;
case Vector1:
for (count = 0; count < 16;count ++) {
sprintf(RegisterValue," 0x%08X - %08X - %08X - %08X", RSP_Vect[count].W[3],
RSP_Vect[count].W[2], RSP_Vect[count].W[1], RSP_Vect[count].W[0]);
SetWindowText(hVECT1[count],RegisterValue);
}
break;
case Vector2:
for (count = 0; count < 16;count ++) {
sprintf(RegisterValue," 0x%08X - %08X - %08X - %08X", RSP_Vect[count + 16].W[3],
RSP_Vect[count + 16].W[2], RSP_Vect[count + 16].W[1], RSP_Vect[count + 16].W[0]);
SetWindowText(hVECT2[count],RegisterValue);
}
break;
}
}
}

151
Source/RSP/RSP Registers.h Normal file
View File

@ -0,0 +1,151 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include "types.h"
#define SP_STATUS_HALT 0x001 /* Bit 0: halt */
#define SP_STATUS_BROKE 0x002 /* Bit 1: broke */
#define SP_STATUS_DMA_BUSY 0x004 /* Bit 2: dma busy */
#define SP_STATUS_DMA_FULL 0x008 /* Bit 3: dma full */
#define SP_STATUS_IO_FULL 0x010 /* Bit 4: io full */
#define SP_STATUS_SSTEP 0x020 /* Bit 5: single step */
#define SP_STATUS_INTR_BREAK 0x040 /* Bit 6: interrupt on break */
#define SP_STATUS_SIG0 0x080 /* Bit 7: signal 0 set */
#define SP_STATUS_SIG1 0x100 /* Bit 8: signal 1 set */
#define SP_STATUS_SIG2 0x200 /* Bit 9: signal 2 set */
#define SP_STATUS_SIG3 0x400 /* Bit 10: signal 3 set */
#define SP_STATUS_SIG4 0x800 /* Bit 11: signal 4 set */
#define SP_STATUS_SIG5 0x1000 /* Bit 12: signal 5 set */
#define SP_STATUS_SIG6 0x2000 /* Bit 13: signal 6 set */
#define SP_STATUS_SIG7 0x4000 /* Bit 14: signal 7 set */
#define SP_CLR_HALT 0x00001 /* Bit 0: clear halt */
#define SP_SET_HALT 0x00002 /* Bit 1: set halt */
#define SP_CLR_BROKE 0x00004 /* Bit 2: clear broke */
#define SP_CLR_INTR 0x00008 /* Bit 3: clear intr */
#define SP_SET_INTR 0x00010 /* Bit 4: set intr */
#define SP_CLR_SSTEP 0x00020 /* Bit 5: clear sstep */
#define SP_SET_SSTEP 0x00040 /* Bit 6: set sstep */
#define SP_CLR_INTR_BREAK 0x00080 /* Bit 7: clear intr on break */
#define SP_SET_INTR_BREAK 0x00100 /* Bit 8: set intr on break */
#define SP_CLR_SIG0 0x00200 /* Bit 9: clear signal 0 */
#define SP_SET_SIG0 0x00400 /* Bit 10: set signal 0 */
#define SP_CLR_SIG1 0x00800 /* Bit 11: clear signal 1 */
#define SP_SET_SIG1 0x01000 /* Bit 12: set signal 1 */
#define SP_CLR_SIG2 0x02000 /* Bit 13: clear signal 2 */
#define SP_SET_SIG2 0x04000 /* Bit 14: set signal 2 */
#define SP_CLR_SIG3 0x08000 /* Bit 15: clear signal 3 */
#define SP_SET_SIG3 0x10000 /* Bit 16: set signal 3 */
#define SP_CLR_SIG4 0x20000 /* Bit 17: clear signal 4 */
#define SP_SET_SIG4 0x40000 /* Bit 18: set signal 4 */
#define SP_CLR_SIG5 0x80000 /* Bit 19: clear signal 5 */
#define SP_SET_SIG5 0x100000 /* Bit 20: set signal 5 */
#define SP_CLR_SIG6 0x200000 /* Bit 21: clear signal 6 */
#define SP_SET_SIG6 0x400000 /* Bit 22: set signal 6 */
#define SP_CLR_SIG7 0x800000 /* Bit 23: clear signal 7 */
#define SP_SET_SIG7 0x1000000 /* Bit 24: set signal 7 */
#define DPC_CLR_XBUS_DMEM_DMA 0x0001 /* Bit 0: clear xbus_dmem_dma */
#define DPC_SET_XBUS_DMEM_DMA 0x0002 /* Bit 1: set xbus_dmem_dma */
#define DPC_CLR_FREEZE 0x0004 /* Bit 2: clear freeze */
#define DPC_SET_FREEZE 0x0008 /* Bit 3: set freeze */
#define DPC_CLR_FLUSH 0x0010 /* Bit 4: clear flush */
#define DPC_SET_FLUSH 0x0020 /* Bit 5: set flush */
#define DPC_CLR_TMEM_CTR 0x0040 /* Bit 6: clear tmem ctr */
#define DPC_CLR_PIPE_CTR 0x0080 /* Bit 7: clear pipe ctr */
#define DPC_CLR_CMD_CTR 0x0100 /* Bit 8: clear cmd ctr */
#define DPC_CLR_CLOCK_CTR 0x0200 /* Bit 9: clear clock ctr */
#define DPC_STATUS_XBUS_DMEM_DMA 0x001 /* Bit 0: xbus_dmem_dma */
#define DPC_STATUS_FREEZE 0x002 /* Bit 1: freeze */
#define DPC_STATUS_FLUSH 0x004 /* Bit 2: flush */
#define DPC_STATUS_START_GCLK 0x008 /* Bit 3: start gclk */
#define DPC_STATUS_TMEM_BUSY 0x010 /* Bit 4: tmem busy */
#define DPC_STATUS_PIPE_BUSY 0x020 /* Bit 5: pipe busy */
#define DPC_STATUS_CMD_BUSY 0x040 /* Bit 6: cmd busy */
#define DPC_STATUS_CBUF_READY 0x080 /* Bit 7: cbuf ready */
#define DPC_STATUS_DMA_BUSY 0x100 /* Bit 8: dma busy */
#define DPC_STATUS_END_VALID 0x200 /* Bit 9: end valid */
#define DPC_STATUS_START_VALID 0x400 /* Bit 10: start valid */
#define R4300i_SP_Intr 0x1
extern char * x86_Strings[8];
extern char * GPR_Strings[32];
#define x86_Name(Reg) (x86_Strings[(Reg)])
#define GPR_Name(Reg) (GPR_Strings[(Reg)])
/*
#define GPR_Name(Reg)\
(Reg) == 0 ? "R0" : (Reg) == 1 ? "AT" : (Reg) == 2 ? "V0" : (Reg) == 3 ? "V1" :\
(Reg) == 4 ? "A0" : (Reg) == 5 ? "A1" : (Reg) == 6 ? "A2" : (Reg) == 7 ? "A3" :\
(Reg) == 8 ? "T0" : (Reg) == 9 ? "T1" : (Reg) == 10 ? "T2" : (Reg) == 11 ? "T3" :\
(Reg) == 12 ? "T4" : (Reg) == 13 ? "T5" : (Reg) == 14 ? "T6" : (Reg) == 15 ? "T7" :\
(Reg) == 16 ? "S0" : (Reg) == 17 ? "S1" : (Reg) == 18 ? "S2" : (Reg) == 19 ? "S3" :\
(Reg) == 20 ? "S4" : (Reg) == 21 ? "S5" : (Reg) == 22 ? "S6" : (Reg) == 23 ? "S7" :\
(Reg) == 24 ? "T8" : (Reg) == 25 ? "T9" : (Reg) == 26 ? "K0" : (Reg) == 27 ? "K1" :\
(Reg) == 28 ? "GP" : (Reg) == 29 ? "SP" : (Reg) == 30 ? "S8" :\
(Reg) == 31 ? "RA" : "Unknown Register"
*/
#define COP0_Name(Reg)\
(Reg) == 0 ? "SP memory address" :\
(Reg) == 1 ? "SP DRAM DMA address" :\
(Reg) == 2 ? "SP read DMA length" :\
(Reg) == 3 ? "SP write DMA length" :\
(Reg) == 4 ? "SP status" :\
(Reg) == 5 ? "SP DMA full" :\
(Reg) == 6 ? "SP DMA busy" :\
(Reg) == 7 ? "SP semaphore" :\
(Reg) == 8 ? "DP CMD DMA start" :\
(Reg) == 9 ? "DP CMD DMA end" :\
(Reg) == 10 ? "DP CMD DMA current" :\
(Reg) == 11 ? "DP CMD status" :\
(Reg) == 12 ? "DP clock counter" :\
(Reg) == 13 ? "DP buffer busy counter" :\
(Reg) == 14 ? "DP pipe busy counter" :\
(Reg) == 15 ? "DP TMEM load counter" :\
"Unknown Register"
#define ElementSpecifier(Elem)\
(Elem) == 0 ? "" : (Elem) == 1 ? "" : (Elem) == 2 ? " [0q]" :\
(Elem) == 3 ? " [1q]" : (Elem) == 4 ? " [0h]" : (Elem) == 5 ? " [1h]" :\
(Elem) == 6 ? " [2h]" : (Elem) == 7 ? " [3h]" : (Elem) == 8 ? " [0]" :\
(Elem) == 9 ? " [1]" : (Elem) == 10 ? " [2]" : (Elem) == 11 ? " [3]" :\
(Elem) == 12 ? " [4]" : (Elem) == 13 ? " [5]" : (Elem) == 14 ? " [6]" :\
(Elem) == 15 ? " [7]" : "Unknown Element"
void Enter_RSP_Register_Window ( void );
void InitilizeRSPRegisters (void);
void UpdateRSPRegistersScreen ( void );
/*** RSP Registers ***/
extern UWORD32 RSP_GPR[32], RSP_Flags[4];
extern UDWORD RSP_ACCUM[8];
extern VECTOR RSP_Vect[32];

291
Source/RSP/RSP.dsp Normal file
View File

@ -0,0 +1,291 @@
# Microsoft Developer Studio Project File - Name="RSP" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=RSP - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "RSP.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "RSP.mak" CFG="RSP - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "RSP - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "RSP - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "RSP - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../Build/RSP/Release"
# PROP Intermediate_Dir "../../Build/RSP/Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RSP_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RSP_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0xc09 /d "NDEBUG"
# ADD RSC /l 0xc09 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../Bin/Release/RSP 1.7.dll"
!ELSEIF "$(CFG)" == "RSP - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../Build/RSP/Debug"
# PROP Intermediate_Dir "../../Build/RSP/Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RSP_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../" /I "./" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RSP_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0xc09 /d "_DEBUG"
# ADD RSC /l 0xc09 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/Debug/RSP 1.7.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "RSP - Win32 Release"
# Name "RSP - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Group "RSP Source Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\breakpoint.c
# End Source File
# Begin Source File
SOURCE=.\Cpu.c
# End Source File
# Begin Source File
SOURCE=.\dma.c
# End Source File
# Begin Source File
SOURCE=".\Interpreter CPU.c"
# End Source File
# Begin Source File
SOURCE=".\Interpreter Ops.c"
# End Source File
# Begin Source File
SOURCE=.\log.cpp
# End Source File
# Begin Source File
SOURCE=.\memory.c
# End Source File
# Begin Source File
SOURCE=.\Mmx.c
# End Source File
# Begin Source File
SOURCE=.\Profiling.cpp
# End Source File
# Begin Source File
SOURCE=".\Recompiler Analysis.c"
# End Source File
# Begin Source File
SOURCE=".\Recompiler CPU.c"
# End Source File
# Begin Source File
SOURCE=".\Recompiler Ops.c"
# End Source File
# Begin Source File
SOURCE=".\Recompiler Sections.c"
# End Source File
# Begin Source File
SOURCE=".\RSP Command.c"
# End Source File
# Begin Source File
SOURCE=".\RSP Register.c"
# End Source File
# Begin Source File
SOURCE=.\RSP.rc
# End Source File
# Begin Source File
SOURCE=.\Sse.c
# End Source File
# Begin Source File
SOURCE=.\X86.c
# End Source File
# End Group
# Begin Source File
SOURCE=.\Main.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Group "RSP Header Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\breakpoint.h
# End Source File
# Begin Source File
SOURCE=.\Cpu.h
# End Source File
# Begin Source File
SOURCE=.\dma.h
# End Source File
# Begin Source File
SOURCE=".\Interpreter CPU.h"
# End Source File
# Begin Source File
SOURCE=".\Interpreter Ops.h"
# End Source File
# Begin Source File
SOURCE=.\log.h
# End Source File
# Begin Source File
SOURCE=.\memory.h
# End Source File
# Begin Source File
SOURCE=.\OpCode.h
# End Source File
# Begin Source File
SOURCE=.\Profiling.h
# End Source File
# Begin Source File
SOURCE=".\Recompiler CPU.h"
# End Source File
# Begin Source File
SOURCE=".\Recompiler Ops.h"
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=".\RSP Command.h"
# End Source File
# Begin Source File
SOURCE=".\RSP Registers.h"
# End Source File
# Begin Source File
SOURCE=.\Rsp.h
# End Source File
# Begin Source File
SOURCE=.\Types.h
# End Source File
# Begin Source File
SOURCE=.\X86.h
# End Source File
# End Group
# Begin Group "Support Headers"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Support\CriticalSection.h
# End Source File
# Begin Source File
SOURCE=".\Support\Ini File Class.h"
# End Source File
# Begin Source File
SOURCE=".\Support\Log Class.h"
# End Source File
# Begin Source File
SOURCE=.\Support\md5.h
# End Source File
# Begin Source File
SOURCE=".\Support\std string.h"
# End Source File
# Begin Source File
SOURCE=.\Support\Support.h
# End Source File
# Begin Source File
SOURCE=.\Support\Version.h
# End Source File
# Begin Source File
SOURCE=.\Support\XString.h
# End Source File
# End Group
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

269
Source/RSP/RSP.rc Normal file
View File

@ -0,0 +1,269 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
RSPCOMMAND DIALOG DISCARDABLE 0, 0, 187, 94
STYLE DS_MODALFRAME | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
FONT 8, "MS Sans Serif"
BEGIN
END
RSPREGISTERS DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
END
RSPCOMPILER DIALOGEX 0, 0, 226, 135
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "RSP Compiler"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "OK",IDOK,109,113,50,14
PUSHBUTTON "Cancel",IDCANCEL,161,113,50,14
CONTROL "SSE",IDC_CHECK_SSE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,127,74,30,10
CONTROL "MMX",IDC_CHECK_MMX,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,127,46,33,10
CONTROL "MMX ²",IDC_CHECK_MMX2,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,127,60,37,10
CONTROL "Vector Dest Analysis",IDC_COMPILER_DEST,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,18,81,10
CONTROL "Accumulator Analysis",IDC_COMPILER_ACCUM,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,32,83,10
CONTROL "Flag Analysis",IDC_COMPILER_FLAGS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,46,57,10
CONTROL "Instruction Re-ordering",IDC_COMPILER_REORDER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,74,87,10
CONTROL "Microcode sections",IDC_COMPILER_SECTIONS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,127,88,77,10
CONTROL "GPR Mem Aligned",IDC_COMPILER_ALIGNGPR,"Button",
BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,127,18,74,10
CONTROL "VEC Mem Aligned",IDC_COMPILER_ALIGNVEC,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,127,32,73,10
GROUPBOX "",IDC_STATIC,7,3,209,104
CONTROL "GPR Constant Analysis",IDC_COMPILER_GPRCONSTANTS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,60,89,10
CTEXT "x86: 0.00 KB / 0.00 KB",IDC_COMPILER_BUFFERS,21,89,91,
11,SS_CENTERIMAGE,WS_EX_CLIENTEDGE
END
RSPCONFIG DIALOG DISCARDABLE 0, 0, 179, 138
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "Configure RSP"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "OK",IDOK,38,116,50,14
PUSHBUTTON "Cancel",IDCANCEL,90,116,50,14
CONTROL "send Audio Lists to Audio Plugin",IDC_AUDIOHLE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,22,42,117,10
CTEXT "disables RSP emulation for the following lists, allows plugins to process them instead",
IDC_STATIC,13,15,155,20
GROUPBOX "",IDC_STATIC,7,3,165,69
CONTROL "send Display Lists to Graphics Plugin",IDC_GRAPHICSHLE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,55,131,10
GROUPBOX "",IDC_STATIC,7,73,166,34
LTEXT "CPU core style:",IDC_STATIC,18,88,50,8
COMBOBOX IDC_COMPILER_SELECT,83,86,78,39,CBS_DROPDOWNLIST |
WS_TABSTOP
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO MOVEABLE PURE
BEGIN
"RSPCOMMAND", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 180
TOPMARGIN, 7
BOTTOMMARGIN, 87
END
"RSPREGISTERS", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
"RSPCOMPILER", DIALOG
BEGIN
LEFTMARGIN, 6
RIGHTMARGIN, 217
TOPMARGIN, 7
BOTTOMMARGIN, 127
END
"RSPCONFIG", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 172
TOPMARGIN, 7
BOTTOMMARGIN, 131
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE MOVEABLE PURE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE MOVEABLE PURE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE MOVEABLE PURE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
RspMenu MENU DISCARDABLE
BEGIN
MENUITEM "RSP &Commands...", ID_RSPCOMMANDS
MENUITEM "RSP &Registers...", ID_RSPREGISTERS
MENUITEM "RSP Com&piler...", ID_COMPILER
MENUITEM SEPARATOR
POPUP "CPU Method"
BEGIN
MENUITEM "Recompiler", ID_CPUMETHOD_RECOMPILER
MENUITEM "Interpreter", ID_CPUMETHOD_INTERPT
END
MENUITEM SEPARATOR
POPUP "Pro&filing"
BEGIN
MENUITEM "&On", ID_PROFILING_ON
MENUITEM "O&ff", ID_PROFILING_OFF
MENUITEM SEPARATOR
MENUITEM "Reset Stats", ID_PROFILING_RESETSTATS
MENUITEM "Generate Log", ID_PROFILING_GENERATELOG
MENUITEM SEPARATOR
MENUITEM "Log Individual Blocks", ID_PROFILING_LOGINDIVIDUALBLOCKS
END
POPUP "Dump"
BEGIN
MENUITEM "&RSP code", ID_DUMP_RSPCODE
MENUITEM "DMEM", ID_DUMP_DMEM
END
POPUP "Settings"
BEGIN
MENUITEM "Show Compiler Errors", ID_SHOWCOMPILERERRORS
MENUITEM "Break on start of task", ID_BREAKONSTARTOFTASK
MENUITEM "Log RDP Commands", ID_LOGRDPCOMMANDS
MENUITEM "Log X86 code", ID_SETTINGS_LOGX86CODE
END
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,7,0,2
PRODUCTVERSION 1,7,0,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Project64\0"
VALUE "FileDescription", "RSP emulation Plugin\0"
VALUE "FileVersion", "1, 7, 0, 2\0"
VALUE "InternalName", "RSP Plugin\0"
VALUE "LegalCopyright", "Copyright © 2006\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "RSP.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", " RSP\0"
VALUE "ProductVersion", "1, 7, 0, 2\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0xc09, 1200
END
END
#endif // !_MAC
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

File diff suppressed because it is too large Load Diff

941
Source/RSP/Recompiler CPU.c Normal file
View File

@ -0,0 +1,941 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include <float.h>
#include "RSP.h"
#include "Cpu.h"
#include "Recompiler CPU.h"
#include "Recompiler Ops.h"
#include "RSP registers.h"
#include "RSP Command.h"
#include "memory.h"
#include "opcode.h"
#include "log.h"
#include "Profiling.h"
#include "x86.h"
/* #define REORDER_BLOCK_VERBOSE */
#define LINK_BRANCHES_VERBOSE /* no choice really */
#define X86_RECOMP_VERBOSE
#define BUILD_BRANCHLABELS_VERBOSE
DWORD CompilePC, BlockID = 0;
DWORD dwBuffer = MainBuffer;
BOOL ChangedPC;
RSP_BLOCK CurrentBlock;
RSP_CODE RspCode;
BYTE * pLastSecondary = NULL, * pLastPrimary = NULL;
void BuildRecompilerCPU ( void ) {
RSP_Opcode[ 0] = Compile_SPECIAL;
RSP_Opcode[ 1] = Compile_REGIMM;
RSP_Opcode[ 2] = Compile_J;
RSP_Opcode[ 3] = Compile_JAL;
RSP_Opcode[ 4] = Compile_BEQ;
RSP_Opcode[ 5] = Compile_BNE;
RSP_Opcode[ 6] = Compile_BLEZ;
RSP_Opcode[ 7] = Compile_BGTZ;
RSP_Opcode[ 8] = Compile_ADDI;
RSP_Opcode[ 9] = Compile_ADDIU;
RSP_Opcode[10] = Compile_SLTI;
RSP_Opcode[11] = Compile_SLTIU;
RSP_Opcode[12] = Compile_ANDI;
RSP_Opcode[13] = Compile_ORI;
RSP_Opcode[14] = Compile_XORI;
RSP_Opcode[15] = Compile_LUI;
RSP_Opcode[16] = Compile_COP0;
RSP_Opcode[17] = Compile_UnknownOpcode;
RSP_Opcode[18] = Compile_COP2;
RSP_Opcode[19] = Compile_UnknownOpcode;
RSP_Opcode[20] = Compile_UnknownOpcode;
RSP_Opcode[21] = Compile_UnknownOpcode;
RSP_Opcode[22] = Compile_UnknownOpcode;
RSP_Opcode[23] = Compile_UnknownOpcode;
RSP_Opcode[24] = Compile_UnknownOpcode;
RSP_Opcode[25] = Compile_UnknownOpcode;
RSP_Opcode[26] = Compile_UnknownOpcode;
RSP_Opcode[27] = Compile_UnknownOpcode;
RSP_Opcode[28] = Compile_UnknownOpcode;
RSP_Opcode[29] = Compile_UnknownOpcode;
RSP_Opcode[30] = Compile_UnknownOpcode;
RSP_Opcode[31] = Compile_UnknownOpcode;
RSP_Opcode[32] = Compile_LB;
RSP_Opcode[33] = Compile_LH;
RSP_Opcode[34] = Compile_UnknownOpcode;
RSP_Opcode[35] = Compile_LW;
RSP_Opcode[36] = Compile_LBU;
RSP_Opcode[37] = Compile_LHU;
RSP_Opcode[38] = Compile_UnknownOpcode;
RSP_Opcode[39] = Compile_UnknownOpcode;
RSP_Opcode[40] = Compile_SB;
RSP_Opcode[41] = Compile_SH;
RSP_Opcode[42] = Compile_UnknownOpcode;
RSP_Opcode[43] = Compile_SW;
RSP_Opcode[44] = Compile_UnknownOpcode;
RSP_Opcode[45] = Compile_UnknownOpcode;
RSP_Opcode[46] = Compile_UnknownOpcode;
RSP_Opcode[47] = Compile_UnknownOpcode;
RSP_Opcode[48] = Compile_UnknownOpcode;
RSP_Opcode[49] = Compile_UnknownOpcode;
RSP_Opcode[50] = Compile_LC2;
RSP_Opcode[51] = Compile_UnknownOpcode;
RSP_Opcode[52] = Compile_UnknownOpcode;
RSP_Opcode[53] = Compile_UnknownOpcode;
RSP_Opcode[54] = Compile_UnknownOpcode;
RSP_Opcode[55] = Compile_UnknownOpcode;
RSP_Opcode[56] = Compile_UnknownOpcode;
RSP_Opcode[57] = Compile_UnknownOpcode;
RSP_Opcode[58] = Compile_SC2;
RSP_Opcode[59] = Compile_UnknownOpcode;
RSP_Opcode[60] = Compile_UnknownOpcode;
RSP_Opcode[61] = Compile_UnknownOpcode;
RSP_Opcode[62] = Compile_UnknownOpcode;
RSP_Opcode[63] = Compile_UnknownOpcode;
RSP_Special[ 0] = Compile_Special_SLL;
RSP_Special[ 1] = Compile_UnknownOpcode;
RSP_Special[ 2] = Compile_Special_SRL;
RSP_Special[ 3] = Compile_Special_SRA;
RSP_Special[ 4] = Compile_Special_SLLV;
RSP_Special[ 5] = Compile_UnknownOpcode;
RSP_Special[ 6] = Compile_Special_SRLV;
RSP_Special[ 7] = Compile_Special_SRAV;
RSP_Special[ 8] = Compile_Special_JR;
RSP_Special[ 9] = Compile_Special_JALR;
RSP_Special[10] = Compile_UnknownOpcode;
RSP_Special[11] = Compile_UnknownOpcode;
RSP_Special[12] = Compile_UnknownOpcode;
RSP_Special[13] = Compile_Special_BREAK;
RSP_Special[14] = Compile_UnknownOpcode;
RSP_Special[15] = Compile_UnknownOpcode;
RSP_Special[16] = Compile_UnknownOpcode;
RSP_Special[17] = Compile_UnknownOpcode;
RSP_Special[18] = Compile_UnknownOpcode;
RSP_Special[19] = Compile_UnknownOpcode;
RSP_Special[20] = Compile_UnknownOpcode;
RSP_Special[21] = Compile_UnknownOpcode;
RSP_Special[22] = Compile_UnknownOpcode;
RSP_Special[23] = Compile_UnknownOpcode;
RSP_Special[24] = Compile_UnknownOpcode;
RSP_Special[25] = Compile_UnknownOpcode;
RSP_Special[26] = Compile_UnknownOpcode;
RSP_Special[27] = Compile_UnknownOpcode;
RSP_Special[28] = Compile_UnknownOpcode;
RSP_Special[29] = Compile_UnknownOpcode;
RSP_Special[30] = Compile_UnknownOpcode;
RSP_Special[31] = Compile_UnknownOpcode;
RSP_Special[32] = Compile_Special_ADD;
RSP_Special[33] = Compile_Special_ADDU;
RSP_Special[34] = Compile_Special_SUB;
RSP_Special[35] = Compile_Special_SUBU;
RSP_Special[36] = Compile_Special_AND;
RSP_Special[37] = Compile_Special_OR;
RSP_Special[38] = Compile_Special_XOR;
RSP_Special[39] = Compile_Special_NOR;
RSP_Special[40] = Compile_UnknownOpcode;
RSP_Special[41] = Compile_UnknownOpcode;
RSP_Special[42] = Compile_Special_SLT;
RSP_Special[43] = Compile_Special_SLTU;
RSP_Special[44] = Compile_UnknownOpcode;
RSP_Special[45] = Compile_UnknownOpcode;
RSP_Special[46] = Compile_UnknownOpcode;
RSP_Special[47] = Compile_UnknownOpcode;
RSP_Special[48] = Compile_UnknownOpcode;
RSP_Special[49] = Compile_UnknownOpcode;
RSP_Special[50] = Compile_UnknownOpcode;
RSP_Special[51] = Compile_UnknownOpcode;
RSP_Special[52] = Compile_UnknownOpcode;
RSP_Special[53] = Compile_UnknownOpcode;
RSP_Special[54] = Compile_UnknownOpcode;
RSP_Special[55] = Compile_UnknownOpcode;
RSP_Special[56] = Compile_UnknownOpcode;
RSP_Special[57] = Compile_UnknownOpcode;
RSP_Special[58] = Compile_UnknownOpcode;
RSP_Special[59] = Compile_UnknownOpcode;
RSP_Special[60] = Compile_UnknownOpcode;
RSP_Special[61] = Compile_UnknownOpcode;
RSP_Special[62] = Compile_UnknownOpcode;
RSP_Special[63] = Compile_UnknownOpcode;
RSP_RegImm[ 0] = Compile_RegImm_BLTZ;
RSP_RegImm[ 1] = Compile_RegImm_BGEZ;
RSP_RegImm[ 2] = Compile_UnknownOpcode;
RSP_RegImm[ 3] = Compile_UnknownOpcode;
RSP_RegImm[ 4] = Compile_UnknownOpcode;
RSP_RegImm[ 5] = Compile_UnknownOpcode;
RSP_RegImm[ 6] = Compile_UnknownOpcode;
RSP_RegImm[ 7] = Compile_UnknownOpcode;
RSP_RegImm[ 8] = Compile_UnknownOpcode;
RSP_RegImm[ 9] = Compile_UnknownOpcode;
RSP_RegImm[10] = Compile_UnknownOpcode;
RSP_RegImm[11] = Compile_UnknownOpcode;
RSP_RegImm[12] = Compile_UnknownOpcode;
RSP_RegImm[13] = Compile_UnknownOpcode;
RSP_RegImm[14] = Compile_UnknownOpcode;
RSP_RegImm[15] = Compile_UnknownOpcode;
RSP_RegImm[16] = Compile_RegImm_BLTZAL;
RSP_RegImm[17] = Compile_RegImm_BGEZAL;
RSP_RegImm[18] = Compile_UnknownOpcode;
RSP_RegImm[19] = Compile_UnknownOpcode;
RSP_RegImm[20] = Compile_UnknownOpcode;
RSP_RegImm[21] = Compile_UnknownOpcode;
RSP_RegImm[22] = Compile_UnknownOpcode;
RSP_RegImm[23] = Compile_UnknownOpcode;
RSP_RegImm[24] = Compile_UnknownOpcode;
RSP_RegImm[25] = Compile_UnknownOpcode;
RSP_RegImm[26] = Compile_UnknownOpcode;
RSP_RegImm[27] = Compile_UnknownOpcode;
RSP_RegImm[28] = Compile_UnknownOpcode;
RSP_RegImm[29] = Compile_UnknownOpcode;
RSP_RegImm[30] = Compile_UnknownOpcode;
RSP_RegImm[31] = Compile_UnknownOpcode;
RSP_Cop0[ 0] = Compile_Cop0_MF;
RSP_Cop0[ 1] = Compile_UnknownOpcode;
RSP_Cop0[ 2] = Compile_UnknownOpcode;
RSP_Cop0[ 3] = Compile_UnknownOpcode;
RSP_Cop0[ 4] = Compile_Cop0_MT;
RSP_Cop0[ 5] = Compile_UnknownOpcode;
RSP_Cop0[ 6] = Compile_UnknownOpcode;
RSP_Cop0[ 7] = Compile_UnknownOpcode;
RSP_Cop0[ 8] = Compile_UnknownOpcode;
RSP_Cop0[ 9] = Compile_UnknownOpcode;
RSP_Cop0[10] = Compile_UnknownOpcode;
RSP_Cop0[11] = Compile_UnknownOpcode;
RSP_Cop0[12] = Compile_UnknownOpcode;
RSP_Cop0[13] = Compile_UnknownOpcode;
RSP_Cop0[14] = Compile_UnknownOpcode;
RSP_Cop0[15] = Compile_UnknownOpcode;
RSP_Cop0[16] = Compile_UnknownOpcode;
RSP_Cop0[17] = Compile_UnknownOpcode;
RSP_Cop0[18] = Compile_UnknownOpcode;
RSP_Cop0[19] = Compile_UnknownOpcode;
RSP_Cop0[20] = Compile_UnknownOpcode;
RSP_Cop0[21] = Compile_UnknownOpcode;
RSP_Cop0[22] = Compile_UnknownOpcode;
RSP_Cop0[23] = Compile_UnknownOpcode;
RSP_Cop0[24] = Compile_UnknownOpcode;
RSP_Cop0[25] = Compile_UnknownOpcode;
RSP_Cop0[26] = Compile_UnknownOpcode;
RSP_Cop0[27] = Compile_UnknownOpcode;
RSP_Cop0[28] = Compile_UnknownOpcode;
RSP_Cop0[29] = Compile_UnknownOpcode;
RSP_Cop0[30] = Compile_UnknownOpcode;
RSP_Cop0[31] = Compile_UnknownOpcode;
RSP_Cop2[ 0] = Compile_Cop2_MF;
RSP_Cop2[ 1] = Compile_UnknownOpcode;
RSP_Cop2[ 2] = Compile_Cop2_CF;
RSP_Cop2[ 3] = Compile_UnknownOpcode;
RSP_Cop2[ 4] = Compile_Cop2_MT;
RSP_Cop2[ 5] = Compile_UnknownOpcode;
RSP_Cop2[ 6] = Compile_Cop2_CT;
RSP_Cop2[ 7] = Compile_UnknownOpcode;
RSP_Cop2[ 8] = Compile_UnknownOpcode;
RSP_Cop2[ 9] = Compile_UnknownOpcode;
RSP_Cop2[10] = Compile_UnknownOpcode;
RSP_Cop2[11] = Compile_UnknownOpcode;
RSP_Cop2[12] = Compile_UnknownOpcode;
RSP_Cop2[13] = Compile_UnknownOpcode;
RSP_Cop2[14] = Compile_UnknownOpcode;
RSP_Cop2[15] = Compile_UnknownOpcode;
RSP_Cop2[16] = Compile_COP2_VECTOR;
RSP_Cop2[17] = Compile_COP2_VECTOR;
RSP_Cop2[18] = Compile_COP2_VECTOR;
RSP_Cop2[19] = Compile_COP2_VECTOR;
RSP_Cop2[20] = Compile_COP2_VECTOR;
RSP_Cop2[21] = Compile_COP2_VECTOR;
RSP_Cop2[22] = Compile_COP2_VECTOR;
RSP_Cop2[23] = Compile_COP2_VECTOR;
RSP_Cop2[24] = Compile_COP2_VECTOR;
RSP_Cop2[25] = Compile_COP2_VECTOR;
RSP_Cop2[26] = Compile_COP2_VECTOR;
RSP_Cop2[27] = Compile_COP2_VECTOR;
RSP_Cop2[28] = Compile_COP2_VECTOR;
RSP_Cop2[29] = Compile_COP2_VECTOR;
RSP_Cop2[30] = Compile_COP2_VECTOR;
RSP_Cop2[31] = Compile_COP2_VECTOR;
RSP_Vector[ 0] = Compile_Vector_VMULF;
RSP_Vector[ 1] = Compile_Vector_VMULU;
RSP_Vector[ 2] = Compile_UnknownOpcode;
RSP_Vector[ 3] = Compile_UnknownOpcode;
RSP_Vector[ 4] = Compile_Vector_VMUDL;
RSP_Vector[ 5] = Compile_Vector_VMUDM;
RSP_Vector[ 6] = Compile_Vector_VMUDN;
RSP_Vector[ 7] = Compile_Vector_VMUDH;
RSP_Vector[ 8] = Compile_Vector_VMACF;
RSP_Vector[ 9] = Compile_Vector_VMACU;
RSP_Vector[10] = Compile_UnknownOpcode;
RSP_Vector[11] = Compile_Vector_VMACQ;
RSP_Vector[12] = Compile_Vector_VMADL;
RSP_Vector[13] = Compile_Vector_VMADM;
RSP_Vector[14] = Compile_Vector_VMADN;
RSP_Vector[15] = Compile_Vector_VMADH;
RSP_Vector[16] = Compile_Vector_VADD;
RSP_Vector[17] = Compile_Vector_VSUB;
RSP_Vector[18] = Compile_UnknownOpcode;
RSP_Vector[19] = Compile_Vector_VABS;
RSP_Vector[20] = Compile_Vector_VADDC;
RSP_Vector[21] = Compile_Vector_VSUBC;
RSP_Vector[22] = Compile_UnknownOpcode;
RSP_Vector[23] = Compile_UnknownOpcode;
RSP_Vector[24] = Compile_UnknownOpcode;
RSP_Vector[25] = Compile_UnknownOpcode;
RSP_Vector[26] = Compile_UnknownOpcode;
RSP_Vector[27] = Compile_UnknownOpcode;
RSP_Vector[28] = Compile_UnknownOpcode;
RSP_Vector[29] = Compile_Vector_VSAW;
RSP_Vector[30] = Compile_UnknownOpcode;
RSP_Vector[31] = Compile_UnknownOpcode;
RSP_Vector[32] = Compile_Vector_VLT;
RSP_Vector[33] = Compile_Vector_VEQ;
RSP_Vector[34] = Compile_Vector_VNE;
RSP_Vector[35] = Compile_Vector_VGE;
RSP_Vector[36] = Compile_Vector_VCL;
RSP_Vector[37] = Compile_Vector_VCH;
RSP_Vector[38] = Compile_Vector_VCR;
RSP_Vector[39] = Compile_Vector_VMRG;
RSP_Vector[40] = Compile_Vector_VAND;
RSP_Vector[41] = Compile_Vector_VNAND;
RSP_Vector[42] = Compile_Vector_VOR;
RSP_Vector[43] = Compile_Vector_VNOR;
RSP_Vector[44] = Compile_Vector_VXOR;
RSP_Vector[45] = Compile_Vector_VNXOR;
RSP_Vector[46] = Compile_UnknownOpcode;
RSP_Vector[47] = Compile_UnknownOpcode;
RSP_Vector[48] = Compile_Vector_VRCP;
RSP_Vector[49] = Compile_Vector_VRCPL;
RSP_Vector[50] = Compile_Vector_VRCPH;
RSP_Vector[51] = Compile_Vector_VMOV;
RSP_Vector[52] = Compile_Vector_VRSQ;
RSP_Vector[53] = Compile_Vector_VRSQL;
RSP_Vector[54] = Compile_Vector_VRSQH;
RSP_Vector[55] = Compile_Vector_VNOOP;
RSP_Vector[56] = Compile_UnknownOpcode;
RSP_Vector[57] = Compile_UnknownOpcode;
RSP_Vector[58] = Compile_UnknownOpcode;
RSP_Vector[59] = Compile_UnknownOpcode;
RSP_Vector[60] = Compile_UnknownOpcode;
RSP_Vector[61] = Compile_UnknownOpcode;
RSP_Vector[62] = Compile_UnknownOpcode;
RSP_Vector[63] = Compile_UnknownOpcode;
RSP_Lc2[ 0] = Compile_Opcode_LBV;
RSP_Lc2[ 1] = Compile_Opcode_LSV;
RSP_Lc2[ 2] = Compile_Opcode_LLV;
RSP_Lc2[ 3] = Compile_Opcode_LDV;
RSP_Lc2[ 4] = Compile_Opcode_LQV;
RSP_Lc2[ 5] = Compile_Opcode_LRV;
RSP_Lc2[ 6] = Compile_Opcode_LPV;
RSP_Lc2[ 7] = Compile_Opcode_LUV;
RSP_Lc2[ 8] = Compile_Opcode_LHV;
RSP_Lc2[ 9] = Compile_Opcode_LFV;
RSP_Lc2[10] = Compile_UnknownOpcode;
RSP_Lc2[11] = Compile_Opcode_LTV;
RSP_Lc2[12] = Compile_UnknownOpcode;
RSP_Lc2[13] = Compile_UnknownOpcode;
RSP_Lc2[14] = Compile_UnknownOpcode;
RSP_Lc2[15] = Compile_UnknownOpcode;
RSP_Lc2[16] = Compile_UnknownOpcode;
RSP_Lc2[17] = Compile_UnknownOpcode;
RSP_Lc2[18] = Compile_UnknownOpcode;
RSP_Lc2[19] = Compile_UnknownOpcode;
RSP_Lc2[20] = Compile_UnknownOpcode;
RSP_Lc2[21] = Compile_UnknownOpcode;
RSP_Lc2[22] = Compile_UnknownOpcode;
RSP_Lc2[23] = Compile_UnknownOpcode;
RSP_Lc2[24] = Compile_UnknownOpcode;
RSP_Lc2[25] = Compile_UnknownOpcode;
RSP_Lc2[26] = Compile_UnknownOpcode;
RSP_Lc2[27] = Compile_UnknownOpcode;
RSP_Lc2[28] = Compile_UnknownOpcode;
RSP_Lc2[29] = Compile_UnknownOpcode;
RSP_Lc2[30] = Compile_UnknownOpcode;
RSP_Lc2[31] = Compile_UnknownOpcode;
RSP_Sc2[ 0] = Compile_Opcode_SBV;
RSP_Sc2[ 1] = Compile_Opcode_SSV;
RSP_Sc2[ 2] = Compile_Opcode_SLV;
RSP_Sc2[ 3] = Compile_Opcode_SDV;
RSP_Sc2[ 4] = Compile_Opcode_SQV;
RSP_Sc2[ 5] = Compile_Opcode_SRV;
RSP_Sc2[ 6] = Compile_Opcode_SPV;
RSP_Sc2[ 7] = Compile_Opcode_SUV;
RSP_Sc2[ 8] = Compile_Opcode_SHV;
RSP_Sc2[ 9] = Compile_Opcode_SFV;
RSP_Sc2[10] = Compile_Opcode_SWV;
RSP_Sc2[11] = Compile_Opcode_STV;
RSP_Sc2[12] = Compile_UnknownOpcode;
RSP_Sc2[13] = Compile_UnknownOpcode;
RSP_Sc2[14] = Compile_UnknownOpcode;
RSP_Sc2[15] = Compile_UnknownOpcode;
RSP_Sc2[16] = Compile_UnknownOpcode;
RSP_Sc2[17] = Compile_UnknownOpcode;
RSP_Sc2[18] = Compile_UnknownOpcode;
RSP_Sc2[19] = Compile_UnknownOpcode;
RSP_Sc2[20] = Compile_UnknownOpcode;
RSP_Sc2[21] = Compile_UnknownOpcode;
RSP_Sc2[22] = Compile_UnknownOpcode;
RSP_Sc2[23] = Compile_UnknownOpcode;
RSP_Sc2[24] = Compile_UnknownOpcode;
RSP_Sc2[25] = Compile_UnknownOpcode;
RSP_Sc2[26] = Compile_UnknownOpcode;
RSP_Sc2[27] = Compile_UnknownOpcode;
RSP_Sc2[28] = Compile_UnknownOpcode;
RSP_Sc2[29] = Compile_UnknownOpcode;
RSP_Sc2[30] = Compile_UnknownOpcode;
RSP_Sc2[31] = Compile_UnknownOpcode;
BlockID = 0;
ChangedPC = FALSE;
#ifdef Log_x86Code
Start_x86_Log();
#endif
}
/******************************************************
** ReOrderSubBlock
**
** Desc:
** this can be done, but will be interesting to put
** between branches labels, and actual branches, whichever
** occurs first in code
**
********************************************************/
void ReOrderInstructions(DWORD StartPC, DWORD EndPC) {
DWORD InstructionCount = EndPC - StartPC;
DWORD Count, ReorderedOps, CurrentPC;
OPCODE PreviousOp, CurrentOp, RspOp;
PreviousOp.Hex = *(DWORD*)(RSPInfo.IMEM + StartPC);
if (TRUE == IsOpcodeBranch(StartPC, PreviousOp)) {
/* the sub block ends here anyway */
return;
}
if (IsOpcodeNop(StartPC) && IsOpcodeNop(StartPC + 4) && IsOpcodeNop(StartPC + 8)) {
/* Dont even bother */
return;
}
CPU_Message("***** Doing reorder (%X to %X) *****", StartPC, EndPC);
if (InstructionCount < 0x0010) { return; }
if (InstructionCount > 0x0A00) { return; }
CPU_Message(" Before:");
for (Count = StartPC; Count < EndPC; Count += 4) {
RSP_LW_IMEM(Count, &RspOp.Hex);
CPU_Message(" %X %s",Count,RSPOpcodeName(RspOp.Hex,Count));
}
for (Count = 0; Count < InstructionCount; Count += 4) {
CurrentPC = StartPC;
PreviousOp.Hex = *(DWORD*)(RSPInfo.IMEM + CurrentPC);
ReorderedOps = 0;
for (;;) {
CurrentPC += 4;
if (CurrentPC >= EndPC) { break; }
CurrentOp.Hex = *(DWORD*)(RSPInfo.IMEM + CurrentPC);
if (TRUE == CompareInstructions(CurrentPC, &PreviousOp, &CurrentOp)) {
/* Move current opcode up */
*(DWORD*)(RSPInfo.IMEM + CurrentPC - 4) = CurrentOp.Hex;
*(DWORD*)(RSPInfo.IMEM + CurrentPC) = PreviousOp.Hex;
ReorderedOps++;
#ifdef REORDER_BLOCK_VERBOSE
CPU_Message("Swapped %X and %X", CurrentPC - 4, CurrentPC);
#endif
}
PreviousOp.Hex = *(DWORD*)(RSPInfo.IMEM + CurrentPC);
if (IsOpcodeNop(CurrentPC) && IsOpcodeNop(CurrentPC + 4) && IsOpcodeNop(CurrentPC + 8)) {
CurrentPC = EndPC;
}
}
if (ReorderedOps == 0) {
Count = InstructionCount;
}
}
CPU_Message(" After:");
for (Count = StartPC; Count < EndPC; Count += 4) {
RSP_LW_IMEM(Count, &RspOp.Hex);
CPU_Message(" %X %s",Count,RSPOpcodeName(RspOp.Hex,Count));
}
CPU_Message("");
}
void ReOrderSubBlock(RSP_BLOCK * Block) {
DWORD end = 0x0ffc;
DWORD count;
if (!Compiler.bReOrdering) {
return;
}
if (Block->CurrPC > 0xFF0) {
return;
}
/* find the label or jump closest to us */
if (RspCode.LabelCount) {
for (count = 0; count < RspCode.LabelCount; count++) {
if (RspCode.BranchLabels[count] < end && RspCode.BranchLabels[count] > Block->CurrPC) {
end = RspCode.BranchLabels[count];
}
}
}
if (RspCode.BranchCount) {
for (count = 0; count < RspCode.BranchCount; count++) {
if (RspCode.BranchLocations[count] < end && RspCode.BranchLocations[count] > Block->CurrPC) {
end = RspCode.BranchLocations[count];
}
}
}
/* it wont actually re-order the op at the end */
ReOrderInstructions(Block->CurrPC, end);
}
/******************************************************
** DetectGPRConstants
**
** Desc:
** this needs to be called on a sub-block basis, like
** after every time we hit a branch and delay slot
**
********************************************************/
void DetectGPRConstants(RSP_CODE * code) {
DWORD Count, Constant = 0;
memset(&code->bIsRegConst, 0, sizeof(BOOL) * 0x20);
memset(&code->MipsRegConst, 0, sizeof(DWORD) * 0x20);
if (!Compiler.bGPRConstants) {
return;
}
CPU_Message("***** Detecting constants *****");
/* R0 is constant zero, R31 or RA is not constant */
code->bIsRegConst[0] = TRUE;
code->MipsRegConst[0] = 0;
/* Do your global search for them */
for (Count = 1; Count < 31; Count++) {
if (IsRegisterConstant(Count, &Constant) == TRUE) {
CPU_Message("Global: %s is a constant of: %08X", GPR_Name(Count), Constant);
code->bIsRegConst[Count] = TRUE;
code->MipsRegConst[Count] = Constant;
}
}
CPU_Message("");
}
/******************************************************
** CompilerToggleBuffer and ClearX86Code
**
** Desc:
** 1> toggles the compiler buffer, useful for poorly
** taken branches like alignment
**
** 2> clears all the x86 code, jump tables etc
**
********************************************************/
void CompilerToggleBuffer(void) {
if (dwBuffer == MainBuffer) {
dwBuffer = SecondaryBuffer;
pLastPrimary = RecompPos;
if (pLastSecondary == NULL) {
pLastSecondary = RecompCodeSecondary;
}
RecompPos = pLastSecondary;
CPU_Message(" (Secondary Buffer Active 0x%08X)", pLastSecondary);
} else {
dwBuffer = MainBuffer;
pLastSecondary = RecompPos;
if (pLastPrimary == NULL) {
pLastPrimary = RecompCode;
}
RecompPos = pLastPrimary;
CPU_Message(" (Primary Buffer Active 0x%08X)", pLastPrimary);
}
}
void ClearAllx86Code (void) {
extern DWORD NoOfMaps, MapsCRC[32];
extern BYTE *JumpTables;
memset(&MapsCRC, 0, sizeof(DWORD) * 0x20);
NoOfMaps = 0;
memset(JumpTables,0,0x1000*32);
RecompPos = RecompCode;
pLastPrimary = NULL;
pLastSecondary = NULL;
}
/******************************************************
** Link Branches
**
** Desc:
** resolves all the collected branches, x86 style
**
********************************************************/
void LinkBranches(RSP_BLOCK * Block) {
DWORD OrigPrgCount = *PrgCount;
DWORD Count, Target;
DWORD * JumpWord;
BYTE * X86Code;
RSP_BLOCK Save;
if (!CurrentBlock.ResolveCount) {
return;
}
CPU_Message("***** Linking branches (%i) *****", CurrentBlock.ResolveCount);
for (Count = 0; Count < CurrentBlock.ResolveCount; Count++) {
Target = CurrentBlock.BranchesToResolve[Count].TargetPC;
X86Code = *(JumpTable + (Target >> 2));
if (!X86Code) {
*PrgCount = Target;
CPU_Message("");
CPU_Message("===== (Generate Code: %04X) =====", Target);
Save = *Block;
/* compile this block and link */
CompilerRSPBlock();
LinkBranches(Block);
*Block = Save;
CPU_Message("===== (End Generate Code: %04X) =====", Target);
CPU_Message("");
X86Code = *(JumpTable + (Target >> 2));
}
JumpWord = CurrentBlock.BranchesToResolve[Count].X86JumpLoc;
x86_SetBranch32b(JumpWord, (DWORD*)X86Code);
CPU_Message("Linked RSP branch from x86: %08X, to RSP: %X / x86: %08X",
JumpWord, Target, X86Code);
}
*PrgCount = OrigPrgCount;
CPU_Message("***** Done Linking Branches *****");
CPU_Message("");
}
/******************************************************
** BuildBranchLabels
**
** Desc:
** Branch labels are used to start and stop re-ordering
** sections as well as set the jump table to points
** within a block that are safe
**
********************************************************/
void BuildBranchLabels(void) {
OPCODE RspOp;
DWORD i, Dest;
#ifdef BUILD_BRANCHLABELS_VERBOSE
CPU_Message("***** Building branch labels *****");
#endif
for (i = 0; i < 0x1000; i += 4) {
RspOp.Hex = *(DWORD*)(RSPInfo.IMEM + i);
if (TRUE == IsOpcodeBranch(i, RspOp)) {
if (RspCode.LabelCount >= (sizeof(RspCode.BranchLabels) / sizeof(RspCode.BranchLabels[0])) - 1) {
CompilerWarning("Out of space for Branch Labels");
return;
}
if (RspCode.BranchCount >= (sizeof(RspCode.BranchLocations) / sizeof(RspCode.BranchLocations[0])) - 1) {
CompilerWarning("Out of space for Branch Locations");
return;
}
RspCode.BranchLocations[RspCode.BranchCount++] = i;
if (RspOp.op == RSP_SPECIAL) {
/* register jump not predictable */
} else if (RspOp.op == RSP_J || RspOp.op == RSP_JAL) {
/* for JAL its a sub-block for returns */
Dest = (RspOp.target << 2) & 0xFFC;
RspCode.BranchLabels[RspCode.LabelCount] = Dest;
RspCode.LabelCount += 1;
#ifdef BUILD_BRANCHLABELS_VERBOSE
CPU_Message("[%02i] Added branch at %X to %X", RspCode.LabelCount, i, Dest);
#endif
} else {
Dest = (i + ((short)RspOp.offset << 2) + 4) & 0xFFC;
RspCode.BranchLabels[RspCode.LabelCount] = Dest;
RspCode.LabelCount += 1;
#ifdef BUILD_BRANCHLABELS_VERBOSE
CPU_Message("[%02i] Added branch at %X to %X", RspCode.LabelCount, i, Dest);
#endif
}
}
}
#ifdef BUILD_BRANCHLABELS_VERBOSE
CPU_Message("***** End branch labels *****");
CPU_Message("");
#endif
}
BOOL IsJumpLabel(DWORD PC) {
DWORD Count;
if (!RspCode.LabelCount) {
return FALSE;
}
for (Count = 0; Count < RspCode.LabelCount; Count++) {
if (PC == RspCode.BranchLabels[Count]) {
return TRUE;
}
}
return FALSE;
}
void CompilerLinkBlocks(void) {
BYTE * KnownCode = *(JumpTable + (CompilePC >> 2));
CPU_Message("***** Linking block to X86: %08X *****", KnownCode);
NextInstruction = FINISH_BLOCK;
/* block linking scenario */
JmpLabel32("Linked block", 0);
x86_SetBranch32b(RecompPos - 4, KnownCode);
}
void CompilerRSPBlock ( void ) {
DWORD Count, Padding, X86BaseAddress = (DWORD)RecompPos;
BYTE * IMEM_SAVE = malloc(0x1000);
NextInstruction = NORMAL;
CompilePC = *PrgCount;
memset(&CurrentBlock, 0, sizeof(CurrentBlock));
CurrentBlock.StartPC = CompilePC;
CurrentBlock.CurrPC = CompilePC;
/* Align the block to a boundary */
if (X86BaseAddress & 7) {
Padding = (8 - (X86BaseAddress & 7)) & 7;
for (Count = 0; Count < Padding; Count++) {
CPU_Message("%08X: nop", RecompPos);
*(RecompPos++) = 0x90;
}
}
CPU_Message("====== block %d ======", BlockID++);
CPU_Message("x86 code at: %X",RecompPos);
CPU_Message("Jumpt Table: %X",Table );
CPU_Message("Start of Block: %X",CurrentBlock.StartPC );
CPU_Message("====== recompiled code ======");
if (Compiler.bReOrdering == TRUE) {
memcpy(IMEM_SAVE, RSPInfo.IMEM, 0x1000);
ReOrderSubBlock(&CurrentBlock);
}
/* this is for the block about to be compiled */
*(JumpTable + (CompilePC >> 2)) = RecompPos;
do {
/*
* Re-Ordering is setup to allow us to have loop labels
* so here we see if this is one and put it in the jump table
*/
if (NextInstruction == NORMAL && IsJumpLabel(CompilePC)) {
/* jumps come around twice */
if (NULL == *(JumpTable + (CompilePC >> 2))) {
CPU_Message("***** Adding Jump Table Entry for PC: %04X at X86: %08X *****", CompilePC, RecompPos);
CPU_Message("");
*(JumpTable + (CompilePC >> 2)) = RecompPos;
/* reorder from here to next label or branch */
CurrentBlock.CurrPC = CompilePC;
ReOrderSubBlock(&CurrentBlock);
} else if (NextInstruction != DELAY_SLOT_DONE) {
/*
* we could link the blocks here, but performance
* wise it might be better to just let it run
*/
}
}
if (Compiler.bSections == TRUE) {
if (TRUE == RSP_DoSections()) {
continue;
}
}
#ifdef X86_RECOMP_VERBOSE
if (FALSE == IsOpcodeNop(CompilePC)) {
CPU_Message("X86 Address: %08X", RecompPos);
}
#endif
RSP_LW_IMEM(CompilePC, &RSPOpC.Hex);
if (LogRDP && NextInstruction != DELAY_SLOT_DONE){
char str[40];
sprintf(str,"%X",CompilePC);
PushImm32(str,CompilePC);
Call_Direct(RDP_LogLoc,"RDP_LogLoc");
AddConstToX86Reg(x86_ESP, 4);
}
if (RSPOpC.Hex == 0xFFFFFFFF) {
/* i think this pops up an unknown op dialog */
/* NextInstruction = FINISH_BLOCK; */
} else {
((void (*)()) RSP_Opcode[ RSPOpC.op ])();
}
switch (NextInstruction) {
case NORMAL:
CompilePC += 4;
break;
case DO_DELAY_SLOT:
NextInstruction = DELAY_SLOT;
CompilePC += 4;
break;
case DELAY_SLOT:
NextInstruction = DELAY_SLOT_DONE;
CompilePC -= 4;
break;
case FINISH_SUB_BLOCK:
NextInstruction = NORMAL;
CompilePC += 8;
if (CompilePC >= 0x1000) {
NextInstruction = FINISH_BLOCK;
} else if (NULL == *(JumpTable + (CompilePC >> 2))) {
/* this is for the new block being compiled now */
CPU_Message("**** Continuing static SubBlock (jump table entry added for PC: %04X at X86: %08X) *****", CompilePC, RecompPos);
*(JumpTable + (CompilePC >> 2)) = RecompPos;
CurrentBlock.CurrPC = CompilePC;
/* reorder from after delay to next label or branch */
ReOrderSubBlock(&CurrentBlock);
} else {
CompilerLinkBlocks();
}
break;
case FINISH_BLOCK: break;
default:
DisplayError("Rsp Main loop\n\nWTF NextInstruction = %d",NextInstruction);
CompilePC += 4;
break;
}
} while ( NextInstruction != FINISH_BLOCK && CompilePC < 0x1000);
CPU_Message("==== end of recompiled code ====");
if (Compiler.bReOrdering == TRUE) {
memcpy(RSPInfo.IMEM, IMEM_SAVE, 0x1000);
}
free(IMEM_SAVE);
}
DWORD RunRecompilerCPU ( DWORD Cycles ) {
BYTE * Block;
RSP_Running = TRUE;
SetJumpTable(0x800);
while (RSP_Running) {
Block = *(JumpTable + (*PrgCount >> 2));
if (Block == NULL) {
if (Profiling && !IndvidualBlock) {
StartTimer(Timer_Compiling);
}
__try {
memset(&RspCode, 0, sizeof(RspCode));
BuildBranchLabels();
DetectGPRConstants(&RspCode);
CompilerRSPBlock();
} __except(EXCEPTION_EXECUTE_HANDLER) {
DisplayError("Error CompilePC = %08X", CompilePC);
ClearAllx86Code();
continue;
}
Block = *(JumpTable + (*PrgCount >> 2));
/*
** we are done compiling, but we may have references
** to fill in still either from this block, or jumps
** that go out of it, let's rock
**/
LinkBranches(&CurrentBlock);
if (Profiling && !IndvidualBlock) {
StopTimer();
}
}
if (Profiling && IndvidualBlock) {
StartTimer(*PrgCount);
}
_asm {
pushad
call Block
popad
}
if (Profiling && IndvidualBlock) {
StopTimer();
}
}
if (IsMmxEnabled == TRUE) {
_asm emms
}
return Cycles;
}

114
Source/RSP/Recompiler CPU.h Normal file
View File

@ -0,0 +1,114 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include "opcode.h"
#define NORMAL 0
#define DO_DELAY_SLOT 1
#define DELAY_SLOT 2
#define DELAY_SLOT_DONE 3
#define FINISH_BLOCK 4
#define FINISH_SUB_BLOCK 5
extern DWORD CompilePC, NextInstruction;
extern BOOL ChangedPC;
#define CompilerWarning if (ShowErrors) DisplayError
#define High16BitAccum 1
#define Middle16BitAccum 2
#define Low16BitAccum 4
#define EntireAccum (Low16BitAccum|Middle16BitAccum|High16BitAccum)
BOOL WriteToAccum (int Location, int PC);
BOOL WriteToVectorDest (DWORD DestReg, int PC);
BOOL UseRspFlags (int PC);
BOOL DelaySlotAffectBranch(DWORD PC);
BOOL CompareInstructions(DWORD PC, OPCODE * Top, OPCODE * Bottom);
BOOL IsOpcodeBranch(DWORD PC, OPCODE RspOp);
BOOL IsOpcodeNop(DWORD PC);
BOOL IsNextInstructionMmx(DWORD PC);
BOOL IsRegisterConstant (DWORD Reg, DWORD * Constant);
void RSP_Element2Mmx(int MmxReg);
void RSP_MultiElement2Mmx(int MmxReg1, int MmxReg2);
#define MainBuffer 0
#define SecondaryBuffer 1
DWORD RunRecompilerCPU ( DWORD Cycles );
void BuildRecompilerCPU ( void );
void CompilerRSPBlock ( void );
void CompilerToggleBuffer (void);
BOOL RSP_DoSections(void);
typedef struct {
DWORD StartPC, CurrPC; /* block start */
struct {
DWORD TargetPC; /* Target for this unknown branch */
DWORD * X86JumpLoc; /* Our x86 dword to fill */
} BranchesToResolve[200]; /* Branches inside or outside block */
DWORD ResolveCount; /* Branches with NULL jump table */
} RSP_BLOCK;
extern RSP_BLOCK CurrentBlock;
typedef struct {
BOOL bIsRegConst[32]; /* BOOLean toggle for constant */
DWORD MipsRegConst[32]; /* Value of register 32-bit */
DWORD BranchLabels[250];
DWORD LabelCount;
DWORD BranchLocations[250];
DWORD BranchCount;
} RSP_CODE;
extern RSP_CODE RspCode;
#define IsRegConst(i) (RspCode.bIsRegConst[i])
#define MipsRegConst(i) (RspCode.MipsRegConst[i])
typedef struct {
BOOL mmx, mmx2, sse; /* CPU specs and compiling */
BOOL bFlags; /* RSP Flag Analysis */
BOOL bReOrdering; /* Instruction reordering */
BOOL bSections; /* Microcode sections */
BOOL bDest; /* Vector destionation toggle */
BOOL bAccum; /* Accumulator toggle */
BOOL bGPRConstants; /* Analyze GPR constants */
BOOL bAlignVector; /* Align known vector loads */
BOOL bAudioUcode; /* Audio ucode analysis */
} RSP_COMPILER;
extern RSP_COMPILER Compiler;
#define IsMmxEnabled (Compiler.mmx)
#define IsMmx2Enabled (Compiler.mmx2)
#define IsSseEnabled (Compiler.sse)

4702
Source/RSP/Recompiler Ops.c Normal file

File diff suppressed because it is too large Load Diff

158
Source/RSP/Recompiler Ops.h Normal file
View File

@ -0,0 +1,158 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
/************************* OpCode functions *************************/
void Compile_SPECIAL ( void );
void Compile_REGIMM ( void );
void Compile_J ( void );
void Compile_JAL ( void );
void Compile_BEQ ( void );
void Compile_BNE ( void );
void Compile_BLEZ ( void );
void Compile_BGTZ ( void );
void Compile_ADDI ( void );
void Compile_ADDIU ( void );
void Compile_SLTI ( void );
void Compile_SLTIU ( void );
void Compile_ANDI ( void );
void Compile_ORI ( void );
void Compile_XORI ( void );
void Compile_LUI ( void );
void Compile_COP0 ( void );
void Compile_COP2 ( void );
void Compile_LB ( void );
void Compile_LH ( void );
void Compile_LW ( void );
void Compile_LBU ( void );
void Compile_LHU ( void );
void Compile_SB ( void );
void Compile_SH ( void );
void Compile_SW ( void );
void Compile_LC2 ( void );
void Compile_SC2 ( void );
/********************** R4300i OpCodes: Special **********************/
void Compile_Special_SLL ( void );
void Compile_Special_SRL ( void );
void Compile_Special_SRA ( void );
void Compile_Special_SLLV ( void );
void Compile_Special_SRLV ( void );
void Compile_Special_SRAV ( void );
void Compile_Special_JR ( void );
void Compile_Special_JALR ( void );
void Compile_Special_BREAK ( void );
void Compile_Special_ADD ( void );
void Compile_Special_ADDU ( void );
void Compile_Special_SUB ( void );
void Compile_Special_SUBU ( void );
void Compile_Special_AND ( void );
void Compile_Special_OR ( void );
void Compile_Special_XOR ( void );
void Compile_Special_NOR ( void );
void Compile_Special_SLT ( void );
void Compile_Special_SLTU ( void );
/********************** R4300i OpCodes: RegImm **********************/
void Compile_RegImm_BLTZ ( void );
void Compile_RegImm_BGEZ ( void );
void Compile_RegImm_BLTZAL ( void );
void Compile_RegImm_BGEZAL ( void );
/************************** Cop0 functions *************************/
void Compile_Cop0_MF ( void );
void Compile_Cop0_MT ( void );
/************************** Cop2 functions *************************/
void Compile_Cop2_MF ( void );
void Compile_Cop2_CF ( void );
void Compile_Cop2_MT ( void );
void Compile_Cop2_CT ( void );
void Compile_COP2_VECTOR ( void );
/************************** Vect functions **************************/
void Compile_Vector_VMULF ( void );
void Compile_Vector_VMULU ( void );
void Compile_Vector_VMUDL ( void );
void Compile_Vector_VMUDM ( void );
void Compile_Vector_VMUDN ( void );
void Compile_Vector_VMUDH ( void );
void Compile_Vector_VMACF ( void );
void Compile_Vector_VMACU ( void );
void Compile_Vector_VMACQ ( void );
void Compile_Vector_VMADL ( void );
void Compile_Vector_VMADM ( void );
void Compile_Vector_VMADN ( void );
void Compile_Vector_VMADH ( void );
void Compile_Vector_VADD ( void );
void Compile_Vector_VSUB ( void );
void Compile_Vector_VABS ( void );
void Compile_Vector_VADDC ( void );
void Compile_Vector_VSUBC ( void );
void Compile_Vector_VSAW ( void );
void Compile_Vector_VLT ( void );
void Compile_Vector_VEQ ( void );
void Compile_Vector_VNE ( void );
void Compile_Vector_VGE ( void );
void Compile_Vector_VCL ( void );
void Compile_Vector_VCH ( void );
void Compile_Vector_VCR ( void );
void Compile_Vector_VMRG ( void );
void Compile_Vector_VAND ( void );
void Compile_Vector_VNAND ( void );
void Compile_Vector_VOR ( void );
void Compile_Vector_VNOR ( void );
void Compile_Vector_VXOR ( void );
void Compile_Vector_VNXOR ( void );
void Compile_Vector_VRCP ( void );
void Compile_Vector_VRCPL ( void );
void Compile_Vector_VRCPH ( void );
void Compile_Vector_VMOV ( void );
void Compile_Vector_VRSQ ( void );
void Compile_Vector_VRSQL ( void );
void Compile_Vector_VRSQH ( void );
void Compile_Vector_VNOOP ( void );
/************************** lc2 functions **************************/
void Compile_Opcode_LBV ( void );
void Compile_Opcode_LSV ( void );
void Compile_Opcode_LLV ( void );
void Compile_Opcode_LDV ( void );
void Compile_Opcode_LQV ( void );
void Compile_Opcode_LRV ( void );
void Compile_Opcode_LPV ( void );
void Compile_Opcode_LUV ( void );
void Compile_Opcode_LHV ( void );
void Compile_Opcode_LFV ( void );
void Compile_Opcode_LTV ( void );
/************************** sc2 functions **************************/
void Compile_Opcode_SBV ( void );
void Compile_Opcode_SSV ( void );
void Compile_Opcode_SLV ( void );
void Compile_Opcode_SDV ( void );
void Compile_Opcode_SQV ( void );
void Compile_Opcode_SRV ( void );
void Compile_Opcode_SPV ( void );
void Compile_Opcode_SUV ( void );
void Compile_Opcode_SHV ( void );
void Compile_Opcode_SFV ( void );
void Compile_Opcode_SWV ( void );
void Compile_Opcode_STV ( void );
/************************** Other functions **************************/
void Compile_UnknownOpcode (void);

File diff suppressed because it is too large Load Diff

152
Source/RSP/Rsp.h Normal file
View File

@ -0,0 +1,152 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#if defined(__cplusplus)
extern "C" {
#endif
/************ Profiling **************/
#define Default_ProfilingOn FALSE
#define Default_IndvidualBlock FALSE
#define Default_ShowErrors FALSE
#define Default_AudioHle FALSE
/* Note: BOOL, BYTE, WORD, DWORD, TRUE, FALSE are defined in windows.h */
#define PLUGIN_TYPE_RSP 1
#define PLUGIN_TYPE_GFX 2
#define PLUGIN_TYPE_AUDIO 3
#define PLUGIN_TYPE_CONTROLLER 4
typedef struct {
WORD Version; /* Should be set to 0x0101 */
WORD Type; /* Set to PLUGIN_TYPE_RSP */
char Name[100]; /* Name of the DLL */
/* If DLL supports memory these memory options then set them to TRUE or FALSE
if it does not support it */
BOOL NormalMemory; /* a normal BYTE array */
BOOL MemoryBswaped; /* a normal BYTE array where the memory has been pre
bswap on a dword (32 bits) boundry */
} PLUGIN_INFO;
typedef struct {
HINSTANCE hInst;
BOOL MemoryBswaped; /* If this is set to TRUE, then the memory has been pre
bswap on a dword (32 bits) boundry */
BYTE * RDRAM;
BYTE * DMEM;
BYTE * IMEM;
DWORD * MI_INTR_REG;
DWORD * SP_MEM_ADDR_REG;
DWORD * SP_DRAM_ADDR_REG;
DWORD * SP_RD_LEN_REG;
DWORD * SP_WR_LEN_REG;
DWORD * SP_STATUS_REG;
DWORD * SP_DMA_FULL_REG;
DWORD * SP_DMA_BUSY_REG;
DWORD * SP_PC_REG;
DWORD * SP_SEMAPHORE_REG;
DWORD * DPC_START_REG;
DWORD * DPC_END_REG;
DWORD * DPC_CURRENT_REG;
DWORD * DPC_STATUS_REG;
DWORD * DPC_CLOCK_REG;
DWORD * DPC_BUFBUSY_REG;
DWORD * DPC_PIPEBUSY_REG;
DWORD * DPC_TMEM_REG;
void (*CheckInterrupts)( void );
void (*ProcessDList)( void );
void (*ProcessAList)( void );
void (*ProcessRdpList)( void );
void (*ShowCFB)( void );
} RSP_INFO;
typedef struct {
/* Menu */
/* Items should have an ID between 5001 and 5100 */
HMENU hRSPMenu;
void (*ProcessMenuItem) ( int ID );
/* Break Points */
BOOL UseBPoints;
char BPPanelName[20];
void (*Add_BPoint) ( void );
void (*CreateBPPanel) ( HWND hDlg, RECT rcBox );
void (*HideBPPanel) ( void );
void (*PaintBPPanel) ( PAINTSTRUCT ps );
void (*ShowBPPanel) ( void );
void (*RefreshBpoints) ( HWND hList );
void (*RemoveBpoint) ( HWND hList, int index );
void (*RemoveAllBpoint) ( void );
/* RSP command Window */
void (*Enter_RSP_Commands_Window) ( void );
} RSPDEBUG_INFO;
typedef struct {
void (*UpdateBreakPoints)( void );
void (*UpdateMemory)( void );
void (*UpdateR4300iRegisters)( void );
void (*Enter_BPoint_Window)( void );
void (*Enter_R4300i_Commands_Window)( void );
void (*Enter_R4300i_Register_Window)( void );
void (*Enter_RSP_Commands_Window) ( void );
void (*Enter_Memory_Window)( void );
} DEBUG_INFO;
__declspec(dllexport) void CloseDLL (void);
__declspec(dllexport) void DllAbout ( HWND hParent );
__declspec(dllexport) DWORD DoRspCycles ( DWORD Cycles );
__declspec(dllexport) void GetDllInfo ( PLUGIN_INFO * PluginInfo );
__declspec(dllexport) void GetRspDebugInfo ( RSPDEBUG_INFO * DebugInfo );
__declspec(dllexport) void InitiateRSP ( RSP_INFO Rsp_Info, DWORD * CycleCount);
__declspec(dllexport) void InitiateRSPDebugger ( DEBUG_INFO Debug_Info);
__declspec(dllexport) void RomClosed (void);
__declspec(dllexport) void DllConfig (HWND hWnd);
__declspec(dllexport) void EnableDebugging (BOOL Enabled);
__declspec(dllexport) void PluginLoaded (void);
DWORD AsciiToHex (char * HexValue);
void DisplayError (char * Message, ...);
int GetStoredWinPos( char * WinName, DWORD * X, DWORD * Y );
#define InterpreterCPU 0
#define RecompilerCPU 1
extern BOOL DebuggingEnabled, Profiling, IndvidualBlock, ShowErrors, BreakOnStart, LogRDP, LogX86Code;
extern DWORD CPUCore;
extern DEBUG_INFO DebugInfo;
extern RSP_INFO RSPInfo;
extern HINSTANCE hinstDLL;
#if defined(__cplusplus)
}
#endif

341
Source/RSP/Sse.c Normal file
View File

@ -0,0 +1,341 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include "rsp.h"
#include "x86.h"
#include "memory.h"
#include "RSP registers.h"
#include "log.h"
#define PUTDST8(dest,value) (*((BYTE *)(dest))=(BYTE)(value)); dest += 1;
#define PUTDST16(dest,value) (*((WORD *)(dest))=(WORD)(value)); dest += 2;
#define PUTDST32(dest,value) (*((DWORD *)(dest))=(DWORD)(value)); dest += 4;
char * sse_Strings[8] = {
"xmm0", "xmm1", "xmm2", "xmm3",
"xmm4", "xmm5", "xmm6", "xmm7"
};
#define sse_Name(Reg) (sse_Strings[(Reg)])
void SseMoveAlignedVariableToReg(void *Variable, char *VariableName, int sseReg) {
BYTE x86Command;
CPU_Message(" movaps %s, xmmword ptr [%s]",sse_Name(sseReg), VariableName);
switch (sseReg) {
case x86_XMM0: x86Command = 0x05; break;
case x86_XMM1: x86Command = 0x0D; break;
case x86_XMM2: x86Command = 0x15; break;
case x86_XMM3: x86Command = 0x1D; break;
case x86_XMM4: x86Command = 0x25; break;
case x86_XMM5: x86Command = 0x2D; break;
case x86_XMM6: x86Command = 0x35; break;
case x86_XMM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x280f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void SseMoveAlignedN64MemToReg(int sseReg, int AddrReg) {
BYTE x86Command;
CPU_Message(" movaps %s, xmmword ptr [Dmem+%s]",sse_Name(sseReg), x86_Name(AddrReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x80; break;
case x86_XMM1: x86Command = 0x88; break;
case x86_XMM2: x86Command = 0x90; break;
case x86_XMM3: x86Command = 0x98; break;
case x86_XMM4: x86Command = 0xA0; break;
case x86_XMM5: x86Command = 0xA8; break;
case x86_XMM6: x86Command = 0xB0; break;
case x86_XMM7: x86Command = 0xB8; break;
}
switch (AddrReg) {
case x86_EAX: x86Command += 0x00; break;
case x86_EBX: x86Command += 0x03; break;
case x86_ECX: x86Command += 0x01; break;
case x86_EDX: x86Command += 0x02; break;
case x86_ESI: x86Command += 0x06; break;
case x86_EDI: x86Command += 0x07; break;
case x86_ESP: x86Command += 0x04; break;
case x86_EBP: x86Command += 0x05; break;
}
PUTDST16(RecompPos,0x280f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,RSPInfo.DMEM);
}
void SseMoveAlignedRegToVariable(int sseReg, void *Variable, char *VariableName) {
BYTE x86Command;
CPU_Message(" movaps xmmword ptr [%s], %s",VariableName, sse_Name(sseReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x05; break;
case x86_XMM1: x86Command = 0x0D; break;
case x86_XMM2: x86Command = 0x15; break;
case x86_XMM3: x86Command = 0x1D; break;
case x86_XMM4: x86Command = 0x25; break;
case x86_XMM5: x86Command = 0x2D; break;
case x86_XMM6: x86Command = 0x35; break;
case x86_XMM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x290f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void SseMoveAlignedRegToN64Mem(int sseReg, int AddrReg) {
BYTE x86Command;
CPU_Message(" movaps xmmword ptr [Dmem+%s], %s",x86_Name(AddrReg),sse_Name(sseReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x80; break;
case x86_XMM1: x86Command = 0x88; break;
case x86_XMM2: x86Command = 0x90; break;
case x86_XMM3: x86Command = 0x98; break;
case x86_XMM4: x86Command = 0xA0; break;
case x86_XMM5: x86Command = 0xA8; break;
case x86_XMM6: x86Command = 0xB0; break;
case x86_XMM7: x86Command = 0xB8; break;
}
switch (AddrReg) {
case x86_EAX: x86Command += 0x00; break;
case x86_EBX: x86Command += 0x03; break;
case x86_ECX: x86Command += 0x01; break;
case x86_EDX: x86Command += 0x02; break;
case x86_ESI: x86Command += 0x06; break;
case x86_EDI: x86Command += 0x07; break;
case x86_ESP: x86Command += 0x04; break;
case x86_EBP: x86Command += 0x05; break;
}
PUTDST16(RecompPos,0x290f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,RSPInfo.DMEM);
}
void SseMoveUnalignedVariableToReg(void *Variable, char *VariableName, int sseReg) {
BYTE x86Command;
CPU_Message(" movups %s, xmmword ptr [%s]",sse_Name(sseReg), VariableName);
switch (sseReg) {
case x86_XMM0: x86Command = 0x05; break;
case x86_XMM1: x86Command = 0x0D; break;
case x86_XMM2: x86Command = 0x15; break;
case x86_XMM3: x86Command = 0x1D; break;
case x86_XMM4: x86Command = 0x25; break;
case x86_XMM5: x86Command = 0x2D; break;
case x86_XMM6: x86Command = 0x35; break;
case x86_XMM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x100f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void SseMoveUnalignedN64MemToReg(int sseReg, int AddrReg) {
BYTE x86Command;
CPU_Message(" movups %s, xmmword ptr [Dmem+%s]",sse_Name(sseReg), x86_Name(AddrReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x80; break;
case x86_XMM1: x86Command = 0x88; break;
case x86_XMM2: x86Command = 0x90; break;
case x86_XMM3: x86Command = 0x98; break;
case x86_XMM4: x86Command = 0xA0; break;
case x86_XMM5: x86Command = 0xA8; break;
case x86_XMM6: x86Command = 0xB0; break;
case x86_XMM7: x86Command = 0xB8; break;
}
switch (AddrReg) {
case x86_EAX: x86Command += 0x00; break;
case x86_EBX: x86Command += 0x03; break;
case x86_ECX: x86Command += 0x01; break;
case x86_EDX: x86Command += 0x02; break;
case x86_ESI: x86Command += 0x06; break;
case x86_EDI: x86Command += 0x07; break;
case x86_ESP: x86Command += 0x04; break;
case x86_EBP: x86Command += 0x05; break;
}
PUTDST16(RecompPos,0x100f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,RSPInfo.DMEM);
}
void SseMoveUnalignedRegToVariable(int sseReg, void *Variable, char *VariableName) {
BYTE x86Command;
CPU_Message(" movups xmmword ptr [%s], %s",VariableName, sse_Name(sseReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x05; break;
case x86_XMM1: x86Command = 0x0D; break;
case x86_XMM2: x86Command = 0x15; break;
case x86_XMM3: x86Command = 0x1D; break;
case x86_XMM4: x86Command = 0x25; break;
case x86_XMM5: x86Command = 0x2D; break;
case x86_XMM6: x86Command = 0x35; break;
case x86_XMM7: x86Command = 0x3D; break;
}
PUTDST16(RecompPos,0x110f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,Variable);
}
void SseMoveUnalignedRegToN64Mem(int sseReg, int AddrReg) {
BYTE x86Command;
CPU_Message(" movups xmmword ptr [Dmem+%s], %s",x86_Name(AddrReg),sse_Name(sseReg));
switch (sseReg) {
case x86_XMM0: x86Command = 0x80; break;
case x86_XMM1: x86Command = 0x88; break;
case x86_XMM2: x86Command = 0x90; break;
case x86_XMM3: x86Command = 0x98; break;
case x86_XMM4: x86Command = 0xA0; break;
case x86_XMM5: x86Command = 0xA8; break;
case x86_XMM6: x86Command = 0xB0; break;
case x86_XMM7: x86Command = 0xB8; break;
}
switch (AddrReg) {
case x86_EAX: x86Command += 0x00; break;
case x86_EBX: x86Command += 0x03; break;
case x86_ECX: x86Command += 0x01; break;
case x86_EDX: x86Command += 0x02; break;
case x86_ESI: x86Command += 0x06; break;
case x86_EDI: x86Command += 0x07; break;
case x86_ESP: x86Command += 0x04; break;
case x86_EBP: x86Command += 0x05; break;
}
PUTDST16(RecompPos,0x110f);
PUTDST8(RecompPos, x86Command);
PUTDST32(RecompPos,RSPInfo.DMEM);
}
void SseMoveRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" movaps %s, %s", sse_Name(Dest), sse_Name(Source));
switch (Dest) {
case x86_XMM0: x86Command = 0x00; break;
case x86_XMM1: x86Command = 0x08; break;
case x86_XMM2: x86Command = 0x10; break;
case x86_XMM3: x86Command = 0x18; break;
case x86_XMM4: x86Command = 0x20; break;
case x86_XMM5: x86Command = 0x28; break;
case x86_XMM6: x86Command = 0x30; break;
case x86_XMM7: x86Command = 0x38; break;
}
switch (Source) {
case x86_XMM0: x86Command += 0x00; break;
case x86_XMM1: x86Command += 0x01; break;
case x86_XMM2: x86Command += 0x02; break;
case x86_XMM3: x86Command += 0x03; break;
case x86_XMM4: x86Command += 0x04; break;
case x86_XMM5: x86Command += 0x05; break;
case x86_XMM6: x86Command += 0x06; break;
case x86_XMM7: x86Command += 0x07; break;
}
PUTDST16(RecompPos,0x280f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void SseXorRegToReg(int Dest, int Source) {
BYTE x86Command;
CPU_Message(" xorps %s, %s", sse_Name(Dest), sse_Name(Source));
switch (Dest) {
case x86_XMM0: x86Command = 0x00; break;
case x86_XMM1: x86Command = 0x08; break;
case x86_XMM2: x86Command = 0x10; break;
case x86_XMM3: x86Command = 0x18; break;
case x86_XMM4: x86Command = 0x20; break;
case x86_XMM5: x86Command = 0x28; break;
case x86_XMM6: x86Command = 0x30; break;
case x86_XMM7: x86Command = 0x28; break;
}
switch (Source) {
case x86_XMM0: x86Command += 0x00; break;
case x86_XMM1: x86Command += 0x01; break;
case x86_XMM2: x86Command += 0x02; break;
case x86_XMM3: x86Command += 0x03; break;
case x86_XMM4: x86Command += 0x04; break;
case x86_XMM5: x86Command += 0x05; break;
case x86_XMM6: x86Command += 0x06; break;
case x86_XMM7: x86Command += 0x07; break;
}
PUTDST16(RecompPos,0x570f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void SseShuffleReg(int Dest, int Source, BYTE Immed) {
BYTE x86Command;
CPU_Message(" shufps %s, %s, %02X", sse_Name(Dest), sse_Name(Source), Immed);
switch (Dest) {
case x86_XMM0: x86Command = 0x00; break;
case x86_XMM1: x86Command = 0x08; break;
case x86_XMM2: x86Command = 0x10; break;
case x86_XMM3: x86Command = 0x18; break;
case x86_XMM4: x86Command = 0x20; break;
case x86_XMM5: x86Command = 0x28; break;
case x86_XMM6: x86Command = 0x30; break;
case x86_XMM7: x86Command = 0x38; break;
}
switch (Source) {
case x86_XMM0: x86Command += 0x00; break;
case x86_XMM1: x86Command += 0x01; break;
case x86_XMM2: x86Command += 0x02; break;
case x86_XMM3: x86Command += 0x03; break;
case x86_XMM4: x86Command += 0x04; break;
case x86_XMM5: x86Command += 0x05; break;
case x86_XMM6: x86Command += 0x06; break;
case x86_XMM7: x86Command += 0x07; break;
}
PUTDST16(RecompPos,0xC60f);
PUTDST8(RecompPos, 0xC0 | x86Command);
PUTDST8(RecompPos, Immed);
}

66
Source/RSP/Types.h Normal file
View File

@ -0,0 +1,66 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#ifndef __Types_h
#define __Types_h
typedef union tagUWORD {
long W;
float F;
unsigned long UW;
short HW[2];
unsigned short UHW[2];
char B[4];
unsigned char UB[4];
} UWORD32;
typedef union tagUDWORD {
double D;
_int64 DW;
unsigned _int64 UDW;
long W[2];
float F[2];
unsigned long UW[2];
short HW[4];
unsigned short UHW[4];
char B[8];
unsigned char UB[8];
} UDWORD;
typedef union tagVect {
double FD[2];
_int64 DW[2];
unsigned _int64 UDW[2];
long W[4];
float FS[4];
unsigned long UW[4];
short HW[8];
unsigned short UHW[8];
char B[16];
unsigned char UB[16];
} VECTOR;
#endif

2812
Source/RSP/X86.c Normal file

File diff suppressed because it is too large Load Diff

262
Source/RSP/X86.h Normal file
View File

@ -0,0 +1,262 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
enum x86RegValues {
x86_EAX = 0, x86_EBX = 1, x86_ECX = 2, x86_EDX = 3,
x86_ESI = 4, x86_EDI = 5, x86_EBP = 6, x86_ESP = 7
};
enum mmxRegValues {
x86_MM0 = 0, x86_MM1 = 1, x86_MM2 = 2, x86_MM3 = 3,
x86_MM4 = 4, x86_MM5 = 5, x86_MM6 = 6, x86_MM7 = 7
};
enum sseRegValues {
x86_XMM0 = 0, x86_XMM1 = 1, x86_XMM2 = 2, x86_XMM3 = 3,
x86_XMM4 = 4, x86_XMM5 = 5, x86_XMM6 = 6, x86_XMM7 = 7
};
void AdcX86RegToX86Reg ( int Destination, int Source );
void AdcX86regToVariable ( int x86reg, void * Variable, char * VariableName );
void AdcX86regHalfToVariable ( int x86reg, void * Variable, char * VariableName );
void AdcConstToX86reg ( BYTE Constant, int x86reg );
void AdcConstToVariable ( void *Variable, char *VariableName, BYTE Constant );
void AdcConstHalfToVariable ( void *Variable, char *VariableName, BYTE Constant );
void AddConstToVariable ( DWORD Const, void *Variable, char *VariableName );
void AddConstToX86Reg ( int x86Reg, DWORD Const );
void AddVariableToX86reg ( int x86reg, void * Variable, char * VariableName );
void AddX86regToVariable ( int x86reg, void * Variable, char * VariableName );
void AddX86regHalfToVariable ( int x86reg, void * Variable, char * VariableName );
void AddX86RegToX86Reg ( int Destination, int Source );
void AndConstToVariable ( DWORD Const, void *Variable, char *VariableName );
void AndConstToX86Reg ( int x86Reg, DWORD Const );
void AndVariableToX86Reg ( void * Variable, char * VariableName, int x86Reg );
void AndVariableToX86regHalf ( void * Variable, char * VariableName, int x86Reg );
void AndX86RegToVariable ( void * Variable, char * VariableName, int x86Reg );
void AndX86RegToX86Reg ( int Destination, int Source );
void AndX86RegHalfToX86RegHalf ( int Destination, int Source );
void X86BreakPoint ( LPCSTR FileName, int LineNumber );
void Call_Direct ( void * FunctAddress, char * FunctName );
void Call_Indirect ( void * FunctAddress, char * FunctName );
void CondMoveEqual ( int Destination, int Source );
void CondMoveNotEqual ( int Destination, int Source );
void CondMoveGreater ( int Destination, int Source );
void CondMoveGreaterEqual ( int Destination, int Source );
void CondMoveLess ( int Destination, int Source );
void CondMoveLessEqual ( int Destination, int Source );
void CompConstToVariable ( DWORD Const, void * Variable, char * VariableName );
void CompConstHalfToVariable ( WORD Const, void * Variable, char * VariableName );
void CompConstToX86reg ( int x86Reg, DWORD Const );
void CompX86regToVariable ( int x86Reg, void * Variable, char * VariableName );
void CompVariableToX86reg ( int x86Reg, void * Variable, char * VariableName );
void CompX86RegToX86Reg ( int Destination, int Source );
void Cwd ( void );
void Cwde ( void );
void DecX86reg ( int x86Reg );
void DivX86reg ( int x86reg );
void idivX86reg ( int x86reg );
void imulX86reg ( int x86reg );
void ImulX86RegToX86Reg ( int Destination, int Source );
void IncX86reg ( int x86Reg );
void JaeLabel32 ( char * Label, DWORD Value );
void JaLabel8 ( char * Label, BYTE Value );
void JaLabel32 ( char * Label, DWORD Value );
void JbLabel8 ( char * Label, BYTE Value );
void JbLabel32 ( char * Label, DWORD Value );
void JeLabel8 ( char * Label, BYTE Value );
void JeLabel32 ( char * Label, DWORD Value );
void JgeLabel8 ( char * Label, BYTE Value );
void JgeLabel32 ( char * Label, DWORD Value );
void JgLabel8 ( char * Label, BYTE Value );
void JgLabel32 ( char * Label, DWORD Value );
void JleLabel8 ( char * Label, BYTE Value );
void JleLabel32 ( char * Label, DWORD Value );
void JlLabel8 ( char * Label, BYTE Value );
void JlLabel32 ( char * Label, DWORD Value );
void JumpX86Reg ( int x86reg );
void JmpLabel8 ( char * Label, BYTE Value );
void JmpLabel32 ( char * Label, DWORD Value );
void JneLabel8 ( char * Label, BYTE Value );
void JneLabel32 ( char * Label, DWORD Value );
void JnsLabel8 ( char * Label, BYTE Value );
void JnsLabel32 ( char * Label, DWORD Value );
void JsLabel32 ( char * Label, DWORD Value );
void LeaSourceAndOffset ( int x86DestReg, int x86SourceReg, int offset );
void MoveConstByteToN64Mem ( BYTE Const, int AddrReg );
void MoveConstHalfToN64Mem ( WORD Const, int AddrReg );
void MoveConstByteToVariable ( BYTE Const,void *Variable, char *VariableName );
void MoveConstHalfToVariable ( WORD Const, void *Variable, char *VariableName );
void MoveConstToN64Mem ( DWORD Const, int AddrReg );
void MoveConstToN64MemDisp ( DWORD Const, int AddrReg, BYTE Disp );
void MoveConstToVariable ( DWORD Const, void *Variable, char *VariableName );
void MoveConstToX86reg ( DWORD Const, int x86reg );
void MoveOffsetToX86reg ( DWORD Const, char * VariableName, int x86reg );
void MoveX86regByteToX86regPointer ( int Source, int AddrReg );
void MoveX86regHalfToX86regPointer ( int Source, int AddrReg );
void MoveX86regHalfToX86regPointerDisp ( int Source, int AddrReg, BYTE Disp);
void MoveX86regToX86regPointer ( int Source, int AddrReg );
void MoveX86RegToX86regPointerDisp ( int Source, int AddrReg, BYTE Disp );
void MoveX86regPointerToX86regByte ( int Destination, int AddrReg );
void MoveX86regPointerToX86regHalf ( int Destination, int AddrReg );
void MoveX86regPointerToX86reg ( int Destination, int AddrReg );
void MoveN64MemDispToX86reg ( int x86reg, int AddrReg, BYTE Disp );
void MoveN64MemToX86reg ( int x86reg, int AddrReg );
void MoveN64MemToX86regByte ( int x86reg, int AddrReg );
void MoveN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveX86regByteToN64Mem ( int x86reg, int AddrReg );
void MoveX86regByteToVariable ( int x86reg, void * Variable, char * VariableName );
void MoveX86regHalfToN64Mem ( int x86reg, int AddrReg );
void MoveX86regHalfToVariable ( int x86reg, void * Variable, char * VariableName );
void MoveX86regToN64Mem ( int x86reg, int AddrReg );
void MoveX86regToN64MemDisp ( int x86reg, int AddrReg, BYTE Disp );
void MoveX86regToVariable ( int x86reg, void * Variable, char * VariableName );
void MoveX86RegToX86Reg ( int Source, int Destination );
void MoveVariableToX86reg ( void *Variable, char *VariableName, int x86reg );
void MoveVariableToX86regByte ( void *Variable, char *VariableName, int x86reg );
void MoveVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MoveSxX86RegHalfToX86Reg ( int Source, int Destination );
void MoveSxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination );
void MoveSxN64MemToX86regByte ( int x86reg, int AddrReg );
void MoveSxN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveSxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MoveZxX86RegHalfToX86Reg ( int Source, int Destination );
void MoveZxX86RegPtrDispToX86RegHalf( int AddrReg, BYTE Disp, int Destination );
void MoveZxN64MemToX86regByte ( int x86reg, int AddrReg );
void MoveZxN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveZxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MulX86reg ( int x86reg );
void NegateX86reg ( int x86reg );
void OrConstToVariable ( DWORD Const, void * Variable, char * VariableName );
void OrConstToX86Reg ( DWORD Const, int x86Reg );
void OrVariableToX86Reg ( void * Variable, char * VariableName, int x86Reg );
void OrVariableToX86regHalf ( void * Variable, char * VariableName, int x86Reg );
void OrX86RegToVariable ( void * Variable, char * VariableName, int x86Reg );
void OrX86RegToX86Reg ( int Destination, int Source );
void Popad ( void );
void Pushad ( void );
void Push ( int x86reg );
void Pop ( int x86reg );
void PushImm32 ( char * String, DWORD Value );
void Ret ( void );
void Seta ( int x86reg );
void Setae ( int x86reg );
void Setl ( int x86reg );
void Setb ( int x86reg );
void Setg ( int x86reg );
void Setz ( int x86reg );
void Setnz ( int x86reg );
void SetlVariable ( void * Variable, char * VariableName );
void SetleVariable ( void * Variable, char * VariableName );
void SetgVariable ( void * Variable, char * VariableName );
void SetgeVariable ( void * Variable, char * VariableName );
void SetbVariable ( void * Variable, char * VariableName );
void SetaVariable ( void * Variable, char * VariableName );
void SetzVariable ( void * Variable, char * VariableName );
void SetnzVariable ( void * Variable, char * VariableName );
void ShiftLeftSign ( int x86reg );
void ShiftLeftSignImmed ( int x86reg, BYTE Immediate );
void ShiftLeftSignVariableImmed ( void *Variable, char *VariableName, BYTE Immediate );
void ShiftRightSignImmed ( int x86reg, BYTE Immediate );
void ShiftRightSignVariableImmed ( void *Variable, char *VariableName, BYTE Immediate );
void ShiftRightUnsign ( int x86reg );
void ShiftRightUnsignImmed ( int x86reg, BYTE Immediate );
void ShiftRightUnsignVariableImmed ( void *Variable, char *VariableName, BYTE Immediate );
void ShiftLeftDoubleImmed ( int Destination, int Source, BYTE Immediate );
void ShiftRightDoubleImmed ( int Destination, int Source, BYTE Immediate );
void SubConstFromVariable ( DWORD Const, void *Variable, char *VariableName );
void SubConstFromX86Reg ( int x86Reg, DWORD Const );
void SubVariableFromX86reg ( int x86reg, void * Variable, char * VariableName );
void SubX86RegToX86Reg ( int Destination, int Source );
void SubX86regFromVariable ( int x86reg, void * Variable, char * VariableName );
void SbbX86RegToX86Reg ( int Destination, int Source );
void TestConstToVariable ( DWORD Const, void * Variable, char * VariableName );
void TestConstToX86Reg ( DWORD Const, int x86reg );
void TestX86RegToX86Reg ( int Destination, int Source );
void XorConstToX86Reg ( int x86Reg, DWORD Const );
void XorX86RegToX86Reg ( int Source, int Destination );
void XorVariableToX86reg ( void *Variable, char *VariableName, int x86reg );
void XorX86RegToVariable ( void *Variable, char *VariableName, int x86reg );
void XorConstToVariable ( void *Variable, char *VariableName, DWORD Const );
#define _MMX_SHUFFLE(a, b, c, d) \
((BYTE)(((a) << 6) | ((b) << 4) | ((c) << 2) | (d)))
void MmxMoveRegToReg ( int Dest, int Source );
void MmxMoveQwordRegToVariable ( int Dest, void *Variable, char *VariableName );
void MmxMoveQwordVariableToReg ( int Dest, void *Variable, char *VariableName );
void MmxPandRegToReg ( int Dest, int Source );
void MmxPandnRegToReg ( int Dest, int Source );
void MmxPandVariableToReg ( void * Variable, char * VariableName, int Dest );
void MmxPorRegToReg ( int Dest, int Source );
void MmxPorVariableToReg ( void * Variable, char * VariableName, int Dest );
void MmxXorRegToReg ( int Dest, int Source );
void MmxShuffleMemoryToReg ( int Dest, void * Variable, char * VariableName, BYTE Immed );
void MmxPmullwRegToReg ( int Dest, int Source );
void MmxPmullwVariableToReg ( int Dest, void * Variable, char * VariableName );
void MmxPmulhuwRegToReg ( int Dest, int Source );
void MmxPmulhwRegToReg ( int Dest, int Source );
void MmxPmulhwRegToVariable ( int Dest, void * Variable, char * VariableName );
void MmxPsrlwImmed ( int Dest, BYTE Immed );
void MmxPsrawImmed ( int Dest, BYTE Immed );
void MmxPsllwImmed ( int Dest, BYTE Immed );
void MmxPaddswRegToReg ( int Dest, int Source );
void MmxPaddswVariableToReg ( int Dest, void * Variable, char * VariableName );
void MmxPaddwRegToReg ( int Dest, int Source );
void MmxPsubswVariableToReg ( int Dest, void * Variable, char * VariableName );
void MmxPsubswRegToReg ( int Dest, int Source );
void MmxPackSignedDwords ( int Dest, int Source );
void MmxUnpackLowWord ( int Dest, int Source );
void MmxUnpackHighWord ( int Dest, int Source );
void MmxCompareGreaterWordRegToReg ( int Dest, int Source );
void MmxEmptyMultimediaState ( void );
void SseMoveAlignedVariableToReg ( void *Variable, char *VariableName, int sseReg );
void SseMoveAlignedRegToVariable ( int sseReg, void *Variable, char *VariableName );
void SseMoveAlignedN64MemToReg ( int sseReg, int AddrReg );
void SseMoveAlignedRegToN64Mem ( int sseReg, int AddrReg );
void SseMoveUnalignedVariableToReg ( void *Variable, char *VariableName, int sseReg );
void SseMoveUnalignedRegToVariable ( int sseReg, void *Variable, char *VariableName );
void SseMoveUnalignedN64MemToReg ( int sseReg, int AddrReg );
void SseMoveUnalignedRegToN64Mem ( int sseReg, int AddrReg );
void SseMoveRegToReg ( int Dest, int Source );
void SseXorRegToReg ( int Dest, int Source );
typedef struct {
union {
struct {
unsigned Reg0 : 2;
unsigned Reg1 : 2;
unsigned Reg2 : 2;
unsigned Reg3 : 2;
};
unsigned UB:8;
};
} SHUFFLE;
void SseShuffleReg ( int Dest, int Source, BYTE Immed );
void x86_SetBranch32b(void * JumpByte, void * Destination);
void x86_SetBranch8b(void * JumpByte, void * Destination);

163
Source/RSP/breakpoint.c Normal file
View File

@ -0,0 +1,163 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <stdio.h>
#include "rsp.h"
#include "CPU.h"
#include "breakpoint.h"
#define IDC_LOCATION_EDIT 105
HWND BPoint_Win_hDlg, hRSPLocation = NULL;
void Add_BPoint ( void ) {
char Title[10];
GetWindowText(hRSPLocation,Title,sizeof(Title));
if (!AddRSP_BPoint(AsciiToHex(Title),TRUE )) {
SendMessage(hRSPLocation,EM_SETSEL,(WPARAM)0,(LPARAM)-1);
SetFocus(hRSPLocation);
}
}
int AddRSP_BPoint( DWORD Location, int Confirm ) {
int count;
if (NoOfBpoints == MaxBPoints) {
DisplayError("Max amount of Break Points set");
return FALSE;
}
for (count = 0; count < NoOfBpoints; count ++) {
if (BPoint[count].Location == Location) {
DisplayError("You already have this Break Point");
return FALSE;
}
}
if (Confirm) {
char Message[150];
int Response;
sprintf(Message,"Break when:\n\nRSP's Program Counter = 0x%03X\n\nIs this correct?",
Location);
Response = MessageBox(BPoint_Win_hDlg, Message, "Breakpoint", MB_YESNO | MB_ICONINFORMATION);
if (Response == IDNO) {
return FALSE;
}
}
BPoint[NoOfBpoints].Location = Location;
NoOfBpoints += 1;
if (DebugInfo.UpdateBreakPoints)
{
DebugInfo.UpdateBreakPoints();
}
return TRUE;
}
int CheckForRSPBPoint ( DWORD Location ) {
int count;
for (count = 0; count < NoOfBpoints; count ++){
if (BPoint[count].Location == Location) {
return TRUE;
}
}
return FALSE;
}
void CreateBPPanel ( HWND hDlg, RECT rcBox ) {
if (hRSPLocation != NULL) { return; }
BPoint_Win_hDlg = hDlg;
hRSPLocation = CreateWindowEx(0,"EDIT","", WS_CHILD | WS_BORDER | ES_UPPERCASE | WS_TABSTOP,
83,90,100,17,hDlg,(HMENU)IDC_LOCATION_EDIT,RSPInfo.hInst,NULL);
if (hRSPLocation) {
char Title[20];
SendMessage(hRSPLocation,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),0);
SendMessage(hRSPLocation,EM_SETLIMITTEXT,(WPARAM)3,(LPARAM)0);
sprintf(Title,"%03X",*PrgCount);
SetWindowText(hRSPLocation,Title);
}
}
void HideBPPanel ( void ) {
ShowWindow(hRSPLocation,FALSE);
}
void PaintBPPanel ( PAINTSTRUCT ps ) {
TextOut( ps.hdc, 29,60,"Break when the Program Counter equals",37);
TextOut( ps.hdc, 59,85,"0x",2);
}
void ShowBPPanel ( void ) {
ShowWindow(hRSPLocation,TRUE);
}
void RefreshBpoints ( HWND hList ) {
char Message[100];
int count, location;
for (count = 0; count < NoOfBpoints; count ++ ) {
sprintf(Message," at 0x%03X (RSP)", BPoint[count].Location);
location = SendMessage(hList,LB_ADDSTRING,0,(LPARAM)Message);
SendMessage(hList,LB_SETITEMDATA,(WPARAM)location,(LPARAM)BPoint[count].Location);
}
}
void RemoveAllBpoint ( void ) {
NoOfBpoints = 0;
}
void RemoveBpoint ( HWND hList, int index ) {
DWORD location;
location = SendMessage(hList,LB_GETITEMDATA,(WPARAM)index,0);
RemoveRSPBreakPoint(location);
}
void RemoveRSPBreakPoint (DWORD Location) {
int count, location = -1;
for (count = 0; count < NoOfBpoints; count ++){
if (BPoint[count].Location == Location) {
location = count;
count = NoOfBpoints;
}
}
if (location >= 0) {
for (count = location; count < NoOfBpoints - 1; count ++ ){
BPoint[count].Location = BPoint[count + 1].Location;
}
NoOfBpoints -= 1;
if (DebugInfo.UpdateBreakPoints)
{
DebugInfo.UpdateBreakPoints();
}
}
}

48
Source/RSP/breakpoint.h Normal file
View File

@ -0,0 +1,48 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#define MaxBPoints 0x30
typedef struct {
unsigned int Location;
} BPOINT;
BPOINT BPoint[MaxBPoints];
int NoOfBpoints;
void Add_BPoint ( void );
void CreateBPPanel ( HWND hDlg, RECT rcBox );
void HideBPPanel ( void );
void PaintBPPanel ( PAINTSTRUCT ps );
void ShowBPPanel ( void );
void RefreshBpoints ( HWND hList );
void RemoveBpoint ( HWND hList, int index );
void RemoveAllBpoint ( void );
int AddRSP_BPoint ( DWORD Location, int Confirm );
int CheckForRSPBPoint ( DWORD Location );
void RemoveRSPBreakPoint (DWORD Location);

143
Source/RSP/dma.c Normal file
View File

@ -0,0 +1,143 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <Windows.h>
#include <stdio.h>
#include "RSP.h"
#include "RSP Registers.h"
#include "memory.h"
// #define RSP_SAFE_DMA /* unoptimized dma transfers */
void SP_DMA_READ (void) {
DWORD i, j, Length, Skip, Count, End;
BYTE *Dest, *Source;
*RSPInfo.SP_DRAM_ADDR_REG &= 0x00FFFFFF;
if (*RSPInfo.SP_DRAM_ADDR_REG > 0x800000) {
MessageBox(NULL,"SP DMA READ\nSP_DRAM_ADDR_REG not in RDRam space","Error",MB_OK);
return;
}
if ((*RSPInfo.SP_RD_LEN_REG & 0xFFF) + 1 + (*RSPInfo.SP_MEM_ADDR_REG & 0xFFF) > 0x1000) {
MessageBox(NULL,"SP DMA READ\ncould not fit copy in memory segement","Error",MB_OK);
return;
}
Length = ((*RSPInfo.SP_RD_LEN_REG & 0xFFF) | 7) + 1;
Skip = (*RSPInfo.SP_RD_LEN_REG >> 20) + Length;
Count = ((*RSPInfo.SP_RD_LEN_REG >> 12) & 0xFF) + 1;
End = ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7) + (((Count - 1) * Skip) + Length);
if ((*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0) {
Dest = RSPInfo.IMEM + ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7);
} else {
Dest = RSPInfo.DMEM + ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7);
}
Source = RSPInfo.RDRAM + (*RSPInfo.SP_DRAM_ADDR_REG & ~7);
#if defined(RSP_SAFE_DMA)
for (j = 0 ; j < Count; j++) {
for (i = 0 ; i < Length; i++) {
*(BYTE *)(((DWORD)Dest + j * Length + i) ^ 3) = *(BYTE *)(((DWORD)Source + j * Skip + i) ^ 3);
}
}
#else
if ((Skip & 0x3) == 0) {
for (j = 0; j < Count; j++) {
memcpy(Dest, Source, Length);
Source += Skip;
Dest += Length;
}
} else {
for (j = 0 ; j < Count; j++) {
for (i = 0 ; i < Length; i++) {
*(BYTE *)(((DWORD)Dest + i) ^ 3) = *(BYTE *)(((DWORD)Source + i) ^ 3);
}
Source += Skip;
Dest += Length;
}
}
#endif
/* FIXME: could this be a problem DMEM to IMEM (?) */
if (CPUCore == RecompilerCPU && (*RSPInfo.SP_MEM_ADDR_REG & 0x1000) != 0) {
SetJumpTable(End);
}
*RSPInfo.SP_DMA_BUSY_REG = 0;
*RSPInfo.SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY;
}
void SP_DMA_WRITE (void) {
DWORD i, j, Length, Skip, Count;
BYTE *Dest, *Source;
*RSPInfo.SP_DRAM_ADDR_REG &= 0x00FFFFFF;
if (*RSPInfo.SP_DRAM_ADDR_REG > 0x800000) {
MessageBox(NULL,"SP DMA WRITE\nSP_DRAM_ADDR_REG not in RDRam space","Error",MB_OK);
return;
}
if ((*RSPInfo.SP_WR_LEN_REG & 0xFFF) + 1 + (*RSPInfo.SP_MEM_ADDR_REG & 0xFFF) > 0x1000) {
MessageBox(NULL,"SP DMA WRITE\ncould not fit copy in memory segement","Error",MB_OK);
return;
}
Length = ((*RSPInfo.SP_WR_LEN_REG & 0xFFF) | 7) + 1;
Skip = (*RSPInfo.SP_WR_LEN_REG >> 20) + Length;
Count = ((*RSPInfo.SP_WR_LEN_REG >> 12) & 0xFF) + 1;
Dest = RSPInfo.RDRAM + (*RSPInfo.SP_DRAM_ADDR_REG & ~7);
Source = RSPInfo.DMEM + ((*RSPInfo.SP_MEM_ADDR_REG & 0x1FFF) & ~7);
#if defined(RSP_SAFE_DMA)
for (j = 0 ; j < Count; j++) {
for (i = 0 ; i < Length; i++) {
*(BYTE *)(((DWORD)Dest + j * Skip + i) ^ 3) = *(BYTE *)(((DWORD)Source + j * Length + i) ^ 3);
}
}
#else
if ((Skip & 0x3) == 0) {
for (j = 0; j < Count; j++) {
memcpy(Dest, Source, Length);
Source += Length;
Dest += Skip;
}
} else {
for (j = 0 ; j < Count; j++) {
for (i = 0 ; i < Length; i++) {
*(BYTE *)(((DWORD)Dest + i) ^ 3) = *(BYTE *)(((DWORD)Source + i) ^ 3);
}
Source += Length;
Dest += Skip;
}
}
#endif
*RSPInfo.SP_DMA_BUSY_REG = 0;
*RSPInfo.SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY;
}

29
Source/RSP/dma.h Normal file
View File

@ -0,0 +1,29 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
void SP_DMA_READ ( void );
void SP_DMA_WRITE ( void );

309
Source/RSP/log.cpp Normal file
View File

@ -0,0 +1,309 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
#include <windows.h>
#include <Common/std string.h>
#include <Common/Log Class.h>
extern "C" {
#include "Log.h"
#include "Rsp.h"
#include "Rsp Registers.h"
}
CLog * RDPLog = NULL;
CLog * CPULog = NULL;
void StartCPULog ( void )
{
if (CPULog == NULL)
{
CPULog = new CLog;
CPULog->Open("RSP_x86Log.txt");
}
}
void StopCPULog ( void )
{
if (CPULog == NULL)
{
delete CPULog;
CPULog = NULL;
}
}
void CPU_Message ( const char * Message, ...)
{
if (CPULog == NULL)
{
return;
}
va_list args;
va_start(args, Message);
CPULog->LogArgs(Message,args);
va_end(args);
}
void StartRDPLog ( void )
{
if (RDPLog == NULL)
{
RDPLog = new CLog;
RDPLog->Open("RDP_Log.txt");
// RDPLog->SetFlush(true);
}
}
void StopRDPLog ( void )
{
if (RDPLog == NULL)
{
delete RDPLog;
RDPLog = NULL;
}
}
void RDP_Message ( const char * Message, ...)
{
if (RDPLog == NULL)
{
return;
}
va_list args;
va_start(args, Message);
RDPLog->LogArgs(Message,args);
va_end(args);
}
void RDP_LogMT0 ( DWORD PC, int Reg, DWORD Value )
{
if (RDPLog == NULL)
{
return;
}
switch (Reg) {
case 0: RDP_Message("%03X: Stored 0x%08X into SP_MEM_ADDR_REG",PC,Value); break;
case 1: RDP_Message("%03X: Stored 0x%08X into SP_DRAM_ADDR_REG",PC,Value); break;
case 2: RDP_Message("%03X: Stored 0x%08X into SP_RD_LEN_REG",PC,Value); break;
case 3: RDP_Message("%03X: Stored 0x%08X into SP_WR_LEN_REG",PC,Value); break;
case 4: RDP_Message("%03X: Stored 0x%08X into SP_STATUS_REG",PC,Value); break;
case 5: RDP_Message("%03X: Stored 0x%08X into Reg 5 ???",PC,Value); break;
case 6: RDP_Message("%03X: Stored 0x%08X into Reg 6 ???",PC,Value); break;
case 7: RDP_Message("%03X: Stored 0x%08X into SP_SEMAPHORE_REG",PC,Value); break;
case 8: RDP_Message("%03X: Stored 0x%08X into DPC_START_REG",PC,Value); break;
case 9: RDP_Message("%03X: Stored 0x%08X into DPC_END_REG",PC,Value); break;
case 10: RDP_Message("%03X: Stored 0x%08X into DPC_CURRENT_REG",PC,Value); break;
case 11: RDP_Message("%03X: Stored 0x%08X into DPC_STATUS_REG",PC,Value); break;
case 12: RDP_Message("%03X: Stored 0x%08X into DPC_CLOCK_REG",PC,Value); break;
}
}
void RDP_LogMF0 ( DWORD PC, int Reg )
{
switch (Reg) {
case 8: RDP_Message("%03X: Read 0x%08X from DPC_START_REG",PC,*RSPInfo.DPC_START_REG); break;
case 9: RDP_Message("%03X: Read 0x%08X from DPC_END_REG",PC,*RSPInfo.DPC_END_REG); break;
case 10: RDP_Message("%03X: Read 0x%08X from DPC_CURRENT_REG",PC,*RSPInfo.DPC_CURRENT_REG); break;
case 11: RDP_Message("%03X: Read 0x%08X from DPC_STATUS_REG",PC,*RSPInfo.DPC_STATUS_REG); break;
case 12: RDP_Message("%03X: Read 0x%08X from DPC_CLOCK_REG",PC,*RSPInfo.DPC_CLOCK_REG); break;
}
}
void RDP_LogDlist ( void )
{
if (RDPLog == NULL)
{
return;
}
RDP_Message(" Dlist length = %d bytes",*RSPInfo.DPC_END_REG - *RSPInfo.DPC_CURRENT_REG);
DWORD Length = *RSPInfo.DPC_END_REG - *RSPInfo.DPC_CURRENT_REG;
DWORD Pos = *RSPInfo.DPC_CURRENT_REG;
while (Pos < *RSPInfo.DPC_END_REG)
{
char Hex[100], Ascii[30];
DWORD count;
memset(&Hex,0,sizeof(Hex));
memset(&Ascii,0,sizeof(Ascii));
BYTE * Mem = RSPInfo.DMEM;
if ((*RSPInfo.DPC_STATUS_REG & DPC_STATUS_XBUS_DMEM_DMA) == 0)
{
Mem = RSPInfo.RDRAM;
}
for (count = 0; count < 0x10; count ++, Pos++ ) {
if ((count % 4) != 0 || count == 0) {
sprintf(Hex,"%s %02X",Hex,Mem[Pos]);
} else {
sprintf(Hex,"%s - %02X",Hex,Mem[Pos]);
}
if (Mem[Pos] < 30 || Mem[Pos] > 127) {
strcat(Ascii,".");
} else {
sprintf(Ascii,"%s%c",Ascii,Mem[Pos]);
}
}
RDP_Message(" %s %s",Hex, Ascii);
}
}
void RDP_LogLoc ( DWORD PC )
{
// RDP_Message("%03X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X %08X",PC, RSP_GPR[26].UW, *(DWORD *)&RSPInfo.IMEM[0xDBC],
// RSP_Flags[0].UW, RSP_Vect[0].UW[0],RSP_Vect[0].UW[1],RSP_Vect[0].UW[2],RSP_Vect[0].UW[3],
// RSP_Vect[28].UW[0],RSP_Vect[28].UW[1],RSP_Vect[28].UW[2],RSP_Vect[28].UW[3],RSP_Vect[31].UW[0]);
}
#ifdef old
#include <windows.h>
#include <stdio.h>
#include "RSP Registers.h"
#include "log.h"
#ifdef Log_x86Code
static HANDLE hCPULogFile = NULL;
#endif
#ifdef GenerateLog
static HANDLE hLogFile = NULL;
#endif
#ifdef Log_x86Code
void CPU_Message (char * Message, ...) {
DWORD dwWritten;
char Msg[400];
va_list ap;
va_start( ap, Message );
vsprintf( Msg, Message, ap );
va_end( ap );
strcat(Msg,"\r\n");
WriteFile( hCPULogFile,Msg,strlen(Msg),&dwWritten,NULL );
}
#endif
#ifdef GenerateLog
void Log_Message (char * Message, ...) {
DWORD dwWritten;
char Msg[400];
va_list ap;
va_start( ap, Message );
vsprintf( Msg, Message, ap );
va_end( ap );
strcat(Msg,"\r\n");
WriteFile( hLogFile,Msg,strlen(Msg),&dwWritten,NULL );
}
#endif
#ifdef Log_x86Code
void Start_x86_Log (void) {
char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR];
char File[_MAX_PATH];
GetModuleFileName(NULL,path_buffer,_MAX_PATH);
_splitpath(path_buffer, drive, dir, NULL, NULL);
sprintf(File, "%s%s\\RSPx86Log.log", drive, dir);
hCPULogFile = CreateFile(File,GENERIC_WRITE, FILE_SHARE_READ,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
SetFilePointer(hCPULogFile,0,NULL,FILE_BEGIN);
}
#endif
#ifdef GenerateLog
void Log_MT_CP0 ( unsigned int PC, int CP0Reg, int Value ) {
switch (CP0Reg) {
//case 0: Log_Message("%03X: Stored 0x%08X in SP_MEM_ADDR_REG",PC,Value); break;
//case 1: Log_Message("%03X: Stored 0x%08X in SP_DRAM_ADDR_REG",PC,Value); break;
//case 2: Log_Message("%03X: Stored 0x%08X in SP_RD_LEN_REG",PC,Value); break;
case 3:
//Log_Message("%03X: Stored 0x%08X in SP_WR_LEN_REG",PC,Value);
Log_Message("Instruction: %08X%08X",RSP_GPR[25].UW,RSP_GPR[24].UW);
//Log_Message("");
break;
/*case 4: Log_Message("%03X: Stored 0x%08X in SP_STATUS_REG",PC,Value); break;
case 5: Log_Message("%03X: Stored 0x%08X in SP_DMA_FULL_REG",PC,Value); break;
case 6: Log_Message("%03X: Stored 0x%08X in SP_DMA_BUSY_REG",PC,Value); break;
case 7: Log_Message("%03X: Stored 0x%08X in SP_SEMAPHORE_REG",PC,Value); break;
case 8: Log_Message("%03X: Stored 0x%08X in DPC_START_REG",PC,Value); break;
case 9: Log_Message("%03X: Stored 0x%08X in DPC_END_REG",PC,Value); break;
case 10: Log_Message("%03X: Stored 0x%08X in DPC_CURRENT_REG",PC,Value); break;
case 11: Log_Message("%03X: Stored 0x%08X in DPC_STATUS_REG",PC,Value); break;
case 12: Log_Message("%03X: Stored 0x%08X in DPC_CLOCK_REG",PC,Value); break;
case 13: Log_Message("%03X: Stored 0x%08X in DPC_BUFBUSY_REG",PC,Value); break;
case 14: Log_Message("%03X: Stored 0x%08X in DPC_PIPEBUSY_REG",PC,Value); break;
case 15: Log_Message("%03X: Stored 0x%08X in DPC_TMEM_REG",PC,Value); break;
default:
Log_Message("%03X: Unkown RSP CP0 register %d",PC,CP0Reg);
break;*/
}
}
void Start_Log (void) {
char path_buffer[_MAX_PATH], drive[_MAX_DRIVE] ,dir[_MAX_DIR];
char File[_MAX_PATH];
GetModuleFileName(NULL,path_buffer,_MAX_PATH);
_splitpath(path_buffer, drive, dir, NULL, NULL);
sprintf(File, "%s%s\\RSP.log", drive, dir);
hLogFile = CreateFile(File,GENERIC_WRITE, FILE_SHARE_READ,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
SetFilePointer(hLogFile,0,NULL,FILE_BEGIN);
}
void Stop_Log (void) {
if (hLogFile) {
CloseHandle(hLogFile);
hLogFile = NULL;
}
}
#endif
#ifdef Log_x86Code
void Stop_x86_Log (void) {
if (hCPULogFile) {
CloseHandle(hCPULogFile);
hCPULogFile = NULL;
}
}
#endif
#endif

45
Source/RSP/log.h Normal file
View File

@ -0,0 +1,45 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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 __cplusplus
extern "C" {
#endif
void StartCPULog ( void );
void StopCPULog ( void );
void CPU_Message ( const char * Message, ...);
void StartRDPLog ( void );
void StopRDPLog ( void );
void RDP_Message ( const char * Message, ...);
void RDP_LogDlist ( void );
void RDP_LogMT0 ( DWORD PC, int Reg, DWORD Value );
void RDP_LogMF0 ( DWORD PC, int Reg );
void RDP_LogLoc ( DWORD PC );
#ifdef __cplusplus
}
#endif

556
Source/RSP/memory.c Normal file
View File

@ -0,0 +1,556 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
enum { MaxMaps = 32 };
#include <windows.h>
#include "rsp.h"
#include "RSP Registers.h"
DWORD NoOfMaps, MapsCRC[MaxMaps], Table;
BYTE * RecompCode, * RecompCodeSecondary, * RecompPos, *JumpTables;
void ** JumpTable;
int AllocateMemory (void) {
RecompCode=(BYTE *) VirtualAlloc( NULL, 0x00400004, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
RecompCode=(BYTE *) VirtualAlloc( RecompCode, 0x00400000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(RecompCode == NULL) {
DisplayError("Not enough memory for RSP RecompCode!");
return FALSE;
}
RecompCodeSecondary = (BYTE *)VirtualAlloc( NULL, 0x00200000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if(RecompCodeSecondary == NULL) {
DisplayError("Not enough memory for RSP RecompCode Secondary!");
return FALSE;
}
JumpTables = (BYTE *)VirtualAlloc( NULL, 0x1000 * MaxMaps, MEM_COMMIT, PAGE_READWRITE );
if( JumpTables == NULL ) {
DisplayError("Not enough memory for Jump Table!");
return FALSE;
}
JumpTable = (void **)JumpTables;
RecompPos = RecompCode;
NoOfMaps = 0;
return TRUE;
}
void FreeMemory (void) {
VirtualFree( RecompCode, 0 , MEM_RELEASE);
VirtualFree( JumpTable, 0 , MEM_RELEASE);
VirtualFree( RecompCodeSecondary, 0 , MEM_RELEASE);
}
void ResetJumpTables ( void )
{
memset(JumpTables,0,0x1000 * MaxMaps);
RecompPos = RecompCode;
NoOfMaps = 0;
}
void SetJumpTable (DWORD End) {
DWORD CRC, count;
CRC = 0;
if (End < 0x800)
{
End = 0x800;
}
if (End == 0x1000 && ((*RSPInfo.SP_MEM_ADDR_REG & 0x0FFF) & ~7) == 0x80)
{
End = 0x800;
}
for (count = 0; count < End; count += 0x40) {
CRC += *(DWORD *)(RSPInfo.IMEM + count);
}
for (count = 0; count < NoOfMaps; count++ ) {
if (CRC == MapsCRC[count]) {
JumpTable = (void **)(JumpTables + count * 0x1000);
Table = count;
return;
}
}
//DisplayError("%X %X",NoOfMaps,CRC);
if (NoOfMaps == MaxMaps) {
ResetJumpTables();
}
MapsCRC[NoOfMaps] = CRC;
JumpTable = (void **)(JumpTables + NoOfMaps * 0x1000);
Table = NoOfMaps;
NoOfMaps += 1;
}
void RSP_LB_DMEM ( DWORD Addr, BYTE * Value ) {
* Value = *(BYTE *)(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) ;
}
void RSP_LBV_DMEM ( DWORD Addr, int vect, int element ) {
RSP_Vect[vect].B[15 - element] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
}
void RSP_LDV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count;
length = 8;
if (length > 16 - element) {
length = 16 - element;
}
for (Count = element; Count < (length + element); Count ++ ){
RSP_Vect[vect].B[15 - Count] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
Addr += 1;
}
}
void RSP_LFV_DMEM ( DWORD Addr, int vect, int element ) {
int length, count;
VECTOR Temp;
length = 8;
if (length > 16 - element) {
length = 16 - element;
}
Temp.HW[7] = *(RSPInfo.DMEM + (((Addr + element) ^3) & 0xFFF)) << 7;
Temp.HW[6] = *(RSPInfo.DMEM + (((Addr + ((0x4 - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[5] = *(RSPInfo.DMEM + (((Addr + ((0x8 - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[4] = *(RSPInfo.DMEM + (((Addr + ((0xC - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[3] = *(RSPInfo.DMEM + (((Addr + ((0x8 - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[2] = *(RSPInfo.DMEM + (((Addr + ((0xC - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[1] = *(RSPInfo.DMEM + (((Addr + ((0x10 - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
Temp.HW[0] = *(RSPInfo.DMEM + (((Addr + ((0x4 - element) ^ 3) & 0xf)) & 0xFFF)) << 7;
for (count = element; count < (length + element); count ++ ){
RSP_Vect[vect].B[15 - count] = Temp.B[15 - count];
}
}
void RSP_LH_DMEM ( DWORD Addr, WORD * Value ) {
if ((Addr & 0x1) != 0) {
if (Addr > 0xFFE) {
DisplayError("hmmmm.... Problem with:\nRSP_LH_DMEM");
return;
}
Addr &= 0xFFF;
*Value = *(BYTE *)(RSPInfo.DMEM + (Addr^ 3)) << 8;
*Value += *(BYTE *)(RSPInfo.DMEM + ((Addr + 1)^ 3));
return;
}
* Value = *(WORD *)(RSPInfo.DMEM + ((Addr ^ 2 ) & 0xFFF));
}
void RSP_LHV_DMEM ( DWORD Addr, int vect, int element ) {
RSP_Vect[vect].HW[7] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[6] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 2) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[5] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 4) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[4] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 6) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[3] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 8) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[2] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 10) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[1] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 12) & 0xF) ^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[0] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 14) & 0xF) ^3) & 0xFFF)) << 7;
}
void RSP_LLV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count;
length = 4;
if (length > 16 - element) {
length = 16 - element;
}
for (Count = element; Count < (length + element); Count ++ ){
RSP_Vect[vect].B[15 - Count] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
Addr += 1;
}
}
void RSP_LPV_DMEM ( DWORD Addr, int vect, int element ) {
RSP_Vect[vect].HW[7] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[6] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 1) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[5] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 2) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[4] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 3) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[3] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 4) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[2] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 5) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[1] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 6) & 0xF)^3) & 0xFFF)) << 8;
RSP_Vect[vect].HW[0] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 7) & 0xF)^3) & 0xFFF)) << 8;
}
void RSP_LRV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count, offset;
offset = (Addr & 0xF) - 1;
length = (Addr & 0xF) - element;
Addr &= 0xFF0;
for (Count = element; Count < (length + element); Count ++ ){
RSP_Vect[vect].B[offset - Count] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
Addr += 1;
}
}
void RSP_LQV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count;
length = ((Addr + 0x10) & ~0xF) - Addr;
if (length > 16 - element) {
length = 16 - element;
}
for (Count = element; Count < (length + element); Count ++ ){
RSP_Vect[vect].B[15 - Count] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
Addr += 1;
}
}
void RSP_LSV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count;
length = 2;
if (length > 16 - element) {
length = 16 - element;
}
for (Count = element; Count < (length + element); Count ++ ){
RSP_Vect[vect].B[15 - Count] = *(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF));
Addr += 1;
}
}
void RSP_LTV_DMEM ( DWORD Addr, int vect, int element ) {
int del, count, length;
length = 8;
if (length > 32 - vect) {
length = 32 - vect;
}
Addr = ((Addr + 8) & 0xFF0) + (element & 0x1);
for (count = 0; count < length; count ++) {
del = ((8 - (element >> 1) + count) << 1) & 0xF;
RSP_Vect[vect + count].B[15 - del] = *(RSPInfo.DMEM + (Addr ^ 3));
RSP_Vect[vect + count].B[14 - del] = *(RSPInfo.DMEM + ((Addr + 1) ^ 3));
Addr += 2;
}
}
void RSP_LUV_DMEM ( DWORD Addr, int vect, int element ) {
RSP_Vect[vect].HW[7] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[6] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 1) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[5] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 2) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[4] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 3) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[3] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 4) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[2] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 5) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[1] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 6) & 0xF)^3) & 0xFFF)) << 7;
RSP_Vect[vect].HW[0] = *(RSPInfo.DMEM + ((Addr + ((0x10 - element + 7) & 0xF)^3) & 0xFFF)) << 7;
}
void RSP_LW_DMEM ( DWORD Addr, DWORD * Value ) {
if ((Addr & 0x3) != 0) {
Addr &= 0xFFF;
if (Addr > 0xFFC) {
DisplayError("hmmmm.... Problem with:\nRSP_LW_DMEM");
return;
}
*Value = *(BYTE *)(RSPInfo.DMEM + (Addr^ 3)) << 0x18;
*Value += *(BYTE *)(RSPInfo.DMEM + ((Addr + 1)^ 3)) << 0x10;
*Value += *(BYTE *)(RSPInfo.DMEM + ((Addr + 2)^ 3)) << 8;
*Value += *(BYTE *)(RSPInfo.DMEM + ((Addr + 3)^ 3));
return;
}
* Value = *(DWORD *)(RSPInfo.DMEM + (Addr & 0xFFF));
}
void RSP_LW_IMEM ( DWORD Addr, DWORD * Value ) {
if ((Addr & 0x3) != 0) {
DisplayError("Unaligned RSP_LW_IMEM");
}
* Value = *(DWORD *)(RSPInfo.IMEM + (Addr & 0xFFF));
}
void RSP_SB_DMEM ( DWORD Addr, BYTE Value ) {
*(BYTE *)(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = Value;
}
void RSP_SBV_DMEM ( DWORD Addr, int vect, int element ) {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].B[15 - element];
}
void RSP_SDV_DMEM ( DWORD Addr, int vect, int element ) {
int Count;
for (Count = element; Count < (8 + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].B[15 - (Count & 0xF)];
Addr += 1;
}
}
void RSP_SFV_DMEM ( DWORD Addr, int vect, int element ) {
int offset = Addr & 0xF;
Addr &= 0xFF0;
switch (element) {
case 0:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[7] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[6] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[5] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[4] >> 7;
break;
case 1:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[1] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[0] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[3] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[2] >> 7;
break;
case 2:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 3:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF)^3))) = 0;
break;
case 4:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[6] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[5] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[4] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[7] >> 7;
break;
case 5:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[0] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[3] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[2] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[1] >> 7;
break;
case 6:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 7:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 8:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[3] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[2] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[1] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[0] >> 7;
break;
case 9:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 10:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 11:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[4] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[7] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[6] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[5] >> 7;
break;
case 12:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[2] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[1] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[0] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[3] >> 7;
break;
case 13:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 14:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = 0;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = 0;
break;
case 15:
*(RSPInfo.DMEM + ((Addr + offset)^3)) = RSP_Vect[vect].UHW[7] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 4) & 0xF))^3)) = RSP_Vect[vect].UHW[6] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 8) & 0xF))^3)) = RSP_Vect[vect].UHW[5] >> 7;
*(RSPInfo.DMEM + ((Addr + ((offset + 12) & 0xF))^3)) = RSP_Vect[vect].UHW[4] >> 7;
break;
}
}
void RSP_SH_DMEM ( DWORD Addr, WORD Value ) {
if ((Addr & 0x1) != 0) {
DisplayError("Unaligned RSP_SH_DMEM");
return;
}
*(WORD *)(RSPInfo.DMEM + ((Addr ^ 2) & 0xFFF)) = Value;
}
void RSP_SHV_DMEM ( DWORD Addr, int vect, int element ) {
*(RSPInfo.DMEM + ((Addr^3) & 0xFFF)) = (RSP_Vect[vect].UB[(15 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(14 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 2)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(13 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(12 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 4)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(11 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(10 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 6)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(9 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(8 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 8)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(7 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(6 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 10)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(5 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(4 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 12)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(3 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(2 - element) & 0xF] >> 7);
*(RSPInfo.DMEM + (((Addr + 14)^3) & 0xFFF)) = (RSP_Vect[vect].UB[(1 - element) & 0xF] << 1) +
(RSP_Vect[vect].UB[(0 - element) & 0xF] >> 7);
}
void RSP_SLV_DMEM ( DWORD Addr, int vect, int element ) {
int Count;
for (Count = element; Count < (4 + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr ^3) & 0xFFF)) = RSP_Vect[vect].B[15 - (Count & 0xF)];
Addr += 1;
}
}
void RSP_SPV_DMEM ( DWORD Addr, int vect, int element ) {
int Count;
for (Count = element; Count < (8 + element); Count ++ ){
if (((Count) & 0xF) < 8) {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].UB[15 - ((Count & 0xF) << 1)];
} else {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = (RSP_Vect[vect].UB[15 - ((Count & 0x7) << 1)] << 1) +
(RSP_Vect[vect].UB[14 - ((Count & 0x7) << 1)] >> 7);
}
Addr += 1;
}
}
void RSP_SQV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count;
length = ((Addr + 0x10) & ~0xF) - Addr;
for (Count = element; Count < (length + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].B[15 - (Count & 0xF)];
Addr += 1;
}
}
void RSP_SRV_DMEM ( DWORD Addr, int vect, int element ) {
int length, Count, offset;
length = (Addr & 0xF);
offset = (0x10 - length) & 0xF;
Addr &= 0xFF0;
for (Count = element; Count < (length + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].B[15 - ((Count + offset) & 0xF)];
Addr += 1;
}
}
void RSP_SSV_DMEM ( DWORD Addr, int vect, int element ) {
int Count;
for (Count = element; Count < (2 + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].B[15 - (Count & 0xF)];
Addr += 1;
}
}
void RSP_STV_DMEM ( DWORD Addr, int vect, int element ) {
int del, count, length;
length = 8;
if (length > 32 - vect) {
length = 32 - vect;
}
length = length << 1;
del = element >> 1;
for (count = 0; count < length; count += 2) {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect + del].UB[15 - count];
*(RSPInfo.DMEM + (((Addr + 1) ^ 3) & 0xFFF)) = RSP_Vect[vect + del].UB[14 - count];
del = (del + 1) & 7;
Addr += 2;
}
}
void RSP_SUV_DMEM ( DWORD Addr, int vect, int element ) {
int Count;
for (Count = element; Count < (8 + element); Count ++ ){
if (((Count) & 0xF) < 8) {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = (RSP_Vect[vect].UB[15 - ((Count & 0x7) << 1)] << 1) +
(RSP_Vect[vect].UB[14 - ((Count & 0x7) << 1)] >> 7);
} else {
*(RSPInfo.DMEM + ((Addr ^ 3) & 0xFFF)) = RSP_Vect[vect].UB[15 - ((Count & 0x7) << 1)];
}
Addr += 1;
}
}
void RSP_SW_DMEM ( DWORD Addr, DWORD Value ) {
Addr &= 0xFFF;
if ((Addr & 0x3) != 0) {
if (Addr > 0xFFC) {
DisplayError("hmmmm.... Problem with:\nRSP_SW_DMEM");
return;
}
*(BYTE *)(RSPInfo.DMEM + (Addr ^ 3)) = (BYTE)(Value >> 0x18);
*(BYTE *)(RSPInfo.DMEM + ((Addr + 1) ^ 3)) = (BYTE)(Value >> 0x10);
*(BYTE *)(RSPInfo.DMEM + ((Addr + 2) ^ 3)) = (BYTE)(Value >> 0x8);
*(BYTE *)(RSPInfo.DMEM + ((Addr + 3) ^ 3)) = (BYTE)(Value);
return;
}
*(DWORD *)(RSPInfo.DMEM + Addr) = Value;
}
void RSP_SWV_DMEM ( DWORD Addr, int vect, int element ) {
int Count, offset;
offset = Addr & 0xF;
Addr &= 0xFF0;
for (Count = element; Count < (16 + element); Count ++ ){
*(RSPInfo.DMEM + ((Addr + (offset & 0xF)) ^ 3)) = RSP_Vect[vect].B[15 - (Count & 0xF)];
offset += 1;
}
}

64
Source/RSP/memory.h Normal file
View File

@ -0,0 +1,64 @@
/*
* RSP Compiler plug in for Project 64 (A Nintendo 64 emulator).
*
* (c) Copyright 2001 jabo (jabo@emulation64.com) and
* zilmar (zilmar@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.
*
*/
int AllocateMemory ( void );
void FreeMemory ( void );
void SetJumpTable ( DWORD End );
extern BYTE * RecompCode, * RecompCodeSecondary, * RecompPos;
extern void ** JumpTable;
extern DWORD Table;
void RSP_LB_DMEM ( DWORD Addr, BYTE * Value );
void RSP_LBV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LDV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LFV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LH_DMEM ( DWORD Addr, WORD * Value );
void RSP_LHV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LLV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LPV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LRV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LQV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LSV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LTV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LUV_DMEM ( DWORD Addr, int vect, int element );
void RSP_LW_DMEM ( DWORD Addr, DWORD * Value );
void RSP_LW_IMEM ( DWORD Addr, DWORD * Value );
void RSP_SB_DMEM ( DWORD Addr, BYTE Value );
void RSP_SBV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SDV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SFV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SH_DMEM ( DWORD Addr, WORD Value );
void RSP_SHV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SLV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SPV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SQV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SRV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SSV_DMEM ( DWORD Addr, int vect, int element );
void RSP_STV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SUV_DMEM ( DWORD Addr, int vect, int element );
void RSP_SW_DMEM ( DWORD Addr, DWORD Value );
void RSP_SWV_DMEM ( DWORD Addr, int vect, int element );

50
Source/RSP/resource.h Normal file
View File

@ -0,0 +1,50 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by RSP.rc
//
#define RspMenu 106
#define IDC_CHECK_SSE 1001
#define IDC_CHECK_MMX 1002
#define IDC_CHECK_MMX2 1003
#define IDC_PRIMARY_BUFFER 1006
#define IDC_SECONDARY_BUFFER 1007
#define IDC_COMPILER_VMULF 1018
#define IDC_COMPILER_DEST 1019
#define IDC_COMPILER_ACCUM 1020
#define IDC_COMPILER_FLAGS 1021
#define IDC_COMPILER_REORDER 1022
#define IDC_COMPILER_SECTIONS 1023
#define IDC_COMPILER_ALIGNGPR 1024
#define IDC_COMPILER_ALIGNVEC 1025
#define IDC_COMPILER_GPRCONSTANTS 1026
#define IDC_AUDIOHLE 1027
#define IDC_GRAPHICSHLE 1028
#define IDC_COMPILER_BUFFERS 1030
#define IDC_COMPILER_SELECT 1031
#define ID_RSPCOMMANDS 5001
#define ID_RSPREGISTERS 5002
#define ID_PROFILING_ON 5003
#define ID_PROFILING_OFF 5004
#define ID_PROFILING_LOGINDIVIDUALBLOCKS 5005
#define ID_PROFILING_RESETSTATS 5006
#define ID_PROFILING_GENERATELOG 5007
#define ID_DUMP_RSPCODE 5008
#define ID_DUMP_DMEM 5009
#define ID_SHOWCOMPILERERRORS 5011
#define ID_COMPILER 5012
#define ID_BREAKONSTARTOFTASK 5014
#define ID_LOGRDPCOMMANDS 5015
#define ID_CPUMETHOD_RECOMPILER 5016
#define ID_CPUMETHOD_INTERPT 5017
#define ID_SETTINGS_LOGX86CODE 5019
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 5020
#define _APS_NEXT_CONTROL_VALUE 1032
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,137 @@
#include <windows.h>
#include <stdio.h>
#include "Settings.h"
enum SettingLocation {
ConstString = 0, ConstValue = 1, LocalSettings = 2, InRegistry = 3, RelativePath = 4, TemporarySetting = 5,
RomSetting = 6, CheatSetting = 7, GameSetting = 8,
};
enum SettingDataType {
Data_DWORD = 0, Data_String = 1, Data_CPUTYPE = 2, Data_SelfMod = 3, Data_OnOff = 4, Data_YesNo = 5, Data_SaveChip = 6
};
typedef struct {
DWORD dwSize;
int DefaultStartRange;
int SettingStartRange;
int MaximumSettings;
int NoDefault;
int DefaultLocation;
void * handle;
unsigned int (*GetSetting) ( void * handle, int ID );
const char * (*GetSettingSz) ( void * handle, int ID, char * Buffer, int BufferLen );
void (*SetSetting) ( void * handle, int ID, unsigned int Value );
void (*SetSettingSz) ( void * handle, int ID, const char * Value );
void (*RegisterSetting) ( void * handle, int ID, int DefaultID, SettingDataType Type,
SettingLocation Location, const char * Category, const char * DefaultStr, DWORD Value );
void (*UseUnregisteredSetting) (int ID);
} PLUGIN_SETTINGS;
static PLUGIN_SETTINGS g_PluginSettings;
static bool g_PluginInitilized = false;
static char g_PluginSettingName[300];
extern "C" {
__declspec(dllexport) void SetSettingInfo (PLUGIN_SETTINGS * info);
}
__declspec(dllexport) void SetSettingInfo (PLUGIN_SETTINGS * info)
{
g_PluginSettings = *info;
g_PluginInitilized = true;
info->UseUnregisteredSetting = UseUnregisteredSetting;
}
BOOL SettingsInitilized ( void )
{
return g_PluginInitilized;
}
void SetModuleName ( const char * Name )
{
_snprintf(g_PluginSettingName,sizeof(g_PluginSettingName),"%s",Name);
}
void RegisterSetting ( short SettingID, SETTING_DATA_TYPE Type, const char * Name, const char * Category,
unsigned int DefaultDW, const char * DefaultStr )
{
int DefaultID = g_PluginSettings.NoDefault;
SettingLocation Location = (SettingLocation)g_PluginSettings.DefaultLocation;
char FullCategory[400];
if (Category && Category[0] != 0)
{
_snprintf(FullCategory,sizeof(FullCategory),"%s\\%s",g_PluginSettingName,Category);
} else {
_snprintf(FullCategory,sizeof(FullCategory),"%s",g_PluginSettingName);
}
switch (Type)
{
case Data_DWORD_Game:
case Data_String_Game:
Location = GameSetting;
break;
case Data_DWORD_RDB:
case Data_String_RDB:
Location = RomSetting;
break;
}
switch (Type)
{
case Data_DWORD_General:
case Data_DWORD_Game:
case Data_DWORD_RDB:
if (DefaultDW != 0)
{
//create default
DefaultID = SettingID + g_PluginSettings.DefaultStartRange;
g_PluginSettings.RegisterSetting(g_PluginSettings.handle,DefaultID,g_PluginSettings.NoDefault,
Data_DWORD,ConstValue,g_PluginSettingName,"",DefaultDW);
}
g_PluginSettings.RegisterSetting(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange,
DefaultID,Data_DWORD,Location,FullCategory,Name,0);
break;
case Data_String_General:
case Data_String_Game:
case Data_String_RDB:
if (DefaultStr != NULL && strlen(DefaultStr) > 0)
{
//create default
DefaultID = SettingID + g_PluginSettings.DefaultStartRange;
g_PluginSettings.RegisterSetting(g_PluginSettings.handle,DefaultID,g_PluginSettings.NoDefault,
Data_String,ConstString,g_PluginSettingName,DefaultStr,0);
}
g_PluginSettings.RegisterSetting(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange,
DefaultID,Data_String,Location,FullCategory,Name,0);
break;
}
}
unsigned int GetSetting ( short SettingID )
{
return g_PluginSettings.GetSetting(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange);
}
const char * GetSettingSz ( short SettingID, char * Buffer, int BufferLen )
{
return g_PluginSettings.GetSettingSz(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange,Buffer,BufferLen);
}
void SetSetting ( short SettingID, unsigned int Value )
{
g_PluginSettings.SetSetting(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange, Value);
}
void SetSettingSz ( short SettingID, const char * Value )
{
g_PluginSettings.SetSettingSz(g_PluginSettings.handle,SettingID + g_PluginSettings.SettingStartRange, Value);
}

View File

@ -0,0 +1,100 @@
# Microsoft Developer Studio Project File - Name="Settings" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Settings - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Settings.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Settings.mak" CFG="Settings - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Settings - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Settings - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Settings - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../Build/Settings/Release"
# PROP Intermediate_Dir "../../Build/Settings/Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0xc09 /d "NDEBUG"
# ADD RSC /l 0xc09 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Settings - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../Build/Settings/Debug"
# PROP Intermediate_Dir "../../Build/Settings/Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0xc09 /d "_DEBUG"
# ADD RSC /l 0xc09 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Settings - Win32 Release"
# Name "Settings - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\Settings.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\Settings.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -0,0 +1,36 @@
#if defined(__cplusplus)
extern "C" {
#endif
// Get Settings, take a setting id
unsigned int GetSetting ( short SettingID );
const char * GetSettingSz ( short SettingID, char * Buffer, int BufferLen );
// Set a settings value
void SetSetting ( short SettingID, unsigned int Value );
void SetSettingSz ( short SettingID, const char * Value );
// enum's
enum SETTING_DATA_TYPE {
Data_DWORD_General = 0, // A unsigned int setting used anywhere
Data_String_General = 1, // A string setting used anywhere
Data_DWORD_Game = 2, // A unsigned int associated with the current game
Data_String_Game = 3, // A string associated with the current game
Data_DWORD_RDB = 4, // A unsigned int associated with the current game in the rom database
Data_String_RDB = 5, // A string associated with the current game in the rom database
};
// set other information about different settings
BOOL SettingsInitilized ( void );
void SetModuleName ( const char * Name );
void RegisterSetting ( short SettingID, SETTING_DATA_TYPE Type, const char * Name, const char * Category,
unsigned int DefaultDW, const char * DefaultStr );
// this must be implemented to be notified when a setting is used but has not been set up
void UseUnregisteredSetting (int SettingID);
#if defined(__cplusplus)
}
#endif

View File

@ -80,13 +80,89 @@ LIB32=link.exe -lib
# Name "WTL - Win32 Release" # Name "WTL - Win32 Release"
# Name "WTL - Win32 Debug" # Name "WTL - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# End Group
# Begin Group "Header Files" # Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\atlapp.h
# End Source File
# Begin Source File
SOURCE=.\atlcrack.h
# End Source File
# Begin Source File
SOURCE=.\atlctrls.h
# End Source File
# Begin Source File
SOURCE=.\atlctrlw.h
# End Source File
# Begin Source File
SOURCE=.\atlctrlx.h
# End Source File
# Begin Source File
SOURCE=.\atlddx.h
# End Source File
# Begin Source File
SOURCE=.\atldlgs.h
# End Source File
# Begin Source File
SOURCE=.\atlfind.h
# End Source File
# Begin Source File
SOURCE=.\atlframe.h
# End Source File
# Begin Source File
SOURCE=.\atlgdi.h
# End Source File
# Begin Source File
SOURCE=.\atlmisc.h
# End Source File
# Begin Source File
SOURCE=.\atlprint.h
# End Source File
# Begin Source File
SOURCE=.\atlres.h
# End Source File
# Begin Source File
SOURCE=.\atlresce.h
# End Source File
# Begin Source File
SOURCE=.\atlscrl.h
# End Source File
# Begin Source File
SOURCE=.\atlsplit.h
# End Source File
# Begin Source File
SOURCE=.\atltheme.h
# End Source File
# Begin Source File
SOURCE=.\atluser.h
# End Source File
# Begin Source File
SOURCE=.\atlwince.h
# End Source File
# Begin Source File
SOURCE=.\atlwinx.h
# End Source File
# End Group # End Group
# End Target # End Target
# End Project # End Project

Binary file not shown.