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.
|
||||
//!
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//! Deterministic disassembler for Prometeu Bytecode (PBC).
|
||||
//! Deterministic disassembler for Prometeu Bytecode (PBX payload).
|
||||
//!
|
||||
//! Goals:
|
||||
//! - Stable formatting across platforms (snapshot-friendly).
|
||||
|
||||
@ -33,7 +33,7 @@ enum Commands {
|
||||
#[arg(long, default_value_t = 7777)]
|
||||
port: u16,
|
||||
},
|
||||
/// Compiles a source project into a cartridge (PBC).
|
||||
/// Compiles a source project into a cartridge directory with `program.pbx`.
|
||||
Build {
|
||||
/// Project source directory.
|
||||
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.
|
||||
|
||||
@ -250,5 +248,3 @@ The time and cycles model allows teaching:
|
||||
- time-oriented architecture
|
||||
- technical trade-offs
|
||||
- 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
|
||||
|
||||
@ -596,5 +594,3 @@ PROMETEU's GFX is simple **by choice**, not by limitation.
|
||||
- Layer = tilemap + cache + scroll
|
||||
- Rasterized projection per frame
|
||||
- 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
|
||||
|
||||
@ -327,5 +325,3 @@ But abstracted for:
|
||||
- Explicit mixer
|
||||
- "Audio CPU" concept
|
||||
- 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
|
||||
|
||||
@ -256,5 +254,3 @@ With clear and reproducible feedback.
|
||||
- queries have an explicit cost
|
||||
- input participates in the CAP
|
||||
- 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
|
||||
|
||||
@ -258,5 +256,3 @@ The TOUCH in PROMETEU is:
|
||||
- predictable
|
||||
- universal
|
||||
- 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) >
|
||||
|
||||
# 📀 MEMCARD Peripheral (Save/Load System)
|
||||
# Save Memory and MEMCARD
|
||||
|
||||
## 1. Overview
|
||||
|
||||
@ -234,5 +232,3 @@ The MEMCARD peripheral in PROMETEU:
|
||||
- is simple to use
|
||||
- is hard to abuse
|
||||
- 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
|
||||
|
||||
@ -81,7 +79,7 @@ No mode alters the logical result of the program.
|
||||
|
||||
### 4.1 Pause and Resume
|
||||
|
||||
The system can be paused at safe points:
|
||||
The system can be paused at safepoints:
|
||||
|
||||
- frame start
|
||||
- before UPDATE
|
||||
@ -287,13 +285,13 @@ Execution can pause when:
|
||||
|
||||
---
|
||||
|
||||
## 10. Event and Interrupt Debugging
|
||||
## 10. Event and Fault Debugging
|
||||
|
||||
PROMETEU allows observing:
|
||||
|
||||
- event queue
|
||||
- active timers
|
||||
- occurred interrupts
|
||||
- published system faults
|
||||
|
||||
Each event has:
|
||||
|
||||
@ -346,5 +344,3 @@ The student learns:
|
||||
- profiling is deterministic
|
||||
- time and memory are visible
|
||||
- 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
|
||||
|
||||
@ -254,5 +252,3 @@ The student learns:
|
||||
- input, audio, and graphics are abstracted
|
||||
- certification is universal
|
||||
- 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** is an imaginary console.
|
||||
|
||||
But not in the weak sense of "imagining".
|
||||
|
||||
PROMETEU was **deliberately designed** to exist as a **complete computational model**: simple enough to be understood, and powerful enough to create real games.
|
||||
|
||||
The name PROMETEU carries two intentional meanings:
|
||||
|
||||
- **Prometheus, the titan**, who stole fire from the gods and gave it to humans
|
||||
- **“Prometeu” as a verb**, a promise made (in Portuguese)
|
||||
|
||||
In this project:
|
||||
|
||||
- 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
|
||||
|
||||
This manual is that written promise.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 What is PROMETEU
|
||||
|
||||
PROMETEU is a **Virtual Microconsole** — a fictitious computer, with clear rules, limited resources, and deterministic behavior.
|
||||
|
||||
It was designed to:
|
||||
|
||||
- teach real computing fundamentals
|
||||
- expose time, memory, and execution
|
||||
- allow full 2D games (platformers, metroidvanias, arcade)
|
||||
- serve as a bridge between:
|
||||
- microcontrollers
|
||||
- classic consoles
|
||||
- virtual machines
|
||||
- modern engines
|
||||
|
||||
PROMETEU **is not**:
|
||||
|
||||
- a generic engine
|
||||
- a substitute for Unity or Godot
|
||||
- a real commercial console
|
||||
|
||||
PROMETEU **is**:
|
||||
|
||||
- a laboratory
|
||||
- a didactic instrument
|
||||
- a serious toy
|
||||
|
||||
---
|
||||
|
||||
## 🧠 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) >
|
||||
# PROMETEU Runtime Specs
|
||||
|
||||
Este diretório reúne as specs da maquina PROMETEU no nível de sistema, hardware virtual, firmware, cartridge e ABI de host.
|
||||
|
||||
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.
|
||||
|
||||
Princípios desta organização:
|
||||
|
||||
- estrutura plana;
|
||||
- sem pasta `topics/`;
|
||||
- sem navegação embutida `Back` / `Next` / `Summary`;
|
||||
- nomes de arquivos semânticos;
|
||||
- cada capítulo deve poder ser aberto isoladamente.
|
||||
|
||||
Arquivos atuais:
|
||||
|
||||
- [`01-time-model-and-cycles.md`](01-time-model-and-cycles.md)
|
||||
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md)
|
||||
- [`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)
|
||||
- [`05-audio-peripheral.md`](05-audio-peripheral.md)
|
||||
- [`06-input-peripheral.md`](06-input-peripheral.md)
|
||||
- [`07-touch-peripheral.md`](07-touch-peripheral.md)
|
||||
- [`08-save-memory-and-memcard.md`](08-save-memory-and-memcard.md)
|
||||
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md)
|
||||
- [`09a-coroutines-and-cooperative-scheduling.md`](09a-coroutines-and-cooperative-scheduling.md)
|
||||
- [`10-debug-inspection-and-profiling.md`](10-debug-inspection-and-profiling.md)
|
||||
- [`11-portability-and-cross-platform-execution.md`](11-portability-and-cross-platform-execution.md)
|
||||
- [`12-firmware-pos-and-prometeuhub.md`](12-firmware-pos-and-prometeuhub.md)
|
||||
- [`13-cartridge.md`](13-cartridge.md)
|
||||
- [`14-boot-profiles.md`](14-boot-profiles.md)
|
||||
- [`15-asset-management.md`](15-asset-management.md)
|
||||
- [`16-host-abi-and-syscalls.md`](16-host-abi-and-syscalls.md)
|
||||
- [`16a-syscall-policies.md`](16a-syscall-policies.md)
|
||||
|
||||
Relação com outros docs:
|
||||
|
||||
- [`../virtual-machine/ARCHITECTURE.md`](../virtual-machine/ARCHITECTURE.md) define as invariantes canônicas da VM/runtime.
|
||||
- [`../virtual-machine/ISA_CORE.md`](../virtual-machine/ISA_CORE.md) define a ISA no nível de bytecode.
|
||||
- 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.
|
||||
|
||||
Critério para novos capítulos:
|
||||
|
||||
- o nome do arquivo deve comunicar o domínio;
|
||||
- o capítulo deve ser legível sem depender de trilha de navegação;
|
||||
- links internos devem ser usados apenas quando agregarem contexto real, não como mecanismo obrigatório de leitura sequencial.
|
||||
|
||||
@ -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