From e6962d38ac54fade7f8718a4bcdd6f36568e2ff3 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Thu, 17 Dec 2020 23:23:46 +0100 Subject: [PATCH] CX16 sprite example is now a 256-color 64*64 TUT sprite. #581 --- src/main/kc/include/cx16-vera.h | 9 +- .../dk/camelot64/kickc/test/TestPrograms.java | 4 +- src/test/kc/examples/cx16/sprite.png | Bin 650 -> 0 bytes .../kc/examples/cx16/{sprite.c => sprites.c} | 81 +- src/test/kc/examples/cx16/tut.png | Bin 0 -> 17616 bytes .../examples/cx16/{sprite.asm => sprites.asm} | 123 +- .../examples/cx16/{sprite.cfg => sprites.cfg} | 94 +- .../examples/cx16/{sprite.log => sprites.log} | 1146 ++++++++++------- .../examples/cx16/{sprite.sym => sprites.sym} | 63 +- 9 files changed, 908 insertions(+), 612 deletions(-) delete mode 100644 src/test/kc/examples/cx16/sprite.png rename src/test/kc/examples/cx16/{sprite.c => sprites.c} (54%) create mode 100644 src/test/kc/examples/cx16/tut.png rename src/test/ref/examples/cx16/{sprite.asm => sprites.asm} (82%) rename src/test/ref/examples/cx16/{sprite.cfg => sprites.cfg} (60%) rename src/test/ref/examples/cx16/{sprite.log => sprites.log} (66%) rename src/test/ref/examples/cx16/{sprite.sym => sprites.sym} (68%) diff --git a/src/main/kc/include/cx16-vera.h b/src/main/kc/include/cx16-vera.h index 9b7021115..696ae090d 100644 --- a/src/main/kc/include/cx16-vera.h +++ b/src/main/kc/include/cx16-vera.h @@ -165,7 +165,14 @@ char * const VERA_SPI_DATA = 0x9f3e; // Bit 0: Select char * const VERA_SPI_CTRL = 0x9f3f; -// Sprite Attributes address in VERA VRAM +// VERA Palette address in VRAM $1FA00 - $1FBFF +// 256 entries of 2 bytes +// byte 0 bits 4-7: Green +// byte 0 bits 0-3: Blue +// byte 1 bits 0-3: Red +const unsigned long VERA_PALETTE = 0x1fa00; + +// Sprite Attributes address in VERA VRAM $1FC00 - $1FFFF const unsigned long VERA_SPRITE_ATTR = 0x1fc00; // The VERA structure of a sprite (8 bytes) diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 218950f1c..95e612650 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -464,8 +464,8 @@ public class TestPrograms { } @Test - public void testCx16Sprite() throws IOException, URISyntaxException { - compileAndCompare("examples/cx16/sprite.c"); + public void testCx16Sprites() throws IOException, URISyntaxException { + compileAndCompare("examples/cx16/sprites.c"); } @Test diff --git a/src/test/kc/examples/cx16/sprite.png b/src/test/kc/examples/cx16/sprite.png deleted file mode 100644 index 23f586478f2b06ee5e0e251271e489661bfc7335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|EK(yp(|mmy zw18|52FCVG1{RPKAeI7R1_q`DOmGp01 z-uk`Y=&_cpktU;h*)CPTCD#Hx-u$jfeBHn9^roEOueFnJm#n;2`q#_WLe*L|$6aoxi*wv}InH+HeXzfK`GX)1 zErz`v>l;6CEHMALR3MM>i`G6CCozZjkG2YIV%Txu#Ydq78h6t_zx!uY!yw`NN4SNb zVUB?6JcgcIwPv5QwC6BG{-(2o`TV{Qd@~r7qT;jW@l7yMlJjSGd9&+^jjTeZi%s3he7A`VAEZCrVVbzB zZfU6%L&zdq_8tEh)><)$DD@v^4BXbZ#a^nOq2pDPaKpve31#(G53;y>UNxc zdt<(wd(76ry4hjQV|mT~i%GuMp7J$tE1x=4xQ;c*n%~mPJ(wZWaOH+CR_C`asMxRi Zk7;Ar=cHU$HV;sm@O1TaS?83{1OQEN00#g7 diff --git a/src/test/kc/examples/cx16/sprite.c b/src/test/kc/examples/cx16/sprites.c similarity index 54% rename from src/test/kc/examples/cx16/sprite.c rename to src/test/kc/examples/cx16/sprites.c index fae41380f..b1daf920c 100644 --- a/src/test/kc/examples/cx16/sprite.c +++ b/src/test/kc/examples/cx16/sprites.c @@ -1,19 +1,47 @@ // Example program for the Commander X16 -// Displays some sprites - exceeding the per-line limits of the CX16 +// Displays 32 64*64 TUT sprites #pragma target(cx16) #include #include <6502.h> -// A 64*64 8bpp sprite -align(0x100) char SPRITE_PIXELS[64*64] = kickasm(resource "sprite.png") {{ - .var pic = LoadPicture("sprite.png", List().add($000000, $ffffff)) - .for (var x=0;x<64; x++) - .for (var y=0; y<64; y++) - .byte (pic.getPixel(x,y)==0) ? 0 : 1 -}}; +#define NUM_SPRITES 32 -#define NUM_SPRITES 128 +// A 64*64 8bpp TUT sprite +align(0x1200) char SPRITE_PIXELS[64*64] = kickasm(resource "tut.png") {{ + .var pic = LoadPicture("tut.png") + // palette: rgb->idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + +}}; // Address to use for sprite pixels in VRAM const unsigned long SPRITE_PIXELS_VRAM = 0x08000; @@ -24,6 +52,8 @@ struct VERA_SPRITE SPRITE_ATTR = { <(SPRITE_PIXELS_VRAM/32)|VERA_SPRITE_8BPP, 32 void main() { // Copy sprite data to VRAM memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, VERA_PALETTE, VERA_SPRITE_ATTR, vram_sprite_attr, &SPRITE_ATTR, sizeof(SPRITE_ATTR)); vram_sprite_attr += sizeof(SPRITE_ATTR); - } - // Make a border - //*VERA_CTRL |= VERA_DCSEL; - //*VERA_DC_HSTART = 16/4; - //*VERA_DC_HSTOP = 624/4; - //*VERA_DC_VSTART = 16/2; - //*VERA_DC_VSTOP = 464/2; + } // Enable sprites *VERA_CTRL &= ~VERA_DCSEL; *VERA_DC_VIDEO |= VERA_SPRITES_ENABLE; @@ -49,13 +73,15 @@ void main() { } // X sine [0;640-64] -align(0x100) unsigned int SINX[241] = kickasm {{ - .fillword 256, 288+288*sin(i*2*PI/241) +const char SINX_LEN = 241; +align(0x100) unsigned int SINX[SINX_LEN] = kickasm {{ + .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) }}; // Y sine [0;480-64] -align(0x100) unsigned int SINY[251] = kickasm {{ - .fillword 256, 208+208*sin(i*2*PI/251) +const char SINY_LEN = 251; +align(0x100) unsigned int SINY[SINY_LEN] = kickasm {{ + .fillword 256, 208+208*sin(i*2*PI/SINY_LEN) }}; // X sine index @@ -65,12 +91,9 @@ volatile unsigned int sin_idx_y = 79; // VSYNC Interrupt Routine void irq_vsync() { - // Color border - //*VERA_CTRL &= ~VERA_DCSEL; - //*VERA_DC_BORDER = 2; // Move the sprite around - if(++sin_idx_x==241) sin_idx_x = 0; - if(--sin_idx_y==0xffff) sin_idx_y = 251-1; + if(++sin_idx_x==SINX_LEN) sin_idx_x = 0; + if(--sin_idx_y==0xffff) sin_idx_y = SINY_LEN-1; const char vram_sprite_attr_bank = (char)>VERA_SPRITE_ATTR; char *vram_sprite_pos = =241) i_x -= 241; - i_y += 5; if(i_y>=251) i_y -= 251; + i_x += 9; if(i_x>=SINX_LEN) i_x -= SINX_LEN; + i_y += 5; if(i_y>=SINY_LEN) i_y -= SINY_LEN; } - // Black border - //*VERA_CTRL &= ~VERA_DCSEL; - //*VERA_DC_BORDER = 0; + // Reset the VSYNC interrupt *VERA_ISR = VERA_VSYNC; // Exit CX16 KERNAL IRQ diff --git a/src/test/kc/examples/cx16/tut.png b/src/test/kc/examples/cx16/tut.png new file mode 100644 index 0000000000000000000000000000000000000000..b660fc4b836edbd24cb26626a507327f264efe51 GIT binary patch literal 17616 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 UXkhwhIRYRqEF)AUpcn9e0Qgb(6aWAK literal 0 HcmV?d00001 diff --git a/src/test/ref/examples/cx16/sprite.asm b/src/test/ref/examples/cx16/sprites.asm similarity index 82% rename from src/test/ref/examples/cx16/sprite.asm rename to src/test/ref/examples/cx16/sprites.asm index 526236607..78c06a237 100644 --- a/src/test/ref/examples/cx16/sprite.asm +++ b/src/test/ref/examples/cx16/sprites.asm @@ -1,8 +1,8 @@ // Example program for the Commander X16 -// Displays some sprites - exceeding the per-line limits of the CX16 +// Displays 32 64*64 TUT sprites .cpu _65c02 // Commodore 64 PRG executable file -.file [name="sprite.prg", type="prg", segments="Program"] +.file [name="sprites.prg", type="prg", segments="Program"] .segmentdef Program [segments="Basic, Code, Data"] .segmentdef Basic [start=$0801] .segmentdef Code [start=$80d] @@ -16,12 +16,22 @@ .const VERA_DCSEL = 2 .const VERA_ADDRSEL = 1 .const VERA_VSYNC = 1 - // Sprite Attributes address in VERA VRAM + // VERA Palette address in VRAM $1FA00 - $1FBFF + // 256 entries of 2 bytes + // byte 0 bits 4-7: Green + // byte 0 bits 0-3: Blue + // byte 1 bits 0-3: Red + .const VERA_PALETTE = $1fa00 + // Sprite Attributes address in VERA VRAM $1FC00 - $1FFFF .const VERA_SPRITE_ATTR = $1fc00 // 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable) .const VERA_SPRITE_8BPP = $8000 // Address to use for sprite pixels in VRAM .const SPRITE_PIXELS_VRAM = $8000 + // X sine [0;640-64] + .const SINX_LEN = $f1 + // Y sine [0;480-64] + .const SINY_LEN = $fb .const SIZEOF_STRUCT_VERA_SPRITE = 8 .const OFFSET_STRUCT_VERA_SPRITE_X = 2 .const OFFSET_STRUCT_VERA_SPRITE_Y = 4 @@ -100,16 +110,16 @@ irq_vsync: { .label s = 2 .label __13 = $16 .label __14 = $18 - // if(++sin_idx_x==241) + // if(++sin_idx_x==SINX_LEN) inc.z sin_idx_x bne !+ inc.z sin_idx_x+1 !: lda.z sin_idx_x+1 - cmp #>$f1 + cmp #>SINX_LEN bne __b1 lda.z sin_idx_x - cmp #<$f1 + cmp #$fb-1 + lda #>SINY_LEN-1 sta.z sin_idx_y+1 __b2: // i_x = sin_idx_x @@ -153,12 +163,9 @@ irq_vsync: { __b5: // for(char s=0;s=241) + // if(i_x>=SINX_LEN) lda.z i_x+1 bne !+ lda.z i_x - cmp #$f1 + cmp #SINX_LEN bcc __b8 !: - // i_x -= 241 + // i_x -= SINX_LEN sec lda.z i_x - sbc #$f1 + sbc #SINX_LEN sta.z i_x lda.z i_x+1 sbc #0 @@ -263,17 +270,17 @@ irq_vsync: { bcc !+ inc.z i_y+1 !: - // if(i_y>=251) + // if(i_y>=SINY_LEN) lda.z i_y+1 bne !+ lda.z i_y - cmp #$fb + cmp #SINY_LEN bcc __b9 !: - // i_y -= 251 + // i_y -= SINY_LEN sec lda.z i_y - sbc #$fb + sbc #SINY_LEN sta.z i_y lda.z i_y+1 sbc #0 @@ -303,6 +310,22 @@ main: { lda #>SPRITE_PIXELS_VRAM&$ffff sta.z memcpy_to_vram.vdest+1 jsr memcpy_to_vram + // memcpy_to_vram((char)>VERA_PALETTE, $200 + sta.z memcpy_to_vram.num+1 + lda #SPRITE_PIXELS+$40*$40 + sta.z memcpy_to_vram.src+1 + ldx #VERA_PALETTE>>$10 + lda #VERA_PALETTE&$ffff + sta.z memcpy_to_vram.vdest+1 + jsr memcpy_to_vram lda #VERA_SPRITE_ATTR&$ffff @@ -312,15 +335,9 @@ main: { __b1: // for(char s=0;sidx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + - // X sine [0;640-64] .align $100 SINX: -.fillword 256, 288+288*sin(i*2*PI/241) +.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - // Y sine [0;480-64] .align $100 SINY: -.fillword 256, 208+208*sin(i*2*PI/251) +.fillword 256, 208+208*sin(i*2*PI/SINY_LEN) // Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM SPRITE_ATTR: .word (SPRITE_PIXELS_VRAM/$20&$ffff)|VERA_SPRITE_8BPP, $140-$20, $f0-$20 diff --git a/src/test/ref/examples/cx16/sprite.cfg b/src/test/ref/examples/cx16/sprites.cfg similarity index 60% rename from src/test/ref/examples/cx16/sprite.cfg rename to src/test/ref/examples/cx16/sprites.cfg index 8f74e5a61..dbdc6a46f 100644 --- a/src/test/ref/examples/cx16/sprite.cfg +++ b/src/test/ref/examples/cx16/sprites.cfg @@ -18,7 +18,7 @@ __start::@return: scope:[__start] from __start::@1 void irq_vsync() irq_vsync: scope:[irq_vsync] from [6] sin_idx_x = ++ sin_idx_x - [7] if(sin_idx_x!=$f1) goto irq_vsync::@1 + [7] if(sin_idx_x!=SINX_LEN) goto irq_vsync::@1 to:irq_vsync::@3 irq_vsync::@3: scope:[irq_vsync] from irq_vsync [8] sin_idx_x = 0 @@ -28,7 +28,7 @@ irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3 [10] if(sin_idx_y!=$ffff) goto irq_vsync::@2 to:irq_vsync::@4 irq_vsync::@4: scope:[irq_vsync] from irq_vsync::@1 - [11] sin_idx_y = $fb-1 + [11] sin_idx_y = SINY_LEN-1 to:irq_vsync::@2 irq_vsync::@2: scope:[irq_vsync] from irq_vsync::@1 irq_vsync::@4 [12] irq_vsync::i_x#0 = sin_idx_x @@ -39,7 +39,7 @@ irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2 irq_vsync::@9 [14] irq_vsync::i_y#3 = phi( irq_vsync::@2/irq_vsync::i_y#0, irq_vsync::@9/irq_vsync::i_y#9 ) [14] irq_vsync::i_x#3 = phi( irq_vsync::@2/irq_vsync::i_x#0, irq_vsync::@9/irq_vsync::i_x#7 ) [14] irq_vsync::s#2 = phi( irq_vsync::@2/0, irq_vsync::@9/irq_vsync::s#1 ) - [15] if(irq_vsync::s#2<$80) goto irq_vsync::@6 + [15] if(irq_vsync::s#2<$20) goto irq_vsync::@6 to:irq_vsync::@7 irq_vsync::@7: scope:[irq_vsync] from irq_vsync::@5 [16] *VERA_ISR = VERA_VSYNC @@ -55,24 +55,24 @@ irq_vsync::@6: scope:[irq_vsync] from irq_vsync::@5 [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 [23] irq_vsync::$14 = SINY + irq_vsync::$12 [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 - [25] memcpy_to_vram::vdest#2 = (void*)irq_vsync::vram_sprite_pos#2 + [25] memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2 [26] call memcpy_to_vram to:irq_vsync::@12 irq_vsync::@12: scope:[irq_vsync] from irq_vsync::@6 [27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE - [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 3 - [29] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 + [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 9 + [29] if(irq_vsync::i_x#1VERA_SPRITE_ATTR ) - [54] memcpy_to_vram::vdest#3 = phi( irq_vsync::@6/memcpy_to_vram::vdest#2, main/(void*) memcpy_to_vram::vdest#3 - [59] *VERA_ADDRX_M = memcpy_to_vram::$1 - [60] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3 - [61] *VERA_ADDRX_H = memcpy_to_vram::$2 - [62] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#3 + memcpy_to_vram::num#3 - [63] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#3 +memcpy_to_vram: scope:[memcpy_to_vram] from irq_vsync::@6 main main::@2 main::@5 + [56] memcpy_to_vram::num#4 = phi( irq_vsync::@6/4, main/(word)$40*$40*SIZEOF_BYTE, main::@2/SIZEOF_STRUCT_VERA_SPRITE, main::@5/$200 ) + [56] memcpy_to_vram::src#4 = phi( irq_vsync::@6/(void*)&SPRITE_ATTR+2, main/(void*)SPRITE_PIXELS, main::@2/(void*)&SPRITE_ATTR, main::@5/(void*)SPRITE_PIXELS+(word)$40*$40 ) + [56] memcpy_to_vram::vbank#4 = phi( irq_vsync::@6/irq_vsync::vram_sprite_attr_bank, main/0, main::@2/(byte)>VERA_SPRITE_ATTR, main::@5/(byte)>VERA_PALETTE ) + [56] memcpy_to_vram::vdest#4 = phi( irq_vsync::@6/memcpy_to_vram::vdest#3, main/(void*) memcpy_to_vram::vdest#4 + [61] *VERA_ADDRX_M = memcpy_to_vram::$1 + [62] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 + [63] *VERA_ADDRX_H = memcpy_to_vram::$2 + [64] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#4 + memcpy_to_vram::num#4 + [65] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#4 to:memcpy_to_vram::@1 memcpy_to_vram::@1: scope:[memcpy_to_vram] from memcpy_to_vram memcpy_to_vram::@2 - [64] memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#4, memcpy_to_vram::@2/memcpy_to_vram::s#1 ) - [65] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 + [66] memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#4, memcpy_to_vram::@2/memcpy_to_vram::s#1 ) + [67] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 to:memcpy_to_vram::@return memcpy_to_vram::@return: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [66] return + [68] return to:@return memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [67] *VERA_DATA0 = *memcpy_to_vram::s#2 - [68] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 + [69] *VERA_DATA0 = *memcpy_to_vram::s#2 + [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 to:memcpy_to_vram::@1 diff --git a/src/test/ref/examples/cx16/sprite.log b/src/test/ref/examples/cx16/sprites.log similarity index 66% rename from src/test/ref/examples/cx16/sprite.log rename to src/test/ref/examples/cx16/sprites.log index e649d6b1c..f87d1e627 100644 --- a/src/test/ref/examples/cx16/sprite.log +++ b/src/test/ref/examples/cx16/sprites.log @@ -1,8 +1,8 @@ Resolved forward reference irq_vsync to void irq_vsync() -Setting struct to load/store in variable affected by address-of main::$6 = call memcpy_to_vram (byte)>VERA_SPRITE_ATTR main::vram_sprite_attr &SPRITE_ATTR main::$5 +Setting struct to load/store in variable affected by address-of main::$7 = call memcpy_to_vram (byte)>VERA_SPRITE_ATTR main::vram_sprite_attr &SPRITE_ATTR main::$6 Setting struct to load/store in variable affected by address-of irq_vsync::$5 = call memcpy_to_vram irq_vsync::vram_sprite_attr_bank irq_vsync::vram_sprite_pos &SPRITE_ATTR+2 4 -Resolving sizeof() main::$5 = sizeof SPRITE_ATTR -Resolving sizeof() main::$7 = sizeof SPRITE_ATTR +Resolving sizeof() main::$6 = sizeof SPRITE_ATTR +Resolving sizeof() main::$8 = sizeof SPRITE_ATTR Resolving sizeof() irq_vsync::$6 = sizeof SPRITE_ATTR Inlined call call SEI Inlined call call CLI @@ -11,22 +11,22 @@ Inlined call call __init CONTROL FLOW GRAPH SSA void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num) -memcpy_to_vram: scope:[memcpy_to_vram] from irq_vsync::@6 main main::@2 - memcpy_to_vram::num#3 = phi( irq_vsync::@6/memcpy_to_vram::num#2, main/memcpy_to_vram::num#0, main::@2/memcpy_to_vram::num#1 ) - memcpy_to_vram::src#3 = phi( irq_vsync::@6/memcpy_to_vram::src#2, main/memcpy_to_vram::src#0, main::@2/memcpy_to_vram::src#1 ) - memcpy_to_vram::vbank#3 = phi( irq_vsync::@6/memcpy_to_vram::vbank#2, main/memcpy_to_vram::vbank#0, main::@2/memcpy_to_vram::vbank#1 ) - memcpy_to_vram::vdest#3 = phi( irq_vsync::@6/memcpy_to_vram::vdest#2, main/memcpy_to_vram::vdest#0, main::@2/memcpy_to_vram::vdest#1 ) +memcpy_to_vram: scope:[memcpy_to_vram] from irq_vsync::@6 main main::@2 main::@5 + memcpy_to_vram::num#4 = phi( irq_vsync::@6/memcpy_to_vram::num#3, main/memcpy_to_vram::num#0, main::@2/memcpy_to_vram::num#2, main::@5/memcpy_to_vram::num#1 ) + memcpy_to_vram::src#4 = phi( irq_vsync::@6/memcpy_to_vram::src#3, main/memcpy_to_vram::src#0, main::@2/memcpy_to_vram::src#2, main::@5/memcpy_to_vram::src#1 ) + memcpy_to_vram::vbank#4 = phi( irq_vsync::@6/memcpy_to_vram::vbank#3, main/memcpy_to_vram::vbank#0, main::@2/memcpy_to_vram::vbank#2, main::@5/memcpy_to_vram::vbank#1 ) + memcpy_to_vram::vdest#4 = phi( irq_vsync::@6/memcpy_to_vram::vdest#3, main/memcpy_to_vram::vdest#0, main::@2/memcpy_to_vram::vdest#2, main::@5/memcpy_to_vram::vdest#1 ) *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL - memcpy_to_vram::$0 = < memcpy_to_vram::vdest#3 + memcpy_to_vram::$0 = < memcpy_to_vram::vdest#4 *VERA_ADDRX_L = memcpy_to_vram::$0 - memcpy_to_vram::$1 = > memcpy_to_vram::vdest#3 + memcpy_to_vram::$1 = > memcpy_to_vram::vdest#4 *VERA_ADDRX_M = memcpy_to_vram::$1 - memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3 + memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 *VERA_ADDRX_H = memcpy_to_vram::$2 - memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#3 - memcpy_to_vram::$3 = memcpy_to_vram::$5 + memcpy_to_vram::num#3 + memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#4 + memcpy_to_vram::$3 = memcpy_to_vram::$5 + memcpy_to_vram::num#4 memcpy_to_vram::end#0 = memcpy_to_vram::$3 - memcpy_to_vram::s#0 = ((byte*)) memcpy_to_vram::src#3 + memcpy_to_vram::s#0 = ((byte*)) memcpy_to_vram::src#4 to:memcpy_to_vram::@1 memcpy_to_vram::@1: scope:[memcpy_to_vram] from memcpy_to_vram memcpy_to_vram::@2 memcpy_to_vram::end#1 = phi( memcpy_to_vram/memcpy_to_vram::end#0, memcpy_to_vram::@2/memcpy_to_vram::end#2 ) @@ -54,32 +54,39 @@ main: scope:[main] from __start::@1 call memcpy_to_vram to:main::@5 main::@5: scope:[main] from main + memcpy_to_vram::vbank#1 = (byte)>VERA_PALETTE + memcpy_to_vram::vdest#1 = (void*)VERA_SPRITE_ATTR - memcpy_to_vram::vdest#1 = (void*)main::vram_sprite_attr#2 - memcpy_to_vram::src#1 = (void*)&SPRITE_ATTR - memcpy_to_vram::num#1 = main::$5 + main::$6 = SIZEOF_STRUCT_VERA_SPRITE + memcpy_to_vram::vbank#2 = (byte)>VERA_SPRITE_ATTR + memcpy_to_vram::vdest#2 = (void*)main::vram_sprite_attr#2 + memcpy_to_vram::src#2 = (void*)&SPRITE_ATTR + memcpy_to_vram::num#2 = main::$6 call memcpy_to_vram - to:main::@6 -main::@6: scope:[main] from main::@2 + to:main::@7 +main::@7: scope:[main] from main::@2 main::s#3 = phi( main::@2/main::s#4 ) main::vram_sprite_attr#3 = phi( main::@2/main::vram_sprite_attr#2 ) - main::$7 = SIZEOF_STRUCT_VERA_SPRITE - main::vram_sprite_attr#1 = main::vram_sprite_attr#3 + main::$7 + main::$8 = SIZEOF_STRUCT_VERA_SPRITE + main::vram_sprite_attr#1 = main::vram_sprite_attr#3 + main::$8 main::s#1 = ++ main::s#3 to:main::@1 main::@3: scope:[main] from main::@1 @@ -103,7 +110,7 @@ main::@return: scope:[main] from main::CLI1 void irq_vsync() irq_vsync: scope:[irq_vsync] from sin_idx_x = ++ sin_idx_x - irq_vsync::$0 = sin_idx_x == $f1 + irq_vsync::$0 = sin_idx_x == SINX_LEN irq_vsync::$1 = ! irq_vsync::$0 if(irq_vsync::$1) goto irq_vsync::@1 to:irq_vsync::@3 @@ -123,14 +130,14 @@ irq_vsync::@2: scope:[irq_vsync] from irq_vsync::@1 irq_vsync::@4 irq_vsync::s#0 = 0 to:irq_vsync::@5 irq_vsync::@4: scope:[irq_vsync] from irq_vsync::@1 - sin_idx_y = $fb-1 + sin_idx_y = SINY_LEN-1 to:irq_vsync::@2 irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2 irq_vsync::@9 irq_vsync::vram_sprite_pos#4 = phi( irq_vsync::@2/irq_vsync::vram_sprite_pos#0, irq_vsync::@9/irq_vsync::vram_sprite_pos#5 ) irq_vsync::i_y#6 = phi( irq_vsync::@2/irq_vsync::i_y#0, irq_vsync::@9/irq_vsync::i_y#9 ) irq_vsync::i_x#6 = phi( irq_vsync::@2/irq_vsync::i_x#0, irq_vsync::@9/irq_vsync::i_x#7 ) irq_vsync::s#2 = phi( irq_vsync::@2/irq_vsync::s#0, irq_vsync::@9/irq_vsync::s#1 ) - irq_vsync::$4 = irq_vsync::s#2 < $80 + irq_vsync::$4 = irq_vsync::s#2 < $20 if(irq_vsync::$4) goto irq_vsync::@6 to:irq_vsync::@7 irq_vsync::@6: scope:[irq_vsync] from irq_vsync::@5 @@ -142,10 +149,10 @@ irq_vsync::@6: scope:[irq_vsync] from irq_vsync::@5 *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = SINX[irq_vsync::$11] irq_vsync::$12 = irq_vsync::i_y#3 * SIZEOF_WORD *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = SINY[irq_vsync::$12] - memcpy_to_vram::vbank#2 = irq_vsync::vram_sprite_attr_bank - memcpy_to_vram::vdest#2 = (void*)irq_vsync::vram_sprite_pos#2 - memcpy_to_vram::src#2 = (void*)&SPRITE_ATTR+2 - memcpy_to_vram::num#2 = 4 + memcpy_to_vram::vbank#3 = irq_vsync::vram_sprite_attr_bank + memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2 + memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR+2 + memcpy_to_vram::num#3 = 4 call memcpy_to_vram to:irq_vsync::@12 irq_vsync::@12: scope:[irq_vsync] from irq_vsync::@6 @@ -155,8 +162,8 @@ irq_vsync::@12: scope:[irq_vsync] from irq_vsync::@6 irq_vsync::vram_sprite_pos#3 = phi( irq_vsync::@6/irq_vsync::vram_sprite_pos#2 ) irq_vsync::$6 = SIZEOF_STRUCT_VERA_SPRITE irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#3 + irq_vsync::$6 - irq_vsync::i_x#1 = irq_vsync::i_x#4 + 3 - irq_vsync::$7 = irq_vsync::i_x#1 >= $f1 + irq_vsync::i_x#1 = irq_vsync::i_x#4 + 9 + irq_vsync::$7 = irq_vsync::i_x#1 >= SINX_LEN irq_vsync::$8 = ! irq_vsync::$7 if(irq_vsync::$8) goto irq_vsync::@8 to:irq_vsync::@10 @@ -170,7 +177,7 @@ irq_vsync::@8: scope:[irq_vsync] from irq_vsync::@10 irq_vsync::@12 irq_vsync::s#5 = phi( irq_vsync::@10/irq_vsync::s#6, irq_vsync::@12/irq_vsync::s#7 ) irq_vsync::i_y#4 = phi( irq_vsync::@10/irq_vsync::i_y#7, irq_vsync::@12/irq_vsync::i_y#8 ) irq_vsync::i_y#1 = irq_vsync::i_y#4 + 5 - irq_vsync::$9 = irq_vsync::i_y#1 >= $fb + irq_vsync::$9 = irq_vsync::i_y#1 >= SINY_LEN irq_vsync::$10 = ! irq_vsync::$9 if(irq_vsync::$10) goto irq_vsync::@9 to:irq_vsync::@11 @@ -179,7 +186,7 @@ irq_vsync::@10: scope:[irq_vsync] from irq_vsync::@12 irq_vsync::s#6 = phi( irq_vsync::@12/irq_vsync::s#7 ) irq_vsync::i_y#7 = phi( irq_vsync::@12/irq_vsync::i_y#8 ) irq_vsync::i_x#5 = phi( irq_vsync::@12/irq_vsync::i_x#1 ) - irq_vsync::i_x#2 = irq_vsync::i_x#5 - $f1 + irq_vsync::i_x#2 = irq_vsync::i_x#5 - SINX_LEN to:irq_vsync::@8 irq_vsync::@9: scope:[irq_vsync] from irq_vsync::@11 irq_vsync::@8 irq_vsync::vram_sprite_pos#5 = phi( irq_vsync::@11/irq_vsync::vram_sprite_pos#6, irq_vsync::@8/irq_vsync::vram_sprite_pos#7 ) @@ -193,7 +200,7 @@ irq_vsync::@11: scope:[irq_vsync] from irq_vsync::@8 irq_vsync::i_x#8 = phi( irq_vsync::@8/irq_vsync::i_x#9 ) irq_vsync::s#4 = phi( irq_vsync::@8/irq_vsync::s#5 ) irq_vsync::i_y#5 = phi( irq_vsync::@8/irq_vsync::i_y#1 ) - irq_vsync::i_y#2 = irq_vsync::i_y#5 - $fb + irq_vsync::i_y#2 = irq_vsync::i_y#5 - SINY_LEN to:irq_vsync::@9 irq_vsync::@return: scope:[irq_vsync] from irq_vsync::@7 return @@ -219,17 +226,47 @@ SYMBOL TABLE SSA const nomodify void()** KERNEL_IRQ = (void()**)$314 const byte OFFSET_STRUCT_VERA_SPRITE_X = 2 const byte OFFSET_STRUCT_VERA_SPRITE_Y = 4 -const word* SINX[$f1] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/241) +const word* SINX[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) }} -const word* SINY[$fb] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/251) +const nomodify byte SINX_LEN = $f1 +const word* SINY[SINY_LEN] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/SINY_LEN) }} +const nomodify byte SINY_LEN = $fb const byte SIZEOF_STRUCT_VERA_SPRITE = 8 const byte SIZEOF_WORD = 2 struct VERA_SPRITE SPRITE_ATTR loadstore = { ADDR: (word)idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + }} const nomodify dword SPRITE_PIXELS_VRAM = $8000 const nomodify byte VERA_ADDRSEL = 1 @@ -243,6 +280,7 @@ const nomodify byte* VERA_DC_VIDEO = (byte*)$9f29 const nomodify byte* VERA_IEN = (byte*)$9f26 const nomodify byte VERA_INC_1 = $10 const nomodify byte* VERA_ISR = (byte*)$9f27 +const nomodify dword VERA_PALETTE = $1fa00 const byte VERA_SPRITES_ENABLE = $40 const nomodify word VERA_SPRITE_8BPP = $8000 const nomodify dword VERA_SPRITE_ATTR = $1fc00 @@ -306,9 +344,9 @@ byte* irq_vsync::vram_sprite_pos#7 byte* irq_vsync::vram_sprite_pos#8 void main() byte~ main::$0 -bool~ main::$4 -byte~ main::$5 -byte~ main::$7 +bool~ main::$5 +byte~ main::$6 +byte~ main::$8 byte main::s byte main::s#0 byte main::s#1 @@ -337,6 +375,7 @@ word memcpy_to_vram::num#0 word memcpy_to_vram::num#1 word memcpy_to_vram::num#2 word memcpy_to_vram::num#3 +word memcpy_to_vram::num#4 byte* memcpy_to_vram::s byte* memcpy_to_vram::s#0 byte* memcpy_to_vram::s#1 @@ -347,43 +386,45 @@ void* memcpy_to_vram::src#0 void* memcpy_to_vram::src#1 void* memcpy_to_vram::src#2 void* memcpy_to_vram::src#3 +void* memcpy_to_vram::src#4 byte memcpy_to_vram::vbank byte memcpy_to_vram::vbank#0 byte memcpy_to_vram::vbank#1 byte memcpy_to_vram::vbank#2 byte memcpy_to_vram::vbank#3 +byte memcpy_to_vram::vbank#4 void* memcpy_to_vram::vdest void* memcpy_to_vram::vdest#0 void* memcpy_to_vram::vdest#1 void* memcpy_to_vram::vdest#2 void* memcpy_to_vram::vdest#3 +void* memcpy_to_vram::vdest#4 volatile word sin_idx_x loadstore volatile word sin_idx_y loadstore Adding number conversion cast (unumber) = $f1 +Adding number conversion cast (unumber) SINY_LEN-1 in sin_idx_y = SINY_LEN-1 +Adding number conversion cast (unumber) 1 in sin_idx_y = ((unumber)) SINY_LEN-1 +Adding number conversion cast (unumber) $20 in irq_vsync::$4 = irq_vsync::s#2 < $20 +Adding number conversion cast (unumber) 2 in memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR+2 +Adding number conversion cast (unumber) 4 in memcpy_to_vram::num#3 = 4 +Adding number conversion cast (unumber) 9 in irq_vsync::i_x#1 = irq_vsync::i_x#4 + 9 Adding number conversion cast (unumber) 5 in irq_vsync::i_y#1 = irq_vsync::i_y#4 + 5 -Adding number conversion cast (unumber) $fb in irq_vsync::$9 = irq_vsync::i_y#1 >= $fb -Adding number conversion cast (unumber) $f1 in irq_vsync::i_x#2 = irq_vsync::i_x#5 - $f1 -Adding number conversion cast (unumber) $fb in irq_vsync::i_y#2 = irq_vsync::i_y#5 - $fb Successful SSA optimization PassNAddNumberTypeConversions -Inlining cast memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#3 +Inlining cast memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#4 +Inlining cast memcpy_to_vram::num#1 = (unumber)$200 Inlining cast sin_idx_x = (unumber)0 -Inlining cast sin_idx_y = (unumber)$fb-1 -Inlining cast memcpy_to_vram::num#2 = (unumber)4 +Inlining cast sin_idx_y = (unumber)SINY_LEN-(unumber)1 +Inlining cast memcpy_to_vram::num#3 = (unumber)4 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 40736 Simplifying constant pointer cast (byte*) 40737 @@ -396,45 +437,40 @@ Simplifying constant pointer cast (byte*) 40745 Simplifying constant pointer cast (void()**) 788 Simplifying constant integer cast = $f1 -Inversing boolean not [89] irq_vsync::$10 = irq_vsync::i_y#1 < $fb from [88] irq_vsync::$9 = irq_vsync::i_y#1 >= $fb +Inversing boolean not [57] irq_vsync::$1 = sin_idx_x != SINX_LEN from [56] irq_vsync::$0 = sin_idx_x == SINX_LEN +Inversing boolean not [61] irq_vsync::$3 = sin_idx_y != $ffff from [60] irq_vsync::$2 = sin_idx_y == $ffff +Inversing boolean not [87] irq_vsync::$8 = irq_vsync::i_x#1 < SINX_LEN from [86] irq_vsync::$7 = irq_vsync::i_x#1 >= SINX_LEN +Inversing boolean not [94] irq_vsync::$10 = irq_vsync::i_y#1 < SINY_LEN from [93] irq_vsync::$9 = irq_vsync::i_y#1 >= SINY_LEN Successful SSA optimization Pass2UnaryNotSimplification Alias memcpy_to_vram::end#0 = memcpy_to_vram::$3 Alias memcpy_to_vram::s#2 = memcpy_to_vram::s#3 @@ -442,7 +478,7 @@ Alias memcpy_to_vram::end#1 = memcpy_to_vram::end#2 Alias memcpy_to_vram::num#0 = main::$0 Alias main::vram_sprite_attr#2 = main::vram_sprite_attr#4 main::vram_sprite_attr#3 Alias main::s#2 = main::s#4 main::s#3 -Alias memcpy_to_vram::num#1 = main::$5 +Alias memcpy_to_vram::num#2 = main::$6 Alias irq_vsync::i_x#3 = irq_vsync::i_x#6 irq_vsync::i_x#4 Alias irq_vsync::i_y#3 = irq_vsync::i_y#6 irq_vsync::i_y#8 irq_vsync::i_y#7 Alias irq_vsync::vram_sprite_pos#2 = irq_vsync::vram_sprite_pos#4 irq_vsync::vram_sprite_pos#3 @@ -462,35 +498,38 @@ Successful SSA optimization Pass2AliasElimination Identical Phi Values memcpy_to_vram::end#1 memcpy_to_vram::end#0 Successful SSA optimization Pass2IdenticalPhiElimination Simple Condition memcpy_to_vram::$4 [13] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -Simple Condition main::$4 [26] if(main::s#2<$80) goto main::@2 -Simple Condition irq_vsync::$1 [46] if(sin_idx_x!=$f1) goto irq_vsync::@1 -Simple Condition irq_vsync::$3 [49] if(sin_idx_y!=$ffff) goto irq_vsync::@2 -Simple Condition irq_vsync::$4 [58] if(irq_vsync::s#2<$80) goto irq_vsync::@6 -Simple Condition irq_vsync::$8 [72] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 -Simple Condition irq_vsync::$10 [78] if(irq_vsync::i_y#1<$fb) goto irq_vsync::@9 +Simple Condition main::$5 [31] if(main::s#2<$20) goto main::@2 +Simple Condition irq_vsync::$1 [51] if(sin_idx_x!=SINX_LEN) goto irq_vsync::@1 +Simple Condition irq_vsync::$3 [54] if(sin_idx_y!=$ffff) goto irq_vsync::@2 +Simple Condition irq_vsync::$4 [63] if(irq_vsync::s#2<$20) goto irq_vsync::@6 +Simple Condition irq_vsync::$8 [77] if(irq_vsync::i_x#1SPRITE_PIXELS_VRAM Constant memcpy_to_vram::vdest#0 = (void*)VERA_PALETTE +Constant memcpy_to_vram::vdest#1 = (void*)VERA_SPRITE_ATTR -Constant memcpy_to_vram::src#1 = (void*)&SPRITE_ATTR -Constant main::$7 = SIZEOF_STRUCT_VERA_SPRITE +Constant memcpy_to_vram::num#2 = SIZEOF_STRUCT_VERA_SPRITE +Constant memcpy_to_vram::vbank#2 = (byte)>VERA_SPRITE_ATTR +Constant memcpy_to_vram::src#2 = (void*)&SPRITE_ATTR +Constant main::$8 = SIZEOF_STRUCT_VERA_SPRITE Constant irq_vsync::vram_sprite_pos#0 = (byte*)SPRITE_PIXELS_VRAM in Successful SSA optimization PassNSimplifyConstantZero @@ -500,42 +539,50 @@ Resolving array sizeof() sizeof SPRITE_PIXELS Successful SSA optimization PassNSizeOfSimplification Adding number conversion cast (unumber) $40*$40 in Successful SSA optimization PassNAddNumberTypeConversions -Inlining Noop Cast [8] memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#3 keeping memcpy_to_vram::src#3 -Inlining Noop Cast [10] memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#3 keeping memcpy_to_vram::src#3 +Inlining Noop Cast [8] memcpy_to_vram::$5 = (byte*)memcpy_to_vram::src#4 keeping memcpy_to_vram::src#4 +Inlining Noop Cast [10] memcpy_to_vram::s#0 = (byte*)memcpy_to_vram::src#4 keeping memcpy_to_vram::src#4 Successful SSA optimization Pass2NopCastInlining -Rewriting multiplication to use shift [42] irq_vsync::$11 = irq_vsync::i_x#3 * SIZEOF_WORD -Rewriting multiplication to use shift [45] irq_vsync::$12 = irq_vsync::i_y#3 * SIZEOF_WORD +Rewriting multiplication to use shift [43] irq_vsync::$11 = irq_vsync::i_x#3 * SIZEOF_WORD +Rewriting multiplication to use shift [46] irq_vsync::$12 = irq_vsync::i_y#3 * SIZEOF_WORD Successful SSA optimization Pass2MultiplyToShiftRewriting Inlining constant with var siblings memcpy_to_vram::num#0 Inlining constant with var siblings memcpy_to_vram::vbank#0 Inlining constant with var siblings memcpy_to_vram::vdest#0 Inlining constant with var siblings memcpy_to_vram::src#0 -Inlining constant with var siblings memcpy_to_vram::num#1 Inlining constant with var siblings memcpy_to_vram::vbank#1 +Inlining constant with var siblings memcpy_to_vram::vdest#1 Inlining constant with var siblings memcpy_to_vram::src#1 +Inlining constant with var siblings memcpy_to_vram::num#1 +Inlining constant with var siblings memcpy_to_vram::num#2 Inlining constant with var siblings memcpy_to_vram::vbank#2 Inlining constant with var siblings memcpy_to_vram::src#2 -Inlining constant with var siblings memcpy_to_vram::num#2 +Inlining constant with var siblings memcpy_to_vram::vbank#3 +Inlining constant with var siblings memcpy_to_vram::src#3 +Inlining constant with var siblings memcpy_to_vram::num#3 Inlining constant with var siblings main::vram_sprite_attr#0 Inlining constant with var siblings main::s#0 Inlining constant with var siblings irq_vsync::vram_sprite_pos#0 Inlining constant with var siblings irq_vsync::s#0 Constant inlined memcpy_to_vram::num#0 = (word)$40*$40*SIZEOF_BYTE Constant inlined main::s#0 = 0 +Constant inlined memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR+2 Constant inlined memcpy_to_vram::vdest#0 = (void*)VERA_SPRITE_ATTR -Constant inlined memcpy_to_vram::vbank#2 = irq_vsync::vram_sprite_attr_bank -Constant inlined main::$7 = SIZEOF_STRUCT_VERA_SPRITE -Constant inlined memcpy_to_vram::num#2 = 4 -Constant inlined memcpy_to_vram::num#1 = SIZEOF_STRUCT_VERA_SPRITE +Constant inlined memcpy_to_vram::src#2 = (void*)&SPRITE_ATTR +Constant inlined memcpy_to_vram::vbank#1 = (byte)>VERA_PALETTE +Constant inlined memcpy_to_vram::vbank#2 = (byte)>VERA_SPRITE_ATTR +Constant inlined memcpy_to_vram::num#3 = 4 +Constant inlined memcpy_to_vram::num#2 = SIZEOF_STRUCT_VERA_SPRITE +Constant inlined memcpy_to_vram::vbank#3 = irq_vsync::vram_sprite_attr_bank +Constant inlined main::$8 = SIZEOF_STRUCT_VERA_SPRITE +Constant inlined memcpy_to_vram::num#1 = $200 Successful SSA optimization Pass2ConstantInlining Eliminating unused constant SIZEOF_WORD Successful SSA optimization PassNEliminateUnusedVars @@ -545,13 +592,10 @@ Finalized unsigned number type (word) $140 Finalized unsigned number type (byte) $20 Finalized unsigned number type (byte) $f0 Finalized unsigned number type (byte) $20 -Finalized unsigned number type (byte) $f1 -Finalized unsigned number type (byte) $fb -Finalized unsigned number type (byte) $fb -Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) $40 +Finalized unsigned number type (byte) $40 Successful SSA optimization PassNFinalizeNumberTypeConversions Simplifying constant integer cast $140-$20 -Simplifying constant integer cast $fb-1 Successful SSA optimization PassNCastSimplification Added new block during phi lifting irq_vsync::@13(between irq_vsync::@12 and irq_vsync::@8) Added new block during phi lifting irq_vsync::@14(between irq_vsync::@8 and irq_vsync::@9) @@ -560,15 +604,16 @@ Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of __start::@2 Adding NOP phi() at start of main Adding NOP phi() at start of main::@5 +Adding NOP phi() at start of main::@6 CALL GRAPH Calls in [__start] to main:4 Calls in [irq_vsync] to memcpy_to_vram:30 -Calls in [main] to memcpy_to_vram:50 memcpy_to_vram:65 +Calls in [main] to memcpy_to_vram:50 memcpy_to_vram:52 memcpy_to_vram:67 Created 13 initial phi equivalence classes Coalesced [15] irq_vsync::i_x#10 = irq_vsync::i_x#0 Coalesced [16] irq_vsync::i_y#10 = irq_vsync::i_y#0 -Coalesced [29] memcpy_to_vram::vdest#4 = memcpy_to_vram::vdest#2 +Coalesced [29] memcpy_to_vram::vdest#5 = memcpy_to_vram::vdest#3 Coalesced [35] irq_vsync::i_x#12 = irq_vsync::i_x#2 Coalesced [40] irq_vsync::i_y#12 = irq_vsync::i_y#2 Coalesced [43] irq_vsync::s#9 = irq_vsync::s#1 @@ -577,19 +622,20 @@ Coalesced [45] irq_vsync::i_y#11 = irq_vsync::i_y#9 Coalesced [46] irq_vsync::vram_sprite_pos#9 = irq_vsync::vram_sprite_pos#1 Coalesced [47] irq_vsync::i_y#13 = irq_vsync::i_y#1 Coalesced [48] irq_vsync::i_x#13 = irq_vsync::i_x#1 -Coalesced [64] memcpy_to_vram::vdest#5 = memcpy_to_vram::vdest#1 -Coalesced [68] main::s#5 = main::s#1 -Coalesced [69] main::vram_sprite_attr#5 = main::vram_sprite_attr#1 -Coalesced [85] memcpy_to_vram::s#5 = memcpy_to_vram::s#1 +Coalesced [66] memcpy_to_vram::vdest#6 = memcpy_to_vram::vdest#2 +Coalesced [70] main::s#5 = main::s#1 +Coalesced [71] main::vram_sprite_attr#5 = main::vram_sprite_attr#1 +Coalesced [87] memcpy_to_vram::s#5 = memcpy_to_vram::s#1 Coalesced down to 11 phi equivalence classes Culled Empty Block label __start::@2 Culled Empty Block label irq_vsync::@14 Culled Empty Block label irq_vsync::@13 -Culled Empty Block label main::@5 -Renumbering block main::@6 to main::@5 +Culled Empty Block label main::@6 +Renumbering block main::@7 to main::@6 Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of main +Adding NOP phi() at start of main::@5 FINAL CONTROL FLOW GRAPH @@ -612,7 +658,7 @@ __start::@return: scope:[__start] from __start::@1 void irq_vsync() irq_vsync: scope:[irq_vsync] from [6] sin_idx_x = ++ sin_idx_x - [7] if(sin_idx_x!=$f1) goto irq_vsync::@1 + [7] if(sin_idx_x!=SINX_LEN) goto irq_vsync::@1 to:irq_vsync::@3 irq_vsync::@3: scope:[irq_vsync] from irq_vsync [8] sin_idx_x = 0 @@ -622,7 +668,7 @@ irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3 [10] if(sin_idx_y!=$ffff) goto irq_vsync::@2 to:irq_vsync::@4 irq_vsync::@4: scope:[irq_vsync] from irq_vsync::@1 - [11] sin_idx_y = $fb-1 + [11] sin_idx_y = SINY_LEN-1 to:irq_vsync::@2 irq_vsync::@2: scope:[irq_vsync] from irq_vsync::@1 irq_vsync::@4 [12] irq_vsync::i_x#0 = sin_idx_x @@ -633,7 +679,7 @@ irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2 irq_vsync::@9 [14] irq_vsync::i_y#3 = phi( irq_vsync::@2/irq_vsync::i_y#0, irq_vsync::@9/irq_vsync::i_y#9 ) [14] irq_vsync::i_x#3 = phi( irq_vsync::@2/irq_vsync::i_x#0, irq_vsync::@9/irq_vsync::i_x#7 ) [14] irq_vsync::s#2 = phi( irq_vsync::@2/0, irq_vsync::@9/irq_vsync::s#1 ) - [15] if(irq_vsync::s#2<$80) goto irq_vsync::@6 + [15] if(irq_vsync::s#2<$20) goto irq_vsync::@6 to:irq_vsync::@7 irq_vsync::@7: scope:[irq_vsync] from irq_vsync::@5 [16] *VERA_ISR = VERA_VSYNC @@ -649,24 +695,24 @@ irq_vsync::@6: scope:[irq_vsync] from irq_vsync::@5 [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 [23] irq_vsync::$14 = SINY + irq_vsync::$12 [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 - [25] memcpy_to_vram::vdest#2 = (void*)irq_vsync::vram_sprite_pos#2 + [25] memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2 [26] call memcpy_to_vram to:irq_vsync::@12 irq_vsync::@12: scope:[irq_vsync] from irq_vsync::@6 [27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE - [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 3 - [29] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 + [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 9 + [29] if(irq_vsync::i_x#1VERA_SPRITE_ATTR ) - [54] memcpy_to_vram::vdest#3 = phi( irq_vsync::@6/memcpy_to_vram::vdest#2, main/(void*) memcpy_to_vram::vdest#3 - [59] *VERA_ADDRX_M = memcpy_to_vram::$1 - [60] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3 - [61] *VERA_ADDRX_H = memcpy_to_vram::$2 - [62] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#3 + memcpy_to_vram::num#3 - [63] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#3 +memcpy_to_vram: scope:[memcpy_to_vram] from irq_vsync::@6 main main::@2 main::@5 + [56] memcpy_to_vram::num#4 = phi( irq_vsync::@6/4, main/(word)$40*$40*SIZEOF_BYTE, main::@2/SIZEOF_STRUCT_VERA_SPRITE, main::@5/$200 ) + [56] memcpy_to_vram::src#4 = phi( irq_vsync::@6/(void*)&SPRITE_ATTR+2, main/(void*)SPRITE_PIXELS, main::@2/(void*)&SPRITE_ATTR, main::@5/(void*)SPRITE_PIXELS+(word)$40*$40 ) + [56] memcpy_to_vram::vbank#4 = phi( irq_vsync::@6/irq_vsync::vram_sprite_attr_bank, main/0, main::@2/(byte)>VERA_SPRITE_ATTR, main::@5/(byte)>VERA_PALETTE ) + [56] memcpy_to_vram::vdest#4 = phi( irq_vsync::@6/memcpy_to_vram::vdest#3, main/(void*) memcpy_to_vram::vdest#4 + [61] *VERA_ADDRX_M = memcpy_to_vram::$1 + [62] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 + [63] *VERA_ADDRX_H = memcpy_to_vram::$2 + [64] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#4 + memcpy_to_vram::num#4 + [65] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#4 to:memcpy_to_vram::@1 memcpy_to_vram::@1: scope:[memcpy_to_vram] from memcpy_to_vram memcpy_to_vram::@2 - [64] memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#4, memcpy_to_vram::@2/memcpy_to_vram::s#1 ) - [65] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 + [66] memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#4, memcpy_to_vram::@2/memcpy_to_vram::s#1 ) + [67] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 to:memcpy_to_vram::@return memcpy_to_vram::@return: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [66] return + [68] return to:@return memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [67] *VERA_DATA0 = *memcpy_to_vram::s#2 - [68] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 + [69] *VERA_DATA0 = *memcpy_to_vram::s#2 + [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 to:memcpy_to_vram::@1 @@ -780,19 +830,19 @@ byte~ memcpy_to_vram::$2 2002.0 byte* memcpy_to_vram::end byte* memcpy_to_vram::end#0 16833.666666666664 word memcpy_to_vram::num -word memcpy_to_vram::num#3 125.125 +word memcpy_to_vram::num#4 125.125 byte* memcpy_to_vram::s byte* memcpy_to_vram::s#1 200002.0 byte* memcpy_to_vram::s#2 133668.3333333333 byte* memcpy_to_vram::s#4 2002.0 void* memcpy_to_vram::src -void* memcpy_to_vram::src#3 +void* memcpy_to_vram::src#4 byte memcpy_to_vram::vbank -byte memcpy_to_vram::vbank#3 166.83333333333334 +byte memcpy_to_vram::vbank#4 166.83333333333334 void* memcpy_to_vram::vdest -void* memcpy_to_vram::vdest#1 202.0 -void* memcpy_to_vram::vdest#2 22.0 -void* memcpy_to_vram::vdest#3 528.5 +void* memcpy_to_vram::vdest#2 202.0 +void* memcpy_to_vram::vdest#3 22.0 +void* memcpy_to_vram::vdest#4 528.5 volatile word sin_idx_x loadstore 1.9999999999999998 volatile word sin_idx_y loadstore 1.714285714285714 @@ -803,10 +853,10 @@ Initial phi equivalence classes [ irq_vsync::vram_sprite_pos#2 irq_vsync::vram_sprite_pos#1 ] [ main::s#2 main::s#1 ] [ main::vram_sprite_attr#2 main::vram_sprite_attr#1 ] -[ memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 memcpy_to_vram::vdest#1 ] -[ memcpy_to_vram::vbank#3 ] -[ memcpy_to_vram::src#3 ] -[ memcpy_to_vram::num#3 ] +[ memcpy_to_vram::vdest#4 memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 ] +[ memcpy_to_vram::vbank#4 ] +[ memcpy_to_vram::src#4 ] +[ memcpy_to_vram::num#4 ] [ memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] Added variable sin_idx_x to live range equivalence class [ sin_idx_x ] Added variable sin_idx_y to live range equivalence class [ sin_idx_y ] @@ -826,10 +876,10 @@ Complete equivalence classes [ irq_vsync::vram_sprite_pos#2 irq_vsync::vram_sprite_pos#1 ] [ main::s#2 main::s#1 ] [ main::vram_sprite_attr#2 main::vram_sprite_attr#1 ] -[ memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 memcpy_to_vram::vdest#1 ] -[ memcpy_to_vram::vbank#3 ] -[ memcpy_to_vram::src#3 ] -[ memcpy_to_vram::num#3 ] +[ memcpy_to_vram::vdest#4 memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 ] +[ memcpy_to_vram::vbank#4 ] +[ memcpy_to_vram::src#4 ] +[ memcpy_to_vram::num#4 ] [ memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] [ sin_idx_x ] [ sin_idx_y ] @@ -848,10 +898,10 @@ Allocated zp[2]:5 [ irq_vsync::i_y#3 irq_vsync::i_y#0 irq_vsync::i_y#9 irq_vsync Allocated zp[2]:7 [ irq_vsync::vram_sprite_pos#2 irq_vsync::vram_sprite_pos#1 ] Allocated zp[1]:9 [ main::s#2 main::s#1 ] Allocated zp[2]:10 [ main::vram_sprite_attr#2 main::vram_sprite_attr#1 ] -Allocated zp[2]:12 [ memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 memcpy_to_vram::vdest#1 ] -Allocated zp[1]:14 [ memcpy_to_vram::vbank#3 ] -Allocated zp[2]:15 [ memcpy_to_vram::src#3 ] -Allocated zp[2]:17 [ memcpy_to_vram::num#3 ] +Allocated zp[2]:12 [ memcpy_to_vram::vdest#4 memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 ] +Allocated zp[1]:14 [ memcpy_to_vram::vbank#4 ] +Allocated zp[2]:15 [ memcpy_to_vram::src#4 ] +Allocated zp[2]:17 [ memcpy_to_vram::num#4 ] Allocated zp[2]:19 [ memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] Allocated zp[2]:21 [ sin_idx_x ] Allocated zp[2]:23 [ sin_idx_y ] @@ -867,95 +917,95 @@ Allocated mem[8] [ SPRITE_ATTR ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [1] sin_idx_x = $77 [ SPRITE_ATTR ] ( [ SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [2] sin_idx_y = $4f [ SPRITE_ATTR ] ( [ SPRITE_ATTR ] { } ) always clobbers reg byte a -Statement [7] if(sin_idx_x!=$f1) goto irq_vsync::@1 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a +Statement [7] if(sin_idx_x!=SINX_LEN) goto irq_vsync::@1 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [8] sin_idx_x = 0 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [9] sin_idx_y = -- sin_idx_y [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [10] if(sin_idx_y!=$ffff) goto irq_vsync::@2 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a -Statement [11] sin_idx_y = $fb-1 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a +Statement [11] sin_idx_y = SINY_LEN-1 [ sin_idx_x sin_idx_y SPRITE_ATTR ] ( [ sin_idx_x sin_idx_y SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [12] irq_vsync::i_x#0 = sin_idx_x [ sin_idx_y irq_vsync::i_x#0 SPRITE_ATTR ] ( [ sin_idx_y irq_vsync::i_x#0 SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [13] irq_vsync::i_y#0 = sin_idx_y [ irq_vsync::i_x#0 irq_vsync::i_y#0 SPRITE_ATTR ] ( [ irq_vsync::i_x#0 irq_vsync::i_y#0 SPRITE_ATTR ] { } ) always clobbers reg byte a Statement [16] *VERA_ISR = VERA_VSYNC [ ] ( [ ] { } ) always clobbers reg byte a -Statement [19] irq_vsync::$11 = irq_vsync::i_x#3 << 1 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$11 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$11 SPRITE_ATTR ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a +Statement [19] irq_vsync::$11 = irq_vsync::i_x#3 << 1 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$11 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$11 SPRITE_ATTR ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ irq_vsync::s#2 irq_vsync::s#1 ] -Statement [20] irq_vsync::$13 = SINX + irq_vsync::$11 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$13 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$13 SPRITE_ATTR ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a -Statement [21] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$13 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a reg byte y +Statement [20] irq_vsync::$13 = SINX + irq_vsync::$11 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$13 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 irq_vsync::$13 SPRITE_ATTR ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a +Statement [21] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$13 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp[1]:2 [ irq_vsync::s#2 irq_vsync::s#1 ] -Statement [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$12 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$12 ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a -Statement [23] irq_vsync::$14 = SINY + irq_vsync::$12 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$14 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$14 ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a -Statement [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a reg byte y -Statement [25] memcpy_to_vram::vdest#2 = (void*)irq_vsync::vram_sprite_pos#2 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR memcpy_to_vram::vdest#2 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR memcpy_to_vram::vdest#2 ] { { memcpy_to_vram::vdest#2 = memcpy_to_vram::vdest#3 } } ) always clobbers reg byte a +Statement [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$12 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$12 ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a +Statement [23] irq_vsync::$14 = SINY + irq_vsync::$12 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$14 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR irq_vsync::$14 ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a +Statement [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a reg byte y +Statement [25] memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2 [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR memcpy_to_vram::vdest#3 ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#2 SPRITE_ATTR memcpy_to_vram::vdest#3 ] { { memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#4 } } ) always clobbers reg byte a Statement [27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR ] ( [ irq_vsync::s#2 irq_vsync::i_x#3 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR ] { } ) always clobbers reg byte a -Statement [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 3 [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] ( [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] { } ) always clobbers reg byte a -Statement [29] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] ( [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] { } ) always clobbers reg byte a -Statement [30] irq_vsync::i_x#2 = irq_vsync::i_x#1 - $f1 [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#2 ] ( [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#2 ] { } ) always clobbers reg byte a +Statement [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 9 [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] ( [ irq_vsync::s#2 irq_vsync::i_y#3 irq_vsync::vram_sprite_pos#1 SPRITE_ATTR irq_vsync::i_x#1 ] { } ) always clobbers reg byte a +Statement [29] if(irq_vsync::i_x#1$f1 + cmp #>SINX_LEN bne __b1 lda.z sin_idx_x - cmp #<$f1 + cmp #$fb-1 + lda #>SINY_LEN-1 sta.z sin_idx_y+1 jmp __b2 // irq_vsync::@2 @@ -1196,17 +1256,14 @@ irq_vsync: { jmp __b5 // irq_vsync::@5 __b5: - // [15] if(irq_vsync::s#2<$80) goto irq_vsync::@6 -- vbuz1_lt_vbuc1_then_la1 + // [15] if(irq_vsync::s#2<$20) goto irq_vsync::@6 -- vbuz1_lt_vbuc1_then_la1 lda.z s - cmp #$80 + cmp #$20 bcc __b6 jmp __b7 // irq_vsync::@7 __b7: // [16] *VERA_ISR = VERA_VSYNC -- _deref_pbuc1=vbuc2 - // Black border - //*VERA_CTRL &= ~VERA_DCSEL; - //*VERA_DC_BORDER = 0; // Reset the VSYNC interrupt lda #VERA_VSYNC sta VERA_ISR @@ -1264,28 +1321,28 @@ irq_vsync: { iny lda (__14),y sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // [25] memcpy_to_vram::vdest#2 = (void*)irq_vsync::vram_sprite_pos#2 -- pvoz1=pvoz2 + // [25] memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2 -- pvoz1=pvoz2 lda.z vram_sprite_pos sta.z memcpy_to_vram.vdest lda.z vram_sprite_pos+1 sta.z memcpy_to_vram.vdest+1 // [26] call memcpy_to_vram // Copy sprite positions to VRAM (the 4 relevant bytes in VERA_SPRITE_ATTR) - // [54] phi from irq_vsync::@6 to memcpy_to_vram [phi:irq_vsync::@6->memcpy_to_vram] + // [56] phi from irq_vsync::@6 to memcpy_to_vram [phi:irq_vsync::@6->memcpy_to_vram] memcpy_to_vram_from___b6: - // [54] phi memcpy_to_vram::num#3 = 4 [phi:irq_vsync::@6->memcpy_to_vram#0] -- vwuz1=vbuc1 + // [56] phi memcpy_to_vram::num#4 = 4 [phi:irq_vsync::@6->memcpy_to_vram#0] -- vwuz1=vbuc1 lda #<4 sta.z memcpy_to_vram.num lda #>4 sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR+2 [phi:irq_vsync::@6->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)&SPRITE_ATTR+2 [phi:irq_vsync::@6->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_ATTR+2 sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = irq_vsync::vram_sprite_attr_bank [phi:irq_vsync::@6->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = irq_vsync::vram_sprite_attr_bank [phi:irq_vsync::@6->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #vram_sprite_attr_bank - // [54] phi memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#2 [phi:irq_vsync::@6->memcpy_to_vram#3] -- register_copy + // [56] phi memcpy_to_vram::vdest#4 = memcpy_to_vram::vdest#3 [phi:irq_vsync::@6->memcpy_to_vram#3] -- register_copy jsr memcpy_to_vram jmp __b12 // irq_vsync::@12 @@ -1298,28 +1355,28 @@ irq_vsync: { bcc !+ inc.z vram_sprite_pos+1 !: - // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 3 -- vwuz1=vwuz1_plus_vbuc1 - lda #3 + // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 9 -- vwuz1=vwuz1_plus_vbuc1 + lda #9 clc adc.z i_x sta.z i_x bcc !+ inc.z i_x+1 !: - // [29] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 -- vwuz1_lt_vbuc1_then_la1 + // [29] if(irq_vsync::i_x#1memcpy_to_vram] + // [56] phi from main to memcpy_to_vram [phi:main->memcpy_to_vram] memcpy_to_vram_from_main: - // [54] phi memcpy_to_vram::num#3 = (word)$40*$40*SIZEOF_BYTE [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 + // [56] phi memcpy_to_vram::num#4 = (word)$40*$40*SIZEOF_BYTE [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 lda #<$40*$40*SIZEOF_BYTE sta.z memcpy_to_vram.num lda #>$40*$40*SIZEOF_BYTE sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)SPRITE_PIXELS [phi:main->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)SPRITE_PIXELS [phi:main->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_PIXELS sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #0 - // [54] phi memcpy_to_vram::vdest#3 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::vdest#4 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 lda #SPRITE_PIXELS_VRAM&$ffff sta.z memcpy_to_vram.vdest+1 jsr memcpy_to_vram - // [39] phi from main to main::@1 [phi:main->main::@1] - __b1_from_main: - // [39] phi main::vram_sprite_attr#2 = (byte*)main::@1#0] -- pbuz1=pbuc1 + // [39] phi from main to main::@5 [phi:main->main::@5] + __b5_from_main: + jmp __b5 + // main::@5 + __b5: + // [40] call memcpy_to_vram + // Copy sprite palette to VRAM + // [56] phi from main::@5 to memcpy_to_vram [phi:main::@5->memcpy_to_vram] + memcpy_to_vram_from___b5: + // [56] phi memcpy_to_vram::num#4 = $200 [phi:main::@5->memcpy_to_vram#0] -- vwuz1=vwuc1 + lda #<$200 + sta.z memcpy_to_vram.num + lda #>$200 + sta.z memcpy_to_vram.num+1 + // [56] phi memcpy_to_vram::src#4 = (void*)SPRITE_PIXELS+(word)$40*$40 [phi:main::@5->memcpy_to_vram#1] -- pvoz1=pvoc1 + lda #SPRITE_PIXELS+$40*$40 + sta.z memcpy_to_vram.src+1 + // [56] phi memcpy_to_vram::vbank#4 = (byte)>VERA_PALETTE [phi:main::@5->memcpy_to_vram#2] -- vbuxx=vbuc1 + ldx #VERA_PALETTE>>$10 + // [56] phi memcpy_to_vram::vdest#4 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 + lda #VERA_PALETTE&$ffff + sta.z memcpy_to_vram.vdest+1 + jsr memcpy_to_vram + // [41] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + __b1_from___b5: + // [41] phi main::vram_sprite_attr#2 = (byte*)main::@1#0] -- pbuz1=pbuc1 lda #VERA_SPRITE_ATTR&$ffff sta.z vram_sprite_attr+1 - // [39] phi main::s#2 = 0 [phi:main->main::@1#1] -- vbuz1=vbuc1 + // [41] phi main::s#2 = 0 [phi:main::@5->main::@1#1] -- vbuz1=vbuc1 lda #0 sta.z s jmp __b1 // main::@1 __b1: - // [40] if(main::s#2<$80) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + // [42] if(main::s#2<$20) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z s - cmp #$80 + cmp #$20 bcc __b2 jmp __b3 // main::@3 __b3: - // [41] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 - // Make a border - //*VERA_CTRL |= VERA_DCSEL; - //*VERA_DC_HSTART = 16/4; - //*VERA_DC_HSTOP = 624/4; - //*VERA_DC_VSTART = 16/2; - //*VERA_DC_VSTOP = 464/2; + // [43] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 // Enable sprites lda #VERA_DCSEL^$ff and VERA_CTRL sta VERA_CTRL - // [42] *VERA_DC_VIDEO = *VERA_DC_VIDEO | VERA_SPRITES_ENABLE -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 + // [44] *VERA_DC_VIDEO = *VERA_DC_VIDEO | VERA_SPRITES_ENABLE -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 lda #VERA_SPRITES_ENABLE ora VERA_DC_VIDEO sta VERA_DC_VIDEO @@ -1444,12 +1522,12 @@ main: { jmp __b4 // main::@4 __b4: - // [44] *KERNEL_IRQ = &irq_vsync -- _deref_qprc1=pprc2 + // [46] *KERNEL_IRQ = &irq_vsync -- _deref_qprc1=pprc2 lda #irq_vsync sta KERNEL_IRQ+1 - // [45] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 + // [47] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 lda #VERA_VSYNC sta VERA_IEN jmp CLI1 @@ -1460,11 +1538,11 @@ main: { jmp __breturn // main::@return __breturn: - // [47] return + // [49] return rts // main::@2 __b2: - // [48] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 + // [50] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 lda #<$a clc adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X @@ -1472,7 +1550,7 @@ main: { lda #>$a adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // [49] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 + // [51] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 lda #<$a clc adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y @@ -1480,32 +1558,32 @@ main: { lda #>$a adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // [50] memcpy_to_vram::vdest#1 = (void*)main::vram_sprite_attr#2 -- pvoz1=pvoz2 + // [52] memcpy_to_vram::vdest#2 = (void*)main::vram_sprite_attr#2 -- pvoz1=pvoz2 lda.z vram_sprite_attr sta.z memcpy_to_vram.vdest lda.z vram_sprite_attr+1 sta.z memcpy_to_vram.vdest+1 - // [51] call memcpy_to_vram - // [54] phi from main::@2 to memcpy_to_vram [phi:main::@2->memcpy_to_vram] + // [53] call memcpy_to_vram + // [56] phi from main::@2 to memcpy_to_vram [phi:main::@2->memcpy_to_vram] memcpy_to_vram_from___b2: - // [54] phi memcpy_to_vram::num#3 = SIZEOF_STRUCT_VERA_SPRITE [phi:main::@2->memcpy_to_vram#0] -- vwuz1=vbuc1 + // [56] phi memcpy_to_vram::num#4 = SIZEOF_STRUCT_VERA_SPRITE [phi:main::@2->memcpy_to_vram#0] -- vwuz1=vbuc1 lda #SIZEOF_STRUCT_VERA_SPRITE sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR [phi:main::@2->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)&SPRITE_ATTR [phi:main::@2->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_ATTR sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = (byte)>VERA_SPRITE_ATTR [phi:main::@2->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = (byte)>VERA_SPRITE_ATTR [phi:main::@2->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #VERA_SPRITE_ATTR>>$10 - // [54] phi memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#1 [phi:main::@2->memcpy_to_vram#3] -- register_copy + // [56] phi memcpy_to_vram::vdest#4 = memcpy_to_vram::vdest#2 [phi:main::@2->memcpy_to_vram#3] -- register_copy jsr memcpy_to_vram - jmp __b5 - // main::@5 - __b5: - // [52] main::vram_sprite_attr#1 = main::vram_sprite_attr#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 + jmp __b6 + // main::@6 + __b6: + // [54] main::vram_sprite_attr#1 = main::vram_sprite_attr#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 lda #SIZEOF_STRUCT_VERA_SPRITE clc adc.z vram_sprite_attr @@ -1513,12 +1591,12 @@ main: { bcc !+ inc.z vram_sprite_attr+1 !: - // [53] main::s#1 = ++ main::s#2 -- vbuz1=_inc_vbuz1 + // [55] main::s#1 = ++ main::s#2 -- vbuz1=_inc_vbuz1 inc.z s - // [39] phi from main::@5 to main::@1 [phi:main::@5->main::@1] - __b1_from___b5: - // [39] phi main::vram_sprite_attr#2 = main::vram_sprite_attr#1 [phi:main::@5->main::@1#0] -- register_copy - // [39] phi main::s#2 = main::s#1 [phi:main::@5->main::@1#1] -- register_copy + // [41] phi from main::@6 to main::@1 [phi:main::@6->main::@1] + __b1_from___b6: + // [41] phi main::vram_sprite_attr#2 = main::vram_sprite_attr#1 [phi:main::@6->main::@1#0] -- register_copy + // [41] phi main::s#2 = main::s#1 [phi:main::@6->main::@1#1] -- register_copy jmp __b1 } // memcpy_to_vram @@ -1535,26 +1613,26 @@ memcpy_to_vram: { .label vdest = $c .label src = $e .label num = $10 - // [55] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [57] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 // Select DATA0 lda #VERA_ADDRSEL^$ff and VERA_CTRL sta VERA_CTRL - // [56] memcpy_to_vram::$0 = < memcpy_to_vram::vdest#3 -- vbuaa=_lo_pvoz1 + // [58] memcpy_to_vram::$0 = < memcpy_to_vram::vdest#4 -- vbuaa=_lo_pvoz1 lda.z vdest - // [57] *VERA_ADDRX_L = memcpy_to_vram::$0 -- _deref_pbuc1=vbuaa + // [59] *VERA_ADDRX_L = memcpy_to_vram::$0 -- _deref_pbuc1=vbuaa // Set address sta VERA_ADDRX_L - // [58] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#3 -- vbuaa=_hi_pvoz1 + // [60] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#4 -- vbuaa=_hi_pvoz1 lda.z vdest+1 - // [59] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa + // [61] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa sta VERA_ADDRX_M - // [60] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3 -- vbuaa=vbuc1_bor_vbuxx + // [62] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 -- vbuaa=vbuc1_bor_vbuxx txa ora #VERA_INC_1 - // [61] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa + // [63] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa sta VERA_ADDRX_H - // [62] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#3 + memcpy_to_vram::num#3 -- pbuz1=pbuz2_plus_vwuz1 + // [64] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#4 + memcpy_to_vram::num#4 -- pbuz1=pbuz2_plus_vwuz1 lda.z end clc adc.z src @@ -1562,15 +1640,15 @@ memcpy_to_vram: { lda.z end+1 adc.z src+1 sta.z end+1 - // [63] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#3 - // [64] phi from memcpy_to_vram memcpy_to_vram::@2 to memcpy_to_vram::@1 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1] + // [65] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#4 + // [66] phi from memcpy_to_vram memcpy_to_vram::@2 to memcpy_to_vram::@1 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1] __b1_from_memcpy_to_vram: __b1_from___b2: - // [64] phi memcpy_to_vram::s#2 = memcpy_to_vram::s#4 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1#0] -- register_copy + // [66] phi memcpy_to_vram::s#2 = memcpy_to_vram::s#4 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1#0] -- register_copy jmp __b1 // memcpy_to_vram::@1 __b1: - // [65] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -- pbuz1_neq_pbuz2_then_la1 + // [67] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -- pbuz1_neq_pbuz2_then_la1 lda.z s+1 cmp.z end+1 bne __b2 @@ -1580,15 +1658,15 @@ memcpy_to_vram: { jmp __breturn // memcpy_to_vram::@return __breturn: - // [66] return + // [68] return rts // memcpy_to_vram::@2 __b2: - // [67] *VERA_DATA0 = *memcpy_to_vram::s#2 -- _deref_pbuc1=_deref_pbuz1 + // [69] *VERA_DATA0 = *memcpy_to_vram::s#2 -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (s),y sta VERA_DATA0 - // [68] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 + // [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 inc.z s bne !+ inc.z s+1 @@ -1597,23 +1675,49 @@ memcpy_to_vram: { } // File Data .segment Data - // A 64*64 8bpp sprite - .align $100 + // A 64*64 8bpp TUT sprite + .align $1200 SPRITE_PIXELS: -.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff)) - .for (var x=0;x<64; x++) - .for (var y=0; y<64; y++) - .byte (pic.getPixel(x,y)==0) ? 0 : 1 +.var pic = LoadPicture("tut.png") + // palette: rgb->idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + - // X sine [0;640-64] .align $100 SINX: -.fillword 256, 288+288*sin(i*2*PI/241) +.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - // Y sine [0;480-64] .align $100 SINY: -.fillword 256, 208+208*sin(i*2*PI/251) +.fillword 256, 208+208*sin(i*2*PI/SINY_LEN) // Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM SPRITE_ATTR: .word (SPRITE_PIXELS_VRAM/$20&$ffff)|VERA_SPRITE_8BPP, $140-$20, $f0-$20 @@ -1635,13 +1739,14 @@ Removing instruction jmp __b10 Removing instruction jmp __b8 Removing instruction jmp __b11 Removing instruction jmp __b9 +Removing instruction jmp __b5 Removing instruction jmp __b1 Removing instruction jmp __b3 Removing instruction jmp SEI1 Removing instruction jmp __b4 Removing instruction jmp CLI1 Removing instruction jmp __breturn -Removing instruction jmp __b5 +Removing instruction jmp __b6 Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination @@ -1656,6 +1761,7 @@ Removing instruction __b8_from___b10: Removing instruction __b8_from___b12: Removing instruction __b9_from___b11: Removing instruction __b9_from___b8: +Removing instruction __b5_from_main: Removing instruction __b1_from_memcpy_to_vram: Removing instruction __b1_from___b2: Succesful ASM optimization Pass5RedundantLabelElimination @@ -1673,15 +1779,17 @@ Removing instruction __b10: Removing instruction __b11: Removing instruction __b5_from___b9: Removing instruction memcpy_to_vram_from_main: -Removing instruction __b1_from_main: +Removing instruction __b5: +Removing instruction memcpy_to_vram_from___b5: +Removing instruction __b1_from___b5: Removing instruction __b3: Removing instruction SEI1: Removing instruction __b4: Removing instruction CLI1: Removing instruction __breturn: Removing instruction memcpy_to_vram_from___b2: -Removing instruction __b5: -Removing instruction __b1_from___b5: +Removing instruction __b6: +Removing instruction __b1_from___b6: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination Removing unreachable instruction rts @@ -1691,17 +1799,47 @@ FINAL SYMBOL TABLE const nomodify void()** KERNEL_IRQ = (void()**) 788 const byte OFFSET_STRUCT_VERA_SPRITE_X = 2 const byte OFFSET_STRUCT_VERA_SPRITE_Y = 4 -const word* SINX[$f1] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/241) +const word* SINX[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) }} -const word* SINY[$fb] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/251) +const nomodify byte SINX_LEN = $f1 +const word* SINY[SINY_LEN] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/SINY_LEN) }} +const nomodify byte SINY_LEN = $fb const byte SIZEOF_BYTE = 1 const byte SIZEOF_STRUCT_VERA_SPRITE = 8 struct VERA_SPRITE SPRITE_ATTR loadstore mem[8] = { ADDR: idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + }} const nomodify dword SPRITE_PIXELS_VRAM = $8000 const nomodify byte VERA_ADDRSEL = 1 @@ -1715,6 +1853,7 @@ const nomodify byte* VERA_DC_VIDEO = (byte*) 40745 const nomodify byte* VERA_IEN = (byte*) 40742 const nomodify byte VERA_INC_1 = $10 const nomodify byte* VERA_ISR = (byte*) 40743 +const nomodify dword VERA_PALETTE = $1fa00 const byte VERA_SPRITES_ENABLE = $40 const nomodify word VERA_SPRITE_8BPP = $8000 const nomodify dword VERA_SPRITE_ATTR = $1fc00 @@ -1758,19 +1897,19 @@ byte~ memcpy_to_vram::$2 reg byte a 2002.0 byte* memcpy_to_vram::end byte* memcpy_to_vram::end#0 end zp[2]:16 16833.666666666664 word memcpy_to_vram::num -word memcpy_to_vram::num#3 num zp[2]:16 125.125 +word memcpy_to_vram::num#4 num zp[2]:16 125.125 byte* memcpy_to_vram::s byte* memcpy_to_vram::s#1 s zp[2]:14 200002.0 byte* memcpy_to_vram::s#2 s zp[2]:14 133668.3333333333 byte* memcpy_to_vram::s#4 s zp[2]:14 2002.0 void* memcpy_to_vram::src -void* memcpy_to_vram::src#3 src zp[2]:14 +void* memcpy_to_vram::src#4 src zp[2]:14 byte memcpy_to_vram::vbank -byte memcpy_to_vram::vbank#3 reg byte x 166.83333333333334 +byte memcpy_to_vram::vbank#4 reg byte x 166.83333333333334 void* memcpy_to_vram::vdest -void* memcpy_to_vram::vdest#1 vdest zp[2]:12 202.0 -void* memcpy_to_vram::vdest#2 vdest zp[2]:12 22.0 -void* memcpy_to_vram::vdest#3 vdest zp[2]:12 528.5 +void* memcpy_to_vram::vdest#2 vdest zp[2]:12 202.0 +void* memcpy_to_vram::vdest#3 vdest zp[2]:12 22.0 +void* memcpy_to_vram::vdest#4 vdest zp[2]:12 528.5 volatile word sin_idx_x loadstore zp[2]:18 1.9999999999999998 volatile word sin_idx_y loadstore zp[2]:20 1.714285714285714 @@ -1780,10 +1919,10 @@ zp[2]:5 [ irq_vsync::i_y#3 irq_vsync::i_y#0 irq_vsync::i_y#9 irq_vsync::i_y#2 ir zp[2]:7 [ irq_vsync::vram_sprite_pos#2 irq_vsync::vram_sprite_pos#1 ] zp[1]:9 [ main::s#2 main::s#1 ] zp[2]:10 [ main::vram_sprite_attr#2 main::vram_sprite_attr#1 ] -zp[2]:12 [ memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 memcpy_to_vram::vdest#1 ] -reg byte x [ memcpy_to_vram::vbank#3 ] -zp[2]:14 [ memcpy_to_vram::src#3 memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] -zp[2]:16 [ memcpy_to_vram::num#3 memcpy_to_vram::end#0 ] +zp[2]:12 [ memcpy_to_vram::vdest#4 memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 ] +reg byte x [ memcpy_to_vram::vbank#4 ] +zp[2]:14 [ memcpy_to_vram::src#4 memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] +zp[2]:16 [ memcpy_to_vram::num#4 memcpy_to_vram::end#0 ] zp[2]:18 [ sin_idx_x ] zp[2]:20 [ sin_idx_y ] zp[2]:22 [ irq_vsync::$11 irq_vsync::$13 ] @@ -1795,15 +1934,15 @@ mem[8] [ SPRITE_ATTR ] FINAL ASSEMBLER -Score: 8490 +Score: 8528 // File Comments // Example program for the Commander X16 -// Displays some sprites - exceeding the per-line limits of the CX16 +// Displays 32 64*64 TUT sprites // Upstart .cpu _65c02 // Commodore 64 PRG executable file -.file [name="sprite.prg", type="prg", segments="Program"] +.file [name="sprites.prg", type="prg", segments="Program"] .segmentdef Program [segments="Basic, Code, Data"] .segmentdef Basic [start=$0801] .segmentdef Code [start=$80d] @@ -1818,12 +1957,22 @@ Score: 8490 .const VERA_DCSEL = 2 .const VERA_ADDRSEL = 1 .const VERA_VSYNC = 1 - // Sprite Attributes address in VERA VRAM + // VERA Palette address in VRAM $1FA00 - $1FBFF + // 256 entries of 2 bytes + // byte 0 bits 4-7: Green + // byte 0 bits 0-3: Blue + // byte 1 bits 0-3: Red + .const VERA_PALETTE = $1fa00 + // Sprite Attributes address in VERA VRAM $1FC00 - $1FFFF .const VERA_SPRITE_ATTR = $1fc00 // 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable) .const VERA_SPRITE_8BPP = $8000 // Address to use for sprite pixels in VRAM .const SPRITE_PIXELS_VRAM = $8000 + // X sine [0;640-64] + .const SINX_LEN = $f1 + // Y sine [0;480-64] + .const SINY_LEN = $fb .const SIZEOF_STRUCT_VERA_SPRITE = 8 .const OFFSET_STRUCT_VERA_SPRITE_X = 2 .const OFFSET_STRUCT_VERA_SPRITE_Y = 4 @@ -1913,18 +2062,18 @@ irq_vsync: { .label s = 2 .label __13 = $16 .label __14 = $18 - // if(++sin_idx_x==241) + // if(++sin_idx_x==SINX_LEN) // [6] sin_idx_x = ++ sin_idx_x -- vwuz1=_inc_vwuz1 inc.z sin_idx_x bne !+ inc.z sin_idx_x+1 !: - // [7] if(sin_idx_x!=$f1) goto irq_vsync::@1 -- vwuz1_neq_vwuc1_then_la1 + // [7] if(sin_idx_x!=SINX_LEN) goto irq_vsync::@1 -- vwuz1_neq_vwuc1_then_la1 lda.z sin_idx_x+1 - cmp #>$f1 + cmp #>SINX_LEN bne __b1 lda.z sin_idx_x - cmp #<$f1 + cmp #$fb-1 + lda #>SINY_LEN-1 sta.z sin_idx_y+1 // irq_vsync::@2 __b2: @@ -1983,16 +2132,13 @@ irq_vsync: { // irq_vsync::@5 __b5: // for(char s=0;smemcpy_to_vram] - // [54] phi memcpy_to_vram::num#3 = 4 [phi:irq_vsync::@6->memcpy_to_vram#0] -- vwuz1=vbuc1 + // [56] phi from irq_vsync::@6 to memcpy_to_vram [phi:irq_vsync::@6->memcpy_to_vram] + // [56] phi memcpy_to_vram::num#4 = 4 [phi:irq_vsync::@6->memcpy_to_vram#0] -- vwuz1=vbuc1 lda #<4 sta.z memcpy_to_vram.num lda #>4 sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR+2 [phi:irq_vsync::@6->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)&SPRITE_ATTR+2 [phi:irq_vsync::@6->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_ATTR+2 sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = irq_vsync::vram_sprite_attr_bank [phi:irq_vsync::@6->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = irq_vsync::vram_sprite_attr_bank [phi:irq_vsync::@6->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #vram_sprite_attr_bank - // [54] phi memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#2 [phi:irq_vsync::@6->memcpy_to_vram#3] -- register_copy + // [56] phi memcpy_to_vram::vdest#4 = memcpy_to_vram::vdest#3 [phi:irq_vsync::@6->memcpy_to_vram#3] -- register_copy jsr memcpy_to_vram // irq_vsync::@12 // vram_sprite_pos += sizeof(SPRITE_ATTR) @@ -2084,29 +2230,29 @@ irq_vsync: { bcc !+ inc.z vram_sprite_pos+1 !: - // i_x += 3 - // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 3 -- vwuz1=vwuz1_plus_vbuc1 - lda #3 + // i_x += 9 + // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + 9 -- vwuz1=vwuz1_plus_vbuc1 + lda #9 clc adc.z i_x sta.z i_x bcc !+ inc.z i_x+1 !: - // if(i_x>=241) - // [29] if(irq_vsync::i_x#1<$f1) goto irq_vsync::@8 -- vwuz1_lt_vbuc1_then_la1 + // if(i_x>=SINX_LEN) + // [29] if(irq_vsync::i_x#1=251) - // [33] if(irq_vsync::i_y#1<$fb) goto irq_vsync::@9 -- vwuz1_lt_vbuc1_then_la1 + // if(i_y>=SINY_LEN) + // [33] if(irq_vsync::i_y#1SPRITE_PIXELS_VRAM, memcpy_to_vram] - // [54] phi memcpy_to_vram::num#3 = (word)$40*$40*SIZEOF_BYTE [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 + // [56] phi from main to memcpy_to_vram [phi:main->memcpy_to_vram] + // [56] phi memcpy_to_vram::num#4 = (word)$40*$40*SIZEOF_BYTE [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 lda #<$40*$40*SIZEOF_BYTE sta.z memcpy_to_vram.num lda #>$40*$40*SIZEOF_BYTE sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)SPRITE_PIXELS [phi:main->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)SPRITE_PIXELS [phi:main->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_PIXELS sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #0 - // [54] phi memcpy_to_vram::vdest#3 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::vdest#4 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 lda #SPRITE_PIXELS_VRAM&$ffff sta.z memcpy_to_vram.vdest+1 jsr memcpy_to_vram - // [39] phi from main to main::@1 [phi:main->main::@1] - // [39] phi main::vram_sprite_attr#2 = (byte*)main::@1#0] -- pbuz1=pbuc1 + // [39] phi from main to main::@5 [phi:main->main::@5] + // main::@5 + // memcpy_to_vram((char)>VERA_PALETTE, memcpy_to_vram] + // [56] phi memcpy_to_vram::num#4 = $200 [phi:main::@5->memcpy_to_vram#0] -- vwuz1=vwuc1 + lda #<$200 + sta.z memcpy_to_vram.num + lda #>$200 + sta.z memcpy_to_vram.num+1 + // [56] phi memcpy_to_vram::src#4 = (void*)SPRITE_PIXELS+(word)$40*$40 [phi:main::@5->memcpy_to_vram#1] -- pvoz1=pvoc1 + lda #SPRITE_PIXELS+$40*$40 + sta.z memcpy_to_vram.src+1 + // [56] phi memcpy_to_vram::vbank#4 = (byte)>VERA_PALETTE [phi:main::@5->memcpy_to_vram#2] -- vbuxx=vbuc1 + ldx #VERA_PALETTE>>$10 + // [56] phi memcpy_to_vram::vdest#4 = (void*)memcpy_to_vram#3] -- pvoz1=pvoc1 + lda #VERA_PALETTE&$ffff + sta.z memcpy_to_vram.vdest+1 + jsr memcpy_to_vram + // [41] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + // [41] phi main::vram_sprite_attr#2 = (byte*)main::@1#0] -- pbuz1=pbuc1 lda #VERA_SPRITE_ATTR&$ffff sta.z vram_sprite_attr+1 - // [39] phi main::s#2 = 0 [phi:main->main::@1#1] -- vbuz1=vbuc1 + // [41] phi main::s#2 = 0 [phi:main::@5->main::@1#1] -- vbuz1=vbuc1 lda #0 sta.z s // main::@1 __b1: // for(char s=0;sirq_vsync sta KERNEL_IRQ+1 // *VERA_IEN = VERA_VSYNC - // [45] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 + // [47] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 lda #VERA_VSYNC sta VERA_IEN // main::CLI1 @@ -2238,12 +2402,12 @@ main: { cli // main::@return // } - // [47] return + // [49] return rts // main::@2 __b2: // SPRITE_ATTR.X += 10 - // [48] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 + // [50] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 lda #<$a clc adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X @@ -2252,7 +2416,7 @@ main: { adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 // SPRITE_ATTR.Y += 10 - // [49] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 + // [51] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) + $a -- _deref_pwuc1=_deref_pwuc1_plus_vwuc2 lda #<$a clc adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y @@ -2261,30 +2425,30 @@ main: { adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 // memcpy_to_vram((char)>VERA_SPRITE_ATTR, vram_sprite_attr, &SPRITE_ATTR, sizeof(SPRITE_ATTR)) - // [50] memcpy_to_vram::vdest#1 = (void*)main::vram_sprite_attr#2 -- pvoz1=pvoz2 + // [52] memcpy_to_vram::vdest#2 = (void*)main::vram_sprite_attr#2 -- pvoz1=pvoz2 lda.z vram_sprite_attr sta.z memcpy_to_vram.vdest lda.z vram_sprite_attr+1 sta.z memcpy_to_vram.vdest+1 - // [51] call memcpy_to_vram - // [54] phi from main::@2 to memcpy_to_vram [phi:main::@2->memcpy_to_vram] - // [54] phi memcpy_to_vram::num#3 = SIZEOF_STRUCT_VERA_SPRITE [phi:main::@2->memcpy_to_vram#0] -- vwuz1=vbuc1 + // [53] call memcpy_to_vram + // [56] phi from main::@2 to memcpy_to_vram [phi:main::@2->memcpy_to_vram] + // [56] phi memcpy_to_vram::num#4 = SIZEOF_STRUCT_VERA_SPRITE [phi:main::@2->memcpy_to_vram#0] -- vwuz1=vbuc1 lda #SIZEOF_STRUCT_VERA_SPRITE sta.z memcpy_to_vram.num+1 - // [54] phi memcpy_to_vram::src#3 = (void*)&SPRITE_ATTR [phi:main::@2->memcpy_to_vram#1] -- pvoz1=pvoc1 + // [56] phi memcpy_to_vram::src#4 = (void*)&SPRITE_ATTR [phi:main::@2->memcpy_to_vram#1] -- pvoz1=pvoc1 lda #SPRITE_ATTR sta.z memcpy_to_vram.src+1 - // [54] phi memcpy_to_vram::vbank#3 = (byte)>VERA_SPRITE_ATTR [phi:main::@2->memcpy_to_vram#2] -- vbuxx=vbuc1 + // [56] phi memcpy_to_vram::vbank#4 = (byte)>VERA_SPRITE_ATTR [phi:main::@2->memcpy_to_vram#2] -- vbuxx=vbuc1 ldx #VERA_SPRITE_ATTR>>$10 - // [54] phi memcpy_to_vram::vdest#3 = memcpy_to_vram::vdest#1 [phi:main::@2->memcpy_to_vram#3] -- register_copy + // [56] phi memcpy_to_vram::vdest#4 = memcpy_to_vram::vdest#2 [phi:main::@2->memcpy_to_vram#3] -- register_copy jsr memcpy_to_vram - // main::@5 + // main::@6 // vram_sprite_attr += sizeof(SPRITE_ATTR) - // [52] main::vram_sprite_attr#1 = main::vram_sprite_attr#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 + // [54] main::vram_sprite_attr#1 = main::vram_sprite_attr#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 lda #SIZEOF_STRUCT_VERA_SPRITE clc adc.z vram_sprite_attr @@ -2293,11 +2457,11 @@ main: { inc.z vram_sprite_attr+1 !: // for(char s=0;smain::@1] - // [39] phi main::vram_sprite_attr#2 = main::vram_sprite_attr#1 [phi:main::@5->main::@1#0] -- register_copy - // [39] phi main::s#2 = main::s#1 [phi:main::@5->main::@1#1] -- register_copy + // [41] phi from main::@6 to main::@1 [phi:main::@6->main::@1] + // [41] phi main::vram_sprite_attr#2 = main::vram_sprite_attr#1 [phi:main::@6->main::@1#0] -- register_copy + // [41] phi main::s#2 = main::s#1 [phi:main::@6->main::@1#1] -- register_copy jmp __b1 } // memcpy_to_vram @@ -2315,33 +2479,33 @@ memcpy_to_vram: { .label src = $e .label num = $10 // *VERA_CTRL &= ~VERA_ADDRSEL - // [55] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 + // [57] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL -- _deref_pbuc1=_deref_pbuc1_band_vbuc2 // Select DATA0 lda #VERA_ADDRSEL^$ff and VERA_CTRL sta VERA_CTRL // vdest - // [58] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#3 -- vbuaa=_hi_pvoz1 + // [60] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#4 -- vbuaa=_hi_pvoz1 lda.z vdest+1 // *VERA_ADDRX_M = >vdest - // [59] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa + // [61] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa sta VERA_ADDRX_M // VERA_INC_1 | vbank - // [60] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#3 -- vbuaa=vbuc1_bor_vbuxx + // [62] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 -- vbuaa=vbuc1_bor_vbuxx txa ora #VERA_INC_1 // *VERA_ADDRX_H = VERA_INC_1 | vbank - // [61] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa + // [63] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa sta VERA_ADDRX_H // end = (char*)src+num - // [62] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#3 + memcpy_to_vram::num#3 -- pbuz1=pbuz2_plus_vwuz1 + // [64] memcpy_to_vram::end#0 = (byte*)memcpy_to_vram::src#4 + memcpy_to_vram::num#4 -- pbuz1=pbuz2_plus_vwuz1 lda.z end clc adc.z src @@ -2349,13 +2513,13 @@ memcpy_to_vram: { lda.z end+1 adc.z src+1 sta.z end+1 - // [63] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#3 - // [64] phi from memcpy_to_vram memcpy_to_vram::@2 to memcpy_to_vram::@1 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1] - // [64] phi memcpy_to_vram::s#2 = memcpy_to_vram::s#4 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1#0] -- register_copy + // [65] memcpy_to_vram::s#4 = (byte*)memcpy_to_vram::src#4 + // [66] phi from memcpy_to_vram memcpy_to_vram::@2 to memcpy_to_vram::@1 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1] + // [66] phi memcpy_to_vram::s#2 = memcpy_to_vram::s#4 [phi:memcpy_to_vram/memcpy_to_vram::@2->memcpy_to_vram::@1#0] -- register_copy // memcpy_to_vram::@1 __b1: // for(char *s = src; s!=end; s++) - // [65] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -- pbuz1_neq_pbuz2_then_la1 + // [67] if(memcpy_to_vram::s#2!=memcpy_to_vram::end#0) goto memcpy_to_vram::@2 -- pbuz1_neq_pbuz2_then_la1 lda.z s+1 cmp.z end+1 bne __b2 @@ -2364,17 +2528,17 @@ memcpy_to_vram: { bne __b2 // memcpy_to_vram::@return // } - // [66] return + // [68] return rts // memcpy_to_vram::@2 __b2: // *VERA_DATA0 = *s - // [67] *VERA_DATA0 = *memcpy_to_vram::s#2 -- _deref_pbuc1=_deref_pbuz1 + // [69] *VERA_DATA0 = *memcpy_to_vram::s#2 -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (s),y sta VERA_DATA0 // for(char *s = src; s!=end; s++) - // [68] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 + // [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 inc.z s bne !+ inc.z s+1 @@ -2383,23 +2547,49 @@ memcpy_to_vram: { } // File Data .segment Data - // A 64*64 8bpp sprite - .align $100 + // A 64*64 8bpp TUT sprite + .align $1200 SPRITE_PIXELS: -.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff)) - .for (var x=0;x<64; x++) - .for (var y=0; y<64; y++) - .byte (pic.getPixel(x,y)==0) ? 0 : 1 +.var pic = LoadPicture("tut.png") + // palette: rgb->idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + - // X sine [0;640-64] .align $100 SINX: -.fillword 256, 288+288*sin(i*2*PI/241) +.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - // Y sine [0;480-64] .align $100 SINY: -.fillword 256, 208+208*sin(i*2*PI/251) +.fillword 256, 208+208*sin(i*2*PI/SINY_LEN) // Sprite attributes: 8bpp, in front, 64x64, address SPRITE_PIXELS_VRAM SPRITE_ATTR: .word (SPRITE_PIXELS_VRAM/$20&$ffff)|VERA_SPRITE_8BPP, $140-$20, $f0-$20 diff --git a/src/test/ref/examples/cx16/sprite.sym b/src/test/ref/examples/cx16/sprites.sym similarity index 68% rename from src/test/ref/examples/cx16/sprite.sym rename to src/test/ref/examples/cx16/sprites.sym index 0618c6b29..63f591205 100644 --- a/src/test/ref/examples/cx16/sprite.sym +++ b/src/test/ref/examples/cx16/sprites.sym @@ -1,17 +1,47 @@ const nomodify void()** KERNEL_IRQ = (void()**) 788 const byte OFFSET_STRUCT_VERA_SPRITE_X = 2 const byte OFFSET_STRUCT_VERA_SPRITE_Y = 4 -const word* SINX[$f1] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/241) +const word* SINX[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) }} -const word* SINY[$fb] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/251) +const nomodify byte SINX_LEN = $f1 +const word* SINY[SINY_LEN] = kickasm {{ .fillword 256, 208+208*sin(i*2*PI/SINY_LEN) }} +const nomodify byte SINY_LEN = $fb const byte SIZEOF_BYTE = 1 const byte SIZEOF_STRUCT_VERA_SPRITE = 8 struct VERA_SPRITE SPRITE_ATTR loadstore mem[8] = { ADDR: idx + .var palette = Hashtable() + // RGB value for each palette index + .var palList = List() + // Next palette index + .var nxt_idx = 0; + .for (var y=0; y<64; y++) { + .for (var x=0;x<64; x++) { + .var rgb = pic.getPixel(x,y); + .var idx = palette.get(rgb) + .if(idx==null) { + .eval idx = nxt_idx++; + .eval palette.put(rgb,idx); + .eval palList.add(rgb) + } + // Output pixel index + .byte idx + } + } + // Output sprite palette (offset 64*64 bytes= + .for(var i=0;i<256;i++) { + .var rgb = palList.get(i) + .var red = floor(rgb / [256*256]) + .var green = floor(rgb/256) & 255 + .var blue = rgb & 255 + // bits 4-8: green, bits 0-3 blue + .byte (green/16)>>4 | blue/16 + // bits bits 0-3 red + .byte red/16 + } + }} const nomodify dword SPRITE_PIXELS_VRAM = $8000 const nomodify byte VERA_ADDRSEL = 1 @@ -25,6 +55,7 @@ const nomodify byte* VERA_DC_VIDEO = (byte*) 40745 const nomodify byte* VERA_IEN = (byte*) 40742 const nomodify byte VERA_INC_1 = $10 const nomodify byte* VERA_ISR = (byte*) 40743 +const nomodify dword VERA_PALETTE = $1fa00 const byte VERA_SPRITES_ENABLE = $40 const nomodify word VERA_SPRITE_8BPP = $8000 const nomodify dword VERA_SPRITE_ATTR = $1fc00 @@ -68,19 +99,19 @@ byte~ memcpy_to_vram::$2 reg byte a 2002.0 byte* memcpy_to_vram::end byte* memcpy_to_vram::end#0 end zp[2]:16 16833.666666666664 word memcpy_to_vram::num -word memcpy_to_vram::num#3 num zp[2]:16 125.125 +word memcpy_to_vram::num#4 num zp[2]:16 125.125 byte* memcpy_to_vram::s byte* memcpy_to_vram::s#1 s zp[2]:14 200002.0 byte* memcpy_to_vram::s#2 s zp[2]:14 133668.3333333333 byte* memcpy_to_vram::s#4 s zp[2]:14 2002.0 void* memcpy_to_vram::src -void* memcpy_to_vram::src#3 src zp[2]:14 +void* memcpy_to_vram::src#4 src zp[2]:14 byte memcpy_to_vram::vbank -byte memcpy_to_vram::vbank#3 reg byte x 166.83333333333334 +byte memcpy_to_vram::vbank#4 reg byte x 166.83333333333334 void* memcpy_to_vram::vdest -void* memcpy_to_vram::vdest#1 vdest zp[2]:12 202.0 -void* memcpy_to_vram::vdest#2 vdest zp[2]:12 22.0 -void* memcpy_to_vram::vdest#3 vdest zp[2]:12 528.5 +void* memcpy_to_vram::vdest#2 vdest zp[2]:12 202.0 +void* memcpy_to_vram::vdest#3 vdest zp[2]:12 22.0 +void* memcpy_to_vram::vdest#4 vdest zp[2]:12 528.5 volatile word sin_idx_x loadstore zp[2]:18 1.9999999999999998 volatile word sin_idx_y loadstore zp[2]:20 1.714285714285714 @@ -90,10 +121,10 @@ zp[2]:5 [ irq_vsync::i_y#3 irq_vsync::i_y#0 irq_vsync::i_y#9 irq_vsync::i_y#2 ir zp[2]:7 [ irq_vsync::vram_sprite_pos#2 irq_vsync::vram_sprite_pos#1 ] zp[1]:9 [ main::s#2 main::s#1 ] zp[2]:10 [ main::vram_sprite_attr#2 main::vram_sprite_attr#1 ] -zp[2]:12 [ memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 memcpy_to_vram::vdest#1 ] -reg byte x [ memcpy_to_vram::vbank#3 ] -zp[2]:14 [ memcpy_to_vram::src#3 memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] -zp[2]:16 [ memcpy_to_vram::num#3 memcpy_to_vram::end#0 ] +zp[2]:12 [ memcpy_to_vram::vdest#4 memcpy_to_vram::vdest#3 memcpy_to_vram::vdest#2 ] +reg byte x [ memcpy_to_vram::vbank#4 ] +zp[2]:14 [ memcpy_to_vram::src#4 memcpy_to_vram::s#2 memcpy_to_vram::s#4 memcpy_to_vram::s#1 ] +zp[2]:16 [ memcpy_to_vram::num#4 memcpy_to_vram::end#0 ] zp[2]:18 [ sin_idx_x ] zp[2]:20 [ sin_idx_y ] zp[2]:22 [ irq_vsync::$11 irq_vsync::$13 ]