diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index ab8f2ef99..6a031aa11 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -46,6 +46,16 @@ public class TestPrograms { AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false); } + @Test + public void testIrqHyperscreen() throws IOException, URISyntaxException { + compileAndCompare("irq-hyperscreen"); + } + + @Test + public void testIrqRaster() throws IOException, URISyntaxException { + compileAndCompare("irq-raster"); + } + @Test public void testInterruptVolatile() throws IOException, URISyntaxException { compileAndCompare("test-interrupt-volatile"); diff --git a/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc b/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc new file mode 100644 index 000000000..c72a40359 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc @@ -0,0 +1,60 @@ +// A raster IRQ that opens the top/bottom border. + +const void()** KERNEL_IRQ = $0314; +const byte* RASTER = $d012; +const byte* VIC_CONTROL = $d011; +const byte VIC_RSEL = $8; +const byte* IRQ_STATUS = $d019; +const byte* IRQ_ENABLE = $d01a; +const byte IRQ_RASTER = %00000001; +const byte IRQ_COLLISION_BG = %00000010; +const byte IRQ_COLLISION_SPRITE = %00000100; +const byte IRQ_LIGHTPEN = %00001000; +const byte* BGCOL = $d020; +const byte* FGCOL = $d021; +const byte WHITE = 1; +const byte RED = 2; + +const byte* CIA1_INTERRUPT = $dc0d; +const byte CIA_INTERRUPT_CLEAR = $7f; + +const byte* GHOST_BYTE = $3fff; + +void main() { + *GHOST_BYTE = 0; + asm { sei } + // Disable CIA 1 Timer IRQ + *CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR; + // Set raster line to $100 + *VIC_CONTROL &=$7f; + *RASTER = $fa; + // Enable Raster Interrupt + *IRQ_ENABLE = IRQ_RASTER; + // Set the IRQ routine + *KERNEL_IRQ = &irq_bottom_1; + asm { cli } +} + +// Interrupt Routine 1 +interrupt void irq_bottom_1() { + *FGCOL = WHITE; + *VIC_CONTROL &= ($ff^VIC_RSEL); + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; + // Trigger IRQ 2 at line $fd + *RASTER = $fd; + *KERNEL_IRQ = &irq_bottom_2; + *FGCOL = RED; +} + +// Interrupt Routine 2 +interrupt void irq_bottom_2() { + *FGCOL = WHITE; + *VIC_CONTROL |= VIC_RSEL; + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; + // Trigger IRQ 1 at line $fa + *RASTER = $fa; + *KERNEL_IRQ = &irq_bottom_1; + *FGCOL = RED; +} \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/kc/irq-raster.kc b/src/test/java/dk/camelot64/kickc/test/kc/irq-raster.kc new file mode 100644 index 000000000..9a2547324 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/kc/irq-raster.kc @@ -0,0 +1,39 @@ +// A minimal working raster IRQ + +const void()** KERNEL_IRQ = $0314; +const byte* RASTER = $d012; +const byte* VIC_CONTROL = $d011; +const byte* IRQ_STATUS = $d019; +const byte* IRQ_ENABLE = $d01a; +const byte IRQ_RASTER = %00000001; +const byte IRQ_COLLISION_BG = %00000010; +const byte IRQ_COLLISION_SPRITE = %00000100; +const byte IRQ_LIGHTPEN = %00001000; +const byte* BGCOL = $d020; +const byte WHITE = 1; +const byte BLACK = 0; + +const byte* CIA1_INTERRUPT = $dc0d; +const byte CIA_INTERRUPT_CLEAR = $7f; + +void main() { + asm { sei } + // Disable CIA 1 Timer IRQ + *CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR; + // Set raster line to $100 + *VIC_CONTROL |=$80; + *RASTER = $00; + // Enable Raster Interrupt + *IRQ_ENABLE = IRQ_RASTER; + // Set the IRQ routine + *KERNEL_IRQ = &irq; + asm { cli } +} + +// Interrupt Routine +interrupt void irq() { + *BGCOL = WHITE; + *BGCOL = BLACK; + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; +} \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm new file mode 100644 index 000000000..6451b0043 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm @@ -0,0 +1,73 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .const VIC_RSEL = 8 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label FGCOL = $d021 + .const WHITE = 1 + .const RED = 2 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f + .label GHOST_BYTE = $3fff + jsr main +main: { + lda #0 + sta GHOST_BYTE + sei + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + lda VIC_CONTROL + and #$7f + sta VIC_CONTROL + lda #$fa + sta RASTER + lda #IRQ_RASTER + sta IRQ_ENABLE + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + cli + rts +} +irq_bottom_2: { + lda #WHITE + sta FGCOL + lda VIC_CONTROL + ora #VIC_RSEL + sta VIC_CONTROL + lda #IRQ_RASTER + sta IRQ_STATUS + lda #$fa + sta RASTER + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + lda #RED + sta FGCOL + jmp $ea81 +} +irq_bottom_1: { + lda #WHITE + sta FGCOL + lda VIC_CONTROL + and #$ff^VIC_RSEL + sta VIC_CONTROL + lda #IRQ_RASTER + sta IRQ_STATUS + lda #$fd + sta RASTER + lda #irq_bottom_2 + sta KERNEL_IRQ+1 + lda #RED + sta FGCOL + jmp $ea81 +} diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg new file mode 100644 index 000000000..fcf358d7f --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg @@ -0,0 +1,44 @@ +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@3 +@3: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main [ ] ( ) + to:@end +@end: scope:[] from @3 + [3] phi() [ ] ( ) +main: scope:[main] from @3 + [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) + asm { sei } + [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) + [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) + [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) + [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) + [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [12] return [ ] ( main:2 [ ] ) + to:@return +irq_bottom_2: scope:[irq_bottom_2] from + [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) + [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) + [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) + [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + to:irq_bottom_2::@return +irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2 + [19] return [ ] ( ) + to:@return +irq_bottom_1: scope:[irq_bottom_1] from + [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) + [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) + [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) + [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + to:irq_bottom_1::@return +irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 + [26] return [ ] ( ) + to:@return diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log new file mode 100644 index 000000000..172ea8219 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log @@ -0,0 +1,882 @@ +PARSING src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc +// A raster IRQ that opens the top/bottom border. + +const void()** KERNEL_IRQ = $0314; +const byte* RASTER = $d012; +const byte* VIC_CONTROL = $d011; +const byte VIC_RSEL = $8; +const byte* IRQ_STATUS = $d019; +const byte* IRQ_ENABLE = $d01a; +const byte IRQ_RASTER = %00000001; +const byte IRQ_COLLISION_BG = %00000010; +const byte IRQ_COLLISION_SPRITE = %00000100; +const byte IRQ_LIGHTPEN = %00001000; +const byte* BGCOL = $d020; +const byte* FGCOL = $d021; +const byte WHITE = 1; +const byte RED = 2; + +const byte* CIA1_INTERRUPT = $dc0d; +const byte CIA_INTERRUPT_CLEAR = $7f; + +const byte* GHOST_BYTE = $3fff; + +void main() { + *GHOST_BYTE = 0; + asm { sei } + // Disable CIA 1 Timer IRQ + *CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR; + // Set raster line to $100 + *VIC_CONTROL &=$7f; + *RASTER = $fa; + // Enable Raster Interrupt + *IRQ_ENABLE = IRQ_RASTER; + // Set the IRQ routine + *KERNEL_IRQ = &irq_bottom_1; + asm { cli } +} + +// Interrupt Routine 1 +interrupt void irq_bottom_1() { + *FGCOL = WHITE; + *VIC_CONTROL &= ($ff^VIC_RSEL); + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; + // Trigger IRQ 2 at line $fd + *RASTER = $fd; + *KERNEL_IRQ = &irq_bottom_2; + *FGCOL = RED; +} + +// Interrupt Routine 2 +interrupt void irq_bottom_2() { + *FGCOL = WHITE; + *VIC_CONTROL |= VIC_RSEL; + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; + // Trigger IRQ 1 at line $fa + *RASTER = $fa; + *KERNEL_IRQ = &irq_bottom_1; + *FGCOL = RED; +} +Resolved forward reference irq_bottom_1 to interrupt(KERNEL)(void()) irq_bottom_1() +Resolved forward reference irq_bottom_2 to interrupt(KERNEL)(void()) irq_bottom_2() +SYMBOLS +(label) @1 +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte*) BGCOL +(byte*) CIA1_INTERRUPT +(byte) CIA_INTERRUPT_CLEAR +(byte*) FGCOL +(byte*) GHOST_BYTE +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) RASTER +(byte) RED +(byte*) VIC_CONTROL +(byte) VIC_RSEL +(byte) WHITE +interrupt(KERNEL)(void()) irq_bottom_1() +(byte/word/dword~) irq_bottom_1::$0 +(void()*~) irq_bottom_1::$1 +(label) irq_bottom_1::@return +interrupt(KERNEL)(void()) irq_bottom_2() +(void()*~) irq_bottom_2::$0 +(label) irq_bottom_2::@return +(void()) main() +(void()*~) main::$0 +(label) main::@return + +Promoting word/signed word/dword/signed dword to void()** in KERNEL_IRQ ← ((void()**)) 788 +Promoting word/dword/signed dword to byte* in RASTER ← ((byte*)) 53266 +Promoting word/dword/signed dword to byte* in VIC_CONTROL ← ((byte*)) 53265 +Promoting word/dword/signed dword to byte* in IRQ_STATUS ← ((byte*)) 53273 +Promoting word/dword/signed dword to byte* in IRQ_ENABLE ← ((byte*)) 53274 +Promoting word/dword/signed dword to byte* in BGCOL ← ((byte*)) 53280 +Promoting word/dword/signed dword to byte* in FGCOL ← ((byte*)) 53281 +Promoting word/dword/signed dword to byte* in CIA1_INTERRUPT ← ((byte*)) 56333 +Promoting word/signed word/dword/signed dword to byte* in GHOST_BYTE ← ((byte*)) 16383 +INITIAL CONTROL FLOW GRAPH +@begin: scope:[] from + (void()**) KERNEL_IRQ ← ((void()**)) (word/signed word/dword/signed dword) 788 + (byte*) RASTER ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) VIC_CONTROL ← ((byte*)) (word/dword/signed dword) 53265 + (byte) VIC_RSEL ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) IRQ_STATUS ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280 + (byte*) FGCOL ← ((byte*)) (word/dword/signed dword) 53281 + (byte) WHITE ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) RED ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte*) CIA1_INTERRUPT ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR ← (byte/signed byte/word/signed word/dword/signed dword) 127 + (byte*) GHOST_BYTE ← ((byte*)) (word/signed word/dword/signed dword) 16383 + to:@1 +main: scope:[main] from + *((byte*) GHOST_BYTE) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + asm { sei } + *((byte*) CIA1_INTERRUPT) ← (byte) CIA_INTERRUPT_CLEAR + *((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) & (byte/signed byte/word/signed word/dword/signed dword) 127 + *((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 250 + *((byte*) IRQ_ENABLE) ← (byte) IRQ_RASTER + (void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1() + *((void()**) KERNEL_IRQ) ← (void()*~) main::$0 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + to:@2 +irq_bottom_1: scope:[irq_bottom_1] from + *((byte*) FGCOL) ← (byte) WHITE + (byte/word/dword~) irq_bottom_1::$0 ← (byte/word/signed word/dword/signed dword) 255 ^ (byte) VIC_RSEL + *((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) & (byte/word/dword~) irq_bottom_1::$0 + *((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER + *((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 253 + (void()*~) irq_bottom_1::$1 ← & interrupt(KERNEL)(void()) irq_bottom_2() + *((void()**) KERNEL_IRQ) ← (void()*~) irq_bottom_1::$1 + *((byte*) FGCOL) ← (byte) RED + to:irq_bottom_1::@return +irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 + return + to:@return +@2: scope:[] from @1 + to:@3 +irq_bottom_2: scope:[irq_bottom_2] from + *((byte*) FGCOL) ← (byte) WHITE + *((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) | (byte) VIC_RSEL + *((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER + *((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 250 + (void()*~) irq_bottom_2::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1() + *((void()**) KERNEL_IRQ) ← (void()*~) irq_bottom_2::$0 + *((byte*) FGCOL) ← (byte) RED + to:irq_bottom_2::@return +irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2 + return + to:@return +@3: scope:[] from @2 + call main + to:@end +@end: scope:[] from @3 + +Eliminating unused variable (byte) IRQ_COLLISION_BG and assignment [7] (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2 +Eliminating unused variable (byte) IRQ_COLLISION_SPRITE and assignment [8] (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4 +Eliminating unused variable (byte) IRQ_LIGHTPEN and assignment [9] (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8 +Eliminating unused variable (byte*) BGCOL and assignment [10] (byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280 +Removing empty block @1 +Removing empty block @2 +PROCEDURE MODIFY VARIABLE ANALYSIS + +Completing Phi functions... + +CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN +@begin: scope:[] from + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte*) FGCOL#0 ← ((byte*)) (word/dword/signed dword) 53281 + (byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) RED#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127 + (byte*) GHOST_BYTE#0 ← ((byte*)) (word/signed word/dword/signed dword) 16383 + to:@3 +main: scope:[main] from @3 + *((byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + asm { sei } + *((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0 + *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 + *((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 + *((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0 + (void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1() + *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +irq_bottom_1: scope:[irq_bottom_1] from + *((byte*) FGCOL#0) ← (byte) WHITE#0 + (byte/word/dword~) irq_bottom_1::$0 ← (byte/word/signed word/dword/signed dword) 255 ^ (byte) VIC_RSEL#0 + *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) & (byte/word/dword~) irq_bottom_1::$0 + *((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0 + *((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 + (void()*~) irq_bottom_1::$1 ← & interrupt(KERNEL)(void()) irq_bottom_2() + *((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_1::$1 + *((byte*) FGCOL#0) ← (byte) RED#0 + to:irq_bottom_1::@return +irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 + return + to:@return +irq_bottom_2: scope:[irq_bottom_2] from + *((byte*) FGCOL#0) ← (byte) WHITE#0 + *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (byte) VIC_RSEL#0 + *((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0 + *((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 + (void()*~) irq_bottom_2::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1() + *((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_2::$0 + *((byte*) FGCOL#0) ← (byte) RED#0 + to:irq_bottom_2::@return +irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2 + return + to:@return +@3: scope:[] from @begin + call main + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +SYMBOL TABLE SSA +(label) @3 +(label) @4 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(byte*) CIA1_INTERRUPT#0 +(byte) CIA_INTERRUPT_CLEAR +(byte) CIA_INTERRUPT_CLEAR#0 +(byte*) FGCOL +(byte*) FGCOL#0 +(byte*) GHOST_BYTE +(byte*) GHOST_BYTE#0 +(byte*) IRQ_ENABLE +(byte*) IRQ_ENABLE#0 +(byte) IRQ_RASTER +(byte) IRQ_RASTER#0 +(byte*) IRQ_STATUS +(byte*) IRQ_STATUS#0 +(void()**) KERNEL_IRQ +(void()**) KERNEL_IRQ#0 +(byte*) RASTER +(byte*) RASTER#0 +(byte) RED +(byte) RED#0 +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL#0 +(byte) VIC_RSEL +(byte) VIC_RSEL#0 +(byte) WHITE +(byte) WHITE#0 +interrupt(KERNEL)(void()) irq_bottom_1() +(byte/word/dword~) irq_bottom_1::$0 +(void()*~) irq_bottom_1::$1 +(label) irq_bottom_1::@return +interrupt(KERNEL)(void()) irq_bottom_2() +(void()*~) irq_bottom_2::$0 +(label) irq_bottom_2::@return +(void()) main() +(void()*~) main::$0 +(label) main::@return + +OPTIMIZING CONTROL FLOW GRAPH +Culled Empty Block (label) @4 +Succesful SSA optimization Pass2CullEmptyBlocks +Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const byte*) RASTER#0 = ((byte*))53266 +Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265 +Constant (const byte) VIC_RSEL#0 = 8 +Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 +Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274 +Constant (const byte) IRQ_RASTER#0 = 1 +Constant (const byte*) FGCOL#0 = ((byte*))53281 +Constant (const byte) WHITE#0 = 1 +Constant (const byte) RED#0 = 2 +Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 +Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127 +Constant (const byte*) GHOST_BYTE#0 = ((byte*))16383 +Constant (const void()*) main::$0 = &irq_bottom_1 +Constant (const void()*) irq_bottom_1::$1 = &irq_bottom_2 +Constant (const void()*) irq_bottom_2::$0 = &irq_bottom_1 +Succesful SSA optimization Pass2ConstantIdentification +Constant (const byte/word/dword) irq_bottom_1::$0 = 255^VIC_RSEL#0 +Succesful SSA optimization Pass2ConstantIdentification +OPTIMIZING CONTROL FLOW GRAPH +Constant inlined irq_bottom_2::$0 = &interrupt(KERNEL)(void()) irq_bottom_1() +Constant inlined irq_bottom_1::$0 = (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 +Constant inlined main::$0 = &interrupt(KERNEL)(void()) irq_bottom_1() +Constant inlined irq_bottom_1::$1 = &interrupt(KERNEL)(void()) irq_bottom_2() +Succesful SSA optimization Pass2ConstantInlining +Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return +Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Propagating live ranges... +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +Propagating live ranges... + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@3 +@3: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main [ ] ( ) + to:@end +@end: scope:[] from @3 + [3] phi() [ ] ( ) +main: scope:[main] from @3 + [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) + asm { sei } + [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) + [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) + [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) + [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) + [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [12] return [ ] ( main:2 [ ] ) + to:@return +irq_bottom_2: scope:[irq_bottom_2] from + [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) + [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) + [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) + [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + to:irq_bottom_2::@return +irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2 + [19] return [ ] ( ) + to:@return +irq_bottom_1: scope:[irq_bottom_1] from + [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) + [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) + [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) + [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + to:irq_bottom_1::@return +irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 + [26] return [ ] ( ) + to:@return + +DOMINATORS +@begin dominated by @begin +@3 dominated by @begin @3 +@end dominated by @begin @3 @end +main dominated by @begin @3 main +main::@return dominated by main::@return @begin @3 main +irq_bottom_2 dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main +irq_bottom_2::@return dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main +irq_bottom_1 dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main +irq_bottom_1::@return dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main + +NATURAL LOOPS +Found back edge: Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: null +Found back edge: Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: null +Populated: Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2 +Populated: Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1 +Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2 +Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1 + +NATURAL LOOPS WITH DEPTH +Found 1 loops in scope [irq_bottom_2] + Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2 +Found 1 loops in scope [irq_bottom_1] + Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1 +Found 0 loops in scope [] +Found 0 loops in scope [main] +Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2 depth: 1 +Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1 depth: 1 + + +VARIABLE REGISTER WEIGHTS +(byte*) CIA1_INTERRUPT +(byte) CIA_INTERRUPT_CLEAR +(byte*) FGCOL +(byte*) GHOST_BYTE +(byte*) IRQ_ENABLE +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) RASTER +(byte) RED +(byte*) VIC_CONTROL +(byte) VIC_RSEL +(byte) WHITE +interrupt(KERNEL)(void()) irq_bottom_1() +interrupt(KERNEL)(void()) irq_bottom_2() +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .const VIC_RSEL = 8 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label FGCOL = $d021 + .const WHITE = 1 + .const RED = 2 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f + .label GHOST_BYTE = $3fff +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @3 [phi:@begin->@3] +b3_from_bbegin: + jmp b3 +//SEG4 @3 +b3: +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @3 to @end [phi:@3->@end] +bend_from_b3: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta GHOST_BYTE + //SEG10 asm { sei } + sei + //SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$7f + sta VIC_CONTROL + //SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG16 asm { cli } + cli + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [12] return [ ] ( main:2 [ ] ) + rts +} +//SEG19 irq_bottom_2 +irq_bottom_2: { + //SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #VIC_RSEL + sta VIC_CONTROL + //SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + jmp breturn + //SEG26 irq_bottom_2::@return + breturn: + //SEG27 [19] return [ ] ( ) + jmp $ea81 +} +//SEG28 irq_bottom_1 +irq_bottom_1: { + //SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$ff^VIC_RSEL + sta VIC_CONTROL + //SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fd + sta RASTER + //SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_2 + sta KERNEL_IRQ+1 + //SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + jmp breturn + //SEG35 irq_bottom_1::@return + breturn: + //SEG36 [26] return [ ] ( ) + jmp $ea81 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a +Statement [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) always clobbers reg byte a +Statement [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a +Statement [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) always clobbers reg byte a +Statement [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) always clobbers reg byte a +Statement [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a +Statement [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a +Statement [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) always clobbers reg byte a +Statement [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a +Statement [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) always clobbers reg byte a +Statement [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) always clobbers reg byte a +Statement [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [irq_bottom_1] +Uplift Scope [irq_bottom_2] +Uplift Scope [] + +Uplifting [main] best 1057 combination +Uplifting [irq_bottom_1] best 1057 combination +Uplifting [irq_bottom_2] best 1057 combination +Uplifting [] best 1057 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .const VIC_RSEL = 8 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label FGCOL = $d021 + .const WHITE = 1 + .const RED = 2 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f + .label GHOST_BYTE = $3fff +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @3 [phi:@begin->@3] +b3_from_bbegin: + jmp b3 +//SEG4 @3 +b3: +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @3 to @end [phi:@3->@end] +bend_from_b3: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta GHOST_BYTE + //SEG10 asm { sei } + sei + //SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$7f + sta VIC_CONTROL + //SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG16 asm { cli } + cli + jmp breturn + //SEG17 main::@return + breturn: + //SEG18 [12] return [ ] ( main:2 [ ] ) + rts +} +//SEG19 irq_bottom_2 +irq_bottom_2: { + //SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #VIC_RSEL + sta VIC_CONTROL + //SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + jmp breturn + //SEG26 irq_bottom_2::@return + breturn: + //SEG27 [19] return [ ] ( ) + jmp $ea81 +} +//SEG28 irq_bottom_1 +irq_bottom_1: { + //SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$ff^VIC_RSEL + sta VIC_CONTROL + //SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fd + sta RASTER + //SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_2 + sta KERNEL_IRQ+1 + //SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + jmp breturn + //SEG35 irq_bottom_1::@return + breturn: + //SEG36 [26] return [ ] ( ) + jmp $ea81 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b3 +Removing instruction jmp bend +Removing instruction jmp breturn +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Removing instruction b3_from_bbegin: +Removing instruction bend_from_b3: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction b3: +Removing instruction bend: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @3 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333 +(byte) CIA_INTERRUPT_CLEAR +(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127 +(byte*) FGCOL +(const byte*) FGCOL#0 FGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) GHOST_BYTE +(const byte*) GHOST_BYTE#0 GHOST_BYTE = ((byte*))(word/signed word/dword/signed dword) 16383 +(byte*) IRQ_ENABLE +(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274 +(byte) IRQ_RASTER +(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) RASTER +(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266 +(byte) RED +(const byte) RED#0 RED = (byte/signed byte/word/signed word/dword/signed dword) 2 +(byte*) VIC_CONTROL +(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265 +(byte) VIC_RSEL +(const byte) VIC_RSEL#0 VIC_RSEL = (byte/signed byte/word/signed word/dword/signed dword) 8 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +interrupt(KERNEL)(void()) irq_bottom_1() +(label) irq_bottom_1::@return +interrupt(KERNEL)(void()) irq_bottom_2() +(label) irq_bottom_2::@return +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 988 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .const VIC_RSEL = 8 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label FGCOL = $d021 + .const WHITE = 1 + .const RED = 2 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f + .label GHOST_BYTE = $3fff +//SEG2 @begin +//SEG3 [1] phi from @begin to @3 [phi:@begin->@3] +//SEG4 @3 +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @3 to @end [phi:@3->@end] +//SEG7 @end +//SEG8 main +main: { + //SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta GHOST_BYTE + //SEG10 asm { sei } + sei + //SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$7f + sta VIC_CONTROL + //SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG16 asm { cli } + cli + //SEG17 main::@return + //SEG18 [12] return [ ] ( main:2 [ ] ) + rts +} +//SEG19 irq_bottom_2 +irq_bottom_2: { + //SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #VIC_RSEL + sta VIC_CONTROL + //SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fa + sta RASTER + //SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_1 + sta KERNEL_IRQ+1 + //SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + //SEG26 irq_bottom_2::@return + //SEG27 [19] return [ ] ( ) + jmp $ea81 +} +//SEG28 irq_bottom_1 +irq_bottom_1: { + //SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta FGCOL + //SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + lda VIC_CONTROL + and #$ff^VIC_RSEL + sta VIC_CONTROL + //SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #$fd + sta RASTER + //SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2 + lda #irq_bottom_2 + sta KERNEL_IRQ+1 + //SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #RED + sta FGCOL + //SEG35 irq_bottom_1::@return + //SEG36 [26] return [ ] ( ) + jmp $ea81 +} + diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym new file mode 100644 index 000000000..eec2a8dfb --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym @@ -0,0 +1,36 @@ +(label) @3 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333 +(byte) CIA_INTERRUPT_CLEAR +(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127 +(byte*) FGCOL +(const byte*) FGCOL#0 FGCOL = ((byte*))(word/dword/signed dword) 53281 +(byte*) GHOST_BYTE +(const byte*) GHOST_BYTE#0 GHOST_BYTE = ((byte*))(word/signed word/dword/signed dword) 16383 +(byte*) IRQ_ENABLE +(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274 +(byte) IRQ_RASTER +(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) RASTER +(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266 +(byte) RED +(const byte) RED#0 RED = (byte/signed byte/word/signed word/dword/signed dword) 2 +(byte*) VIC_CONTROL +(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265 +(byte) VIC_RSEL +(const byte) VIC_RSEL#0 VIC_RSEL = (byte/signed byte/word/signed word/dword/signed dword) 8 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +interrupt(KERNEL)(void()) irq_bottom_1() +(label) irq_bottom_1::@return +interrupt(KERNEL)(void()) irq_bottom_2() +(label) irq_bottom_2::@return +(void()) main() +(label) main::@return + diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.asm b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.asm new file mode 100644 index 000000000..228dd630a --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.asm @@ -0,0 +1,42 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label BGCOL = $d020 + .const WHITE = 1 + .const BLACK = 0 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f + jsr main +main: { + sei + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + lda VIC_CONTROL + ora #$80 + sta VIC_CONTROL + lda #0 + sta RASTER + lda #IRQ_RASTER + sta IRQ_ENABLE + lda #irq + sta KERNEL_IRQ+1 + cli + rts +} +irq: { + lda #WHITE + sta BGCOL + lda #BLACK + sta BGCOL + lda #IRQ_RASTER + sta IRQ_STATUS + jmp $ea81 +} diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.cfg b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.cfg new file mode 100644 index 000000000..4a586b290 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.cfg @@ -0,0 +1,29 @@ +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@2 +@2: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main [ ] ( ) + to:@end +@end: scope:[] from @2 + [3] phi() [ ] ( ) +main: scope:[main] from @2 + asm { sei } + [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) + [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) + [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) + [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) + [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [11] return [ ] ( main:2 [ ] ) + to:@return +irq: scope:[irq] from + [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) + [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + to:irq::@return +irq::@return: scope:[irq] from irq + [15] return [ ] ( ) + to:@return diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.log b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.log new file mode 100644 index 000000000..eb5da27f1 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.log @@ -0,0 +1,604 @@ +PARSING src/test/java/dk/camelot64/kickc/test/kc/irq-raster.kc +// A minimal working raster IRQ + +const void()** KERNEL_IRQ = $0314; +const byte* RASTER = $d012; +const byte* VIC_CONTROL = $d011; +const byte* IRQ_STATUS = $d019; +const byte* IRQ_ENABLE = $d01a; +const byte IRQ_RASTER = %00000001; +const byte IRQ_COLLISION_BG = %00000010; +const byte IRQ_COLLISION_SPRITE = %00000100; +const byte IRQ_LIGHTPEN = %00001000; +const byte* BGCOL = $d020; +const byte WHITE = 1; +const byte BLACK = 0; + +const byte* CIA1_INTERRUPT = $dc0d; +const byte CIA_INTERRUPT_CLEAR = $7f; + +void main() { + asm { sei } + // Disable CIA 1 Timer IRQ + *CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR; + // Set raster line to $100 + *VIC_CONTROL |=$80; + *RASTER = $00; + // Enable Raster Interrupt + *IRQ_ENABLE = IRQ_RASTER; + // Set the IRQ routine + *KERNEL_IRQ = &irq; + asm { cli } +} + +// Interrupt Routine +interrupt void irq() { + *BGCOL = WHITE; + *BGCOL = BLACK; + // Acknowledge the IRQ + *IRQ_STATUS = IRQ_RASTER; +} +Resolved forward reference irq to interrupt(KERNEL)(void()) irq() +SYMBOLS +(label) @1 +(label) @2 +(label) @begin +(label) @end +(byte*) BGCOL +(byte) BLACK +(byte*) CIA1_INTERRUPT +(byte) CIA_INTERRUPT_CLEAR +(byte) IRQ_COLLISION_BG +(byte) IRQ_COLLISION_SPRITE +(byte*) IRQ_ENABLE +(byte) IRQ_LIGHTPEN +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) RASTER +(byte*) VIC_CONTROL +(byte) WHITE +interrupt(KERNEL)(void()) irq() +(label) irq::@return +(void()) main() +(void()*~) main::$0 +(label) main::@return + +Promoting word/signed word/dword/signed dword to void()** in KERNEL_IRQ ← ((void()**)) 788 +Promoting word/dword/signed dword to byte* in RASTER ← ((byte*)) 53266 +Promoting word/dword/signed dword to byte* in VIC_CONTROL ← ((byte*)) 53265 +Promoting word/dword/signed dword to byte* in IRQ_STATUS ← ((byte*)) 53273 +Promoting word/dword/signed dword to byte* in IRQ_ENABLE ← ((byte*)) 53274 +Promoting word/dword/signed dword to byte* in BGCOL ← ((byte*)) 53280 +Promoting word/dword/signed dword to byte* in CIA1_INTERRUPT ← ((byte*)) 56333 +INITIAL CONTROL FLOW GRAPH +@begin: scope:[] from + (void()**) KERNEL_IRQ ← ((void()**)) (word/signed word/dword/signed dword) 788 + (byte*) RASTER ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) VIC_CONTROL ← ((byte*)) (word/dword/signed dword) 53265 + (byte*) IRQ_STATUS ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8 + (byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280 + (byte) WHITE ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) BLACK ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*) CIA1_INTERRUPT ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR ← (byte/signed byte/word/signed word/dword/signed dword) 127 + to:@1 +main: scope:[main] from + asm { sei } + *((byte*) CIA1_INTERRUPT) ← (byte) CIA_INTERRUPT_CLEAR + *((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) | (byte/word/signed word/dword/signed dword) 128 + *((byte*) RASTER) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + *((byte*) IRQ_ENABLE) ← (byte) IRQ_RASTER + (void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq() + *((void()**) KERNEL_IRQ) ← (void()*~) main::$0 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + to:@2 +irq: scope:[irq] from + *((byte*) BGCOL) ← (byte) WHITE + *((byte*) BGCOL) ← (byte) BLACK + *((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER + to:irq::@return +irq::@return: scope:[irq] from irq + return + to:@return +@2: scope:[] from @1 + call main + to:@end +@end: scope:[] from @2 + +Eliminating unused variable (byte) IRQ_COLLISION_BG and assignment [6] (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2 +Eliminating unused variable (byte) IRQ_COLLISION_SPRITE and assignment [7] (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4 +Eliminating unused variable (byte) IRQ_LIGHTPEN and assignment [8] (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8 +Removing empty block @1 +PROCEDURE MODIFY VARIABLE ANALYSIS + +Completing Phi functions... + +CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN +@begin: scope:[] from + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266 + (byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265 + (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274 + (byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 + (byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 + (byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127 + to:@2 +main: scope:[main] from @2 + asm { sei } + *((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0 + *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 + *((byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + *((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0 + (void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq() + *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +irq: scope:[irq] from + *((byte*) BGCOL#0) ← (byte) WHITE#0 + *((byte*) BGCOL#0) ← (byte) BLACK#0 + *((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0 + to:irq::@return +irq::@return: scope:[irq] from irq + return + to:@return +@2: scope:[] from @begin + call main + to:@3 +@3: scope:[] from @2 + to:@end +@end: scope:[] from @3 + +SYMBOL TABLE SSA +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte*) BGCOL +(byte*) BGCOL#0 +(byte) BLACK +(byte) BLACK#0 +(byte*) CIA1_INTERRUPT +(byte*) CIA1_INTERRUPT#0 +(byte) CIA_INTERRUPT_CLEAR +(byte) CIA_INTERRUPT_CLEAR#0 +(byte*) IRQ_ENABLE +(byte*) IRQ_ENABLE#0 +(byte) IRQ_RASTER +(byte) IRQ_RASTER#0 +(byte*) IRQ_STATUS +(byte*) IRQ_STATUS#0 +(void()**) KERNEL_IRQ +(void()**) KERNEL_IRQ#0 +(byte*) RASTER +(byte*) RASTER#0 +(byte*) VIC_CONTROL +(byte*) VIC_CONTROL#0 +(byte) WHITE +(byte) WHITE#0 +interrupt(KERNEL)(void()) irq() +(label) irq::@return +(void()) main() +(void()*~) main::$0 +(label) main::@return + +OPTIMIZING CONTROL FLOW GRAPH +Culled Empty Block (label) @3 +Succesful SSA optimization Pass2CullEmptyBlocks +Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const byte*) RASTER#0 = ((byte*))53266 +Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265 +Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 +Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274 +Constant (const byte) IRQ_RASTER#0 = 1 +Constant (const byte*) BGCOL#0 = ((byte*))53280 +Constant (const byte) WHITE#0 = 1 +Constant (const byte) BLACK#0 = 0 +Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 +Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127 +Constant (const void()*) main::$0 = &irq +Succesful SSA optimization Pass2ConstantIdentification +OPTIMIZING CONTROL FLOW GRAPH +Constant inlined main::$0 = &interrupt(KERNEL)(void()) irq() +Succesful SSA optimization Pass2ConstantInlining +Block Sequence Planned @begin @2 @end main main::@return irq irq::@return +Block Sequence Planned @begin @2 @end main main::@return irq irq::@return +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Propagating live ranges... +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Block Sequence Planned @begin @2 @end main main::@return irq irq::@return +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Propagating live ranges... + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() [ ] ( ) + to:@2 +@2: scope:[] from @begin + [1] phi() [ ] ( ) + [2] call main [ ] ( ) + to:@end +@end: scope:[] from @2 + [3] phi() [ ] ( ) +main: scope:[main] from @2 + asm { sei } + [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) + [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) + [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) + [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) + [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [11] return [ ] ( main:2 [ ] ) + to:@return +irq: scope:[irq] from + [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) + [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) + [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) + to:irq::@return +irq::@return: scope:[irq] from irq + [15] return [ ] ( ) + to:@return + +DOMINATORS +@begin dominated by @begin +@2 dominated by @2 @begin +@end dominated by @2 @begin @end +main dominated by @2 @begin main +main::@return dominated by main::@return @2 @begin main +irq dominated by main::@return @2 @begin @end irq irq::@return main +irq::@return dominated by main::@return @2 @begin @end irq irq::@return main + +NATURAL LOOPS +Found back edge: Loop head: irq::@return tails: irq blocks: null +Populated: Loop head: irq::@return tails: irq blocks: irq +Loop head: irq::@return tails: irq blocks: irq + +NATURAL LOOPS WITH DEPTH +Found 1 loops in scope [irq] + Loop head: irq::@return tails: irq blocks: irq +Found 0 loops in scope [] +Found 0 loops in scope [main] +Loop head: irq::@return tails: irq blocks: irq depth: 1 + + +VARIABLE REGISTER WEIGHTS +(byte*) BGCOL +(byte) BLACK +(byte*) CIA1_INTERRUPT +(byte) CIA_INTERRUPT_CLEAR +(byte*) IRQ_ENABLE +(byte) IRQ_RASTER +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) RASTER +(byte*) VIC_CONTROL +(byte) WHITE +interrupt(KERNEL)(void()) irq() +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label BGCOL = $d020 + .const WHITE = 1 + .const BLACK = 0 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @2 [phi:@begin->@2] +b2_from_bbegin: + jmp b2 +//SEG4 @2 +b2: +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @2 to @end [phi:@2->@end] +bend_from_b2: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #$80 + sta VIC_CONTROL + //SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta RASTER + //SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG15 asm { cli } + cli + jmp breturn + //SEG16 main::@return + breturn: + //SEG17 [11] return [ ] ( main:2 [ ] ) + rts +} +//SEG18 irq +irq: { + //SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + //SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + jmp breturn + //SEG22 irq::@return + breturn: + //SEG23 [15] return [ ] ( ) + jmp $ea81 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a +Statement [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) always clobbers reg byte a +Statement [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [irq] +Uplift Scope [] + +Uplifting [main] best 278 combination +Uplifting [irq] best 278 combination +Uplifting [] best 278 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label BGCOL = $d020 + .const WHITE = 1 + .const BLACK = 0 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @2 [phi:@begin->@2] +b2_from_bbegin: + jmp b2 +//SEG4 @2 +b2: +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @2 to @end [phi:@2->@end] +bend_from_b2: + jmp bend +//SEG7 @end +bend: +//SEG8 main +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #$80 + sta VIC_CONTROL + //SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta RASTER + //SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG15 asm { cli } + cli + jmp breturn + //SEG16 main::@return + breturn: + //SEG17 [11] return [ ] ( main:2 [ ] ) + rts +} +//SEG18 irq +irq: { + //SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + //SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + jmp breturn + //SEG22 irq::@return + breturn: + //SEG23 [15] return [ ] ( ) + jmp $ea81 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b2 +Removing instruction jmp bend +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Removing instruction b2_from_bbegin: +Removing instruction bend_from_b2: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction b2: +Removing instruction bend: +Removing instruction breturn: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @2 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) CIA1_INTERRUPT +(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333 +(byte) CIA_INTERRUPT_CLEAR +(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127 +(byte*) IRQ_ENABLE +(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274 +(byte) IRQ_RASTER +(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) RASTER +(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266 +(byte*) VIC_CONTROL +(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +interrupt(KERNEL)(void()) irq() +(label) irq::@return +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 239 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label RASTER = $d012 + .label VIC_CONTROL = $d011 + .label IRQ_STATUS = $d019 + .label IRQ_ENABLE = $d01a + .const IRQ_RASTER = 1 + .label BGCOL = $d020 + .const WHITE = 1 + .const BLACK = 0 + .label CIA1_INTERRUPT = $dc0d + .const CIA_INTERRUPT_CLEAR = $7f +//SEG2 @begin +//SEG3 [1] phi from @begin to @2 [phi:@begin->@2] +//SEG4 @2 +//SEG5 [2] call main [ ] ( ) + jsr main +//SEG6 [3] phi from @2 to @end [phi:@2->@end] +//SEG7 @end +//SEG8 main +main: { + //SEG9 asm { sei } + sei + //SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #CIA_INTERRUPT_CLEAR + sta CIA1_INTERRUPT + //SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + lda VIC_CONTROL + ora #$80 + sta VIC_CONTROL + //SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #0 + sta RASTER + //SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_ENABLE + //SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG15 asm { cli } + cli + //SEG16 main::@return + //SEG17 [11] return [ ] ( main:2 [ ] ) + rts +} +//SEG18 irq +irq: { + //SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #WHITE + sta BGCOL + //SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #BLACK + sta BGCOL + //SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + lda #IRQ_RASTER + sta IRQ_STATUS + //SEG22 irq::@return + //SEG23 [15] return [ ] ( ) + jmp $ea81 +} + diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.sym b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.sym new file mode 100644 index 000000000..641868856 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-raster.sym @@ -0,0 +1,30 @@ +(label) @2 +(label) @begin +(label) @end +(byte*) BGCOL +(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280 +(byte) BLACK +(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 +(byte*) CIA1_INTERRUPT +(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333 +(byte) CIA_INTERRUPT_CLEAR +(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127 +(byte*) IRQ_ENABLE +(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274 +(byte) IRQ_RASTER +(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1 +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) RASTER +(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266 +(byte*) VIC_CONTROL +(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265 +(byte) WHITE +(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 +interrupt(KERNEL)(void()) irq() +(label) irq::@return +(void()) main() +(label) main::@return +