Resolved forward reference irq to interrupt(HARDWARE_CLOBBER)(void()) irq()
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx 
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3
Culled Empty Block (label) @4
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@5
Culled Empty Block (label) main::@6
Culled Empty Block (label) @5
Culled Empty Block (label) @6

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  (byte*) PROCPORT_DDR#0 ← ((byte*)) (number) 0
  (byte) PROCPORT_DDR_MEMORY_MASK#0 ← (number) 7
  (byte*) PROCPORT#0 ← ((byte*)) (number) 1
  (byte) PROCPORT_RAM_IO#0 ← (number) $35
  (byte*) RASTER#0 ← ((byte*)) (number) $d012
  (byte*) BORDERCOL#0 ← ((byte*)) (number) $d020
  (byte*) BGCOL#0 ← ((byte*)) (number) $d021
  (byte*) VIC_CONTROL#0 ← ((byte*)) (number) $d011
  (byte*) IRQ_STATUS#0 ← ((byte*)) (number) $d019
  (byte*) IRQ_ENABLE#0 ← ((byte*)) (number) $d01a
  (byte) IRQ_RASTER#0 ← (number) 1
  (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (number) $dc0d
  (byte) CIA_INTERRUPT_CLEAR#0 ← (number) $7f
  (void()**) HARDWARE_IRQ#0 ← ((void()**)) (number) $fffe
  (byte) BLACK#0 ← (number) 0
  (byte) WHITE#0 ← (number) 1
  to:@7
main: scope:[main]  from @7
  asm { sei  }
  *((byte*) PROCPORT_DDR#0) ← (byte) PROCPORT_DDR_MEMORY_MASK#0
  *((byte*) PROCPORT#0) ← (byte) PROCPORT_RAM_IO#0
  *((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0
  *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (number) $80
  *((byte*) RASTER#0) ← (number) 0
  *((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0
  (void()*~) main::$0 ← & interrupt(HARDWARE_CLOBBER)(void()) irq()
  *((void()**) HARDWARE_IRQ#0) ← (void()*~) main::$0
  asm { cli  }
  to:main::@1
main::@1: scope:[main]  from main main::@2
  if(true) goto main::@2
  to:main::@return
main::@2: scope:[main]  from main::@1
  *((byte*) BORDERCOL#0) ← ++ *((byte*) BORDERCOL#0)
  to:main::@1
main::@return: scope:[main]  from main::@1
  return 
  to:@return
irq: scope:[irq]  from
  call do_irq 
  to:irq::@1
irq::@1: scope:[irq]  from irq
  to:irq::@return
irq::@return: scope:[irq]  from irq::@1
  return 
  to:@return
do_irq: scope:[do_irq]  from irq
  *((byte*) BGCOL#0) ← (byte) WHITE#0
  *((byte*) BGCOL#0) ← (byte) BLACK#0
  *((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0
  to:do_irq::@return
do_irq::@return: scope:[do_irq]  from do_irq
  return 
  to:@return
@7: scope:[]  from @begin
  call main 
  to:@8
@8: scope:[]  from @7
  to:@end
@end: scope:[]  from @8

SYMBOL TABLE SSA
(label) @7
(label) @8
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte) BLACK
(byte) BLACK#0
(byte*) BORDERCOL
(byte*) BORDERCOL#0
(byte*) CIA1_INTERRUPT
(byte*) CIA1_INTERRUPT#0
(byte) CIA_INTERRUPT_CLEAR
(byte) CIA_INTERRUPT_CLEAR#0
(void()**) HARDWARE_IRQ
(void()**) HARDWARE_IRQ#0
(byte*) IRQ_ENABLE
(byte*) IRQ_ENABLE#0
(byte) IRQ_RASTER
(byte) IRQ_RASTER#0
(byte*) IRQ_STATUS
(byte*) IRQ_STATUS#0
(byte*) PROCPORT
(byte*) PROCPORT#0
(byte*) PROCPORT_DDR
(byte*) PROCPORT_DDR#0
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_DDR_MEMORY_MASK#0
(byte) PROCPORT_RAM_IO
(byte) PROCPORT_RAM_IO#0
(byte*) RASTER
(byte*) RASTER#0
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL#0
(byte) WHITE
(byte) WHITE#0
(void()) do_irq()
(label) do_irq::@return
interrupt(HARDWARE_CLOBBER)(void()) irq()
(label) irq::@1
(label) irq::@return
(void()) main()
(void()*~) main::$0
(label) main::@1
(label) main::@2
(label) main::@return

Adding number conversion cast (unumber) 7 in (byte) PROCPORT_DDR_MEMORY_MASK#0 ← (number) 7
Adding number conversion cast (unumber) $35 in (byte) PROCPORT_RAM_IO#0 ← (number) $35
Adding number conversion cast (unumber) 1 in (byte) IRQ_RASTER#0 ← (number) 1
Adding number conversion cast (unumber) $7f in (byte) CIA_INTERRUPT_CLEAR#0 ← (number) $7f
Adding number conversion cast (unumber) 0 in (byte) BLACK#0 ← (number) 0
Adding number conversion cast (unumber) 1 in (byte) WHITE#0 ← (number) 1
Adding number conversion cast (unumber) $80 in *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (number) $80
Adding number conversion cast (unumber) 0 in *((byte*) RASTER#0) ← (number) 0
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte*) PROCPORT_DDR#0 ← (byte*)(number) 0
Inlining cast (byte) PROCPORT_DDR_MEMORY_MASK#0 ← (unumber)(number) 7
Inlining cast (byte*) PROCPORT#0 ← (byte*)(number) 1
Inlining cast (byte) PROCPORT_RAM_IO#0 ← (unumber)(number) $35
Inlining cast (byte*) RASTER#0 ← (byte*)(number) $d012
Inlining cast (byte*) BORDERCOL#0 ← (byte*)(number) $d020
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
Inlining cast (byte*) VIC_CONTROL#0 ← (byte*)(number) $d011
Inlining cast (byte*) IRQ_STATUS#0 ← (byte*)(number) $d019
Inlining cast (byte*) IRQ_ENABLE#0 ← (byte*)(number) $d01a
Inlining cast (byte) IRQ_RASTER#0 ← (unumber)(number) 1
Inlining cast (byte*) CIA1_INTERRUPT#0 ← (byte*)(number) $dc0d
Inlining cast (byte) CIA_INTERRUPT_CLEAR#0 ← (unumber)(number) $7f
Inlining cast (void()**) HARDWARE_IRQ#0 ← (void()**)(number) $fffe
Inlining cast (byte) BLACK#0 ← (unumber)(number) 0
Inlining cast (byte) WHITE#0 ← (unumber)(number) 1
Inlining cast *((byte*) RASTER#0) ← (unumber)(number) 0
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 0
Simplifying constant integer cast 7
Simplifying constant pointer cast (byte*) 1
Simplifying constant integer cast $35
Simplifying constant pointer cast (byte*) 53266
Simplifying constant pointer cast (byte*) 53280
Simplifying constant pointer cast (byte*) 53281
Simplifying constant pointer cast (byte*) 53265
Simplifying constant pointer cast (byte*) 53273
Simplifying constant pointer cast (byte*) 53274
Simplifying constant integer cast 1
Simplifying constant pointer cast (byte*) 56333
Simplifying constant integer cast $7f
Simplifying constant pointer cast (void()**) 65534
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast $80
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 7
Finalized unsigned number type (byte) $35
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) $7f
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) $80
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant right-side identified [23] (void()*~) main::$0 ← & interrupt(HARDWARE_CLOBBER)(void()) irq()
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) PROCPORT_DDR#0 = (byte*) 0
Constant (const byte) PROCPORT_DDR_MEMORY_MASK#0 = 7
Constant (const byte*) PROCPORT#0 = (byte*) 1
Constant (const byte) PROCPORT_RAM_IO#0 = $35
Constant (const byte*) RASTER#0 = (byte*) 53266
Constant (const byte*) BORDERCOL#0 = (byte*) 53280
Constant (const byte*) BGCOL#0 = (byte*) 53281
Constant (const byte*) VIC_CONTROL#0 = (byte*) 53265
Constant (const byte*) IRQ_STATUS#0 = (byte*) 53273
Constant (const byte*) IRQ_ENABLE#0 = (byte*) 53274
Constant (const byte) IRQ_RASTER#0 = 1
Constant (const byte*) CIA1_INTERRUPT#0 = (byte*) 56333
Constant (const byte) CIA_INTERRUPT_CLEAR#0 = $7f
Constant (const void()**) HARDWARE_IRQ#0 = (void()**) 65534
Constant (const byte) BLACK#0 = 0
Constant (const byte) WHITE#0 = 1
Constant (const void()*) main::$0 = &irq
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [26] if(true) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Constant inlined main::$0 = &interrupt(HARDWARE_CLOBBER)(void()) irq()
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @7
Adding NOP phi() at start of @8
Adding NOP phi() at start of @end
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of irq
Adding NOP phi() at start of irq::@1
CALL GRAPH
Calls in [] to main:2 
Calls in [irq] to do_irq:17 

Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @8
Culled Empty Block (label) main::@1
Culled Empty Block (label) irq::@1
Renumbering block @7 to @1
Renumbering block main::@2 to main::@1
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of irq

FINAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  [0] phi()
  to:@1
@1: scope:[]  from @begin
  [1] phi()
  [2] call main 
  to:@end
@end: scope:[]  from @1
  [3] phi()
main: scope:[main]  from @1
  asm { sei  }
  [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0
  [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0
  [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
  [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte) $80
  [9] *((const byte*) RASTER#0) ← (byte) 0
  [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
  [11] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq()
  asm { cli  }
  to:main::@1
main::@1: scope:[main]  from main main::@1
  [13] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
  to:main::@1
irq: scope:[irq]  from
  [14] phi()
  [15] call do_irq 
  to:irq::@return
irq::@return: scope:[irq]  from irq
  [16] return 
  to:@return
do_irq: scope:[do_irq]  from irq
  [17] *((const byte*) BGCOL#0) ← (const byte) WHITE#0
  [18] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
  [19] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
  to:do_irq::@return
do_irq::@return: scope:[do_irq]  from do_irq
  [20] return 
  to:@return


VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte) BLACK
(byte*) BORDERCOL
(byte*) CIA1_INTERRUPT
(byte) CIA_INTERRUPT_CLEAR
(void()**) HARDWARE_IRQ
(byte*) IRQ_ENABLE
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(byte*) PROCPORT
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_RAM_IO
(byte*) RASTER
(byte*) VIC_CONTROL
(byte) WHITE
(void()) do_irq()
interrupt(HARDWARE_CLOBBER)(void()) irq()
(void()) main()

Initial phi equivalence classes
Complete equivalence classes

INITIAL ASM
  // File Comments
// A minimal working raster hardware IRQ with clobber-based register savings
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  // Processor port data direction register
  .label PROCPORT_DDR = 0
  // Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
  .const PROCPORT_DDR_MEMORY_MASK = 7
  // Processor Port Register controlling RAM/ROM configuration and the datasette
  .label PROCPORT = 1
  // RAM in $A000, $E000 I/O in $D000
  .const PROCPORT_RAM_IO = $35
  .label RASTER = $d012
  .label BORDERCOL = $d020
  .label BGCOL = $d021
  .label VIC_CONTROL = $d011
  // VIC II IRQ Status Register
  .label IRQ_STATUS = $d019
  // VIC II IRQ Enable Register
  .label IRQ_ENABLE = $d01a
  // Bits for the IRQ Status/Enable Registers
  .const IRQ_RASTER = 1
  // CIA#1 Interrupt Status & Control Register
  .label CIA1_INTERRUPT = $dc0d
  // Value that disables all CIA interrupts when stored to the CIA Interrupt registers
  .const CIA_INTERRUPT_CLEAR = $7f
  // The vector used when the HARDWARE serves IRQ interrupts
  .label HARDWARE_IRQ = $fffe
  // The colors of the C64
  .const BLACK = 0
  .const WHITE = 1
  // @begin
bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
  jmp b1
  // @1
b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
  jmp bend
  // @end
bend:
  // main
main: {
    // asm { sei  }
    sei
    // [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2 
    // Disable kernal & basic
    lda #PROCPORT_DDR_MEMORY_MASK
    sta PROCPORT_DDR
    // [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2 
    lda #PROCPORT_RAM_IO
    sta PROCPORT
    // [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 
    // Disable CIA 1 Timer IRQ
    lda #CIA_INTERRUPT_CLEAR
    sta CIA1_INTERRUPT
    // [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte) $80 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 
    // Set raster line to $100
    lda #$80
    ora VIC_CONTROL
    sta VIC_CONTROL
    // [9] *((const byte*) RASTER#0) ← (byte) 0 -- _deref_pbuc1=vbuc2 
    lda #0
    sta RASTER
    // [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Enable Raster Interrupt
    lda #IRQ_RASTER
    sta IRQ_ENABLE
    // [11] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2 
    // Set the IRQ routine
    lda #<irq
    sta HARDWARE_IRQ
    lda #>irq
    sta HARDWARE_IRQ+1
    // asm { cli  }
    cli
    jmp b1
    // main::@1
  b1:
    // [13] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1 
    inc BORDERCOL
    jmp b1
}
  // irq
// Interrupt Routine
irq: {
    // entry interrupt(HARDWARE_CLOBBER)
    sta rega+1
    stx regx+1
    sty regy+1
    // [15] call do_irq 
    jsr do_irq
    jmp breturn
    // irq::@return
  breturn:
    // [16] return  - exit interrupt(HARDWARE_CLOBBER)
  rega:
    lda #00
  regx:
    ldx #00
  regy:
    ldy #00
    rti
}
  // do_irq
do_irq: {
    // [17] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 
    lda #WHITE
    sta BGCOL
    // [18] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [19] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Acknowledge the IRQ
    lda #IRQ_RASTER
    sta IRQ_STATUS
    jmp breturn
    // do_irq::@return
  breturn:
    // [20] return 
    rts
}
  // File Data

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte) $80 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [9] *((const byte*) RASTER#0) ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [11] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [16] return  [ ] (  [ ] ) always clobbers reg byte a reg byte x reg byte y 
Statement [17] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( do_irq:15 [ ] ) always clobbers reg byte a 
Statement [18] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( do_irq:15 [ ] ) always clobbers reg byte a 
Statement [19] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( do_irq:15 [ ] ) always clobbers reg byte a 

REGISTER UPLIFT SCOPES
Uplift Scope [main] 
Uplift Scope [irq] 
Uplift Scope [do_irq] 
Uplift Scope [] 

Uplifting [main] best 329 combination 
Uplifting [irq] best 329 combination 
Uplifting [do_irq] best 329 combination 
Uplifting [] best 329 combination 
Interrupt procedure irq clobbers ANZ
Removing interrupt register storage stx regx+1 in SEG22 entry interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage sty regy+1 in SEG22 entry interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage regx: in SEG25 [16] return  - exit interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage ldx #00 in SEG25 [16] return  - exit interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage regy: in SEG25 [16] return  - exit interrupt(HARDWARE_CLOBBER)
Removing interrupt register storage ldy #00 in SEG25 [16] return  - exit interrupt(HARDWARE_CLOBBER)

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// A minimal working raster hardware IRQ with clobber-based register savings
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  // Processor port data direction register
  .label PROCPORT_DDR = 0
  // Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
  .const PROCPORT_DDR_MEMORY_MASK = 7
  // Processor Port Register controlling RAM/ROM configuration and the datasette
  .label PROCPORT = 1
  // RAM in $A000, $E000 I/O in $D000
  .const PROCPORT_RAM_IO = $35
  .label RASTER = $d012
  .label BORDERCOL = $d020
  .label BGCOL = $d021
  .label VIC_CONTROL = $d011
  // VIC II IRQ Status Register
  .label IRQ_STATUS = $d019
  // VIC II IRQ Enable Register
  .label IRQ_ENABLE = $d01a
  // Bits for the IRQ Status/Enable Registers
  .const IRQ_RASTER = 1
  // CIA#1 Interrupt Status & Control Register
  .label CIA1_INTERRUPT = $dc0d
  // Value that disables all CIA interrupts when stored to the CIA Interrupt registers
  .const CIA_INTERRUPT_CLEAR = $7f
  // The vector used when the HARDWARE serves IRQ interrupts
  .label HARDWARE_IRQ = $fffe
  // The colors of the C64
  .const BLACK = 0
  .const WHITE = 1
  // @begin
bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
  jmp b1
  // @1
b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
  jmp bend
  // @end
bend:
  // main
main: {
    // asm { sei  }
    sei
    // [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2 
    // Disable kernal & basic
    lda #PROCPORT_DDR_MEMORY_MASK
    sta PROCPORT_DDR
    // [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2 
    lda #PROCPORT_RAM_IO
    sta PROCPORT
    // [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 
    // Disable CIA 1 Timer IRQ
    lda #CIA_INTERRUPT_CLEAR
    sta CIA1_INTERRUPT
    // [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte) $80 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 
    // Set raster line to $100
    lda #$80
    ora VIC_CONTROL
    sta VIC_CONTROL
    // [9] *((const byte*) RASTER#0) ← (byte) 0 -- _deref_pbuc1=vbuc2 
    lda #0
    sta RASTER
    // [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Enable Raster Interrupt
    lda #IRQ_RASTER
    sta IRQ_ENABLE
    // [11] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2 
    // Set the IRQ routine
    lda #<irq
    sta HARDWARE_IRQ
    lda #>irq
    sta HARDWARE_IRQ+1
    // asm { cli  }
    cli
    jmp b1
    // main::@1
  b1:
    // [13] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1 
    inc BORDERCOL
    jmp b1
}
  // irq
// Interrupt Routine
irq: {
    // entry interrupt(HARDWARE_CLOBBER)
    sta rega+1
    // [15] call do_irq 
    jsr do_irq
    jmp breturn
    // irq::@return
  breturn:
    // [16] return  - exit interrupt(HARDWARE_CLOBBER)
  rega:
    lda #00
    rti
}
  // do_irq
do_irq: {
    // [17] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 
    lda #WHITE
    sta BGCOL
    // [18] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [19] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Acknowledge the IRQ
    lda #IRQ_RASTER
    sta IRQ_STATUS
    jmp breturn
    // do_irq::@return
  breturn:
    // [20] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction breturn:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte) 0
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = (byte*) 53280
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = (byte*) 56333
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte) $7f
(void()**) HARDWARE_IRQ
(const void()**) HARDWARE_IRQ#0 HARDWARE_IRQ = (void()**) 65534
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = (byte*) 53274
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte) 1
(byte*) IRQ_STATUS
(const byte*) IRQ_STATUS#0 IRQ_STATUS = (byte*) 53273
(byte*) PROCPORT
(const byte*) PROCPORT#0 PROCPORT = (byte*) 1
(byte*) PROCPORT_DDR
(const byte*) PROCPORT_DDR#0 PROCPORT_DDR = (byte*) 0
(byte) PROCPORT_DDR_MEMORY_MASK
(const byte) PROCPORT_DDR_MEMORY_MASK#0 PROCPORT_DDR_MEMORY_MASK = (byte) 7
(byte) PROCPORT_RAM_IO
(const byte) PROCPORT_RAM_IO#0 PROCPORT_RAM_IO = (byte) $35
(byte*) RASTER
(const byte*) RASTER#0 RASTER = (byte*) 53266
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = (byte*) 53265
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte) 1
(void()) do_irq()
(label) do_irq::@return
interrupt(HARDWARE_CLOBBER)(void()) irq()
(label) irq::@return
(void()) main()
(label) main::@1



FINAL ASSEMBLER
Score: 224

  // File Comments
// A minimal working raster hardware IRQ with clobber-based register savings
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  // Processor port data direction register
  .label PROCPORT_DDR = 0
  // Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
  .const PROCPORT_DDR_MEMORY_MASK = 7
  // Processor Port Register controlling RAM/ROM configuration and the datasette
  .label PROCPORT = 1
  // RAM in $A000, $E000 I/O in $D000
  .const PROCPORT_RAM_IO = $35
  .label RASTER = $d012
  .label BORDERCOL = $d020
  .label BGCOL = $d021
  .label VIC_CONTROL = $d011
  // VIC II IRQ Status Register
  .label IRQ_STATUS = $d019
  // VIC II IRQ Enable Register
  .label IRQ_ENABLE = $d01a
  // Bits for the IRQ Status/Enable Registers
  .const IRQ_RASTER = 1
  // CIA#1 Interrupt Status & Control Register
  .label CIA1_INTERRUPT = $dc0d
  // Value that disables all CIA interrupts when stored to the CIA Interrupt registers
  .const CIA_INTERRUPT_CLEAR = $7f
  // The vector used when the HARDWARE serves IRQ interrupts
  .label HARDWARE_IRQ = $fffe
  // The colors of the C64
  .const BLACK = 0
  .const WHITE = 1
  // @begin
  // [1] phi from @begin to @1 [phi:@begin->@1]
  // @1
  // [2] call main 
  // [3] phi from @1 to @end [phi:@1->@end]
  // @end
  // main
main: {
    // asm
    // asm { sei  }
    sei
    // *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK
    // [5] *((const byte*) PROCPORT_DDR#0) ← (const byte) PROCPORT_DDR_MEMORY_MASK#0 -- _deref_pbuc1=vbuc2 
    // Disable kernal & basic
    lda #PROCPORT_DDR_MEMORY_MASK
    sta PROCPORT_DDR
    // *PROCPORT = PROCPORT_RAM_IO
    // [6] *((const byte*) PROCPORT#0) ← (const byte) PROCPORT_RAM_IO#0 -- _deref_pbuc1=vbuc2 
    lda #PROCPORT_RAM_IO
    sta PROCPORT
    // *CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR
    // [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 
    // Disable CIA 1 Timer IRQ
    lda #CIA_INTERRUPT_CLEAR
    sta CIA1_INTERRUPT
    // *VIC_CONTROL |=$80
    // [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte) $80 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 
    // Set raster line to $100
    lda #$80
    ora VIC_CONTROL
    sta VIC_CONTROL
    // *RASTER = $00
    // [9] *((const byte*) RASTER#0) ← (byte) 0 -- _deref_pbuc1=vbuc2 
    lda #0
    sta RASTER
    // *IRQ_ENABLE = IRQ_RASTER
    // [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Enable Raster Interrupt
    lda #IRQ_RASTER
    sta IRQ_ENABLE
    // *HARDWARE_IRQ = &irq
    // [11] *((const void()**) HARDWARE_IRQ#0) ← &interrupt(HARDWARE_CLOBBER)(void()) irq() -- _deref_pptc1=pprc2 
    // Set the IRQ routine
    lda #<irq
    sta HARDWARE_IRQ
    lda #>irq
    sta HARDWARE_IRQ+1
    // asm
    // asm { cli  }
    cli
    // main::@1
  b1:
    // (*BORDERCOL)++;
    // [13] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1 
    inc BORDERCOL
    jmp b1
}
  // irq
// Interrupt Routine
irq: {
    // entry interrupt(HARDWARE_CLOBBER)
    sta rega+1
    // do_irq()
    // [15] call do_irq 
    jsr do_irq
    // irq::@return
    // }
    // [16] return  - exit interrupt(HARDWARE_CLOBBER)
  rega:
    lda #00
    rti
}
  // do_irq
do_irq: {
    // *BGCOL = WHITE
    // [17] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 
    lda #WHITE
    sta BGCOL
    // *BGCOL = BLACK
    // [18] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // *IRQ_STATUS = IRQ_RASTER
    // [19] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 
    // Acknowledge the IRQ
    lda #IRQ_RASTER
    sta IRQ_STATUS
    // do_irq::@return
    // }
    // [20] return 
    rts
}
  // File Data

