diff --git a/presets/vicdual/snake1.c b/presets/vicdual/snake1.c index e53777b4..3c124879 100644 --- a/presets/vicdual/snake1.c +++ b/presets/vicdual/snake1.c @@ -108,7 +108,7 @@ void draw_playfield() { draw_box(0,0,27,29,BOX_CHARS); } -typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } dir_t; +typedef enum { D_RIGHT, D_DOWN, D_LEFT, D_UP } Direction; const char DIR_X[4] = { 1, 0, -1, 0 }; const char DIR_Y[4] = { 0, -1, 0, 1 }; @@ -132,8 +132,12 @@ void draw_player(Player* p) { putchar(p->x, p->y, p->head_attr); } -void move_player(Player* p) { +void erase_player(Player* p) { putchar(p->x, p->y, p->tail_attr); +} + +void move_player(Player* p) { + erase_player(p); p->x += DIR_X[p->dir]; p->y += DIR_Y[p->dir]; if (getchar(p->x, p->y) != CHAR(' ')) @@ -142,20 +146,20 @@ void move_player(Player* p) { } void human_control(Player* p) { - byte dir = 0xff; + Direction dir = 0xff; if (LEFT1) dir = D_LEFT; if (RIGHT1) dir = D_RIGHT; if (UP1) dir = D_UP; if (DOWN1) dir = D_DOWN; // don't let the player reverse - if (dir < 0x80 && dir != (p->dir ^ 2)) { + if (dir != 0xff && dir != (p->dir ^ 2)) { p->dir = dir; } } void ai_control(Player* p) { byte x,y; - dir_t dir = p->dir; + Direction dir = p->dir; x = p->x + DIR_X[dir]; y = p->y + DIR_Y[dir]; if (getchar(x,y) != CHAR(' ')) { diff --git a/presets/vicdual/snake2.c b/presets/vicdual/snake2.c index 874510e6..8f2d6944 100644 --- a/presets/vicdual/snake2.c +++ b/presets/vicdual/snake2.c @@ -14,7 +14,7 @@ __sfr __at (0x1) ay8910_reg; __sfr __at (0x2) ay8910_data; __sfr __at (0x40) palette; -byte __at (0xe000) cellram[32][32]; +byte __at (0xe000) cellram[28][32]; byte __at (0xe800) tileram[256][8]; #define LEFT1 !(input1 & 0x10) @@ -25,6 +25,7 @@ byte __at (0xe800) tileram[256][8]; #define COIN1 (input3 & 0x8) #define START1 !(input2 & 0x10) #define START2 !(input3 & 0x20) +#define VSYNC (input1 & 0x8) // GAME DATA @@ -105,8 +106,8 @@ word rand() { } void wait_for_vsync() { - while ((input1 & 0x8) != 0) lfsr++; // wait for VSYNC end - while ((input1 & 0x8) == 0) lfsr++; // wait for VSYNC start + while (VSYNC != 0) lfsr++; // wait for VSYNC end + while (VSYNC == 0) lfsr++; // wait for VSYNC start } #define LOCHAR 0x0 @@ -128,7 +129,7 @@ void putchar(byte x, byte y, byte attr) { void putstring(byte x, byte y, const char* string) { while (*string) { - putchar(x++, y, (*string++ - LOCHAR)); + putchar(x++, y, CHAR(*string++)); } } @@ -165,6 +166,18 @@ void draw_bcd_word(byte x, byte y, word bcd) { } } +/* +void draw_bcd_byte(byte x, byte y, byte bcd) { + putchar(CHAR('0'+(bcd&0xf)), x+1, y); + putchar(CHAR('0'+((bcd>>4)&0xf)), x, y); +} + +void draw_bcd_word2(byte x, byte y, word bcd) { + draw_bcd_byte(x+2, y, bcd); + draw_bcd_byte(x, y, bcd>>8); +} +*/ + void draw_playfield() { draw_box(0,0,27,29,BOX_CHARS); putstring(0,31,"PLAYER 1"); diff --git a/presets/williams/gfxtest.c b/presets/williams/gfxtest.c new file mode 100644 index 00000000..a71045ee --- /dev/null +++ b/presets/williams/gfxtest.c @@ -0,0 +1,141 @@ + +#include + +typedef unsigned char byte; +typedef unsigned short word; + +byte __at (0xc000) palette[16]; +byte __at (0xc800) input0; +byte __at (0xc802) input1; +byte __at (0xc804) input2; +byte __at (0xc900) rom_select; +byte __at (0xcb00) video_counter; +byte __at (0xcbff) watchdog0x39; +byte __at (0xcc00) nvram[0x400]; + +// blitter flags +#define SRCSCREEN 0x1 +#define DSTSCREEN 0x2 +#define ESYNC 0x4 +#define FGONLY 0x8 +#define SOLID 0x10 +#define RSHIFT 0x20 +#define EVENONLY 0x40 +#define ODDONLY 0x80 + +struct { + byte flags; + byte solid; + word sstart; + word dstart; + byte width; + byte height; +} __at (0xca00) blitter; + +byte __at (0x0) vidmem[128][304]; // 256x304x4bpp video memory + +void main(); + +// start routine @ 0x0 +// set stack pointer, enable interrupts +void start() { +__asm + LD SP,#0xc000 + DI +__endasm; + main(); +} + +#define LOCHAR 0x21 +#define HICHAR 0x5e + +const byte font8x8[HICHAR-LOCHAR+1][8] = { +{ 0x18,0x18,0x18,0x18,0x00,0x00,0x18,0x00 }, { 0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00 }, { 0x66,0x66,0xff,0x66,0xff,0x66,0x66,0x00 }, { 0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00 }, { 0x62,0x66,0x0c,0x18,0x30,0x66,0x46,0x00 }, { 0x3c,0x66,0x3c,0x38,0x67,0x66,0x3f,0x00 }, { 0x06,0x0c,0x18,0x00,0x00,0x00,0x00,0x00 }, { 0x0c,0x18,0x30,0x30,0x30,0x18,0x0c,0x00 }, { 0x30,0x18,0x0c,0x0c,0x0c,0x18,0x30,0x00 }, { 0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00 }, { 0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30 }, { 0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 }, { 0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x00 }, { 0x3c,0x66,0x6e,0x76,0x66,0x66,0x3c,0x00 }, { 0x18,0x18,0x38,0x18,0x18,0x18,0x7e,0x00 }, { 0x3c,0x66,0x06,0x0c,0x30,0x60,0x7e,0x00 }, { 0x3c,0x66,0x06,0x1c,0x06,0x66,0x3c,0x00 }, { 0x06,0x0e,0x1e,0x66,0x7f,0x06,0x06,0x00 }, { 0x7e,0x60,0x7c,0x06,0x06,0x66,0x3c,0x00 }, { 0x3c,0x66,0x60,0x7c,0x66,0x66,0x3c,0x00 }, { 0x7e,0x66,0x0c,0x18,0x18,0x18,0x18,0x00 }, { 0x3c,0x66,0x66,0x3c,0x66,0x66,0x3c,0x00 }, { 0x3c,0x66,0x66,0x3e,0x06,0x66,0x3c,0x00 }, { 0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00 }, { 0x00,0x00,0x18,0x00,0x00,0x18,0x18,0x30 }, { 0x0e,0x18,0x30,0x60,0x30,0x18,0x0e,0x00 }, { 0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00 }, { 0x70,0x18,0x0c,0x06,0x0c,0x18,0x70,0x00 }, { 0x3c,0x66,0x06,0x0c,0x18,0x00,0x18,0x00 }, { 0x3c,0x66,0x6e,0x6e,0x60,0x62,0x3c,0x00 }, { 0x18,0x3c,0x66,0x7e,0x66,0x66,0x66,0x00 }, { 0x7c,0x66,0x66,0x7c,0x66,0x66,0x7c,0x00 }, { 0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x00 }, { 0x78,0x6c,0x66,0x66,0x66,0x6c,0x78,0x00 }, { 0x7e,0x60,0x60,0x78,0x60,0x60,0x7e,0x00 }, { 0x7e,0x60,0x60,0x78,0x60,0x60,0x60,0x00 }, { 0x3c,0x66,0x60,0x6e,0x66,0x66,0x3c,0x00 }, { 0x66,0x66,0x66,0x7e,0x66,0x66,0x66,0x00 }, { 0x3c,0x18,0x18,0x18,0x18,0x18,0x3c,0x00 }, { 0x1e,0x0c,0x0c,0x0c,0x0c,0x6c,0x38,0x00 }, { 0x66,0x6c,0x78,0x70,0x78,0x6c,0x66,0x00 }, { 0x60,0x60,0x60,0x60,0x60,0x60,0x7e,0x00 }, { 0x63,0x77,0x7f,0x6b,0x63,0x63,0x63,0x00 }, { 0x66,0x76,0x7e,0x7e,0x6e,0x66,0x66,0x00 }, { 0x3c,0x66,0x66,0x66,0x66,0x66,0x3c,0x00 }, { 0x7c,0x66,0x66,0x7c,0x60,0x60,0x60,0x00 }, { 0x3c,0x66,0x66,0x66,0x66,0x3c,0x0e,0x00 }, { 0x7c,0x66,0x66,0x7c,0x78,0x6c,0x66,0x00 }, { 0x3c,0x66,0x60,0x3c,0x06,0x66,0x3c,0x00 }, { 0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x00 }, { 0x66,0x66,0x66,0x66,0x66,0x66,0x3c,0x00 }, { 0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00 }, { 0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00 }, { 0x66,0x66,0x3c,0x18,0x3c,0x66,0x66,0x00 }, { 0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x00 }, { 0x7e,0x06,0x0c,0x18,0x30,0x60,0x7e,0x00 }, { 0x3c,0x30,0x30,0x30,0x30,0x30,0x3c,0x00 }, { 0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x00 }, { 0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00 }, { 0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18 } +}; + +const byte sprite1[] = { + 4,6, + 0x33,0x33,0x33,0x32, + 0x33,0x33,0x32,0x33, + 0x33,0x32,0x00,0x33, + 0x32,0x00,0x00,0x33, + 0x33,0x00,0x00,0x33, + 0x33,0x33,0x33,0x33 +}; + +inline word swapw(word j) { + return ((j << 8) | (j >> 8)); +} + +// x1: 0-151 +// y1: 0-255 +void blit_solid(byte x1, byte y1, byte w, byte h, byte color) { + blitter.width = w^4; + blitter.height = h^4; + blitter.dstart = x1+y1*256; // swapped + blitter.solid = color; + blitter.flags = DSTSCREEN|SOLID; +} + +void blit_copy(byte x1, byte y1, byte w, byte h, const byte* data) { + blitter.width = w^4; + blitter.height = h^4; + blitter.sstart = swapw((word)data); + blitter.dstart = x1+y1*256; // swapped + blitter.solid = 0; + blitter.flags = DSTSCREEN|FGONLY; +} + +void draw_sprite(const byte* data, byte x, byte y) { + blitter.width = data[0]^4; + blitter.height = data[1]^4; + blitter.sstart = swapw((word)(data+2)); + blitter.dstart = x+y*256; // swapped + blitter.solid = 0; + blitter.flags = DSTSCREEN|FGONLY; +} + +void draw_char(char ch, byte x, byte y, byte color) { + byte data[8][4]; + const byte* src = &font8x8[ch-LOCHAR][0]; + int i,j,pixels; + if (ch < LOCHAR || ch > HICHAR) return; + for (i=0; i<8; i++) { + byte b = *src++; + for (j=0; j<4; j++) { + pixels = 0; + if (b & 0x80) pixels |= color & 0xf0; + if (b & 0x40) pixels |= color & 0x0f; + data[i][j] = pixels; + b <<= 2; + } + } + blit_copy(x, y, 4, 8, (char*)data); +} + +void draw_string(const char* str, byte x, byte y, byte color) { + char ch; + do { + ch = *str++; + draw_char(ch, x, y, color); + x += 4; + } while (ch); +} + +void main() { + int i; + for (i=0; i<16; i++) + palette[i] = i*5; + for (i=0; i<128; i+=8) { + vidmem[0][i] += 16; + vidmem[i][2] += 32; + //blit_solid(i/2,i,149-i,255-i*2,i*0x11+1); + } + draw_sprite(sprite1, 10, 20); + draw_char('A', 5, 5, 0xff); + draw_string("HELLO WORLD", 20, 5, 0x88); + //blit_solid(0,0,100,100,0x11); + //blit_solid(10,20,100,200,0x22); + watchdog0x39 = 0x39; + main(); +} diff --git a/src/platform/galaxian.js b/src/platform/galaxian.js index a5382457..b6855326 100644 --- a/src/platform/galaxian.js +++ b/src/platform/galaxian.js @@ -1,9 +1,8 @@ "use strict"; var GALAXIAN_PRESETS = [ - {id:'minimal.c', name:'Minimal Example'}, - {id:'hello.c', name:'Hello World'}, {id:'gfxtest.c', name:'Graphics Test'}, + {id:'game1.c', name:'Shoot-em-up Game'}, ]; var GALAXIAN_KEYCODE_MAP = makeKeycodeMap([ @@ -30,7 +29,7 @@ var SCRAMBLE_KEYCODE_MAP = makeKeycodeMap([ [Keys.VK_1, 1, -0x80], [Keys.VK_2, 1, -0x40], [Keys.VK_DOWN, 2, -0x40], - [Keys.VK_UP, 2, -0x10], + //[Keys.VK_UP, 2, -0x10], ]); @@ -116,7 +115,7 @@ var GalaxianPlatform = function(mainElement, options) { var bm = 128>>i; var color = ((data1&bm)?1:0) + ((data2&bm)?2:0); if (color) - pixels[outi+i] = palette[color0 + color]; + pixels[flipx?(outi+15-i):(outi+i)] = palette[color0 + color]; } var data1 = rom[addr+8]; var data2 = rom[addr+0x808]; @@ -124,7 +123,7 @@ var GalaxianPlatform = function(mainElement, options) { var bm = 128>>i; var color = ((data1&bm)?1:0) + ((data2&bm)?2:0); if (color) - pixels[outi+i+8] = palette[color0 + color]; + pixels[flipx?(outi+7-i):(outi+i+8)] = palette[color0 + color]; } } } @@ -227,6 +226,8 @@ var GalaxianPlatform = function(mainElement, options) { [0x6801, 0x6801, 0, function(a,v) { interruptEnabled = 1; }], [0x6802, 0x6802, 0, function(a,v) { /* TODO: coin counter */ }], [0x6804, 0x6804, 0, function(a,v) { starsEnabled = v; }], + [0x6805, 0x6805, 0, function(a,v) { missileWidth = v; }], // not on h/w + [0x6806, 0x6806, 0, function(a,v) { missileOffset = v; }], // not on h/w [0x8202, 0x8202, 0, scramble_protection_w], //[0x8100, 0x8103, 0, function(a,v){ /* PPI 0 */ }], //[0x8200, 0x8203, 0, function(a,v){ /* PPI 1 */ }], diff --git a/src/platform/vicdual.js b/src/platform/vicdual.js index 2f07a63d..a54ac9de 100644 --- a/src/platform/vicdual.js +++ b/src/platform/vicdual.js @@ -5,8 +5,8 @@ var VICDUAL_PRESETS = [ {id:'hello.c', name:'Hello World'}, {id:'gfxtest.c', name:'Graphics Test'}, {id:'soundtest.c', name:'Sound Test'}, - {id:'snake1.c', name:'Snake Game #1'}, - {id:'snake2.c', name:'Snake Game #2'}, + {id:'snake1.c', name:'Snake Game (Prototype)'}, + {id:'snake2.c', name:'Snake Game (Full)'}, ]; var VicDualPlatform = function(mainElement) { diff --git a/src/platform/williams.js b/src/platform/williams.js index b9a722ea..20c5625d 100644 --- a/src/platform/williams.js +++ b/src/platform/williams.js @@ -128,7 +128,7 @@ var WilliamsPlatform = function(mainElement, proto) { [0xa00, 0xa07, 0x7, setBlitter], [0xbff, 0xbff, 0, function(a,v) { if (v == 0x39) watchdog_counter = INITIAL_WATCHDOG; }], [0xc00, 0xfff, 0x3ff, function(a,v) { nvram.mem[a] = v; }], - [0x0, 0xfff, 0, function(a,v) { console.log('iowrite',hex(a),hex(v)); }], + //[0x0, 0xfff, 0, function(a,v) { console.log('iowrite',hex(a),hex(v)); }], ]); var memread_williams = new AddressDecoder([ @@ -142,7 +142,7 @@ var WilliamsPlatform = function(mainElement, proto) { [0x0000, 0x8fff, 0, write_display_byte], [0x9000, 0xbfff, 0, function(a,v) { ram.mem[a] = v; }], [0xc000, 0xcfff, 0x0fff, iowrite_williams], - [0x0000, 0xffff, 0, function(a,v) { console.log(hex(a), hex(v)); }], + //[0x0000, 0xffff, 0, function(a,v) { console.log(hex(a), hex(v)); }], ]); // d1d6 ldu $11 / beq $d1ed diff --git a/src/worker/workermain.js b/src/worker/workermain.js index 7057691f..32edfac1 100644 --- a/src/worker/workermain.js +++ b/src/worker/workermain.js @@ -645,6 +645,7 @@ function compileSDCC(code, platform) { noFSInit:true, print:print_fn, printErr:match_msvc, + TOTAL_MEMORY:256*1024*1024, }); var FS = SDCC['FS']; setupStdin(FS, code);