From 3c500d2cf0efb92748462a8ac2feb81388c3766f Mon Sep 17 00:00:00 2001 From: Peter Bonanni Date: Fri, 17 Jul 2026 19:41:38 -0400 Subject: [PATCH] [SystemService] Write notice skip flag as byte (#346) The Gen5 caller supplies a one-byte flag. Preserve pointer and memory-fault behavior while writing only that byte, and cover a seeded guest-memory boundary that rejects the former four-byte write. --- .../SystemService/SystemServiceExports.cs | 4 +-- .../SystemServiceExportsTests.cs | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/SharpEmu.Libs.Tests/SystemService/SystemServiceExportsTests.cs diff --git a/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs b/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs index 260a3c6..8ac5088 100644 --- a/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs +++ b/src/SharpEmu.Libs/SystemService/SystemServiceExports.cs @@ -38,8 +38,8 @@ public static class SystemServiceExports } // No system notice screen to skip in the emulator; report "do not skip". - Span flagBytes = stackalloc byte[sizeof(int)]; - BinaryPrimitives.WriteInt32LittleEndian(flagBytes, 0); + Span flagBytes = stackalloc byte[1]; + flagBytes[0] = 0; return ctx.Memory.TryWrite(flagAddress, flagBytes) ? ctx.SetReturn(0) : ctx.SetReturn((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT); diff --git a/tests/SharpEmu.Libs.Tests/SystemService/SystemServiceExportsTests.cs b/tests/SharpEmu.Libs.Tests/SystemService/SystemServiceExportsTests.cs new file mode 100644 index 0000000..ba1e1df --- /dev/null +++ b/tests/SharpEmu.Libs.Tests/SystemService/SystemServiceExportsTests.cs @@ -0,0 +1,29 @@ +// Copyright (C) 2026 SharpEmu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +using SharpEmu.HLE; +using SharpEmu.Libs.SystemService; +using Xunit; + +namespace SharpEmu.Libs.Tests.SystemService; + +public sealed class SystemServiceExportsTests +{ + private const ulong MemoryBase = 0x1_0000_0000; + + [Fact] + public void GetNoticeScreenSkipFlagWritesOneByteAtMemoryBoundary() + { + var memory = new FakeCpuMemory(MemoryBase, 1); + var context = new CpuContext(memory, Generation.Gen5); + Assert.True(memory.TryWrite(MemoryBase, new byte[] { 0xA5 })); + context[CpuRegister.Rdi] = MemoryBase; + + Assert.Equal(0, SystemServiceExports.SystemServiceGetNoticeScreenSkipFlag(context)); + Assert.Equal(0UL, context[CpuRegister.Rax]); + + Span flag = stackalloc byte[1]; + Assert.True(memory.TryRead(MemoryBase, flag)); + Assert.Equal(0, flag[0]); + } +}