# How SharpEmu Manages Generation Targeting for OrbisGen2: A Deep Dive into PlayStation 4 and 5 API Compatibility

> Discover how SharpEmu achieves generation targeting for OrbisGen2 on PS4 and PS5. Learn about its API compatibility, bitwise flags, and attribute filtering for seamless system call management.

- Repository: [Berk/sharpemu](https://github.com/par274/sharpemu)
- Tags: deep-dive
- Published: 2026-07-13

---

**SharpEmu uses a bitwise flag enum and `[ExportedFunction]` attributes to selectively expose PlayStation 4 (Gen4) or PlayStation 5 (Gen5) HLE APIs at runtime, filtering system calls through generation targeting while maintaining a unified OrbisGen2 error code surface.**

The SharpEmu emulator implements a sophisticated dual-generation architecture that cleanly separates PlayStation 4-style APIs from their PlayStation 5 successors. By leveraging a flag-based `Generation` enum and targeted export attributes, the codebase hosted at `par274/sharpemu` enables the same emulator binary to host both Gen4 and Gen5 implementations while keeping the underlying system call implementations isolated.

## The Generation Flag Architecture

At the core of SharpEmu's generation targeting system lies a compact `[Flags]` enum that defines available hardware generations. Located in [`/src/SharpEmu.HLE/Generation.cs`](https://github.com/par274/sharpemu/blob/main//src/SharpEmu.HLE/Generation.cs), this enumeration provides the bitwise foundation for all generation-based filtering:

```csharp
[Flags]
public enum Generation { 
    None = 0, 
    Gen4 = 1, 
    Gen5 = 2 
}

```

Each bit represents a distinct console generation, allowing simultaneous targeting through bitwise OR operations. When the emulator initializes, it sets a single generation flag in `SharpEmuRuntimeOptions` (typically via command-line flags like `--gen5`), establishing the execution context for the current session.

### Kernel-Style Result Codes

Regardless of which generation is active, all OrbisGen2 APIs return standardized error codes defined in [`/src/SharpEmu.HLE/OrbisGen2Result.cs`](https://github.com/par274/sharpemu/blob/main//src/SharpEmu.HLE/OrbisGen2Result.cs). This enum ensures consistent kernel-style semantics across both Gen4 and Gen5 execution paths:

```csharp
public enum OrbisGen2Result : int { 
    ORBIS_GEN2_OK = 0, 
    ORBIS_GEN2_ERROR_PERMISSION_DENIED = unchecked((int)0x80020001), 
    /* ... */
    ORBIS_GEN2_ERROR_MEMORY_FAULT = unchecked((int)0x80020101) 
}

```

Every exported function casts these results to `int` before returning, preserving the PlayStation kernel's error code conventions regardless of the underlying generation.

## Export Function Targeting

SharpEmu annotates each High-Level Emulation (HLE) function with an `[ExportedFunction]` attribute that specifies which generations the implementation supports. This metadata-driven approach appears throughout the library exports, such as in [`/src/SharpEmu.Libs/VideoOut/VideoOutExports.cs`](https://github.com/par274/sharpemu/blob/main//src/SharpEmu.Libs/VideoOut/VideoOutExports.cs):

```csharp
[ExportedFunction(Target = Generation.Gen4 | Generation.Gen5)]
public static int sceVideoOutGetResolution(IntPtr ctx, int videoOutHandle,
                                            out int width, out int height)
{
    // Implementation supports both generations
    return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}

```

Functions can restrict themselves to specific generations by omitting unwanted flags. A Gen5-exclusive feature would declare:

```csharp
[ExportedFunction(Target = Generation.Gen5)]
public static int scePlayGoInitialize(IntPtr ctx)
{
    // PlayStation 5 specific functionality
    return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}

```

## Runtime Selection and Dispatch

The generation filtering mechanism activates during system call dispatch. When a guest thread invokes a system call, the runtime evaluates the bitwise intersection between the export's `Target` flag and the current `SharpEmuRuntime.Options.Generation` setting.

The dispatch logic in [`/src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs`](https://github.com/par274/sharpemu/blob/main//src/SharpEmu.Core/Runtime/SharpEmuRuntime.cs) performs this check:

```csharp
// Runtime selection established at startup
runtime.Options.Generation = Generation.Gen5; // User-specified via CLI

// During system call dispatch:
if ((export.Target & runtime.Options.Generation) != 0) { 
    // Expose the function to the guest
    ExecuteExport(export);
} else { 
    // Hide or reject the call
    return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_IMPLEMENTED;
}

```

This design ensures that only functions explicitly marked for the current generation become callable. If a Gen4-only title attempts to invoke a Gen5-exclusive API while running in Gen4 mode, the dispatcher intercepts the call before execution.

## Practical Implementation Examples

Developers extending SharpEmu's HLE layer follow a three-step pattern to implement generation targeting:

**1. Declare multi-generation support for shared APIs:**

```csharp
[ExportedFunction(Target = Generation.Gen4 | Generation.Gen5)]
public static int sceAudioOutOpen(IntPtr ctx, int userId, int type, 
                                   int index, uint len, uint freq, uint param)
{
    // Shared audio implementation
    return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}

```

**2. Restrict new APIs to specific generations:**

```csharp
[ExportedFunction(Target = Generation.Gen5)]
public static int sceSystemServiceHideSplashScreen(IntPtr ctx)
{
    // PS5-specific system service
    return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}

```

**3. Configure runtime options at initialization:**

```csharp
var options = new SharpEmuRuntimeOptions
{
    Generation = Generation.Gen5   // Forces visibility of Gen5-only exports
};
var runtime = new SharpEmuRuntime(options);

```

## Summary

- **Flag-based architecture**: The `[Flags]` enum in [`Generation.cs`](https://github.com/par274/sharpemu/blob/main/Generation.cs) enables bitwise combination of Gen4 and Gen5 targets.
- **Metadata-driven filtering**: The `Target` property on `[ExportedFunction]` attributes declares generation compatibility without conditional compilation.
- **Runtime dispatch**: The dispatcher checks `(export.Target & runtime.Options.Generation) != 0` to determine API visibility.
- **Unified error surface**: `OrbisGen2Result` provides consistent kernel-style error codes across both generations.
- **Clean separation**: Generation targeting allows shared infrastructure while isolating incompatible PlayStation 4 and PlayStation 5 behaviors.

## Frequently Asked Questions

### What is OrbisGen2 and how does it relate to generation targeting?

OrbisGen2 refers to SharpEmu's implementation layer for Sony's second-generation Orbis operating system APIs, encompassing both PlayStation 4 (Gen4) and PlayStation 5 (Gen5) system call interfaces. The generation targeting mechanism allows the emulator to expose the appropriate subset of these APIs based on which console generation the user is emulating, ensuring that a PlayStation 4 game cannot accidentally invoke PlayStation 5-specific kernel functions.

### How does SharpEmu filter system calls based on the selected generation?

The emulator maintains a `Generation` flag in `SharpEmuRuntimeOptions` that is set at startup (often via command-line arguments like `--gen5`). When dispatching system calls, SharpEmu performs a bitwise AND operation between this runtime flag and the `Target` flag specified on each `[ExportedFunction]` attribute. If the result is non-zero, the function is exposed to the guest; otherwise, it remains hidden or returns a "not implemented" error.

### Can a single HLE function support multiple generations?

Yes. Developers specify multiple generations using bitwise OR syntax in the attribute declaration, such as `[ExportedFunction(Target = Generation.Gen4 | Generation.Gen5)]`. This approach is common for system calls that remained functionally identical between the PlayStation 4 and PlayStation 5, allowing code reuse while maintaining the ability to split implementations if generational differences emerge.

### What error handling does SharpEmu use for OrbisGen2 API calls?

All OrbisGen2 functions return values from the `OrbisGen2Result` enum defined in [`/src/SharpEmu.HLE/OrbisGen2Result.cs`](https://github.com/par274/sharpemu/blob/main//src/SharpEmu.HLE/OrbisGen2Result.cs). These kernel-style error codes (prefixed with `ORBIS_GEN2_`) mirror PlayStation 5 kernel conventions, with `ORBIS_GEN2_OK` (0) indicating success and values like `ORBIS_GEN2_ERROR_MEMORY_FAULT` (0x80020101) indicating specific failure conditions. This ensures consistent error semantics regardless of which generation is currently active.