From 598b5b81d299c6d26963351b4068a55969af98b7 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Wed, 13 Jan 2021 13:34:51 +0100 Subject: [PATCH 01/31] 2BPP demo started. --- .../cache/fragment-cache-wdc65c02.asm | 8 + src/main/kc/include/cx16-vera.h | 43 +++-- src/main/kc/lib/veralib.c | 31 ++++ src/test/kc/examples/cx16/tilemap_2bpp.c | 147 ++++++++++++++++++ 4 files changed, 207 insertions(+), 22 deletions(-) create mode 100644 src/test/kc/examples/cx16/tilemap_2bpp.c diff --git a/src/main/fragment/cache/fragment-cache-wdc65c02.asm b/src/main/fragment/cache/fragment-cache-wdc65c02.asm index efb92a157..a5970ef03 100644 --- a/src/main/fragment/cache/fragment-cache-wdc65c02.asm +++ b/src/main/fragment/cache/fragment-cache-wdc65c02.asm @@ -4909,3 +4909,11 @@ ldy {c1}+1 sty $ff ldy #0 sta ($fe),y +//FRAGMENT pbuz1=pbuz2_plus_vbuc1 +lda #{c1} +clc +adc {z2} +sta {z1} +lda #0 +adc {z2}+1 +sta {z1}+1 diff --git a/src/main/kc/include/cx16-vera.h b/src/main/kc/include/cx16-vera.h index 2f6501ab6..b6c75b743 100644 --- a/src/main/kc/include/cx16-vera.h +++ b/src/main/kc/include/cx16-vera.h @@ -124,30 +124,34 @@ char * const VERA_DC_VSTART = 0x9f2b; char * const VERA_DC_VSTOP = 0x9f2c; // Configuration work tables -unsigned int const VERA_CONFIG_WIDTH[4] = { 32, 64, 128, 256 }; -unsigned int const VERA_CONFIG_HEIGHT[4] = { 32, 64, 128, 256 }; // Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles) -char const VERA_LAYER_CONFIG_WIDTH_32 = 0x00; -char const VERA_LAYER_CONFIG_WIDTH_64 = 0x10; -char const VERA_LAYER_CONFIG_WIDTH_128 = 0x20; -char const VERA_LAYER_CONFIG_WIDTH_256 = 0x30; -char const VERA_LAYER_CONFIG_WIDTH_MASK = 0x30; +byte const VERA_LAYER_CONFIG_WIDTH_32 = 0x00; +byte const VERA_LAYER_CONFIG_WIDTH_64 = 0x10; +byte const VERA_LAYER_CONFIG_WIDTH_128 = 0x20; +byte const VERA_LAYER_CONFIG_WIDTH_256 = 0x30; +byte const VERA_LAYER_CONFIG_WIDTH_MASK = 0x30; +word const VERA_CONFIG_WIDTH[4] = {32, 64, 128, 256}; // Bit 6-7: Map Height (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles) -char const VERA_LAYER_CONFIG_HEIGHT_32 = 0x00; -char const VERA_LAYER_CONFIG_HEIGHT_64 = 0x40; -char const VERA_LAYER_CONFIG_HEIGHT_128 = 0x80; -char const VERA_LAYER_CONFIG_HEIGHT_256 = 0xC0; -char const VERA_LAYER_CONFIG_HEIGHT_MASK = 0xC0; +byte const VERA_LAYER_CONFIG_HEIGHT_32 = 0x00; +byte const VERA_LAYER_CONFIG_HEIGHT_64 = 0x40; +byte const VERA_LAYER_CONFIG_HEIGHT_128 = 0x80; +byte const VERA_LAYER_CONFIG_HEIGHT_256 = 0xC0; +byte const VERA_LAYER_CONFIG_HEIGHT_MASK = 0xC0; +word const VERA_CONFIG_HEIGHT[4] = {32, 64, 128, 256}; + +// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp) +byte const VERA_LAYER_COLOR_DEPTH_1BPP = 0x00; +byte const VERA_LAYER_COLOR_DEPTH_2BPP = 0x01; +byte const VERA_LAYER_COLOR_DEPTH_4BPP = 0x02; +byte const VERA_LAYER_COLOR_DEPTH_8BPP = 0x03; +byte const VERA_LAYER_COLOR_DEPTH_MASK = 0x03; +byte const VERA_LAYER_COLOR_DEPTH[4] = {1, 2, 4, 8}; + // $9F2D L0_CONFIG Layer 0 Configuration char * const VERA_L0_CONFIG = 0x9f2d; -// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp) -char const VERA_L0_CONFIG_COLOR_1BPP = 0x00; -char const VERA_L0_CONFIG_COLOR_2BPP = 0x01; -char const VERA_L0_CONFIG_COLOR_4BPP = 0x02; -char const VERA_L0_CONFIG_COLOR_8BPP = 0x03; // Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode) char const VERA_L0_CONFIG_MODE_TILE = 0x00; char const VERA_L0_CONFIG_MODE_BITMAP = 0x04; @@ -171,11 +175,6 @@ char * const VERA_L0_VSCROLL_L = 0x9f32; char * const VERA_L0_VSCROLL_H = 0x9f33; // $9F34 L1_CONFIG Layer 1 Configuration char * const VERA_L1_CONFIG = 0x9f34; -// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp) -char const VERA_L1_CONFIG_COLOR_1BPP = 0x00; -char const VERA_L1_CONFIG_COLOR_2BPP = 0x01; -char const VERA_L1_CONFIG_COLOR_4BPP = 0x02; -char const VERA_L1_CONFIG_COLOR_8BPP = 0x03; // Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode) char const VERA_L1_CONFIG_MODE_TILE = 0x00; char const VERA_L1_CONFIG_MODE_BITMAP = 0x04; diff --git a/src/main/kc/lib/veralib.c b/src/main/kc/lib/veralib.c index c0bc51994..6a16a2d69 100644 --- a/src/main/kc/lib/veralib.c +++ b/src/main/kc/lib/veralib.c @@ -125,6 +125,37 @@ word vera_get_layer_map_height(unsigned byte layer) { return VERA_CONFIG_HEIGHT[ (*config & mask) >> 6]; } +// Set the color depth of the layer in terms of bit per pixel (BPP) of the tile base. +// - layer: Value of 0 or 1. +inline void vera_set_layer_color_depth_1BPP(unsigned byte layer) { + byte* addr = vera_layer_config[layer]; + *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; + *addr |= VERA_LAYER_COLOR_DEPTH_1BPP; +} +inline void vera_set_layer_color_depth_2BPP(unsigned byte layer) { + byte* addr = vera_layer_config[layer]; + *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; + *addr |= VERA_LAYER_COLOR_DEPTH_2BPP; +} +inline void vera_set_layer_color_depth_4BPP(unsigned byte layer) { + byte* addr = vera_layer_config[layer]; + *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; + *addr |= VERA_LAYER_COLOR_DEPTH_4BPP; +} +inline void vera_set_layer_color_depth_8BPP(unsigned byte layer) { + byte* addr = vera_layer_config[layer]; + *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; + *addr |= VERA_LAYER_COLOR_DEPTH_8BPP; +} + +// Get the map width or height of the layer. +// - layer: Value of 0 or 1. +// - return: 1, 2, 4 or 8. +word vera_get_layer_color_depth(unsigned byte layer) { + byte* config = vera_layer_config[layer]; + byte mask = (byte)VERA_LAYER_COLOR_DEPTH_MASK; + return VERA_LAYER_COLOR_DEPTH[(*config & mask)]; +} // Enable the layer to be displayed on the screen. // - layer: 0 or 1. diff --git a/src/test/kc/examples/cx16/tilemap_2bpp.c b/src/test/kc/examples/cx16/tilemap_2bpp.c new file mode 100644 index 000000000..12eab4cb0 --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_2bpp.c @@ -0,0 +1,147 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. +// The CX16 starts in tile map mode, 2BPP in 4 color mode, and uses 8x8 tiles. +// The map base is address 0x10000 in VERA VRAM. +// The tile base is address 0x0800 in VERA VRAM. +// We are displaying 128 tiles vertically and 128 tiles horizontally. +// The tile base is from 64 tiles. + +#include +#include +#include <6502.h> + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + // Now we set the tile map width and height. + vera_set_layer_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! + vera_set_layer_config(0, vera_get_layer_config(1)); + vera_set_layer_color_depth_2BPP(0); + vera_set_layer_tilebase(0, 0xA0); + vera_set_layer_map_width_128(0); + vera_set_layer_map_height_64(0); + dword tilebase = vera_get_layer_tilebase_address(0); + vera_show_layer(0); + + byte tile[64] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + byte map[16] = {0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00}; + + memcpy_to_vram(1, 0x4000, tile, 64); + memcpy_to_vram(1, 0x0000, map, 16); + + + while(!kbhit()); + + screenlayer(0); + scroll(1); // Scrolling on conio is activated, so conio will not output beyond the borders of the visible screen. + textcolor(WHITE); + bgcolor(GREEN); + + draw_characters(tilebase); + + while(!kbhit()); + + // Enable VSYNC IRQ (also set line bit 8 to 0) + SEI(); + *KERNEL_IRQ = &irq_vsync; + *VERA_IEN = VERA_VSYNC; + CLI(); + + + vera_hide_layer(0); + textcolor(GREY); + bgcolor(GREEN); + draw_characters(tilebase); + vera_show_layer(0); + + screenlayer(1); + + textcolor(WHITE); + bgcolor(BLACK); + printf("\n\nthis demo displays the design of the standard x16 commander\n"); + printf("character set on the vera layer 0. it's the character set i grew up with :-).\n"); + printf("\nthe smooth scrolling is implemented by manipulating the scrolling \n"); + printf("registers of layer 0. at each raster line interrupt, \n"); + printf("the x and y scrolling registers are manipulated. the cx16 terminal \n"); + printf("works on layer 1. when layer 0 is enabled with the scrolling, \n"); + printf("it gives a nice background effect. this technique can be used to implement\n"); + printf("smooth scrolling backgrounds using tile layouts in games or demos.\n"); + + textcolor(YELLOW); + printf("\npress a key to continue ..."); + + while(!kbhit()); + + screenlayer(0); + vera_hide_layer(0); + textcolor(DARK_GREY); + bgcolor(BLACK); + draw_characters(tilebase); + vera_show_layer(0); + + screenlayer(1); + gotoxy(0,20); + +} + +void draw_characters(dword tilebase) { + dword tilecolumn = tilebase; + dword tilerow = tilebase; + clrscr(); + + for(byte y:0..15) { + printf("@"); + } +} + +// X sine index +volatile int scroll_x = 0; +volatile int scroll_y = 0; +volatile int delta_x = 2; +volatile int delta_y = 0; +volatile int speed = 2; + +// VSYNC Interrupt Routine +__interrupt(rom_sys_cx16) void irq_vsync() { + + + scroll_x += delta_x; + scroll_y += delta_y; + + if( scroll_x>(128*8-80*8)) { + delta_x = 0; + delta_y = speed; + scroll_x = (128*8-80*8); + } + if( scroll_y>(128*8-60*8)) { + delta_x = -speed; + delta_y = 0; + scroll_y = (128*8-60*8); + } + if(scroll_x<0) { + delta_x = 0; + delta_y = -speed; + scroll_x = 0; + } + if(scroll_y<0) { + delta_x = speed; + delta_y = 0; + scroll_y = 0; + } + + vera_set_layer_horizontal_scroll(0,(word)scroll_x); + vera_set_layer_vertical_scroll(0,(word)scroll_y); + + // Reset the VSYNC interrupt + *VERA_ISR = VERA_VSYNC; +} \ No newline at end of file From bdfb6a21eba9f5f9a2a15894f3dde8d97ab2e149 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Wed, 13 Jan 2021 19:41:12 +0100 Subject: [PATCH 02/31] 2BPP demo started. --- src/test/kc/examples/cx16/tilemap_2bpp.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/kc/examples/cx16/tilemap_2bpp.c b/src/test/kc/examples/cx16/tilemap_2bpp.c index 12eab4cb0..5c5e186cb 100644 --- a/src/test/kc/examples/cx16/tilemap_2bpp.c +++ b/src/test/kc/examples/cx16/tilemap_2bpp.c @@ -34,11 +34,34 @@ void main() { 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + byte map[16] = {0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00}; memcpy_to_vram(1, 0x4000, tile, 64); memcpy_to_vram(1, 0x0000, map, 16); + tilebase = 0; + dword mapbase = ver_get_vera_layer_mapbase_address(0); + + for(byte y:0..15) { + tilerow = tilebase; + for(byte r:0..3) { + tilecolumn = tilerow; + for(byte x:0..15) { + for(byte c: 0..1) { + vera_vram_address0(mapbase,VERA_INC_1); + *VERA_DATA0 = map[x]; + *VERA_DATA0 = map[x]; + } + byte bit = data; + tilecolumn += 8; + printf(""); + } + //printf("\n"); + tilerow += 1; + } + } + while(!kbhit()); From d45e58a1be11592fcc2b0b3e9f9837562f871651 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Thu, 14 Jan 2021 21:47:18 +0100 Subject: [PATCH 03/31] 2BPP 8x8 first explanation done. Created new vera functions to set the mode of a layer, in one call, and to paint an area with a tile. More functions like this will be made. (like tile increment, tile template fill, etc, etc). --- .../cache/fragment-cache-wdc65c02.asm | 1044 +++++++ src/main/kc/include/cx16-vera.h | 31 +- src/main/kc/lib/veralib.c | 194 +- src/test/kc/examples/cx16/tilemap.c | 14 +- src/test/kc/examples/cx16/tilemap_2bpp.c | 170 -- .../kc/examples/cx16/tilemap_2bpp_8_x_8.c | 74 + src/test/ref/examples/cx16/sprites.asm | 514 ---- src/test/ref/examples/cx16/sprites.cfg | 150 - src/test/ref/examples/cx16/sprites.log | 2598 ----------------- src/test/ref/examples/cx16/sprites.sym | 136 - 10 files changed, 1319 insertions(+), 3606 deletions(-) delete mode 100644 src/test/kc/examples/cx16/tilemap_2bpp.c create mode 100644 src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c delete mode 100644 src/test/ref/examples/cx16/sprites.asm delete mode 100644 src/test/ref/examples/cx16/sprites.cfg delete mode 100644 src/test/ref/examples/cx16/sprites.log delete mode 100644 src/test/ref/examples/cx16/sprites.sym diff --git a/src/main/fragment/cache/fragment-cache-wdc65c02.asm b/src/main/fragment/cache/fragment-cache-wdc65c02.asm index 82d6a08f5..7474d6077 100644 --- a/src/main/fragment/cache/fragment-cache-wdc65c02.asm +++ b/src/main/fragment/cache/fragment-cache-wdc65c02.asm @@ -2885,3 +2885,1047 @@ lda {z1} sta {z1}+1 lda #0 sta {z1} +//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuz2 +ldy {z2} +lda {c1},y +ldy #0 +sta ({z1}),y +//FRAGMENT vbuz1_ge_vbuz2_then_la1 +lda {z1} +cmp {z2} +bcs {la1} +//FRAGMENT vbuz1=vbuz1_minus_vbuz2 +lda {z1} +sec +sbc {z2} +sta {z1} +//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuaa +tay +lda {c1},y +ldy #0 +sta ({z1}),y +//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuxx +lda {c1},x +ldy #0 +sta ({z1}),y +//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuyy +lda {c1},y +ldy #0 +sta ({z1}),y +//FRAGMENT vbuaa_ge_vbuz1_then_la1 +cmp {z1} +bcs {la1} +//FRAGMENT vbuxx=vbuxx_minus_vbuz1 +txa +sec +sbc {z1} +tax +//FRAGMENT vbuz1=vbuz1_minus_vbuaa +eor #$ff +sec +adc {z1} +sta {z1} +//FRAGMENT vbuxx=vbuxx_minus_vbuaa +sta $ff +txa +sec +sbc $ff +tax +//FRAGMENT vbuz1=vbuz1_minus_vbuxx +txa +eor #$ff +sec +adc {z1} +sta {z1} +//FRAGMENT vbuxx=vbuxx_minus_vbuxx +lda #0 +tax +//FRAGMENT vbuz1=vbuz1_minus_vbuyy +tya +eor #$ff +sec +adc {z1} +sta {z1} +//FRAGMENT vbuxx=vbuxx_minus_vbuyy +txa +sty $ff +sec +sbc $ff +tax +//FRAGMENT vbuxx_ge_vbuz1_then_la1 +cpx {z1} +bcs {la1} +//FRAGMENT vbuz1_ge_vbuxx_then_la1 +lda {z1} +stx $ff +cmp $ff +bcs {la1} +//FRAGMENT vbuz1_ge_vbuyy_then_la1 +lda {z1} +sty $ff +cmp $ff +bcs {la1} +//FRAGMENT vbuxx_ge_vbuyy_then_la1 +sty $ff +cpx $ff +bcs {la1} +//FRAGMENT vbuyy_ge_vbuz1_then_la1 +cpy {z1} +bcs {la1} +//FRAGMENT vbuz1=_byte_vduz2 +lda {z2} +sta {z1} +//FRAGMENT vbuz1=vbuz2_rol_2 +lda {z2} +asl +asl +sta {z1} +//FRAGMENT vduz1=pduc1_derefidx_vbuz2 +ldy {z2} +lda {c1},y +sta {z1} +lda {c1}+1,y +sta {z1}+1 +lda {c1}+2,y +sta {z1}+2 +lda {c1}+3,y +sta {z1}+3 +//FRAGMENT vduz1_ge_vduz2_then_la1 +lda {z1}+3 +cmp {z2}+3 +bcc !+ +bne {la1} +lda {z1}+2 +cmp {z2}+2 +bcc !+ +bne {la1} +lda {z1}+1 +cmp {z2}+1 +bcc !+ +bne {la1} +lda {z1} +cmp {z2} +bcs {la1} +!: +//FRAGMENT vbsz1=_sbyte_vwuz2 +lda {z2} +sta {z1} +//FRAGMENT vbsz1=_inc_vbsz1 +inc {z1} +//FRAGMENT vbsz1=vbsz2_minus_vbsz3 +lda {z2} +sec +sbc {z3} +sta {z1} +//FRAGMENT vbsz1_ge_0_then_la1 +lda {z1} +cmp #0 +bpl {la1} +//FRAGMENT vbsz1=vbsc1 +lda #{c1} +sta {z1} +//FRAGMENT 0_neq_vbsz1_then_la1 +lda {z1} +cmp #0 +bne {la1} +//FRAGMENT vduz1=vduz1_minus_vduz2 +lda {z1} +sec +sbc {z2} +sta {z1} +lda {z1}+1 +sbc {z2}+1 +sta {z1}+1 +lda {z1}+2 +sbc {z2}+2 +sta {z1}+2 +lda {z1}+3 +sbc {z2}+3 +sta {z1}+3 +//FRAGMENT 0_neq__deref_pbuz1_then_la1 +ldy #0 +lda ({z1}),y +cmp #0 +bne {la1} +//FRAGMENT vbuz1_le_vbuc1_then_la1 +lda #{c1} +cmp {z1} +bcs {la1} +//FRAGMENT vbuaa=_byte_vduz1 +lda {z1} +//FRAGMENT vbuxx=_byte_vduz1 +lda {z1} +tax +//FRAGMENT vbuyy=_byte_vduz1 +lda {z1} +tay +//FRAGMENT vbuz1=vbuaa_rol_2 +asl +asl +sta {z1} +//FRAGMENT vbuz1=vbuxx_rol_2 +txa +asl +asl +sta {z1} +//FRAGMENT vbuz1=vbuyy_rol_2 +tya +asl +asl +sta {z1} +//FRAGMENT vbuaa=vbuz1_rol_2 +lda {z1} +asl +asl +//FRAGMENT vbuaa=vbuaa_rol_2 +asl +asl +//FRAGMENT vbuaa=vbuxx_rol_2 +txa +asl +asl +//FRAGMENT vbuaa=vbuyy_rol_2 +tya +asl +asl +//FRAGMENT vbuxx=vbuz1_rol_2 +lda {z1} +asl +asl +tax +//FRAGMENT vbuxx=vbuaa_rol_2 +asl +asl +tax +//FRAGMENT vbuxx=vbuxx_rol_2 +txa +asl +asl +tax +//FRAGMENT vbuxx=vbuyy_rol_2 +tya +asl +asl +tax +//FRAGMENT vbuyy=vbuz1_rol_2 +lda {z1} +asl +asl +tay +//FRAGMENT vbuyy=vbuaa_rol_2 +asl +asl +tay +//FRAGMENT vbuyy=vbuxx_rol_2 +txa +asl +asl +tay +//FRAGMENT vbuyy=vbuyy_rol_2 +tya +asl +asl +tay +//FRAGMENT vduz1=pduc1_derefidx_vbuaa +tay +lda {c1},y +sta {z1} +lda {c1}+1,y +sta {z1}+1 +lda {c1}+2,y +sta {z1}+2 +lda {c1}+3,y +sta {z1}+3 +//FRAGMENT vduz1=pduc1_derefidx_vbuxx +lda {c1},x +sta {z1} +lda {c1}+1,x +sta {z1}+1 +lda {c1}+2,x +sta {z1}+2 +lda {c1}+3,x +sta {z1}+3 +//FRAGMENT vduz1=pduc1_derefidx_vbuyy +lda {c1},y +sta {z1} +lda {c1}+1,y +sta {z1}+1 +lda {c1}+2,y +sta {z1}+2 +lda {c1}+3,y +sta {z1}+3 +//FRAGMENT vbsaa=_sbyte_vwuz1 +lda {z1} +//FRAGMENT vbsxx=_sbyte_vwuz1 +ldx {z1} +//FRAGMENT vbsz1=vbsz2_minus_vbsaa +eor #$ff +sec +adc {z2} +sta {z1} +//FRAGMENT vbsz1=vbsz2_minus_vbsxx +txa +eor #$ff +sec +adc {z2} +sta {z1} +//FRAGMENT vbsz1=vbsz2_minus_vbsyy +tya +eor #$ff +sec +adc {z2} +sta {z1} +//FRAGMENT vbsz1=vbsxx_minus_vbsz2 +txa +sec +sbc {z2} +sta {z1} +//FRAGMENT vbsz1=vbsxx_minus_vbsaa +sta $ff +txa +sec +sbc $ff +sta {z1} +//FRAGMENT vbsz1=vbsxx_minus_vbsxx +lda #0 +sta {z1} +//FRAGMENT vbsz1=vbsxx_minus_vbsyy +txa +sty $ff +sec +sbc $ff +sta {z1} +//FRAGMENT vbsz1=vbsyy_minus_vbsz2 +tya +sec +sbc {z2} +sta {z1} +//FRAGMENT vbsz1=vbsyy_minus_vbsaa +sta $ff +tya +sec +sbc $ff +sta {z1} +//FRAGMENT vbsz1=vbsyy_minus_vbsxx +tya +stx $ff +sec +sbc $ff +sta {z1} +//FRAGMENT vbsz1=vbsyy_minus_vbsyy +lda #0 +sta {z1} +//FRAGMENT vbsxx=vbsz1_minus_vbsz2 +lda {z1} +sec +sbc {z2} +tax +//FRAGMENT vbsxx=vbsz1_minus_vbsaa +eor #$ff +sec +adc {z1} +tax +//FRAGMENT vbsxx=vbsz1_minus_vbsxx +txa +eor #$ff +sec +adc {z1} +tax +//FRAGMENT vbsxx=vbsz1_minus_vbsyy +tya +eor #$ff +sec +adc {z1} +tax +//FRAGMENT vbsxx=vbsxx_minus_vbsz1 +txa +sec +sbc {z1} +tax +//FRAGMENT vbsxx=vbsxx_minus_vbsaa +sta $ff +txa +sec +sbc $ff +tax +//FRAGMENT vbsxx=vbsxx_minus_vbsxx +lda #0 +tax +//FRAGMENT vbsxx=vbsxx_minus_vbsyy +txa +sty $ff +sec +sbc $ff +tax +//FRAGMENT vbsxx=vbsyy_minus_vbsz1 +tya +sec +sbc {z1} +tax +//FRAGMENT vbsxx=vbsyy_minus_vbsaa +sta $ff +tya +sec +sbc $ff +tax +//FRAGMENT vbsxx=vbsyy_minus_vbsxx +tya +stx $ff +sec +sbc $ff +tax +//FRAGMENT vbsxx=vbsyy_minus_vbsyy +lda #0 +tax +//FRAGMENT vbsxx_ge_0_then_la1 +cpx #0 +bpl {la1} +//FRAGMENT 0_neq_vbsxx_then_la1 +cpx #0 +bne {la1} +//FRAGMENT _deref_pbuz1=vbuaa +ldy #0 +sta ({z1}),y +//FRAGMENT vbuaa_le_vbuc1_then_la1 +cmp #{c1} +bcc {la1} +beq {la1} +//FRAGMENT vbuaa=vbuaa_plus_vbuc1 +clc +adc #{c1} +//FRAGMENT vbuxx_le_vbuc1_then_la1 +cpx #{c1} +bcc {la1} +beq {la1} +//FRAGMENT vbuyy_le_vbuc1_then_la1 +cpy #{c1} +bcc {la1} +beq {la1} +//FRAGMENT vbsxx=_inc_vbsxx +inx +//FRAGMENT vbsyy=_sbyte_vwuz1 +ldy {z1} +//FRAGMENT vbsyy=_inc_vbsyy +iny +//FRAGMENT vwuz1_ge_vwuz2_then_la1 +lda {z2}+1 +cmp {z1}+1 +bne !+ +lda {z2} +cmp {z1} +beq {la1} +!: +bcc {la1} +//FRAGMENT vwuz1=vwuz1_minus_vwuz2 +lda {z1} +sec +sbc {z2} +sta {z1} +lda {z1}+1 +sbc {z2}+1 +sta {z1}+1 +//FRAGMENT vbuaa=_byte_vwuz1 +lda {z1} +//FRAGMENT vbuxx=_byte_vwuz1 +lda {z1} +tax +//FRAGMENT vbuyy=_byte_vwuz1 +lda {z1} +tay +//FRAGMENT vduz1=vbuz2 +lda {z2} +sta {z1} +lda #0 +sta {z1}+1 +sta {z1}+2 +sta {z1}+3 +//FRAGMENT vduz1=vbuaa +sta {z1} +lda #0 +sta {z1}+1 +sta {z1}+2 +sta {z1}+3 +//FRAGMENT vduz1=vbuxx +txa +sta {z1} +lda #0 +sta {z1}+1 +sta {z1}+2 +sta {z1}+3 +//FRAGMENT vduz1=vbuyy +tya +sta {z1} +lda #0 +sta {z1}+1 +sta {z1}+2 +sta {z1}+3 +//FRAGMENT vduz1=vduc1 +lda #<{c1} +sta {z1} +lda #>{c1} +sta {z1}+1 +lda #<{c1}>>$10 +sta {z1}+2 +lda #>{c1}>>$10 +sta {z1}+3 +//FRAGMENT vduz1=vwuc1 +NO_SYNTHESIS +//FRAGMENT vduz1=vwsc1 +NO_SYNTHESIS +//FRAGMENT _deref_pwuc1=vbuc2 +lda #0 +sta {c1}+1 +lda #<{c2} +sta {c1} +//FRAGMENT _deref_pduc1=vduc2 +lda #<{c2} +sta {c1} +lda #>{c2} +sta {c1}+1 +lda #<{c2}>>$10 +sta {c1}+2 +lda #>{c2}>>$10 +sta {c1}+3 +//FRAGMENT _deref_pwuc1=vwuc2 +lda #<{c2} +sta {c1} +lda #>{c2} +sta {c1}+1 +//FRAGMENT _deref_pduc1=vwuc2 +NO_SYNTHESIS +//FRAGMENT vduz1=_deref_pduc1 +lda {c1} +sta {z1} +lda {c1}+1 +sta {z1}+1 +lda {c1}+2 +sta {z1}+2 +lda {c1}+3 +sta {z1}+3 +//FRAGMENT vwuz1=vbuc1_rol_vbuz2 +lda #{c1} +ldy {z2} +sta {z1} +lda #0 +sta {z1}+1 +cpy #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dey +bne !- +!e: +//FRAGMENT vduz1=vduz2_plus_vwuz3 +lda {z2} +clc +adc {z3} +sta {z1} +lda {z2}+1 +adc {z3}+1 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz2_plus_vbuc1 +lda #{c1} +clc +adc {z2} +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vbuz1=vbuz2_bor__deref_pbuc1 +lda {c1} +ora {z2} +sta {z1} +//FRAGMENT pbuc1_derefidx_vbuaa=vbuc2 +tay +lda #{c2} +sta {c1},y +//FRAGMENT pbuc1_derefidx_vbuxx=vbuc2 +lda #{c2} +sta {c1},x +//FRAGMENT pbuc1_derefidx_vbuyy=vbuc2 +lda #{c2} +sta {c1},y +//FRAGMENT vwuz1=vwuc1_rol_vbuaa +tay +lda #<{c1} +sta {z1} +lda #>{c1}+1 +sta {z1}+1 +cpy #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dey +bne !- +!e: +//FRAGMENT vwuz1=vwuc1_rol_vbuxx +lda #<{c1} +sta {z1} +lda #>{c1}+1 +sta {z1}+1 +cpx #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dex +bne !- +!e: +//FRAGMENT vwuz1=vwuc1_rol_vbuyy +lda #<{c1} +sta {z1} +lda #>{c1}+1 +sta {z1}+1 +cpy #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dey +bne !- +!e: +//FRAGMENT vwuz1=vbuc1_rol_vbuxx +lda #{c1} +sta {z1} +lda #0 +sta {z1}+1 +cpx #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dex +bne !- +!e: +//FRAGMENT vwuz1=vbuc1_rol_vbuyy +lda #{c1} +sta {z1} +lda #0 +sta {z1}+1 +cpy #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dey +bne !- +!e: +//FRAGMENT vbuz1=vbuaa_bor__deref_pbuc1 +ora {c1} +sta {z1} +//FRAGMENT vbuz1=vbuxx_bor__deref_pbuc1 +txa +ora {c1} +sta {z1} +//FRAGMENT vbuz1=vbuyy_bor__deref_pbuc1 +tya +ora {c1} +sta {z1} +//FRAGMENT vbuaa=vbuz1_bor__deref_pbuc1 +lda {c1} +ora {z1} +//FRAGMENT vbuaa=vbuaa_bor__deref_pbuc1 +ora {c1} +//FRAGMENT vbuaa=vbuxx_bor__deref_pbuc1 +txa +ora {c1} +//FRAGMENT vbuaa=vbuyy_bor__deref_pbuc1 +tya +ora {c1} +//FRAGMENT vbuxx=vbuz1_bor__deref_pbuc1 +lda {c1} +ora {z1} +tax +//FRAGMENT vbuxx=vbuaa_bor__deref_pbuc1 +ora {c1} +tax +//FRAGMENT vbuxx=vbuxx_bor__deref_pbuc1 +txa +ora {c1} +tax +//FRAGMENT vbuxx=vbuyy_bor__deref_pbuc1 +tya +ora {c1} +tax +//FRAGMENT vbuyy=vbuz1_bor__deref_pbuc1 +lda {c1} +ora {z1} +tay +//FRAGMENT vbuyy=vbuaa_bor__deref_pbuc1 +ora {c1} +tay +//FRAGMENT vbuyy=vbuxx_bor__deref_pbuc1 +txa +ora {c1} +tay +//FRAGMENT vbuyy=vbuyy_bor__deref_pbuc1 +tya +ora {c1} +tay +//FRAGMENT vbuz1=vbuaa_bor_vbuc1 +ora #{c1} +sta {z1} +//FRAGMENT vbuz1=vbuyy_bor_vbuc1 +tya +ora #{c1} +sta {z1} +//FRAGMENT vbuaa=vbuaa_bor_vbuc1 +ora #{c1} +//FRAGMENT vbuaa=vbuyy_bor_vbuc1 +tya +ora #{c1} +//FRAGMENT vbuxx=vbuaa_bor_vbuc1 +ora #{c1} +tax +//FRAGMENT vbuxx=vbuyy_bor_vbuc1 +tya +ora #{c1} +tax +//FRAGMENT vbuyy=vbuaa_bor_vbuc1 +ora #{c1} +tay +//FRAGMENT vbuyy=vbuyy_bor_vbuc1 +tya +ora #{c1} +tay +//FRAGMENT vduz1=vduz1_plus_vwuz2 +lda {z1} +clc +adc {z2} +sta {z1} +lda {z1}+1 +adc {z2}+1 +sta {z1}+1 +lda {z1}+2 +adc #0 +sta {z1}+2 +lda {z1}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz2_plus_vbuz3 +lda {z3} +clc +adc {z2} +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz2_plus_vbuaa +clc +adc {z2} +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz2_plus_vbuxx +txa +clc +adc {z2} +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz2_plus_vbuyy +tya +clc +adc {z2} +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vduz1=vduz1_plus_vbuaa +clc +adc {z1} +sta {z1} +lda {z1}+1 +adc #0 +sta {z1}+1 +lda {z1}+2 +adc #0 +sta {z1}+2 +lda {z1}+3 +adc #0 +sta {z1}+3 +//FRAGMENT vbuz1=vbuyy_bor_vbuz2 +tya +ora {z2} +sta {z1} +//FRAGMENT vbuaa=vbuaa_bor_vbuz1 +ora {z1} +//FRAGMENT vbuaa=vbuxx_bor_vbuz1 +txa +ora {z1} +//FRAGMENT vbuaa=vbuyy_bor_vbuz1 +tya +ora {z1} +//FRAGMENT vbuxx=vbuaa_bor_vbuz1 +ora {z1} +tax +//FRAGMENT vbuxx=vbuxx_bor_vbuz1 +txa +ora {z1} +tax +//FRAGMENT vbuxx=vbuyy_bor_vbuz1 +tya +ora {z1} +tax +//FRAGMENT vbuyy=vbuaa_bor_vbuz1 +ora {z1} +tay +//FRAGMENT vbuyy=vbuxx_bor_vbuz1 +txa +ora {z1} +tay +//FRAGMENT vbuyy=vbuyy_bor_vbuz1 +tya +ora {z1} +tay +//FRAGMENT vbuxx=vbuxx_bor_vbuaa +stx $ff +ora $ff +tax +//FRAGMENT vbuxx=vbuyy_bor_vbuaa +sty $ff +ora $ff +tax +//FRAGMENT vwuz1=_word_vbuaa +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=_word_vbuyy +tya +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz2_rol_vbuxx +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 +cpx #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dex +bne !- +!e: +//FRAGMENT vwuz1=vwuz2_rol_vbuyy +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 +cpy #0 +beq !e+ +!: +asl {z1} +rol {z1}+1 +dey +bne !- +!e: +//FRAGMENT vbuyy_lt_vbuz1_then_la1 +cpy {z1} +bcc {la1} +//FRAGMENT vbuaa=vbuaa_bor_vbuyy +sty $ff +ora $ff +//FRAGMENT vbuz1=vbuaa_bor_vbuyy +sty $ff +ora $ff +sta {z1} +//FRAGMENT vbuz1=vbuaa_bor_vbuz1 +ora {z1} +sta {z1} +//FRAGMENT vwuz1=_deref_pwuc1 +lda {c1} +sta {z1} +lda {c1}+1 +sta {z1}+1 +//FRAGMENT vbuz1=pbuz2_derefidx_vbuz3 +ldy {z3} +lda ({z2}),y +sta {z1} +//FRAGMENT vbuaa_eq_vbuc1_then_la1 +cmp #{c1} +beq {la1} +//FRAGMENT vbuz1_lt_vbuaa_then_la1 +cmp {z1} +beq !+ +bcs {la1} +!: +//FRAGMENT vbuaa=pbuz1_derefidx_vbuz2 +ldy {z2} +lda ({z1}),y +//FRAGMENT vbuxx=pbuz1_derefidx_vbuz2 +ldy {z2} +lda ({z1}),y +tax +//FRAGMENT vbuyy=pbuz1_derefidx_vbuz2 +ldy {z2} +lda ({z1}),y +tay +//FRAGMENT vbuz1=pbuz2_derefidx_vbuaa +tay +lda ({z2}),y +sta {z1} +//FRAGMENT vbuaa=pbuz1_derefidx_vbuaa +tay +lda ({z1}),y +//FRAGMENT vbuxx=pbuz1_derefidx_vbuaa +tay +lda ({z1}),y +tax +//FRAGMENT vbuyy=pbuz1_derefidx_vbuaa +tay +lda ({z1}),y +tay +//FRAGMENT vbuz1=pbuz2_derefidx_vbuxx +txa +tay +lda ({z2}),y +sta {z1} +//FRAGMENT vbuaa=pbuz1_derefidx_vbuxx +txa +tay +lda ({z1}),y +//FRAGMENT vbuxx=pbuz1_derefidx_vbuxx +txa +tay +lda ({z1}),y +tax +//FRAGMENT vbuyy=pbuz1_derefidx_vbuxx +txa +tay +lda ({z1}),y +tay +//FRAGMENT vbuz1=pbuz2_derefidx_vbuyy +lda ({z2}),y +sta {z1} +//FRAGMENT vbuaa=pbuz1_derefidx_vbuyy +lda ({z1}),y +//FRAGMENT vbuxx=pbuz1_derefidx_vbuyy +lda ({z1}),y +tax +//FRAGMENT vbuyy=pbuz1_derefidx_vbuyy +lda ({z1}),y +tay +//FRAGMENT vbuz1_lt_vbuxx_then_la1 +cpx {z1} +beq !+ +bcs {la1} +!: +//FRAGMENT vbuz1_lt_vbuyy_then_la1 +cpy {z1} +beq !+ +bcs {la1} +!: +//FRAGMENT vbuz1=vbuz1_plus_1 +inc {z1} +//FRAGMENT vbuz1=vbuaa_bor_vbuxx +stx $ff +ora $ff +sta {z1} +//FRAGMENT vbuaa=vbuaa_bor_vbuxx +stx $ff +ora $ff +//FRAGMENT vbuxx=vbuaa_bor_vbuxx +stx $ff +ora $ff +tax +//FRAGMENT vbuyy=vbuaa_bor_vbuxx +stx $ff +ora $ff +tay +//FRAGMENT vbuxx=vbuaa_bor_vbuyy +sty $ff +ora $ff +tax +//FRAGMENT vbuyy=vbuaa_bor_vbuyy +sty $ff +ora $ff +tay +//FRAGMENT vwuz1=_inc_vwuz2 +clc +lda {z2} +adc #1 +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz2_band_vbuc1 +lda #{c1} +and {z2} +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuz1_band_vbuc1 +lda #{c1} +and {z1} +sta {z1} +lda #0 +sta {z1}+1 +//FRAGMENT vbuz1=_inc_vbuz2 +lda {z2} +inc +sta {z1} +//FRAGMENT vbuaa=_inc_vbuz1 +lda {z1} +inc +//FRAGMENT vbuxx=_inc_vbuz1 +ldx {z1} +inx +//FRAGMENT vbuz1=_inc_vbuaa +inc +sta {z1} +//FRAGMENT vbuz1=_inc_vbuxx +inx +stx {z1} +//FRAGMENT vbuyy=_inc_vbuz1 +ldy {z1} +iny +//FRAGMENT vbuz1=_inc_vbuyy +iny +sty {z1} +//FRAGMENT _deref_pduc1=vwsc2 +NO_SYNTHESIS +//FRAGMENT pbuc1_derefidx_vbuz1=vbuaa +ldy {z1} +sta {c1},y diff --git a/src/main/kc/include/cx16-vera.h b/src/main/kc/include/cx16-vera.h index 521bb68c8..bae2dcb7a 100644 --- a/src/main/kc/include/cx16-vera.h +++ b/src/main/kc/include/cx16-vera.h @@ -141,20 +141,20 @@ char * const VERA_DC_VSTOP = 0x9f2c; // Configuration work tables // Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles) -byte const VERA_LAYER_CONFIG_WIDTH_32 = 0x00; -byte const VERA_LAYER_CONFIG_WIDTH_64 = 0x10; -byte const VERA_LAYER_CONFIG_WIDTH_128 = 0x20; -byte const VERA_LAYER_CONFIG_WIDTH_256 = 0x30; -byte const VERA_LAYER_CONFIG_WIDTH_MASK = 0x30; -word const VERA_LAYER_CONFIG_WIDTH[4] = {32, 64, 128, 256}; +byte const VERA_LAYER_WIDTH_32 = 0x00; +byte const VERA_LAYER_WIDTH_64 = 0x10; +byte const VERA_LAYER_WIDTH_128 = 0x20; +byte const VERA_LAYER_WIDTH_256 = 0x30; +byte const VERA_LAYER_WIDTH_MASK = 0x30; +word const VERA_LAYER_WIDTH[4] = {32, 64, 128, 256}; // Bit 6-7: Map Height (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles) -byte const VERA_LAYER_CONFIG_HEIGHT_32 = 0x00; -byte const VERA_LAYER_CONFIG_HEIGHT_64 = 0x40; -byte const VERA_LAYER_CONFIG_HEIGHT_128 = 0x80; -byte const VERA_LAYER_CONFIG_HEIGHT_256 = 0xC0; -byte const VERA_LAYER_CONFIG_HEIGHT_MASK = 0xC0; -word const VERA_LAYER_CONFIG_HEIGHT[4] = {32, 64, 128, 256}; +byte const VERA_LAYER_HEIGHT_32 = 0x00; +byte const VERA_LAYER_HEIGHT_64 = 0x40; +byte const VERA_LAYER_HEIGHT_128 = 0x80; +byte const VERA_LAYER_HEIGHT_256 = 0xC0; +byte const VERA_LAYER_HEIGHT_MASK = 0xC0; +word const VERA_LAYER_HEIGHT[4] = {32, 64, 128, 256}; // Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp) byte const VERA_LAYER_COLOR_DEPTH_1BPP = 0x00; @@ -178,6 +178,13 @@ char * const VERA_L0_MAPBASE = 0x9f2e; // $9F2F L0_TILEBASE Layer 0 Tile Base // Bit 2-7: Tile Base Address (16:11) // Bit 1: Tile Height (0:8 pixels, 1:16 pixels) +byte const VERA_TILEBASE_WIDTH_8 = 0x00; +byte const VERA_TILEBASE_WIDTH_16 = 0x01; +byte const VERA_TILEBASE_WIDTH_MASK = 0x01; +byte const VERA_TILEBASE_HEIGHT_8 = 0x00; +byte const VERA_TILEBASE_HEIGHT_16 = 0x02; +byte const VERA_TILEBASE_HEIGHT_MASK = 0x02; +byte const VERA_TILEBASE_MASK = 0xfC; // Bit 0: Tile Width (0:8 pixels, 1:16 pixels) char * const VERA_L0_TILEBASE = 0x9f2f; // $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0) diff --git a/src/main/kc/lib/veralib.c b/src/main/kc/lib/veralib.c index 0bf5221d4..1ed0b60f5 100644 --- a/src/main/kc/lib/veralib.c +++ b/src/main/kc/lib/veralib.c @@ -9,6 +9,21 @@ // --- VERA function encapsulation --- // --- VERA layer management --- + +word vera_mapbase_word[2] = {0,0}; +byte vera_mapbase_bank[2] = {0,0}; +dword vera_mapbase_dword[2] = {0,0}; + +word vera_tilebase_word[2] = {0,0}; +byte vera_tilebase_bank[2] = {0,0}; +dword vera_tilebase_dword[2] = {0,0}; + +byte vera_row_shift[2] = {0,0}; + +const byte vera_layer_hflip[2] = {0,0x04}; +const byte vera_layer_vflip[2] = {0,0x08}; + + byte* vera_layer_config[2] = {VERA_L0_CONFIG, VERA_L1_CONFIG}; byte vera_layer_enable[2] = { VERA_LAYER0_ENABLE, VERA_LAYER1_ENABLE }; @@ -46,6 +61,19 @@ void vera_vram_address1(dword bankaddr, byte incr) { *VERA_ADDRX_H = <(*word_h) | incr; } +// Get the map base address of the tiles for the layer. +// - layer: Value of 0 or 1. +// - return: Specifies the map base address of the layer, which is returned as a dword. +// Note that the register only specifies bits 16:9 of the 17 total bit-address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes! +dword vera_get_layer_mapbase_address(byte layer) { + layer &= $1; + byte mapbase = *vera_layer_mapbase[layer]; + dword address = mapbase; + address <<= 8; + address <<= 1; + return address; +} // --- VERA layer management --- // Set the configuration of the layer. @@ -70,58 +98,58 @@ char vera_get_layer_config(char layer) { // - layer: Value of 0 or 1. inline void vera_set_layer_map_width_32(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK; - *addr |= VERA_LAYER_CONFIG_WIDTH_32; + *addr &= ~VERA_LAYER_WIDTH_MASK; + *addr |= VERA_LAYER_WIDTH_32; } inline void vera_set_layer_map_width_64(unsigned byte layer) { byte* addr = vera_layer_config[layer]; //*addr &= (~VERA_CONFIG_WIDTH_MASK) | VERA_CONFIG_WIDTH_64; - *addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK; - *addr |= VERA_LAYER_CONFIG_WIDTH_64; + *addr &= ~VERA_LAYER_WIDTH_MASK; + *addr |= VERA_LAYER_WIDTH_64; } inline void vera_set_layer_map_width_128(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK; - *addr |= VERA_LAYER_CONFIG_WIDTH_128; + *addr &= ~VERA_LAYER_WIDTH_MASK; + *addr |= VERA_LAYER_WIDTH_128; } inline void vera_set_layer_map_width_256(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK; - *addr |= VERA_LAYER_CONFIG_WIDTH_256; + *addr &= ~VERA_LAYER_WIDTH_MASK; + *addr |= VERA_LAYER_WIDTH_256; } inline void vera_set_layer_map_height_32(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK; - *addr |= VERA_LAYER_CONFIG_HEIGHT_32; + *addr &= ~VERA_LAYER_HEIGHT_MASK; + *addr |= VERA_LAYER_HEIGHT_32; } inline void vera_set_layer_map_height_64(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK; - *addr |= VERA_LAYER_CONFIG_HEIGHT_64; + *addr &= ~VERA_LAYER_HEIGHT_MASK; + *addr |= VERA_LAYER_HEIGHT_64; } inline void vera_set_layer_map_height_128(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK; - *addr |= VERA_LAYER_CONFIG_HEIGHT_128; + *addr &= ~VERA_LAYER_HEIGHT_MASK; + *addr |= VERA_LAYER_HEIGHT_128; } inline void vera_set_layer_map_height_256(unsigned byte layer) { byte* addr = vera_layer_config[layer]; - *addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK; - *addr |= VERA_LAYER_CONFIG_HEIGHT_256; + *addr &= ~VERA_LAYER_HEIGHT_MASK; + *addr |= VERA_LAYER_HEIGHT_256; } // Get the map width or height of the layer. // - layer: Value of 0 or 1. word vera_get_layer_map_width(unsigned byte layer) { byte* config = vera_layer_config[layer]; - byte mask = (byte)VERA_LAYER_CONFIG_WIDTH_MASK; - return VERA_LAYER_CONFIG_WIDTH[ (*config & mask) >> 4]; + byte mask = (byte)VERA_LAYER_WIDTH_MASK; + return VERA_LAYER_WIDTH[ (*config & mask) >> 4]; } word vera_get_layer_map_height(unsigned byte layer) { byte* config = vera_layer_config[layer]; - byte mask = VERA_LAYER_CONFIG_HEIGHT_MASK; - return VERA_LAYER_CONFIG_HEIGHT[ (*config & mask) >> 6]; + byte mask = VERA_LAYER_HEIGHT_MASK; + return VERA_LAYER_HEIGHT[ (*config & mask) >> 6]; } // Set the color depth of the layer in terms of bit per pixel (BPP) of the tile base. @@ -308,3 +336,129 @@ inline void vera_set_layer_vertical_scroll(byte layer, word scroll) { *vera_layer_vscroll_l[layer] = scroll; } + + +void vera_mode_tile(byte layer, dword mapbase_dw, dword tilebase_dw, word mapwidth, word mapheight, byte tilewidth, byte tileheight, byte color_depth ) { + // config + byte config = 0x00; + switch(color_depth) { + case 1: + config |= VERA_LAYER_COLOR_DEPTH_1BPP; + break; + case 2: + config |= VERA_LAYER_COLOR_DEPTH_2BPP; + break; + case 4: + config |= VERA_LAYER_COLOR_DEPTH_4BPP; + break; + case 8: + config |= VERA_LAYER_COLOR_DEPTH_8BPP; + break; + } + + switch(mapwidth) { + case 32: + config |= VERA_LAYER_WIDTH_32; + vera_row_shift[layer] = 6; + break; + case 64: + config |= VERA_LAYER_WIDTH_64; + vera_row_shift[layer] = 7; + break; + case 128: + config |= VERA_LAYER_WIDTH_128; + vera_row_shift[layer] = 8; + break; + case 256: + config |= VERA_LAYER_WIDTH_256; + vera_row_shift[layer] = 9; + break; + } + switch(mapheight) { + case 32: + config |= VERA_LAYER_HEIGHT_32; + break; + case 64: + config |= VERA_LAYER_HEIGHT_64; + break; + case 128: + config |= VERA_LAYER_HEIGHT_128; + break; + case 256: + config |= VERA_LAYER_HEIGHT_256; + break; + } + vera_set_layer_config(layer, config); + + // mapbase + vera_mapbase_word[layer] = mapbase_dw; + vera_mapbase_dword[layer] = mapbase_dw; + + mapbase_dw = mapbase_dw >> 1; + byte mapbase = (byte)<(mapbase_dw >> 8); + vera_set_layer_mapbase(layer,mapbase); + + + //printf("%lx\n",mapbase_dw); + + // tilebase + vera_tilebase_word[layer] = tilebase_dw; + vera_tilebase_dword[layer] = tilebase_dw; + + //printf("tilebase word = %x\n",vera_tilebase_word[layer]); + //printf("tilebase bank = %x\n",vera_tilebase_bank[layer]); + //printf("tilebase dword = %lx\n",vera_tilebase_dword[layer]); + + tilebase_dw = tilebase_dw >> 1; + byte tilebase = (byte)<(tilebase_dw >> 8); + tilebase &= VERA_TILEBASE_MASK; + switch(tilewidth) { + case 8: + tilebase |= VERA_TILEBASE_WIDTH_8; + break; + case 16: + tilebase |= VERA_TILEBASE_WIDTH_16; + break; + } + switch(tileheight) { + case 8: + tilebase |= VERA_TILEBASE_HEIGHT_8; + break; + case 16: + tilebase |= VERA_TILEBASE_HEIGHT_16; + break; + } + //printf("tilebase = %x\n",tilebase); + vera_set_layer_tilebase(layer,tilebase); +} + +// --- TILE FUNCTIONS --- + +void vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) { + + dword mapbase = vera_mapbase_dword[layer]; + byte shift = vera_row_shift[layer]; + word rowskip = (word)1 << shift; + hflip = vera_layer_hflip[hflip]; + vflip = vera_layer_vflip[vflip]; + offset = offset << 4; + byte index_l = tileindex; + index_h |= hflip; + index_h |= vflip; + index_h |= offset; + mapbase += ((word)y << shift); + mapbase += (x << 1); + for(byte r=0; r -#include -#include <6502.h> - -void main() { - - textcolor(WHITE); - bgcolor(BLACK); - clrscr(); - - // Now we set the tile map width and height. - vera_set_layer_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! - vera_set_layer_config(0, vera_get_layer_config(1)); - vera_set_layer_color_depth_2BPP(0); - vera_set_layer_tilebase(0, 0xA0); - vera_set_layer_map_width_128(0); - vera_set_layer_map_height_64(0); - dword tilebase = vera_get_layer_tilebase_address(0); - vera_show_layer(0); - - byte tile[64] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, - 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - - byte map[16] = {0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00}; - - memcpy_to_vram(1, 0x4000, tile, 64); - memcpy_to_vram(1, 0x0000, map, 16); - - tilebase = 0; - dword mapbase = ver_get_vera_layer_mapbase_address(0); - - for(byte y:0..15) { - tilerow = tilebase; - for(byte r:0..3) { - tilecolumn = tilerow; - for(byte x:0..15) { - for(byte c: 0..1) { - vera_vram_address0(mapbase,VERA_INC_1); - *VERA_DATA0 = map[x]; - *VERA_DATA0 = map[x]; - } - byte bit = data; - tilecolumn += 8; - printf(""); - } - //printf("\n"); - tilerow += 1; - } - } - - - while(!kbhit()); - - screenlayer(0); - scroll(1); // Scrolling on conio is activated, so conio will not output beyond the borders of the visible screen. - textcolor(WHITE); - bgcolor(GREEN); - - draw_characters(tilebase); - - while(!kbhit()); - - // Enable VSYNC IRQ (also set line bit 8 to 0) - SEI(); - *KERNEL_IRQ = &irq_vsync; - *VERA_IEN = VERA_VSYNC; - CLI(); - - - vera_hide_layer(0); - textcolor(GREY); - bgcolor(GREEN); - draw_characters(tilebase); - vera_show_layer(0); - - screenlayer(1); - - textcolor(WHITE); - bgcolor(BLACK); - printf("\n\nthis demo displays the design of the standard x16 commander\n"); - printf("character set on the vera layer 0. it's the character set i grew up with :-).\n"); - printf("\nthe smooth scrolling is implemented by manipulating the scrolling \n"); - printf("registers of layer 0. at each raster line interrupt, \n"); - printf("the x and y scrolling registers are manipulated. the cx16 terminal \n"); - printf("works on layer 1. when layer 0 is enabled with the scrolling, \n"); - printf("it gives a nice background effect. this technique can be used to implement\n"); - printf("smooth scrolling backgrounds using tile layouts in games or demos.\n"); - - textcolor(YELLOW); - printf("\npress a key to continue ..."); - - while(!kbhit()); - - screenlayer(0); - vera_hide_layer(0); - textcolor(DARK_GREY); - bgcolor(BLACK); - draw_characters(tilebase); - vera_show_layer(0); - - screenlayer(1); - gotoxy(0,20); - -} - -void draw_characters(dword tilebase) { - dword tilecolumn = tilebase; - dword tilerow = tilebase; - clrscr(); - - for(byte y:0..15) { - printf("@"); - } -} - -// X sine index -volatile int scroll_x = 0; -volatile int scroll_y = 0; -volatile int delta_x = 2; -volatile int delta_y = 0; -volatile int speed = 2; - -// VSYNC Interrupt Routine -__interrupt(rom_sys_cx16) void irq_vsync() { - - - scroll_x += delta_x; - scroll_y += delta_y; - - if( scroll_x>(128*8-80*8)) { - delta_x = 0; - delta_y = speed; - scroll_x = (128*8-80*8); - } - if( scroll_y>(128*8-60*8)) { - delta_x = -speed; - delta_y = 0; - scroll_y = (128*8-60*8); - } - if(scroll_x<0) { - delta_x = 0; - delta_y = -speed; - scroll_x = 0; - } - if(scroll_y<0) { - delta_x = speed; - delta_y = 0; - scroll_y = 0; - } - - vera_set_layer_horizontal_scroll(0,(word)scroll_x); - vera_set_layer_vertical_scroll(0,(word)scroll_y); - - // Reset the VSYNC interrupt - *VERA_ISR = VERA_VSYNC; -} \ No newline at end of file diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c b/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c new file mode 100644 index 000000000..f698b50e2 --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c @@ -0,0 +1,74 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. +// The CX16 starts in tile map mode, 2BPP in 4 color mode, and uses 8x8 tiles. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + vera_mode_tile(0, 0x04000, 0x14000, 128, 128, 8, 8, 2); + + byte tiles[64] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + byte map[16] = {0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x00,0x03,0x00}; + + memcpy_to_vram(1, 0x4000, tiles, 64); + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 80, 60, 0, 0, 0); + + // Draw 4 squares with each tile, staring from row 2, width 10, height 10, separated by 2 characters. + vera_tile_area(0, 0, 4, 4, 10, 10, 0, 0, 0); + vera_tile_area(0, 1, 16, 4, 10, 10, 0, 0, 0); + vera_tile_area(0, 2, 28, 4, 10, 10, 0, 0, 0); + vera_tile_area(0, 3, 40, 4, 10, 10, 0, 0, 0); + + word tile = 0; + byte offset = 0; + + byte row = 22; + + for(byte r:0..3) { + byte column = 4; + for(byte c:0..15) { + vera_tile_area(0, tile, column, row, 3, 3, 0, 0, offset); + column+=4; + offset++; + } + tile++; + tile &= 0x3; + row += 4; + } + + vera_show_layer(0); + + gotoxy(0,40); + printf("vera in tile mode 8 x 8, color depth 2 bits per pixel.\n"); + + printf("in this mode, tiles are 8 pixels wide and 8 pixels tall.\n"); + printf("each tile can have a variation of 4 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors, and only the first 4 colors\n"); + printf("can be used per offset!\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/ref/examples/cx16/sprites.asm b/src/test/ref/examples/cx16/sprites.asm deleted file mode 100644 index 2fa092ce6..000000000 --- a/src/test/ref/examples/cx16/sprites.asm +++ /dev/null @@ -1,514 +0,0 @@ -// Example program for the Commander X16 -// Displays 32 64*64 TUT sprites -.cpu _65c02 - // Commodore 64 PRG executable file -.file [name="sprites.prg", type="prg", segments="Program"] -.segmentdef Program [segments="Basic, Code, Data"] -.segmentdef Basic [start=$0801] -.segmentdef Code [start=$80d] -.segmentdef Data [startAfter="Code"] -.segment Basic -:BasicUpstart(__start) - .const VERA_INC_1 = $10 - .const VERA_DCSEL = 2 - .const VERA_ADDRSEL = 1 - .const VERA_VSYNC = 1 - // 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 - .const VERA_SPRITES_ENABLE = $40 - // $9F20 VRAM Address (7:0) - .label VERA_ADDRX_L = $9f20 - // $9F21 VRAM Address (15:8) - .label VERA_ADDRX_M = $9f21 - // $9F22 VRAM Address (7:0) - // Bit 4-7: Address Increment The following is the amount incremented per value value:increment - // 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640 - // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. - // Bit 0: VRAM Address (16) - .label VERA_ADDRX_H = $9f22 - // $9F23 DATA0 VRAM Data port 0 - .label VERA_DATA0 = $9f23 - // $9F25 CTRL Control - // Bit 7: Reset - // Bit 1: DCSEL - // Bit 2: ADDRSEL - .label VERA_CTRL = $9f25 - // $9F26 IEN Interrupt Enable - // Bit 7: IRQ line (8) - // Bit 3: AFLOW - // Bit 2: SPRCOL - // Bit 1: LINE - // Bit 0: VSYNC - .label VERA_IEN = $9f26 - // $9F27 ISR Interrupt Status - // Interrupts will be generated for the interrupt sources set in the lower 4 bits of IEN. ISR will indicate the interrupts that have occurred. - // Writing a 1 to one of the lower 3 bits in ISR will clear that interrupt status. AFLOW can only be cleared by filling the audio FIFO for at least 1/4. - // Bit 4-7: Sprite Collisions. This field indicates which groups of sprites have collided. - // Bit 3: AFLOW - // Bit 2: SPRCOL - // Bit 1: LINE - // Bit 0: VSYNC - .label VERA_ISR = $9f27 - // $9F29 DC_VIDEO (DCSEL=0) - // Bit 7: Current Field Read-only bit which reflects the active interlaced field in composite and RGB modes. (0: even, 1: odd) - // Bit 6: Sprites Enable Enable output from the Sprites renderer - // Bit 5: Layer1 Enable Enable output from the Layer1 renderer - // Bit 4: Layer0 Enable Enable output from the Layer0 renderer - // Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.) - // Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector) - .label VERA_DC_VIDEO = $9f29 - // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts - .label KERNEL_IRQ = $314 - // X sine index - .label sin_idx_x = $12 - // Y sine index - .label sin_idx_y = $14 -.segment Code -__start: { - // sin_idx_x = 119 - lda #<$77 - sta.z sin_idx_x - lda #>$77 - sta.z sin_idx_x+1 - // sin_idx_y = 79 - lda #<$4f - sta.z sin_idx_y - lda #>$4f - sta.z sin_idx_y+1 - jsr main - rts -} -// VSYNC Interrupt Routine -irq_vsync: { - .const vram_sprite_attr_bank = VERA_SPRITE_ATTR>>$10 - .label __11 = $16 - .label __12 = $18 - .label i_x = 3 - .label i_y = 5 - .label vram_sprite_pos = 7 - .label s = 2 - .label __13 = $16 - .label __14 = $18 - // 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 #>SINX_LEN - bne __b1 - lda.z sin_idx_x - cmp #$ffff - bne __b2 - lda.z sin_idx_y - cmp #<$ffff - bne __b2 - // sin_idx_y = SINY_LEN-1 - lda #SINY_LEN-1 - sta.z sin_idx_y+1 - __b2: - // i_x = sin_idx_x - lda.z sin_idx_x - sta.z i_x - lda.z sin_idx_x+1 - sta.z i_x+1 - // i_y = sin_idx_y - lda.z sin_idx_y - sta.z i_y - lda.z sin_idx_y+1 - sta.z i_y+1 - lda #VERA_SPRITE_ATTR+2&$ffff - sta.z vram_sprite_pos+1 - lda #0 - sta.z s - __b5: - // for(char s=0;sSINX - sta.z __13+1 - ldy #0 - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - iny - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // SPRITE_ATTR.Y = SINY[i_y] - lda.z i_y - asl - sta.z __12 - lda.z i_y+1 - rol - sta.z __12+1 - clc - lda.z __14 - adc #SINY - sta.z __14+1 - ldy #0 - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - iny - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // memcpy_to_vram(vram_sprite_attr_bank, vram_sprite_pos, &SPRITE_ATTR+2, 4) - lda.z vram_sprite_pos - sta.z memcpy_to_vram.vdest - lda.z vram_sprite_pos+1 - sta.z memcpy_to_vram.vdest+1 - // Copy sprite positions to VRAM (the 4 relevant bytes in VERA_SPRITE_ATTR) - lda #<4 - sta.z memcpy_to_vram.num - lda #>4 - sta.z memcpy_to_vram.num+1 - lda #SPRITE_ATTR+2 - sta.z memcpy_to_vram.src+1 - ldx #vram_sprite_attr_bank - jsr memcpy_to_vram - // vram_sprite_pos += sizeof(SPRITE_ATTR) - lda #SIZEOF_STRUCT_VERA_SPRITE - clc - adc.z vram_sprite_pos - sta.z vram_sprite_pos - bcc !+ - inc.z vram_sprite_pos+1 - !: - // i_x += 25 - lda #$19 - clc - adc.z i_x - sta.z i_x - bcc !+ - inc.z i_x+1 - !: - // if(i_x>=SINX_LEN) - lda.z i_x+1 - bne !+ - lda.z i_x - cmp #SINX_LEN - bcc __b8 - !: - // i_x -= SINX_LEN - sec - lda.z i_x - sbc #SINX_LEN - sta.z i_x - lda.z i_x+1 - sbc #0 - sta.z i_x+1 - __b8: - // i_y += 19 - lda #$13 - clc - adc.z i_y - sta.z i_y - bcc !+ - inc.z i_y+1 - !: - // if(i_y>=SINY_LEN) - lda.z i_y+1 - bne !+ - lda.z i_y - cmp #SINY_LEN - bcc __b9 - !: - // i_y -= SINY_LEN - sec - lda.z i_y - sbc #SINY_LEN - sta.z i_y - lda.z i_y+1 - sbc #0 - sta.z i_y+1 - __b9: - // for(char s=0;sSPRITE_PIXELS_VRAM, $40*$40 - sta.z memcpy_to_vram.num+1 - lda #SPRITE_PIXELS - sta.z memcpy_to_vram.src+1 - ldx #0 - 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 - sta.z vram_sprite_attr+1 - lda #0 - sta.z s - __b1: - // for(char s=0;sirq_vsync - sta KERNEL_IRQ+1 - // *VERA_IEN = VERA_VSYNC - lda #VERA_VSYNC - sta VERA_IEN - // asm - cli - // } - rts - __b2: - // SPRITE_ATTR.X += 10 - lda #<$a - clc - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - lda #>$a - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // SPRITE_ATTR.Y += 10 - lda #<$a - clc - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - lda #>$a - 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)) - lda.z vram_sprite_attr - sta.z memcpy_to_vram.vdest - lda.z vram_sprite_attr+1 - sta.z memcpy_to_vram.vdest+1 - lda #SIZEOF_STRUCT_VERA_SPRITE - sta.z memcpy_to_vram.num+1 - lda #SPRITE_ATTR - sta.z memcpy_to_vram.src+1 - ldx #VERA_SPRITE_ATTR>>$10 - jsr memcpy_to_vram - // vram_sprite_attr += sizeof(SPRITE_ATTR) - lda #SIZEOF_STRUCT_VERA_SPRITE - clc - adc.z vram_sprite_attr - sta.z vram_sprite_attr - bcc !+ - inc.z vram_sprite_attr+1 - !: - // for(char s=0;svdest - lda.z vdest+1 - // *VERA_ADDRX_M = >vdest - sta VERA_ADDRX_M - // VERA_INC_1 | vbank - txa - ora #VERA_INC_1 - // *VERA_ADDRX_H = VERA_INC_1 | vbank - sta VERA_ADDRX_H - // end = (char*)src+num - lda.z end - clc - adc.z src - sta.z end - lda.z end+1 - adc.z src+1 - sta.z end+1 - __b1: - // for(char *s = src; s!=end; s++) - lda.z s+1 - cmp.z end+1 - bne __b2 - lda.z s - cmp.z end - bne __b2 - // } - rts - __b2: - // *VERA_DATA0 = *s - ldy #0 - lda (s),y - sta VERA_DATA0 - // for(char *s = src; s!=end; s++) - inc.z s - bne !+ - inc.z s+1 - !: - jmp __b1 -} -.segment Data - // A 64*64 8bpp TUT sprite and palette - .align $1000 -SPRITE_PIXELS: -.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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - - .align $100 -SINX: -.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - - .align $100 -SINY: -.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 - .byte $c, $f0 diff --git a/src/test/ref/examples/cx16/sprites.cfg b/src/test/ref/examples/cx16/sprites.cfg deleted file mode 100644 index dea836c69..000000000 --- a/src/test/ref/examples/cx16/sprites.cfg +++ /dev/null @@ -1,150 +0,0 @@ - -void __start() -__start: scope:[__start] from - [0] phi() - to:__start::__init1 -__start::__init1: scope:[__start] from __start - [1] sin_idx_x = $77 - [2] sin_idx_y = $4f - to:__start::@1 -__start::@1: scope:[__start] from __start::__init1 - [3] phi() - [4] call main - to:__start::@return -__start::@return: scope:[__start] from __start::@1 - [5] return - to:@return - -__interrupt(rom_sys_cx16) void irq_vsync() -irq_vsync: scope:[irq_vsync] from - [6] sin_idx_x = ++ sin_idx_x - [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 - to:irq_vsync::@1 -irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3 - [9] sin_idx_y = -- sin_idx_y - [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 = 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 - [13] irq_vsync::i_y#0 = sin_idx_y - to:irq_vsync::@5 -irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2 irq_vsync::@9 - [14] irq_vsync::vram_sprite_pos#2 = phi( irq_vsync::@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 - [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 - [68] return - to:@return -memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [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/sprites.log b/src/test/ref/examples/cx16/sprites.log deleted file mode 100644 index 4c836c5ed..000000000 --- a/src/test/ref/examples/cx16/sprites.log +++ /dev/null @@ -1,2598 +0,0 @@ -Resolved forward reference irq_vsync to __interrupt(rom_sys_cx16) 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 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() irq_vsync::$6 = sizeof SPRITE_ATTR -Inlined call call SEI -Inlined call call CLI -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 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#4 - *VERA_ADDRX_L = memcpy_to_vram::$0 - 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#4 - *VERA_ADDRX_H = memcpy_to_vram::$2 - 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#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 ) - memcpy_to_vram::s#2 = phi( memcpy_to_vram/memcpy_to_vram::s#0, memcpy_to_vram::@2/memcpy_to_vram::s#1 ) - memcpy_to_vram::$4 = memcpy_to_vram::s#2 != memcpy_to_vram::end#1 - if(memcpy_to_vram::$4) goto memcpy_to_vram::@2 - to:memcpy_to_vram::@return -memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - memcpy_to_vram::end#2 = phi( memcpy_to_vram::@1/memcpy_to_vram::end#1 ) - memcpy_to_vram::s#3 = phi( memcpy_to_vram::@1/memcpy_to_vram::s#2 ) - *VERA_DATA0 = *memcpy_to_vram::s#3 - memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#3 - to:memcpy_to_vram::@1 -memcpy_to_vram::@return: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - return - to:@return - -void main() -main: scope:[main] from __start::@1 - memcpy_to_vram::vbank#0 = (byte)>SPRITE_PIXELS_VRAM - memcpy_to_vram::vdest#0 = (void*)VERA_PALETTE - memcpy_to_vram::vdest#1 = (void*)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::$5 - call memcpy_to_vram - 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::s#1 = ++ main::s#3 - to:main::@1 -main::@3: scope:[main] from main::@1 - *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL - *VERA_DC_VIDEO = *VERA_DC_VIDEO | VERA_SPRITES_ENABLE - to:main::SEI1 -main::SEI1: scope:[main] from main::@3 - asm { sei } - to:main::@4 -main::@4: scope:[main] from main::SEI1 - *KERNEL_IRQ = &irq_vsync - *VERA_IEN = VERA_VSYNC - to:main::CLI1 -main::CLI1: scope:[main] from main::@4 - asm { cli } - to:main::@return -main::@return: scope:[main] from main::CLI1 - return - to:@return - -__interrupt(rom_sys_cx16) void irq_vsync() -irq_vsync: scope:[irq_vsync] from - sin_idx_x = ++ sin_idx_x - 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 -irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3 - sin_idx_y = -- sin_idx_y - irq_vsync::$2 = sin_idx_y == $ffff - irq_vsync::$3 = ! irq_vsync::$2 - if(irq_vsync::$3) goto irq_vsync::@2 - to:irq_vsync::@4 -irq_vsync::@3: scope:[irq_vsync] from irq_vsync - sin_idx_x = 0 - to:irq_vsync::@1 -irq_vsync::@2: scope:[irq_vsync] from irq_vsync::@1 irq_vsync::@4 - irq_vsync::vram_sprite_pos#0 = (byte*)= SINX_LEN - irq_vsync::$8 = ! irq_vsync::$7 - if(irq_vsync::$8) goto irq_vsync::@8 - to:irq_vsync::@10 -irq_vsync::@7: scope:[irq_vsync] from irq_vsync::@5 - *VERA_ISR = VERA_VSYNC - asm { jmp$e034 } - to:irq_vsync::@return -irq_vsync::@8: scope:[irq_vsync] from irq_vsync::@10 irq_vsync::@12 - irq_vsync::vram_sprite_pos#7 = phi( irq_vsync::@10/irq_vsync::vram_sprite_pos#8, irq_vsync::@12/irq_vsync::vram_sprite_pos#1 ) - irq_vsync::i_x#9 = phi( irq_vsync::@10/irq_vsync::i_x#2, irq_vsync::@12/irq_vsync::i_x#1 ) - 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 + $13 - 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 -irq_vsync::@10: scope:[irq_vsync] from irq_vsync::@12 - irq_vsync::vram_sprite_pos#8 = phi( irq_vsync::@12/irq_vsync::vram_sprite_pos#1 ) - 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 - 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 ) - irq_vsync::i_y#9 = phi( irq_vsync::@11/irq_vsync::i_y#2, irq_vsync::@8/irq_vsync::i_y#1 ) - irq_vsync::i_x#7 = phi( irq_vsync::@11/irq_vsync::i_x#8, irq_vsync::@8/irq_vsync::i_x#9 ) - irq_vsync::s#3 = phi( irq_vsync::@11/irq_vsync::s#4, irq_vsync::@8/irq_vsync::s#5 ) - irq_vsync::s#1 = ++ irq_vsync::s#3 - to:irq_vsync::@5 -irq_vsync::@11: scope:[irq_vsync] from irq_vsync::@8 - irq_vsync::vram_sprite_pos#6 = phi( irq_vsync::@8/irq_vsync::vram_sprite_pos#7 ) - 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 - SINY_LEN - to:irq_vsync::@9 -irq_vsync::@return: scope:[irq_vsync] from irq_vsync::@7 - return - to:@return - -void __start() -__start: scope:[__start] from - to:__start::__init1 -__start::__init1: scope:[__start] from __start - sin_idx_x = $77 - sin_idx_y = $4f - to:__start::@1 -__start::@1: scope:[__start] from __start::__init1 - call main - to:__start::@2 -__start::@2: scope:[__start] from __start::@1 - to:__start::@return -__start::@return: scope:[__start] from __start::@2 - return - to:@return - -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[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - }} -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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - }} -const nomodify dword SPRITE_PIXELS_VRAM = $8000 -const nomodify byte VERA_ADDRSEL = 1 -const nomodify byte* VERA_ADDRX_H = (byte*)$9f22 -const nomodify byte* VERA_ADDRX_L = (byte*)$9f20 -const nomodify byte* VERA_ADDRX_M = (byte*)$9f21 -const nomodify byte* VERA_CTRL = (byte*)$9f25 -const nomodify byte* VERA_DATA0 = (byte*)$9f23 -const nomodify byte VERA_DCSEL = 2 -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 -const nomodify byte VERA_VSYNC = 1 -void __start() -__interrupt(rom_sys_cx16) void irq_vsync() -bool~ irq_vsync::$0 -bool~ irq_vsync::$1 -bool~ irq_vsync::$10 -word~ irq_vsync::$11 -word~ irq_vsync::$12 -bool~ irq_vsync::$2 -bool~ irq_vsync::$3 -bool~ irq_vsync::$4 -byte~ irq_vsync::$6 -bool~ irq_vsync::$7 -bool~ irq_vsync::$8 -bool~ irq_vsync::$9 -word irq_vsync::i_x -word irq_vsync::i_x#0 -word irq_vsync::i_x#1 -word irq_vsync::i_x#2 -word irq_vsync::i_x#3 -word irq_vsync::i_x#4 -word irq_vsync::i_x#5 -word irq_vsync::i_x#6 -word irq_vsync::i_x#7 -word irq_vsync::i_x#8 -word irq_vsync::i_x#9 -word irq_vsync::i_y -word irq_vsync::i_y#0 -word irq_vsync::i_y#1 -word irq_vsync::i_y#2 -word irq_vsync::i_y#3 -word irq_vsync::i_y#4 -word irq_vsync::i_y#5 -word irq_vsync::i_y#6 -word irq_vsync::i_y#7 -word irq_vsync::i_y#8 -word irq_vsync::i_y#9 -byte irq_vsync::s -byte irq_vsync::s#0 -byte irq_vsync::s#1 -byte irq_vsync::s#2 -byte irq_vsync::s#3 -byte irq_vsync::s#4 -byte irq_vsync::s#5 -byte irq_vsync::s#6 -byte irq_vsync::s#7 -byte irq_vsync::s#8 -const nomodify byte irq_vsync::vram_sprite_attr_bank = (byte)>VERA_SPRITE_ATTR -byte* irq_vsync::vram_sprite_pos -byte* irq_vsync::vram_sprite_pos#0 -byte* irq_vsync::vram_sprite_pos#1 -byte* irq_vsync::vram_sprite_pos#2 -byte* irq_vsync::vram_sprite_pos#3 -byte* irq_vsync::vram_sprite_pos#4 -byte* irq_vsync::vram_sprite_pos#5 -byte* irq_vsync::vram_sprite_pos#6 -byte* irq_vsync::vram_sprite_pos#7 -byte* irq_vsync::vram_sprite_pos#8 -void main() -bool~ main::$4 -byte~ main::$5 -byte~ main::$7 -byte main::s -byte main::s#0 -byte main::s#1 -byte main::s#2 -byte main::s#3 -byte main::s#4 -byte* main::vram_sprite_attr -byte* main::vram_sprite_attr#0 -byte* main::vram_sprite_attr#1 -byte* main::vram_sprite_attr#2 -byte* main::vram_sprite_attr#3 -byte* main::vram_sprite_attr#4 -void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num) -byte~ memcpy_to_vram::$0 -byte~ memcpy_to_vram::$1 -byte~ memcpy_to_vram::$2 -byte*~ memcpy_to_vram::$3 -bool~ memcpy_to_vram::$4 -byte*~ memcpy_to_vram::$5 -byte* memcpy_to_vram::end -byte* memcpy_to_vram::end#0 -byte* memcpy_to_vram::end#1 -byte* memcpy_to_vram::end#2 -word memcpy_to_vram::num -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 -byte* memcpy_to_vram::s#2 -byte* memcpy_to_vram::s#3 -void* memcpy_to_vram::src -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) = SINX_LEN -Inversing boolean not [93] irq_vsync::$10 = irq_vsync::i_y#1 < SINY_LEN from [92] 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 -Alias memcpy_to_vram::end#1 = memcpy_to_vram::end#2 -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#2 = main::$5 -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 -Alias irq_vsync::s#2 = irq_vsync::s#8 irq_vsync::s#7 irq_vsync::s#6 -Alias irq_vsync::i_x#1 = irq_vsync::i_x#5 -Alias irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#8 -Alias irq_vsync::i_y#1 = irq_vsync::i_y#5 -Alias irq_vsync::s#4 = irq_vsync::s#5 -Alias irq_vsync::i_x#8 = irq_vsync::i_x#9 -Alias irq_vsync::vram_sprite_pos#6 = irq_vsync::vram_sprite_pos#7 -Successful SSA optimization Pass2AliasElimination -Alias irq_vsync::i_y#3 = irq_vsync::i_y#4 -Alias irq_vsync::s#2 = irq_vsync::s#4 irq_vsync::s#3 -Alias irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#6 irq_vsync::vram_sprite_pos#5 -Alias irq_vsync::i_x#7 = irq_vsync::i_x#8 -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 [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#2 = (void*)&SPRITE_ATTR -Constant main::$7 = SIZEOF_STRUCT_VERA_SPRITE -Constant irq_vsync::vram_sprite_pos#0 = (byte*)SPRITE_PIXELS_VRAM in -Successful SSA optimization PassNSimplifyConstantZero -Simplifying constant integer cast 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::$7 = 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 -Finalized unsigned number type (byte) $40 -Finalized unsigned number type (byte) $40 -Finalized unsigned number type (word) $200 -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) $40 -Finalized unsigned number type (byte) $40 -Finalized unsigned number type (byte) $40 -Finalized unsigned number type (byte) $40 -Successful SSA optimization PassNFinalizeNumberTypeConversions -Simplifying constant integer cast $140-$20 -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) -Adding NOP phi() at start of __start -Adding NOP phi() at start of __start::@1 -Adding NOP phi() at start of __start::@2 -Adding NOP phi() at start of 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: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#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 -Coalesced [44] irq_vsync::i_x#11 = irq_vsync::i_x#7 -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 [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::@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 - -void __start() -__start: scope:[__start] from - [0] phi() - to:__start::__init1 -__start::__init1: scope:[__start] from __start - [1] sin_idx_x = $77 - [2] sin_idx_y = $4f - to:__start::@1 -__start::@1: scope:[__start] from __start::__init1 - [3] phi() - [4] call main - to:__start::@return -__start::@return: scope:[__start] from __start::@1 - [5] return - to:@return - -__interrupt(rom_sys_cx16) void irq_vsync() -irq_vsync: scope:[irq_vsync] from - [6] sin_idx_x = ++ sin_idx_x - [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 - to:irq_vsync::@1 -irq_vsync::@1: scope:[irq_vsync] from irq_vsync irq_vsync::@3 - [9] sin_idx_y = -- sin_idx_y - [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 = 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 - [13] irq_vsync::i_y#0 = sin_idx_y - to:irq_vsync::@5 -irq_vsync::@5: scope:[irq_vsync] from irq_vsync::@2 irq_vsync::@9 - [14] irq_vsync::vram_sprite_pos#2 = phi( irq_vsync::@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 - [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 - [68] return - to:@return -memcpy_to_vram::@2: scope:[memcpy_to_vram] from memcpy_to_vram::@1 - [69] *VERA_DATA0 = *memcpy_to_vram::s#2 - [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 - to:memcpy_to_vram::@1 - - -VARIABLE REGISTER WEIGHTS -struct VERA_SPRITE SPRITE_ATTR loadstore = { ADDR: $77 - sta.z sin_idx_x+1 - // [2] sin_idx_y = $4f -- vwuz1=vwuc1 - lda #<$4f - sta.z sin_idx_y - lda #>$4f - sta.z sin_idx_y+1 - // [3] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] - __b1_from___init1: - jmp __b1 - // __start::@1 - __b1: - // [4] call main - // [37] phi from __start::@1 to main [phi:__start::@1->main] - main_from___b1: - jsr main - jmp __breturn - // __start::@return - __breturn: - // [5] return - rts -} - // irq_vsync -// VSYNC Interrupt Routine -irq_vsync: { - .const vram_sprite_attr_bank = VERA_SPRITE_ATTR>>$10 - .label __11 = $16 - .label __12 = $18 - .label i_x = 3 - .label i_y = 5 - .label vram_sprite_pos = 7 - .label s = 2 - .label __13 = $16 - .label __14 = $18 - // interrupt(isr_rom_sys_cx16_entry) -- isr_rom_sys_cx16_entry - // [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!=SINX_LEN) goto irq_vsync::@1 -- vwuz1_neq_vwuc1_then_la1 - lda.z sin_idx_x+1 - cmp #>SINX_LEN - bne __b1 - lda.z sin_idx_x - cmp #0 - sta.z sin_idx_x+1 - jmp __b1 - // irq_vsync::@1 - __b1: - // [9] sin_idx_y = -- sin_idx_y -- vwuz1=_dec_vwuz1 - lda.z sin_idx_y - bne !+ - dec.z sin_idx_y+1 - !: - dec.z sin_idx_y - // [10] if(sin_idx_y!=$ffff) goto irq_vsync::@2 -- vwuz1_neq_vwuc1_then_la1 - lda.z sin_idx_y+1 - cmp #>$ffff - bne __b2 - lda.z sin_idx_y - cmp #<$ffff - bne __b2 - jmp __b4 - // irq_vsync::@4 - __b4: - // [11] sin_idx_y = SINY_LEN-1 -- vwuz1=vbuc1 - lda #SINY_LEN-1 - sta.z sin_idx_y+1 - jmp __b2 - // irq_vsync::@2 - __b2: - // [12] irq_vsync::i_x#0 = sin_idx_x -- vwuz1=vwuz2 - lda.z sin_idx_x - sta.z i_x - lda.z sin_idx_x+1 - sta.z i_x+1 - // [13] irq_vsync::i_y#0 = sin_idx_y -- vwuz1=vwuz2 - lda.z sin_idx_y - sta.z i_y - lda.z sin_idx_y+1 - sta.z i_y+1 - // [14] phi from irq_vsync::@2 to irq_vsync::@5 [phi:irq_vsync::@2->irq_vsync::@5] - __b5_from___b2: - // [14] phi irq_vsync::vram_sprite_pos#2 = (byte*)irq_vsync::@5#0] -- pbuz1=pbuc1 - lda #VERA_SPRITE_ATTR+2&$ffff - sta.z vram_sprite_pos+1 - // [14] phi irq_vsync::i_y#3 = irq_vsync::i_y#0 [phi:irq_vsync::@2->irq_vsync::@5#1] -- register_copy - // [14] phi irq_vsync::i_x#3 = irq_vsync::i_x#0 [phi:irq_vsync::@2->irq_vsync::@5#2] -- register_copy - // [14] phi irq_vsync::s#2 = 0 [phi:irq_vsync::@2->irq_vsync::@5#3] -- vbuz1=vbuc1 - lda #0 - sta.z s - jmp __b5 - // irq_vsync::@5 - __b5: - // [15] if(irq_vsync::s#2<$20) goto irq_vsync::@6 -- vbuz1_lt_vbuc1_then_la1 - lda.z s - cmp #$20 - bcc __b6 - jmp __b7 - // irq_vsync::@7 - __b7: - // [16] *VERA_ISR = VERA_VSYNC -- _deref_pbuc1=vbuc2 - // Reset the VSYNC interrupt - lda #VERA_VSYNC - sta VERA_ISR - // asm { jmp$e034 } - // Exit CX16 KERNAL IRQ - jmp $e034 - jmp __breturn - // irq_vsync::@return - __breturn: - // [18] return - // interrupt(isr_rom_sys_cx16_exit) -- isr_rom_sys_cx16_exit - jmp $e034 - // irq_vsync::@6 - __b6: - // [19] irq_vsync::$11 = irq_vsync::i_x#3 << 1 -- vwuz1=vwuz2_rol_1 - lda.z i_x - asl - sta.z __11 - lda.z i_x+1 - rol - sta.z __11+1 - // [20] irq_vsync::$13 = SINX + irq_vsync::$11 -- pwuz1=pwuc1_plus_vwuz1 - clc - lda.z __13 - adc #SINX - sta.z __13+1 - // [21] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$13 -- _deref_pwuc1=_deref_pwuz1 - ldy #0 - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - iny - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 -- vwuz1=vwuz2_rol_1 - lda.z i_y - asl - sta.z __12 - lda.z i_y+1 - rol - sta.z __12+1 - // [23] irq_vsync::$14 = SINY + irq_vsync::$12 -- pwuz1=pwuc1_plus_vwuz1 - clc - lda.z __14 - adc #SINY - sta.z __14+1 - // [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 -- _deref_pwuc1=_deref_pwuz1 - ldy #0 - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - iny - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // [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) - // [56] phi from irq_vsync::@6 to memcpy_to_vram [phi:irq_vsync::@6->memcpy_to_vram] - memcpy_to_vram_from___b6: - // [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 - // [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 - // [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 - // [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 - __b12: - // [27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 - lda #SIZEOF_STRUCT_VERA_SPRITE - clc - adc.z vram_sprite_pos - sta.z vram_sprite_pos - bcc !+ - inc.z vram_sprite_pos+1 - !: - // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + $19 -- vwuz1=vwuz1_plus_vbuc1 - lda #$19 - clc - adc.z i_x - sta.z i_x - bcc !+ - inc.z i_x+1 - !: - // [29] if(irq_vsync::i_x#1irq_vsync::@8] - __b8_from___b10: - __b8_from___b12: - // [31] phi irq_vsync::i_x#7 = irq_vsync::i_x#2 [phi:irq_vsync::@10/irq_vsync::@12->irq_vsync::@8#0] -- register_copy - jmp __b8 - // irq_vsync::@8 - __b8: - // [32] irq_vsync::i_y#1 = irq_vsync::i_y#3 + $13 -- vwuz1=vwuz1_plus_vbuc1 - lda #$13 - clc - adc.z i_y - sta.z i_y - bcc !+ - inc.z i_y+1 - !: - // [33] if(irq_vsync::i_y#1irq_vsync::@9] - __b9_from___b11: - __b9_from___b8: - // [35] phi irq_vsync::i_y#9 = irq_vsync::i_y#2 [phi:irq_vsync::@11/irq_vsync::@8->irq_vsync::@9#0] -- register_copy - jmp __b9 - // irq_vsync::@9 - __b9: - // [36] irq_vsync::s#1 = ++ irq_vsync::s#2 -- vbuz1=_inc_vbuz1 - inc.z s - // [14] phi from irq_vsync::@9 to irq_vsync::@5 [phi:irq_vsync::@9->irq_vsync::@5] - __b5_from___b9: - // [14] phi irq_vsync::vram_sprite_pos#2 = irq_vsync::vram_sprite_pos#1 [phi:irq_vsync::@9->irq_vsync::@5#0] -- register_copy - // [14] phi irq_vsync::i_y#3 = irq_vsync::i_y#9 [phi:irq_vsync::@9->irq_vsync::@5#1] -- register_copy - // [14] phi irq_vsync::i_x#3 = irq_vsync::i_x#7 [phi:irq_vsync::@9->irq_vsync::@5#2] -- register_copy - // [14] phi irq_vsync::s#2 = irq_vsync::s#1 [phi:irq_vsync::@9->irq_vsync::@5#3] -- register_copy - jmp __b5 -} - // main -main: { - // Copy 8* sprite attributes to VRAM - .label vram_sprite_attr = $a - .label s = 9 - // [38] call memcpy_to_vram - // Copy sprite data to VRAM - // [56] phi from main to memcpy_to_vram [phi:main->memcpy_to_vram] - memcpy_to_vram_from_main: - // [56] phi memcpy_to_vram::num#4 = (word)$40*$40 [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 - lda #<$40*$40 - sta.z memcpy_to_vram.num - lda #>$40*$40 - sta.z memcpy_to_vram.num+1 - // [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 - // [56] phi memcpy_to_vram::vbank#4 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 - ldx #0 - // [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::@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 - // [41] phi main::s#2 = 0 [phi:main::@5->main::@1#1] -- vbuz1=vbuc1 - lda #0 - sta.z s - jmp __b1 - // main::@1 - __b1: - // [42] if(main::s#2<$20) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 - lda.z s - cmp #$20 - bcc __b2 - jmp __b3 - // main::@3 - __b3: - // [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 - // [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 - jmp SEI1 - // main::SEI1 - SEI1: - // asm { sei } - sei - jmp __b4 - // main::@4 - __b4: - // [46] *KERNEL_IRQ = &irq_vsync -- _deref_qprc1=pprc2 - lda #irq_vsync - sta KERNEL_IRQ+1 - // [47] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 - lda #VERA_VSYNC - sta VERA_IEN - jmp CLI1 - // main::CLI1 - CLI1: - // asm { cli } - cli - jmp __breturn - // main::@return - __breturn: - // [49] return - rts - // main::@2 - __b2: - // [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 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - lda #>$a - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // [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 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - lda #>$a - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // [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 - // [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: - // [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 - // [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 - // [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 - // [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 __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 - sta.z vram_sprite_attr - bcc !+ - inc.z vram_sprite_attr+1 - !: - // [55] main::s#1 = ++ main::s#2 -- vbuz1=_inc_vbuz1 - inc.z s - // [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 -// Copy block of memory (from RAM to VRAM) -// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM. -// - vbank: Which 64K VRAM bank to put data into (0/1) -// - vdest: The destination address in VRAM -// - src: The source address in RAM -// - num: The number of bytes to copy -// memcpy_to_vram(byte register(X) vbank, void* zp($c) vdest, void* zp($e) src, word zp($10) num) -memcpy_to_vram: { - .label end = $10 - .label s = $e - .label vdest = $c - .label src = $e - .label num = $10 - // [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 - // [58] memcpy_to_vram::$0 = < memcpy_to_vram::vdest#4 -- vbuaa=_lo_pvoz1 - lda.z vdest - // [59] *VERA_ADDRX_L = memcpy_to_vram::$0 -- _deref_pbuc1=vbuaa - // Set address - sta VERA_ADDRX_L - // [60] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#4 -- vbuaa=_hi_pvoz1 - lda.z vdest+1 - // [61] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa - sta VERA_ADDRX_M - // [62] memcpy_to_vram::$2 = VERA_INC_1 | memcpy_to_vram::vbank#4 -- vbuaa=vbuc1_bor_vbuxx - txa - ora #VERA_INC_1 - // [63] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa - sta VERA_ADDRX_H - // [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 - sta.z end - lda.z end+1 - adc.z src+1 - sta.z end+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: - // [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: - // [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 - lda.z s - cmp.z end - bne __b2 - jmp __breturn - // memcpy_to_vram::@return - __breturn: - // [68] return - rts - // memcpy_to_vram::@2 - __b2: - // [69] *VERA_DATA0 = *memcpy_to_vram::s#2 -- _deref_pbuc1=_deref_pbuz1 - ldy #0 - lda (s),y - sta VERA_DATA0 - // [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 - inc.z s - bne !+ - inc.z s+1 - !: - jmp __b1_from___b2 -} - // File Data -.segment Data - // A 64*64 8bpp TUT sprite and palette - .align $1000 -SPRITE_PIXELS: -.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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - - .align $100 -SINX: -.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - - .align $100 -SINY: -.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 - .byte $c, $f0 - -ASSEMBLER OPTIMIZATIONS -Removing instruction jmp __init1 -Removing instruction jmp __b1 -Removing instruction jmp __breturn -Removing instruction jmp __b3 -Removing instruction jmp __b1 -Removing instruction jmp __b4 -Removing instruction jmp __b2 -Removing instruction jmp __b5 -Removing instruction jmp __b7 -Removing instruction jmp __breturn -Removing instruction jmp __b12 -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 __b6 -Removing instruction jmp __b1 -Removing instruction jmp __breturn -Succesful ASM optimization Pass5NextJumpElimination -Removing instruction lda #>0 -Succesful ASM optimization Pass5UnnecesaryLoadElimination -Replacing label __b8_from___b12 with __b8 -Replacing label __b9_from___b8 with __b9 -Replacing label __b1_from___b2 with __b1 -Removing instruction __b1_from___init1: -Removing instruction main_from___b1: -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 -Removing instruction __init1: -Removing instruction __b1: -Removing instruction __breturn: -Removing instruction __b3: -Removing instruction __b4: -Removing instruction __b5_from___b2: -Removing instruction __b7: -Removing instruction __breturn: -Removing instruction memcpy_to_vram_from___b6: -Removing instruction __b12: -Removing instruction __b10: -Removing instruction __b11: -Removing instruction __b5_from___b9: -Removing instruction memcpy_to_vram_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 __b6: -Removing instruction __b1_from___b6: -Removing instruction __breturn: -Succesful ASM optimization Pass5UnusedLabelElimination -Removing unreachable instruction jmp $e034 -Succesful ASM optimization Pass5UnreachableCodeElimination - -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[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - }} -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 -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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - }} -const nomodify dword SPRITE_PIXELS_VRAM = $8000 -const nomodify byte VERA_ADDRSEL = 1 -const nomodify byte* VERA_ADDRX_H = (byte*) 40738 -const nomodify byte* VERA_ADDRX_L = (byte*) 40736 -const nomodify byte* VERA_ADDRX_M = (byte*) 40737 -const nomodify byte* VERA_CTRL = (byte*) 40741 -const nomodify byte* VERA_DATA0 = (byte*) 40739 -const nomodify byte VERA_DCSEL = 2 -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 -const nomodify byte VERA_VSYNC = 1 -void __start() -__interrupt(rom_sys_cx16) void irq_vsync() -word~ irq_vsync::$11 zp[2]:22 22.0 -word~ irq_vsync::$12 zp[2]:24 22.0 -word*~ irq_vsync::$13 zp[2]:22 22.0 -word*~ irq_vsync::$14 zp[2]:24 22.0 -word irq_vsync::i_x -word irq_vsync::i_x#0 i_x zp[2]:3 2.0 -word irq_vsync::i_x#1 i_x zp[2]:3 22.0 -word irq_vsync::i_x#2 i_x zp[2]:3 22.0 -word irq_vsync::i_x#3 i_x zp[2]:3 3.1818181818181817 -word irq_vsync::i_x#7 i_x zp[2]:3 5.5 -word irq_vsync::i_y -word irq_vsync::i_y#0 i_y zp[2]:5 4.0 -word irq_vsync::i_y#1 i_y zp[2]:5 22.0 -word irq_vsync::i_y#2 i_y zp[2]:5 22.0 -word irq_vsync::i_y#3 i_y zp[2]:5 2.333333333333333 -word irq_vsync::i_y#9 i_y zp[2]:5 16.5 -byte irq_vsync::s -byte irq_vsync::s#1 s zp[1]:2 22.0 -byte irq_vsync::s#2 s zp[1]:2 1.736842105263158 -const nomodify byte irq_vsync::vram_sprite_attr_bank = (byte)>VERA_SPRITE_ATTR -byte* irq_vsync::vram_sprite_pos -byte* irq_vsync::vram_sprite_pos#1 vram_sprite_pos zp[2]:7 2.2 -byte* irq_vsync::vram_sprite_pos#2 vram_sprite_pos zp[2]:7 2.2 -void main() -byte main::s -byte main::s#1 s zp[1]:9 202.0 -byte main::s#2 s zp[1]:9 43.285714285714285 -byte* main::vram_sprite_attr -byte* main::vram_sprite_attr#1 vram_sprite_attr zp[2]:10 101.0 -byte* main::vram_sprite_attr#2 vram_sprite_attr zp[2]:10 33.666666666666664 -void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num) -byte~ memcpy_to_vram::$0 reg byte a 2002.0 -byte~ memcpy_to_vram::$1 reg byte a 2002.0 -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#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#4 src zp[2]:14 -byte memcpy_to_vram::vbank -byte memcpy_to_vram::vbank#4 reg byte x 166.83333333333334 -void* memcpy_to_vram::vdest -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 - -zp[1]:2 [ irq_vsync::s#2 irq_vsync::s#1 ] -zp[2]:3 [ irq_vsync::i_x#3 irq_vsync::i_x#0 irq_vsync::i_x#7 irq_vsync::i_x#2 irq_vsync::i_x#1 ] -zp[2]:5 [ irq_vsync::i_y#3 irq_vsync::i_y#0 irq_vsync::i_y#9 irq_vsync::i_y#2 irq_vsync::i_y#1 ] -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#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 ] -zp[2]:24 [ irq_vsync::$12 irq_vsync::$14 ] -reg byte a [ memcpy_to_vram::$0 ] -reg byte a [ memcpy_to_vram::$1 ] -reg byte a [ memcpy_to_vram::$2 ] -mem[8] [ SPRITE_ATTR ] - - -FINAL ASSEMBLER -Score: 8528 - - // File Comments -// Example program for the Commander X16 -// Displays 32 64*64 TUT sprites - // Upstart -.cpu _65c02 - // Commodore 64 PRG executable file -.file [name="sprites.prg", type="prg", segments="Program"] -.segmentdef Program [segments="Basic, Code, Data"] -.segmentdef Basic [start=$0801] -.segmentdef Code [start=$80d] -.segmentdef Data [startAfter="Code"] -.segment Basic -:BasicUpstart(__start) - // Global Constants & labels - .const VERA_INC_1 = $10 - .const VERA_DCSEL = 2 - .const VERA_ADDRSEL = 1 - .const VERA_VSYNC = 1 - // 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 - .const VERA_SPRITES_ENABLE = $40 - // $9F20 VRAM Address (7:0) - .label VERA_ADDRX_L = $9f20 - // $9F21 VRAM Address (15:8) - .label VERA_ADDRX_M = $9f21 - // $9F22 VRAM Address (7:0) - // Bit 4-7: Address Increment The following is the amount incremented per value value:increment - // 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640 - // Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field. - // Bit 0: VRAM Address (16) - .label VERA_ADDRX_H = $9f22 - // $9F23 DATA0 VRAM Data port 0 - .label VERA_DATA0 = $9f23 - // $9F25 CTRL Control - // Bit 7: Reset - // Bit 1: DCSEL - // Bit 2: ADDRSEL - .label VERA_CTRL = $9f25 - // $9F26 IEN Interrupt Enable - // Bit 7: IRQ line (8) - // Bit 3: AFLOW - // Bit 2: SPRCOL - // Bit 1: LINE - // Bit 0: VSYNC - .label VERA_IEN = $9f26 - // $9F27 ISR Interrupt Status - // Interrupts will be generated for the interrupt sources set in the lower 4 bits of IEN. ISR will indicate the interrupts that have occurred. - // Writing a 1 to one of the lower 3 bits in ISR will clear that interrupt status. AFLOW can only be cleared by filling the audio FIFO for at least 1/4. - // Bit 4-7: Sprite Collisions. This field indicates which groups of sprites have collided. - // Bit 3: AFLOW - // Bit 2: SPRCOL - // Bit 1: LINE - // Bit 0: VSYNC - .label VERA_ISR = $9f27 - // $9F29 DC_VIDEO (DCSEL=0) - // Bit 7: Current Field Read-only bit which reflects the active interlaced field in composite and RGB modes. (0: even, 1: odd) - // Bit 6: Sprites Enable Enable output from the Sprites renderer - // Bit 5: Layer1 Enable Enable output from the Layer1 renderer - // Bit 4: Layer0 Enable Enable output from the Layer0 renderer - // Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.) - // Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector) - .label VERA_DC_VIDEO = $9f29 - // $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts - .label KERNEL_IRQ = $314 - // X sine index - .label sin_idx_x = $12 - // Y sine index - .label sin_idx_y = $14 -.segment Code - // __start -__start: { - // __start::__init1 - // sin_idx_x = 119 - // [1] sin_idx_x = $77 -- vwuz1=vwuc1 - lda #<$77 - sta.z sin_idx_x - lda #>$77 - sta.z sin_idx_x+1 - // sin_idx_y = 79 - // [2] sin_idx_y = $4f -- vwuz1=vwuc1 - lda #<$4f - sta.z sin_idx_y - lda #>$4f - sta.z sin_idx_y+1 - // [3] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] - // __start::@1 - // [4] call main - // [37] phi from __start::@1 to main [phi:__start::@1->main] - jsr main - // __start::@return - // [5] return - rts -} - // irq_vsync -// VSYNC Interrupt Routine -irq_vsync: { - .const vram_sprite_attr_bank = VERA_SPRITE_ATTR>>$10 - .label __11 = $16 - .label __12 = $18 - .label i_x = 3 - .label i_y = 5 - .label vram_sprite_pos = 7 - .label s = 2 - .label __13 = $16 - .label __14 = $18 - // interrupt(isr_rom_sys_cx16_entry) -- isr_rom_sys_cx16_entry - // 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!=SINX_LEN) goto irq_vsync::@1 -- vwuz1_neq_vwuc1_then_la1 - lda.z sin_idx_x+1 - cmp #>SINX_LEN - bne __b1 - lda.z sin_idx_x - cmp #$ffff - bne __b2 - lda.z sin_idx_y - cmp #<$ffff - bne __b2 - // irq_vsync::@4 - // sin_idx_y = SINY_LEN-1 - // [11] sin_idx_y = SINY_LEN-1 -- vwuz1=vbuc1 - lda #SINY_LEN-1 - sta.z sin_idx_y+1 - // irq_vsync::@2 - __b2: - // i_x = sin_idx_x - // [12] irq_vsync::i_x#0 = sin_idx_x -- vwuz1=vwuz2 - lda.z sin_idx_x - sta.z i_x - lda.z sin_idx_x+1 - sta.z i_x+1 - // i_y = sin_idx_y - // [13] irq_vsync::i_y#0 = sin_idx_y -- vwuz1=vwuz2 - lda.z sin_idx_y - sta.z i_y - lda.z sin_idx_y+1 - sta.z i_y+1 - // [14] phi from irq_vsync::@2 to irq_vsync::@5 [phi:irq_vsync::@2->irq_vsync::@5] - // [14] phi irq_vsync::vram_sprite_pos#2 = (byte*)irq_vsync::@5#0] -- pbuz1=pbuc1 - lda #VERA_SPRITE_ATTR+2&$ffff - sta.z vram_sprite_pos+1 - // [14] phi irq_vsync::i_y#3 = irq_vsync::i_y#0 [phi:irq_vsync::@2->irq_vsync::@5#1] -- register_copy - // [14] phi irq_vsync::i_x#3 = irq_vsync::i_x#0 [phi:irq_vsync::@2->irq_vsync::@5#2] -- register_copy - // [14] phi irq_vsync::s#2 = 0 [phi:irq_vsync::@2->irq_vsync::@5#3] -- vbuz1=vbuc1 - lda #0 - sta.z s - // irq_vsync::@5 - __b5: - // for(char s=0;sSINX - sta.z __13+1 - // [21] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$13 -- _deref_pwuc1=_deref_pwuz1 - ldy #0 - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - iny - lda (__13),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // SPRITE_ATTR.Y = SINY[i_y] - // [22] irq_vsync::$12 = irq_vsync::i_y#3 << 1 -- vwuz1=vwuz2_rol_1 - lda.z i_y - asl - sta.z __12 - lda.z i_y+1 - rol - sta.z __12+1 - // [23] irq_vsync::$14 = SINY + irq_vsync::$12 -- pwuz1=pwuc1_plus_vwuz1 - clc - lda.z __14 - adc #SINY - sta.z __14+1 - // [24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14 -- _deref_pwuc1=_deref_pwuz1 - ldy #0 - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - iny - lda (__14),y - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y+1 - // memcpy_to_vram(vram_sprite_attr_bank, vram_sprite_pos, &SPRITE_ATTR+2, 4) - // [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) - // [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 - // [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 - // [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 - // [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) - // [27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE -- pbuz1=pbuz1_plus_vbuc1 - lda #SIZEOF_STRUCT_VERA_SPRITE - clc - adc.z vram_sprite_pos - sta.z vram_sprite_pos - bcc !+ - inc.z vram_sprite_pos+1 - !: - // i_x += 25 - // [28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + $19 -- vwuz1=vwuz1_plus_vbuc1 - lda #$19 - clc - adc.z i_x - sta.z i_x - bcc !+ - inc.z i_x+1 - !: - // if(i_x>=SINX_LEN) - // [29] if(irq_vsync::i_x#1irq_vsync::@8] - // [31] phi irq_vsync::i_x#7 = irq_vsync::i_x#2 [phi:irq_vsync::@10/irq_vsync::@12->irq_vsync::@8#0] -- register_copy - // irq_vsync::@8 - __b8: - // i_y += 19 - // [32] irq_vsync::i_y#1 = irq_vsync::i_y#3 + $13 -- vwuz1=vwuz1_plus_vbuc1 - lda #$13 - clc - adc.z i_y - sta.z i_y - bcc !+ - inc.z i_y+1 - !: - // if(i_y>=SINY_LEN) - // [33] if(irq_vsync::i_y#1irq_vsync::@9] - // [35] phi irq_vsync::i_y#9 = irq_vsync::i_y#2 [phi:irq_vsync::@11/irq_vsync::@8->irq_vsync::@9#0] -- register_copy - // irq_vsync::@9 - __b9: - // for(char s=0;sirq_vsync::@5] - // [14] phi irq_vsync::vram_sprite_pos#2 = irq_vsync::vram_sprite_pos#1 [phi:irq_vsync::@9->irq_vsync::@5#0] -- register_copy - // [14] phi irq_vsync::i_y#3 = irq_vsync::i_y#9 [phi:irq_vsync::@9->irq_vsync::@5#1] -- register_copy - // [14] phi irq_vsync::i_x#3 = irq_vsync::i_x#7 [phi:irq_vsync::@9->irq_vsync::@5#2] -- register_copy - // [14] phi irq_vsync::s#2 = irq_vsync::s#1 [phi:irq_vsync::@9->irq_vsync::@5#3] -- register_copy - jmp __b5 -} - // main -main: { - // Copy 8* sprite attributes to VRAM - .label vram_sprite_attr = $a - .label s = 9 - // memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, memcpy_to_vram] - // [56] phi memcpy_to_vram::num#4 = (word)$40*$40 [phi:main->memcpy_to_vram#0] -- vwuz1=vwuc1 - lda #<$40*$40 - sta.z memcpy_to_vram.num - lda #>$40*$40 - sta.z memcpy_to_vram.num+1 - // [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 - // [56] phi memcpy_to_vram::vbank#4 = 0 [phi:main->memcpy_to_vram#2] -- vbuxx=vbuc1 - ldx #0 - // [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::@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 - // [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 - // [47] *VERA_IEN = VERA_VSYNC -- _deref_pbuc1=vbuc2 - lda #VERA_VSYNC - sta VERA_IEN - // main::CLI1 - // asm - // asm { cli } - cli - // main::@return - // } - // [49] return - rts - // main::@2 - __b2: - // SPRITE_ATTR.X += 10 - // [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 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X - lda #>$a - adc SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X+1 - // SPRITE_ATTR.Y += 10 - // [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 - sta SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y - lda #>$a - 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)) - // [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 - // [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 - // [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 - // [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 - // [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::@6 - // vram_sprite_attr += sizeof(SPRITE_ATTR) - // [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 - sta.z vram_sprite_attr - bcc !+ - inc.z vram_sprite_attr+1 - !: - // for(char s=0;smain::@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 -// Copy block of memory (from RAM to VRAM) -// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM. -// - vbank: Which 64K VRAM bank to put data into (0/1) -// - vdest: The destination address in VRAM -// - src: The source address in RAM -// - num: The number of bytes to copy -// memcpy_to_vram(byte register(X) vbank, void* zp($c) vdest, void* zp($e) src, word zp($10) num) -memcpy_to_vram: { - .label end = $10 - .label s = $e - .label vdest = $c - .label src = $e - .label num = $10 - // *VERA_CTRL &= ~VERA_ADDRSEL - // [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 - // [60] memcpy_to_vram::$1 = > memcpy_to_vram::vdest#4 -- vbuaa=_hi_pvoz1 - lda.z vdest+1 - // *VERA_ADDRX_M = >vdest - // [61] *VERA_ADDRX_M = memcpy_to_vram::$1 -- _deref_pbuc1=vbuaa - sta VERA_ADDRX_M - // VERA_INC_1 | vbank - // [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 - // [63] *VERA_ADDRX_H = memcpy_to_vram::$2 -- _deref_pbuc1=vbuaa - sta VERA_ADDRX_H - // end = (char*)src+num - // [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 - sta.z end - lda.z end+1 - adc.z src+1 - sta.z end+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] - // [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++) - // [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 - lda.z s - cmp.z end - bne __b2 - // memcpy_to_vram::@return - // } - // [68] return - rts - // memcpy_to_vram::@2 - __b2: - // *VERA_DATA0 = *s - // [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++) - // [70] memcpy_to_vram::s#1 = ++ memcpy_to_vram::s#2 -- pbuz1=_inc_pbuz1 - inc.z s - bne !+ - inc.z s+1 - !: - jmp __b1 -} - // File Data -.segment Data - // A 64*64 8bpp TUT sprite and palette - .align $1000 -SPRITE_PIXELS: -.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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - - .align $100 -SINX: -.fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - - .align $100 -SINY: -.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 - .byte $c, $f0 - diff --git a/src/test/ref/examples/cx16/sprites.sym b/src/test/ref/examples/cx16/sprites.sym deleted file mode 100644 index 62cf323d9..000000000 --- a/src/test/ref/examples/cx16/sprites.sym +++ /dev/null @@ -1,136 +0,0 @@ -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[SINX_LEN] = kickasm {{ .fillword 256, 288+288*sin(i*2*PI/SINX_LEN) - }} -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 -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; - // Extract palette while outputting pixels as palete index values - .for (var y=0; y<64; y++) { - .for (var x=0;x<64; x++) { - // Find palette index (add if not known) - .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 as palette index - .byte idx - } - } - .if(nxt_idx>256) .error "Image has too many colours "+nxt_idx - // Output sprite palette (at 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&$f0 | blue/16 - // bits bits 0-3 red - .byte red/16 - } - }} -const nomodify dword SPRITE_PIXELS_VRAM = $8000 -const nomodify byte VERA_ADDRSEL = 1 -const nomodify byte* VERA_ADDRX_H = (byte*) 40738 -const nomodify byte* VERA_ADDRX_L = (byte*) 40736 -const nomodify byte* VERA_ADDRX_M = (byte*) 40737 -const nomodify byte* VERA_CTRL = (byte*) 40741 -const nomodify byte* VERA_DATA0 = (byte*) 40739 -const nomodify byte VERA_DCSEL = 2 -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 -const nomodify byte VERA_VSYNC = 1 -void __start() -__interrupt(rom_sys_cx16) void irq_vsync() -word~ irq_vsync::$11 zp[2]:22 22.0 -word~ irq_vsync::$12 zp[2]:24 22.0 -word*~ irq_vsync::$13 zp[2]:22 22.0 -word*~ irq_vsync::$14 zp[2]:24 22.0 -word irq_vsync::i_x -word irq_vsync::i_x#0 i_x zp[2]:3 2.0 -word irq_vsync::i_x#1 i_x zp[2]:3 22.0 -word irq_vsync::i_x#2 i_x zp[2]:3 22.0 -word irq_vsync::i_x#3 i_x zp[2]:3 3.1818181818181817 -word irq_vsync::i_x#7 i_x zp[2]:3 5.5 -word irq_vsync::i_y -word irq_vsync::i_y#0 i_y zp[2]:5 4.0 -word irq_vsync::i_y#1 i_y zp[2]:5 22.0 -word irq_vsync::i_y#2 i_y zp[2]:5 22.0 -word irq_vsync::i_y#3 i_y zp[2]:5 2.333333333333333 -word irq_vsync::i_y#9 i_y zp[2]:5 16.5 -byte irq_vsync::s -byte irq_vsync::s#1 s zp[1]:2 22.0 -byte irq_vsync::s#2 s zp[1]:2 1.736842105263158 -const nomodify byte irq_vsync::vram_sprite_attr_bank = (byte)>VERA_SPRITE_ATTR -byte* irq_vsync::vram_sprite_pos -byte* irq_vsync::vram_sprite_pos#1 vram_sprite_pos zp[2]:7 2.2 -byte* irq_vsync::vram_sprite_pos#2 vram_sprite_pos zp[2]:7 2.2 -void main() -byte main::s -byte main::s#1 s zp[1]:9 202.0 -byte main::s#2 s zp[1]:9 43.285714285714285 -byte* main::vram_sprite_attr -byte* main::vram_sprite_attr#1 vram_sprite_attr zp[2]:10 101.0 -byte* main::vram_sprite_attr#2 vram_sprite_attr zp[2]:10 33.666666666666664 -void memcpy_to_vram(byte memcpy_to_vram::vbank , void* memcpy_to_vram::vdest , void* memcpy_to_vram::src , word memcpy_to_vram::num) -byte~ memcpy_to_vram::$0 reg byte a 2002.0 -byte~ memcpy_to_vram::$1 reg byte a 2002.0 -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#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#4 src zp[2]:14 -byte memcpy_to_vram::vbank -byte memcpy_to_vram::vbank#4 reg byte x 166.83333333333334 -void* memcpy_to_vram::vdest -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 - -zp[1]:2 [ irq_vsync::s#2 irq_vsync::s#1 ] -zp[2]:3 [ irq_vsync::i_x#3 irq_vsync::i_x#0 irq_vsync::i_x#7 irq_vsync::i_x#2 irq_vsync::i_x#1 ] -zp[2]:5 [ irq_vsync::i_y#3 irq_vsync::i_y#0 irq_vsync::i_y#9 irq_vsync::i_y#2 irq_vsync::i_y#1 ] -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#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 ] -zp[2]:24 [ irq_vsync::$12 irq_vsync::$14 ] -reg byte a [ memcpy_to_vram::$0 ] -reg byte a [ memcpy_to_vram::$1 ] -reg byte a [ memcpy_to_vram::$2 ] -mem[8] [ SPRITE_ATTR ] From a5b10d962f1b672f3101c449dee381f0e20d954e Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 17 Jan 2021 08:20:45 +0100 Subject: [PATCH 04/31] fixed much code, working on 16x16 8bit tile mode. There is an error in the compiler i think which i need to communicate to Jesper. --- .../cache/fragment-cache-wdc65c02.asm | 56 ++++ src/main/kc/include/cx16-vera.h | 2 +- src/main/kc/include/veralib.h | 105 ++++++-- src/main/kc/lib/conio-cx16.c | 129 ++++----- src/main/kc/lib/veralib.c | 250 ++++++++++-------- src/test/kc/examples/cx16/tilemap.c | 26 +- .../kc/examples/cx16/tilemap_2bpp_16_x_16.c | 94 +++++++ .../kc/examples/cx16/tilemap_2bpp_8_x_8.c | 2 +- .../kc/examples/cx16/tilemap_4bpp_16_x_16.c | 222 ++++++++++++++++ .../kc/examples/cx16/tilemap_4bpp_8_x_8.c | 125 +++++++++ .../kc/examples/cx16/tilemap_8bpp_16_x_16.c | 152 +++++++++++ .../kc/examples/cx16/tilemap_8bpp_8_x_8.c | 90 +++++++ src/test/kc/examples/cx16/veralayers.c | 32 +-- 13 files changed, 1066 insertions(+), 219 deletions(-) create mode 100644 src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c create mode 100644 src/test/kc/examples/cx16/tilemap_4bpp_16_x_16.c create mode 100644 src/test/kc/examples/cx16/tilemap_4bpp_8_x_8.c create mode 100644 src/test/kc/examples/cx16/tilemap_8bpp_16_x_16.c create mode 100644 src/test/kc/examples/cx16/tilemap_8bpp_8_x_8.c diff --git a/src/main/fragment/cache/fragment-cache-wdc65c02.asm b/src/main/fragment/cache/fragment-cache-wdc65c02.asm index 7474d6077..b105d9cec 100644 --- a/src/main/fragment/cache/fragment-cache-wdc65c02.asm +++ b/src/main/fragment/cache/fragment-cache-wdc65c02.asm @@ -3929,3 +3929,59 @@ NO_SYNTHESIS //FRAGMENT pbuc1_derefidx_vbuz1=vbuaa ldy {z1} sta {c1},y +//FRAGMENT vbuz1=vbuz1_plus_2 +lda {z1} +clc +adc #2 +sta {z1} +//FRAGMENT vbuxx=vbuxx_plus_2 +inx +inx +//FRAGMENT pbuc1_derefidx_vbuz1=pbuc1_derefidx_vbuz1_plus_1 +ldy {z1} +lda {c1},y +inc +sta {c1},y +//FRAGMENT pbuc1_derefidx_vbuaa=pbuc1_derefidx_vbuaa_plus_1 +tay +lda {c1},y +inc +sta {c1},y +//FRAGMENT pbuc1_derefidx_vbuxx=pbuc1_derefidx_vbuxx_plus_1 +lda {c1},x +inc +sta {c1},x +//FRAGMENT pbuc1_derefidx_vbuyy=pbuc1_derefidx_vbuyy_plus_1 +lda {c1},y +inc +sta {c1},y +//FRAGMENT vwuz1=vwuz1_plus_vwuc1 +clc +lda {z1} +adc #<{c1} +sta {z1} +lda {z1}+1 +adc #>{c1} +sta {z1}+1 +//FRAGMENT vbuyy_neq_0_then_la1 +cpy #0 +bne {la1} +//FRAGMENT vbuz1=vbuc1_bor_vbuaa +ora #{c1} +sta {z1} +//FRAGMENT vbuaa=vbuc1_bor_vbuaa +ora #{c1} +//FRAGMENT vbuxx=vbuc1_bor_vbuaa +ora #{c1} +tax +//FRAGMENT vbuyy=vbuc1_bor_vbuaa +ora #{c1} +tay +//FRAGMENT vbuyy=vbuxx_bor_vbuaa +stx $ff +ora $ff +tay +//FRAGMENT _deref_pduc1=vbuc2 +NO_SYNTHESIS +//FRAGMENT _deref_pduc1=vbsc2 +NO_SYNTHESIS diff --git a/src/main/kc/include/cx16-vera.h b/src/main/kc/include/cx16-vera.h index bae2dcb7a..5e23eb51c 100644 --- a/src/main/kc/include/cx16-vera.h +++ b/src/main/kc/include/cx16-vera.h @@ -184,7 +184,7 @@ byte const VERA_TILEBASE_WIDTH_MASK = 0x01; byte const VERA_TILEBASE_HEIGHT_8 = 0x00; byte const VERA_TILEBASE_HEIGHT_16 = 0x02; byte const VERA_TILEBASE_HEIGHT_MASK = 0x02; -byte const VERA_TILEBASE_MASK = 0xfC; +byte const VERA_LAYER_TILEBASE_MASK = 0xfC; // Bit 0: Tile Width (0:8 pixels, 1:16 pixels) char * const VERA_L0_TILEBASE = 0x9f2f; // $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0) diff --git a/src/main/kc/include/veralib.h b/src/main/kc/include/veralib.h index ac0c72595..f91639272 100644 --- a/src/main/kc/include/veralib.h +++ b/src/main/kc/include/veralib.h @@ -3,70 +3,125 @@ // Author: Sven Van de Velde +#include + // --- VERA function encapsulation --- +__ma word vera_mapbase_offset[2] = {0,0}; +__ma byte vera_mapbase_bank[2] = {0,0}; +__ma dword vera_mapbase_address[2] = {0,0}; + +word vera_tilebase_offset[2] = {0,0}; +byte vera_tilebase_bank[2] = {0,0}; +dword vera_tilebase_address[2] = {0,0}; + +byte vera_layer_rowshift[2] = {0,0}; +word vera_layer_rowskip[2] = {0,0}; + +const byte vera_layer_hflip[2] = {0,0x04}; +const byte vera_layer_vflip[2] = {0,0x08}; + + +byte* vera_layer_config[2] = {VERA_L0_CONFIG, VERA_L1_CONFIG}; +byte vera_layer_enable[2] = { VERA_LAYER0_ENABLE, VERA_LAYER1_ENABLE }; + +byte* vera_layer_mapbase[2] = {VERA_L0_MAPBASE, VERA_L1_MAPBASE}; +byte* vera_layer_tilebase[2] = {VERA_L0_TILEBASE, VERA_L1_TILEBASE}; +byte* vera_layer_vscroll_l[2] = {VERA_L0_VSCROLL_L, VERA_L1_VSCROLL_L}; +byte* vera_layer_vscroll_h[2] = {VERA_L0_VSCROLL_H, VERA_L1_VSCROLL_H}; +byte* vera_layer_hscroll_l[2] = {VERA_L0_HSCROLL_L, VERA_L1_HSCROLL_L}; +byte* vera_layer_hscroll_h[2] = {VERA_L0_HSCROLL_H, VERA_L1_HSCROLL_H}; + +byte vera_layer_textcolor[2] = {WHITE, WHITE}; +byte vera_layer_backcolor[2] = {BLUE, BLUE}; + // --- VERA LAYERS --- // Set the configuration of the layer. // - layer: Value of 0 or 1. // - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'. -void vera_set_layer_config(unsigned byte layer, unsigned byte config); +void vera_layer_set_config(unsigned byte layer, unsigned byte config); // Set the configuration of the layer. // - layer: Value of 0 or 1. // - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'. -unsigned byte vera_get_layer_config(unsigned byte layer); +unsigned byte vera_layer_get_config(unsigned byte layer); // Set the map width or height of the layer. // - layer: Value of 0 or 1. -inline void vera_set_layer_map_width_32(unsigned byte layer); -inline void vera_set_layer_map_width_64(unsigned byte layer); -inline void vera_set_layer_map_width_128(unsigned byte layer); -inline void vera_set_layer_map_width_256(unsigned byte layer); -inline void vera_set_layer_map_height_32(unsigned byte layer); -inline void vera_set_layer_map_height_64(unsigned byte layer); -inline void vera_set_layer_map_height_128(unsigned byte layer); -inline void vera_set_layer_map_height_256(unsigned byte layer); +inline void vera_layer_set_width_32(unsigned byte layer); +inline void vera_layer_set_width_64(unsigned byte layer); +inline void vera_layer_set_width_128(unsigned byte layer); +inline void vera_layer_set_width_256(unsigned byte layer); +inline void vera_layer_set_height_32(unsigned byte layer); +inline void vera_layer_set_height_64(unsigned byte layer); +inline void vera_layer_set_height_128(unsigned byte layer); +inline void vera_layer_set_height_256(unsigned byte layer); // Enable the layer to be displayed on the screen. // - layer: 0 or 1. -void vera_show_layer(unsigned byte layer); +void vera_layer_show(unsigned byte layer); // Disable the layer to be displayed on the screen. // - layer: 0 or 1. -void vera_hide_layer(unsigned byte layer); +void vera_layer_hide(unsigned byte layer); // Is the layer shown on the screen? // - returns: 1 if layer is displayed on the screen, 0 if not. -unsigned byte vera_is_layer_shown(unsigned byte layer); +unsigned byte vera_layer_is_visible(unsigned byte layer); // Set the base of the map for the layer with which the conio will interact. // - layer: Value of 0 or 1. // - mapbase: Specifies the base address of the tile map. // Note that the register only specifies bits 16:9 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. -void vera_set_layer_mapbase(unsigned byte layer, unsigned byte mapbase); +void vera_layer_set_mapbase(unsigned byte layer, unsigned byte mapbase); // Get the base of the map for the layer with which the conio will interact. // - layer: Value of 0 or 1. // - return: Returns the base address of the tile map. // Note that the register is a byte, specifying only bits 16:9 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes! -unsigned byte vera_get_layer_mapbase(unsigned byte layer); +unsigned byte vera_layer_get_mapbase(unsigned byte layer); + +// Set the base of the map layer with which the conio will interact. +// - layer: Value of 0 or 1. +// - dw_mapbase: a dword typed address (4 bytes), that specifies the full address of the map base. +// The function does the translation from the dword that contains the 17 bit address, +// to the respective mapbase vera register. +// Note that the register only specifies bits 16:9 of the address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. +void vera_layer_set_mapbase_address(byte layer, dword dw_mapbase); + +// Get the map base address of the tiles for the layer. +// - layer: Value of 0 or 1. +// - return: Specifies the map base address of the layer, which is returned as a dword. +// Note that the register only specifies bits 16:9 of the 17 bit address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes! +dword vera_layer_get_mapbase_address(byte layer); // Set the base of the tiles for the layer with which the conio will interact. // - layer: Value of 0 or 1. // - tilebase: Specifies the base address of the tile map. // Note that the register only specifies bits 16:11 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! -void vera_set_layer_tilebase(unsigned byte layer, unsigned byte tilebase); +void vera_layer_set_tilebase(byte layer, byte tilebase); + +// Set the base of the tiles for the layer with which the conio will interact. +// - layer: Value of 0 or 1. +// - dw_tilebase: a dword typed address (4 bytes), that specifies the base address of the tile map. +// The function does the translation from the dword that contains the 17 bit address, +// to the respective tilebase vera register. +// Note that the resulting vera register holds only specifies bits 16:11 of the address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! +void vera_layer_set_tilebase_address(byte layer, dword dw_tilebase); // Get the base of the tiles for the layer with which the conio will interact. // - layer: Value of 0 or 1. // - return: Specifies the base address of the tile map. // Note that the register only specifies bits 16:11 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! -unsigned byte vera_get_layer_tilebase(unsigned byte layer); +unsigned byte vera_layer_get_tilebase(unsigned byte layer); // Set the front color for text output. The old front text color setting is returned. @@ -74,42 +129,44 @@ unsigned byte vera_get_layer_tilebase(unsigned byte layer); // - color: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_set_layer_textcolor(unsigned byte layer, unsigned byte color); +unsigned byte vera_layer_set_textcolor(unsigned byte layer, unsigned byte color); // Get the front color for text output. The old front text color setting is returned. // - layer: Value of 0 or 1. // - return: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_textcolor(unsigned byte layer); +unsigned byte vera_layer_get_textcolor(unsigned byte layer); // Set the back color for text output. The old back text color setting is returned. // - layer: Value of 0 or 1. // - color: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_set_layer_backcolor(unsigned byte layer, unsigned byte color); +unsigned byte vera_layer_set_backcolor(unsigned byte layer, unsigned byte color); // Get the back color for text output. The old back text color setting is returned. // - layer: Value of 0 or 1. // - return: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_backcolor(unsigned byte layer); +unsigned byte vera_layer_get_backcolor(unsigned byte layer); // Get the text and back color for text output in 16 color mode. // - layer: Value of 0 or 1. // - return: an 8 bit value with bit 7:4 containing the back color and bit 3:0 containing the front color. // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_color(unsigned byte layer); +unsigned byte vera_layer_get_color(unsigned byte layer); // Scroll the horizontal (X) axis of the layer visible area over the layer tile map area. // - layer: Value of 0 or 1. // - scroll: A value between 0 and 4096. -inline void vera_set_layer_horizontal_scroll(byte layer, word scroll); +inline void vera_layer_set_horizontal_scroll(byte layer, word scroll); // Scroll the vertical (Y) axis of the layer visible area over the layer tile map area. // - layer: Value of 0 or 1. // - scroll: A value between 0 and 4096. -inline void vera_set_layer_vertical_scroll(byte layer, word scroll); +inline void vera_layer_set_vertical_scroll(byte layer, word scroll); + +void vera_layer_mode_tile(byte layer, dword mapbase_address, dword dw_tilebase, word mapwidth, word mapheight, byte tilewidth, byte tileheight, byte color_depth ); diff --git a/src/main/kc/lib/conio-cx16.c b/src/main/kc/lib/conio-cx16.c index 7f02b6e1f..10f1a71ed 100644 --- a/src/main/kc/lib/conio-cx16.c +++ b/src/main/kc/lib/conio-cx16.c @@ -1,6 +1,7 @@ // CX16 conio.h implementation #include #include +#include // The screen width #define CONIO_WIDTH conio_screen_width @@ -25,6 +26,43 @@ const char CONIO_TEXTCOLOR_DEFAULT = WHITE; // The default back color const char CONIO_BACKCOLOR_DEFAULT = BLUE; + +// This requires the following constants to be defined +// - CONIO_WIDTH - The screen width +// - CONIO_HEIGHT - The screen height +// - CONIO_SCREEN_TEXT - The text screen address +// - CONIO_SCREEN_COLORS - The color screen address +// - CONIO_TEXTCOLOR_DEFAULT - The default text color + +#include + +// The number of bytes on the screen +#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH + +// The current cursor x-position +unsigned byte conio_cursor_x[2] = {0,0}; +// The current cursor y-position +unsigned byte conio_cursor_y[2] = {0,0}; +// The current text cursor line start +unsigned word conio_line_text[2] = {0x0000,0x0000}; +// Is a cursor whown when waiting for input (0: no, other: yes) +__ma unsigned byte conio_display_cursor = 0; +// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no). +// If disabled the cursor just moves back to (0,0) instead +unsigned byte conio_scroll_enable[2] = {1,1}; +// Variable holding the screen width; +__ma unsigned byte conio_screen_width = 0; +// Variable holding the screen height; +__ma unsigned byte conio_screen_height = 0; +// Variable holding the screen layer on the VERA card with which conio interacts; +__ma unsigned byte conio_screen_layer = 1; + +// Variables holding the current map width and map height of the layer. +__ma word conio_width = 0; +__ma word conio_height = 0; +__ma byte conio_rowshift = 0; +__ma word conio_rowskip = 0; + // Initializer for conio.h on X16 Commander. #pragma constructor_for(conio_x16_init, cputc, clrscr, cscroll) @@ -33,12 +71,21 @@ void conio_x16_init() { // Position cursor at current line char * const BASIC_CURSOR_LINE = 0xD6; char line = *BASIC_CURSOR_LINE; + //vera_layer_mode_tile(1,0x00000,0x0F800,128,64,8,8,1); + vera_mapbase_address[1] = 0x00000; + vera_mapbase_offset[1] = 0x0000; + vera_mapbase_bank[1] = 0x00; + vera_tilebase_address[1] = 0x0f800; + vera_tilebase_bank[1] = 0x00; + vera_tilebase_offset[1] = 0xf800; + vera_layer_rowskip[1] = 256; + vera_layer_rowshift[1] = 8; screensize(&conio_screen_width, &conio_screen_height); screenlayer(1); - vera_set_layer_textcolor(1, WHITE); - vera_set_layer_backcolor(1, BLUE); - vera_set_layer_mapbase(0,0x20); - vera_set_layer_mapbase(1,0x00); + vera_layer_set_textcolor(1, WHITE); + vera_layer_set_backcolor(1, BLUE); + vera_layer_set_mapbase(0,0x20); + vera_layer_set_mapbase(1,0x00); if(line>=CONIO_HEIGHT) line=CONIO_HEIGHT-1; gotoxy(0, line); } @@ -87,46 +134,10 @@ unsigned char kbhit(void) { return ch; } -// This requires the following constants to be defined -// - CONIO_WIDTH - The screen width -// - CONIO_HEIGHT - The screen height -// - CONIO_SCREEN_TEXT - The text screen address -// - CONIO_SCREEN_COLORS - The color screen address -// - CONIO_TEXTCOLOR_DEFAULT - The default text color - -#include - -// The number of bytes on the screen -#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH - -// The current cursor x-position -unsigned byte conio_cursor_x[2] = {0,0}; -// The current cursor y-position -unsigned byte conio_cursor_y[2] = {0,0}; -// The current text cursor line start -unsigned word conio_line_text[2] = {0x0000,0x0000}; -// Is a cursor whown when waiting for input (0: no, other: yes) -__ma unsigned byte conio_display_cursor = 0; -// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no). -// If disabled the cursor just moves back to (0,0) instead -unsigned byte conio_scroll_enable[2] = {1,1}; -// Variable holding the screen width; -__ma unsigned byte conio_screen_width = 0; -// Variable holding the screen height; -__ma unsigned byte conio_screen_height = 0; -// Variable holding the screen layer on the VERA card with which conio interacts; -__ma unsigned byte conio_screen_layer = 1; - -// Variables holding the current map width and map height of the layer. -__ma word conio_width = 0; -__ma word conio_height = 0; -__ma byte conio_skip = 0; - // clears the screen and moves the cursor to the upper left-hand corner of the screen. void clrscr(void) { char* line_text = CONIO_SCREEN_TEXT; - word skip = (word)((word)1<=CONIO_WIDTH) x = 0; conio_cursor_x[conio_screen_layer] = x; conio_cursor_y[conio_screen_layer] = y; - unsigned int line_offset = (unsigned int)y << conio_skip; + unsigned int line_offset = (unsigned int)y << conio_rowshift; conio_line_text[conio_screen_layer] = line_offset; } @@ -193,7 +204,7 @@ inline unsigned byte wherey(void) { // Output one character at the current cursor position // Moves the cursor forward. Scrolls the entire screen if needed void cputc(char c) { - char color = vera_get_layer_color( conio_screen_layer); + char color = vera_layer_get_color( conio_screen_layer); char* conio_addr = CONIO_SCREEN_TEXT + conio_line_text[conio_screen_layer]; conio_addr += conio_cursor_x[conio_screen_layer] << 1; @@ -225,7 +236,7 @@ void cputc(char c) { void cputln() { // TODO: This needs to be optimized! other variations don't compile because of sections not available! word temp = conio_line_text[conio_screen_layer]; - temp += (word)((word)1<addr; *VERA_ADDRX_H = VERA_INC_1; - char color = vera_get_layer_color( conio_screen_layer); + char color = vera_layer_get_color( conio_screen_layer); for( unsigned int c=0;c0; i--) { - unsigned int line = (conio_cursor_y[conio_screen_layer] + i - 1) << conio_skip; + unsigned int line = (conio_cursor_y[conio_screen_layer] + i - 1) << conio_rowshift; unsigned char* start = CONIO_SCREEN_TEXT + line; - memcpy_in_vram(0, start+((word)1<addr_i; - CONIO_SCREEN_TEXT = addr_i << 8; - conio_width = vera_get_layer_map_width(conio_screen_layer); - conio_skip = (byte)(conio_width >> 4); - conio_height = vera_get_layer_map_height(conio_screen_layer); + CONIO_SCREEN_BANK = vera_layer_get_mapbase_bank(conio_screen_layer); + CONIO_SCREEN_TEXT = vera_layer_get_mapbase_offset(conio_screen_layer); + conio_width = vera_layer_get_width(conio_screen_layer); + conio_rowshift = vera_layer_get_rowshift(conio_screen_layer); + conio_rowskip = vera_layer_get_rowskip(conio_screen_layer); + conio_height = vera_layer_get_height(conio_screen_layer); } @@ -352,7 +361,7 @@ void screenlayer(unsigned byte layer) { // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. inline char textcolor(char color) { - return vera_set_layer_textcolor(conio_screen_layer, color); + return vera_layer_set_textcolor(conio_screen_layer, color); } // Set the back color for text output. The old back text color setting is returned. @@ -360,7 +369,7 @@ inline char textcolor(char color) { // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. inline char bgcolor(char color) { - return vera_set_layer_backcolor(conio_screen_layer, color); + return vera_layer_set_backcolor(conio_screen_layer, color); } // Set the color for the border. The old color setting is returned. diff --git a/src/main/kc/lib/veralib.c b/src/main/kc/lib/veralib.c index 1ed0b60f5..94d3e3e14 100644 --- a/src/main/kc/lib/veralib.c +++ b/src/main/kc/lib/veralib.c @@ -10,32 +10,6 @@ // --- VERA layer management --- -word vera_mapbase_word[2] = {0,0}; -byte vera_mapbase_bank[2] = {0,0}; -dword vera_mapbase_dword[2] = {0,0}; - -word vera_tilebase_word[2] = {0,0}; -byte vera_tilebase_bank[2] = {0,0}; -dword vera_tilebase_dword[2] = {0,0}; - -byte vera_row_shift[2] = {0,0}; - -const byte vera_layer_hflip[2] = {0,0x04}; -const byte vera_layer_vflip[2] = {0,0x08}; - - -byte* vera_layer_config[2] = {VERA_L0_CONFIG, VERA_L1_CONFIG}; -byte vera_layer_enable[2] = { VERA_LAYER0_ENABLE, VERA_LAYER1_ENABLE }; - -byte* vera_layer_mapbase[2] = {VERA_L0_MAPBASE, VERA_L1_MAPBASE}; -byte* vera_layer_tilebase[2] = {VERA_L0_TILEBASE, VERA_L1_TILEBASE}; -byte* vera_layer_vscroll_l[2] = {VERA_L0_VSCROLL_L, VERA_L1_VSCROLL_L}; -byte* vera_layer_vscroll_h[2] = {VERA_L0_VSCROLL_H, VERA_L1_VSCROLL_H}; -byte* vera_layer_hscroll_l[2] = {VERA_L0_HSCROLL_L, VERA_L1_HSCROLL_L}; -byte* vera_layer_hscroll_h[2] = {VERA_L0_HSCROLL_H, VERA_L1_HSCROLL_H}; - -byte vera_layer_textcolor[2] = {WHITE, WHITE}; -byte vera_layer_backcolor[2] = {BLUE, BLUE}; // --- VERA addressing --- @@ -61,25 +35,12 @@ void vera_vram_address1(dword bankaddr, byte incr) { *VERA_ADDRX_H = <(*word_h) | incr; } -// Get the map base address of the tiles for the layer. -// - layer: Value of 0 or 1. -// - return: Specifies the map base address of the layer, which is returned as a dword. -// Note that the register only specifies bits 16:9 of the 17 total bit-address, -// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes! -dword vera_get_layer_mapbase_address(byte layer) { - layer &= $1; - byte mapbase = *vera_layer_mapbase[layer]; - dword address = mapbase; - address <<= 8; - address <<= 1; - return address; -} // --- VERA layer management --- // Set the configuration of the layer. // - layer: Value of 0 or 1. // - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'. -void vera_set_layer_config(char layer, char config) { +void vera_layer_set_config(char layer, char config) { layer &= $1; char* addr = vera_layer_config[layer]; *addr = config; @@ -88,51 +49,50 @@ void vera_set_layer_config(char layer, char config) { // Set the configuration of the layer. // - layer: Value of 0 or 1. // - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'. -char vera_get_layer_config(char layer) { - layer &= $1; +char vera_layer_get_config(char layer) { char* config = vera_layer_config[layer]; return *config; } // Set the map width or height of the layer. // - layer: Value of 0 or 1. -inline void vera_set_layer_map_width_32(unsigned byte layer) { +inline void vera_layer_set_width_32(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_WIDTH_MASK; *addr |= VERA_LAYER_WIDTH_32; } -inline void vera_set_layer_map_width_64(unsigned byte layer) { +inline void vera_layer_set_width_64(unsigned byte layer) { byte* addr = vera_layer_config[layer]; //*addr &= (~VERA_CONFIG_WIDTH_MASK) | VERA_CONFIG_WIDTH_64; *addr &= ~VERA_LAYER_WIDTH_MASK; *addr |= VERA_LAYER_WIDTH_64; } -inline void vera_set_layer_map_width_128(unsigned byte layer) { +inline void vera_layer_set_width_128(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_WIDTH_MASK; *addr |= VERA_LAYER_WIDTH_128; } -inline void vera_set_layer_map_width_256(unsigned byte layer) { +inline void vera_layer_set_width_256(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_WIDTH_MASK; *addr |= VERA_LAYER_WIDTH_256; } -inline void vera_set_layer_map_height_32(unsigned byte layer) { +inline void vera_layer_set_height_32(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_HEIGHT_MASK; *addr |= VERA_LAYER_HEIGHT_32; } -inline void vera_set_layer_map_height_64(unsigned byte layer) { +inline void vera_layer_set_height_64(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_HEIGHT_MASK; *addr |= VERA_LAYER_HEIGHT_64; } -inline void vera_set_layer_map_height_128(unsigned byte layer) { +inline void vera_layer_set_height_128(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_HEIGHT_MASK; *addr |= VERA_LAYER_HEIGHT_128; } -inline void vera_set_layer_map_height_256(unsigned byte layer) { +inline void vera_layer_set_height_256(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_HEIGHT_MASK; *addr |= VERA_LAYER_HEIGHT_256; @@ -140,13 +100,13 @@ inline void vera_set_layer_map_height_256(unsigned byte layer) { // Get the map width or height of the layer. // - layer: Value of 0 or 1. -word vera_get_layer_map_width(unsigned byte layer) { +word vera_layer_get_width(unsigned byte layer) { byte* config = vera_layer_config[layer]; byte mask = (byte)VERA_LAYER_WIDTH_MASK; return VERA_LAYER_WIDTH[ (*config & mask) >> 4]; } -word vera_get_layer_map_height(unsigned byte layer) { +word vera_layer_get_height(unsigned byte layer) { byte* config = vera_layer_config[layer]; byte mask = VERA_LAYER_HEIGHT_MASK; return VERA_LAYER_HEIGHT[ (*config & mask) >> 6]; @@ -154,22 +114,22 @@ word vera_get_layer_map_height(unsigned byte layer) { // Set the color depth of the layer in terms of bit per pixel (BPP) of the tile base. // - layer: Value of 0 or 1. -inline void vera_set_layer_color_depth_1BPP(unsigned byte layer) { +inline void vera_layer_set_color_depth_1BPP(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; *addr |= VERA_LAYER_COLOR_DEPTH_1BPP; } -inline void vera_set_layer_color_depth_2BPP(unsigned byte layer) { +inline void vera_layer_set_color_depth_2BPP(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; *addr |= VERA_LAYER_COLOR_DEPTH_2BPP; } -inline void vera_set_layer_color_depth_4BPP(unsigned byte layer) { +inline void vera_layer_set_color_depth_4BPP(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; *addr |= VERA_LAYER_COLOR_DEPTH_4BPP; } -inline void vera_set_layer_color_depth_8BPP(unsigned byte layer) { +inline void vera_layer_set_color_depth_8BPP(unsigned byte layer) { byte* addr = vera_layer_config[layer]; *addr &= ~VERA_LAYER_COLOR_DEPTH_MASK; *addr |= VERA_LAYER_COLOR_DEPTH_8BPP; @@ -178,7 +138,7 @@ inline void vera_set_layer_color_depth_8BPP(unsigned byte layer) { // Get the map width or height of the layer. // - layer: Value of 0 or 1. // - return: 1, 2, 4 or 8. -word vera_get_layer_color_depth(unsigned byte layer) { +word vera_layer_get_color_depth(unsigned byte layer) { byte* config = vera_layer_config[layer]; byte mask = (byte)VERA_LAYER_COLOR_DEPTH_MASK; return VERA_LAYER_COLOR_DEPTH[(*config & mask)]; @@ -186,22 +146,21 @@ word vera_get_layer_color_depth(unsigned byte layer) { // Enable the layer to be displayed on the screen. // - layer: 0 or 1. -inline void vera_show_layer(char layer) { +inline void vera_layer_show(char layer) { *VERA_DC_VIDEO |= vera_layer_enable[layer]; } // Disable the layer to be displayed on the screen. // - layer: 0 or 1. -inline void vera_hide_layer(char layer) { +inline void vera_layer_hide(char layer) { *VERA_DC_VIDEO &= ~vera_layer_enable[layer]; } // Is the layer shown on the screen? // - returns: 1 if layer is displayed on the screen, 0 if not. -char vera_is_layer_shown(char layer) { - layer &= $1; +char vera_layer_is_visible(char layer) { return *VERA_DC_VIDEO & vera_layer_enable[layer]; } @@ -210,19 +169,61 @@ char vera_is_layer_shown(char layer) { // - mapbase: Specifies the base address of the tile map. // Note that the register only specifies bits 16:9 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. -void vera_set_layer_mapbase(unsigned byte layer, unsigned byte mapbase) { - layer &= $1; +void vera_layer_set_mapbase(unsigned byte layer, unsigned byte mapbase) { unsigned byte* addr = vera_layer_mapbase[layer]; *addr = mapbase; } +// Set the base of the map layer with which the conio will interact. +// - layer: Value of 0 or 1. +// - dw_mapbase: a dword typed address (4 bytes), that specifies the full address of the map base. +// The function does the translation from the dword that contains the 17 bit address, +// to the respective mapbase vera register. +// Note that the register only specifies bits 16:9 of the address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. +void vera_layer_set_mapbase_address(byte layer, dword dw_mapbase) { + + dw_mapbase = dw_mapbase & 0x1FF00; // Aligned to 2048 bit zones. + byte bank_mapbase = (byte)>dw_mapbase; + word offset_mapbase = (<(dw_mapbase>>1)); + vera_layer_set_mapbase(layer,mapbase); +} + +// Get the map base address of the tiles for the layer. +// - layer: Value of 0 or 1. +// - return: Specifies the map base address of the layer, which is returned as a dword. +// Note that the register only specifies bits 16:9 of the 17 bit address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes! +dword vera_layer_get_mapbase_address(byte layer) { + return vera_mapbase_address[layer]; +} + +// Get the map base bank of the tiles for the layer. +// - layer: Value of 0 or 1. +// - return: Bank in vera vram. +byte vera_layer_get_mapbase_bank(byte layer) { + return vera_mapbase_bank[layer]; +} + +// Get the map base lower 16-bit address (offset) of the tiles for the layer. +// - layer: Value of 0 or 1. +// - return: Offset in vera vram of the specified bank. +word vera_layer_get_mapbase_offset(byte layer) { + return vera_mapbase_offset[layer]; +} + // Get the base of the map layer with which the conio will interact. // - layer: Value of 0 or 1. // - return: Returns the base address of the tile map. // Note that the register is a byte, specifying only bits 16:9 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. -unsigned byte vera_get_layer_mapbase(unsigned byte layer) { - layer &= $1; +unsigned byte vera_layer_get_mapbase(unsigned byte layer) { unsigned byte* mapbase = vera_layer_mapbase[layer]; return *mapbase; } @@ -232,8 +233,7 @@ unsigned byte vera_get_layer_mapbase(unsigned byte layer) { // - tilebase: Specifies the base address of the tile map. // Note that the register only specifies bits 16:11 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! -void vera_set_layer_tilebase(unsigned byte layer, unsigned byte tilebase) { - layer &= $1; +void vera_layer_set_tilebase(unsigned byte layer, unsigned byte tilebase) { unsigned byte* addr = vera_layer_tilebase[layer]; *addr = tilebase; } @@ -243,19 +243,44 @@ void vera_set_layer_tilebase(unsigned byte layer, unsigned byte tilebase) { // - return: Specifies the base address of the tile map. // Note that the register only specifies bits 16:11 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! -unsigned byte vera_get_layer_tilebase(unsigned byte layer) { - layer &= $1; - unsigned byte* tilebase = vera_layer_tilebase[layer]; +byte vera_layer_get_tilebase(byte layer) { + byte* tilebase = vera_layer_tilebase[layer]; return *tilebase; } +// Set the base address of the tiles for the layer with which the conio will interact. +// - layer: Value of 0 or 1. +// - dw_tilebase: a dword typed address (4 bytes), that specifies the base address of the tile map. +// The function does the translation from the dword that contains the 17 bit address, +// to the respective tilebase vera register. +// Note that the resulting vera register holds only specifies bits 16:11 of the address, +// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! +void vera_layer_set_tilebase_address(byte layer, dword dw_tilebase) { + + dw_tilebase = dw_tilebase & 0x1FC00; // Aligned to 2048 bit zones. + byte bank_tilebase = (byte)>dw_tilebase; + word word_tilebase = (<(dw_tilebase>>1)); + tilebase &= VERA_LAYER_TILEBASE_MASK; // Ensure that only tilebase is blanked, but keep the rest! + //printf("tilebase = %x\n",tilebase); + //while(!kbhit()); + tilebase = tilebase | ( *vera_tilebase & ~VERA_LAYER_TILEBASE_MASK ); + + vera_layer_set_tilebase(layer,tilebase); +} + // Get the tile base address of the tiles for the layer. // - layer: Value of 0 or 1. // - return: Specifies the base address of the tile map, which is calculated as an unsigned long int. // Note that the register only specifies bits 16:11 of the address, // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! -dword vera_get_layer_tilebase_address(byte layer) { - layer &= $1; +dword vera_layer_get_tilebase_address(byte layer) { byte tilebase = *vera_layer_tilebase[layer]; dword address = tilebase; address &= $FC; @@ -271,8 +296,7 @@ dword vera_get_layer_tilebase_address(byte layer) { // - color: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_set_layer_textcolor(unsigned byte layer, unsigned byte color) { - layer &= $1; +unsigned byte vera_layer_set_textcolor(unsigned byte layer, unsigned byte color) { unsigned byte old = vera_layer_textcolor[layer]; vera_layer_textcolor[layer] = color; return old; @@ -283,7 +307,7 @@ unsigned byte vera_set_layer_textcolor(unsigned byte layer, unsigned byte color) // - return: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_textcolor(unsigned byte layer) { +unsigned byte vera_layer_get_textcolor(unsigned byte layer) { layer &= $1; return vera_layer_textcolor[layer]; } @@ -293,7 +317,7 @@ unsigned byte vera_get_layer_textcolor(unsigned byte layer) { // - color: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_set_layer_backcolor(unsigned byte layer, unsigned byte color) { +unsigned byte vera_layer_set_backcolor(unsigned byte layer, unsigned byte color) { layer &= $1; unsigned byte old = vera_layer_backcolor[layer]; vera_layer_backcolor[layer] = color; @@ -305,7 +329,7 @@ unsigned byte vera_set_layer_backcolor(unsigned byte layer, unsigned byte color) // - return: a 4 bit value ( decimal between 0 and 15). // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_backcolor(unsigned byte layer) { +unsigned byte vera_layer_get_backcolor(unsigned byte layer) { layer &= $1; return vera_layer_backcolor[layer]; } @@ -315,7 +339,7 @@ unsigned byte vera_get_layer_backcolor(unsigned byte layer) { // - return: an 8 bit value with bit 7:4 containing the back color and bit 3:0 containing the front color. // This will only work when the VERA is in 16 color mode! // Note that on the VERA, the transparent color has value 0. -unsigned byte vera_get_layer_color(unsigned byte layer) { +unsigned byte vera_layer_get_color(unsigned byte layer) { layer &= $1; return ((vera_layer_backcolor[layer] << 4) | vera_layer_textcolor[layer]); } @@ -324,7 +348,7 @@ unsigned byte vera_get_layer_color(unsigned byte layer) { // Scroll the horizontal (X) axis of the layer visible area over the layer tile map area. // - layer: Value of 0 or 1. // - scroll: A value between 0 and 4096. -inline void vera_set_layer_horizontal_scroll(byte layer, word scroll) { +inline void vera_layer_set_horizontal_scroll(byte layer, word scroll) { *vera_layer_hscroll_l[layer] = scroll; } @@ -332,13 +356,27 @@ inline void vera_set_layer_horizontal_scroll(byte layer, word scroll) { // Scroll the vertical (Y) axis of the layer visible area over the layer tile map area. // - layer: Value of 0 or 1. // - scroll: A value between 0 and 4096. -inline void vera_set_layer_vertical_scroll(byte layer, word scroll) { +inline void vera_layer_set_vertical_scroll(byte layer, word scroll) { *vera_layer_vscroll_l[layer] = scroll; } +// Get the bit shift value required to skip a whole line fast. +// - layer: Value of 0 or 1. +// - return: Rowshift value to calculate fast from a y value to line offset in tile mode. +byte vera_layer_get_rowshift(byte layer) { + return vera_layer_rowshift[layer]; +} -void vera_mode_tile(byte layer, dword mapbase_dw, dword tilebase_dw, word mapwidth, word mapheight, byte tilewidth, byte tileheight, byte color_depth ) { +// Get the value required to skip a whole line fast. +// - layer: Value of 0 or 1. +// - return: Skip value to calculate fast from a y value to line offset in tile mode. +word vera_layer_get_rowskip(byte layer) { + return vera_layer_rowskip[layer]; +} + + +void vera_layer_mode_tile(byte layer, dword mapbase_address, dword dw_tilebase, word mapwidth, word mapheight, byte tilewidth, byte tileheight, byte color_depth ) { // config byte config = 0x00; switch(color_depth) { @@ -359,19 +397,23 @@ void vera_mode_tile(byte layer, dword mapbase_dw, dword tilebase_dw, word mapwid switch(mapwidth) { case 32: config |= VERA_LAYER_WIDTH_32; - vera_row_shift[layer] = 6; + vera_layer_rowshift[layer] = 6; + vera_layer_rowskip[layer] = 64; break; case 64: config |= VERA_LAYER_WIDTH_64; - vera_row_shift[layer] = 7; + vera_layer_rowshift[layer] = 7; + vera_layer_rowskip[layer] = 128; break; case 128: config |= VERA_LAYER_WIDTH_128; - vera_row_shift[layer] = 8; + vera_layer_rowshift[layer] = 8; + vera_layer_rowskip[layer] = 256; break; case 256: config |= VERA_LAYER_WIDTH_256; - vera_row_shift[layer] = 9; + vera_layer_rowshift[layer] = 9; + vera_layer_rowskip[layer] = 512; break; } switch(mapheight) { @@ -388,32 +430,32 @@ void vera_mode_tile(byte layer, dword mapbase_dw, dword tilebase_dw, word mapwid config |= VERA_LAYER_HEIGHT_256; break; } - vera_set_layer_config(layer, config); + vera_layer_set_config(layer, config); // mapbase - vera_mapbase_word[layer] = mapbase_dw; - vera_mapbase_dword[layer] = mapbase_dw; + vera_mapbase_offset[layer] = mapbase_address); + vera_mapbase_address[layer] = mapbase_address; - mapbase_dw = mapbase_dw >> 1; - byte mapbase = (byte)<(mapbase_dw >> 8); - vera_set_layer_mapbase(layer,mapbase); + mapbase_address = mapbase_address >> 1; + byte mapbase = (byte)<(mapbase_address >> 8); + vera_layer_set_mapbase(layer,mapbase); - //printf("%lx\n",mapbase_dw); + //printf("%lx\n",dw_mapbase); // tilebase - vera_tilebase_word[layer] = tilebase_dw; - vera_tilebase_dword[layer] = tilebase_dw; + vera_tilebase_offset[layer] = dw_tilebase; + vera_tilebase_address[layer] = dw_tilebase; - //printf("tilebase word = %x\n",vera_tilebase_word[layer]); + //printf("tilebase word = %x\n",vera_tilebase_offset[layer]); //printf("tilebase bank = %x\n",vera_tilebase_bank[layer]); - //printf("tilebase dword = %lx\n",vera_tilebase_dword[layer]); + //printf("tilebase dword = %lx\n",vera_tilebase_address[layer]); - tilebase_dw = tilebase_dw >> 1; - byte tilebase = (byte)<(tilebase_dw >> 8); - tilebase &= VERA_TILEBASE_MASK; + dw_tilebase = dw_tilebase >> 1; + byte tilebase = (byte)<(dw_tilebase >> 8); + tilebase &= VERA_LAYER_TILEBASE_MASK; switch(tilewidth) { case 8: tilebase |= VERA_TILEBASE_WIDTH_8; @@ -431,15 +473,15 @@ void vera_mode_tile(byte layer, dword mapbase_dw, dword tilebase_dw, word mapwid break; } //printf("tilebase = %x\n",tilebase); - vera_set_layer_tilebase(layer,tilebase); + vera_layer_set_tilebase(layer,tilebase); } // --- TILE FUNCTIONS --- void vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) { - dword mapbase = vera_mapbase_dword[layer]; - byte shift = vera_row_shift[layer]; + dword mapbase = vera_mapbase_address[layer]; + byte shift = vera_layer_rowshift[layer]; word rowskip = (word)1 << shift; hflip = vera_layer_hflip[hflip]; vflip = vera_layer_vflip[vflip]; diff --git a/src/test/kc/examples/cx16/tilemap.c b/src/test/kc/examples/cx16/tilemap.c index 1a032b232..e8dc036ee 100644 --- a/src/test/kc/examples/cx16/tilemap.c +++ b/src/test/kc/examples/cx16/tilemap.c @@ -20,12 +20,12 @@ void main() { clrscr(); // Now we set the tile map width and height. - // vera_set_layer_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! - // vera_set_layer_config(0, vera_get_layer_config(1)); - // vera_set_layer_tilebase(0, vera_get_layer_tilebase(1)); - // vera_set_layer_map_width_128(0); - // vera_set_layer_map_height_128(0); - dword tilebase = vera_get_layer_tilebase_address(1); + // vera_layer_set_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! + // vera_layer_set_config(0, vera_layer_get_config(1)); + // vera_layer_set_tilebase(0, vera_layer_get_tilebase(1)); + // vera_layer_set_width_128(0); + // vera_layer_set_height_128(0); + dword tilebase = vera_layer_get_tilebase_address(1); vera_mode_tile(0, 0x10000, 0xF800, 128, 128, 8, 8, 1); @@ -42,14 +42,14 @@ void main() { *VERA_IEN = VERA_VSYNC; CLI(); - vera_show_layer(0); + vera_layer_show(0); while(!kbhit()); - vera_hide_layer(0); + vera_layer_hide(0); textcolor(GREY); bgcolor(GREEN); draw_characters(tilebase); - vera_show_layer(0); + vera_layer_show(0); screenlayer(1); @@ -70,11 +70,11 @@ void main() { while(!kbhit()); screenlayer(0); - vera_hide_layer(0); + vera_layer_hide(0); textcolor(DARK_GREY); bgcolor(BLACK); draw_characters(tilebase); - vera_show_layer(0); + vera_layer_show(0); screenlayer(1); gotoxy(0,20); @@ -142,8 +142,8 @@ __interrupt(rom_sys_cx16) void irq_vsync() { scroll_y = 0; } - vera_set_layer_horizontal_scroll(0,(word)scroll_x); - vera_set_layer_vertical_scroll(0,(word)scroll_y); + vera_layer_set_horizontal_scroll(0,(word)scroll_x); + vera_layer_set_vertical_scroll(0,(word)scroll_y); // Reset the VSYNC interrupt *VERA_ISR = VERA_VSYNC; diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c new file mode 100644 index 000000000..45072aad4 --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c @@ -0,0 +1,94 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. +// The CX16 starts in tile map mode, 2BPP in 4 color mode, and uses 16x16 tiles. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + //vera_layer_mode_tile(1, 0x10000, 0x00000, 128, 64, 8, 8, 1); + vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); + //vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); + + byte tiles[256] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + }; + + memcpy_to_vram(1, 0x4000, tiles, 256); + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 40, 30, 0, 0, 0); + + // Draw 4 squares with each tile, starting from row 4, width 1, height 1, separated by 2 characters. + vera_tile_area(0, 0, 4, 2, 1, 1, 0, 0, 0); + vera_tile_area(0, 1, 10, 2, 1, 1, 0, 0, 0); + vera_tile_area(0, 2, 16, 2, 1, 1, 0, 0, 0); + vera_tile_area(0, 3, 22, 2, 1, 1, 0, 0, 0); + + // Draw 4 squares with each tile, starting from row 6, width 4, height 4, separated by 2 characters. + vera_tile_area(0, 0, 4, 4, 4, 4, 0, 0, 0); + vera_tile_area(0, 1, 10, 4, 4, 4, 0, 0, 0); + vera_tile_area(0, 2, 16, 4, 4, 4, 0, 0, 0); + vera_tile_area(0, 3, 22, 4, 4, 4, 0, 0, 0); + + word tile = 0; + byte offset = 0; + + byte row = 10; + + for(byte r:0..3) { + byte column = 4; + for(byte c:0..16) { + vera_tile_area(0, tile, column, row, 1, 1, 0, 0, offset); + column+=2; + offset++; + } + tile++; + tile &= 0x3; + row += 2; + } + + vera_layer_show(0); + + gotoxy(0,40); + printf("vera in tile mode 8 x 8, color depth 2 bits per pixel.\n"); + + printf("in this mode, tiles are 8 pixels wide and 8 pixels tall.\n"); + printf("each tile can have a variation of 4 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors, and only the first 4 colors\n"); + printf("can be used per offset!\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c b/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c index f698b50e2..4679ffe5e 100644 --- a/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c +++ b/src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c @@ -56,7 +56,7 @@ void main() { row += 4; } - vera_show_layer(0); + vera_layer_show(0); gotoxy(0,40); printf("vera in tile mode 8 x 8, color depth 2 bits per pixel.\n"); diff --git a/src/test/kc/examples/cx16/tilemap_4bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_4bpp_16_x_16.c new file mode 100644 index 000000000..b8bd6cc8a --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_4bpp_16_x_16.c @@ -0,0 +1,222 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. +// The CX16 starts in tile map mode, 2BPP in 4 color mode, and uses 16x16 tiles. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + vera_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 4); + + byte tiles[2048] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + }; + + memcpy_to_vram(1, 0x4000, tiles, 2048); + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 40, 30, 0, 0, 0); + + word tile = 0; + + // Draw 4 squares with each tile, starting from row 4, width 1, height 1, separated by 2 characters. + tile = 0; + byte column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 1, 1, 1, 0, 0, 0); + column+=4; + tile++; + } + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 3, 1, 1, 0, 0, 0); + column+=4; + tile++; + } + + tile = 0; + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 5, 3, 3, 0, 0, 0); + column+=4; + tile++; + } + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 9, 3, 3, 0, 0, 0); + column+=4; + tile++; + } + + tile = 0; + byte offset = 0; + + byte row = 13; + + for(byte r:0..7) { + byte column = 1; + for(byte c:0..31) { + vera_tile_area(0, tile, column, row, 1, 1, 0, 0, offset); + column+=1; + tile++; + if((c & 0x0f) == 0x0f) offset++; + tile &= 0x0f; + } + row += 1; + } + + vera_layer_show(0); + + gotoxy(0,46); + printf("vera in tile mode 16 x 16, color depth 4 bits per pixel.\n"); + + printf("in this mode, tiles are 16 pixels wide and 16 pixels tall.\n"); + printf("each tile can have a variation of 16 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors in the palette!.\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/kc/examples/cx16/tilemap_4bpp_8_x_8.c b/src/test/kc/examples/cx16/tilemap_4bpp_8_x_8.c new file mode 100644 index 000000000..aba90d398 --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_4bpp_8_x_8.c @@ -0,0 +1,125 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + vera_mode_tile(0, 0x04000, 0x14000, 128, 128, 8, 8, 4); + + byte tiles[512] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB,0xBB, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + }; + + memcpy_to_vram(1, 0x4000, tiles, 512); + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 80, 60, 0, 0, 0); + + word tile = 0; + + // Draw 4 squares with each tile, starting from row 4, width 1, height 1, separated by 2 characters. + tile = 0; + byte column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 1, 1, 1, 0, 0, 0); + column+=8; + tile++; + } + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 3, 1, 1, 0, 0, 0); + column+=8; + tile++; + } + + tile = 0; + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 5, 6, 6, 0, 0, 0); + column+=8; + tile++; + } + column = 1; + for(byte c:0..7) { + vera_tile_area(0, tile, column, 12, 6, 6, 0, 0, 0); + column+=8; + tile++; + } + + tile = 0; + byte offset = 0; + + byte row = 20; + + for(byte r:0..7) { + byte column = 1; + for(byte c:0..31) { + vera_tile_area(0, tile, column, row, 2, 2, 0, 0, offset); + column+=2; + tile++; + if((c & 0x0f) == 0x0f) offset++; + tile &= 0x0f; + } + row += 2; + } + + vera_layer_show(0); + + gotoxy(0,46); + printf("vera in tile mode 8 x 8, color depth 4 bits per pixel.\n"); + + printf("in this mode, tiles are 8 pixels wide and 8 pixels tall.\n"); + printf("each tile can have a variation of 16 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors in the palette!.\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/kc/examples/cx16/tilemap_8bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_8bpp_16_x_16.c new file mode 100644 index 000000000..e7efbc22b --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_8bpp_16_x_16.c @@ -0,0 +1,152 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + + byte tiles[256] = { + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }; + + // Before we can load the tiles into memory we need to re-arrange a few things! + // The amount of tiles is 256, the color depth is 256, so each tile is 256 bytes! + // That is 65356 bytes of memory, which is 64K. Yup! One memory bank in VRAM. + // VERA VRAM holds in bank 1 many registers that interfere loading all of this data. + // So it is better to load all in bank 0, but then there is an other issue. + // So the default CX16 character set is located in bank 0, at address 0xF800. + // So we need to move this character set to bank 1, suggested is at address 0xF000. + // The CX16 by default writes textual output to layer 1 in text mode, so we need to + // realign the moved character set to 0xf000 as the new tile base for layer 1. + // We also will need to realign for layer 1 the map base from 0x00000 to 0x10000. + // This is now all easily done with a few statements in the new kickc vera lib ... + + // Copy block of memory (from VRAM to VRAM) + // Copies the values from the location pointed by src to the location pointed by dest. + // The method uses the VERA access ports 0 and 1 to copy data from and to in VRAM. + // - src_bank: 64K VRAM bank number to copy from (0/1). + // - src: pointer to the location to copy from. Note that the address is a 16 bit value! + // - src_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access. + // - dest_bank: 64K VRAM bank number to copy to (0/1). + // - dest: pointer to the location to copy to. Note that the address is a 16 bit value! + // - dest_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access. + // - num: The number of bytes to copy + // void memcpy_in_vram(char dest_bank, void *dest, char dest_increment, char src_bank, void *src, char src_increment, unsigned int num ); + memcpy_in_vram(1, 0xF000, VERA_INC_1, 0, 0xF800, VERA_INC_0, 256*8); // We copy the 128 character set of 8 bytes each. + + // Set the base of the tiles for the layer with which the conio will interact. + // - layer: Value of 0 or 1. + // - dw_tilebase: a dword typed address (4 bytes), that specifies the base address of the tile map. + // The function does the translation from the dword that contains the 17 bit address, + // to the respective tilebase vera register. + // Note that the resulting vera register holds only specifies bits 16:11 of the address, + // so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes! + vera_layer_set_tilebase_address(1, 0x1F000); // Here we set layer 1 new character set base (tile base) to the new address. + + // Set the base of the map layer with which the conio will interact. + // - layer: Value of 0 or 1. + // - dw_mapbase: a dword typed address (4 bytes), that specifies the full address of the map base. + // The function does the translation from the dword that contains the 17 bit address, + // to the respective mapbase vera register. + // Note that the register only specifies bits 16:9 of the address, + // so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes. + // void vera_layer_set_mapbase_address(byte layer, dword dw_mapbase); + vera_layer_set_mapbase_address(1, 0x10000); // Here we set the map base of layer 1 to 0x10000; + + vera_layer_mode_tile(1, 0x10000, 0x00000, 128, 64, 8, 8, 1); + + screenlayer(1); + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + while(!kbhit()); + + // Now we can use the full bank 0! + // We set the mapbase of the tile demo to output to 0x12000, + // and the tilebase is set to 0x0000! + vera_layer_mode_tile(0, 0x10000, 0x00000, 64, 64, 16, 16, 8); + + + word tilebase = 0x0000; + memcpy_to_vram(0, tilebase, tiles, 256); + tilebase+=256; + for(byte t:1..10) { + for(byte p:0..255) { + tiles[p]+=1; + } + memcpy_to_vram(1, tilebase, tiles, 256); + tilebase+=256; + } + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 40, 30, 0, 0, 0); + + word tile = 0; + + // Draw 4 squares with each tile, starting from row 4, width 1, height 1, separated by 2 characters. + byte row = 1; + for(byte r:0..15) { + byte column = 1; + for(byte c:0..15) { + vera_tile_area(0, tile, column, row, 1, 1, 0, 0, 0); + column+=2; + tile++; + tile &= 0xff; + } + row += 2; + } + + tile = 0; + row = 20; + for(byte r:0..7) { + byte column = 1; + for(byte c:0..31) { + vera_tile_area(0, tile, column, row, 2, 2, 0, 0, 0); + column+=2; + tile++; + tile &= 0xff; + } + row += 2; + } + + vera_layer_show(0); + + gotoxy(0,46); + printf("vera in tile mode 8 x 8, color depth 8 bits per pixel.\n"); + + printf("in this mode, tiles are 8 pixels wide and 8 pixels tall.\n"); + printf("each tile can have a variation of 256 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors in the palette!.\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/kc/examples/cx16/tilemap_8bpp_8_x_8.c b/src/test/kc/examples/cx16/tilemap_8bpp_8_x_8.c new file mode 100644 index 000000000..40b41a888 --- /dev/null +++ b/src/test/kc/examples/cx16/tilemap_8bpp_8_x_8.c @@ -0,0 +1,90 @@ +// Example program for the Commander X16. +// Demonstrates the usage of the VERA tile map modes and layering. + +// Author: Sven Van de Velde + +// The default layer of the CX16 is layer 1, but the tiles are written on layer 0. + +// An explanation is given how this mode is organized, and how the tiles display and coloring works. +// Pälette offsets are explained also. + +#include +#include + +void main() { + + textcolor(WHITE); + bgcolor(BLACK); + clrscr(); + + vera_mode_tile(0, 0x04000, 0x14000, 128, 128, 8, 8, 8); + + byte tiles[64] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + + word tilebase = 0x4000; + memcpy_to_vram(1, tilebase, tiles, 64); + tilebase+=64; + for(byte t:1..255) { + for(byte p:0..63) { + tiles[p]+=1; + } + memcpy_to_vram(1, tilebase, tiles, 64); + tilebase+=64; + } + + //vera_tile_area(byte layer, word tileindex, byte x, byte y, byte w, byte h, byte hflip, byte vflip, byte offset) + + vera_tile_area(0, 0, 0, 0, 80, 60, 0, 0, 0); + + word tile = 0; + + // Draw 4 squares with each tile, starting from row 4, width 1, height 1, separated by 2 characters. + byte row = 1; + for(byte r:0..7) { + byte column = 1; + for(byte c:0..31) { + vera_tile_area(0, tile, column, row, 1, 1, 0, 0, 0); + column+=2; + tile++; + tile &= 0xff; + } + row += 2; + } + + tile = 0; + row = 20; + for(byte r:0..7) { + byte column = 1; + for(byte c:0..31) { + vera_tile_area(0, tile, column, row, 2, 2, 0, 0, 0); + column+=2; + tile++; + tile &= 0xff; + } + row += 2; + } + + vera_layer_show(0); + + gotoxy(0,46); + printf("vera in tile mode 8 x 8, color depth 8 bits per pixel.\n"); + + printf("in this mode, tiles are 8 pixels wide and 8 pixels tall.\n"); + printf("each tile can have a variation of 256 colors.\n"); + printf("the vera palette of 256 colors, can be used by setting the palette\n"); + printf("offset for each tile.\n"); + printf("here each column is displaying the same tile, but with different offsets!\n"); + printf("each offset aligns to multiples of 16 colors in the palette!.\n"); + printf("however, the first color will always be transparent (black).\n"); + + while(!kbhit()); +} diff --git a/src/test/kc/examples/cx16/veralayers.c b/src/test/kc/examples/cx16/veralayers.c index 669bb96c7..498625c64 100644 --- a/src/test/kc/examples/cx16/veralayers.c +++ b/src/test/kc/examples/cx16/veralayers.c @@ -39,12 +39,12 @@ void main() { // It displays the characters in 1BPP 16x16 color mode! unsigned byte dcvideo = *VERA_DC_VIDEO; printf("\nvera dc video = %x\n", dcvideo); - unsigned byte config = vera_get_layer_config(1); + unsigned byte config = vera_layer_get_config(1); printf("\nvera layer 1 config = %x\n", config); - unsigned byte layershown = vera_is_layer_shown(1); + unsigned byte layershown = vera_layer_is_visible(1); printf("vera layer 1 shown = %c\n", layershown); - unsigned byte mapbase = vera_get_layer_mapbase(1); - unsigned byte tilebase = vera_get_layer_tilebase(1); + unsigned byte mapbase = vera_layer_get_mapbase(1); + unsigned byte tilebase = vera_layer_get_tilebase(1); printf("vera layer 1 mapbase = %hhx, tilebase = %hhx\n", mapbase, tilebase); // Wait for a keypress and after clear the line! @@ -62,17 +62,17 @@ void main() { // But first, we also print the layer 0 VERA configuration. // This statement sets the base of the display layer 1 at VRAM address 0x0200 - vera_set_layer_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! - vera_set_layer_config(0, vera_get_layer_config(1)); - vera_set_layer_tilebase(0, vera_get_layer_tilebase(1)); + vera_layer_set_mapbase(0,0x80); // Set the map base to address 0x10000 in VERA VRAM! + vera_layer_set_config(0, vera_layer_get_config(1)); + vera_layer_set_tilebase(0, vera_layer_get_tilebase(1)); textcolor(WHITE); - config = vera_get_layer_config(0); - printf("\nvera layer 0 config = %x\n", vera_get_layer_config(0)); - layershown = vera_is_layer_shown(0); + config = vera_layer_get_config(0); + printf("\nvera layer 0 config = %x\n", vera_layer_get_config(0)); + layershown = vera_layer_is_visible(0); printf("vera layer 0 shown = %x\n", layershown); - mapbase = vera_get_layer_mapbase(0); - tilebase = vera_get_layer_tilebase(0); + mapbase = vera_layer_get_mapbase(0); + tilebase = vera_layer_get_tilebase(0); printf("vera layer 0 mapbase = %x, tilebase = %x\n", mapbase, tilebase); // Now we print the layer 0 text on the layer 0! @@ -98,10 +98,10 @@ void main() { clearline(); // Now we activate layer 0. - vera_show_layer(0); + vera_layer_show(0); textcolor(WHITE); bgcolor(BLACK); - printf("vera layer 0 shown = %x. ", vera_is_layer_shown(0)); + printf("vera layer 0 shown = %x. ", vera_layer_is_visible(0)); // Wait for a keypress and after clear the line! textcolor(YELLOW); @@ -110,10 +110,10 @@ void main() { while(!kbhit()); clearline(); - vera_hide_layer(0); + vera_layer_hide(0); textcolor(WHITE); bgcolor(BLACK); - printf("vera layer 0 shown = %x. ", vera_is_layer_shown(0)); + printf("vera layer 0 shown = %x. ", vera_layer_is_visible(0)); // Wait for a keypress and after clear the line! textcolor(YELLOW); From a5e81ca64db2e8dc39d039ea21ceccc2f180bbc8 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 17 Jan 2021 08:21:20 +0100 Subject: [PATCH 05/31] fixed much code, working on 16x16 8bit tile mode. There is an error in the compiler i think which i need to communicate to Jesper. --- src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c index 45072aad4..72bb7e5a0 100644 --- a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c +++ b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c @@ -18,7 +18,6 @@ void main() { bgcolor(BLACK); clrscr(); - //vera_layer_mode_tile(1, 0x10000, 0x00000, 128, 64, 8, 8, 1); vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); //vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); From 056259b2e07dffe3ce2c604d1e7a69c0ed209934 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 17 Jan 2021 08:21:46 +0100 Subject: [PATCH 06/31] fixed much code, working on 16x16 8bit tile mode. There is an error in the compiler i think which i need to communicate to Jesper. --- src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c index 72bb7e5a0..ded52bf14 100644 --- a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c +++ b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c @@ -9,7 +9,7 @@ // An explanation is given how this mode is organized, and how the tiles display and coloring works. // Pälette offsets are explained also. -#include +#include #include void main() { From bdb1dba43baa5d75dac8f9160dd49ca4e36e1f4c Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 17 Jan 2021 08:39:17 +0100 Subject: [PATCH 07/31] fixed much code, working on 16x16 8bit tile mode. There is an error in the compiler i think which i need to communicate to Jesper. --- src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c index ded52bf14..6ca180432 100644 --- a/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c +++ b/src/test/kc/examples/cx16/tilemap_2bpp_16_x_16.c @@ -19,7 +19,7 @@ void main() { clrscr(); vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); - //vera_layer_mode_tile(0, 0x04000, 0x14000, 128, 128, 16, 16, 2); + //vera_layer_mode_tile(0, 0x00000, 0x14000, 128, 128, 16, 16, 2); byte tiles[256] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, From ead5a4308591b398c225acab5719378207e5f7df Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 17 Jan 2021 20:53:13 +0100 Subject: [PATCH 08/31] Added 2 new fragments to resolve asm dword related code. Optimized a lot of veralib code. Test programs added. --- .idea/jarRepositories.xml | 5 + .../Maven__org_antlr_antlr_runtime_3_5_2.xml | 13 + kickc.iml | 1 + .../cache/fragment-cache-wdc65c02.asm | 4456 ++++++----------- .../pduc1_derefidx_vbuxx=vdum1.asm | 8 + .../mos6502-common/vdum1=vdum1_ror_1.asm | 4 + src/main/kc/lib/conio-cx16.c | 8 +- src/main/kc/lib/veralib.c | 4 +- src/test/kc/examples/cx16/dword.c | 15 + src/test/kc/examples/cx16/dword_low_hi.c | 11 + .../kc/examples/cx16/tilemap_2bpp_16_x_16.c | 1 - 11 files changed, 1551 insertions(+), 2975 deletions(-) create mode 100644 .idea/libraries/Maven__org_antlr_antlr_runtime_3_5_2.xml create mode 100644 src/main/fragment/mos6502-common/pduc1_derefidx_vbuxx=vdum1.asm create mode 100644 src/main/fragment/mos6502-common/vdum1=vdum1_ror_1.asm create mode 100644 src/test/kc/examples/cx16/dword.c create mode 100644 src/test/kc/examples/cx16/dword_low_hi.c diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml index bc3a852ae..50a8f6e7e 100644 --- a/.idea/jarRepositories.xml +++ b/.idea/jarRepositories.xml @@ -6,6 +6,11 @@