1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-05-29 03:41:40 +00:00

Added example of music routines.

This commit is contained in:
jespergravgaard 2019-03-26 21:27:36 +01:00
parent 022d77fc56
commit 0993be3f01
18 changed files with 2360 additions and 73 deletions

View File

@ -1,5 +1,6 @@
3rd Party Licenses
- kickassembler is redistributed by personal permission from Mads Nielsen
- KickAssembler is redistributed by personal permission from Mads Nielsen
- Toiletrensdyr SID is redistributed by personal permission from Søren Lund
- antlr4 is redistributed under BSD License
- picocli is redistributed under Apache License 2.0
@ -7,6 +8,9 @@
KickAssembler - https://theweb.dk/KickAssembler/
-------------------------------------------------
-------------------------------------------------
Toiletrensdyr - https://csdb.dk/sid/?id=54859
-------------------------------------------------
-------------------------------------------------
ANTLR4 - http://www.antlr.org/

View File

@ -32,6 +32,17 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testMusicIrq() throws IOException, URISyntaxException {
compileAndCompare("examples/music/music_irq");
}
@Test
public void testMusic() throws IOException, URISyntaxException {
compileAndCompare("examples/music/music");
}
@Test
public void testConstEarlyIdentification() throws IOException, URISyntaxException {
compileAndCompare("const-early-identification");

View File

@ -0,0 +1,29 @@
// A simple SID music player playing music in the main loop.
import "c64.kc"
const byte* MUSIC = $1000;
// Load the SID
kickasm(resource "toiletrensdyr.sid") {{
.const music = LoadSid("toiletrensdyr.sid")
}}
// Place the SID into memory
kickasm(pc MUSIC) {{
.fill music.size, music.getData(i)
}}
// Play the music
void main() {
// Initialize the music
asm { jsr music.init }
do {
// Wait for the RASTER
do {} while (*RASTER != $fd);
(*BORDERCOL)++;
// Play the music
asm { jsr music.play }
(*BORDERCOL)--;
} while (true);
}

View File

@ -0,0 +1,43 @@
// A simple SID music player using RASTER IRQ
import "c64.kc"
const byte* MUSIC = $1000;
// Load the SID
kickasm(resource "toiletrensdyr.sid") {{
.const music = LoadSid("toiletrensdyr.sid")
}}
// Place the SID into memory
kickasm(pc MUSIC) {{
.fill music.size, music.getData(i)
}}
// Setup Raster IRQ and initialize SID player
void main() {
asm {
sei
jsr music.init
}
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to $fd
*VIC_CONTROL &=$7f;
*RASTER = $fd;
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq_play;
asm { cli }
}
// Raster IRQ Routine playing music
interrupt(kernel_keyboard) void irq_play() {
(*BORDERCOL)++;
// Play SID
asm { jsr music.play }
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
(*BORDERCOL)--;
}

Binary file not shown.

View File

@ -4,10 +4,17 @@
// A fix could be adding support for "declared" types for constant literal values
// - enabling the lo/hi to know that their operand is a word (from the cast).
const dword DVAL = $20000;
const byte* SCREEN = $400;
void main() {
SCREEN[0] = <(word)(DVAL/$400);
SCREEN[1] = >(word)(DVAL/$400);
dword dw = $2000;
word w1 = < dw;
word w2 = < (dw+1);
SCREEN[0] = <w1;
SCREEN[1] = >w1;
SCREEN[3] = <w2;
SCREEN[4] = >w2;
}

View File

@ -0,0 +1,29 @@
// A simple SID music player playing music in the main loop.
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label RASTER = $d012
.label BORDERCOL = $d020
.label MUSIC = $1000
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
// Place the SID into memory
// Play the music
main: {
// Initialize the music
jsr music.init
// Wait for the RASTER
b2:
lda RASTER
cmp #$fd
bne b2
inc BORDERCOL
// Play the music
jsr music.play
dec BORDERCOL
jmp b2
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)

View File

@ -0,0 +1,26 @@
@begin: scope:[] from
[0] phi()
to:@4
@4: scope:[] from @begin
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@5
@5: scope:[] from @4
[3] phi()
[4] call main
to:@end
@end: scope:[] from @5
[5] phi()
main: scope:[main] from @5
asm { jsrmusic.init }
to:main::@2
main::@2: scope:[main] from main main::@2 main::@3
[7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@2
[8] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { jsrmusic.play }
[10] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:main::@2

View File

@ -0,0 +1,815 @@
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) PROCPORT_DDR#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) PROCPORT_DDR_MEMORY_MASK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7
(byte*) PROCPORT#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) PROCPORT_RAM_ALL#0 ← (byte/signed byte/word/signed word/dword/signed dword) $30
(byte) PROCPORT_RAM_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $35
(byte) PROCPORT_RAM_CHARROM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $31
(byte) PROCPORT_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $36
(byte) PROCPORT_BASIC_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $37
(byte*) CHARGEN#0 ← ((byte*)) (word/dword/signed dword) $d000
(word) SPRITE_PTRS#0 ← (word/signed word/dword/signed dword) $3f8
(byte*) SPRITES_XPOS#0 ← ((byte*)) (word/dword/signed dword) $d000
(byte*) SPRITES_YPOS#0 ← ((byte*)) (word/dword/signed dword) $d001
(byte*) SPRITES_XMSB#0 ← ((byte*)) (word/dword/signed dword) $d010
(byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) $d012
(byte*) SPRITES_ENABLE#0 ← ((byte*)) (word/dword/signed dword) $d015
(byte*) SPRITES_EXPAND_Y#0 ← ((byte*)) (word/dword/signed dword) $d017
(byte*) SPRITES_PRIORITY#0 ← ((byte*)) (word/dword/signed dword) $d01b
(byte*) SPRITES_MC#0 ← ((byte*)) (word/dword/signed dword) $d01c
(byte*) SPRITES_EXPAND_X#0 ← ((byte*)) (word/dword/signed dword) $d01d
(byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) $d020
(byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) $d021
(byte*) BGCOL1#0 ← ((byte*)) (word/dword/signed dword) $d021
(byte*) BGCOL2#0 ← ((byte*)) (word/dword/signed dword) $d022
(byte*) BGCOL3#0 ← ((byte*)) (word/dword/signed dword) $d023
(byte*) BGCOL4#0 ← ((byte*)) (word/dword/signed dword) $d024
(byte*) SPRITES_MC1#0 ← ((byte*)) (word/dword/signed dword) $d025
(byte*) SPRITES_MC2#0 ← ((byte*)) (word/dword/signed dword) $d026
(byte*) SPRITES_COLS#0 ← ((byte*)) (word/dword/signed dword) $d027
(byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) $d011
(byte*) D011#0 ← ((byte*)) (word/dword/signed dword) $d011
(byte) VIC_RST8#0 ← (byte/word/signed word/dword/signed dword) $80
(byte) VIC_ECM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $40
(byte) VIC_BMM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $20
(byte) VIC_DEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) $10
(byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) VIC_CONTROL2#0 ← ((byte*)) (word/dword/signed dword) $d016
(byte*) D016#0 ← ((byte*)) (word/dword/signed dword) $d016
(byte) VIC_MCM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $10
(byte) VIC_CSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) D018#0 ← ((byte*)) (word/dword/signed dword) $d018
(byte*) VIC_MEMORY#0 ← ((byte*)) (word/dword/signed dword) $d018
(byte*) LIGHTPEN_X#0 ← ((byte*)) (word/dword/signed dword) $d013
(byte*) LIGHTPEN_Y#0 ← ((byte*)) (word/dword/signed dword) $d014
(byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) $d019
(byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) $d01a
(byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) IRQ_COLLISION_BG#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte) IRQ_COLLISION_SPRITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) IRQ_LIGHTPEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) COLS#0 ← ((byte*)) (word/dword/signed dword) $d800
(byte*) CIA1_PORT_A#0 ← ((byte*)) (word/dword/signed dword) $dc00
(byte*) CIA1_PORT_B#0 ← ((byte*)) (word/dword/signed dword) $dc01
(byte*) CIA1_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) $dc02
(byte*) CIA1_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) $dc03
(byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) $dc0d
(byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) $7f
(byte*) CIA2_PORT_A#0 ← ((byte*)) (word/dword/signed dword) $dd00
(byte*) CIA2_PORT_B#0 ← ((byte*)) (word/dword/signed dword) $dd01
(byte*) CIA2_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) $dd02
(byte*) CIA2_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) $dd03
(byte*) CIA2_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) $dd0d
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) $314
(void()**) HARDWARE_IRQ#0 ← ((void()**)) (word/dword/signed dword) $fffe
(byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(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) CYAN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 3
(byte) PURPLE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 5
(byte) BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 6
(byte) YELLOW#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7
(byte) ORANGE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte) BROWN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 9
(byte) PINK#0 ← (byte/signed byte/word/signed word/dword/signed dword) $a
(byte) DARK_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $b
(byte) GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $c
(byte) LIGHT_GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) $d
(byte) LIGHT_BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) $e
(byte) LIGHT_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $f
to:@4
@4: scope:[] from @begin
(byte*) MUSIC#0 ← ((byte*)) (word/signed word/dword/signed dword) $1000
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@5
main: scope:[main] from @5
asm { jsrmusic.init }
to:main::@2
main::@1: scope:[main] from main::@3
to:main::@2
main::@2: scope:[main] from main main::@1 main::@2
(bool~) main::$0 ← *((byte*) RASTER#0) != (byte/word/signed word/dword/signed dword) $fd
if((bool~) main::$0) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@2
*((byte*) BORDERCOL#0) ← ++ *((byte*) BORDERCOL#0)
asm { jsrmusic.play }
*((byte*) BORDERCOL#0) ← -- *((byte*) BORDERCOL#0)
if(true) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
@5: scope:[] from @4
call main
to:@6
@6: scope:[] from @5
to:@end
@end: scope:[] from @6
SYMBOL TABLE SSA
(label) @4
(label) @5
(label) @6
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte*) BGCOL1
(byte*) BGCOL1#0
(byte*) BGCOL2
(byte*) BGCOL2#0
(byte*) BGCOL3
(byte*) BGCOL3#0
(byte*) BGCOL4
(byte*) BGCOL4#0
(byte) BLACK
(byte) BLACK#0
(byte) BLUE
(byte) BLUE#0
(byte*) BORDERCOL
(byte*) BORDERCOL#0
(byte) BROWN
(byte) BROWN#0
(byte*) CHARGEN
(byte*) CHARGEN#0
(byte*) CIA1_INTERRUPT
(byte*) CIA1_INTERRUPT#0
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A#0
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_A_DDR#0
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B#0
(byte*) CIA1_PORT_B_DDR
(byte*) CIA1_PORT_B_DDR#0
(byte*) CIA2_INTERRUPT
(byte*) CIA2_INTERRUPT#0
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A#0
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_A_DDR#0
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B#0
(byte*) CIA2_PORT_B_DDR
(byte*) CIA2_PORT_B_DDR#0
(byte) CIA_INTERRUPT_CLEAR
(byte) CIA_INTERRUPT_CLEAR#0
(byte*) COLS
(byte*) COLS#0
(byte) CYAN
(byte) CYAN#0
(byte*) D011
(byte*) D011#0
(byte*) D016
(byte*) D016#0
(byte*) D018
(byte*) D018#0
(byte) DARK_GREY
(byte) DARK_GREY#0
(byte) GREEN
(byte) GREEN#0
(byte) GREY
(byte) GREY#0
(void()**) HARDWARE_IRQ
(void()**) HARDWARE_IRQ#0
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_BG#0
(byte) IRQ_COLLISION_SPRITE
(byte) IRQ_COLLISION_SPRITE#0
(byte*) IRQ_ENABLE
(byte*) IRQ_ENABLE#0
(byte) IRQ_LIGHTPEN
(byte) IRQ_LIGHTPEN#0
(byte) IRQ_RASTER
(byte) IRQ_RASTER#0
(byte*) IRQ_STATUS
(byte*) IRQ_STATUS#0
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_X#0
(byte*) LIGHTPEN_Y
(byte*) LIGHTPEN_Y#0
(byte) LIGHT_BLUE
(byte) LIGHT_BLUE#0
(byte) LIGHT_GREEN
(byte) LIGHT_GREEN#0
(byte) LIGHT_GREY
(byte) LIGHT_GREY#0
(byte*) MUSIC
(byte*) MUSIC#0
(byte) ORANGE
(byte) ORANGE#0
(byte) PINK
(byte) PINK#0
(byte*) PROCPORT
(byte*) PROCPORT#0
(byte) PROCPORT_BASIC_KERNEL_IO
(byte) PROCPORT_BASIC_KERNEL_IO#0
(byte*) PROCPORT_DDR
(byte*) PROCPORT_DDR#0
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_DDR_MEMORY_MASK#0
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_KERNEL_IO#0
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_ALL#0
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_CHARROM#0
(byte) PROCPORT_RAM_IO
(byte) PROCPORT_RAM_IO#0
(byte) PURPLE
(byte) PURPLE#0
(byte*) RASTER
(byte*) RASTER#0
(byte) RED
(byte) RED#0
(byte*) SPRITES_COLS
(byte*) SPRITES_COLS#0
(byte*) SPRITES_ENABLE
(byte*) SPRITES_ENABLE#0
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_X#0
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_EXPAND_Y#0
(byte*) SPRITES_MC
(byte*) SPRITES_MC#0
(byte*) SPRITES_MC1
(byte*) SPRITES_MC1#0
(byte*) SPRITES_MC2
(byte*) SPRITES_MC2#0
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_PRIORITY#0
(byte*) SPRITES_XMSB
(byte*) SPRITES_XMSB#0
(byte*) SPRITES_XPOS
(byte*) SPRITES_XPOS#0
(byte*) SPRITES_YPOS
(byte*) SPRITES_YPOS#0
(word) SPRITE_PTRS
(word) SPRITE_PTRS#0
(byte) VIC_BMM
(byte) VIC_BMM#0
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL#0
(byte*) VIC_CONTROL2
(byte*) VIC_CONTROL2#0
(byte) VIC_CSEL
(byte) VIC_CSEL#0
(byte) VIC_DEN
(byte) VIC_DEN#0
(byte) VIC_ECM
(byte) VIC_ECM#0
(byte) VIC_MCM
(byte) VIC_MCM#0
(byte*) VIC_MEMORY
(byte*) VIC_MEMORY#0
(byte) VIC_RSEL
(byte) VIC_RSEL#0
(byte) VIC_RST8
(byte) VIC_RST8#0
(byte) WHITE
(byte) WHITE#0
(byte) YELLOW
(byte) YELLOW#0
(void()) main()
(bool~) main::$0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
Culled Empty Block (label) main::@1
Culled Empty Block (label) @6
Successful SSA optimization Pass2CullEmptyBlocks
Simple Condition (bool~) main::$0 [84] if(*((byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) PROCPORT_DDR#0 = ((byte*))0
Constant (const byte) PROCPORT_DDR_MEMORY_MASK#0 = 7
Constant (const byte*) PROCPORT#0 = ((byte*))1
Constant (const byte) PROCPORT_RAM_ALL#0 = $30
Constant (const byte) PROCPORT_RAM_IO#0 = $35
Constant (const byte) PROCPORT_RAM_CHARROM#0 = $31
Constant (const byte) PROCPORT_KERNEL_IO#0 = $36
Constant (const byte) PROCPORT_BASIC_KERNEL_IO#0 = $37
Constant (const byte*) CHARGEN#0 = ((byte*))$d000
Constant (const word) SPRITE_PTRS#0 = $3f8
Constant (const byte*) SPRITES_XPOS#0 = ((byte*))$d000
Constant (const byte*) SPRITES_YPOS#0 = ((byte*))$d001
Constant (const byte*) SPRITES_XMSB#0 = ((byte*))$d010
Constant (const byte*) RASTER#0 = ((byte*))$d012
Constant (const byte*) SPRITES_ENABLE#0 = ((byte*))$d015
Constant (const byte*) SPRITES_EXPAND_Y#0 = ((byte*))$d017
Constant (const byte*) SPRITES_PRIORITY#0 = ((byte*))$d01b
Constant (const byte*) SPRITES_MC#0 = ((byte*))$d01c
Constant (const byte*) SPRITES_EXPAND_X#0 = ((byte*))$d01d
Constant (const byte*) BORDERCOL#0 = ((byte*))$d020
Constant (const byte*) BGCOL#0 = ((byte*))$d021
Constant (const byte*) BGCOL1#0 = ((byte*))$d021
Constant (const byte*) BGCOL2#0 = ((byte*))$d022
Constant (const byte*) BGCOL3#0 = ((byte*))$d023
Constant (const byte*) BGCOL4#0 = ((byte*))$d024
Constant (const byte*) SPRITES_MC1#0 = ((byte*))$d025
Constant (const byte*) SPRITES_MC2#0 = ((byte*))$d026
Constant (const byte*) SPRITES_COLS#0 = ((byte*))$d027
Constant (const byte*) VIC_CONTROL#0 = ((byte*))$d011
Constant (const byte*) D011#0 = ((byte*))$d011
Constant (const byte) VIC_RST8#0 = $80
Constant (const byte) VIC_ECM#0 = $40
Constant (const byte) VIC_BMM#0 = $20
Constant (const byte) VIC_DEN#0 = $10
Constant (const byte) VIC_RSEL#0 = 8
Constant (const byte*) VIC_CONTROL2#0 = ((byte*))$d016
Constant (const byte*) D016#0 = ((byte*))$d016
Constant (const byte) VIC_MCM#0 = $10
Constant (const byte) VIC_CSEL#0 = 8
Constant (const byte*) D018#0 = ((byte*))$d018
Constant (const byte*) VIC_MEMORY#0 = ((byte*))$d018
Constant (const byte*) LIGHTPEN_X#0 = ((byte*))$d013
Constant (const byte*) LIGHTPEN_Y#0 = ((byte*))$d014
Constant (const byte*) IRQ_STATUS#0 = ((byte*))$d019
Constant (const byte*) IRQ_ENABLE#0 = ((byte*))$d01a
Constant (const byte) IRQ_RASTER#0 = 1
Constant (const byte) IRQ_COLLISION_BG#0 = 2
Constant (const byte) IRQ_COLLISION_SPRITE#0 = 4
Constant (const byte) IRQ_LIGHTPEN#0 = 8
Constant (const byte*) COLS#0 = ((byte*))$d800
Constant (const byte*) CIA1_PORT_A#0 = ((byte*))$dc00
Constant (const byte*) CIA1_PORT_B#0 = ((byte*))$dc01
Constant (const byte*) CIA1_PORT_A_DDR#0 = ((byte*))$dc02
Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))$dc03
Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))$dc0d
Constant (const byte) CIA_INTERRUPT_CLEAR#0 = $7f
Constant (const byte*) CIA2_PORT_A#0 = ((byte*))$dd00
Constant (const byte*) CIA2_PORT_B#0 = ((byte*))$dd01
Constant (const byte*) CIA2_PORT_A_DDR#0 = ((byte*))$dd02
Constant (const byte*) CIA2_PORT_B_DDR#0 = ((byte*))$dd03
Constant (const byte*) CIA2_INTERRUPT#0 = ((byte*))$dd0d
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))$314
Constant (const void()**) HARDWARE_IRQ#0 = ((void()**))$fffe
Constant (const byte) BLACK#0 = 0
Constant (const byte) WHITE#0 = 1
Constant (const byte) RED#0 = 2
Constant (const byte) CYAN#0 = 3
Constant (const byte) PURPLE#0 = 4
Constant (const byte) GREEN#0 = 5
Constant (const byte) BLUE#0 = 6
Constant (const byte) YELLOW#0 = 7
Constant (const byte) ORANGE#0 = 8
Constant (const byte) BROWN#0 = 9
Constant (const byte) PINK#0 = $a
Constant (const byte) DARK_GREY#0 = $b
Constant (const byte) GREY#0 = $c
Constant (const byte) LIGHT_GREEN#0 = $d
Constant (const byte) LIGHT_BLUE#0 = $e
Constant (const byte) LIGHT_GREY#0 = $f
Constant (const byte*) MUSIC#0 = ((byte*))$1000
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [7] if(true) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Successful SSA optimization PassNEliminateUnusedVars
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @5
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:4
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @5
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@4
@4: scope:[] from @begin
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@5
@5: scope:[] from @4
[3] phi()
[4] call main
to:@end
@end: scope:[] from @5
[5] phi()
main: scope:[main] from @5
asm { jsrmusic.init }
to:main::@2
main::@2: scope:[main] from main main::@2 main::@3
[7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@2
[8] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { jsrmusic.play }
[10] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:main::@2
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// A simple SID music player playing music in the main loop.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label MUSIC = $1000
//SEG3 @begin
bbegin:
jmp b4
//SEG4 @4
b4:
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @5 [phi:@4->@5]
b5_from_b4:
jmp b5
//SEG8 @5
b5:
//SEG9 [4] call main
jsr main
//SEG10 [5] phi from @5 to @end [phi:@5->@end]
bend_from_b5:
jmp bend
//SEG11 @end
bend:
//SEG12 main
// Play the music
main: {
//SEG13 asm { jsrmusic.init }
// Initialize the music
jsr music.init
jmp b2
// Wait for the RASTER
//SEG14 main::@2
b2:
//SEG15 [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2 -- _deref_pbuc1_neq_vbuc2_then_la1
lda RASTER
cmp #$fd
bne b2
jmp b3
//SEG16 main::@3
b3:
//SEG17 [8] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG18 asm { jsrmusic.play }
// Play the music
jsr music.play
//SEG19 [10] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
jmp b2
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)
REGISTER UPLIFT POTENTIAL REGISTERS
Statement asm { jsrmusic.init } always clobbers reg byte a reg byte x reg byte y
Statement [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2 [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement asm { jsrmusic.play } always clobbers reg byte a reg byte x reg byte y
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 4227 combination
Uplifting [] best 4227 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A simple SID music player playing music in the main loop.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label MUSIC = $1000
//SEG3 @begin
bbegin:
jmp b4
//SEG4 @4
b4:
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @5 [phi:@4->@5]
b5_from_b4:
jmp b5
//SEG8 @5
b5:
//SEG9 [4] call main
jsr main
//SEG10 [5] phi from @5 to @end [phi:@5->@end]
bend_from_b5:
jmp bend
//SEG11 @end
bend:
//SEG12 main
// Play the music
main: {
//SEG13 asm { jsrmusic.init }
// Initialize the music
jsr music.init
jmp b2
// Wait for the RASTER
//SEG14 main::@2
b2:
//SEG15 [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2 -- _deref_pbuc1_neq_vbuc2_then_la1
lda RASTER
cmp #$fd
bne b2
jmp b3
//SEG16 main::@3
b3:
//SEG17 [8] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG18 asm { jsrmusic.play }
// Play the music
jsr music.play
//SEG19 [10] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
jmp b2
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b4
Removing instruction jmp b5
Removing instruction jmp bend
Removing instruction jmp b2
Removing instruction jmp b3
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b4:
Removing instruction b5_from_b4:
Removing instruction bend_from_b5:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b5:
Removing instruction bend:
Removing instruction b3:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @4
(label) @5
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) $d020
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(const byte*) MUSIC#0 MUSIC = ((byte*))(word/signed word/dword/signed dword) $1000
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) $d012
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
(void()) main()
(label) main::@2
(label) main::@3
FINAL ASSEMBLER
Score: 3882
//SEG0 File Comments
// A simple SID music player playing music in the main loop.
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label MUSIC = $1000
//SEG3 @begin
//SEG4 @4
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @5 [phi:@4->@5]
//SEG8 @5
//SEG9 [4] call main
//SEG10 [5] phi from @5 to @end [phi:@5->@end]
//SEG11 @end
//SEG12 main
// Play the music
main: {
//SEG13 asm { jsrmusic.init }
// Initialize the music
jsr music.init
// Wait for the RASTER
//SEG14 main::@2
b2:
//SEG15 [7] if(*((const byte*) RASTER#0)!=(byte/word/signed word/dword/signed dword) $fd) goto main::@2 -- _deref_pbuc1_neq_vbuc2_then_la1
lda RASTER
cmp #$fd
bne b2
//SEG16 main::@3
//SEG17 [8] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG18 asm { jsrmusic.play }
// Play the music
jsr music.play
//SEG19 [10] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
jmp b2
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)

View File

@ -0,0 +1,91 @@
(label) @4
(label) @5
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) $d020
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(const byte*) MUSIC#0 MUSIC = ((byte*))(word/signed word/dword/signed dword) $1000
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) $d012
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
(void()) main()
(label) main::@2
(label) main::@3

View File

@ -0,0 +1,62 @@
// A simple SID music player using RASTER IRQ
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label RASTER = $d012
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.label MUSIC = $1000
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
// Place the SID into memory
// Setup Raster IRQ and initialize SID player
main: {
sei
jsr music.init
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
// Set raster line to $fd
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
lda #$fd
sta RASTER
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
// Set the IRQ routine
lda #<irq_play
sta KERNEL_IRQ
lda #>irq_play
sta KERNEL_IRQ+1
cli
rts
}
// Raster IRQ Routine playing music
irq_play: {
inc BORDERCOL
// Play SID
jsr music.play
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
dec BORDERCOL
jmp $ea31
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)

View File

@ -0,0 +1,36 @@
@begin: scope:[] from
[0] phi()
to:@4
@4: scope:[] from @begin
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@6
@6: scope:[] from @4
[3] phi()
[4] call main
to:@end
@end: scope:[] from @6
[5] phi()
main: scope:[main] from @6
asm { sei jsrmusic.init }
[7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f
[9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd
[10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play()
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[13] return
to:@return
irq_play: scope:[irq_play] from
[14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { jsrmusic.play }
[16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[17] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:irq_play::@return
irq_play::@return: scope:[irq_play] from irq_play
[18] return
to:@return

View File

@ -0,0 +1,973 @@
Resolved forward reference irq_play to interrupt(KERNEL_KEYBOARD)(void()) irq_play()
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) PROCPORT_DDR#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 0
(byte) PROCPORT_DDR_MEMORY_MASK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7
(byte*) PROCPORT#0 ← ((byte*)) (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) PROCPORT_RAM_ALL#0 ← (byte/signed byte/word/signed word/dword/signed dword) $30
(byte) PROCPORT_RAM_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $35
(byte) PROCPORT_RAM_CHARROM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $31
(byte) PROCPORT_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $36
(byte) PROCPORT_BASIC_KERNEL_IO#0 ← (byte/signed byte/word/signed word/dword/signed dword) $37
(byte*) CHARGEN#0 ← ((byte*)) (word/dword/signed dword) $d000
(word) SPRITE_PTRS#0 ← (word/signed word/dword/signed dword) $3f8
(byte*) SPRITES_XPOS#0 ← ((byte*)) (word/dword/signed dword) $d000
(byte*) SPRITES_YPOS#0 ← ((byte*)) (word/dword/signed dword) $d001
(byte*) SPRITES_XMSB#0 ← ((byte*)) (word/dword/signed dword) $d010
(byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) $d012
(byte*) SPRITES_ENABLE#0 ← ((byte*)) (word/dword/signed dword) $d015
(byte*) SPRITES_EXPAND_Y#0 ← ((byte*)) (word/dword/signed dword) $d017
(byte*) SPRITES_PRIORITY#0 ← ((byte*)) (word/dword/signed dword) $d01b
(byte*) SPRITES_MC#0 ← ((byte*)) (word/dword/signed dword) $d01c
(byte*) SPRITES_EXPAND_X#0 ← ((byte*)) (word/dword/signed dword) $d01d
(byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) $d020
(byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) $d021
(byte*) BGCOL1#0 ← ((byte*)) (word/dword/signed dword) $d021
(byte*) BGCOL2#0 ← ((byte*)) (word/dword/signed dword) $d022
(byte*) BGCOL3#0 ← ((byte*)) (word/dword/signed dword) $d023
(byte*) BGCOL4#0 ← ((byte*)) (word/dword/signed dword) $d024
(byte*) SPRITES_MC1#0 ← ((byte*)) (word/dword/signed dword) $d025
(byte*) SPRITES_MC2#0 ← ((byte*)) (word/dword/signed dword) $d026
(byte*) SPRITES_COLS#0 ← ((byte*)) (word/dword/signed dword) $d027
(byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) $d011
(byte*) D011#0 ← ((byte*)) (word/dword/signed dword) $d011
(byte) VIC_RST8#0 ← (byte/word/signed word/dword/signed dword) $80
(byte) VIC_ECM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $40
(byte) VIC_BMM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $20
(byte) VIC_DEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) $10
(byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) VIC_CONTROL2#0 ← ((byte*)) (word/dword/signed dword) $d016
(byte*) D016#0 ← ((byte*)) (word/dword/signed dword) $d016
(byte) VIC_MCM#0 ← (byte/signed byte/word/signed word/dword/signed dword) $10
(byte) VIC_CSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) D018#0 ← ((byte*)) (word/dword/signed dword) $d018
(byte*) VIC_MEMORY#0 ← ((byte*)) (word/dword/signed dword) $d018
(byte*) LIGHTPEN_X#0 ← ((byte*)) (word/dword/signed dword) $d013
(byte*) LIGHTPEN_Y#0 ← ((byte*)) (word/dword/signed dword) $d014
(byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) $d019
(byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) $d01a
(byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) IRQ_COLLISION_BG#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte) IRQ_COLLISION_SPRITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) IRQ_LIGHTPEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) COLS#0 ← ((byte*)) (word/dword/signed dword) $d800
(byte*) CIA1_PORT_A#0 ← ((byte*)) (word/dword/signed dword) $dc00
(byte*) CIA1_PORT_B#0 ← ((byte*)) (word/dword/signed dword) $dc01
(byte*) CIA1_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) $dc02
(byte*) CIA1_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) $dc03
(byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) $dc0d
(byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) $7f
(byte*) CIA2_PORT_A#0 ← ((byte*)) (word/dword/signed dword) $dd00
(byte*) CIA2_PORT_B#0 ← ((byte*)) (word/dword/signed dword) $dd01
(byte*) CIA2_PORT_A_DDR#0 ← ((byte*)) (word/dword/signed dword) $dd02
(byte*) CIA2_PORT_B_DDR#0 ← ((byte*)) (word/dword/signed dword) $dd03
(byte*) CIA2_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) $dd0d
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) $314
(void()**) HARDWARE_IRQ#0 ← ((void()**)) (word/dword/signed dword) $fffe
(byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(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) CYAN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 3
(byte) PURPLE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 5
(byte) BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 6
(byte) YELLOW#0 ← (byte/signed byte/word/signed word/dword/signed dword) 7
(byte) ORANGE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte) BROWN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 9
(byte) PINK#0 ← (byte/signed byte/word/signed word/dword/signed dword) $a
(byte) DARK_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $b
(byte) GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $c
(byte) LIGHT_GREEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) $d
(byte) LIGHT_BLUE#0 ← (byte/signed byte/word/signed word/dword/signed dword) $e
(byte) LIGHT_GREY#0 ← (byte/signed byte/word/signed word/dword/signed dword) $f
to:@4
@4: scope:[] from @begin
(byte*) MUSIC#0 ← ((byte*)) (word/signed word/dword/signed dword) $1000
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@6
main: scope:[main] from @6
asm { sei jsrmusic.init }
*((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) $7f
*((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd
*((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0
(void()*~) main::$0 ← & interrupt(KERNEL_KEYBOARD)(void()) irq_play()
*((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0
asm { cli }
to:main::@return
main::@return: scope:[main] from main
return
to:@return
irq_play: scope:[irq_play] from
*((byte*) BORDERCOL#0) ← ++ *((byte*) BORDERCOL#0)
asm { jsrmusic.play }
*((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0
*((byte*) BORDERCOL#0) ← -- *((byte*) BORDERCOL#0)
to:irq_play::@return
irq_play::@return: scope:[irq_play] from irq_play
return
to:@return
@6: scope:[] from @4
call main
to:@7
@7: scope:[] from @6
to:@end
@end: scope:[] from @7
SYMBOL TABLE SSA
(label) @4
(label) @6
(label) @7
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte*) BGCOL1
(byte*) BGCOL1#0
(byte*) BGCOL2
(byte*) BGCOL2#0
(byte*) BGCOL3
(byte*) BGCOL3#0
(byte*) BGCOL4
(byte*) BGCOL4#0
(byte) BLACK
(byte) BLACK#0
(byte) BLUE
(byte) BLUE#0
(byte*) BORDERCOL
(byte*) BORDERCOL#0
(byte) BROWN
(byte) BROWN#0
(byte*) CHARGEN
(byte*) CHARGEN#0
(byte*) CIA1_INTERRUPT
(byte*) CIA1_INTERRUPT#0
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A#0
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_A_DDR#0
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B#0
(byte*) CIA1_PORT_B_DDR
(byte*) CIA1_PORT_B_DDR#0
(byte*) CIA2_INTERRUPT
(byte*) CIA2_INTERRUPT#0
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A#0
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_A_DDR#0
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B#0
(byte*) CIA2_PORT_B_DDR
(byte*) CIA2_PORT_B_DDR#0
(byte) CIA_INTERRUPT_CLEAR
(byte) CIA_INTERRUPT_CLEAR#0
(byte*) COLS
(byte*) COLS#0
(byte) CYAN
(byte) CYAN#0
(byte*) D011
(byte*) D011#0
(byte*) D016
(byte*) D016#0
(byte*) D018
(byte*) D018#0
(byte) DARK_GREY
(byte) DARK_GREY#0
(byte) GREEN
(byte) GREEN#0
(byte) GREY
(byte) GREY#0
(void()**) HARDWARE_IRQ
(void()**) HARDWARE_IRQ#0
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_BG#0
(byte) IRQ_COLLISION_SPRITE
(byte) IRQ_COLLISION_SPRITE#0
(byte*) IRQ_ENABLE
(byte*) IRQ_ENABLE#0
(byte) IRQ_LIGHTPEN
(byte) IRQ_LIGHTPEN#0
(byte) IRQ_RASTER
(byte) IRQ_RASTER#0
(byte*) IRQ_STATUS
(byte*) IRQ_STATUS#0
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_X#0
(byte*) LIGHTPEN_Y
(byte*) LIGHTPEN_Y#0
(byte) LIGHT_BLUE
(byte) LIGHT_BLUE#0
(byte) LIGHT_GREEN
(byte) LIGHT_GREEN#0
(byte) LIGHT_GREY
(byte) LIGHT_GREY#0
(byte*) MUSIC
(byte*) MUSIC#0
(byte) ORANGE
(byte) ORANGE#0
(byte) PINK
(byte) PINK#0
(byte*) PROCPORT
(byte*) PROCPORT#0
(byte) PROCPORT_BASIC_KERNEL_IO
(byte) PROCPORT_BASIC_KERNEL_IO#0
(byte*) PROCPORT_DDR
(byte*) PROCPORT_DDR#0
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_DDR_MEMORY_MASK#0
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_KERNEL_IO#0
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_ALL#0
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_CHARROM#0
(byte) PROCPORT_RAM_IO
(byte) PROCPORT_RAM_IO#0
(byte) PURPLE
(byte) PURPLE#0
(byte*) RASTER
(byte*) RASTER#0
(byte) RED
(byte) RED#0
(byte*) SPRITES_COLS
(byte*) SPRITES_COLS#0
(byte*) SPRITES_ENABLE
(byte*) SPRITES_ENABLE#0
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_X#0
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_EXPAND_Y#0
(byte*) SPRITES_MC
(byte*) SPRITES_MC#0
(byte*) SPRITES_MC1
(byte*) SPRITES_MC1#0
(byte*) SPRITES_MC2
(byte*) SPRITES_MC2#0
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_PRIORITY#0
(byte*) SPRITES_XMSB
(byte*) SPRITES_XMSB#0
(byte*) SPRITES_XPOS
(byte*) SPRITES_XPOS#0
(byte*) SPRITES_YPOS
(byte*) SPRITES_YPOS#0
(word) SPRITE_PTRS
(word) SPRITE_PTRS#0
(byte) VIC_BMM
(byte) VIC_BMM#0
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL#0
(byte*) VIC_CONTROL2
(byte*) VIC_CONTROL2#0
(byte) VIC_CSEL
(byte) VIC_CSEL#0
(byte) VIC_DEN
(byte) VIC_DEN#0
(byte) VIC_ECM
(byte) VIC_ECM#0
(byte) VIC_MCM
(byte) VIC_MCM#0
(byte*) VIC_MEMORY
(byte*) VIC_MEMORY#0
(byte) VIC_RSEL
(byte) VIC_RSEL#0
(byte) VIC_RST8
(byte) VIC_RST8#0
(byte) WHITE
(byte) WHITE#0
(byte) YELLOW
(byte) YELLOW#0
interrupt(KERNEL_KEYBOARD)(void()) irq_play()
(label) irq_play::@return
(void()) main()
(void()*~) main::$0
(label) main::@return
Culled Empty Block (label) @7
Successful SSA optimization Pass2CullEmptyBlocks
Constant (const byte*) PROCPORT_DDR#0 = ((byte*))0
Constant (const byte) PROCPORT_DDR_MEMORY_MASK#0 = 7
Constant (const byte*) PROCPORT#0 = ((byte*))1
Constant (const byte) PROCPORT_RAM_ALL#0 = $30
Constant (const byte) PROCPORT_RAM_IO#0 = $35
Constant (const byte) PROCPORT_RAM_CHARROM#0 = $31
Constant (const byte) PROCPORT_KERNEL_IO#0 = $36
Constant (const byte) PROCPORT_BASIC_KERNEL_IO#0 = $37
Constant (const byte*) CHARGEN#0 = ((byte*))$d000
Constant (const word) SPRITE_PTRS#0 = $3f8
Constant (const byte*) SPRITES_XPOS#0 = ((byte*))$d000
Constant (const byte*) SPRITES_YPOS#0 = ((byte*))$d001
Constant (const byte*) SPRITES_XMSB#0 = ((byte*))$d010
Constant (const byte*) RASTER#0 = ((byte*))$d012
Constant (const byte*) SPRITES_ENABLE#0 = ((byte*))$d015
Constant (const byte*) SPRITES_EXPAND_Y#0 = ((byte*))$d017
Constant (const byte*) SPRITES_PRIORITY#0 = ((byte*))$d01b
Constant (const byte*) SPRITES_MC#0 = ((byte*))$d01c
Constant (const byte*) SPRITES_EXPAND_X#0 = ((byte*))$d01d
Constant (const byte*) BORDERCOL#0 = ((byte*))$d020
Constant (const byte*) BGCOL#0 = ((byte*))$d021
Constant (const byte*) BGCOL1#0 = ((byte*))$d021
Constant (const byte*) BGCOL2#0 = ((byte*))$d022
Constant (const byte*) BGCOL3#0 = ((byte*))$d023
Constant (const byte*) BGCOL4#0 = ((byte*))$d024
Constant (const byte*) SPRITES_MC1#0 = ((byte*))$d025
Constant (const byte*) SPRITES_MC2#0 = ((byte*))$d026
Constant (const byte*) SPRITES_COLS#0 = ((byte*))$d027
Constant (const byte*) VIC_CONTROL#0 = ((byte*))$d011
Constant (const byte*) D011#0 = ((byte*))$d011
Constant (const byte) VIC_RST8#0 = $80
Constant (const byte) VIC_ECM#0 = $40
Constant (const byte) VIC_BMM#0 = $20
Constant (const byte) VIC_DEN#0 = $10
Constant (const byte) VIC_RSEL#0 = 8
Constant (const byte*) VIC_CONTROL2#0 = ((byte*))$d016
Constant (const byte*) D016#0 = ((byte*))$d016
Constant (const byte) VIC_MCM#0 = $10
Constant (const byte) VIC_CSEL#0 = 8
Constant (const byte*) D018#0 = ((byte*))$d018
Constant (const byte*) VIC_MEMORY#0 = ((byte*))$d018
Constant (const byte*) LIGHTPEN_X#0 = ((byte*))$d013
Constant (const byte*) LIGHTPEN_Y#0 = ((byte*))$d014
Constant (const byte*) IRQ_STATUS#0 = ((byte*))$d019
Constant (const byte*) IRQ_ENABLE#0 = ((byte*))$d01a
Constant (const byte) IRQ_RASTER#0 = 1
Constant (const byte) IRQ_COLLISION_BG#0 = 2
Constant (const byte) IRQ_COLLISION_SPRITE#0 = 4
Constant (const byte) IRQ_LIGHTPEN#0 = 8
Constant (const byte*) COLS#0 = ((byte*))$d800
Constant (const byte*) CIA1_PORT_A#0 = ((byte*))$dc00
Constant (const byte*) CIA1_PORT_B#0 = ((byte*))$dc01
Constant (const byte*) CIA1_PORT_A_DDR#0 = ((byte*))$dc02
Constant (const byte*) CIA1_PORT_B_DDR#0 = ((byte*))$dc03
Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))$dc0d
Constant (const byte) CIA_INTERRUPT_CLEAR#0 = $7f
Constant (const byte*) CIA2_PORT_A#0 = ((byte*))$dd00
Constant (const byte*) CIA2_PORT_B#0 = ((byte*))$dd01
Constant (const byte*) CIA2_PORT_A_DDR#0 = ((byte*))$dd02
Constant (const byte*) CIA2_PORT_B_DDR#0 = ((byte*))$dd03
Constant (const byte*) CIA2_INTERRUPT#0 = ((byte*))$dd0d
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))$314
Constant (const void()**) HARDWARE_IRQ#0 = ((void()**))$fffe
Constant (const byte) BLACK#0 = 0
Constant (const byte) WHITE#0 = 1
Constant (const byte) RED#0 = 2
Constant (const byte) CYAN#0 = 3
Constant (const byte) PURPLE#0 = 4
Constant (const byte) GREEN#0 = 5
Constant (const byte) BLUE#0 = 6
Constant (const byte) YELLOW#0 = 7
Constant (const byte) ORANGE#0 = 8
Constant (const byte) BROWN#0 = 9
Constant (const byte) PINK#0 = $a
Constant (const byte) DARK_GREY#0 = $b
Constant (const byte) GREY#0 = $c
Constant (const byte) LIGHT_GREEN#0 = $d
Constant (const byte) LIGHT_BLUE#0 = $e
Constant (const byte) LIGHT_GREY#0 = $f
Constant (const byte*) MUSIC#0 = ((byte*))$1000
Constant (const void()*) main::$0 = &irq_play
Successful SSA optimization Pass2ConstantIdentification
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$0 = &interrupt(KERNEL_KEYBOARD)(void()) irq_play()
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @6
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:4
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @6
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@4
@4: scope:[] from @begin
kickasm() {{ .const music = LoadSid("toiletrensdyr.sid")
}}
kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i)
}}
to:@6
@6: scope:[] from @4
[3] phi()
[4] call main
to:@end
@end: scope:[] from @6
[5] phi()
main: scope:[main] from @6
asm { sei jsrmusic.init }
[7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0
[8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f
[9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd
[10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0
[11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play()
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[13] return
to:@return
irq_play: scope:[irq_play] from
[14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0)
asm { jsrmusic.play }
[16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0
[17] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0)
to:irq_play::@return
irq_play::@return: scope:[irq_play] from irq_play
[18] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
interrupt(KERNEL_KEYBOARD)(void()) irq_play()
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
//SEG0 File Comments
// A simple SID music player using RASTER IRQ
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.label MUSIC = $1000
//SEG3 @begin
bbegin:
jmp b4
//SEG4 @4
b4:
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @6 [phi:@4->@6]
b6_from_b4:
jmp b6
//SEG8 @6
b6:
//SEG9 [4] call main
jsr main
//SEG10 [5] phi from @6 to @end [phi:@6->@end]
bend_from_b6:
jmp bend
//SEG11 @end
bend:
//SEG12 main
// Setup Raster IRQ and initialize SID player
main: {
//SEG13 asm { sei jsrmusic.init }
sei
jsr music.init
//SEG14 [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG15 [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fd
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG16 [9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG17 [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG18 [11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play() -- _deref_pptc1=pprc2
// Set the IRQ routine
lda #<irq_play
sta KERNEL_IRQ
lda #>irq_play
sta KERNEL_IRQ+1
//SEG19 asm { cli }
cli
jmp breturn
//SEG20 main::@return
breturn:
//SEG21 [13] return
rts
}
//SEG22 irq_play
// Raster IRQ Routine playing music
irq_play: {
//SEG23 entry interrupt(KERNEL_KEYBOARD)
//SEG24 [14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG25 asm { jsrmusic.play }
// Play SID
jsr music.play
//SEG26 [16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG27 [17] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
jmp breturn
//SEG28 irq_play::@return
breturn:
//SEG29 [18] return - exit interrupt(KERNEL_KEYBOARD)
jmp $ea31
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)
REGISTER UPLIFT POTENTIAL REGISTERS
Statement asm { sei jsrmusic.init } always clobbers reg byte a reg byte x reg byte y
Statement [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play() [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement asm { jsrmusic.play } always clobbers reg byte a reg byte x reg byte y
Statement [16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [irq_play]
Uplift Scope []
Uplifting [main] best 643 combination
Uplifting [irq_play] best 643 combination
Uplifting [] best 643 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// A simple SID music player using RASTER IRQ
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.label MUSIC = $1000
//SEG3 @begin
bbegin:
jmp b4
//SEG4 @4
b4:
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @6 [phi:@4->@6]
b6_from_b4:
jmp b6
//SEG8 @6
b6:
//SEG9 [4] call main
jsr main
//SEG10 [5] phi from @6 to @end [phi:@6->@end]
bend_from_b6:
jmp bend
//SEG11 @end
bend:
//SEG12 main
// Setup Raster IRQ and initialize SID player
main: {
//SEG13 asm { sei jsrmusic.init }
sei
jsr music.init
//SEG14 [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG15 [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fd
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG16 [9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG17 [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG18 [11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play() -- _deref_pptc1=pprc2
// Set the IRQ routine
lda #<irq_play
sta KERNEL_IRQ
lda #>irq_play
sta KERNEL_IRQ+1
//SEG19 asm { cli }
cli
jmp breturn
//SEG20 main::@return
breturn:
//SEG21 [13] return
rts
}
//SEG22 irq_play
// Raster IRQ Routine playing music
irq_play: {
//SEG23 entry interrupt(KERNEL_KEYBOARD)
//SEG24 [14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG25 asm { jsrmusic.play }
// Play SID
jsr music.play
//SEG26 [16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG27 [17] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
jmp breturn
//SEG28 irq_play::@return
breturn:
//SEG29 [18] return - exit interrupt(KERNEL_KEYBOARD)
jmp $ea31
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b4
Removing instruction jmp b6
Removing instruction jmp bend
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b4:
Removing instruction b6_from_b4:
Removing instruction bend_from_b6:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b6:
Removing instruction bend:
Removing instruction breturn:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @4
(label) @6
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) $d020
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) $dc0d
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) $7f
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) $d01a
(byte) IRQ_LIGHTPEN
(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) $d019
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) $314
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(const byte*) MUSIC#0 MUSIC = ((byte*))(word/signed word/dword/signed dword) $1000
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) $d012
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) $d011
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
interrupt(KERNEL_KEYBOARD)(void()) irq_play()
(label) irq_play::@return
(void()) main()
(label) main::@return
FINAL ASSEMBLER
Score: 595
//SEG0 File Comments
// A simple SID music player using RASTER IRQ
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.label RASTER = $d012
.label BORDERCOL = $d020
.label VIC_CONTROL = $d011
// VIC II IRQ Status Register
.label IRQ_STATUS = $d019
// VIC II IRQ Enable Register
.label IRQ_ENABLE = $d01a
// Bits for the IRQ Status/Enable Registers
.const IRQ_RASTER = 1
// CIA#1 Interrupt Status & Control Register
.label CIA1_INTERRUPT = $dc0d
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
.const CIA_INTERRUPT_CLEAR = $7f
// The vector used when the KERNAL serves IRQ interrupts
.label KERNEL_IRQ = $314
.label MUSIC = $1000
//SEG3 @begin
//SEG4 @4
//SEG5 kickasm() {{ .const music = LoadSid("toiletrensdyr.sid") }}
// Load the SID
.const music = LoadSid("toiletrensdyr.sid")
//SEG6 kickasm(location (const byte*) MUSIC#0) {{ .fill music.size, music.getData(i) }}
// Place the SID into memory
//SEG7 [3] phi from @4 to @6 [phi:@4->@6]
//SEG8 @6
//SEG9 [4] call main
//SEG10 [5] phi from @6 to @end [phi:@6->@end]
//SEG11 @end
//SEG12 main
// Setup Raster IRQ and initialize SID player
main: {
//SEG13 asm { sei jsrmusic.init }
sei
jsr music.init
//SEG14 [7] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2
// Disable CIA 1 Timer IRQ
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG15 [8] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) $7f -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
// Set raster line to $fd
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG16 [9] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) $fd -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG17 [10] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Enable Raster Interrupt
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG18 [11] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq_play() -- _deref_pptc1=pprc2
// Set the IRQ routine
lda #<irq_play
sta KERNEL_IRQ
lda #>irq_play
sta KERNEL_IRQ+1
//SEG19 asm { cli }
cli
//SEG20 main::@return
//SEG21 [13] return
rts
}
//SEG22 irq_play
// Raster IRQ Routine playing music
irq_play: {
//SEG23 entry interrupt(KERNEL_KEYBOARD)
//SEG24 [14] *((const byte*) BORDERCOL#0) ← ++ *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_inc__deref_pbuc1
inc BORDERCOL
//SEG25 asm { jsrmusic.play }
// Play SID
jsr music.play
//SEG26 [16] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2
// Acknowledge the IRQ
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG27 [17] *((const byte*) BORDERCOL#0) ← -- *((const byte*) BORDERCOL#0) -- _deref_pbuc1=_dec__deref_pbuc1
dec BORDERCOL
//SEG28 irq_play::@return
//SEG29 [18] return - exit interrupt(KERNEL_KEYBOARD)
jmp $ea31
}
.pc = MUSIC "MUSIC"
.fill music.size, music.getData(i)

View File

@ -0,0 +1,99 @@
(label) @4
(label) @6
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL1
(byte*) BGCOL2
(byte*) BGCOL3
(byte*) BGCOL4
(byte) BLACK
(byte) BLUE
(byte*) BORDERCOL
(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) $d020
(byte) BROWN
(byte*) CHARGEN
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) $dc0d
(byte*) CIA1_PORT_A
(byte*) CIA1_PORT_A_DDR
(byte*) CIA1_PORT_B
(byte*) CIA1_PORT_B_DDR
(byte*) CIA2_INTERRUPT
(byte*) CIA2_PORT_A
(byte*) CIA2_PORT_A_DDR
(byte*) CIA2_PORT_B
(byte*) CIA2_PORT_B_DDR
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) $7f
(byte*) COLS
(byte) CYAN
(byte*) D011
(byte*) D016
(byte*) D018
(byte) DARK_GREY
(byte) GREEN
(byte) GREY
(void()**) HARDWARE_IRQ
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) $d01a
(byte) IRQ_LIGHTPEN
(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) $d019
(void()**) KERNEL_IRQ
(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) $314
(byte*) LIGHTPEN_X
(byte*) LIGHTPEN_Y
(byte) LIGHT_BLUE
(byte) LIGHT_GREEN
(byte) LIGHT_GREY
(byte*) MUSIC
(const byte*) MUSIC#0 MUSIC = ((byte*))(word/signed word/dword/signed dword) $1000
(byte) ORANGE
(byte) PINK
(byte*) PROCPORT
(byte) PROCPORT_BASIC_KERNEL_IO
(byte*) PROCPORT_DDR
(byte) PROCPORT_DDR_MEMORY_MASK
(byte) PROCPORT_KERNEL_IO
(byte) PROCPORT_RAM_ALL
(byte) PROCPORT_RAM_CHARROM
(byte) PROCPORT_RAM_IO
(byte) PURPLE
(byte*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) $d012
(byte) RED
(byte*) SPRITES_COLS
(byte*) SPRITES_ENABLE
(byte*) SPRITES_EXPAND_X
(byte*) SPRITES_EXPAND_Y
(byte*) SPRITES_MC
(byte*) SPRITES_MC1
(byte*) SPRITES_MC2
(byte*) SPRITES_PRIORITY
(byte*) SPRITES_XMSB
(byte*) SPRITES_XPOS
(byte*) SPRITES_YPOS
(word) SPRITE_PTRS
(byte) VIC_BMM
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) $d011
(byte*) VIC_CONTROL2
(byte) VIC_CSEL
(byte) VIC_DEN
(byte) VIC_ECM
(byte) VIC_MCM
(byte*) VIC_MEMORY
(byte) VIC_RSEL
(byte) VIC_RST8
(byte) WHITE
(byte) YELLOW
interrupt(KERNEL_KEYBOARD)(void()) irq_play()
(label) irq_play::@return
(void()) main()
(label) main::@return

View File

@ -6,12 +6,18 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const DVAL = $20000
.label SCREEN = $400
main: {
lda #DVAL/$400
.const dw = $2000
.const w1 = dw&$ffff
.const w2 = <dw+1
lda #<w1
sta SCREEN
lda #0
lda #>w1
sta SCREEN+1
lda #<w2
sta SCREEN+3
lda #>w2
sta SCREEN+4
rts
}

View File

@ -8,9 +8,11 @@
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
[5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
[4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0
[5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0
[6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0
[7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0
to:main::@return
main::@return: scope:[main] from main
[6] return
[8] return
to:@return

View File

@ -1,18 +1,24 @@
Identified constant variable (dword) main::dw
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(dword) DVAL#0 ← (dword/signed dword) $20000
(byte*) SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400
to:@1
main: scope:[main] from @1
(dword~) main::$0 ← (dword) DVAL#0 / (word/signed word/dword/signed dword) $400
(word~) main::$1 ← ((word)) (dword~) main::$0
(byte~) main::$2 ← < (word~) main::$1
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte~) main::$2
(dword~) main::$3 ← (dword) DVAL#0 / (word/signed word/dword/signed dword) $400
(word~) main::$4 ← ((word)) (dword~) main::$3
(byte~) main::$5 ← > (word~) main::$4
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$5
(dword) main::dw#0 ← (word/signed word/dword/signed dword) $2000
(word~) main::$0 ← < (dword) main::dw#0
(word) main::w1#0 ← (word~) main::$0
(dword~) main::$1 ← (dword) main::dw#0 + (byte/signed byte/word/signed word/dword/signed dword) 1
(word~) main::$2 ← < (dword~) main::$1
(word) main::w2#0 ← (word~) main::$2
(byte~) main::$3 ← < (word) main::w1#0
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte~) main::$3
(byte~) main::$4 ← > (word) main::w1#0
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte~) main::$4
(byte~) main::$5 ← < (word) main::w2#0
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte~) main::$5
(byte~) main::$6 ← > (word) main::w2#0
*((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 4) ← (byte~) main::$6
to:main::@return
main::@return: scope:[main] from main
return
@ -29,42 +35,52 @@ SYMBOL TABLE SSA
(label) @2
(label) @begin
(label) @end
(dword) DVAL
(dword) DVAL#0
(byte*) SCREEN
(byte*) SCREEN#0
(void()) main()
(dword~) main::$0
(word~) main::$1
(byte~) main::$2
(dword~) main::$3
(word~) main::$4
(word~) main::$0
(dword~) main::$1
(word~) main::$2
(byte~) main::$3
(byte~) main::$4
(byte~) main::$5
(byte~) main::$6
(label) main::@return
(dword) main::dw
(dword) main::dw#0
(word) main::w1
(word) main::w1#0
(word) main::w2
(word) main::w2#0
Culled Empty Block (label) @2
Successful SSA optimization Pass2CullEmptyBlocks
Constant (const dword) DVAL#0 = $20000
Alias (word) main::w1#0 = (word~) main::$0
Alias (word) main::w2#0 = (word~) main::$2
Successful SSA optimization Pass2AliasElimination
Constant (const byte*) SCREEN#0 = ((byte*))$400
Constant (const dword) main::dw#0 = $2000
Successful SSA optimization Pass2ConstantIdentification
Constant (const dword) main::$0 = DVAL#0/$400
Constant (const dword) main::$3 = DVAL#0/$400
Constant (const word) main::w1#0 = <main::dw#0
Constant (const dword) main::$1 = main::dw#0+1
Successful SSA optimization Pass2ConstantIdentification
Constant (const word) main::$1 = ((word))main::$0
Constant (const word) main::$4 = ((word))main::$3
Constant (const word) main::w2#0 = <main::$1
Constant (const byte) main::$3 = <main::w1#0
Constant (const byte) main::$4 = >main::w1#0
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) main::$2 = <main::$1
Constant (const byte) main::$5 = >main::$4
Constant (const byte) main::$5 = <main::w2#0
Constant (const byte) main::$6 = >main::w2#0
Successful SSA optimization Pass2ConstantIdentification
Consolidated array index constant in *(SCREEN#0+0)
Consolidated array index constant in *(SCREEN#0+1)
Consolidated array index constant in *(SCREEN#0+3)
Consolidated array index constant in *(SCREEN#0+4)
Successful SSA optimization Pass2ConstantAdditionElimination
Constant inlined main::$1 = ((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$2 = <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$0 = (const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$5 = >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$3 = (const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$4 = ((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
Constant inlined main::$5 = <(const word) main::w2#0
Constant inlined main::$6 = >(const word) main::w2#0
Constant inlined main::$3 = <(const word) main::w1#0
Constant inlined main::$4 = >(const word) main::w1#0
Constant inlined main::$1 = (const dword) main::dw#0+(byte/signed byte/word/signed word/dword/signed dword) 1
Successful SSA optimization Pass2ConstantInlining
Simplifying constant plus zero SCREEN#0+0
Adding NOP phi() at start of @begin
@ -90,18 +106,22 @@ FINAL CONTROL FLOW GRAPH
@end: scope:[] from @1
[3] phi()
main: scope:[main] from @1
[4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
[5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400
[4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0
[5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0
[6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0
[7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0
to:main::@return
main::@return: scope:[main] from main
[6] return
[8] return
to:@return
VARIABLE REGISTER WEIGHTS
(dword) DVAL
(byte*) SCREEN
(void()) main()
(dword) main::dw
(word) main::w1
(word) main::w2
Initial phi equivalence classes
Complete equivalence classes
@ -118,7 +138,6 @@ INITIAL ASM
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const DVAL = $20000
.label SCREEN = $400
//SEG3 @begin
bbegin:
@ -136,29 +155,40 @@ bend_from_b1:
bend:
//SEG9 main
main: {
//SEG10 [4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #DVAL/$400
.const dw = $2000
.const w1 = dw&$ffff
.const w2 = <dw+1
//SEG10 [4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #<w1
sta SCREEN
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #0
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #>w1
sta SCREEN+1
//SEG12 [6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #<w2
sta SCREEN+3
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #>w2
sta SCREEN+4
jmp breturn
//SEG12 main::@return
//SEG14 main::@return
breturn:
//SEG13 [6] return
//SEG15 [8] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 33 combination
Uplifting [] best 33 combination
Uplifting [main] best 45 combination
Uplifting [] best 45 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
@ -172,7 +202,6 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const DVAL = $20000
.label SCREEN = $400
//SEG3 @begin
bbegin:
@ -190,16 +219,25 @@ bend_from_b1:
bend:
//SEG9 main
main: {
//SEG10 [4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #DVAL/$400
.const dw = $2000
.const w1 = dw&$ffff
.const w2 = <dw+1
//SEG10 [4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #<w1
sta SCREEN
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #0
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #>w1
sta SCREEN+1
//SEG12 [6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #<w2
sta SCREEN+3
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #>w2
sta SCREEN+4
jmp breturn
//SEG12 main::@return
//SEG14 main::@return
breturn:
//SEG13 [6] return
//SEG15 [8] return
rts
}
@ -225,17 +263,21 @@ FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(dword) DVAL
(const dword) DVAL#0 DVAL = (dword/signed dword) $20000
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(void()) main()
(label) main::@return
(dword) main::dw
(const dword) main::dw#0 dw = (word/signed word/dword/signed dword) $2000
(word) main::w1
(const word) main::w1#0 w1 = <(const dword) main::dw#0
(word) main::w2
(const word) main::w2#0 w2 = <(const dword) main::dw#0+(byte/signed byte/word/signed word/dword/signed dword) 1
FINAL ASSEMBLER
Score: 18
Score: 30
//SEG0 File Comments
// Illustrates problem with constant evaluation of lo/hi-operator
@ -248,7 +290,6 @@ Score: 18
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
.const DVAL = $20000
.label SCREEN = $400
//SEG3 @begin
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
@ -258,14 +299,23 @@ Score: 18
//SEG8 @end
//SEG9 main
main: {
//SEG10 [4] *((const byte*) SCREEN#0) ← <((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #DVAL/$400
.const dw = $2000
.const w1 = dw&$ffff
.const w2 = <dw+1
//SEG10 [4] *((const byte*) SCREEN#0) ← <(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #<w1
sta SCREEN
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >((word))(const dword) DVAL#0/(word/signed word/dword/signed dword) $400 -- _deref_pbuc1=vbuc2
lda #0
//SEG11 [5] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← >(const word) main::w1#0 -- _deref_pbuc1=vbuc2
lda #>w1
sta SCREEN+1
//SEG12 main::@return
//SEG13 [6] return
//SEG12 [6] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← <(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #<w2
sta SCREEN+3
//SEG13 [7] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 4) ← >(const word) main::w2#0 -- _deref_pbuc1=vbuc2
lda #>w2
sta SCREEN+4
//SEG14 main::@return
//SEG15 [8] return
rts
}

View File

@ -1,10 +1,14 @@
(label) @1
(label) @begin
(label) @end
(dword) DVAL
(const dword) DVAL#0 DVAL = (dword/signed dword) $20000
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400
(void()) main()
(label) main::@return
(dword) main::dw
(const dword) main::dw#0 dw = (word/signed word/dword/signed dword) $2000
(word) main::w1
(const word) main::w1#0 w1 = <(const dword) main::dw#0
(word) main::w2
(const word) main::w2#0 w2 = <(const dword) main::dw#0+(byte/signed byte/word/signed word/dword/signed dword) 1