mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 08:55:38 +00:00
Codegen: on_scanline per-state dispatch + NMI reload
Extends the \`on_scanline\` codegen to support multiple scanline handlers across states: - \`__irq_user\` now dispatches by \`current_state\`: each state with a scanline handler gets a CMP/BNE/JSR entry in the dispatch table. States without a handler fall through to just acknowledge the IRQ. - New \`__ir_mmc3_reload\` helper that (re)loads the MMC3 counter latch based on \`current_state\`. States without a scanline handler fall through to disable the IRQ (\$E000 write). - Linker detects the \`__ir_mmc3_reload\` label in user code and splices a JSR into it at the top of the NMI handler, so the counter is reloaded once per frame with the current state's target scanline. - IRQ handler no longer re-enables IRQ on ACK (the NMI reload now handles that) so it won't fire multiple times per frame. - Program init chooses the start state's scanline count (if any) or the first scanline handler found as a fallback. Also fixes \`dump_asm\`: a \`NOP\` with a \`Label\` operand is a label definition, but any other opcode with a \`Label\` operand is a real instruction like \`JSR foo\`. The old dump was hiding JSR/JMP targets. https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
359241d906
commit
08322abda4
4 changed files with 127 additions and 26 deletions
|
|
@ -156,6 +156,28 @@ fn program_with_on_scanline_mmc3() {
|
|||
rom::validate_ines(&rom_data).expect("should be valid iNES");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_with_on_scanline_per_state() {
|
||||
// Two states, each with its own scanline handler at a different
|
||||
// position. The IR codegen should emit per-state dispatch in
|
||||
// both `__irq_user` and `__ir_mmc3_reload`.
|
||||
let source = r#"
|
||||
game "MultiSL" { mapper: MMC3 }
|
||||
var s: u8 = 0
|
||||
state A {
|
||||
on frame { wait_frame }
|
||||
on scanline(64) { scroll(0, 0) }
|
||||
}
|
||||
state B {
|
||||
on frame { wait_frame }
|
||||
on scanline(192) { scroll(0, 0) }
|
||||
}
|
||||
start A
|
||||
"#;
|
||||
let rom_data = compile(source);
|
||||
rom::validate_ines(&rom_data).expect("should be valid iNES");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_with_structs() {
|
||||
let source = r#"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue