//-----------------------------------------------------------
// SCRIPT LIBRARY and SCRIPT MACRO Demo
// Demonstrates reusable Starlark functions and macros
//-----------------------------------------------------------

#INCLUDE <c64start.c65>

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
