1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00
kickc/src/test/ref/examples/kernalload/kernalload.log
2020-12-30 01:55:04 +01:00

1433 lines
55 KiB
Plaintext

Loading link script "kernalload.ld"
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
Inlined call main::$3 = call toSpritePtr LOAD_SPRITE
CONTROL FLOW GRAPH SSA
word strlen(byte* strlen::str)
strlen: scope:[strlen] from setnam
strlen::str#4 = phi( setnam/strlen::str#1 )
strlen::len#0 = 0
to:strlen::@1
strlen::@1: scope:[strlen] from strlen strlen::@2
strlen::len#4 = phi( strlen/strlen::len#0, strlen::@2/strlen::len#1 )
strlen::str#2 = phi( strlen/strlen::str#4, strlen::@2/strlen::str#0 )
strlen::$0 = 0 != *strlen::str#2
if(strlen::$0) goto strlen::@2
to:strlen::@3
strlen::@2: scope:[strlen] from strlen::@1
strlen::str#3 = phi( strlen::@1/strlen::str#2 )
strlen::len#2 = phi( strlen::@1/strlen::len#4 )
strlen::len#1 = ++ strlen::len#2
strlen::str#0 = ++ strlen::str#3
to:strlen::@1
strlen::@3: scope:[strlen] from strlen::@1
strlen::len#3 = phi( strlen::@1/strlen::len#4 )
strlen::return#0 = strlen::len#3
to:strlen::@return
strlen::@return: scope:[strlen] from strlen::@3
strlen::return#3 = phi( strlen::@3/strlen::return#0 )
strlen::return#1 = strlen::return#3
return
to:@return
void main()
main: scope:[main] from __start
loadFileToMemory::device#0 = 8
loadFileToMemory::filename#0 = main::filename
loadFileToMemory::address#0 = LOAD_SPRITE
call loadFileToMemory
loadFileToMemory::return#0 = loadFileToMemory::return#2
to:main::@4
main::@4: scope:[main] from main
loadFileToMemory::return#3 = phi( main/loadFileToMemory::return#0 )
main::$0 = loadFileToMemory::return#3
main::status#0 = main::$0
main::$1 = main::status#0 != $ff
main::$2 = ! main::$1
if(main::$2) goto main::@1
to:main::@2
main::@1: scope:[main] from main::@4 main::@5
*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
main::toSpritePtr1_sprite#0 = LOAD_SPRITE
to:main::toSpritePtr1
main::toSpritePtr1: scope:[main] from main::@1
main::toSpritePtr1_sprite#1 = phi( main::@1/main::toSpritePtr1_sprite#0 )
main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#1
main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
to:main::toSpritePtr1_@return
main::toSpritePtr1_@return: scope:[main] from main::toSpritePtr1
main::toSpritePtr1_return#2 = phi( main::toSpritePtr1/main::toSpritePtr1_return#0 )
main::toSpritePtr1_return#1 = main::toSpritePtr1_return#2
to:main::@3
main::@3: scope:[main] from main::toSpritePtr1_@return
main::toSpritePtr1_return#3 = phi( main::toSpritePtr1_@return/main::toSpritePtr1_return#1 )
main::$3 = main::toSpritePtr1_return#3
SPRITES_PTR[0] = main::$3
SPRITES_COLOR[0] = GREEN
SPRITES_XPOS[0] = $15
SPRITES_YPOS[0] = $33
to:main::@return
main::@2: scope:[main] from main::@4
main::status#1 = phi( main::@4/main::status#0 )
*((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2
error::err#0 = main::status#1
call error
to:main::@5
main::@5: scope:[main] from main::@2
to:main::@1
main::@return: scope:[main] from main::@3
return
to:@return
byte loadFileToMemory(byte loadFileToMemory::device , byte* loadFileToMemory::filename , byte* loadFileToMemory::address)
loadFileToMemory: scope:[loadFileToMemory] from main
loadFileToMemory::address#3 = phi( main/loadFileToMemory::address#0 )
loadFileToMemory::device#2 = phi( main/loadFileToMemory::device#0 )
loadFileToMemory::filename#1 = phi( main/loadFileToMemory::filename#0 )
setnam::filename#0 = loadFileToMemory::filename#1
call setnam
to:loadFileToMemory::@1
loadFileToMemory::@1: scope:[loadFileToMemory] from loadFileToMemory
loadFileToMemory::address#2 = phi( loadFileToMemory/loadFileToMemory::address#3 )
loadFileToMemory::device#1 = phi( loadFileToMemory/loadFileToMemory::device#2 )
setlfs::device#0 = loadFileToMemory::device#1
call setlfs
to:loadFileToMemory::@2
loadFileToMemory::@2: scope:[loadFileToMemory] from loadFileToMemory::@1
loadFileToMemory::address#1 = phi( loadFileToMemory::@1/loadFileToMemory::address#2 )
load::address#0 = loadFileToMemory::address#1
load::verify#0 = false
call load
load::return#0 = load::return#2
to:loadFileToMemory::@3
loadFileToMemory::@3: scope:[loadFileToMemory] from loadFileToMemory::@2
load::return#3 = phi( loadFileToMemory::@2/load::return#0 )
loadFileToMemory::$2 = load::return#3
loadFileToMemory::return#1 = loadFileToMemory::$2
to:loadFileToMemory::@return
loadFileToMemory::@return: scope:[loadFileToMemory] from loadFileToMemory::@3
loadFileToMemory::return#4 = phi( loadFileToMemory::@3/loadFileToMemory::return#1 )
loadFileToMemory::return#2 = loadFileToMemory::return#4
return
to:@return
void error(byte error::err)
error: scope:[error] from main::@2
error::err#1 = phi( main::@2/error::err#0 )
*error::errCode = error::err#1
asm { ldxerrCode jsr$a437 }
to:error::@return
error::@return: scope:[error] from error
return
to:@return
void setnam(byte* setnam::filename)
setnam: scope:[setnam] from loadFileToMemory
setnam::filename#1 = phi( loadFileToMemory/setnam::filename#0 )
strlen::str#1 = setnam::filename#1
call strlen
strlen::return#2 = strlen::return#1
to:setnam::@1
setnam::@1: scope:[setnam] from setnam
setnam::filename#2 = phi( setnam/setnam::filename#1 )
strlen::return#4 = phi( setnam/strlen::return#2 )
setnam::$0 = strlen::return#4
*setnam::filename_len = (byte)setnam::$0
*setnam::filename_ptr = setnam::filename#2
asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd }
to:setnam::@return
setnam::@return: scope:[setnam] from setnam::@1
return
to:@return
void setlfs(byte setlfs::device)
setlfs: scope:[setlfs] from loadFileToMemory::@1
setlfs::device#1 = phi( loadFileToMemory::@1/setlfs::device#0 )
*setlfs::deviceNum = setlfs::device#1
asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba }
to:setlfs::@return
setlfs::@return: scope:[setlfs] from setlfs
return
to:@return
byte load(byte* load::address , bool load::verify)
load: scope:[load] from loadFileToMemory::@2
load::address#1 = phi( loadFileToMemory::@2/load::address#0 )
load::verify#1 = phi( loadFileToMemory::@2/load::verify#0 )
*load::loadOrVerify = (byte)load::verify#1
*load::loadAddress = load::address#1
asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus }
load::return#1 = *load::status
to:load::@return
load::@return: scope:[load] from load
load::return#4 = phi( load/load::return#1 )
load::return#2 = load::return#4
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
const nomodify byte GREEN = 5
const nomodify byte* LOAD_SPRITE = (byte*)$3000
const nomodify word OFFSET_SPRITE_PTRS = $3f8
const byte OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR = $20
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
const nomodify byte* SCREEN = (byte*)$400
const byte* SPRITE[] = kickasm {{ .var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
.for (var y=0; y<21; y++)
.for (var x=0;x<3; x++)
.byte pic.getSinglecolorByte(x,y)
}}
const nomodify byte* SPRITES_COLOR = (byte*)$d027
const nomodify byte* SPRITES_PTR = SCREEN+OFFSET_SPRITE_PTRS
const nomodify byte* SPRITES_XPOS = (byte*)$d000
const nomodify byte* SPRITES_YPOS = (byte*)$d001
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*)$d000
void __start()
void error(byte error::err)
byte error::err
byte error::err#0
byte error::err#1
const nomodify byte* error::errCode = (byte*)$ff
byte load(byte* load::address , bool load::verify)
byte* load::address
byte* load::address#0
byte* load::address#1
const byte** load::loadAddress = (byte**)$fe
const byte* load::loadOrVerify = (byte*)$fd
byte load::return
byte load::return#0
byte load::return#1
byte load::return#2
byte load::return#3
byte load::return#4
const byte* load::status = (byte*)$fd
bool load::verify
bool load::verify#0
bool load::verify#1
byte loadFileToMemory(byte loadFileToMemory::device , byte* loadFileToMemory::filename , byte* loadFileToMemory::address)
byte~ loadFileToMemory::$2
byte* loadFileToMemory::address
byte* loadFileToMemory::address#0
byte* loadFileToMemory::address#1
byte* loadFileToMemory::address#2
byte* loadFileToMemory::address#3
byte loadFileToMemory::device
byte loadFileToMemory::device#0
byte loadFileToMemory::device#1
byte loadFileToMemory::device#2
byte* loadFileToMemory::filename
byte* loadFileToMemory::filename#0
byte* loadFileToMemory::filename#1
byte loadFileToMemory::return
byte loadFileToMemory::return#0
byte loadFileToMemory::return#1
byte loadFileToMemory::return#2
byte loadFileToMemory::return#3
byte loadFileToMemory::return#4
void main()
byte~ main::$0
bool~ main::$1
bool~ main::$2
byte~ main::$3
const byte* main::filename[7] = "SPRITE"
byte main::status
byte main::status#0
byte main::status#1
number~ main::toSpritePtr1_$0
word~ main::toSpritePtr1_$1
byte main::toSpritePtr1_return
byte main::toSpritePtr1_return#0
byte main::toSpritePtr1_return#1
byte main::toSpritePtr1_return#2
byte main::toSpritePtr1_return#3
byte* main::toSpritePtr1_sprite
byte* main::toSpritePtr1_sprite#0
byte* main::toSpritePtr1_sprite#1
void setlfs(byte setlfs::device)
byte setlfs::device
byte setlfs::device#0
byte setlfs::device#1
const nomodify byte* setlfs::deviceNum = (byte*)$ff
void setnam(byte* setnam::filename)
word~ setnam::$0
byte* setnam::filename
byte* setnam::filename#0
byte* setnam::filename#1
byte* setnam::filename#2
const nomodify byte* setnam::filename_len = (byte*)$fd
const nomodify byte** setnam::filename_ptr = (byte**)$fe
word strlen(byte* strlen::str)
bool~ strlen::$0
word strlen::len
word strlen::len#0
word strlen::len#1
word strlen::len#2
word strlen::len#3
word strlen::len#4
word strlen::return
word strlen::return#0
word strlen::return#1
word strlen::return#2
word strlen::return#3
word strlen::return#4
byte* strlen::str
byte* strlen::str#0
byte* strlen::str#1
byte* strlen::str#2
byte* strlen::str#3
byte* strlen::str#4
Adding number conversion cast (unumber) 0 in strlen::$0 = 0 != *strlen::str#2
Adding number conversion cast (unumber) 8 in loadFileToMemory::device#0 = 8
Adding number conversion cast (unumber) $ff in main::$1 = main::status#0 != $ff
Adding number conversion cast (unumber) 1 in *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
Adding number conversion cast (unumber) $40 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
Adding number conversion cast (unumber) main::toSpritePtr1_$0 in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / (unumber)$40
Adding number conversion cast (unumber) 0 in SPRITES_PTR[0] = main::$3
Adding number conversion cast (unumber) 0 in SPRITES_COLOR[0] = GREEN
Adding number conversion cast (unumber) $15 in SPRITES_XPOS[0] = $15
Adding number conversion cast (unumber) 0 in SPRITES_XPOS[0] = ((unumber)) $15
Adding number conversion cast (unumber) $33 in SPRITES_YPOS[0] = $33
Adding number conversion cast (unumber) 0 in SPRITES_YPOS[0] = ((unumber)) $33
Adding number conversion cast (unumber) 2 in *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast loadFileToMemory::device#0 = (unumber)8
Inlining cast *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = (unumber)1
Inlining cast SPRITES_XPOS[(unumber)0] = (unumber)$15
Inlining cast SPRITES_YPOS[(unumber)0] = (unumber)$33
Inlining cast *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = (unumber)2
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53248
Simplifying constant pointer cast (byte*) 53249
Simplifying constant pointer cast (byte*) 53287
Simplifying constant pointer cast (struct MOS6569_VICII*) 53248
Simplifying constant pointer cast (byte*) 12288
Simplifying constant pointer cast (byte*) 1024
Simplifying constant pointer cast (byte*) 255
Simplifying constant pointer cast (byte*) 253
Simplifying constant pointer cast (byte**) 254
Simplifying constant pointer cast (byte*) 255
Simplifying constant pointer cast (byte*) 253
Simplifying constant pointer cast (byte**) 254
Simplifying constant pointer cast (byte*) 253
Simplifying constant integer cast 0
Simplifying constant integer cast 8
Simplifying constant integer cast $ff
Simplifying constant integer cast 1
Simplifying constant integer cast $40
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast $15
Simplifying constant integer cast 0
Simplifying constant integer cast $33
Simplifying constant integer cast 0
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 8
Finalized unsigned number type (byte) $ff
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) $40
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) $15
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) $33
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to word in main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
Inversing boolean not [22] main::$2 = main::status#0 == $ff from [21] main::$1 = main::status#0 != $ff
Successful SSA optimization Pass2UnaryNotSimplification
Alias strlen::len#2 = strlen::len#4 strlen::len#3 strlen::return#0 strlen::return#3 strlen::return#1
Alias strlen::str#2 = strlen::str#3
Alias loadFileToMemory::return#0 = loadFileToMemory::return#3
Alias main::status#0 = main::$0 main::status#1
Alias main::toSpritePtr1_sprite#0 = main::toSpritePtr1_sprite#1
Alias main::toSpritePtr1_return#0 = main::toSpritePtr1_return#2 main::toSpritePtr1_return#1 main::toSpritePtr1_return#3 main::$3
Alias loadFileToMemory::device#1 = loadFileToMemory::device#2
Alias loadFileToMemory::address#1 = loadFileToMemory::address#2 loadFileToMemory::address#3
Alias load::return#0 = load::return#3
Alias loadFileToMemory::return#1 = loadFileToMemory::$2 loadFileToMemory::return#4 loadFileToMemory::return#2
Alias strlen::return#2 = strlen::return#4
Alias setnam::filename#1 = setnam::filename#2
Alias load::return#1 = load::return#4 load::return#2
Successful SSA optimization Pass2AliasElimination
Identical Phi Values strlen::str#4 strlen::str#1
Identical Phi Values loadFileToMemory::filename#1 loadFileToMemory::filename#0
Identical Phi Values loadFileToMemory::device#1 loadFileToMemory::device#0
Identical Phi Values loadFileToMemory::address#1 loadFileToMemory::address#0
Identical Phi Values error::err#1 error::err#0
Identical Phi Values setnam::filename#1 setnam::filename#0
Identical Phi Values setlfs::device#1 setlfs::device#0
Identical Phi Values load::verify#1 load::verify#0
Identical Phi Values load::address#1 load::address#0
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition strlen::$0 [4] if(0!=*strlen::str#2) goto strlen::@2
Simple Condition main::$2 [15] if(main::status#0==$ff) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant strlen::len#0 = 0
Constant loadFileToMemory::device#0 = 8
Constant loadFileToMemory::filename#0 = main::filename
Constant loadFileToMemory::address#0 = LOAD_SPRITE
Constant main::toSpritePtr1_sprite#0 = LOAD_SPRITE
Constant load::verify#0 = false
Successful SSA optimization Pass2ConstantIdentification
Constant main::toSpritePtr1_$1 = (word)main::toSpritePtr1_sprite#0
Constant setnam::filename#0 = loadFileToMemory::filename#0
Constant setlfs::device#0 = loadFileToMemory::device#0
Constant load::address#0 = loadFileToMemory::address#0
Successful SSA optimization Pass2ConstantIdentification
Constant strlen::str#1 = setnam::filename#0
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte)load::verify#0 in [58] *load::loadOrVerify = (byte)load::verify#0
Successful SSA optimization Pass2ConstantValues
Simplifying constant evaluating to zero (byte)load::verify#0 in [58] *load::loadOrVerify = (byte)load::verify#0
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero SPRITES_PTR in [21] SPRITES_PTR[0] = main::toSpritePtr1_return#0
Simplifying expression containing zero SPRITES_COLOR in [22] SPRITES_COLOR[0] = GREEN
Simplifying expression containing zero SPRITES_XPOS in [23] SPRITES_XPOS[0] = $15
Simplifying expression containing zero SPRITES_YPOS in [24] SPRITES_YPOS[0] = $33
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant load::verify#0
Successful SSA optimization PassNEliminateUnusedVars
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
Constant right-side identified [10] main::toSpritePtr1_$0 = main::toSpritePtr1_$1 / $40
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::toSpritePtr1_$0 = main::toSpritePtr1_$1/$40
Successful SSA optimization Pass2ConstantIdentification
Constant main::toSpritePtr1_return#0 = (byte)main::toSpritePtr1_$0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings strlen::len#0
Inlining constant with var siblings strlen::str#1
Constant inlined main::toSpritePtr1_sprite#0 = LOAD_SPRITE
Constant inlined load::address#0 = LOAD_SPRITE
Constant inlined setnam::filename#0 = main::filename
Constant inlined main::toSpritePtr1_$0 = (word)LOAD_SPRITE/$40
Constant inlined strlen::str#1 = main::filename
Constant inlined loadFileToMemory::address#0 = LOAD_SPRITE
Constant inlined setlfs::device#0 = loadFileToMemory::device#0
Constant inlined main::toSpritePtr1_$1 = (word)LOAD_SPRITE
Constant inlined strlen::len#0 = 0
Constant inlined loadFileToMemory::filename#0 = main::filename
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@5
Adding NOP phi() at start of main::toSpritePtr1
Adding NOP phi() at start of main::toSpritePtr1_@return
Adding NOP phi() at start of loadFileToMemory
Adding NOP phi() at start of loadFileToMemory::@1
Adding NOP phi() at start of loadFileToMemory::@2
Adding NOP phi() at start of setnam
Adding NOP phi() at start of strlen
Adding NOP phi() at start of strlen::@3
CALL GRAPH
Calls in [main] to loadFileToMemory:1 error:7
Calls in [loadFileToMemory] to setnam:18 setlfs:20 load:22
Calls in [setnam] to strlen:30
Created 2 initial phi equivalence classes
Coalesced [52] strlen::str#5 = strlen::str#0
Coalesced [53] strlen::len#5 = strlen::len#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@5
Culled Empty Block label main::toSpritePtr1_@return
Culled Empty Block label strlen::@3
Adding NOP phi() at start of main
Adding NOP phi() at start of main::toSpritePtr1
Adding NOP phi() at start of loadFileToMemory
Adding NOP phi() at start of loadFileToMemory::@1
Adding NOP phi() at start of loadFileToMemory::@2
Adding NOP phi() at start of setnam
Adding NOP phi() at start of strlen
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call loadFileToMemory
[2] loadFileToMemory::return#0 = loadFileToMemory::return#1
to:main::@4
main::@4: scope:[main] from main
[3] main::status#0 = loadFileToMemory::return#0
[4] if(main::status#0==$ff) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@4
[5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2
[6] error::err#0 = main::status#0
[7] call error
to:main::@1
main::@1: scope:[main] from main::@2 main::@4
[8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1
to:main::toSpritePtr1
main::toSpritePtr1: scope:[main] from main::@1
[9] phi()
to:main::@3
main::@3: scope:[main] from main::toSpritePtr1
[10] *SPRITES_PTR = main::toSpritePtr1_return#0
[11] *SPRITES_COLOR = GREEN
[12] *SPRITES_XPOS = $15
[13] *SPRITES_YPOS = $33
to:main::@return
main::@return: scope:[main] from main::@3
[14] return
to:@return
byte loadFileToMemory(byte loadFileToMemory::device , byte* loadFileToMemory::filename , byte* loadFileToMemory::address)
loadFileToMemory: scope:[loadFileToMemory] from main
[15] phi()
[16] call setnam
to:loadFileToMemory::@1
loadFileToMemory::@1: scope:[loadFileToMemory] from loadFileToMemory
[17] phi()
[18] call setlfs
to:loadFileToMemory::@2
loadFileToMemory::@2: scope:[loadFileToMemory] from loadFileToMemory::@1
[19] phi()
[20] call load
[21] load::return#0 = load::return#1
to:loadFileToMemory::@3
loadFileToMemory::@3: scope:[loadFileToMemory] from loadFileToMemory::@2
[22] loadFileToMemory::return#1 = load::return#0
to:loadFileToMemory::@return
loadFileToMemory::@return: scope:[loadFileToMemory] from loadFileToMemory::@3
[23] return
to:@return
void error(byte error::err)
error: scope:[error] from main::@2
[24] *error::errCode = error::err#0
asm { ldxerrCode jsr$a437 }
to:error::@return
error::@return: scope:[error] from error
[26] return
to:@return
void setnam(byte* setnam::filename)
setnam: scope:[setnam] from loadFileToMemory
[27] phi()
[28] call strlen
[29] strlen::return#2 = strlen::len#2
to:setnam::@1
setnam::@1: scope:[setnam] from setnam
[30] setnam::$0 = strlen::return#2
[31] *setnam::filename_len = (byte)setnam::$0
[32] *setnam::filename_ptr = main::filename
asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd }
to:setnam::@return
setnam::@return: scope:[setnam] from setnam::@1
[34] return
to:@return
void setlfs(byte setlfs::device)
setlfs: scope:[setlfs] from loadFileToMemory::@1
[35] *setlfs::deviceNum = loadFileToMemory::device#0
asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba }
to:setlfs::@return
setlfs::@return: scope:[setlfs] from setlfs
[37] return
to:@return
byte load(byte* load::address , bool load::verify)
load: scope:[load] from loadFileToMemory::@2
[38] *load::loadOrVerify = 0
[39] *load::loadAddress = LOAD_SPRITE
asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus }
[41] load::return#1 = *load::status
to:load::@return
load::@return: scope:[load] from load
[42] return
to:@return
word strlen(byte* strlen::str)
strlen: scope:[strlen] from setnam
[43] phi()
to:strlen::@1
strlen::@1: scope:[strlen] from strlen strlen::@2
[44] strlen::len#2 = phi( strlen/0, strlen::@2/strlen::len#1 )
[44] strlen::str#2 = phi( strlen/main::filename, strlen::@2/strlen::str#0 )
[45] if(0!=*strlen::str#2) goto strlen::@2
to:strlen::@return
strlen::@return: scope:[strlen] from strlen::@1
[46] return
to:@return
strlen::@2: scope:[strlen] from strlen::@1
[47] strlen::len#1 = ++ strlen::len#2
[48] strlen::str#0 = ++ strlen::str#2
to:strlen::@1
VARIABLE REGISTER WEIGHTS
void error(byte error::err)
byte error::err
byte error::err#0 13.0
byte load(byte* load::address , bool load::verify)
byte* load::address
byte load::return
byte load::return#0 22.0
byte load::return#1 37.33333333333333
bool load::verify
byte loadFileToMemory(byte loadFileToMemory::device , byte* loadFileToMemory::filename , byte* loadFileToMemory::address)
byte* loadFileToMemory::address
byte loadFileToMemory::device
byte* loadFileToMemory::filename
byte loadFileToMemory::return
byte loadFileToMemory::return#0 4.0
byte loadFileToMemory::return#1 4.333333333333333
void main()
byte main::status
byte main::status#0 2.0
byte main::toSpritePtr1_return
byte* main::toSpritePtr1_sprite
void setlfs(byte setlfs::device)
byte setlfs::device
void setnam(byte* setnam::filename)
word~ setnam::$0 101.0
byte* setnam::filename
word strlen(byte* strlen::str)
word strlen::len
word strlen::len#1 10001.0
word strlen::len#2 5025.75
word strlen::return
word strlen::return#2 202.0
byte* strlen::str
byte* strlen::str#0 20002.0
byte* strlen::str#2 10001.0
Initial phi equivalence classes
[ strlen::str#2 strlen::str#0 ]
[ strlen::len#2 strlen::len#1 ]
Added variable loadFileToMemory::return#0 to live range equivalence class [ loadFileToMemory::return#0 ]
Added variable main::status#0 to live range equivalence class [ main::status#0 ]
Added variable error::err#0 to live range equivalence class [ error::err#0 ]
Added variable load::return#0 to live range equivalence class [ load::return#0 ]
Added variable loadFileToMemory::return#1 to live range equivalence class [ loadFileToMemory::return#1 ]
Added variable strlen::return#2 to live range equivalence class [ strlen::return#2 ]
Added variable setnam::$0 to live range equivalence class [ setnam::$0 ]
Added variable load::return#1 to live range equivalence class [ load::return#1 ]
Complete equivalence classes
[ strlen::str#2 strlen::str#0 ]
[ strlen::len#2 strlen::len#1 ]
[ loadFileToMemory::return#0 ]
[ main::status#0 ]
[ error::err#0 ]
[ load::return#0 ]
[ loadFileToMemory::return#1 ]
[ strlen::return#2 ]
[ setnam::$0 ]
[ load::return#1 ]
Allocated zp[2]:2 [ strlen::str#2 strlen::str#0 ]
Allocated zp[2]:4 [ strlen::len#2 strlen::len#1 ]
Allocated zp[1]:6 [ loadFileToMemory::return#0 ]
Allocated zp[1]:7 [ main::status#0 ]
Allocated zp[1]:8 [ error::err#0 ]
Allocated zp[1]:9 [ load::return#0 ]
Allocated zp[1]:10 [ loadFileToMemory::return#1 ]
Allocated zp[2]:11 [ strlen::return#2 ]
Allocated zp[2]:13 [ setnam::$0 ]
Allocated zp[1]:15 [ load::return#1 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2 [ main::status#0 ] ( [ main::status#0 ] { { error::err#0 = main::status#0 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:7 [ main::status#0 ]
Statement [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [10] *SPRITES_PTR = main::toSpritePtr1_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [11] *SPRITES_COLOR = GREEN [ ] ( [ ] { } ) always clobbers reg byte a
Statement [12] *SPRITES_XPOS = $15 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [13] *SPRITES_YPOS = $33 [ ] ( [ ] { } ) always clobbers reg byte a
Statement asm { ldxerrCode jsr$a437 } always clobbers reg byte a reg byte x reg byte y
Statement [29] strlen::return#2 = strlen::len#2 [ strlen::return#2 ] ( loadFileToMemory:1::setnam:16 [ strlen::return#2 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [30] setnam::$0 = strlen::return#2 [ setnam::$0 ] ( loadFileToMemory:1::setnam:16 [ setnam::$0 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement [31] *setnam::filename_len = (byte)setnam::$0 [ ] ( loadFileToMemory:1::setnam:16 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement [32] *setnam::filename_ptr = main::filename [ ] ( loadFileToMemory:1::setnam:16 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd } always clobbers reg byte a reg byte x reg byte y
Statement [35] *setlfs::deviceNum = loadFileToMemory::device#0 [ ] ( loadFileToMemory:1::setlfs:18 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba } always clobbers reg byte a reg byte x reg byte y
Statement [38] *load::loadOrVerify = 0 [ ] ( loadFileToMemory:1::load:20 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { load::return#0 = load::return#1 } } ) always clobbers reg byte a
Statement [39] *load::loadAddress = LOAD_SPRITE [ ] ( loadFileToMemory:1::load:20 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { load::return#0 = load::return#1 } } ) always clobbers reg byte a
Statement asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus } always clobbers reg byte a reg byte x reg byte y
Statement [45] if(0!=*strlen::str#2) goto strlen::@2 [ strlen::len#2 strlen::str#2 ] ( loadFileToMemory:1::setnam:16::strlen:28 [ strlen::len#2 strlen::str#2 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2 [ main::status#0 ] ( [ main::status#0 ] { { error::err#0 = main::status#0 } } ) always clobbers reg byte a
Statement [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [10] *SPRITES_PTR = main::toSpritePtr1_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [11] *SPRITES_COLOR = GREEN [ ] ( [ ] { } ) always clobbers reg byte a
Statement [12] *SPRITES_XPOS = $15 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [13] *SPRITES_YPOS = $33 [ ] ( [ ] { } ) always clobbers reg byte a
Statement asm { ldxerrCode jsr$a437 } always clobbers reg byte a reg byte x reg byte y
Statement [29] strlen::return#2 = strlen::len#2 [ strlen::return#2 ] ( loadFileToMemory:1::setnam:16 [ strlen::return#2 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a
Statement [30] setnam::$0 = strlen::return#2 [ setnam::$0 ] ( loadFileToMemory:1::setnam:16 [ setnam::$0 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement [31] *setnam::filename_len = (byte)setnam::$0 [ ] ( loadFileToMemory:1::setnam:16 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement [32] *setnam::filename_ptr = main::filename [ ] ( loadFileToMemory:1::setnam:16 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd } always clobbers reg byte a reg byte x reg byte y
Statement [35] *setlfs::deviceNum = loadFileToMemory::device#0 [ ] ( loadFileToMemory:1::setlfs:18 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } } ) always clobbers reg byte a
Statement asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba } always clobbers reg byte a reg byte x reg byte y
Statement [38] *load::loadOrVerify = 0 [ ] ( loadFileToMemory:1::load:20 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { load::return#0 = load::return#1 } } ) always clobbers reg byte a
Statement [39] *load::loadAddress = LOAD_SPRITE [ ] ( loadFileToMemory:1::load:20 [ ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { load::return#0 = load::return#1 } } ) always clobbers reg byte a
Statement asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus } always clobbers reg byte a reg byte x reg byte y
Statement [45] if(0!=*strlen::str#2) goto strlen::@2 [ strlen::len#2 strlen::str#2 ] ( loadFileToMemory:1::setnam:16::strlen:28 [ strlen::len#2 strlen::str#2 ] { { loadFileToMemory::return#0 = loadFileToMemory::return#1 } { strlen::return#2 = strlen::len#2 } } ) always clobbers reg byte a reg byte y
Potential registers zp[2]:2 [ strlen::str#2 strlen::str#0 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ strlen::len#2 strlen::len#1 ] : zp[2]:4 ,
Potential registers zp[1]:6 [ loadFileToMemory::return#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::status#0 ] : zp[1]:7 , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ error::err#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ load::return#0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ loadFileToMemory::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[2]:11 [ strlen::return#2 ] : zp[2]:11 ,
Potential registers zp[2]:13 [ setnam::$0 ] : zp[2]:13 ,
Potential registers zp[1]:15 [ load::return#1 ] : zp[1]:15 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [strlen] 30,003: zp[2]:2 [ strlen::str#2 strlen::str#0 ] 15,026.75: zp[2]:4 [ strlen::len#2 strlen::len#1 ] 202: zp[2]:11 [ strlen::return#2 ]
Uplift Scope [setnam] 101: zp[2]:13 [ setnam::$0 ]
Uplift Scope [load] 37.33: zp[1]:15 [ load::return#1 ] 22: zp[1]:9 [ load::return#0 ]
Uplift Scope [error] 13: zp[1]:8 [ error::err#0 ]
Uplift Scope [loadFileToMemory] 4.33: zp[1]:10 [ loadFileToMemory::return#1 ] 4: zp[1]:6 [ loadFileToMemory::return#0 ]
Uplift Scope [main] 2: zp[1]:7 [ main::status#0 ]
Uplift Scope [MOS6526_CIA]
Uplift Scope [MOS6569_VICII]
Uplift Scope [MOS6581_SID]
Uplift Scope [setlfs]
Uplift Scope []
Uplifting [strlen] best 1032 combination zp[2]:2 [ strlen::str#2 strlen::str#0 ] zp[2]:4 [ strlen::len#2 strlen::len#1 ] zp[2]:11 [ strlen::return#2 ]
Uplifting [setnam] best 1032 combination zp[2]:13 [ setnam::$0 ]
Uplifting [load] best 1020 combination reg byte a [ load::return#1 ] reg byte a [ load::return#0 ]
Uplifting [error] best 1014 combination reg byte a [ error::err#0 ]
Uplifting [loadFileToMemory] best 1002 combination reg byte a [ loadFileToMemory::return#1 ] reg byte a [ loadFileToMemory::return#0 ]
Uplifting [main] best 997 combination reg byte x [ main::status#0 ]
Uplifting [MOS6526_CIA] best 997 combination
Uplifting [MOS6569_VICII] best 997 combination
Uplifting [MOS6581_SID] best 997 combination
Uplifting [setlfs] best 997 combination
Uplifting [] best 997 combination
Coalescing zero page register [ zp[2]:4 [ strlen::len#2 strlen::len#1 ] ] with [ zp[2]:11 [ strlen::return#2 ] ] - score: 1
Coalescing zero page register [ zp[2]:4 [ strlen::len#2 strlen::len#1 strlen::return#2 ] ] with [ zp[2]:13 [ setnam::$0 ] ] - score: 1
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Load a file to memory using the C64 KERNAL LOAD functions
// The kernalload.ld link file creates a D64 disk image containing the executable and the sprite.
// To execute the program succesfully you must mount the D64 disk image and execute the kernalload.PRG program
// Upstart
// Create a D64 disk containing the program and a sprite file
.disk [filename="kernalload.d64", name="DISK", id=1] {
[name="KERNALLOAD", type="prg", segments="Program"],
[name="SPRITE", type="prg", segments="Sprite"]
}
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef Sprite
.segment Basic
:BasicUpstart(main)
.segment Code
// Global Constants & labels
// The offset of the sprite pointers from the screen start address
.const OFFSET_SPRITE_PTRS = $3f8
.const GREEN = 5
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
.const OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR = $20
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
.label SPRITES_COLOR = $d027
// The VIC-II MOS 6567/6569
.label VICII = $d000
// Address to load to
.label LOAD_SPRITE = $3000
.label SCREEN = $400
.label SPRITES_PTR = SCREEN+OFFSET_SPRITE_PTRS
.segment Code
// main
main: {
.const toSpritePtr1_return = LOAD_SPRITE/$40
// [1] call loadFileToMemory
// [15] phi from main to loadFileToMemory [phi:main->loadFileToMemory]
loadFileToMemory_from_main:
jsr loadFileToMemory
// [2] loadFileToMemory::return#0 = loadFileToMemory::return#1
jmp __b4
// main::@4
__b4:
// [3] main::status#0 = loadFileToMemory::return#0 -- vbuxx=vbuaa
tax
// [4] if(main::status#0==$ff) goto main::@1 -- vbuxx_eq_vbuc1_then_la1
cpx #$ff
beq __b1
jmp __b2
// main::@2
__b2:
// [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2 -- _deref_pbuc1=vbuc2
lda #2
sta VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
// [6] error::err#0 = main::status#0 -- vbuaa=vbuxx
txa
// [7] call error
jsr error
jmp __b1
// main::@1
__b1:
// [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
// Show the loaded sprite on screen
lda #1
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
// [9] phi from main::@1 to main::toSpritePtr1 [phi:main::@1->main::toSpritePtr1]
toSpritePtr1_from___b1:
jmp toSpritePtr1
// main::toSpritePtr1
toSpritePtr1:
jmp __b3
// main::@3
__b3:
// [10] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
lda #toSpritePtr1_return
sta SPRITES_PTR
// [11] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
lda #GREEN
sta SPRITES_COLOR
// [12] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
lda #$15
sta SPRITES_XPOS
// [13] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
lda #$33
sta SPRITES_YPOS
jmp __breturn
// main::@return
__breturn:
// [14] return
rts
.segment Data
filename: .text "SPRITE"
.byte 0
}
.segment Code
// loadFileToMemory
// Load a file to memory
// Returns a status:
// - 0xff: Success
// - other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf)
loadFileToMemory: {
.label device = 8
// [16] call setnam
// [27] phi from loadFileToMemory to setnam [phi:loadFileToMemory->setnam]
setnam_from_loadFileToMemory:
jsr setnam
// [17] phi from loadFileToMemory to loadFileToMemory::@1 [phi:loadFileToMemory->loadFileToMemory::@1]
__b1_from_loadFileToMemory:
jmp __b1
// loadFileToMemory::@1
__b1:
// [18] call setlfs
jsr setlfs
// [19] phi from loadFileToMemory::@1 to loadFileToMemory::@2 [phi:loadFileToMemory::@1->loadFileToMemory::@2]
__b2_from___b1:
jmp __b2
// loadFileToMemory::@2
__b2:
// [20] call load
jsr load
// [21] load::return#0 = load::return#1
jmp __b3
// loadFileToMemory::@3
__b3:
// [22] loadFileToMemory::return#1 = load::return#0
jmp __breturn
// loadFileToMemory::@return
__breturn:
// [23] return
rts
}
// error
// Basic ERROR function
// ERROR. Show error.
// error(byte register(A) err)
error: {
.label errCode = $ff
// [24] *error::errCode = error::err#0 -- _deref_pbuc1=vbuaa
sta errCode
// asm { ldxerrCode jsr$a437 }
ldx errCode
jsr $a437
jmp __breturn
// error::@return
__breturn:
// [26] return
rts
}
// setnam
// Kernal SETNAM function
// SETNAM. Set file name parameters.
setnam: {
.label filename_len = $fd
.label filename_ptr = $fe
.label __0 = 4
// [28] call strlen
// [43] phi from setnam to strlen [phi:setnam->strlen]
strlen_from_setnam:
jsr strlen
// [29] strlen::return#2 = strlen::len#2
jmp __b1
// setnam::@1
__b1:
// [30] setnam::$0 = strlen::return#2
// [31] *setnam::filename_len = (byte)setnam::$0 -- _deref_pbuc1=_byte_vwuz1
lda.z __0
sta filename_len
// [32] *setnam::filename_ptr = main::filename -- _deref_qbuc1=pbuc2
lda #<main.filename
sta filename_ptr
lda #>main.filename
sta filename_ptr+1
// asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd }
lda filename_len
ldx filename_ptr
ldy filename_ptr+1
jsr $ffbd
jmp __breturn
// setnam::@return
__breturn:
// [34] return
rts
}
// setlfs
// SETLFS. Set file parameters.
setlfs: {
.label deviceNum = $ff
// [35] *setlfs::deviceNum = loadFileToMemory::device#0 -- _deref_pbuc1=vbuc2
lda #loadFileToMemory.device
sta deviceNum
// asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba }
ldx deviceNum
lda #1
ldy #0
jsr $ffba
jmp __breturn
// setlfs::@return
__breturn:
// [37] return
rts
}
// load
//LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
// Returns a status, 0xff: Success other: Kernal Error Code
load: {
.label loadOrVerify = $fd
.label loadAddress = $fe
.label status = $fd
// [38] *load::loadOrVerify = 0 -- _deref_pbuc1=vbuc2
lda #0
sta loadOrVerify
// [39] *load::loadAddress = LOAD_SPRITE -- _deref_qbuc1=pbuc2
lda #<LOAD_SPRITE
sta loadAddress
lda #>LOAD_SPRITE
sta loadAddress+1
// asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus }
ldx loadAddress
ldy loadAddress+1
lda loadOrVerify
jsr $ffd5
bcs error
lda #$ff
error:
sta status
// [41] load::return#1 = *load::status -- vbuaa=_deref_pbuc1
lda status
jmp __breturn
// load::@return
__breturn:
// [42] return
rts
}
// strlen
// Computes the length of the string str up to but not including the terminating null character.
// strlen(byte* zp(2) str)
strlen: {
.label len = 4
.label str = 2
.label return = 4
// [44] phi from strlen to strlen::@1 [phi:strlen->strlen::@1]
__b1_from_strlen:
// [44] phi strlen::len#2 = 0 [phi:strlen->strlen::@1#0] -- vwuz1=vwuc1
lda #<0
sta.z len
lda #>0
sta.z len+1
// [44] phi strlen::str#2 = main::filename [phi:strlen->strlen::@1#1] -- pbuz1=pbuc1
lda #<main.filename
sta.z str
lda #>main.filename
sta.z str+1
jmp __b1
// strlen::@1
__b1:
// [45] if(0!=*strlen::str#2) goto strlen::@2 -- 0_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
jmp __breturn
// strlen::@return
__breturn:
// [46] return
rts
// strlen::@2
__b2:
// [47] strlen::len#1 = ++ strlen::len#2 -- vwuz1=_inc_vwuz1
inc.z len
bne !+
inc.z len+1
!:
// [48] strlen::str#0 = ++ strlen::str#2 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
// [44] phi from strlen::@2 to strlen::@1 [phi:strlen::@2->strlen::@1]
__b1_from___b2:
// [44] phi strlen::len#2 = strlen::len#1 [phi:strlen::@2->strlen::@1#0] -- register_copy
// [44] phi strlen::str#2 = strlen::str#0 [phi:strlen::@2->strlen::@1#1] -- register_copy
jmp __b1
}
// File Data
.segment Sprite
SPRITE:
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
.for (var y=0; y<21; y++)
.for (var x=0;x<3; x++)
.byte pic.getSinglecolorByte(x,y)
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b4
Removing instruction jmp __b2
Removing instruction jmp __b1
Removing instruction jmp toSpritePtr1
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing instruction ldx errCode with TAX
Replacing instruction ldx deviceNum with TAX
Replacing instruction ldy loadAddress+1 with TAY
Removing instruction lda status
Removing instruction lda #>0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction toSpritePtr1_from___b1:
Removing instruction toSpritePtr1:
Removing instruction __b1_from_loadFileToMemory:
Removing instruction __b2_from___b1:
Removing instruction __breturn:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction loadFileToMemory_from_main:
Removing instruction __b4:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __breturn:
Removing instruction setnam_from_loadFileToMemory:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __breturn:
Removing instruction strlen_from_setnam:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __b1_from_strlen:
Removing instruction __breturn:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
const nomodify byte GREEN = 5
const nomodify byte* LOAD_SPRITE = (byte*) 12288
const nomodify word OFFSET_SPRITE_PTRS = $3f8
const byte OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR = $20
const byte OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
const nomodify byte* SCREEN = (byte*) 1024
const byte* SPRITE[] = kickasm {{ .var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
.for (var y=0; y<21; y++)
.for (var x=0;x<3; x++)
.byte pic.getSinglecolorByte(x,y)
}}
const nomodify byte* SPRITES_COLOR = (byte*) 53287
const nomodify byte* SPRITES_PTR = SCREEN+OFFSET_SPRITE_PTRS
const nomodify byte* SPRITES_XPOS = (byte*) 53248
const nomodify byte* SPRITES_YPOS = (byte*) 53249
const nomodify struct MOS6569_VICII* VICII = (struct MOS6569_VICII*) 53248
void error(byte error::err)
byte error::err
byte error::err#0 reg byte a 13.0
const nomodify byte* error::errCode = (byte*) 255
byte load(byte* load::address , bool load::verify)
byte* load::address
const byte** load::loadAddress = (byte**) 254
const byte* load::loadOrVerify = (byte*) 253
byte load::return
byte load::return#0 reg byte a 22.0
byte load::return#1 reg byte a 37.33333333333333
const byte* load::status = (byte*) 253
bool load::verify
byte loadFileToMemory(byte loadFileToMemory::device , byte* loadFileToMemory::filename , byte* loadFileToMemory::address)
byte* loadFileToMemory::address
byte loadFileToMemory::device
const byte loadFileToMemory::device#0 device = 8
byte* loadFileToMemory::filename
byte loadFileToMemory::return
byte loadFileToMemory::return#0 reg byte a 4.0
byte loadFileToMemory::return#1 reg byte a 4.333333333333333
void main()
const byte* main::filename[7] = "SPRITE"
byte main::status
byte main::status#0 reg byte x 2.0
byte main::toSpritePtr1_return
const byte main::toSpritePtr1_return#0 toSpritePtr1_return = (byte)(word)LOAD_SPRITE/$40
byte* main::toSpritePtr1_sprite
void setlfs(byte setlfs::device)
byte setlfs::device
const nomodify byte* setlfs::deviceNum = (byte*) 255
void setnam(byte* setnam::filename)
word~ setnam::$0 zp[2]:4 101.0
byte* setnam::filename
const nomodify byte* setnam::filename_len = (byte*) 253
const nomodify byte** setnam::filename_ptr = (byte**) 254
word strlen(byte* strlen::str)
word strlen::len
word strlen::len#1 len zp[2]:4 10001.0
word strlen::len#2 len zp[2]:4 5025.75
word strlen::return
word strlen::return#2 return zp[2]:4 202.0
byte* strlen::str
byte* strlen::str#0 str zp[2]:2 20002.0
byte* strlen::str#2 str zp[2]:2 10001.0
zp[2]:2 [ strlen::str#2 strlen::str#0 ]
zp[2]:4 [ strlen::len#2 strlen::len#1 strlen::return#2 setnam::$0 ]
reg byte a [ loadFileToMemory::return#0 ]
reg byte x [ main::status#0 ]
reg byte a [ error::err#0 ]
reg byte a [ load::return#0 ]
reg byte a [ loadFileToMemory::return#1 ]
reg byte a [ load::return#1 ]
FINAL ASSEMBLER
Score: 811
// File Comments
// Load a file to memory using the C64 KERNAL LOAD functions
// The kernalload.ld link file creates a D64 disk image containing the executable and the sprite.
// To execute the program succesfully you must mount the D64 disk image and execute the kernalload.PRG program
// Upstart
// Create a D64 disk containing the program and a sprite file
.disk [filename="kernalload.d64", name="DISK", id=1] {
[name="KERNALLOAD", type="prg", segments="Program"],
[name="SPRITE", type="prg", segments="Sprite"]
}
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$0810]
.segmentdef Data [startAfter="Code"]
.segmentdef Sprite
.segment Basic
:BasicUpstart(main)
.segment Code
// Global Constants & labels
// The offset of the sprite pointers from the screen start address
.const OFFSET_SPRITE_PTRS = $3f8
.const GREEN = 5
.const OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE = $15
.const OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR = $20
.label SPRITES_XPOS = $d000
.label SPRITES_YPOS = $d001
.label SPRITES_COLOR = $d027
// The VIC-II MOS 6567/6569
.label VICII = $d000
// Address to load to
.label LOAD_SPRITE = $3000
.label SCREEN = $400
.label SPRITES_PTR = SCREEN+OFFSET_SPRITE_PTRS
.segment Code
// main
main: {
.const toSpritePtr1_return = LOAD_SPRITE/$40
// loadFileToMemory(8, "SPRITE", LOAD_SPRITE)
// [1] call loadFileToMemory
// [15] phi from main to loadFileToMemory [phi:main->loadFileToMemory]
jsr loadFileToMemory
// loadFileToMemory(8, "SPRITE", LOAD_SPRITE)
// [2] loadFileToMemory::return#0 = loadFileToMemory::return#1
// main::@4
// status = loadFileToMemory(8, "SPRITE", LOAD_SPRITE)
// [3] main::status#0 = loadFileToMemory::return#0 -- vbuxx=vbuaa
tax
// if(status!=0xff)
// [4] if(main::status#0==$ff) goto main::@1 -- vbuxx_eq_vbuc1_then_la1
cpx #$ff
beq __b1
// main::@2
// VICII->BORDER_COLOR = 0x02
// [5] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR) = 2 -- _deref_pbuc1=vbuc2
lda #2
sta VICII+OFFSET_STRUCT_MOS6569_VICII_BORDER_COLOR
// error(status)
// [6] error::err#0 = main::status#0 -- vbuaa=vbuxx
txa
// [7] call error
jsr error
// main::@1
__b1:
// VICII->SPRITES_ENABLE = %00000001
// [8] *((byte*)VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE) = 1 -- _deref_pbuc1=vbuc2
// Show the loaded sprite on screen
lda #1
sta VICII+OFFSET_STRUCT_MOS6569_VICII_SPRITES_ENABLE
// [9] phi from main::@1 to main::toSpritePtr1 [phi:main::@1->main::toSpritePtr1]
// main::toSpritePtr1
// main::@3
// SPRITES_PTR[0] = toSpritePtr(LOAD_SPRITE)
// [10] *SPRITES_PTR = main::toSpritePtr1_return#0 -- _deref_pbuc1=vbuc2
lda #toSpritePtr1_return
sta SPRITES_PTR
// SPRITES_COLOR[0] = GREEN
// [11] *SPRITES_COLOR = GREEN -- _deref_pbuc1=vbuc2
lda #GREEN
sta SPRITES_COLOR
// SPRITES_XPOS[0] = 0x15
// [12] *SPRITES_XPOS = $15 -- _deref_pbuc1=vbuc2
lda #$15
sta SPRITES_XPOS
// SPRITES_YPOS[0] = 0x33
// [13] *SPRITES_YPOS = $33 -- _deref_pbuc1=vbuc2
lda #$33
sta SPRITES_YPOS
// main::@return
// }
// [14] return
rts
.segment Data
filename: .text "SPRITE"
.byte 0
}
.segment Code
// loadFileToMemory
// Load a file to memory
// Returns a status:
// - 0xff: Success
// - other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf)
loadFileToMemory: {
.label device = 8
// setnam(filename)
// [16] call setnam
// [27] phi from loadFileToMemory to setnam [phi:loadFileToMemory->setnam]
jsr setnam
// [17] phi from loadFileToMemory to loadFileToMemory::@1 [phi:loadFileToMemory->loadFileToMemory::@1]
// loadFileToMemory::@1
// setlfs(device)
// [18] call setlfs
jsr setlfs
// [19] phi from loadFileToMemory::@1 to loadFileToMemory::@2 [phi:loadFileToMemory::@1->loadFileToMemory::@2]
// loadFileToMemory::@2
// load(address, false)
// [20] call load
jsr load
// [21] load::return#0 = load::return#1
// loadFileToMemory::@3
// [22] loadFileToMemory::return#1 = load::return#0
// loadFileToMemory::@return
// }
// [23] return
rts
}
// error
// Basic ERROR function
// ERROR. Show error.
// error(byte register(A) err)
error: {
.label errCode = $ff
// *errCode = err
// [24] *error::errCode = error::err#0 -- _deref_pbuc1=vbuaa
sta errCode
// asm
// asm { ldxerrCode jsr$a437 }
tax
jsr $a437
// error::@return
// }
// [26] return
rts
}
// setnam
// Kernal SETNAM function
// SETNAM. Set file name parameters.
setnam: {
.label filename_len = $fd
.label filename_ptr = $fe
.label __0 = 4
// strlen(filename)
// [28] call strlen
// [43] phi from setnam to strlen [phi:setnam->strlen]
jsr strlen
// strlen(filename)
// [29] strlen::return#2 = strlen::len#2
// setnam::@1
// [30] setnam::$0 = strlen::return#2
// *filename_len = (char)strlen(filename)
// [31] *setnam::filename_len = (byte)setnam::$0 -- _deref_pbuc1=_byte_vwuz1
lda.z __0
sta filename_len
// *filename_ptr = filename
// [32] *setnam::filename_ptr = main::filename -- _deref_qbuc1=pbuc2
lda #<main.filename
sta filename_ptr
lda #>main.filename
sta filename_ptr+1
// asm
// asm { ldafilename_len ldxfilename_ptr ldyfilename_ptr+1 jsr$ffbd }
lda filename_len
ldx filename_ptr
ldy filename_ptr+1
jsr $ffbd
// setnam::@return
// }
// [34] return
rts
}
// setlfs
// SETLFS. Set file parameters.
setlfs: {
.label deviceNum = $ff
// *deviceNum = device
// [35] *setlfs::deviceNum = loadFileToMemory::device#0 -- _deref_pbuc1=vbuc2
lda #loadFileToMemory.device
sta deviceNum
// asm
// asm { ldxdeviceNum lda#1 ldy#0 jsr$ffba }
tax
lda #1
ldy #0
jsr $ffba
// setlfs::@return
// }
// [37] return
rts
}
// load
//LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
// Returns a status, 0xff: Success other: Kernal Error Code
load: {
.label loadOrVerify = $fd
.label loadAddress = $fe
.label status = $fd
// *loadOrVerify = (char)verify
// [38] *load::loadOrVerify = 0 -- _deref_pbuc1=vbuc2
lda #0
sta loadOrVerify
// *loadAddress = address
// [39] *load::loadAddress = LOAD_SPRITE -- _deref_qbuc1=pbuc2
lda #<LOAD_SPRITE
sta loadAddress
lda #>LOAD_SPRITE
sta loadAddress+1
// asm
// asm { ldxloadAddress ldyloadAddress+1 ldaloadOrVerify jsr$ffd5 bcserror lda#$ff error: stastatus }
ldx loadAddress
tay
lda loadOrVerify
jsr $ffd5
bcs error
lda #$ff
error:
sta status
// return *status;
// [41] load::return#1 = *load::status -- vbuaa=_deref_pbuc1
// load::@return
// }
// [42] return
rts
}
// strlen
// Computes the length of the string str up to but not including the terminating null character.
// strlen(byte* zp(2) str)
strlen: {
.label len = 4
.label str = 2
.label return = 4
// [44] phi from strlen to strlen::@1 [phi:strlen->strlen::@1]
// [44] phi strlen::len#2 = 0 [phi:strlen->strlen::@1#0] -- vwuz1=vwuc1
lda #<0
sta.z len
sta.z len+1
// [44] phi strlen::str#2 = main::filename [phi:strlen->strlen::@1#1] -- pbuz1=pbuc1
lda #<main.filename
sta.z str
lda #>main.filename
sta.z str+1
// strlen::@1
__b1:
// while(*str)
// [45] if(0!=*strlen::str#2) goto strlen::@2 -- 0_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
// strlen::@return
// }
// [46] return
rts
// strlen::@2
__b2:
// len++;
// [47] strlen::len#1 = ++ strlen::len#2 -- vwuz1=_inc_vwuz1
inc.z len
bne !+
inc.z len+1
!:
// str++;
// [48] strlen::str#0 = ++ strlen::str#2 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
// [44] phi from strlen::@2 to strlen::@1 [phi:strlen::@2->strlen::@1]
// [44] phi strlen::len#2 = strlen::len#1 [phi:strlen::@2->strlen::@1#0] -- register_copy
// [44] phi strlen::str#2 = strlen::str#0 [phi:strlen::@2->strlen::@1#1] -- register_copy
jmp __b1
}
// File Data
.segment Sprite
SPRITE:
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
.for (var y=0; y<21; y++)
.for (var x=0;x<3; x++)
.byte pic.getSinglecolorByte(x,y)