mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-01-02 23:30:21 +00:00
added libcv/libcvu for coleco
This commit is contained in:
parent
4974e395e5
commit
85bf12a970
100
presets/coleco/cursorsmooth.c
Normal file
100
presets/coleco/cursorsmooth.c
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t sprite[0x1][0x20] = {
|
||||
{0xa0, 0x40, 0xa0, 0x10, 0xa, 0x4, 0xa, 0, 0, 0xa, 0x4, 0xa, 0x10, 0xa0, 0x40, 0xa0, 0x5, 0x2, 0x5, 0x8, 0x50, 0x20, 0x50, 0, 0, 0x50, 0x20, 0x50, 0x8, 0x5, 0x2, 0x5}
|
||||
};
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
/* VRAM map
|
||||
0x0000 - 0x17ff character pattern table
|
||||
0x1800 - 0x1aff image table
|
||||
0x2000 - 0x37ff color table
|
||||
0x3800 - 0x3bff sprite pattern table
|
||||
0x3c00 - 0x3fff sprite attribute table
|
||||
*/
|
||||
|
||||
const cv_vmemp IMAGE = 0x1800;
|
||||
const cv_vmemp SPRITES = 0x3c00;
|
||||
const cv_vmemp SPRITE_PATTERNS = 0x3800;
|
||||
|
||||
volatile bool step; // Has to be volatile since it's modified in the NMI handler.
|
||||
|
||||
void move_cursor(struct cvu_sprite *s)
|
||||
{
|
||||
int x, y;
|
||||
struct cv_controller_state cs;
|
||||
|
||||
cv_get_controller_state(&cs, 0); // Read the controller.
|
||||
|
||||
x = cvu_get_sprite_x(s);
|
||||
y = cvu_get_sprite_y(s);
|
||||
|
||||
if(cs.joystick & CV_RIGHT) // Move cursor to the right by one pixel.
|
||||
x++;
|
||||
else if(cs.joystick & CV_LEFT) // Move the cursor to the left by one pixel.
|
||||
x--;
|
||||
if(cs.joystick & CV_DOWN) // Move the cursor down by one pixel.
|
||||
y++;
|
||||
else if(cs.joystick & CV_UP) // Move the cursor up by one pixel.
|
||||
y--;
|
||||
|
||||
// Move cursor by how much the wheels on the super action controllers or the ball in the roller controller indicate.
|
||||
x += cvu_get_spinner(0);
|
||||
y += cvu_get_spinner(1);
|
||||
|
||||
// Limit to area.
|
||||
if(x > 239)
|
||||
x = 239;
|
||||
else if(x < 0)
|
||||
x = 0;
|
||||
if(y > 152)
|
||||
y = 152;
|
||||
else if(y < 0)
|
||||
y = 0;
|
||||
|
||||
cvu_set_sprite_xy(s, x, y);
|
||||
|
||||
cvu_set_sprite(SPRITES, 0, s); // Update the cursor on the screen.
|
||||
}
|
||||
|
||||
void nmi(void)
|
||||
{
|
||||
step = true;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct cvu_sprite s; // The sprite used for the cursor.
|
||||
|
||||
cv_set_screen_active(false); // Switch screen off.
|
||||
|
||||
cv_set_color_table(0x3fff);
|
||||
cv_set_character_pattern_t(0x1fff);
|
||||
cv_set_image_table(IMAGE);
|
||||
cv_set_sprite_pattern_table(SPRITE_PATTERNS);
|
||||
cv_set_sprite_attribute_table(SPRITES);
|
||||
cv_set_screen_mode(CV_SCREENMODE_BITMAP); // Doesn't really matter much here. We only need a screen mode that supports sprites.
|
||||
cvu_vmemset(0x2000, (CV_COLOR_BLACK << 4) | CV_COLOR_BLACK, 6144); // Set both colors for all characters to black to get a black background.
|
||||
|
||||
cv_set_sprite_magnification(false);
|
||||
cv_set_sprite_big(true); // 16x16 pixel sprites.
|
||||
|
||||
cvu_set_sprite_x(&s, 60); // Set initial cursor position.
|
||||
cvu_set_sprite_y(&s, 60); // Set initial cursor position.
|
||||
cvu_set_sprite_color(&s, CV_COLOR_WHITE);
|
||||
s.name = 0; // Use sprite pattern number 0.
|
||||
cvu_memtovmemcpy(SPRITE_PATTERNS, sprite, 0x20); // Copy sprite pattern number 0 to graphics memory.
|
||||
|
||||
cv_set_screen_active(true); // Switch screen on.
|
||||
|
||||
cv_set_vint_handler(nmi);
|
||||
for(;;)
|
||||
{
|
||||
step = false;
|
||||
while(!step); // Wait until the NMI handler sets step to true.
|
||||
move_cursor(&s);
|
||||
}
|
||||
}
|
85
presets/coleco/hello.c
Normal file
85
presets/coleco/hello.c
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
#define IMAGE ((const cv_vmemp)0x1c00)
|
||||
|
||||
#define COLS 40
|
||||
#define ROWS 24
|
||||
|
||||
uintptr_t __at(0x6a) font_bitmap_a;
|
||||
uintptr_t __at(0x6c) font_bitmap_0;
|
||||
|
||||
void setup_40_column_font() {
|
||||
cv_set_image_table(IMAGE);
|
||||
cvu_memtovmemcpy(0x1800, (void *)(font_bitmap_0 - 0x30*8), 2048);
|
||||
cv_set_character_pattern_t(0x1800);
|
||||
cv_set_screen_mode(CV_SCREENMODE_TEXT);
|
||||
}
|
||||
|
||||
char cursor_x;
|
||||
char cursor_y;
|
||||
|
||||
void clrscr() {
|
||||
cvu_vmemset(IMAGE, ' ', COLS*ROWS);
|
||||
}
|
||||
|
||||
void setup_stdio() {
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
clrscr();
|
||||
}
|
||||
|
||||
void scrollup() {
|
||||
char buf[COLS];
|
||||
char y;
|
||||
for (y=0; y<ROWS-1; y++) {
|
||||
cvu_vmemtomemcpy(buf, IMAGE + COLS*y + COLS, COLS);
|
||||
cvu_memtovmemcpy(IMAGE + COLS*y, buf, COLS);
|
||||
}
|
||||
cvu_vmemset(IMAGE + COLS*(ROWS-1), ' ', COLS);
|
||||
}
|
||||
|
||||
void newline() {
|
||||
if (cursor_y >= ROWS-1) {
|
||||
scrollup();
|
||||
} else {
|
||||
cursor_y++;
|
||||
}
|
||||
}
|
||||
|
||||
int putchar(int ch) {
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
newline(); // TODO: scrolling
|
||||
case '\r':
|
||||
cursor_x = 0;
|
||||
return 0;
|
||||
}
|
||||
cvu_voutb(ch, IMAGE + COLS*cursor_y + cursor_x);
|
||||
cursor_x++;
|
||||
if (cursor_x >= COLS) {
|
||||
newline();
|
||||
cursor_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
unsigned char byteval = 123;
|
||||
signed char charval = 123;
|
||||
short shortval = 12345;
|
||||
|
||||
setup_40_column_font();
|
||||
setup_stdio();
|
||||
cv_set_colors(CV_COLOR_LIGHT_GREEN, CV_COLOR_BLACK);
|
||||
cv_set_screen_active(true);
|
||||
printf("HELLO WORLD!\n");
|
||||
while (1) {
|
||||
printf("char %d byte %u sh %d\n",
|
||||
charval++, byteval++, shortval++);
|
||||
}
|
||||
}
|
323
presets/coleco/huffman.c
Normal file
323
presets/coleco/huffman.c
Normal file
File diff suppressed because one or more lines are too long
289
presets/coleco/siegegame.c
Normal file
289
presets/coleco/siegegame.c
Normal file
@ -0,0 +1,289 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
#define COLOR ((const cv_vmemp)0x2000)
|
||||
#define IMAGE ((const cv_vmemp)0x1c00)
|
||||
|
||||
#define COLS 32
|
||||
#define ROWS 24
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef signed char sbyte;
|
||||
typedef unsigned short word;
|
||||
|
||||
uintptr_t __at(0x6a) font_bitmap_a;
|
||||
uintptr_t __at(0x6c) font_bitmap_0;
|
||||
|
||||
volatile bool vint;
|
||||
volatile uint_fast8_t vint_counter;
|
||||
|
||||
void vint_handler(void)
|
||||
{
|
||||
vint = true;
|
||||
vint_counter++;
|
||||
}
|
||||
|
||||
void setup_32_column_font() {
|
||||
cv_set_image_table(IMAGE);
|
||||
cvu_memtovmemcpy(0x1800, (void *)(font_bitmap_0 - '0'*8), 256*8);
|
||||
cv_set_character_pattern_t(0x1800);
|
||||
cv_set_screen_mode(CV_SCREENMODE_STANDARD);
|
||||
cv_set_color_table(COLOR);
|
||||
cvu_vmemset(COLOR, 0x36, 8); // set color for chars 0-63
|
||||
cvu_vmemset(COLOR+8, 0x06, 32-8); // set chars 63-255
|
||||
}
|
||||
|
||||
char cursor_x;
|
||||
char cursor_y;
|
||||
|
||||
void clrscr() {
|
||||
cvu_vmemset(IMAGE, ' ', COLS*ROWS);
|
||||
}
|
||||
|
||||
#define LOCHAR 0x0
|
||||
#define HICHAR 0xff
|
||||
|
||||
#define CHAR(ch) (ch-LOCHAR)
|
||||
|
||||
byte getchar(byte x, byte y) {
|
||||
return cvu_vinb(IMAGE + y*COLS + x);
|
||||
}
|
||||
|
||||
void putchar(byte x, byte y, byte attr) {
|
||||
cvu_voutb(attr, IMAGE + y*COLS + x);
|
||||
}
|
||||
|
||||
void putstring(byte x, byte y, const char* string) {
|
||||
while (*string) {
|
||||
putchar(x++, y, CHAR(*string++));
|
||||
}
|
||||
}
|
||||
|
||||
void wait_vsync() {
|
||||
vint = false;
|
||||
while (!vint) ;
|
||||
}
|
||||
|
||||
void delay(byte i) {
|
||||
while (i--) {
|
||||
wait_vsync();
|
||||
}
|
||||
}
|
||||
|
||||
////////// GAME DATA
|
||||
|
||||
typedef struct {
|
||||
byte x;
|
||||
byte y;
|
||||
byte dir;
|
||||
word score;
|
||||
char head_attr;
|
||||
char tail_attr;
|
||||
char collided:1;
|
||||
char human:1;
|
||||
} Player;
|
||||
|
||||
Player players[2];
|
||||
|
||||
byte credits = 0;
|
||||
byte frames_per_move;
|
||||
|
||||
#define START_SPEED 12
|
||||
#define MAX_SPEED 5
|
||||
#define MAX_SCORE 7
|
||||
|
||||
///////////
|
||||
|
||||
const char BOX_CHARS[8] = { '+', '+', '+', '+', '-', '-', '!', '!' };
|
||||
|
||||
void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
|
||||
byte x1 = x;
|
||||
putchar(x, y, chars[2]);
|
||||
putchar(x2, y, chars[3]);
|
||||
putchar(x, y2, chars[0]);
|
||||
putchar(x2, y2, chars[1]);
|
||||
while (++x < x2) {
|
||||
putchar(x, y, chars[5]);
|
||||
putchar(x, y2, chars[4]);
|
||||
}
|
||||
while (++y < y2) {
|
||||
putchar(x1, y, chars[6]);
|
||||
putchar(x2, y, chars[7]);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_playfield() {
|
||||
draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS);
|
||||
putstring(0,0,"Plyr1:");
|
||||
putstring(20,0,"Plyr2:");
|
||||
putchar(7,0,CHAR(players[0].score+'0'));
|
||||
putchar(27,0,CHAR(players[1].score+'0'));
|
||||
}
|
||||
|
||||
typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t;
|
||||
const char DIR_X[4] = { 1, 0, -1, 0 };
|
||||
const char DIR_Y[4] = { 0, 1, 0, -1 };
|
||||
|
||||
void init_game() {
|
||||
memset(players, 0, sizeof(players));
|
||||
players[0].head_attr = CHAR('1');
|
||||
players[1].head_attr = CHAR('2');
|
||||
players[0].tail_attr = 254;
|
||||
players[1].tail_attr = 254;
|
||||
frames_per_move = START_SPEED;
|
||||
}
|
||||
|
||||
void reset_players() {
|
||||
players[0].x = players[0].y = 5;
|
||||
players[0].dir = D_RIGHT;
|
||||
players[1].x = 25;
|
||||
players[1].y = 19;
|
||||
players[1].dir = D_LEFT;
|
||||
players[0].collided = players[1].collided = 0;
|
||||
}
|
||||
|
||||
void draw_player(Player* p) {
|
||||
putchar(p->x, p->y, p->head_attr);
|
||||
}
|
||||
|
||||
void move_player(Player* p) {
|
||||
putchar(p->x, p->y, p->tail_attr);
|
||||
p->x += DIR_X[p->dir];
|
||||
p->y += DIR_Y[p->dir];
|
||||
if (getchar(p->x, p->y) != CHAR(' '))
|
||||
p->collided = 1;
|
||||
draw_player(p);
|
||||
}
|
||||
|
||||
void human_control(Player* p) {
|
||||
byte dir = 0xff;
|
||||
struct cv_controller_state cs;
|
||||
cv_get_controller_state(&cs, 0); // Read the controller.
|
||||
if (!p->human) return;
|
||||
if (cs.joystick & CV_LEFT) dir = D_LEFT;
|
||||
if (cs.joystick & CV_RIGHT) dir = D_RIGHT;
|
||||
if (cs.joystick & CV_UP) dir = D_UP;
|
||||
if (cs.joystick & CV_DOWN) dir = D_DOWN;
|
||||
// don't let the player reverse
|
||||
if (dir < 0x80 && dir != (p->dir ^ 2)) {
|
||||
p->dir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
byte ai_try_dir(Player* p, dir_t dir, byte shift) {
|
||||
byte x,y;
|
||||
dir &= 3;
|
||||
x = p->x + (DIR_X[dir] << shift);
|
||||
y = p->y + (DIR_Y[dir] << shift);
|
||||
if (x < 29 && y < 27 && getchar(x, y) == CHAR(' ')) {
|
||||
p->dir = dir;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ai_control(Player* p) {
|
||||
dir_t dir;
|
||||
if (p->human) return;
|
||||
dir = p->dir;
|
||||
if (!ai_try_dir(p, dir, 0)) {
|
||||
ai_try_dir(p, dir+1, 0);
|
||||
ai_try_dir(p, dir-1, 0);
|
||||
} else {
|
||||
ai_try_dir(p, dir-1, 0) && ai_try_dir(p, dir-1, 1+(rand() & 3));
|
||||
ai_try_dir(p, dir+1, 0) && ai_try_dir(p, dir+1, 1+(rand() & 3));
|
||||
ai_try_dir(p, dir, rand() & 3);
|
||||
}
|
||||
}
|
||||
|
||||
byte gameover;
|
||||
|
||||
void flash_colliders() {
|
||||
byte i;
|
||||
// flash players that collided
|
||||
for (i=0; i<56; i++) {
|
||||
//cv_set_frequency(CV_SOUNDCHANNEL_0, 1000+i*8);
|
||||
//cv_set_attenuation(CV_SOUNDCHANNEL_0, i/2);
|
||||
if (players[0].collided) players[0].head_attr ^= 0x80;
|
||||
if (players[1].collided) players[1].head_attr ^= 0x80;
|
||||
delay(2);
|
||||
draw_player(&players[0]);
|
||||
draw_player(&players[1]);
|
||||
}
|
||||
//cv_set_attenuation(CV_SOUNDCHANNEL_0, 28);
|
||||
}
|
||||
|
||||
void make_move() {
|
||||
byte i;
|
||||
for (i=0; i<frames_per_move; i++) {
|
||||
human_control(&players[0]);
|
||||
delay(1);
|
||||
}
|
||||
ai_control(&players[0]);
|
||||
ai_control(&players[1]);
|
||||
// if players collide, 2nd player gets the point
|
||||
move_player(&players[1]);
|
||||
move_player(&players[0]);
|
||||
}
|
||||
|
||||
void play_game();
|
||||
|
||||
void declare_winner(byte winner) {
|
||||
byte i;
|
||||
clrscr();
|
||||
for (i=0; i<ROWS/2-3; i++) {
|
||||
draw_box(i,i,COLS-1-i,ROWS-1-i,BOX_CHARS);
|
||||
delay(1);
|
||||
}
|
||||
putstring(12,10,"WINNER:");
|
||||
putstring(12,13,"PLAYER ");
|
||||
putchar(12+7, 13, CHAR('1')+winner);
|
||||
delay(75);
|
||||
gameover = 1;
|
||||
}
|
||||
|
||||
void play_round() {
|
||||
reset_players();
|
||||
clrscr();
|
||||
draw_playfield();
|
||||
while (1) {
|
||||
make_move();
|
||||
if (players[0].collided || players[1].collided) break;
|
||||
}
|
||||
flash_colliders();
|
||||
// add scores to players that didn't collide
|
||||
if (players[0].collided) players[1].score++;
|
||||
if (players[1].collided) players[0].score++;
|
||||
// increase speed
|
||||
if (frames_per_move > MAX_SPEED) frames_per_move--;
|
||||
// game over?
|
||||
if (players[0].score != players[1].score) {
|
||||
if (players[0].score >= MAX_SCORE)
|
||||
declare_winner(0);
|
||||
else if (players[1].score >= MAX_SCORE)
|
||||
declare_winner(1);
|
||||
}
|
||||
}
|
||||
|
||||
void play_game() {
|
||||
gameover = 0;
|
||||
init_game();
|
||||
players[0].human = 1;
|
||||
while (!gameover) {
|
||||
play_round();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
setup_32_column_font();
|
||||
cv_set_screen_active(true);
|
||||
cv_set_vint_handler(&vint_handler);
|
||||
|
||||
draw_playfield();
|
||||
play_game();
|
||||
}
|
23
presets/coleco/simplemusic.c
Normal file
23
presets/coleco/simplemusic.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdint.h>
|
||||
|
||||
const uint16_t notes[] = { 12846, 12334, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11042, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 9806, 10574, 12430, 12846, 12334, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11054, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 10062, 10062, 10126, 11054, 12334, 12878, 14158, 13902, 14158, 14670, 14158, 13646, 12878, 13390, 13646, 3918, 12878, 14158, 13902, 12878, 12366, 12878, 12366, 12878, 11086, 10062, 9870, 12334, 11054, 11086, 10062, 10062, 9806, 10062, 10574, 11086, 10062, 11086, 12430, 11054, 12334, 12878, 14158, 14158, 12878, 13390, 13646, 10574, 10062, 10062, 10126, 0xffff };
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu_sound.h"
|
||||
|
||||
struct cvu_music music;
|
||||
|
||||
void play(void)
|
||||
{
|
||||
cvu_play_music(&music);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
cvu_init_music(&music);
|
||||
music.notes = notes;
|
||||
cv_set_vint_handler(&play);
|
||||
cv_set_colors(CV_COLOR_BLACK, CV_COLOR_BLACK);
|
||||
cv_set_screen_active(true);
|
||||
for(;;);
|
||||
}
|
81
presets/coleco/stars.c
Normal file
81
presets/coleco/stars.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
#define PATTERN ((const cv_vmemp)0x0000)
|
||||
#define COLOR ((const cv_vmemp)0x2000)
|
||||
#define IMAGE ((const cv_vmemp)0x1c00)
|
||||
|
||||
volatile bool vint;
|
||||
volatile uint_fast8_t vint_counter;
|
||||
uint_fast8_t oldcounter;
|
||||
|
||||
void vint_handler(void)
|
||||
{
|
||||
vint = true;
|
||||
vint_counter++;
|
||||
}
|
||||
|
||||
void update_stars(void)
|
||||
{
|
||||
uint_fast8_t j;
|
||||
uint_fast8_t tmp = vint_counter;
|
||||
tmp %= (16 * 8);
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
cvu_voutb(0x00, PATTERN + j * 256 * 8 + oldcounter);
|
||||
cvu_voutb(0x10, PATTERN + j * 256 * 8 + tmp);
|
||||
}
|
||||
|
||||
oldcounter = tmp;
|
||||
}
|
||||
|
||||
void init_stars(void)
|
||||
{
|
||||
uint_fast8_t i, j, r;
|
||||
|
||||
for(j = 0; j < 32; j += rand() % 2)
|
||||
{
|
||||
r = rand() % 16;
|
||||
for(i = 0; i < 24; i++)
|
||||
{
|
||||
cvu_voutb(r++, IMAGE + j + i * 32);
|
||||
r %= 16;
|
||||
}
|
||||
}
|
||||
|
||||
for(j = 0; j < 3; j++)
|
||||
cvu_vmemset(COLOR + j * 256 * 8, (CV_COLOR_WHITE << 4) | CV_COLOR_BLACK, 16 * 8);
|
||||
|
||||
cvu_voutb(0x10, PATTERN);
|
||||
oldcounter = 0;
|
||||
vint_counter = 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
cv_set_screen_active(false);
|
||||
cv_set_image_table(IMAGE);
|
||||
cv_set_color_table(0x3fff);
|
||||
cv_set_character_pattern_t(0x1fff);
|
||||
cv_set_screen_mode(CV_SCREENMODE_BITMAP);
|
||||
cv_set_vint_handler(&vint_handler);
|
||||
|
||||
cvu_vmemset(PATTERN, 0, 8 * 256 * 3);
|
||||
cvu_vmemset(COLOR, 0, 8 * 256 * 3);
|
||||
cvu_vmemset(IMAGE, 0xff, 32 * 24);
|
||||
|
||||
init_stars();
|
||||
|
||||
cv_set_screen_active(true);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
while(!vint);
|
||||
update_stars();
|
||||
vint = false;
|
||||
}
|
||||
}
|
29
presets/coleco/text.c
Normal file
29
presets/coleco/text.c
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
#define PATTERN ((const cv_vmemp)0x0000)
|
||||
#define COLOR ((const cv_vmemp)0x2000)
|
||||
#define IMAGE ((const cv_vmemp)0x1c00)
|
||||
|
||||
uintptr_t __at(0x6a) font_bitmap_a;
|
||||
uintptr_t __at(0x6c) font_bitmap_0;
|
||||
|
||||
void setup_40_column_font() {
|
||||
cv_set_image_table(IMAGE);
|
||||
cvu_memtovmemcpy(0x1800, (void *)(font_bitmap_0 - 0x30*8), 2048);
|
||||
cv_set_character_pattern_t(0x1800);
|
||||
cv_set_screen_mode(CV_SCREENMODE_TEXT);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
setup_40_column_font();
|
||||
cv_set_colors(CV_COLOR_LIGHT_GREEN, CV_COLOR_BLACK);
|
||||
cvu_vmemset(IMAGE, '.', 960);
|
||||
cvu_memtovmemcpy(IMAGE + 1, "Hello Professor Falken", 22);
|
||||
cv_set_screen_active(true);
|
||||
while (1);
|
||||
}
|
88
presets/coleco/text32.c
Normal file
88
presets/coleco/text32.c
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "cvu.h"
|
||||
|
||||
#define COLOR ((const cv_vmemp)0x2000)
|
||||
#define IMAGE ((const cv_vmemp)0x1c00)
|
||||
|
||||
#define COLS 32
|
||||
#define ROWS 24
|
||||
|
||||
uintptr_t __at(0x6a) font_bitmap_a;
|
||||
uintptr_t __at(0x6c) font_bitmap_0;
|
||||
|
||||
void setup_32_column_font() {
|
||||
cv_set_image_table(IMAGE);
|
||||
cvu_memtovmemcpy(0x1800, (void *)(font_bitmap_0 - '0'*8), 2048);
|
||||
cv_set_character_pattern_t(0x1800);
|
||||
cv_set_screen_mode(CV_SCREENMODE_STANDARD);
|
||||
cv_set_color_table(COLOR);
|
||||
cvu_vmemset(COLOR, 0x36, 8); // set color for chars 0-63
|
||||
cvu_vmemset(COLOR+8, 0x06, 32-8); // set chars 63-255
|
||||
}
|
||||
|
||||
char cursor_x;
|
||||
char cursor_y;
|
||||
|
||||
void clrscr() {
|
||||
cvu_vmemset(IMAGE, ' ', COLS*ROWS);
|
||||
}
|
||||
|
||||
void setup_stdio() {
|
||||
cursor_x = 0;
|
||||
cursor_y = 0;
|
||||
clrscr();
|
||||
}
|
||||
|
||||
void scrollup() {
|
||||
char buf[COLS];
|
||||
char y;
|
||||
for (y=0; y<ROWS-1; y++) {
|
||||
cvu_vmemtomemcpy(buf, IMAGE + COLS*y + COLS, COLS);
|
||||
cvu_memtovmemcpy(IMAGE + COLS*y, buf, COLS);
|
||||
}
|
||||
cvu_vmemset(IMAGE + COLS*(ROWS-1), ' ', COLS);
|
||||
}
|
||||
|
||||
void newline() {
|
||||
if (cursor_y >= ROWS-1) {
|
||||
scrollup();
|
||||
} else {
|
||||
cursor_y++;
|
||||
}
|
||||
}
|
||||
|
||||
int putchar(int ch) {
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
newline(); // TODO: scrolling
|
||||
case '\r':
|
||||
cursor_x = 0;
|
||||
return 0;
|
||||
}
|
||||
cvu_voutb(ch, IMAGE + COLS*cursor_y + cursor_x);
|
||||
cursor_x++;
|
||||
if (cursor_x >= COLS) {
|
||||
newline();
|
||||
cursor_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
unsigned char byteval = 123;
|
||||
signed char charval = 123;
|
||||
short shortval = 12345;
|
||||
|
||||
setup_32_column_font();
|
||||
setup_stdio();
|
||||
cv_set_screen_active(true);
|
||||
printf("HELLO WORLD!\n");
|
||||
while (1) {
|
||||
printf("char %d byte %u sh %d\n",
|
||||
charval++, byteval++, shortval++);
|
||||
}
|
||||
}
|
@ -52,13 +52,13 @@ void newline() {
|
||||
}
|
||||
}
|
||||
|
||||
void putchar(char ch) {
|
||||
int putchar(int ch) {
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
newline(); // TODO: scrolling
|
||||
case '\r':
|
||||
cursor_x = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
cellram[cursor_x][31-cursor_y] = ch;
|
||||
cursor_x++;
|
||||
|
13
src/emu.js
13
src/emu.js
@ -873,6 +873,7 @@ var BaseMAMEPlatform = function() {
|
||||
var romdata;
|
||||
var video;
|
||||
var preload_files;
|
||||
var running = false;
|
||||
|
||||
this.luacall = function(s) {
|
||||
//console.log(s);
|
||||
@ -884,11 +885,17 @@ var BaseMAMEPlatform = function() {
|
||||
}
|
||||
|
||||
this.pause = function() {
|
||||
if (loaded) this.luacall('emu.pause()');
|
||||
if (loaded && running) {
|
||||
this.luacall('emu.pause()');
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.resume = function() {
|
||||
if (loaded) this.luacall('emu.unpause()');
|
||||
if (loaded && !running) {
|
||||
this.luacall('emu.unpause()');
|
||||
running = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.reset = function() {
|
||||
@ -896,7 +903,7 @@ var BaseMAMEPlatform = function() {
|
||||
}
|
||||
|
||||
this.isRunning = function() {
|
||||
// TODO
|
||||
return running;
|
||||
}
|
||||
|
||||
this.startModule = function(mainElement, opts) {
|
||||
|
@ -5,11 +5,21 @@
|
||||
// http://www.kernelcrash.com/blog/recreating-the-colecovision/2016/01/27/
|
||||
// http://www.atarihq.com/danb/files/CV-Tech.txt
|
||||
// http://www.colecoboxart.com/faq/FAQ05.htm
|
||||
// http://www.theadamresource.com/manuals/technical/Jeffcoleco.html
|
||||
// http://bifi.msxnet.org/msxnet//tech/tms9918a.txt
|
||||
// http://www.colecovision.dk/tools.htm?refreshed
|
||||
|
||||
var ColecoVision_PRESETS = [
|
||||
{id:'minimal.c', name:'Minimal Example'},
|
||||
{id:'text.c', name:'Text Mode'},
|
||||
{id:'hello.c', name:'Scrolling Text'},
|
||||
{id:'text32.c', name:'32-Column Text'},
|
||||
{id:'stars.c', name:'Scrolling Starfield'},
|
||||
{id:'cursorsmooth.c', name:'Moving Cursor'},
|
||||
{id:'simplemusic.c', name:'Simple Music'},
|
||||
{id:'siegegame.c', name:'Siege Game'},
|
||||
];
|
||||
|
||||
// doesn't work, use MAME
|
||||
var ColecoVisionPlatform = function(mainElement) {
|
||||
var self = this;
|
||||
this.__proto__ = new BaseZ80Platform();
|
||||
|
24
src/ui.js
24
src/ui.js
@ -398,6 +398,7 @@ function setCompileOutput(data) {
|
||||
addr2symbol = invertMap(symbolmap);
|
||||
addr2symbol[0x10000] = '__END__';
|
||||
compparams = data.params;
|
||||
updatePreset(current_preset_id, editor.getValue()); // update persisted entry
|
||||
// errors?
|
||||
function addErrorMarker(line, msg) {
|
||||
var div = document.createElement("div");
|
||||
@ -422,7 +423,6 @@ function setCompileOutput(data) {
|
||||
}
|
||||
current_output = null;
|
||||
} else {
|
||||
updatePreset(current_preset_id, editor.getValue()); // update persisted entry
|
||||
// load ROM
|
||||
var rom = data.output;
|
||||
var rom_changed = rom && !arrayCompare(rom, current_output);
|
||||
@ -1112,18 +1112,28 @@ function showBookLink() {
|
||||
}
|
||||
|
||||
function addPageFocusHandlers() {
|
||||
var hidden = false;
|
||||
document.addEventListener("visibilitychange", function() {
|
||||
if (document.visibilityState == 'hidden')
|
||||
if (document.visibilityState == 'hidden' && platform.isRunning()) {
|
||||
platform.pause();
|
||||
else if (document.visibilityState == 'visible')
|
||||
hidden = true;
|
||||
} else if (document.visibilityState == 'visible' && hidden) {
|
||||
platform.resume();
|
||||
hidden = false;
|
||||
}
|
||||
});
|
||||
window.onfocus = function() {
|
||||
$(window).on("focus", function() {
|
||||
if (hidden) {
|
||||
platform.resume();
|
||||
};
|
||||
window.onblur = function() {
|
||||
hidden = false;
|
||||
}
|
||||
});
|
||||
$(window).on("blur", function() {
|
||||
if (platform.isRunning()) {
|
||||
platform.pause();
|
||||
};
|
||||
hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function startPlatform() {
|
||||
|
25865
src/worker/fssdcc.data
25865
src/worker/fssdcc.data
File diff suppressed because it is too large
Load Diff
@ -85,8 +85,10 @@ Module.expectedDataFileDownloads++;
|
||||
console.error('package error:', error);
|
||||
};
|
||||
|
||||
var fetched = null, fetchedCallback = null;
|
||||
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, function(data) {
|
||||
var fetchedCallback = null;
|
||||
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
|
||||
|
||||
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, function(data) {
|
||||
if (fetchedCallback) {
|
||||
fetchedCallback(data);
|
||||
fetchedCallback = null;
|
||||
@ -101,6 +103,7 @@ Module.expectedDataFileDownloads++;
|
||||
if (!check) throw msg + new Error().stack;
|
||||
}
|
||||
Module['FS_createPath']('/', 'include', true, true);
|
||||
Module['FS_createPath']('/include', 'pic16', true, true);
|
||||
Module['FS_createPath']('/include', 'ds390', true, true);
|
||||
Module['FS_createPath']('/include', 'asm', true, true);
|
||||
Module['FS_createPath']('/include/asm', 'default', true, true);
|
||||
@ -115,12 +118,18 @@ Module['FS_createPath']('/include/asm', 'pic14', true, true);
|
||||
Module['FS_createPath']('/include/asm', 'gbz80', true, true);
|
||||
Module['FS_createPath']('/include/asm', 'r2k', true, true);
|
||||
Module['FS_createPath']('/include/asm', 'z80', true, true);
|
||||
Module['FS_createPath']('/include', 'xa51', true, true);
|
||||
Module['FS_createPath']('/include', 'mcs51', true, true);
|
||||
Module['FS_createPath']('/include', 'hc08', true, true);
|
||||
Module['FS_createPath']('/include', 'z180', true, true);
|
||||
Module['FS_createPath']('/include', 'pic14', true, true);
|
||||
Module['FS_createPath']('/include', 'ds400', true, true);
|
||||
Module['FS_createPath']('/', 'lib', true, true);
|
||||
Module['FS_createPath']('/lib', 'z80', true, true);
|
||||
Module['FS_createPath']('/lib', 'libcv', true, true);
|
||||
Module['FS_createPath']('/lib', 'libcvu', true, true);
|
||||
Module['FS_createPath']('/include', 'libcv', true, true);
|
||||
Module['FS_createPath']('/include', 'libcvu', true, true);
|
||||
|
||||
function DataRequest(start, end, crunched, audio) {
|
||||
this.start = start;
|
||||
|
File diff suppressed because one or more lines are too long
@ -3,66 +3,69 @@
|
||||
var PLATFORM_PARAMS = {
|
||||
'mw8080bw': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x2000,
|
||||
rom_size: 0x2000,
|
||||
data_start: 0x2000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x2400,
|
||||
},
|
||||
'vicdual': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x4020,
|
||||
rom_size: 0x4020,
|
||||
data_start: 0xe400,
|
||||
data_size: 0x400,
|
||||
stack_end: 0xe800,
|
||||
},
|
||||
'galaxian': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x4000,
|
||||
rom_size: 0x4000,
|
||||
data_start: 0x4000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x4800,
|
||||
},
|
||||
'galaxian-scramble': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x5020,
|
||||
rom_size: 0x5020,
|
||||
data_start: 0x4000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x4800,
|
||||
},
|
||||
'williams-z80': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x9800,
|
||||
rom_size: 0x9800,
|
||||
data_start: 0x9800,
|
||||
data_size: 0x2800,
|
||||
stack_end: 0xc000,
|
||||
},
|
||||
'vector-z80color': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x8000,
|
||||
rom_size: 0x8000,
|
||||
data_start: 0xe000,
|
||||
data_size: 0x2000,
|
||||
stack_end: 0x0,
|
||||
},
|
||||
'sound_williams-z80': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x4000,
|
||||
rom_size: 0x4000,
|
||||
data_start: 0x4000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x8000,
|
||||
},
|
||||
'base_z80': {
|
||||
code_start: 0x0,
|
||||
code_size: 0x8000,
|
||||
rom_size: 0x8000,
|
||||
data_start: 0x8000,
|
||||
data_size: 0x8000,
|
||||
stack_end: 0x0,
|
||||
},
|
||||
'coleco': {
|
||||
code_start: 0x8000,
|
||||
code_size: 0x8000,
|
||||
data_start: 0x6000,
|
||||
rom_start: 0x8000,
|
||||
code_start: 0x8100,
|
||||
rom_size: 0x8000,
|
||||
data_start: 0x7000,
|
||||
data_size: 0x400,
|
||||
stack_end: 0x8000,
|
||||
extra_preproc_args: ['-I', '/share/include/libcv', '-I', '/share/include/libcvu'],
|
||||
extra_link_args: ['-k', '/share/lib/libcv', '-l', 'libcv', '-k', '/share/lib/libcvu', '-l', 'libcvu', '/share/lib/libcv/crt0.rel', 'main.rel'],
|
||||
},
|
||||
};
|
||||
|
||||
@ -631,13 +634,13 @@ function hexToArray(s, ofs) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function parseIHX(ihx, code_start, code_size) {
|
||||
var output = new Uint8Array(new ArrayBuffer(code_size));
|
||||
function parseIHX(ihx, rom_start, rom_size) {
|
||||
var output = new Uint8Array(new ArrayBuffer(rom_size));
|
||||
for (var s of ihx.split("\n")) {
|
||||
if (s[0] == ':') {
|
||||
var arr = hexToArray(s, 1);
|
||||
var count = arr[0];
|
||||
var address = (arr[1]<<8) + arr[2] - code_start;
|
||||
var address = (arr[1]<<8) + arr[2] - rom_start;
|
||||
var rectype = arr[3];
|
||||
if (rectype == 0) {
|
||||
for (var i=0; i<count; i++) {
|
||||
@ -699,6 +702,7 @@ function assemblelinkSDASZ80(code, platform) {
|
||||
});
|
||||
}
|
||||
}
|
||||
var updateListing = !params.extra_link_args;
|
||||
var LDZ80 = sdldz80({
|
||||
noInitialRun:true,
|
||||
//logReadFiles:true,
|
||||
@ -708,16 +712,24 @@ function assemblelinkSDASZ80(code, platform) {
|
||||
var FS = LDZ80['FS'];
|
||||
setupFS(FS, 'sdcc');
|
||||
FS.writeFile("main.rel", objout, {encoding:'utf8'});
|
||||
if (updateListing) {
|
||||
FS.writeFile("main.lst", lstout, {encoding:'utf8'});
|
||||
LDZ80.callMain(['-mjwxyu', '-i', 'main.ihx',
|
||||
}
|
||||
var args = ['-mjwxy'+(updateListing?'u':''),
|
||||
'-i', 'main.ihx',
|
||||
'-b', '_CODE=0x'+params.code_start.toString(16),
|
||||
'-b', '_DATA=0x'+params.data_start.toString(16),
|
||||
'-k', '/share/lib/z80',
|
||||
'-l', 'z80',
|
||||
'main.rel']);
|
||||
'-l', 'z80'];
|
||||
if (params.extra_link_args) {
|
||||
args.push.apply(args, params.extra_link_args);
|
||||
} else {
|
||||
args.push('main.rel');
|
||||
}
|
||||
LDZ80.callMain(args);
|
||||
var hexout = FS.readFile("main.ihx", {encoding:'utf8'});
|
||||
var mapout = FS.readFile("main.noi", {encoding:'utf8'});
|
||||
var rstout = FS.readFile("main.rst", {encoding:'utf8'});
|
||||
var rstout = updateListing ? FS.readFile("main.rst", {encoding:'utf8'}) : lstout;
|
||||
//var dbgout = FS.readFile("main.cdb", {encoding:'utf8'});
|
||||
// 0000 21 02 00 [10] 52 ld hl, #2
|
||||
// TODO: offset by start address?
|
||||
@ -732,7 +744,7 @@ function assemblelinkSDASZ80(code, platform) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
output:parseIHX(hexout, params.code_start, params.code_size),
|
||||
output:parseIHX(hexout, params.rom_start?params.rom_start:params.code_start, params.rom_size),
|
||||
lines:asmlines,
|
||||
srclines:srclines,
|
||||
errors:msvc_errors, // TODO?
|
||||
@ -765,7 +777,7 @@ function compileSDCC(code, platform) {
|
||||
//FS.writeFile("main.c", code, {encoding:'utf8'});
|
||||
msvc_errors = [];
|
||||
var t1 = new Date();
|
||||
SDCC.callMain(['--vc', '--std-sdcc99', '-mz80', //'-Wall',
|
||||
var args = ['--vc', '--std-sdcc99', '-mz80', //'-Wall',
|
||||
'--c1mode', // '--debug',
|
||||
//'-S', 'main.c',
|
||||
//'--asm=z80asm',
|
||||
@ -775,7 +787,11 @@ function compileSDCC(code, platform) {
|
||||
'--oldralloc', // TODO: does this make it fater?
|
||||
//'--cyclomatic',
|
||||
//'--nooverlay','--nogcse','--nolabelopt','--noinvariant','--noinduction','--nojtbound','--noloopreverse','--no-peep','--nolospre',
|
||||
'-o', 'main.asm']);
|
||||
'-o', 'main.asm'];
|
||||
if (params.extra_compile_args) {
|
||||
args.push.apply(args, params.extra_compile_args);
|
||||
}
|
||||
SDCC.callMain(args);
|
||||
var t2 = new Date();
|
||||
//console.profileEnd();
|
||||
//console.log(t2.getTime() - t1.getTime());
|
||||
@ -861,6 +877,8 @@ function assembleXASM6809(code, platform) {
|
||||
|
||||
function preprocessMCPP(code, platform) {
|
||||
load("mcpp");
|
||||
var params = PLATFORM_PARAMS[platform];
|
||||
if (!params) throw Error("Platform not supported: " + platform);
|
||||
// <stdin>:2: error: Can't open include file "foo.h"
|
||||
var errors = [];
|
||||
var match_fn = makeErrorMatcher(errors, /<stdin>:(\d+): (.+)/, 1, 2);
|
||||
@ -873,13 +891,17 @@ function preprocessMCPP(code, platform) {
|
||||
var FS = MCPP['FS'];
|
||||
setupFS(FS, 'sdcc');
|
||||
FS.writeFile("main.c", code, {encoding:'utf8'});
|
||||
MCPP.callMain([
|
||||
var args = [
|
||||
"-D", "__8BITWORKSHOP__",
|
||||
"-D", platform.toUpperCase().replace('-','_'),
|
||||
"-D", "__SDCC_z80",
|
||||
"-I", "/share/include",
|
||||
"-Q",
|
||||
"main.c", "main.i"]);
|
||||
"main.c", "main.i"];
|
||||
if (params.extra_preproc_args) {
|
||||
args.push.apply(args, params.extra_preproc_args);
|
||||
}
|
||||
MCPP.callMain(args);
|
||||
try {
|
||||
var iout = FS.readFile("main.i", {encoding:'utf8'});
|
||||
iout = iout.replace(/^#line /gm,'\n# ');
|
||||
|
Loading…
Reference in New Issue
Block a user