1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-28 01:29:44 +00:00

Merged FlightControl/CX16_FRAMEWORK implemeting CX16 veralib.h and conio.h by Sven Van de Velde.

This commit is contained in:
Jesper Gravgaard 2021-01-13 18:18:14 +01:00
commit ee9f738f87
14 changed files with 1190 additions and 18 deletions

View File

@ -1,6 +1,10 @@
// Atari 8-bit 400/800/XL/XE Registers and Constants
// https://en.wikipedia.org/wiki/Atari_8-bit_family
#ifndef __ATARIXL__
#error "Target platform must be atarixl"
#endif
#include <atari-antic.h>
#include <atari-gtia.h>
#include <atari-pokey.h>

View File

@ -1,6 +1,10 @@
// Atari 2600 Registers and Constants
// https://web.archive.org/web/20170215054248/http://www.atariguide.com/pdfs/Atari_2600_VCS_Domestic_Field_Service_Manual.pdf
#ifndef __ATARI2600__
#error "Target platform must be atari2600"
#endif
#include <atari-tia.h>
#include <mos6532.h>

View File

@ -1,6 +1,24 @@
// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
// The colors of the CX16
const char BLACK = 0x0;
const char WHITE = 0x1;
const char RED = 0x2;
const char CYAN = 0x3;
const char PURPLE = 0x4;
const char GREEN = 0x5;
const char BLUE = 0x6;
const char YELLOW = 0x7;
const char ORANGE = 0x8;
const char BROWN = 0x9;
const char PINK = 0xa;
const char DARK_GREY = 0xb;
const char GREY = 0xc;
const char LIGHT_GREEN = 0xd;
const char LIGHT_BLUE = 0xe;
const char LIGHT_GREY = 0xf;
// To access the VRAM (which is 128kB in size) an indirection mechanism is used.
// First the address to be accessed needs to be set (ADDRx_L/ADDRx_M/ADDRx_H) and
// then the data on that VRAM address can be read from or written to via the DATA0/1 register.
@ -36,6 +54,22 @@ const char VERA_INC_80 = 0xc0;
const char VERA_INC_160 = 0xd0;
const char VERA_INC_320 = 0xe0;
const char VERA_INC_640 = 0xf0;
const char VERA_DECR_0 = 0x08;
const char VERA_DECR_1 = 0x18;
const char VERA_DECR_2 = 0x28;
const char VERA_DECR_4 = 0x38;
const char VERA_DECR_8 = 0x48;
const char VERA_DECR_16 = 0x58;
const char VERA_DECR_32 = 0x68;
const char VERA_DECR_64 = 0x78;
const char VERA_DECR_128 = 0x88;
const char VERA_DECR_256 = 0x98;
const char VERA_DECR_512 = 0xa8;
const char VERA_DECR_40 = 0xb8;
const char VERA_DECR_80 = 0xc8;
const char VERA_DECR_160 = 0xd8;
const char VERA_DECR_320 = 0xe8;
const char VERA_DECR_640 = 0xf8;
// $9F23 DATA0 VRAM Data port 0
char * const VERA_DATA0 = 0x9f23;
// $9F24 DATA1 VRAM Data port 1
@ -81,14 +115,14 @@ char * const VERA_IRQLINE_L = 0x9f28;
// 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)
char * const VERA_DC_VIDEO = 0x9f29;
char VERA_SPRITES_ENABLE = 0x40;
char VERA_LAYER1_ENABLE = 0x20;
char VERA_LAYER0_ENABLE = 0x10;
char VERA_CROMA_DISABLE = 0x04;
char VERA_OUTPUT_DISABLE = 0x00;
char VERA_OUTPUT_VGA = 0x01;
char VERA_OUTPUT_NTSC = 0x02;
char VERA_OUTPUT_RGB = 0x03;
const char VERA_SPRITES_ENABLE = 0x40;
const char VERA_LAYER1_ENABLE = 0x20;
const char VERA_LAYER0_ENABLE = 0x10;
const char VERA_CROMA_DISABLE = 0x04;
const char VERA_OUTPUT_DISABLE = 0x00;
const char VERA_OUTPUT_VGA = 0x01;
const char VERA_OUTPUT_NTSC = 0x02;
const char VERA_OUTPUT_RGB = 0x03;
// $9F2A DC_HSCALE (DCSEL=0) Active Display H-Scale
char * const VERA_DC_HSCALE = 0x9f2a;
// $9F2B DC_VSCALE (DCSEL=0) Active Display V-Scale
@ -110,6 +144,29 @@ char * const VERA_DC_VSTOP = 0x9f2c;
// Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode)
// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp)
char * const VERA_L0_CONFIG = 0x9f2d;
// Layer Configuration Bit 6-7: Map Height (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
char const VERA_CONFIG_HEIGHT_32 = 0x00;
char const VERA_CONFIG_HEIGHT_64 = 0x40;
char const VERA_CONFIG_HEIGHT_128 = 0x80;
char const VERA_CONFIG_HEIGHT_256 = 0xC0;
char const VERA_CONFIG_HEIGHT_MASK = 0xC0;
// Layer Configuration Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
char const VERA_CONFIG_WIDTH_32 = 0x00;
char const VERA_CONFIG_WIDTH_64 = 0x10;
char const VERA_CONFIG_WIDTH_128 = 0x20;
char const VERA_CONFIG_WIDTH_256 = 0x30;
char const VERA_CONFIG_WIDTH_MASK = 0x30;
// Layer Configuration Bit 3: T256C (0: tiles use a 16-color foreground and background color, 1: tiles use a 256-color foreground color) (only relevant in 1bpp modes)
char const VERA_CONFIG_16C = 0x00;
char const VERA_CONFIG_256C = 0x08;
// Layer Configuration Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode)
char const VERA_CONFIG_MODE_TILE = 0x00;
char const VERA_CONFIG_MODE_BITMAP = 0x04;
// Layer Configuration Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp)
char const VERA_CONFIG_COLOR_1BPP = 0x00;
char const VERA_CONFIG_COLOR_2BPP = 0x01;
char const VERA_CONFIG_COLOR_4BPP = 0x02;
char const VERA_CONFIG_COLOR_8BPP = 0x03;
// $9F2E L0_MAPBASE Layer 0 Map Base Address (16:9)
char * const VERA_L0_MAPBASE = 0x9f2e;
// $9F2F L0_TILEBASE Layer 0 Tile Base
@ -125,7 +182,6 @@ char * const VERA_L0_HSCROLL_H = 0x9f31;
char * const VERA_L0_VSCROLL_L = 0x9f32;
// $9F33 L0_VSCROLL_H Layer 0 V-Scroll (11:8)
char * const VERA_L0_VSCROLL_H = 0x9f33;
// $9F34 L1_CONFIG Layer 1 Configuration
// Bit 6-7: Map Height (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)
// Bit 3: T256C (0: tiles use a 16-color foreground and background color, 1: tiles use a 256-color foreground color) (only relevant in 1bpp modes)

View File

@ -1,7 +1,9 @@
// Commander X16
// https://www.commanderx16.com/forum/index.php?/about-faq/
// https://github.com/commanderx16/x16-docs/blob/master/Commander%20X16%20Programmer's%20Reference%20Guide.md
#ifndef __CX16__
#error "Target platform must be cx16"
#endif
#include <cx16-vera.h>
#include <mos6522.h>
@ -61,3 +63,16 @@ char vpeek(char vbank, char* vaddr);
// - src: The source address in RAM
// - num: The number of bytes to copy
void memcpy_to_vram(char vbank, void* vdest, void* src, unsigned int num );
// 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 );

View File

@ -0,0 +1,115 @@
// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
// Author: Sven Van de Velde
// --- VERA function encapsulation ---
// --- 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);
// 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);
// 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);
// Enable the layer to be displayed on the screen.
// - layer: 0 or 1.
void vera_show_layer(unsigned byte layer);
// Disable the layer to be displayed on the screen.
// - layer: 0 or 1.
void vera_hide_layer(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);
// 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);
// 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);
// 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);
// 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);
// Set the front color for text output. The old front 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_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);
// 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);
// 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);
// 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);
// 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);
// 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);

View File

@ -0,0 +1,373 @@
// CX16 conio.h implementation
#include <conio.h>
#include <cx16.h>
// The screen width
#define CONIO_WIDTH conio_screen_width
// The screen height
#define CONIO_HEIGHT conio_screen_height
// The text screen base address, which is a 16:0 bit value in VERA VRAM.
// That is 128KB addressable space, thus 17 bits in total.
// CONIO_SCREEN_TEXT contains bits 15:0 of the address.
// CONIO_SCREEN_BANK contains bit 16, the the 64K memory bank in VERA VRAM (the upper 17th bit).
// !!! note that these values are not const for the cx16!
// This conio implements the two layers of VERA, which can be layer 0 or layer 1.
// Configuring conio to output to a different layer, will change these fields to the address base
// configured using VERA_L0_MAPBASE = 0x9f2e or VERA_L1_MAPBASE = 0x9f35.
// Using the function setscreenlayer(layer) will re-calculate using CONIO_SCREEN_TEXT and CONIO_SCREEN_BASE
// based on the values of VERA_L0_MAPBASE or VERA_L1_MAPBASE, mapping the base address of the selected layer.
// The function setscreenlayermapbase(layer,mapbase) allows to configure bit 16:9 of the
// mapbase address of the time map in VRAM of the selected layer VERA_L0_MAPBASE or VERA_L1_MAPBASE.
char* CONIO_SCREEN_TEXT = DEFAULT_SCREEN;
char CONIO_SCREEN_BANK = 0; // Default screen of the CX16 emulator uses memory bank 0 for text.
// The default text color
const char CONIO_TEXTCOLOR_DEFAULT = WHITE;
// The default back color
const char CONIO_BACKCOLOR_DEFAULT = BLUE;
// Initializer for conio.h on X16 Commander.
#pragma constructor_for(conio_x16_init, cputc, clrscr, cscroll)
// Set initial cursor position
void conio_x16_init() {
// Position cursor at current line
char * const BASIC_CURSOR_LINE = 0xD6;
char line = *BASIC_CURSOR_LINE;
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);
if(line>=CONIO_HEIGHT) line=CONIO_HEIGHT-1;
gotoxy(0, line);
}
// Return true if there's a key waiting, return false if not
unsigned char kbhit(void) {
char ch = 0;
char* const chptr = &ch;
char* const IN_DEV = $028A; // Current input device number
char* const GETIN = $FFE4; // CBM GETIN API
kickasm(uses chptr, uses IN_DEV, uses GETIN) {{
jsr _kbhit
bne L3
jmp continue1
.var via1 = $9f60 //VIA#1
.var d1pra = via1+1
_kbhit:
ldy d1pra // The count of keys pressed is stored in RAM bank 0.
stz d1pra // Set d1pra to zero to access RAM bank 0.
lda $A00A // Get number of characters from this address in the ROM of the CX16 (ROM 38).
sty d1pra // Set d1pra to previous value.
rts
L3:
ldy IN_DEV // Save current input device
stz IN_DEV // Keyboard
phy
jsr GETIN // Read char, and return in .A
ply
sta chptr // Store the character read in ch
sty IN_DEV // Restore input device
ldx #>$0000
rts
continue1:
nop
}}
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 <string.h>
// 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_skip);
char color = ( vera_get_layer_backcolor(conio_screen_layer) << 4 ) | vera_get_layer_textcolor(conio_screen_layer);
for( char l=0;l<conio_height; l++ ) {
char *ch = line_text;
// Select DATA0
*VERA_CTRL &= ~VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <ch;
*VERA_ADDRX_M = >ch;
*VERA_ADDRX_H = CONIO_SCREEN_BANK | VERA_INC_1;
for( char c=0;c<conio_width; c++ ) {
*VERA_DATA0 = ' ';
*VERA_DATA0 = color;
}
line_text += skip;
}
conio_cursor_x[conio_screen_layer] = 0;
conio_cursor_y[conio_screen_layer] = 0;
conio_line_text[conio_screen_layer] = 0;
}
// Set the cursor to the specified position
void gotoxy(unsigned byte x, unsigned byte y) {
if(y>CONIO_HEIGHT) y = 0;
if(x>=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;
conio_line_text[conio_screen_layer] = line_offset;
}
// Return the current screen size.
void screensize(unsigned byte* x, unsigned byte* y) {
// VERA returns in VERA_DC_HSCALE the value of 128 when 80 columns is used in text mode,
// and the value of 64 when 40 columns is used in text mode.
// Basically, 40 columns mode in the VERA is a double scan mode.
// Same for the VERA_DC_VSCALE mode, but then the subdivision is 60 or 30 rows.
// I still need to test the other modes, but this will suffice for now for the pure text modes.
char hscale = (*VERA_DC_HSCALE) >> 7;
*x = 40 << hscale;
char vscale = (*VERA_DC_VSCALE) >> 7;
*y = 30 << vscale;
//printf("%u, %u\n", *x, *y);
}
// Return the current screen size X width.
inline unsigned byte screensizex() {
return conio_screen_width;
}
// Return the current screen size Y height.
inline unsigned byte screensizey() {
return conio_screen_height;
}
// Return the X position of the cursor
inline unsigned byte wherex(void) {
return conio_cursor_x[conio_screen_layer];
}
// Return the Y position of the cursor
inline unsigned byte wherey(void) {
return conio_cursor_y[conio_screen_layer];
}
// 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* conio_addr = CONIO_SCREEN_TEXT + conio_line_text[conio_screen_layer];
conio_addr += conio_cursor_x[conio_screen_layer] << 1;
if(c=='\n') {
cputln();
} else {
// Select DATA0
*VERA_CTRL &= ~VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <conio_addr;
*VERA_ADDRX_M = >conio_addr;
*VERA_ADDRX_H = CONIO_SCREEN_BANK | VERA_INC_1;
*VERA_DATA0 = c;
*VERA_DATA0 = color;
conio_cursor_x[conio_screen_layer]++;
byte scroll_enable = conio_scroll_enable[conio_screen_layer];
if(scroll_enable) {
if(conio_cursor_x[conio_screen_layer] == CONIO_WIDTH)
cputln();
} else {
if((unsigned int)conio_cursor_x[conio_screen_layer] == conio_width)
cputln();
}
}
}
// Print a newline
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<<conio_skip);
conio_line_text[conio_screen_layer] = temp;
conio_cursor_x[conio_screen_layer] = 0;
conio_cursor_y[conio_screen_layer]++;
cscroll();
}
void clearline() {
// Select DATA0
*VERA_CTRL &= ~VERA_ADDRSEL;
// Set address
byte* addr = CONIO_SCREEN_TEXT + conio_line_text[conio_screen_layer];
*VERA_ADDRX_L = <addr;
*VERA_ADDRX_M = >addr;
*VERA_ADDRX_H = VERA_INC_1;
char color = vera_get_layer_color( conio_screen_layer);
for( unsigned int c=0;c<CONIO_WIDTH; c++ ) {
// Set data
*VERA_DATA0 = ' ';
*VERA_DATA0 = color;
}
conio_cursor_x[conio_screen_layer] = 0;
}
// Insert a new line, and scroll the lower part of the screen down.
void insertdown() {
unsigned byte cy = CONIO_HEIGHT - conio_cursor_y[conio_screen_layer];
cy -= 1;
unsigned byte width = CONIO_WIDTH * 2;
for(unsigned byte i=cy; i>0; i--) {
unsigned int line = (conio_cursor_y[conio_screen_layer] + i - 1) << conio_skip;
unsigned char* start = CONIO_SCREEN_TEXT + line;
memcpy_in_vram(0, start+((word)1<<conio_skip), VERA_INC_1, 0, start, VERA_INC_1, width);
}
clearline();
}
// Insert a new line, and scroll the upper part of the screen up.
void insertup() {
unsigned byte cy = conio_cursor_y[conio_screen_layer];
unsigned byte width = CONIO_WIDTH * 2;
for(unsigned byte i=1; i<=cy; i++) {
unsigned int line = (i-1) << conio_skip;
unsigned char* start = CONIO_SCREEN_TEXT + line;
memcpy_in_vram(0, start, VERA_INC_1, 0, start+((word)1<<conio_skip), VERA_INC_1, width);
}
clearline();
}
// Scroll the entire screen if the cursor is beyond the last line
void cscroll() {
if(conio_cursor_y[conio_screen_layer]>=CONIO_HEIGHT) {
if(conio_scroll_enable[conio_screen_layer]) {
insertup();
gotoxy( 0, CONIO_HEIGHT-1);
} else {
if(conio_cursor_y[conio_screen_layer]>=conio_height) {
//gotoxy(0,0);
}
}
}
}
// Output a NUL-terminated string at the current cursor position
void cputs(const char* s) {
char c;
while(c=*s++)
cputc(c);
}
// Move cursor and output one character
// Same as "gotoxy (x, y); cputc (c);"
void cputcxy(unsigned byte x, unsigned byte y, char c) {
gotoxy(x, y);
cputc(c);
}
// Move cursor and output a NUL-terminated string
// Same as "gotoxy (x, y); puts (s);"
void cputsxy(unsigned byte x, unsigned byte y, const char* s) {
gotoxy(x, y);
cputs(s);
}
// If onoff is 1, a cursor is displayed when waiting for keyboard input.
// If onoff is 0, the cursor is hidden when waiting for keyboard input.
// The function returns the old cursor setting.
unsigned byte cursor(unsigned byte onoff) {
char old = conio_display_cursor;
conio_display_cursor = onoff;
return old;
}
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
// The function returns the old scroll setting.
unsigned byte scroll(unsigned byte onoff) {
char old = conio_scroll_enable[conio_screen_layer];
conio_scroll_enable[conio_screen_layer] = onoff;
return old;
}
// --- Defined in cx16.c and cx16-vera.h ---
// --- layer management in VERA ---
// Set the layer with which the conio will interact.
// - layer: value of 0 or 1.
void screenlayer(unsigned byte layer) {
layer &= $1;
conio_screen_layer = layer;
unsigned byte addr = vera_get_layer_mapbase(layer);
unsigned int addr_i = addr << 1;
CONIO_SCREEN_BANK = >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);
}
// Set the front color for text output. The old front text color setting is returned.
// - 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.
inline char textcolor(char color) {
return vera_set_layer_textcolor(conio_screen_layer, color);
}
// Set the back color for text output. The old back text color setting is returned.
// - 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.
inline char bgcolor(char color) {
return vera_set_layer_backcolor(conio_screen_layer, color);
}
// Set the color for the border. The old color setting is returned.
char bordercolor(unsigned char color) {
// The border color register address
char old = *VERA_DC_BORDER;
*VERA_DC_BORDER = color;
return old;
}

View File

@ -17,6 +17,8 @@
#include "conio-nes.c"
#elif defined(__ATARIXL__)
#include "conio-atarixl.c"
#elif defined(__CX16__)
#include "conio-cx16.c"
#else
#error "Target platform does not support conio.h"
#endif

View File

@ -54,3 +54,35 @@ void memcpy_to_vram(char vbank, void* vdest, void* src, unsigned int num ) {
for(char *s = src; s!=end; s++)
*VERA_DATA0 = *s;
}
// 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 ) {
// Select DATA0
*VERA_CTRL &= ~VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <src;
*VERA_ADDRX_M = >src;
*VERA_ADDRX_H = src_increment | src_bank;
// Select DATA1
*VERA_CTRL |= VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <dest;
*VERA_ADDRX_M = >dest;
*VERA_ADDRX_H = dest_increment | dest_bank;
// Transfer the data
for(unsigned int i=0; i<num; i++) {
*VERA_DATA1 = *VERA_DATA0;
}
}

282
src/main/kc/lib/veralib.c Normal file
View File

@ -0,0 +1,282 @@
// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
// Author: Sven Van de Velde
#include <cx16.h>
#include <veralib.h>
// --- VERA function encapsulation ---
// --- VERA layer management ---
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 ---
void vera_vram_address0(dword bankaddr, byte incr) {
word* word_l = &(<bankaddr);
word* word_h = &(>bankaddr);
// Select DATA0
*VERA_CTRL &= ~VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <(*word_l);
*VERA_ADDRX_M = >(*word_l);
*VERA_ADDRX_H = <(*word_h) | incr;
}
void vera_vram_address1(dword bankaddr, byte incr) {
word* word_l = &(<bankaddr);
word* word_h = &(>bankaddr);
// Select DATA1
*VERA_CTRL |= VERA_ADDRSEL;
// Set address
*VERA_ADDRX_L = <(*word_l);
*VERA_ADDRX_M = >(*word_l);
*VERA_ADDRX_H = <(*word_h) | incr;
}
// --- 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) {
layer &= $1;
char* addr = vera_layer_config[layer];
*addr = 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* 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) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_WIDTH_MASK;
*addr |= VERA_CONFIG_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_CONFIG_WIDTH_MASK;
*addr |= VERA_CONFIG_WIDTH_64;
}
inline void vera_set_layer_map_width_128(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_WIDTH_MASK;
*addr |= VERA_CONFIG_WIDTH_128;
}
inline void vera_set_layer_map_width_256(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_WIDTH_MASK;
*addr |= VERA_CONFIG_WIDTH_256;
}
inline void vera_set_layer_map_height_32(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_HEIGHT_MASK;
*addr |= VERA_CONFIG_HEIGHT_32;
}
inline void vera_set_layer_map_height_64(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_HEIGHT_MASK;
*addr |= VERA_CONFIG_HEIGHT_64;
}
inline void vera_set_layer_map_height_128(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_HEIGHT_MASK;
*addr |= VERA_CONFIG_HEIGHT_128;
}
inline void vera_set_layer_map_height_256(unsigned byte layer) {
byte* addr = vera_layer_config[layer];
*addr &= ~VERA_CONFIG_HEIGHT_MASK;
*addr |= VERA_CONFIG_HEIGHT_256;
}
unsigned int const VERA_CONFIG_WIDTH[4] = { 32, 64, 128, 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_CONFIG_WIDTH_MASK;
return VERA_CONFIG_WIDTH[ (*config & mask) >> 4];
}
unsigned int const VERA_CONFIG_HEIGHT[4] = { 32, 64, 128, 256 };
word vera_get_layer_map_height(unsigned byte layer) {
byte* config = vera_layer_config[layer];
byte mask = VERA_CONFIG_HEIGHT_MASK;
return VERA_CONFIG_HEIGHT[ (*config & mask) >> 6];
}
// Enable the layer to be displayed on the screen.
// - layer: 0 or 1.
inline void vera_show_layer(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) {
*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;
return *VERA_DC_VIDEO & vera_layer_enable[layer];
}
// Set the base of the map 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) {
layer &= $1;
unsigned byte* addr = vera_layer_mapbase[layer];
*addr = mapbase;
}
// 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* mapbase = vera_layer_mapbase[layer];
return *mapbase;
}
// 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) {
layer &= $1;
unsigned byte* addr = vera_layer_tilebase[layer];
*addr = 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) {
layer &= $1;
unsigned byte* tilebase = vera_layer_tilebase[layer];
return *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;
byte tilebase = *vera_layer_tilebase[layer];
dword address = tilebase;
address &= $FC;
address <<= 8;
address <<= 1;
return address;
}
// --- VERA color management ---
// Set the front color for text output. The old front 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_textcolor(unsigned byte layer, unsigned byte color) {
layer &= $1;
unsigned byte old = vera_layer_textcolor[layer];
vera_layer_textcolor[layer] = color;
return old;
}
// 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) {
layer &= $1;
return vera_layer_textcolor[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) {
layer &= $1;
unsigned byte old = vera_layer_backcolor[layer];
vera_layer_backcolor[layer] = color;
return old;
}
// 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) {
layer &= $1;
return vera_layer_backcolor[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) {
layer &= $1;
return ((vera_layer_backcolor[layer] << 4) | vera_layer_textcolor[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) {
*vera_layer_hscroll_l[layer] = <scroll;
*vera_layer_hscroll_h[layer] = >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) {
*vera_layer_vscroll_l[layer] = <scroll;
*vera_layer_vscroll_h[layer] = >scroll;
}

View File

@ -5,7 +5,7 @@
"start_address": "0x080d",
"cpu": "WDC65C02",
"interrupt": "rom_min_cx16",
"emulator": "x16emu -debug -run -scale 2 -prg",
"emulator": "x16emu -debug -run -prg",
"defines": {
"__CX16__": 1
}

View File

@ -458,6 +458,17 @@ public class TestPrograms {
compileAndCompare("examples/nes/nes-demo.c");
}
@Test
public void testCx16VeraLayers() throws IOException, URISyntaxException {
compileAndCompare("examples/cx16/veralayers.c");
}
@Test
public void testCx16TileMap() throws IOException, URISyntaxException {
compileAndCompare("examples/cx16/tilemap.c");
}
@Test
public void testCx16Sprites() throws IOException, URISyntaxException {
compileAndCompare("examples/cx16/sprites.c");

View File

@ -92,7 +92,7 @@ volatile unsigned int sin_idx_x = 119;
volatile unsigned int sin_idx_y = 79;
// VSYNC Interrupt Routine
__interrupt(rom_sys_cx16) void irq_vsync() {
__interrupt void irq_vsync() {
// Move the sprite around
if(++sin_idx_x==SINX_LEN) sin_idx_x = 0;
if(--sin_idx_y==0xffff) sin_idx_y = SINY_LEN-1;
@ -112,9 +112,4 @@ __interrupt(rom_sys_cx16) void irq_vsync() {
// Reset the VSYNC interrupt
*VERA_ISR = VERA_VSYNC;
// Exit CX16 KERNAL IRQ
asm {
// soft exit (keep kernal running)
jmp $e034
}
}
}

View File

@ -0,0 +1,149 @@
// Example program for the Commander X16.
// Demonstrates the usage of the VERA layer 0 and 1.
// Author: Sven Van de Velde
// The default layer of the CX16 is layer 1.
// The CX16 starts in tile map mode, 1BPP in 16 color mode, and uses 8x8 tiles.
// The map base is address 0x00000 in VERA VRAM, the tile map is address 0x0F800.
#pragma target(cx16)
#include <conio.h>
#include <veralib.h>
#include <stdio.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_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(0);
screenlayer(0);
scroll(0); // Scrolling on conio is deactivated, so conio will output beyond the borders of the visible screen.
textcolor(WHITE);
bgcolor(GREEN);
draw_characters(tilebase);
// Enable VSYNC IRQ (also set line bit 8 to 0)
SEI();
*KERNEL_IRQ = &irq_vsync;
*VERA_IEN = VERA_VSYNC;
CLI();
vera_show_layer(0);
while(!kbhit());
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) {
tilerow = tilebase;
for(byte r:0..7) {
tilecolumn = tilerow;
for(byte x:0..15) {
vera_vram_address0(tilecolumn,VERA_INC_0);
byte data = *VERA_DATA0;
byte bit = data;
for(byte b:8..1) {
bit = (data >> (b-1)) & $1;
printf("%c", (char)((bit)?'*':'.'));
}
tilecolumn += 8;
printf("");
}
//printf("\n");
tilerow += 1;
}
tilebase += 8*16;
}
}
// 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 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;
}

View File

@ -0,0 +1,134 @@
// Example program for the Commander X16.
// Demonstrates the usage of the VERA layer 0 and 1.
// Author: Sven Van de Velde
// The default layer of the CX16 is layer 1.
// The CX16 starts in tile map mode, 1BPP in 16 color mode, and uses 8x8 tiles.
// The map base is address 0x00000 in VERA VRAM, the tile map is address 0x0F800.
#pragma target(cx16)
#include <conio.h>
#include <stdio.h>
#include <veralib.h>
void main() {
textcolor(WHITE);
bgcolor(BLACK);
clrscr();
// Wait for a keypress and after clear the line!
textcolor(YELLOW);
printf("press a key");
while(!kbhit());
clearline();
screenlayer(1);
gotoxy(0,16);
textcolor(GREEN);
printf("this program demonstrates the layer functionality in text mode.\n");
// Here we use the screensizex and screensizey functions to show the width and height of the text screen.
printf("\nvera card width = %u; height = %u\n", screensizex(), screensizey());
// This is the content of the main controller registers of the VERA of layer 1.
// Layer 1 is the default layer that is activated in the CX16 at startup.
// 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);
printf("\nvera layer 1 config = %x\n", config);
unsigned byte layershown = vera_is_layer_shown(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);
printf("vera layer 1 mapbase = %hhx, tilebase = %hhx\n", mapbase, tilebase);
// Wait for a keypress and after clear the line!
textcolor(YELLOW);
printf("press a key");
while(!kbhit());
clearline();
// Now we continue with demonstrating the layering!
// We set the mapbase of layer 0 to an address in VRAM.
// We copy the tilebase address from layer 1, so that we reference to the same tilebase.
// We print a text on layer 0, which of course, won't yet be displayed,
// because we haven't activated layer 0 on the VERA.
// But the text will be printed and awaiting to be displayer later, once we activate layer 0!
// 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));
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);
printf("vera layer 0 shown = %x\n", layershown);
mapbase = vera_get_layer_mapbase(0);
tilebase = vera_get_layer_tilebase(0);
printf("vera layer 0 mapbase = %x, tilebase = %x\n", mapbase, tilebase);
// Now we print the layer 0 text on the layer 0!
screenlayer(0); // We set conio to output to layer 0 instead of layer 1!
textcolor(BLUE);
bgcolor(BLACK);
clrscr(); // We clear the screen of layer 0!
bgcolor(WHITE);
gotoxy(19,4);
printf(" ");
gotoxy(19,5);
printf(" this is printed on layer 0 !!! ");
gotoxy(19,6);
printf(" ");
screenlayer(1); // Now we ask conio again to output to layer 1!
// Wait for a keypress and after clear the line!
textcolor(YELLOW);
bgcolor(BLACK);
printf("press a key to show layer 0 and show the text!");
while(!kbhit());
clearline();
// Now we activate layer 0.
vera_show_layer(0);
textcolor(WHITE);
bgcolor(BLACK);
printf("vera layer 0 shown = %x. ", vera_is_layer_shown(0));
// Wait for a keypress and after clear the line!
textcolor(YELLOW);
bgcolor(BLACK);
printf("press a key to hide layer 0 and hide the text again");
while(!kbhit());
clearline();
vera_hide_layer(0);
textcolor(WHITE);
bgcolor(BLACK);
printf("vera layer 0 shown = %x. ", vera_is_layer_shown(0));
// Wait for a keypress and after clear the line!
textcolor(YELLOW);
bgcolor(BLACK);
printf("press a key to finish");
while(!kbhit());
clearline();
clrscr();
textcolor(RED);
bgcolor(WHITE);
gotoxy(19,10);
printf(" ");
gotoxy(19,11);
printf(" analyze the code and learn! ");
gotoxy(19,12);
printf(" ");
}