212 lines
6.4 KiB
Markdown
212 lines
6.4 KiB
Markdown
# Cartridges
|
|
|
|
Domain: cartridge package
|
|
Function: normative
|
|
|
|
This chapter defines the cartridge contract consumed by the current runtime.
|
|
|
|
## 1 Scope
|
|
|
|
A cartridge is the distributable unit loaded by firmware/runtime.
|
|
|
|
In the current implementation, the supported dev/runtime form is a directory containing:
|
|
|
|
- `manifest.json`
|
|
- `program.pbx`
|
|
- optional `assets.pa`
|
|
|
|
The loader also recognizes `.pmc` as a future packaged form, but packaged cartridge loading is not implemented yet.
|
|
|
|
## 2 Cartridge Metadata
|
|
|
|
The runtime currently expects the following manifest fields:
|
|
|
|
```json
|
|
{
|
|
"magic": "PMTU",
|
|
"cartridge_version": 1,
|
|
"app_id": 1234,
|
|
"title": "My Game",
|
|
"app_version": "1.0.0",
|
|
"app_mode": "Game"
|
|
}
|
|
```
|
|
|
|
Additional manifest-supported fields include:
|
|
|
|
- `capabilities`
|
|
|
|
## 3 Required Fields
|
|
|
|
Current required manifest fields:
|
|
|
|
- `magic`
|
|
- `cartridge_version`
|
|
- `app_id`
|
|
- `title`
|
|
- `app_version`
|
|
- `app_mode`
|
|
|
|
Current required file payloads:
|
|
|
|
- `program.pbx`
|
|
|
|
Optional file payloads:
|
|
|
|
- `assets.pa`
|
|
|
|
## 4 Runtime Validation Rules
|
|
|
|
The current loader validates:
|
|
|
|
- `magic == "PMTU"`
|
|
- `cartridge_version == 1`
|
|
- manifest parse validity
|
|
- capability normalization
|
|
- presence of `program.pbx`
|
|
- when `Asset` capability is declared, presence of valid `assets.pa` before asset bootstrap
|
|
|
|
If validation fails, cartridge loading is rejected before execution.
|
|
|
|
## 5 App Mode and Boot Protocol
|
|
|
|
`app_mode` controls firmware launch behavior:
|
|
|
|
- `Game`
|
|
- `System`
|
|
|
|
`app_mode` is the runtime profile discriminator. No separate manifest `target`
|
|
field participates in profile selection.
|
|
|
|
Cartridge boot is protocol-driven, not manifest-driven.
|
|
|
|
The executable entrypoint of a valid cartridge is always `func_id = 0`.
|
|
|
|
This means:
|
|
|
|
- `manifest.json` does not select the callable to execute;
|
|
- firmware/runtime loads the cartridge and starts execution from `func_id = 0`;
|
|
- nominal exports may exist for linking or introspection, but they do not hold boot authority.
|
|
|
|
## 5.1 Runtime Profiles
|
|
|
|
`Game` and `System` are distinct runtime profiles.
|
|
|
|
`Game` cartridges use the game pipeline. The game profile owns the public game
|
|
surfaces for frame composition, GFX, game input, banks, sprites, and
|
|
memory-card-style persistence.
|
|
|
|
`System` cartridges use a Runtime/Hub pipeline dedicated to system UI and app
|
|
hosting. The system profile must not inherit the game stdlib or game ABI as its
|
|
public authoring surface. In particular, `System` must not expose
|
|
`FrameComposer`, `Gfx`, game `Input`, banks, sprites, or game memory cards as
|
|
public profile APIs.
|
|
|
|
Future `System` APIs may be transported through syscalls, but syscall transport
|
|
does not define the conceptual ABI boundary. The author-facing contract for
|
|
system apps is a dedicated `System` profile ABI and stdlib/framework.
|
|
|
|
The following contracts are intentionally deferred from this cartridge chapter:
|
|
|
|
- complete WindowManager design;
|
|
- component tree and lifecycle semantics;
|
|
- rich invalidation and transitions;
|
|
- public PBS `System` ABI;
|
|
- multitasking and scheduler semantics;
|
|
- detailed `System` filesystem semantics.
|
|
|
|
The positive filesystem contract for `System` remains owned by the dedicated
|
|
filesystem discussion/spec work. The only profile rule fixed here is negative:
|
|
`System` does not use game memory cards as its public storage model.
|
|
|
|
## 6 Assets and Preload
|
|
|
|
`assets.pa` is the runtime-facing asset artifact consumed by the current runtime.
|
|
|
|
`assets.pa` v1 is an autocontained binary with:
|
|
|
|
- fixed binary prelude;
|
|
- JSON header;
|
|
- binary payload region.
|
|
|
|
The fixed prelude includes, at minimum:
|
|
|
|
- `magic`
|
|
- `schema_version`
|
|
- `header_len`
|
|
- `payload_offset`
|
|
|
|
It may additionally include:
|
|
|
|
- `flags`
|
|
- `reserved`
|
|
- `header_checksum`
|
|
|
|
The JSON header carries:
|
|
|
|
- `asset_table`
|
|
- `preload`
|
|
|
|
`asset_table` and `preload` are therefore no longer the primary runtime contract of `manifest.json`.
|
|
|
|
`preload` is structurally validated as part of `assets.pa` bootstrap:
|
|
|
|
- each preload entry is `{ asset_id, slot }`;
|
|
- `asset_id` uses 32-bit signed integer semantics;
|
|
- each `preload.asset_id` must resolve to an entry in the same `asset_table`;
|
|
- no two preload entries may claim the same `(bank_type, slot)` pair once `bank_type` is resolved from `asset_table`.
|
|
|
|
Runtime lifecycle:
|
|
|
|
- `asset_table` is loaded from `assets.pa` and remains live while the cartridge is running;
|
|
- `preload` is loaded from `assets.pa`, consumed during cartridge initialization, and may be discarded after boot;
|
|
- payload bytes are resolved from the payload region using offsets relative to `payload_offset`.
|
|
|
|
Runtime loading policy:
|
|
|
|
- cartridges without `assets.pa` remain valid when `Asset` capability is not declared;
|
|
- cartridges that declare `Asset` capability must provide valid `assets.pa`;
|
|
- `assets.pa` with invalid preload references or preload slot clashes is structurally invalid;
|
|
- failure must occur as early as cartridge bootstrap, before preload execution.
|
|
|
|
## 7 Runtime Forms
|
|
|
|
### Directory form
|
|
|
|
This is the working runtime/dev form used by the current loader.
|
|
|
|
Directory cartridges are also the only form discovered by the v1 local Home
|
|
games library. When a host provides `--games-root <dir>`, discovery scans only
|
|
immediate child directories under that root. Each child directory is a candidate
|
|
cartridge.
|
|
|
|
For the v1 Home games library:
|
|
|
|
- a candidate must have a valid `manifest.json`;
|
|
- the manifest must declare `app_mode: "Game"`;
|
|
- the library retains the loaded manifest data, `title`, `app_id`,
|
|
`app_version`, the internal cartridge path, and discovery metadata;
|
|
- invalid candidates are logged or reported as diagnostics and omitted from the
|
|
Home list;
|
|
- valid non-Game cartridges are omitted from the Game library.
|
|
|
|
Discovery reads metadata for cataloging. It does not replace the normal
|
|
cartridge loader used when firmware starts the selected cartridge.
|
|
|
|
### Packaged `.pmc` form
|
|
|
|
This form is recognized conceptually by the loader boundary, but its actual load path is not implemented yet.
|
|
|
|
Packaged `.pmc` cartridges are not discovered by the v1 Home games library.
|
|
|
|
The cartridge spec therefore distinguishes:
|
|
|
|
- supported current load form;
|
|
- reserved future distribution form.
|
|
|
|
## 8 Relationship to Other Specs
|
|
|
|
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md) defines how firmware consumes cartridge metadata.
|
|
- [`14-boot-profiles.md`](14-boot-profiles.md) defines cartridge selection at boot.
|
|
- [`15-asset-management.md`](15-asset-management.md) defines the `assets.pa` envelope, asset table semantics, preload lifecycle, and residency semantics.
|