//----------------------------------------------------------- // SCRIPT LIBRARY and SCRIPT MACRO Demo // Demonstrates reusable Starlark functions and macros //----------------------------------------------------------- #INCLUDE GOTO start //----------------------------------------------------------- // SCRIPT LIBRARY: Define reusable code generation functions //----------------------------------------------------------- SCRIPT LIBRARY def emit_nops(count): for i in range(count): print(" nop") def emit_delay(cycles): # 4 cycles per iteration (2x nop) for i in range(cycles // 4): print(" nop") print(" nop") remainder = cycles % 4 if remainder >= 3: print(" bit $ea") remainder -= 3 # 2 cycles per nop for i in range(remainder // 2): print(" nop") def emit_border_flash(color1, color2): print(" lda #%d" % color1) print(" sta $d020") print(" lda #%d" % color2) print(" sta $d020") ENDSCRIPT //----------------------------------------------------------- // SCRIPT MACRO: Named macros with parameters //----------------------------------------------------------- SCRIPT MACRO delay(cycles) if cycles < 2: fail("Cannot delay less than 2 cycles") emit_delay(cycles) ENDSCRIPT SCRIPT MACRO nops(count) emit_nops(count) ENDSCRIPT SCRIPT MACRO border_flash(c1, c2) emit_border_flash(c1, c2) ENDSCRIPT // Macro with label parameter (passed as string) SCRIPT MACRO set_irq(handler) print(" lda #<%s" % handler) print(" sta $fffe") print(" lda #>%s" % handler) print(" sta $ffff") ENDSCRIPT //----------------------------------------------------------- // Constants for testing expression evaluation //----------------------------------------------------------- BYTE CONST CYCLES_PER_LINE = 63 BYTE CONST RED = 2 BYTE CONST BLUE = 6 //----------------------------------------------------------- // Main code demonstrating macros //----------------------------------------------------------- LABEL start // Macro invocation outside ASM block @delay(10) @nops(3) @border_flash(RED, BLUE) // Macro with expression argument @delay(CYCLES_PER_LINE-20) // Macro with label argument @set_irq(my_handler) // Macro invocation inside ASM block ASM lda #$00 |@delay(8)| sta $d020 |@nops(2)| lda #$01 ENDASM SUBEND LABEL my_handler ASM pha inc $d020 pla rti ENDASM