Fixing pointer addition (word*~) bsearch16u::$7 ← (word*) bsearch16u::items + (byte~) bsearch16u::$6 Fixing pointer addition (word*~) bsearch16u::$15 ← (word*) bsearch16u::pivot + (number) 1 Fixing pointer addition (word*~) bsearch16u::$1 ← (word*) bsearch16u::items - (number) 1 Fixing pointer array-indexing *((word*) utoa::digit_values + (byte) utoa::digit) Fixing pointer array-indexing *((dword*) ultoa::digit_values + (byte) ultoa::digit) Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src) Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_lines::str) Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch Warning! Adding boolean cast to non-boolean condition *((byte*) print_str::str) Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::str) Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch Identified constant variable (byte*) HEAP_TOP 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) clock::@1 Culled Empty Block (label) @5 Culled Empty Block (label) @6 Culled Empty Block (label) @7 Culled Empty Block (label) @8 Culled Empty Block (label) @9 Culled Empty Block (label) @10 Culled Empty Block (label) @11 Culled Empty Block (label) @12 Culled Empty Block (label) @13 Culled Empty Block (label) @14 Culled Empty Block (label) @15 Culled Empty Block (label) @16 Culled Empty Block (label) @17 Culled Empty Block (label) @18 Culled Empty Block (label) @19 Culled Empty Block (label) @20 Culled Empty Block (label) @21 Culled Empty Block (label) @22 Culled Empty Block (label) @23 Culled Empty Block (label) @24 Culled Empty Block (label) @25 Culled Empty Block (label) @26 Culled Empty Block (label) @27 Culled Empty Block (label) @28 Culled Empty Block (label) @29 Culled Empty Block (label) @30 Culled Empty Block (label) @31 Culled Empty Block (label) @32 Culled Empty Block (label) @33 Culled Empty Block (label) @34 Culled Empty Block (label) @35 Culled Empty Block (label) @36 Culled Empty Block (label) @37 Culled Empty Block (label) @38 Culled Empty Block (label) @39 Culled Empty Block (label) @40 Culled Empty Block (label) @41 Culled Empty Block (label) @42 Culled Empty Block (label) main::@4 Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@5 Culled Empty Block (label) main::@6 CONTROL FLOW GRAPH SSA @begin: scope:[] from to:@43 (dword()) clock() clock: scope:[clock] from main::@2 (number~) clock::$0 ← (number) $ffffffff - *((const dword*) CIA2_TIMER_AB) (dword) clock::return#0 ← (number~) clock::$0 to:clock::@return clock::@return: scope:[clock] from clock (dword) clock::return#3 ← phi( clock/(dword) clock::return#0 ) (dword) clock::return#1 ← (dword) clock::return#3 return to:@return (void()) clock_start() clock_start: scope:[clock_start] from main *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A *((const dword*) CIA2_TIMER_AB) ← (number) $ffffffff *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES to:clock_start::@return clock_start::@return: scope:[clock_start] from clock_start return to:@return (void()) print_word_at((word) print_word_at::w , (byte*) print_word_at::at) print_word_at: scope:[print_word_at] from print_dword_at print_dword_at::@1 (byte*) print_word_at::at#2 ← phi( print_dword_at/(byte*) print_word_at::at#0 print_dword_at::@1/(byte*) print_word_at::at#1 ) (word) print_word_at::w#2 ← phi( print_dword_at/(word) print_word_at::w#0 print_dword_at::@1/(word) print_word_at::w#1 ) (byte~) print_word_at::$0 ← > (word) print_word_at::w#2 (byte) print_byte_at::b#0 ← (byte~) print_word_at::$0 (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 call print_byte_at to:print_word_at::@1 print_word_at::@1: scope:[print_word_at] from print_word_at (byte*) print_word_at::at#3 ← phi( print_word_at/(byte*) print_word_at::at#2 ) (word) print_word_at::w#3 ← phi( print_word_at/(word) print_word_at::w#2 ) (byte~) print_word_at::$2 ← < (word) print_word_at::w#3 (byte*~) print_word_at::$3 ← (byte*) print_word_at::at#3 + (number) 2 (byte) print_byte_at::b#1 ← (byte~) print_word_at::$2 (byte*) print_byte_at::at#1 ← (byte*~) print_word_at::$3 call print_byte_at to:print_word_at::@2 print_word_at::@2: scope:[print_word_at] from print_word_at::@1 to:print_word_at::@return print_word_at::@return: scope:[print_word_at] from print_word_at::@2 return to:@return (void()) print_dword_at((dword) print_dword_at::dw , (byte*) print_dword_at::at) print_dword_at: scope:[print_dword_at] from main::@8 (byte*) print_dword_at::at#1 ← phi( main::@8/(byte*) print_dword_at::at#0 ) (dword) print_dword_at::dw#1 ← phi( main::@8/(dword) print_dword_at::dw#0 ) (word~) print_dword_at::$0 ← > (dword) print_dword_at::dw#1 (word) print_word_at::w#0 ← (word~) print_dword_at::$0 (byte*) print_word_at::at#0 ← (byte*) print_dword_at::at#1 call print_word_at to:print_dword_at::@1 print_dword_at::@1: scope:[print_dword_at] from print_dword_at (byte*) print_dword_at::at#2 ← phi( print_dword_at/(byte*) print_dword_at::at#1 ) (dword) print_dword_at::dw#2 ← phi( print_dword_at/(dword) print_dword_at::dw#1 ) (word~) print_dword_at::$2 ← < (dword) print_dword_at::dw#2 (byte*~) print_dword_at::$3 ← (byte*) print_dword_at::at#2 + (number) 4 (word) print_word_at::w#1 ← (word~) print_dword_at::$2 (byte*) print_word_at::at#1 ← (byte*~) print_dword_at::$3 call print_word_at to:print_dword_at::@2 print_dword_at::@2: scope:[print_dword_at] from print_dword_at::@1 to:print_dword_at::@return print_dword_at::@return: scope:[print_dword_at] from print_dword_at::@2 return to:@return (void()) print_byte_at((byte) print_byte_at::b , (byte*) print_byte_at::at) print_byte_at: scope:[print_byte_at] from print_word_at print_word_at::@1 (byte*) print_byte_at::at#2 ← phi( print_word_at/(byte*) print_byte_at::at#0 print_word_at::@1/(byte*) print_byte_at::at#1 ) (byte) print_byte_at::b#2 ← phi( print_word_at/(byte) print_byte_at::b#0 print_word_at::@1/(byte) print_byte_at::b#1 ) (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (number) 4 (byte) print_char_at::ch#0 ← *((const byte*) print_hextab + (byte~) print_byte_at::$0) (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 call print_char_at to:print_byte_at::@1 print_byte_at::@1: scope:[print_byte_at] from print_byte_at (byte*) print_byte_at::at#3 ← phi( print_byte_at/(byte*) print_byte_at::at#2 ) (byte) print_byte_at::b#3 ← phi( print_byte_at/(byte) print_byte_at::b#2 ) (number~) print_byte_at::$2 ← (byte) print_byte_at::b#3 & (number) $f (byte*~) print_byte_at::$3 ← (byte*) print_byte_at::at#3 + (number) 1 (byte) print_char_at::ch#1 ← *((const byte*) print_hextab + (number~) print_byte_at::$2) (byte*) print_char_at::at#1 ← (byte*~) print_byte_at::$3 call print_char_at to:print_byte_at::@2 print_byte_at::@2: scope:[print_byte_at] from print_byte_at::@1 to:print_byte_at::@return print_byte_at::@return: scope:[print_byte_at] from print_byte_at::@2 return to:@return (void()) print_char_at((byte) print_char_at::ch , (byte*) print_char_at::at) print_char_at: scope:[print_char_at] from print_byte_at print_byte_at::@1 (byte*) print_char_at::at#2 ← phi( print_byte_at/(byte*) print_char_at::at#0 print_byte_at::@1/(byte*) print_char_at::at#1 ) (byte) print_char_at::ch#2 ← phi( print_byte_at/(byte) print_char_at::ch#0 print_byte_at::@1/(byte) print_char_at::ch#1 ) *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 to:print_char_at::@return print_char_at::@return: scope:[print_char_at] from print_char_at return to:@return (void()) main() main: scope:[main] from @43 call clock_start to:main::@7 main::@7: scope:[main] from main to:main::@1 main::@1: scope:[main] from main::@7 main::@9 if(true) goto main::@2 to:main::@return main::@2: scope:[main] from main::@1 call clock (dword) clock::return#2 ← (dword) clock::return#1 to:main::@8 main::@8: scope:[main] from main::@2 (dword) clock::return#4 ← phi( main::@2/(dword) clock::return#2 ) (dword~) main::$1 ← (dword) clock::return#4 (dword) print_dword_at::dw#0 ← (dword~) main::$1 (byte*) print_dword_at::at#0 ← (const byte*) SCREEN call print_dword_at to:main::@9 main::@9: scope:[main] from main::@8 to:main::@1 main::@return: scope:[main] from main::@1 return to:@return @43: scope:[] from @begin call main to:@44 @44: scope:[] from @43 to:@end @end: scope:[] from @44 SYMBOL TABLE SSA (label) @43 (label) @44 (label) @begin (label) @end (const dword*) CIA2_TIMER_AB = (dword*)(number) $dd04 (const byte*) CIA2_TIMER_A_CONTROL = (byte*)(number) $dd0e (const byte*) CIA2_TIMER_B_CONTROL = (byte*)(number) $dd0f (const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES = (number) 0 (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = (number) $40 (const byte) CIA_TIMER_CONTROL_CONTINUOUS = (number) 0 (const byte) CIA_TIMER_CONTROL_START = (number) 1 (const byte) CIA_TIMER_CONTROL_STOP = (number) 0 (const byte) RADIX::BINARY = (number) 2 (const byte) RADIX::DECIMAL = (number) $a (const byte) RADIX::HEXADECIMAL = (number) $10 (const byte) RADIX::OCTAL = (number) 8 (const byte*) SCREEN = (byte*)(number) $400 (dword()) clock() (number~) clock::$0 (label) clock::@return (dword) clock::return (dword) clock::return#0 (dword) clock::return#1 (dword) clock::return#2 (dword) clock::return#3 (dword) clock::return#4 (void()) clock_start() (label) clock_start::@return (void()) main() (dword~) main::$1 (label) main::@1 (label) main::@2 (label) main::@7 (label) main::@8 (label) main::@9 (label) main::@return (void()) print_byte_at((byte) print_byte_at::b , (byte*) print_byte_at::at) (byte~) print_byte_at::$0 (number~) print_byte_at::$2 (byte*~) print_byte_at::$3 (label) print_byte_at::@1 (label) print_byte_at::@2 (label) print_byte_at::@return (byte*) print_byte_at::at (byte*) print_byte_at::at#0 (byte*) print_byte_at::at#1 (byte*) print_byte_at::at#2 (byte*) print_byte_at::at#3 (byte) print_byte_at::b (byte) print_byte_at::b#0 (byte) print_byte_at::b#1 (byte) print_byte_at::b#2 (byte) print_byte_at::b#3 (void()) print_char_at((byte) print_char_at::ch , (byte*) print_char_at::at) (label) print_char_at::@return (byte*) print_char_at::at (byte*) print_char_at::at#0 (byte*) print_char_at::at#1 (byte*) print_char_at::at#2 (byte) print_char_at::ch (byte) print_char_at::ch#0 (byte) print_char_at::ch#1 (byte) print_char_at::ch#2 (void()) print_dword_at((dword) print_dword_at::dw , (byte*) print_dword_at::at) (word~) print_dword_at::$0 (word~) print_dword_at::$2 (byte*~) print_dword_at::$3 (label) print_dword_at::@1 (label) print_dword_at::@2 (label) print_dword_at::@return (byte*) print_dword_at::at (byte*) print_dword_at::at#0 (byte*) print_dword_at::at#1 (byte*) print_dword_at::at#2 (dword) print_dword_at::dw (dword) print_dword_at::dw#0 (dword) print_dword_at::dw#1 (dword) print_dword_at::dw#2 (const byte*) print_hextab = (string) "0123456789abcdef"z (void()) print_word_at((word) print_word_at::w , (byte*) print_word_at::at) (byte~) print_word_at::$0 (byte~) print_word_at::$2 (byte*~) print_word_at::$3 (label) print_word_at::@1 (label) print_word_at::@2 (label) print_word_at::@return (byte*) print_word_at::at (byte*) print_word_at::at#0 (byte*) print_word_at::at#1 (byte*) print_word_at::at#2 (byte*) print_word_at::at#3 (word) print_word_at::w (word) print_word_at::w#0 (word) print_word_at::w#1 (word) print_word_at::w#2 (word) print_word_at::w#3 Adding number conversion cast (unumber) $ffffffff in (number~) clock::$0 ← (number) $ffffffff - *((const dword*) CIA2_TIMER_AB) Adding number conversion cast (unumber) clock::$0 in (number~) clock::$0 ← (unumber)(number) $ffffffff - *((const dword*) CIA2_TIMER_AB) Adding number conversion cast (unumber) $ffffffff in *((const dword*) CIA2_TIMER_AB) ← (number) $ffffffff Adding number conversion cast (unumber) 2 in (byte*~) print_word_at::$3 ← (byte*) print_word_at::at#3 + (number) 2 Adding number conversion cast (unumber) 4 in (byte*~) print_dword_at::$3 ← (byte*) print_dword_at::at#2 + (number) 4 Adding number conversion cast (unumber) 4 in (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (number) 4 Adding number conversion cast (unumber) $f in (number~) print_byte_at::$2 ← (byte) print_byte_at::b#3 & (number) $f Adding number conversion cast (unumber) print_byte_at::$2 in (number~) print_byte_at::$2 ← (byte) print_byte_at::b#3 & (unumber)(number) $f Adding number conversion cast (unumber) 1 in (byte*~) print_byte_at::$3 ← (byte*) print_byte_at::at#3 + (number) 1 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast *((const dword*) CIA2_TIMER_AB) ← (unumber)(number) $ffffffff Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (dword*) 56580 Simplifying constant pointer cast (byte*) 56590 Simplifying constant pointer cast (byte*) 56591 Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast $ffffffff Simplifying constant integer cast $ffffffff Simplifying constant integer cast 2 Simplifying constant integer cast 4 Simplifying constant integer cast 4 Simplifying constant integer cast $f Simplifying constant integer cast 1 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (dword) $ffffffff Finalized unsigned number type (dword) $ffffffff Finalized unsigned number type (byte) 2 Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) $f Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to dword in (unumber~) clock::$0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) Inferred type updated to byte in (unumber~) print_byte_at::$2 ← (byte) print_byte_at::b#3 & (byte) $f Alias (dword) clock::return#0 = (dword~) clock::$0 (dword) clock::return#3 (dword) clock::return#1 Alias (byte) print_byte_at::b#0 = (byte~) print_word_at::$0 Alias (word) print_word_at::w#2 = (word) print_word_at::w#3 Alias (byte*) print_word_at::at#2 = (byte*) print_word_at::at#3 Alias (byte) print_byte_at::b#1 = (byte~) print_word_at::$2 Alias (byte*) print_byte_at::at#1 = (byte*~) print_word_at::$3 Alias (word) print_word_at::w#0 = (word~) print_dword_at::$0 Alias (dword) print_dword_at::dw#1 = (dword) print_dword_at::dw#2 Alias (byte*) print_dword_at::at#1 = (byte*) print_dword_at::at#2 Alias (word) print_word_at::w#1 = (word~) print_dword_at::$2 Alias (byte*) print_word_at::at#1 = (byte*~) print_dword_at::$3 Alias (byte) print_byte_at::b#2 = (byte) print_byte_at::b#3 Alias (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#3 Alias (byte*) print_char_at::at#1 = (byte*~) print_byte_at::$3 Alias (dword) clock::return#2 = (dword) clock::return#4 Alias (dword) print_dword_at::dw#0 = (dword~) main::$1 Successful SSA optimization Pass2AliasElimination Identical Phi Values (dword) print_dword_at::dw#1 (dword) print_dword_at::dw#0 Identical Phi Values (byte*) print_dword_at::at#1 (byte*) print_dword_at::at#0 Successful SSA optimization Pass2IdenticalPhiElimination Constant (const byte*) print_dword_at::at#0 = SCREEN Successful SSA optimization Pass2ConstantIdentification Constant (const byte*) print_word_at::at#0 = print_dword_at::at#0 Successful SSA optimization Pass2ConstantIdentification if() condition always true - replacing block destination [51] if(true) goto main::@2 Successful SSA optimization Pass2ConstantIfs Simplifying constant evaluating to zero (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES in [5] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES Simplifying constant evaluating to zero (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS in [6] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_STOP|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A Successful SSA optimization PassNSimplifyConstantZero Simplifying expression containing zero CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A in [6] *((const byte*) CIA2_TIMER_B_CONTROL) ← (byte) 0|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A Simplifying expression containing zero CIA_TIMER_CONTROL_START in [8] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A Simplifying expression containing zero CIA_TIMER_CONTROL_START|CIA_TIMER_CONTROL_CONTINUOUS in [9] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_CONTINUOUS|(const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES Successful SSA optimization PassNSimplifyExpressionWithZero Simplifying expression containing zero CIA_TIMER_CONTROL_START in [9] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_CONTINUOUS Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant (const byte) CIA_TIMER_CONTROL_STOP Eliminating unused constant (const byte) CIA_TIMER_CONTROL_CONTINUOUS Eliminating unused constant (const byte) CIA_TIMER_CONTROL_A_COUNT_CYCLES Successful SSA optimization PassNEliminateUnusedVars Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks Constant right-side identified [19] (byte*) print_word_at::at#1 ← (const byte*) print_dword_at::at#0 + (byte) 4 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte*) print_word_at::at#1 = print_dword_at::at#0+4 Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings (const byte*) print_word_at::at#0 Inlining constant with var siblings (const byte*) print_word_at::at#1 Constant inlined print_dword_at::at#0 = (const byte*) SCREEN Constant inlined print_word_at::at#1 = (const byte*) SCREEN+(byte) 4 Constant inlined print_word_at::at#0 = (const byte*) SCREEN Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin Adding NOP phi() at start of @43 Adding NOP phi() at start of @44 Adding NOP phi() at start of @end Adding NOP phi() at start of main Adding NOP phi() at start of main::@7 Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main::@2 Adding NOP phi() at start of main::@9 Adding NOP phi() at start of print_dword_at::@2 Adding NOP phi() at start of print_word_at::@2 Adding NOP phi() at start of print_byte_at::@2 CALL GRAPH Calls in [] to main:2 Calls in [main] to clock_start:6 clock:10 print_dword_at:13 Calls in [print_dword_at] to print_word_at:17 print_word_at:20 Calls in [print_word_at] to print_byte_at:28 print_byte_at:33 Calls in [print_byte_at] to print_char_at:42 print_char_at:48 Created 6 initial phi equivalence classes Coalesced [16] print_word_at::w#4 ← print_word_at::w#0 Coalesced [19] print_word_at::w#5 ← print_word_at::w#1 Coalesced [26] print_byte_at::b#4 ← print_byte_at::b#0 Coalesced [27] print_byte_at::at#4 ← print_byte_at::at#0 Coalesced [31] print_byte_at::b#5 ← print_byte_at::b#1 Coalesced [32] print_byte_at::at#5 ← print_byte_at::at#1 Coalesced [40] print_char_at::ch#3 ← print_char_at::ch#0 Coalesced [41] print_char_at::at#3 ← print_char_at::at#0 Coalesced [46] print_char_at::ch#4 ← print_char_at::ch#1 Coalesced [47] print_char_at::at#4 ← print_char_at::at#1 Coalesced down to 6 phi equivalence classes Culled Empty Block (label) @44 Culled Empty Block (label) main::@7 Culled Empty Block (label) main::@1 Culled Empty Block (label) main::@9 Culled Empty Block (label) print_dword_at::@2 Culled Empty Block (label) print_word_at::@2 Culled Empty Block (label) print_byte_at::@2 Renumbering block @43 to @1 Renumbering block main::@2 to main::@1 Renumbering block main::@8 to main::@2 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 main Adding NOP phi() at start of main::@1 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() (void()) main() main: scope:[main] from @1 [4] phi() [5] call clock_start to:main::@1 main::@1: scope:[main] from main main::@2 [6] phi() [7] call clock [8] (dword) clock::return#2 ← (dword) clock::return#0 to:main::@2 main::@2: scope:[main] from main::@1 [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 [10] call print_dword_at to:main::@1 (void()) print_dword_at((dword) print_dword_at::dw , (byte*) print_dword_at::at) print_dword_at: scope:[print_dword_at] from main::@2 [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 [12] call print_word_at to:print_dword_at::@1 print_dword_at::@1: scope:[print_dword_at] from print_dword_at [13] (word) print_word_at::w#1 ← < (dword) print_dword_at::dw#0 [14] call print_word_at to:print_dword_at::@return print_dword_at::@return: scope:[print_dword_at] from print_dword_at::@1 [15] return to:@return (void()) print_word_at((word) print_word_at::w , (byte*) print_word_at::at) print_word_at: scope:[print_word_at] from print_dword_at print_dword_at::@1 [16] (byte*) print_word_at::at#2 ← phi( print_dword_at/(const byte*) SCREEN print_dword_at::@1/(const byte*) SCREEN+(byte) 4 ) [16] (word) print_word_at::w#2 ← phi( print_dword_at/(word) print_word_at::w#0 print_dword_at::@1/(word) print_word_at::w#1 ) [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 [19] call print_byte_at to:print_word_at::@1 print_word_at::@1: scope:[print_word_at] from print_word_at [20] (byte) print_byte_at::b#1 ← < (word) print_word_at::w#2 [21] (byte*) print_byte_at::at#1 ← (byte*) print_word_at::at#2 + (byte) 2 [22] call print_byte_at to:print_word_at::@return print_word_at::@return: scope:[print_word_at] from print_word_at::@1 [23] return to:@return (void()) print_byte_at((byte) print_byte_at::b , (byte*) print_byte_at::at) print_byte_at: scope:[print_byte_at] from print_word_at print_word_at::@1 [24] (byte*) print_byte_at::at#2 ← phi( print_word_at/(byte*) print_byte_at::at#0 print_word_at::@1/(byte*) print_byte_at::at#1 ) [24] (byte) print_byte_at::b#2 ← phi( print_word_at/(byte) print_byte_at::b#0 print_word_at::@1/(byte) print_byte_at::b#1 ) [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 [26] (byte) print_char_at::ch#0 ← *((const byte*) print_hextab + (byte~) print_byte_at::$0) [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 [28] call print_char_at to:print_byte_at::@1 print_byte_at::@1: scope:[print_byte_at] from print_byte_at [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 [31] (byte) print_char_at::ch#1 ← *((const byte*) print_hextab + (byte~) print_byte_at::$2) [32] call print_char_at to:print_byte_at::@return print_byte_at::@return: scope:[print_byte_at] from print_byte_at::@1 [33] return to:@return (void()) print_char_at((byte) print_char_at::ch , (byte*) print_char_at::at) print_char_at: scope:[print_char_at] from print_byte_at print_byte_at::@1 [34] (byte*) print_char_at::at#2 ← phi( print_byte_at/(byte*) print_char_at::at#0 print_byte_at::@1/(byte*) print_char_at::at#1 ) [34] (byte) print_char_at::ch#2 ← phi( print_byte_at/(byte) print_char_at::ch#0 print_byte_at::@1/(byte) print_char_at::ch#1 ) [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 to:print_char_at::@return print_char_at::@return: scope:[print_char_at] from print_char_at [36] return to:@return (dword()) clock() clock: scope:[clock] from main::@1 [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) to:clock::@return clock::@return: scope:[clock] from clock [38] return to:@return (void()) clock_start() clock_start: scope:[clock_start] from main [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START to:clock_start::@return clock_start::@return: scope:[clock_start] from clock_start [44] return to:@return VARIABLE REGISTER WEIGHTS (dword()) clock() (dword) clock::return (dword) clock::return#0 4.333333333333333 (dword) clock::return#2 22.0 (void()) clock_start() (void()) main() (void()) print_byte_at((byte) print_byte_at::b , (byte*) print_byte_at::at) (byte~) print_byte_at::$0 4.0 (byte~) print_byte_at::$2 2.0 (byte*) print_byte_at::at (byte*) print_byte_at::at#0 4.0 (byte*) print_byte_at::at#1 4.0 (byte*) print_byte_at::at#2 1.3333333333333333 (byte) print_byte_at::b (byte) print_byte_at::b#0 2.0 (byte) print_byte_at::b#1 2.0 (byte) print_byte_at::b#2 1.6 (void()) print_char_at((byte) print_char_at::ch , (byte*) print_char_at::at) (byte*) print_char_at::at (byte*) print_char_at::at#0 4.0 (byte*) print_char_at::at#1 2.0 (byte*) print_char_at::at#2 6.0 (byte) print_char_at::ch (byte) print_char_at::ch#0 2.0 (byte) print_char_at::ch#1 4.0 (byte) print_char_at::ch#2 6.0 (void()) print_dword_at((dword) print_dword_at::dw , (byte*) print_dword_at::at) (byte*) print_dword_at::at (dword) print_dword_at::dw (dword) print_dword_at::dw#0 5.0 (void()) print_word_at((word) print_word_at::w , (byte*) print_word_at::at) (byte*) print_word_at::at (byte*) print_word_at::at#2 0.8 (word) print_word_at::w (word) print_word_at::w#0 4.0 (word) print_word_at::w#1 4.0 (word) print_word_at::w#2 2.0 Initial phi equivalence classes [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] [ print_word_at::at#2 ] [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] Added variable clock::return#2 to zero page equivalence class [ clock::return#2 ] Added variable print_dword_at::dw#0 to zero page equivalence class [ print_dword_at::dw#0 ] Added variable print_byte_at::$0 to zero page equivalence class [ print_byte_at::$0 ] Added variable print_byte_at::$2 to zero page equivalence class [ print_byte_at::$2 ] Added variable clock::return#0 to zero page equivalence class [ clock::return#0 ] Complete equivalence classes [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] [ print_word_at::at#2 ] [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] [ clock::return#2 ] [ print_dword_at::dw#0 ] [ print_byte_at::$0 ] [ print_byte_at::$2 ] [ clock::return#0 ] Allocated zp[2]:2 [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] Allocated zp[2]:4 [ print_word_at::at#2 ] Allocated zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] Allocated zp[2]:7 [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] Allocated zp[1]:9 [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] Allocated zp[2]:10 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] Allocated zp[4]:12 [ clock::return#2 ] Allocated zp[4]:16 [ print_dword_at::dw#0 ] Allocated zp[1]:20 [ print_byte_at::$0 ] Allocated zp[1]:21 [ print_byte_at::$2 ] Allocated zp[4]:22 [ clock::return#0 ] INITIAL ASM Target platform is c64basic / MOS6502X // File Comments // Setup and run a simple CIA-timer // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 // CIA #2 Timer A Control Register .label CIA2_TIMER_A_CONTROL = $dd0e // CIA #2 Timer B Control Register .label CIA2_TIMER_B_CONTROL = $dd0f // Timer Control - Start/stop timer (0:stop, 1: start) .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 .label SCREEN = $400 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 // @1 __b1: // [2] call main // [4] phi from @1 to main [phi:@1->main] main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: jmp __bend // @end __bend: // main main: { // [5] call clock_start jsr clock_start // [6] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1] __b1_from_main: __b1_from___b2: jmp __b1 // main::@1 __b1: // [7] call clock jsr clock // [8] (dword) clock::return#2 ← (dword) clock::return#0 -- vduz1=vduz2 lda.z clock.return sta.z clock.return_1 lda.z clock.return+1 sta.z clock.return_1+1 lda.z clock.return+2 sta.z clock.return_1+2 lda.z clock.return+3 sta.z clock.return_1+3 jmp __b2 // main::@2 __b2: // [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 -- vduz1=vduz2 lda.z clock.return_1 sta.z print_dword_at.dw lda.z clock.return_1+1 sta.z print_dword_at.dw+1 lda.z clock.return_1+2 sta.z print_dword_at.dw+2 lda.z clock.return_1+3 sta.z print_dword_at.dw+3 // [10] call print_dword_at jsr print_dword_at jmp __b1_from___b2 } // print_dword_at // Print a dword as HEX at a specific position // print_dword_at(dword zeropage($10) dw) print_dword_at: { .label dw = $10 // [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 -- vwuz1=_hi_vduz2 lda.z dw+2 sta.z print_word_at.w lda.z dw+3 sta.z print_word_at.w+1 // [12] call print_word_at // [16] phi from print_dword_at to print_word_at [phi:print_dword_at->print_word_at] print_word_at_from_print_dword_at: // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN [phi:print_dword_at->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#0 [phi:print_dword_at->print_word_at#1] -- register_copy jsr print_word_at jmp __b1 // print_dword_at::@1 __b1: // [13] (word) print_word_at::w#1 ← < (dword) print_dword_at::dw#0 -- vwuz1=_lo_vduz2 lda.z dw sta.z print_word_at.w lda.z dw+1 sta.z print_word_at.w+1 // [14] call print_word_at // [16] phi from print_dword_at::@1 to print_word_at [phi:print_dword_at::@1->print_word_at] print_word_at_from___b1: // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN+(byte) 4 [phi:print_dword_at::@1->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN+4 sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#1 [phi:print_dword_at::@1->print_word_at#1] -- register_copy jsr print_word_at jmp __breturn // print_dword_at::@return __breturn: // [15] return rts } // print_word_at // Print a word as HEX at a specific position // print_word_at(word zeropage(2) w, byte* zeropage(4) at) print_word_at: { .label w = 2 .label at = 4 // [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 -- vbuz1=_hi_vwuz2 lda.z w+1 sta.z print_byte_at.b // [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 -- pbuz1=pbuz2 lda.z at sta.z print_byte_at.at lda.z at+1 sta.z print_byte_at.at+1 // [19] call print_byte_at // [24] phi from print_word_at to print_byte_at [phi:print_word_at->print_byte_at] print_byte_at_from_print_word_at: // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#0 [phi:print_word_at->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#0 [phi:print_word_at->print_byte_at#1] -- register_copy jsr print_byte_at jmp __b1 // print_word_at::@1 __b1: // [20] (byte) print_byte_at::b#1 ← < (word) print_word_at::w#2 -- vbuz1=_lo_vwuz2 lda.z w sta.z print_byte_at.b // [21] (byte*) print_byte_at::at#1 ← (byte*) print_word_at::at#2 + (byte) 2 -- pbuz1=pbuz2_plus_2 lda.z at clc adc #2 sta.z print_byte_at.at lda.z at+1 adc #0 sta.z print_byte_at.at+1 // [22] call print_byte_at // [24] phi from print_word_at::@1 to print_byte_at [phi:print_word_at::@1->print_byte_at] print_byte_at_from___b1: // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#1 [phi:print_word_at::@1->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#1 [phi:print_word_at::@1->print_byte_at#1] -- register_copy jsr print_byte_at jmp __breturn // print_word_at::@return __breturn: // [23] return rts } // print_byte_at // Print a byte as HEX at a specific position // print_byte_at(byte zeropage(6) b, byte* zeropage(7) at) print_byte_at: { .label __0 = $14 .label __2 = $15 .label b = 6 .label at = 7 // [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 -- vbuz1=vbuz2_ror_4 lda.z b lsr lsr lsr lsr sta.z __0 // [26] (byte) print_char_at::ch#0 ← *((const byte*) print_hextab + (byte~) print_byte_at::$0) -- vbuz1=pbuc1_derefidx_vbuz2 ldy.z __0 lda print_hextab,y sta.z print_char_at.ch // [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 -- pbuz1=pbuz2 lda.z at sta.z print_char_at.at lda.z at+1 sta.z print_char_at.at+1 // [28] call print_char_at // [34] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] print_char_at_from_print_byte_at: // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#0 [phi:print_byte_at->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#0 [phi:print_byte_at->print_char_at#1] -- register_copy jsr print_char_at jmp __b1 // print_byte_at::@1 __b1: // [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f -- vbuz1=vbuz2_band_vbuc1 lda #$f and.z b sta.z __2 // [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 -- pbuz1=pbuz2_plus_1 lda.z at clc adc #1 sta.z print_char_at.at lda.z at+1 adc #0 sta.z print_char_at.at+1 // [31] (byte) print_char_at::ch#1 ← *((const byte*) print_hextab + (byte~) print_byte_at::$2) -- vbuz1=pbuc1_derefidx_vbuz2 ldy.z __2 lda print_hextab,y sta.z print_char_at.ch // [32] call print_char_at // [34] phi from print_byte_at::@1 to print_char_at [phi:print_byte_at::@1->print_char_at] print_char_at_from___b1: // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#1 [phi:print_byte_at::@1->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#1 [phi:print_byte_at::@1->print_char_at#1] -- register_copy jsr print_char_at jmp __breturn // print_byte_at::@return __breturn: // [33] return rts } // print_char_at // Print a single char // print_char_at(byte zeropage(9) ch, byte* zeropage($a) at) print_char_at: { .label ch = 9 .label at = $a // [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 -- _deref_pbuz1=vbuz2 lda.z ch ldy #0 sta (at),y jmp __breturn // print_char_at::@return __breturn: // [36] return rts } // clock // Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program). // This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start() clock: { .label return = $16 .label return_1 = $c // [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) -- vduz1=vduc1_minus__deref_pduc2 lda #<$ffffffff sec sbc CIA2_TIMER_AB sta.z return lda #>$ffffffff sbc CIA2_TIMER_AB+1 sta.z return+1 lda #<$ffffffff>>$10 sbc CIA2_TIMER_AB+2 sta.z return+2 lda #>$ffffffff>>$10 sbc CIA2_TIMER_AB+3 sta.z return+3 jmp __breturn // clock::@return __breturn: // [38] return rts } // clock_start // Reset & start the processor clock time. The value can be read using clock(). // This uses CIA #2 Timer A+B on the C64 clock_start: { // [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Setup CIA#2 timer A to count (down) CPU cycles lda #0 sta CIA2_TIMER_A_CONTROL // [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff -- _deref_pduc1=vduc2 lda #<$ffffffff sta CIA2_TIMER_AB lda #>$ffffffff sta CIA2_TIMER_AB+1 lda #<$ffffffff>>$10 sta CIA2_TIMER_AB+2 lda #>$ffffffff>>$10 sta CIA2_TIMER_AB+3 // [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START|CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START sta CIA2_TIMER_A_CONTROL jmp __breturn // clock_start::@return __breturn: // [44] return rts } // File Data print_hextab: .text "0123456789abcdef" REGISTER UPLIFT POTENTIAL REGISTERS Statement [8] (dword) clock::return#2 ← (dword) clock::return#0 [ clock::return#2 ] ( main:2 [ clock::return#2 ] ) always clobbers reg byte a Statement [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 [ print_dword_at::dw#0 ] ( main:2 [ print_dword_at::dw#0 ] ) always clobbers reg byte a Statement [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 [ print_dword_at::dw#0 print_word_at::w#0 ] ( main:2::print_dword_at:10 [ print_dword_at::dw#0 print_word_at::w#0 ] ) always clobbers reg byte a Statement [13] (word) print_word_at::w#1 ← < (dword) print_dword_at::dw#0 [ print_word_at::w#1 ] ( main:2::print_dword_at:10 [ print_word_at::w#1 ] ) always clobbers reg byte a Statement [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] ) always clobbers reg byte a Statement [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] Statement [20] (byte) print_byte_at::b#1 ← < (word) print_word_at::w#2 [ print_word_at::at#2 print_byte_at::b#1 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::at#2 print_byte_at::b#1 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::at#2 print_byte_at::b#1 ] ) always clobbers reg byte a Statement [21] (byte*) print_byte_at::at#1 ← (byte*) print_word_at::at#2 + (byte) 2 [ print_byte_at::b#1 print_byte_at::at#1 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_byte_at::b#1 print_byte_at::at#1 ] main:2::print_dword_at:10::print_word_at:14 [ print_byte_at::b#1 print_byte_at::at#1 ] ) always clobbers reg byte a Statement [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 [ print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] ) always clobbers reg byte a Statement [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 [ print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:9 [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] Statement [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f [ print_byte_at::at#2 print_byte_at::$2 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::at#2 print_byte_at::$2 ] ) always clobbers reg byte a Statement [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 [ print_byte_at::$2 print_char_at::at#1 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::$2 print_char_at::at#1 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:21 [ print_byte_at::$2 ] Statement [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 [ ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19::print_char_at:28 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19::print_char_at:28 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22::print_char_at:28 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22::print_char_at:28 [ print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:19::print_char_at:32 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19::print_char_at:32 [ print_word_at::w#2 print_word_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22::print_char_at:32 [ print_dword_at::dw#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22::print_char_at:32 [ ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] Statement [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) [ clock::return#0 ] ( main:2::clock:7 [ clock::return#0 ] ) always clobbers reg byte a Statement [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [8] (dword) clock::return#2 ← (dword) clock::return#0 [ clock::return#2 ] ( main:2 [ clock::return#2 ] ) always clobbers reg byte a Statement [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 [ print_dword_at::dw#0 ] ( main:2 [ print_dword_at::dw#0 ] ) always clobbers reg byte a Statement [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 [ print_dword_at::dw#0 print_word_at::w#0 ] ( main:2::print_dword_at:10 [ print_dword_at::dw#0 print_word_at::w#0 ] ) always clobbers reg byte a Statement [13] (word) print_word_at::w#1 ← < (dword) print_dword_at::dw#0 [ print_word_at::w#1 ] ( main:2::print_dword_at:10 [ print_word_at::w#1 ] ) always clobbers reg byte a Statement [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 ] ) always clobbers reg byte a Statement [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#0 print_byte_at::at#0 ] ) always clobbers reg byte a Statement [20] (byte) print_byte_at::b#1 ← < (word) print_word_at::w#2 [ print_word_at::at#2 print_byte_at::b#1 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_word_at::at#2 print_byte_at::b#1 ] main:2::print_dword_at:10::print_word_at:14 [ print_word_at::at#2 print_byte_at::b#1 ] ) always clobbers reg byte a Statement [21] (byte*) print_byte_at::at#1 ← (byte*) print_word_at::at#2 + (byte) 2 [ print_byte_at::b#1 print_byte_at::at#1 ] ( main:2::print_dword_at:10::print_word_at:12 [ print_dword_at::dw#0 print_byte_at::b#1 print_byte_at::at#1 ] main:2::print_dword_at:10::print_word_at:14 [ print_byte_at::b#1 print_byte_at::at#1 ] ) always clobbers reg byte a Statement [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 [ print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::b#2 print_byte_at::at#2 print_byte_at::$0 ] ) always clobbers reg byte a Statement [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 [ print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::b#2 print_byte_at::at#2 print_char_at::ch#0 print_char_at::at#0 ] ) always clobbers reg byte a Statement [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f [ print_byte_at::at#2 print_byte_at::$2 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::at#2 print_byte_at::$2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::at#2 print_byte_at::$2 ] ) always clobbers reg byte a Statement [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 [ print_byte_at::$2 print_char_at::at#1 ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22 [ print_dword_at::dw#0 print_byte_at::$2 print_char_at::at#1 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22 [ print_byte_at::$2 print_char_at::at#1 ] ) always clobbers reg byte a Statement [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 [ ] ( main:2::print_dword_at:10::print_word_at:12::print_byte_at:19::print_char_at:28 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19::print_char_at:28 [ print_word_at::w#2 print_word_at::at#2 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22::print_char_at:28 [ print_dword_at::dw#0 print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22::print_char_at:28 [ print_byte_at::b#2 print_byte_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:19::print_char_at:32 [ print_dword_at::dw#0 print_word_at::w#2 print_word_at::at#2 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:19::print_char_at:32 [ print_word_at::w#2 print_word_at::at#2 ] main:2::print_dword_at:10::print_word_at:12::print_byte_at:22::print_char_at:32 [ print_dword_at::dw#0 ] main:2::print_dword_at:10::print_word_at:14::print_byte_at:22::print_char_at:32 [ ] ) always clobbers reg byte a reg byte y Statement [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) [ clock::return#0 ] ( main:2::clock:7 [ clock::return#0 ] ) always clobbers reg byte a Statement [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Statement [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START [ ] ( main:2::clock_start:5 [ ] ) always clobbers reg byte a Potential registers zp[2]:2 [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] : zp[2]:2 , Potential registers zp[2]:4 [ print_word_at::at#2 ] : zp[2]:4 , Potential registers zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] : zp[1]:6 , reg byte x , Potential registers zp[2]:7 [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] : zp[2]:7 , Potential registers zp[1]:9 [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] : zp[1]:9 , reg byte x , reg byte y , Potential registers zp[2]:10 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] : zp[2]:10 , Potential registers zp[4]:12 [ clock::return#2 ] : zp[4]:12 , Potential registers zp[4]:16 [ print_dword_at::dw#0 ] : zp[4]:16 , Potential registers zp[1]:20 [ print_byte_at::$0 ] : zp[1]:20 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:21 [ print_byte_at::$2 ] : zp[1]:21 , reg byte x , reg byte y , Potential registers zp[4]:22 [ clock::return#0 ] : zp[4]:22 , REGISTER UPLIFT SCOPES Uplift Scope [clock] 22: zp[4]:12 [ clock::return#2 ] 4.33: zp[4]:22 [ clock::return#0 ] Uplift Scope [print_char_at] 12: zp[1]:9 [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] 12: zp[2]:10 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] Uplift Scope [print_byte_at] 9.33: zp[2]:7 [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] 5.6: zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] 4: zp[1]:20 [ print_byte_at::$0 ] 2: zp[1]:21 [ print_byte_at::$2 ] Uplift Scope [print_word_at] 10: zp[2]:2 [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] 0.8: zp[2]:4 [ print_word_at::at#2 ] Uplift Scope [print_dword_at] 5: zp[4]:16 [ print_dword_at::dw#0 ] Uplift Scope [clock_start] Uplift Scope [RADIX] Uplift Scope [main] Uplift Scope [] Uplifting [clock] best 1062 combination zp[4]:12 [ clock::return#2 ] zp[4]:22 [ clock::return#0 ] Uplifting [print_char_at] best 1055 combination reg byte x [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] zp[2]:10 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] Uplifting [print_byte_at] best 1047 combination zp[2]:7 [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] reg byte a [ print_byte_at::$0 ] reg byte y [ print_byte_at::$2 ] Uplifting [print_word_at] best 1047 combination zp[2]:2 [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] zp[2]:4 [ print_word_at::at#2 ] Uplifting [print_dword_at] best 1047 combination zp[4]:16 [ print_dword_at::dw#0 ] Uplifting [clock_start] best 1047 combination Uplifting [RADIX] best 1047 combination Uplifting [main] best 1047 combination Uplifting [] best 1047 combination Attempting to uplift remaining variables inzp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] Uplifting [print_byte_at] best 1047 combination zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] Coalescing zero page register [ zp[2]:4 [ print_word_at::at#2 ] ] with [ zp[2]:7 [ print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] ] - score: 2 Coalescing zero page register [ zp[4]:12 [ clock::return#2 ] ] with [ zp[4]:16 [ print_dword_at::dw#0 ] ] - score: 1 Coalescing zero page register [ zp[4]:12 [ clock::return#2 print_dword_at::dw#0 ] ] with [ zp[4]:22 [ clock::return#0 ] ] - score: 1 Allocated (was zp[2]:10) zp[2]:7 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] Allocated (was zp[4]:12) zp[4]:9 [ clock::return#2 print_dword_at::dw#0 clock::return#0 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments // Setup and run a simple CIA-timer // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 // CIA #2 Timer A Control Register .label CIA2_TIMER_A_CONTROL = $dd0e // CIA #2 Timer B Control Register .label CIA2_TIMER_B_CONTROL = $dd0f // Timer Control - Start/stop timer (0:stop, 1: start) .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 .label SCREEN = $400 // @begin __bbegin: // [1] phi from @begin to @1 [phi:@begin->@1] __b1_from___bbegin: jmp __b1 // @1 __b1: // [2] call main // [4] phi from @1 to main [phi:@1->main] main_from___b1: jsr main // [3] phi from @1 to @end [phi:@1->@end] __bend_from___b1: jmp __bend // @end __bend: // main main: { // [5] call clock_start jsr clock_start // [6] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1] __b1_from_main: __b1_from___b2: jmp __b1 // main::@1 __b1: // [7] call clock jsr clock // [8] (dword) clock::return#2 ← (dword) clock::return#0 jmp __b2 // main::@2 __b2: // [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 // [10] call print_dword_at jsr print_dword_at jmp __b1_from___b2 } // print_dword_at // Print a dword as HEX at a specific position // print_dword_at(dword zeropage(9) dw) print_dword_at: { .label dw = 9 // [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 -- vwuz1=_hi_vduz2 lda.z dw+2 sta.z print_word_at.w lda.z dw+3 sta.z print_word_at.w+1 // [12] call print_word_at // [16] phi from print_dword_at to print_word_at [phi:print_dword_at->print_word_at] print_word_at_from_print_dword_at: // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN [phi:print_dword_at->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#0 [phi:print_dword_at->print_word_at#1] -- register_copy jsr print_word_at jmp __b1 // print_dword_at::@1 __b1: // [13] (word) print_word_at::w#1 ← < (dword) print_dword_at::dw#0 -- vwuz1=_lo_vduz2 lda.z dw sta.z print_word_at.w lda.z dw+1 sta.z print_word_at.w+1 // [14] call print_word_at // [16] phi from print_dword_at::@1 to print_word_at [phi:print_dword_at::@1->print_word_at] print_word_at_from___b1: // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN+(byte) 4 [phi:print_dword_at::@1->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN+4 sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#1 [phi:print_dword_at::@1->print_word_at#1] -- register_copy jsr print_word_at jmp __breturn // print_dword_at::@return __breturn: // [15] return rts } // print_word_at // Print a word as HEX at a specific position // print_word_at(word zeropage(2) w, byte* zeropage(4) at) print_word_at: { .label w = 2 .label at = 4 // [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 -- vbuz1=_hi_vwuz2 lda.z w+1 sta.z print_byte_at.b // [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 // [19] call print_byte_at // [24] phi from print_word_at to print_byte_at [phi:print_word_at->print_byte_at] print_byte_at_from_print_word_at: // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#0 [phi:print_word_at->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#0 [phi:print_word_at->print_byte_at#1] -- register_copy jsr print_byte_at jmp __b1 // print_word_at::@1 __b1: // [20] (byte) print_byte_at::b#1 ← < (word) print_word_at::w#2 -- vbuz1=_lo_vwuz2 lda.z w sta.z print_byte_at.b // [21] (byte*) print_byte_at::at#1 ← (byte*) print_word_at::at#2 + (byte) 2 -- pbuz1=pbuz1_plus_2 lda.z print_byte_at.at clc adc #2 sta.z print_byte_at.at bcc !+ inc.z print_byte_at.at+1 !: // [22] call print_byte_at // [24] phi from print_word_at::@1 to print_byte_at [phi:print_word_at::@1->print_byte_at] print_byte_at_from___b1: // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#1 [phi:print_word_at::@1->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#1 [phi:print_word_at::@1->print_byte_at#1] -- register_copy jsr print_byte_at jmp __breturn // print_word_at::@return __breturn: // [23] return rts } // print_byte_at // Print a byte as HEX at a specific position // print_byte_at(byte zeropage(6) b, byte* zeropage(4) at) print_byte_at: { .label b = 6 .label at = 4 // [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 -- vbuaa=vbuz1_ror_4 lda.z b lsr lsr lsr lsr // [26] (byte) print_char_at::ch#0 ← *((const byte*) print_hextab + (byte~) print_byte_at::$0) -- vbuxx=pbuc1_derefidx_vbuaa tay ldx print_hextab,y // [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 -- pbuz1=pbuz2 lda.z at sta.z print_char_at.at lda.z at+1 sta.z print_char_at.at+1 // [28] call print_char_at // [34] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] print_char_at_from_print_byte_at: // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#0 [phi:print_byte_at->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#0 [phi:print_byte_at->print_char_at#1] -- register_copy jsr print_char_at jmp __b1 // print_byte_at::@1 __b1: // [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f -- vbuyy=vbuz1_band_vbuc1 lda #$f and.z b tay // [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 -- pbuz1=pbuz2_plus_1 lda.z at clc adc #1 sta.z print_char_at.at lda.z at+1 adc #0 sta.z print_char_at.at+1 // [31] (byte) print_char_at::ch#1 ← *((const byte*) print_hextab + (byte~) print_byte_at::$2) -- vbuxx=pbuc1_derefidx_vbuyy ldx print_hextab,y // [32] call print_char_at // [34] phi from print_byte_at::@1 to print_char_at [phi:print_byte_at::@1->print_char_at] print_char_at_from___b1: // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#1 [phi:print_byte_at::@1->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#1 [phi:print_byte_at::@1->print_char_at#1] -- register_copy jsr print_char_at jmp __breturn // print_byte_at::@return __breturn: // [33] return rts } // print_char_at // Print a single char // print_char_at(byte register(X) ch, byte* zeropage(7) at) print_char_at: { .label at = 7 // [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 -- _deref_pbuz1=vbuxx txa ldy #0 sta (at),y jmp __breturn // print_char_at::@return __breturn: // [36] return rts } // clock // Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program). // This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start() clock: { .label return = 9 // [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) -- vduz1=vduc1_minus__deref_pduc2 lda #<$ffffffff sec sbc CIA2_TIMER_AB sta.z return lda #>$ffffffff sbc CIA2_TIMER_AB+1 sta.z return+1 lda #<$ffffffff>>$10 sbc CIA2_TIMER_AB+2 sta.z return+2 lda #>$ffffffff>>$10 sbc CIA2_TIMER_AB+3 sta.z return+3 jmp __breturn // clock::@return __breturn: // [38] return rts } // clock_start // Reset & start the processor clock time. The value can be read using clock(). // This uses CIA #2 Timer A+B on the C64 clock_start: { // [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Setup CIA#2 timer A to count (down) CPU cycles lda #0 sta CIA2_TIMER_A_CONTROL // [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff -- _deref_pduc1=vduc2 lda #<$ffffffff sta CIA2_TIMER_AB lda #>$ffffffff sta CIA2_TIMER_AB+1 lda #<$ffffffff>>$10 sta CIA2_TIMER_AB+2 lda #>$ffffffff>>$10 sta CIA2_TIMER_AB+3 // [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START|CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START sta CIA2_TIMER_A_CONTROL jmp __breturn // clock_start::@return __breturn: // [44] return rts } // File Data print_hextab: .text "0123456789abcdef" ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 Removing instruction jmp __bend Removing instruction jmp __b1 Removing instruction jmp __b2 Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __breturn Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Replacing label __bbegin with __b1 Replacing label __b1_from___b2 with __b1 Removing instruction __bbegin: Removing instruction __b1_from___bbegin: Removing instruction main_from___b1: Removing instruction __bend_from___b1: Removing instruction __b1_from_main: Removing instruction __b1_from___b2: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __bend: Removing instruction __b2: Removing instruction print_word_at_from_print_dword_at: Removing instruction __b1: Removing instruction print_word_at_from___b1: Removing instruction __breturn: Removing instruction print_byte_at_from_print_word_at: Removing instruction __b1: Removing instruction print_byte_at_from___b1: Removing instruction __breturn: Removing instruction print_char_at_from_print_byte_at: Removing instruction __b1: Removing instruction print_char_at_from___b1: Removing instruction __breturn: Removing instruction __breturn: Removing instruction __breturn: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main Succesful ASM optimization Pass5SkipBegin Removing instruction __b1: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE (label) @1 (label) @begin (label) @end (const dword*) CIA2_TIMER_AB = (dword*) 56580 (const byte*) CIA2_TIMER_A_CONTROL = (byte*) 56590 (const byte*) CIA2_TIMER_B_CONTROL = (byte*) 56591 (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = (number) $40 (const byte) CIA_TIMER_CONTROL_START = (number) 1 (const byte) RADIX::BINARY = (number) 2 (const byte) RADIX::DECIMAL = (number) $a (const byte) RADIX::HEXADECIMAL = (number) $10 (const byte) RADIX::OCTAL = (number) 8 (const byte*) SCREEN = (byte*) 1024 (dword()) clock() (label) clock::@return (dword) clock::return (dword) clock::return#0 return zp[4]:9 4.333333333333333 (dword) clock::return#2 return zp[4]:9 22.0 (void()) clock_start() (label) clock_start::@return (void()) main() (label) main::@1 (label) main::@2 (void()) print_byte_at((byte) print_byte_at::b , (byte*) print_byte_at::at) (byte~) print_byte_at::$0 reg byte a 4.0 (byte~) print_byte_at::$2 reg byte y 2.0 (label) print_byte_at::@1 (label) print_byte_at::@return (byte*) print_byte_at::at (byte*) print_byte_at::at#0 at zp[2]:4 4.0 (byte*) print_byte_at::at#1 at zp[2]:4 4.0 (byte*) print_byte_at::at#2 at zp[2]:4 1.3333333333333333 (byte) print_byte_at::b (byte) print_byte_at::b#0 b zp[1]:6 2.0 (byte) print_byte_at::b#1 b zp[1]:6 2.0 (byte) print_byte_at::b#2 b zp[1]:6 1.6 (void()) print_char_at((byte) print_char_at::ch , (byte*) print_char_at::at) (label) print_char_at::@return (byte*) print_char_at::at (byte*) print_char_at::at#0 at zp[2]:7 4.0 (byte*) print_char_at::at#1 at zp[2]:7 2.0 (byte*) print_char_at::at#2 at zp[2]:7 6.0 (byte) print_char_at::ch (byte) print_char_at::ch#0 reg byte x 2.0 (byte) print_char_at::ch#1 reg byte x 4.0 (byte) print_char_at::ch#2 reg byte x 6.0 (void()) print_dword_at((dword) print_dword_at::dw , (byte*) print_dword_at::at) (label) print_dword_at::@1 (label) print_dword_at::@return (byte*) print_dword_at::at (dword) print_dword_at::dw (dword) print_dword_at::dw#0 dw zp[4]:9 5.0 (const byte*) print_hextab = (string) "0123456789abcdef"z (void()) print_word_at((word) print_word_at::w , (byte*) print_word_at::at) (label) print_word_at::@1 (label) print_word_at::@return (byte*) print_word_at::at (byte*) print_word_at::at#2 at zp[2]:4 0.8 (word) print_word_at::w (word) print_word_at::w#0 w zp[2]:2 4.0 (word) print_word_at::w#1 w zp[2]:2 4.0 (word) print_word_at::w#2 w zp[2]:2 2.0 zp[2]:2 [ print_word_at::w#2 print_word_at::w#0 print_word_at::w#1 ] zp[2]:4 [ print_word_at::at#2 print_byte_at::at#2 print_byte_at::at#0 print_byte_at::at#1 ] zp[1]:6 [ print_byte_at::b#2 print_byte_at::b#0 print_byte_at::b#1 ] reg byte x [ print_char_at::ch#2 print_char_at::ch#0 print_char_at::ch#1 ] zp[2]:7 [ print_char_at::at#2 print_char_at::at#0 print_char_at::at#1 ] zp[4]:9 [ clock::return#2 print_dword_at::dw#0 clock::return#0 ] reg byte a [ print_byte_at::$0 ] reg byte y [ print_byte_at::$2 ] FINAL ASSEMBLER Score: 455 // File Comments // Setup and run a simple CIA-timer // Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels // CIA #2 Timer A+B Value (32-bit) .label CIA2_TIMER_AB = $dd04 // CIA #2 Timer A Control Register .label CIA2_TIMER_A_CONTROL = $dd0e // CIA #2 Timer B Control Register .label CIA2_TIMER_B_CONTROL = $dd0f // Timer Control - Start/stop timer (0:stop, 1: start) .const CIA_TIMER_CONTROL_START = 1 // Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high) .const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40 .label SCREEN = $400 // @begin // [1] phi from @begin to @1 [phi:@begin->@1] // @1 // [2] call main // [4] phi from @1 to main [phi:@1->main] // [3] phi from @1 to @end [phi:@1->@end] // @end // main main: { // clock_start() // [5] call clock_start jsr clock_start // [6] phi from main main::@2 to main::@1 [phi:main/main::@2->main::@1] // main::@1 __b1: // clock() // [7] call clock jsr clock // [8] (dword) clock::return#2 ← (dword) clock::return#0 // main::@2 // print_dword_at(clock(), SCREEN) // [9] (dword) print_dword_at::dw#0 ← (dword) clock::return#2 // [10] call print_dword_at jsr print_dword_at jmp __b1 } // print_dword_at // Print a dword as HEX at a specific position // print_dword_at(dword zeropage(9) dw) print_dword_at: { .label dw = 9 // print_word_at(>dw, at) // [11] (word) print_word_at::w#0 ← > (dword) print_dword_at::dw#0 -- vwuz1=_hi_vduz2 lda.z dw+2 sta.z print_word_at.w lda.z dw+3 sta.z print_word_at.w+1 // [12] call print_word_at // [16] phi from print_dword_at to print_word_at [phi:print_dword_at->print_word_at] // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN [phi:print_dword_at->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#0 [phi:print_dword_at->print_word_at#1] -- register_copy jsr print_word_at // print_dword_at::@1 // print_word_at(print_word_at] // [16] phi (byte*) print_word_at::at#2 = (const byte*) SCREEN+(byte) 4 [phi:print_dword_at::@1->print_word_at#0] -- pbuz1=pbuc1 lda #SCREEN+4 sta.z print_word_at.at+1 // [16] phi (word) print_word_at::w#2 = (word) print_word_at::w#1 [phi:print_dword_at::@1->print_word_at#1] -- register_copy jsr print_word_at // print_dword_at::@return // } // [15] return rts } // print_word_at // Print a word as HEX at a specific position // print_word_at(word zeropage(2) w, byte* zeropage(4) at) print_word_at: { .label w = 2 .label at = 4 // print_byte_at(>w, at) // [17] (byte) print_byte_at::b#0 ← > (word) print_word_at::w#2 -- vbuz1=_hi_vwuz2 lda.z w+1 sta.z print_byte_at.b // [18] (byte*) print_byte_at::at#0 ← (byte*) print_word_at::at#2 // [19] call print_byte_at // [24] phi from print_word_at to print_byte_at [phi:print_word_at->print_byte_at] // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#0 [phi:print_word_at->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#0 [phi:print_word_at->print_byte_at#1] -- register_copy jsr print_byte_at // print_word_at::@1 // print_byte_at(print_byte_at] // [24] phi (byte*) print_byte_at::at#2 = (byte*) print_byte_at::at#1 [phi:print_word_at::@1->print_byte_at#0] -- register_copy // [24] phi (byte) print_byte_at::b#2 = (byte) print_byte_at::b#1 [phi:print_word_at::@1->print_byte_at#1] -- register_copy jsr print_byte_at // print_word_at::@return // } // [23] return rts } // print_byte_at // Print a byte as HEX at a specific position // print_byte_at(byte zeropage(6) b, byte* zeropage(4) at) print_byte_at: { .label b = 6 .label at = 4 // b>>4 // [25] (byte~) print_byte_at::$0 ← (byte) print_byte_at::b#2 >> (byte) 4 -- vbuaa=vbuz1_ror_4 lda.z b lsr lsr lsr lsr // print_char_at(print_hextab[b>>4], at) // [26] (byte) print_char_at::ch#0 ← *((const byte*) print_hextab + (byte~) print_byte_at::$0) -- vbuxx=pbuc1_derefidx_vbuaa tay ldx print_hextab,y // [27] (byte*) print_char_at::at#0 ← (byte*) print_byte_at::at#2 -- pbuz1=pbuz2 lda.z at sta.z print_char_at.at lda.z at+1 sta.z print_char_at.at+1 // [28] call print_char_at // [34] phi from print_byte_at to print_char_at [phi:print_byte_at->print_char_at] // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#0 [phi:print_byte_at->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#0 [phi:print_byte_at->print_char_at#1] -- register_copy jsr print_char_at // print_byte_at::@1 // b&$f // [29] (byte~) print_byte_at::$2 ← (byte) print_byte_at::b#2 & (byte) $f -- vbuyy=vbuz1_band_vbuc1 lda #$f and.z b tay // print_char_at(print_hextab[b&$f], at+1) // [30] (byte*) print_char_at::at#1 ← (byte*) print_byte_at::at#2 + (byte) 1 -- pbuz1=pbuz2_plus_1 lda.z at clc adc #1 sta.z print_char_at.at lda.z at+1 adc #0 sta.z print_char_at.at+1 // [31] (byte) print_char_at::ch#1 ← *((const byte*) print_hextab + (byte~) print_byte_at::$2) -- vbuxx=pbuc1_derefidx_vbuyy ldx print_hextab,y // [32] call print_char_at // [34] phi from print_byte_at::@1 to print_char_at [phi:print_byte_at::@1->print_char_at] // [34] phi (byte*) print_char_at::at#2 = (byte*) print_char_at::at#1 [phi:print_byte_at::@1->print_char_at#0] -- register_copy // [34] phi (byte) print_char_at::ch#2 = (byte) print_char_at::ch#1 [phi:print_byte_at::@1->print_char_at#1] -- register_copy jsr print_char_at // print_byte_at::@return // } // [33] return rts } // print_char_at // Print a single char // print_char_at(byte register(X) ch, byte* zeropage(7) at) print_char_at: { .label at = 7 // *(at) = ch // [35] *((byte*) print_char_at::at#2) ← (byte) print_char_at::ch#2 -- _deref_pbuz1=vbuxx txa ldy #0 sta (at),y // print_char_at::@return // } // [36] return rts } // clock // Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program). // This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start() clock: { .label return = 9 // 0xffffffff - *CIA2_TIMER_AB // [37] (dword) clock::return#0 ← (dword) $ffffffff - *((const dword*) CIA2_TIMER_AB) -- vduz1=vduc1_minus__deref_pduc2 lda #<$ffffffff sec sbc CIA2_TIMER_AB sta.z return lda #>$ffffffff sbc CIA2_TIMER_AB+1 sta.z return+1 lda #<$ffffffff>>$10 sbc CIA2_TIMER_AB+2 sta.z return+2 lda #>$ffffffff>>$10 sbc CIA2_TIMER_AB+3 sta.z return+3 // clock::@return // } // [38] return rts } // clock_start // Reset & start the processor clock time. The value can be read using clock(). // This uses CIA #2 Timer A+B on the C64 clock_start: { // *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES // [39] *((const byte*) CIA2_TIMER_A_CONTROL) ← (byte) 0 -- _deref_pbuc1=vbuc2 // Setup CIA#2 timer A to count (down) CPU cycles lda #0 sta CIA2_TIMER_A_CONTROL // *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A // [40] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // *CIA2_TIMER_AB = 0xffffffff // [41] *((const dword*) CIA2_TIMER_AB) ← (dword) $ffffffff -- _deref_pduc1=vduc2 lda #<$ffffffff sta CIA2_TIMER_AB lda #>$ffffffff sta CIA2_TIMER_AB+1 lda #<$ffffffff>>$10 sta CIA2_TIMER_AB+2 lda #>$ffffffff>>$10 sta CIA2_TIMER_AB+3 // *CIA2_TIMER_B_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A // [42] *((const byte*) CIA2_TIMER_B_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START|(const byte) CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START|CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A sta CIA2_TIMER_B_CONTROL // *CIA2_TIMER_A_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES // [43] *((const byte*) CIA2_TIMER_A_CONTROL) ← (const byte) CIA_TIMER_CONTROL_START -- _deref_pbuc1=vbuc2 lda #CIA_TIMER_CONTROL_START sta CIA2_TIMER_A_CONTROL // clock_start::@return // } // [44] return rts } // File Data print_hextab: .text "0123456789abcdef"