3.1 KiB
3.1 KiB
PR-03 — Lowering: Host Contracts for Gfx/Input using deterministic syscalls
Goal
Map PBS host contracts to stable syscalls with a deterministic ABI.
Required host contracts in PBS surface
pub declare contract Gfx host
{
fn clear(color: Color): void;
}
pub declare contract Input host
{
fn pad(): Pad;
fn touch(): Touch;
}
Required lowering rules
Gfx.clear(color)
- Emit
SYSCALL_GFX_CLEAR - ABI: args = [Color.raw] as
bounded - returns: void
Input.pad()
- Emit
SYSCALL_INPUT_PAD - args: none
- returns: flattened
Padin field order as declared
Input.touch()
- Emit
SYSCALL_INPUT_TOUCH - args: none
- returns: flattened
Touchin field order as declared
Flattening order (binding)
ButtonState returns 4 slots in order:
- pressed (bool)
- released (bool)
- down (bool)
- hold_frames (bounded)
Pad returns 12 ButtonState blocks in this exact order:
up, down, left, right, a, b, x, y, l, r, start, select
Touch returns:
- f (ButtonState block)
- x (int)
- y (int)
Tests (mandatory)
- Lowering golden test:
Gfx.clear(Color.WHITE)emitsSYSCALL_GFX_CLEARwith 1 arg. - Lowering golden test:
Input.pad()emitsSYSCALL_INPUT_PADand assigns to local. - Lowering golden test:
Input.touch()emitsSYSCALL_INPUT_TOUCH.
Non-goals
- No runtime changes
- No VM heap
PR-04 — Runtime: Implement syscalls for Color/Gfx and Input pad/touch + integration cartridge
Goal
Make the new syscalls actually work and prove them with an integration test cartridge.
Required syscall implementations
1) SYSCALL_GFX_CLEAR
-
Read 1 arg:
boundedraw color -
Convert to
u16internally (runtime-only)- If raw > 0xFFFF, trap
TRAP_OOBorTRAP_TYPE(choose one and document)
- If raw > 0xFFFF, trap
-
Fill framebuffer with that RGB565 value
2) SYSCALL_INPUT_PAD
-
No args
-
Snapshot the current runtime
Padand push a flattenedPadreturn:- For each button: pressed, released, down, hold_frames
- hold_frames pushed as
bounded
3) SYSCALL_INPUT_TOUCH
-
No args
-
Snapshot
Touchand push flattenedTouchreturn:- f ButtonState
- x int
- y int
Integration cartridge (mandatory)
Add test-cartridges/hw_hello (or similar) with:
fn frame(): void
{
// 1) clear screen white
Gfx.clear(Color.WHITE);
// 2) read pad and branch
let p: Pad = Input.pad();
if p.any() {
Gfx.clear(Color.MAGENTA);
}
// 3) read touch and branch on f.down
let t: Touch = Input.touch();
if t.f.down {
// choose a third color to prove the struct returned correctly
Gfx.clear(Color.BLUE);
}
}
Acceptance criteria
- Cartridge runs without VM faults.
- With no input: screen is WHITE.
- With any pad button held: screen becomes MAGENTA.
- With touch f.down: screen becomes BLUE.
Tests (mandatory)
- Runtime unit test:
SYSCALL_GFX_CLEARrejects raw > 0xFFFF deterministically. - Runtime unit test:
SYSCALL_INPUT_PADreturns correct number of stack slots (48). - Runtime unit test:
SYSCALL_INPUT_TOUCHreturns correct number of stack slots (4 + 2 = 6).