Running a title
A run loads a title's container, maps its segments, resolves its import table and starts the guest in a worker process. The guest's instructions run natively; everything orbistoun does is the operating system beneath them. What a run produces is a record of what the guest asked for and what it got, compared with the previous run of the same title.
Starting and stopping
In the window, select a title and press start, or double-click it. While it runs, the right side of the window shows its picture (see graphics) and the toolbar shows its name. Stop, available on Windows, ends the worker. "quit the title" in the shell button's power menu first tells the title it is being closed, then ends the worker.
On the command line:
orbistoun-cli run <title>/eboot.bin # execute; prints the verdict against the last run
orbistoun-cli report <title>/eboot.bin # survey the module, persist a report, print the delta
orbistoun-cli verify <title>/eboot.bin # how much of the import list the symbol database namesrun option |
Does |
|---|---|
--limit <seconds> |
seconds of guest execution before the run is stopped and reported;
default 20, 0 for none |
--calls <n> |
imports the guest may call before it is stopped; default 20,000,000,
0 for none |
--profile <name> |
present a named machine profile instead of
shell.toml's; see machine
profile |
--input <file> |
play a pad script on player 1; see controllers |
--staged |
run a loose build as a staged title, with a writable
/app0 |
--relink |
build a fresh link plan and report any difference from the stored one; see linking ahead of time |
Limits
A run ends at the first of: the guest exits, the guest faults, the time limit passes, or the call budget is spent. The call budget is the deterministic limit: two runs of one build stop at the same call, so a verdict between them measures the change rather than the machine. The time limit is the backstop for a guest that stops calling imports.
The window's runs take the limit from the toolbar (or preferences -
general) and the budget from run-call-budget under
[library] in config.toml. Both default to
0, no limit, because a title launched from the window is
being played.
GPU work alongside the title
A title the window plays runs on while its GPU work is carried out on
a thread of its own, as on hardware (D821): a fence it waits on is
written when the work behind it has run. A run from the command line
carries each submission out as the submit returns, so two runs agree on
when every fence was written and a verdict between them measures
orbistoun. ORBISTOUN_SUBMIT=async gives a command-line run
the window's behaviour, and ORBISTOUN_SUBMIT=sync the
window the command line's.
Sound
A title the window plays is heard on the host's default output device (D819). Each output port waits on the device, so the title's audio runs at the device's pace, about 64 ms behind the title. A run from the command line is silent unless asked:
ORBISTOUN_AUDIO=host orbistoun-cli run <title>/eboot.binSound plays on Windows only; elsewhere output is paced by its sample
rate and heard nowhere. Output through sceAudioOutOutputs
or sceAudioOut2ContextPush is not heard yet, and the run
result names it under "on the host", as it does a device that did not
open.
Linking ahead of time
A run starts from the title's link plan (D724). The first run of an executable builds the plan and stores it in the title library beside the title, keyed by the executable's hash, the loader's build and the host CPU's features; later runs apply the stored plan instead of linking again. There is no setting for this: a stored plan is a cache, and a changed executable, loader or CPU builds a new one. Implementations attach when the guest starts, so a new implementation reuses the stored plan. The shader translation cache is stored the same way and filled from the title's recorded shaders before the guest starts (D113).
run --relink builds a fresh plan and compares it with
the stored one. A difference is a loader defect, and the run report
lists it.
orbistoun-cli link <title>/eboot.bin # build and store the plan without running
orbistoun-cli link <title>/eboot.bin --native <file> # also write it as a host executableA native executable loads the orbistoun runtime library and runs the title in its own process, with the same thunks and the same trace as a run from the window. It is built from the operator's own title and stays on the machine that built it (scope).
On a host CPU without SSE4a, the plan rewrites extrq and
insertq (D725), and the run report lists how many
instructions it rewrote. Most sites jump to a trampoline. A site too
short for a jump is carried out at its fault, and monitorx
and mwaitx become a no-op and a pause (D924).
ORBISTOUN_HOST_LACKS=sse4a,monitorx runs a title on an AMD
host as an Intel host would.
The run result
When a run ends, the detail panel shows what it produced, top to bottom:
| Part | Shows |
|---|---|
| progress | the verdict and its one-line summary;
imports +n, calls +n against the previous run; the fault,
and the previous run's fault beside it |
| stack line | how many calls the guest made, and whether any arrived on a misaligned stack |
| last calls before the fault | the final calls, each with its first argument, when the run faulted |
| what it asked for | every import the guest called, with its call count |
| events | anything else the run reported |
A run that could not start shows the reason in red instead.
Verdicts
run compares a run with the previous run of the same
module and prints one verdict; the window shows the same words.
| Verdict | Means |
|---|---|
FURTHER |
the guest executed code it could not reach before |
same |
nothing moved |
BACK |
the guest reached less of the interface than it did |
MIXED |
more of the interface along a different path, or further along its path with less of the interface |
| (none) | the first run of this module; nothing to compare against |
FURTHER is the measure of progress. A verdict is
differential: it says that something changed, not that an answer was
correct. Correctness needs an oracle, which is a probe (obSCEne) run on real
hardware through Prosperous.
A change that replaces a plausible answer with a refusal can make a run stop earlier. That is the intended trade: an unimplemented call refuses at the call, so an early stop names its cause, where a stub returning success lets the guest carry damage far from where it began.
Reports
report surveys a module, persists a run report under
reports/, and prints the delta against the previous run of
the same title: the reached state, the unresolved-import count, and
which imports became newly resolved or newly unresolved.
verify answers a narrower question, how much of a
module's import list the symbol database can name, printed as
N of M imports named. It is a naming measure, not a
progress one; see names and hashes.
Log levels
A run is quiet unless asked:
OOPS_LOG=debug orbistoun-cli run <title>/eboot.bin # decisions and resolved configuration
OOPS_LOG=trace orbistoun-cli run <title>/eboot.bin # per-call detail
OOPS_LOG=warn,orbistoun_loader=debug orbistoun-cli run <title>/eboot.binOOPS_LOG and RUST_LOG are both read;
OOPS_LOG is the one every tool in the collection answers
to. The levels mean the same everywhere: error is giving
up, warn is a surprise that did not stop the work,
info is an action with a side effect, debug is
decisions, trace is per item.
Preferences
settings - preferences... opens the preferences window. A list of
panes is on the left, in the order below; save writes
config.toml and shell.toml together, and
rescan library reads the folder again. Settings apply to the next
run.
| Pane | Sets |
|---|---|
| general | library folder (and the folder it resolves to), run limit, and the view the window opens in |
| payloads | the background daemon payloads started with each run, one per line, found in the shared payloads folder |
| entry | how control reaches the guest's first instruction: the convention (function or process) and what the first argument register holds. The reporting and handoff choices are diagnostics, and a run under one is not compared with an ordinary run. |
| threads | how many cores the guest is told it has and how many are usable, and how guest affinity requests are handled: observe, map or strict |
| memory | whether direct memory is mapped for real; see memory |
| shell | the machine's users and which one is signed in, the language as a
BCP 47 tag (en-GB), and which button confirms, south or
east |
| controllers | ports, what drives each, and the key for each button; see controllers |
| performance | the frame limit, the most flips a second a run lets through, and how
much of the host a run takes: how many of its cores and its priority
among the host's programs; and the render scale, how many times its size
a title's frames are drawn and shown at (D862); a title's own
frame_limit, host_cores,
host_priority and render_scale settings take
their place for its runs (D835) |
| profiling | what the performance overlay (F3) shows - each phase's share, and how many of the finer spans when the run measures them - whether each run starts the Tracy profiler's client and on which port, and the Tracy tools: where they were found, installing them, and opening the viewer; see profiling with Tracy |
A user's name reaches the guest as text. The language and confirm-button settings reach a guest only through an encoding measured on hardware; a question with no measured encoding is refused and counted rather than answered with an invented value (D311). User identifiers are never reused, because save data is keyed on them.
Mods
A title's mods sit beside it, in its directory's mods,
one directory each (D836):
<title directory>/mods/<name>/
mod.toml optional - enabled = false turns it off; description says what it is
app0/ files laid over the title's own, as its /app0 sees them
patches.toml bytes replaced in the title's executable or its modules once linked
cheats.toml values written into the running title, once or at every flip
In the GUI, mods on the toolbar (or settings, title
mods) lists the selected title's mods with what each changes and a
switch that sets enabled in its mod.toml, and
opens the mods folder to install one.
A patch names its place by its offset from the executable's base, as
a disassembler shows it, the bytes that must be there and the bytes
written instead, as many. module names one of the title's
own modules by file name instead, and the offset is then from that
module's base:
[[patch]]
offset = 0x1a2b3c
original = "74 0e"
bytes = "eb 0e"
description = "skip the intro"
[[patch]]
module = "libSomething.prx" # optional: one of the title's own modules
offset = 0x4410
original = "75 08"
bytes = "90 90"A mod's patches to one module apply all or none: one finding other
bytes than it expects - a mod made for another build of the title -
leaves every patch of that mod to that module unwritten, and the log
says what it found. A patch naming a module the title does not load is
refused by name; a system library orbistoun provides itself, such as
libc.prx, is not one of the title's modules.
A cheat writes a value into the running title, at every flip by default - a frozen value - or once. Its address starts at an offset from the executable's base and follows a pointer chain where it names one, each step reading the eight bytes there as an address and adding the step:
[[cheat]]
offset = 0xcc5000
pointers = [0x18, 0x40] # optional
value = "e7 03 00 00"
every = "flip" # or "once"
description = "999 lives"A step that lands on unmapped memory, or a null pointer - a structure the title has not made yet - is tried again at the next flip; a value is only written where the title itself may write.
Every mod not turned off applies, in the order of the directories'
names, so where two replace the same file the later name's wins. A mod's
files are never written: a staged title's writes land in its own
overlay, over the mods. The run log names the mods it applied, and a mod
whose mod.toml does not parse is left off with the reason.
Orbistoun ships no mods and changes nothing for a title by its id.
Machine profile
orbistoun's Machine presents a platform along four axes
- generation, kind, revision and firmware - configured in the
[machine] table of shell.toml (D394).
| Key | Values | Default |
|---|---|---|
generation |
prospero, orbis |
prospero |
kind |
cex (retail), dex (development kit),
tex (test kit) |
cex |
revision |
base, pro |
base |
firmware |
the system software version, packed as the guest reads it: 12.40 is
0x1240 |
0, unset |
kernel-release |
what kern.osrelease answers |
empty, unset |
The generation, kind and revision default to a retail base
Prospero-generation machine. The version fields refuse by default:
firmware = 0 and an empty kernel-release
refuse the calls that read them, so an unconfigured emulator claims no
particular firmware. software-version,
kernel-version, kernel-sdk-version and
hardware-model follow the same rule.
The reference configuration is a retail Prospero-generation machine on system software 12.40, as measured on hardware:
[machine]
generation = "prospero"
kind = "cex"
revision = "base"
firmware = 4672 # 0x1240 = 12.40
kernel-release = "0.0-prototype" # what kern.osrelease returns on that machineorbistoun-cli run --profile prospero-cex-12.40 presents
that machine, with every measured field, for one run without editing
shell.toml. The profiles are in
crates/orbistoun-shell/data/machine-profiles.toml.