< [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) > # ⚙️ ** PVM (PROMETEU VM) — Instruction Set** ## 1. Overview The **PROMETEU VM** is a mandatory virtual machine always present in the logical hardware: * **stack-based** * deterministic * cycle-oriented * designed for teaching and inspection It exists to: * map high-level language concepts * make computational cost visible * allow execution analysis * serve as the foundation of the PROMETEU cartridge > The PROMETEU VM is simple by choice. > Simplicity is a pedagogical tool. --- ## 2. Execution Model ### 2.1 Main Components The VM has: * **PC (Program Counter)** — next instruction * **Operand Stack** — value stack * **Call Stack** — stores execution frames for function calls * **Scope Stack** — stores frames for blocks within a function * **Heap** — dynamic memory * **Globals** — global variables * **Constant Pool** — literals and references * **ROM** — cartridge bytecode * **RAM** — mutable data --- ### 2.2 Execution Cycle Each instruction executes: ``` FETCH → DECODE → EXECUTE → ADVANCE PC ``` Properties: * every instruction has a fixed cost in cycles * there is no invisible implicit work * execution is fully deterministic --- ## 3. Fundamental Types | Type | Description | | --------- | ------------------------- | | `integer` | 64-bit signed integer | | `float` | 64-bit floating point | | `boolean` | true/false | | `string` | immutable UTF-8 | | `null` | absence of value | | `ref` | heap reference | Do not exist: * magic coercions * implicit casts * silent overflows --- ## 4. Stack Conventions * Operations use the top of the stack * Results always return to the stack * Last pushed = first consumed Example: ``` PUSH_CONST 3 PUSH_CONST 4 ADD ``` State: ``` [3] [3, 4] [7] ``` --- ## 5. Instruction Categories 1. Flow control 2. Stack 3. Arithmetic and logic 4. Variables 5. Functions 6. Heap and structures 7. Peripherals (syscalls) 8. System --- ## 6. Instructions — VM Set 1 ### 6.1 Execution Control | Instruction | Cycles | Description | | ------------------- | ------ | ------------------------- | | `NOP` | 1 | Does nothing | | `HALT` | 1 | Terminates execution | | `JMP addr` | 2 | Unconditional jump | | `JMP_IF_FALSE addr` | 3 | Jumps if top is false | --- ### 6.2 Stack | Instruction | Cycles | Description | | -------------- | ------ | ------------------- | | `PUSH_CONST k` | 2 | Pushes constant | | `POP` | 1 | Removes top | | `DUP` | 1 | Duplicates top | | `SWAP` | 1 | Swaps two tops | --- ### 6.3 Arithmetic | Instruction | Cycles | | ----------- | ------ | | `ADD` | 2 | | `SUB` | 2 | | `MUL` | 4 | | `DIV` | 6 | --- ### 6.4 Comparison and Logic | Instruction | Cycles | | ----------- | ------ | | `EQ` | 2 | | `NEQ` | 2 | | `LT` | 2 | | `GT` | 2 | | `AND` | 2 | | `OR` | 2 | | `NOT` | 1 | --- ### 6.5 Variables | Instruction | Cycles | Description | | -------------- | ------ | ---------------- | | `GET_GLOBAL i` | 3 | Reads global | | `SET_GLOBAL i` | 3 | Writes global | | `GET_LOCAL i` | 2 | Reads local | | `SET_LOCAL i` | 2 | Writes local | --- ### 6.6 Functions | Instruction | Cycles | Description | |----------------| ------ |--------------------------------------------| | `CALL addr` | 5 | Saves PC and creates a new call frame | | `RET` | 4 | Returns from function, restoring PC | | `PUSH_SCOPE` | 3 | Creates a scope within the current function | | `POP_SCOPE` | 3 | Removes current scope and its local variables | **ABI Rules for Functions:** * **Mandatory Return Value:** Every function MUST leave exactly one value on the stack before `RET`. If the function logic doesn't return a value, it must push `null`. * **Stack Cleanup:** `RET` automatically clears all local variables (based on `stack_base`) and re-pushes the return value. --- ### 6.7 Heap | Instruction | Cycles | Description | | --------------- | ------ | --------------- | | `ALLOC size` | 10 | Allocates on heap | | `LOAD_REF off` | 3 | Reads field | | `STORE_REF off` | 3 | Writes field | Heap is: * finite * monitored * accounted for in the CAP --- ### 6.8 Peripherals (Syscalls) | Instruction | Cycles | Description | |--------------| -------- | --------------------- | | `SYSCALL id` | variable | Call to hardware | **ABI Rules for Syscalls:** * **Argument Order:** Arguments must be pushed in the order they appear in the call (LIFO stack behavior). * Example: `gfx.draw_rect(x, y, w, h, color)` means: 1. `PUSH x` 2. `PUSH y` 3. `PUSH w` 4. `PUSH h` 5. `PUSH color` 6. `SYSCALL 0x1002` * **Consumption:** The native function MUST pop all its arguments from the stack. * **Return Value:** If the syscall returns a value, it will be pushed onto the stack by the native implementation. If not, the stack state for the caller remains as it was before pushing arguments. #### Implemented Syscalls (v0.1) | ID | Name | Arguments (Stack) | Return | | ---------- | ----------------- | ---------------------------- | ------- | | `0x0001` | `system.has_cart` | - | `bool` | | `0x0002` | `system.run_cart` | - | - | | `0x1001` | `gfx.clear` | `color_idx` | - | | `0x1002` | `gfx.draw_rect` | `x, y, w, h, color_idx` | - | | `0x1003` | `gfx.draw_line` | `x1, y1, x2, y2, color_idx` | - | | `0x1004` | `gfx.draw_circle` | `xc, yc, r, color_idx` | - | | `0x1005` | `gfx.draw_disc` | `xc, yc, r, b_col, f_col` | - | | `0x1006` | `gfx.draw_square` | `x, y, w, h, b_col, f_col` | - | | `0x2001` | `input.get_pad` | `button_id` | `bool` | | `0x3001` | `audio.play` | `s_id, v_id, vol, pan, pitch`| - | **Button IDs:** - `0`: Up, `1`: Down, `2`: Left, `3`: Right - `4`: A, `5`: B, `6`: X, `7`: Y - `8`: L, `9`: R - `10`: Start, `11`: Select --- ## 7. Execution Errors Errors are: * explicit * fatal * never silent Types: * stack underflow * invalid type * invalid heap * invalid frame Generate: * clear message * state dump * stack trace --- ## 8. Determinism Guarantees: * same input → same result * same sequence → same cycles * no speculative execution * no invisible optimizations > If you see the instruction, you pay for it. --- ## 9. Relationship with Languages Java, TypeScript, Lua etc: * are source languages * compiled to this bytecode * never executed directly All run on the **same VM**. --- ## 10. Example Source: ```java x = 3 + 4; ``` Bytecode: ``` PUSH_CONST 3 PUSH_CONST 4 ADD SET_GLOBAL 0 ``` Cost: ``` 2 + 2 + 2 + 3 = 9 cycles ``` --- ## 11. Execution per Tick The VM does not run infinitely. It executes: * until consuming the **logical frame** budget * or until `HALT` The budget is defined by the PROMETEU logical hardware (e.g., `CYCLES_PER_FRAME`). Example: ``` vm.step_budget(10_000) ``` This feeds: * CAP * profiling * certification --- ## 12. Logical Frame and `FRAME_SYNC` PROMETEU defines **logical frame** as the minimum unit of consistent game update. * **Input is latched per logical frame** (does not change until the logical frame is completed). * The **cycle budget** is applied to the logical frame. * A new logical frame only starts when the current frame ends. ### 12.1 System Instruction: `FRAME_SYNC` The `FRAME_SYNC` instruction marks the **end of the logical frame**. | Instruction | Cycles | Description | | ------------ | ------ | ---------------------------------- | | `FRAME_SYNC` | 1 | Finalizes the current logical frame | Properties: * `FRAME_SYNC` is a **system instruction**. * It should not be exposed as a "manual" API to the user. * Tooling/compiler can **inject** `FRAME_SYNC` automatically at the end of the main loop. ### 12.2 Semantics (what happens when it executes) When executing `FRAME_SYNC`, the core: 1. **Finalizes** the current logical frame. 2. **Presents** the frame (`gfx.present()` or `gfx.compose_and_present()` depending on the GFX model). 3. **Releases** the input latch. 4. **Resets** the budget for the next logical frame. ### 12.3 Overbudget (when the frame doesn't finish on time) If the logical frame budget runs out **before** the VM reaches `FRAME_SYNC`: * the VM **pauses** (PC and stacks remain at the exact point) * there is **no present** * the input latch is **maintained** * on the next host tick, the VM **continues** from where it left off, still in the same logical frame Practical effect: * if the code needs 2 budgets to reach `FRAME_SYNC`, the game updates at ~30 FPS (logical frame takes 2 ticks) * this is deterministic and reportable in the CAP --- ## 15. Extensibility The Instruction Set is versioned. Future: * DMA * streaming * vectors * fictitious coprocessors No existing instruction changes its meaning. --- ## 16. Summary * stack-based VM * explicit cost * deterministic execution * integrated with CAP * foundation of every PROMETEU cartridge < [Back](chapter-1.md) | [Summary](table-of-contents.md) | [Next](chapter-3.md) >