From 27459d0e400bc7c157a6f870801d9650609970e8 Mon Sep 17 00:00:00 2001 From: "Eric P. Nusbaum" Date: Sat, 30 Dec 2023 11:54:43 -0500 Subject: [PATCH] Fix for SKPWRD - Fixes a bug with `SKPWRD` where it wouldn't properly skip a word where the final character (`/0`) was at offer `0xFFFF` - Added Unit Tests to `skpwrd_Tests.cs` to test for this specific scenario --- .../ExportedModules/ExportedModuleTestBase.cs | 8 ++-- .../ExportedModules/Majorbbs/skpwrd_Tests.cs | 37 +++++++++++++++++++ .../HostProcess/ExportedModules/Majorbbs.cs | 2 +- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/MBBSEmu.Tests/ExportedModules/ExportedModuleTestBase.cs b/MBBSEmu.Tests/ExportedModules/ExportedModuleTestBase.cs index 6aaf0773..23122e00 100644 --- a/MBBSEmu.Tests/ExportedModules/ExportedModuleTestBase.cs +++ b/MBBSEmu.Tests/ExportedModules/ExportedModuleTestBase.cs @@ -23,9 +23,11 @@ namespace MBBSEmu.Tests.ExportedModules { public abstract class ExportedModuleTestBase : TestBase, IDisposable { - // list of ordinals that use the __stdcall convention, which means the callee cleans up the - // stack. - // __cdecl convention has the caller cleaning up the stack. + /// + /// List of ordinals that use the __stdcall convention, which means the callee cleans up the stack. + /// + /// __cdecl convention has the caller cleaning up the stack. + /// private static readonly HashSet STDCALL_ORDINALS = new HashSet { 654, // f_ldiv 656, // f_ludiv diff --git a/MBBSEmu.Tests/ExportedModules/Majorbbs/skpwrd_Tests.cs b/MBBSEmu.Tests/ExportedModules/Majorbbs/skpwrd_Tests.cs index 5f030337..509721b4 100644 --- a/MBBSEmu.Tests/ExportedModules/Majorbbs/skpwrd_Tests.cs +++ b/MBBSEmu.Tests/ExportedModules/Majorbbs/skpwrd_Tests.cs @@ -33,5 +33,42 @@ public void SKPWRD_Test(string inputString, string expectedString) Encoding.ASCII.GetString( mbbsEmuMemoryCore.GetString(mbbsEmuCpuRegisters.GetPointer()))); } + + /// + /// These tests are to verify a specific scenario where the final character of the string being parsed + /// is at the last offset in a segment (0xFFFF) + /// + /// + /// + [Theory] + [InlineData("TEST TEST\0", " TEST\0")] + [InlineData("TEST\0", "\0")] + [InlineData("\0", "\0")] + public void SKPWRD_Test_EndOfSegment(string inputString, string expectedString) + { + //Reset State + Reset(); + + //Set Argument Values to be Passed In + var stringPointer = mbbsEmuMemoryCore.AllocateVariable("INPUT_STRING", (ushort)(inputString.Length + 1)); + + //Ensure Input String ends in \0 + if (inputString[^1] != '\0') + inputString += '\0'; + + //This will change the final character of the string (\0) to be at 0xFFFF + stringPointer.Offset = (ushort)(0x10000 - inputString.Length); + + //Get the Segment and we'll allocate this at the end + mbbsEmuMemoryCore.SetArray(stringPointer, Encoding.ASCII.GetBytes(inputString)); + + //Execute Test + ExecuteApiTest(HostProcess.ExportedModules.Majorbbs.Segment, SKPWRD_ORDINAL, new List { stringPointer }); + + //Verify Results + Assert.Equal(expectedString, + Encoding.ASCII.GetString( + mbbsEmuMemoryCore.GetString(mbbsEmuCpuRegisters.GetPointer()))); + } } } diff --git a/MBBSEmu/HostProcess/ExportedModules/Majorbbs.cs b/MBBSEmu/HostProcess/ExportedModules/Majorbbs.cs index c0601364..7a99b0b9 100644 --- a/MBBSEmu/HostProcess/ExportedModules/Majorbbs.cs +++ b/MBBSEmu/HostProcess/ExportedModules/Majorbbs.cs @@ -7212,7 +7212,7 @@ private void skpwrd() { var stringPointerBase = GetParameterPointer(0); - for (var i = stringPointerBase.Offset; i < ushort.MaxValue; i++) + for (var i = stringPointerBase.Offset; i <= ushort.MaxValue; i++) { var currentCharacter = Module.Memory.GetByte(stringPointerBase.Segment, i); if (currentCharacter != 0 && currentCharacter != ' ') continue;