mirror of
https://github.com/imjasonh/nescript
synced 2026-07-11 18:20:47 +00:00
Closes seven of the cc65/nesdoug parity gaps catalogued in docs/future-work.md in a single pass. All of the new features are gated on marker labels so programs that don't use them produce byte-identical ROM output (every pre-existing committed .nes file round-trips unchanged). Language / runtime additions: - `rand8()` / `rand16()` / `seed_rand(u16)` intrinsics backed by a 16-bit Galois LFSR (~30 bytes of runtime, ~40 cycles per draw). Reset path seeds state to 0xACE1 so the first draw is useful even without explicit seeding. - `p1.button.a.pressed` / `.released` edge-triggered input via a new ReadInputEdge IR op plus an NMI-side prev-frame snapshot into $07E6/$07E7, gated on the `__edge_input_used` marker. - `set_palette_brightness(level)` builtin mapping levels 0..8 to PPU mask emphasis bytes (`$2001`) for neslib-style screen fades. - `mapper: AxROM` (iNES 7) with automatic 32 KB PRG padding so emulators that enforce mapper-7's 32 KB page size boot cleanly. - `mapper: CNROM` (iNES 3) with a reset-time CHR bank 0 select. - `--fceux-labels <prefix>` CLI flag emitting per-bank `.nl` label files and a `.ram.nl` file for FCEUX's debugger. Tests + examples: - Five new example programs with committed .nes ROMs and pixel+audio goldens: prng_demo, edge_input_demo, palette_brightness_demo, axrom_simple, cnrom_simple. - Seven integration tests covering JSR emission, the omitted-when-unused invariant, the NMI prev-input snapshot, the correct mapper numbers for AxROM/CNROM, and negative tests for unknown button names and bad rand8 arity. - `is_intrinsic()` now runs in expression-position Call paths too, so `var x = rand8(1, 2)` errors at compile time instead of silently dropping the extra arguments.
45 lines
1.2 KiB
Text
45 lines
1.2 KiB
Text
// PRNG demo — sprite positions driven by the runtime PRNG.
|
|
//
|
|
// Each frame draws four sprites at addresses pulled from the
|
|
// xorshift-style `rand8()` intrinsic, with an extra `rand16()`
|
|
// sample binned into a horizontal velocity. Exercises `rand8`,
|
|
// `rand16`, and `seed_rand` end-to-end.
|
|
|
|
game "PRNG Demo" {
|
|
mapper: NROM
|
|
}
|
|
|
|
var seeded: u8 = 0
|
|
|
|
on frame {
|
|
if seeded == 0 {
|
|
// Pin the seed so the recording is deterministic. The
|
|
// runtime forces bit 0 of the low byte high so a zero
|
|
// seed doesn't stick the LFSR.
|
|
seed_rand(0x1234)
|
|
seeded = 1
|
|
}
|
|
|
|
// Four random sprites per frame. Each call pulls fresh
|
|
// entropy from the shared PRNG state, so the positions
|
|
// drift over time instead of staying fixed.
|
|
var x1: u8 = rand8()
|
|
var y1: u8 = rand8()
|
|
draw Ball at: (x1, y1)
|
|
|
|
var x2: u8 = rand8()
|
|
var y2: u8 = rand8()
|
|
draw Ball at: (x2, y2)
|
|
|
|
// rand16() returns u16; truncate to u8 for the draw.
|
|
var r: u16 = rand16()
|
|
var x3: u8 = r as u8
|
|
var y3: u8 = (r >> 8) as u8
|
|
draw Ball at: (x3, y3)
|
|
|
|
var x4: u8 = rand8()
|
|
var y4: u8 = rand8()
|
|
draw Ball at: (x4, y4)
|
|
}
|
|
|
|
start Main
|