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 23f586478..000000000 Binary files a/src/test/kc/examples/cx16/sprite.png and /dev/null differ 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 000000000..b660fc4b8 Binary files /dev/null and b/src/test/kc/examples/cx16/tut.png differ 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 ]