From 0993be3f0186540e826d71ee65f84425e44ec858 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Tue, 26 Mar 2019 21:27:36 +0100 Subject: [PATCH] Added example of music routines. --- NOTICE.txt | 6 +- .../dk/camelot64/kickc/test/TestPrograms.java | 11 + src/test/kc/examples/music/music.kc | 29 + src/test/kc/examples/music/music_irq.kc | 43 + src/test/kc/examples/music/toiletrensdyr.sid | Bin 0 -> 2863 bytes src/test/kc/operator-lohi-problem.kc | 13 +- src/test/ref/examples/music/music.asm | 29 + src/test/ref/examples/music/music.cfg | 26 + src/test/ref/examples/music/music.log | 815 +++++++++++++++ src/test/ref/examples/music/music.sym | 91 ++ src/test/ref/examples/music/music_irq.asm | 62 ++ src/test/ref/examples/music/music_irq.cfg | 36 + src/test/ref/examples/music/music_irq.log | 973 ++++++++++++++++++ src/test/ref/examples/music/music_irq.sym | 99 ++ src/test/ref/operator-lohi-problem.asm | 12 +- src/test/ref/operator-lohi-problem.cfg | 8 +- src/test/ref/operator-lohi-problem.log | 172 ++-- src/test/ref/operator-lohi-problem.sym | 8 +- 18 files changed, 2360 insertions(+), 73 deletions(-) create mode 100755 src/test/kc/examples/music/music.kc create mode 100755 src/test/kc/examples/music/music_irq.kc create mode 100644 src/test/kc/examples/music/toiletrensdyr.sid create mode 100644 src/test/ref/examples/music/music.asm create mode 100644 src/test/ref/examples/music/music.cfg create mode 100644 src/test/ref/examples/music/music.log create mode 100644 src/test/ref/examples/music/music.sym create mode 100644 src/test/ref/examples/music/music_irq.asm create mode 100644 src/test/ref/examples/music/music_irq.cfg create mode 100644 src/test/ref/examples/music/music_irq.log create mode 100644 src/test/ref/examples/music/music_irq.sym diff --git a/NOTICE.txt b/NOTICE.txt index 139ecdd37..eb53315f3 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -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/ diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index a9e3a1fb9..0c8ca6dcf 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -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"); diff --git a/src/test/kc/examples/music/music.kc b/src/test/kc/examples/music/music.kc new file mode 100755 index 000000000..e8c1b7c44 --- /dev/null +++ b/src/test/kc/examples/music/music.kc @@ -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); +} \ No newline at end of file diff --git a/src/test/kc/examples/music/music_irq.kc b/src/test/kc/examples/music/music_irq.kc new file mode 100755 index 000000000..1e20de6a8 --- /dev/null +++ b/src/test/kc/examples/music/music_irq.kc @@ -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)--; +} \ No newline at end of file diff --git a/src/test/kc/examples/music/toiletrensdyr.sid b/src/test/kc/examples/music/toiletrensdyr.sid new file mode 100644 index 0000000000000000000000000000000000000000..57459d920bab6d81505a0ef05b48266d07799e95 GIT binary patch literal 2863 zcmb7FeQZkdUM*38OGb zAzCS9B!ed*bwfzwj+HH1TtRWAb$PGKlfu+WaitaiVNLs^jUqIu9hIiXpepDYd*|AT zXev;*W509nx#xF2@4fHs?CE@(6p`bEP(rQ5fJ`sOKK) zg3{rU{@|vbQJjZX1HuiBVsLx!{()CU53SZLOaA;wrE!pMfwa~ed^A~Cj4enj^T&>5 zb8rnb>;1G*THp1v^ZIALZHMAZ>womyo8LS3aoxn{yRM6W7C(65%Zpv^)F0j$ z85)_q_C@rf@2zKTpQJvad;Wf~xpv!Gm->4(ICtfr2c%O1JipB2Z2JoG|gxKbD%XFU`5D0e`sp~Y|O zj(~CubZ0<04qAvRRrG2#Rl;S;pjWG>N;hbYRQVxj5vu$IE|cJOxa{PtG;U!rU{PQL z5HDgLh})PK;)FE=^8tGvSQ`ZEz0ynmX>-SPW=EX3i6W#gmj>fL^ni>Y8=A-rO_*{4 zg1QW~p+lEbUFf^k#&$RE$K7GO0n=L0PhV0%F;78vExs(|@{wF27&ECkv%fz^Sw zQ((0aw_-j^Bvr082}&TX)e0d)xeb~iC_`wejDp?_$$6tn`*(mj(rgRWmIBP4W-%If zGh15661oZn$#Z?69Tb*PLxObPo6ktv?h942QpmQ!g0$IZ+)6$$HYSGhk>jspzGq*{ zr~I|7uDrH_4*dfAv}~#G1MHw4gOoe?k-rdGkJ1TKZ=n;Jxi)y$Oqz*H$wZ<%`Fi5R zq?|a-s=2XV%C}$v)wz@_+s)I(Mf5{?anz_w28}0^JB{aLsotx5!1ztF$Z(yrVo#;> zercnBC4oNP-u&+6iyacM$pvu{6N`fJS8gq!-EuFmT?oQn@g0}-0qC^gNtn@&@k$n> zfJnoe%o=V4#IQZB{&*HQF)vBa_!p9ib0W5<`Ckdvhh}>ObkktZtFcE2$EuB|3L788 z48GZn%h-hXu~Ngc;&%&0bc|wPeJ5b+b^*4o8(Y^`3`BG4Jvr!$fs#S3Agyevn-2@FKK=?uV4Yk0%~8 z4<5-mJfo!ntiSSH$%W?oyZE79rt?;Q^}!y$;5( zuXUg!(3NV@t3ep=g7JQ=Xh!Rz!gwtxM?rgsj@N-Q2D%rFCvZ=z&-GnB3XG($jsdfz zrN%P!iK5<*_I1lk(%p4`G_`Kpe7_6Zsa>P@-{Hrr9dIk38|Ie@Pr2cqnS3_0&zz+9 zvtF1s*>0H5upZzpH=(oLybXE?#(VgU!=S=A-o1R_@emKBSHWTxq`C`!g<%W&MNb9$ z<_9bG55C3T^L6{h{8fJO$`BYm+I%3jURww#KL@2Ot^Fflbl{Di!DZzLNJ<$8ZAQJY ze-!YRYpK9~L>9pFfxjJrkB>lVE!sV_nxkOs(S99BRcV(3tc@~jI%Kd`%8Jt3djVrR zzH4Ss%>X2$jDs5yCyXPYfO$JGjz)PqgnbII2t34lfrp0r7K-l=Jx1{rqqoy`e4p9U zvdxvtlRGu12+*tk!*z9f_u{qb+h}}_aD=9&|196^kL0^&|ibzQ?NGK&P z7jYb*#_5jvW%C>%__x~Z4yVIi?8d2+IEjO#2>F~WA!y0K$z4)pC3aL04|0#w>2!OX z#C_z;!;#PK3=R&ydFR8+n6h-D-REFGmVrcZbX2 z!rYx)%JIbhZ_1IoU-_PT`FGbh{8$k9-j-KXjAnBuddW$dkd=X)#2QYJH^|9ek~_JV zoayCre9rW7-0B6HJZ;3nB_2mnO{9h4m7gRxHmqWGWwFGx_Z{ zy`^$R_S69BB^arqBvWdl*pH%&&xBke(word)(DVAL/$400); + dword dw = $2000; + word w1 = < dw; + word w2 = < (dw+1); + + SCREEN[0] = w1; + + SCREEN[3] = w2; + } \ No newline at end of file diff --git a/src/test/ref/examples/music/music.asm b/src/test/ref/examples/music/music.asm new file mode 100644 index 000000000..672599779 --- /dev/null +++ b/src/test/ref/examples/music/music.asm @@ -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) + diff --git a/src/test/ref/examples/music/music.cfg b/src/test/ref/examples/music/music.cfg new file mode 100644 index 000000000..b43e00506 --- /dev/null +++ b/src/test/ref/examples/music/music.cfg @@ -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 diff --git a/src/test/ref/examples/music/music.log b/src/test/ref/examples/music/music.log new file mode 100644 index 000000000..2b8b9f45a --- /dev/null +++ b/src/test/ref/examples/music/music.log @@ -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) + + diff --git a/src/test/ref/examples/music/music.sym b/src/test/ref/examples/music/music.sym new file mode 100644 index 000000000..78db248ac --- /dev/null +++ b/src/test/ref/examples/music/music.sym @@ -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 + diff --git a/src/test/ref/examples/music/music_irq.asm b/src/test/ref/examples/music/music_irq.asm new file mode 100644 index 000000000..6d2ed307a --- /dev/null +++ b/src/test/ref/examples/music/music_irq.asm @@ -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+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) + diff --git a/src/test/ref/examples/music/music_irq.cfg b/src/test/ref/examples/music/music_irq.cfg new file mode 100644 index 000000000..4418af607 --- /dev/null +++ b/src/test/ref/examples/music/music_irq.cfg @@ -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 diff --git a/src/test/ref/examples/music/music_irq.log b/src/test/ref/examples/music/music_irq.log new file mode 100644 index 000000000..4b4c629d6 --- /dev/null +++ b/src/test/ref/examples/music/music_irq.log @@ -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+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+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+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) + + diff --git a/src/test/ref/examples/music/music_irq.sym b/src/test/ref/examples/music/music_irq.sym new file mode 100644 index 000000000..01b8de07f --- /dev/null +++ b/src/test/ref/examples/music/music_irq.sym @@ -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 + diff --git a/src/test/ref/operator-lohi-problem.asm b/src/test/ref/operator-lohi-problem.asm index 906ee8bbc..83e1032ff 100644 --- a/src/test/ref/operator-lohi-problem.asm +++ b/src/test/ref/operator-lohi-problem.asm @@ -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 = w1 sta SCREEN+1 + lda #w2 + sta SCREEN+4 rts } diff --git a/src/test/ref/operator-lohi-problem.cfg b/src/test/ref/operator-lohi-problem.cfg index cba730f0e..bac7c1b26 100644 --- a/src/test/ref/operator-lohi-problem.cfg +++ b/src/test/ref/operator-lohi-problem.cfg @@ -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 diff --git a/src/test/ref/operator-lohi-problem.log b/src/test/ref/operator-lohi-problem.log index 66a3fe0e1..604e9b960 100644 --- a/src/test/ref/operator-lohi-problem.log +++ b/src/test/ref/operator-lohi-problem.log @@ -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::w1#0 Successful SSA optimization Pass2ConstantIdentification -Constant (const byte) main::$2 = main::$4 +Constant (const byte) main::$5 = 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 = ((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 #(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 = ((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 #(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 = ((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 #(const word) main::w2#0 -- _deref_pbuc1=vbuc2 + lda #>w2 + sta SCREEN+4 + //SEG14 main::@return + //SEG15 [8] return rts } diff --git a/src/test/ref/operator-lohi-problem.sym b/src/test/ref/operator-lohi-problem.sym index fc3a74cc8..8e9d34294 100644 --- a/src/test/ref/operator-lohi-problem.sym +++ b/src/test/ref/operator-lohi-problem.sym @@ -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