Inlined call vicSelectGfxBank::$0 = call toDd00(vicSelectGfxBank::gfx)

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start
  asm { sei  }
  *SPRITES_ENABLE = 1
  SPRITES_YPOS[0] = $64
  SPRITES_XPOS[0] = $64
  *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40
  call saveZeropage
  to:main::@1
main::@1: scope:[main]  from main
  call sinZeropage
  to:main::@2
main::@2: scope:[main]  from main::@1
  call animSprite
  to:main::@3
main::@3: scope:[main]  from main::@2
  call restoreZeropage
  to:main::@4
main::@4: scope:[main]  from main::@3
  to:main::@return
main::@return: scope:[main]  from main::@4
  return 
  to:@return

void saveZeropage()
saveZeropage: scope:[saveZeropage]  from main
  asm { ldx#0 !: lda$00,x staZP_STORAGE,x inx bne!-  }
  to:saveZeropage::@return
saveZeropage::@return: scope:[saveZeropage]  from saveZeropage
  return 
  to:@return

void restoreZeropage()
restoreZeropage: scope:[restoreZeropage]  from main::@3
  asm { ldx#0 !: ldaZP_STORAGE,x sta$00,x inx bne!-  }
  to:restoreZeropage::@return
restoreZeropage::@return: scope:[restoreZeropage]  from restoreZeropage
  return 
  to:@return

void sinZeropage()
sinZeropage: scope:[sinZeropage]  from main::@1
  asm { ldx#0 !: ldaSINTABLE,x sta$00,x inx bne!-  }
  to:sinZeropage::@return
sinZeropage::@return: scope:[sinZeropage]  from sinZeropage
  return 
  to:@return

void animSprite()
animSprite: scope:[animSprite]  from main::@2
  kickasm() {{ ldx #$00
    repeat:
        lda #$fe
    !:
        cmp $d012
        bne !-
        lda #$ff
    !:
        cmp $d012
        bne !-
        .break
        lda $00,x
        clc
        adc #$38
        sta $d000
        lda #0
        adc #0
        sta $d010
        inx
        jmp repeat
     }}
  to:animSprite::@return
animSprite::@return: scope:[animSprite]  from animSprite
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  call main
  to:__start::@1
__start::@1: scope:[__start]  from __start
  to:__start::@return
__start::@return: scope:[__start]  from __start::@1
  return 
  to:@return

SYMBOL TABLE SSA
__constant const unsigned int OFFSET_SPRITE_PTRS = $3f8
__constant char * const SCREEN = (char *)$400
__constant const char SINTABLE[$100] = kickasm {{ .for(var i=0;i<$100;i++)
        .byte round(127.5+127.5*cos(toRadians(360*i/256)))
 }}
__constant const char SPRITE[$40] = kickasm {{ .fill $40,$ff  }}
__constant char * const SPRITES_ENABLE = (char *)$d015
__constant char * const SPRITES_XPOS = (char *)$d000
__constant char * const SPRITES_YPOS = (char *)$d001
__constant const char ZP_STORAGE[$100] = { fill( $100, 0) }
void __start()
void animSprite()
void main()
void restoreZeropage()
void saveZeropage()
void sinZeropage()

Adding number conversion cast (unumber) 1 in *SPRITES_ENABLE = 1
Adding number conversion cast (unumber) $64 in SPRITES_YPOS[0] = $64
Adding number conversion cast (unumber) 0 in SPRITES_YPOS[0] = ((unumber)) $64
Adding number conversion cast (unumber) $64 in SPRITES_XPOS[0] = $64
Adding number conversion cast (unumber) 0 in SPRITES_XPOS[0] = ((unumber)) $64
Adding number conversion cast (unumber) $40 in *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *SPRITES_ENABLE = (unumber)1
Inlining cast SPRITES_YPOS[(unumber)0] = (unumber)$64
Inlining cast SPRITES_XPOS[(unumber)0] = (unumber)$64
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 53248
Simplifying constant pointer cast (char *) 53249
Simplifying constant pointer cast (char *) 53269
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 1
Simplifying constant integer cast $64
Simplifying constant integer cast 0
Simplifying constant integer cast $64
Simplifying constant integer cast 0
Simplifying constant integer cast $40
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) $64
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $64
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $40
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero SPRITES_YPOS in [2] SPRITES_YPOS[0] = $64
Simplifying expression containing zero SPRITES_XPOS in [3] SPRITES_XPOS[0] = $64
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Finalized unsigned number type (unsigned int) $100
Finalized unsigned number type (unsigned int) $100
Finalized unsigned number type (unsigned int) $100
Finalized unsigned number type (char) $40
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of main::@4
CALL GRAPH
Calls in [main] to saveZeropage:5 sinZeropage:7 animSprite:9 restoreZeropage:11 

Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block label main::@4
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@3

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  asm { sei  }
  [1] *SPRITES_ENABLE = 1
  [2] *SPRITES_YPOS = $64
  [3] *SPRITES_XPOS = $64
  [4] *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40
  [5] call saveZeropage
  to:main::@1
main::@1: scope:[main]  from main
  [6] phi()
  [7] call sinZeropage
  to:main::@2
main::@2: scope:[main]  from main::@1
  [8] phi()
  [9] call animSprite
  to:main::@3
main::@3: scope:[main]  from main::@2
  [10] phi()
  [11] call restoreZeropage
  to:main::@return
main::@return: scope:[main]  from main::@3
  [12] return 
  to:@return

void saveZeropage()
saveZeropage: scope:[saveZeropage]  from main
  asm { ldx#0 !: lda$00,x staZP_STORAGE,x inx bne!-  }
  to:saveZeropage::@return
saveZeropage::@return: scope:[saveZeropage]  from saveZeropage
  [14] return 
  to:@return

void sinZeropage()
sinZeropage: scope:[sinZeropage]  from main::@1
  asm { ldx#0 !: ldaSINTABLE,x sta$00,x inx bne!-  }
  to:sinZeropage::@return
sinZeropage::@return: scope:[sinZeropage]  from sinZeropage
  [16] return 
  to:@return

void animSprite()
animSprite: scope:[animSprite]  from main::@2
  kickasm() {{ ldx #$00
    repeat:
        lda #$fe
    !:
        cmp $d012
        bne !-
        lda #$ff
    !:
        cmp $d012
        bne !-
        .break
        lda $00,x
        clc
        adc #$38
        sta $d000
        lda #0
        adc #0
        sta $d010
        inx
        jmp repeat
     }}
  to:animSprite::@return
animSprite::@return: scope:[animSprite]  from animSprite
  [18] return 
  to:@return

void restoreZeropage()
restoreZeropage: scope:[restoreZeropage]  from main::@3
  asm { ldx#0 !: ldaZP_STORAGE,x sta$00,x inx bne!-  }
  to:restoreZeropage::@return
restoreZeropage::@return: scope:[restoreZeropage]  from restoreZeropage
  [20] return 
  to:@return


VARIABLE REGISTER WEIGHTS
void animSprite()
void main()
void restoreZeropage()
void saveZeropage()
void sinZeropage()

Initial phi equivalence classes
Complete equivalence classes
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] *SPRITES_ENABLE = 1 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [2] *SPRITES_YPOS = $64 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [3] *SPRITES_XPOS = $64 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [4] *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement asm { ldx#0 !: lda$00,x staZP_STORAGE,x inx bne!-  } always clobbers reg byte a reg byte x 
Statement asm { ldx#0 !: ldaSINTABLE,x sta$00,x inx bne!-  } always clobbers reg byte a reg byte x 
Statement asm { ldx#0 !: ldaZP_STORAGE,x sta$00,x inx bne!-  } always clobbers reg byte a reg byte x 

REGISTER UPLIFT SCOPES
Uplift Scope [MOS6526_CIA] 
Uplift Scope [MOS6569_VICII] 
Uplift Scope [MOS6581_SID] 
Uplift Scope [main] 
Uplift Scope [saveZeropage] 
Uplift Scope [restoreZeropage] 
Uplift Scope [sinZeropage] 
Uplift Scope [animSprite] 
Uplift Scope [] 

Uplifting [MOS6526_CIA] best 405 combination 
Uplifting [MOS6569_VICII] best 405 combination 
Uplifting [MOS6581_SID] best 405 combination 
Uplifting [main] best 405 combination 
Uplifting [saveZeropage] best 405 combination 
Uplifting [restoreZeropage] best 405 combination 
Uplifting [sinZeropage] best 405 combination 
Uplifting [animSprite] best 405 combination 
Uplifting [] best 405 combination 

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Attempt to store and use a sine on zeropage
// $00/$11 is carefully chosen to be $ff - which plays well with the processor port
  // Upstart
  // Commodore 64 PRG executable file
.file [name="zeropage-sinus.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
  // Global Constants & labels
  /// The offset of the sprite pointers from the screen start address
  .const OFFSET_SPRITE_PTRS = $3f8
  /// Sprite X position register for sprite #0
  .label SPRITES_XPOS = $d000
  /// Sprite Y position register for sprite #0
  .label SPRITES_YPOS = $d001
  /// Sprite enable register
  .label SPRITES_ENABLE = $d015
  .label SCREEN = $400
.segment Code
  // main
main: {
    // asm { sei  }
    // Stop interrupts
    sei
    // [1] *SPRITES_ENABLE = 1 -- _deref_pbuc1=vbuc2 
    // Show sprite
    lda #1
    sta SPRITES_ENABLE
    // [2] *SPRITES_YPOS = $64 -- _deref_pbuc1=vbuc2 
    lda #$64
    sta SPRITES_YPOS
    // [3] *SPRITES_XPOS = $64 -- _deref_pbuc1=vbuc2 
    lda #$64
    sta SPRITES_XPOS
    // [4] *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40 -- _deref_pbuc1=vbuc2 
    lda #$ff&SPRITE/$40
    sta SCREEN+OFFSET_SPRITE_PTRS
    // [5] call saveZeropage
    jsr saveZeropage
    // [6] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [7] call sinZeropage
    jsr sinZeropage
    // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    jmp __b2
    // main::@2
  __b2:
    // [9] call animSprite
    jsr animSprite
    // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
  __b3_from___b2:
    jmp __b3
    // main::@3
  __b3:
    // [11] call restoreZeropage
    jsr restoreZeropage
    jmp __breturn
    // main::@return
  __breturn:
    // [12] return 
    rts
}
  // saveZeropage
// Save all values on zeropage
saveZeropage: {
    // asm { ldx#0 !: lda$00,x staZP_STORAGE,x inx bne!-  }
    ldx #0
  !:
    lda.z 0,x
    sta ZP_STORAGE,x
    inx
    bne !-
    jmp __breturn
    // saveZeropage::@return
  __breturn:
    // [14] return 
    rts
}
  // sinZeropage
// Move the SINE values to zeropage
sinZeropage: {
    // asm { ldx#0 !: ldaSINTABLE,x sta$00,x inx bne!-  }
    ldx #0
  !:
    lda SINTABLE,x
    sta.z 0,x
    inx
    bne !-
    jmp __breturn
    // sinZeropage::@return
  __breturn:
    // [16] return 
    rts
}
  // animSprite
// Move a sprite in the sine on zeropage
animSprite: {
    // kickasm() {{ ldx #$00     repeat:         lda #$fe     !:         cmp $d012         bne !-         lda #$ff     !:         cmp $d012         bne !-         .break         lda $00,x         clc         adc #$38         sta $d000         lda #0         adc #0         sta $d010         inx         jmp repeat      }}
    ldx #$00
    repeat:
        lda #$fe
    !:
        cmp $d012
        bne !-
        lda #$ff
    !:
        cmp $d012
        bne !-
        .break
        lda $00,x
        clc
        adc #$38
        sta $d000
        lda #0
        adc #0
        sta $d010
        inx
        jmp repeat
    
    jmp __breturn
    // animSprite::@return
  __breturn:
    // [18] return 
    rts
}
  // restoreZeropage
// Save all values on zeropage
restoreZeropage: {
    // asm { ldx#0 !: ldaZP_STORAGE,x sta$00,x inx bne!-  }
    ldx #0
  !:
    lda ZP_STORAGE,x
    sta.z 0,x
    inx
    bne !-
    jmp __breturn
    // restoreZeropage::@return
  __breturn:
    // [20] return 
    rts
}
  // File Data
.segment Data
  // A 256-byte (co)sine (with $ff in the first two entries)
  .align $100
SINTABLE:
.for(var i=0;i<$100;i++)
        .byte round(127.5+127.5*cos(toRadians(360*i/256)))

  // Storage for saving/restoring zeropage
  .align $100
  ZP_STORAGE: .fill $100, 0
  // A single sprite to animate
  .align $40
SPRITE:
.fill $40,$ff 

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #$64
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1_from_main:
Removing instruction __b2_from___b1:
Removing instruction __b3_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant const unsigned int OFFSET_SPRITE_PTRS = $3f8
__constant char * const SCREEN = (char *) 1024
__constant const char SINTABLE[$100] = kickasm {{ .for(var i=0;i<$100;i++)
        .byte round(127.5+127.5*cos(toRadians(360*i/256)))
 }}
__constant const char SPRITE[$40] = kickasm {{ .fill $40,$ff  }}
__constant char * const SPRITES_ENABLE = (char *) 53269
__constant char * const SPRITES_XPOS = (char *) 53248
__constant char * const SPRITES_YPOS = (char *) 53249
__constant const char ZP_STORAGE[$100] = { fill( $100, 0) }
void animSprite()
void main()
void restoreZeropage()
void saveZeropage()
void sinZeropage()



FINAL ASSEMBLER
Score: 379

  // File Comments
// Attempt to store and use a sine on zeropage
// $00/$11 is carefully chosen to be $ff - which plays well with the processor port
  // Upstart
  // Commodore 64 PRG executable file
.file [name="zeropage-sinus.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
  // Global Constants & labels
  /// The offset of the sprite pointers from the screen start address
  .const OFFSET_SPRITE_PTRS = $3f8
  /// Sprite X position register for sprite #0
  .label SPRITES_XPOS = $d000
  /// Sprite Y position register for sprite #0
  .label SPRITES_YPOS = $d001
  /// Sprite enable register
  .label SPRITES_ENABLE = $d015
  .label SCREEN = $400
.segment Code
  // main
main: {
    // asm
    // asm { sei  }
    // Stop interrupts
    sei
    // *SPRITES_ENABLE = 1
    // [1] *SPRITES_ENABLE = 1 -- _deref_pbuc1=vbuc2 
    // Show sprite
    lda #1
    sta SPRITES_ENABLE
    // SPRITES_YPOS[0] = 100
    // [2] *SPRITES_YPOS = $64 -- _deref_pbuc1=vbuc2 
    lda #$64
    sta SPRITES_YPOS
    // SPRITES_XPOS[0] = 100
    // [3] *SPRITES_XPOS = $64 -- _deref_pbuc1=vbuc2 
    sta SPRITES_XPOS
    // *(SCREEN+OFFSET_SPRITE_PTRS) = (byte)(SPRITE/0x40)
    // [4] *(SCREEN+OFFSET_SPRITE_PTRS) = (char)SPRITE/$40 -- _deref_pbuc1=vbuc2 
    lda #$ff&SPRITE/$40
    sta SCREEN+OFFSET_SPRITE_PTRS
    // saveZeropage()
    // [5] call saveZeropage
    jsr saveZeropage
    // [6] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // sinZeropage()
    // [7] call sinZeropage
    jsr sinZeropage
    // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // main::@2
    // animSprite()
    // [9] call animSprite
    jsr animSprite
    // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
    // main::@3
    // restoreZeropage()
    // [11] call restoreZeropage
    jsr restoreZeropage
    // main::@return
    // }
    // [12] return 
    rts
}
  // saveZeropage
// Save all values on zeropage
saveZeropage: {
    // asm
    // asm { ldx#0 !: lda$00,x staZP_STORAGE,x inx bne!-  }
    ldx #0
  !:
    lda.z 0,x
    sta ZP_STORAGE,x
    inx
    bne !-
    // saveZeropage::@return
    // }
    // [14] return 
    rts
}
  // sinZeropage
// Move the SINE values to zeropage
sinZeropage: {
    // asm
    // asm { ldx#0 !: ldaSINTABLE,x sta$00,x inx bne!-  }
    ldx #0
  !:
    lda SINTABLE,x
    sta.z 0,x
    inx
    bne !-
    // sinZeropage::@return
    // }
    // [16] return 
    rts
}
  // animSprite
// Move a sprite in the sine on zeropage
animSprite: {
    // kickasm
    // kickasm() {{ ldx #$00     repeat:         lda #$fe     !:         cmp $d012         bne !-         lda #$ff     !:         cmp $d012         bne !-         .break         lda $00,x         clc         adc #$38         sta $d000         lda #0         adc #0         sta $d010         inx         jmp repeat      }}
    ldx #$00
    repeat:
        lda #$fe
    !:
        cmp $d012
        bne !-
        lda #$ff
    !:
        cmp $d012
        bne !-
        .break
        lda $00,x
        clc
        adc #$38
        sta $d000
        lda #0
        adc #0
        sta $d010
        inx
        jmp repeat
    
    // animSprite::@return
    // }
    // [18] return 
    rts
}
  // restoreZeropage
// Save all values on zeropage
restoreZeropage: {
    // asm
    // asm { ldx#0 !: ldaZP_STORAGE,x sta$00,x inx bne!-  }
    ldx #0
  !:
    lda ZP_STORAGE,x
    sta.z 0,x
    inx
    bne !-
    // restoreZeropage::@return
    // }
    // [20] return 
    rts
}
  // File Data
.segment Data
  // A 256-byte (co)sine (with $ff in the first two entries)
  .align $100
SINTABLE:
.for(var i=0;i<$100;i++)
        .byte round(127.5+127.5*cos(toRadians(360*i/256)))

  // Storage for saving/restoring zeropage
  .align $100
  ZP_STORAGE: .fill $100, 0
  // A single sprite to animate
  .align $40
SPRITE:
.fill $40,$ff 

