mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-30 22:49:53 +08:00
revert: restore state before huge regression
This commit is contained in:
@@ -1,86 +0,0 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using SharpEmu.HLE;
|
||||
using SharpEmu.Libs.Audio;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Audio;
|
||||
|
||||
public sealed class AudioOut2PortGetStateExportsTests
|
||||
{
|
||||
private const ulong MemoryBase = 0x1_0000_0000;
|
||||
private const ulong StateAddress = MemoryBase + 0x100;
|
||||
|
||||
private static CpuContext CreateContext(out FakeCpuMemory memory)
|
||||
{
|
||||
memory = new FakeCpuMemory(MemoryBase, 0x1000);
|
||||
return new CpuContext(memory, Generation.Gen5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortGetState_WritesFixedSizeIgnoringPollutedR9()
|
||||
{
|
||||
var ctx = CreateContext(out var memory);
|
||||
// Paint the buffer so we can see the write footprint.
|
||||
Span<byte> paint = stackalloc byte[0x100];
|
||||
paint.Fill(0xAB);
|
||||
Assert.True(memory.TryWrite(StateAddress, paint));
|
||||
|
||||
ctx[CpuRegister.Rdi] = 0xDE1FF6800001UL;
|
||||
ctx[CpuRegister.Rsi] = StateAddress;
|
||||
ctx[CpuRegister.Rdx] = StateAddress + 0x200;
|
||||
// Polluted GetSize leftover — must NOT enlarge the write.
|
||||
ctx[CpuRegister.R9] = 0x180;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2PortGetState(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
Span<byte> state = stackalloc byte[0x100];
|
||||
Assert.True(memory.TryRead(StateAddress, state));
|
||||
Assert.Equal(1, BinaryPrimitives.ReadUInt16LittleEndian(state));
|
||||
Assert.Equal(2, state[2]);
|
||||
// Bytes past the fixed 0x20 header must remain untouched.
|
||||
Assert.Equal(0xAB, state[0x20]);
|
||||
Assert.Equal(0xAB, state[0x7F]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortGetState_SkipsGuestStackOutBuffer()
|
||||
{
|
||||
var ctx = CreateContext(out _);
|
||||
const ulong stackOut = 0x00007FFFDE1FF688UL;
|
||||
ctx[CpuRegister.Rdi] = 0xDE1FF688004DUL;
|
||||
ctx[CpuRegister.Rsi] = stackOut;
|
||||
ctx[CpuRegister.Rdx] = 0;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2PortGetState(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSpeakerInfo_WritesFixedSizeToRdiNotRsiTypeFlag()
|
||||
{
|
||||
var ctx = CreateContext(out var memory);
|
||||
Span<byte> paint = stackalloc byte[0x80];
|
||||
paint.Fill(0xCD);
|
||||
Assert.True(memory.TryWrite(StateAddress, paint));
|
||||
|
||||
ctx[CpuRegister.Rdi] = StateAddress;
|
||||
ctx[CpuRegister.Rsi] = 1;
|
||||
ctx[CpuRegister.Rdx] = StateAddress + 0x200;
|
||||
ctx[CpuRegister.R8] = 0x840;
|
||||
ctx[CpuRegister.R9] = 0x10C;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2GetSpeakerInfo(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
Span<byte> info = stackalloc byte[0x80];
|
||||
Assert.True(memory.TryRead(StateAddress, info));
|
||||
Assert.Equal(2u, BinaryPrimitives.ReadUInt32LittleEndian(info));
|
||||
Assert.Equal(48000u, BinaryPrimitives.ReadUInt32LittleEndian(info[4..]));
|
||||
Assert.Equal(0xCD, info[0x20]);
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using SharpEmu.HLE;
|
||||
using SharpEmu.Libs.Audio;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Audio;
|
||||
|
||||
public sealed class AudioOut2SpeakerArrayExportsTests
|
||||
{
|
||||
private const ulong MemoryBase = 0x1_0000_0000;
|
||||
private const ulong OutHandleAddress = MemoryBase + 0x100;
|
||||
private const ulong ReservedAddress = MemoryBase + 0x120;
|
||||
private const ulong ParamAddress = MemoryBase + 0x200;
|
||||
private const ulong SpeakerMemoryAddress = MemoryBase + 0x400;
|
||||
|
||||
private static CpuContext CreateContext(out FakeCpuMemory memory)
|
||||
{
|
||||
memory = new FakeCpuMemory(MemoryBase, 0x2000);
|
||||
return new CpuContext(memory, Generation.Gen5);
|
||||
}
|
||||
|
||||
private static void WriteU64(FakeCpuMemory memory, ulong address, ulong value)
|
||||
{
|
||||
Span<byte> bytes = stackalloc byte[8];
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(bytes, value);
|
||||
Assert.True(memory.TryWrite(address, bytes));
|
||||
}
|
||||
|
||||
private static ulong ReadU64(FakeCpuMemory memory, ulong address)
|
||||
{
|
||||
Span<byte> bytes = stackalloc byte[8];
|
||||
Assert.True(memory.TryRead(address, bytes));
|
||||
return BinaryPrimitives.ReadUInt64LittleEndian(bytes);
|
||||
}
|
||||
|
||||
private static uint ReadU32(FakeCpuMemory memory, ulong address)
|
||||
{
|
||||
Span<byte> bytes = stackalloc byte[4];
|
||||
Assert.True(memory.TryRead(address, bytes));
|
||||
return BinaryPrimitives.ReadUInt32LittleEndian(bytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSpeakerArrayMemorySize_NeverReturnsTheNotFoundSentinel()
|
||||
{
|
||||
var ctx = CreateContext(out _);
|
||||
ctx[CpuRegister.Rdi] = 8;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2GetSpeakerArrayMemorySize(ctx);
|
||||
|
||||
Assert.NotEqual((int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND, result);
|
||||
Assert.Equal(0x40 + 8 * 0x100 + 0x400, result);
|
||||
Assert.Equal((ulong)result, ctx[CpuRegister.Rax]);
|
||||
Assert.True(result < 0x10000);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetSpeakerArrayMemorySize_TwoChannelsIsExactChannelScaledSize()
|
||||
{
|
||||
var ctx = CreateContext(out _);
|
||||
ctx[CpuRegister.Rdi] = 2;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2GetSpeakerArrayMemorySize(ctx);
|
||||
|
||||
Assert.Equal(0x40 + 2 * 0x100 + 0x400, result);
|
||||
Assert.Equal(0x640UL, ctx[CpuRegister.Rax]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpeakerArrayCreate_PublishesObjectPointerAndLeavesReservedSizeAlone()
|
||||
{
|
||||
var ctx = CreateContext(out var memory);
|
||||
// Stage a size in the reserved slot the way callers do before Create.
|
||||
WriteU64(memory, ReservedAddress, 0x100);
|
||||
ctx[CpuRegister.Rdi] = ParamAddress;
|
||||
ctx[CpuRegister.Rsi] = OutHandleAddress;
|
||||
ctx[CpuRegister.Rdx] = ReservedAddress;
|
||||
ctx[CpuRegister.Rcx] = 2;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2SpeakerArrayCreate(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
Assert.NotEqual(0UL, ctx[CpuRegister.Rax]);
|
||||
Assert.NotEqual(0x100UL, ctx[CpuRegister.Rax]);
|
||||
Assert.Equal(ctx[CpuRegister.Rax], ReadU64(memory, OutHandleAddress));
|
||||
// Reserved/size slot must remain untouched — writing it corrupted canaries.
|
||||
Assert.Equal(0x100UL, ReadU64(memory, ReservedAddress));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpeakerArrayCreate_PublishesHandleForTypicalCallShape()
|
||||
{
|
||||
var ctx = CreateContext(out _);
|
||||
ctx[CpuRegister.Rdi] = ParamAddress;
|
||||
ctx[CpuRegister.Rsi] = OutHandleAddress;
|
||||
ctx[CpuRegister.Rdx] = ReservedAddress;
|
||||
ctx[CpuRegister.Rcx] = 2;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2SpeakerArrayCreate(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
Assert.NotEqual(0UL, ctx[CpuRegister.Rax]);
|
||||
Assert.NotEqual(0x10000UL, ctx[CpuRegister.Rax]);
|
||||
Assert.NotEqual((int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpeakerArrayCreate_IgnoresCorruptedParamBufferFields()
|
||||
{
|
||||
var ctx = CreateContext(out var memory);
|
||||
// Simulate PortGetState having overwritten param+0x18 (size) with a
|
||||
// state blob — Create must NOT adopt that as an in-place buffer.
|
||||
WriteU64(memory, ParamAddress + 0x10, SpeakerMemoryAddress);
|
||||
WriteU64(memory, ParamAddress + 0x18, 0x100);
|
||||
ctx[CpuRegister.Rdi] = ParamAddress;
|
||||
ctx[CpuRegister.Rsi] = OutHandleAddress;
|
||||
ctx[CpuRegister.Rdx] = ReservedAddress;
|
||||
ctx[CpuRegister.Rcx] = 2;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2SpeakerArrayCreate(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
Assert.NotEqual(SpeakerMemoryAddress, ctx[CpuRegister.Rax]);
|
||||
Assert.NotEqual(0x100UL, ctx[CpuRegister.Rax]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpeakerArrayDestroy_UnknownHandleStillSucceeds()
|
||||
{
|
||||
var ctx = CreateContext(out _);
|
||||
ctx[CpuRegister.Rdi] = 0xDEAD_BEEF;
|
||||
|
||||
var result = AudioOut2Exports.AudioOut2SpeakerArrayDestroy(ctx);
|
||||
|
||||
Assert.Equal(0, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user