diff --git a/Source/Project64-core/N64System/Mips/Eeprom.cpp b/Source/Project64-core/N64System/Mips/Eeprom.cpp index 886137b88..8982d25b5 100644 --- a/Source/Project64-core/N64System/Mips/Eeprom.cpp +++ b/Source/Project64-core/N64System/Mips/Eeprom.cpp @@ -1,202 +1,199 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#include "stdafx.h" -#include -#include -#include -#include -#include - -CEeprom::CEeprom(bool ReadOnly) : -m_ReadOnly(ReadOnly), -m_hFile(NULL) -{ - memset(m_EEPROM, 0xFF, sizeof(m_EEPROM)); -} - -CEeprom::~CEeprom() -{ - if (m_hFile) - { - CloseHandle(m_hFile); - m_hFile = NULL; - } -} - -uint8_t byte2bcd(int32_t n) -{ - n %= 100; - return (uint8_t)(((n / 10) << 4) | (n % 10)); -} - -void CEeprom::EepromCommand(uint8_t * Command) -{ - time_t curtime_time; - struct tm curtime; - - if (g_System->m_SaveUsing == SaveChip_Auto) - { - g_System->m_SaveUsing = SaveChip_Eeprom_4K; - } - - switch (Command[2]) - { - case 0: // check - if (g_System->m_SaveUsing != SaveChip_Eeprom_4K && g_System->m_SaveUsing != SaveChip_Eeprom_16K) - { - Command[1] |= 0x80; - break; - } - if (Command[1] != 3) - { - Command[1] |= 0x40; - if ((Command[1] & 3) > 0) - Command[3] = 0x00; - if ((Command[1] & 3) > 1) - Command[4] = (g_System->m_SaveUsing == SaveChip_Eeprom_4K) ? 0x80 : 0xC0; - if ((Command[1] & 3) > 2) - Command[5] = 0x00; - } - else - { - Command[3] = 0x00; - Command[4] = g_System->m_SaveUsing == SaveChip_Eeprom_4K ? 0x80 : 0xC0; - Command[5] = 0x00; - } - break; - case 4: // Read from Eeprom - if (Command[0] != 2 && bHaveDebugger()) - { - g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); - } - if (Command[1] != 8 && bHaveDebugger()) - { - g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); - } - ReadFrom(&Command[4], Command[3]); - break; - case 5: //Write to Eeprom - if (Command[0] != 10 && bHaveDebugger()) - { - g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); - } - if (Command[1] != 1 && bHaveDebugger()) - { - g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); - } - WriteTo(&Command[4], Command[3]); - break; - case 6: //RTC Status query - Command[3] = 0x00; - Command[4] = 0x10; - Command[5] = 0x00; - break; - case 7: //Read RTC block - switch (Command[3]) - { - case 0: //Block number - Command[4] = 0x00; - Command[5] = 0x02; - Command[12] = 0x00; - break; - case 1: - //read block, Command[2], Unimplemented - break; - case 2: //Set RTC Time - time(&curtime_time); - memcpy(&curtime, localtime(&curtime_time), sizeof(curtime)); // fd's fix - Command[4] = byte2bcd(curtime.tm_sec); - Command[5] = byte2bcd(curtime.tm_min); - Command[6] = 0x80 + byte2bcd(curtime.tm_hour); - Command[7] = byte2bcd(curtime.tm_mday); - Command[8] = byte2bcd(curtime.tm_wday); - Command[9] = byte2bcd(curtime.tm_mon + 1); - Command[10] = byte2bcd(curtime.tm_year); - Command[11] = byte2bcd(curtime.tm_year / 100); - Command[12] = 0x00; // status - break; - } - break; - case 8: - //Write RTC, unimplemented - if (g_Settings->LoadDword(Debugger_ShowPifErrors)) - { - g_Notify->DisplayError("Write RTC, unimplemented"); - } - break; - default: - if (g_Settings->LoadDword(Debugger_ShowPifErrors)) - { - g_Notify->DisplayError(stdstr_f("Unknown EepromCommand %d", Command[2]).c_str()); - } - } -} - -void CEeprom::LoadEeprom() -{ - CPath FileName; - DWORD dwRead; - - memset(m_EEPROM, 0xFF, sizeof(m_EEPROM)); - - FileName.SetDriveDirectory(g_Settings->LoadStringVal(Directory_NativeSave).c_str()); - FileName.SetName(g_Settings->LoadStringVal(Game_GameName).c_str()); - FileName.SetExtension("eep"); - - if (!FileName.DirectoryExists()) - { - FileName.DirectoryCreate(); - } - - m_hFile = CreateFile(FileName, m_ReadOnly ? GENERIC_READ : GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); - if (m_hFile == INVALID_HANDLE_VALUE) - { - WriteTrace(TraceN64System, TraceError, "Failed to open (%s), ReadOnly = %d, LastError = %X", (LPCTSTR)FileName, m_ReadOnly, GetLastError()); - g_Notify->DisplayError(GS(MSG_FAIL_OPEN_EEPROM)); - return; - } - SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); - ReadFile(m_hFile, m_EEPROM, sizeof(m_EEPROM), &dwRead, NULL); -} - -void CEeprom::ReadFrom(uint8_t * Buffer, int32_t line) -{ - int32_t i; - - if (m_hFile == NULL) - { - LoadEeprom(); - } - - for (i = 0; i < 8; i++) - { - Buffer[i] = m_EEPROM[line * 8 + i]; - } -} - -void CEeprom::WriteTo(uint8_t * Buffer, int32_t line) -{ - DWORD dwWritten; - int32_t i; - - if (m_hFile == NULL) - { - LoadEeprom(); - } - for (i = 0; i < 8; i++) - { - m_EEPROM[line * 8 + i] = Buffer[i]; - } - SetFilePointer(m_hFile, line * 8, NULL, FILE_BEGIN); - WriteFile(m_hFile, Buffer, 8, &dwWritten, NULL); - FlushFileBuffers(m_hFile); +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#include "stdafx.h" +#include +#include +#include +#include + +CEeprom::CEeprom(bool ReadOnly) : +m_ReadOnly(ReadOnly) +{ + memset(m_EEPROM, 0xFF, sizeof(m_EEPROM)); +} + +CEeprom::~CEeprom() +{ +} + +uint8_t byte2bcd(int32_t n) +{ + n %= 100; + return (uint8_t)(((n / 10) << 4) | (n % 10)); +} + +void CEeprom::EepromCommand(uint8_t * Command) +{ + time_t curtime_time; + struct tm curtime; + + if (g_System->m_SaveUsing == SaveChip_Auto) + { + g_System->m_SaveUsing = SaveChip_Eeprom_4K; + } + + switch (Command[2]) + { + case 0: // check + if (g_System->m_SaveUsing != SaveChip_Eeprom_4K && g_System->m_SaveUsing != SaveChip_Eeprom_16K) + { + Command[1] |= 0x80; + break; + } + if (Command[1] != 3) + { + Command[1] |= 0x40; + if ((Command[1] & 3) > 0) + { + Command[3] = 0x00; + } + if ((Command[1] & 3) > 1) + { + Command[4] = (g_System->m_SaveUsing == SaveChip_Eeprom_4K) ? 0x80 : 0xC0; + } + if ((Command[1] & 3) > 2) + { + Command[5] = 0x00; + } + } + else + { + Command[3] = 0x00; + Command[4] = g_System->m_SaveUsing == SaveChip_Eeprom_4K ? 0x80 : 0xC0; + Command[5] = 0x00; + } + break; + case 4: // Read from Eeprom + if (Command[0] != 2 && bHaveDebugger()) + { + g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); + } + if (Command[1] != 8 && bHaveDebugger()) + { + g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); + } + ReadFrom(&Command[4], Command[3]); + break; + case 5: //Write to Eeprom + if (Command[0] != 10 && bHaveDebugger()) + { + g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); + } + if (Command[1] != 1 && bHaveDebugger()) + { + g_Notify->DisplayError("What am I meant to do with this Eeprom Command"); + } + WriteTo(&Command[4], Command[3]); + break; + case 6: //RTC Status query + Command[3] = 0x00; + Command[4] = 0x10; + Command[5] = 0x00; + break; + case 7: //Read RTC block + switch (Command[3]) + { + case 0: //Block number + Command[4] = 0x00; + Command[5] = 0x02; + Command[12] = 0x00; + break; + case 1: + //read block, Command[2], Unimplemented + break; + case 2: //Set RTC Time + time(&curtime_time); + memcpy(&curtime, localtime(&curtime_time), sizeof(curtime)); // fd's fix + Command[4] = byte2bcd(curtime.tm_sec); + Command[5] = byte2bcd(curtime.tm_min); + Command[6] = 0x80 + byte2bcd(curtime.tm_hour); + Command[7] = byte2bcd(curtime.tm_mday); + Command[8] = byte2bcd(curtime.tm_wday); + Command[9] = byte2bcd(curtime.tm_mon + 1); + Command[10] = byte2bcd(curtime.tm_year); + Command[11] = byte2bcd(curtime.tm_year / 100); + Command[12] = 0x00; // status + break; + } + break; + case 8: + //Write RTC, unimplemented + if (g_Settings->LoadDword(Debugger_ShowPifErrors)) + { + g_Notify->DisplayError("Write RTC, unimplemented"); + } + break; + default: + if (g_Settings->LoadDword(Debugger_ShowPifErrors)) + { + g_Notify->DisplayError(stdstr_f("Unknown EepromCommand %d", Command[2]).c_str()); + } + } +} + +void CEeprom::LoadEeprom() +{ + memset(m_EEPROM, 0xFF, sizeof(m_EEPROM)); + + CPath FileName(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), ""); + FileName.SetName(g_Settings->LoadStringVal(Game_GameName).c_str()); + FileName.SetExtension("eep"); + + if (!FileName.DirectoryExists()) + { + FileName.DirectoryCreate(); + } + + if (!m_File.Open(FileName, (m_ReadOnly ? CFileBase::modeRead : CFileBase::modeReadWrite) | CFileBase::modeNoTruncate | CFileBase::modeCreate)) + { +#ifdef _WIN32 + WriteTrace(TraceN64System, TraceError, "Failed to open (%s), ReadOnly = %d, LastError = %X", (const char *)FileName, m_ReadOnly, GetLastError()); +#else + WriteTrace(TraceN64System, TraceError, "Failed to open (%s), ReadOnly = %d", (const char *)FileName, m_ReadOnly); +#endif + g_Notify->DisplayError(GS(MSG_FAIL_OPEN_EEPROM)); + return; + } + m_File.SeekToBegin(); + m_File.Read(m_EEPROM, sizeof(m_EEPROM)); +} + +void CEeprom::ReadFrom(uint8_t * Buffer, int32_t line) +{ + int32_t i; + + if (!m_File.IsOpen()) + { + LoadEeprom(); + } + + for (i = 0; i < 8; i++) + { + Buffer[i] = m_EEPROM[line * 8 + i]; + } +} + +void CEeprom::WriteTo(uint8_t * Buffer, int32_t line) +{ + int32_t i; + + if (!m_File.IsOpen()) + { + LoadEeprom(); + } + for (i = 0; i < 8; i++) + { + m_EEPROM[line * 8 + i] = Buffer[i]; + } + m_File.Seek(line * 8, CFile::begin); + m_File.Write(Buffer, 8); + m_File.Flush(); } \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/Eeprom.h b/Source/Project64-core/N64System/Mips/Eeprom.h index 192c3a590..2fb633854 100644 --- a/Source/Project64-core/N64System/Mips/Eeprom.h +++ b/Source/Project64-core/N64System/Mips/Eeprom.h @@ -1,35 +1,35 @@ -/**************************************************************************** -* * -* Project64 - A Nintendo 64 emulator. * -* http://www.pj64-emu.com/ * -* Copyright (C) 2012 Project64. All rights reserved. * -* * -* License: * -* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * -* * -****************************************************************************/ -#pragma once -#include - -class CEeprom : - private CDebugSettings -{ -public: - CEeprom(bool ReadOnly); - ~CEeprom(); - - void EepromCommand(uint8_t * Command); - -private: - CEeprom(void); // Disable default constructor - CEeprom(const CEeprom&); // Disable copy constructor - CEeprom& operator=(const CEeprom&); // Disable assignment - - void LoadEeprom(); - void ReadFrom(uint8_t * Buffer, int32_t line); - void WriteTo(uint8_t * Buffer, int32_t line); - - uint8_t m_EEPROM[0x800]; - bool m_ReadOnly; - void * m_hFile; -}; +/**************************************************************************** +* * +* Project64 - A Nintendo 64 emulator. * +* http://www.pj64-emu.com/ * +* Copyright (C) 2012 Project64. All rights reserved. * +* * +* License: * +* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * +* * +****************************************************************************/ +#pragma once +#include + +class CEeprom : + private CDebugSettings +{ +public: + CEeprom(bool ReadOnly); + ~CEeprom(); + + void EepromCommand(uint8_t * Command); + +private: + CEeprom(void); // Disable default constructor + CEeprom(const CEeprom&); // Disable copy constructor + CEeprom& operator=(const CEeprom&); // Disable assignment + + void LoadEeprom(); + void ReadFrom(uint8_t * Buffer, int32_t line); + void WriteTo(uint8_t * Buffer, int32_t line); + + uint8_t m_EEPROM[0x800]; + bool m_ReadOnly; + CFile m_File; +};