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