1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 00:45:38 +00:00
nescript/examples/gnrom_simple.ne

26 lines
573 B
Text
Raw Normal View History

compiler: GNROM / debug port / sprite flicker / fade / sprite-0 split + docs Another batch from the cc65/nesdoug gap catalogue. All six items gated on marker labels (or default-false attributes) so existing programs produce byte-identical ROMs — every pre-existing .nes file round-trips unchanged. **Language / runtime additions:** - `mapper: GNROM` (iNES 66). Combines AxROM's 32 KB PRG pages with CNROM's 8 KB CHR banks in a single `$8000` register. Linker pads single-page ROMs to 32 KB to match mapper-66 expectations. - `game { debug_port: fceux | mesen | 0xXXXX }`. `debug.log`, `debug.assert`, and the `__debug_halt` sentinel now target a user-selected address. `fceux` (default, $4800) and `mesen` ($4018) are named aliases; custom hex addresses are accepted for unusual debuggers. - `game { sprite_flicker: true }`. IR lowerer injects an `IrOp::CycleSprites` at the top of every `on frame` handler, which flips on the rotating-OAM NMI variant with no per-site boilerplate. Default false so existing ROMs keep their layout. - `fade_out(step_frames)` / `fade_in(step_frames)` builtins. Blocking helpers that walk brightness 4 → 0 or 0 → 4 with `step_frames` frames between each step. Runtime splices `__fade_out`, `__fade_in`, and a callable `__wait_frame_rt` helper when the builtin is used. Zero-guard on step_frames prevents a pathological 256-frame spin when the caller accidentally passes 0. - `sprite_0_split(scroll_x, scroll_y)` intrinsic. Emits a two-phase busy-wait on `$2002` bit 6 (wait-for-clear, wait-for-set) then writes the new scroll values to `$2005`. Works on any mapper — unlike `on_scanline(N)` which requires MMC3. Enables HUD-over-playfield scrolling on NROM/UxROM/MMC1. **Docs:** - New paragraph in the language guide explaining the no-recursion design choice and the explicit-stack workaround pattern. - `future-work.md` updated to mark the shipped items out of the catalogue; remaining items reshuffled in the priority ranking. - README + examples/README updated with the new mapper and builtins. **Tests:** - 12 new integration tests covering: GNROM header emission, debug-port targeting (fceux/mesen/custom), unknown-alias rejection, sprite_flicker on/off/bad-value, fade_out JSR + marker coupling, fade omitted-when-unused, fade-in-expression rejected, sprite_0_split byte-level busy-wait verification, sprite_0_split arity enforcement, sprite_0_split omitted-when-unused, and an extended void-intrinsic-in-expression-position test covering the three new void builtins. - `nes2_mapper_high_nibble_in_byte_8_is_zero_for_small_mappers` extended to include GNROM. - Four new examples with committed .nes ROMs + pixel/audio goldens: `gnrom_simple`, `auto_sprite_flicker`, `fade_demo`, `sprite_0_split_demo`. All 752 tests pass. Clippy clean. 44/44 emulator goldens match.
2026-04-18 19:31:55 +00:00
// GNROM (mapper 66) demo — 32 KB PRG page + 8 KB CHR bank in a
// single write to `$8000-$FFFF`. Bits 4-5 select the PRG page,
// bits 0-1 select the CHR bank. Single-page GNROM is functionally
// equivalent to AxROM at the PRG level; this example just exercises
// the reset-time init and iNES header emission.
game "GNROM Demo" {
mapper: GNROM
}
var px: u8 = 120
var dx: u8 = 1
on frame {
if dx == 1 {
px += 1
if px >= 240 { dx = 0 }
} else {
px -= 1
if px == 0 { dx = 1 }
}
draw Ball at: (px, 100)
}
start Main