prometeu-runtime/docs/specs/pbs/files/PRs para Junie.md
Nilton Constantino ef8b7b524a
pr 38
2026-01-31 00:59:45 +00:00

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

  1. Gfx.clear(color)
  • Emit SYSCALL_GFX_CLEAR
  • ABI: args = [Color.raw] as bounded
  • returns: void
  1. Input.pad()
  • Emit SYSCALL_INPUT_PAD
  • args: none
  • returns: flattened Pad in field order as declared
  1. Input.touch()
  • Emit SYSCALL_INPUT_TOUCH
  • args: none
  • returns: flattened Touch in field order as declared

Flattening order (binding)

ButtonState returns 4 slots in order:

  1. pressed (bool)
  2. released (bool)
  3. down (bool)
  4. 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:

  1. f (ButtonState block)
  2. x (int)
  3. y (int)

Tests (mandatory)

  • Lowering golden test: Gfx.clear(Color.WHITE) emits SYSCALL_GFX_CLEAR with 1 arg.
  • Lowering golden test: Input.pad() emits SYSCALL_INPUT_PAD and assigns to local.
  • Lowering golden test: Input.touch() emits SYSCALL_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: bounded raw color

  • Convert to u16 internally (runtime-only)

    • If raw > 0xFFFF, trap TRAP_OOB or TRAP_TYPE (choose one and document)
  • Fill framebuffer with that RGB565 value

2) SYSCALL_INPUT_PAD

  • No args

  • Snapshot the current runtime Pad and push a flattened Pad return:

    • For each button: pressed, released, down, hold_frames
    • hold_frames pushed as bounded

3) SYSCALL_INPUT_TOUCH

  • No args

  • Snapshot Touch and push flattened Touch return:

    • 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_CLEAR rejects raw > 0xFFFF deterministically.
  • Runtime unit test: SYSCALL_INPUT_PAD returns correct number of stack slots (48).
  • Runtime unit test: SYSCALL_INPUT_TOUCH returns correct number of stack slots (4 + 2 = 6).