mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-19 09:26:16 +08:00
Astro Bot shader type 4, pthread_cond_timedwait, and HLE/memory/cpu bug fixes (#40)
* [agc] Add shader type 4 (GS) and register defaults v13 support Astro Bot (#11) crashes on boot due to two missing GPU features: 1. Shader type 4 (Geometry Shader) — SPI_SHADER_PGM_LO/HI register offsets 0x8A/0x8B were missing. Added constants and switch cases for shader type 4 in GetExpectedSpiShaderPgmLo/Hi. Also added type 4 to IsEsGeometryShaderType (2 or 4 or 6). 2. Register defaults version 13 — was not recognized as supported. Added RegisterDefaultsVersion13 constant and included it in IsSupportedRegisterDefaultsVersion. * [kernel] Add POSIX pthread_cond_timedwait export SILENT HILL (#4) and Poppy Playtime (#3) crash on boot due to missing POSIX pthread_cond_timedwait (NID 27bAgiJmOh0). The Sony wrapper scePthreadCondTimedwait (NID BmMjYxmew1w) was already implemented, but the raw POSIX symbol was not exported. Added [SysAbiExport] for pthread_cond_timedwait delegating to existing PthreadCondWaitCore with timed: true. * [memory] Fix FlushInstructionCache null process handle PhysicalVirtualMemory.cs called FlushInstructionCache with null as the process handle in two places (SetProtection and TryWriteExclusive). On Windows, a null handle does not reliably resolve to the current process — the correct call is GetCurrentProcess() (pseudo-handle -1). Also corrected the P/Invoke signature: - Changed return type from void to bool with [return: MarshalAs(Bool)] - Added SetLastError = true - Added GetCurrentProcess() P/Invoke import This matches the pattern already used in DirectExecutionBackend.cs which correctly passes GetCurrentProcess() to all FlushInstructionCache calls. * [hle] Distinguish NOT_FOUND from NOT_IMPLEMENTED and log duplicate NIDs Three diagnostic improvements to the HLE dispatch path: 1. ModuleManager.RegisterFromAssembly — duplicate NID registration was silently skipped (dispatchTable first-wins, exportTable last-wins, causing metadata divergence). Now logs a warning with the NID and export name so conflicts are visible. 2. ModuleManager.TryDispatch — generation mismatch returned ORBIS_GEN2_ERROR_NOT_FOUND, conflating 'function does not exist' with 'function exists but not for this generation'. Now returns ORBIS_GEN2_ERROR_NOT_IMPLEMENTED for generation mismatch, matching the existing convention in CpuDispatcher. Also adds debug logging for both NOT_FOUND and NOT_IMPLEMENTED paths. 3. DirectExecutionBackend.Imports.cs — the import dispatch else-branch (the actual hot path that bypasses ModuleManager.TyDispatch via cached export) had the same conflation. Split into: - else if (export exists but generation mismatch) → NOT_IMPLEMENTED - else (no export at all) → NOT_FOUND This makes runtime diagnostics correctly distinguish missing exports from generation-unsupported exports. * [cpu] Check VirtualProtect return values in all stub creation paths 9 VirtualProtect calls in DirectExecutionBackend.cs had unchecked return values. If VirtualProtect silently fails, memory protection remains incorrect — stubs allocated with PAGE_EXECUTE_READWRITE (0x40) never get downgraded to PAGE_EXECUTE_READ (0x20), or guest thread entry stubs never get upgraded to writable. This causes access violations on next execution or silent data corruption. Fixed all 9 sites with proper error handling: - 6 stub creation methods (return 0 on failure + log error) - 2 guest thread entry methods (set reason + return Exception) - 1 guest entry method (set LastError + return MEMORY_FAULT) Stub creation sites fixed: - CreateImportDispatchStub (line ~1683) - EnsureTlsHandler (void, log + return) - CreateUnresolvedReturnStub (return 0) - CreateGuestReturnStub (return 0) - CreateExceptionHandlerTrampoline (return 0) - CreateTlsStoreHelperStub (return 0) Guest thread entry sites fixed: - StartGuestThreadNativeCall (return Exception) - StartGuestContinuationNativeCall (return Exception) - RunGuestEntryPoint (return MEMORY_FAULT) * [kernel] Remove unused duplicate _nextFileDescriptor field KernelExports.cs declared _nextFileDescriptor but never used it. The actual field used for file descriptor allocation lives in KernelMemoryCompatExports.cs (lines 1314, 1337). This was a dead duplicate causing CS0414 warning. Build is now 0 errors, 0 warnings. --------- Co-authored-by: Hermes Atlas <hermesatlas@example.com>
This commit is contained in:
@@ -58,6 +58,8 @@ public static class AgcExports
|
||||
private const uint SpiShaderPgmHiEs = 0xC9;
|
||||
private const uint SpiShaderPgmLoLs = 0x148;
|
||||
private const uint SpiShaderPgmHiLs = 0x149;
|
||||
private const uint SpiShaderPgmLoGs = 0x8A;
|
||||
private const uint SpiShaderPgmHiGs = 0x8B;
|
||||
private const uint SpiPsInputEna = 0x1B3;
|
||||
private const uint SpiPsInputAddr = 0x1B4;
|
||||
private const uint ComputePgmLo = 0x20C;
|
||||
@@ -115,6 +117,7 @@ public static class AgcExports
|
||||
private const uint RegisterDefaultsVersion7 = 7;
|
||||
private const uint RegisterDefaultsVersion8 = 8;
|
||||
private const uint RegisterDefaultsVersion10 = 10;
|
||||
private const uint RegisterDefaultsVersion13 = 13;
|
||||
private const int RegisterDefaultsSize = 0x40;
|
||||
private const int RegisterDefaultBlockSize = 16 * 8;
|
||||
|
||||
@@ -5081,6 +5084,7 @@ public static class AgcExports
|
||||
0 => ComputePgmLo,
|
||||
1 => SpiShaderPgmLoPs,
|
||||
2 or 6 => SpiShaderPgmLoEs,
|
||||
4 => SpiShaderPgmLoGs,
|
||||
7 => SpiShaderPgmLoLs,
|
||||
_ => 0u,
|
||||
};
|
||||
@@ -5089,6 +5093,7 @@ public static class AgcExports
|
||||
0 => ComputePgmHi,
|
||||
1 => SpiShaderPgmHiPs,
|
||||
2 or 6 => SpiShaderPgmHiEs,
|
||||
4 => SpiShaderPgmHiGs,
|
||||
7 => SpiShaderPgmHiLs,
|
||||
_ => 0u,
|
||||
};
|
||||
@@ -5105,7 +5110,7 @@ public static class AgcExports
|
||||
}
|
||||
|
||||
private static bool IsEsGeometryShaderType(byte shaderType) =>
|
||||
shaderType is 2 or 6;
|
||||
shaderType is 2 or 4 or 6;
|
||||
|
||||
private static int SetIndirectPatchAddress(CpuContext ctx, string registerSpace)
|
||||
{
|
||||
@@ -5252,7 +5257,8 @@ public static class AgcExports
|
||||
return version is
|
||||
RegisterDefaultsVersion7 or
|
||||
RegisterDefaultsVersion8 or
|
||||
RegisterDefaultsVersion10;
|
||||
RegisterDefaultsVersion10 or
|
||||
RegisterDefaultsVersion13;
|
||||
}
|
||||
|
||||
private static bool TryGetRegisterDefaultsAllocation(
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace SharpEmu.Libs.Kernel;
|
||||
|
||||
public static class KernelExports
|
||||
{
|
||||
private static int _nextFileDescriptor = 2;
|
||||
private static readonly object _cxaGate = new();
|
||||
private static readonly List<CxaDestructorEntry> _cxaDestructors = new();
|
||||
private static readonly object _coredumpGate = new();
|
||||
|
||||
@@ -329,6 +329,12 @@ public static class KernelPthreadCompatExports
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libKernel")]
|
||||
public static int PosixPthreadCondSignal(CpuContext ctx) => PthreadCondSignalCore(ctx, ctx[CpuRegister.Rdi], broadcast: false);
|
||||
[SysAbiExport(
|
||||
Nid = "27bAgiJmOh0",
|
||||
ExportName = "pthread_cond_timedwait",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
LibraryName = "libKernel")]
|
||||
public static int PosixPthreadCondTimedwait(CpuContext ctx) => PthreadCondWaitCore(ctx, ctx[CpuRegister.Rdi], ctx[CpuRegister.Rsi], timed: true, timeoutUsec: unchecked((uint)ctx[CpuRegister.Rdx]));
|
||||
|
||||
[SysAbiExport(
|
||||
Nid = "m5-2bsNfv7s",
|
||||
|
||||
Reference in New Issue
Block a user