mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-23 11:19:01 +08:00
Libs: add libSceDiscMap HLE exports (ported from Kyty) (#79)
Port the libSceDiscMap stubs from Kyty (InoriRus/Kyty, MIT) into the SysAbiExport model. Disc-installed titles probe these NIDs on most file accesses to decide whether a read must be redirected to the disc drive; answering that every request is already resident on internal storage keeps I/O on the regular file system path instead of failing with unresolved-import errors. - sceDiscMapIsRequestOnHDD (lbQKqsERhtE): validates args, writes 1 to the result pointer, returns 0 - fJgP+wqifno / ioKMruft1ek: zero-fill the three output pointers, return 0 (names not present in ps5_names.txt; kept as descriptive Unknown exports like the existing sceKernelUnknown* convention) - DISC_MAP_ERROR_INVALID_ARGUMENT (0x81100001) on null pointers, matching the documented libSceDiscMap error range - optional tracing via SHARPEMU_LOG_DISCMAP=1 Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
using SharpEmu.HLE;
|
||||||
|
|
||||||
|
namespace SharpEmu.Libs.DiscMap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HLE implementation of libSceDiscMap, ported from Kyty's LibDiscMap.cpp
|
||||||
|
/// (https://github.com/InoriRus/Kyty, MIT). Titles installed to internal
|
||||||
|
/// storage query these entry points on nearly every file access to decide
|
||||||
|
/// whether a read must be redirected to the Blu-ray drive. Reporting every
|
||||||
|
/// request as already resident on HDD lets the regular file system path
|
||||||
|
/// service the read.
|
||||||
|
/// </summary>
|
||||||
|
public static class DiscMapExports
|
||||||
|
{
|
||||||
|
private const int DiscMapErrorInvalidArgument = unchecked((int)0x81100001);
|
||||||
|
private const int DiscMapErrorLocationNotMapped = unchecked((int)0x81100002);
|
||||||
|
private const int DiscMapErrorFileNotFound = unchecked((int)0x81100003);
|
||||||
|
private const int DiscMapErrorNoBitmapInfo = unchecked((int)0x81100004);
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "lbQKqsERhtE",
|
||||||
|
ExportName = "sceDiscMapIsRequestOnHDD",
|
||||||
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
|
LibraryName = "libSceDiscMap")]
|
||||||
|
public static int DiscMapIsRequestOnHDD(CpuContext ctx)
|
||||||
|
{
|
||||||
|
var pathAddress = ctx[CpuRegister.Rdi];
|
||||||
|
var offset = ctx[CpuRegister.Rsi];
|
||||||
|
var size = ctx[CpuRegister.Rdx];
|
||||||
|
var resultAddress = ctx[CpuRegister.Rcx];
|
||||||
|
|
||||||
|
if (pathAddress == 0 || resultAddress == 0)
|
||||||
|
{
|
||||||
|
return DiscMapErrorInvalidArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx.TryWriteInt32(resultAddress, 1))
|
||||||
|
{
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceDiscMap(ctx, "sceDiscMapIsRequestOnHDD", pathAddress, offset, size);
|
||||||
|
|
||||||
|
ctx[CpuRegister.Rax] = 0;
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "fJgP+wqifno",
|
||||||
|
ExportName = "sceDiscMapUnknownFJgP",
|
||||||
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
|
LibraryName = "libSceDiscMap")]
|
||||||
|
public static int DiscMapUnknownFJgP(CpuContext ctx) => WriteMappingTriple(ctx, "sceDiscMapUnknownFJgP");
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "ioKMruft1ek",
|
||||||
|
ExportName = "sceDiscMapUnknownIoKM",
|
||||||
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
|
LibraryName = "libSceDiscMap")]
|
||||||
|
public static int DiscMapUnknownIoKM(CpuContext ctx) => WriteMappingTriple(ctx, "sceDiscMapUnknownIoKM");
|
||||||
|
|
||||||
|
private static int WriteMappingTriple(CpuContext ctx, string exportName)
|
||||||
|
{
|
||||||
|
var pathAddress = ctx[CpuRegister.Rdi];
|
||||||
|
var offset = ctx[CpuRegister.Rsi];
|
||||||
|
var size = ctx[CpuRegister.Rdx];
|
||||||
|
var flagsAddress = ctx[CpuRegister.Rcx];
|
||||||
|
var outAddress1 = ctx[CpuRegister.R8];
|
||||||
|
var outAddress2 = ctx[CpuRegister.R9];
|
||||||
|
|
||||||
|
if (pathAddress == 0 || flagsAddress == 0 || outAddress1 == 0 || outAddress2 == 0)
|
||||||
|
{
|
||||||
|
return DiscMapErrorInvalidArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx.TryWriteUInt64(flagsAddress, 0) ||
|
||||||
|
!ctx.TryWriteUInt64(outAddress1, 0) ||
|
||||||
|
!ctx.TryWriteUInt64(outAddress2, 0))
|
||||||
|
{
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceDiscMap(ctx, exportName, pathAddress, offset, size);
|
||||||
|
|
||||||
|
ctx[CpuRegister.Rax] = 0;
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void TraceDiscMap(CpuContext ctx, string exportName, ulong pathAddress, ulong offset, ulong size)
|
||||||
|
{
|
||||||
|
if (!string.Equals(Environment.GetEnvironmentVariable("SHARPEMU_LOG_DISCMAP"), "1", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = ctx.TryReadNullTerminatedUtf8(pathAddress, 1024, out var value)
|
||||||
|
? value
|
||||||
|
: $"<unreadable 0x{pathAddress:X16}>";
|
||||||
|
Console.Error.WriteLine($"[HLE][DISCMAP] {exportName} path={path} offset=0x{offset:X} size=0x{size:X}");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user