mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
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).
This commit is contained in:
parent
72dd0f044c
commit
d45e58a1be
1044
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
1044
src/main/fragment/cache/fragment-cache-wdc65c02.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -141,20 +141,20 @@ char * const VERA_DC_VSTOP = 0x9f2c;
|
|||||||
// Configuration work tables
|
// Configuration work tables
|
||||||
|
|
||||||
// Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
|
// 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_WIDTH_32 = 0x00;
|
||||||
byte const VERA_LAYER_CONFIG_WIDTH_64 = 0x10;
|
byte const VERA_LAYER_WIDTH_64 = 0x10;
|
||||||
byte const VERA_LAYER_CONFIG_WIDTH_128 = 0x20;
|
byte const VERA_LAYER_WIDTH_128 = 0x20;
|
||||||
byte const VERA_LAYER_CONFIG_WIDTH_256 = 0x30;
|
byte const VERA_LAYER_WIDTH_256 = 0x30;
|
||||||
byte const VERA_LAYER_CONFIG_WIDTH_MASK = 0x30;
|
byte const VERA_LAYER_WIDTH_MASK = 0x30;
|
||||||
word const VERA_LAYER_CONFIG_WIDTH[4] = {32, 64, 128, 256};
|
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)
|
// 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_HEIGHT_32 = 0x00;
|
||||||
byte const VERA_LAYER_CONFIG_HEIGHT_64 = 0x40;
|
byte const VERA_LAYER_HEIGHT_64 = 0x40;
|
||||||
byte const VERA_LAYER_CONFIG_HEIGHT_128 = 0x80;
|
byte const VERA_LAYER_HEIGHT_128 = 0x80;
|
||||||
byte const VERA_LAYER_CONFIG_HEIGHT_256 = 0xC0;
|
byte const VERA_LAYER_HEIGHT_256 = 0xC0;
|
||||||
byte const VERA_LAYER_CONFIG_HEIGHT_MASK = 0xC0;
|
byte const VERA_LAYER_HEIGHT_MASK = 0xC0;
|
||||||
word const VERA_LAYER_CONFIG_HEIGHT[4] = {32, 64, 128, 256};
|
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)
|
// 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_1BPP = 0x00;
|
||||||
@ -178,6 +178,13 @@ char * const VERA_L0_MAPBASE = 0x9f2e;
|
|||||||
// $9F2F L0_TILEBASE Layer 0 Tile Base
|
// $9F2F L0_TILEBASE Layer 0 Tile Base
|
||||||
// Bit 2-7: Tile Base Address (16:11)
|
// Bit 2-7: Tile Base Address (16:11)
|
||||||
// Bit 1: Tile Height (0:8 pixels, 1:16 pixels)
|
// 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)
|
// Bit 0: Tile Width (0:8 pixels, 1:16 pixels)
|
||||||
char * const VERA_L0_TILEBASE = 0x9f2f;
|
char * const VERA_L0_TILEBASE = 0x9f2f;
|
||||||
// $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0)
|
// $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0)
|
||||||
|
@ -9,6 +9,21 @@
|
|||||||
// --- VERA function encapsulation ---
|
// --- VERA function encapsulation ---
|
||||||
|
|
||||||
// --- VERA layer management ---
|
// --- 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_config[2] = {VERA_L0_CONFIG, VERA_L1_CONFIG};
|
||||||
byte vera_layer_enable[2] = { VERA_LAYER0_ENABLE, VERA_LAYER1_ENABLE };
|
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;
|
*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 ---
|
// --- VERA layer management ---
|
||||||
|
|
||||||
// Set the configuration of the layer.
|
// Set the configuration of the layer.
|
||||||
@ -70,58 +98,58 @@ char vera_get_layer_config(char layer) {
|
|||||||
// - layer: Value of 0 or 1.
|
// - layer: Value of 0 or 1.
|
||||||
inline void vera_set_layer_map_width_32(unsigned byte layer) {
|
inline void vera_set_layer_map_width_32(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK;
|
*addr &= ~VERA_LAYER_WIDTH_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_WIDTH_32;
|
*addr |= VERA_LAYER_WIDTH_32;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_width_64(unsigned byte layer) {
|
inline void vera_set_layer_map_width_64(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
//*addr &= (~VERA_CONFIG_WIDTH_MASK) | VERA_CONFIG_WIDTH_64;
|
//*addr &= (~VERA_CONFIG_WIDTH_MASK) | VERA_CONFIG_WIDTH_64;
|
||||||
*addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK;
|
*addr &= ~VERA_LAYER_WIDTH_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_WIDTH_64;
|
*addr |= VERA_LAYER_WIDTH_64;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_width_128(unsigned byte layer) {
|
inline void vera_set_layer_map_width_128(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK;
|
*addr &= ~VERA_LAYER_WIDTH_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_WIDTH_128;
|
*addr |= VERA_LAYER_WIDTH_128;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_width_256(unsigned byte layer) {
|
inline void vera_set_layer_map_width_256(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_WIDTH_MASK;
|
*addr &= ~VERA_LAYER_WIDTH_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_WIDTH_256;
|
*addr |= VERA_LAYER_WIDTH_256;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_height_32(unsigned byte layer) {
|
inline void vera_set_layer_map_height_32(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK;
|
*addr &= ~VERA_LAYER_HEIGHT_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_HEIGHT_32;
|
*addr |= VERA_LAYER_HEIGHT_32;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_height_64(unsigned byte layer) {
|
inline void vera_set_layer_map_height_64(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK;
|
*addr &= ~VERA_LAYER_HEIGHT_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_HEIGHT_64;
|
*addr |= VERA_LAYER_HEIGHT_64;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_height_128(unsigned byte layer) {
|
inline void vera_set_layer_map_height_128(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK;
|
*addr &= ~VERA_LAYER_HEIGHT_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_HEIGHT_128;
|
*addr |= VERA_LAYER_HEIGHT_128;
|
||||||
}
|
}
|
||||||
inline void vera_set_layer_map_height_256(unsigned byte layer) {
|
inline void vera_set_layer_map_height_256(unsigned byte layer) {
|
||||||
byte* addr = vera_layer_config[layer];
|
byte* addr = vera_layer_config[layer];
|
||||||
*addr &= ~VERA_LAYER_CONFIG_HEIGHT_MASK;
|
*addr &= ~VERA_LAYER_HEIGHT_MASK;
|
||||||
*addr |= VERA_LAYER_CONFIG_HEIGHT_256;
|
*addr |= VERA_LAYER_HEIGHT_256;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the map width or height of the layer.
|
// Get the map width or height of the layer.
|
||||||
// - layer: Value of 0 or 1.
|
// - layer: Value of 0 or 1.
|
||||||
word vera_get_layer_map_width(unsigned byte layer) {
|
word vera_get_layer_map_width(unsigned byte layer) {
|
||||||
byte* config = vera_layer_config[layer];
|
byte* config = vera_layer_config[layer];
|
||||||
byte mask = (byte)VERA_LAYER_CONFIG_WIDTH_MASK;
|
byte mask = (byte)VERA_LAYER_WIDTH_MASK;
|
||||||
return VERA_LAYER_CONFIG_WIDTH[ (*config & mask) >> 4];
|
return VERA_LAYER_WIDTH[ (*config & mask) >> 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
word vera_get_layer_map_height(unsigned byte layer) {
|
word vera_get_layer_map_height(unsigned byte layer) {
|
||||||
byte* config = vera_layer_config[layer];
|
byte* config = vera_layer_config[layer];
|
||||||
byte mask = VERA_LAYER_CONFIG_HEIGHT_MASK;
|
byte mask = VERA_LAYER_HEIGHT_MASK;
|
||||||
return VERA_LAYER_CONFIG_HEIGHT[ (*config & mask) >> 6];
|
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.
|
// 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;
|
*vera_layer_vscroll_l[layer] = <scroll;
|
||||||
*vera_layer_vscroll_h[layer] = >scroll;
|
*vera_layer_vscroll_h[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_bank[layer] = (byte)>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_bank[layer] = (byte)>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;
|
||||||
|
byte index_h = >tileindex;
|
||||||
|
index_h |= hflip;
|
||||||
|
index_h |= vflip;
|
||||||
|
index_h |= offset;
|
||||||
|
mapbase += ((word)y << shift);
|
||||||
|
mapbase += (x << 1);
|
||||||
|
for(byte r=0; r<h; r++) {
|
||||||
|
vera_vram_address0(mapbase,VERA_INC_1);
|
||||||
|
for(byte c=0; c<w; c++) {
|
||||||
|
*VERA_DATA0 = index_l;
|
||||||
|
*VERA_DATA0 = index_h;
|
||||||
|
}
|
||||||
|
mapbase += rowskip;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,14 @@ void main() {
|
|||||||
clrscr();
|
clrscr();
|
||||||
|
|
||||||
// Now we set the tile map width and height.
|
// 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_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_config(0, vera_get_layer_config(1));
|
||||||
vera_set_layer_tilebase(0, vera_get_layer_tilebase(1));
|
// vera_set_layer_tilebase(0, vera_get_layer_tilebase(1));
|
||||||
vera_set_layer_map_width_128(0);
|
// vera_set_layer_map_width_128(0);
|
||||||
vera_set_layer_map_height_128(0);
|
// vera_set_layer_map_height_128(0);
|
||||||
dword tilebase = vera_get_layer_tilebase_address(0);
|
dword tilebase = vera_get_layer_tilebase_address(1);
|
||||||
|
|
||||||
|
vera_mode_tile(0, 0x10000, 0xF800, 128, 128, 8, 8, 1);
|
||||||
|
|
||||||
screenlayer(0);
|
screenlayer(0);
|
||||||
scroll(0); // Scrolling on conio is deactivated, so conio will output beyond the borders of the visible screen.
|
scroll(0); // Scrolling on conio is deactivated, so conio will output beyond the borders of the visible screen.
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
// 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 <veralib.h>
|
|
||||||
#include <printf.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
74
src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c
Normal file
74
src/test/kc/examples/cx16/tilemap_2bpp_8_x_8.c
Normal file
@ -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 <veralib.h>
|
||||||
|
#include <printf.h>
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
@ -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 #<SINX_LEN
|
|
||||||
bne __b1
|
|
||||||
// sin_idx_x = 0
|
|
||||||
lda #<0
|
|
||||||
sta.z sin_idx_x
|
|
||||||
sta.z sin_idx_x+1
|
|
||||||
__b1:
|
|
||||||
// if(--sin_idx_y==0xffff)
|
|
||||||
lda.z sin_idx_y
|
|
||||||
bne !+
|
|
||||||
dec.z sin_idx_y+1
|
|
||||||
!:
|
|
||||||
dec.z sin_idx_y
|
|
||||||
lda.z sin_idx_y+1
|
|
||||||
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
|
|
||||||
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
|
|
||||||
lda #>VERA_SPRITE_ATTR+2&$ffff
|
|
||||||
sta.z vram_sprite_pos+1
|
|
||||||
lda #0
|
|
||||||
sta.z s
|
|
||||||
__b5:
|
|
||||||
// for(char s=0;s<NUM_SPRITES;s++)
|
|
||||||
lda.z s
|
|
||||||
cmp #$20
|
|
||||||
bcc __b6
|
|
||||||
// *VERA_ISR = VERA_VSYNC
|
|
||||||
// Reset the VSYNC interrupt
|
|
||||||
lda #VERA_VSYNC
|
|
||||||
sta VERA_ISR
|
|
||||||
// asm
|
|
||||||
// Exit CX16 KERNAL IRQ
|
|
||||||
jmp $e034
|
|
||||||
// }
|
|
||||||
__b6:
|
|
||||||
// SPRITE_ATTR.X = SINX[i_x]
|
|
||||||
lda.z i_x
|
|
||||||
asl
|
|
||||||
sta.z __11
|
|
||||||
lda.z i_x+1
|
|
||||||
rol
|
|
||||||
sta.z __11+1
|
|
||||||
clc
|
|
||||||
lda.z __13
|
|
||||||
adc #<SINX
|
|
||||||
sta.z __13
|
|
||||||
lda.z __13+1
|
|
||||||
adc #>SINX
|
|
||||||
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
|
|
||||||
lda.z __14+1
|
|
||||||
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
|
|
||||||
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;s<NUM_SPRITES;s++)
|
|
||||||
inc.z s
|
|
||||||
jmp __b5
|
|
||||||
}
|
|
||||||
main: {
|
|
||||||
// Copy 8* sprite attributes to VRAM
|
|
||||||
.label vram_sprite_attr = $a
|
|
||||||
.label s = 9
|
|
||||||
// memcpy_to_vram((char)>SPRITE_PIXELS_VRAM, <SPRITE_PIXELS_VRAM, SPRITE_PIXELS, 64*64)
|
|
||||||
// Copy sprite data to VRAM
|
|
||||||
lda #<$40*$40
|
|
||||||
sta.z memcpy_to_vram.num
|
|
||||||
lda #>$40*$40
|
|
||||||
sta.z memcpy_to_vram.num+1
|
|
||||||
lda #<SPRITE_PIXELS
|
|
||||||
sta.z memcpy_to_vram.src
|
|
||||||
lda #>SPRITE_PIXELS
|
|
||||||
sta.z memcpy_to_vram.src+1
|
|
||||||
ldx #0
|
|
||||||
lda #<SPRITE_PIXELS_VRAM&$ffff
|
|
||||||
sta.z memcpy_to_vram.vdest
|
|
||||||
lda #>SPRITE_PIXELS_VRAM&$ffff
|
|
||||||
sta.z memcpy_to_vram.vdest+1
|
|
||||||
jsr memcpy_to_vram
|
|
||||||
// memcpy_to_vram((char)>VERA_PALETTE, <VERA_PALETTE, SPRITE_PIXELS+64*64, 0x200)
|
|
||||||
// Copy sprite palette to VRAM
|
|
||||||
lda #<$200
|
|
||||||
sta.z memcpy_to_vram.num
|
|
||||||
lda #>$200
|
|
||||||
sta.z memcpy_to_vram.num+1
|
|
||||||
lda #<SPRITE_PIXELS+$40*$40
|
|
||||||
sta.z memcpy_to_vram.src
|
|
||||||
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
|
|
||||||
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
|
|
||||||
lda #>VERA_SPRITE_ATTR&$ffff
|
|
||||||
sta.z vram_sprite_attr+1
|
|
||||||
lda #0
|
|
||||||
sta.z s
|
|
||||||
__b1:
|
|
||||||
// for(char s=0;s<NUM_SPRITES;s++)
|
|
||||||
lda.z s
|
|
||||||
cmp #$20
|
|
||||||
bcc __b2
|
|
||||||
// *VERA_CTRL &= ~VERA_DCSEL
|
|
||||||
// Enable sprites
|
|
||||||
lda #VERA_DCSEL^$ff
|
|
||||||
and VERA_CTRL
|
|
||||||
sta VERA_CTRL
|
|
||||||
// *VERA_DC_VIDEO |= VERA_SPRITES_ENABLE
|
|
||||||
lda #VERA_SPRITES_ENABLE
|
|
||||||
ora VERA_DC_VIDEO
|
|
||||||
sta VERA_DC_VIDEO
|
|
||||||
// asm
|
|
||||||
sei
|
|
||||||
// *KERNEL_IRQ = &irq_vsync
|
|
||||||
lda #<irq_vsync
|
|
||||||
sta KERNEL_IRQ
|
|
||||||
lda #>irq_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
|
|
||||||
lda #>SIZEOF_STRUCT_VERA_SPRITE
|
|
||||||
sta.z memcpy_to_vram.num+1
|
|
||||||
lda #<SPRITE_ATTR
|
|
||||||
sta.z memcpy_to_vram.src
|
|
||||||
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;s<NUM_SPRITES;s++)
|
|
||||||
inc.z s
|
|
||||||
jmp __b1
|
|
||||||
}
|
|
||||||
// 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
|
|
||||||
// Select DATA0
|
|
||||||
lda #VERA_ADDRSEL^$ff
|
|
||||||
and VERA_CTRL
|
|
||||||
sta VERA_CTRL
|
|
||||||
// <vdest
|
|
||||||
lda.z vdest
|
|
||||||
// *VERA_ADDRX_L = <vdest
|
|
||||||
// Set address
|
|
||||||
sta VERA_ADDRX_L
|
|
||||||
// >vdest
|
|
||||||
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
|
|
@ -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+2, irq_vsync::@9/irq_vsync::vram_sprite_pos#1 )
|
|
||||||
[14] irq_vsync::i_y#3 = phi( irq_vsync::@2/irq_vsync::i_y#0, irq_vsync::@9/irq_vsync::i_y#9 )
|
|
||||||
[14] irq_vsync::i_x#3 = phi( irq_vsync::@2/irq_vsync::i_x#0, irq_vsync::@9/irq_vsync::i_x#7 )
|
|
||||||
[14] irq_vsync::s#2 = phi( irq_vsync::@2/0, irq_vsync::@9/irq_vsync::s#1 )
|
|
||||||
[15] if(irq_vsync::s#2<$20) goto irq_vsync::@6
|
|
||||||
to:irq_vsync::@7
|
|
||||||
irq_vsync::@7: scope:[irq_vsync] from irq_vsync::@5
|
|
||||||
[16] *VERA_ISR = VERA_VSYNC
|
|
||||||
asm { jmp$e034 }
|
|
||||||
to:irq_vsync::@return
|
|
||||||
irq_vsync::@return: scope:[irq_vsync] from irq_vsync::@7
|
|
||||||
[18] return
|
|
||||||
to:@return
|
|
||||||
irq_vsync::@6: scope:[irq_vsync] from irq_vsync::@5
|
|
||||||
[19] irq_vsync::$11 = irq_vsync::i_x#3 << 1
|
|
||||||
[20] irq_vsync::$13 = SINX + irq_vsync::$11
|
|
||||||
[21] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *irq_vsync::$13
|
|
||||||
[22] irq_vsync::$12 = irq_vsync::i_y#3 << 1
|
|
||||||
[23] irq_vsync::$14 = SINY + irq_vsync::$12
|
|
||||||
[24] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *irq_vsync::$14
|
|
||||||
[25] memcpy_to_vram::vdest#3 = (void*)irq_vsync::vram_sprite_pos#2
|
|
||||||
[26] call memcpy_to_vram
|
|
||||||
to:irq_vsync::@12
|
|
||||||
irq_vsync::@12: scope:[irq_vsync] from irq_vsync::@6
|
|
||||||
[27] irq_vsync::vram_sprite_pos#1 = irq_vsync::vram_sprite_pos#2 + SIZEOF_STRUCT_VERA_SPRITE
|
|
||||||
[28] irq_vsync::i_x#1 = irq_vsync::i_x#3 + $19
|
|
||||||
[29] if(irq_vsync::i_x#1<SINX_LEN) goto irq_vsync::@8
|
|
||||||
to:irq_vsync::@10
|
|
||||||
irq_vsync::@10: scope:[irq_vsync] from irq_vsync::@12
|
|
||||||
[30] irq_vsync::i_x#2 = irq_vsync::i_x#1 - SINX_LEN
|
|
||||||
to:irq_vsync::@8
|
|
||||||
irq_vsync::@8: scope:[irq_vsync] from irq_vsync::@10 irq_vsync::@12
|
|
||||||
[31] irq_vsync::i_x#7 = phi( irq_vsync::@10/irq_vsync::i_x#2, irq_vsync::@12/irq_vsync::i_x#1 )
|
|
||||||
[32] irq_vsync::i_y#1 = irq_vsync::i_y#3 + $13
|
|
||||||
[33] if(irq_vsync::i_y#1<SINY_LEN) goto irq_vsync::@9
|
|
||||||
to:irq_vsync::@11
|
|
||||||
irq_vsync::@11: scope:[irq_vsync] from irq_vsync::@8
|
|
||||||
[34] irq_vsync::i_y#2 = irq_vsync::i_y#1 - SINY_LEN
|
|
||||||
to:irq_vsync::@9
|
|
||||||
irq_vsync::@9: scope:[irq_vsync] from irq_vsync::@11 irq_vsync::@8
|
|
||||||
[35] irq_vsync::i_y#9 = phi( irq_vsync::@11/irq_vsync::i_y#2, irq_vsync::@8/irq_vsync::i_y#1 )
|
|
||||||
[36] irq_vsync::s#1 = ++ irq_vsync::s#2
|
|
||||||
to:irq_vsync::@5
|
|
||||||
|
|
||||||
void main()
|
|
||||||
main: scope:[main] from __start::@1
|
|
||||||
[37] phi()
|
|
||||||
[38] call memcpy_to_vram
|
|
||||||
to:main::@5
|
|
||||||
main::@5: scope:[main] from main
|
|
||||||
[39] phi()
|
|
||||||
[40] call memcpy_to_vram
|
|
||||||
to:main::@1
|
|
||||||
main::@1: scope:[main] from main::@5 main::@6
|
|
||||||
[41] main::vram_sprite_attr#2 = phi( main::@5/(byte*)<VERA_SPRITE_ATTR, main::@6/main::vram_sprite_attr#1 )
|
|
||||||
[41] main::s#2 = phi( main::@5/0, main::@6/main::s#1 )
|
|
||||||
[42] if(main::s#2<$20) goto main::@2
|
|
||||||
to:main::@3
|
|
||||||
main::@3: scope:[main] from main::@1
|
|
||||||
[43] *VERA_CTRL = *VERA_CTRL & ~VERA_DCSEL
|
|
||||||
[44] *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
|
|
||||||
[46] *KERNEL_IRQ = &irq_vsync
|
|
||||||
[47] *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
|
|
||||||
[49] return
|
|
||||||
to:@return
|
|
||||||
main::@2: scope:[main] from main::@1
|
|
||||||
[50] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_X) + $a
|
|
||||||
[51] *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) = *((word*)&SPRITE_ATTR+OFFSET_STRUCT_VERA_SPRITE_Y) + $a
|
|
||||||
[52] memcpy_to_vram::vdest#2 = (void*)main::vram_sprite_attr#2
|
|
||||||
[53] call memcpy_to_vram
|
|
||||||
to:main::@6
|
|
||||||
main::@6: scope:[main] from main::@2
|
|
||||||
[54] main::vram_sprite_attr#1 = main::vram_sprite_attr#2 + SIZEOF_STRUCT_VERA_SPRITE
|
|
||||||
[55] main::s#1 = ++ main::s#2
|
|
||||||
to:main::@1
|
|
||||||
|
|
||||||
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
|
|
||||||
[56] memcpy_to_vram::num#4 = phi( irq_vsync::@6/4, main/(word)$40*$40, main::@2/SIZEOF_STRUCT_VERA_SPRITE, main::@5/$200 )
|
|
||||||
[56] memcpy_to_vram::src#4 = phi( irq_vsync::@6/(void*)&SPRITE_ATTR+2, main/(void*)SPRITE_PIXELS, main::@2/(void*)&SPRITE_ATTR, main::@5/(void*)SPRITE_PIXELS+(word)$40*$40 )
|
|
||||||
[56] memcpy_to_vram::vbank#4 = phi( irq_vsync::@6/irq_vsync::vram_sprite_attr_bank, main/0, main::@2/(byte)>VERA_SPRITE_ATTR, main::@5/(byte)>VERA_PALETTE )
|
|
||||||
[56] memcpy_to_vram::vdest#4 = phi( irq_vsync::@6/memcpy_to_vram::vdest#3, main/(void*)<SPRITE_PIXELS_VRAM, main::@2/memcpy_to_vram::vdest#2, main::@5/(void*)<VERA_PALETTE )
|
|
||||||
[57] *VERA_CTRL = *VERA_CTRL & ~VERA_ADDRSEL
|
|
||||||
[58] memcpy_to_vram::$0 = < memcpy_to_vram::vdest#4
|
|
||||||
[59] *VERA_ADDRX_L = memcpy_to_vram::$0
|
|
||||||
[60] memcpy_to_vram::$1 = > 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
|
|
File diff suppressed because it is too large
Load Diff
@ -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: <SPRITE_PIXELS_VRAM/$20|VERA_SPRITE_8BPP, X: $140-$20, Y: (word)$f0-$20, CTRL1: $c, CTRL2: $f0 }
|
|
||||||
const byte* SPRITE_PIXELS[$40*$40+$200] = kickasm {{ .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
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
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 ]
|
|
Loading…
Reference in New Issue
Block a user