From 02e57b06cb31fe570a9915ca448d2fc5a2053311 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Tue, 15 Dec 2020 00:42:52 +0100 Subject: [PATCH] Improved raster bars. Added simple VRAM example. #581 --- .../cache/fragment-cache-wdc65c02.asm | 167 ++ src/main/kc/include/cx16-vera.h | 18 +- src/main/kc/include/cx16.h | 9 +- src/main/kc/lib/cx16.c | 21 + .../dk/camelot64/kickc/test/TestPrograms.java | 5 + src/test/kc/examples/cx16/rasterbars.c | 82 +- src/test/kc/examples/cx16/text.c | 15 + src/test/ref/examples/cx16/rasterbars.asm | 168 +- src/test/ref/examples/cx16/rasterbars.cfg | 164 +- src/test/ref/examples/cx16/rasterbars.log | 1716 +++++++++++++---- src/test/ref/examples/cx16/rasterbars.sym | 77 +- src/test/ref/examples/cx16/text.asm | 104 + src/test/ref/examples/cx16/text.cfg | 43 + src/test/ref/examples/cx16/text.log | 668 +++++++ src/test/ref/examples/cx16/text.sym | 32 + 15 files changed, 2756 insertions(+), 533 deletions(-) create mode 100644 src/main/kc/lib/cx16.c create mode 100644 src/test/kc/examples/cx16/text.c create mode 100644 src/test/ref/examples/cx16/text.asm create mode 100644 src/test/ref/examples/cx16/text.cfg create mode 100644 src/test/ref/examples/cx16/text.log create mode 100644 src/test/ref/examples/cx16/text.sym diff --git a/src/main/fragment/cache/fragment-cache-wdc65c02.asm b/src/main/fragment/cache/fragment-cache-wdc65c02.asm index e64a515e5..5079ca8cb 100644 --- a/src/main/fragment/cache/fragment-cache-wdc65c02.asm +++ b/src/main/fragment/cache/fragment-cache-wdc65c02.asm @@ -148,3 +148,170 @@ iny //FRAGMENT vbuyy_neq_vbuc1_then_la1 cpy #{c1} bne {la1} +//FRAGMENT vbuz1=vbuz2 +lda {z2} +sta {z1} +//FRAGMENT pbuz1=pbuc1_plus_pbuc2_derefidx_vbuz2 +ldy {z2} +lda {c2},y +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT vbuz1=vbuz1_plus_vbuc1 +lda #{c1} +clc +adc {z1} +sta {z1} +//FRAGMENT pbuz1_derefidx_vbuz2=pbuc1_derefidx_vbuz2 +ldy {z2} +lda {c1},y +sta ({z1}),y +//FRAGMENT pbuz1=pbuc1 +lda #<{c1} +sta {z1} +lda #>{c1} +sta {z1}+1 +//FRAGMENT pbuz1_neq_pbuc1_then_la1 +lda {z1}+1 +cmp #>{c1} +bne {la1} +lda {z1} +cmp #<{c1} +bne {la1} +//FRAGMENT _deref_pbuz1=vbuc1 +lda #{c1} +ldy #0 +sta ({z1}),y +//FRAGMENT pbuz1=_inc_pbuz1 +inc {z1} +bne !+ +inc {z1}+1 +!: +//FRAGMENT vbuaa=vbuz1 +lda {z1} +//FRAGMENT vbuxx=vbuz1 +ldx {z1} +//FRAGMENT pbuz1=pbuc1_plus_pbuc2_derefidx_vbuaa +tay +lda {c2},y +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT pbuz1=pbuc1_plus_pbuc2_derefidx_vbuxx +lda {c2},x +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT pbuz1=pbuc1_plus_pbuc2_derefidx_vbuyy +lda {c2},y +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT vbuxx=vbuxx_plus_vbuc1 +txa +clc +adc #{c1} +tax +//FRAGMENT vbuyy=vbuyy_plus_vbuc1 +tya +clc +adc #{c1} +tay +//FRAGMENT pbuz1_derefidx_vbuaa=pbuc1_derefidx_vbuaa +tay +lda {c1},y +sta ({z1}),y +//FRAGMENT pbuz1_derefidx_vbuxx=pbuc1_derefidx_vbuxx +txa +tay +lda {c1},y +sta ({z1}),y +//FRAGMENT pbuz1_derefidx_vbuyy=pbuc1_derefidx_vbuyy +lda {c1},y +sta ({z1}),y +//FRAGMENT 0_neq_pbuc1_derefidx_vbuz1_then_la1 +ldy {z1} +lda {c1},y +cmp #0 +bne {la1} +//FRAGMENT pbuz1=pbuz2 +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 +//FRAGMENT vbuz1=pbuc1_derefidx_vbuz2 +ldy {z2} +lda {c1},y +sta {z1} +//FRAGMENT pbuz1=_inc_pbuz2 +clc +lda {z2} +adc #1 +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +//FRAGMENT vbuz1=_lo_pbuz2 +lda {z2} +sta {z1} +//FRAGMENT vbuz1=_hi_pbuz2 +lda {z2}+1 +sta {z1} +//FRAGMENT 0_neq_pbuc1_derefidx_vbuaa_then_la1 +tay +lda {c1},y +cmp #0 +bne {la1} +//FRAGMENT 0_neq_pbuc1_derefidx_vbuxx_then_la1 +lda {c1},x +cmp #0 +bne {la1} +//FRAGMENT 0_neq_pbuc1_derefidx_vbuyy_then_la1 +lda {c1},y +cmp #0 +bne {la1} +//FRAGMENT vbuz1=pbuc1_derefidx_vbuxx +lda {c1},x +sta {z1} +//FRAGMENT vbuz1=pbuc1_derefidx_vbuyy +lda {c1},y +sta {z1} +//FRAGMENT vbuaa=pbuc1_derefidx_vbuz1 +ldy {z1} +lda {c1},y +//FRAGMENT vbuaa=pbuc1_derefidx_vbuxx +lda {c1},x +//FRAGMENT vbuaa=pbuc1_derefidx_vbuyy +lda {c1},y +//FRAGMENT vbuxx=pbuc1_derefidx_vbuz1 +ldy {z1} +ldx {c1},y +//FRAGMENT vbuaa=_lo_pbuz1 +lda {z1} +//FRAGMENT vbuxx=_lo_pbuz1 +ldx {z1} +//FRAGMENT vbuaa=_hi_pbuz1 +lda {z1}+1 +//FRAGMENT vbuxx=_hi_pbuz1 +ldx {z1}+1 +//FRAGMENT vbuyy=_lo_pbuz1 +ldy {z1} +//FRAGMENT vbuyy=_hi_pbuz1 +ldy {z1}+1 +//FRAGMENT vbuyy=pbuc1_derefidx_vbuz1 +ldx {z1} +ldy {c1},x +//FRAGMENT vbuxx=pbuc1_derefidx_vbuyy +ldx {c1},y diff --git a/src/main/kc/include/cx16-vera.h b/src/main/kc/include/cx16-vera.h index 6d72e759e..b3d77b94f 100644 --- a/src/main/kc/include/cx16-vera.h +++ b/src/main/kc/include/cx16-vera.h @@ -11,7 +11,7 @@ // See https://github.com/commanderx16/x16-emulator/wiki/(VERA-0.8)-Registers-$9F23-and-$9F24-(and-$9F25) // $9F20 VRAM Address (7:0) -char * const VERA_ADDRC_L = 0x9f20; +char * const VERA_ADDRX_L = 0x9f20; // $9F21 VRAM Address (15:8) char * const VERA_ADDRX_M = 0x9f21; // $9F22 VRAM Address (7:0) @@ -20,6 +20,22 @@ char * const VERA_ADDRX_M = 0x9f21; // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. // Bit 0: VRAM Address (16) char * const VERA_ADDRX_H = 0x9f22; +const char VERA_INC_0 = 0x00; +const char VERA_INC_1 = 0x10; +const char VERA_INC_2 = 0x20; +const char VERA_INC_4 = 0x30; +const char VERA_INC_8 = 0x40; +const char VERA_INC_16 = 0x50; +const char VERA_INC_32 = 0x60; +const char VERA_INC_64 = 0x70; +const char VERA_INC_128 = 0x80; +const char VERA_INC_256 = 0x90; +const char VERA_INC_512 = 0xa0; +const char VERA_INC_40 = 0xb0; +const char VERA_INC_80 = 0xc0; +const char VERA_INC_160 = 0xd0; +const char VERA_INC_320 = 0xe0; +const char VERA_INC_640 = 0xf0; // $9F23 DATA0 VRAM Data port 0 char * const VERA_DATA0 = 0x9f23; // $9F24 DATA1 VRAM Data port 1 diff --git a/src/main/kc/include/cx16.h b/src/main/kc/include/cx16.h index 1a416a976..24749f7a3 100644 --- a/src/main/kc/include/cx16.h +++ b/src/main/kc/include/cx16.h @@ -33,4 +33,11 @@ void()** const HARDWARE_IRQ = 0xfffe; // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts void()** const KERNEL_IRQ = 0x0314; // $0316 (RAM) BRK vector - The vector used when the KERNAL serves IRQ caused by a BRK -void()** const KERNEL_BRK = 0x0316; \ No newline at end of file +void()** const KERNEL_BRK = 0x0316; + +// Put a single byte into VRAM. +// Uses VERA DATA0 +// - bank: Which 64K VRAM bank to put data into (0/1) +// - addr: The address in VRAM +// - data: The data to put into VRAM +void vpoke(char bank, char* addr, char data); \ No newline at end of file diff --git a/src/main/kc/lib/cx16.c b/src/main/kc/lib/cx16.c new file mode 100644 index 000000000..65555da98 --- /dev/null +++ b/src/main/kc/lib/cx16.c @@ -0,0 +1,21 @@ +// Commander X16 Functions +// https://www.commanderx16.com/forum/index.php?/about-faq/ +// https://github.com/commanderx16/x16-docs/blob/master/Commander%20X16%20Programmer's%20Reference%20Guide.md + +#include + +// Put a single byte into VRAM. +// Uses VERA DATA0 +// - bank: Which 64K VRAM bank to put data into (0/1) +// - addr: The address in VRAM +// - data: The data to put into VRAM +void vpoke(char bank, char* addr, char data) { + // Select DATA0 + *VERA_CTRL &= ~VERA_ADDRSEL; + // Set address + *VERA_ADDRX_L = addr; + *VERA_ADDRX_H = VERA_INC_0 | bank; + // Set data + *VERA_DATA0 = data; +} \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 3e78bd7fe..dd4b0b1de 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -463,6 +463,11 @@ public class TestPrograms { compileAndCompare("examples/nes/nes-demo.c"); } + @Test + public void testCx16Text() throws IOException, URISyntaxException { + compileAndCompare("examples/cx16/text.c"); + } + @Test public void testCx16Rasterbars() throws IOException, URISyntaxException { compileAndCompare("examples/cx16/rasterbars.c"); diff --git a/src/test/kc/examples/cx16/rasterbars.c b/src/test/kc/examples/cx16/rasterbars.c index 1e06a2adb..9bb74263a 100644 --- a/src/test/kc/examples/cx16/rasterbars.c +++ b/src/test/kc/examples/cx16/rasterbars.c @@ -4,53 +4,25 @@ #pragma target(cx16) #include #include <6502.h> +#include -align(0x100)char BARS[] = { +align(0x100) char SIN[256] = kickasm {{ + .fill 256, 99+99*sin(i*2*PI/256) +}}; - 0x10, 0, 0x11, 0, 0x12, 0, 0x13, 0, - 0x14, 0, 0x15, 0, 0x16, 0, 0x17, 0, - 0x18, 0, 0x19, 0, 0x1a, 0, 0x1b, 0, - 0x1c, 0, 0x1d, 0, 0x1e, 0, 0x1f, 0, - 0x1f, 0, 0x1e, 0, 0x1d, 0, 0x1c, 0, - 0x1b, 0, 0x1a, 0, 0x19, 0, 0x18, 0, - 0x17, 0, 0x16, 0, 0x15, 0, 0x14, 0, - 0x13, 0, 0x12, 0, 0x11, 0, 0x10, 0, - - 0x10, 0, 0x11, 0, 0x12, 0, 0x13, 0, - 0x14, 0, 0x15, 0, 0x16, 0, 0x17, 0, - 0x18, 0, 0x19, 0, 0x1a, 0, 0x1b, 0, - 0x1c, 0, 0x1d, 0, 0x1e, 0, 0x1f, 0, - 0x1f, 0, 0x1e, 0, 0x1d, 0, 0x1c, 0, - 0x1b, 0, 0x1a, 0, 0x19, 0, 0x18, 0, - 0x17, 0, 0x16, 0, 0x15, 0, 0x14, 0, - 0x13, 0, 0x12, 0, 0x11, 0, 0x10, 0, - - 0x10, 0, 0x11, 0, 0x12, 0, 0x13, 0, - 0x14, 0, 0x15, 0, 0x16, 0, 0x17, 0, - 0x18, 0, 0x19, 0, 0x1a, 0, 0x1b, 0, - 0x1c, 0, 0x1d, 0, 0x1e, 0, 0x1f, 0, - 0x1f, 0, 0x1e, 0, 0x1d, 0, 0x1c, 0, - 0x1b, 0, 0x1a, 0, 0x19, 0, 0x18, 0, - 0x17, 0, 0x16, 0, 0x15, 0, 0x14, 0, - 0x13, 0, 0x12, 0, 0x11, 0, 0x10, 0, - - 0x10, 0, 0x11, 0, 0x12, 0, 0x13, 0, - 0x14, 0, 0x15, 0, 0x16, 0, 0x17, 0, - 0x18, 0, 0x19, 0, 0x1a, 0, 0x1b, 0, - 0x1c, 0, 0x1d, 0, 0x1e, 0, 0x1f, 0, - 0x1f, 0, 0x1e, 0, 0x1d, 0, 0x1c, 0, - 0x1b, 0, 0x1a, 0, 0x19, 0, 0x18, 0, - 0x17, 0, 0x16, 0, 0x15, 0, 0x14, 0, - 0x13, 0, 0x12, 0, 0x11, 0, 0x10, 0, +align(0x100) char BARS[230]; +align(0x100) char BAR[32] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, }; void main() { // Enable LINE IRQ (also set line bit 8 to 0) SEI(); - *KERNEL_IRQ = &irq_zero; + *KERNEL_IRQ = &irq_line; *VERA_IEN = VERA_LINE; - *VERA_IRQLINE_L = 0; + *VERA_IRQLINE_L = 5; CLI(); // Wait forever for(;;) ; @@ -60,24 +32,33 @@ void main() { volatile char hstart = 0/4; // The horizontal stop volatile char hstop = 640/4; +// The vertical start +volatile char vstart = 0/2; +// The vertical stop +volatile char vstop = 480/2; // The countdown volatile char cnt = 2; +// The sin idx +volatile char sin_idx = 100; -// Interrupt Routine at raster 0 -void irq_zero() { +// LINE Interrupt Routine +void irq_line() { // Update the border *VERA_CTRL |= VERA_DCSEL; *VERA_DC_HSTART = hstart; *VERA_DC_HSTOP = hstop; + *VERA_DC_VSTART = vstart; + *VERA_DC_VSTOP = vstop; // Show color raster bars in the border *VERA_CTRL &= ~VERA_DCSEL; - for(char l=0;l!=255;l++) { + for(char l=0;l!=230;l++) { *VERA_DC_BORDER = BARS[l]; - for(char i=0;i<23;i++) ; + for(char i=0;i<24;i++) ; // Wait exactly long enought to go to the next raster line + *VERA_DC_BORDER = 0; + for(char i=0;i<23;i++) ; // Wait exactly long enought to go to the next raster line + asm { nop nop } } - *VERA_DC_BORDER = 0; - *VERA_CTRL |= VERA_DCSEL; // Animate the border if(--cnt==0) { @@ -85,9 +66,22 @@ void irq_zero() { if(hstart<=320/4) { hstart++; hstop--; + vstart++; + vstop--; } } + // Animate the bars + memset(BARS, 0, sizeof(BARS)); + char idx = sin_idx--; + for(char b=0;b<8;b++) { + char * bar = BARS + SIN[idx]; + for(char i=0;i + +void main() { + char MSG[] = "hello world!"; + // Address of the default screen + char* vaddr = 0x0000; + for(char i=0;MSG[i];i++) { + vpoke(0, vaddr++, MSG[i]); // Message + vpoke(0, vaddr++, 0x21); // Red background, White foreground + } +} \ No newline at end of file diff --git a/src/test/ref/examples/cx16/rasterbars.asm b/src/test/ref/examples/cx16/rasterbars.asm index 185a197b0..0d0c82e59 100644 --- a/src/test/ref/examples/cx16/rasterbars.asm +++ b/src/test/ref/examples/cx16/rasterbars.asm @@ -14,6 +14,7 @@ .const VERA_DCSEL = 2 .const VERA_LINE = 2 + .const SIZEOF_BYTE = 1 // $9F25 CTRL Control // Bit 7: Reset // Bit 1: DCSEL @@ -46,14 +47,24 @@ .label VERA_DC_HSTART = $9f29 // $9F2A DC_HSTOP (DCSEL=1) Active Display H-Stop (9:2) .label VERA_DC_HSTOP = $9f2a + // $9F2B DC_VSTART (DCSEL=1) Active Display V-Start (8:1) + .label VERA_DC_VSTART = $9f2b + // $9F2C DC_VSTOP (DCSEL=1) Active Display V-Stop (8:1) + .label VERA_DC_VSTOP = $9f2c // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The horizontal start - .label hstart = 2 + .label hstart = 3 // The horizontal stop - .label hstop = 3 + .label hstop = 4 + // The vertical start + .label vstart = 5 + // The vertical stop + .label vstop = 6 // The countdown - .label cnt = 4 + .label cnt = 7 + // The sin idx + .label sin_idx = 8 .segment Code __start: { // hstart = 0/4 @@ -62,14 +73,25 @@ __start: { // hstop = 640/4 lda #$280/4 sta.z hstop + // vstart = 0/2 + lda #0 + sta.z vstart + // vstop = 480/2 + lda #$1e0/2 + sta.z vstop // cnt = 2 lda #2 sta.z cnt + // sin_idx = 100 + lda #$64 + sta.z sin_idx jsr main rts } -// Interrupt Routine at raster 0 -irq_zero: { +// LINE Interrupt Routine +irq_line: { + .label idx = 2 + .label bar = 9 // *VERA_CTRL |= VERA_DCSEL // Update the border lda #VERA_DCSEL @@ -81,6 +103,12 @@ irq_zero: { // *VERA_DC_HSTOP = hstop lda.z hstop sta VERA_DC_HSTOP + // *VERA_DC_VSTART = vstart + lda.z vstart + sta VERA_DC_VSTART + // *VERA_DC_VSTOP = vstop + lda.z vstop + sta VERA_DC_VSTOP // *VERA_CTRL &= ~VERA_DCSEL // Show color raster bars in the border lda #VERA_DCSEL^$ff @@ -88,16 +116,9 @@ irq_zero: { sta VERA_CTRL ldx #0 __b2: - // for(char l=0;l!=255;l++) - cpx #$ff + // for(char l=0;l!=230;l++) + cpx #$e6 bne __b3 - // *VERA_DC_BORDER = 0 - lda #0 - sta VERA_DC_BORDER - // *VERA_CTRL |= VERA_DCSEL - lda #VERA_DCSEL - ora VERA_CTRL - sta VERA_CTRL // if(--cnt==0) dec.z cnt lda.z cnt @@ -114,7 +135,23 @@ irq_zero: { inc.z hstart // hstop--; dec.z hstop + // vstart++; + inc.z vstart + // vstop--; + dec.z vstop __b1: + // memset(BARS, 0, sizeof(BARS)) + // Animate the bars + jsr memset + // idx = sin_idx-- + lda.z sin_idx + sta.z idx + dec.z sin_idx + ldx #0 + __b13: + // for(char b=0;b<8;b++) + cpx #8 + bcc __b14 // *VERA_ISR = VERA_LINE // Reset the LINE interrupt lda #VERA_LINE @@ -127,42 +164,127 @@ irq_zero: { rti // } rts + __b14: + // bar = BARS + SIN[idx] + ldy.z idx + lda SIN,y + clc + adc #BARS + adc #0 + sta.z bar+1 + ldy #0 + __b16: + // for(char i=0;iirq_zero + lda #>irq_line sta KERNEL_IRQ+1 // *VERA_IEN = VERA_LINE lda #VERA_LINE sta VERA_IEN - // *VERA_IRQLINE_L = 0 - lda #0 + // *VERA_IRQLINE_L = 5 + lda #5 sta VERA_IRQLINE_L // asm cli __b1: jmp __b1 } +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +memset: { + .const num = $e6*SIZEOF_BYTE + .const c = 0 + .label str = BARS + .label end = str+num + .label dst = 9 + lda #str + sta.z dst+1 + __b1: + // for(char* dst = str; dst!=end; dst++) + lda.z dst+1 + cmp #>end + bne __b2 + lda.z dst + cmp #=(byte)$140/4+1) goto irq_zero::@1 - to:irq_zero::@9 -irq_zero::@9: scope:[irq_zero] from irq_zero::@8 - [19] hstart = ++ hstart - [20] hstop = -- hstop - to:irq_zero::@1 -irq_zero::@1: scope:[irq_zero] from irq_zero::@4 irq_zero::@8 irq_zero::@9 - [21] *VERA_ISR = VERA_LINE +void irq_line() +irq_line: scope:[irq_line] from + [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL + [11] *VERA_DC_HSTART = hstart + [12] *VERA_DC_HSTOP = hstop + [13] *VERA_DC_VSTART = vstart + [14] *VERA_DC_VSTOP = vstop + [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL + to:irq_line::@2 +irq_line::@2: scope:[irq_line] from irq_line irq_line::@10 + [16] irq_line::l#2 = phi( irq_line/0, irq_line::@10/irq_line::l#1 ) + [17] if(irq_line::l#2!=$e6) goto irq_line::@3 + to:irq_line::@4 +irq_line::@4: scope:[irq_line] from irq_line::@2 + [18] cnt = -- cnt + [19] if(cnt!=0) goto irq_line::@1 + to:irq_line::@11 +irq_line::@11: scope:[irq_line] from irq_line::@4 + [20] cnt = 2 + [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 + to:irq_line::@12 +irq_line::@12: scope:[irq_line] from irq_line::@11 + [22] hstart = ++ hstart + [23] hstop = -- hstop + [24] vstart = ++ vstart + [25] vstop = -- vstop + to:irq_line::@1 +irq_line::@1: scope:[irq_line] from irq_line::@11 irq_line::@12 irq_line::@4 + [26] phi() + [27] call memset + to:irq_line::@19 +irq_line::@19: scope:[irq_line] from irq_line::@1 + [28] irq_line::idx#0 = sin_idx + [29] sin_idx = -- sin_idx + to:irq_line::@13 +irq_line::@13: scope:[irq_line] from irq_line::@18 irq_line::@19 + [30] irq_line::idx#2 = phi( irq_line::@18/irq_line::idx#1, irq_line::@19/irq_line::idx#0 ) + [30] irq_line::b#2 = phi( irq_line::@18/irq_line::b#1, irq_line::@19/0 ) + [31] if(irq_line::b#2<8) goto irq_line::@14 + to:irq_line::@15 +irq_line::@15: scope:[irq_line] from irq_line::@13 + [32] *VERA_ISR = VERA_LINE asm { ply plx pla rti } - to:irq_zero::@return -irq_zero::@return: scope:[irq_zero] from irq_zero::@1 - [23] return + to:irq_line::@return +irq_line::@return: scope:[irq_line] from irq_line::@15 + [34] return to:@return -irq_zero::@3: scope:[irq_zero] from irq_zero::@2 - [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] - to:irq_zero::@5 -irq_zero::@5: scope:[irq_zero] from irq_zero::@3 irq_zero::@6 - [25] irq_zero::i#2 = phi( irq_zero::@3/0, irq_zero::@6/irq_zero::i#1 ) - [26] if(irq_zero::i#2<$17) goto irq_zero::@6 - to:irq_zero::@7 -irq_zero::@7: scope:[irq_zero] from irq_zero::@5 - [27] irq_zero::l#1 = ++ irq_zero::l#2 - to:irq_zero::@2 -irq_zero::@6: scope:[irq_zero] from irq_zero::@5 - [28] irq_zero::i#1 = ++ irq_zero::i#2 - to:irq_zero::@5 +irq_line::@14: scope:[irq_line] from irq_line::@13 + [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] + to:irq_line::@16 +irq_line::@16: scope:[irq_line] from irq_line::@14 irq_line::@17 + [36] irq_line::i2#2 = phi( irq_line::@14/0, irq_line::@17/irq_line::i2#1 ) + [37] if(irq_line::i2#2<$20*SIZEOF_BYTE) goto irq_line::@17 + to:irq_line::@18 +irq_line::@18: scope:[irq_line] from irq_line::@16 + [38] irq_line::idx#1 = irq_line::idx#2 + $d + [39] irq_line::b#1 = ++ irq_line::b#2 + to:irq_line::@13 +irq_line::@17: scope:[irq_line] from irq_line::@16 + [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] + [41] irq_line::i2#1 = ++ irq_line::i2#2 + to:irq_line::@16 +irq_line::@3: scope:[irq_line] from irq_line::@2 + [42] *VERA_DC_BORDER = BARS[irq_line::l#2] + to:irq_line::@5 +irq_line::@5: scope:[irq_line] from irq_line::@3 irq_line::@6 + [43] irq_line::i#2 = phi( irq_line::@3/0, irq_line::@6/irq_line::i#1 ) + [44] if(irq_line::i#2<$18) goto irq_line::@6 + to:irq_line::@7 +irq_line::@7: scope:[irq_line] from irq_line::@5 + [45] *VERA_DC_BORDER = 0 + to:irq_line::@8 +irq_line::@8: scope:[irq_line] from irq_line::@7 irq_line::@9 + [46] irq_line::i1#2 = phi( irq_line::@7/0, irq_line::@9/irq_line::i1#1 ) + [47] if(irq_line::i1#2<$17) goto irq_line::@9 + to:irq_line::@10 +irq_line::@10: scope:[irq_line] from irq_line::@8 + asm { nop nop } + [49] irq_line::l#1 = ++ irq_line::l#2 + to:irq_line::@2 +irq_line::@9: scope:[irq_line] from irq_line::@8 + [50] irq_line::i1#1 = ++ irq_line::i1#2 + to:irq_line::@8 +irq_line::@6: scope:[irq_line] from irq_line::@5 + [51] irq_line::i#1 = ++ irq_line::i#2 + to:irq_line::@5 void main() main: scope:[main] from __start::@1 - [29] phi() + [52] phi() to:main::SEI1 main::SEI1: scope:[main] from main asm { sei } to:main::@2 main::@2: scope:[main] from main::SEI1 - [31] *KERNEL_IRQ = &irq_zero - [32] *VERA_IEN = VERA_LINE - [33] *VERA_IRQLINE_L = 0 + [54] *KERNEL_IRQ = &irq_line + [55] *VERA_IEN = VERA_LINE + [56] *VERA_IRQLINE_L = 5 to:main::CLI1 main::CLI1: scope:[main] from main::@2 asm { cli } to:main::@1 main::@1: scope:[main] from main::@1 main::CLI1 - [35] phi() + [58] phi() to:main::@1 + +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from irq_line::@1 + [59] phi() + to:memset::@1 +memset::@1: scope:[memset] from memset memset::@2 + [60] memset::dst#2 = phi( memset/(byte*)memset::str#0, memset::@2/memset::dst#1 ) + [61] if(memset::dst#2!=memset::end#0) goto memset::@2 + to:memset::@return +memset::@return: scope:[memset] from memset::@1 + [62] return + to:@return +memset::@2: scope:[memset] from memset::@1 + [63] *memset::dst#2 = memset::c#0 + [64] memset::dst#1 = ++ memset::dst#2 + to:memset::@1 diff --git a/src/test/ref/examples/cx16/rasterbars.log b/src/test/ref/examples/cx16/rasterbars.log index 419d39954..1cf37d703 100644 --- a/src/test/ref/examples/cx16/rasterbars.log +++ b/src/test/ref/examples/cx16/rasterbars.log @@ -1,10 +1,54 @@ -Resolved forward reference irq_zero to void irq_zero() +Resolved forward reference irq_line to void irq_line() Inlined call call SEI Inlined call call CLI Inlined call call __init CONTROL FLOW GRAPH SSA +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from irq_line::@1 + memset::c#4 = phi( irq_line::@1/memset::c#0 ) + memset::str#3 = phi( irq_line::@1/memset::str#0 ) + memset::num#1 = phi( irq_line::@1/memset::num#0 ) + memset::$0 = memset::num#1 > 0 + memset::$1 = ! memset::$0 + if(memset::$1) goto memset::@1 + to:memset::@2 +memset::@1: scope:[memset] from memset memset::@3 + memset::str#1 = phi( memset/memset::str#3, memset::@3/memset::str#4 ) + memset::return#0 = memset::str#1 + to:memset::@return +memset::@2: scope:[memset] from memset + memset::c#3 = phi( memset/memset::c#4 ) + memset::num#2 = phi( memset/memset::num#1 ) + memset::str#2 = phi( memset/memset::str#3 ) + memset::$4 = (byte*)memset::str#2 + memset::$2 = memset::$4 + memset::num#2 + memset::end#0 = memset::$2 + memset::dst#0 = ((byte*)) memset::str#2 + to:memset::@3 +memset::@3: scope:[memset] from memset::@2 memset::@4 + memset::c#2 = phi( memset::@2/memset::c#3, memset::@4/memset::c#1 ) + memset::str#4 = phi( memset::@2/memset::str#2, memset::@4/memset::str#5 ) + memset::end#1 = phi( memset::@2/memset::end#0, memset::@4/memset::end#2 ) + memset::dst#2 = phi( memset::@2/memset::dst#0, memset::@4/memset::dst#1 ) + memset::$3 = memset::dst#2 != memset::end#1 + if(memset::$3) goto memset::@4 + to:memset::@1 +memset::@4: scope:[memset] from memset::@3 + memset::str#5 = phi( memset::@3/memset::str#4 ) + memset::end#2 = phi( memset::@3/memset::end#1 ) + memset::dst#3 = phi( memset::@3/memset::dst#2 ) + memset::c#1 = phi( memset::@3/memset::c#2 ) + *memset::dst#3 = memset::c#1 + memset::dst#1 = ++ memset::dst#3 + to:memset::@3 +memset::@return: scope:[memset] from memset::@1 + memset::return#3 = phi( memset::@1/memset::return#0 ) + memset::return#1 = memset::return#3 + return + to:@return + void main() main: scope:[main] from __start::@1 to:main::SEI1 @@ -12,9 +56,9 @@ main::SEI1: scope:[main] from main asm { sei } to:main::@2 main::@2: scope:[main] from main::SEI1 - *KERNEL_IRQ = &irq_zero + *KERNEL_IRQ = &irq_line *VERA_IEN = VERA_LINE - *VERA_IRQLINE_L = 0 + *VERA_IRQLINE_L = 5 to:main::CLI1 main::CLI1: scope:[main] from main::@2 asm { cli } @@ -25,62 +69,130 @@ main::@return: scope:[main] from return to:@return -void irq_zero() -irq_zero: scope:[irq_zero] from +void irq_line() +irq_line: scope:[irq_line] from *VERA_CTRL = *VERA_CTRL | VERA_DCSEL *VERA_DC_HSTART = hstart *VERA_DC_HSTOP = hstop + *VERA_DC_VSTART = vstart + *VERA_DC_VSTOP = vstop *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL - irq_zero::l#0 = 0 - to:irq_zero::@2 -irq_zero::@2: scope:[irq_zero] from irq_zero irq_zero::@7 - irq_zero::l#2 = phi( irq_zero/irq_zero::l#0, irq_zero::@7/irq_zero::l#1 ) - irq_zero::$2 = irq_zero::l#2 != $ff - if(irq_zero::$2) goto irq_zero::@3 - to:irq_zero::@4 -irq_zero::@3: scope:[irq_zero] from irq_zero::@2 - irq_zero::l#3 = phi( irq_zero::@2/irq_zero::l#2 ) - *VERA_DC_BORDER = BARS[irq_zero::l#3] - irq_zero::i#0 = 0 - to:irq_zero::@5 -irq_zero::@4: scope:[irq_zero] from irq_zero::@2 - *VERA_DC_BORDER = 0 - *VERA_CTRL = *VERA_CTRL | VERA_DCSEL + irq_line::l#0 = 0 + to:irq_line::@2 +irq_line::@2: scope:[irq_line] from irq_line irq_line::@10 + irq_line::l#2 = phi( irq_line/irq_line::l#0, irq_line::@10/irq_line::l#1 ) + irq_line::$4 = irq_line::l#2 != $e6 + if(irq_line::$4) goto irq_line::@3 + to:irq_line::@4 +irq_line::@3: scope:[irq_line] from irq_line::@2 + irq_line::l#3 = phi( irq_line::@2/irq_line::l#2 ) + *VERA_DC_BORDER = BARS[irq_line::l#3] + irq_line::i#0 = 0 + to:irq_line::@5 +irq_line::@4: scope:[irq_line] from irq_line::@2 cnt = -- cnt - irq_zero::$0 = cnt == 0 - irq_zero::$1 = ! irq_zero::$0 - if(irq_zero::$1) goto irq_zero::@1 - to:irq_zero::@8 -irq_zero::@5: scope:[irq_zero] from irq_zero::@3 irq_zero::@6 - irq_zero::l#5 = phi( irq_zero::@3/irq_zero::l#3, irq_zero::@6/irq_zero::l#6 ) - irq_zero::i#2 = phi( irq_zero::@3/irq_zero::i#0, irq_zero::@6/irq_zero::i#1 ) - irq_zero::$3 = irq_zero::i#2 < $17 - if(irq_zero::$3) goto irq_zero::@6 - to:irq_zero::@7 -irq_zero::@6: scope:[irq_zero] from irq_zero::@5 - irq_zero::l#6 = phi( irq_zero::@5/irq_zero::l#5 ) - irq_zero::i#3 = phi( irq_zero::@5/irq_zero::i#2 ) - irq_zero::i#1 = ++ irq_zero::i#3 - to:irq_zero::@5 -irq_zero::@7: scope:[irq_zero] from irq_zero::@5 - irq_zero::l#4 = phi( irq_zero::@5/irq_zero::l#5 ) - irq_zero::l#1 = ++ irq_zero::l#4 - to:irq_zero::@2 -irq_zero::@1: scope:[irq_zero] from irq_zero::@4 irq_zero::@8 irq_zero::@9 - *VERA_ISR = VERA_LINE - asm { ply plx pla rti } - to:irq_zero::@return -irq_zero::@8: scope:[irq_zero] from irq_zero::@4 + irq_line::$0 = cnt == 0 + irq_line::$1 = ! irq_line::$0 + if(irq_line::$1) goto irq_line::@1 + to:irq_line::@11 +irq_line::@5: scope:[irq_line] from irq_line::@3 irq_line::@6 + irq_line::l#8 = phi( irq_line::@3/irq_line::l#3, irq_line::@6/irq_line::l#9 ) + irq_line::i#2 = phi( irq_line::@3/irq_line::i#0, irq_line::@6/irq_line::i#1 ) + irq_line::$5 = irq_line::i#2 < $18 + if(irq_line::$5) goto irq_line::@6 + to:irq_line::@7 +irq_line::@6: scope:[irq_line] from irq_line::@5 + irq_line::l#9 = phi( irq_line::@5/irq_line::l#8 ) + irq_line::i#3 = phi( irq_line::@5/irq_line::i#2 ) + irq_line::i#1 = ++ irq_line::i#3 + to:irq_line::@5 +irq_line::@7: scope:[irq_line] from irq_line::@5 + irq_line::l#6 = phi( irq_line::@5/irq_line::l#8 ) + *VERA_DC_BORDER = 0 + irq_line::i1#0 = 0 + to:irq_line::@8 +irq_line::@8: scope:[irq_line] from irq_line::@7 irq_line::@9 + irq_line::l#5 = phi( irq_line::@7/irq_line::l#6, irq_line::@9/irq_line::l#7 ) + irq_line::i1#2 = phi( irq_line::@7/irq_line::i1#0, irq_line::@9/irq_line::i1#1 ) + irq_line::$6 = irq_line::i1#2 < $17 + if(irq_line::$6) goto irq_line::@9 + to:irq_line::@10 +irq_line::@9: scope:[irq_line] from irq_line::@8 + irq_line::l#7 = phi( irq_line::@8/irq_line::l#5 ) + irq_line::i1#3 = phi( irq_line::@8/irq_line::i1#2 ) + irq_line::i1#1 = ++ irq_line::i1#3 + to:irq_line::@8 +irq_line::@10: scope:[irq_line] from irq_line::@8 + irq_line::l#4 = phi( irq_line::@8/irq_line::l#5 ) + asm { nop nop } + irq_line::l#1 = ++ irq_line::l#4 + to:irq_line::@2 +irq_line::@1: scope:[irq_line] from irq_line::@11 irq_line::@12 irq_line::@4 + irq_line::$2 = sizeof BARS + memset::str#0 = (void*)BARS + memset::c#0 = 0 + memset::num#0 = irq_line::$2 + call memset + memset::return#2 = memset::return#1 + to:irq_line::@19 +irq_line::@19: scope:[irq_line] from irq_line::@1 + irq_line::idx#0 = sin_idx + sin_idx = -- sin_idx + irq_line::b#0 = 0 + to:irq_line::@13 +irq_line::@11: scope:[irq_line] from irq_line::@4 cnt = 2 - irq_zero::$4 = hstart <= $140/4 - irq_zero::$5 = ! irq_zero::$4 - if(irq_zero::$5) goto irq_zero::@1 - to:irq_zero::@9 -irq_zero::@9: scope:[irq_zero] from irq_zero::@8 + irq_line::$7 = hstart <= $140/4 + irq_line::$8 = ! irq_line::$7 + if(irq_line::$8) goto irq_line::@1 + to:irq_line::@12 +irq_line::@12: scope:[irq_line] from irq_line::@11 hstart = ++ hstart hstop = -- hstop - to:irq_zero::@1 -irq_zero::@return: scope:[irq_zero] from irq_zero::@1 + vstart = ++ vstart + vstop = -- vstop + to:irq_line::@1 +irq_line::@13: scope:[irq_line] from irq_line::@18 irq_line::@19 + irq_line::idx#4 = phi( irq_line::@18/irq_line::idx#1, irq_line::@19/irq_line::idx#0 ) + irq_line::b#2 = phi( irq_line::@18/irq_line::b#1, irq_line::@19/irq_line::b#0 ) + irq_line::$9 = irq_line::b#2 < 8 + if(irq_line::$9) goto irq_line::@14 + to:irq_line::@15 +irq_line::@14: scope:[irq_line] from irq_line::@13 + irq_line::b#5 = phi( irq_line::@13/irq_line::b#2 ) + irq_line::idx#2 = phi( irq_line::@13/irq_line::idx#4 ) + irq_line::$10 = BARS + SIN[irq_line::idx#2] + irq_line::bar#0 = irq_line::$10 + irq_line::i2#0 = 0 + to:irq_line::@16 +irq_line::@15: scope:[irq_line] from irq_line::@13 + *VERA_ISR = VERA_LINE + asm { ply plx pla rti } + to:irq_line::@return +irq_line::@16: scope:[irq_line] from irq_line::@14 irq_line::@17 + irq_line::b#4 = phi( irq_line::@14/irq_line::b#5, irq_line::@17/irq_line::b#6 ) + irq_line::idx#5 = phi( irq_line::@14/irq_line::idx#2, irq_line::@17/irq_line::idx#6 ) + irq_line::bar#2 = phi( irq_line::@14/irq_line::bar#0, irq_line::@17/irq_line::bar#1 ) + irq_line::i2#2 = phi( irq_line::@14/irq_line::i2#0, irq_line::@17/irq_line::i2#1 ) + irq_line::$11 = sizeof BAR + irq_line::$12 = irq_line::i2#2 < irq_line::$11 + if(irq_line::$12) goto irq_line::@17 + to:irq_line::@18 +irq_line::@17: scope:[irq_line] from irq_line::@16 + irq_line::b#6 = phi( irq_line::@16/irq_line::b#4 ) + irq_line::idx#6 = phi( irq_line::@16/irq_line::idx#5 ) + irq_line::bar#1 = phi( irq_line::@16/irq_line::bar#2 ) + irq_line::i2#3 = phi( irq_line::@16/irq_line::i2#2 ) + irq_line::bar#1[irq_line::i2#3] = BAR[irq_line::i2#3] + irq_line::i2#1 = ++ irq_line::i2#3 + to:irq_line::@16 +irq_line::@18: scope:[irq_line] from irq_line::@16 + irq_line::b#3 = phi( irq_line::@16/irq_line::b#4 ) + irq_line::idx#3 = phi( irq_line::@16/irq_line::idx#5 ) + irq_line::idx#1 = irq_line::idx#3 + $d + irq_line::b#1 = ++ irq_line::b#3 + to:irq_line::@13 +irq_line::@return: scope:[irq_line] from irq_line::@15 return to:@return @@ -90,7 +202,10 @@ __start: scope:[__start] from __start::__init1: scope:[__start] from __start hstart = (byte)0/4 hstop = (byte)$280/4 + vstart = (byte)0/2 + vstop = (byte)$1e0/2 cnt = 2 + sin_idx = $64 to:__start::@1 __start::@1: scope:[__start] from __start::__init1 call main @@ -102,13 +217,18 @@ __start::@return: scope:[__start] from __start::@2 to:@return SYMBOL TABLE SSA -const byte* BARS[] = { $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0 } +const byte* BAR[$20] = { $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f, $1f, $1e, $1d, $1c, $1b, $1a, $19, $18, $17, $16, $15, $14, $13, $12, $11, $10 } +const byte* BARS[$e6] = { fill( $e6, 0) } const nomodify void()** KERNEL_IRQ = (void()**)$314 +const byte* SIN[$100] = kickasm {{ .fill 256, 99+99*sin(i*2*PI/256) + }} const nomodify byte* VERA_CTRL = (byte*)$9f25 const nomodify byte VERA_DCSEL = 2 const nomodify byte* VERA_DC_BORDER = (byte*)$9f2c const nomodify byte* VERA_DC_HSTART = (byte*)$9f29 const nomodify byte* VERA_DC_HSTOP = (byte*)$9f2a +const nomodify byte* VERA_DC_VSTART = (byte*)$9f2b +const nomodify byte* VERA_DC_VSTOP = (byte*)$9f2c const nomodify byte* VERA_IEN = (byte*)$9f26 const nomodify byte* VERA_IRQLINE_L = (byte*)$9f28 const nomodify byte* VERA_ISR = (byte*)$9f27 @@ -117,38 +237,124 @@ void __start() volatile byte cnt loadstore volatile byte hstart loadstore volatile byte hstop loadstore -void irq_zero() -bool~ irq_zero::$0 -bool~ irq_zero::$1 -bool~ irq_zero::$2 -bool~ irq_zero::$3 -bool~ irq_zero::$4 -bool~ irq_zero::$5 -byte irq_zero::i -byte irq_zero::i#0 -byte irq_zero::i#1 -byte irq_zero::i#2 -byte irq_zero::i#3 -byte irq_zero::l -byte irq_zero::l#0 -byte irq_zero::l#1 -byte irq_zero::l#2 -byte irq_zero::l#3 -byte irq_zero::l#4 -byte irq_zero::l#5 -byte irq_zero::l#6 +void irq_line() +bool~ irq_line::$0 +bool~ irq_line::$1 +byte*~ irq_line::$10 +byte~ irq_line::$11 +bool~ irq_line::$12 +byte~ irq_line::$2 +bool~ irq_line::$4 +bool~ irq_line::$5 +bool~ irq_line::$6 +bool~ irq_line::$7 +bool~ irq_line::$8 +bool~ irq_line::$9 +byte irq_line::b +byte irq_line::b#0 +byte irq_line::b#1 +byte irq_line::b#2 +byte irq_line::b#3 +byte irq_line::b#4 +byte irq_line::b#5 +byte irq_line::b#6 +byte* irq_line::bar +byte* irq_line::bar#0 +byte* irq_line::bar#1 +byte* irq_line::bar#2 +byte irq_line::i +byte irq_line::i#0 +byte irq_line::i#1 +byte irq_line::i#2 +byte irq_line::i#3 +byte irq_line::i1 +byte irq_line::i1#0 +byte irq_line::i1#1 +byte irq_line::i1#2 +byte irq_line::i1#3 +byte irq_line::i2 +byte irq_line::i2#0 +byte irq_line::i2#1 +byte irq_line::i2#2 +byte irq_line::i2#3 +byte irq_line::idx +byte irq_line::idx#0 +byte irq_line::idx#1 +byte irq_line::idx#2 +byte irq_line::idx#3 +byte irq_line::idx#4 +byte irq_line::idx#5 +byte irq_line::idx#6 +byte irq_line::l +byte irq_line::l#0 +byte irq_line::l#1 +byte irq_line::l#2 +byte irq_line::l#3 +byte irq_line::l#4 +byte irq_line::l#5 +byte irq_line::l#6 +byte irq_line::l#7 +byte irq_line::l#8 +byte irq_line::l#9 void main() +void* memset(void* memset::str , byte memset::c , word memset::num) +bool~ memset::$0 +bool~ memset::$1 +byte*~ memset::$2 +bool~ memset::$3 +byte*~ memset::$4 +byte memset::c +byte memset::c#0 +byte memset::c#1 +byte memset::c#2 +byte memset::c#3 +byte memset::c#4 +byte* memset::dst +byte* memset::dst#0 +byte* memset::dst#1 +byte* memset::dst#2 +byte* memset::dst#3 +byte* memset::end +byte* memset::end#0 +byte* memset::end#1 +byte* memset::end#2 +word memset::num +word memset::num#0 +word memset::num#1 +word memset::num#2 +void* memset::return +void* memset::return#0 +void* memset::return#1 +void* memset::return#2 +void* memset::return#3 +void* memset::str +void* memset::str#0 +void* memset::str#1 +void* memset::str#2 +void* memset::str#3 +void* memset::str#4 +void* memset::str#5 +volatile byte sin_idx loadstore +volatile byte vstart loadstore +volatile byte vstop loadstore -Adding number conversion cast (unumber) 0 in *VERA_IRQLINE_L = 0 -Adding number conversion cast (unumber) $ff in irq_zero::$2 = irq_zero::l#2 != $ff +Adding number conversion cast (unumber) 0 in memset::$0 = memset::num#1 > 0 +Adding number conversion cast (unumber) 5 in *VERA_IRQLINE_L = 5 +Adding number conversion cast (unumber) $e6 in irq_line::$4 = irq_line::l#2 != $e6 +Adding number conversion cast (unumber) 0 in irq_line::$0 = cnt == 0 +Adding number conversion cast (unumber) $18 in irq_line::$5 = irq_line::i#2 < $18 Adding number conversion cast (unumber) 0 in *VERA_DC_BORDER = 0 -Adding number conversion cast (unumber) 0 in irq_zero::$0 = cnt == 0 -Adding number conversion cast (unumber) $17 in irq_zero::$3 = irq_zero::i#2 < $17 +Adding number conversion cast (unumber) $17 in irq_line::$6 = irq_line::i1#2 < $17 +Adding number conversion cast (unumber) 0 in memset::c#0 = 0 Adding number conversion cast (unumber) 2 in cnt = 2 -Adding number conversion cast (unumber) $140/4 in irq_zero::$4 = hstart <= $140/4 +Adding number conversion cast (unumber) $140/4 in irq_line::$7 = hstart <= $140/4 +Adding number conversion cast (unumber) 8 in irq_line::$9 = irq_line::b#2 < 8 +Adding number conversion cast (unumber) $d in irq_line::idx#1 = irq_line::idx#3 + $d Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast *VERA_IRQLINE_L = (unumber)0 +Inlining cast memset::dst#0 = (byte*)memset::str#2 +Inlining cast *VERA_IRQLINE_L = (unumber)5 Inlining cast *VERA_DC_BORDER = (unumber)0 +Inlining cast memset::c#0 = (unumber)0 Inlining cast cnt = (unumber)2 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 40741 @@ -158,78 +364,195 @@ Simplifying constant pointer cast (byte*) 40744 Simplifying constant pointer cast (byte*) 40748 Simplifying constant pointer cast (byte*) 40745 Simplifying constant pointer cast (byte*) 40746 +Simplifying constant pointer cast (byte*) 40747 +Simplifying constant pointer cast (byte*) 40748 Simplifying constant pointer cast (void()**) 788 Simplifying constant integer cast 0 -Simplifying constant integer cast $ff +Simplifying constant integer cast 5 +Simplifying constant integer cast $e6 Simplifying constant integer cast 0 +Simplifying constant integer cast $18 Simplifying constant integer cast 0 Simplifying constant integer cast $17 +Simplifying constant integer cast 0 Simplifying constant integer cast 2 +Simplifying constant integer cast 8 +Simplifying constant integer cast $d Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 -Finalized unsigned number type (byte) $ff +Finalized unsigned number type (byte) 5 +Finalized unsigned number type (byte) $e6 Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $18 Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) $17 +Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 2 +Finalized unsigned number type (byte) 8 +Finalized unsigned number type (byte) $d Successful SSA optimization PassNFinalizeNumberTypeConversions -Inversing boolean not [21] irq_zero::$1 = cnt != 0 from [20] irq_zero::$0 = cnt == 0 -Inversing boolean not [34] irq_zero::$5 = hstart > (byte)$140/4 from [33] irq_zero::$4 = hstart <= (byte)$140/4 +Inversing boolean not [2] memset::$1 = memset::num#1 <= 0 from [1] memset::$0 = memset::num#1 > 0 +Inversing boolean not [41] irq_line::$1 = cnt != 0 from [40] irq_line::$0 = cnt == 0 +Inversing boolean not [70] irq_line::$8 = hstart > (byte)$140/4 from [69] irq_line::$7 = hstart <= (byte)$140/4 Successful SSA optimization Pass2UnaryNotSimplification -Alias irq_zero::l#2 = irq_zero::l#3 -Alias irq_zero::i#2 = irq_zero::i#3 -Alias irq_zero::l#4 = irq_zero::l#6 irq_zero::l#5 +Alias memset::return#0 = memset::str#1 memset::return#3 memset::return#1 +Alias memset::str#2 = memset::str#3 +Alias memset::num#1 = memset::num#2 +Alias memset::c#3 = memset::c#4 +Alias memset::end#0 = memset::$2 +Alias memset::c#1 = memset::c#2 +Alias memset::dst#2 = memset::dst#3 +Alias memset::end#1 = memset::end#2 +Alias memset::str#4 = memset::str#5 +Alias irq_line::l#2 = irq_line::l#3 +Alias irq_line::i#2 = irq_line::i#3 +Alias irq_line::l#6 = irq_line::l#9 irq_line::l#8 +Alias irq_line::i1#2 = irq_line::i1#3 +Alias irq_line::l#4 = irq_line::l#7 irq_line::l#5 +Alias memset::num#0 = irq_line::$2 +Alias irq_line::idx#2 = irq_line::idx#4 +Alias irq_line::b#2 = irq_line::b#5 +Alias irq_line::bar#0 = irq_line::$10 +Alias irq_line::i2#2 = irq_line::i2#3 +Alias irq_line::bar#1 = irq_line::bar#2 +Alias irq_line::idx#3 = irq_line::idx#6 irq_line::idx#5 +Alias irq_line::b#3 = irq_line::b#6 irq_line::b#4 Successful SSA optimization Pass2AliasElimination -Identical Phi Values irq_zero::l#4 irq_zero::l#2 +Identical Phi Values memset::num#1 memset::num#0 +Identical Phi Values memset::str#2 memset::str#0 +Identical Phi Values memset::c#3 memset::c#0 +Identical Phi Values memset::end#1 memset::end#0 +Identical Phi Values memset::str#4 memset::str#2 +Identical Phi Values memset::c#1 memset::c#3 +Identical Phi Values irq_line::l#6 irq_line::l#2 +Identical Phi Values irq_line::l#4 irq_line::l#6 +Identical Phi Values irq_line::bar#1 irq_line::bar#0 +Identical Phi Values irq_line::idx#3 irq_line::idx#2 +Identical Phi Values irq_line::b#3 irq_line::b#2 Successful SSA optimization Pass2IdenticalPhiElimination -Simple Condition irq_zero::$2 [13] if(irq_zero::l#2!=$ff) goto irq_zero::@3 -Simple Condition irq_zero::$1 [20] if(cnt!=0) goto irq_zero::@1 -Simple Condition irq_zero::$3 [23] if(irq_zero::i#2<$17) goto irq_zero::@6 -Simple Condition irq_zero::$5 [30] if(hstart>(byte)$140/4) goto irq_zero::@1 +Identical Phi Values memset::return#0 memset::str#0 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition memset::$1 [2] if(memset::num#0<=0) goto memset::@1 +Simple Condition memset::$3 [9] if(memset::dst#2!=memset::end#0) goto memset::@4 +Simple Condition irq_line::$4 [28] if(irq_line::l#2!=$e6) goto irq_line::@3 +Simple Condition irq_line::$1 [33] if(cnt!=0) goto irq_line::@1 +Simple Condition irq_line::$5 [36] if(irq_line::i#2<$18) goto irq_line::@6 +Simple Condition irq_line::$6 [42] if(irq_line::i1#2<$17) goto irq_line::@9 +Simple Condition irq_line::$8 [56] if(hstart>(byte)$140/4) goto irq_line::@1 +Simple Condition irq_line::$9 [63] if(irq_line::b#2<8) goto irq_line::@14 +Simple Condition irq_line::$12 [71] if(irq_line::i2#2(byte)$140/4) goto irq_zero::@1 -Simplifying constant evaluating to zero (byte)0/4 in [34] hstart = (byte)0/4 +Constant memset::$4 = (byte*)memset::str#0 +Constant memset::dst#0 = (byte*)memset::str#0 +Constant memset::return#2 = memset::str#0 +Successful SSA optimization Pass2ConstantIdentification +Rewriting conditional comparison [56] if(hstart>(byte)$140/4) goto irq_line::@1 +Simplifying constant evaluating to zero (byte)0/4 in [77] hstart = (byte)0/4 +Simplifying constant evaluating to zero (byte)0/2 in [79] vstart = (byte)0/2 Successful SSA optimization PassNSimplifyConstantZero +Eliminating unused constant memset::return#2 +Successful SSA optimization PassNEliminateUnusedVars Removing unused block main::@return Successful SSA optimization Pass2EliminateUnusedBlocks -Adding number conversion cast (unumber) (byte)$140/4+1 in if(hstart>=(byte)$140/4+1) goto irq_zero::@1 -Adding number conversion cast (unumber) 1 in if(hstart>=(unumber)(byte)$140/4+1) goto irq_zero::@1 +Adding number conversion cast (unumber) (byte)$140/4+1 in if(hstart>=(byte)$140/4+1) goto irq_line::@1 +Adding number conversion cast (unumber) 1 in if(hstart>=(unumber)(byte)$140/4+1) goto irq_line::@1 Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant integer cast (byte)$140/4+(unumber)1 Simplifying constant integer cast 1 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions -Inlining constant with var siblings irq_zero::l#0 -Inlining constant with var siblings irq_zero::i#0 -Constant inlined irq_zero::l#0 = 0 -Constant inlined irq_zero::i#0 = 0 +Resolving array sizeof() sizeof BARS +Resolving array sizeof() sizeof BAR +Successful SSA optimization PassNSizeOfSimplification +Constant right-side identified [1] memset::end#0 = memset::$4 + memset::num#0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant memset::end#0 = memset::$4+memset::num#0 +Successful SSA optimization Pass2ConstantIdentification +if() condition always false - eliminating [0] if(memset::num#0<=0) goto memset::@1 +Successful SSA optimization Pass2ConstantIfs +Adding number conversion cast (unumber) $e6 in +Adding number conversion cast (unumber) $20 in +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant integer cast $e6 +Simplifying constant integer cast $20 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) $e6 +Finalized unsigned number type (byte) $20 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inlining constant with var siblings memset::dst#0 +Inlining constant with var siblings irq_line::l#0 +Inlining constant with var siblings irq_line::i#0 +Inlining constant with var siblings irq_line::i1#0 +Inlining constant with var siblings irq_line::b#0 +Inlining constant with var siblings irq_line::i2#0 +Constant inlined irq_line::i#0 = 0 +Constant inlined irq_line::$11 = $20*SIZEOF_BYTE +Constant inlined memset::$4 = (byte*)memset::str#0 +Constant inlined irq_line::l#0 = 0 +Constant inlined irq_line::i2#0 = 0 +Constant inlined irq_line::i1#0 = 0 +Constant inlined memset::dst#0 = (byte*)memset::str#0 +Constant inlined irq_line::b#0 = 0 Successful SSA optimization Pass2ConstantInlining +Finalized unsigned number type (word) $100 +Finalized unsigned number type (byte) $e6 +Finalized unsigned number type (byte) $e6 +Finalized unsigned number type (byte) $20 Finalized unsigned number type (word) $140 Finalized unsigned number type (byte) 4 Finalized unsigned number type (word) $280 Finalized unsigned number type (byte) 4 +Finalized unsigned number type (word) $1e0 +Finalized unsigned number type (byte) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of __start::@2 +Adding NOP phi() at start of irq_line::@1 Adding NOP phi() at start of main Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of memset +Adding NOP phi() at start of memset::@2 +Adding NOP phi() at start of memset::@1 CALL GRAPH -Calls in [__start] to main:5 +Calls in [__start] to main:8 +Calls in [irq_line] to memset:28 -Created 2 initial phi equivalence classes -Coalesced [29] irq_zero::l#7 = irq_zero::l#1 -Coalesced [31] irq_zero::i#4 = irq_zero::i#1 -Coalesced down to 2 phi equivalence classes +Created 7 initial phi equivalence classes +Coalesced [31] irq_line::idx#8 = irq_line::idx#0 +Coalesced [42] irq_line::b#7 = irq_line::b#1 +Coalesced [43] irq_line::idx#7 = irq_line::idx#1 +Coalesced [46] irq_line::i2#4 = irq_line::i2#1 +Coalesced [55] irq_line::l#10 = irq_line::l#1 +Coalesced [57] irq_line::i1#4 = irq_line::i1#1 +Coalesced [59] irq_line::i#4 = irq_line::i#1 +Coalesced [75] memset::dst#4 = memset::dst#1 +Coalesced down to 7 phi equivalence classes Culled Empty Block label __start::@2 +Culled Empty Block label memset::@2 +Culled Empty Block label memset::@1 +Renumbering block memset::@3 to memset::@1 +Renumbering block memset::@4 to memset::@2 Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 +Adding NOP phi() at start of irq_line::@1 Adding NOP phi() at start of main Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of memset FINAL CONTROL FLOW GRAPH @@ -240,178 +563,341 @@ __start: scope:[__start] from __start::__init1: scope:[__start] from __start [1] hstart = 0 [2] hstop = (byte)$280/4 - [3] cnt = 2 + [3] vstart = 0 + [4] vstop = (byte)$1e0/2 + [5] cnt = 2 + [6] sin_idx = $64 to:__start::@1 __start::@1: scope:[__start] from __start::__init1 - [4] phi() - [5] call main + [7] phi() + [8] call main to:__start::@return __start::@return: scope:[__start] from __start::@1 - [6] return + [9] return to:@return -void irq_zero() -irq_zero: scope:[irq_zero] from - [7] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL - [8] *VERA_DC_HSTART = hstart - [9] *VERA_DC_HSTOP = hstop - [10] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL - to:irq_zero::@2 -irq_zero::@2: scope:[irq_zero] from irq_zero irq_zero::@7 - [11] irq_zero::l#2 = phi( irq_zero/0, irq_zero::@7/irq_zero::l#1 ) - [12] if(irq_zero::l#2!=$ff) goto irq_zero::@3 - to:irq_zero::@4 -irq_zero::@4: scope:[irq_zero] from irq_zero::@2 - [13] *VERA_DC_BORDER = 0 - [14] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL - [15] cnt = -- cnt - [16] if(cnt!=0) goto irq_zero::@1 - to:irq_zero::@8 -irq_zero::@8: scope:[irq_zero] from irq_zero::@4 - [17] cnt = 2 - [18] if(hstart>=(byte)$140/4+1) goto irq_zero::@1 - to:irq_zero::@9 -irq_zero::@9: scope:[irq_zero] from irq_zero::@8 - [19] hstart = ++ hstart - [20] hstop = -- hstop - to:irq_zero::@1 -irq_zero::@1: scope:[irq_zero] from irq_zero::@4 irq_zero::@8 irq_zero::@9 - [21] *VERA_ISR = VERA_LINE +void irq_line() +irq_line: scope:[irq_line] from + [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL + [11] *VERA_DC_HSTART = hstart + [12] *VERA_DC_HSTOP = hstop + [13] *VERA_DC_VSTART = vstart + [14] *VERA_DC_VSTOP = vstop + [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL + to:irq_line::@2 +irq_line::@2: scope:[irq_line] from irq_line irq_line::@10 + [16] irq_line::l#2 = phi( irq_line/0, irq_line::@10/irq_line::l#1 ) + [17] if(irq_line::l#2!=$e6) goto irq_line::@3 + to:irq_line::@4 +irq_line::@4: scope:[irq_line] from irq_line::@2 + [18] cnt = -- cnt + [19] if(cnt!=0) goto irq_line::@1 + to:irq_line::@11 +irq_line::@11: scope:[irq_line] from irq_line::@4 + [20] cnt = 2 + [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 + to:irq_line::@12 +irq_line::@12: scope:[irq_line] from irq_line::@11 + [22] hstart = ++ hstart + [23] hstop = -- hstop + [24] vstart = ++ vstart + [25] vstop = -- vstop + to:irq_line::@1 +irq_line::@1: scope:[irq_line] from irq_line::@11 irq_line::@12 irq_line::@4 + [26] phi() + [27] call memset + to:irq_line::@19 +irq_line::@19: scope:[irq_line] from irq_line::@1 + [28] irq_line::idx#0 = sin_idx + [29] sin_idx = -- sin_idx + to:irq_line::@13 +irq_line::@13: scope:[irq_line] from irq_line::@18 irq_line::@19 + [30] irq_line::idx#2 = phi( irq_line::@18/irq_line::idx#1, irq_line::@19/irq_line::idx#0 ) + [30] irq_line::b#2 = phi( irq_line::@18/irq_line::b#1, irq_line::@19/0 ) + [31] if(irq_line::b#2<8) goto irq_line::@14 + to:irq_line::@15 +irq_line::@15: scope:[irq_line] from irq_line::@13 + [32] *VERA_ISR = VERA_LINE asm { ply plx pla rti } - to:irq_zero::@return -irq_zero::@return: scope:[irq_zero] from irq_zero::@1 - [23] return + to:irq_line::@return +irq_line::@return: scope:[irq_line] from irq_line::@15 + [34] return to:@return -irq_zero::@3: scope:[irq_zero] from irq_zero::@2 - [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] - to:irq_zero::@5 -irq_zero::@5: scope:[irq_zero] from irq_zero::@3 irq_zero::@6 - [25] irq_zero::i#2 = phi( irq_zero::@3/0, irq_zero::@6/irq_zero::i#1 ) - [26] if(irq_zero::i#2<$17) goto irq_zero::@6 - to:irq_zero::@7 -irq_zero::@7: scope:[irq_zero] from irq_zero::@5 - [27] irq_zero::l#1 = ++ irq_zero::l#2 - to:irq_zero::@2 -irq_zero::@6: scope:[irq_zero] from irq_zero::@5 - [28] irq_zero::i#1 = ++ irq_zero::i#2 - to:irq_zero::@5 +irq_line::@14: scope:[irq_line] from irq_line::@13 + [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] + to:irq_line::@16 +irq_line::@16: scope:[irq_line] from irq_line::@14 irq_line::@17 + [36] irq_line::i2#2 = phi( irq_line::@14/0, irq_line::@17/irq_line::i2#1 ) + [37] if(irq_line::i2#2<$20*SIZEOF_BYTE) goto irq_line::@17 + to:irq_line::@18 +irq_line::@18: scope:[irq_line] from irq_line::@16 + [38] irq_line::idx#1 = irq_line::idx#2 + $d + [39] irq_line::b#1 = ++ irq_line::b#2 + to:irq_line::@13 +irq_line::@17: scope:[irq_line] from irq_line::@16 + [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] + [41] irq_line::i2#1 = ++ irq_line::i2#2 + to:irq_line::@16 +irq_line::@3: scope:[irq_line] from irq_line::@2 + [42] *VERA_DC_BORDER = BARS[irq_line::l#2] + to:irq_line::@5 +irq_line::@5: scope:[irq_line] from irq_line::@3 irq_line::@6 + [43] irq_line::i#2 = phi( irq_line::@3/0, irq_line::@6/irq_line::i#1 ) + [44] if(irq_line::i#2<$18) goto irq_line::@6 + to:irq_line::@7 +irq_line::@7: scope:[irq_line] from irq_line::@5 + [45] *VERA_DC_BORDER = 0 + to:irq_line::@8 +irq_line::@8: scope:[irq_line] from irq_line::@7 irq_line::@9 + [46] irq_line::i1#2 = phi( irq_line::@7/0, irq_line::@9/irq_line::i1#1 ) + [47] if(irq_line::i1#2<$17) goto irq_line::@9 + to:irq_line::@10 +irq_line::@10: scope:[irq_line] from irq_line::@8 + asm { nop nop } + [49] irq_line::l#1 = ++ irq_line::l#2 + to:irq_line::@2 +irq_line::@9: scope:[irq_line] from irq_line::@8 + [50] irq_line::i1#1 = ++ irq_line::i1#2 + to:irq_line::@8 +irq_line::@6: scope:[irq_line] from irq_line::@5 + [51] irq_line::i#1 = ++ irq_line::i#2 + to:irq_line::@5 void main() main: scope:[main] from __start::@1 - [29] phi() + [52] phi() to:main::SEI1 main::SEI1: scope:[main] from main asm { sei } to:main::@2 main::@2: scope:[main] from main::SEI1 - [31] *KERNEL_IRQ = &irq_zero - [32] *VERA_IEN = VERA_LINE - [33] *VERA_IRQLINE_L = 0 + [54] *KERNEL_IRQ = &irq_line + [55] *VERA_IEN = VERA_LINE + [56] *VERA_IRQLINE_L = 5 to:main::CLI1 main::CLI1: scope:[main] from main::@2 asm { cli } to:main::@1 main::@1: scope:[main] from main::@1 main::CLI1 - [35] phi() + [58] phi() to:main::@1 +void* memset(void* memset::str , byte memset::c , word memset::num) +memset: scope:[memset] from irq_line::@1 + [59] phi() + to:memset::@1 +memset::@1: scope:[memset] from memset memset::@2 + [60] memset::dst#2 = phi( memset/(byte*)memset::str#0, memset::@2/memset::dst#1 ) + [61] if(memset::dst#2!=memset::end#0) goto memset::@2 + to:memset::@return +memset::@return: scope:[memset] from memset::@1 + [62] return + to:@return +memset::@2: scope:[memset] from memset::@1 + [63] *memset::dst#2 = memset::c#0 + [64] memset::dst#1 = ++ memset::dst#2 + to:memset::@1 + VARIABLE REGISTER WEIGHTS void __start() -volatile byte cnt loadstore 0.7142857142857142 -volatile byte hstart loadstore 0.5882352941176471 -volatile byte hstop loadstore 0.4444444444444444 -void irq_zero() -byte irq_zero::i -byte irq_zero::i#1 202.0 -byte irq_zero::i#2 151.5 -byte irq_zero::l -byte irq_zero::l#1 22.0 -byte irq_zero::l#2 7.333333333333333 +volatile byte cnt loadstore 0.5263157894736842 +volatile byte hstart loadstore 0.4545454545454546 +volatile byte hstop loadstore 0.34782608695652173 +void irq_line() +byte irq_line::b +byte irq_line::b#1 22.0 +byte irq_line::b#2 4.125 +byte* irq_line::bar +byte* irq_line::bar#0 22.4 +byte irq_line::i +byte irq_line::i#1 202.0 +byte irq_line::i#2 151.5 +byte irq_line::i1 +byte irq_line::i1#1 202.0 +byte irq_line::i1#2 151.5 +byte irq_line::i2 +byte irq_line::i2#1 202.0 +byte irq_line::i2#2 168.33333333333331 +byte irq_line::idx +byte irq_line::idx#0 2.0 +byte irq_line::idx#1 11.0 +byte irq_line::idx#2 5.0 +byte irq_line::l +byte irq_line::l#1 22.0 +byte irq_line::l#2 4.0 void main() +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +byte* memset::dst +byte* memset::dst#1 202.0 +byte* memset::dst#2 134.66666666666666 +byte* memset::end +word memset::num +void* memset::return +void* memset::str +volatile byte sin_idx loadstore 0.27586206896551724 +volatile byte vstart loadstore 0.3333333333333333 +volatile byte vstop loadstore 0.32 Initial phi equivalence classes -[ irq_zero::l#2 irq_zero::l#1 ] -[ irq_zero::i#2 irq_zero::i#1 ] +[ irq_line::l#2 irq_line::l#1 ] +[ irq_line::b#2 irq_line::b#1 ] +[ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +[ irq_line::i2#2 irq_line::i2#1 ] +[ irq_line::i#2 irq_line::i#1 ] +[ irq_line::i1#2 irq_line::i1#1 ] +[ memset::dst#2 memset::dst#1 ] Added variable hstart to live range equivalence class [ hstart ] Added variable hstop to live range equivalence class [ hstop ] +Added variable vstart to live range equivalence class [ vstart ] +Added variable vstop to live range equivalence class [ vstop ] Added variable cnt to live range equivalence class [ cnt ] +Added variable sin_idx to live range equivalence class [ sin_idx ] +Added variable irq_line::bar#0 to live range equivalence class [ irq_line::bar#0 ] Complete equivalence classes -[ irq_zero::l#2 irq_zero::l#1 ] -[ irq_zero::i#2 irq_zero::i#1 ] +[ irq_line::l#2 irq_line::l#1 ] +[ irq_line::b#2 irq_line::b#1 ] +[ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +[ irq_line::i2#2 irq_line::i2#1 ] +[ irq_line::i#2 irq_line::i#1 ] +[ irq_line::i1#2 irq_line::i1#1 ] +[ memset::dst#2 memset::dst#1 ] [ hstart ] [ hstop ] +[ vstart ] +[ vstop ] [ cnt ] -Allocated zp[1]:2 [ irq_zero::l#2 irq_zero::l#1 ] -Allocated zp[1]:3 [ irq_zero::i#2 irq_zero::i#1 ] -Allocated zp[1]:4 [ hstart ] -Allocated zp[1]:5 [ hstop ] -Allocated zp[1]:6 [ cnt ] +[ sin_idx ] +[ irq_line::bar#0 ] +Allocated zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] +Allocated zp[1]:3 [ irq_line::b#2 irq_line::b#1 ] +Allocated zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Allocated zp[1]:5 [ irq_line::i2#2 irq_line::i2#1 ] +Allocated zp[1]:6 [ irq_line::i#2 irq_line::i#1 ] +Allocated zp[1]:7 [ irq_line::i1#2 irq_line::i1#1 ] +Allocated zp[2]:8 [ memset::dst#2 memset::dst#1 ] +Allocated zp[1]:10 [ hstart ] +Allocated zp[1]:11 [ hstop ] +Allocated zp[1]:12 [ vstart ] +Allocated zp[1]:13 [ vstop ] +Allocated zp[1]:14 [ cnt ] +Allocated zp[1]:15 [ sin_idx ] +Allocated zp[2]:16 [ irq_line::bar#0 ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [1] hstart = 0 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] hstop = (byte)$280/4 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [3] cnt = 2 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [7] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [8] *VERA_DC_HSTART = hstart [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [9] *VERA_DC_HSTOP = hstop [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [10] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [13] *VERA_DC_BORDER = 0 [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [14] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [16] if(cnt!=0) goto irq_zero::@1 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [17] cnt = 2 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [18] if(hstart>=(byte)$140/4+1) goto irq_zero::@1 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [21] *VERA_ISR = VERA_LINE [ ] ( [ ] { } ) always clobbers reg byte a +Statement [3] vstart = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [4] vstop = (byte)$1e0/2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [5] cnt = 2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] sin_idx = $64 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [11] *VERA_DC_HSTART = hstart [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [12] *VERA_DC_HSTOP = hstop [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [13] *VERA_DC_VSTART = vstart [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [14] *VERA_DC_VSTOP = vstop [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [19] if(cnt!=0) goto irq_line::@1 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [20] cnt = 2 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [32] *VERA_ISR = VERA_LINE [ ] ( [ ] { } ) always clobbers reg byte a Statement asm { ply plx pla rti } always clobbers reg byte a reg byte x reg byte y -Statement [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] [ hstart hstop cnt irq_zero::l#2 ] ( [ hstart hstop cnt irq_zero::l#2 ] { } ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp[1]:2 [ irq_zero::l#2 irq_zero::l#1 ] -Statement [31] *KERNEL_IRQ = &irq_zero [ ] ( main:5 [ ] { } ) always clobbers reg byte a -Statement [32] *VERA_IEN = VERA_LINE [ ] ( main:5 [ ] { } ) always clobbers reg byte a -Statement [33] *VERA_IRQLINE_L = 0 [ ] ( main:5 [ ] { } ) always clobbers reg byte a +Statement [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 ] ( [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:3 [ irq_line::b#2 irq_line::b#1 ] +Removing always clobbered register reg byte a as potential for zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Statement [38] irq_line::idx#1 = irq_line::idx#2 + $d [ irq_line::b#2 irq_line::idx#1 ] ( [ irq_line::b#2 irq_line::idx#1 ] { } ) always clobbers reg byte a +Statement [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 irq_line::i2#2 ] ( [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 irq_line::i2#2 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:5 [ irq_line::i2#2 irq_line::i2#1 ] +Statement [42] *VERA_DC_BORDER = BARS[irq_line::l#2] [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] ( [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] +Statement [45] *VERA_DC_BORDER = 0 [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] ( [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] { } ) always clobbers reg byte a +Statement [54] *KERNEL_IRQ = &irq_line [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [55] *VERA_IEN = VERA_LINE [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [56] *VERA_IRQLINE_L = 5 [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [61] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( memset:27 [ sin_idx memset::dst#2 ] { } ) always clobbers reg byte a +Statement [63] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( memset:27 [ sin_idx memset::dst#2 ] { } ) always clobbers reg byte a reg byte y Statement [1] hstart = 0 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] hstop = (byte)$280/4 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [3] cnt = 2 [ ] ( [ ] { } ) always clobbers reg byte a -Statement [7] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [8] *VERA_DC_HSTART = hstart [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [9] *VERA_DC_HSTOP = hstop [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [10] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [13] *VERA_DC_BORDER = 0 [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [14] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop cnt ] ( [ hstart hstop cnt ] { } ) always clobbers reg byte a -Statement [16] if(cnt!=0) goto irq_zero::@1 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [17] cnt = 2 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [18] if(hstart>=(byte)$140/4+1) goto irq_zero::@1 [ hstart hstop ] ( [ hstart hstop ] { } ) always clobbers reg byte a -Statement [21] *VERA_ISR = VERA_LINE [ ] ( [ ] { } ) always clobbers reg byte a +Statement [3] vstart = 0 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [4] vstop = (byte)$1e0/2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [5] cnt = 2 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [6] sin_idx = $64 [ ] ( [ ] { } ) always clobbers reg byte a +Statement [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [11] *VERA_DC_HSTART = hstart [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [12] *VERA_DC_HSTOP = hstop [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [13] *VERA_DC_VSTART = vstart [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [14] *VERA_DC_VSTOP = vstop [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL [ hstart hstop vstart vstop cnt sin_idx ] ( [ hstart hstop vstart vstop cnt sin_idx ] { } ) always clobbers reg byte a +Statement [19] if(cnt!=0) goto irq_line::@1 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [20] cnt = 2 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 [ hstart hstop vstart vstop sin_idx ] ( [ hstart hstop vstart vstop sin_idx ] { } ) always clobbers reg byte a +Statement [32] *VERA_ISR = VERA_LINE [ ] ( [ ] { } ) always clobbers reg byte a Statement asm { ply plx pla rti } always clobbers reg byte a reg byte x reg byte y -Statement [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] [ hstart hstop cnt irq_zero::l#2 ] ( [ hstart hstop cnt irq_zero::l#2 ] { } ) always clobbers reg byte a -Statement [31] *KERNEL_IRQ = &irq_zero [ ] ( main:5 [ ] { } ) always clobbers reg byte a -Statement [32] *VERA_IEN = VERA_LINE [ ] ( main:5 [ ] { } ) always clobbers reg byte a -Statement [33] *VERA_IRQLINE_L = 0 [ ] ( main:5 [ ] { } ) always clobbers reg byte a -Potential registers zp[1]:2 [ irq_zero::l#2 irq_zero::l#1 ] : zp[1]:2 , reg byte x , reg byte y , -Potential registers zp[1]:3 [ irq_zero::i#2 irq_zero::i#1 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:4 [ hstart ] : zp[1]:4 , -Potential registers zp[1]:5 [ hstop ] : zp[1]:5 , -Potential registers zp[1]:6 [ cnt ] : zp[1]:6 , +Statement [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 ] ( [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 ] { } ) always clobbers reg byte a +Statement [38] irq_line::idx#1 = irq_line::idx#2 + $d [ irq_line::b#2 irq_line::idx#1 ] ( [ irq_line::b#2 irq_line::idx#1 ] { } ) always clobbers reg byte a +Statement [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 irq_line::i2#2 ] ( [ irq_line::b#2 irq_line::idx#2 irq_line::bar#0 irq_line::i2#2 ] { } ) always clobbers reg byte a +Statement [42] *VERA_DC_BORDER = BARS[irq_line::l#2] [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] ( [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] { } ) always clobbers reg byte a +Statement [45] *VERA_DC_BORDER = 0 [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] ( [ hstart hstop vstart vstop cnt sin_idx irq_line::l#2 ] { } ) always clobbers reg byte a +Statement [54] *KERNEL_IRQ = &irq_line [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [55] *VERA_IEN = VERA_LINE [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [56] *VERA_IRQLINE_L = 5 [ ] ( main:8 [ ] { } ) always clobbers reg byte a +Statement [61] if(memset::dst#2!=memset::end#0) goto memset::@2 [ memset::dst#2 ] ( memset:27 [ sin_idx memset::dst#2 ] { } ) always clobbers reg byte a +Statement [63] *memset::dst#2 = memset::c#0 [ memset::dst#2 ] ( memset:27 [ sin_idx memset::dst#2 ] { } ) always clobbers reg byte a reg byte y +Potential registers zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] : zp[1]:2 , reg byte x , reg byte y , +Potential registers zp[1]:3 [ irq_line::b#2 irq_line::b#1 ] : zp[1]:3 , reg byte x , reg byte y , +Potential registers zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] : zp[1]:4 , reg byte x , reg byte y , +Potential registers zp[1]:5 [ irq_line::i2#2 irq_line::i2#1 ] : zp[1]:5 , reg byte x , reg byte y , +Potential registers zp[1]:6 [ irq_line::i#2 irq_line::i#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:7 [ irq_line::i1#2 irq_line::i1#1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:8 [ memset::dst#2 memset::dst#1 ] : zp[2]:8 , +Potential registers zp[1]:10 [ hstart ] : zp[1]:10 , +Potential registers zp[1]:11 [ hstop ] : zp[1]:11 , +Potential registers zp[1]:12 [ vstart ] : zp[1]:12 , +Potential registers zp[1]:13 [ vstop ] : zp[1]:13 , +Potential registers zp[1]:14 [ cnt ] : zp[1]:14 , +Potential registers zp[1]:15 [ sin_idx ] : zp[1]:15 , +Potential registers zp[2]:16 [ irq_line::bar#0 ] : zp[2]:16 , REGISTER UPLIFT SCOPES -Uplift Scope [irq_zero] 353.5: zp[1]:3 [ irq_zero::i#2 irq_zero::i#1 ] 29.33: zp[1]:2 [ irq_zero::l#2 irq_zero::l#1 ] -Uplift Scope [] 0.71: zp[1]:6 [ cnt ] 0.59: zp[1]:4 [ hstart ] 0.44: zp[1]:5 [ hstop ] +Uplift Scope [irq_line] 370.33: zp[1]:5 [ irq_line::i2#2 irq_line::i2#1 ] 353.5: zp[1]:6 [ irq_line::i#2 irq_line::i#1 ] 353.5: zp[1]:7 [ irq_line::i1#2 irq_line::i1#1 ] 26.12: zp[1]:3 [ irq_line::b#2 irq_line::b#1 ] 26: zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] 22.4: zp[2]:16 [ irq_line::bar#0 ] 18: zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Uplift Scope [memset] 336.67: zp[2]:8 [ memset::dst#2 memset::dst#1 ] +Uplift Scope [] 0.53: zp[1]:14 [ cnt ] 0.45: zp[1]:10 [ hstart ] 0.35: zp[1]:11 [ hstop ] 0.33: zp[1]:12 [ vstart ] 0.32: zp[1]:13 [ vstop ] 0.28: zp[1]:15 [ sin_idx ] Uplift Scope [MOS6522_VIA] Uplift Scope [main] Uplift Scope [__start] -Uplifting [irq_zero] best 2323 combination reg byte a [ irq_zero::i#2 irq_zero::i#1 ] reg byte x [ irq_zero::l#2 irq_zero::l#1 ] -Uplifting [] best 2323 combination zp[1]:6 [ cnt ] zp[1]:4 [ hstart ] zp[1]:5 [ hstop ] -Uplifting [MOS6522_VIA] best 2323 combination -Uplifting [main] best 2323 combination -Uplifting [__start] best 2323 combination -Attempting to uplift remaining variables inzp[1]:6 [ cnt ] -Uplifting [] best 2323 combination zp[1]:6 [ cnt ] -Attempting to uplift remaining variables inzp[1]:4 [ hstart ] -Uplifting [] best 2323 combination zp[1]:4 [ hstart ] -Attempting to uplift remaining variables inzp[1]:5 [ hstop ] -Uplifting [] best 2323 combination zp[1]:5 [ hstop ] -Allocated (was zp[1]:4) zp[1]:2 [ hstart ] -Allocated (was zp[1]:5) zp[1]:3 [ hstop ] -Allocated (was zp[1]:6) zp[1]:4 [ cnt ] +Uplifting [irq_line] best 8197 combination reg byte y [ irq_line::i2#2 irq_line::i2#1 ] reg byte a [ irq_line::i#2 irq_line::i#1 ] reg byte a [ irq_line::i1#2 irq_line::i1#1 ] reg byte x [ irq_line::b#2 irq_line::b#1 ] zp[1]:2 [ irq_line::l#2 irq_line::l#1 ] zp[2]:16 [ irq_line::bar#0 ] zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Limited combination testing to 100 combinations of 1296 possible. +Uplifting [memset] best 8197 combination zp[2]:8 [ memset::dst#2 memset::dst#1 ] +Uplifting [] best 8197 combination zp[1]:14 [ cnt ] zp[1]:10 [ hstart ] zp[1]:11 [ hstop ] zp[1]:12 [ vstart ] zp[1]:13 [ vstop ] zp[1]:15 [ sin_idx ] +Uplifting [MOS6522_VIA] best 8197 combination +Uplifting [main] best 8197 combination +Uplifting [__start] best 8197 combination +Attempting to uplift remaining variables inzp[1]:2 [ irq_line::l#2 irq_line::l#1 ] +Uplifting [irq_line] best 8077 combination reg byte x [ irq_line::l#2 irq_line::l#1 ] +Attempting to uplift remaining variables inzp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Uplifting [irq_line] best 8077 combination zp[1]:4 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Attempting to uplift remaining variables inzp[1]:14 [ cnt ] +Uplifting [] best 8077 combination zp[1]:14 [ cnt ] +Attempting to uplift remaining variables inzp[1]:10 [ hstart ] +Uplifting [] best 8077 combination zp[1]:10 [ hstart ] +Attempting to uplift remaining variables inzp[1]:11 [ hstop ] +Uplifting [] best 8077 combination zp[1]:11 [ hstop ] +Attempting to uplift remaining variables inzp[1]:12 [ vstart ] +Uplifting [] best 8077 combination zp[1]:12 [ vstart ] +Attempting to uplift remaining variables inzp[1]:13 [ vstop ] +Uplifting [] best 8077 combination zp[1]:13 [ vstop ] +Attempting to uplift remaining variables inzp[1]:15 [ sin_idx ] +Uplifting [] best 8077 combination zp[1]:15 [ sin_idx ] +Coalescing zero page register [ zp[2]:16 [ irq_line::bar#0 ] ] with [ zp[2]:8 [ memset::dst#2 memset::dst#1 ] ] +Allocated (was zp[1]:4) zp[1]:2 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +Allocated (was zp[1]:10) zp[1]:3 [ hstart ] +Allocated (was zp[1]:11) zp[1]:4 [ hstop ] +Allocated (was zp[1]:12) zp[1]:5 [ vstart ] +Allocated (was zp[1]:13) zp[1]:6 [ vstop ] +Allocated (was zp[1]:14) zp[1]:7 [ cnt ] +Allocated (was zp[1]:15) zp[1]:8 [ sin_idx ] +Allocated (was zp[2]:16) zp[2]:9 [ irq_line::bar#0 memset::dst#2 memset::dst#1 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -433,6 +919,7 @@ ASSEMBLER BEFORE OPTIMIZATION // Global Constants & labels .const VERA_DCSEL = 2 .const VERA_LINE = 2 + .const SIZEOF_BYTE = 1 // $9F25 CTRL Control // Bit 7: Reset // Bit 1: DCSEL @@ -465,14 +952,24 @@ ASSEMBLER BEFORE OPTIMIZATION .label VERA_DC_HSTART = $9f29 // $9F2A DC_HSTOP (DCSEL=1) Active Display H-Stop (9:2) .label VERA_DC_HSTOP = $9f2a + // $9F2B DC_VSTART (DCSEL=1) Active Display V-Start (8:1) + .label VERA_DC_VSTART = $9f2b + // $9F2C DC_VSTOP (DCSEL=1) Active Display V-Stop (8:1) + .label VERA_DC_VSTOP = $9f2c // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The horizontal start - .label hstart = 2 + .label hstart = 3 // The horizontal stop - .label hstop = 3 + .label hstop = 4 + // The vertical start + .label vstart = 5 + // The vertical stop + .label vstop = 6 // The countdown - .label cnt = 4 + .label cnt = 7 + // The sin idx + .label sin_idx = 8 .segment Code // __start __start: { @@ -485,90 +982,135 @@ __start: { // [2] hstop = (byte)$280/4 -- vbuz1=vbuc1 lda #$280/4 sta.z hstop - // [3] cnt = 2 -- vbuz1=vbuc1 + // [3] vstart = 0 -- vbuz1=vbuc1 + lda #0 + sta.z vstart + // [4] vstop = (byte)$1e0/2 -- vbuz1=vbuc1 + lda #$1e0/2 + sta.z vstop + // [5] cnt = 2 -- vbuz1=vbuc1 lda #2 sta.z cnt - // [4] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + // [6] sin_idx = $64 -- vbuz1=vbuc1 + lda #$64 + sta.z sin_idx + // [7] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] __b1_from___init1: jmp __b1 // __start::@1 __b1: - // [5] call main - // [29] phi from __start::@1 to main [phi:__start::@1->main] + // [8] call main + // [52] phi from __start::@1 to main [phi:__start::@1->main] main_from___b1: jsr main jmp __breturn // __start::@return __breturn: - // [6] return + // [9] return rts } - // irq_zero -// Interrupt Routine at raster 0 -irq_zero: { - // [7] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // irq_line +// LINE Interrupt Routine +irq_line: { + .label idx = 2 + .label bar = 9 + // [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Update the border lda #VERA_DCSEL ora VERA_CTRL sta VERA_CTRL - // [8] *VERA_DC_HSTART = hstart -- _deref_pbuc1=vbuz1 + // [11] *VERA_DC_HSTART = hstart -- _deref_pbuc1=vbuz1 lda.z hstart sta VERA_DC_HSTART - // [9] *VERA_DC_HSTOP = hstop -- _deref_pbuc1=vbuz1 + // [12] *VERA_DC_HSTOP = hstop -- _deref_pbuc1=vbuz1 lda.z hstop sta VERA_DC_HSTOP - // [10] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [13] *VERA_DC_VSTART = vstart -- _deref_pbuc1=vbuz1 + lda.z vstart + sta VERA_DC_VSTART + // [14] *VERA_DC_VSTOP = vstop -- _deref_pbuc1=vbuz1 + lda.z vstop + sta VERA_DC_VSTOP + // [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 // Show color raster bars in the border lda #VERA_DCSEL^$ff and VERA_CTRL sta VERA_CTRL - // [11] phi from irq_zero to irq_zero::@2 [phi:irq_zero->irq_zero::@2] - __b2_from_irq_zero: - // [11] phi irq_zero::l#2 = 0 [phi:irq_zero->irq_zero::@2#0] -- vbuxx=vbuc1 + // [16] phi from irq_line to irq_line::@2 [phi:irq_line->irq_line::@2] + __b2_from_irq_line: + // [16] phi irq_line::l#2 = 0 [phi:irq_line->irq_line::@2#0] -- vbuxx=vbuc1 ldx #0 jmp __b2 - // irq_zero::@2 + // irq_line::@2 __b2: - // [12] if(irq_zero::l#2!=$ff) goto irq_zero::@3 -- vbuxx_neq_vbuc1_then_la1 - cpx #$ff + // [17] if(irq_line::l#2!=$e6) goto irq_line::@3 -- vbuxx_neq_vbuc1_then_la1 + cpx #$e6 bne __b3 jmp __b4 - // irq_zero::@4 + // irq_line::@4 __b4: - // [13] *VERA_DC_BORDER = 0 -- _deref_pbuc1=vbuc2 - lda #0 - sta VERA_DC_BORDER - // [14] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 - lda #VERA_DCSEL - ora VERA_CTRL - sta VERA_CTRL - // [15] cnt = -- cnt -- vbuz1=_dec_vbuz1 + // [18] cnt = -- cnt -- vbuz1=_dec_vbuz1 dec.z cnt - // [16] if(cnt!=0) goto irq_zero::@1 -- vbuz1_neq_0_then_la1 + // [19] if(cnt!=0) goto irq_line::@1 -- vbuz1_neq_0_then_la1 lda.z cnt cmp #0 - bne __b1 - jmp __b8 - // irq_zero::@8 - __b8: - // [17] cnt = 2 -- vbuz1=vbuc1 + bne __b1_from___b4 + jmp __b11 + // irq_line::@11 + __b11: + // [20] cnt = 2 -- vbuz1=vbuc1 lda #2 sta.z cnt - // [18] if(hstart>=(byte)$140/4+1) goto irq_zero::@1 -- vbuz1_ge_vbuc1_then_la1 + // [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 -- vbuz1_ge_vbuc1_then_la1 lda.z hstart cmp #$140/4+1 - bcs __b1 - jmp __b9 - // irq_zero::@9 - __b9: - // [19] hstart = ++ hstart -- vbuz1=_inc_vbuz1 + bcs __b1_from___b11 + jmp __b12 + // irq_line::@12 + __b12: + // [22] hstart = ++ hstart -- vbuz1=_inc_vbuz1 inc.z hstart - // [20] hstop = -- hstop -- vbuz1=_dec_vbuz1 + // [23] hstop = -- hstop -- vbuz1=_dec_vbuz1 dec.z hstop + // [24] vstart = ++ vstart -- vbuz1=_inc_vbuz1 + inc.z vstart + // [25] vstop = -- vstop -- vbuz1=_dec_vbuz1 + dec.z vstop + // [26] phi from irq_line::@11 irq_line::@12 irq_line::@4 to irq_line::@1 [phi:irq_line::@11/irq_line::@12/irq_line::@4->irq_line::@1] + __b1_from___b11: + __b1_from___b12: + __b1_from___b4: jmp __b1 - // irq_zero::@1 + // irq_line::@1 __b1: - // [21] *VERA_ISR = VERA_LINE -- _deref_pbuc1=vbuc2 + // [27] call memset + // Animate the bars + // [59] phi from irq_line::@1 to memset [phi:irq_line::@1->memset] + memset_from___b1: + jsr memset + jmp __b19 + // irq_line::@19 + __b19: + // [28] irq_line::idx#0 = sin_idx -- vbuz1=vbuz2 + lda.z sin_idx + sta.z idx + // [29] sin_idx = -- sin_idx -- vbuz1=_dec_vbuz1 + dec.z sin_idx + // [30] phi from irq_line::@19 to irq_line::@13 [phi:irq_line::@19->irq_line::@13] + __b13_from___b19: + // [30] phi irq_line::idx#2 = irq_line::idx#0 [phi:irq_line::@19->irq_line::@13#0] -- register_copy + // [30] phi irq_line::b#2 = 0 [phi:irq_line::@19->irq_line::@13#1] -- vbuxx=vbuc1 + ldx #0 + jmp __b13 + // irq_line::@13 + __b13: + // [31] if(irq_line::b#2<8) goto irq_line::@14 -- vbuxx_lt_vbuc1_then_la1 + cpx #8 + bcc __b14 + jmp __b15 + // irq_line::@15 + __b15: + // [32] *VERA_ISR = VERA_LINE -- _deref_pbuc1=vbuc2 // Reset the LINE interrupt lda #VERA_LINE sta VERA_ISR @@ -579,41 +1121,117 @@ irq_zero: { pla rti jmp __breturn - // irq_zero::@return + // irq_line::@return __breturn: - // [23] return + // [34] return rts - // irq_zero::@3 + // irq_line::@14 + __b14: + // [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] -- pbuz1=pbuc1_plus_pbuc2_derefidx_vbuz2 + ldy.z idx + lda SIN,y + clc + adc #BARS + adc #0 + sta.z bar+1 + // [36] phi from irq_line::@14 to irq_line::@16 [phi:irq_line::@14->irq_line::@16] + __b16_from___b14: + // [36] phi irq_line::i2#2 = 0 [phi:irq_line::@14->irq_line::@16#0] -- vbuyy=vbuc1 + ldy #0 + jmp __b16 + // irq_line::@16 + __b16: + // [37] if(irq_line::i2#2<$20*SIZEOF_BYTE) goto irq_line::@17 -- vbuyy_lt_vbuc1_then_la1 + cpy #$20*SIZEOF_BYTE + bcc __b17 + jmp __b18 + // irq_line::@18 + __b18: + // [38] irq_line::idx#1 = irq_line::idx#2 + $d -- vbuz1=vbuz1_plus_vbuc1 + lda #$d + clc + adc.z idx + sta.z idx + // [39] irq_line::b#1 = ++ irq_line::b#2 -- vbuxx=_inc_vbuxx + inx + // [30] phi from irq_line::@18 to irq_line::@13 [phi:irq_line::@18->irq_line::@13] + __b13_from___b18: + // [30] phi irq_line::idx#2 = irq_line::idx#1 [phi:irq_line::@18->irq_line::@13#0] -- register_copy + // [30] phi irq_line::b#2 = irq_line::b#1 [phi:irq_line::@18->irq_line::@13#1] -- register_copy + jmp __b13 + // irq_line::@17 + __b17: + // [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] -- pbuz1_derefidx_vbuyy=pbuc1_derefidx_vbuyy + lda BAR,y + sta (bar),y + // [41] irq_line::i2#1 = ++ irq_line::i2#2 -- vbuyy=_inc_vbuyy + iny + // [36] phi from irq_line::@17 to irq_line::@16 [phi:irq_line::@17->irq_line::@16] + __b16_from___b17: + // [36] phi irq_line::i2#2 = irq_line::i2#1 [phi:irq_line::@17->irq_line::@16#0] -- register_copy + jmp __b16 + // irq_line::@3 __b3: - // [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] -- _deref_pbuc1=pbuc2_derefidx_vbuxx + // [42] *VERA_DC_BORDER = BARS[irq_line::l#2] -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda BARS,x sta VERA_DC_BORDER - // [25] phi from irq_zero::@3 to irq_zero::@5 [phi:irq_zero::@3->irq_zero::@5] + // [43] phi from irq_line::@3 to irq_line::@5 [phi:irq_line::@3->irq_line::@5] __b5_from___b3: - // [25] phi irq_zero::i#2 = 0 [phi:irq_zero::@3->irq_zero::@5#0] -- vbuaa=vbuc1 + // [43] phi irq_line::i#2 = 0 [phi:irq_line::@3->irq_line::@5#0] -- vbuaa=vbuc1 lda #0 jmp __b5 - // irq_zero::@5 + // irq_line::@5 __b5: - // [26] if(irq_zero::i#2<$17) goto irq_zero::@6 -- vbuaa_lt_vbuc1_then_la1 - cmp #$17 + // [44] if(irq_line::i#2<$18) goto irq_line::@6 -- vbuaa_lt_vbuc1_then_la1 + cmp #$18 bcc __b6 jmp __b7 - // irq_zero::@7 + // irq_line::@7 __b7: - // [27] irq_zero::l#1 = ++ irq_zero::l#2 -- vbuxx=_inc_vbuxx + // [45] *VERA_DC_BORDER = 0 -- _deref_pbuc1=vbuc2 + // Wait exactly long enought to go to the next raster line + lda #0 + sta VERA_DC_BORDER + // [46] phi from irq_line::@7 to irq_line::@8 [phi:irq_line::@7->irq_line::@8] + __b8_from___b7: + // [46] phi irq_line::i1#2 = 0 [phi:irq_line::@7->irq_line::@8#0] -- vbuaa=vbuc1 + lda #0 + jmp __b8 + // irq_line::@8 + __b8: + // [47] if(irq_line::i1#2<$17) goto irq_line::@9 -- vbuaa_lt_vbuc1_then_la1 + cmp #$17 + bcc __b9 + jmp __b10 + // irq_line::@10 + __b10: + // asm { nop nop } + // Wait exactly long enought to go to the next raster line + nop + nop + // [49] irq_line::l#1 = ++ irq_line::l#2 -- vbuxx=_inc_vbuxx inx - // [11] phi from irq_zero::@7 to irq_zero::@2 [phi:irq_zero::@7->irq_zero::@2] - __b2_from___b7: - // [11] phi irq_zero::l#2 = irq_zero::l#1 [phi:irq_zero::@7->irq_zero::@2#0] -- register_copy + // [16] phi from irq_line::@10 to irq_line::@2 [phi:irq_line::@10->irq_line::@2] + __b2_from___b10: + // [16] phi irq_line::l#2 = irq_line::l#1 [phi:irq_line::@10->irq_line::@2#0] -- register_copy jmp __b2 - // irq_zero::@6 - __b6: - // [28] irq_zero::i#1 = ++ irq_zero::i#2 -- vbuaa=_inc_vbuaa + // irq_line::@9 + __b9: + // [50] irq_line::i1#1 = ++ irq_line::i1#2 -- vbuaa=_inc_vbuaa inc - // [25] phi from irq_zero::@6 to irq_zero::@5 [phi:irq_zero::@6->irq_zero::@5] + // [46] phi from irq_line::@9 to irq_line::@8 [phi:irq_line::@9->irq_line::@8] + __b8_from___b9: + // [46] phi irq_line::i1#2 = irq_line::i1#1 [phi:irq_line::@9->irq_line::@8#0] -- register_copy + jmp __b8 + // irq_line::@6 + __b6: + // [51] irq_line::i#1 = ++ irq_line::i#2 -- vbuaa=_inc_vbuaa + inc + // [43] phi from irq_line::@6 to irq_line::@5 [phi:irq_line::@6->irq_line::@5] __b5_from___b6: - // [25] phi irq_zero::i#2 = irq_zero::i#1 [phi:irq_zero::@6->irq_zero::@5#0] -- register_copy + // [43] phi irq_line::i#2 = irq_line::i#1 [phi:irq_line::@6->irq_line::@5#0] -- register_copy jmp __b5 } // main @@ -626,34 +1244,86 @@ main: { jmp __b2 // main::@2 __b2: - // [31] *KERNEL_IRQ = &irq_zero -- _deref_qprc1=pprc2 - lda #irq_zero + lda #>irq_line sta KERNEL_IRQ+1 - // [32] *VERA_IEN = VERA_LINE -- _deref_pbuc1=vbuc2 + // [55] *VERA_IEN = VERA_LINE -- _deref_pbuc1=vbuc2 lda #VERA_LINE sta VERA_IEN - // [33] *VERA_IRQLINE_L = 0 -- _deref_pbuc1=vbuc2 - lda #0 + // [56] *VERA_IRQLINE_L = 5 -- _deref_pbuc1=vbuc2 + lda #5 sta VERA_IRQLINE_L jmp CLI1 // main::CLI1 CLI1: // asm { cli } cli - // [35] phi from main::@1 main::CLI1 to main::@1 [phi:main::@1/main::CLI1->main::@1] + // [58] phi from main::@1 main::CLI1 to main::@1 [phi:main::@1/main::CLI1->main::@1] __b1_from___b1: __b1_from_CLI1: jmp __b1 // main::@1 __b1: jmp __b1_from___b1 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +memset: { + .const num = $e6*SIZEOF_BYTE + .const c = 0 + .label str = BARS + .label end = str+num + .label dst = 9 + // [60] phi from memset to memset::@1 [phi:memset->memset::@1] + __b1_from_memset: + // [60] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 + lda #str + sta.z dst+1 + jmp __b1 + // memset::@1 + __b1: + // [61] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 + lda.z dst+1 + cmp #>end + bne __b2 + lda.z dst + cmp #memset::@1] + __b1_from___b2: + // [60] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy + jmp __b1 } // File Data .segment Data .align $100 - BARS: .byte $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0 +SIN: +.fill 256, 99+99*sin(i*2*PI/256) + + .align $100 + BARS: .fill $e6, 0 + .align $100 + BAR: .byte $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f, $1f, $1e, $1d, $1c, $1b, $1a, $19, $18, $17, $16, $15, $14, $13, $12, $11, $10 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __init1 @@ -661,74 +1331,149 @@ Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b2 Removing instruction jmp __b4 -Removing instruction jmp __b8 -Removing instruction jmp __b9 +Removing instruction jmp __b11 +Removing instruction jmp __b12 Removing instruction jmp __b1 +Removing instruction jmp __b19 +Removing instruction jmp __b13 +Removing instruction jmp __b15 Removing instruction jmp __breturn +Removing instruction jmp __b16 +Removing instruction jmp __b18 Removing instruction jmp __b5 Removing instruction jmp __b7 +Removing instruction jmp __b8 +Removing instruction jmp __b10 Removing instruction jmp SEI1 Removing instruction jmp __b2 Removing instruction jmp CLI1 Removing instruction jmp __b1 +Removing instruction jmp __b1 +Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination +Replacing label __b1_from___b4 with __b1 +Replacing label __b1_from___b11 with __b1 Replacing label __b1_from___b1 with __b1 Removing instruction __b1_from___init1: Removing instruction main_from___b1: +Removing instruction __b1_from___b11: +Removing instruction __b1_from___b12: +Removing instruction __b1_from___b4: Removing instruction __b1_from___b1: Removing instruction __b1_from_CLI1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __init1: Removing instruction __b1: Removing instruction __breturn: -Removing instruction __b2_from_irq_zero: +Removing instruction __b2_from_irq_line: Removing instruction __b4: -Removing instruction __b8: -Removing instruction __b9: +Removing instruction __b11: +Removing instruction __b12: +Removing instruction memset_from___b1: +Removing instruction __b19: +Removing instruction __b13_from___b19: +Removing instruction __b15: Removing instruction __breturn: +Removing instruction __b16_from___b14: +Removing instruction __b18: +Removing instruction __b13_from___b18: +Removing instruction __b16_from___b17: Removing instruction __b5_from___b3: Removing instruction __b7: -Removing instruction __b2_from___b7: +Removing instruction __b8_from___b7: +Removing instruction __b10: +Removing instruction __b2_from___b10: +Removing instruction __b8_from___b9: Removing instruction __b5_from___b6: Removing instruction SEI1: Removing instruction __b2: Removing instruction CLI1: +Removing instruction __b1_from_memset: +Removing instruction __breturn: +Removing instruction __b1_from___b2: Succesful ASM optimization Pass5UnusedLabelElimination +Removing instruction lda #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination FINAL SYMBOL TABLE -const byte* BARS[] = { $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0 } +const byte* BAR[$20] = { $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f, $1f, $1e, $1d, $1c, $1b, $1a, $19, $18, $17, $16, $15, $14, $13, $12, $11, $10 } +const byte* BARS[$e6] = { fill( $e6, 0) } const nomodify void()** KERNEL_IRQ = (void()**) 788 +const byte* SIN[$100] = kickasm {{ .fill 256, 99+99*sin(i*2*PI/256) + }} +const byte SIZEOF_BYTE = 1 const nomodify byte* VERA_CTRL = (byte*) 40741 const nomodify byte VERA_DCSEL = 2 const nomodify byte* VERA_DC_BORDER = (byte*) 40748 const nomodify byte* VERA_DC_HSTART = (byte*) 40745 const nomodify byte* VERA_DC_HSTOP = (byte*) 40746 +const nomodify byte* VERA_DC_VSTART = (byte*) 40747 +const nomodify byte* VERA_DC_VSTOP = (byte*) 40748 const nomodify byte* VERA_IEN = (byte*) 40742 const nomodify byte* VERA_IRQLINE_L = (byte*) 40744 const nomodify byte* VERA_ISR = (byte*) 40743 const nomodify byte VERA_LINE = 2 void __start() -volatile byte cnt loadstore zp[1]:4 0.7142857142857142 -volatile byte hstart loadstore zp[1]:2 0.5882352941176471 -volatile byte hstop loadstore zp[1]:3 0.4444444444444444 -void irq_zero() -byte irq_zero::i -byte irq_zero::i#1 reg byte a 202.0 -byte irq_zero::i#2 reg byte a 151.5 -byte irq_zero::l -byte irq_zero::l#1 reg byte x 22.0 -byte irq_zero::l#2 reg byte x 7.333333333333333 +volatile byte cnt loadstore zp[1]:7 0.5263157894736842 +volatile byte hstart loadstore zp[1]:3 0.4545454545454546 +volatile byte hstop loadstore zp[1]:4 0.34782608695652173 +void irq_line() +byte irq_line::b +byte irq_line::b#1 reg byte x 22.0 +byte irq_line::b#2 reg byte x 4.125 +byte* irq_line::bar +byte* irq_line::bar#0 bar zp[2]:9 22.4 +byte irq_line::i +byte irq_line::i#1 reg byte a 202.0 +byte irq_line::i#2 reg byte a 151.5 +byte irq_line::i1 +byte irq_line::i1#1 reg byte a 202.0 +byte irq_line::i1#2 reg byte a 151.5 +byte irq_line::i2 +byte irq_line::i2#1 reg byte y 202.0 +byte irq_line::i2#2 reg byte y 168.33333333333331 +byte irq_line::idx +byte irq_line::idx#0 idx zp[1]:2 2.0 +byte irq_line::idx#1 idx zp[1]:2 11.0 +byte irq_line::idx#2 idx zp[1]:2 5.0 +byte irq_line::l +byte irq_line::l#1 reg byte x 22.0 +byte irq_line::l#2 reg byte x 4.0 void main() +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +const byte memset::c#0 c = 0 +byte* memset::dst +byte* memset::dst#1 dst zp[2]:9 202.0 +byte* memset::dst#2 dst zp[2]:9 134.66666666666666 +byte* memset::end +const byte* memset::end#0 end = (byte*)memset::str#0+memset::num#0 +word memset::num +const word memset::num#0 num = $e6*SIZEOF_BYTE +void* memset::return +void* memset::str +const void* memset::str#0 str = (void*)BARS +volatile byte sin_idx loadstore zp[1]:8 0.27586206896551724 +volatile byte vstart loadstore zp[1]:5 0.3333333333333333 +volatile byte vstop loadstore zp[1]:6 0.32 -reg byte x [ irq_zero::l#2 irq_zero::l#1 ] -reg byte a [ irq_zero::i#2 irq_zero::i#1 ] -zp[1]:2 [ hstart ] -zp[1]:3 [ hstop ] -zp[1]:4 [ cnt ] +reg byte x [ irq_line::l#2 irq_line::l#1 ] +reg byte x [ irq_line::b#2 irq_line::b#1 ] +zp[1]:2 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +reg byte y [ irq_line::i2#2 irq_line::i2#1 ] +reg byte a [ irq_line::i#2 irq_line::i#1 ] +reg byte a [ irq_line::i1#2 irq_line::i1#1 ] +zp[1]:3 [ hstart ] +zp[1]:4 [ hstop ] +zp[1]:5 [ vstart ] +zp[1]:6 [ vstop ] +zp[1]:7 [ cnt ] +zp[1]:8 [ sin_idx ] +zp[2]:9 [ irq_line::bar#0 memset::dst#2 memset::dst#1 ] FINAL ASSEMBLER -Score: 1549 +Score: 5780 // File Comments // Example program for the Commander X16 @@ -749,6 +1494,7 @@ Score: 1549 // Global Constants & labels .const VERA_DCSEL = 2 .const VERA_LINE = 2 + .const SIZEOF_BYTE = 1 // $9F25 CTRL Control // Bit 7: Reset // Bit 1: DCSEL @@ -781,14 +1527,24 @@ Score: 1549 .label VERA_DC_HSTART = $9f29 // $9F2A DC_HSTOP (DCSEL=1) Active Display H-Stop (9:2) .label VERA_DC_HSTOP = $9f2a + // $9F2B DC_VSTART (DCSEL=1) Active Display V-Start (8:1) + .label VERA_DC_VSTART = $9f2b + // $9F2C DC_VSTOP (DCSEL=1) Active Display V-Stop (8:1) + .label VERA_DC_VSTOP = $9f2c // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The horizontal start - .label hstart = 2 + .label hstart = 3 // The horizontal stop - .label hstop = 3 + .label hstop = 4 + // The vertical start + .label vstart = 5 + // The vertical stop + .label vstop = 6 // The countdown - .label cnt = 4 + .label cnt = 7 + // The sin idx + .label sin_idx = 8 .segment Code // __start __start: { @@ -801,89 +1557,132 @@ __start: { // [2] hstop = (byte)$280/4 -- vbuz1=vbuc1 lda #$280/4 sta.z hstop + // vstart = 0/2 + // [3] vstart = 0 -- vbuz1=vbuc1 + lda #0 + sta.z vstart + // vstop = 480/2 + // [4] vstop = (byte)$1e0/2 -- vbuz1=vbuc1 + lda #$1e0/2 + sta.z vstop // cnt = 2 - // [3] cnt = 2 -- vbuz1=vbuc1 + // [5] cnt = 2 -- vbuz1=vbuc1 lda #2 sta.z cnt - // [4] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] + // sin_idx = 100 + // [6] sin_idx = $64 -- vbuz1=vbuc1 + lda #$64 + sta.z sin_idx + // [7] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] // __start::@1 - // [5] call main - // [29] phi from __start::@1 to main [phi:__start::@1->main] + // [8] call main + // [52] phi from __start::@1 to main [phi:__start::@1->main] jsr main // __start::@return - // [6] return + // [9] return rts } - // irq_zero -// Interrupt Routine at raster 0 -irq_zero: { + // irq_line +// LINE Interrupt Routine +irq_line: { + .label idx = 2 + .label bar = 9 // *VERA_CTRL |= VERA_DCSEL - // [7] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [10] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Update the border lda #VERA_DCSEL ora VERA_CTRL sta VERA_CTRL // *VERA_DC_HSTART = hstart - // [8] *VERA_DC_HSTART = hstart -- _deref_pbuc1=vbuz1 + // [11] *VERA_DC_HSTART = hstart -- _deref_pbuc1=vbuz1 lda.z hstart sta VERA_DC_HSTART // *VERA_DC_HSTOP = hstop - // [9] *VERA_DC_HSTOP = hstop -- _deref_pbuc1=vbuz1 + // [12] *VERA_DC_HSTOP = hstop -- _deref_pbuc1=vbuz1 lda.z hstop sta VERA_DC_HSTOP + // *VERA_DC_VSTART = vstart + // [13] *VERA_DC_VSTART = vstart -- _deref_pbuc1=vbuz1 + lda.z vstart + sta VERA_DC_VSTART + // *VERA_DC_VSTOP = vstop + // [14] *VERA_DC_VSTOP = vstop -- _deref_pbuc1=vbuz1 + lda.z vstop + sta VERA_DC_VSTOP // *VERA_CTRL &= ~VERA_DCSEL - // [10] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [15] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 // Show color raster bars in the border lda #VERA_DCSEL^$ff and VERA_CTRL sta VERA_CTRL - // [11] phi from irq_zero to irq_zero::@2 [phi:irq_zero->irq_zero::@2] - // [11] phi irq_zero::l#2 = 0 [phi:irq_zero->irq_zero::@2#0] -- vbuxx=vbuc1 + // [16] phi from irq_line to irq_line::@2 [phi:irq_line->irq_line::@2] + // [16] phi irq_line::l#2 = 0 [phi:irq_line->irq_line::@2#0] -- vbuxx=vbuc1 ldx #0 - // irq_zero::@2 + // irq_line::@2 __b2: - // for(char l=0;l!=255;l++) - // [12] if(irq_zero::l#2!=$ff) goto irq_zero::@3 -- vbuxx_neq_vbuc1_then_la1 - cpx #$ff + // for(char l=0;l!=230;l++) + // [17] if(irq_line::l#2!=$e6) goto irq_line::@3 -- vbuxx_neq_vbuc1_then_la1 + cpx #$e6 bne __b3 - // irq_zero::@4 - // *VERA_DC_BORDER = 0 - // [13] *VERA_DC_BORDER = 0 -- _deref_pbuc1=vbuc2 - lda #0 - sta VERA_DC_BORDER - // *VERA_CTRL |= VERA_DCSEL - // [14] *VERA_CTRL = *VERA_CTRL | VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 - lda #VERA_DCSEL - ora VERA_CTRL - sta VERA_CTRL + // irq_line::@4 // if(--cnt==0) - // [15] cnt = -- cnt -- vbuz1=_dec_vbuz1 + // [18] cnt = -- cnt -- vbuz1=_dec_vbuz1 dec.z cnt - // [16] if(cnt!=0) goto irq_zero::@1 -- vbuz1_neq_0_then_la1 + // [19] if(cnt!=0) goto irq_line::@1 -- vbuz1_neq_0_then_la1 lda.z cnt cmp #0 bne __b1 - // irq_zero::@8 + // irq_line::@11 // cnt = 2 - // [17] cnt = 2 -- vbuz1=vbuc1 + // [20] cnt = 2 -- vbuz1=vbuc1 lda #2 sta.z cnt // if(hstart<=320/4) - // [18] if(hstart>=(byte)$140/4+1) goto irq_zero::@1 -- vbuz1_ge_vbuc1_then_la1 + // [21] if(hstart>=(byte)$140/4+1) goto irq_line::@1 -- vbuz1_ge_vbuc1_then_la1 lda.z hstart cmp #$140/4+1 bcs __b1 - // irq_zero::@9 + // irq_line::@12 // hstart++; - // [19] hstart = ++ hstart -- vbuz1=_inc_vbuz1 + // [22] hstart = ++ hstart -- vbuz1=_inc_vbuz1 inc.z hstart // hstop--; - // [20] hstop = -- hstop -- vbuz1=_dec_vbuz1 + // [23] hstop = -- hstop -- vbuz1=_dec_vbuz1 dec.z hstop - // irq_zero::@1 + // vstart++; + // [24] vstart = ++ vstart -- vbuz1=_inc_vbuz1 + inc.z vstart + // vstop--; + // [25] vstop = -- vstop -- vbuz1=_dec_vbuz1 + dec.z vstop + // [26] phi from irq_line::@11 irq_line::@12 irq_line::@4 to irq_line::@1 [phi:irq_line::@11/irq_line::@12/irq_line::@4->irq_line::@1] + // irq_line::@1 __b1: + // memset(BARS, 0, sizeof(BARS)) + // [27] call memset + // Animate the bars + // [59] phi from irq_line::@1 to memset [phi:irq_line::@1->memset] + jsr memset + // irq_line::@19 + // idx = sin_idx-- + // [28] irq_line::idx#0 = sin_idx -- vbuz1=vbuz2 + lda.z sin_idx + sta.z idx + // [29] sin_idx = -- sin_idx -- vbuz1=_dec_vbuz1 + dec.z sin_idx + // [30] phi from irq_line::@19 to irq_line::@13 [phi:irq_line::@19->irq_line::@13] + // [30] phi irq_line::idx#2 = irq_line::idx#0 [phi:irq_line::@19->irq_line::@13#0] -- register_copy + // [30] phi irq_line::b#2 = 0 [phi:irq_line::@19->irq_line::@13#1] -- vbuxx=vbuc1 + ldx #0 + // irq_line::@13 + __b13: + // for(char b=0;b<8;b++) + // [31] if(irq_line::b#2<8) goto irq_line::@14 -- vbuxx_lt_vbuc1_then_la1 + cpx #8 + bcc __b14 + // irq_line::@15 // *VERA_ISR = VERA_LINE - // [21] *VERA_ISR = VERA_LINE -- _deref_pbuc1=vbuc2 + // [32] *VERA_ISR = VERA_LINE -- _deref_pbuc1=vbuc2 // Reset the LINE interrupt lda #VERA_LINE sta VERA_ISR @@ -894,39 +1693,113 @@ irq_zero: { plx pla rti - // irq_zero::@return + // irq_line::@return // } - // [23] return + // [34] return rts - // irq_zero::@3 + // irq_line::@14 + __b14: + // bar = BARS + SIN[idx] + // [35] irq_line::bar#0 = BARS + SIN[irq_line::idx#2] -- pbuz1=pbuc1_plus_pbuc2_derefidx_vbuz2 + ldy.z idx + lda SIN,y + clc + adc #BARS + adc #0 + sta.z bar+1 + // [36] phi from irq_line::@14 to irq_line::@16 [phi:irq_line::@14->irq_line::@16] + // [36] phi irq_line::i2#2 = 0 [phi:irq_line::@14->irq_line::@16#0] -- vbuyy=vbuc1 + ldy #0 + // irq_line::@16 + __b16: + // for(char i=0;iirq_line::@13] + // [30] phi irq_line::idx#2 = irq_line::idx#1 [phi:irq_line::@18->irq_line::@13#0] -- register_copy + // [30] phi irq_line::b#2 = irq_line::b#1 [phi:irq_line::@18->irq_line::@13#1] -- register_copy + jmp __b13 + // irq_line::@17 + __b17: + // bar[i] = BAR[i] + // [40] irq_line::bar#0[irq_line::i2#2] = BAR[irq_line::i2#2] -- pbuz1_derefidx_vbuyy=pbuc1_derefidx_vbuyy + lda BAR,y + sta (bar),y + // for(char i=0;iirq_line::@16] + // [36] phi irq_line::i2#2 = irq_line::i2#1 [phi:irq_line::@17->irq_line::@16#0] -- register_copy + jmp __b16 + // irq_line::@3 __b3: // *VERA_DC_BORDER = BARS[l] - // [24] *VERA_DC_BORDER = BARS[irq_zero::l#2] -- _deref_pbuc1=pbuc2_derefidx_vbuxx + // [42] *VERA_DC_BORDER = BARS[irq_line::l#2] -- _deref_pbuc1=pbuc2_derefidx_vbuxx lda BARS,x sta VERA_DC_BORDER - // [25] phi from irq_zero::@3 to irq_zero::@5 [phi:irq_zero::@3->irq_zero::@5] - // [25] phi irq_zero::i#2 = 0 [phi:irq_zero::@3->irq_zero::@5#0] -- vbuaa=vbuc1 + // [43] phi from irq_line::@3 to irq_line::@5 [phi:irq_line::@3->irq_line::@5] + // [43] phi irq_line::i#2 = 0 [phi:irq_line::@3->irq_line::@5#0] -- vbuaa=vbuc1 lda #0 - // irq_zero::@5 + // irq_line::@5 __b5: - // for(char i=0;i<23;i++) - // [26] if(irq_zero::i#2<$17) goto irq_zero::@6 -- vbuaa_lt_vbuc1_then_la1 - cmp #$17 + // for(char i=0;i<24;i++) + // [44] if(irq_line::i#2<$18) goto irq_line::@6 -- vbuaa_lt_vbuc1_then_la1 + cmp #$18 bcc __b6 - // irq_zero::@7 - // for(char l=0;l!=255;l++) - // [27] irq_zero::l#1 = ++ irq_zero::l#2 -- vbuxx=_inc_vbuxx - inx - // [11] phi from irq_zero::@7 to irq_zero::@2 [phi:irq_zero::@7->irq_zero::@2] - // [11] phi irq_zero::l#2 = irq_zero::l#1 [phi:irq_zero::@7->irq_zero::@2#0] -- register_copy - jmp __b2 - // irq_zero::@6 - __b6: + // irq_line::@7 + // *VERA_DC_BORDER = 0 + // [45] *VERA_DC_BORDER = 0 -- _deref_pbuc1=vbuc2 + // Wait exactly long enought to go to the next raster line + lda #0 + sta VERA_DC_BORDER + // [46] phi from irq_line::@7 to irq_line::@8 [phi:irq_line::@7->irq_line::@8] + // [46] phi irq_line::i1#2 = 0 [phi:irq_line::@7->irq_line::@8#0] -- vbuaa=vbuc1 + // irq_line::@8 + __b8: // for(char i=0;i<23;i++) - // [28] irq_zero::i#1 = ++ irq_zero::i#2 -- vbuaa=_inc_vbuaa + // [47] if(irq_line::i1#2<$17) goto irq_line::@9 -- vbuaa_lt_vbuc1_then_la1 + cmp #$17 + bcc __b9 + // irq_line::@10 + // asm + // asm { nop nop } + // Wait exactly long enought to go to the next raster line + nop + nop + // for(char l=0;l!=230;l++) + // [49] irq_line::l#1 = ++ irq_line::l#2 -- vbuxx=_inc_vbuxx + inx + // [16] phi from irq_line::@10 to irq_line::@2 [phi:irq_line::@10->irq_line::@2] + // [16] phi irq_line::l#2 = irq_line::l#1 [phi:irq_line::@10->irq_line::@2#0] -- register_copy + jmp __b2 + // irq_line::@9 + __b9: + // for(char i=0;i<23;i++) + // [50] irq_line::i1#1 = ++ irq_line::i1#2 -- vbuaa=_inc_vbuaa inc - // [25] phi from irq_zero::@6 to irq_zero::@5 [phi:irq_zero::@6->irq_zero::@5] - // [25] phi irq_zero::i#2 = irq_zero::i#1 [phi:irq_zero::@6->irq_zero::@5#0] -- register_copy + // [46] phi from irq_line::@9 to irq_line::@8 [phi:irq_line::@9->irq_line::@8] + // [46] phi irq_line::i1#2 = irq_line::i1#1 [phi:irq_line::@9->irq_line::@8#0] -- register_copy + jmp __b8 + // irq_line::@6 + __b6: + // for(char i=0;i<24;i++) + // [51] irq_line::i#1 = ++ irq_line::i#2 -- vbuaa=_inc_vbuaa + inc + // [43] phi from irq_line::@6 to irq_line::@5 [phi:irq_line::@6->irq_line::@5] + // [43] phi irq_line::i#2 = irq_line::i#1 [phi:irq_line::@6->irq_line::@5#0] -- register_copy jmp __b5 } // main @@ -936,31 +1809,82 @@ main: { // asm { sei } sei // main::@2 - // *KERNEL_IRQ = &irq_zero - // [31] *KERNEL_IRQ = &irq_zero -- _deref_qprc1=pprc2 - lda #irq_zero + lda #>irq_line sta KERNEL_IRQ+1 // *VERA_IEN = VERA_LINE - // [32] *VERA_IEN = VERA_LINE -- _deref_pbuc1=vbuc2 + // [55] *VERA_IEN = VERA_LINE -- _deref_pbuc1=vbuc2 lda #VERA_LINE sta VERA_IEN - // *VERA_IRQLINE_L = 0 - // [33] *VERA_IRQLINE_L = 0 -- _deref_pbuc1=vbuc2 - lda #0 + // *VERA_IRQLINE_L = 5 + // [56] *VERA_IRQLINE_L = 5 -- _deref_pbuc1=vbuc2 + lda #5 sta VERA_IRQLINE_L // main::CLI1 // asm // asm { cli } cli - // [35] phi from main::@1 main::CLI1 to main::@1 [phi:main::@1/main::CLI1->main::@1] + // [58] phi from main::@1 main::CLI1 to main::@1 [phi:main::@1/main::CLI1->main::@1] // main::@1 __b1: jmp __b1 +} + // memset +// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str. +memset: { + .const num = $e6*SIZEOF_BYTE + .const c = 0 + .label str = BARS + .label end = str+num + .label dst = 9 + // [60] phi from memset to memset::@1 [phi:memset->memset::@1] + // [60] phi memset::dst#2 = (byte*)memset::str#0 [phi:memset->memset::@1#0] -- pbuz1=pbuc1 + lda #str + sta.z dst+1 + // memset::@1 + __b1: + // for(char* dst = str; dst!=end; dst++) + // [61] if(memset::dst#2!=memset::end#0) goto memset::@2 -- pbuz1_neq_pbuc1_then_la1 + lda.z dst+1 + cmp #>end + bne __b2 + lda.z dst + cmp #memset::@1] + // [60] phi memset::dst#2 = memset::dst#1 [phi:memset::@2->memset::@1#0] -- register_copy + jmp __b1 } // File Data .segment Data .align $100 - BARS: .byte $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0 +SIN: +.fill 256, 99+99*sin(i*2*PI/256) + + .align $100 + BARS: .fill $e6, 0 + .align $100 + BAR: .byte $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f, $1f, $1e, $1d, $1c, $1b, $1a, $19, $18, $17, $16, $15, $14, $13, $12, $11, $10 diff --git a/src/test/ref/examples/cx16/rasterbars.sym b/src/test/ref/examples/cx16/rasterbars.sym index b01a4fd39..e907961e8 100644 --- a/src/test/ref/examples/cx16/rasterbars.sym +++ b/src/test/ref/examples/cx16/rasterbars.sym @@ -1,29 +1,74 @@ -const byte* BARS[] = { $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0, $10, 0, $11, 0, $12, 0, $13, 0, $14, 0, $15, 0, $16, 0, $17, 0, $18, 0, $19, 0, $1a, 0, $1b, 0, $1c, 0, $1d, 0, $1e, 0, $1f, 0, $1f, 0, $1e, 0, $1d, 0, $1c, 0, $1b, 0, $1a, 0, $19, 0, $18, 0, $17, 0, $16, 0, $15, 0, $14, 0, $13, 0, $12, 0, $11, 0, $10, 0 } +const byte* BAR[$20] = { $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $1a, $1b, $1c, $1d, $1e, $1f, $1f, $1e, $1d, $1c, $1b, $1a, $19, $18, $17, $16, $15, $14, $13, $12, $11, $10 } +const byte* BARS[$e6] = { fill( $e6, 0) } const nomodify void()** KERNEL_IRQ = (void()**) 788 +const byte* SIN[$100] = kickasm {{ .fill 256, 99+99*sin(i*2*PI/256) + }} +const byte SIZEOF_BYTE = 1 const nomodify byte* VERA_CTRL = (byte*) 40741 const nomodify byte VERA_DCSEL = 2 const nomodify byte* VERA_DC_BORDER = (byte*) 40748 const nomodify byte* VERA_DC_HSTART = (byte*) 40745 const nomodify byte* VERA_DC_HSTOP = (byte*) 40746 +const nomodify byte* VERA_DC_VSTART = (byte*) 40747 +const nomodify byte* VERA_DC_VSTOP = (byte*) 40748 const nomodify byte* VERA_IEN = (byte*) 40742 const nomodify byte* VERA_IRQLINE_L = (byte*) 40744 const nomodify byte* VERA_ISR = (byte*) 40743 const nomodify byte VERA_LINE = 2 void __start() -volatile byte cnt loadstore zp[1]:4 0.7142857142857142 -volatile byte hstart loadstore zp[1]:2 0.5882352941176471 -volatile byte hstop loadstore zp[1]:3 0.4444444444444444 -void irq_zero() -byte irq_zero::i -byte irq_zero::i#1 reg byte a 202.0 -byte irq_zero::i#2 reg byte a 151.5 -byte irq_zero::l -byte irq_zero::l#1 reg byte x 22.0 -byte irq_zero::l#2 reg byte x 7.333333333333333 +volatile byte cnt loadstore zp[1]:7 0.5263157894736842 +volatile byte hstart loadstore zp[1]:3 0.4545454545454546 +volatile byte hstop loadstore zp[1]:4 0.34782608695652173 +void irq_line() +byte irq_line::b +byte irq_line::b#1 reg byte x 22.0 +byte irq_line::b#2 reg byte x 4.125 +byte* irq_line::bar +byte* irq_line::bar#0 bar zp[2]:9 22.4 +byte irq_line::i +byte irq_line::i#1 reg byte a 202.0 +byte irq_line::i#2 reg byte a 151.5 +byte irq_line::i1 +byte irq_line::i1#1 reg byte a 202.0 +byte irq_line::i1#2 reg byte a 151.5 +byte irq_line::i2 +byte irq_line::i2#1 reg byte y 202.0 +byte irq_line::i2#2 reg byte y 168.33333333333331 +byte irq_line::idx +byte irq_line::idx#0 idx zp[1]:2 2.0 +byte irq_line::idx#1 idx zp[1]:2 11.0 +byte irq_line::idx#2 idx zp[1]:2 5.0 +byte irq_line::l +byte irq_line::l#1 reg byte x 22.0 +byte irq_line::l#2 reg byte x 4.0 void main() +void* memset(void* memset::str , byte memset::c , word memset::num) +byte memset::c +const byte memset::c#0 c = 0 +byte* memset::dst +byte* memset::dst#1 dst zp[2]:9 202.0 +byte* memset::dst#2 dst zp[2]:9 134.66666666666666 +byte* memset::end +const byte* memset::end#0 end = (byte*)memset::str#0+memset::num#0 +word memset::num +const word memset::num#0 num = $e6*SIZEOF_BYTE +void* memset::return +void* memset::str +const void* memset::str#0 str = (void*)BARS +volatile byte sin_idx loadstore zp[1]:8 0.27586206896551724 +volatile byte vstart loadstore zp[1]:5 0.3333333333333333 +volatile byte vstop loadstore zp[1]:6 0.32 -reg byte x [ irq_zero::l#2 irq_zero::l#1 ] -reg byte a [ irq_zero::i#2 irq_zero::i#1 ] -zp[1]:2 [ hstart ] -zp[1]:3 [ hstop ] -zp[1]:4 [ cnt ] +reg byte x [ irq_line::l#2 irq_line::l#1 ] +reg byte x [ irq_line::b#2 irq_line::b#1 ] +zp[1]:2 [ irq_line::idx#2 irq_line::idx#1 irq_line::idx#0 ] +reg byte y [ irq_line::i2#2 irq_line::i2#1 ] +reg byte a [ irq_line::i#2 irq_line::i#1 ] +reg byte a [ irq_line::i1#2 irq_line::i1#1 ] +zp[1]:3 [ hstart ] +zp[1]:4 [ hstop ] +zp[1]:5 [ vstart ] +zp[1]:6 [ vstop ] +zp[1]:7 [ cnt ] +zp[1]:8 [ sin_idx ] +zp[2]:9 [ irq_line::bar#0 memset::dst#2 memset::dst#1 ] diff --git a/src/test/ref/examples/cx16/text.asm b/src/test/ref/examples/cx16/text.asm new file mode 100644 index 000000000..195dd1e40 --- /dev/null +++ b/src/test/ref/examples/cx16/text.asm @@ -0,0 +1,104 @@ +// Example program for the Commander X16 +// Displays text on the screen by transfering data to VERA +.cpu _65c02 + // Commodore 64 PRG executable file +.file [name="text.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) +.segment Code + + + .const VERA_ADDRSEL = 1 + // $9F20 VRAM Address (7:0) + .label VERA_ADDRX_L = $9f20 + // $9F21 VRAM Address (15:8) + .label VERA_ADDRX_M = $9f21 + // $9F22 VRAM Address (7:0) + // Bit 4-7: Address Increment The following is the amount incremented per value value:increment + // 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640 + // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. + // Bit 0: VRAM Address (16) + .label VERA_ADDRX_H = $9f22 + // $9F23 DATA0 VRAM Data port 0 + .label VERA_DATA0 = $9f23 + // $9F25 CTRL Control + // Bit 7: Reset + // Bit 1: DCSEL + // Bit 2: ADDRSEL + .label VERA_CTRL = $9f25 +.segment Code +main: { + // Address of the default screen + .label vaddr = 2 + lda #<0 + sta.z vaddr + sta.z vaddr+1 + tay + __b1: + // for(char i=0;MSG[i];i++) + lda MSG,y + cmp #0 + bne __b2 + // } + rts + __b2: + // vpoke(0, vaddr++, MSG[i]) + ldx MSG,y + jsr vpoke + // vpoke(0, vaddr++, MSG[i]); + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // vpoke(0, vaddr++, 0x21) + // Message + ldx #$21 + jsr vpoke + // vpoke(0, vaddr++, 0x21); + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // for(char i=0;MSG[i];i++) + iny + jmp __b1 + .segment Data + MSG: .text "hello world!" + .byte 0 +} +.segment Code +// Put a single byte into VRAM. +// Uses VERA DATA0 +// - bank: Which 64K VRAM bank to put data into (0/1) +// - addr: The address in VRAM +// - data: The data to put into VRAM +// vpoke(byte* zp(2) addr, byte register(X) data) +vpoke: { + .label addr = 2 + // *VERA_CTRL &= ~VERA_ADDRSEL + // Select DATA0 + lda #VERA_ADDRSEL^$ff + and VERA_CTRL + sta VERA_CTRL + // addr + lda.z addr+1 + // *VERA_ADDRX_M = >addr + sta VERA_ADDRX_M + // *VERA_ADDRX_H = VERA_INC_0 | bank + lda #0 + sta VERA_ADDRX_H + // *VERA_DATA0 = data + // Set data + stx VERA_DATA0 + // } + rts +} diff --git a/src/test/ref/examples/cx16/text.cfg b/src/test/ref/examples/cx16/text.cfg new file mode 100644 index 000000000..098b654c0 --- /dev/null +++ b/src/test/ref/examples/cx16/text.cfg @@ -0,0 +1,43 @@ + +void main() +main: scope:[main] from + [0] phi() + to:main::@1 +main::@1: scope:[main] from main main::@4 + [1] main::vaddr#3 = phi( main/(byte*) 0, main::@4/main::vaddr#2 ) + [1] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [2] if(0!=main::MSG[main::i#2]) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [3] return + to:@return +main::@2: scope:[main] from main::@1 + [4] vpoke::addr#0 = main::vaddr#3 + [5] vpoke::data#0 = main::MSG[main::i#2] + [6] call vpoke + to:main::@3 +main::@3: scope:[main] from main::@2 + [7] main::vaddr#1 = ++ main::vaddr#3 + [8] vpoke::addr#1 = main::vaddr#1 + [9] call vpoke + to:main::@4 +main::@4: scope:[main] from main::@3 + [10] main::vaddr#2 = ++ main::vaddr#1 + [11] main::i#1 = ++ main::i#2 + to:main::@1 + +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +vpoke: scope:[vpoke] from main::@2 main::@3 + [12] vpoke::data#2 = phi( main::@2/vpoke::data#0, main::@3/$21 ) + [12] vpoke::addr#2 = phi( main::@2/vpoke::addr#0, main::@3/vpoke::addr#1 ) + [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL + [14] vpoke::$0 = < vpoke::addr#2 + [15] *VERA_ADDRX_L = vpoke::$0 + [16] vpoke::$1 = > vpoke::addr#2 + [17] *VERA_ADDRX_M = vpoke::$1 + [18] *VERA_ADDRX_H = 0 + [19] *VERA_DATA0 = vpoke::data#2 + to:vpoke::@return +vpoke::@return: scope:[vpoke] from vpoke + [20] return + to:@return diff --git a/src/test/ref/examples/cx16/text.log b/src/test/ref/examples/cx16/text.log new file mode 100644 index 000000000..7678129de --- /dev/null +++ b/src/test/ref/examples/cx16/text.log @@ -0,0 +1,668 @@ + +CONTROL FLOW GRAPH SSA + +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +vpoke: scope:[vpoke] from main::@2 main::@3 + vpoke::data#2 = phi( main::@2/vpoke::data#0, main::@3/vpoke::data#1 ) + vpoke::bank#2 = phi( main::@2/vpoke::bank#0, main::@3/vpoke::bank#1 ) + vpoke::addr#2 = phi( main::@2/vpoke::addr#0, main::@3/vpoke::addr#1 ) + *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL + vpoke::$0 = < vpoke::addr#2 + *VERA_ADDRX_L = vpoke::$0 + vpoke::$1 = > vpoke::addr#2 + *VERA_ADDRX_M = vpoke::$1 + vpoke::$2 = VERA_INC_0 | vpoke::bank#2 + *VERA_ADDRX_H = vpoke::$2 + *VERA_DATA0 = vpoke::data#2 + to:vpoke::@return +vpoke::@return: scope:[vpoke] from vpoke + return + to:@return + +void main() +main: scope:[main] from __start + main::vaddr#0 = (byte*)0 + main::i#0 = 0 + to:main::@1 +main::@1: scope:[main] from main main::@4 + main::vaddr#6 = phi( main/main::vaddr#0, main::@4/main::vaddr#2 ) + main::i#2 = phi( main/main::i#0, main::@4/main::i#1 ) + main::$2 = 0 != main::MSG[main::i#2] + if(main::$2) goto main::@2 + to:main::@return +main::@2: scope:[main] from main::@1 + main::i#3 = phi( main::@1/main::i#2 ) + main::vaddr#3 = phi( main::@1/main::vaddr#6 ) + vpoke::bank#0 = 0 + vpoke::addr#0 = main::vaddr#3 + vpoke::data#0 = main::MSG[main::i#3] + call vpoke + to:main::@3 +main::@3: scope:[main] from main::@2 + main::i#5 = phi( main::@2/main::i#3 ) + main::vaddr#4 = phi( main::@2/main::vaddr#3 ) + main::vaddr#1 = ++ main::vaddr#4 + vpoke::bank#1 = 0 + vpoke::addr#1 = main::vaddr#1 + vpoke::data#1 = $21 + call vpoke + to:main::@4 +main::@4: scope:[main] from main::@3 + main::i#4 = phi( main::@3/main::i#5 ) + main::vaddr#5 = phi( main::@3/main::vaddr#1 ) + main::vaddr#2 = ++ main::vaddr#5 + main::i#1 = ++ main::i#4 + to:main::@1 +main::@return: scope:[main] from main::@1 + return + to:@return + +void __start() +__start: scope:[__start] from + call main + to:__start::@1 +__start::@1: scope:[__start] from __start + to:__start::@return +__start::@return: scope:[__start] from __start::@1 + return + to:@return + +SYMBOL TABLE SSA +const nomodify byte VERA_ADDRSEL = 1 +const nomodify byte* VERA_ADDRX_H = (byte*)$9f22 +const nomodify byte* VERA_ADDRX_L = (byte*)$9f20 +const nomodify byte* VERA_ADDRX_M = (byte*)$9f21 +const nomodify byte* VERA_CTRL = (byte*)$9f25 +const nomodify byte* VERA_DATA0 = (byte*)$9f23 +const nomodify byte VERA_INC_0 = 0 +void __start() +void main() +bool~ main::$2 +const byte* main::MSG[] = "hello world!" +byte main::i +byte main::i#0 +byte main::i#1 +byte main::i#2 +byte main::i#3 +byte main::i#4 +byte main::i#5 +byte* main::vaddr +byte* main::vaddr#0 +byte* main::vaddr#1 +byte* main::vaddr#2 +byte* main::vaddr#3 +byte* main::vaddr#4 +byte* main::vaddr#5 +byte* main::vaddr#6 +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +byte~ vpoke::$0 +byte~ vpoke::$1 +byte~ vpoke::$2 +byte* vpoke::addr +byte* vpoke::addr#0 +byte* vpoke::addr#1 +byte* vpoke::addr#2 +byte vpoke::bank +byte vpoke::bank#0 +byte vpoke::bank#1 +byte vpoke::bank#2 +byte vpoke::data +byte vpoke::data#0 +byte vpoke::data#1 +byte vpoke::data#2 + +Adding number conversion cast (unumber) 0 in main::$2 = 0 != main::MSG[main::i#2] +Adding number conversion cast (unumber) 0 in vpoke::bank#0 = 0 +Adding number conversion cast (unumber) 0 in vpoke::bank#1 = 0 +Adding number conversion cast (unumber) $21 in vpoke::data#1 = $21 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast vpoke::bank#0 = (unumber)0 +Inlining cast vpoke::bank#1 = (unumber)0 +Inlining cast vpoke::data#1 = (unumber)$21 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 40736 +Simplifying constant pointer cast (byte*) 40737 +Simplifying constant pointer cast (byte*) 40738 +Simplifying constant pointer cast (byte*) 40739 +Simplifying constant pointer cast (byte*) 40741 +Simplifying constant pointer cast (byte*) 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast $21 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $21 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Alias main::vaddr#3 = main::vaddr#6 main::vaddr#4 +Alias main::i#2 = main::i#3 main::i#5 main::i#4 +Alias main::vaddr#1 = main::vaddr#5 +Successful SSA optimization Pass2AliasElimination +Simple Condition main::$2 [14] if(0!=main::MSG[main::i#2]) goto main::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant main::vaddr#0 = (byte*) 0 +Constant main::i#0 = 0 +Constant vpoke::bank#0 = 0 +Constant vpoke::bank#1 = 0 +Constant vpoke::data#1 = $21 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero vpoke::bank#2 in [6] vpoke::$2 = VERA_INC_0 | vpoke::bank#2 +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant VERA_INC_0 +Successful SSA optimization PassNEliminateUnusedVars +Removing unused procedure __start +Removing unused procedure block __start +Removing unused procedure block __start::@1 +Removing unused procedure block __start::@return +Successful SSA optimization PassNEliminateEmptyStart +Alias vpoke::bank#2 = vpoke::$2 +Successful SSA optimization Pass2AliasElimination +Inlining constant with var siblings vpoke::bank#0 +Inlining constant with var siblings vpoke::bank#1 +Inlining constant with var siblings vpoke::data#1 +Inlining constant with var siblings main::vaddr#0 +Inlining constant with var siblings main::i#0 +Constant inlined main::i#0 = 0 +Constant inlined vpoke::bank#1 = 0 +Constant inlined vpoke::bank#0 = 0 +Constant inlined main::vaddr#0 = (byte*) 0 +Constant inlined vpoke::data#1 = $21 +Successful SSA optimization Pass2ConstantInlining +Identical Phi Values vpoke::bank#2 0 +Successful SSA optimization Pass2IdenticalPhiElimination +Adding NOP phi() at start of main +CALL GRAPH +Calls in [main] to vpoke:8 vpoke:12 + +Created 4 initial phi equivalence classes +Coalesced [6] vpoke::addr#3 = vpoke::addr#0 +Coalesced [7] vpoke::data#3 = vpoke::data#0 +Coalesced [11] vpoke::addr#4 = vpoke::addr#1 +Coalesced [15] main::i#6 = main::i#1 +Coalesced [16] main::vaddr#7 = main::vaddr#2 +Coalesced down to 4 phi equivalence classes +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH + +void main() +main: scope:[main] from + [0] phi() + to:main::@1 +main::@1: scope:[main] from main main::@4 + [1] main::vaddr#3 = phi( main/(byte*) 0, main::@4/main::vaddr#2 ) + [1] main::i#2 = phi( main/0, main::@4/main::i#1 ) + [2] if(0!=main::MSG[main::i#2]) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@1 + [3] return + to:@return +main::@2: scope:[main] from main::@1 + [4] vpoke::addr#0 = main::vaddr#3 + [5] vpoke::data#0 = main::MSG[main::i#2] + [6] call vpoke + to:main::@3 +main::@3: scope:[main] from main::@2 + [7] main::vaddr#1 = ++ main::vaddr#3 + [8] vpoke::addr#1 = main::vaddr#1 + [9] call vpoke + to:main::@4 +main::@4: scope:[main] from main::@3 + [10] main::vaddr#2 = ++ main::vaddr#1 + [11] main::i#1 = ++ main::i#2 + to:main::@1 + +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +vpoke: scope:[vpoke] from main::@2 main::@3 + [12] vpoke::data#2 = phi( main::@2/vpoke::data#0, main::@3/$21 ) + [12] vpoke::addr#2 = phi( main::@2/vpoke::addr#0, main::@3/vpoke::addr#1 ) + [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL + [14] vpoke::$0 = < vpoke::addr#2 + [15] *VERA_ADDRX_L = vpoke::$0 + [16] vpoke::$1 = > vpoke::addr#2 + [17] *VERA_ADDRX_M = vpoke::$1 + [18] *VERA_ADDRX_H = 0 + [19] *VERA_DATA0 = vpoke::data#2 + to:vpoke::@return +vpoke::@return: scope:[vpoke] from vpoke + [20] return + to:@return + + +VARIABLE REGISTER WEIGHTS +void main() +byte main::i +byte main::i#1 22.0 +byte main::i#2 4.888888888888889 +byte* main::vaddr +byte* main::vaddr#1 11.0 +byte* main::vaddr#2 11.0 +byte* main::vaddr#3 6.6000000000000005 +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +byte~ vpoke::$0 202.0 +byte~ vpoke::$1 202.0 +byte* vpoke::addr +byte* vpoke::addr#0 11.0 +byte* vpoke::addr#1 22.0 +byte* vpoke::addr#2 56.0 +byte vpoke::bank +byte vpoke::data +byte vpoke::data#0 22.0 +byte vpoke::data#2 16.0 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::vaddr#3 main::vaddr#2 ] +[ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] +[ vpoke::data#2 vpoke::data#0 ] +Added variable main::vaddr#1 to live range equivalence class [ main::vaddr#1 ] +Added variable vpoke::$0 to live range equivalence class [ vpoke::$0 ] +Added variable vpoke::$1 to live range equivalence class [ vpoke::$1 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::vaddr#3 main::vaddr#2 ] +[ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] +[ vpoke::data#2 vpoke::data#0 ] +[ main::vaddr#1 ] +[ vpoke::$0 ] +[ vpoke::$1 ] +Allocated zp[1]:2 [ main::i#2 main::i#1 ] +Allocated zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] +Allocated zp[2]:5 [ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] +Allocated zp[1]:7 [ vpoke::data#2 vpoke::data#0 ] +Allocated zp[2]:8 [ main::vaddr#1 ] +Allocated zp[1]:10 [ vpoke::$0 ] +Allocated zp[1]:11 [ vpoke::$1 ] +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [2] if(0!=main::MSG[main::i#2]) goto main::@2 [ main::i#2 main::vaddr#3 ] ( [ main::i#2 main::vaddr#3 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] +Statement [4] vpoke::addr#0 = main::vaddr#3 [ main::i#2 main::vaddr#3 vpoke::addr#0 ] ( [ main::i#2 main::vaddr#3 vpoke::addr#0 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } ) always clobbers reg byte a +Statement [7] main::vaddr#1 = ++ main::vaddr#3 [ main::i#2 main::vaddr#1 ] ( [ main::i#2 main::vaddr#1 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [8] vpoke::addr#1 = main::vaddr#1 [ main::i#2 main::vaddr#1 vpoke::addr#1 ] ( [ main::i#2 main::vaddr#1 vpoke::addr#1 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [10] main::vaddr#2 = ++ main::vaddr#1 [ main::i#2 main::vaddr#2 ] ( [ main::i#2 main::vaddr#2 ] { } ) always clobbers reg byte a +Statement [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL [ vpoke::addr#2 vpoke::data#2 ] ( vpoke:6 [ main::i#2 main::vaddr#3 vpoke::addr#2 vpoke::data#2 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } vpoke:9 [ main::i#2 main::vaddr#1 vpoke::addr#2 vpoke::data#2 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:7 [ vpoke::data#2 vpoke::data#0 ] +Statement [18] *VERA_ADDRX_H = 0 [ vpoke::data#2 ] ( vpoke:6 [ main::i#2 main::vaddr#3 vpoke::data#2 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } vpoke:9 [ main::i#2 main::vaddr#1 vpoke::data#2 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [2] if(0!=main::MSG[main::i#2]) goto main::@2 [ main::i#2 main::vaddr#3 ] ( [ main::i#2 main::vaddr#3 ] { } ) always clobbers reg byte a +Statement [4] vpoke::addr#0 = main::vaddr#3 [ main::i#2 main::vaddr#3 vpoke::addr#0 ] ( [ main::i#2 main::vaddr#3 vpoke::addr#0 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } ) always clobbers reg byte a +Statement [7] main::vaddr#1 = ++ main::vaddr#3 [ main::i#2 main::vaddr#1 ] ( [ main::i#2 main::vaddr#1 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [8] vpoke::addr#1 = main::vaddr#1 [ main::i#2 main::vaddr#1 vpoke::addr#1 ] ( [ main::i#2 main::vaddr#1 vpoke::addr#1 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [10] main::vaddr#2 = ++ main::vaddr#1 [ main::i#2 main::vaddr#2 ] ( [ main::i#2 main::vaddr#2 ] { } ) always clobbers reg byte a +Statement [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL [ vpoke::addr#2 vpoke::data#2 ] ( vpoke:6 [ main::i#2 main::vaddr#3 vpoke::addr#2 vpoke::data#2 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } vpoke:9 [ main::i#2 main::vaddr#1 vpoke::addr#2 vpoke::data#2 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Statement [18] *VERA_ADDRX_H = 0 [ vpoke::data#2 ] ( vpoke:6 [ main::i#2 main::vaddr#3 vpoke::data#2 ] { { vpoke::addr#0 = vpoke::addr#2 main::vaddr#3 } { vpoke::data#0 = vpoke::data#2 } } vpoke:9 [ main::i#2 main::vaddr#1 vpoke::data#2 ] { { vpoke::addr#1 = vpoke::addr#2 main::vaddr#1 } } ) always clobbers reg byte a +Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , +Potential registers zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] : zp[2]:3 , +Potential registers zp[2]:5 [ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] : zp[2]:5 , +Potential registers zp[1]:7 [ vpoke::data#2 vpoke::data#0 ] : zp[1]:7 , reg byte x , reg byte y , +Potential registers zp[2]:8 [ main::vaddr#1 ] : zp[2]:8 , +Potential registers zp[1]:10 [ vpoke::$0 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:11 [ vpoke::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [vpoke] 202: zp[1]:10 [ vpoke::$0 ] 202: zp[1]:11 [ vpoke::$1 ] 89: zp[2]:5 [ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] 38: zp[1]:7 [ vpoke::data#2 vpoke::data#0 ] +Uplift Scope [main] 26.89: zp[1]:2 [ main::i#2 main::i#1 ] 17.6: zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] 11: zp[2]:8 [ main::vaddr#1 ] +Uplift Scope [MOS6522_VIA] +Uplift Scope [] + +Uplifting [vpoke] best 1154 combination reg byte a [ vpoke::$0 ] reg byte a [ vpoke::$1 ] zp[2]:5 [ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] reg byte x [ vpoke::data#2 vpoke::data#0 ] +Uplifting [main] best 1034 combination reg byte y [ main::i#2 main::i#1 ] zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] zp[2]:8 [ main::vaddr#1 ] +Uplifting [MOS6522_VIA] best 1034 combination +Uplifting [] best 1034 combination +Coalescing zero page register [ zp[2]:3 [ main::vaddr#3 main::vaddr#2 ] ] with [ zp[2]:8 [ main::vaddr#1 ] ] - score: 2 +Coalescing zero page register [ zp[2]:3 [ main::vaddr#3 main::vaddr#2 main::vaddr#1 ] ] with [ zp[2]:5 [ vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] ] - score: 1 +Allocated (was zp[2]:3) zp[2]:2 [ main::vaddr#3 main::vaddr#2 main::vaddr#1 vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Example program for the Commander X16 +// Displays text on the screen by transfering data to VERA + // Upstart +.cpu _65c02 + // Commodore 64 PRG executable file +.file [name="text.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) +.segment Code + + + // Global Constants & labels + .const VERA_ADDRSEL = 1 + // $9F20 VRAM Address (7:0) + .label VERA_ADDRX_L = $9f20 + // $9F21 VRAM Address (15:8) + .label VERA_ADDRX_M = $9f21 + // $9F22 VRAM Address (7:0) + // Bit 4-7: Address Increment The following is the amount incremented per value value:increment + // 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640 + // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. + // Bit 0: VRAM Address (16) + .label VERA_ADDRX_H = $9f22 + // $9F23 DATA0 VRAM Data port 0 + .label VERA_DATA0 = $9f23 + // $9F25 CTRL Control + // Bit 7: Reset + // Bit 1: DCSEL + // Bit 2: ADDRSEL + .label VERA_CTRL = $9f25 +.segment Code + // main +main: { + // Address of the default screen + .label vaddr = 2 + // [1] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [1] phi main::vaddr#3 = (byte*) 0 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #<0 + sta.z vaddr + lda #>0 + sta.z vaddr+1 + // [1] phi main::i#2 = 0 [phi:main->main::@1#1] -- vbuyy=vbuc1 + ldy #0 + jmp __b1 + // main::@1 + __b1: + // [2] if(0!=main::MSG[main::i#2]) goto main::@2 -- 0_neq_pbuc1_derefidx_vbuyy_then_la1 + lda MSG,y + cmp #0 + bne __b2 + jmp __breturn + // main::@return + __breturn: + // [3] return + rts + // main::@2 + __b2: + // [4] vpoke::addr#0 = main::vaddr#3 + // [5] vpoke::data#0 = main::MSG[main::i#2] -- vbuxx=pbuc1_derefidx_vbuyy + ldx MSG,y + // [6] call vpoke + // [12] phi from main::@2 to vpoke [phi:main::@2->vpoke] + vpoke_from___b2: + // [12] phi vpoke::data#2 = vpoke::data#0 [phi:main::@2->vpoke#0] -- register_copy + // [12] phi vpoke::addr#2 = vpoke::addr#0 [phi:main::@2->vpoke#1] -- register_copy + jsr vpoke + jmp __b3 + // main::@3 + __b3: + // [7] main::vaddr#1 = ++ main::vaddr#3 -- pbuz1=_inc_pbuz1 + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // [8] vpoke::addr#1 = main::vaddr#1 + // [9] call vpoke + // Message + // [12] phi from main::@3 to vpoke [phi:main::@3->vpoke] + vpoke_from___b3: + // [12] phi vpoke::data#2 = $21 [phi:main::@3->vpoke#0] -- vbuxx=vbuc1 + ldx #$21 + // [12] phi vpoke::addr#2 = vpoke::addr#1 [phi:main::@3->vpoke#1] -- register_copy + jsr vpoke + jmp __b4 + // main::@4 + __b4: + // [10] main::vaddr#2 = ++ main::vaddr#1 -- pbuz1=_inc_pbuz1 + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // [11] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy + iny + // [1] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + __b1_from___b4: + // [1] phi main::vaddr#3 = main::vaddr#2 [phi:main::@4->main::@1#0] -- register_copy + // [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#1] -- register_copy + jmp __b1 + .segment Data + MSG: .text "hello world!" + .byte 0 +} +.segment Code + // vpoke +// Put a single byte into VRAM. +// Uses VERA DATA0 +// - bank: Which 64K VRAM bank to put data into (0/1) +// - addr: The address in VRAM +// - data: The data to put into VRAM +// vpoke(byte* zp(2) addr, byte register(X) data) +vpoke: { + .label addr = 2 + // [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // Select DATA0 + lda #VERA_ADDRSEL^$ff + and VERA_CTRL + sta VERA_CTRL + // [14] vpoke::$0 = < vpoke::addr#2 -- vbuaa=_lo_pbuz1 + lda.z addr + // [15] *VERA_ADDRX_L = vpoke::$0 -- _deref_pbuc1=vbuaa + // Set address + sta VERA_ADDRX_L + // [16] vpoke::$1 = > vpoke::addr#2 -- vbuaa=_hi_pbuz1 + lda.z addr+1 + // [17] *VERA_ADDRX_M = vpoke::$1 -- _deref_pbuc1=vbuaa + sta VERA_ADDRX_M + // [18] *VERA_ADDRX_H = 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta VERA_ADDRX_H + // [19] *VERA_DATA0 = vpoke::data#2 -- _deref_pbuc1=vbuxx + // Set data + stx VERA_DATA0 + jmp __breturn + // vpoke::@return + __breturn: + // [20] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Removing instruction jmp __b3 +Removing instruction jmp __b4 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda #>0 +Replacing instruction ldy #0 with TAY +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Removing instruction __b1_from_main: +Removing instruction __breturn: +Removing instruction vpoke_from___b2: +Removing instruction __b3: +Removing instruction vpoke_from___b3: +Removing instruction __b4: +Removing instruction __b1_from___b4: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +const nomodify byte VERA_ADDRSEL = 1 +const nomodify byte* VERA_ADDRX_H = (byte*) 40738 +const nomodify byte* VERA_ADDRX_L = (byte*) 40736 +const nomodify byte* VERA_ADDRX_M = (byte*) 40737 +const nomodify byte* VERA_CTRL = (byte*) 40741 +const nomodify byte* VERA_DATA0 = (byte*) 40739 +void main() +const byte* main::MSG[] = "hello world!" +byte main::i +byte main::i#1 reg byte y 22.0 +byte main::i#2 reg byte y 4.888888888888889 +byte* main::vaddr +byte* main::vaddr#1 vaddr zp[2]:2 11.0 +byte* main::vaddr#2 vaddr zp[2]:2 11.0 +byte* main::vaddr#3 vaddr zp[2]:2 6.6000000000000005 +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +byte~ vpoke::$0 reg byte a 202.0 +byte~ vpoke::$1 reg byte a 202.0 +byte* vpoke::addr +byte* vpoke::addr#0 addr zp[2]:2 11.0 +byte* vpoke::addr#1 addr zp[2]:2 22.0 +byte* vpoke::addr#2 addr zp[2]:2 56.0 +byte vpoke::bank +byte vpoke::data +byte vpoke::data#0 reg byte x 22.0 +byte vpoke::data#2 reg byte x 16.0 + +reg byte y [ main::i#2 main::i#1 ] +zp[2]:2 [ main::vaddr#3 main::vaddr#2 main::vaddr#1 vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] +reg byte x [ vpoke::data#2 vpoke::data#0 ] +reg byte a [ vpoke::$0 ] +reg byte a [ vpoke::$1 ] + + +FINAL ASSEMBLER +Score: 595 + + // File Comments +// Example program for the Commander X16 +// Displays text on the screen by transfering data to VERA + // Upstart +.cpu _65c02 + // Commodore 64 PRG executable file +.file [name="text.prg", type="prg", segments="Program"] +.segmentdef Program [segments="Basic, Code, Data"] +.segmentdef Basic [start=$0801] +.segmentdef Code [start=$80d] +.segmentdef Data [startAfter="Code"] +.segment Basic +:BasicUpstart(main) +.segment Code + + + // Global Constants & labels + .const VERA_ADDRSEL = 1 + // $9F20 VRAM Address (7:0) + .label VERA_ADDRX_L = $9f20 + // $9F21 VRAM Address (15:8) + .label VERA_ADDRX_M = $9f21 + // $9F22 VRAM Address (7:0) + // Bit 4-7: Address Increment The following is the amount incremented per value value:increment + // 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640 + // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. + // Bit 0: VRAM Address (16) + .label VERA_ADDRX_H = $9f22 + // $9F23 DATA0 VRAM Data port 0 + .label VERA_DATA0 = $9f23 + // $9F25 CTRL Control + // Bit 7: Reset + // Bit 1: DCSEL + // Bit 2: ADDRSEL + .label VERA_CTRL = $9f25 +.segment Code + // main +main: { + // Address of the default screen + .label vaddr = 2 + // [1] phi from main to main::@1 [phi:main->main::@1] + // [1] phi main::vaddr#3 = (byte*) 0 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #<0 + sta.z vaddr + sta.z vaddr+1 + // [1] phi main::i#2 = 0 [phi:main->main::@1#1] -- vbuyy=vbuc1 + tay + // main::@1 + __b1: + // for(char i=0;MSG[i];i++) + // [2] if(0!=main::MSG[main::i#2]) goto main::@2 -- 0_neq_pbuc1_derefidx_vbuyy_then_la1 + lda MSG,y + cmp #0 + bne __b2 + // main::@return + // } + // [3] return + rts + // main::@2 + __b2: + // vpoke(0, vaddr++, MSG[i]) + // [4] vpoke::addr#0 = main::vaddr#3 + // [5] vpoke::data#0 = main::MSG[main::i#2] -- vbuxx=pbuc1_derefidx_vbuyy + ldx MSG,y + // [6] call vpoke + // [12] phi from main::@2 to vpoke [phi:main::@2->vpoke] + // [12] phi vpoke::data#2 = vpoke::data#0 [phi:main::@2->vpoke#0] -- register_copy + // [12] phi vpoke::addr#2 = vpoke::addr#0 [phi:main::@2->vpoke#1] -- register_copy + jsr vpoke + // main::@3 + // vpoke(0, vaddr++, MSG[i]); + // [7] main::vaddr#1 = ++ main::vaddr#3 -- pbuz1=_inc_pbuz1 + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // vpoke(0, vaddr++, 0x21) + // [8] vpoke::addr#1 = main::vaddr#1 + // [9] call vpoke + // Message + // [12] phi from main::@3 to vpoke [phi:main::@3->vpoke] + // [12] phi vpoke::data#2 = $21 [phi:main::@3->vpoke#0] -- vbuxx=vbuc1 + ldx #$21 + // [12] phi vpoke::addr#2 = vpoke::addr#1 [phi:main::@3->vpoke#1] -- register_copy + jsr vpoke + // main::@4 + // vpoke(0, vaddr++, 0x21); + // [10] main::vaddr#2 = ++ main::vaddr#1 -- pbuz1=_inc_pbuz1 + inc.z vaddr + bne !+ + inc.z vaddr+1 + !: + // for(char i=0;MSG[i];i++) + // [11] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy + iny + // [1] phi from main::@4 to main::@1 [phi:main::@4->main::@1] + // [1] phi main::vaddr#3 = main::vaddr#2 [phi:main::@4->main::@1#0] -- register_copy + // [1] phi main::i#2 = main::i#1 [phi:main::@4->main::@1#1] -- register_copy + jmp __b1 + .segment Data + MSG: .text "hello world!" + .byte 0 +} +.segment Code + // vpoke +// Put a single byte into VRAM. +// Uses VERA DATA0 +// - bank: Which 64K VRAM bank to put data into (0/1) +// - addr: The address in VRAM +// - data: The data to put into VRAM +// vpoke(byte* zp(2) addr, byte register(X) data) +vpoke: { + .label addr = 2 + // *VERA_CTRL &= ~VERA_ADDRSEL + // [13] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // Select DATA0 + lda #VERA_ADDRSEL^$ff + and VERA_CTRL + sta VERA_CTRL + // addr + // [16] vpoke::$1 = > vpoke::addr#2 -- vbuaa=_hi_pbuz1 + lda.z addr+1 + // *VERA_ADDRX_M = >addr + // [17] *VERA_ADDRX_M = vpoke::$1 -- _deref_pbuc1=vbuaa + sta VERA_ADDRX_M + // *VERA_ADDRX_H = VERA_INC_0 | bank + // [18] *VERA_ADDRX_H = 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta VERA_ADDRX_H + // *VERA_DATA0 = data + // [19] *VERA_DATA0 = vpoke::data#2 -- _deref_pbuc1=vbuxx + // Set data + stx VERA_DATA0 + // vpoke::@return + // } + // [20] return + rts +} + // File Data + diff --git a/src/test/ref/examples/cx16/text.sym b/src/test/ref/examples/cx16/text.sym new file mode 100644 index 000000000..9a80f9940 --- /dev/null +++ b/src/test/ref/examples/cx16/text.sym @@ -0,0 +1,32 @@ +const nomodify byte VERA_ADDRSEL = 1 +const nomodify byte* VERA_ADDRX_H = (byte*) 40738 +const nomodify byte* VERA_ADDRX_L = (byte*) 40736 +const nomodify byte* VERA_ADDRX_M = (byte*) 40737 +const nomodify byte* VERA_CTRL = (byte*) 40741 +const nomodify byte* VERA_DATA0 = (byte*) 40739 +void main() +const byte* main::MSG[] = "hello world!" +byte main::i +byte main::i#1 reg byte y 22.0 +byte main::i#2 reg byte y 4.888888888888889 +byte* main::vaddr +byte* main::vaddr#1 vaddr zp[2]:2 11.0 +byte* main::vaddr#2 vaddr zp[2]:2 11.0 +byte* main::vaddr#3 vaddr zp[2]:2 6.6000000000000005 +void vpoke(byte vpoke::bank , byte* vpoke::addr , byte vpoke::data) +byte~ vpoke::$0 reg byte a 202.0 +byte~ vpoke::$1 reg byte a 202.0 +byte* vpoke::addr +byte* vpoke::addr#0 addr zp[2]:2 11.0 +byte* vpoke::addr#1 addr zp[2]:2 22.0 +byte* vpoke::addr#2 addr zp[2]:2 56.0 +byte vpoke::bank +byte vpoke::data +byte vpoke::data#0 reg byte x 22.0 +byte vpoke::data#2 reg byte x 16.0 + +reg byte y [ main::i#2 main::i#1 ] +zp[2]:2 [ main::vaddr#3 main::vaddr#2 main::vaddr#1 vpoke::addr#2 vpoke::addr#0 vpoke::addr#1 ] +reg byte x [ vpoke::data#2 vpoke::data#0 ] +reg byte a [ vpoke::$0 ] +reg byte a [ vpoke::$1 ]