1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-10 10:29:36 +00:00
kickc/src/test/ref/irq-idx-problem.log
2024-01-02 19:21:16 +01:00

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