[Project64] Make the mempak belong to the n64 system

This commit is contained in:
zilmar 2016-07-07 21:51:06 +10:00
parent 35c64e5d16
commit 676be8fcdc
7 changed files with 104 additions and 96 deletions

View File

@ -10,13 +10,17 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
class Mempak class CMempak
{ {
public: public:
static uint8_t CalculateCrc(uint8_t * DataToCrc); static uint8_t CalculateCrc(uint8_t * DataToCrc);
static void ReadFrom(int32_t Control, uint32_t address, uint8_t * data); void ReadFrom(int32_t Control, uint32_t address, uint8_t * data);
static void WriteTo(int32_t Control, uint32_t address, uint8_t * data); void WriteTo(int32_t Control, uint32_t address, uint8_t * data);
private: private:
static void LoadMempak(int32_t Control); void LoadMempak(int32_t Control);
static void Format(int32_t Control); void Format(int32_t Control);
uint8_t m_Mempaks[4][128 * 256]; /* [CONTROLLERS][PAGES][BYTES_PER_PAGE] */
CFile m_MempakHandle[4];
}; };

View File

@ -14,15 +14,12 @@
#include <stdio.h> #include <stdio.h>
#include <Common/path.h> #include <Common/path.h>
uint8_t Mempaks[4][128 * 256]; /* [CONTROLLERS][PAGES][BYTES_PER_PAGE] */ void CMempak::LoadMempak(int32_t Control)
CFile MempakHandle[4];
void Mempak::LoadMempak(int32_t Control)
{ {
stdstr MempakName; stdstr MempakName;
MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1); MempakName.Format("%s_Cont_%d", g_Settings->LoadStringVal(Game_GameName).c_str(), Control + 1);
CPath MempakPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk",MempakName.c_str()).c_str()); CPath MempakPath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), stdstr_f("%s.mpk", MempakName.c_str()).c_str());
if (g_Settings->LoadBool(Setting_UniqueSaveDir)) if (g_Settings->LoadBool(Setting_UniqueSaveDir))
{ {
@ -35,21 +32,21 @@ void Mempak::LoadMempak(int32_t Control)
bool formatMempak = !MempakPath.Exists(); bool formatMempak = !MempakPath.Exists();
MempakHandle[Control].Open(MempakPath, CFileBase::modeReadWrite | CFileBase::modeNoTruncate | CFileBase::modeCreate); m_MempakHandle[Control].Open(MempakPath, CFileBase::modeReadWrite | CFileBase::modeNoTruncate | CFileBase::modeCreate);
MempakHandle[Control].SeekToBegin(); m_MempakHandle[Control].SeekToBegin();
if (formatMempak) if (formatMempak)
{ {
Mempak::Format(Control); CMempak::Format(Control);
MempakHandle[Control].Write(Mempaks[Control], 0x8000); m_MempakHandle[Control].Write(m_Mempaks[Control], 0x8000);
} }
else else
{ {
MempakHandle[Control].Read(Mempaks[Control], 0x8000); m_MempakHandle[Control].Read(m_Mempaks[Control], 0x8000);
} }
} }
void Mempak::Format(int32_t Control) void CMempak::Format(int32_t Control)
{ {
static const uint8_t Initialize[] = { static const uint8_t Initialize[] = {
0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x81, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
@ -71,16 +68,16 @@ void Mempak::Format(int32_t Control)
0x00, 0x71, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x71, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03,
}; };
memcpy(&Mempaks[Control][0], &Initialize[0], sizeof(Initialize)); memcpy(&m_Mempaks[Control][0], &Initialize[0], sizeof(Initialize));
for (size_t count = sizeof(Initialize); count < 128 * 256; count += 2) for (size_t count = sizeof(Initialize); count < 128 * 256; count += 2)
{ {
Mempaks[Control][count + 0] = 0x00; m_Mempaks[Control][count + 0] = 0x00;
Mempaks[Control][count + 1] = 0x03; m_Mempaks[Control][count + 1] = 0x03;
} }
} }
uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc) uint8_t CMempak::CalculateCrc(uint8_t * DataToCrc)
{ {
uint32_t Count; uint32_t Count;
uint32_t XorTap; uint32_t XorTap;
@ -113,16 +110,16 @@ uint8_t Mempak::CalculateCrc(uint8_t * DataToCrc)
return CRC; return CRC;
} }
void Mempak::ReadFrom(int32_t Control, uint32_t address, uint8_t * data) void CMempak::ReadFrom(int32_t Control, uint32_t address, uint8_t * data)
{ {
if (address < 0x8000) if (address < 0x8000)
{ {
if (!MempakHandle[Control].IsOpen()) if (!m_MempakHandle[Control].IsOpen())
{ {
LoadMempak(Control); LoadMempak(Control);
} }
memcpy(data, &Mempaks[Control][address], 0x20); memcpy(data, &m_Mempaks[Control][address], 0x20);
} }
else else
{ {
@ -131,22 +128,22 @@ void Mempak::ReadFrom(int32_t Control, uint32_t address, uint8_t * data)
} }
} }
void Mempak::WriteTo(int32_t Control, uint32_t address, uint8_t * data) void CMempak::WriteTo(int32_t Control, uint32_t address, uint8_t * data)
{ {
if (address < 0x8000) if (address < 0x8000)
{ {
if (!MempakHandle[Control].IsOpen()) if (!m_MempakHandle[Control].IsOpen())
{ {
LoadMempak(Control); LoadMempak(Control);
} }
memcpy(&Mempaks[Control][address], data, 0x20); memcpy(&m_Mempaks[Control][address], data, 0x20);
MempakHandle[Control].Seek(address, CFile::begin); m_MempakHandle[Control].Seek(address, CFile::begin);
MempakHandle[Control].Write(data, 0x20); m_MempakHandle[Control].Write(data, 0x20);
} }
else else
{ {
/* Rumble pack area */ /* Rumble pack area */
} }
} }

View File

@ -170,28 +170,28 @@ void CPifRam::PifRamWrite()
{ {
case 0x02: case 0x02:
// format the 'challenge' message into 30 nibbles for X-Scale's CIC code // format the 'challenge' message into 30 nibbles for X-Scale's CIC code
{ {
char Challenge[30], Response[30]; char Challenge[30], Response[30];
for (int32_t i = 0; i < 15; i++) for (int32_t i = 0; i < 15; i++)
{ {
Challenge[i * 2] = (m_PifRam[48 + i] >> 4) & 0x0f; Challenge[i * 2] = (m_PifRam[48 + i] >> 4) & 0x0f;
Challenge[i * 2 + 1] = m_PifRam[48 + i] & 0x0f; Challenge[i * 2 + 1] = m_PifRam[48 + i] & 0x0f;
} }
n64_cic_nus_6105(Challenge, Response, CHALLENGE_LENGTH - 2); n64_cic_nus_6105(Challenge, Response, CHALLENGE_LENGTH - 2);
uint64_t ResponseValue = 0; uint64_t ResponseValue = 0;
m_PifRam[46] = m_PifRam[47] = 0x00; m_PifRam[46] = m_PifRam[47] = 0x00;
for (int32_t z = 8; z > 0; z--) for (int32_t z = 8; z > 0; z--)
{ {
ResponseValue = (ResponseValue << 8) | ((Response[(z - 1) * 2] << 4) + Response[(z - 1) * 2 + 1]); ResponseValue = (ResponseValue << 8) | ((Response[(z - 1) * 2] << 4) + Response[(z - 1) * 2 + 1]);
} }
memcpy(&m_PifRam[48], &ResponseValue, sizeof(uint64_t)); memcpy(&m_PifRam[48], &ResponseValue, sizeof(uint64_t));
ResponseValue = 0; ResponseValue = 0;
for (int32_t z = 7; z > 0; z--) for (int32_t z = 7; z > 0; z--)
{ {
ResponseValue = (ResponseValue << 8) | ((Response[((z + 8) - 1) * 2] << 4) + Response[((z + 8) - 1) * 2 + 1]); ResponseValue = (ResponseValue << 8) | ((Response[((z + 8) - 1) * 2] << 4) + Response[((z + 8) - 1) * 2 + 1]);
} }
memcpy(&m_PifRam[56], &ResponseValue, sizeof(uint64_t)); memcpy(&m_PifRam[56], &ResponseValue, sizeof(uint64_t));
} }
break; break;
case 0x08: case 0x08:
m_PifRam[0x3F] = 0; m_PifRam[0x3F] = 0;
@ -330,8 +330,8 @@ void CPifRam::SI_DMA_READ()
{ {
if ((count % 4) == 0) if ((count % 4) == 0)
{ {
HexData[0] = '\0'; HexData[0] = '\0';
AsciiData[0] = '\0'; AsciiData[0] = '\0';
} }
sprintf(Addon, "%02X %02X %02X %02X", sprintf(Addon, "%02X %02X %02X %02X",
m_PifRam[(count << 2) + 0], m_PifRam[(count << 2) + 1], m_PifRam[(count << 2) + 0], m_PifRam[(count << 2) + 1],
@ -417,8 +417,8 @@ void CPifRam::SI_DMA_WRITE()
{ {
if ((count % 4) == 0) if ((count % 4) == 0)
{ {
HexData[0] = '\0'; HexData[0] = '\0';
AsciiData[0] = '\0'; AsciiData[0] = '\0';
} }
sprintf(Addon, "%02X %02X %02X %02X", sprintf(Addon, "%02X %02X %02X %02X",
m_PifRam[(count << 2) + 0], m_PifRam[(count << 2) + 1], m_PifRam[(count << 2) + 0], m_PifRam[(count << 2) + 1],
@ -476,7 +476,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
g_Notify->DisplayError("What am I meant to do with this Controller Command"); g_Notify->DisplayError("What am I meant to do with this Controller Command");
} }
} }
if (Controllers[Control].Present == true) if (Controllers[Control].Present != 0)
{ {
Command[3] = 0x05; Command[3] = 0x05;
Command[4] = 0x00; Command[4] = 0x00;
@ -520,7 +520,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
g_Notify->DisplayError("What am I meant to do with this Controller Command"); g_Notify->DisplayError("What am I meant to do with this Controller Command");
} }
} }
if (Controllers[Control].Present == true) if (Controllers[Control].Present != 0)
{ {
uint32_t address = (Command[3] << 8) | (Command[4] & 0xE0); uint32_t address = (Command[3] << 8) | (Command[4] & 0xE0);
uint8_t* data = &Command[5]; uint8_t* data = &Command[5];
@ -528,7 +528,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
switch (Controllers[Control].Plugin) switch (Controllers[Control].Plugin)
{ {
case PLUGIN_RUMBLE_PAK: Rumblepak::ReadFrom(address, data); break; case PLUGIN_RUMBLE_PAK: Rumblepak::ReadFrom(address, data); break;
case PLUGIN_MEMPAK: Mempak::ReadFrom(Control, address, data); break; case PLUGIN_MEMPAK: g_Mempak->ReadFrom(Control, address, data); break;
case PLUGIN_TANSFER_PAK: Transferpak::ReadFrom(address, data); break; case PLUGIN_TANSFER_PAK: Transferpak::ReadFrom(address, data); break;
case PLUGIN_RAW: if (g_Plugins->Control()->ControllerCommand) { g_Plugins->Control()->ControllerCommand(Control, Command); } break; case PLUGIN_RAW: if (g_Plugins->Control()->ControllerCommand) { g_Plugins->Control()->ControllerCommand(Control, Command); } break;
default: default:
@ -537,7 +537,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
if (Controllers[Control].Plugin != PLUGIN_RAW) if (Controllers[Control].Plugin != PLUGIN_RAW)
{ {
Command[0x25] = Mempak::CalculateCrc(data); Command[0x25] = CMempak::CalculateCrc(data);
} }
} }
else else
@ -568,7 +568,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
switch (Controllers[Control].Plugin) switch (Controllers[Control].Plugin)
{ {
case PLUGIN_MEMPAK: Mempak::WriteTo(Control, address, data); break; case PLUGIN_MEMPAK: g_Mempak->WriteTo(Control, address, data); break;
case PLUGIN_RUMBLE_PAK: Rumblepak::WriteTo(Control, address, data); break; case PLUGIN_RUMBLE_PAK: Rumblepak::WriteTo(Control, address, data); break;
case PLUGIN_TANSFER_PAK: Transferpak::WriteTo(address, data); break; case PLUGIN_TANSFER_PAK: Transferpak::WriteTo(address, data); break;
case PLUGIN_RAW: if (g_Plugins->Control()->ControllerCommand) { g_Plugins->Control()->ControllerCommand(Control, Command); } break; case PLUGIN_RAW: if (g_Plugins->Control()->ControllerCommand) { g_Plugins->Control()->ControllerCommand(Control, Command); } break;
@ -576,7 +576,7 @@ void CPifRam::ProcessControllerCommand(int32_t Control, uint8_t * Command)
if (Controllers[Control].Plugin != PLUGIN_RAW) if (Controllers[Control].Plugin != PLUGIN_RAW)
{ {
Command[0x25] = Mempak::CalculateCrc(data); Command[0x25] = CMempak::CalculateCrc(data);
} }
} }
else else
@ -603,7 +603,7 @@ void CPifRam::ReadControllerCommand(int32_t Control, uint8_t * Command)
switch (Command[2]) switch (Command[2])
{ {
case 0x01: // read controller case 0x01: // read controller
if (Controllers[Control].Present == true) if (Controllers[Control].Present != 0)
{ {
if (bShowPifRamErrors()) if (bShowPifRamErrors())
{ {
@ -615,7 +615,7 @@ void CPifRam::ReadControllerCommand(int32_t Control, uint8_t * Command)
} }
break; break;
case 0x02: //read from controller pack case 0x02: //read from controller pack
if (Controllers[Control].Present == true) if (Controllers[Control].Present != 0)
{ {
switch (Controllers[Control].Plugin) switch (Controllers[Control].Plugin)
{ {
@ -624,7 +624,7 @@ void CPifRam::ReadControllerCommand(int32_t Control, uint8_t * Command)
} }
break; break;
case 0x03: //write controller pak case 0x03: //write controller pak
if (Controllers[Control].Present == true) if (Controllers[Control].Present != 0)
{ {
switch (Controllers[Control].Plugin) switch (Controllers[Control].Plugin)
{ {
@ -647,8 +647,8 @@ void CPifRam::LogControllerPakData(const char * Description)
{ {
if ((count % 4) == 0) if ((count % 4) == 0)
{ {
HexData[0] = '\0'; HexData[0] = '\0';
AsciiData[0] = '\0'; AsciiData[0] = '\0';
} }
sprintf(Addon, "%02X %02X %02X %02X", sprintf(Addon, "%02X %02X %02X %02X",
PIF_Ram[(count << 2) + 0], PIF_Ram[(count << 2) + 1], PIF_Ram[(count << 2) + 0], PIF_Ram[(count << 2) + 1],
@ -680,4 +680,4 @@ void CPifRam::LogControllerPakData(const char * Description)
} }
} }
LogMessage(""); LogMessage("");
} }

View File

@ -31,33 +31,33 @@
#pragma warning(disable:4355) // Disable 'this' : used in base member initializer list #pragma warning(disable:4355) // Disable 'this' : used in base member initializer list
CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) : CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem) :
CSystemEvents(this, Plugins), CSystemEvents(this, Plugins),
m_EndEmulation(false), m_EndEmulation(false),
m_SaveUsing((SAVE_CHIP_TYPE)g_Settings->LoadDword(Game_SaveChip)), m_SaveUsing((SAVE_CHIP_TYPE)g_Settings->LoadDword(Game_SaveChip)),
m_Plugins(Plugins), m_Plugins(Plugins),
m_SyncCPU(NULL), m_SyncCPU(NULL),
m_SyncPlugins(NULL), m_SyncPlugins(NULL),
m_MMU_VM(SavesReadOnly), m_MMU_VM(SavesReadOnly),
m_TLB(this), m_TLB(this),
m_Reg(this, this), m_Reg(this, this),
m_Recomp(NULL), m_Recomp(NULL),
m_InReset(false), m_InReset(false),
m_NextTimer(0), m_NextTimer(0),
m_SystemTimer(m_NextTimer), m_SystemTimer(m_NextTimer),
m_bCleanFrameBox(true), m_bCleanFrameBox(true),
m_bInitialized(false), m_bInitialized(false),
m_RspBroke(true), m_RspBroke(true),
m_DMAUsed(false), m_DMAUsed(false),
m_TestTimer(false), m_TestTimer(false),
m_NextInstruction(0), m_NextInstruction(0),
m_JumpToLocation(0), m_JumpToLocation(0),
m_TLBLoadAddress(0), m_TLBLoadAddress(0),
m_TLBStoreAddress(0), m_TLBStoreAddress(0),
m_SyncCount(0), m_SyncCount(0),
m_thread(NULL), m_thread(NULL),
m_hPauseEvent(true), m_hPauseEvent(true),
m_CheatsSlectionChanged(false), m_CheatsSlectionChanged(false),
m_SyncCpu(SyncSystem) m_SyncCpu(SyncSystem)
{ {
uint32_t gameHertz = g_Settings->LoadDword(Game_ScreenHertz); uint32_t gameHertz = g_Settings->LoadDword(Game_ScreenHertz);
if (gameHertz == 0) if (gameHertz == 0)
@ -73,7 +73,7 @@ CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly, bool SyncSystem)
if (!SyncSystem) if (!SyncSystem)
{ {
uint32_t CpuType = g_Settings->LoadDword(Game_CpuType); uint32_t CpuType = g_Settings->LoadDword(Game_CpuType);
WriteTrace(TraceN64System, TraceDebug, "CpuType = %d",CpuType); WriteTrace(TraceN64System, TraceDebug, "CpuType = %d", CpuType);
if (CpuType == CPU_SyncCores && !g_Settings->LoadBool(Debugger_Enabled)) if (CpuType == CPU_SyncCores && !g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Settings->SaveDword(Game_CpuType, CPU_Recompiler); g_Settings->SaveDword(Game_CpuType, CPU_Recompiler);
@ -483,7 +483,7 @@ bool CN64System::EmulationStarting(CThread * thread)
void CN64System::StartEmulation2(bool NewThread) void CN64System::StartEmulation2(bool NewThread)
{ {
WriteTrace(TraceN64System, TraceDebug, "Start (NewThread: %s)",NewThread ? "true" : "false"); WriteTrace(TraceN64System, TraceDebug, "Start (NewThread: %s)", NewThread ? "true" : "false");
if (NewThread) if (NewThread)
{ {
if (bHaveDebugger()) if (bHaveDebugger())
@ -697,6 +697,7 @@ bool CN64System::SetActiveSystem(bool bActive)
g_MMU = &m_MMU_VM; g_MMU = &m_MMU_VM;
g_TLB = &m_TLB; g_TLB = &m_TLB;
g_Reg = &m_Reg; g_Reg = &m_Reg;
g_Mempak = &m_Mempak;
g_Audio = &m_Audio; g_Audio = &m_Audio;
g_SystemTimer = &m_SystemTimer; g_SystemTimer = &m_SystemTimer;
g_TransVaddr = &m_MMU_VM; g_TransVaddr = &m_MMU_VM;

View File

@ -19,6 +19,7 @@
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h> #include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Mips/SystemEvents.h> #include <Project64-core/N64System/Mips/SystemEvents.h>
#include <Project64-core/N64System/Mips/SystemTiming.h> #include <Project64-core/N64System/Mips/SystemTiming.h>
#include <Project64-core/N64System/Mips/Mempak.h>
#include <Project64-core/Settings/DebugSettings.h> #include <Project64-core/Settings/DebugSettings.h>
#include <Project64-core/Plugin.h> #include <Project64-core/Plugin.h>
#include <Project64-core/Logging.h> #include <Project64-core/Logging.h>
@ -135,6 +136,7 @@ private:
CMipsMemoryVM m_MMU_VM; //Memory of the n64 CMipsMemoryVM m_MMU_VM; //Memory of the n64
CTLB m_TLB; CTLB m_TLB;
CRegisters m_Reg; CRegisters m_Reg;
CMempak m_Mempak;
CFramePerSecond m_FPS; CFramePerSecond m_FPS;
CProfiling m_CPU_Usage; //used to track the cpu usage CProfiling m_CPU_Usage; //used to track the cpu usage
CRecompiler * m_Recomp; CRecompiler * m_Recomp;

View File

@ -31,5 +31,6 @@ uint32_t * g_TLBLoadAddress = NULL;
uint32_t * g_TLBStoreAddress = NULL; uint32_t * g_TLBStoreAddress = NULL;
CDebugger * g_Debugger = NULL; CDebugger * g_Debugger = NULL;
uint8_t ** g_RecompPos = NULL; uint8_t ** g_RecompPos = NULL;
CMempak * g_Mempak = NULL;
int * g_NextTimer; int * g_NextTimer;

View File

@ -60,3 +60,6 @@ __interface CDebugger;
extern CDebugger * g_Debugger; extern CDebugger * g_Debugger;
extern uint8_t ** g_RecompPos; extern uint8_t ** g_RecompPos;
class CMempak;
extern CMempak * g_Mempak;