mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Fixed a bug caused by static usage of Core::System::GetInstance()
Removed unused headers Removed unneeded code Optimised code Added sanity checks Added SafeCopyFromEmu/SafeCopyToEmu Set Triforce buttons to be translatable
This commit is contained in:
parent
1ac4c03457
commit
5a87533e42
@ -53,7 +53,6 @@
|
|||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
#include "Core/HW/CPU.h"
|
#include "Core/HW/CPU.h"
|
||||||
#include "Core/HW/DSP.h"
|
#include "Core/HW/DSP.h"
|
||||||
#include "Core/HW/DVD/AMMediaboard.h"
|
|
||||||
#include "Core/HW/EXI/EXI.h"
|
#include "Core/HW/EXI/EXI.h"
|
||||||
#include "Core/HW/GBAPad.h"
|
#include "Core/HW/GBAPad.h"
|
||||||
#include "Core/HW/GCKeyboard.h"
|
#include "Core/HW/GCKeyboard.h"
|
||||||
|
|||||||
@ -90,9 +90,6 @@ static File::IOFile s_dimm;
|
|||||||
|
|
||||||
static Common::UniqueBuffer<u8> s_dimm_disc;
|
static Common::UniqueBuffer<u8> s_dimm_disc;
|
||||||
|
|
||||||
auto& s_system = Core::System::GetInstance();
|
|
||||||
auto& s_memory = s_system.GetMemory();
|
|
||||||
|
|
||||||
static u8 s_firmware[2 * 1024 * 1024];
|
static u8 s_firmware[2 * 1024 * 1024];
|
||||||
static u32 s_media_buffer_32[192];
|
static u32 s_media_buffer_32[192];
|
||||||
static u8* const s_media_buffer = reinterpret_cast<u8*>(s_media_buffer_32);
|
static u8* const s_media_buffer = reinterpret_cast<u8*>(s_media_buffer_32);
|
||||||
@ -107,6 +104,54 @@ constexpr char s_allnet_reply[] = {
|
|||||||
"second=12&place_id=1234&setting=0x123®ion0=jap®ion_name0=japan®ion_name1=usa®ion_"
|
"second=12&place_id=1234&setting=0x123®ion0=jap®ion_name0=japan®ion_name1=usa®ion_"
|
||||||
"name2=asia®ion_name3=export&end"};
|
"name2=asia®ion_name3=export&end"};
|
||||||
|
|
||||||
|
static const MediaBoardRanges s_mediaboard_ranges[] = {
|
||||||
|
{DIMMCommandVersion1, 0x1F900040, s_media_buffer, sizeof(s_media_buffer_32),
|
||||||
|
DIMMCommandVersion1},
|
||||||
|
{DIMMCommandVersion2, 0x84000060, s_media_buffer, sizeof(s_media_buffer_32),
|
||||||
|
DIMMCommandVersion2},
|
||||||
|
{DIMMCommandVersion2_2, 0x89000220, s_media_buffer, sizeof(s_media_buffer_32),
|
||||||
|
DIMMCommandVersion2_2},
|
||||||
|
{NetworkCommandAddress1, NetworkBufferAddress2, s_network_command_buffer,
|
||||||
|
sizeof(s_network_command_buffer), NetworkCommandAddress1},
|
||||||
|
{NetworkCommandAddress2, 0x89060200, s_network_command_buffer, sizeof(s_network_command_buffer),
|
||||||
|
NetworkCommandAddress2},
|
||||||
|
{NetworkBufferAddress1, 0x1FA10000, s_network_buffer, sizeof(s_network_buffer),
|
||||||
|
NetworkBufferAddress1},
|
||||||
|
{NetworkBufferAddress2, 0x1FD10000, s_network_buffer, sizeof(s_network_buffer),
|
||||||
|
NetworkBufferAddress2},
|
||||||
|
{NetworkBufferAddress3, 0x89110000, s_network_buffer, sizeof(s_network_buffer),
|
||||||
|
NetworkBufferAddress3},
|
||||||
|
{NetworkBufferAddress4, 0x89240000, s_network_buffer, sizeof(s_network_buffer),
|
||||||
|
NetworkBufferAddress4},
|
||||||
|
{NetworkBufferAddress5, 0x1FB10000, s_network_buffer, sizeof(s_network_buffer),
|
||||||
|
NetworkBufferAddress5},
|
||||||
|
{AllNetSettings, 0x1F000000, s_allnet_settings, sizeof(s_allnet_settings), AllNetSettings},
|
||||||
|
{AllNetBuffer, 0x89011000, s_allnet_buffer, sizeof(s_allnet_buffer), AllNetBuffer},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::unordered_map<u16, GameType> s_game_map = {{0x4747, FZeroAX},
|
||||||
|
{0x4841, FZeroAXMonster},
|
||||||
|
{0x4B50, MarioKartGP},
|
||||||
|
{0x4B5A, MarioKartGP},
|
||||||
|
{0x4E4A, MarioKartGP2},
|
||||||
|
{0x4E4C, MarioKartGP2},
|
||||||
|
{0x454A, VirtuaStriker3},
|
||||||
|
{0x4559, VirtuaStriker3},
|
||||||
|
{0x4C4A, VirtuaStriker4_2006},
|
||||||
|
{0x4C4B, VirtuaStriker4_2006},
|
||||||
|
{0x4C4C, VirtuaStriker4_2006},
|
||||||
|
{0x484A, VirtuaStriker4},
|
||||||
|
{0x484E, VirtuaStriker4},
|
||||||
|
{0x485A, VirtuaStriker4},
|
||||||
|
{0x4A41, VirtuaStriker4},
|
||||||
|
{0x4A4A, VirtuaStriker4},
|
||||||
|
{0x4658, KeyOfAvalon},
|
||||||
|
{0x4A4E, KeyOfAvalon},
|
||||||
|
{0x4758, GekitouProYakyuu},
|
||||||
|
{0x5342, VirtuaStriker3},
|
||||||
|
{0x3132, VirtuaStriker3},
|
||||||
|
{0x454C, VirtuaStriker3},
|
||||||
|
{0x3030, FirmwareUpdate}};
|
||||||
// Sockets FDs are required to go from 0 to 63.
|
// Sockets FDs are required to go from 0 to 63.
|
||||||
// Games use the FD as indexes so we have to workaround it.
|
// Games use the FD as indexes so we have to workaround it.
|
||||||
|
|
||||||
@ -121,58 +166,75 @@ static u32 SocketCheck(u32 x)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool NetworkCMDBufferCheck(u32 x)
|
static bool NetworkCMDBufferCheck(u32 offset, u32 length)
|
||||||
{
|
{
|
||||||
if (x < std::size(s_network_command_buffer))
|
if (offset <= std::size(s_network_command_buffer) &&
|
||||||
|
length <= std::size(s_network_command_buffer) - offset)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid command network buffer offset:{}", x);
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid command buffer range: offset={}, length={}", offset,
|
||||||
|
length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool NetworkBufferCheck(u32 x)
|
static bool NetworkBufferCheck(u32 offset, u32 length)
|
||||||
{
|
{
|
||||||
if (x < std::size(s_network_buffer))
|
if (offset <= std::size(s_network_buffer) && length <= std::size(s_network_buffer) - offset)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid network buffer offset:{}", x);
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid network buffer range: offset={}, length={}", offset,
|
||||||
|
length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NetworkCMDBufferRead(u32 offset, u32 address, u32 length)
|
static bool SafeCopyToEmu(Memory::MemoryManager& memory, u32 address, const u8* source,
|
||||||
|
u64 source_size, u32 offset, u32 length)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read NETWORK COMMAND BUFFER ({:08x},{})", offset, length);
|
if (offset > source_size || length > source_size - offset)
|
||||||
if (NetworkCMDBufferCheck(offset))
|
|
||||||
{
|
{
|
||||||
s_memory.CopyToEmu(address, s_network_command_buffer + offset, length);
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Read overflow: offset=0x{:08x}, length={}, source_size={}",
|
||||||
|
offset, length, source_size);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void NetworkBufferRead(u32 offset, u32 address, u32 length)
|
auto span = memory.GetSpanForAddress(address);
|
||||||
{
|
if (length > span.size())
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read NETWORK BUFFER ({:08x},{})", offset, length);
|
|
||||||
if (NetworkBufferCheck(offset))
|
|
||||||
{
|
{
|
||||||
s_memory.CopyToEmu(address, s_network_buffer + offset, length);
|
ERROR_LOG_FMT(AMMEDIABOARD,
|
||||||
|
"GC-AM: Memory buffer too small: address=0x{:08x}, length={}, span={}", address,
|
||||||
|
length, span.size());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void NetworkBufferWrite(u32 offset, u32 address, u32 length)
|
memory.CopyToEmu(address, source + offset, length);
|
||||||
{
|
return true;
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write NETWORK BUFFER ({:08x},{})", offset, length);
|
|
||||||
if (NetworkBufferCheck(offset))
|
|
||||||
{
|
|
||||||
s_memory.CopyFromEmu(s_network_buffer + offset, address, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
static bool SafeCopyFromEmu(Memory::MemoryManager& memory, u8* destionation, u32 address,
|
||||||
static void NetworkCMDBufferWrite(u32 offset, u32 address, u32 length)
|
u64 destionation_size, u32 offset, u32 length)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write NETWORK COMMAND BUFFER ({:08x},{})", offset, length);
|
if (offset > destionation_size || length > destionation_size - offset)
|
||||||
if (NetworkCMDBufferCheck(offset))
|
|
||||||
{
|
{
|
||||||
s_memory.CopyFromEmu(s_network_command_buffer + offset, address, length);
|
ERROR_LOG_FMT(AMMEDIABOARD,
|
||||||
|
"GC-AM: Write overflow: offset=0x{:08x}, length={}, destionation_size={}", offset,
|
||||||
|
length, destionation_size);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto span = memory.GetSpanForAddress(address);
|
||||||
|
if (length > span.size())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(AMMEDIABOARD,
|
||||||
|
"GC-AM: Memory buffer too small: address=0x{:08x}, length={}, span={}", address,
|
||||||
|
length, span.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory.CopyFromEmu(destionation + offset, address, length);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SOCKET socket_(int af, int type, int protocol)
|
static SOCKET socket_(int af, int type, int protocol)
|
||||||
@ -209,11 +271,14 @@ static SOCKET accept_(int fd, sockaddr* addr, socklen_t* len)
|
|||||||
|
|
||||||
static inline void PrintMBBuffer(u32 address, u32 length)
|
static inline void PrintMBBuffer(u32 address, u32 length)
|
||||||
{
|
{
|
||||||
|
const auto& system = Core::System::GetInstance();
|
||||||
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
for (u32 i = 0; i < length; i += 0x10)
|
for (u32 i = 0; i < length; i += 0x10)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: {:08x} {:08x} {:08x} {:08x}", s_memory.Read_U32(address + i),
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: {:08x} {:08x} {:08x} {:08x}", memory.Read_U32(address + i),
|
||||||
s_memory.Read_U32(address + i + 4), s_memory.Read_U32(address + i + 8),
|
memory.Read_U32(address + i + 4), memory.Read_U32(address + i + 8),
|
||||||
s_memory.Read_U32(address + i + 12));
|
memory.Read_U32(address + i + 12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +375,7 @@ u8* InitDIMM(u32 size)
|
|||||||
s_dimm_disc.reset(size);
|
s_dimm_disc.reset(size);
|
||||||
if (s_dimm_disc.empty())
|
if (s_dimm_disc.empty())
|
||||||
{
|
{
|
||||||
PanicAlertFmt("Failed to allocate DIMM s_memory.");
|
PanicAlertFmt("Failed to allocate DIMM memory.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,15 +521,43 @@ static s32 NetDIMMConnect(int fd, sockaddr_in* addr, int len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FileWriteData(File::IOFile* file, u32 seek_pos, const u8* data, size_t length)
|
static void FileWriteData(Memory::MemoryManager& memory, File::IOFile* file, u32 seek_pos,
|
||||||
|
u32 address, size_t length)
|
||||||
{
|
{
|
||||||
|
auto span = memory.GetSpanForAddress(address);
|
||||||
|
if (length <= span.size())
|
||||||
|
{
|
||||||
file->Seek(seek_pos, File::SeekOrigin::Begin);
|
file->Seek(seek_pos, File::SeekOrigin::Begin);
|
||||||
file->WriteBytes(data, length);
|
file->WriteBytes(span.data(), length);
|
||||||
file->Flush();
|
file->Flush();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Write overflow: address=0x{:08x}, length={}, span={}",
|
||||||
|
address, length, span.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void FileReadData(Memory::MemoryManager& memory, File::IOFile* file, u32 seek_pos,
|
||||||
|
u32 address, size_t length)
|
||||||
|
{
|
||||||
|
auto span = memory.GetSpanForAddress(address);
|
||||||
|
if (length <= span.size())
|
||||||
|
{
|
||||||
|
file->Seek(seek_pos, File::SeekOrigin::Begin);
|
||||||
|
file->ReadBytes(span.data(), length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Read overflow: address=0x{:08x}, length={}, span={}",
|
||||||
|
address, length, span.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length)
|
u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u32 length)
|
||||||
{
|
{
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
dicmd_buf[0] ^= s_gcam_key_a;
|
dicmd_buf[0] ^= s_gcam_key_a;
|
||||||
dicmd_buf[1] ^= s_gcam_key_b;
|
dicmd_buf[1] ^= s_gcam_key_b;
|
||||||
dicmd_buf[2] ^= s_gcam_key_c;
|
dicmd_buf[2] ^= s_gcam_key_c;
|
||||||
@ -481,12 +574,12 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
|
|
||||||
if (s_gcam_key_a == 0)
|
if (s_gcam_key_a == 0)
|
||||||
{
|
{
|
||||||
if (s_memory.Read_U32(0))
|
if (memory.Read_U32(0))
|
||||||
{
|
{
|
||||||
HLE::Patch(s_system, 0x813048B8, "OSReport");
|
HLE::Patch(system, 0x813048B8, "OSReport");
|
||||||
HLE::Patch(s_system, 0x8130095C, "OSReport"); // Apploader
|
HLE::Patch(system, 0x8130095C, "OSReport"); // Apploader
|
||||||
|
|
||||||
InitKeys(s_memory.Read_U32(0), s_memory.Read_U32(4), s_memory.Read_U32(8));
|
InitKeys(memory.Read_U32(0), memory.Read_U32(4), memory.Read_U32(8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +594,10 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
if (offset == 0x0002440)
|
if (offset == 0x0002440)
|
||||||
{
|
{
|
||||||
// Set by OSResetSystem
|
// Set by OSResetSystem
|
||||||
if (s_memory.Read_U32(0x811FFF00) == 1)
|
if (memory.Read_U32(0x811FFF00) == 1)
|
||||||
{
|
{
|
||||||
// Don't map firmware while in SegaBoot
|
// Don't map firmware while in SegaBoot
|
||||||
if (s_memory.Read_U32(0x8006BF70) != 0x0A536567)
|
if (memory.Read_U32(0x8006BF70) != 0x0A536567)
|
||||||
{
|
{
|
||||||
s_firmware_map = true;
|
s_firmware_map = true;
|
||||||
}
|
}
|
||||||
@ -540,35 +633,35 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case MediaBoardStatus1:
|
case MediaBoardStatus1:
|
||||||
s_memory.Write_U16(1, address);
|
memory.Write_U16(1, address);
|
||||||
break;
|
break;
|
||||||
case MediaBoardStatus2:
|
case MediaBoardStatus2:
|
||||||
s_memory.Memset(address, 0, length);
|
memory.Memset(address, 0, length);
|
||||||
break;
|
break;
|
||||||
case MediaBoardStatus3:
|
case MediaBoardStatus3:
|
||||||
s_memory.Memset(address, 0xFF, length);
|
memory.Memset(address, 0xFF, length);
|
||||||
// DIMM size (512MB)
|
// DIMM size (512MB)
|
||||||
s_memory.Write_U32_Swap(0x20000000, address);
|
memory.Write_U32_Swap(0x20000000, address);
|
||||||
// GCAM signature
|
// GCAM signature
|
||||||
s_memory.Write_U32(0x4743414D, address + 4);
|
memory.Write_U32(0x4743414D, address + 4);
|
||||||
break;
|
break;
|
||||||
case 0x80000100:
|
case 0x80000100:
|
||||||
s_memory.Write_U32_Swap(0x001F1F1F, address);
|
memory.Write_U32_Swap(0x001F1F1F, address);
|
||||||
break;
|
break;
|
||||||
case FirmwareStatus1:
|
case FirmwareStatus1:
|
||||||
s_memory.Write_U32_Swap(0x01FA, address);
|
memory.Write_U32_Swap(0x01FA, address);
|
||||||
break;
|
break;
|
||||||
case FirmwareStatus2:
|
case FirmwareStatus2:
|
||||||
s_memory.Write_U32_Swap(1, address);
|
memory.Write_U32_Swap(1, address);
|
||||||
break;
|
break;
|
||||||
case 0x80000160:
|
case 0x80000160:
|
||||||
s_memory.Write_U32(0x00001E00, address);
|
memory.Write_U32(0x00001E00, address);
|
||||||
break;
|
break;
|
||||||
case 0x80000180:
|
case 0x80000180:
|
||||||
s_memory.Write_U32(0, address);
|
memory.Write_U32(0, address);
|
||||||
break;
|
break;
|
||||||
case 0x800001A0:
|
case 0x800001A0:
|
||||||
s_memory.Write_U32(0xFFFFFFFF, address);
|
memory.Write_U32(0xFFFFFFFF, address);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PrintMBBuffer(address, length);
|
PrintMBBuffer(address, length);
|
||||||
@ -581,109 +674,57 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
// Network configuration
|
// Network configuration
|
||||||
if (offset == 0x00000000 && length == 0x80)
|
if (offset == 0x00000000 && length == 0x80)
|
||||||
{
|
{
|
||||||
s_netcfg.Seek(0, File::SeekOrigin::Begin);
|
FileReadData(memory, &s_netcfg, 0, address, length);
|
||||||
s_netcfg.ReadBytes(s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// media crc check on/off
|
// Media crc check on/off
|
||||||
if (offset == DIMMExtraSettings && length == 0x20)
|
if (offset == DIMMExtraSettings && length == 0x20)
|
||||||
{
|
{
|
||||||
s_extra.Seek(0, File::SeekOrigin::Begin);
|
FileReadData(memory, &s_extra, 0, address, length);
|
||||||
s_extra.ReadBytes(s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIMM s_memory (8MB)
|
// DIMM memory (8MB)
|
||||||
if (offset >= DIMMMemory && offset < 0x1F800000)
|
if (offset >= DIMMMemory && offset < 0x1F800000)
|
||||||
{
|
{
|
||||||
const u32 dimm_offset = offset - DIMMMemory;
|
FileReadData(memory, &s_dimm, offset - DIMMMemory, address, length);
|
||||||
s_dimm.Seek(dimm_offset, File::SeekOrigin::Begin);
|
return 0;
|
||||||
s_dimm.ReadBytes(s_memory.GetSpanForAddress(address).data(), length);
|
}
|
||||||
|
|
||||||
|
// DIMM memory (8MB)
|
||||||
|
if (offset >= DIMMMemory2 && offset < 0xFF800000)
|
||||||
|
{
|
||||||
|
FileReadData(memory, &s_dimm, offset - DIMMMemory2, address, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset == NetworkControl && length == 0x20)
|
||||||
|
{
|
||||||
|
FileReadData(memory, &s_netctrl, 0, address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset >= AllNetBuffer && offset < 0x89011000)
|
if (offset >= AllNetBuffer && offset < 0x89011000)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read All.Net Buffer ({:08x},{})", offset, length);
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read All.Net Buffer ({:08x},{})", offset, length);
|
||||||
|
|
||||||
// Fake reply
|
// Fake reply
|
||||||
s_memory.CopyToEmu(address, s_allnet_reply, sizeof(s_allnet_reply));
|
SafeCopyToEmu(memory, address, (u8*)s_allnet_reply, sizeof(s_allnet_reply),
|
||||||
|
offset - AllNetBuffer, sizeof(s_allnet_reply));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset >= DIMMCommandVersion1 && offset < 0x1F900040 && length == 0x20)
|
for (const auto& range : s_mediaboard_ranges)
|
||||||
{
|
{
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion1;
|
if (offset >= range.start && offset < range.end)
|
||||||
|
{
|
||||||
s_memory.CopyToEmu(address, s_media_buffer + dimm_offset, length);
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MediaBoard ({:08x},{:08x},{:08x})", offset,
|
||||||
|
range.base_offset, length);
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MEDIA BOARD COMM AREA (1) ({:08x},{})", offset,
|
SafeCopyToEmu(memory, address, range.buffer, range.buffer_size, offset - range.base_offset,
|
||||||
length);
|
length);
|
||||||
PrintMBBuffer(address, length);
|
PrintMBBuffer(address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == DIMMCommandVersion2 || offset == DIMMCommandVersion2_1 && length == 0x20)
|
|
||||||
{
|
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion2;
|
|
||||||
s_memory.CopyToEmu(address, s_media_buffer + dimm_offset, length);
|
|
||||||
|
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MEDIA BOARD COMM AREA (2) ({:08x},{})", offset,
|
|
||||||
length);
|
|
||||||
PrintMBBuffer(address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset == DIMMCommandVersion2_2 || offset == DIMMCommandVersion2_2_1 && length == 0x20)
|
|
||||||
{
|
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion2_2;
|
|
||||||
s_memory.CopyToEmu(address, s_media_buffer + dimm_offset, length);
|
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MEDIA BOARD COMM AREA (3) ({:08x})", dimm_offset);
|
|
||||||
PrintMBBuffer(address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress4 && offset < 0x89240000)
|
|
||||||
{
|
|
||||||
NetworkBufferRead(offset - NetworkBufferAddress4, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress5 && offset < 0x1FB10000)
|
|
||||||
{
|
|
||||||
NetworkBufferRead(offset - NetworkBufferAddress5, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkCommandAddress1 && offset < NetworkBufferAddress2)
|
|
||||||
{
|
|
||||||
NetworkCMDBufferRead(offset - NetworkCommandAddress1, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkCommandAddress2 && offset < 0x89060200)
|
|
||||||
{
|
|
||||||
NetworkCMDBufferRead(offset - NetworkCommandAddress2, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress1 && offset < 0x1FA10000)
|
|
||||||
{
|
|
||||||
NetworkBufferRead(offset - NetworkBufferAddress1, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress2 && offset < 0x1FD10000)
|
|
||||||
{
|
|
||||||
NetworkBufferRead(offset - NetworkBufferAddress2, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress3 && offset < 0x89110000)
|
|
||||||
{
|
|
||||||
NetworkBufferRead(offset - NetworkBufferAddress3, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == DIMMCommandExecute2)
|
if (offset == DIMMCommandExecute2)
|
||||||
@ -734,7 +775,8 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
const u32 addr_off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
const u32 addr_off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
||||||
const u32 len_off = s_media_buffer_32[4] - NetworkCommandAddress2;
|
const u32 len_off = s_media_buffer_32[4] - NetworkCommandAddress2;
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(addr_off) || !NetworkCMDBufferCheck(len_off))
|
if (!NetworkCMDBufferCheck(addr_off, sizeof(sockaddr)) ||
|
||||||
|
!NetworkCMDBufferCheck(len_off, sizeof(u32)))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -758,7 +800,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
||||||
const u32 len = s_media_buffer_32[4];
|
const u32 len = s_media_buffer_32[4];
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(off))
|
if (!NetworkCMDBufferCheck(off, len))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -810,7 +852,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
const u32 off = s_media_buffer_32[3] - NetworkCommandAddress2;
|
||||||
const u32 len = s_media_buffer_32[4];
|
const u32 len = s_media_buffer_32[4];
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(off))
|
if (!NetworkCMDBufferCheck(off, len))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -863,22 +905,24 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
case AMMBCommand::Recv:
|
case AMMBCommand::Recv:
|
||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
||||||
const u32 off = s_media_buffer_32[3];
|
u32 off = s_media_buffer_32[3];
|
||||||
const auto len = std::min<u32>(s_media_buffer_32[4], sizeof(s_network_buffer));
|
auto len = std::min<u32>(s_media_buffer_32[4], sizeof(s_network_buffer));
|
||||||
|
|
||||||
u8* buffer = s_network_buffer + off;
|
if (off >= NetworkBufferAddress4 &&
|
||||||
|
off + len <= NetworkBufferAddress4 + sizeof(s_network_buffer))
|
||||||
if (off >= NetworkBufferAddress4 && off < NetworkBufferAddress4 + sizeof(s_network_buffer))
|
|
||||||
{
|
{
|
||||||
buffer = s_network_buffer + off - NetworkBufferAddress4;
|
off -= NetworkBufferAddress4;
|
||||||
}
|
}
|
||||||
else
|
else if (off + len > sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv(error) unhandled destination:{:08x}\n", off);
|
ERROR_LOG_FMT(AMMEDIABOARD_NET,
|
||||||
buffer = s_network_buffer;
|
"GC-AM: recv(error) invalid destination or length: off={:08x}, len={}\n",
|
||||||
|
off, len);
|
||||||
|
off = 0;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ret = recv(fd, reinterpret_cast<char*>(buffer), len, 0);
|
int ret = recv(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
||||||
const int err = WSAGetLastError();
|
const int err = WSAGetLastError();
|
||||||
|
|
||||||
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv( {}, 0x{:08x}, {} ):{} {}\n", fd, off, len,
|
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv( {}, 0x{:08x}, {} ):{} {}\n", fd, off, len,
|
||||||
@ -892,16 +936,20 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
||||||
u32 off = s_media_buffer_32[3];
|
u32 off = s_media_buffer_32[3];
|
||||||
const u32 len = s_media_buffer_32[4];
|
auto len = std::min<u32>(s_media_buffer_32[4], sizeof(s_network_buffer));
|
||||||
|
|
||||||
if (off >= NetworkBufferAddress3 && off < NetworkBufferAddress3 + sizeof(s_network_buffer))
|
if (off >= NetworkBufferAddress3 &&
|
||||||
|
off + len <= NetworkBufferAddress3 + sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
off -= NetworkBufferAddress3;
|
off -= NetworkBufferAddress3;
|
||||||
}
|
}
|
||||||
else
|
else if (off + len > sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: send(error) unhandled destination:{:08x}\n", off);
|
ERROR_LOG_FMT(AMMEDIABOARD_NET,
|
||||||
|
"GC-AM: send(error) unhandled destination or length: {:08x}, len={}", off,
|
||||||
|
len);
|
||||||
off = 0;
|
off = 0;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ret = send(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
const int ret = send(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
||||||
@ -959,7 +1007,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
if (s_media_buffer_32[6] != 0)
|
if (s_media_buffer_32[6] != 0)
|
||||||
{
|
{
|
||||||
const u32 fd_set_offset = s_media_buffer_32[6] - NetworkCommandAddress2;
|
const u32 fd_set_offset = s_media_buffer_32[6] - NetworkCommandAddress2;
|
||||||
if (!NetworkCMDBufferCheck(fd_set_offset + sizeof(fd_set)))
|
if (!NetworkCMDBufferCheck(fd_set_offset, sizeof(fd_set)))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Select(error) unhandled destination:{:08x}\n",
|
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Select(error) unhandled destination:{:08x}\n",
|
||||||
s_media_buffer_32[6]);
|
s_media_buffer_32[6]);
|
||||||
@ -1017,11 +1065,11 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
case AMMBCommand::SetSockOpt:
|
case AMMBCommand::SetSockOpt:
|
||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[2])];
|
||||||
const int level = (int)(s_media_buffer_32[3]);
|
const int level = static_cast<int>(s_media_buffer_32[3]);
|
||||||
const int optname = (int)(s_media_buffer_32[4]);
|
const int optname = static_cast<int>(s_media_buffer_32[4]);
|
||||||
const int optlen = (int)(s_media_buffer_32[6]);
|
const int optlen = static_cast<int>(s_media_buffer_32[6]);
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(s_media_buffer_32[5] - NetworkCommandAddress2 + optlen))
|
if (!NetworkCMDBufferCheck(s_media_buffer_32[5] - NetworkCommandAddress2, optlen))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1097,7 +1145,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
{
|
{
|
||||||
const u32 net_buffer_offset = s_media_buffer_32[2] - NetworkCommandAddress2;
|
const u32 net_buffer_offset = s_media_buffer_32[2] - NetworkCommandAddress2;
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(net_buffer_offset))
|
if (!NetworkCMDBufferCheck(net_buffer_offset, 15))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1134,38 +1182,12 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
|
|
||||||
s_media_buffer[3] |= 0x80; // Command complete flag
|
s_media_buffer[3] |= 0x80; // Command complete flag
|
||||||
|
|
||||||
s_memory.Memset(address, 0, length);
|
memory.Memset(address, 0, length);
|
||||||
|
|
||||||
ExpansionInterface::GenerateInterrupt(0x10);
|
ExpansionInterface::GenerateInterrupt(0x10);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIMM s_memory (8MB)
|
|
||||||
if (offset >= DIMMMemory2 && offset < 0xFF800000)
|
|
||||||
{
|
|
||||||
const u32 dimm_offset = offset - DIMMMemory2;
|
|
||||||
s_dimm.Seek(dimm_offset, File::SeekOrigin::Begin);
|
|
||||||
s_dimm.ReadBytes(s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= AllNetSettings && offset < 0x1F000000)
|
|
||||||
{
|
|
||||||
const u32 allnet_offset = offset - AllNetSettings;
|
|
||||||
if (allnet_offset + length < sizeof(s_allnet_settings))
|
|
||||||
{
|
|
||||||
s_memory.CopyToEmu(address, s_allnet_settings + allnet_offset, length);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset == NetworkControl && length == 0x20)
|
|
||||||
{
|
|
||||||
s_netctrl.Seek(0, File::SeekOrigin::Begin);
|
|
||||||
s_netctrl.ReadBytes(s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max GC disc offset
|
// Max GC disc offset
|
||||||
if (offset >= 0x57058000)
|
if (offset >= 0x57058000)
|
||||||
{
|
{
|
||||||
@ -1175,13 +1197,21 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
|
|
||||||
if (s_firmware_map)
|
if (s_firmware_map)
|
||||||
{
|
{
|
||||||
s_memory.CopyToEmu(address, s_firmware + offset, length);
|
if (!SafeCopyToEmu(memory, address, s_firmware, sizeof(s_firmware), offset, length))
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid firmware buffer range: offset={}, length={}",
|
||||||
|
offset, length);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_dimm_disc.size())
|
if (s_dimm_disc.size())
|
||||||
{
|
{
|
||||||
s_memory.CopyToEmu(address, s_dimm_disc.data() + offset, length);
|
if (!SafeCopyToEmu(memory, address, s_dimm_disc.data(), s_dimm_disc.size(), offset, length))
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid DIMM Disc read from: offset={}, length={}",
|
||||||
|
offset, length);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,11 +1234,11 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
|
|
||||||
if (s_firmware_map)
|
if (s_firmware_map)
|
||||||
{
|
{
|
||||||
// Firmware s_memory (2MB)
|
// Firmware memory (2MB)
|
||||||
if ((offset >= 0x00400000) && (offset <= 0x600000))
|
if ((offset >= 0x00400000) && (offset <= 0x600000))
|
||||||
{
|
{
|
||||||
const u32 fwoffset = offset - 0x00400000;
|
const u32 fwoffset = offset - 0x00400000;
|
||||||
s_memory.CopyFromEmu(s_firmware + fwoffset, address, length);
|
memory.CopyFromEmu(s_firmware + fwoffset, address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1216,101 +1246,59 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
// Network configuration
|
// Network configuration
|
||||||
if (offset == 0x00000000 && length == 0x80)
|
if (offset == 0x00000000 && length == 0x80)
|
||||||
{
|
{
|
||||||
FileWriteData(&s_netcfg, 0, s_memory.GetSpanForAddress(address).data(), length);
|
FileWriteData(memory, &s_netcfg, 0, address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// media crc check on/off
|
// media crc check on/off
|
||||||
if (offset == DIMMExtraSettings && length == 0x20)
|
if (offset == DIMMExtraSettings && length == 0x20)
|
||||||
{
|
{
|
||||||
FileWriteData(&s_extra, 0, s_memory.GetSpanForAddress(address).data(), length);
|
FileWriteData(memory, &s_extra, 0, address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup s_memory (8MB)
|
// Backup memory (8MB)
|
||||||
if (offset >= BackupMemory && offset < 0x00800000)
|
if (offset >= BackupMemory && offset < 0x00800000)
|
||||||
{
|
{
|
||||||
FileWriteData(&s_backup, 0, s_memory.GetSpanForAddress(address).data(), length);
|
FileWriteData(memory, &s_backup, 0, address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIMM s_memory (8MB)
|
// DIMM memory (8MB)
|
||||||
if (offset >= DIMMMemory && offset < 0x1F800000)
|
if (offset >= DIMMMemory && offset < 0x1F800000)
|
||||||
{
|
{
|
||||||
const u32 dimm_offset = offset - DIMMMemory;
|
FileWriteData(memory, &s_dimm, offset - DIMMMemory, address, length);
|
||||||
FileWriteData(&s_dimm, dimm_offset, s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset >= AllNetBuffer && offset < 0x89011000)
|
// Firmware Write
|
||||||
|
if (offset >= FirmwareAddress && offset < 0x84818000)
|
||||||
{
|
{
|
||||||
const u32 allnet_offset = offset - AllNetBuffer;
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write Firmware ({:08x})", offset);
|
||||||
if (allnet_offset + length < sizeof(s_allnet_settings))
|
|
||||||
{
|
|
||||||
s_memory.CopyFromEmu(s_allnet_buffer + allnet_offset, address, length);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkCommandAddress1 && offset < 0x1F801240)
|
|
||||||
{
|
|
||||||
NetworkCMDBufferWrite(offset - NetworkCommandAddress1, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkCommandAddress2 && offset < 0x89060200 && length <= 0x60)
|
|
||||||
{
|
|
||||||
NetworkCMDBufferWrite(offset - NetworkCommandAddress2, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress1 && offset < 0x1FA20000)
|
|
||||||
{
|
|
||||||
NetworkBufferWrite(offset - NetworkBufferAddress1, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress2 && offset < 0x1FD10000)
|
|
||||||
{
|
|
||||||
NetworkBufferWrite(offset - NetworkBufferAddress2, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= NetworkBufferAddress3 && offset < 0x89110000)
|
|
||||||
{
|
|
||||||
NetworkBufferWrite(offset - NetworkBufferAddress3, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset >= DIMMCommandVersion1 && offset < 0x1F900040 && length == 0x20)
|
|
||||||
{
|
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion1;
|
|
||||||
|
|
||||||
s_memory.CopyFromEmu(s_media_buffer + dimm_offset, address, length);
|
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MEDIA BOARD COMM AREA (1) ({:08x},{})", offset,
|
|
||||||
length);
|
|
||||||
PrintMBBuffer(address, length);
|
PrintMBBuffer(address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == DIMMCommandVersion2 || offset == DIMMCommandVersion2_1 && length == 0x20)
|
// DIMM memory (8MB)
|
||||||
|
if (offset >= DIMMMemory2 && offset < 0xFF800000)
|
||||||
{
|
{
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion2;
|
FileWriteData(memory, &s_dimm, offset - DIMMMemory2, address, length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s_memory.CopyFromEmu(s_media_buffer + dimm_offset, address, length);
|
if (offset == NetworkControl && length == 0x20)
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MEDIA BOARD COMM AREA (2) ({:08x},{})", offset,
|
{
|
||||||
length);
|
FileWriteData(memory, &s_netctrl, 0, address, length);
|
||||||
PrintMBBuffer(address, length);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == DIMMCommandExecute1 && length == 0x20)
|
if (offset == DIMMCommandExecute1 && length == 0x20)
|
||||||
{
|
{
|
||||||
if (s_memory.Read_U8(address) == 1)
|
if (memory.Read_U8(address) == 1)
|
||||||
{
|
{
|
||||||
const AMMBCommand ammb_command = Common::BitCastPtr<AMMBCommand>(s_media_buffer + 0x22);
|
const AMMBCommand ammb_command = Common::BitCastPtr<AMMBCommand>(s_media_buffer + 0x22);
|
||||||
|
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Execute command (2):{0:04X}",
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Execute command: (1):{0:04X}",
|
||||||
static_cast<u16>(ammb_command));
|
static_cast<u16>(ammb_command));
|
||||||
|
|
||||||
memset(s_media_buffer, 0, 0x20);
|
memset(s_media_buffer, 0, 0x20);
|
||||||
@ -1365,41 +1353,19 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
ExpansionInterface::GenerateInterrupt(0x04);
|
ExpansionInterface::GenerateInterrupt(0x04);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == DIMMCommandVersion2_2 || offset == DIMMCommandVersion2_2_1 && length == 0x20)
|
for (const auto& range : s_mediaboard_ranges)
|
||||||
{
|
{
|
||||||
const u32 dimm_offset = offset - DIMMCommandVersion2_2;
|
if (offset >= range.start && offset < range.end)
|
||||||
|
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MEDIA BOARD COMM AREA (3) ({:08x},{})", offset,
|
|
||||||
length);
|
|
||||||
PrintMBBuffer(address, length);
|
|
||||||
|
|
||||||
s_memory.CopyFromEmu(s_media_buffer + dimm_offset, address, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Firmware Write
|
|
||||||
if (offset >= FirmwareAddress && offset < 0x84818000)
|
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write Firmware ({:08x})", offset);
|
INFO_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MediaBoard ({:08x},{:08x},{:08x})", offset,
|
||||||
|
range.base_offset, length);
|
||||||
|
SafeCopyFromEmu(memory, range.buffer, address, range.buffer_size,
|
||||||
|
offset - range.base_offset, length);
|
||||||
PrintMBBuffer(address, length);
|
PrintMBBuffer(address, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIMM s_memory (8MB)
|
|
||||||
if (offset >= DIMMMemory2 && offset < 0xFF800000)
|
|
||||||
{
|
|
||||||
const u32 dimm_offset = offset - DIMMMemory2;
|
|
||||||
FileWriteData(&s_dimm, dimm_offset, s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset == NetworkControl && length == 0x20)
|
|
||||||
{
|
|
||||||
FileWriteData(&s_netctrl, 0, s_memory.GetSpanForAddress(address).data(), length);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Max GC disc offset
|
// Max GC disc offset
|
||||||
@ -1481,13 +1447,13 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
// 0x04: Network
|
// 0x04: Network
|
||||||
|
|
||||||
DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: TestHardware: ({:08x})", s_media_buffer_32[11]);
|
DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: TestHardware: ({:08x})", s_media_buffer_32[11]);
|
||||||
// Pointer to a s_memory address that is directly displayed on screen as a string
|
// Pointer to a memory address that is directly displayed on screen as a string
|
||||||
DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: ({:08x})", s_media_buffer_32[12]);
|
DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: ({:08x})", s_media_buffer_32[12]);
|
||||||
|
|
||||||
// On real s_system it shows the status about the DIMM/GD-ROM here
|
// On real systems it shows the status about the DIMM/GD-ROM here
|
||||||
// We just show "TEST OK"
|
// We just show "TEST OK"
|
||||||
s_memory.Write_U32(0x54534554, s_media_buffer_32[12]);
|
memory.Write_U32(0x54534554, s_media_buffer_32[12]);
|
||||||
s_memory.Write_U32(0x004B4F20, s_media_buffer_32[12] + 4);
|
memory.Write_U32(0x004B4F20, s_media_buffer_32[12] + 4);
|
||||||
|
|
||||||
s_media_buffer_32[1] = s_media_buffer_32[9];
|
s_media_buffer_32[1] = s_media_buffer_32[9];
|
||||||
break;
|
break;
|
||||||
@ -1512,7 +1478,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
const u32 off = s_media_buffer_32[11] - NetworkCommandAddress1;
|
const u32 off = s_media_buffer_32[11] - NetworkCommandAddress1;
|
||||||
const u32 len = s_media_buffer_32[12];
|
const u32 len = s_media_buffer_32[12];
|
||||||
|
|
||||||
if (NetworkCMDBufferCheck(off + sizeof(sockaddr_in)))
|
if (NetworkCMDBufferCheck(off, sizeof(sockaddr_in)))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1533,22 +1499,24 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
case AMMBCommand::Recv:
|
case AMMBCommand::Recv:
|
||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
||||||
const u32 off = s_media_buffer_32[11];
|
u32 off = s_media_buffer_32[11];
|
||||||
const auto len = std::min<u32>(s_media_buffer_32[12], sizeof(s_network_buffer));
|
auto len = std::min<u32>(s_media_buffer_32[12], sizeof(s_network_buffer));
|
||||||
|
|
||||||
auto* buffer = s_network_buffer + off;
|
if (off >= NetworkBufferAddress5 &&
|
||||||
|
off + len <= NetworkBufferAddress5 + sizeof(s_network_buffer))
|
||||||
if (off >= NetworkBufferAddress5 && off < NetworkBufferAddress5 + sizeof(s_network_buffer))
|
|
||||||
{
|
{
|
||||||
buffer = s_network_buffer + off - NetworkBufferAddress5;
|
off -= NetworkBufferAddress5;
|
||||||
}
|
}
|
||||||
else
|
else if (off + len > sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv(error) unhandled destination:{:08x}\n", off);
|
ERROR_LOG_FMT(AMMEDIABOARD_NET,
|
||||||
buffer = s_network_buffer;
|
"GC-AM: recv(error) invalid destination or length: off={:08x}, len={}\n",
|
||||||
|
off, len);
|
||||||
|
off = 0;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ret = recv(fd, reinterpret_cast<char*>(buffer), len, 0);
|
int ret = recv(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
||||||
const int err = WSAGetLastError();
|
const int err = WSAGetLastError();
|
||||||
|
|
||||||
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv( {}, 0x{:08x}, {} ):{} {}\n", fd, off, len,
|
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: recv( {}, 0x{:08x}, {} ):{} {}\n", fd, off, len,
|
||||||
@ -1562,16 +1530,20 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
||||||
u32 off = s_media_buffer_32[11];
|
u32 off = s_media_buffer_32[11];
|
||||||
const u32 len = s_media_buffer_32[12];
|
auto len = std::min<u32>(s_media_buffer_32[12], sizeof(s_network_buffer));
|
||||||
|
|
||||||
if (off >= NetworkBufferAddress1 && off < NetworkBufferAddress1 + sizeof(s_network_buffer))
|
if (off >= NetworkBufferAddress1 &&
|
||||||
|
off + len <= NetworkBufferAddress1 + sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
off -= NetworkBufferAddress1;
|
off -= NetworkBufferAddress1;
|
||||||
}
|
}
|
||||||
else
|
else if (off + len > sizeof(s_network_buffer))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: send(error) unhandled destination:{:08x}\n", off);
|
ERROR_LOG_FMT(AMMEDIABOARD_NET,
|
||||||
|
"GC-AM: send(error) unhandled destination or length: {:08x}, len={}", off,
|
||||||
|
len);
|
||||||
off = 0;
|
off = 0;
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ret = send(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
const int ret = send(fd, reinterpret_cast<char*>(s_network_buffer + off), len, 0);
|
||||||
@ -1617,7 +1589,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
if (s_media_buffer_32[14] != 0)
|
if (s_media_buffer_32[14] != 0)
|
||||||
{
|
{
|
||||||
const u32 fd_set_offset = s_media_buffer_32[14] - NetworkCommandAddress1;
|
const u32 fd_set_offset = s_media_buffer_32[14] - NetworkCommandAddress1;
|
||||||
if (!NetworkCMDBufferCheck(fd_set_offset + sizeof(fd_set)))
|
if (!NetworkCMDBufferCheck(fd_set_offset, sizeof(fd_set)))
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Select(error) unhandled destination:{:08x}\n",
|
ERROR_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Select(error) unhandled destination:{:08x}\n",
|
||||||
s_media_buffer_32[14]);
|
s_media_buffer_32[14]);
|
||||||
@ -1665,7 +1637,6 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
"GC-AM: select( {}({}), 0x{:08x} 0x{:08x} 0x{:08x} 0x{:08x} ):{} {} \n", fd,
|
"GC-AM: select( {}({}), 0x{:08x} 0x{:08x} 0x{:08x} 0x{:08x} ):{} {} \n", fd,
|
||||||
s_media_buffer_32[10], s_media_buffer_32[11], s_media_buffer_32[14],
|
s_media_buffer_32[10], s_media_buffer_32[11], s_media_buffer_32[14],
|
||||||
s_media_buffer_32[15], s_media_buffer_32[16], ret, err);
|
s_media_buffer_32[15], s_media_buffer_32[16], ret, err);
|
||||||
// hexdump( NetworkCMDBuffer, 0x40 );
|
|
||||||
|
|
||||||
s_media_buffer[1] = 0;
|
s_media_buffer[1] = 0;
|
||||||
s_media_buffer_32[1] = ret;
|
s_media_buffer_32[1] = ret;
|
||||||
@ -1674,11 +1645,11 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
case AMMBCommand::SetSockOpt:
|
case AMMBCommand::SetSockOpt:
|
||||||
{
|
{
|
||||||
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
const SOCKET fd = s_sockets[SocketCheck(s_media_buffer_32[10])];
|
||||||
const int level = (int)(s_media_buffer_32[11]);
|
const int level = static_cast<int>(s_media_buffer_32[11]);
|
||||||
const int optname = (int)(s_media_buffer_32[12]);
|
const int optname = static_cast<int>(s_media_buffer_32[12]);
|
||||||
const int optlen = (int)(s_media_buffer_32[14]);
|
const int optlen = static_cast<int>(s_media_buffer_32[14]);
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(s_media_buffer_32[13] - NetworkCommandAddress1 + optlen))
|
if (!NetworkCMDBufferCheck(s_media_buffer_32[13] - NetworkCommandAddress1, optlen))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1701,7 +1672,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
{
|
{
|
||||||
const u32 net_buffer_offset = s_media_buffer_32[10] - NetworkCommandAddress1;
|
const u32 net_buffer_offset = s_media_buffer_32[10] - NetworkCommandAddress1;
|
||||||
|
|
||||||
if (!NetworkCMDBufferCheck(net_buffer_offset))
|
if (!NetworkCMDBufferCheck(net_buffer_offset, 15))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1760,7 +1731,7 @@ u32 ExecuteCommand(std::array<u32, 3>& dicmd_buf, u32* diimm_buf, u32 address, u
|
|||||||
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Offset: ({:04x})", off);
|
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: Offset: ({:04x})", off);
|
||||||
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: ({:08x})", addr);
|
NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: ({:08x})", addr);
|
||||||
|
|
||||||
if (!NetworkBufferCheck(off + addr - NetworkBufferAddress2))
|
if (!NetworkBufferCheck(off + addr - NetworkBufferAddress2, 0x20))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1822,15 +1793,12 @@ u32 GetMediaType()
|
|||||||
case GekitouProYakyuu:
|
case GekitouProYakyuu:
|
||||||
case KeyOfAvalon:
|
case KeyOfAvalon:
|
||||||
return GDROM;
|
return GDROM;
|
||||||
break;
|
|
||||||
|
|
||||||
case MarioKartGP:
|
case MarioKartGP:
|
||||||
case MarioKartGP2:
|
case MarioKartGP2:
|
||||||
case FZeroAXMonster:
|
case FZeroAXMonster:
|
||||||
return NAND;
|
return NAND;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Never reached
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is checking for the real game IDs (See boot.id within the game)
|
// This is checking for the real game IDs (See boot.id within the game)
|
||||||
@ -1839,41 +1807,17 @@ u32 GetGameType()
|
|||||||
u16 triforce_id = 0;
|
u16 triforce_id = 0;
|
||||||
const std::string& game_id = SConfig::GetInstance().GetGameID();
|
const std::string& game_id = SConfig::GetInstance().GetGameID();
|
||||||
|
|
||||||
if (game_id.length() > 6)
|
if (game_id.length() == 6)
|
||||||
{
|
|
||||||
triforce_id = 0x3232;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
triforce_id = game_id[1] << 8 | game_id[2];
|
triforce_id = game_id[1] << 8 | game_id[2];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
triforce_id = 0x454A; // Fallback (VirtuaStriker3)
|
||||||
|
}
|
||||||
|
|
||||||
static const std::unordered_map<u16, GameType> game_map = {{0x4747, FZeroAX},
|
auto it = s_game_map.find(triforce_id);
|
||||||
{0x4841, FZeroAXMonster},
|
if (it != s_game_map.end())
|
||||||
{0x4B50, MarioKartGP},
|
|
||||||
{0x4B5A, MarioKartGP},
|
|
||||||
{0x4E4A, MarioKartGP2},
|
|
||||||
{0x4E4C, MarioKartGP2},
|
|
||||||
{0x454A, VirtuaStriker3},
|
|
||||||
{0x4559, VirtuaStriker3},
|
|
||||||
{0x4C4A, VirtuaStriker4_2006},
|
|
||||||
{0x4C4B, VirtuaStriker4_2006},
|
|
||||||
{0x4C4C, VirtuaStriker4_2006},
|
|
||||||
{0x484A, VirtuaStriker4},
|
|
||||||
{0x484E, VirtuaStriker4},
|
|
||||||
{0x485A, VirtuaStriker4},
|
|
||||||
{0x4A41, VirtuaStriker4},
|
|
||||||
{0x4A4A, VirtuaStriker4},
|
|
||||||
{0x4658, KeyOfAvalon},
|
|
||||||
{0x4A4E, KeyOfAvalon},
|
|
||||||
{0x4758, GekitouProYakyuu},
|
|
||||||
{0x5342, VirtuaStriker3},
|
|
||||||
{0x3132, VirtuaStriker3},
|
|
||||||
{0x454C, VirtuaStriker3},
|
|
||||||
{0x3030, FirmwareUpdate}};
|
|
||||||
|
|
||||||
auto it = game_map.find(triforce_id);
|
|
||||||
if (it != game_map.end())
|
|
||||||
{
|
{
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,15 @@ class CPUThreadGuard;
|
|||||||
class System;
|
class System;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
struct MediaBoardRanges
|
||||||
|
{
|
||||||
|
u32 start;
|
||||||
|
u32 end;
|
||||||
|
u8* buffer;
|
||||||
|
size_t buffer_size;
|
||||||
|
u32 base_offset;
|
||||||
|
};
|
||||||
|
|
||||||
namespace AMMediaboard
|
namespace AMMediaboard
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -154,9 +163,7 @@ enum MediaBoardAddress : u32
|
|||||||
|
|
||||||
DIMMCommandVersion1 = 0x1F900000,
|
DIMMCommandVersion1 = 0x1F900000,
|
||||||
DIMMCommandVersion2 = 0x84000000,
|
DIMMCommandVersion2 = 0x84000000,
|
||||||
DIMMCommandVersion2_1 = 0x84000020,
|
|
||||||
DIMMCommandVersion2_2 = 0x89000000,
|
DIMMCommandVersion2_2 = 0x89000000,
|
||||||
DIMMCommandVersion2_2_1 = 0x89000200,
|
|
||||||
DIMMCommandExecute1 = 0x84000040,
|
DIMMCommandExecute1 = 0x84000040,
|
||||||
DIMMCommandExecute2 = 0x88000000,
|
DIMMCommandExecute2 = 0x88000000,
|
||||||
|
|
||||||
|
|||||||
@ -24,9 +24,6 @@
|
|||||||
#include "Core/HW/EXI/EXI_Device.h"
|
#include "Core/HW/EXI/EXI_Device.h"
|
||||||
#include "Core/HW/MMIO.h"
|
#include "Core/HW/MMIO.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/HW/SI/SI.h"
|
|
||||||
#include "Core/HW/SI/SI_Device.h"
|
|
||||||
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
@ -140,9 +137,7 @@ void CEXIBaseboard::DMAWrite(u32 addr, u32 size)
|
|||||||
NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Write: {:08x} {:x}", addr, size);
|
NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Write: {:08x} {:x}", addr, size);
|
||||||
|
|
||||||
m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin);
|
m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin);
|
||||||
|
|
||||||
m_backup.WriteBytes(memory.GetSpanForAddress(addr).data(), size);
|
m_backup.WriteBytes(memory.GetSpanForAddress(addr).data(), size);
|
||||||
|
|
||||||
m_backup.Flush();
|
m_backup.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +149,6 @@ void CEXIBaseboard::DMARead(u32 addr, u32 size)
|
|||||||
NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Read: {:08x} {:x}", addr, size);
|
NOTICE_LOG_FMT(SP1, "AM-BB: COMMAND: Backup DMA Read: {:08x} {:x}", addr, size);
|
||||||
|
|
||||||
m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin);
|
m_backup.Seek(m_backup_offset, File::SeekOrigin::Begin);
|
||||||
|
|
||||||
m_backup.Flush();
|
|
||||||
|
|
||||||
m_backup.ReadBytes(memory.GetSpanForAddress(addr).data(), size);
|
m_backup.ReadBytes(memory.GetSpanForAddress(addr).data(), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +256,6 @@ void CEXIBaseboard::TransferByte(u8& byte)
|
|||||||
{
|
{
|
||||||
// 1 byte out
|
// 1 byte out
|
||||||
case BackupRead:
|
case BackupRead:
|
||||||
m_backup.Flush();
|
|
||||||
m_backup.ReadBytes(&byte, 1);
|
m_backup.ReadBytes(&byte, 1);
|
||||||
break;
|
break;
|
||||||
case DMAOffsetLengthSet:
|
case DMAOffsetLengthSet:
|
||||||
|
|||||||
@ -73,7 +73,7 @@ GCPad::GCPad(const unsigned int index) : m_index(index)
|
|||||||
groups.emplace_back(m_triforce = new ControllerEmu::Buttons(TRIFORCE_GROUP));
|
groups.emplace_back(m_triforce = new ControllerEmu::Buttons(TRIFORCE_GROUP));
|
||||||
for (const char* named_button : {TEST_BUTTON, SERVICE_BUTTON, COIN_BUTTON})
|
for (const char* named_button : {TEST_BUTTON, SERVICE_BUTTON, COIN_BUTTON})
|
||||||
{
|
{
|
||||||
m_triforce->AddInput(Translatability::DoNotTranslate, named_button);
|
m_triforce->AddInput(Translatability::Translate, named_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Microphone
|
// Microphone
|
||||||
|
|||||||
@ -56,7 +56,7 @@ public:
|
|||||||
void RemoveEvent(int device_number);
|
void RemoveEvent(int device_number);
|
||||||
|
|
||||||
void UpdateDevices();
|
void UpdateDevices();
|
||||||
u32 GetInLength(void) const { return m_com_csr.INLNGTH; }
|
u32 GetInLength() const { return m_com_csr.INLNGTH; }
|
||||||
|
|
||||||
void RemoveDevice(int device_number);
|
void RemoveDevice(int device_number);
|
||||||
void AddDevice(SIDevices device, int device_number);
|
void AddDevice(SIDevices device, int device_number);
|
||||||
|
|||||||
@ -44,15 +44,15 @@ namespace SerialInterface
|
|||||||
|
|
||||||
void JVSIOMessage::Start(int node)
|
void JVSIOMessage::Start(int node)
|
||||||
{
|
{
|
||||||
m_last_start = m_ptr;
|
m_last_start = m_pointer;
|
||||||
const u8 hdr[3] = {0xE0, (u8)node, 0};
|
const u8 header[3] = {0xE0, (u8)node, 0};
|
||||||
m_csum = 0;
|
m_checksum = 0;
|
||||||
AddData(hdr, 3, 1);
|
AddData(header, 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVSIOMessage::AddData(const u8* dst, size_t len, int sync = 0)
|
void JVSIOMessage::AddData(const u8* dst, size_t len, int sync = 0)
|
||||||
{
|
{
|
||||||
if (m_ptr + len >= 0x80)
|
if (m_pointer + len >= sizeof(m_message))
|
||||||
{
|
{
|
||||||
PanicAlertFmt("JVSIOMessage overrun!");
|
PanicAlertFmt("JVSIOMessage overrun!");
|
||||||
return;
|
return;
|
||||||
@ -63,16 +63,26 @@ void JVSIOMessage::AddData(const u8* dst, size_t len, int sync = 0)
|
|||||||
const u8 c = *dst++;
|
const u8 c = *dst++;
|
||||||
if (!sync && ((c == 0xE0) || (c == 0xD0)))
|
if (!sync && ((c == 0xE0) || (c == 0xD0)))
|
||||||
{
|
{
|
||||||
m_msg[m_ptr++] = 0xD0;
|
if (m_pointer + 2 > sizeof(m_message))
|
||||||
m_msg[m_ptr++] = c - 1;
|
{
|
||||||
|
PanicAlertFmt("JVSIOMessage overrun!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_message[m_pointer++] = 0xD0;
|
||||||
|
m_message[m_pointer++] = c - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_msg[m_ptr++] = c;
|
if (m_pointer >= sizeof(m_message))
|
||||||
|
{
|
||||||
|
PanicAlertFmt("JVSIOMessage overrun!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_message[m_pointer++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sync)
|
if (!sync)
|
||||||
m_csum += c;
|
m_checksum += c;
|
||||||
sync = 0;
|
sync = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,9 +105,16 @@ void JVSIOMessage::AddData(u32 n)
|
|||||||
|
|
||||||
void JVSIOMessage::End()
|
void JVSIOMessage::End()
|
||||||
{
|
{
|
||||||
const u32 len = m_ptr - m_last_start;
|
const u32 len = m_pointer - m_last_start;
|
||||||
m_msg[m_last_start + 2] = len - 2; // assuming len <0xD0
|
if (m_last_start + 2 < sizeof(m_message) && len >= 3)
|
||||||
AddData(m_csum + len - 2);
|
{
|
||||||
|
m_message[m_last_start + 2] = len - 2; // assuming len <0xD0
|
||||||
|
AddData(m_checksum + len - 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PanicAlertFmt("JVSIOMessage: Not enough space for checksum!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 CheckSumXOR(u8* data, u32 length)
|
static u8 CheckSumXOR(u8* data, u32 length)
|
||||||
@ -2095,8 +2112,8 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length)
|
|||||||
|
|
||||||
data_out[data_offset++] = gcam_command;
|
data_out[data_offset++] = gcam_command;
|
||||||
|
|
||||||
const u8* buf = message.m_msg.data();
|
const u8* buf = message.m_message.data();
|
||||||
const u32 len = message.m_ptr;
|
const u32 len = message.m_pointer;
|
||||||
data_out[data_offset++] = len;
|
data_out[data_offset++] = len;
|
||||||
|
|
||||||
for (u32 i = 0; i < len; ++i)
|
for (u32 i = 0; i < len; ++i)
|
||||||
|
|||||||
@ -26,12 +26,12 @@ public:
|
|||||||
void AddData(u32 n);
|
void AddData(u32 n);
|
||||||
void End();
|
void End();
|
||||||
|
|
||||||
u32 m_ptr = 0;
|
u32 m_pointer = 0;
|
||||||
std::array<u8, 0x80> m_msg;
|
std::array<u8, 0x80> m_message;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 m_last_start = 0;
|
u32 m_last_start = 0;
|
||||||
u32 m_csum = 0;
|
u32 m_checksum = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Triforce (GC-AM) baseboard
|
// Triforce (GC-AM) baseboard
|
||||||
|
|||||||
@ -31,41 +31,24 @@ std::string VolumeDisc::GetGameID(const Partition& partition) const
|
|||||||
|
|
||||||
memcpy(id + 1, boot_id->game_id.data() + 2, 2);
|
memcpy(id + 1, boot_id->game_id.data() + 2, 2);
|
||||||
|
|
||||||
switch (boot_id->region_flags)
|
switch (GetCountry())
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case 0x02: // JAPAN
|
case Country::Japan:
|
||||||
id[3] = 'J';
|
id[3] = 'J';
|
||||||
break;
|
break;
|
||||||
case 0x08: // ASIA
|
case Country::Taiwan:
|
||||||
id[3] = 'W';
|
id[3] = 'W';
|
||||||
break;
|
break;
|
||||||
case 0x0E: // USA
|
case Country::USA:
|
||||||
id[3] = 'E';
|
id[3] = 'E';
|
||||||
break;
|
break;
|
||||||
case 0x0C: // EXPORT
|
case Country::Europe:
|
||||||
id[3] = 'P';
|
id[3] = 'P';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There only seem to be three different makers here,
|
memcpy(id + 4, GetMakerID().c_str(), 2);
|
||||||
// so we can just check the first char to difference between them.
|
|
||||||
//
|
|
||||||
// NAMCO CORPORATION, SEGA CORPORATION and Hitmaker co,ltd.
|
|
||||||
|
|
||||||
switch (boot_id->manufacturer[0])
|
|
||||||
{
|
|
||||||
case 'N': // NAMCO CORPORATION
|
|
||||||
id[4] = '8';
|
|
||||||
id[5] = '2';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case 'H': // Hitmaker co,ltd.
|
|
||||||
case 'S': // SEGA CORPORATION
|
|
||||||
id[4] = '6';
|
|
||||||
id[5] = 'E';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DecodeString(id);
|
return DecodeString(id);
|
||||||
}
|
}
|
||||||
@ -134,6 +117,11 @@ std::string VolumeDisc::GetMakerID(const Partition& partition) const
|
|||||||
{
|
{
|
||||||
const BootID* boot_id = static_cast<const VolumeGC*>(this)->GetTriforceBootID();
|
const BootID* boot_id = static_cast<const VolumeGC*>(this)->GetTriforceBootID();
|
||||||
|
|
||||||
|
// There only seem to be three different makers here,
|
||||||
|
// so we can just check the first char to difference between them.
|
||||||
|
//
|
||||||
|
// NAMCO CORPORATION, SEGA CORPORATION and Hitmaker co,ltd.
|
||||||
|
|
||||||
switch (boot_id->manufacturer[0])
|
switch (boot_id->manufacturer[0])
|
||||||
{
|
{
|
||||||
case 'S': // SEGA CORPORATION
|
case 'S': // SEGA CORPORATION
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user