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:
commit
ee9f738f87
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 );
|
||||
|
||||
|
115
src/main/kc/include/veralib.h
Normal file
115
src/main/kc/include/veralib.h
Normal 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);
|
373
src/main/kc/lib/conio-cx16.c
Normal file
373
src/main/kc/lib/conio-cx16.c
Normal 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
282
src/main/kc/lib/veralib.c
Normal 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;
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
149
src/test/kc/examples/cx16/tilemap.c
Normal file
149
src/test/kc/examples/cx16/tilemap.c
Normal 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;
|
||||
}
|
134
src/test/kc/examples/cx16/veralayers.c
Normal file
134
src/test/kc/examples/cx16/veralayers.c
Normal 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(" ");
|
||||
}
|
Loading…
Reference in New Issue
Block a user