From 4a635617e6653e419b4baf07503a1ad81c386b03 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 13 Mar 2026 20:52:55 -0500 Subject: [PATCH] AMMediaboard: Add a GetSpanForMediaboardAddress function to eliminate the hardcoded network buffer base addresses. --- Source/Core/Core/HW/DVD/AMMediaboard.cpp | 380 +++++++++++------------ 1 file changed, 179 insertions(+), 201 deletions(-) diff --git a/Source/Core/Core/HW/DVD/AMMediaboard.cpp b/Source/Core/Core/HW/DVD/AMMediaboard.cpp index 60a1cf9554..ad4e091648 100644 --- a/Source/Core/Core/HW/DVD/AMMediaboard.cpp +++ b/Source/Core/Core/HW/DVD/AMMediaboard.cpp @@ -195,6 +195,17 @@ static const MediaBoardRange s_mediaboard_ranges[] = { {AllNetBuffer, 0x1000, s_allnet_buffer}, }; +static std::span GetSpanForMediaboardAddress(u32 address) +{ + for (const auto& range : s_mediaboard_ranges) + { + if (address >= range.start && address < range.end) + return std::span{range.buffer, range.buffer_size}.subspan(address - range.start); + } + + return {}; +} + static const std::unordered_map s_game_map = { {0x4747, FZeroAX}, {0x4841, FZeroAXMonster}, @@ -268,64 +279,18 @@ static GuestSocket GetGuestSocket(SOCKET x) return GuestSocket(it - std::begin(s_sockets)); } -static bool NetworkCMDBufferCheck(u32 offset, u32 length) +static std::string_view GetSafeString(u32 offset, u32 max_length) { - if (offset <= std::size(s_network_command_buffer) && - length <= std::size(s_network_command_buffer) - offset) - { - return true; - } + const auto str_span = GetSpanForMediaboardAddress(offset); - ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid command buffer range: offset={}, length={}", offset, - length); - return false; -} - -static constexpr u8* GetSafePtr(std::span buffer, u32 buffer_base, u32 offset, u32 length) -{ - if (offset >= buffer_base) - { - const u64 off = offset - buffer_base; - if ((off + length) <= buffer.size()) - return std::data(buffer) + off; - } - - if (offset != 0) - { - ERROR_LOG_FMT(AMMEDIABOARD, - "GetSafePtr: buffer[0x{:08x}] base=0x{:08x} offset=0x{:08x} length=0x{:08x}", - buffer.size(), buffer_base, offset, length); - } - - return nullptr; -} - -static constexpr std::string_view GetSafeString(std::span buffer, u32 buffer_base, u32 offset, - u32 max_length) -{ - auto* const ptr = GetSafePtr(buffer, buffer_base, offset, 0); - - if (ptr == nullptr) + if (str_span.empty()) return {}; // Don't exceed max_length or end of buffer. - const auto adjusted_length = - std::min(max_length, buffer.data() + buffer.size() - ptr); - const auto length = strnlen(reinterpret_cast(ptr), adjusted_length); + const auto adjusted_length = std::min(max_length, str_span.size()); + const auto length = strnlen(reinterpret_cast(str_span.data()), adjusted_length); - return {reinterpret_cast(ptr), length}; -} - -static bool NetworkBufferCheck(u32 offset, u32 length) -{ - if (offset <= std::size(s_network_buffer) && length <= std::size(s_network_buffer) - offset) - { - return true; - } - - ERROR_LOG_FMT(AMMEDIABOARD, "GC-AM: Invalid network buffer range: offset={}, length={}", offset, - length); - return false; + return {reinterpret_cast(str_span.data()), length}; } static bool SafeCopyToEmu(Memory::MemoryManager& memory, u32 address, const u8* source, @@ -983,27 +948,22 @@ static u32 NetDIMMBind(GuestSocket guest_socket, const GuestSocketAddress& guest return bind_result; } -static void AMMBCommandRecv(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandRecv(u32 parameter_offset) { const auto fd = GetHostSocket(GuestSocket(s_media_buffer_32[parameter_offset])); - u32 off = s_media_buffer_32[parameter_offset + 1]; - auto len = std::min(s_media_buffer_32[parameter_offset + 2], sizeof(s_network_buffer)); - const u64 off_len = u64(off) + len; + const u32 off = s_media_buffer_32[parameter_offset + 1]; + const u32 len = s_media_buffer_32[parameter_offset + 2]; - if (off >= network_buffer_base && off_len <= network_buffer_base + sizeof(s_network_buffer)) + const auto data_span = GetSpanForMediaboardAddress(off); + if (data_span.size() < len) { - off -= network_buffer_base; - } - else if (off_len > sizeof(s_network_buffer)) - { - ERROR_LOG_FMT(AMMEDIABOARD_NET, - "GC-AM: recv(error) invalid destination or length: off={:08x}, len={}", off, len); - off = 0; - len = 0; + ERROR_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandRecv: Bad data offset or length: off={:08x} len={}", + off, len); + return; } // TODO: Might be blocking depending on the timeout (see SetTimeouts command). - const int ret = recv(fd, reinterpret_cast(s_network_buffer.data() + off), len, 0); + const int ret = recv(fd, reinterpret_cast(data_span.data()), len, 0); const int err = WSAGetLastError(); if (ret < 0 && err != WSAEWOULDBLOCK) @@ -1026,28 +986,23 @@ static void AMMBCommandRecv(u32 parameter_offset, u32 network_buffer_base) s_media_buffer_32[1] = ret; } -static void AMMBCommandSend(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandSend(u32 parameter_offset) { const auto guest_socket = GuestSocket(s_media_buffer_32[parameter_offset]); const auto fd = GetHostSocket(guest_socket); - u32 off = s_media_buffer_32[parameter_offset + 1]; - auto len = std::min(s_media_buffer_32[parameter_offset + 2], sizeof(s_network_buffer)); - const u64 off_len = u64(off) + len; + const u32 off = s_media_buffer_32[parameter_offset + 1]; + const u32 len = s_media_buffer_32[parameter_offset + 2]; - if (off >= network_buffer_base && off_len <= network_buffer_base + sizeof(s_network_buffer)) + const auto data_span = GetSpanForMediaboardAddress(off); + if (data_span.size() < len) { - off -= network_buffer_base; - } - else if (off_len > sizeof(s_network_buffer)) - { - ERROR_LOG_FMT(AMMEDIABOARD_NET, - "GC-AM: send(error) unhandled destination or length: {:08x}, len={}", off, len); - off = 0; - len = 0; + ERROR_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandSend: Bad data offset or length: off={:08x} len={}", + off, len); + return; } // TODO: Might be blocking depending on the timeout (see SetTimeouts command). - const int ret = send(fd, reinterpret_cast(s_network_buffer.data() + off), len, SEND_FLAGS); + const int ret = send(fd, reinterpret_cast(data_span.data()), len, SEND_FLAGS); const int err = WSAGetLastError(); if (ret < 0 && err != WSAEWOULDBLOCK) @@ -1095,7 +1050,7 @@ static void AMMBCommandClosesocket(u32 parameter_offset) s_last_error = SSC_SUCCESS; } -static void AMMBCommandConnect(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandConnect(u32 parameter_offset) { const auto guest_socket = GuestSocket(s_media_buffer_32[parameter_offset + 0]); const u32 addr_offset = s_media_buffer_32[parameter_offset + 1]; @@ -1109,12 +1064,14 @@ static void AMMBCommandConnect(u32 parameter_offset, u32 network_buffer_base) return; } - const auto* addr_ptr = - GetSafePtr(s_network_command_buffer, network_buffer_base, addr_offset, sizeof(addr)); - if (addr_ptr == nullptr) + const auto addr_span = GetSpanForMediaboardAddress(addr_offset); + if (addr_span.size() < sizeof(addr)) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandConnect: Bad address offset: {:08x}", addr_offset); return; + } - memcpy(&addr, addr_ptr, sizeof(addr)); + memcpy(&addr, addr_span.data(), sizeof(addr)); const int ret = NetDIMMConnect(guest_socket, addr); @@ -1122,19 +1079,34 @@ static void AMMBCommandConnect(u32 parameter_offset, u32 network_buffer_base) s_media_buffer_32[1] = ret; } -static void AMMBCommandAccept(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandAccept(u32 parameter_offset) { const auto guest_socket = GuestSocket(s_media_buffer_32[parameter_offset]); const u32 addr_off = s_media_buffer_32[parameter_offset + 1]; const u32 addrlen_off = s_media_buffer_32[parameter_offset + 2]; - auto* const addrlen_ptr = - GetSafePtr(s_network_command_buffer, network_buffer_base, addrlen_off, sizeof(u32)); + const auto addrlen_span = GetSpanForMediaboardAddress(addrlen_off); - auto* const addr_ptr = (addrlen_ptr == nullptr) ? - nullptr : - GetSafePtr(s_network_command_buffer, network_buffer_base, addr_off, - Common::BitCastPtr(addrlen_ptr)); + u8* addr_ptr{}; + u8* addrlen_ptr{}; + + if (addrlen_span.size() >= sizeof(u32)) + { + addrlen_ptr = addrlen_span.data(); + const u32 addrlen = Common::BitCastPtr(addrlen_ptr); + + const auto addr_span = GetSpanForMediaboardAddress(addr_off); + if (addr_span.size() >= addrlen) + { + addr_ptr = addr_span.data(); + } + else + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, + "AMMBCommandAccept: Bad address offset or addrlen: off={:08x} len={}", addr_off, + addrlen); + } + } const auto accept_result = NetDIMMAccept(guest_socket, addr_ptr, addrlen_ptr); @@ -1155,12 +1127,14 @@ static void AMMBCommandBind() return; } - const auto* addr_ptr = - GetSafePtr(s_network_command_buffer, NetworkCommandAddress2, addr_offset, sizeof(guest_addr)); - if (addr_ptr == nullptr) + const auto addr_span = GetSpanForMediaboardAddress(addr_offset); + if (addr_span.size() < sizeof(guest_addr)) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandBind: Bad address offset: {:08x}", addr_offset); return; + } - memcpy(&guest_addr, addr_ptr, sizeof(guest_addr)); + memcpy(&guest_addr, addr_span.data(), sizeof(guest_addr)); const auto bind_result = NetDIMMBind(guest_socket, guest_addr); @@ -1168,15 +1142,22 @@ static void AMMBCommandBind() s_last_error = SSC_SUCCESS; } -// Expects a pointer to a GuestFdSet or nullptr. -static void FillPollFdsFromGuestFdSet(std::span pfds, const void* guest_fds_ptr, +static void FillPollFdsFromGuestFdSet(std::span pfds, u32 guest_fds_offset, short requested_events) { - if (guest_fds_ptr == nullptr) + if (guest_fds_offset == 0) return; GuestFdSet guest_fds; - std::memcpy(&guest_fds, guest_fds_ptr, sizeof(guest_fds)); + + const auto guest_fds_span = GetSpanForMediaboardAddress(guest_fds_offset); + if (guest_fds_span.size() < sizeof(guest_fds)) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "Bad FDSET offset: {:08x}", guest_fds_offset); + return; + } + + std::memcpy(&guest_fds, guest_fds_span.data(), sizeof(guest_fds)); u32 index = 0; for (auto& pfd : pfds) @@ -1192,15 +1173,21 @@ static void FillPollFdsFromGuestFdSet(std::span pfds, const void* gue } } -// Expects a pointer to a GuestFdSet or nullptr. -static void WriteGuestFdSetFromPollFds(void* guest_fds_ptr, std::span fds, +static void WriteGuestFdSetFromPollFds(u32 guest_fds_offset, std::span fds, short returned_events) { - if (guest_fds_ptr == nullptr) + if (guest_fds_offset == 0) return; GuestFdSet guest_fds; + const auto guest_fds_span = GetSpanForMediaboardAddress(guest_fds_offset); + if (guest_fds_span.size() < sizeof(guest_fds)) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "Bad FDSET offset: {:08x}", guest_fds_offset); + return; + } + for (const auto& fd : fds) { if ((fd.revents & returned_events) == 0) @@ -1213,41 +1200,40 @@ static void WriteGuestFdSetFromPollFds(void* guest_fds_ptr, std::span(nfds, std::size(s_sockets)); std::chrono::milliseconds timeout{-1}; - if (guest_timeout_ptr != nullptr) + if (timeout_offset != 0) { - TimeVal guest_timeout; - std::memcpy(&guest_timeout, guest_timeout_ptr, sizeof(guest_timeout)); + const auto guest_timeout_span = GetSpanForMediaboardAddress(timeout_offset); - timeout = duration_cast( - std::chrono::seconds(guest_timeout.seconds) + - std::chrono::microseconds(guest_timeout.microseconds)); + TimeVal guest_timeout; + + if (guest_timeout_span.size() < sizeof(guest_timeout)) + { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "AMMBCommandSelect: Bad timeout offset: {:08x}", + timeout_offset); + } + else + { + std::memcpy(&guest_timeout, guest_timeout_span.data(), sizeof(guest_timeout)); + + timeout = duration_cast( + std::chrono::seconds(guest_timeout.seconds) + + std::chrono::microseconds(guest_timeout.microseconds)); + } } if (timeout < std::chrono::milliseconds{}) @@ -1264,9 +1250,9 @@ static void AMMBCommandSelect(u32 parameter_offset, u32 network_buffer_base) // Fill with the host sockets for each guest socket less-than `nfds` in each GuestFdSet. std::vector pollfds(nfds, WSAPOLLFD{.fd = INVALID_SOCKET}); - FillPollFdsFromGuestFdSet(pollfds, guest_readfds_ptr, POLLIN); - FillPollFdsFromGuestFdSet(pollfds, guest_writefds_ptr, POLLOUT); - FillPollFdsFromGuestFdSet(pollfds, guest_exceptfds_ptr, POLLPRI); + FillPollFdsFromGuestFdSet(pollfds, readfds_offset, POLLIN); + FillPollFdsFromGuestFdSet(pollfds, writefds_offset, POLLOUT); + FillPollFdsFromGuestFdSet(pollfds, exceptfds_offset, POLLPRI); // Erase "INVALID" entries and also entries that weren't in any GuestFdSet. std::erase_if(pollfds, [](const WSAPOLLFD& fd) { return fd.fd == INVALID_SOCKET; }); @@ -1280,9 +1266,9 @@ static void AMMBCommandSelect(u32 parameter_offset, u32 network_buffer_base) if (ret >= 0) { - WriteGuestFdSetFromPollFds(guest_readfds_ptr, pollfds, POLLIN); - WriteGuestFdSetFromPollFds(guest_writefds_ptr, pollfds, POLLOUT); - WriteGuestFdSetFromPollFds(guest_exceptfds_ptr, pollfds, POLLPRI); + WriteGuestFdSetFromPollFds(readfds_offset, pollfds, POLLIN); + WriteGuestFdSetFromPollFds(writefds_offset, pollfds, POLLOUT); + WriteGuestFdSetFromPollFds(exceptfds_offset, pollfds, POLLPRI); DEBUG_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: select result: {}", ret); } else @@ -1295,20 +1281,24 @@ static void AMMBCommandSelect(u32 parameter_offset, u32 network_buffer_base) s_media_buffer_32[1] = ret; } -static void AMMBCommandSetSockOpt(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandSetSockOpt(u32 parameter_offset) { const auto fd = GetHostSocket(GuestSocket(s_media_buffer_32[parameter_offset])); const int level = static_cast(s_media_buffer_32[parameter_offset + 1]); const int optname = static_cast(s_media_buffer_32[parameter_offset + 2]); - const u32 optval_offset = s_media_buffer_32[parameter_offset + 3] - network_buffer_base; - const int optlen = static_cast(s_media_buffer_32[parameter_offset + 4]); + const u32 optval_offset = s_media_buffer_32[parameter_offset + 3]; + const u32 optlen = s_media_buffer_32[parameter_offset + 4]; - if (!NetworkCMDBufferCheck(optval_offset, optlen)) + const auto optval_span = GetSpanForMediaboardAddress(optval_offset); + if (optval_span.size() < optlen) { + ERROR_LOG_FMT(AMMEDIABOARD_NET, + "AMMBCommandSetSockOpt: Bad optval offset or length: off={:08x} len={}", + optval_offset, optlen); return; } - const char* optval = reinterpret_cast(s_network_command_buffer.data() + optval_offset); + const char* optval = reinterpret_cast(optval_span.data()); // TODO: Ensure parameters are compatible with host's setsockopt const int ret = setsockopt(fd, level, optname, optval, optlen); @@ -1321,11 +1311,10 @@ static void AMMBCommandSetSockOpt(u32 parameter_offset, u32 network_buffer_base) s_media_buffer_32[1] = ret; } -static void AMMBCommandModifyMyIPaddr(u32 parameter_offset, u32 network_buffer_base) +static void AMMBCommandModifyMyIPaddr(u32 parameter_offset) { const u32 ip_address_offset = s_media_buffer_32[parameter_offset]; - const auto ip_address_str = GetSafeString(s_network_command_buffer, network_buffer_base, - ip_address_offset, MAX_IPV4_STRING_LENGTH); + const auto ip_address_str = GetSafeString(ip_address_offset, MAX_IPV4_STRING_LENGTH); NOTICE_LOG_FMT(AMMEDIABOARD_NET, "GC-AM: modifyMyIPaddr({})", ip_address_str); @@ -1530,30 +1519,27 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u // Intercept 128-byte read after GetNetworkConfig: serve network config from trinetcfg.bin if (s_netconfig_read_pending && length == 0x80) { - for (const auto& range : s_mediaboard_ranges) + if (!GetSpanForMediaboardAddress(offset).empty()) { - if (offset >= range.start && offset < range.end) + s_netconfig_read_pending = false; + + u8 config[0x80] = {}; + if (s_netcfg.IsOpen()) { - s_netconfig_read_pending = false; - - u8 config[0x80] = {}; - if (s_netcfg.IsOpen()) - { - s_netcfg.Seek(0, File::SeekOrigin::Begin); - s_netcfg.ReadBytes(config, sizeof(config)); - } - - // config[0] is used as a menu table index. Entry 0 is NULL, - // which causes a NULL dereference. Default to 2 (valid entry). - if (config[0] == 0) - config[0] = 2; - - DEBUG_LOG_FMT(AMMEDIABOARD, - "GC-AM: NetConfig Read (intercepted) offset={:08x} config[0]={}", offset, - config[0]); - memory.CopyToEmu(address, config, sizeof(config)); - return 0; + s_netcfg.Seek(0, File::SeekOrigin::Begin); + s_netcfg.ReadBytes(config, sizeof(config)); } + + // config[0] is used as a menu table index. Entry 0 is NULL, + // which causes a NULL dereference. Default to 2 (valid entry). + if (config[0] == 0) + config[0] = 2; + + DEBUG_LOG_FMT(AMMEDIABOARD, + "GC-AM: NetConfig Read (intercepted) offset={:08x} config[0]={}", offset, + config[0]); + memory.CopyToEmu(address, config, sizeof(config)); + return 0; } } @@ -1573,17 +1559,12 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u return 0; } - for (const auto& range : s_mediaboard_ranges) + if (const auto mediaboard_span = GetSpanForMediaboardAddress(offset); !mediaboard_span.empty()) { - if (offset >= range.start && offset < range.end) - { - DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MediaBoard ({:08x},{:08x},{:08x})", offset, - range.start, length); - SafeCopyToEmu(memory, address, range.buffer, range.buffer_size, offset - range.start, - length); - PrintMBBuffer(address, length); - return 0; - } + DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: Read MediaBoard ({:08x},{:08x})", offset, length); + SafeCopyToEmu(memory, address, mediaboard_span.data(), mediaboard_span.size(), 0, length); + PrintMBBuffer(address, length); + return 0; } if (offset == DIMMCommandExecute2) @@ -1652,7 +1633,7 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u break; } case AMMBCommand::Accept: - AMMBCommandAccept(2, NetworkCommandAddress2); + AMMBCommandAccept(2); break; case AMMBCommand::Bind: AMMBCommandBind(); @@ -1661,7 +1642,7 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u AMMBCommandClosesocket(2); break; case AMMBCommand::Connect: - AMMBCommandConnect(2, NetworkCommandAddress2); + AMMBCommandConnect(2); break; case AMMBCommand::InetAddr: { @@ -1697,19 +1678,19 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u break; } case AMMBCommand::Recv: - AMMBCommandRecv(2, NetworkBufferAddress4); + AMMBCommandRecv(2); break; case AMMBCommand::Send: - AMMBCommandSend(2, NetworkBufferAddress3); + AMMBCommandSend(2); break; case AMMBCommand::Socket: AMMBCommandSocket(2); break; case AMMBCommand::Select: - AMMBCommandSelect(2, NetworkCommandAddress2); + AMMBCommandSelect(2); break; case AMMBCommand::SetSockOpt: - AMMBCommandSetSockOpt(2, NetworkCommandAddress2); + AMMBCommandSetSockOpt(2); break; case AMMBCommand::SetTimeOuts: { @@ -1766,7 +1747,7 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u break; } case AMMBCommand::ModifyMyIPaddr: - AMMBCommandModifyMyIPaddr(2, NetworkCommandAddress2); + AMMBCommandModifyMyIPaddr(2); break; case AMMBCommand::GetLastError: { @@ -2038,27 +2019,22 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u } } - for (const auto& range : s_mediaboard_ranges) + if (const auto mediaboard_span = GetSpanForMediaboardAddress(offset); !mediaboard_span.empty()) { - if (offset >= range.start && offset < range.end) + // Persist network config to trinetcfg.bin for SET IP ADDRESS. + // The DMA Write (0x80 bytes) arrives before the corresponding command (0x0204), + // so we detect it here by size and non-zero status byte. + if (length == 0x80 && memory.Read_U8(address) != 0 && s_netcfg.IsOpen()) { - // Persist network config to trinetcfg.bin for SET IP ADDRESS. - // The DMA Write (0x80 bytes) arrives before the corresponding command (0x0204), - // so we detect it here by size and non-zero status byte. - if (length == 0x80 && memory.Read_U8(address) != 0 && s_netcfg.IsOpen()) - { - DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: NetConfig persist to trinetcfg.bin (status={})", - memory.Read_U8(address)); - FileWriteData(memory, &s_netcfg, 0, address, length); - } - - DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MediaBoard ({:08x},{:08x},{:08x})", offset, - range.start, length); - SafeCopyFromEmu(memory, range.buffer, address, range.buffer_size, offset - range.start, - length); - PrintMBBuffer(address, length); - return 0; + DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: NetConfig persist to trinetcfg.bin (status={})", + memory.Read_U8(address)); + FileWriteData(memory, &s_netcfg, 0, address, length); } + + DEBUG_LOG_FMT(AMMEDIABOARD, "GC-AM: Write MediaBoard ({:08x},{:08x})", offset, length); + SafeCopyFromEmu(memory, mediaboard_span.data(), address, mediaboard_span.size(), 0, length); + PrintMBBuffer(address, length); + return 0; } // Max GC disc offset @@ -2149,25 +2125,25 @@ u32 ExecuteCommand(std::array& dicmd_buf, u32* diimm_buf, u32 address, u AMMBCommandClosesocket(10); break; case AMMBCommand::Connect: - AMMBCommandConnect(10, NetworkCommandAddress1); + AMMBCommandConnect(10); break; case AMMBCommand::Recv: - AMMBCommandRecv(10, NetworkBufferAddress5); + AMMBCommandRecv(10); break; case AMMBCommand::Send: - AMMBCommandSend(10, NetworkBufferAddress1); + AMMBCommandSend(10); break; case AMMBCommand::Socket: AMMBCommandSocket(10); break; case AMMBCommand::Select: - AMMBCommandSelect(10, NetworkCommandAddress1); + AMMBCommandSelect(10); break; case AMMBCommand::SetSockOpt: - AMMBCommandSetSockOpt(10, NetworkCommandAddress1); + AMMBCommandSetSockOpt(10); break; case AMMBCommand::ModifyMyIPaddr: - AMMBCommandModifyMyIPaddr(10, NetworkCommandAddress1); + AMMBCommandModifyMyIPaddr(10); break; // Empty reply case AMMBCommand::InitLink: @@ -2214,12 +2190,14 @@ u32 ExecuteCommand(std::array& 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: ({:08x})", addr); - if (!NetworkBufferCheck(off + addr - NetworkBufferAddress2, 0x20)) + const auto data_span = GetSpanForMediaboardAddress(off + addr); + if (data_span.size() < 0x20) { + ERROR_LOG_FMT(AMMEDIABOARD_NET, "SearchDevices: Bad data offset: {:08x}", off + addr); break; } - const u8* const data = s_network_buffer.data() + (off + addr - NetworkBufferAddress2); + const u8* const data = data_span.data(); for (u32 i = 0; i < 0x20; i += 0x10) {