mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-06-10 10:29:36 +00:00
772 lines
32 KiB
Plaintext
772 lines
32 KiB
Plaintext
Resolved forward reference table_driven_irq to __interrupt(rom_min_c64) void table_driven_irq()
|
|
Inlined call vicSelectGfxBank::$0 = call toDd00(vicSelectGfxBank::gfx)
|
|
Inlined call call __init
|
|
|
|
CONTROL FLOW GRAPH SSA
|
|
|
|
void main()
|
|
main: scope:[main] from __start::@1
|
|
asm { sei }
|
|
*((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL
|
|
*VICII_CONTROL1 = *VICII_CONTROL1 & $7f
|
|
*RASTER = $60
|
|
*IRQ_ENABLE = IRQ_RASTER
|
|
*IRQ_STATUS = IRQ_RASTER
|
|
*KERNEL_IRQ = &table_driven_irq
|
|
asm { cli }
|
|
to:main::@return
|
|
main::@return: scope:[main] from main
|
|
return
|
|
to:@return
|
|
|
|
__interrupt(rom_min_c64) void table_driven_irq()
|
|
table_driven_irq: scope:[table_driven_irq] from
|
|
to:table_driven_irq::@1
|
|
table_driven_irq::@1: scope:[table_driven_irq] from table_driven_irq table_driven_irq::@4
|
|
table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx]
|
|
table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx]
|
|
irq_idx = ++ irq_idx
|
|
table_driven_irq::$0 = table_driven_irq::idx#0 < VICII_SIZE
|
|
if(table_driven_irq::$0) goto table_driven_irq::@2
|
|
to:table_driven_irq::@5
|
|
table_driven_irq::@2: scope:[table_driven_irq] from table_driven_irq::@1
|
|
table_driven_irq::idx#1 = phi( table_driven_irq::@1/table_driven_irq::idx#0 )
|
|
table_driven_irq::val#1 = phi( table_driven_irq::@1/table_driven_irq::val#0 )
|
|
VICII_BASE[table_driven_irq::idx#1] = table_driven_irq::val#1
|
|
to:table_driven_irq::@4
|
|
table_driven_irq::@5: scope:[table_driven_irq] from table_driven_irq::@1
|
|
table_driven_irq::val#4 = phi( table_driven_irq::@1/table_driven_irq::val#0 )
|
|
table_driven_irq::idx#2 = phi( table_driven_irq::@1/table_driven_irq::idx#0 )
|
|
table_driven_irq::$1 = table_driven_irq::idx#2 < VICII_SIZE+8
|
|
if(table_driven_irq::$1) goto table_driven_irq::@3
|
|
to:table_driven_irq::@6
|
|
table_driven_irq::@3: scope:[table_driven_irq] from table_driven_irq::@5
|
|
table_driven_irq::val#2 = phi( table_driven_irq::@5/table_driven_irq::val#4 )
|
|
table_driven_irq::idx#3 = phi( table_driven_irq::@5/table_driven_irq::idx#2 )
|
|
table_driven_irq::$4 = table_driven_irq::idx#3 + $3f8
|
|
table_driven_irq::$5 = table_driven_irq::$4 - VICII_SIZE
|
|
SCREEN[table_driven_irq::$5] = table_driven_irq::val#2
|
|
to:table_driven_irq::@4
|
|
table_driven_irq::@6: scope:[table_driven_irq] from table_driven_irq::@5
|
|
table_driven_irq::val#3 = phi( table_driven_irq::@5/table_driven_irq::val#4 )
|
|
*IRQ_STATUS = IRQ_RASTER
|
|
*RASTER = table_driven_irq::val#3
|
|
table_driven_irq::$2 = table_driven_irq::val#3 < *RASTER
|
|
table_driven_irq::$3 = ! table_driven_irq::$2
|
|
if(table_driven_irq::$3) goto table_driven_irq::@return
|
|
to:table_driven_irq::@7
|
|
table_driven_irq::@7: scope:[table_driven_irq] from table_driven_irq::@6
|
|
irq_idx = 0
|
|
to:table_driven_irq::@return
|
|
table_driven_irq::@return: scope:[table_driven_irq] from table_driven_irq::@4 table_driven_irq::@6 table_driven_irq::@7
|
|
return
|
|
to:@return
|
|
table_driven_irq::@4: scope:[table_driven_irq] from table_driven_irq::@2 table_driven_irq::@3
|
|
if(true) goto table_driven_irq::@1
|
|
to:table_driven_irq::@return
|
|
|
|
void __start()
|
|
__start: scope:[__start] from
|
|
to:__start::__init1
|
|
__start::__init1: scope:[__start] from __start
|
|
irq_idx = 0
|
|
to:__start::@1
|
|
__start::@1: scope:[__start] from __start::__init1
|
|
call main
|
|
to:__start::@2
|
|
__start::@2: scope:[__start] from __start::@1
|
|
to:__start::@return
|
|
__start::@return: scope:[__start] from __start::@2
|
|
return
|
|
to:@return
|
|
|
|
SYMBOL TABLE SSA
|
|
__constant struct MOS6526_CIA * const CIA1 = (struct MOS6526_CIA *)$dc00
|
|
__constant const char CIA_INTERRUPT_CLEAR_ALL = $7f
|
|
__constant char IRQ_CHANGE_IDX[] = { $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT }
|
|
__constant const char IRQ_CHANGE_NEXT = $7f
|
|
__constant char IRQ_CHANGE_VAL[] = { $b, $b, $63, 0, 0, $80, 7, 7, $83, 0, 0, $60 }
|
|
__constant char * const IRQ_ENABLE = (char *)$d01a
|
|
__constant const char IRQ_RASTER = 1
|
|
__constant char * const IRQ_STATUS = (char *)$d019
|
|
__constant void (** const KERNEL_IRQ)() = (void (**)())$314
|
|
__constant char OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
|
__constant char * const RASTER = (char *)$d012
|
|
__constant char * const SCREEN = (char *)$400
|
|
__constant char * const VICII_BASE = (char *)$d000
|
|
__constant char * const VICII_CONTROL1 = (char *)$d011
|
|
__constant const char VICII_SIZE = $30
|
|
void __start()
|
|
__loadstore volatile char irq_idx
|
|
void main()
|
|
__interrupt(rom_min_c64) void table_driven_irq()
|
|
bool table_driven_irq::$0
|
|
bool table_driven_irq::$1
|
|
bool table_driven_irq::$2
|
|
bool table_driven_irq::$3
|
|
number table_driven_irq::$4
|
|
number table_driven_irq::$5
|
|
char table_driven_irq::idx
|
|
char table_driven_irq::idx#0
|
|
char table_driven_irq::idx#1
|
|
char table_driven_irq::idx#2
|
|
char table_driven_irq::idx#3
|
|
char table_driven_irq::val
|
|
char table_driven_irq::val#0
|
|
char table_driven_irq::val#1
|
|
char table_driven_irq::val#2
|
|
char table_driven_irq::val#3
|
|
char table_driven_irq::val#4
|
|
|
|
Adding number conversion cast (unumber) $7f in *VICII_CONTROL1 = *VICII_CONTROL1 & $7f
|
|
Adding number conversion cast (unumber) $60 in *RASTER = $60
|
|
Adding number conversion cast (unumber) VICII_SIZE+8 in table_driven_irq::$1 = table_driven_irq::idx#2 < VICII_SIZE+8
|
|
Adding number conversion cast (unumber) 8 in table_driven_irq::$1 = table_driven_irq::idx#2 < (unumber)VICII_SIZE+8
|
|
Adding number conversion cast (unumber) $3f8 in table_driven_irq::$4 = table_driven_irq::idx#3 + $3f8
|
|
Adding number conversion cast (unumber) table_driven_irq::$4 in table_driven_irq::$4 = table_driven_irq::idx#3 + (unumber)$3f8
|
|
Adding number conversion cast (unumber) table_driven_irq::$5 in table_driven_irq::$5 = table_driven_irq::$4 - VICII_SIZE
|
|
Adding number conversion cast (unumber) 0 in irq_idx = 0
|
|
Successful SSA optimization PassNAddNumberTypeConversions
|
|
Inlining cast *RASTER = (unumber)$60
|
|
Inlining cast irq_idx = (unumber)0
|
|
Successful SSA optimization Pass2InlineCast
|
|
Simplifying constant pointer cast (char *) 53266
|
|
Simplifying constant pointer cast (char *) 53265
|
|
Simplifying constant pointer cast (char *) 53273
|
|
Simplifying constant pointer cast (char *) 53274
|
|
Simplifying constant pointer cast (struct MOS6526_CIA *) 56320
|
|
Simplifying constant pointer cast (void (**)()) 788
|
|
Simplifying constant pointer cast (char *) 1024
|
|
Simplifying constant pointer cast (char *) 53248
|
|
Simplifying constant integer cast $7f
|
|
Simplifying constant integer cast $60
|
|
Simplifying constant integer cast VICII_SIZE+(unumber)8
|
|
Simplifying constant integer cast 8
|
|
Simplifying constant integer cast $3f8
|
|
Simplifying constant integer cast 0
|
|
Successful SSA optimization PassNCastSimplification
|
|
Finalized unsigned number type (char) $7f
|
|
Finalized unsigned number type (char) $60
|
|
Finalized unsigned number type (char) 8
|
|
Finalized unsigned number type (unsigned int) $3f8
|
|
Finalized unsigned number type (char) 0
|
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
|
Inferred type updated to unsigned int in table_driven_irq::$4 = table_driven_irq::idx#3 + $3f8
|
|
Inferred type updated to unsigned int in table_driven_irq::$5 = table_driven_irq::$4 - VICII_SIZE
|
|
Inversing boolean not [27] table_driven_irq::$3 = table_driven_irq::val#3 >= *RASTER from [26] table_driven_irq::$2 = table_driven_irq::val#3 < *RASTER
|
|
Successful SSA optimization Pass2UnaryNotSimplification
|
|
Alias table_driven_irq::val#0 = table_driven_irq::val#1 table_driven_irq::val#4 table_driven_irq::val#2 table_driven_irq::val#3
|
|
Alias table_driven_irq::idx#0 = table_driven_irq::idx#1 table_driven_irq::idx#2 table_driven_irq::idx#3
|
|
Successful SSA optimization Pass2AliasElimination
|
|
Simple Condition table_driven_irq::$0 [13] if(table_driven_irq::idx#0<VICII_SIZE) goto table_driven_irq::@2
|
|
Simple Condition table_driven_irq::$1 [16] if(table_driven_irq::idx#0<VICII_SIZE+8) goto table_driven_irq::@3
|
|
Simple Condition table_driven_irq::$3 [23] if(table_driven_irq::val#0>=*RASTER) goto table_driven_irq::@return
|
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
|
if() condition always true - replacing block destination [26] if(true) goto table_driven_irq::@1
|
|
Successful SSA optimization Pass2ConstantIfs
|
|
De-inlining pointer[w] to *(pointer+w) [19] SCREEN[table_driven_irq::$5] = table_driven_irq::val#0
|
|
Successful SSA optimization Pass2DeInlineWordDerefIdx
|
|
Consolidated constant in assignment table_driven_irq::$6
|
|
Successful SSA optimization Pass2ConstantAdditionElimination
|
|
Alias table_driven_irq::$5 = table_driven_irq::$4
|
|
Successful SSA optimization Pass2AliasElimination
|
|
Consolidated constant in assignment table_driven_irq::$6
|
|
Successful SSA optimization Pass2ConstantAdditionElimination
|
|
Alias table_driven_irq::idx#0 = table_driven_irq::$5
|
|
Successful SSA optimization Pass2AliasElimination
|
|
Converting *(pointer+n) to pointer[n] [16] *table_driven_irq::$6 = table_driven_irq::val#0 -- (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0]
|
|
Successful SSA optimization Pass2InlineDerefIdx
|
|
Eliminating unused variable table_driven_irq::$6 and assignment [15] table_driven_irq::$6 = SCREEN+-VICII_SIZE+$3f8 + table_driven_irq::idx#0
|
|
Successful SSA optimization PassNEliminateUnusedVars
|
|
Adding NOP phi() at start of __start
|
|
Adding NOP phi() at start of __start::@1
|
|
Adding NOP phi() at start of __start::@2
|
|
Adding NOP phi() at start of table_driven_irq
|
|
Adding NOP phi() at start of table_driven_irq::@4
|
|
CALL GRAPH
|
|
Calls in [__start] to main:3
|
|
|
|
Created 0 initial phi equivalence classes
|
|
Coalesced down to 0 phi equivalence classes
|
|
Culled Empty Block label __start::@2
|
|
Culled Empty Block label table_driven_irq::@4
|
|
Renumbering block table_driven_irq::@5 to table_driven_irq::@4
|
|
Renumbering block table_driven_irq::@6 to table_driven_irq::@5
|
|
Renumbering block table_driven_irq::@7 to table_driven_irq::@6
|
|
Adding NOP phi() at start of __start
|
|
Adding NOP phi() at start of __start::@1
|
|
Adding NOP phi() at start of table_driven_irq
|
|
|
|
FINAL CONTROL FLOW GRAPH
|
|
|
|
void __start()
|
|
__start: scope:[__start] from
|
|
[0] phi()
|
|
to:__start::__init1
|
|
__start::__init1: scope:[__start] from __start
|
|
[1] irq_idx = 0
|
|
to:__start::@1
|
|
__start::@1: scope:[__start] from __start::__init1
|
|
[2] phi()
|
|
[3] call main
|
|
to:__start::@return
|
|
__start::@return: scope:[__start] from __start::@1
|
|
[4] return
|
|
to:@return
|
|
|
|
__interrupt(rom_min_c64) void table_driven_irq()
|
|
table_driven_irq: scope:[table_driven_irq] from
|
|
[5] phi()
|
|
to:table_driven_irq::@1
|
|
table_driven_irq::@1: scope:[table_driven_irq] from table_driven_irq table_driven_irq::@2 table_driven_irq::@3
|
|
[6] table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx]
|
|
[7] table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx]
|
|
[8] irq_idx = ++ irq_idx
|
|
[9] if(table_driven_irq::idx#0<VICII_SIZE) goto table_driven_irq::@2
|
|
to:table_driven_irq::@4
|
|
table_driven_irq::@4: scope:[table_driven_irq] from table_driven_irq::@1
|
|
[10] if(table_driven_irq::idx#0<VICII_SIZE+8) goto table_driven_irq::@3
|
|
to:table_driven_irq::@5
|
|
table_driven_irq::@5: scope:[table_driven_irq] from table_driven_irq::@4
|
|
[11] *IRQ_STATUS = IRQ_RASTER
|
|
[12] *RASTER = table_driven_irq::val#0
|
|
[13] if(table_driven_irq::val#0>=*RASTER) goto table_driven_irq::@return
|
|
to:table_driven_irq::@6
|
|
table_driven_irq::@6: scope:[table_driven_irq] from table_driven_irq::@5
|
|
[14] irq_idx = 0
|
|
to:table_driven_irq::@return
|
|
table_driven_irq::@return: scope:[table_driven_irq] from table_driven_irq::@5 table_driven_irq::@6
|
|
[15] return
|
|
to:@return
|
|
table_driven_irq::@3: scope:[table_driven_irq] from table_driven_irq::@4
|
|
[16] (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0] = table_driven_irq::val#0
|
|
to:table_driven_irq::@1
|
|
table_driven_irq::@2: scope:[table_driven_irq] from table_driven_irq::@1
|
|
[17] VICII_BASE[table_driven_irq::idx#0] = table_driven_irq::val#0
|
|
to:table_driven_irq::@1
|
|
|
|
void main()
|
|
main: scope:[main] from __start::@1
|
|
asm { sei }
|
|
[19] *((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL
|
|
[20] *VICII_CONTROL1 = *VICII_CONTROL1 & $7f
|
|
[21] *RASTER = $60
|
|
[22] *IRQ_ENABLE = IRQ_RASTER
|
|
[23] *IRQ_STATUS = IRQ_RASTER
|
|
[24] *KERNEL_IRQ = &table_driven_irq
|
|
asm { cli }
|
|
to:main::@return
|
|
main::@return: scope:[main] from main
|
|
[26] return
|
|
to:@return
|
|
|
|
|
|
VARIABLE REGISTER WEIGHTS
|
|
void __start()
|
|
__loadstore volatile char irq_idx // 6.0
|
|
void main()
|
|
__interrupt(rom_min_c64) void table_driven_irq()
|
|
char table_driven_irq::idx
|
|
char table_driven_irq::idx#0 // 11.0
|
|
char table_driven_irq::val
|
|
char table_driven_irq::val#0 // 6.166666666666666
|
|
|
|
Initial phi equivalence classes
|
|
Added variable irq_idx to live range equivalence class [ irq_idx ]
|
|
Added variable table_driven_irq::idx#0 to live range equivalence class [ table_driven_irq::idx#0 ]
|
|
Added variable table_driven_irq::val#0 to live range equivalence class [ table_driven_irq::val#0 ]
|
|
Complete equivalence classes
|
|
[ irq_idx ]
|
|
[ table_driven_irq::idx#0 ]
|
|
[ table_driven_irq::val#0 ]
|
|
Allocated zp[1]:2 [ table_driven_irq::idx#0 ]
|
|
Allocated zp[1]:3 [ table_driven_irq::val#0 ]
|
|
Allocated zp[1]:4 [ irq_idx ]
|
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
|
Statement [1] irq_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [6] table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx] [ irq_idx table_driven_irq::idx#0 ] ( [ irq_idx table_driven_irq::idx#0 ] { } ) always clobbers reg byte y
|
|
Statement [7] table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx] [ irq_idx table_driven_irq::idx#0 table_driven_irq::val#0 ] ( [ irq_idx table_driven_irq::idx#0 table_driven_irq::val#0 ] { } ) always clobbers reg byte y
|
|
Removing always clobbered register reg byte y as potential for zp[1]:2 [ table_driven_irq::idx#0 ]
|
|
Statement [11] *IRQ_STATUS = IRQ_RASTER [ table_driven_irq::val#0 ] ( [ table_driven_irq::val#0 ] { } ) always clobbers reg byte a
|
|
Removing always clobbered register reg byte a as potential for zp[1]:3 [ table_driven_irq::val#0 ]
|
|
Statement [14] irq_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [16] (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0] = table_driven_irq::val#0 [ irq_idx ] ( [ irq_idx ] { } ) always clobbers reg byte a
|
|
Statement [17] VICII_BASE[table_driven_irq::idx#0] = table_driven_irq::val#0 [ irq_idx ] ( [ irq_idx ] { } ) always clobbers reg byte a
|
|
Statement [19] *((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [20] *VICII_CONTROL1 = *VICII_CONTROL1 & $7f [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [21] *RASTER = $60 [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [22] *IRQ_ENABLE = IRQ_RASTER [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [23] *IRQ_STATUS = IRQ_RASTER [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [24] *KERNEL_IRQ = &table_driven_irq [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [1] irq_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [6] table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx] [ irq_idx table_driven_irq::idx#0 ] ( [ irq_idx table_driven_irq::idx#0 ] { } ) always clobbers reg byte y
|
|
Statement [7] table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx] [ irq_idx table_driven_irq::idx#0 table_driven_irq::val#0 ] ( [ irq_idx table_driven_irq::idx#0 table_driven_irq::val#0 ] { } ) always clobbers reg byte y
|
|
Statement [11] *IRQ_STATUS = IRQ_RASTER [ table_driven_irq::val#0 ] ( [ table_driven_irq::val#0 ] { } ) always clobbers reg byte a
|
|
Statement [14] irq_idx = 0 [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [16] (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0] = table_driven_irq::val#0 [ irq_idx ] ( [ irq_idx ] { } ) always clobbers reg byte a
|
|
Statement [17] VICII_BASE[table_driven_irq::idx#0] = table_driven_irq::val#0 [ irq_idx ] ( [ irq_idx ] { } ) always clobbers reg byte a
|
|
Statement [19] *((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [20] *VICII_CONTROL1 = *VICII_CONTROL1 & $7f [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [21] *RASTER = $60 [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [22] *IRQ_ENABLE = IRQ_RASTER [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [23] *IRQ_STATUS = IRQ_RASTER [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Statement [24] *KERNEL_IRQ = &table_driven_irq [ ] ( main:3 [ ] { } ) always clobbers reg byte a
|
|
Potential registers zp[1]:4 [ irq_idx ] : zp[1]:4 ,
|
|
Potential registers zp[1]:2 [ table_driven_irq::idx#0 ] : zp[1]:2 , reg byte a , reg byte x ,
|
|
Potential registers zp[1]:3 [ table_driven_irq::val#0 ] : zp[1]:3 , reg byte x , reg byte y ,
|
|
|
|
REGISTER UPLIFT SCOPES
|
|
Uplift Scope [table_driven_irq] 11: zp[1]:2 [ table_driven_irq::idx#0 ] 6.17: zp[1]:3 [ table_driven_irq::val#0 ]
|
|
Uplift Scope [] 6: zp[1]:4 [ irq_idx ]
|
|
Uplift Scope [MOS6526_CIA]
|
|
Uplift Scope [MOS6569_VICII]
|
|
Uplift Scope [MOS6581_SID]
|
|
Uplift Scope [main]
|
|
Uplift Scope [__start]
|
|
|
|
Uplifting [table_driven_irq] best 789 combination reg byte a [ table_driven_irq::idx#0 ] reg byte x [ table_driven_irq::val#0 ]
|
|
Uplifting [] best 789 combination zp[1]:4 [ irq_idx ]
|
|
Uplifting [MOS6526_CIA] best 789 combination
|
|
Uplifting [MOS6569_VICII] best 789 combination
|
|
Uplifting [MOS6581_SID] best 789 combination
|
|
Uplifting [main] best 789 combination
|
|
Uplifting [__start] best 789 combination
|
|
Attempting to uplift remaining variables inzp[1]:4 [ irq_idx ]
|
|
Uplifting [] best 789 combination zp[1]:4 [ irq_idx ]
|
|
Allocated (was zp[1]:4) zp[1]:2 [ irq_idx ]
|
|
|
|
ASSEMBLER BEFORE OPTIMIZATION
|
|
// File Comments
|
|
// Test interrupt routine using a variable between calls (irq_idx)
|
|
/// @file
|
|
/// Commodore 64 Registers and Constants
|
|
/// @file
|
|
/// The MOS 6526 Complex Interface Adapter (CIA)
|
|
///
|
|
/// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
|
// Upstart
|
|
// Commodore 64 PRG executable file
|
|
.file [name="irq-idx-problem.prg", type="prg", segments="Program"]
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
.segmentdef Basic [start=$0801]
|
|
.segmentdef Code [start=$80d]
|
|
.segmentdef Data [startAfter="Code"]
|
|
.segment Basic
|
|
:BasicUpstart(__start)
|
|
// Global Constants & labels
|
|
/// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
|
.const CIA_INTERRUPT_CLEAR_ALL = $7f
|
|
/// VICII IRQ Status/Enable Raster
|
|
// @see #IRQ_ENABLE #IRQ_STATUS
|
|
/// 0 | RST| Reaching a certain raster line. The line is specified by writing
|
|
/// | | to register 0xd012 and bit 7 of $d011 and internally stored by
|
|
/// | | the VIC for the raster compare. The test for reaching the
|
|
/// | | interrupt raster line is done in cycle 0 of every line (for line
|
|
/// | | 0, in cycle 1).
|
|
.const IRQ_RASTER = 1
|
|
.const VICII_SIZE = $30
|
|
.const IRQ_CHANGE_NEXT = $7f
|
|
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
|
/// $D012 RASTER Raster counter
|
|
.label RASTER = $d012
|
|
/// $D011 Control Register #1
|
|
/// - Bit#0-#2: YSCROLL Screen Soft Scroll Vertical
|
|
/// - Bit#3: RSEL Switch betweem 25 or 24 visible rows
|
|
/// RSEL| Display window height | First line | Last line
|
|
/// ----+--------------------------+-------------+----------
|
|
/// 0 | 24 text lines/192 pixels | 55 ($37) | 246 ($f6)
|
|
/// 1 | 25 text lines/200 pixels | 51 ($33) | 250 ($fa)
|
|
/// - Bit#4: DEN Switch VIC-II output on/off
|
|
/// - Bit#5: BMM Turn Bitmap Mode on/off
|
|
/// - Bit#6: ECM Turn Extended Color Mode on/off
|
|
/// - Bit#7: RST8 9th Bit for $D012 Rasterline counter
|
|
/// Initial Value: %10011011
|
|
.label VICII_CONTROL1 = $d011
|
|
/// VIC II IRQ Status Register
|
|
.label IRQ_STATUS = $d019
|
|
/// VIC II IRQ Enable Register
|
|
.label IRQ_ENABLE = $d01a
|
|
/// The CIA#1: keyboard matrix, joystick #1/#2
|
|
.label CIA1 = $dc00
|
|
/// The vector used when the KERNAL serves IRQ interrupts
|
|
.label KERNEL_IRQ = $314
|
|
.label SCREEN = $400
|
|
.label VICII_BASE = $d000
|
|
.label irq_idx = 2
|
|
.segment Code
|
|
// __start
|
|
__start: {
|
|
jmp __init1
|
|
// __start::__init1
|
|
__init1:
|
|
// [1] irq_idx = 0 -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z irq_idx
|
|
// [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
|
|
__b1_from___init1:
|
|
jmp __b1
|
|
// __start::@1
|
|
__b1:
|
|
// [3] call main
|
|
jsr main
|
|
jmp __breturn
|
|
// __start::@return
|
|
__breturn:
|
|
// [4] return
|
|
rts
|
|
}
|
|
// table_driven_irq
|
|
table_driven_irq: {
|
|
// interrupt(isr_rom_min_c64_entry) -- isr_rom_min_c64_entry
|
|
jmp __b1
|
|
// table_driven_irq::@1
|
|
__b1:
|
|
// [6] table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx] -- vbuaa=pbuc1_derefidx_vbuz1
|
|
ldy.z irq_idx
|
|
lda IRQ_CHANGE_IDX,y
|
|
// [7] table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx] -- vbuxx=pbuc1_derefidx_vbuz1
|
|
ldy.z irq_idx
|
|
ldx IRQ_CHANGE_VAL,y
|
|
// [8] irq_idx = ++ irq_idx -- vbuz1=_inc_vbuz1
|
|
inc.z irq_idx
|
|
// [9] if(table_driven_irq::idx#0<VICII_SIZE) goto table_driven_irq::@2 -- vbuaa_lt_vbuc1_then_la1
|
|
cmp #VICII_SIZE
|
|
bcc __b2
|
|
jmp __b4
|
|
// table_driven_irq::@4
|
|
__b4:
|
|
// [10] if(table_driven_irq::idx#0<VICII_SIZE+8) goto table_driven_irq::@3 -- vbuaa_lt_vbuc1_then_la1
|
|
cmp #VICII_SIZE+8
|
|
bcc __b3
|
|
jmp __b5
|
|
// table_driven_irq::@5
|
|
__b5:
|
|
// [11] *IRQ_STATUS = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
lda #IRQ_RASTER
|
|
sta IRQ_STATUS
|
|
// [12] *RASTER = table_driven_irq::val#0 -- _deref_pbuc1=vbuxx
|
|
stx RASTER
|
|
// [13] if(table_driven_irq::val#0>=*RASTER) goto table_driven_irq::@return -- vbuxx_ge__deref_pbuc1_then_la1
|
|
cpx RASTER
|
|
bcs __breturn
|
|
jmp __b6
|
|
// table_driven_irq::@6
|
|
__b6:
|
|
// [14] irq_idx = 0 -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z irq_idx
|
|
jmp __breturn
|
|
// table_driven_irq::@return
|
|
__breturn:
|
|
// [15] return
|
|
// interrupt(isr_rom_min_c64_exit) -- isr_rom_min_c64_exit
|
|
jmp $ea81
|
|
// table_driven_irq::@3
|
|
__b3:
|
|
// [16] (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0] = table_driven_irq::val#0 -- pbuc1_derefidx_vbuaa=vbuxx
|
|
tay
|
|
txa
|
|
sta SCREEN+-VICII_SIZE+$3f8,y
|
|
jmp __b1
|
|
// table_driven_irq::@2
|
|
__b2:
|
|
// [17] VICII_BASE[table_driven_irq::idx#0] = table_driven_irq::val#0 -- pbuc1_derefidx_vbuaa=vbuxx
|
|
tay
|
|
txa
|
|
sta VICII_BASE,y
|
|
jmp __b1
|
|
}
|
|
// main
|
|
main: {
|
|
// asm { sei }
|
|
sei
|
|
// [19] *((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL -- _deref_pbuc1=vbuc2
|
|
// Disable CIA 1 Timer IRQ
|
|
lda #CIA_INTERRUPT_CLEAR_ALL
|
|
sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT
|
|
// [20] *VICII_CONTROL1 = *VICII_CONTROL1 & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
|
// Set raster line to $60
|
|
lda #$7f
|
|
and VICII_CONTROL1
|
|
sta VICII_CONTROL1
|
|
// [21] *RASTER = $60 -- _deref_pbuc1=vbuc2
|
|
lda #$60
|
|
sta RASTER
|
|
// [22] *IRQ_ENABLE = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
// Enable Raster Interrupt
|
|
lda #IRQ_RASTER
|
|
sta IRQ_ENABLE
|
|
// [23] *IRQ_STATUS = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
// Acknowledge any IRQ
|
|
lda #IRQ_RASTER
|
|
sta IRQ_STATUS
|
|
// [24] *KERNEL_IRQ = &table_driven_irq -- _deref_qprc1=pprc2
|
|
// Setup the table driven IRQ routine
|
|
lda #<table_driven_irq
|
|
sta KERNEL_IRQ
|
|
lda #>table_driven_irq
|
|
sta KERNEL_IRQ+1
|
|
// asm { cli }
|
|
cli
|
|
jmp __breturn
|
|
// main::@return
|
|
__breturn:
|
|
// [26] return
|
|
rts
|
|
}
|
|
// File Data
|
|
.segment Data
|
|
IRQ_CHANGE_IDX: .byte $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT
|
|
IRQ_CHANGE_VAL: .byte $b, $b, $63, 0, 0, $80, 7, 7, $83, 0, 0, $60
|
|
|
|
ASSEMBLER OPTIMIZATIONS
|
|
Removing instruction jmp __init1
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __breturn
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __b4
|
|
Removing instruction jmp __b5
|
|
Removing instruction jmp __b6
|
|
Removing instruction jmp __breturn
|
|
Removing instruction jmp __breturn
|
|
Succesful ASM optimization Pass5NextJumpElimination
|
|
Removing instruction ldy.z irq_idx
|
|
Removing instruction lda #IRQ_RASTER
|
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
|
Removing instruction __b1_from___init1:
|
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
|
Removing instruction __init1:
|
|
Removing instruction __b1:
|
|
Removing instruction __breturn:
|
|
Removing instruction __b4:
|
|
Removing instruction __b5:
|
|
Removing instruction __b6:
|
|
Removing instruction __breturn:
|
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
|
Skipping double jump to $ea81 in bcs __breturn
|
|
Succesful ASM optimization Pass5DoubleJumpElimination
|
|
Removing instruction __breturn:
|
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
|
Fixing long branch [75] bcs $ea81 to bcc
|
|
|
|
FINAL SYMBOL TABLE
|
|
__constant struct MOS6526_CIA * const CIA1 = (struct MOS6526_CIA *) 56320
|
|
__constant const char CIA_INTERRUPT_CLEAR_ALL = $7f
|
|
__constant char IRQ_CHANGE_IDX[] = { $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT }
|
|
__constant const char IRQ_CHANGE_NEXT = $7f
|
|
__constant char IRQ_CHANGE_VAL[] = { $b, $b, $63, 0, 0, $80, 7, 7, $83, 0, 0, $60 }
|
|
__constant char * const IRQ_ENABLE = (char *) 53274
|
|
__constant const char IRQ_RASTER = 1
|
|
__constant char * const IRQ_STATUS = (char *) 53273
|
|
__constant void (** const KERNEL_IRQ)() = (void (**)()) 788
|
|
__constant char OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
|
__constant char * const RASTER = (char *) 53266
|
|
__constant char * const SCREEN = (char *) 1024
|
|
__constant char * const VICII_BASE = (char *) 53248
|
|
__constant char * const VICII_CONTROL1 = (char *) 53265
|
|
__constant const char VICII_SIZE = $30
|
|
void __start()
|
|
__loadstore volatile char irq_idx // zp[1]:2 6.0
|
|
void main()
|
|
__interrupt(rom_min_c64) void table_driven_irq()
|
|
char table_driven_irq::idx
|
|
char table_driven_irq::idx#0 // reg byte a 11.0
|
|
char table_driven_irq::val
|
|
char table_driven_irq::val#0 // reg byte x 6.166666666666666
|
|
|
|
zp[1]:2 [ irq_idx ]
|
|
reg byte a [ table_driven_irq::idx#0 ]
|
|
reg byte x [ table_driven_irq::val#0 ]
|
|
|
|
|
|
FINAL ASSEMBLER
|
|
Score: 625
|
|
|
|
// File Comments
|
|
// Test interrupt routine using a variable between calls (irq_idx)
|
|
/// @file
|
|
/// Commodore 64 Registers and Constants
|
|
/// @file
|
|
/// The MOS 6526 Complex Interface Adapter (CIA)
|
|
///
|
|
/// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
|
|
// Upstart
|
|
// Commodore 64 PRG executable file
|
|
.file [name="irq-idx-problem.prg", type="prg", segments="Program"]
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
.segmentdef Basic [start=$0801]
|
|
.segmentdef Code [start=$80d]
|
|
.segmentdef Data [startAfter="Code"]
|
|
.segment Basic
|
|
:BasicUpstart(__start)
|
|
// Global Constants & labels
|
|
/// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
|
|
.const CIA_INTERRUPT_CLEAR_ALL = $7f
|
|
/// VICII IRQ Status/Enable Raster
|
|
// @see #IRQ_ENABLE #IRQ_STATUS
|
|
/// 0 | RST| Reaching a certain raster line. The line is specified by writing
|
|
/// | | to register 0xd012 and bit 7 of $d011 and internally stored by
|
|
/// | | the VIC for the raster compare. The test for reaching the
|
|
/// | | interrupt raster line is done in cycle 0 of every line (for line
|
|
/// | | 0, in cycle 1).
|
|
.const IRQ_RASTER = 1
|
|
.const VICII_SIZE = $30
|
|
.const IRQ_CHANGE_NEXT = $7f
|
|
.const OFFSET_STRUCT_MOS6526_CIA_INTERRUPT = $d
|
|
/// $D012 RASTER Raster counter
|
|
.label RASTER = $d012
|
|
/// $D011 Control Register #1
|
|
/// - Bit#0-#2: YSCROLL Screen Soft Scroll Vertical
|
|
/// - Bit#3: RSEL Switch betweem 25 or 24 visible rows
|
|
/// RSEL| Display window height | First line | Last line
|
|
/// ----+--------------------------+-------------+----------
|
|
/// 0 | 24 text lines/192 pixels | 55 ($37) | 246 ($f6)
|
|
/// 1 | 25 text lines/200 pixels | 51 ($33) | 250 ($fa)
|
|
/// - Bit#4: DEN Switch VIC-II output on/off
|
|
/// - Bit#5: BMM Turn Bitmap Mode on/off
|
|
/// - Bit#6: ECM Turn Extended Color Mode on/off
|
|
/// - Bit#7: RST8 9th Bit for $D012 Rasterline counter
|
|
/// Initial Value: %10011011
|
|
.label VICII_CONTROL1 = $d011
|
|
/// VIC II IRQ Status Register
|
|
.label IRQ_STATUS = $d019
|
|
/// VIC II IRQ Enable Register
|
|
.label IRQ_ENABLE = $d01a
|
|
/// The CIA#1: keyboard matrix, joystick #1/#2
|
|
.label CIA1 = $dc00
|
|
/// The vector used when the KERNAL serves IRQ interrupts
|
|
.label KERNEL_IRQ = $314
|
|
.label SCREEN = $400
|
|
.label VICII_BASE = $d000
|
|
.label irq_idx = 2
|
|
.segment Code
|
|
// __start
|
|
__start: {
|
|
// __start::__init1
|
|
// volatile byte irq_idx = 0
|
|
// [1] irq_idx = 0 -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z irq_idx
|
|
// [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
|
|
// __start::@1
|
|
// [3] call main
|
|
jsr main
|
|
// __start::@return
|
|
// [4] return
|
|
rts
|
|
}
|
|
// table_driven_irq
|
|
table_driven_irq: {
|
|
// interrupt(isr_rom_min_c64_entry) -- isr_rom_min_c64_entry
|
|
// table_driven_irq::@1
|
|
__b1:
|
|
// byte idx = IRQ_CHANGE_IDX[irq_idx]
|
|
// [6] table_driven_irq::idx#0 = IRQ_CHANGE_IDX[irq_idx] -- vbuaa=pbuc1_derefidx_vbuz1
|
|
ldy.z irq_idx
|
|
lda IRQ_CHANGE_IDX,y
|
|
// byte val = IRQ_CHANGE_VAL[irq_idx]
|
|
// [7] table_driven_irq::val#0 = IRQ_CHANGE_VAL[irq_idx] -- vbuxx=pbuc1_derefidx_vbuz1
|
|
ldx IRQ_CHANGE_VAL,y
|
|
// irq_idx++;
|
|
// [8] irq_idx = ++ irq_idx -- vbuz1=_inc_vbuz1
|
|
inc.z irq_idx
|
|
// if (idx < VICII_SIZE)
|
|
// [9] if(table_driven_irq::idx#0<VICII_SIZE) goto table_driven_irq::@2 -- vbuaa_lt_vbuc1_then_la1
|
|
cmp #VICII_SIZE
|
|
bcc __b2
|
|
// table_driven_irq::@4
|
|
// if (idx < VICII_SIZE + 8)
|
|
// [10] if(table_driven_irq::idx#0<VICII_SIZE+8) goto table_driven_irq::@3 -- vbuaa_lt_vbuc1_then_la1
|
|
cmp #VICII_SIZE+8
|
|
bcc __b3
|
|
// table_driven_irq::@5
|
|
// *IRQ_STATUS = IRQ_RASTER
|
|
// [11] *IRQ_STATUS = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
lda #IRQ_RASTER
|
|
sta IRQ_STATUS
|
|
// *RASTER = val
|
|
// [12] *RASTER = table_driven_irq::val#0 -- _deref_pbuc1=vbuxx
|
|
stx RASTER
|
|
// if (val < *RASTER)
|
|
// [13] if(table_driven_irq::val#0>=*RASTER) goto table_driven_irq::@return -- vbuxx_ge__deref_pbuc1_then_la1
|
|
cpx RASTER
|
|
bcc !__ea81+
|
|
jmp $ea81
|
|
!__ea81:
|
|
// table_driven_irq::@6
|
|
// irq_idx = 0
|
|
// [14] irq_idx = 0 -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z irq_idx
|
|
// table_driven_irq::@return
|
|
// }
|
|
// [15] return
|
|
// interrupt(isr_rom_min_c64_exit) -- isr_rom_min_c64_exit
|
|
jmp $ea81
|
|
// table_driven_irq::@3
|
|
__b3:
|
|
// SCREEN[idx + $3f8 - VICII_SIZE] = val
|
|
// [16] (SCREEN+-VICII_SIZE+$3f8)[table_driven_irq::idx#0] = table_driven_irq::val#0 -- pbuc1_derefidx_vbuaa=vbuxx
|
|
tay
|
|
txa
|
|
sta SCREEN+-VICII_SIZE+$3f8,y
|
|
jmp __b1
|
|
// table_driven_irq::@2
|
|
__b2:
|
|
// VICII_BASE[idx] = val
|
|
// [17] VICII_BASE[table_driven_irq::idx#0] = table_driven_irq::val#0 -- pbuc1_derefidx_vbuaa=vbuxx
|
|
tay
|
|
txa
|
|
sta VICII_BASE,y
|
|
jmp __b1
|
|
}
|
|
// main
|
|
main: {
|
|
// asm
|
|
// asm { sei }
|
|
sei
|
|
// CIA1->INTERRUPT = CIA_INTERRUPT_CLEAR_ALL
|
|
// [19] *((char *)CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT) = CIA_INTERRUPT_CLEAR_ALL -- _deref_pbuc1=vbuc2
|
|
// Disable CIA 1 Timer IRQ
|
|
lda #CIA_INTERRUPT_CLEAR_ALL
|
|
sta CIA1+OFFSET_STRUCT_MOS6526_CIA_INTERRUPT
|
|
// *VICII_CONTROL1 &=$7f
|
|
// [20] *VICII_CONTROL1 = *VICII_CONTROL1 & $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
|
|
// Set raster line to $60
|
|
lda #$7f
|
|
and VICII_CONTROL1
|
|
sta VICII_CONTROL1
|
|
// *RASTER = $60
|
|
// [21] *RASTER = $60 -- _deref_pbuc1=vbuc2
|
|
lda #$60
|
|
sta RASTER
|
|
// *IRQ_ENABLE = IRQ_RASTER
|
|
// [22] *IRQ_ENABLE = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
// Enable Raster Interrupt
|
|
lda #IRQ_RASTER
|
|
sta IRQ_ENABLE
|
|
// *IRQ_STATUS = IRQ_RASTER
|
|
// [23] *IRQ_STATUS = IRQ_RASTER -- _deref_pbuc1=vbuc2
|
|
// Acknowledge any IRQ
|
|
sta IRQ_STATUS
|
|
// *KERNEL_IRQ = &table_driven_irq
|
|
// [24] *KERNEL_IRQ = &table_driven_irq -- _deref_qprc1=pprc2
|
|
// Setup the table driven IRQ routine
|
|
lda #<table_driven_irq
|
|
sta KERNEL_IRQ
|
|
lda #>table_driven_irq
|
|
sta KERNEL_IRQ+1
|
|
// asm
|
|
// asm { cli }
|
|
cli
|
|
// main::@return
|
|
// }
|
|
// [26] return
|
|
rts
|
|
}
|
|
// File Data
|
|
.segment Data
|
|
IRQ_CHANGE_IDX: .byte $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT, $20, $21, IRQ_CHANGE_NEXT
|
|
IRQ_CHANGE_VAL: .byte $b, $b, $63, 0, 0, $80, 7, 7, $83, 0, 0, $60
|
|
|