adjustments on docs
This commit is contained in:
parent
1b0e290e1d
commit
f6751a03a4
@ -1,4 +1,4 @@
|
|||||||
//! Canonical bytecode decoder for Prometeu Bytecode (PBC).
|
//! Canonical bytecode decoder for Prometeu Bytecode (PBX payload).
|
||||||
//!
|
//!
|
||||||
//! Single source of truth for instruction decoding used by compiler/linker/verifier/VM.
|
//! Single source of truth for instruction decoding used by compiler/linker/verifier/VM.
|
||||||
//!
|
//!
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
//! Deterministic disassembler for Prometeu Bytecode (PBC).
|
//! Deterministic disassembler for Prometeu Bytecode (PBX payload).
|
||||||
//!
|
//!
|
||||||
//! Goals:
|
//! Goals:
|
||||||
//! - Stable formatting across platforms (snapshot-friendly).
|
//! - Stable formatting across platforms (snapshot-friendly).
|
||||||
|
|||||||
@ -33,7 +33,7 @@ enum Commands {
|
|||||||
#[arg(long, default_value_t = 7777)]
|
#[arg(long, default_value_t = 7777)]
|
||||||
port: u16,
|
port: u16,
|
||||||
},
|
},
|
||||||
/// Compiles a source project into a cartridge (PBC).
|
/// Compiles a source project into a cartridge directory with `program.pbx`.
|
||||||
Build {
|
Build {
|
||||||
/// Project source directory.
|
/// Project source directory.
|
||||||
project_dir: String,
|
project_dir: String,
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
< [Summary](table-of-contents.md) | [Next](chapter-2.md) >
|
# Time Model and Cycles
|
||||||
|
|
||||||
# ⏱️ **Time Model and Cycles**
|
## 1 Overview
|
||||||
|
|
||||||
# 1. Overview
|
|
||||||
|
|
||||||
PROMETEU is a **time-oriented** system.
|
PROMETEU is a **time-oriented** system.
|
||||||
|
|
||||||
@ -250,5 +248,3 @@ The time and cycles model allows teaching:
|
|||||||
- time-oriented architecture
|
- time-oriented architecture
|
||||||
- technical trade-offs
|
- technical trade-offs
|
||||||
- reading real profiles
|
- reading real profiles
|
||||||
|
|
||||||
< [Summary](table-of-contents.md) | [Next](chapter-2.md) >
|
|
||||||
126
docs/runtime/specs/02-vm-instruction-set.md
Normal file
126
docs/runtime/specs/02-vm-instruction-set.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# Prometeu Virtual Machine (PVM)
|
||||||
|
|
||||||
|
This chapter defines the VM as an execution subsystem inside the PROMETEU machine.
|
||||||
|
|
||||||
|
It is intentionally narrower than the broader machine specs:
|
||||||
|
|
||||||
|
- execution model;
|
||||||
|
- opcode families;
|
||||||
|
- verifier boundary;
|
||||||
|
- relationship between the VM and adjacent specs.
|
||||||
|
|
||||||
|
For the bytecode-level instruction contract, see [`../virtual-machine/ISA_CORE.md`](../virtual-machine/ISA_CORE.md).
|
||||||
|
|
||||||
|
## 1 Scope
|
||||||
|
|
||||||
|
The PVM is a **deterministic, stack-based VM** designed for a fantasy console environment with fixed frame timing and explicit hardware-facing services.
|
||||||
|
|
||||||
|
This chapter does not fully restate:
|
||||||
|
|
||||||
|
- detailed value and calling semantics;
|
||||||
|
- heap/gate/GC internals;
|
||||||
|
- coroutine scheduling internals;
|
||||||
|
- host ABI policy.
|
||||||
|
|
||||||
|
Those now live in focused companion specs:
|
||||||
|
|
||||||
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md)
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md)
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md)
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md)
|
||||||
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md)
|
||||||
|
- [`16a-syscall-policies.md`](16a-syscall-policies.md)
|
||||||
|
|
||||||
|
## 2 Core Design Principles
|
||||||
|
|
||||||
|
The PVM is designed around the following constraints:
|
||||||
|
|
||||||
|
1. **Deterministic execution**: no hidden threads or asynchronous callbacks.
|
||||||
|
2. **Frame-based timing**: execution is bounded by frame time and explicit safepoints.
|
||||||
|
3. **Safe memory model**: heap access is mediated by validated handles.
|
||||||
|
4. **Simple compilation target**: stack-based bytecode with verified control flow.
|
||||||
|
5. **Stable ABI**: calls and syscalls follow fixed slot-based contracts.
|
||||||
|
6. **First-class functions**: user function values are represented through closures.
|
||||||
|
|
||||||
|
## 3 Execution Model
|
||||||
|
|
||||||
|
The PVM executes bytecode inside the PROMETEU frame loop.
|
||||||
|
|
||||||
|
Each frame:
|
||||||
|
|
||||||
|
1. firmware enters the VM;
|
||||||
|
2. the VM runs until:
|
||||||
|
- the frame budget is consumed; or
|
||||||
|
- a `FRAME_SYNC` instruction is reached;
|
||||||
|
3. at `FRAME_SYNC`, the VM reaches the primary safepoint for GC and cooperative scheduling;
|
||||||
|
4. control returns to firmware/runtime orchestration.
|
||||||
|
|
||||||
|
`FRAME_SYNC` is the primary VM synchronization point. It is the boundary where the machine can safely account for:
|
||||||
|
|
||||||
|
- GC opportunity;
|
||||||
|
- coroutine handoff;
|
||||||
|
- frame-completion semantics;
|
||||||
|
- deterministic return to firmware.
|
||||||
|
|
||||||
|
## 4 Instruction Families
|
||||||
|
|
||||||
|
The public VM instruction surface is documented at the bytecode level in [`../virtual-machine/ISA_CORE.md`](../virtual-machine/ISA_CORE.md). At the machine/spec level, the instruction families are:
|
||||||
|
|
||||||
|
- execution control:
|
||||||
|
- `NOP`, `HALT`, `JMP`, `JMP_IF_FALSE`, `JMP_IF_TRUE`, `TRAP`, `FRAME_SYNC`
|
||||||
|
- stack manipulation:
|
||||||
|
- `PUSH_CONST`, literal pushes, `POP`, `POP_N`, `DUP`, `SWAP`
|
||||||
|
- arithmetic and logic:
|
||||||
|
- numeric, comparison, boolean, and bitwise operations
|
||||||
|
- variable access:
|
||||||
|
- globals and locals
|
||||||
|
- function calls:
|
||||||
|
- `CALL`, `RET`
|
||||||
|
- function values:
|
||||||
|
- `MAKE_CLOSURE`, `CALL_CLOSURE`
|
||||||
|
- cooperative concurrency:
|
||||||
|
- `SPAWN`, `YIELD`, `SLEEP`
|
||||||
|
- VM/host boundary:
|
||||||
|
- `HOSTCALL`, `SYSCALL`, `INTRINSIC`
|
||||||
|
|
||||||
|
The machine-level rule is simple:
|
||||||
|
|
||||||
|
- opcodes define explicit behavior;
|
||||||
|
- there are no hidden execution paths;
|
||||||
|
- timing-sensitive behavior is exposed through frame and safepoint semantics.
|
||||||
|
|
||||||
|
## 5 Verifier Boundary
|
||||||
|
|
||||||
|
Before execution, bytecode must pass the verifier.
|
||||||
|
|
||||||
|
The verifier ensures, at minimum:
|
||||||
|
|
||||||
|
1. valid instruction decoding;
|
||||||
|
2. valid jump targets;
|
||||||
|
3. consistent stack depth across control-flow joins;
|
||||||
|
4. valid call/return shape;
|
||||||
|
5. closure call safety rules;
|
||||||
|
6. patched syscall and intrinsic validity.
|
||||||
|
|
||||||
|
The verifier is structural. It does not replace runtime validation of dynamic values.
|
||||||
|
|
||||||
|
## 6 Relationship to Adjacent Specs
|
||||||
|
|
||||||
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) defines slot values, tuples, frames, and return-slot semantics.
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md) defines closure representation and function-value behavior.
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines stack/heap, handles, object layout, and GC.
|
||||||
|
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines events, timers, and the frame boundary model.
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine lifecycle and scheduling.
|
||||||
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) defines the syscall ABI boundary.
|
||||||
|
|
||||||
|
## 7 Summary
|
||||||
|
|
||||||
|
The PVM is:
|
||||||
|
|
||||||
|
- stack-based;
|
||||||
|
- deterministic;
|
||||||
|
- frame-synchronized;
|
||||||
|
- verifier-gated;
|
||||||
|
- closure-capable;
|
||||||
|
- coroutine-capable;
|
||||||
|
- embedded inside the larger PROMETEU console model, not equal to it.
|
||||||
99
docs/runtime/specs/02a-vm-values-and-calling-convention.md
Normal file
99
docs/runtime/specs/02a-vm-values-and-calling-convention.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# VM Values and Calling Convention
|
||||||
|
|
||||||
|
This chapter isolates the slot/value model and the rules for calls, returns, tuples, and frames.
|
||||||
|
|
||||||
|
## 1 Value Types
|
||||||
|
|
||||||
|
All runtime values are stored in VM slots as `Value`.
|
||||||
|
|
||||||
|
### Primitive value types
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| ------- | --------------------- |
|
||||||
|
| `int` | 64-bit signed integer |
|
||||||
|
| `bool` | Boolean value |
|
||||||
|
| `float` | 64-bit floating point |
|
||||||
|
|
||||||
|
### Built-in vector and graphics types
|
||||||
|
|
||||||
|
These are treated as VM values with stable layout semantics.
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| ------- | --------------------------------- |
|
||||||
|
| `vec2` | 2D vector (x, y) |
|
||||||
|
| `color` | Packed color value |
|
||||||
|
| `pixel` | Combination of position and color |
|
||||||
|
|
||||||
|
These values:
|
||||||
|
|
||||||
|
- live on the stack;
|
||||||
|
- are copied by value;
|
||||||
|
- do not require heap allocation by themselves.
|
||||||
|
|
||||||
|
### Heap values
|
||||||
|
|
||||||
|
Heap-resident entities are referenced indirectly through handles.
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| -------- | -------------------------- |
|
||||||
|
| `handle` | Reference to a heap object |
|
||||||
|
| `null` | Null handle |
|
||||||
|
|
||||||
|
Handle semantics are defined in [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md).
|
||||||
|
|
||||||
|
## 2 Tuples and Multi-Return ABI
|
||||||
|
|
||||||
|
The PVM supports multi-value returns.
|
||||||
|
|
||||||
|
Tuple rules:
|
||||||
|
|
||||||
|
- tuples are stack-only;
|
||||||
|
- tuples are not heap objects by default;
|
||||||
|
- tuple persistence requires explicit boxing into a heap representation when such a representation exists in the language/toolchain;
|
||||||
|
- return shape is part of the function contract.
|
||||||
|
|
||||||
|
## 3 Call Convention
|
||||||
|
|
||||||
|
Each function declares a fixed return-slot shape.
|
||||||
|
|
||||||
|
At call time:
|
||||||
|
|
||||||
|
1. the caller prepares arguments;
|
||||||
|
2. `CALL` transfers control;
|
||||||
|
3. the callee executes under its frame contract;
|
||||||
|
4. `RET` leaves exactly the declared return-slot shape on the stack.
|
||||||
|
|
||||||
|
The verifier ensures:
|
||||||
|
|
||||||
|
- all reachable return paths agree on return-slot count;
|
||||||
|
- stack depth remains coherent across the function body.
|
||||||
|
|
||||||
|
## 4 Call Stack and Frames
|
||||||
|
|
||||||
|
The VM uses a call stack.
|
||||||
|
|
||||||
|
Conceptual frame shape:
|
||||||
|
|
||||||
|
```
|
||||||
|
Frame {
|
||||||
|
return_pc
|
||||||
|
base_pointer
|
||||||
|
ret_slots
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Execution uses the public call instructions:
|
||||||
|
|
||||||
|
| Opcode | Description |
|
||||||
|
| ------ | ---------------------- |
|
||||||
|
| `CALL` | Calls a function by id |
|
||||||
|
| `RET` | Returns from function |
|
||||||
|
|
||||||
|
There is no separate public ISA for manual frame stack manipulation.
|
||||||
|
|
||||||
|
## 5 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines the VM execution subsystem at a higher level.
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md) defines first-class function values.
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines stack/heap and handle-backed objects.
|
||||||
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) reuses the same slot-oriented argument/return philosophy for syscalls.
|
||||||
67
docs/runtime/specs/02b-vm-function-values-and-closures.md
Normal file
67
docs/runtime/specs/02b-vm-function-values-and-closures.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# VM Function Values and Closures
|
||||||
|
|
||||||
|
This chapter defines how the PVM models first-class function values.
|
||||||
|
|
||||||
|
## 1 First-Class Function Model
|
||||||
|
|
||||||
|
The PVM treats user function values as closures.
|
||||||
|
|
||||||
|
This means:
|
||||||
|
|
||||||
|
- functions can be stored in variables;
|
||||||
|
- functions can be passed as arguments;
|
||||||
|
- functions can be returned from other functions;
|
||||||
|
- function values carry explicit runtime representation.
|
||||||
|
|
||||||
|
Even functions without captures may be represented as closures with an empty capture set.
|
||||||
|
|
||||||
|
## 2 Closure Layout
|
||||||
|
|
||||||
|
Closures are heap objects.
|
||||||
|
|
||||||
|
Conceptual layout:
|
||||||
|
|
||||||
|
```
|
||||||
|
Closure {
|
||||||
|
func_id
|
||||||
|
captures[]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Captures may be:
|
||||||
|
|
||||||
|
- copied values;
|
||||||
|
- handles to heap objects.
|
||||||
|
|
||||||
|
Closure environments are part of the GC root graph as long as the closure remains reachable.
|
||||||
|
|
||||||
|
## 3 Direct and Indirect Calls
|
||||||
|
|
||||||
|
The PVM supports two forms of invocation:
|
||||||
|
|
||||||
|
| Opcode | Description |
|
||||||
|
| -------------- | -------------------------------------- |
|
||||||
|
| `CALL` | Direct call by function id |
|
||||||
|
| `CALL_CLOSURE` | Indirect call through a closure handle |
|
||||||
|
|
||||||
|
For `CALL_CLOSURE`:
|
||||||
|
|
||||||
|
1. the closure handle is read from the stack;
|
||||||
|
2. the VM resolves the target function;
|
||||||
|
3. captured environment state becomes available to the callee according to the closure calling convention.
|
||||||
|
|
||||||
|
## 4 Verification and Safety
|
||||||
|
|
||||||
|
The verifier ensures, at minimum:
|
||||||
|
|
||||||
|
- closure call sites have coherent arity;
|
||||||
|
- invalid closure call shapes are rejected or trapped according to the verifier/runtime boundary;
|
||||||
|
- return-slot contracts remain valid.
|
||||||
|
|
||||||
|
Handle validity, heap reachability, and dynamic misuse remain subject to runtime checks where static proof is not possible.
|
||||||
|
|
||||||
|
## 5 Relationship to Memory and GC
|
||||||
|
|
||||||
|
- Closure objects live in heap memory, so their object model is constrained by [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md).
|
||||||
|
- Captured heap references participate in the GC root graph.
|
||||||
|
- Closures are function values, not syscalls; syscall calls remain a separate non-first-class boundary defined in [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md).
|
||||||
189
docs/runtime/specs/03-memory-stack-heap-and-allocation.md
Normal file
189
docs/runtime/specs/03-memory-stack-heap-and-allocation.md
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# Memory Model
|
||||||
|
|
||||||
|
This chapter defines the VM memory architecture: stack, heap, handles, object layout, allocation, and garbage collection.
|
||||||
|
|
||||||
|
It intentionally focuses on VM-managed memory.
|
||||||
|
|
||||||
|
Host-owned memory surfaces such as asset banks and persistent save storage are covered by their own domain specs and by the host ABI docs.
|
||||||
|
|
||||||
|
## 1 Overview
|
||||||
|
|
||||||
|
The PVM memory model is based on:
|
||||||
|
|
||||||
|
- stack-resident execution values;
|
||||||
|
- heap-resident objects;
|
||||||
|
- validated handles for indirect heap access;
|
||||||
|
- GC-managed object lifetime.
|
||||||
|
|
||||||
|
## 2 Stack Memory
|
||||||
|
|
||||||
|
The stack stores transient execution values and frame-scoped data.
|
||||||
|
|
||||||
|
### Stack value types
|
||||||
|
|
||||||
|
The stack may contain:
|
||||||
|
|
||||||
|
- primitive values;
|
||||||
|
- built-in fixed-layout values;
|
||||||
|
- heap handles;
|
||||||
|
- tuple-shaped multi-return values.
|
||||||
|
|
||||||
|
See [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) for the slot/value model.
|
||||||
|
|
||||||
|
### Stack properties
|
||||||
|
|
||||||
|
- stack values are local to execution state;
|
||||||
|
- stack discipline is verifier-sensitive;
|
||||||
|
- stack underflow and invalid access are traps.
|
||||||
|
|
||||||
|
## 3 Heap Memory
|
||||||
|
|
||||||
|
The heap stores runtime objects that require identity and reachability tracking.
|
||||||
|
|
||||||
|
### Heap characteristics
|
||||||
|
|
||||||
|
- user objects live in the heap;
|
||||||
|
- arrays and closures live in the heap;
|
||||||
|
- heap access is indirect through handles;
|
||||||
|
- the collector is non-moving in the baseline model.
|
||||||
|
|
||||||
|
## 4 Handles and Gate Table
|
||||||
|
|
||||||
|
All heap objects are accessed via handles.
|
||||||
|
|
||||||
|
A conceptual handle:
|
||||||
|
|
||||||
|
```
|
||||||
|
handle = { index, generation }
|
||||||
|
```
|
||||||
|
|
||||||
|
Conceptual gate entry:
|
||||||
|
|
||||||
|
```
|
||||||
|
GateEntry {
|
||||||
|
alive: bool
|
||||||
|
generation: u32
|
||||||
|
base: usize
|
||||||
|
slots: u32
|
||||||
|
type_id: u32
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Handle safety
|
||||||
|
|
||||||
|
When an object is freed:
|
||||||
|
|
||||||
|
- `alive` becomes false;
|
||||||
|
- `generation` is incremented.
|
||||||
|
|
||||||
|
When a handle is used:
|
||||||
|
|
||||||
|
- the index must exist;
|
||||||
|
- the generation must match;
|
||||||
|
- invalid or stale handles trap.
|
||||||
|
|
||||||
|
This prevents:
|
||||||
|
|
||||||
|
- use-after-free;
|
||||||
|
- stale references;
|
||||||
|
- hidden raw memory access.
|
||||||
|
|
||||||
|
## 5 Object Layout
|
||||||
|
|
||||||
|
Heap objects use explicit, implementation-visible layout rules.
|
||||||
|
|
||||||
|
Conceptual form:
|
||||||
|
|
||||||
|
```
|
||||||
|
Object {
|
||||||
|
type_id
|
||||||
|
field_0
|
||||||
|
field_1
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
|
||||||
|
- fields are stored in slot order;
|
||||||
|
- there is no raw pointer arithmetic in the VM model;
|
||||||
|
- layout rules are explicit and verifier/runtime-friendly.
|
||||||
|
|
||||||
|
Closures and coroutine-owned state may build on top of this memory model, but their behavioral rules are documented separately:
|
||||||
|
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md)
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md)
|
||||||
|
|
||||||
|
## 6 Garbage Collection
|
||||||
|
|
||||||
|
The PVM uses a **mark-sweep collector**.
|
||||||
|
|
||||||
|
### GC properties
|
||||||
|
|
||||||
|
- non-moving in the baseline model;
|
||||||
|
- runs only at safepoints;
|
||||||
|
- primary safepoint: `FRAME_SYNC`.
|
||||||
|
|
||||||
|
### GC triggers
|
||||||
|
|
||||||
|
GC may run when:
|
||||||
|
|
||||||
|
- heap usage exceeds threshold;
|
||||||
|
- allocation pressure is high.
|
||||||
|
|
||||||
|
### Root set
|
||||||
|
|
||||||
|
The collector marks from:
|
||||||
|
|
||||||
|
- operand stack;
|
||||||
|
- call stack frames;
|
||||||
|
- global variables;
|
||||||
|
- coroutine-owned execution state;
|
||||||
|
- closure environments;
|
||||||
|
- host-held roots where the host legally retains VM heap references.
|
||||||
|
|
||||||
|
## 7 Allocation and Deallocation
|
||||||
|
|
||||||
|
### Allocation
|
||||||
|
|
||||||
|
Heap allocation conceptually performs:
|
||||||
|
|
||||||
|
1. reserve object storage;
|
||||||
|
2. create or reuse gate entry;
|
||||||
|
3. return validated handle.
|
||||||
|
|
||||||
|
If allocation fails:
|
||||||
|
|
||||||
|
- the VM may trigger GC;
|
||||||
|
- if pressure remains unresolved, allocation may trap or fail according to the runtime contract.
|
||||||
|
|
||||||
|
### Deallocation
|
||||||
|
|
||||||
|
Objects are reclaimed by GC.
|
||||||
|
|
||||||
|
When reclaimed:
|
||||||
|
|
||||||
|
- the gate is marked dead;
|
||||||
|
- the generation is incremented;
|
||||||
|
- storage becomes reusable.
|
||||||
|
|
||||||
|
## 8 Memory Safety Rules
|
||||||
|
|
||||||
|
The VM enforces:
|
||||||
|
|
||||||
|
1. all heap access goes through handles;
|
||||||
|
2. generation checks validate handle freshness;
|
||||||
|
3. object and field access is bounds-checked;
|
||||||
|
4. there is no guest-visible raw pointer arithmetic;
|
||||||
|
5. stack discipline remains verifier-constrained.
|
||||||
|
|
||||||
|
Any violation results in a trap or rejected program image.
|
||||||
|
|
||||||
|
## 9 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) defines stack values and tuple/call-slot semantics.
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md) defines closure function values.
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine state and scheduling behavior.
|
||||||
|
- [`15-asset-management.md`](15-asset-management.md) defines asset-bank surfaces outside VM heap ownership.
|
||||||
|
- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md) defines save storage outside VM heap ownership.
|
||||||
|
- [`16a-syscall-policies.md`](16a-syscall-policies.md) defines host-root rules and host/heap interaction policy.
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >
|
# GFX Peripheral (Graphics System)
|
||||||
|
|
||||||
# 🎨 **GFX Peripheral (Graphics System)**
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -596,5 +594,3 @@ PROMETEU's GFX is simple **by choice**, not by limitation.
|
|||||||
- Layer = tilemap + cache + scroll
|
- Layer = tilemap + cache + scroll
|
||||||
- Rasterized projection per frame
|
- Rasterized projection per frame
|
||||||
- Depth defined by drawing order
|
- Depth defined by drawing order
|
||||||
|
|
||||||
< [Back](chapter-3.md) | [Summary](table-of-contents.md) | [Next](chapter-5.md) >
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
|
# Audio Peripheral (Audio System)
|
||||||
|
|
||||||
# 🔊 AUDIO Peripheral (Audio System)
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -327,5 +325,3 @@ But abstracted for:
|
|||||||
- Explicit mixer
|
- Explicit mixer
|
||||||
- "Audio CPU" concept
|
- "Audio CPU" concept
|
||||||
- Implementation is the host's role
|
- Implementation is the host's role
|
||||||
|
|
||||||
< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >
|
# Input Peripheral (Input System)
|
||||||
|
|
||||||
# 🎮 **INPUT Peripheral (Input System)**
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -256,5 +254,3 @@ With clear and reproducible feedback.
|
|||||||
- queries have an explicit cost
|
- queries have an explicit cost
|
||||||
- input participates in the CAP
|
- input participates in the CAP
|
||||||
- model is deterministic
|
- model is deterministic
|
||||||
|
|
||||||
< [Back](chapter-5.md) | [Summary](table-of-contents.md) | [Next](chapter-7.md) >
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >
|
# Touch Peripheral (Absolute Pointer Input System)
|
||||||
|
|
||||||
# 🖐️ TOUCH Peripheral (Absolute Pointer Input System)
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -258,5 +256,3 @@ The TOUCH in PROMETEU is:
|
|||||||
- predictable
|
- predictable
|
||||||
- universal
|
- universal
|
||||||
- deterministic
|
- deterministic
|
||||||
|
|
||||||
< [Back](chapter-6.md) | [Summary](table-of-contents.md) | [Next](chapter-8.md) >
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >
|
# Save Memory and MEMCARD
|
||||||
|
|
||||||
# 📀 MEMCARD Peripheral (Save/Load System)
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -234,5 +232,3 @@ The MEMCARD peripheral in PROMETEU:
|
|||||||
- is simple to use
|
- is simple to use
|
||||||
- is hard to abuse
|
- is hard to abuse
|
||||||
- grows without breaking compatibility
|
- grows without breaking compatibility
|
||||||
|
|
||||||
< [Back](chapter-7.md) | [Summary](table-of-contents.md) | [Next](chapter-9.md) >
|
|
||||||
120
docs/runtime/specs/09-events-and-concurrency.md
Normal file
120
docs/runtime/specs/09-events-and-concurrency.md
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
# Events and Scheduling
|
||||||
|
|
||||||
|
This chapter defines events, timers, faults, and the frame-boundary model of the PROMETEU machine.
|
||||||
|
|
||||||
|
Coroutine lifecycle and cooperative scheduling details now live in a dedicated companion chapter.
|
||||||
|
|
||||||
|
## 1 Core Philosophy
|
||||||
|
|
||||||
|
PROMETEU does not model hidden asynchronous execution.
|
||||||
|
|
||||||
|
Machine-visible event behavior is based on:
|
||||||
|
|
||||||
|
- explicit frame steps;
|
||||||
|
- deterministic delivery points;
|
||||||
|
- observable costs;
|
||||||
|
- no surprise callbacks.
|
||||||
|
|
||||||
|
## 2 Events
|
||||||
|
|
||||||
|
### 2.1 Definition
|
||||||
|
|
||||||
|
Events are machine-level facts made visible to the system in controlled phases.
|
||||||
|
|
||||||
|
Examples include:
|
||||||
|
|
||||||
|
- input state changes;
|
||||||
|
- timer expiry;
|
||||||
|
- host-signaled machine events;
|
||||||
|
- fault publication at the machine boundary.
|
||||||
|
|
||||||
|
### 2.2 Event Queue
|
||||||
|
|
||||||
|
Events are conceptually queued and processed at known synchronization points.
|
||||||
|
|
||||||
|
The machine model forbids arbitrary guest code execution at event arrival time.
|
||||||
|
|
||||||
|
## 3 Frame Boundary (Sync Phase)
|
||||||
|
|
||||||
|
The frame boundary is the primary global synchronization point of the machine.
|
||||||
|
|
||||||
|
At this phase, the system may:
|
||||||
|
|
||||||
|
- sample input;
|
||||||
|
- deliver pending events;
|
||||||
|
- account for frame-level work;
|
||||||
|
- coordinate VM/runtime/firmware transitions around `FRAME_SYNC`.
|
||||||
|
|
||||||
|
This preserves determinism and keeps machine behavior legible.
|
||||||
|
|
||||||
|
## 4 System Events vs System Faults
|
||||||
|
|
||||||
|
### 4.1 Normal events
|
||||||
|
|
||||||
|
Normal events report machine state changes without implying system failure.
|
||||||
|
|
||||||
|
### 4.2 System faults
|
||||||
|
|
||||||
|
System faults are not ordinary events.
|
||||||
|
|
||||||
|
When a terminal fault occurs:
|
||||||
|
|
||||||
|
- execution stops or transitions to fault-handling flow;
|
||||||
|
- diagnostics are produced;
|
||||||
|
- the fault is not treated like a recoverable guest event queue item.
|
||||||
|
|
||||||
|
## 5 Timers
|
||||||
|
|
||||||
|
Timers are modeled as frame-based counters.
|
||||||
|
|
||||||
|
Properties:
|
||||||
|
|
||||||
|
- measured in frames, not wall-clock time;
|
||||||
|
- deterministic across runs;
|
||||||
|
- integrated with the frame model rather than hidden interrupts.
|
||||||
|
|
||||||
|
Timers do not execute code by themselves; they make state or events available to be observed at deterministic boundaries.
|
||||||
|
|
||||||
|
## 6 Relationship Between Events and the Frame Loop
|
||||||
|
|
||||||
|
High-level structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
FRAME N
|
||||||
|
------------------------
|
||||||
|
Sample Input
|
||||||
|
Deliver Events
|
||||||
|
Run VM until:
|
||||||
|
- budget exhausted, or
|
||||||
|
- FRAME_SYNC reached
|
||||||
|
Sync Phase
|
||||||
|
------------------------
|
||||||
|
```
|
||||||
|
|
||||||
|
Important properties:
|
||||||
|
|
||||||
|
- events are processed at known points;
|
||||||
|
- no execution occurs outside the frame loop;
|
||||||
|
- frame structure remains observable for tooling and certification.
|
||||||
|
|
||||||
|
## 7 Determinism and Best Practices
|
||||||
|
|
||||||
|
PROMETEU encourages:
|
||||||
|
|
||||||
|
- treating events as data;
|
||||||
|
- querying state explicitly;
|
||||||
|
- structuring logic around frame boundaries;
|
||||||
|
- avoiding implicit control flow hidden behind event delivery.
|
||||||
|
|
||||||
|
PROMETEU discourages:
|
||||||
|
|
||||||
|
- asynchronous callback simulation;
|
||||||
|
- hidden timing channels;
|
||||||
|
- ambiguous out-of-band execution.
|
||||||
|
|
||||||
|
## 8 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md) defines coroutine lifecycle and scheduling behavior.
|
||||||
|
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines observability and diagnostics surfaces.
|
||||||
|
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md) defines firmware orchestration at machine level.
|
||||||
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines VM execution inside this frame model.
|
||||||
104
docs/runtime/specs/09a-coroutines-and-cooperative-scheduling.md
Normal file
104
docs/runtime/specs/09a-coroutines-and-cooperative-scheduling.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# Coroutines and Cooperative Scheduling
|
||||||
|
|
||||||
|
This chapter isolates PROMETEU coroutine semantics from the broader event/frame model.
|
||||||
|
|
||||||
|
## 1 Coroutine Model
|
||||||
|
|
||||||
|
PROMETEU provides coroutines as the only guest-visible concurrency model.
|
||||||
|
|
||||||
|
Coroutines are:
|
||||||
|
|
||||||
|
- cooperative;
|
||||||
|
- deterministic;
|
||||||
|
- scheduled only at safepoints;
|
||||||
|
- never preemptive.
|
||||||
|
|
||||||
|
There is:
|
||||||
|
|
||||||
|
- no parallel execution;
|
||||||
|
- no hidden threads;
|
||||||
|
- no scheduler behavior outside explicit machine rules.
|
||||||
|
|
||||||
|
## 2 Coroutine Lifecycle
|
||||||
|
|
||||||
|
Each coroutine can be in one of the following states:
|
||||||
|
|
||||||
|
- `Ready`
|
||||||
|
- `Running`
|
||||||
|
- `Sleeping`
|
||||||
|
- `Finished`
|
||||||
|
|
||||||
|
Coroutine-local execution state includes, conceptually:
|
||||||
|
|
||||||
|
```
|
||||||
|
Coroutine {
|
||||||
|
call_stack
|
||||||
|
operand_stack
|
||||||
|
state
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3 Scheduling
|
||||||
|
|
||||||
|
At each eligible scheduling boundary:
|
||||||
|
|
||||||
|
1. the scheduler selects the next coroutine;
|
||||||
|
2. ordering remains deterministic;
|
||||||
|
3. execution continues within the frame-budget model.
|
||||||
|
|
||||||
|
Baseline policy:
|
||||||
|
|
||||||
|
- round-robin or equivalent deterministic ordering;
|
||||||
|
- no surprise priority inversion hidden from the model;
|
||||||
|
- no preemption between safepoints.
|
||||||
|
|
||||||
|
## 4 Coroutine Operations
|
||||||
|
|
||||||
|
Typical operations:
|
||||||
|
|
||||||
|
| Operation | Description |
|
||||||
|
| --------- | ----------------------------- |
|
||||||
|
| `spawn` | Create a coroutine |
|
||||||
|
| `yield` | Voluntarily suspend execution |
|
||||||
|
| `sleep` | Suspend for N frames |
|
||||||
|
|
||||||
|
`yield` and `sleep` only take effect at safepoints.
|
||||||
|
|
||||||
|
## 5 Interaction with the Frame Loop
|
||||||
|
|
||||||
|
Coroutine scheduling happens inside the frame model, not beside it.
|
||||||
|
|
||||||
|
Conceptually:
|
||||||
|
|
||||||
|
```
|
||||||
|
FRAME N
|
||||||
|
------------------------
|
||||||
|
Sample Input
|
||||||
|
Deliver Events
|
||||||
|
Schedule Coroutine
|
||||||
|
Run VM
|
||||||
|
FRAME_SYNC
|
||||||
|
------------------------
|
||||||
|
```
|
||||||
|
|
||||||
|
This preserves:
|
||||||
|
|
||||||
|
- deterministic replay;
|
||||||
|
- explicit cost accounting;
|
||||||
|
- consistent host/runtime handoff.
|
||||||
|
|
||||||
|
## 6 Costs and Determinism
|
||||||
|
|
||||||
|
Coroutine management:
|
||||||
|
|
||||||
|
- consumes cycles;
|
||||||
|
- contributes to certification/cost reporting;
|
||||||
|
- remains part of the deterministic execution trace.
|
||||||
|
|
||||||
|
Nothing about scheduling is "free" or hidden.
|
||||||
|
|
||||||
|
## 7 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines the broader frame/event model.
|
||||||
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines coroutine-related instruction families.
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines coroutine-owned execution state in the memory model.
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >
|
# Debug, Inspection, and Profiling
|
||||||
|
|
||||||
# 🛠️ **Debug, Inspection, and Profiling**
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -81,7 +79,7 @@ No mode alters the logical result of the program.
|
|||||||
|
|
||||||
### 4.1 Pause and Resume
|
### 4.1 Pause and Resume
|
||||||
|
|
||||||
The system can be paused at safe points:
|
The system can be paused at safepoints:
|
||||||
|
|
||||||
- frame start
|
- frame start
|
||||||
- before UPDATE
|
- before UPDATE
|
||||||
@ -287,13 +285,13 @@ Execution can pause when:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Event and Interrupt Debugging
|
## 10. Event and Fault Debugging
|
||||||
|
|
||||||
PROMETEU allows observing:
|
PROMETEU allows observing:
|
||||||
|
|
||||||
- event queue
|
- event queue
|
||||||
- active timers
|
- active timers
|
||||||
- occurred interrupts
|
- published system faults
|
||||||
|
|
||||||
Each event has:
|
Each event has:
|
||||||
|
|
||||||
@ -346,5 +344,3 @@ The student learns:
|
|||||||
- profiling is deterministic
|
- profiling is deterministic
|
||||||
- time and memory are visible
|
- time and memory are visible
|
||||||
- certification is evidence-based
|
- certification is evidence-based
|
||||||
|
|
||||||
< [Back](chapter-9.md) | [Summary](table-of-contents.md) | [Next](chapter-11.md) >
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
< [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >
|
# Portability Guarantees and Cross-Platform Execution
|
||||||
|
|
||||||
# 🌍 **Portability Guarantees and Cross-Platform Execution**
|
|
||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
@ -254,5 +252,3 @@ The student learns:
|
|||||||
- input, audio, and graphics are abstracted
|
- input, audio, and graphics are abstracted
|
||||||
- certification is universal
|
- certification is universal
|
||||||
- portability is guaranteed by design
|
- portability is guaranteed by design
|
||||||
|
|
||||||
< [Back](chapter-10.md) | [Summary](table-of-contents.md) | [Next](chapter-12.md) >
|
|
||||||
133
docs/runtime/specs/12-firmware-pos-and-prometeuhub.md
Normal file
133
docs/runtime/specs/12-firmware-pos-and-prometeuhub.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# Firmware - POS and PrometeuHub
|
||||||
|
|
||||||
|
This chapter defines the firmware layer of the PROMETEU machine.
|
||||||
|
|
||||||
|
It covers:
|
||||||
|
|
||||||
|
- machine authority above the VM;
|
||||||
|
- POS responsibilities;
|
||||||
|
- Hub responsibilities;
|
||||||
|
- firmware states and cartridge launch flow.
|
||||||
|
|
||||||
|
## 1 Firmware Scope
|
||||||
|
|
||||||
|
The PROMETEU firmware is composed of two cooperating layers:
|
||||||
|
|
||||||
|
- **PrometeuOS (POS)**: the machine authority responsible for boot, VM/runtime orchestration, peripherals, crash handling, and system-level policy;
|
||||||
|
- **PrometeuHub**: the launcher/UI layer that runs over POS and uses the system window model.
|
||||||
|
|
||||||
|
The VM does not own the machine lifecycle. Firmware does.
|
||||||
|
|
||||||
|
## 2 Terms
|
||||||
|
|
||||||
|
- **Host**: the real platform that drives the core loop and presents output.
|
||||||
|
- **POS**: system firmware/core authority.
|
||||||
|
- **PrometeuHub**: launcher and system UI running over POS.
|
||||||
|
- **PVM**: the VM subsystem that executes cartridge bytecode.
|
||||||
|
- **Cartridge**: the executable package loaded by firmware.
|
||||||
|
- **AppMode**: cartridge mode, currently `Game` or `System`.
|
||||||
|
- **Logical frame**: execution unit completed when the app reaches `FRAME_SYNC`.
|
||||||
|
- **Host tick**: the host-driven outer update tick.
|
||||||
|
|
||||||
|
## 3 POS Responsibilities
|
||||||
|
|
||||||
|
POS is responsible for:
|
||||||
|
|
||||||
|
- deterministic reset into known machine state;
|
||||||
|
- VM initialization and teardown for cartridge execution;
|
||||||
|
- input latching and logical-frame budgeting;
|
||||||
|
- peripheral reset/orchestration;
|
||||||
|
- fault capture and crash-flow transition;
|
||||||
|
- return to Hub after app exit or crash.
|
||||||
|
|
||||||
|
At the VM boundary, POS must preserve:
|
||||||
|
|
||||||
|
- logical-frame semantics;
|
||||||
|
- `FRAME_SYNC` as the canonical frame boundary;
|
||||||
|
- deterministic transition from host tick to VM slice execution.
|
||||||
|
|
||||||
|
## 4 PrometeuHub Responsibilities
|
||||||
|
|
||||||
|
PrometeuHub is responsible for:
|
||||||
|
|
||||||
|
- presenting available apps;
|
||||||
|
- reading cartridge metadata needed for launch decisions;
|
||||||
|
- deciding launch behavior based on `AppMode`;
|
||||||
|
- managing the system window surface for system-mode apps.
|
||||||
|
|
||||||
|
The Hub does not execute bytecode directly. It always delegates execution setup to POS.
|
||||||
|
|
||||||
|
## 5 App Modes
|
||||||
|
|
||||||
|
### Game
|
||||||
|
|
||||||
|
Game-mode cartridges:
|
||||||
|
|
||||||
|
- transition firmware into the game-running state;
|
||||||
|
- run as the active app flow;
|
||||||
|
- present through the main frame path.
|
||||||
|
|
||||||
|
### System
|
||||||
|
|
||||||
|
System-mode cartridges:
|
||||||
|
|
||||||
|
- are initialized by POS;
|
||||||
|
- are integrated into the Hub/window environment;
|
||||||
|
- do not replace the firmware state with the game-running path.
|
||||||
|
|
||||||
|
## 6 Cartridge Load Flow
|
||||||
|
|
||||||
|
Current high-level flow:
|
||||||
|
|
||||||
|
1. POS receives a cartridge to load;
|
||||||
|
2. asset manager is initialized from the cartridge asset table, preload list, and packed asset bytes;
|
||||||
|
3. POS initializes the VM/runtime for the cartridge;
|
||||||
|
4. launch behavior branches by `AppMode`:
|
||||||
|
- `Game` -> transition to the game-running firmware state;
|
||||||
|
- `System` -> create/focus a Hub window and return to the Hub state.
|
||||||
|
|
||||||
|
If VM initialization fails, firmware transitions to the crash path.
|
||||||
|
|
||||||
|
## 7 Firmware States
|
||||||
|
|
||||||
|
The current firmware state model includes:
|
||||||
|
|
||||||
|
- `Reset`
|
||||||
|
- `SplashScreen`
|
||||||
|
- `LaunchHub`
|
||||||
|
- `HubHome`
|
||||||
|
- `LoadCartridge`
|
||||||
|
- `GameRunning`
|
||||||
|
- `AppCrashes`
|
||||||
|
|
||||||
|
These states express machine orchestration above the VM. They are not guest-visible bytecode states.
|
||||||
|
|
||||||
|
## 8 Execution Contract
|
||||||
|
|
||||||
|
For game-mode execution, firmware/runtime coordination preserves:
|
||||||
|
|
||||||
|
- input latched per logical frame;
|
||||||
|
- execution in host-driven slices until `FRAME_SYNC`;
|
||||||
|
- present only when a logical frame completes;
|
||||||
|
- no frame present when budget ends before `FRAME_SYNC`.
|
||||||
|
|
||||||
|
This keeps the machine model deterministic and observable.
|
||||||
|
|
||||||
|
## 9 Crash Handling
|
||||||
|
|
||||||
|
Firmware owns terminal fault presentation.
|
||||||
|
|
||||||
|
When a terminal app fault occurs:
|
||||||
|
|
||||||
|
- POS captures the crash report;
|
||||||
|
- firmware leaves normal app execution flow;
|
||||||
|
- the machine transitions to `AppCrashes`.
|
||||||
|
|
||||||
|
Crash handling is outside the guest VM execution model.
|
||||||
|
|
||||||
|
## 10 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines the VM subsystem run by firmware.
|
||||||
|
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines the frame-boundary model used by firmware.
|
||||||
|
- [`13-cartridge.md`](13-cartridge.md) defines cartridge structure and metadata consumed by firmware.
|
||||||
|
- [`14-boot-profiles.md`](14-boot-profiles.md) defines startup target selection.
|
||||||
108
docs/runtime/specs/13-cartridge.md
Normal file
108
docs/runtime/specs/13-cartridge.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Cartridges
|
||||||
|
|
||||||
|
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",
|
||||||
|
"entrypoint": "main"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional manifest-supported fields include:
|
||||||
|
|
||||||
|
- `capabilities`
|
||||||
|
- `asset_table`
|
||||||
|
- `preload`
|
||||||
|
|
||||||
|
## 3 Required Fields
|
||||||
|
|
||||||
|
Current required manifest fields:
|
||||||
|
|
||||||
|
- `magic`
|
||||||
|
- `cartridge_version`
|
||||||
|
- `app_id`
|
||||||
|
- `title`
|
||||||
|
- `app_version`
|
||||||
|
- `app_mode`
|
||||||
|
- `entrypoint`
|
||||||
|
|
||||||
|
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`
|
||||||
|
|
||||||
|
If validation fails, cartridge loading is rejected before execution.
|
||||||
|
|
||||||
|
## 5 App Mode and Entrypoint
|
||||||
|
|
||||||
|
`app_mode` controls firmware launch behavior:
|
||||||
|
|
||||||
|
- `Game`
|
||||||
|
- `System`
|
||||||
|
|
||||||
|
`entrypoint` is passed to the VM initialization flow and may be resolved as a symbol or function identifier according to the VM/runtime contract.
|
||||||
|
|
||||||
|
## 6 Assets and Preload
|
||||||
|
|
||||||
|
If present, the manifest may provide:
|
||||||
|
|
||||||
|
- `asset_table`: runtime asset descriptors;
|
||||||
|
- `preload`: initial residency requests.
|
||||||
|
|
||||||
|
If `assets.pa` exists, its bytes become the cartridge asset payload used by the asset manager during cartridge initialization.
|
||||||
|
|
||||||
|
## 7 Runtime Forms
|
||||||
|
|
||||||
|
### Directory form
|
||||||
|
|
||||||
|
This is the working runtime/dev form used by the current loader.
|
||||||
|
|
||||||
|
### Packaged `.pmc` form
|
||||||
|
|
||||||
|
This form is recognized conceptually by the loader boundary, but its actual load path is not implemented yet.
|
||||||
|
|
||||||
|
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 asset table and residency semantics.
|
||||||
82
docs/runtime/specs/14-boot-profiles.md
Normal file
82
docs/runtime/specs/14-boot-profiles.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# Boot Profiles
|
||||||
|
|
||||||
|
This chapter defines how PROMETEU chooses what to execute at startup.
|
||||||
|
|
||||||
|
## 1 Boot Target
|
||||||
|
|
||||||
|
The current firmware-side boot target concept is:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
enum BootTarget {
|
||||||
|
Hub,
|
||||||
|
Cartridge { path: String, debug: bool, debug_port: u16 },
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a firmware/host orchestration contract, not a guest-visible ABI.
|
||||||
|
|
||||||
|
## 2 Boot Modes
|
||||||
|
|
||||||
|
### Hub
|
||||||
|
|
||||||
|
When the boot target is `Hub`:
|
||||||
|
|
||||||
|
- firmware boots into the Hub flow;
|
||||||
|
- no cartridge is auto-launched.
|
||||||
|
|
||||||
|
### Cartridge
|
||||||
|
|
||||||
|
When the boot target is `Cartridge`:
|
||||||
|
|
||||||
|
1. firmware loads the requested cartridge;
|
||||||
|
2. cartridge metadata is read;
|
||||||
|
3. launch behavior follows cartridge `app_mode`.
|
||||||
|
|
||||||
|
## 3 Launch Resolution by App Mode
|
||||||
|
|
||||||
|
For a cartridge boot target:
|
||||||
|
|
||||||
|
- `Game` cartridges transition into game-running flow;
|
||||||
|
- `System` cartridges are initialized and integrated into the Hub/window path.
|
||||||
|
|
||||||
|
This preserves the distinction between machine firmware state and app execution mode.
|
||||||
|
|
||||||
|
## 4 Host CLI Relationship
|
||||||
|
|
||||||
|
Typical host-facing boot intents are:
|
||||||
|
|
||||||
|
- default start -> enter Hub;
|
||||||
|
- run cartridge -> boot with cartridge target;
|
||||||
|
- debug cartridge -> boot with cartridge target plus debug mode parameters.
|
||||||
|
|
||||||
|
The CLI is an entry surface for boot target selection; the firmware contract remains the same underneath.
|
||||||
|
|
||||||
|
## 5 Firmware State Relationship
|
||||||
|
|
||||||
|
Boot target selection feeds into firmware states such as:
|
||||||
|
|
||||||
|
- `Reset`
|
||||||
|
- `SplashScreen`
|
||||||
|
- `LaunchHub`
|
||||||
|
- `HubHome`
|
||||||
|
- `LoadCartridge`
|
||||||
|
- `GameRunning`
|
||||||
|
- `AppCrashes`
|
||||||
|
|
||||||
|
Boot target is not itself a firmware state. It is an input to the firmware state machine.
|
||||||
|
|
||||||
|
## 6 Debug Boot
|
||||||
|
|
||||||
|
When booting a cartridge in debug mode:
|
||||||
|
|
||||||
|
- firmware/runtime uses the cartridge target path;
|
||||||
|
- debugger-related startup behavior is enabled;
|
||||||
|
- execution still follows the same cartridge/app-mode resolution path.
|
||||||
|
|
||||||
|
Debug mode changes orchestration, not the cartridge contract.
|
||||||
|
|
||||||
|
## 7 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md) defines the firmware state machine that consumes boot targets.
|
||||||
|
- [`13-cartridge.md`](13-cartridge.md) defines cartridge structure.
|
||||||
|
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines the observability/debugging layer.
|
||||||
125
docs/runtime/specs/15-asset-management.md
Normal file
125
docs/runtime/specs/15-asset-management.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# Asset Management
|
||||||
|
|
||||||
|
This chapter defines the runtime-facing asset model of PROMETEU.
|
||||||
|
|
||||||
|
## 1 Scope
|
||||||
|
|
||||||
|
PROMETEU asset management is bank-centric.
|
||||||
|
|
||||||
|
Assets are:
|
||||||
|
|
||||||
|
- cold bytes stored in the cartridge;
|
||||||
|
- described by cartridge metadata;
|
||||||
|
- materialized into host-managed banks;
|
||||||
|
- separate from VM heap ownership.
|
||||||
|
|
||||||
|
This chapter describes the runtime contract currently visible in the codebase. It is not a full tooling pipeline specification.
|
||||||
|
|
||||||
|
## 2 Core Principles
|
||||||
|
|
||||||
|
1. asset residency is explicit;
|
||||||
|
2. asset memory belongs to the machine, not to the VM heap;
|
||||||
|
3. banks and slots are hardware/runtime concepts;
|
||||||
|
4. loading and activation are explicit operations;
|
||||||
|
5. asset memory does not participate in GC.
|
||||||
|
|
||||||
|
## 3 Cartridge Asset Surfaces
|
||||||
|
|
||||||
|
The runtime currently consumes two cartridge asset surfaces:
|
||||||
|
|
||||||
|
- `asset_table`: metadata entries describing asset content;
|
||||||
|
- `assets.pa`: packed asset bytes.
|
||||||
|
|
||||||
|
An optional `preload` list may request initial slot residency during cartridge initialization.
|
||||||
|
|
||||||
|
## 4 Asset Table
|
||||||
|
|
||||||
|
Current runtime-facing asset metadata includes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AssetEntry {
|
||||||
|
asset_id
|
||||||
|
asset_name
|
||||||
|
bank_type
|
||||||
|
offset
|
||||||
|
size
|
||||||
|
decoded_size
|
||||||
|
codec
|
||||||
|
metadata
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This table describes content identity and storage layout, not live residency.
|
||||||
|
|
||||||
|
## 5 Banks and Slots
|
||||||
|
|
||||||
|
The current runtime exposes bank types:
|
||||||
|
|
||||||
|
- `TILES`
|
||||||
|
- `SOUNDS`
|
||||||
|
|
||||||
|
Assets are loaded into explicit slots identified by bank context plus index.
|
||||||
|
|
||||||
|
Conceptual slot reference:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SlotRef { bank_type, index }
|
||||||
|
```
|
||||||
|
|
||||||
|
This prevents ambiguity between graphics and audio residency.
|
||||||
|
|
||||||
|
## 6 Load Lifecycle
|
||||||
|
|
||||||
|
The runtime asset manager exposes a staged lifecycle:
|
||||||
|
|
||||||
|
- `PENDING`
|
||||||
|
- `LOADING`
|
||||||
|
- `READY`
|
||||||
|
- `COMMITTED`
|
||||||
|
- `CANCELED`
|
||||||
|
- `ERROR`
|
||||||
|
|
||||||
|
High-level flow:
|
||||||
|
|
||||||
|
1. request load of an asset into a slot;
|
||||||
|
2. perform read/decode/materialization work;
|
||||||
|
3. mark the load `READY`;
|
||||||
|
4. explicitly `commit`;
|
||||||
|
5. activate the resident asset in the slot.
|
||||||
|
|
||||||
|
The runtime does not treat asset installation as implicit side effect.
|
||||||
|
|
||||||
|
## 7 Residency and Ownership
|
||||||
|
|
||||||
|
Asset banks are host/runtime-owned memory.
|
||||||
|
|
||||||
|
Therefore:
|
||||||
|
|
||||||
|
- VM heap does not own asset residency;
|
||||||
|
- GC does not scan asset bank memory;
|
||||||
|
- shutting down a cartridge can release bank residency independently of VM heap behavior.
|
||||||
|
|
||||||
|
## 8 Bank Telemetry
|
||||||
|
|
||||||
|
The runtime surfaces bank and slot statistics such as:
|
||||||
|
|
||||||
|
- total bytes;
|
||||||
|
- used bytes;
|
||||||
|
- free bytes;
|
||||||
|
- inflight bytes;
|
||||||
|
- slot occupancy;
|
||||||
|
- resident asset identity per slot.
|
||||||
|
|
||||||
|
These metrics support debugging, telemetry, and certification-oriented inspection.
|
||||||
|
|
||||||
|
## 9 Preload
|
||||||
|
|
||||||
|
The cartridge may declare preload requests.
|
||||||
|
|
||||||
|
These preload entries are consumed during cartridge initialization so the asset manager can establish initial residency before normal execution flow.
|
||||||
|
|
||||||
|
## 10 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`13-cartridge.md`](13-cartridge.md) defines cartridge fields that carry `asset_table`, `preload`, and `assets.pa`.
|
||||||
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) defines the syscall boundary used to manipulate assets.
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines the distinction between VM heap memory and host-owned memory.
|
||||||
167
docs/runtime/specs/16-host-abi-and-syscalls.md
Normal file
167
docs/runtime/specs/16-host-abi-and-syscalls.md
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
# Host ABI and Syscalls
|
||||||
|
|
||||||
|
This chapter defines the structural ABI between the PVM and the host environment.
|
||||||
|
|
||||||
|
It focuses on:
|
||||||
|
|
||||||
|
- syscall identity;
|
||||||
|
- load-time resolution;
|
||||||
|
- instruction-level call semantics;
|
||||||
|
- metadata shape;
|
||||||
|
- argument and return-slot contract.
|
||||||
|
|
||||||
|
Operational policies such as capabilities, fault classes, determinism, GC interaction, budgeting, and blocking are split into a companion chapter.
|
||||||
|
|
||||||
|
## 1 Design Principles
|
||||||
|
|
||||||
|
The syscall ABI follows these rules:
|
||||||
|
|
||||||
|
1. **Stack-based ABI**: arguments and return values are passed through VM slots.
|
||||||
|
2. **Canonical identity**: host services are named by stable `(module, name, version)`.
|
||||||
|
3. **Load-time resolution**: symbolic host bindings are resolved before execution.
|
||||||
|
4. **Metadata-driven execution**: arity and result shape come from syscall metadata.
|
||||||
|
5. **Not first-class**: syscalls are callable but not ordinary function values.
|
||||||
|
|
||||||
|
## 2 Canonical Syscall Identity
|
||||||
|
|
||||||
|
Syscalls are identified by a canonical triple:
|
||||||
|
|
||||||
|
```
|
||||||
|
(module, name, version)
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
("gfx", "present", 1)
|
||||||
|
("input", "state", 1)
|
||||||
|
("audio", "play", 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
This identity is:
|
||||||
|
|
||||||
|
- language-independent;
|
||||||
|
- toolchain-stable;
|
||||||
|
- used for linking and capability gating.
|
||||||
|
|
||||||
|
## 3 Syscall Resolution
|
||||||
|
|
||||||
|
The host maintains a registry:
|
||||||
|
|
||||||
|
```
|
||||||
|
(module, name, version) -> syscall_id
|
||||||
|
```
|
||||||
|
|
||||||
|
At load time:
|
||||||
|
|
||||||
|
1. the cartridge declares required syscalls by canonical identity;
|
||||||
|
2. bytecode encodes host-backed call sites as `HOSTCALL <sysc_index>`;
|
||||||
|
3. the loader validates and resolves those identities;
|
||||||
|
4. the loader rewrites `HOSTCALL <sysc_index>` into `SYSCALL <id>`;
|
||||||
|
5. the executable image uses only numeric syscall ids at runtime.
|
||||||
|
|
||||||
|
Raw `SYSCALL <id>` is not valid in a PBX pre-load artifact and must be rejected there.
|
||||||
|
|
||||||
|
## 4 Syscall Instruction Semantics
|
||||||
|
|
||||||
|
Pre-load artifact form:
|
||||||
|
|
||||||
|
```
|
||||||
|
HOSTCALL <sysc_index>
|
||||||
|
```
|
||||||
|
|
||||||
|
Final executable form:
|
||||||
|
|
||||||
|
```
|
||||||
|
SYSCALL <id>
|
||||||
|
```
|
||||||
|
|
||||||
|
Where:
|
||||||
|
|
||||||
|
- `<sysc_index>` indexes the program-declared syscall table;
|
||||||
|
- `<id>` is the final numeric host syscall id.
|
||||||
|
|
||||||
|
Execution steps:
|
||||||
|
|
||||||
|
1. the VM looks up syscall metadata by `<id>`;
|
||||||
|
2. the VM ensures the argument contract is satisfiable;
|
||||||
|
3. the syscall executes in the host environment;
|
||||||
|
4. the syscall produces exactly the declared `ret_slots`.
|
||||||
|
|
||||||
|
## 5 Syscall Metadata Table
|
||||||
|
|
||||||
|
Each syscall is defined by metadata.
|
||||||
|
|
||||||
|
Conceptual structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
SyscallMeta {
|
||||||
|
id: u32
|
||||||
|
module: string
|
||||||
|
name: string
|
||||||
|
version: u16
|
||||||
|
arg_slots: u8
|
||||||
|
ret_slots: u8
|
||||||
|
capability: CapabilityId
|
||||||
|
may_allocate: bool
|
||||||
|
cost_hint: u32
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
|
||||||
|
| Field | Description |
|
||||||
|
| -------------- | ------------------------------------------------ |
|
||||||
|
| `id` | Unique numeric syscall identifier |
|
||||||
|
| `module` | Canonical module name |
|
||||||
|
| `name` | Canonical syscall name |
|
||||||
|
| `version` | ABI version of the syscall |
|
||||||
|
| `arg_slots` | Number of input stack slots |
|
||||||
|
| `ret_slots` | Number of return stack slots |
|
||||||
|
| `capability` | Required capability |
|
||||||
|
| `may_allocate` | Whether the syscall may allocate VM heap objects |
|
||||||
|
| `cost_hint` | Expected cycle cost |
|
||||||
|
|
||||||
|
The loader uses this table to resolve identities and validate declared ABI shape.
|
||||||
|
|
||||||
|
## 6 Arguments and Return Values
|
||||||
|
|
||||||
|
Syscalls use the same slot-oriented argument/return philosophy as ordinary calls.
|
||||||
|
|
||||||
|
### Argument passing
|
||||||
|
|
||||||
|
Arguments are pushed before the syscall.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
push a
|
||||||
|
push b
|
||||||
|
SYSCALL X
|
||||||
|
```
|
||||||
|
|
||||||
|
### Return values
|
||||||
|
|
||||||
|
After execution, the syscall leaves exactly `ret_slots` values on the stack.
|
||||||
|
|
||||||
|
Composite results use multiple stack slots rather than implicit hidden structures.
|
||||||
|
|
||||||
|
## 7 Syscalls as Callable Entities (Not First-Class)
|
||||||
|
|
||||||
|
Syscalls behave like call sites, not like first-class guest values.
|
||||||
|
|
||||||
|
This means:
|
||||||
|
|
||||||
|
- syscalls can be invoked;
|
||||||
|
- syscalls cannot be stored in variables;
|
||||||
|
- syscalls cannot be passed as function values;
|
||||||
|
- syscalls cannot be returned as closures.
|
||||||
|
|
||||||
|
Only user-defined functions and closures are first-class.
|
||||||
|
|
||||||
|
## 8 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`16a-syscall-policies.md`](16a-syscall-policies.md) defines operational policies layered on top of this ABI.
|
||||||
|
- [`15-asset-management.md`](15-asset-management.md) defines asset-domain semantics behind some syscall families.
|
||||||
|
- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md) defines persistent save-domain semantics.
|
||||||
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md) defines the slot/call philosophy reused by the syscall ABI.
|
||||||
109
docs/runtime/specs/16a-syscall-policies.md
Normal file
109
docs/runtime/specs/16a-syscall-policies.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# Syscall Policies
|
||||||
|
|
||||||
|
This chapter defines the operational policies that sit on top of the host ABI.
|
||||||
|
|
||||||
|
It complements [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md), which defines the structural ABI itself.
|
||||||
|
|
||||||
|
## 1 Error Model: Faults vs Status Returns
|
||||||
|
|
||||||
|
Syscalls use a hybrid model.
|
||||||
|
|
||||||
|
### Fault conditions
|
||||||
|
|
||||||
|
The VM faults when contract rules are violated, for example:
|
||||||
|
|
||||||
|
- invalid syscall id;
|
||||||
|
- unresolved canonical identity;
|
||||||
|
- missing required capability;
|
||||||
|
- insufficient argument slots;
|
||||||
|
- invalid or dead heap handle.
|
||||||
|
|
||||||
|
These are not ordinary domain statuses.
|
||||||
|
|
||||||
|
### Status returns
|
||||||
|
|
||||||
|
Normal operational conditions should be represented as values in return slots.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- asset not yet loaded;
|
||||||
|
- audio voice unavailable;
|
||||||
|
- persistent storage full.
|
||||||
|
|
||||||
|
## 2 Capability System
|
||||||
|
|
||||||
|
Each syscall requires a declared capability.
|
||||||
|
|
||||||
|
Example groups:
|
||||||
|
|
||||||
|
- `gfx`
|
||||||
|
- `audio`
|
||||||
|
- `input`
|
||||||
|
- `asset`
|
||||||
|
- `memcard`
|
||||||
|
|
||||||
|
Capability checks exist to constrain which host-managed surfaces a cartridge may use.
|
||||||
|
|
||||||
|
## 3 Interaction with the Garbage Collector
|
||||||
|
|
||||||
|
The VM heap and host-managed memory are separate.
|
||||||
|
|
||||||
|
### Heap vs host memory
|
||||||
|
|
||||||
|
| Memory | Managed by | GC scanned |
|
||||||
|
| --------------- | ---------- | ---------- |
|
||||||
|
| VM heap objects | VM GC | Yes |
|
||||||
|
| Asset banks | Host | No |
|
||||||
|
| Audio buffers | Host | No |
|
||||||
|
| Framebuffers | Host | No |
|
||||||
|
|
||||||
|
### Host root rule
|
||||||
|
|
||||||
|
If the host stores a VM heap handle beyond the duration of the syscall, that handle must be treated as a host root according to the runtime contract.
|
||||||
|
|
||||||
|
This rule applies to VM heap objects, not to host-owned asset identifiers or primitive values.
|
||||||
|
|
||||||
|
## 4 Determinism Rules
|
||||||
|
|
||||||
|
Syscalls must obey machine-level determinism.
|
||||||
|
|
||||||
|
Forbidden patterns:
|
||||||
|
|
||||||
|
- reading wall-clock time as gameplay state;
|
||||||
|
- non-deterministic OS access in the gameplay contract;
|
||||||
|
- blocking I/O in the execution slice.
|
||||||
|
|
||||||
|
Allowed patterns:
|
||||||
|
|
||||||
|
- frame-based timing;
|
||||||
|
- request + poll status models;
|
||||||
|
- deterministic event publication at frame boundaries.
|
||||||
|
|
||||||
|
## 5 Cost Model and Budgeting
|
||||||
|
|
||||||
|
Each syscall contributes to frame cost.
|
||||||
|
|
||||||
|
The system may account for:
|
||||||
|
|
||||||
|
- syscall count;
|
||||||
|
- cycles spent in syscalls;
|
||||||
|
- allocations triggered by syscalls.
|
||||||
|
|
||||||
|
This keeps host interaction visible in certification, telemetry, and profiling.
|
||||||
|
|
||||||
|
## 6 Blocking and Long Operations
|
||||||
|
|
||||||
|
Syscalls must not block the execution model.
|
||||||
|
|
||||||
|
Long operations should follow explicit staged patterns such as:
|
||||||
|
|
||||||
|
1. request;
|
||||||
|
2. status polling or completion observation.
|
||||||
|
|
||||||
|
This keeps the host ABI compatible with a deterministic frame machine.
|
||||||
|
|
||||||
|
## 7 Relationship to Other Specs
|
||||||
|
|
||||||
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md) defines the structural ABI.
|
||||||
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md) defines VM heap ownership and handles.
|
||||||
|
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md) defines visibility of cost and diagnostics.
|
||||||
@ -1,299 +1,48 @@
|
|||||||
# 📜 Prometeu — The Fire and the Promise
|
# PROMETEU Runtime Specs
|
||||||
|
|
||||||
**PROMETEU** is an imaginary console.
|
Este diretório reúne as specs da maquina PROMETEU no nível de sistema, hardware virtual, firmware, cartridge e ABI de host.
|
||||||
|
|
||||||
But not in the weak sense of "imagining".
|
PROMETEU não é apenas a VM. A VM é um subsistema da fantasy handheld / fantasy console. As specs aqui descrevem a maquina maior e sua superfície técnica.
|
||||||
|
|
||||||
PROMETEU was **deliberately designed** to exist as a **complete computational model**: simple enough to be understood, and powerful enough to create real games.
|
Princípios desta organização:
|
||||||
|
|
||||||
The name PROMETEU carries two intentional meanings:
|
- estrutura plana;
|
||||||
|
- sem pasta `topics/`;
|
||||||
- **Prometheus, the titan**, who stole fire from the gods and gave it to humans
|
- sem navegação embutida `Back` / `Next` / `Summary`;
|
||||||
- **“Prometeu” as a verb**, a promise made (in Portuguese)
|
- nomes de arquivos semânticos;
|
||||||
|
- cada capítulo deve poder ser aberto isoladamente.
|
||||||
In this project:
|
|
||||||
|
Arquivos atuais:
|
||||||
- the *fire* is the knowledge of how computers really work
|
|
||||||
- the *promise* is that nothing is magic, nothing is hidden, and everything can be understood
|
- [`01-time-model-and-cycles.md`](01-time-model-and-cycles.md)
|
||||||
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md)
|
||||||
This manual is that written promise.
|
- [`02a-vm-values-and-calling-convention.md`](02a-vm-values-and-calling-convention.md)
|
||||||
|
- [`02b-vm-function-values-and-closures.md`](02b-vm-function-values-and-closures.md)
|
||||||
---
|
- [`03-memory-stack-heap-and-allocation.md`](03-memory-stack-heap-and-allocation.md)
|
||||||
|
- [`04-gfx-peripheral.md`](04-gfx-peripheral.md)
|
||||||
## 🎯 What is PROMETEU
|
- [`05-audio-peripheral.md`](05-audio-peripheral.md)
|
||||||
|
- [`06-input-peripheral.md`](06-input-peripheral.md)
|
||||||
PROMETEU is a **Virtual Microconsole** — a fictitious computer, with clear rules, limited resources, and deterministic behavior.
|
- [`07-touch-peripheral.md`](07-touch-peripheral.md)
|
||||||
|
- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md)
|
||||||
It was designed to:
|
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md)
|
||||||
|
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md)
|
||||||
- teach real computing fundamentals
|
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md)
|
||||||
- expose time, memory, and execution
|
- [`11-portability-and-cross-platform-execution.md`](11-portability-and-cross-platform-execution.md)
|
||||||
- allow full 2D games (platformers, metroidvanias, arcade)
|
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md)
|
||||||
- serve as a bridge between:
|
- [`13-cartridge.md`](13-cartridge.md)
|
||||||
- microcontrollers
|
- [`14-boot-profiles.md`](14-boot-profiles.md)
|
||||||
- classic consoles
|
- [`15-asset-management.md`](15-asset-management.md)
|
||||||
- virtual machines
|
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md)
|
||||||
- modern engines
|
- [`16a-syscall-policies.md`](16a-syscall-policies.md)
|
||||||
|
|
||||||
PROMETEU **is not**:
|
Relação com outros docs:
|
||||||
|
|
||||||
- a generic engine
|
- [`../virtual-machine/ARCHITECTURE.md`](../virtual-machine/ARCHITECTURE.md) define as invariantes canônicas da VM/runtime.
|
||||||
- a substitute for Unity or Godot
|
- [`../virtual-machine/ISA_CORE.md`](../virtual-machine/ISA_CORE.md) define a ISA no nível de bytecode.
|
||||||
- a real commercial console
|
- As specs deste diretório podem aprofundar o modelo da máquina, mas não devem contradizer as invariantes canônicas da VM/runtime quando tratarem dessa camada.
|
||||||
|
|
||||||
PROMETEU **is**:
|
Critério para novos capítulos:
|
||||||
|
|
||||||
- a laboratory
|
- o nome do arquivo deve comunicar o domínio;
|
||||||
- a didactic instrument
|
- o capítulo deve ser legível sem depender de trilha de navegação;
|
||||||
- a serious toy
|
- links internos devem ser usados apenas quando agregarem contexto real, não como mecanismo obrigatório de leitura sequencial.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧠 Fundamental Mental Model
|
|
||||||
|
|
||||||
> PROMETEU is a microcontroller that draws pixels, plays sound, and handles player input.
|
|
||||||
>
|
|
||||||
|
|
||||||
Everything in the system derives from this.
|
|
||||||
|
|
||||||
### Conceptual equivalence
|
|
||||||
|
|
||||||
| Real microcontroller | PROMETEU |
|
|
||||||
| --- | --- |
|
|
||||||
| Clock | VM Tick |
|
|
||||||
| Flash | PROMETEU Cartridge |
|
|
||||||
| RAM | Heap + Stack |
|
|
||||||
| GPIO | Input |
|
|
||||||
| DMA | Graphics transfer |
|
|
||||||
| ISR | System events |
|
|
||||||
| Peripherals | GFX, AUDIO, INPUT, FS |
|
|
||||||
|
|
||||||
If you understand an MCU, you understand PROMETEU.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧩 Design Philosophy
|
|
||||||
|
|
||||||
### 1. Visible Simplicity
|
|
||||||
|
|
||||||
- Every operation has a cost
|
|
||||||
- Every frame has a budget
|
|
||||||
- Every error has an observable cause
|
|
||||||
|
|
||||||
Nothing happens "just because".
|
|
||||||
|
|
||||||
### 2. Determinism
|
|
||||||
|
|
||||||
- Same cartridge
|
|
||||||
- Same input
|
|
||||||
- Same result
|
|
||||||
|
|
||||||
Regardless of the platform.
|
|
||||||
|
|
||||||
### 3. Limitation as a pedagogical tool
|
|
||||||
|
|
||||||
PROMETEU imposes **intentional** limits:
|
|
||||||
|
|
||||||
- finite memory
|
|
||||||
- time per frame
|
|
||||||
- limited graphics resources
|
|
||||||
|
|
||||||
Limits teach design.
|
|
||||||
|
|
||||||
### 4. Progressive depth
|
|
||||||
|
|
||||||
PROMETEU can be explored in layers:
|
|
||||||
|
|
||||||
1. **Game Layer** — `update()` and `draw()`
|
|
||||||
2. **System Layer** — bytecode, stack, heap
|
|
||||||
3. **Machine Layer** — cycles, events, peripherals
|
|
||||||
|
|
||||||
The student decides how deep to go.
|
|
||||||
|
|
||||||
## 🏗️ General Architecture
|
|
||||||
|
|
||||||
```
|
|
||||||
+---------------------------+
|
|
||||||
| CARTRIDGE |
|
|
||||||
| (bytecodeX + assets) |
|
|
||||||
+-------------+-------------+
|
|
||||||
|
|
|
||||||
+-------------v-------------+
|
|
||||||
| PROMETEU VM |
|
|
||||||
| (stack-based, |
|
|
||||||
| deterministic) |
|
|
||||||
+-------------+-------------+
|
|
||||||
|
|
|
||||||
+-------------v-------------+
|
|
||||||
| VIRTUAL PERIPHERALS |
|
|
||||||
| GFX | AUDIO |INPUT | FS| |
|
|
||||||
+-------------+-------------+
|
|
||||||
|
|
|
||||||
+-------------v-------------+
|
|
||||||
| PLATFORM LAYER |
|
|
||||||
| PC | SteamOS | Android |
|
|
||||||
| iOS | Consoles (future) |
|
|
||||||
+---------------------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
This manual describes **the PROMETEU machine**, not external tools.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 The PROMETEU Cartridge
|
|
||||||
|
|
||||||
A **PROMETEU cartridge** is an immutable package, equivalent to firmware.
|
|
||||||
|
|
||||||
Typical content:
|
|
||||||
|
|
||||||
- `program.pbx` — PROMETEU bytecode (bytecodeX)
|
|
||||||
- `assets/` — graphics, audio, maps
|
|
||||||
- `manifest.json` — metadata and configuration
|
|
||||||
|
|
||||||
The cartridge:
|
|
||||||
|
|
||||||
- can always be executed
|
|
||||||
- can always be distributed
|
|
||||||
- is never blocked by the system
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Programming Languages
|
|
||||||
|
|
||||||
PROMETEU **does not execute high-level languages directly**.
|
|
||||||
|
|
||||||
The languages are **sources**, compiled to PROMETEU bytecode.
|
|
||||||
|
|
||||||
### Planned languages
|
|
||||||
|
|
||||||
- **Java (subset)** — architecture, deep teaching
|
|
||||||
- **TypeScript (subset)** — accessibility and market
|
|
||||||
- **Lua (subset)** — classic and lightweight scripting
|
|
||||||
|
|
||||||
All converge to:
|
|
||||||
|
|
||||||
> The same bytecode. The same VM. The same behavior.
|
|
||||||
>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Execution Model
|
|
||||||
|
|
||||||
PROMETEU executes in a fixed loop:
|
|
||||||
|
|
||||||
```
|
|
||||||
BOOT
|
|
||||||
↓
|
|
||||||
LOAD CARTRIDGE
|
|
||||||
↓
|
|
||||||
INIT
|
|
||||||
↓
|
|
||||||
LOOP (60 Hz):
|
|
||||||
├─INPUT
|
|
||||||
├─UPDATE
|
|
||||||
├─ DRAW
|
|
||||||
├─ AUDIO
|
|
||||||
└─ SYNC
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- Default frequency: **60 Hz**
|
|
||||||
- Each iteration corresponds to **one frame**
|
|
||||||
- Execution time is **measurable**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⏱️ CAP — Execution Cap
|
|
||||||
|
|
||||||
### Definition
|
|
||||||
|
|
||||||
The **CAP** defines an execution budget (time, memory, and resources) **in a specific context**, such as a Game Jam or evaluation.
|
|
||||||
|
|
||||||
> CAP never blocks execution.
|
|
||||||
> CAP never blocks packaging.
|
|
||||||
> CAP never prevents the game from being played.
|
|
||||||
>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### When the CAP is used
|
|
||||||
|
|
||||||
- PROMETEU Game Jams
|
|
||||||
- Academic evaluations
|
|
||||||
- Technical challenges
|
|
||||||
- Comparisons between solutions
|
|
||||||
|
|
||||||
Outside of these contexts, PROMETEU operates in **free mode**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### The role of the CAP
|
|
||||||
|
|
||||||
The CAP serves to:
|
|
||||||
|
|
||||||
- guide technical decisions
|
|
||||||
- provide measurable feedback
|
|
||||||
- generate **technical certifications**
|
|
||||||
- create objective evaluation criteria
|
|
||||||
|
|
||||||
PROMETEU **helps during development**:
|
|
||||||
|
|
||||||
- visual indicators
|
|
||||||
- cost alerts
|
|
||||||
- per-frame profiling
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📄 PROMETEU Certification
|
|
||||||
|
|
||||||
### What it is
|
|
||||||
|
|
||||||
The **PROMETEU Certification** is a technical report generated from the execution of the game under a defined CAP.
|
|
||||||
|
|
||||||
It:
|
|
||||||
|
|
||||||
- **does not prevent** the game from running
|
|
||||||
- **does not invalidate** the delivery
|
|
||||||
- **records technical evidence**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Report Example
|
|
||||||
|
|
||||||
```
|
|
||||||
PROMETEUCERTIFICATIONREPORT
|
|
||||||
-----------------------------
|
|
||||||
Context:PROMETEUJAM#03
|
|
||||||
Target Profile:PROMETEU-LITE
|
|
||||||
|
|
||||||
Execution:
|
|
||||||
Avg cycles/frame:4,820
|
|
||||||
Peak cycles/frame:5,612❌
|
|
||||||
|
|
||||||
Memory:
|
|
||||||
Heap peak:34KB❌(limit:32KB)
|
|
||||||
|
|
||||||
Status:
|
|
||||||
❌NOTCOMPLIANT
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
-OverruncausedbyenemyAIupdateloop
|
|
||||||
-Heappressurecausedbyper-frameallocations
|
|
||||||
```
|
|
||||||
|
|
||||||
The report **accompanies the game**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎓 Educational Use
|
|
||||||
|
|
||||||
Evaluation may consider:
|
|
||||||
|
|
||||||
- Game quality (creativity, design)
|
|
||||||
- Technical quality (certification)
|
|
||||||
- Justified architectural decisions
|
|
||||||
- Evolution between versions
|
|
||||||
|
|
||||||
PROMETEU evaluates **process**, not just result.
|
|
||||||
|
|
||||||
< [Summary](topics/table-of-contents.md) >
|
|
||||||
|
|||||||
@ -1,236 +0,0 @@
|
|||||||
< [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >
|
|
||||||
|
|
||||||
# 🧠 Firmware — PrometeuOS (POS) + PrometeuHub
|
|
||||||
|
|
||||||
## 1. Overview
|
|
||||||
|
|
||||||
The **PROMETEU Firmware** is composed of two layers:
|
|
||||||
|
|
||||||
- **PrometeuOS (POS)**: the system firmware/base. It is the maximum authority for boot, peripherals, PVM execution, and fault handling.
|
|
||||||
- **PrometeuHub**: the system launcher and UI environment, embedded in the firmware, executed **over** the POS and using the **PROMETEU Window System**.
|
|
||||||
|
|
||||||
> **Every cartridge is an App**.
|
|
||||||
> The difference is the **App mode** (Game or System), specified in the cartridge header.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Terms and Definitions
|
|
||||||
|
|
||||||
- **Host**: real platform (desktop, mobile, DIY console, etc.) that calls the core at 60Hz and displays the framebuffer.
|
|
||||||
- **POS (PrometeuOS)**: firmware (system core). Controls boot, PVM, budget, input latch, peripherals, and crash.
|
|
||||||
- **PrometeuHub**: system UI / launcher running over POS.
|
|
||||||
- **PVM (PROMETEU Virtual Machine)**: VM that executes the App's bytecode.
|
|
||||||
- **App / Cartridge**: PROMETEU executable package (e.g., `.pbc`).
|
|
||||||
- **AppMode**: App mode in the cartridge header:
|
|
||||||
- `GAME`: assumes full screen, own UI
|
|
||||||
- `SYSTEM`: app integrated into the system, should run "in a window" in the Hub
|
|
||||||
- **Logical frame**: App update unit, terminated by `FRAME_SYNC`.
|
|
||||||
- **Host tick**: call from the host (real 60Hz).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Responsibilities of the POS (PrometeuOS)
|
|
||||||
|
|
||||||
The POS must guarantee:
|
|
||||||
|
|
||||||
### 3.1 Boot and System States
|
|
||||||
- Deterministic RESET (known state)
|
|
||||||
- Optional SPLASH (short)
|
|
||||||
- initialization of the PrometeuHub and the Window System
|
|
||||||
- return to the Hub after app exit/crash
|
|
||||||
|
|
||||||
### 3.2 PVM Control
|
|
||||||
- load cartridge into the PVM
|
|
||||||
- reset PC/stack/heap upon app start
|
|
||||||
- execute budget per logical frame
|
|
||||||
- respect `FRAME_SYNC` as logical frame boundary
|
|
||||||
- maintain input latched per logical frame
|
|
||||||
|
|
||||||
### 3.3 Peripheral Control
|
|
||||||
- initialization and reset of:
|
|
||||||
- GFX / buffers
|
|
||||||
- AUDIO (channels, command queue)
|
|
||||||
- INPUT / TOUCH
|
|
||||||
- "safe mode" policy (ignore Hub/config if requested)
|
|
||||||
|
|
||||||
### 3.4 Failures and Recovery
|
|
||||||
- capture fatal PVM faults
|
|
||||||
- present **POS_CRASH_SCREEN** (outside the PVM)
|
|
||||||
- allow:
|
|
||||||
- app restart
|
|
||||||
- return to Hub
|
|
||||||
- system reset
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Responsibilities of the PrometeuHub
|
|
||||||
|
|
||||||
The PrometeuHub must:
|
|
||||||
|
|
||||||
- list available Apps in storage
|
|
||||||
- read metadata from the cartridge header (including `AppMode`)
|
|
||||||
- allow selection and launch
|
|
||||||
- apply system theme/UI via Window System
|
|
||||||
- decide the "execution behavior" based on the `AppMode`
|
|
||||||
|
|
||||||
### 4.1 Decision by `AppMode`
|
|
||||||
When selecting an App:
|
|
||||||
|
|
||||||
- If `AppMode = GAME`:
|
|
||||||
- the Hub delegates to the POS: **execute as a game** (full screen)
|
|
||||||
- If `AppMode = SYSTEM`:
|
|
||||||
- the Hub delegates to the POS: **load the App**
|
|
||||||
- and the Hub **opens a window** and runs the App "integrated into the system"
|
|
||||||
|
|
||||||
> Note: the Hub does not execute bytecode directly; it always delegates to the POS.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. PROMETEU Window System (System UI)
|
|
||||||
|
|
||||||
The Window System is part of the firmware (POS + Hub) and offers:
|
|
||||||
|
|
||||||
- global theme (palette, fonts, UI sounds)
|
|
||||||
- window system (at least: one active window + dialog stack)
|
|
||||||
- input routing:
|
|
||||||
- focus, navigation, confirmation/cancellation
|
|
||||||
- touch as "tap" (single pointer)
|
|
||||||
|
|
||||||
### 5.1 System App Integration
|
|
||||||
System Apps are executed in "window" mode and must:
|
|
||||||
|
|
||||||
- respect the viewport area provided by the window
|
|
||||||
- cooperate with the Window System's focus/inputs
|
|
||||||
- accept being suspended/closed by the Hub
|
|
||||||
|
|
||||||
The Hub can offer window "chrome":
|
|
||||||
- title
|
|
||||||
- back/close button
|
|
||||||
- overlays (toast, dialogs)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Cartridge Header (minimum requirement for the firmware)
|
|
||||||
|
|
||||||
The firmware requires every cartridge to provide at least the following in the header:
|
|
||||||
|
|
||||||
- `magic` / `version`
|
|
||||||
- `app_id` (short string or hash)
|
|
||||||
- `title` (string)
|
|
||||||
- `entrypoint` (PC address)
|
|
||||||
- `app_mode`: `GAME` or `SYSTEM`
|
|
||||||
- (optional) `icon_id` / `cover_id`
|
|
||||||
- (optional) `requested_cap` / VM version
|
|
||||||
|
|
||||||
The POS/HUB must use `app_mode` to decide on execution.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Official Boot States (Firmware)
|
|
||||||
|
|
||||||
### 7.1 POS_RESET
|
|
||||||
- initializes peripherals
|
|
||||||
- prepares PVM
|
|
||||||
- loads config
|
|
||||||
- detects safe mode
|
|
||||||
|
|
||||||
Transition: `POS_SPLASH` or `POS_LAUNCH_HUB`
|
|
||||||
|
|
||||||
### 7.2 POS_SPLASH (optional)
|
|
||||||
- displays logo/version
|
|
||||||
- fixed time or "skip"
|
|
||||||
|
|
||||||
Transition: `POS_LAUNCH_HUB`
|
|
||||||
|
|
||||||
### 7.3 POS_LAUNCH_HUB
|
|
||||||
- starts Window System
|
|
||||||
- enters the Hub loop
|
|
||||||
|
|
||||||
Transition: `HUB_HOME`
|
|
||||||
|
|
||||||
### 7.4 HUB_HOME
|
|
||||||
- lists Apps
|
|
||||||
- allows selection:
|
|
||||||
- `GAME` → `POS_RUN_GAME(app)`
|
|
||||||
- `SYSTEM` → `HUB_OPEN_WINDOW(app)` (which delegates `POS_RUN_SYSTEM(app)`)
|
|
||||||
|
|
||||||
### 7.5 POS_RUN_GAME(app)
|
|
||||||
- loads cartridge into the PVM
|
|
||||||
- executes logical frame (budget + `FRAME_SYNC`)
|
|
||||||
- presents frames
|
|
||||||
- maintains latch per logical frame
|
|
||||||
|
|
||||||
Exits:
|
|
||||||
- `APP_EXIT` → `POS_LAUNCH_HUB`
|
|
||||||
- `APP_FAULT` → `POS_CRASH_SCREEN`
|
|
||||||
|
|
||||||
### 7.6 POS_RUN_SYSTEM(app)
|
|
||||||
- loads cartridge into the PVM (or separate instance, if supported in the future)
|
|
||||||
- executes under the Hub/Window System cycle
|
|
||||||
- presents in the window area (viewport)
|
|
||||||
|
|
||||||
Exits:
|
|
||||||
- `APP_EXIT` → returns to the Hub
|
|
||||||
- `APP_FAULT` → `POS_CRASH_SCREEN` (or crash window + fallback)
|
|
||||||
|
|
||||||
### 7.7 POS_CRASH_SCREEN
|
|
||||||
- displays error (type, PC, stack trace)
|
|
||||||
- actions: restart app / hub / reset
|
|
||||||
|
|
||||||
Transition: as chosen.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Execution Model (Budget, Latch, and `FRAME_SYNC`)
|
|
||||||
|
|
||||||
The POS is responsible for guaranteeing:
|
|
||||||
|
|
||||||
- **Input latched per logical frame**
|
|
||||||
- execution in slices (host ticks) until the app reaches `FRAME_SYNC`
|
|
||||||
- only at `FRAME_SYNC`:
|
|
||||||
- `present()` (or compose+present)
|
|
||||||
- advances `logical_frame_index`
|
|
||||||
- releases input latch
|
|
||||||
- resets the budget for the next logical frame
|
|
||||||
|
|
||||||
If the budget runs out before `FRAME_SYNC`:
|
|
||||||
- does not present
|
|
||||||
- maintains latch
|
|
||||||
- execution continues in the next host tick within the same logical frame
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Rules for Returning to the Hub
|
|
||||||
|
|
||||||
The firmware must offer a "return to system" mechanism:
|
|
||||||
|
|
||||||
- button shortcut (e.g., START+SELECT for X ticks)
|
|
||||||
- or controlled syscall (System Apps only)
|
|
||||||
|
|
||||||
Upon returning to the Hub:
|
|
||||||
- the POS terminates or suspends the current App
|
|
||||||
- returns to the Window System with a consistent state
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Pedagogical Objectives
|
|
||||||
|
|
||||||
This firmware allows teaching:
|
|
||||||
|
|
||||||
- boot stages and firmware as an authority
|
|
||||||
- separation between system and application
|
|
||||||
- deterministic execution with budget and logical frame
|
|
||||||
- difference between apps (Game vs System)
|
|
||||||
- fault tolerance and realistic crash handling
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Summary
|
|
||||||
|
|
||||||
- POS is the base layer and controls the PVM, budget, latch, peripherals, and crash.
|
|
||||||
- PrometeuHub is the embedded firmware launcher/UI over the POS.
|
|
||||||
- Every cartridge is an App; the header defines the `app_mode` (GAME/SYSTEM).
|
|
||||||
- `GAME` runs in full screen; `SYSTEM` runs integrated into the Hub in a window.
|
|
||||||
- `FRAME_SYNC` is the logical frame boundary.
|
|
||||||
|
|
||||||
< [Back](chapter-11.md) | [Summary](table-of-contents.md) | [Next](chapter-13.md) >
|
|
||||||
@ -1,110 +0,0 @@
|
|||||||
< [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >
|
|
||||||
|
|
||||||
# Cartridges
|
|
||||||
|
|
||||||
**Version:** 1.0 (stable baseline)
|
|
||||||
**Status:** Proposal
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Objective
|
|
||||||
|
|
||||||
Define a minimum and stable contract for Prometeu cartridges, allowing:
|
|
||||||
|
|
||||||
* App identification
|
|
||||||
* Mode selection (Game/System)
|
|
||||||
* Entrypoint resolution
|
|
||||||
* Predictable loading by the runtime
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Concept
|
|
||||||
|
|
||||||
A cartridge is the distributable unit of Prometeu. It can exist as:
|
|
||||||
|
|
||||||
* **Directory (dev)** — ideal for development and hot-reload
|
|
||||||
* **Packaged file (.pmc)** — ideal for distribution
|
|
||||||
|
|
||||||
Both share the same logical layout.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Logical Layout
|
|
||||||
|
|
||||||
```
|
|
||||||
<cartridge>/
|
|
||||||
├── manifest.json
|
|
||||||
├── program.pbc
|
|
||||||
└── assets/
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
Required fields:
|
|
||||||
|
|
||||||
* `manifest.json`
|
|
||||||
* `program.pbc` (Prometeu bytecode)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. manifest.json (Contract v1)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"magic": "PMTU",
|
|
||||||
"cartridge_version": 1,
|
|
||||||
"app_id": 1234,
|
|
||||||
"title": "My Game",
|
|
||||||
"app_version": "1.0.0",
|
|
||||||
"app_mode": "Game",
|
|
||||||
"entrypoint": "main"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fields
|
|
||||||
|
|
||||||
* `magic`: fixed string `PMTU`
|
|
||||||
* `cartridge_version`: format version
|
|
||||||
* `app_id`: unique numerical identifier
|
|
||||||
* `title`: name of the app
|
|
||||||
* `app_version`: app version
|
|
||||||
* `app_mode`: `Game` or `System`
|
|
||||||
* `entrypoint`: symbol or index recognized by the VM
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Runtime Rules
|
|
||||||
|
|
||||||
* Validate `magic` and `cartridge_version`
|
|
||||||
* Read `app_mode` to decide execution flow
|
|
||||||
* Resolve `entrypoint` in `program.pbc`
|
|
||||||
* Ignore `assets/` if not supported yet
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Usage Modes
|
|
||||||
|
|
||||||
### Directory (development)
|
|
||||||
|
|
||||||
```
|
|
||||||
prometeu --run ./mycart/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Packaged file
|
|
||||||
|
|
||||||
```
|
|
||||||
prometeu --run mygame.pmc
|
|
||||||
```
|
|
||||||
|
|
||||||
Both must behave identically in the runtime.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Contract Stability
|
|
||||||
|
|
||||||
From v1 onwards:
|
|
||||||
|
|
||||||
* `manifest.json` is the source of truth
|
|
||||||
* Fields can only be added in a backward-compatible manner
|
|
||||||
* Incompatible changes require a new `cartridge_version`
|
|
||||||
|
|
||||||
< [Back](chapter-12.md) | [Summary](table-of-contents.md) | [Next](chapter-14.md) >
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
< [Back](chapter-13.md) | [Summary](table-of-contents.md) | [Next](chapter-15.md) >
|
|
||||||
|
|
||||||
# Boot Profiles
|
|
||||||
|
|
||||||
**Version:** 1.0
|
|
||||||
**Status:** Proposal
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Objective
|
|
||||||
|
|
||||||
Define how Prometeu decides what to execute at startup:
|
|
||||||
|
|
||||||
* Hub
|
|
||||||
* Automatic cartridge
|
|
||||||
* Debug mode
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. BootTarget Concept
|
|
||||||
|
|
||||||
At the beginning of boot, the POS resolves a target:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
enum BootTarget {
|
|
||||||
Hub,
|
|
||||||
Cartridge { path: String, debug: bool },
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. General Rules
|
|
||||||
|
|
||||||
### If BootTarget == Hub
|
|
||||||
|
|
||||||
* Firmware enters `HubHome`
|
|
||||||
* No cartridge is automatically loaded
|
|
||||||
|
|
||||||
### If BootTarget == Cartridge
|
|
||||||
|
|
||||||
1. Load cartridge
|
|
||||||
2. Read `app_mode` in the manifest
|
|
||||||
3. Apply rules:
|
|
||||||
|
|
||||||
* `Game`:
|
|
||||||
|
|
||||||
* Enter `RunningGame`
|
|
||||||
* `System`:
|
|
||||||
|
|
||||||
* Stay in `HubHome`
|
|
||||||
* Open the app as a window/system tool
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Host CLI
|
|
||||||
|
|
||||||
### Default boot
|
|
||||||
|
|
||||||
```
|
|
||||||
prometeu
|
|
||||||
```
|
|
||||||
|
|
||||||
Result: enters the Hub
|
|
||||||
|
|
||||||
### Run cartridge
|
|
||||||
|
|
||||||
```
|
|
||||||
prometeu run <cartridge>
|
|
||||||
```
|
|
||||||
|
|
||||||
Result:
|
|
||||||
|
|
||||||
* Game → enters directly into the game
|
|
||||||
* System → opens as a tool in the Hub
|
|
||||||
|
|
||||||
### Run with debugger
|
|
||||||
|
|
||||||
```
|
|
||||||
prometeu debug <cartridge>
|
|
||||||
```
|
|
||||||
|
|
||||||
Result:
|
|
||||||
|
|
||||||
* Same flow as `run`
|
|
||||||
* Runtime starts in debug mode
|
|
||||||
* Waits for connection from the Java Debugger
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Firmware States
|
|
||||||
|
|
||||||
Firmware maintains only:
|
|
||||||
|
|
||||||
* `Boot`
|
|
||||||
* `HubHome`
|
|
||||||
* `RunningGame`
|
|
||||||
* `AppCrashed`
|
|
||||||
|
|
||||||
System apps never change the firmware state.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Behavior on Real Hardware (future)
|
|
||||||
|
|
||||||
* If miniSD/physical cartridge is present at boot:
|
|
||||||
|
|
||||||
* POS can:
|
|
||||||
|
|
||||||
* always go to the Hub, or
|
|
||||||
* auto-execute according to user configuration
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Integration with Debugger
|
|
||||||
|
|
||||||
When `debug == true`:
|
|
||||||
|
|
||||||
* Runtime:
|
|
||||||
|
|
||||||
* Initializes
|
|
||||||
* Opens DevTools socket
|
|
||||||
* Waits for `start` command
|
|
||||||
* Only after that does it start cartridge execution
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Stability
|
|
||||||
|
|
||||||
* BootTarget is an internal POS contract
|
|
||||||
* Host CLI must respect these rules
|
|
||||||
* New boot modes must be compatible extensions
|
|
||||||
|
|
||||||
|
|
||||||
< [Back](chapter-13.md) | [Summary](table-of-contents.md) | [Next](chapter-15.md) >
|
|
||||||
@ -1,331 +0,0 @@
|
|||||||
< [Back](chapter-14.md) | [Summary](table-of-contents.md) | [Next](chapter-16.md) >
|
|
||||||
|
|
||||||
# Asset Management
|
|
||||||
|
|
||||||
## Bank-Centric Hardware Asset Model
|
|
||||||
|
|
||||||
**Scope:** Runtime / Hardware Asset Management (SDK-agnostic)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Fundamental Principles
|
|
||||||
|
|
||||||
1. **Every asset in Prometeu resides in a Bank**
|
|
||||||
2. **A Bank is a hardware memory management system**
|
|
||||||
3. **Assets are cold binaries stored in the cartridge**
|
|
||||||
4. **Asset memory belongs to the console, not to the VM**
|
|
||||||
5. **Loading, residency, and eviction are explicit**
|
|
||||||
6. **Hardware does not interpret gameplay semantics**
|
|
||||||
7. **The SDK orchestrates policies; hardware executes contracts**
|
|
||||||
|
|
||||||
> In Prometeu, you do not load “data”. You load **residency**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Asset Origin (Cold Storage)
|
|
||||||
|
|
||||||
* All assets initially reside in **cold storage** inside the cartridge.
|
|
||||||
* Typically, each asset corresponds to a binary file.
|
|
||||||
* The runtime **never scans the cartridge directly**.
|
|
||||||
* All access goes through the **Asset Table**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Asset Table
|
|
||||||
|
|
||||||
The Asset Table is an index loaded at cartridge boot.
|
|
||||||
|
|
||||||
It describes **content**, not residency.
|
|
||||||
|
|
||||||
### Location
|
|
||||||
|
|
||||||
* The Asset Table **must be embedded as JSON inside `manifest.json`**.
|
|
||||||
* Tooling may compile this JSON into a binary table for runtime use, but the source of truth is the manifest.
|
|
||||||
|
|
||||||
### Required Fields (conceptual)
|
|
||||||
|
|
||||||
* `asset_id` (integer, internal identifier)
|
|
||||||
* `asset_name` (string, user-facing identifier)
|
|
||||||
* `asset_type` (TILEBANK, SOUNDBANK, BLOB, TILEMAP, ...)
|
|
||||||
* `bank_kind` (mandatory, single)
|
|
||||||
* `offset` (byte offset in cartridge)
|
|
||||||
* `size` (cold size)
|
|
||||||
* `decoded_size` (resident size)
|
|
||||||
* `codec` (RAW, LZ4, ZSTD, ...)
|
|
||||||
* `asset_metadata` (type-specific)
|
|
||||||
|
|
||||||
> `bank_kind` defines **where** an asset may reside in hardware.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Bank — Definition
|
|
||||||
|
|
||||||
> **A Bank is the residency and swapping mechanism of the Prometeu hardware.**
|
|
||||||
|
|
||||||
A Bank:
|
|
||||||
|
|
||||||
* owns **numbered slots**
|
|
||||||
* enforces **resident memory budgets**
|
|
||||||
* enforces **staging / inflight budgets**
|
|
||||||
* accepts only compatible assets
|
|
||||||
* supports **atomic swap via commit**
|
|
||||||
* exposes memory and residency metrics
|
|
||||||
|
|
||||||
Banks are hardware infrastructure, not assets.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. BankKind
|
|
||||||
|
|
||||||
Each Bank belongs to a **BankKind**, defining its pipeline and constraints.
|
|
||||||
|
|
||||||
### Example BankKinds
|
|
||||||
|
|
||||||
* `GFX_TILEBANK`
|
|
||||||
* `AUDIO_SOUNDBANK`
|
|
||||||
* `DATA_BLOBBANK`
|
|
||||||
* `MAP_TILEMAPBANK`
|
|
||||||
|
|
||||||
Each BankKind defines:
|
|
||||||
|
|
||||||
* slot count
|
|
||||||
* maximum resident memory
|
|
||||||
* inflight / staging memory budget
|
|
||||||
* decode and validation pipeline
|
|
||||||
* hardware consumer subsystem (renderer, audio mixer, etc.)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Slots and Slot References
|
|
||||||
|
|
||||||
* Each BankKind owns a fixed set of **slots**.
|
|
||||||
* A slot:
|
|
||||||
|
|
||||||
* references a resident asset (or is empty)
|
|
||||||
* never stores data directly
|
|
||||||
* may expose a **generation counter** (debug)
|
|
||||||
|
|
||||||
### Slot Reference
|
|
||||||
|
|
||||||
Slots are always referenced with explicit BankKind context:
|
|
||||||
|
|
||||||
* `gfxSlot(3)`
|
|
||||||
* `audioSlot(1)`
|
|
||||||
* `blobSlot(7)`
|
|
||||||
|
|
||||||
This prevents cross-bank ambiguity.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Bank Memory Model
|
|
||||||
|
|
||||||
* Bank memory is **console-owned memory**.
|
|
||||||
* It does not belong to the VM heap.
|
|
||||||
* It does not participate in GC.
|
|
||||||
* It can be fully released when the cartridge shuts down.
|
|
||||||
|
|
||||||
Each Bank manages:
|
|
||||||
|
|
||||||
* total memory
|
|
||||||
* used memory
|
|
||||||
* free memory
|
|
||||||
* inflight (staging) memory
|
|
||||||
|
|
||||||
Conceptually, each Bank is a **specialized allocator**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Unified Loader
|
|
||||||
|
|
||||||
### Conceptual API
|
|
||||||
|
|
||||||
```text
|
|
||||||
handle = asset.load(asset_name, slotRef, flags)
|
|
||||||
```
|
|
||||||
|
|
||||||
Load flow:
|
|
||||||
|
|
||||||
1. Resolve `asset_name` via Asset Table to get its `asset_id`
|
|
||||||
2. Read `bank_kind` from asset entry
|
|
||||||
3. Validate compatibility with `slotRef`
|
|
||||||
4. Enqueue load request
|
|
||||||
5. Perform IO + decode on worker
|
|
||||||
6. Produce materialized asset in staging
|
|
||||||
|
|
||||||
### Handle States
|
|
||||||
|
|
||||||
* `PENDING` — enqueued
|
|
||||||
* `LOADING` — IO/decode in progress
|
|
||||||
* `READY` — staging completed
|
|
||||||
* `COMMITTED` — installed into slot
|
|
||||||
* `CANCELED`
|
|
||||||
* `ERROR`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Commit
|
|
||||||
|
|
||||||
```text
|
|
||||||
asset.commit(handle)
|
|
||||||
```
|
|
||||||
|
|
||||||
* Commit is **explicit** and **atomic**
|
|
||||||
* Executed at a safe frame boundary
|
|
||||||
* Performs **pointer swap** in the target slot
|
|
||||||
* Previous asset is released if no longer referenced
|
|
||||||
|
|
||||||
The hardware **never swaps slots automatically**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Asset Deduplication
|
|
||||||
|
|
||||||
* A decoded asset exists **at most once per BankKind**.
|
|
||||||
* Multiple slots may reference the same resident asset.
|
|
||||||
* Redundant loads become **install-only** operations.
|
|
||||||
|
|
||||||
Memory duplication is forbidden by contract.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Bank Specializations
|
|
||||||
|
|
||||||
### 11.1 GFX_TILEBANK
|
|
||||||
|
|
||||||
* AssetType: TILEBANK
|
|
||||||
* Immutable graphical tile + palette structure
|
|
||||||
* Consumed by the graphics subsystem
|
|
||||||
|
|
||||||
### 11.2 AUDIO_SOUNDBANK
|
|
||||||
|
|
||||||
* AssetType: SOUNDBANK
|
|
||||||
* Resident audio samples or streams
|
|
||||||
* Consumed by the audio mixer
|
|
||||||
|
|
||||||
### 11.3 DATA_BLOBBANK
|
|
||||||
|
|
||||||
* AssetType: BLOB
|
|
||||||
* Read-only byte buffers
|
|
||||||
* Hardware does not interpret contents
|
|
||||||
|
|
||||||
Used by the SDK via:
|
|
||||||
|
|
||||||
* **Views** (zero-copy, read-only)
|
|
||||||
* **Decode** (materialization into VM heap)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. Views and Decode (SDK Contract)
|
|
||||||
|
|
||||||
* **View**
|
|
||||||
|
|
||||||
* read-only
|
|
||||||
* zero-copy
|
|
||||||
* valid only while the blob remains resident
|
|
||||||
|
|
||||||
* **Decode**
|
|
||||||
|
|
||||||
* allocates VM-owned entities
|
|
||||||
* independent from the Bank after creation
|
|
||||||
|
|
||||||
Hardware is unaware of Views and Decode semantics.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. Manifest and Initial Load
|
|
||||||
|
|
||||||
* The cartridge may include a `manifest.json`.
|
|
||||||
* The manifest may declare:
|
|
||||||
|
|
||||||
* assets to preload
|
|
||||||
* target slot references
|
|
||||||
|
|
||||||
These loads occur **before the first frame**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14. Shutdown and Eviction
|
|
||||||
|
|
||||||
* On cartridge shutdown:
|
|
||||||
|
|
||||||
* all Banks are cleared
|
|
||||||
* all resident memory is released
|
|
||||||
|
|
||||||
No implicit persistence exists.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 15. Debugger and Telemetry
|
|
||||||
|
|
||||||
Each Bank must expose:
|
|
||||||
|
|
||||||
* total memory
|
|
||||||
* used memory
|
|
||||||
* free memory
|
|
||||||
* inflight memory
|
|
||||||
* occupied slots
|
|
||||||
* `asset_id` per slot
|
|
||||||
* `asset_name` per slot
|
|
||||||
* generation per slot
|
|
||||||
|
|
||||||
This enables debuggers to visualize:
|
|
||||||
|
|
||||||
* memory stacks per Bank
|
|
||||||
* memory pressure
|
|
||||||
* streaming strategies
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 16. Minimal Syscall API (Derived)
|
|
||||||
|
|
||||||
The following syscalls form the minimal hardware contract for asset management:
|
|
||||||
|
|
||||||
```text
|
|
||||||
asset.load(asset_name, slotRef, flags) -> handle
|
|
||||||
asset.status(handle) -> LoadStatus
|
|
||||||
asset.commit(handle)
|
|
||||||
asset.cancel(handle)
|
|
||||||
|
|
||||||
bank.info(bank_kind) -> BankStats
|
|
||||||
bank.slot_info(slotRef) -> SlotStats
|
|
||||||
```
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
* `LoadStatus` ∈ { PENDING, LOADING, READY, COMMITTED, CANCELED, ERROR }
|
|
||||||
* `BankStats` exposes memory usage and limits
|
|
||||||
* `SlotStats` exposes current asset_id, asset_name and generation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 17. Separation of Responsibilities
|
|
||||||
|
|
||||||
### Hardware (Prometeu)
|
|
||||||
|
|
||||||
* manages memory
|
|
||||||
* loads bytes
|
|
||||||
* decodes assets
|
|
||||||
* swaps pointers
|
|
||||||
* reports usage
|
|
||||||
|
|
||||||
### SDK
|
|
||||||
|
|
||||||
* defines packs, scenes, and policies
|
|
||||||
* interprets blobs
|
|
||||||
* creates VM entities
|
|
||||||
|
|
||||||
### VM
|
|
||||||
|
|
||||||
* executes logic
|
|
||||||
* manages its own heap
|
|
||||||
* never owns hardware assets
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 18. Golden Rule
|
|
||||||
|
|
||||||
> **Banks are the foundation of the hardware.**
|
|
||||||
> **Asset Types describe content.**
|
|
||||||
> **The SDK orchestrates; the hardware executes.**
|
|
||||||
|
|
||||||
< [Back](chapter-14.md) | [Summary](table-of-contents.md) | [Next](chapter-16.md) >
|
|
||||||
@ -1,384 +0,0 @@
|
|||||||
< [Back](chapter-15.md) | [Summary](table-of-contents.md) >
|
|
||||||
|
|
||||||
# **Host ABI and Syscalls**
|
|
||||||
|
|
||||||
This chapter defines the Application Binary Interface (ABI) between the Prometeu Virtual Machine (PVM) and the host environment. It specifies how syscalls are identified, resolved, invoked, verified, and accounted for.
|
|
||||||
|
|
||||||
Syscalls provide controlled access to host-managed subsystems such as graphics, audio, input, asset banks, and persistent storage.
|
|
||||||
|
|
||||||
This chapter defines the **contract**. Individual subsystems (GFX, AUDIO, MEMCARD, ASSETS, etc.) define their own syscall tables that conform to this ABI.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1 Design Principles
|
|
||||||
|
|
||||||
The syscall system follows these rules:
|
|
||||||
|
|
||||||
1. **Deterministic**: Syscalls must behave deterministically for the same inputs and frame state.
|
|
||||||
2. **Synchronous**: Syscalls execute to completion within the current VM slice.
|
|
||||||
3. **Non-blocking**: Long operations must be modeled as request + status polling.
|
|
||||||
4. **Capability-gated**: Each syscall requires a declared capability.
|
|
||||||
5. **Stack-based ABI**: Arguments and return values are passed via VM slots.
|
|
||||||
6. **Not first-class**: Syscalls are callable but cannot be stored as values.
|
|
||||||
7. **Language-agnostic identity**: Syscalls are identified by canonical names, not language syntax.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2 Canonical Syscall Identity
|
|
||||||
|
|
||||||
Syscalls are identified by a **canonical triple**:
|
|
||||||
|
|
||||||
```
|
|
||||||
(module, name, version)
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
("gfx", "present", 1)
|
|
||||||
("input", "state", 1)
|
|
||||||
("audio", "play", 2)
|
|
||||||
```
|
|
||||||
|
|
||||||
This identity is:
|
|
||||||
|
|
||||||
* Independent of language syntax.
|
|
||||||
* Stable across languages and toolchains.
|
|
||||||
* Used for capability checks and linking.
|
|
||||||
|
|
||||||
### Language independence
|
|
||||||
|
|
||||||
Different languages may reference the same syscall using different syntax:
|
|
||||||
|
|
||||||
| Language style | Reference form |
|
|
||||||
| -------------- | --------------- |
|
|
||||||
| Dot-based | `gfx.present` |
|
|
||||||
| Namespace | `gfx::present` |
|
|
||||||
| Object-style | `Gfx.present()` |
|
|
||||||
| Functional | `present(gfx)` |
|
|
||||||
|
|
||||||
All of these map to the same canonical identity:
|
|
||||||
|
|
||||||
```
|
|
||||||
("gfx", "present", 1)
|
|
||||||
```
|
|
||||||
|
|
||||||
The compiler is responsible for this mapping.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3 Syscall Resolution
|
|
||||||
|
|
||||||
The host maintains a **Syscall Registry**:
|
|
||||||
|
|
||||||
```
|
|
||||||
(module, name, version) -> syscall_id
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
("gfx", "present", 1) -> 0x0101
|
|
||||||
("gfx", "submit", 1) -> 0x0102
|
|
||||||
("audio", "play", 1) -> 0x0201
|
|
||||||
```
|
|
||||||
|
|
||||||
### Resolution process
|
|
||||||
|
|
||||||
At cartridge load time:
|
|
||||||
|
|
||||||
1. The cartridge declares required syscalls using canonical identities.
|
|
||||||
2. The cartridge bytecode encodes host-backed call sites as `HOSTCALL <sysc_index>` into that declaration table.
|
|
||||||
3. The host verifies capabilities from the cartridge manifest before execution begins.
|
|
||||||
4. The host resolves each canonical identity to a numeric `syscall_id`.
|
|
||||||
5. The loader rewrites every `HOSTCALL <sysc_index>` into `SYSCALL <id>`.
|
|
||||||
6. The VM stores the patched executable image for fast execution.
|
|
||||||
|
|
||||||
At runtime, the VM executes:
|
|
||||||
|
|
||||||
```
|
|
||||||
SYSCALL <id>
|
|
||||||
```
|
|
||||||
|
|
||||||
Only numeric IDs are used during execution.
|
|
||||||
Raw `SYSCALL <id>` is not valid in a PBX pre-load artifact and must be rejected by the loader.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4 Syscall Instruction Semantics
|
|
||||||
|
|
||||||
The VM provides two relevant instruction forms across the load pipeline:
|
|
||||||
|
|
||||||
Pre-load PBX artifact:
|
|
||||||
|
|
||||||
```
|
|
||||||
HOSTCALL <sysc_index>
|
|
||||||
```
|
|
||||||
|
|
||||||
Final executable image:
|
|
||||||
|
|
||||||
```
|
|
||||||
SYSCALL <id>
|
|
||||||
```
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
* `<sysc_index>` is an index into the program-declared syscall table.
|
|
||||||
* `<id>` is a 32-bit integer identifying the syscall.
|
|
||||||
|
|
||||||
Execution steps:
|
|
||||||
|
|
||||||
1. The VM looks up syscall metadata using `<id>`.
|
|
||||||
2. The VM verifies that enough arguments exist on the stack.
|
|
||||||
3. The VM checks capability requirements defensively.
|
|
||||||
4. The syscall executes in the host environment.
|
|
||||||
5. The syscall leaves exactly `ret_slots` values on the stack.
|
|
||||||
|
|
||||||
If any contract rule is violated, the VM traps.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5 Syscall Metadata Table
|
|
||||||
|
|
||||||
Each syscall is defined by a metadata entry.
|
|
||||||
|
|
||||||
### SyscallMeta structure
|
|
||||||
|
|
||||||
```
|
|
||||||
SyscallMeta {
|
|
||||||
id: u32
|
|
||||||
module: string
|
|
||||||
name: string
|
|
||||||
version: u16
|
|
||||||
arg_slots: u8
|
|
||||||
ret_slots: u8
|
|
||||||
capability: CapabilityId
|
|
||||||
may_allocate: bool
|
|
||||||
cost_hint: u32
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Fields:
|
|
||||||
|
|
||||||
| Field | Description |
|
|
||||||
| -------------- | ------------------------------------------------ |
|
|
||||||
| `id` | Unique numeric syscall identifier |
|
|
||||||
| `module` | Canonical module name |
|
|
||||||
| `name` | Canonical syscall name |
|
|
||||||
| `version` | ABI version of the syscall |
|
|
||||||
| `arg_slots` | Number of input stack slots |
|
|
||||||
| `ret_slots` | Number of return stack slots |
|
|
||||||
| `capability` | Required capability |
|
|
||||||
| `may_allocate` | Whether the syscall may allocate VM heap objects |
|
|
||||||
| `cost_hint` | Expected cycle cost |
|
|
||||||
|
|
||||||
The loader uses this table to resolve canonical identities, validate declared ABI shape, and enforce capability gating. The verifier uses the final numeric metadata to validate stack effects after patching.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6 Arguments and Return Values
|
|
||||||
|
|
||||||
Syscalls use the same slot-based ABI as functions.
|
|
||||||
|
|
||||||
### Argument passing
|
|
||||||
|
|
||||||
Arguments are pushed onto the stack before the syscall.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
push a
|
|
||||||
push b
|
|
||||||
SYSCALL X // expects 2 arguments
|
|
||||||
```
|
|
||||||
|
|
||||||
### Return values
|
|
||||||
|
|
||||||
After execution, the syscall leaves exactly `ret_slots` values on the stack.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
// before: []
|
|
||||||
SYSCALL input_state
|
|
||||||
// after: [held, pressed, released]
|
|
||||||
```
|
|
||||||
|
|
||||||
Composite return values are represented as multiple slots (stack tuples).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7 Syscalls as Callable Entities (Not First-Class)
|
|
||||||
|
|
||||||
Syscalls behave like functions in terms of arguments and return values, but they are **not first-class values**.
|
|
||||||
|
|
||||||
This means:
|
|
||||||
|
|
||||||
* Syscalls can be invoked.
|
|
||||||
* Syscalls cannot be stored in variables.
|
|
||||||
* Syscalls cannot be passed as arguments.
|
|
||||||
* Syscalls cannot be returned from functions.
|
|
||||||
|
|
||||||
Only user-defined functions and closures are first-class.
|
|
||||||
|
|
||||||
### Conceptual declaration
|
|
||||||
|
|
||||||
```
|
|
||||||
host fn input_state() -> (int, int, int)
|
|
||||||
```
|
|
||||||
|
|
||||||
This represents a syscall with three return values, but it cannot be treated as a function value.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8 Error Model: Traps vs Status Codes
|
|
||||||
|
|
||||||
Syscalls use a hybrid error model.
|
|
||||||
|
|
||||||
### Trap conditions (contract violations)
|
|
||||||
|
|
||||||
The VM traps when:
|
|
||||||
|
|
||||||
* The syscall id is invalid.
|
|
||||||
* The canonical identity cannot be resolved.
|
|
||||||
* The required capability is missing.
|
|
||||||
* The stack does not contain enough arguments.
|
|
||||||
* A handle is invalid or dead.
|
|
||||||
|
|
||||||
These are fatal contract violations.
|
|
||||||
|
|
||||||
### Status returns (domain conditions)
|
|
||||||
|
|
||||||
Normal operational states are returned as values.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
* asset not yet loaded
|
|
||||||
* audio voice unavailable
|
|
||||||
* memcard full
|
|
||||||
|
|
||||||
These are represented by status codes in return slots.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9 Capability System
|
|
||||||
|
|
||||||
Each syscall requires a capability.
|
|
||||||
|
|
||||||
Capabilities are declared by the cartridge manifest.
|
|
||||||
|
|
||||||
Example capability groups:
|
|
||||||
|
|
||||||
* `gfx`
|
|
||||||
* `audio`
|
|
||||||
* `input`
|
|
||||||
* `asset`
|
|
||||||
* `memcard`
|
|
||||||
|
|
||||||
If a syscall is invoked without the required capability:
|
|
||||||
|
|
||||||
* The VM traps.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10 Interaction with the Garbage Collector
|
|
||||||
|
|
||||||
The VM heap is managed by the GC. Host-managed memory is separate.
|
|
||||||
|
|
||||||
### Heap vs host memory
|
|
||||||
|
|
||||||
| Memory | Managed by | GC scanned |
|
|
||||||
| --------------- | ---------- | ---------- |
|
|
||||||
| VM heap objects | VM GC | Yes |
|
|
||||||
| Asset banks | Host | No |
|
|
||||||
| Audio buffers | Host | No |
|
|
||||||
| Framebuffers | Host | No |
|
|
||||||
|
|
||||||
Assets are addressed by identifiers, not VM heap handles.
|
|
||||||
|
|
||||||
### Host root rule
|
|
||||||
|
|
||||||
If a syscall stores a handle to a VM heap object beyond the duration of the call, it must register that handle as a **host root**.
|
|
||||||
|
|
||||||
This prevents the GC from collecting objects still in use by the host.
|
|
||||||
|
|
||||||
This rule applies only to VM heap objects (such as closures or user objects), not to asset identifiers or primitive values.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11 Determinism Rules
|
|
||||||
|
|
||||||
Syscalls must obey deterministic execution rules.
|
|
||||||
|
|
||||||
Forbidden behaviors:
|
|
||||||
|
|
||||||
* reading real-time clocks
|
|
||||||
* accessing non-deterministic OS APIs
|
|
||||||
* performing blocking I/O
|
|
||||||
|
|
||||||
Allowed patterns:
|
|
||||||
|
|
||||||
* frame-based timers
|
|
||||||
* request + poll status models
|
|
||||||
* event delivery at frame boundaries
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12 Cost Model and Budgeting
|
|
||||||
|
|
||||||
Each syscall contributes to frame cost.
|
|
||||||
|
|
||||||
The VM tracks:
|
|
||||||
|
|
||||||
* cycles spent in syscalls
|
|
||||||
* syscall counts
|
|
||||||
* allocation cost (if any)
|
|
||||||
|
|
||||||
Example telemetry:
|
|
||||||
|
|
||||||
```
|
|
||||||
Frame 10231:
|
|
||||||
Syscalls: 12
|
|
||||||
Cycles (syscalls): 380
|
|
||||||
Allocations via syscalls: 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Nothing is free.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13 Blocking and Long Operations
|
|
||||||
|
|
||||||
Syscalls must not block.
|
|
||||||
|
|
||||||
Long operations must use a two-phase model:
|
|
||||||
|
|
||||||
1. Request
|
|
||||||
2. Status polling or event notification
|
|
||||||
|
|
||||||
Example pattern:
|
|
||||||
|
|
||||||
```
|
|
||||||
asset.load(id)
|
|
||||||
...
|
|
||||||
status, progress = asset.status(id)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14 Summary
|
|
||||||
|
|
||||||
* Syscalls are deterministic, synchronous, and non-blocking.
|
|
||||||
* They use the same slot-based ABI as functions.
|
|
||||||
* They are callable but not first-class.
|
|
||||||
* They are identified canonically by `(module, name, version)`.
|
|
||||||
* Language syntax does not affect the ABI.
|
|
||||||
* The host resolves canonical identities to numeric syscall IDs.
|
|
||||||
* Capabilities control access to host subsystems.
|
|
||||||
* GC only manages VM heap objects.
|
|
||||||
* Host-held heap objects must be registered as roots.
|
|
||||||
* All syscall costs are tracked per frame.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
< [Back](chapter-15.md) | [Summary](table-of-contents.md) >
|
|
||||||
@ -1,427 +0,0 @@
|
|||||||
< [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >
|
|
||||||
|
|
||||||
# **Prometeu Virtual Machine (PVM)**
|
|
||||||
|
|
||||||
This chapter defines the execution model, value system, calling convention, memory model, and host interface of the Prometeu Virtual Machine.
|
|
||||||
|
|
||||||
The PVM is a **deterministic, stack-based VM** designed for a 2D fantasy console environment. Its primary goal is to provide predictable performance, safe memory access, and a stable execution contract suitable for real-time games running at a fixed frame rate. fileciteturn2file0
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1 Core Design Principles
|
|
||||||
|
|
||||||
The PVM is designed around the following constraints:
|
|
||||||
|
|
||||||
1. **Deterministic execution**: no hidden threads or asynchronous callbacks.
|
|
||||||
2. **Frame-based timing**: execution is bounded by frame time.
|
|
||||||
3. **Safe memory model**: all heap objects are accessed through handles.
|
|
||||||
4. **Simple compilation target**: stack-based bytecode with verified control flow.
|
|
||||||
5. **Stable ABI**: multi-value returns with fixed slot semantics.
|
|
||||||
6. **First-class functions**: functions can be passed, stored, and returned.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2 Execution Model
|
|
||||||
|
|
||||||
The PVM executes bytecode in a **frame loop**. Each frame:
|
|
||||||
|
|
||||||
1. The firmware enters the VM.
|
|
||||||
2. The VM runs until:
|
|
||||||
|
|
||||||
* the frame budget is consumed, or
|
|
||||||
* a `FRAME_SYNC` instruction is reached.
|
|
||||||
3. At `FRAME_SYNC`:
|
|
||||||
|
|
||||||
* events are delivered
|
|
||||||
* input is sampled
|
|
||||||
* optional GC may run
|
|
||||||
4. Control returns to the firmware.
|
|
||||||
|
|
||||||
`FRAME_SYNC` is the **primary safepoint** in the system.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3 Value Types
|
|
||||||
|
|
||||||
All runtime values are stored in VM slots as a `Value`.
|
|
||||||
|
|
||||||
### Primitive value types (stack values)
|
|
||||||
|
|
||||||
| Type | Description |
|
|
||||||
| ------- | --------------------- |
|
|
||||||
| `int` | 64-bit signed integer |
|
|
||||||
| `bool` | Boolean value |
|
|
||||||
| `float` | 64-bit floating point |
|
|
||||||
|
|
||||||
### Built-in vector and graphics types (stack values)
|
|
||||||
|
|
||||||
These are treated as VM primitives with dedicated opcodes:
|
|
||||||
|
|
||||||
| Type | Description |
|
|
||||||
| ------- | --------------------------------- |
|
|
||||||
| `vec2` | 2D vector (x, y) |
|
|
||||||
| `color` | Packed color value |
|
|
||||||
| `pixel` | Combination of position and color |
|
|
||||||
|
|
||||||
These types:
|
|
||||||
|
|
||||||
* live entirely on the stack
|
|
||||||
* are copied by value
|
|
||||||
* never allocate on the heap
|
|
||||||
|
|
||||||
### Heap values
|
|
||||||
|
|
||||||
All user-defined objects live on the heap and are accessed via **handles**.
|
|
||||||
|
|
||||||
| Type | Description |
|
|
||||||
| -------- | -------------------------- |
|
|
||||||
| `handle` | Reference to a heap object |
|
|
||||||
| `null` | Null handle |
|
|
||||||
|
|
||||||
Handles may refer to:
|
|
||||||
|
|
||||||
* user objects
|
|
||||||
* arrays
|
|
||||||
* strings
|
|
||||||
* closures
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4 Handles and Gate Table
|
|
||||||
|
|
||||||
Heap objects are accessed through **handles**. A handle is a pair:
|
|
||||||
|
|
||||||
```
|
|
||||||
handle = { index, generation }
|
|
||||||
```
|
|
||||||
|
|
||||||
The VM maintains a **gate table**:
|
|
||||||
|
|
||||||
```
|
|
||||||
GateEntry {
|
|
||||||
alive: bool
|
|
||||||
generation: u32
|
|
||||||
base: usize
|
|
||||||
slots: u32
|
|
||||||
type_id: u32
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When an object is freed:
|
|
||||||
|
|
||||||
* its gate entry is marked dead
|
|
||||||
* its generation is incremented
|
|
||||||
|
|
||||||
If a handle’s generation does not match the gate entry, the VM traps.
|
|
||||||
|
|
||||||
This prevents use-after-free bugs.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5 Heap Model
|
|
||||||
|
|
||||||
* All user objects live in the heap.
|
|
||||||
* Objects are fixed-layout blocks of slots.
|
|
||||||
* No inheritance at the memory level.
|
|
||||||
* Traits/interfaces are resolved by the compiler or via vtables.
|
|
||||||
|
|
||||||
Built-in types remain stack-only.
|
|
||||||
|
|
||||||
Heap objects include:
|
|
||||||
|
|
||||||
* user structs/classes
|
|
||||||
* strings
|
|
||||||
* arrays
|
|
||||||
* closures
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6 Tuples and Multi-Return ABI
|
|
||||||
|
|
||||||
The PVM supports **multi-value returns**.
|
|
||||||
|
|
||||||
### Tuple rules
|
|
||||||
|
|
||||||
* Tuples are **stack-only**.
|
|
||||||
* Maximum tuple arity is **N = 6**.
|
|
||||||
* Tuples are not heap objects by default.
|
|
||||||
* To persist a tuple, it must be explicitly boxed.
|
|
||||||
|
|
||||||
### Call convention
|
|
||||||
|
|
||||||
Each function declares a fixed `ret_slots` value.
|
|
||||||
|
|
||||||
At call time:
|
|
||||||
|
|
||||||
1. Caller prepares arguments.
|
|
||||||
2. `CALL` transfers control.
|
|
||||||
3. Callee executes.
|
|
||||||
4. `RET` leaves exactly `ret_slots` values on the stack.
|
|
||||||
|
|
||||||
The verifier ensures that:
|
|
||||||
|
|
||||||
* all control paths produce the same `ret_slots`
|
|
||||||
* stack depth is consistent.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7 Call Stack and Frames
|
|
||||||
|
|
||||||
The VM uses a **call stack**.
|
|
||||||
|
|
||||||
Each frame contains:
|
|
||||||
|
|
||||||
```
|
|
||||||
Frame {
|
|
||||||
return_pc
|
|
||||||
base_pointer
|
|
||||||
ret_slots
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Execution uses only the following call instructions:
|
|
||||||
|
|
||||||
| Opcode | Description |
|
|
||||||
| ------ | ---------------------- |
|
|
||||||
| `CALL` | Calls a function by id |
|
|
||||||
| `RET` | Returns from function |
|
|
||||||
|
|
||||||
There is no separate `PUSH_FRAME` or `POP_FRAME` instruction in the public ISA.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8 Closures and First-Class Functions
|
|
||||||
|
|
||||||
Closures are heap objects and represent **function values**.
|
|
||||||
|
|
||||||
The PVM treats functions as **first-class values**. This means:
|
|
||||||
|
|
||||||
* Functions can be stored in variables.
|
|
||||||
* Functions can be passed as arguments.
|
|
||||||
* Functions can be returned from other functions.
|
|
||||||
* All function values are represented as closures.
|
|
||||||
|
|
||||||
Even functions without captures are represented as closures with an empty capture set.
|
|
||||||
|
|
||||||
### Closure layout
|
|
||||||
|
|
||||||
```
|
|
||||||
Closure {
|
|
||||||
func_id
|
|
||||||
captures[]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Captures are stored as handles or value copies.
|
|
||||||
|
|
||||||
All closure environments are part of the GC root set.
|
|
||||||
|
|
||||||
### Direct and indirect calls
|
|
||||||
|
|
||||||
The PVM supports two forms of function invocation:
|
|
||||||
|
|
||||||
| Opcode | Description |
|
|
||||||
| -------------- | -------------------------------------- |
|
|
||||||
| `CALL` | Direct call by function id |
|
|
||||||
| `CALL_CLOSURE` | Indirect call through a closure handle |
|
|
||||||
|
|
||||||
For `CALL_CLOSURE`:
|
|
||||||
|
|
||||||
1. The closure handle is read from the stack.
|
|
||||||
2. The VM extracts the `func_id` from the closure.
|
|
||||||
3. The function is invoked using the closure’s captures as its environment.
|
|
||||||
|
|
||||||
The verifier ensures that:
|
|
||||||
|
|
||||||
* The closure handle is valid.
|
|
||||||
* The target function’s arity matches the call site.
|
|
||||||
* The `ret_slots` contract is respected.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9 Coroutines (Deterministic)
|
|
||||||
|
|
||||||
The PVM supports **cooperative coroutines**.
|
|
||||||
|
|
||||||
Characteristics:
|
|
||||||
|
|
||||||
* Coroutines are scheduled deterministically.
|
|
||||||
* No preemption.
|
|
||||||
* No parallel execution.
|
|
||||||
* All scheduling happens at safepoints.
|
|
||||||
|
|
||||||
Each coroutine contains:
|
|
||||||
|
|
||||||
```
|
|
||||||
Coroutine {
|
|
||||||
call_stack
|
|
||||||
operand_stack
|
|
||||||
state
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Coroutine instructions
|
|
||||||
|
|
||||||
| Opcode | Description |
|
|
||||||
| ------- | -------------------------- |
|
|
||||||
| `SPAWN` | Creates a coroutine |
|
|
||||||
| `YIELD` | Suspends current coroutine |
|
|
||||||
| `SLEEP` | Suspends for N frames |
|
|
||||||
|
|
||||||
Scheduling is:
|
|
||||||
|
|
||||||
* round-robin
|
|
||||||
* deterministic
|
|
||||||
* bounded by frame budget
|
|
||||||
|
|
||||||
Coroutine stacks are part of the GC root set.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10 Garbage Collection
|
|
||||||
|
|
||||||
The PVM uses a **mark-sweep collector**.
|
|
||||||
|
|
||||||
### GC rules
|
|
||||||
|
|
||||||
* GC runs only at **safepoints**.
|
|
||||||
* The primary safepoint is `FRAME_SYNC`.
|
|
||||||
* GC is triggered by:
|
|
||||||
|
|
||||||
* heap thresholds, or
|
|
||||||
* allocation pressure.
|
|
||||||
|
|
||||||
### Root set
|
|
||||||
|
|
||||||
The GC marks from:
|
|
||||||
|
|
||||||
* operand stack
|
|
||||||
* call stack frames
|
|
||||||
* global variables
|
|
||||||
* coroutine stacks
|
|
||||||
* closure environments
|
|
||||||
* host-held handles
|
|
||||||
|
|
||||||
The collector:
|
|
||||||
|
|
||||||
* does not compact memory (v1)
|
|
||||||
* uses free lists for reuse
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11 Event and Interrupt Model
|
|
||||||
|
|
||||||
The PVM does not allow asynchronous callbacks.
|
|
||||||
|
|
||||||
All events are:
|
|
||||||
|
|
||||||
* queued by the firmware
|
|
||||||
* delivered at `FRAME_SYNC`
|
|
||||||
|
|
||||||
This ensures:
|
|
||||||
|
|
||||||
* deterministic execution
|
|
||||||
* predictable frame timing
|
|
||||||
|
|
||||||
Coroutines are the only supported concurrency mechanism.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12 Host Interface (Syscalls)
|
|
||||||
|
|
||||||
All hardware access occurs through syscalls.
|
|
||||||
|
|
||||||
Syscalls are:
|
|
||||||
|
|
||||||
* synchronous
|
|
||||||
* deterministic
|
|
||||||
* capability-checked
|
|
||||||
|
|
||||||
They operate on the following subsystems:
|
|
||||||
|
|
||||||
### Graphics
|
|
||||||
|
|
||||||
* tilebanks
|
|
||||||
* layers
|
|
||||||
* sprites
|
|
||||||
* palette control
|
|
||||||
* fade registers
|
|
||||||
* frame present
|
|
||||||
|
|
||||||
### Audio
|
|
||||||
|
|
||||||
* voice allocation
|
|
||||||
* play/stop
|
|
||||||
* volume/pan/pitch
|
|
||||||
* steal policy
|
|
||||||
|
|
||||||
### Input
|
|
||||||
|
|
||||||
* sampled once per frame
|
|
||||||
* exposed as frame state
|
|
||||||
|
|
||||||
### Assets
|
|
||||||
|
|
||||||
Asset banks are **host-owned memory**.
|
|
||||||
|
|
||||||
The VM interacts through handles:
|
|
||||||
|
|
||||||
| Syscall | Description |
|
|
||||||
| -------------- | ---------------------------- |
|
|
||||||
| `asset.load` | Request asset load into slot |
|
|
||||||
| `asset.status` | Query load state |
|
|
||||||
| `asset.commit` | Activate loaded asset |
|
|
||||||
|
|
||||||
Asset memory:
|
|
||||||
|
|
||||||
* is not part of the VM heap
|
|
||||||
* is not scanned by GC
|
|
||||||
|
|
||||||
### Save Memory (MEMCARD)
|
|
||||||
|
|
||||||
| Syscall | Description |
|
|
||||||
| --------------- | --------------- |
|
|
||||||
| `mem.read_all` | Read save data |
|
|
||||||
| `mem.write_all` | Write save data |
|
|
||||||
| `mem.commit` | Persist save |
|
|
||||||
| `mem.size` | Query capacity |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13 Verifier Requirements
|
|
||||||
|
|
||||||
Before execution, bytecode must pass the verifier.
|
|
||||||
|
|
||||||
The verifier ensures:
|
|
||||||
|
|
||||||
1. Valid jump targets
|
|
||||||
2. Stack depth consistency
|
|
||||||
3. Correct `ret_slots` across all paths
|
|
||||||
4. Handle safety rules
|
|
||||||
5. Closure call safety
|
|
||||||
6. No invalid opcode sequences
|
|
||||||
|
|
||||||
Invalid bytecode is rejected.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14 Summary
|
|
||||||
|
|
||||||
The Prometeu VM is:
|
|
||||||
|
|
||||||
* stack-based
|
|
||||||
* deterministic
|
|
||||||
* frame-synchronized
|
|
||||||
* handle-based for heap access
|
|
||||||
* multi-return capable
|
|
||||||
* first-class function capable
|
|
||||||
* coroutine-driven for concurrency
|
|
||||||
|
|
||||||
This design balances:
|
|
||||||
|
|
||||||
* ease of compilation
|
|
||||||
* predictable performance
|
|
||||||
* safety and debuggability
|
|
||||||
* suitability for real-time 2D games.
|
|
||||||
|
|
||||||
< [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >
|
|
||||||
@ -1,353 +0,0 @@
|
|||||||
< [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
|
|
||||||
|
|
||||||
# 🧠 **Memory Model**
|
|
||||||
|
|
||||||
This chapter defines the memory architecture of the Prometeu Virtual Machine (PVM). It describes the stack, heap, handles, object layout, garbage collection, and interaction with host-owned memory such as asset banks.
|
|
||||||
|
|
||||||
The memory model is designed to be:
|
|
||||||
|
|
||||||
* deterministic
|
|
||||||
* safe
|
|
||||||
* simple to verify
|
|
||||||
* suitable for real-time 2D games
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1 Overview
|
|
||||||
|
|
||||||
The PVM uses a **split memory model**:
|
|
||||||
|
|
||||||
1. **Stack memory**
|
|
||||||
|
|
||||||
* used for temporary values
|
|
||||||
* function arguments
|
|
||||||
* multi-return tuples
|
|
||||||
2. **Heap memory**
|
|
||||||
|
|
||||||
* used for all user-defined objects
|
|
||||||
* accessed only through handles
|
|
||||||
3. **Host-owned memory**
|
|
||||||
|
|
||||||
* asset banks
|
|
||||||
* audio buffers
|
|
||||||
* framebuffers
|
|
||||||
* not part of the VM heap
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2 Stack Memory
|
|
||||||
|
|
||||||
The stack is used for:
|
|
||||||
|
|
||||||
* primitive values
|
|
||||||
* built-in value types
|
|
||||||
* temporary results
|
|
||||||
* function arguments
|
|
||||||
* tuple returns
|
|
||||||
|
|
||||||
### Stack value types
|
|
||||||
|
|
||||||
| Type | Description |
|
|
||||||
| -------- | ------------------------ |
|
|
||||||
| `int` | 64-bit integer |
|
|
||||||
| `bool` | Boolean |
|
|
||||||
| `float` | 64-bit float |
|
|
||||||
| `vec2` | 2D vector |
|
|
||||||
| `color` | Packed color |
|
|
||||||
| `pixel` | Position + color |
|
|
||||||
| `handle` | Reference to heap object |
|
|
||||||
|
|
||||||
All stack values are:
|
|
||||||
|
|
||||||
* fixed-size
|
|
||||||
* copied by value
|
|
||||||
* never directly reference raw memory
|
|
||||||
|
|
||||||
### Stack properties
|
|
||||||
|
|
||||||
* Stack is bounded and verified.
|
|
||||||
* Stack depth must be consistent across all control paths.
|
|
||||||
* Stack never stores raw pointers.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3 Tuples (Stack-Only Aggregates)
|
|
||||||
|
|
||||||
Tuples are used for multi-value returns.
|
|
||||||
|
|
||||||
### Tuple rules
|
|
||||||
|
|
||||||
* Tuples exist only on the stack.
|
|
||||||
* Maximum tuple arity: **6 slots**.
|
|
||||||
* Tuples are not heap objects by default.
|
|
||||||
* To persist a tuple, it must be explicitly boxed into a heap object.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
Function returning two values:
|
|
||||||
|
|
||||||
```
|
|
||||||
fn position(): (int, int)
|
|
||||||
```
|
|
||||||
|
|
||||||
At runtime:
|
|
||||||
|
|
||||||
```
|
|
||||||
stack top → [x, y]
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4 Heap Memory
|
|
||||||
|
|
||||||
All user-defined objects live in the heap.
|
|
||||||
|
|
||||||
### Heap characteristics
|
|
||||||
|
|
||||||
* Linear slot-based storage.
|
|
||||||
* Objects are fixed-layout blocks.
|
|
||||||
* No raw pointer access.
|
|
||||||
* No inheritance at memory level.
|
|
||||||
|
|
||||||
Heap objects include:
|
|
||||||
|
|
||||||
* user structs/classes
|
|
||||||
* arrays
|
|
||||||
* strings
|
|
||||||
* closures
|
|
||||||
* boxed tuples (optional)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5 Handles and Gate Table
|
|
||||||
|
|
||||||
All heap objects are accessed via **handles**.
|
|
||||||
|
|
||||||
A handle is defined as:
|
|
||||||
|
|
||||||
```
|
|
||||||
handle = { index, generation }
|
|
||||||
```
|
|
||||||
|
|
||||||
The VM maintains a **gate table**:
|
|
||||||
|
|
||||||
```
|
|
||||||
GateEntry {
|
|
||||||
alive: bool
|
|
||||||
generation: u32
|
|
||||||
base: usize
|
|
||||||
slots: u32
|
|
||||||
type_id: u32
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Handle safety
|
|
||||||
|
|
||||||
When an object is freed:
|
|
||||||
|
|
||||||
* `alive` becomes false
|
|
||||||
* `generation` is incremented
|
|
||||||
|
|
||||||
When a handle is used:
|
|
||||||
|
|
||||||
* index must exist
|
|
||||||
* generation must match
|
|
||||||
|
|
||||||
Otherwise, the VM traps.
|
|
||||||
|
|
||||||
This prevents:
|
|
||||||
|
|
||||||
* use-after-free
|
|
||||||
* stale references
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6 Object Layout
|
|
||||||
|
|
||||||
Heap objects have a simple, fixed layout:
|
|
||||||
|
|
||||||
```
|
|
||||||
Object {
|
|
||||||
type_id
|
|
||||||
field_0
|
|
||||||
field_1
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Properties:
|
|
||||||
|
|
||||||
* Fields are stored in slot order.
|
|
||||||
* No hidden base classes.
|
|
||||||
* No pointer arithmetic.
|
|
||||||
|
|
||||||
Traits and method dispatch are resolved:
|
|
||||||
|
|
||||||
* statically by the compiler, or
|
|
||||||
* via vtable handles (if dynamic dispatch is used).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7 Closures
|
|
||||||
|
|
||||||
Closures are heap objects.
|
|
||||||
|
|
||||||
Layout:
|
|
||||||
|
|
||||||
```
|
|
||||||
Closure {
|
|
||||||
func_id
|
|
||||||
capture_count
|
|
||||||
captures[]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Captures may be:
|
|
||||||
|
|
||||||
* copied values
|
|
||||||
* handles to heap objects
|
|
||||||
|
|
||||||
Closure environments are part of the GC root set.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8 Coroutine Memory
|
|
||||||
|
|
||||||
Each coroutine owns its own stacks:
|
|
||||||
|
|
||||||
```
|
|
||||||
Coroutine {
|
|
||||||
call_stack
|
|
||||||
operand_stack
|
|
||||||
state
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
All coroutine stacks are included in the GC root set.
|
|
||||||
|
|
||||||
Coroutines do not share stacks or frames.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9 Garbage Collection
|
|
||||||
|
|
||||||
The PVM uses a **mark-sweep collector**.
|
|
||||||
|
|
||||||
### GC properties
|
|
||||||
|
|
||||||
* Non-moving (no compaction in v1).
|
|
||||||
* Runs only at **safepoints**.
|
|
||||||
* Primary safepoint: `FRAME_SYNC`.
|
|
||||||
|
|
||||||
### GC triggers
|
|
||||||
|
|
||||||
GC may run when:
|
|
||||||
|
|
||||||
* heap usage exceeds threshold
|
|
||||||
* allocation pressure is high
|
|
||||||
|
|
||||||
### Root set
|
|
||||||
|
|
||||||
The collector marks from:
|
|
||||||
|
|
||||||
* operand stack
|
|
||||||
* call stack frames
|
|
||||||
* global variables
|
|
||||||
* coroutine stacks
|
|
||||||
* closure environments
|
|
||||||
* host-held handles
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10 Allocation and Deallocation
|
|
||||||
|
|
||||||
### Allocation
|
|
||||||
|
|
||||||
Heap allocation:
|
|
||||||
|
|
||||||
1. VM reserves a slot block.
|
|
||||||
2. A gate entry is created.
|
|
||||||
3. A handle is returned.
|
|
||||||
|
|
||||||
If allocation fails:
|
|
||||||
|
|
||||||
* VM may trigger GC.
|
|
||||||
* If still failing, a trap occurs.
|
|
||||||
|
|
||||||
### Deallocation
|
|
||||||
|
|
||||||
Objects are freed only by the GC.
|
|
||||||
|
|
||||||
When freed:
|
|
||||||
|
|
||||||
* gate is marked dead
|
|
||||||
* generation is incremented
|
|
||||||
* memory becomes available via free list
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11 Host-Owned Memory (Asset Banks)
|
|
||||||
|
|
||||||
Asset memory is **not part of the VM heap**.
|
|
||||||
|
|
||||||
It is managed by the firmware.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
* tilebanks
|
|
||||||
* audio sample banks
|
|
||||||
* sprite sheets
|
|
||||||
|
|
||||||
### Properties
|
|
||||||
|
|
||||||
* VM cannot access asset memory directly.
|
|
||||||
* Access occurs only through syscalls.
|
|
||||||
* Asset memory is not scanned by GC.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12 Save Memory (MEMCARD)
|
|
||||||
|
|
||||||
Save memory is a host-managed persistent storage area.
|
|
||||||
|
|
||||||
Properties:
|
|
||||||
|
|
||||||
* fixed size
|
|
||||||
* accessed only via syscalls
|
|
||||||
* not part of the VM heap
|
|
||||||
* not scanned by GC
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13 Memory Safety Rules
|
|
||||||
|
|
||||||
The VM enforces:
|
|
||||||
|
|
||||||
1. All heap access via handles.
|
|
||||||
2. Generation checks on every handle use.
|
|
||||||
3. Bounds checking on object fields.
|
|
||||||
4. No raw pointer arithmetic.
|
|
||||||
5. Verified stack discipline.
|
|
||||||
|
|
||||||
Any violation results in a trap.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14 Summary
|
|
||||||
|
|
||||||
The PVM memory model is based on:
|
|
||||||
|
|
||||||
* stack-only primitive and tuple values
|
|
||||||
* heap-only user objects
|
|
||||||
* generation-based handles
|
|
||||||
* deterministic GC at frame safepoints
|
|
||||||
* strict separation between VM heap and host memory
|
|
||||||
|
|
||||||
This design ensures:
|
|
||||||
|
|
||||||
* predictable performance
|
|
||||||
* memory safety
|
|
||||||
* simple verification
|
|
||||||
* suitability for real-time game workloads.
|
|
||||||
|
|
||||||
< [Back](chapter-2.md) | [Summary](table-of-contents.md) | [Next](chapter-4.md) >
|
|
||||||
@ -1,308 +0,0 @@
|
|||||||
< [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >
|
|
||||||
|
|
||||||
# ⚡ **Events and Scheduling**
|
|
||||||
|
|
||||||
This chapter defines how the Prometeu Virtual Machine (PVM) handles events, frame synchronization, and cooperative concurrency. It replaces the older interrupt-oriented terminology with a simpler and more accurate model based on **frame boundaries**, **event queues**, and **coroutines**.
|
|
||||||
|
|
||||||
The goal is to preserve determinism while still allowing responsive and structured game logic.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1 Core Philosophy
|
|
||||||
|
|
||||||
Prometeu does **not use asynchronous callbacks** or preemptive interrupts for user code.
|
|
||||||
|
|
||||||
All external signals are:
|
|
||||||
|
|
||||||
* queued by the firmware
|
|
||||||
* delivered at deterministic points
|
|
||||||
* processed inside the main execution loop
|
|
||||||
|
|
||||||
Nothing executes “out of time”.
|
|
||||||
Nothing interrupts the program in the middle of an instruction.
|
|
||||||
Nothing occurs without a known cost.
|
|
||||||
|
|
||||||
This guarantees:
|
|
||||||
|
|
||||||
* deterministic behavior
|
|
||||||
* reproducible runs
|
|
||||||
* stable frame timing
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2 Events
|
|
||||||
|
|
||||||
### 2.1 Definition
|
|
||||||
|
|
||||||
An **event** is a logical signal generated by the system or by internal runtime mechanisms.
|
|
||||||
|
|
||||||
Events:
|
|
||||||
|
|
||||||
* represent something that has occurred
|
|
||||||
* do not execute code automatically
|
|
||||||
* are processed explicitly during the frame
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
* end of frame
|
|
||||||
* timer expiration
|
|
||||||
* asset load completion
|
|
||||||
* system state change
|
|
||||||
* execution error
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2.2 Event Queue
|
|
||||||
|
|
||||||
The firmware maintains an **event queue**.
|
|
||||||
|
|
||||||
Properties:
|
|
||||||
|
|
||||||
* events are queued in order
|
|
||||||
* events are processed at frame boundaries
|
|
||||||
* event processing is deterministic
|
|
||||||
|
|
||||||
Events never:
|
|
||||||
|
|
||||||
* execute user code automatically
|
|
||||||
* interrupt instructions
|
|
||||||
* run outside the main loop
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3 Frame Boundary (Sync Phase)
|
|
||||||
|
|
||||||
The primary synchronization point in Prometeu is the **frame boundary**, reached by the `FRAME_SYNC` instruction.
|
|
||||||
|
|
||||||
At this point:
|
|
||||||
|
|
||||||
1. Input state is sampled.
|
|
||||||
2. Events are delivered.
|
|
||||||
3. Coroutine scheduling occurs.
|
|
||||||
4. Optional garbage collection may run.
|
|
||||||
5. Control returns to the firmware.
|
|
||||||
|
|
||||||
This replaces the older notion of a "VBlank interrupt".
|
|
||||||
|
|
||||||
The frame boundary:
|
|
||||||
|
|
||||||
* has a fixed, measurable cost
|
|
||||||
* does not execute arbitrary user code
|
|
||||||
* is fully deterministic
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4 System Events vs System Faults
|
|
||||||
|
|
||||||
Prometeu distinguishes between normal events and system faults.
|
|
||||||
|
|
||||||
### 4.1 Normal events
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
* timer expired
|
|
||||||
* asset loaded
|
|
||||||
* frame boundary
|
|
||||||
|
|
||||||
These are delivered through the event queue.
|
|
||||||
|
|
||||||
### 4.2 System faults
|
|
||||||
|
|
||||||
Generated by exceptional conditions:
|
|
||||||
|
|
||||||
* invalid instruction
|
|
||||||
* memory violation
|
|
||||||
* handle misuse
|
|
||||||
* verifier failure
|
|
||||||
|
|
||||||
Result:
|
|
||||||
|
|
||||||
* VM execution stops
|
|
||||||
* state is preserved
|
|
||||||
* a diagnostic report is generated
|
|
||||||
|
|
||||||
System faults are not recoverable events.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5 Timers
|
|
||||||
|
|
||||||
Timers are modeled as **frame-based counters**.
|
|
||||||
|
|
||||||
Properties:
|
|
||||||
|
|
||||||
* measured in frames, not real time
|
|
||||||
* deterministic across runs
|
|
||||||
* generate events when they expire
|
|
||||||
|
|
||||||
Timers:
|
|
||||||
|
|
||||||
* do not execute code automatically
|
|
||||||
* produce queryable or queued events
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
if timer.expired(t1) {
|
|
||||||
// handle event
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6 Coroutines and Cooperative Scheduling
|
|
||||||
|
|
||||||
Prometeu provides **coroutines** as the only form of concurrency.
|
|
||||||
|
|
||||||
Coroutines are:
|
|
||||||
|
|
||||||
* cooperative
|
|
||||||
* deterministic
|
|
||||||
* scheduled only at safe points
|
|
||||||
|
|
||||||
There is:
|
|
||||||
|
|
||||||
* no preemption
|
|
||||||
* no parallel execution
|
|
||||||
* no hidden threads
|
|
||||||
|
|
||||||
### 6.1 Coroutine lifecycle
|
|
||||||
|
|
||||||
Each coroutine can be in one of the following states:
|
|
||||||
|
|
||||||
* `Ready`
|
|
||||||
* `Running`
|
|
||||||
* `Sleeping`
|
|
||||||
* `Finished`
|
|
||||||
|
|
||||||
### 6.2 Scheduling
|
|
||||||
|
|
||||||
At each frame boundary:
|
|
||||||
|
|
||||||
1. The scheduler selects the next coroutine.
|
|
||||||
2. Coroutines run in a deterministic order.
|
|
||||||
3. Each coroutine executes within the frame budget.
|
|
||||||
|
|
||||||
The default scheduling policy is:
|
|
||||||
|
|
||||||
* round-robin
|
|
||||||
* deterministic
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6.3 Coroutine operations
|
|
||||||
|
|
||||||
Typical coroutine instructions:
|
|
||||||
|
|
||||||
| Operation | Description |
|
|
||||||
| --------- | ----------------------------- |
|
|
||||||
| `spawn` | Create a coroutine |
|
|
||||||
| `yield` | Voluntarily suspend execution |
|
|
||||||
| `sleep` | Suspend for N frames |
|
|
||||||
|
|
||||||
`yield` and `sleep` only take effect at safe points.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7 Relationship Between Events, Coroutines, and the Frame Loop
|
|
||||||
|
|
||||||
The high-level frame structure is:
|
|
||||||
|
|
||||||
```
|
|
||||||
FRAME N
|
|
||||||
------------------------
|
|
||||||
Sample Input
|
|
||||||
Deliver Events
|
|
||||||
Schedule Coroutines
|
|
||||||
Run VM until:
|
|
||||||
- budget exhausted, or
|
|
||||||
- FRAME_SYNC reached
|
|
||||||
Sync Phase
|
|
||||||
------------------------
|
|
||||||
```
|
|
||||||
|
|
||||||
Important properties:
|
|
||||||
|
|
||||||
* events are processed at known points
|
|
||||||
* coroutine scheduling is deterministic
|
|
||||||
* no execution occurs outside the frame loop
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8 Costs and Budget
|
|
||||||
|
|
||||||
All event processing and scheduling:
|
|
||||||
|
|
||||||
* consumes cycles
|
|
||||||
* contributes to the CAP (certification and analysis profile)
|
|
||||||
* appears in profiling reports
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
Frame 18231:
|
|
||||||
Event processing: 120 cycles
|
|
||||||
Coroutine scheduling: 40 cycles
|
|
||||||
Frame sync: 80 cycles
|
|
||||||
```
|
|
||||||
|
|
||||||
Nothing is free.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9 Determinism and Reproducibility
|
|
||||||
|
|
||||||
Prometeu guarantees:
|
|
||||||
|
|
||||||
* same sequence of inputs and events → same behavior
|
|
||||||
* frame-based timers
|
|
||||||
* deterministic coroutine scheduling
|
|
||||||
|
|
||||||
This allows:
|
|
||||||
|
|
||||||
* reliable replays
|
|
||||||
* precise debugging
|
|
||||||
* fair certification
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10 Best Practices
|
|
||||||
|
|
||||||
Prometeu encourages:
|
|
||||||
|
|
||||||
* treating events as data
|
|
||||||
* querying events explicitly
|
|
||||||
* structuring logic around frame steps
|
|
||||||
* using coroutines for asynchronous flows
|
|
||||||
|
|
||||||
Prometeu discourages:
|
|
||||||
|
|
||||||
* simulating asynchronous callbacks
|
|
||||||
* relying on hidden timing
|
|
||||||
* using events as implicit control flow
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11 Conceptual Comparison
|
|
||||||
|
|
||||||
| Traditional System | Prometeu |
|
|
||||||
| ------------------ | ----------------------- |
|
|
||||||
| Hardware interrupt | Frame boundary event |
|
|
||||||
| ISR | System sync phase |
|
|
||||||
| Main loop | VM frame loop |
|
|
||||||
| Timer interrupt | Frame-based timer event |
|
|
||||||
| Threads | Coroutines |
|
|
||||||
|
|
||||||
Prometeu teaches reactive system concepts without the unpredictability of real interrupts.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12 Summary
|
|
||||||
|
|
||||||
* Events inform; they do not execute code.
|
|
||||||
* The frame boundary is the only global synchronization point.
|
|
||||||
* System faults stop execution.
|
|
||||||
* Coroutines provide cooperative concurrency.
|
|
||||||
* All behavior is deterministic and measurable.
|
|
||||||
|
|
||||||
< [Back](chapter-8.md) | [Summary](table-of-contents.md) | [Next](chapter-10.md) >
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
# Table of Contents
|
|
||||||
|
|
||||||
- [Chapter 1: Time Model and Cycles](chapter-1.md)
|
|
||||||
- [Chapter 2: PROMETEU VM Instruction Set](chapter-2.md)
|
|
||||||
- [Chapter 3: Memory: Stack, Heap, and Allocation](chapter-3.md)
|
|
||||||
- [Chapter 4: GFX Peripheral (Graphics System)](chapter-4.md)
|
|
||||||
- [Chapter 5: AUDIO Peripheral (Audio System)](chapter-5.md)
|
|
||||||
- [Chapter 6: INPUT Peripheral (Input System)](chapter-6.md)
|
|
||||||
- [Chapter 7: TOUCH Peripheral (Absolute Pointer Input System)](chapter-7.md)
|
|
||||||
- [Chapter 8: MEMCARD Peripheral (Save/Load System)](chapter-8.md)
|
|
||||||
- [Chapter 9: Events and Interrupts](chapter-9.md)
|
|
||||||
- [Chapter 10: Debug, Inspection, and Profiling](chapter-10.md)
|
|
||||||
- [Chapter 11: Portability Guarantees and Cross-Platform Execution](chapter-11.md)
|
|
||||||
- [Chapter 12: Firmware — PrometeuOS (POS) + PrometeuHub](chapter-12.md)
|
|
||||||
- [Chapter 13: Cartridge](chapter-13.md)
|
|
||||||
- [Chapter 14: Boot Profiles](chapter-14.md)
|
|
||||||
- [Chapter 15: Asset Management](chapter-15.md)
|
|
||||||
- [Chapter 16: Host ABI and Syscalls](chapter-16.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
[Back to README](../README.md)
|
|
||||||
Loading…
x
Reference in New Issue
Block a user