mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-30 09:57:11 +00:00
1652 lines
81 KiB
Plaintext
1652 lines
81 KiB
Plaintext
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(<dw, at+4)
|
|
// [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]
|
|
// [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
|
|
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(<w, at+2)
|
|
// [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]
|
|
// [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"
|
|
|