From 2d02b64464a7d4a94841528bf9bc6cdb607d4c3f Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Fri, 18 Feb 2022 11:53:33 -0600 Subject: [PATCH 1/9] williams: working on cmoc --- index.html | 2 + presets/williams/gfxtest.c | 83 ++++++++ presets/williams/williams.c | 75 +++++++ presets/williams/williams.h | 100 +++++++++ src/platform/williams.ts | 5 +- src/worker/lib/williams/assert.h | 20 ++ src/worker/lib/williams/cmoc.h | 345 +++++++++++++++++++++++++++++++ src/worker/lib/williams/stdarg.h | 22 ++ src/worker/lib/williams/stdlib.h | 13 ++ src/worker/tools/m6809.ts | 5 + src/worker/workermain.ts | 4 +- 11 files changed, 671 insertions(+), 3 deletions(-) create mode 100644 presets/williams/gfxtest.c create mode 100644 presets/williams/williams.c create mode 100644 presets/williams/williams.h create mode 100644 src/worker/lib/williams/assert.h create mode 100644 src/worker/lib/williams/cmoc.h create mode 100644 src/worker/lib/williams/stdarg.h create mode 100644 src/worker/lib/williams/stdlib.h diff --git a/index.html b/index.html index 6a95a8c0..52c42c1b 100644 --- a/index.html +++ b/index.html @@ -208,6 +208,8 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
  • Atari 2600 (MAME)
  • ColecoVision (MAME)
  • NES (MAME)
  • +
    +
  • Williams (6809)
  • diff --git a/presets/williams/gfxtest.c b/presets/williams/gfxtest.c new file mode 100644 index 00000000..fb9f4614 --- /dev/null +++ b/presets/williams/gfxtest.c @@ -0,0 +1,83 @@ + +#include "williams.h" +//#link "williams.c" + +// 256x304x4bpp video memory + +#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[] = { +8,16, +0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00, +0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00, +0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90, +0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49, +0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99, +0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90, +0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00, +0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00, +0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00, +0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00, +0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00, +0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00, +0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30, +0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00, +0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00, +0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, +}; + +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] = (byte)pixels; + b <<= 2; + } + } + blit_copy(x, y, 4, 8, (byte*)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); +} + +int main(void) { + byte i; + rom_select = 1; + blit_solid(0, 0, 152, 255, 0x00); + for (i=0; i<16; i++) + palette[i] = (byte)(i*7); + for (i=0; i<152; i++) { + vidmem[0][i] = 16; + vidmem[i][2] = 32; + blit_pixel(i, i, 0x77); + blit_pixel(i+1, i, 0x33); + } + while (1) { + watchdog0x39 = 0x39; + draw_sprite(sprite1, 35, 20); + draw_sprite_solid(sprite1, 55, 20, 0x24); + blit_solid(75, 20, 40, 20, 0x35); + draw_string("HELLO WORLD", 20, 5, 0x88); + } + return 0; +} + + diff --git a/presets/williams/williams.c b/presets/williams/williams.c new file mode 100644 index 00000000..1bad3294 --- /dev/null +++ b/presets/williams/williams.c @@ -0,0 +1,75 @@ + +#include "williams.h" + +// 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 = ((word)x1<<8)+y1; // 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 = (word)data; + blitter.dstart = ((word)x1<<8)+y1; // swapped + blitter.solid = 0; + blitter.flags = DSTSCREEN|FGONLY; +} + +void blit_copy_solid(byte x1, byte y1, byte w, byte h, const byte* data, byte solid) { + blitter.width = w^4; + blitter.height = h^4; + blitter.sstart = (word)data; + blitter.dstart = ((word)x1<<8)+y1; // swapped + blitter.solid = solid; + blitter.flags = DSTSCREEN|FGONLY|SOLID; +} + +void draw_sprite(const byte* data, byte x, byte y) { + blitter.width = data[0]^4; + blitter.height = data[1]^4; + blitter.sstart = (word)(data+2); + blitter.dstart = ((word)x<<8)+y; // swapped + blitter.solid = 0; + blitter.flags = DSTSCREEN|FGONLY; +} + +void blit_pixel(word xx, byte y, byte color) { + blitter.width = 1^4; + blitter.height = 1^4; + blitter.dstart = (((xx>>1)&0xff)<<8)+y; // swapped + blitter.solid = color; + blitter.flags = (xx&1) ? SOLID|ODDONLY : SOLID|EVENONLY; +} + +void draw_sprite_solid(const byte* data, byte x, byte y, byte color) { + blitter.width = data[0]^4; + blitter.height = data[1]^4; + blitter.sstart = (word)(data+2); + blitter.dstart = ((word)x<<8)+y; // swapped + blitter.solid = color; + blitter.flags = DSTSCREEN|FGONLY|SOLID; +} + +void erase_sprite_rect(const byte* data, byte x, byte y) { + blitter.width = data[0]^4; + blitter.height = data[1]^4; + blitter.dstart = ((word)x<<8)+y; // swapped + blitter.solid = 0; + blitter.flags = DSTSCREEN|SOLID; +} + +void draw_sprite_strided(const byte* data, byte x, byte y, byte stride) { + const byte* src = data+2; + byte height = data[1]^4; + byte width = data[0]^4; + while (height--) { + blit_copy(x, y, width, 1, src); + y += stride; + src += width; + } +} diff --git a/presets/williams/williams.h b/presets/williams/williams.h new file mode 100644 index 00000000..36ec034c --- /dev/null +++ b/presets/williams/williams.h @@ -0,0 +1,100 @@ + +#ifndef _WILLIAMS_H +#define _WILLIAMS_H + +typedef unsigned char byte; +typedef unsigned short word; + +byte* palette = 0xc000; +byte* nvram = 0xcc00; + +#define input0 (*(byte*)0xc804) +#define input1 (*(byte*)0xc806) +#define input2 (*(byte*)0xc80c) +#define sound_pia (*(byte*)0xc80c) +#define rom_select *((byte*)0xc900) +#define video_counter *((byte*)0xcb00) +#define watchdog0x39 *((byte*)0xcbff) + +// switch flags + +#define UP1 (input0 & 0x1) +#define DOWN1 (input0 & 0x2) +#define LEFT1 (input0 & 0x4) +#define RIGHT1 (input0 & 0x8) +#define START1 (input0 & 0x10) +#define START2 (input0 & 0x20) +#define UP2 (input0 & 0x40) +#define DOWN2 (input0 & 0x80) +#define LEFT2 (input1 & 0x1) +#define RIGHT2 (input1 & 0x2) +#define AUTOUP (input2 & 0x1) +#define ADVANCE (input2 & 0x2) +#define COIN2 (input2 & 0x4) +#define HIGHSCORERESET (input2 & 0x8) +#define COIN1 (input2 & 0x10) +#define COIN3 (input2 & 0x20) +#define TILTSWITCH (input2 & 0x40) +#define SOUNDACK (input2 & 0x80) + +// 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; +} *_blitter = 0xca00; + +#define blitter (*_blitter) + +struct { + byte mem[152][256]; +} *_vid = 0x0; + +#define vidmem (_vid->mem) + +#define BLIT_OP(_x,_y,_w,_h,_src,_color,_flags) do {\ + blitter.width = (_w)^4; \ + blitter.height = (_h)^4; \ + blitter.sstart = (word)(_src); \ + blitter.dstart = ((word)(_x)<<8)+(_y); \ + blitter.solid = (_color); \ + blitter.flags = (_flags); \ + } while (0) + +#define BLIT_SOLID(x, y, w, h, color) \ + BLIT_OP(x, y, w, h, 0, color, DSTSCREEN|SOLID) + + +// x1: 0-151 +// y1: 0-255 +void blit_solid(byte x1, byte y1, byte w, byte h, byte color); + +void blit_copy(byte x1, byte y1, byte w, byte h, const byte* data); + +void blit_copy_solid(byte x1, byte y1, byte w, byte h, const byte* data, byte solid); + +void draw_sprite(const byte* data, byte x, byte y); + +void draw_sprite_solid(const byte* data, byte x, byte y, byte color); + +void erase_sprite_rect(const byte* data, byte x, byte y); + +void draw_sprite_strided(const byte* data, byte x, byte y, byte stride); + +// x1: 0-303 +// y1: 0-255 +void blit_pixel(word xx, byte y, byte color); + +#endif diff --git a/src/platform/williams.ts b/src/platform/williams.ts index f678bc72..7c2275ca 100644 --- a/src/platform/williams.ts +++ b/src/platform/williams.ts @@ -98,7 +98,7 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { var iowrite_defender = newAddressDecoder([ [0x0, 0xf, 0xf, setPalette], - [0x3fc, 0x3ff, 0, function(a, v) { if (v == 0x38) watchdog_counter = INITIAL_WATCHDOG; }], + [0x3fc, 0x3ff, 0, function(a, v) { if (v == 0x38) watchdog_counter = INITIAL_WATCHDOG; watchdog_enabled=true; }], [0x400, 0x5ff, 0x1ff, function(a, v) { nvram.mem[a] = v; }], [0xc02, 0xc02, 0x1, function(a, v) { if (worker) worker.postMessage({ command: v & 0x3f }); }], [0xc00, 0xc07, 0x7, function(a, v) { pia6821[a] = v; }], @@ -145,7 +145,7 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { //[0x80c, 0x80f, 0x3, function(a,v) { console.log('iowrite',a+4); }], // TODO: sound [0x900, 0x9ff, 0, function(a, v) { banksel = v & 0x1; }], [0xa00, 0xa07, 0x7, setBlitter], - [0xbff, 0xbff, 0, function(a, v) { if (v == 0x39) watchdog_counter = INITIAL_WATCHDOG; }], + [0xbff, 0xbff, 0, function(a, v) { if (v == 0x39) { watchdog_counter = INITIAL_WATCHDOG; watchdog_enabled=true; } }], [0xc00, 0xfff, 0x3ff, function(a, v) { nvram.mem[a] = v; }], //[0x0, 0xfff, 0, function(a,v) { console.log('iowrite',hex(a),hex(v)); }], ]); @@ -418,6 +418,7 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { this.reset = function() { cpu.reset(); watchdog_counter = INITIAL_WATCHDOG; + watchdog_enabled = false; banksel = 1; } this.scaleCPUFrequency = function(scale) { diff --git a/src/worker/lib/williams/assert.h b/src/worker/lib/williams/assert.h new file mode 100644 index 00000000..45d9fba0 --- /dev/null +++ b/src/worker/lib/williams/assert.h @@ -0,0 +1,20 @@ +/* assert.h - Assert macro for CMOC + + By Pierre Sarrazin . + This file is in the public domain. +*/ + +#ifndef _ASSERT_H +#define _ASSERT_H + +#include "cmoc.h" + +#ifdef NDEBUG +#define assert(cond) +#else +#define assert(cond) do { if (!(cond)) { \ + printf("***ASSERT FAILED: %s:%u: %s\n", __FILE__, __LINE__, #cond); \ + for (;;); } } while (0) +#endif + +#endif /* _ASSERT_H */ diff --git a/src/worker/lib/williams/cmoc.h b/src/worker/lib/williams/cmoc.h new file mode 100644 index 00000000..090f69ef --- /dev/null +++ b/src/worker/lib/williams/cmoc.h @@ -0,0 +1,345 @@ +// cmoc.h - CMOC's standard library functions. +// +// By Pierre Sarrazin . +// This file is in the public domain. +// +// Functions not documented here should be assumed to behave as in C. + +#ifndef _H_CMOC +#define _H_CMOC + +#ifndef __GNUC__ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + + +#ifndef _CMOC_CONST_ +#define _CMOC_CONST_ const +#endif + + +// Gives the offset in bytes of the specified 'member' in the struct +// or union named 'Type'. +// +#define offsetof(Type, member) ((unsigned) &((Type *) 0)->member) + +typedef unsigned size_t; + + +#ifndef VECTREX +// Supports %u, %d, %x, %X, %p, %s, %c and %%. Specifying a field width is +// allowed, but a left justification is only supported for strings, i.e., +// %-15s will work, but %-6u will not. Zero padding for a number is supported +// (e.g., %04x). +// +int printf(_CMOC_CONST_ char *format, ...); +#endif + + +// Writes to 'dest'. Not thread-safe. Does not check for buffer overflow. +int sprintf(char *dest, _CMOC_CONST_ char *format, ...); + + +#ifndef VECTREX +// Writes the first 'n' characters designated by 's', regardless of any +// null characters encountered among them. +// +void putstr(_CMOC_CONST_ char *s, size_t n); + +void putchar(int c); +#endif + +int strcmp(_CMOC_CONST_ char *s1, _CMOC_CONST_ char *s2); +int stricmp(_CMOC_CONST_ char *s1, _CMOC_CONST_ char *s2); +int memcmp(_CMOC_CONST_ void *s1, _CMOC_CONST_ void *s2, size_t n); +int memicmp(_CMOC_CONST_ void *s1, _CMOC_CONST_ void *s2, size_t n); +void *memcpy(void *dest, _CMOC_CONST_ void *src, size_t n); +void *memset(void *s, int c, size_t n); +size_t strlen(_CMOC_CONST_ char *s); +char *strcpy(char *dest, _CMOC_CONST_ char *src); +char *strcat(char *dest, _CMOC_CONST_ char *src); +char *strncpy(char *dest, _CMOC_CONST_ char *src, size_t n); +char *strchr(_CMOC_CONST_ char *s, int c); +char *strstr(const char *haystack, const char *needle); +char *strlwr(char *s); +char *strupr(char *s); + + +// Converts an ASCII unsigned decimal string into an unsigned word. +// +unsigned atoui(_CMOC_CONST_ char *s); + + +// Converts an ASCII signed decimal string into a signed word. +// +int atoi(_CMOC_CONST_ char *s); + + +// Converts an integer to a NUL-terminated ASCII signed decimal string. +// Returns 'str'. +// The caller must be careful to pass an array of sufficient size, +// including room for the terminating '\0'. +// +char *itoa10(int value, char *str); + + +// Converts an integer to a NUL-terminated ASCII signed decimal string. +// N.B.: 'base' must be 10. No other base is supported by this implementation. +// Returns 'str'. +// The caller must be careful to pass an array of sufficient size, +// including room for the terminating '\0'. +// +#define itoa(value, str, base) (itoa10((value), (str))) + + +// Like itoa10(), but 'value' can be in the range 32768..65535. +// +char *utoa10(unsigned value, char *str); + + +// Like itoa(), but 'value' can be in the range 32768..65535. +// N.B.: 'base' must be 10. No other base is supported by this implementation. +// +#define utoa(value, str, base) (utoa10((value), (str))) + + +// Like itoa10(), but 'value' can be 32 bits. +// +char *ltoa10(long value, char *str); + + +// Like itoa(), but 'value' can be 32 bits. +// N.B.: 'base' must be 10. No other base is supported by this implementation. +// +#define ltoa(value, str, base) (ltoa10((value), (str))) + + +// Like utoa10(), but 'value' can be 32 bits. +// +char *ultoa10(unsigned long value, char *str); + + +// Like utoa(), but 'value' can be 32 bits. +// N.B.: 'base' must be 10. No other base is supported by this implementation. +// +#define ultoa(value, str, base) (ultoa10((value), (str))) + + +// Double-word to ASCII. +// Converts the unsigned 32-bit integer formed by hi * 65536 + lo into +// an ASCII decimal representation that gets written to 'out'. +// 'out' must point to at least 11 bytes. The string written there will +// be terminated by a null character. +// Returns the address of the first non-'0' character in the 11-byte +// buffer, or to "0" if hi and lo are both zero. +// Example: char s[11]; char *p = dwtoa(s, 1, 2); +// s will get the string " +// NOTE: This operation can also be done with the 'long' type and by +// calling sprintf() with the "%lu" or "%ld" placeholders. +// +char *dwtoa(char *out, unsigned hi, unsigned lo); + + +// Returns the integer part of the square root of n. +// +unsigned char sqrt16(unsigned n); + + +// Returns the quotient and remainder of a 16-bit unsigned division +// in a single operation. +// +void divmod16(unsigned dividend, unsigned divisor, + unsigned *quotient, unsigned *remainder); + + +// Returns the quotient and remainder of an 8-bit unsigned division +// in a single operation. +// +void divmod8(unsigned char dividend, unsigned char divisor, + unsigned char *quotient, unsigned char *remainder); + + +// Divides an unsigned 32-bit integer by an unsigned 8-bit integer. +// The two words designated by 'dividendInQuotientOut' are the input dividend. +// The 32-bit quotient is left in those two words. +// +void divdwb(unsigned dividendInQuotientOut[2], unsigned char divisor); + + +// Previous name of divdwb(). +// +#define div328 divdwb + + +// Divides an unsigned 32-bit integer by an unsigned 16-bit integer. +// The two words designated by 'dividendInQuotientOut' are the input dividend. +// The 32-bit quotient is left in those two words. +// +void divdww(unsigned dividendInQuotientOut[2], unsigned divisor); + + +// Multiply a word by a byte. +// Stores the high word of the product in *hi and returns the low word. +// +unsigned mulwb(unsigned char *hi, unsigned wordFactor, unsigned char byteFactor); + + +// Similar to mulwb(). +unsigned mulww(unsigned *hi, unsigned factor0, unsigned factor1); + + +// Stores 0 in twoWords[0], twoWords[1]. +// +void zerodw(unsigned *twoWords); + + +// Adds the 16-bit integer 'term' to the 32-bit integer designated by +// twoWords[0] and twoWords[1]. +// +void adddww(unsigned *twoWords, unsigned term); + + +// Subtracts the 16-bit integer 'term' from the 32-bit integer designated by +// twoWords[0] and twoWords[1]. +// +void subdww(unsigned *twoWords, unsigned term); + + +// Returns 0 if the 32-bit unsigned word composed of left[0] and left[1] +// (where left[0] is the high word) is equal to 'right'; +// returns +1 if left > right; -1 if left < right. +// +char cmpdww(unsigned left[2], unsigned right); + + +#ifdef _COCO_BASIC_ + +// Converts an ASCII decimal floating point number to a float. +// The string is allowed to contain a suffix (e.g., "1.2E6XYZ"); +// endptr: Receives the address where the parsing stopped. +// Caution: Passing a string whose value does not fit in a float +// may have undefined behavior. +// An 'E' used in exponential notation must be in upper-case. +// +float strtof(_CMOC_CONST_ char *nptr, char **endptr); + + +// Like strtof(), but does not return the end pointer. +// +float atoff(_CMOC_CONST_ char *nptr); + + +// Writes an ASCII decimal representation of 'f' in the buffer +// at 'out' which must contain at least 38 bytes. +// Returns 'out' upon success, or null upon failure. +// +char *ftoa(char out[38], float f); + +#endif /* _COCO_BASIC_ */ + + +// CAUTION: base is ignored, only base 10 is supported. +// +unsigned long strtoul(_CMOC_CONST_ char *nptr, char **endptr, int base); + +unsigned long atoul(_CMOC_CONST_ char *nptr); + +// CAUTION: base is ignored, only base 10 is supported. +// +long strtol(_CMOC_CONST_ char *nptr, char **endptr, int base); + +long atol(_CMOC_CONST_ char *nptr); + +int tolower(int c); +int toupper(int c); +void exit(int status); + +#define RAND_MAX 0x7FFF +void srand(unsigned seed); +int rand(); + +// See the CMOC manual. +void *sbrk(size_t increment); +size_t sbrkmax(); +void set_null_ptr_handler(void (*newHandler)(void *)); +void set_stack_overflow_handler(void (*newHandler)(void *, void *)); + + +// Function pointer type used by setConsoleOutHook(). +// +typedef void (*ConsoleOutHook)(); + + +// Redirect printf() et al. to the function at 'routine', which will +// receive each character to be printed in register A. +// +// That routine MUST preserve registers B, X, Y and U. +// +// If this function is never called, printf() et al. write to the +// system's standard character output routine. +// +// Returns the original output routine address. +// To uninstall the new routine, call this function again with +// the original routine address. +// +ConsoleOutHook setConsoleOutHook(ConsoleOutHook routine); + + +#ifndef VECTREX + +// Blocks the execution for the specified time in 60ths of a second. +// +void delay(size_t sixtiethsOfASecond); + + +// Reads a line from standard input, converts an expected 16-bit decimal +// number and returns it. Not thread-safe. +// +unsigned readword(); + + +// Reads a line from standard input and returns it. +// Not thread-safe. +// Returns a null pointer if the operation failed (e.g., end of file +// encountered). +// +char *readline(); + +#endif /* ndef VECTREX */ + + +// Sorts an array that starts at 'base', that has 'nmemb' elements, whose +// elements are 'size' bytes each. +// compar: Pointer to a function that receives pointers to two array elements +// and that returns -1, 0 or +1 depending on whether the first element +// comes before, is equal to, or comes after the second element. +// This function is recursive and will thus use stack space. +// +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(_CMOC_CONST_ void *, _CMOC_CONST_ void *)); + + +// Searches for the value pointed to by 'key' in the array starting at 'base', +// that has 'nmemb' elements, whose elements are 'size' bytes each. +// compar: Pointer to a function that receives pointers to the targeted key and +// to an array element. It must return -1, 0 or +1 depending on whether +// the targeted key comes before, is equal to, or comes after the second element. +// Returns a pointer to the element of the array that matches the targeted key, +// or NULL if none is found. +// The time taken by this function is proportional to the logarithm of the array size. +// This function is recursive and will thus use stack space. +// +void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(_CMOC_CONST_ void *key, _CMOC_CONST_ void *element)); + + +#else + +#include +#include +#include + +#endif /* __GNUC__ */ + +#endif /* _H_CMOC */ diff --git a/src/worker/lib/williams/stdarg.h b/src/worker/lib/williams/stdarg.h new file mode 100644 index 00000000..e3d0b345 --- /dev/null +++ b/src/worker/lib/williams/stdarg.h @@ -0,0 +1,22 @@ +/* stdarg.h - Support for variable argument functions + + By Pierre Sarrazin . + This file is in the public domain. +*/ + +#ifndef _stdarg_h_ +#define _stdarg_h_ + + +typedef char *va_list; + + +char *__va_arg(va_list *app, unsigned int sizeInBytes); + + +#define va_start(ap, lastFixed) do { (ap) = (char *) &(lastFixed) + sizeof(lastFixed); } while (0) +#define va_arg(ap, type) (* (type *) __va_arg(&(ap), sizeof(type))) +#define va_end(ap) do {} while (0) + + +#endif /* _stdarg_h_ */ diff --git a/src/worker/lib/williams/stdlib.h b/src/worker/lib/williams/stdlib.h new file mode 100644 index 00000000..3da92a0e --- /dev/null +++ b/src/worker/lib/williams/stdlib.h @@ -0,0 +1,13 @@ +#ifndef __vectrex_stdlib_h__ +#define __vectrex_stdlib_h__ + +/** + * Most stdlib functions are supported on the Vectrex, except those that imply having a keyboard and console: + * printf, putsr, putchar, readword, readline. + * Also delay is not implemented as it does not seem to make much sense to have a delay function on the Vectrex. + */ + +//#include "vectrex.h" +#include "cmoc.h" + +#endif // __vectrex_stdlib_h__ diff --git a/src/worker/tools/m6809.ts b/src/worker/tools/m6809.ts index 538fa8c4..2ea6ddbc 100644 --- a/src/worker/tools/m6809.ts +++ b/src/worker/tools/m6809.ts @@ -116,6 +116,9 @@ export function compileCMOC(step: BuildStep): BuildStepResult { if (errors.length) return { errors: errors }; var asmout = FS.readFile(destpath, { encoding: 'utf8' }); + if (step.params.set_stack_end) + asmout = asmout.replace('stack space in bytes', `\n lds #${step.params.set_stack_end}\n`) + console.log(asmout); putWorkFile(destpath, asmout); } return { @@ -240,6 +243,8 @@ export function linkLWLINK(step: BuildStep): BuildStepResult { // * Line //threed.c:117: init of variable e var srclines = parseSourceLines(lstout, /Line .+?:(\d+)/i, /^([0-9A-F]{4})/i); putWorkFile(fn, lstout); + // strip out left margin + lstout = lstout.split('\n').map(l => l.substring(0,15) + l.substring(56)).join('\n') // TODO: you have to get rid of all source lines to get asm listing listings[fn] = { asmlines: srclines.length ? asmlines : null, diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index 3c2d07ac..fc5347f4 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -127,9 +127,11 @@ var PLATFORM_PARAMS = { data_start: 0x9800, data_size: 0x2800, stack_end: 0xc000, + set_stack_end: 0xc000, extra_link_files: ['williams.scr', 'libcmoc-crt-vec.a', 'libcmoc-std-vec.a'], extra_link_args: ['-swilliams.scr', '-lcmoc-crt-vec', '-lcmoc-std-vec'], - extra_compile_files: ['assert.h','cmoc.h','stdarg.h','vectrex.h','stdlib.h','bios.h'], + extra_compile_files: ['assert.h','cmoc.h','stdarg.h','stdlib.h'], + //extra_compile_args: ['--vectrex'], }, 'williams-defender': { arch: '6809', From 7b9f635bc049e465201b0642ab87183a6ff70610 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Sat, 19 Feb 2022 17:27:26 -0600 Subject: [PATCH 2/9] editor: set focus when switching between files --- src/ide/views/editors.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ide/views/editors.ts b/src/ide/views/editors.ts index d5a81d28..949353d5 100644 --- a/src/ide/views/editors.ts +++ b/src/ide/views/editors.ts @@ -76,6 +76,12 @@ export class SourceEditor implements ProjectView { return div; } + setVisible(showing: boolean): void { + if (showing) { + this.editor.focus(); // so that keyboard works when moving between files + } + } + newEditor(parent:HTMLElement, isAsmOverride?:boolean) { var modedef = MODEDEFS[this.mode] || MODEDEFS.default; var isAsm = isAsmOverride || modedef.isAsm; @@ -599,5 +605,5 @@ export class ListingView extends DisassemblerView implements ProjectView { } } } -} +} From 69a57799754aadf16fde3a5354e730e08208c0d2 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 09:30:12 -0600 Subject: [PATCH 3/9] github: gh-pages build --- .github/workflows/node.js.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 52c2d8c7..c6e8d9bf 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -29,7 +29,12 @@ jobs: - run: git submodule init - run: git submodule update - run: npm ci - - run: npm run build --if-present + - run: make distro - run: npm test env: TEST8BIT_GITHUB_TOKEN: ${{ secrets.TEST8BIT_GITHUB_TOKEN }} + - name: Deploy + uses: JamesIves/github-pages-deploy-action@v4.2.5 + with: + branch: gh-pages + folder: tmp/dist From 3a960c3e6e08a5b2a4391be409b1ef53282a0591 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 09:33:59 -0600 Subject: [PATCH 4/9] github: fix for build --- .github/workflows/node.js.yml | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index c6e8d9bf..385b2fa8 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -29,10 +29,11 @@ jobs: - run: git submodule init - run: git submodule update - run: npm ci - - run: make distro + - run: npm run build --if-present - run: npm test env: TEST8BIT_GITHUB_TOKEN: ${{ secrets.TEST8BIT_GITHUB_TOKEN }} + - run: make distro - name: Deploy uses: JamesIves/github-pages-deploy-action@v4.2.5 with: diff --git a/README.md b/README.md index 86389797..bbc49d93 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 8bitworkshop -![example workflow](https://github.com/sehugg/8bitworkshop/actions/workflows/node.js.yml/badge.svg) +![Build Status](https://github.com/sehugg/8bitworkshop/actions/workflows/node.js.yml/badge.svg) ## Use Online From 1d3b8ab99c3c68a2b0b11b2f0adff20389dcf9f4 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 09:39:49 -0600 Subject: [PATCH 5/9] github: load config.js from 8bitworkshop.com --- src/ide/ui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ide/ui.ts b/src/ide/ui.ts index 518b96f3..289c49b1 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -642,7 +642,7 @@ async function getGithubService() { // load firebase await loadScript('https://www.gstatic.com/firebasejs/8.8.1/firebase-app.js'); await loadScript('https://www.gstatic.com/firebasejs/8.8.1/firebase-auth.js'); - await loadScript('./config.js'); + await loadScript('https://8bitworkshop.com/config.js'); // get github API key from cookie // TODO: move to service? var ghkey = getCookie('__github_key'); From d7626be789bc458091e8d9aedef58acb55d9541c Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 10:43:58 -0600 Subject: [PATCH 6/9] updated README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bbc49d93..4a36e107 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Use Online * Latest release: https://8bitworkshop.com/ -* Dev build: https://8bitworkshop.com/dev/ +* Latest Github build: https://sehugg.github.io/8bitworkshop/ ## Install Locally @@ -33,11 +33,11 @@ make tsweb npm test ``` -Note: Github tests may fail due to lack of permissions. +Note: Github tests may fail due to lack of API key. ## License -Copyright © 2016-2021 [Steven Hugg](https://github.com/sehugg). +Copyright © 2016-2022 [Steven Hugg](https://github.com/sehugg). This project is [GPL-3.0](https://github.com/sehugg/8bitworkshop/blob/master/LICENSE) licensed. From 0682af1eed8d1a681af17cbe9fbebd23c6bdbcc4 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 16:54:33 -0600 Subject: [PATCH 7/9] fixed atari-vector 6502, pass options=... to platform constructor --- src/common/baseplatform.ts | 3 ++- src/common/cpu/MOS6502.ts | 2 +- src/ide/ui.ts | 5 ++++- src/platform/vector.ts | 2 +- src/platform/williams.ts | 6 +++++- src/worker/lib/vector-ataricolor/crt0.o | Bin 977 -> 983 bytes src/worker/lib/vector-ataricolor/crt0.s | 3 +-- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/common/baseplatform.ts b/src/common/baseplatform.ts index e7af32e6..9c8190d7 100644 --- a/src/common/baseplatform.ts +++ b/src/common/baseplatform.ts @@ -13,6 +13,7 @@ import { SampledAudio } from "./audio"; import { ProbeRecorder } from "./recorder"; import { BaseWASMMachine } from "./wasmplatform"; import { CPU6809 } from "./cpu/6809"; +import { _MOS6502 } from "./cpu/MOS6502"; /// @@ -448,7 +449,7 @@ export abstract class Base6502Platform extends BaseDebugPlatform { abstract readAddress(addr:number) : number; newCPU(membus : MemoryBus) { - var cpu = new jt.M6502(); + var cpu = new _MOS6502(); cpu.connectBus(membus); return cpu; } diff --git a/src/common/cpu/MOS6502.ts b/src/common/cpu/MOS6502.ts index 33362d8e..2f516999 100644 --- a/src/common/cpu/MOS6502.ts +++ b/src/common/cpu/MOS6502.ts @@ -3,7 +3,7 @@ import { CPU, Bus, ClockBased, SavesState, Interruptable } from "../devices"; // Copyright 2015 by Paulo Augusto Peccin. See license.txt distributed with this file. -var _MOS6502 = function() { +export var _MOS6502 = function() { var self = this; this.powerOn = function() { diff --git a/src/ide/ui.ts b/src/ide/ui.ts index 289c49b1..4551dfe9 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -30,6 +30,7 @@ declare var $ : JQueryStatic; // use browser jquery interface UIQueryString { platform? : string; + options?: string; repo? : string; file? : string; electron? : string; @@ -2213,7 +2214,9 @@ function installGAHooks() { async function startPlatform() { if (!PLATFORMS[platform_id]) throw Error("Invalid platform '" + platform_id + "'."); - platform = new PLATFORMS[platform_id]($("#emuscreen")[0]); + let emudiv = $("#emuscreen")[0]; + let options = decodeQueryString(qs.options || ''); + platform = new PLATFORMS[platform_id](emudiv, options); setPlatformUI(); stateRecorder = new StateRecorderImpl(platform); PRESETS = platform.getPresets ? platform.getPresets() : []; diff --git a/src/platform/vector.ts b/src/platform/vector.ts index ba2c5ed0..2df13cc2 100644 --- a/src/platform/vector.ts +++ b/src/platform/vector.ts @@ -270,7 +270,7 @@ var AtariColorVectorPlatform = function(mainElement) { clock++; if (--nmicount == 0) { //console.log("NMI", cpu.saveState()); - var n = cpu.setIRQAndWait(); // TODO: only if I flag set + var n = cpu.setIRQ(); // TODO: only if I flag set clock += n; nmicount = cpuCyclesPerNMI - n; //console.log(n, clock, nmicount); diff --git a/src/platform/williams.ts b/src/platform/williams.ts index 7c2275ca..777e9cb1 100644 --- a/src/platform/williams.ts +++ b/src/platform/williams.ts @@ -432,6 +432,10 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { ] } }; } +var Williams6809Platform = function(mainElement) { + this.__proto__ = new WilliamsPlatform(mainElement, null, false); +} + var WilliamsZ80Platform = function(mainElement) { this.__proto__ = new WilliamsPlatform(mainElement, BaseZ80Platform, false); @@ -462,7 +466,7 @@ var WilliamsDefenderPlatform = function(mainElement) { ] } }; } -PLATFORMS['williams'] = WilliamsPlatform; +PLATFORMS['williams'] = Williams6809Platform; PLATFORMS['williams-defender'] = WilliamsDefenderPlatform; PLATFORMS['williams-z80'] = WilliamsZ80Platform; diff --git a/src/worker/lib/vector-ataricolor/crt0.o b/src/worker/lib/vector-ataricolor/crt0.o index 26a68713544253bc9a63d64fbf8a6bc73055083e..a904d8000fbc9b4d4fed074c7707b0478438e438 100644 GIT binary patch delta 636 zcmYL_O=}ZT6o$`xW-?!Clcr6a#E@jtru75u_|>8dp~X!Fk)l;xHKbu6LZy-h)P=-O zskn^H&W+HWR2S}C`4=<=KQ@9Z|A0S0&xr-$^1SbR@44q(?$G{b4;sx&MD!j+RnbqP zEP5z&Ygy+VHDg){d1-QoH$HW9Kk~?lPL~{E)k%KBZ%m7&Q@WAUZ+F$@6=_G}?*o2_oxZZ9r`a{EfS M-D!2BWXkyX7x5rbR{#J2 delta 626 zcmYL_&1(};6vfZEna`I@)tIJ9$Hp0x)-P;Ss0(q?ofX|GF5Hw5n}Vg%R&WvTds)M zGMBo-qt4ET^js0pvtrE^A#320uA(t_h0h!ua0a}?sw+yYLJq+b;3B7T0A~?UN{*vo zJJZO(jRH3R=QA-U=p=(wcubOpl>dpN&XSn*X{Hjf&RjyJCjleY#8Wh zDYF+0O`D%uQJ)CNtTt_E>p{cZX~RXsIRw3pt;_S9uD5(`A-i{V{>s95M{f9D|LN-1 h_`Bqjm%4-XwSIT-WM!q>TVH#;`l!FLIc}Cd{{a)IMeG0o diff --git a/src/worker/lib/vector-ataricolor/crt0.s b/src/worker/lib/vector-ataricolor/crt0.s index 9dc585df..6ebaa318 100644 --- a/src/worker/lib/vector-ataricolor/crt0.s +++ b/src/worker/lib/vector-ataricolor/crt0.s @@ -8,7 +8,6 @@ .export __STARTUP__ : absolute = 1 ; Mark as startup .import zerobss, callmain .import initlib, donelib, copydata - .import exit .import __PRGRAM_START__, __PRGRAM_SIZE__ ; Linker generated ; .import __STACKSIZE__ ; Linker generated @@ -30,7 +29,7 @@ start: _exit: pha jsr donelib pla - jmp exit + jmp start nmi: inc $0 From 8c63bef8c9732072bef9b30cb2f94a1e1ab5e036 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Mon, 21 Feb 2022 21:23:10 -0600 Subject: [PATCH 8/9] williams: options=rotate%3D --- src/platform/williams.ts | 18 ++++++++++-------- src/worker/tools/m6809.ts | 2 -- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/platform/williams.ts b/src/platform/williams.ts index 777e9cb1..54de92ab 100644 --- a/src/platform/williams.ts +++ b/src/platform/williams.ts @@ -11,10 +11,11 @@ var WILLIAMS_PRESETS = [ { id: 'bitmap_rle.c', name: 'RLE Bitmap' }, ]; -var WilliamsPlatform = function(mainElement, proto, isDefender) { +var WilliamsPlatform = function(mainElement, proto, options) { var self = this; this.__proto__ = new (proto ? proto : Base6809Platform)(); + var isDefender = options.isDefender; var SCREEN_HEIGHT = 304; var SCREEN_WIDTH = 256; @@ -302,7 +303,8 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { workerchannel = new WorkerSoundChannel(worker); audio.master.addChannel(workerchannel); - video = new RasterVideo(mainElement, SCREEN_WIDTH, SCREEN_HEIGHT, { rotate: -90 }); + let rotate = options.rotate == null ? -90 : parseFloat(options.rotate); + video = new RasterVideo(mainElement, SCREEN_WIDTH, SCREEN_HEIGHT, { rotate }); video.create(); $(video.canvas).click(function(e) { var x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width()); @@ -432,12 +434,12 @@ var WilliamsPlatform = function(mainElement, proto, isDefender) { ] } }; } -var Williams6809Platform = function(mainElement) { - this.__proto__ = new WilliamsPlatform(mainElement, null, false); +var Williams6809Platform = function(mainElement, options) { + this.__proto__ = new WilliamsPlatform(mainElement, null, options); } -var WilliamsZ80Platform = function(mainElement) { - this.__proto__ = new WilliamsPlatform(mainElement, BaseZ80Platform, false); +var WilliamsZ80Platform = function(mainElement, options) { + this.__proto__ = new WilliamsPlatform(mainElement, BaseZ80Platform, options); // Z80 @ 4 MHz // also scale bitblt clocks @@ -456,8 +458,8 @@ var WilliamsZ80Platform = function(mainElement) { } } -var WilliamsDefenderPlatform = function(mainElement) { - this.__proto__ = new WilliamsPlatform(mainElement, null, true); +var WilliamsDefenderPlatform = function(mainElement, options) { + this.__proto__ = new WilliamsPlatform(mainElement, null, {isDefender:true}); this.getMemoryMap = function() { return { main:[ {name:'NVRAM',start:0x400,size:0x200,type:'ram'}, {name:'Video RAM',start:0x0000,size:0xc000,type:'ram'}, diff --git a/src/worker/tools/m6809.ts b/src/worker/tools/m6809.ts index 2ea6ddbc..ead8f41c 100644 --- a/src/worker/tools/m6809.ts +++ b/src/worker/tools/m6809.ts @@ -41,7 +41,6 @@ export function assembleXASM6809(step: BuildStep): BuildStepResult { return { errors: errors }; var aout = FS.readFile(binpath, { encoding: 'binary' }); if (aout.length == 0) { - console.log(alst); errors.push({ line: 0, msg: "Empty output file" }); return { errors: errors }; } @@ -118,7 +117,6 @@ export function compileCMOC(step: BuildStep): BuildStepResult { var asmout = FS.readFile(destpath, { encoding: 'utf8' }); if (step.params.set_stack_end) asmout = asmout.replace('stack space in bytes', `\n lds #${step.params.set_stack_end}\n`) - console.log(asmout); putWorkFile(destpath, asmout); } return { From b9fc1628853486a9fd037fa392d42eb01375ddb7 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Tue, 22 Feb 2022 09:40:05 -0600 Subject: [PATCH 9/9] cmoc: better listing parser, williams: updated presets --- presets/williams/bitmap_rle.c | 137 +++++++ presets/williams/font.c | 118 ++++++ presets/williams/font.h | 4 + presets/williams/fonttest.c | 30 ++ presets/williams/game1.c | 653 ++++++++++++++++++++++++++++++++++ presets/williams/gfxtest.c | 8 +- presets/williams/sprites.c | 334 +++++++++++++++++ presets/williams/williams.c | 102 +++++- presets/williams/williams.h | 27 +- src/common/workertypes.ts | 2 + src/worker/tools/m6809.ts | 18 +- src/worker/workermain.ts | 40 ++- test/cli/testworker.js | 5 + 13 files changed, 1441 insertions(+), 37 deletions(-) create mode 100644 presets/williams/bitmap_rle.c create mode 100644 presets/williams/font.c create mode 100644 presets/williams/font.h create mode 100644 presets/williams/fonttest.c create mode 100644 presets/williams/game1.c create mode 100644 presets/williams/sprites.c diff --git a/presets/williams/bitmap_rle.c b/presets/williams/bitmap_rle.c new file mode 100644 index 00000000..50382669 --- /dev/null +++ b/presets/williams/bitmap_rle.c @@ -0,0 +1,137 @@ + +#include "williams.h" + +word swapw(word a) { + return (a >> 8) | (a << 8); +} + +const byte example_tga[] = { +0x00,0x01,0x09,0x00,0x00,0x08,0x00,0x18,0x00,0x00,0x00,0x00,0xc0,0x00,0x8b,0x00,0x08,0x00,0x00,0x00,0x00,0x32,0x29,0x2e,0x66,0x3b,0x4d,0x9f,0x42,0x57,0xc5,0x54,0xbe,0xe6,0xe4,0xe3,0xbe,0xab,0xb4,0xc1,0x9c,0x67,0xff,0x00,0xbf,0x00,0xff,0x00,0xbf,0x00,0xfc,0x00,0x01,0x04,0x04,0xc0,0x00,0xfb,0x00,0x82,0x04,0xc0,0x00,0xfb,0x00,0x82,0x04,0xc0,0x00,0xfa,0x00,0x82,0x04,0xc1,0x00,0xfa,0x00,0x82,0x04,0xc1,0x00,0xf9,0x00,0x82,0x04,0xc2,0x00,0xf8,0x00,0x82,0x04,0xc3,0x00,0xf8,0x00,0x82,0x04,0xc3,0x00,0xcd,0x00,0x03,0x04,0x04,0x00,0x00,0x83,0x04,0xa2,0x00,0x01,0x04,0x04,0xc4,0x00,0xcc,0x00,0x89,0x04,0xa0,0x00,0x82,0x04,0xc4,0x00,0xcc,0x00,0x89, +0x04,0xa0,0x00,0x01,0x04,0x04,0xc5,0x00,0xcb,0x00,0x84,0x04,0x82,0x01,0x83,0x04,0x9e,0x00,0x82,0x04,0xc5,0x00,0xca,0x00,0x84,0x04,0x83,0x01,0x02,0x06,0x04,0x04,0x9f,0x00,0x01,0x04,0x04,0xc6,0x00,0xca,0x00,0x83,0x04,0x84,0x02,0x02,0x06,0x04,0x04,0x9e,0x00,0x82,0x04,0xc6,0x00,0xc9,0x00,0x83,0x04,0x02,0x02,0x02,0x03,0x82,0x04,0x01,0x06,0x04,0x9f,0x00,0x01,0x04,0x04,0xc7,0x00,0xc9,0x00,0x82,0x04,0x01,0x02,0x01,0x82,0x02,0x00,0x03,0x82,0x04,0x9a,0x00,0x01,0x04,0x04,0x82,0x00,0x01,0x04,0x04,0xc7,0x00,0xc8,0x00,0x83,0x04,0x04,0x01,0x02,0x02,0x03,0x03,0x82,0x04,0x99,0x00,0x83,0x04,0x03,0x00,0x00,0x04,0x04,0xc8,0x00,0xc8,0x00,0x82,0x04,0x01, +0x02,0x02,0x82,0x03,0x01,0x04,0x04,0x8d,0x00,0x00,0x04,0x8b,0x00,0x88,0x04,0xc8,0x00,0xc7,0x00,0x83,0x04,0x01,0x02,0x03,0x83,0x04,0x8d,0x00,0x82,0x04,0x8a,0x00,0x87,0x04,0xc9,0x00,0xc7,0x00,0x82,0x04,0x01,0x02,0x03,0x85,0x04,0x8b,0x00,0x83,0x04,0x89,0x00,0x83,0x04,0x00,0x03,0x83,0x04,0xc9,0x00,0xc6,0x00,0x82,0x04,0x01,0x03,0x02,0x8b,0x04,0x85,0x00,0x84,0x04,0x03,0x00,0x00,0x04,0x04,0x84,0x00,0x84,0x04,0x03,0x02,0x06,0x04,0x04,0x87,0x00,0x00,0x04,0xc1,0x00,0xa2,0x00,0x8d,0x05,0x82,0x04,0x8a,0x05,0x05,0x00,0x00,0x05,0x05,0x00,0x00,0x84,0x04,0x02,0x03,0x06,0x06,0x8b,0x04,0x02,0x05,0x05,0x06,0x8b,0x04,0x02,0x06,0x05,0x06,0x84,0x04,0x04, +0x02,0x03,0x05,0x04,0x04,0x83,0x00,0x01,0x05,0x05,0x82,0x04,0xa2,0x05,0x9e,0x00,0xa1,0x00,0x01,0x05,0x06,0xa5,0x04,0x00,0x06,0x8e,0x04,0x01,0x06,0x06,0x84,0x04,0x01,0x02,0x06,0x85,0x04,0x00,0x06,0x85,0x04,0x03,0x02,0x04,0x06,0x04,0x85,0x00,0x04,0x05,0x04,0x04,0x03,0x07,0x9b,0x06,0x00,0x07,0x83,0x06,0x01,0x05,0x05,0x9d,0x00,0xa2,0x00,0x00,0x06,0x95,0x04,0x00,0x03,0x83,0x04,0x04,0x03,0x04,0x04,0x03,0x03,0x8a,0x04,0x04,0x03,0x02,0x01,0x01,0x02,0x84,0x04,0x00,0x03,0x85,0x04,0x02,0x02,0x02,0x06,0x84,0x04,0x00,0x03,0x85,0x04,0x01,0x02,0x03,0x82,0x04,0x86,0x00,0x02,0x04,0x03,0x02,0x98,0x03,0x02,0x07,0x07,0x03,0x85,0x07,0x00,0x06,0x9e,0x00, +0xa3,0x00,0x02,0x04,0x04,0x03,0x83,0x02,0x03,0x03,0x02,0x03,0x04,0x82,0x02,0x83,0x04,0x00,0x03,0x8c,0x02,0x87,0x04,0x00,0x02,0x86,0x01,0x83,0x04,0x01,0x03,0x03,0x85,0x04,0x02,0x01,0x02,0x05,0x83,0x04,0x00,0x02,0x85,0x04,0x02,0x03,0x01,0x03,0x82,0x04,0x85,0x00,0x06,0x04,0x04,0x01,0x01,0x02,0x02,0x03,0x91,0x02,0x06,0x03,0x03,0x02,0x03,0x03,0x02,0x02,0x83,0x03,0x02,0x07,0x06,0x05,0x9e,0x00,0xa3,0x00,0x02,0x05,0x04,0x04,0x83,0x02,0x03,0x01,0x01,0x02,0x04,0x82,0x02,0x00,0x03,0x82,0x04,0x8c,0x02,0x00,0x03,0x85,0x04,0x00,0x03,0x85,0x01,0x03,0x02,0x02,0x03,0x05,0x82,0x04,0x00,0x02,0x85,0x04,0x01,0x02,0x01,0x85,0x04,0x00,0x02,0x85,0x04,0x01, +0x01,0x02,0x82,0x04,0x86,0x00,0x02,0x04,0x02,0x01,0x8b,0x02,0x01,0x03,0x03,0x87,0x02,0x03,0x03,0x03,0x02,0x03,0x84,0x02,0x03,0x03,0x03,0x06,0x05,0x9f,0x00,0xa4,0x00,0x02,0x04,0x04,0x02,0x82,0x01,0x82,0x02,0x04,0x03,0x04,0x02,0x02,0x03,0x82,0x04,0x8c,0x02,0x85,0x04,0x84,0x01,0x83,0x02,0x02,0x03,0x05,0x06,0x82,0x04,0x00,0x02,0x84,0x04,0x02,0x03,0x01,0x02,0x84,0x04,0x00,0x02,0x85,0x04,0x02,0x03,0x01,0x03,0x82,0x04,0x85,0x00,0x02,0x04,0x03,0x01,0x8c,0x02,0x01,0x03,0x03,0x86,0x02,0x01,0x03,0x07,0x82,0x03,0x84,0x02,0x02,0x03,0x07,0x06,0xa0,0x00,0xa4,0x00,0x04,0x05,0x04,0x04,0x02,0x01,0x84,0x02,0x07,0x04,0x03,0x02,0x02,0x03,0x04,0x04,0x03, +0x8b,0x02,0x83,0x04,0x00,0x02,0x83,0x01,0x85,0x02,0x84,0x04,0x01,0x01,0x02,0x84,0x04,0x01,0x02,0x01,0x85,0x04,0x00,0x03,0x85,0x04,0x01,0x02,0x02,0x83,0x04,0x85,0x00,0x02,0x04,0x01,0x01,0x84,0x02,0x00,0x03,0x88,0x02,0x00,0x03,0x85,0x02,0x00,0x03,0x87,0x02,0x03,0x03,0x03,0x06,0x05,0xa0,0x00,0xa5,0x00,0x02,0x04,0x04,0x03,0x84,0x02,0x05,0x01,0x03,0x04,0x02,0x02,0x03,0x82,0x04,0x8a,0x02,0x00,0x03,0x83,0x04,0x82,0x01,0x83,0x02,0x00,0x03,0x82,0x02,0x00,0x06,0x82,0x04,0x01,0x02,0x01,0x84,0x04,0x02,0x03,0x01,0x03,0x84,0x04,0x01,0x03,0x06,0x85,0x04,0x00,0x02,0x84,0x04,0x84,0x00,0x02,0x04,0x02,0x01,0x85,0x02,0x02,0x03,0x06,0x03,0x8d,0x02,0x03, +0x03,0x02,0x02,0x03,0x83,0x02,0x03,0x03,0x03,0x07,0x06,0xa1,0x00,0xa6,0x00,0x01,0x04,0x04,0x86,0x02,0x03,0x04,0x03,0x02,0x02,0x82,0x04,0x00,0x03,0x89,0x02,0x83,0x04,0x02,0x02,0x01,0x01,0x87,0x02,0x83,0x04,0x02,0x03,0x01,0x01,0x84,0x04,0x02,0x02,0x02,0x06,0x87,0x04,0x00,0x03,0x88,0x04,0x84,0x00,0x03,0x04,0x04,0x01,0x01,0x85,0x02,0x03,0x07,0x05,0x06,0x03,0x8b,0x02,0x03,0x03,0x02,0x02,0x03,0x84,0x02,0x03,0x03,0x07,0x06,0x05,0xa1,0x00,0xa6,0x00,0x02,0x05,0x04,0x03,0x85,0x02,0x04,0x03,0x04,0x02,0x02,0x03,0x82,0x04,0x89,0x02,0x83,0x04,0x89,0x02,0x83,0x04,0x03,0x03,0x01,0x01,0x02,0x84,0x04,0x00,0x02,0x88,0x04,0x01,0x02,0x02,0x85,0x04,0x02, +0x02,0x06,0x04,0x84,0x00,0x02,0x04,0x01,0x01,0x86,0x02,0x02,0x07,0x06,0x07,0x8c,0x02,0x03,0x03,0x02,0x02,0x07,0x84,0x02,0x02,0x03,0x06,0x05,0xa2,0x00,0xa7,0x00,0x04,0x04,0x04,0x03,0x06,0x03,0x83,0x02,0x00,0x04,0x82,0x02,0x82,0x04,0x00,0x03,0x87,0x02,0x00,0x03,0x82,0x04,0x01,0x03,0x01,0x87,0x02,0x84,0x04,0x03,0x01,0x01,0x02,0x02,0x87,0x04,0x00,0x02,0x84,0x04,0x03,0x03,0x01,0x01,0x03,0x82,0x04,0x04,0x03,0x02,0x01,0x06,0x04,0x83,0x00,0x02,0x04,0x02,0x01,0x87,0x02,0x82,0x03,0x8b,0x02,0x0b,0x03,0x02,0x02,0x03,0x02,0x02,0x01,0x02,0x02,0x03,0x07,0x06,0xa3,0x00,0xa7,0x00,0x03,0x05,0x04,0x04,0x03,0x84,0x02,0x07,0x03,0x04,0x02,0x02,0x03,0x04, +0x04,0x03,0x87,0x02,0x83,0x04,0x88,0x02,0x84,0x04,0x01,0x01,0x01,0x82,0x02,0x86,0x04,0x01,0x02,0x01,0x84,0x04,0x83,0x01,0x82,0x02,0x0b,0x01,0x01,0x02,0x06,0x04,0x04,0x00,0x00,0x04,0x03,0x01,0x01,0x88,0x02,0x01,0x03,0x03,0x87,0x02,0x07,0x03,0x02,0x02,0x03,0x03,0x02,0x02,0x03,0x83,0x02,0x03,0x03,0x03,0x06,0x05,0xa3,0x00,0xa8,0x00,0x02,0x06,0x04,0x03,0x85,0x02,0x03,0x04,0x03,0x02,0x03,0x82,0x04,0x00,0x03,0x86,0x02,0x83,0x04,0x87,0x02,0x84,0x04,0x01,0x01,0x01,0x84,0x02,0x84,0x04,0x00,0x02,0x82,0x01,0x82,0x04,0x03,0x01,0x01,0x02,0x02,0x85,0x01,0x00,0x02,0x82,0x04,0x04,0x00,0x04,0x04,0x01,0x01,0x96,0x02,0x03,0x03,0x02,0x02,0x03,0x84,0x02, +0x02,0x03,0x07,0x05,0xa4,0x00,0xa8,0x00,0x02,0x05,0x04,0x04,0x85,0x02,0x03,0x04,0x04,0x02,0x02,0x82,0x04,0x00,0x03,0x85,0x02,0x00,0x03,0x82,0x04,0x00,0x03,0x85,0x02,0x00,0x03,0x83,0x04,0x02,0x03,0x01,0x01,0x84,0x02,0x04,0x01,0x03,0x04,0x04,0x03,0x82,0x01,0x03,0x02,0x01,0x01,0x02,0x82,0x01,0x82,0x02,0x83,0x01,0x82,0x02,0x00,0x03,0x82,0x04,0x01,0x02,0x01,0x96,0x02,0x04,0x03,0x03,0x02,0x02,0x03,0x82,0x02,0x04,0x03,0x03,0x07,0x06,0x05,0xa4,0x00,0xa9,0x00,0x02,0x05,0x04,0x03,0x84,0x02,0x04,0x03,0x04,0x03,0x02,0x03,0x82,0x04,0x00,0x03,0x84,0x02,0x83,0x04,0x84,0x02,0x00,0x03,0x84,0x04,0x02,0x02,0x01,0x01,0x86,0x02,0x01,0x01,0x02,0x82,0x01, +0x83,0x02,0x82,0x01,0x8a,0x02,0x86,0x01,0x96,0x02,0x04,0x03,0x03,0x02,0x03,0x03,0x82,0x02,0x03,0x03,0x03,0x06,0x05,0xa5,0x00,0xaa,0x00,0x03,0x06,0x04,0x03,0x03,0x83,0x02,0x03,0x04,0x04,0x02,0x03,0x82,0x04,0x00,0x03,0x83,0x02,0x00,0x03,0x83,0x04,0x82,0x02,0x01,0x03,0x03,0x84,0x04,0x02,0x02,0x01,0x01,0x87,0x02,0x84,0x01,0x84,0x02,0x01,0x01,0x01,0x8b,0x02,0x84,0x01,0x01,0x02,0x02,0x83,0x03,0x88,0x02,0x00,0x03,0x87,0x02,0x03,0x03,0x02,0x03,0x03,0x82,0x02,0x04,0x03,0x03,0x07,0x05,0x05,0xa5,0x00,0xaa,0x00,0x03,0x05,0x04,0x04,0x03,0x83,0x02,0x03,0x03,0x04,0x03,0x02,0x83,0x04,0x00,0x03,0x82,0x02,0x00,0x03,0x83,0x04,0x01,0x02,0x03,0x85,0x04, +0x00,0x02,0x82,0x01,0x03,0x02,0x02,0x03,0x03,0x86,0x02,0x00,0x01,0x8f,0x02,0x01,0x03,0x03,0x84,0x02,0x00,0x01,0x82,0x02,0x03,0x03,0x06,0x03,0x03,0x91,0x02,0x0b,0x03,0x03,0x02,0x03,0x03,0x02,0x02,0x03,0x03,0x07,0x06,0x05,0xa6,0x00,0xab,0x00,0x02,0x05,0x04,0x03,0x83,0x02,0x00,0x03,0x86,0x04,0x03,0x03,0x03,0x02,0x03,0x8a,0x04,0x00,0x03,0x82,0x01,0x83,0x02,0x03,0x03,0x03,0x02,0x02,0x82,0x03,0x84,0x02,0x00,0x03,0x8c,0x02,0x00,0x03,0x82,0x02,0x07,0x03,0x03,0x07,0x03,0x02,0x02,0x03,0x02,0x82,0x03,0x90,0x02,0x06,0x03,0x03,0x02,0x02,0x03,0x02,0x02,0x82,0x03,0x01,0x07,0x05,0xa7,0x00,0xab,0x00,0x0a,0x05,0x04,0x04,0x03,0x02,0x03,0x03,0x02,0x03, +0x04,0x06,0x84,0x04,0x02,0x03,0x02,0x03,0x88,0x04,0x01,0x03,0x02,0x82,0x01,0x01,0x02,0x02,0x8f,0x03,0x08,0x02,0x03,0x02,0x02,0x03,0x02,0x03,0x03,0x02,0x87,0x03,0x04,0x02,0x02,0x03,0x03,0x02,0x82,0x03,0x02,0x02,0x03,0x03,0x8b,0x02,0x02,0x03,0x02,0x02,0x83,0x03,0x03,0x02,0x03,0x03,0x02,0x82,0x03,0x02,0x07,0x06,0x05,0xa7,0x00,0xac,0x00,0x0a,0x05,0x04,0x04,0x02,0x02,0x03,0x02,0x03,0x04,0x04,0x03,0x84,0x04,0x00,0x03,0x83,0x04,0x84,0x02,0x83,0x01,0x01,0x02,0x02,0x8f,0x03,0x00,0x02,0x98,0x03,0x02,0x02,0x03,0x02,0x82,0x03,0x83,0x02,0x01,0x03,0x03,0x86,0x02,0x89,0x03,0x02,0x07,0x06,0x05,0xa8,0x00,0xad,0x00,0x01,0x06,0x04,0x83,0x03,0x04,0x02, +0x03,0x04,0x03,0x03,0x83,0x04,0x00,0x03,0x83,0x04,0x00,0x02,0x85,0x01,0x01,0x02,0x02,0xa4,0x03,0x00,0x02,0x89,0x03,0x01,0x02,0x02,0x85,0x03,0x04,0x02,0x03,0x02,0x03,0x03,0x82,0x02,0x88,0x03,0x02,0x07,0x05,0x05,0xa8,0x00,0xad,0x00,0x02,0x05,0x04,0x04,0x84,0x03,0x02,0x04,0x04,0x03,0x88,0x04,0x86,0x02,0xc9,0x03,0x02,0x07,0x06,0x05,0xa9,0x00,0xad,0x00,0x03,0x05,0x05,0x04,0x04,0x83,0x03,0x02,0x04,0x04,0x03,0x87,0x04,0x01,0x02,0x02,0xc9,0x03,0x00,0x07,0x84,0x03,0x02,0x06,0x05,0x06,0xa9,0x00,0xae,0x00,0x00,0x05,0x84,0x04,0x00,0x03,0x87,0x04,0x09,0x03,0x04,0x03,0x02,0x03,0x04,0x04,0x03,0x03,0x04,0x9a,0x03,0x03,0x04,0x03,0x03,0x04,0x9f,0x03, +0x02,0x04,0x03,0x03,0x83,0x04,0x83,0x03,0x03,0x07,0x05,0x05,0x06,0xa9,0x00,0xad,0x00,0x8e,0x05,0x00,0x06,0x82,0x02,0x00,0x06,0x85,0x05,0x00,0x06,0x82,0x04,0x93,0x03,0x00,0x06,0x8d,0x05,0x02,0x06,0x04,0x04,0x8e,0x03,0x03,0x07,0x04,0x06,0x06,0x91,0x05,0xa8,0x00,0x8a,0x00,0xb2,0x05,0x02,0x06,0x02,0x07,0x89,0x05,0x82,0x04,0x8f,0x03,0x01,0x07,0x07,0x90,0x05,0x01,0x04,0x04,0x8a,0x03,0x01,0x07,0x06,0xbf,0x05,0x87,0x00,0x82,0x05,0x01,0x06,0x06,0x98,0x05,0x01,0x06,0x06,0x83,0x05,0x00,0x06,0x90,0x05,0x82,0x06,0x84,0x05,0x00,0x06,0x85,0x05,0x82,0x04,0x8d,0x03,0x04,0x07,0x05,0x05,0x06,0x06,0x8d,0x05,0x01,0x04,0x04,0x88,0x03,0x01,0x07,0x06,0x85, +0x05,0x83,0x06,0x02,0x05,0x06,0x06,0x8c,0x05,0x01,0x06,0x06,0x82,0x05,0x00,0x06,0x9e,0x05,0x02,0x06,0x06,0x05,0x85,0x00,0x82,0x05,0x00,0x06,0xa1,0x05,0x00,0x06,0x9c,0x05,0x00,0x06,0x82,0x05,0x82,0x04,0x8b,0x03,0x04,0x07,0x06,0x05,0x05,0x06,0x8e,0x05,0x01,0x04,0x04,0x86,0x03,0x01,0x07,0x07,0x83,0x05,0x01,0x06,0x06,0x96,0x05,0x00,0x06,0x82,0x05,0x00,0x06,0xa0,0x05,0x00,0x00,0x83,0x00,0x82,0x05,0x00,0x06,0x9d,0x05,0x00,0x06,0x84,0x05,0x00,0x06,0x9d,0x05,0x00,0x06,0x82,0x05,0x82,0x04,0x89,0x03,0x04,0x07,0x07,0x05,0x05,0x06,0x8f,0x05,0x01,0x04,0x04,0x85,0x03,0x01,0x07,0x07,0x82,0x05,0x01,0x06,0x06,0x97,0x05,0x00,0x06,0x83,0x05,0x00,0x06, +0x8e,0x05,0x03,0x06,0x05,0x05,0x06,0x82,0x05,0x00,0x06,0x87,0x05,0x02,0x06,0x05,0x00,0x82,0x00,0x82,0x05,0x00,0x06,0x9d,0x05,0x00,0x06,0x82,0x05,0x03,0x06,0x05,0x05,0x06,0x9e,0x05,0x03,0x06,0x06,0x05,0x05,0x82,0x04,0x88,0x03,0x00,0x07,0x82,0x05,0x00,0x06,0x8f,0x05,0x01,0x04,0x04,0x84,0x03,0x01,0x07,0x06,0x82,0x05,0x00,0x06,0x99,0x05,0x00,0x06,0x83,0x05,0x00,0x06,0x8b,0x05,0x00,0x06,0x82,0x05,0x03,0x06,0x05,0x05,0x06,0x89,0x05,0x03,0x06,0x06,0x05,0x00,0x82,0x00,0x02,0x05,0x05,0x06,0x9e,0x05,0x07,0x06,0x05,0x05,0x04,0x06,0x05,0x05,0x06,0x9f,0x05,0x00,0x06,0x82,0x05,0x01,0x04,0x04,0x87,0x03,0x04,0x07,0x07,0x05,0x05,0x06,0x90,0x05,0x01, +0x04,0x04,0x83,0x03,0x01,0x07,0x06,0x9d,0x05,0x00,0x06,0x84,0x05,0x00,0x06,0x8d,0x05,0x05,0x06,0x06,0x05,0x06,0x06,0x05,0x86,0x06,0x82,0x05,0x03,0x06,0x05,0x00,0x00,0x07,0x00,0x00,0x05,0x05,0x06,0x05,0x05,0x06,0x9b,0x05,0x08,0x06,0x05,0x05,0x04,0x04,0x06,0x05,0x05,0x06,0xa0,0x05,0x02,0x06,0x05,0x05,0x82,0x04,0x86,0x03,0x00,0x07,0x82,0x05,0x00,0x06,0x90,0x05,0x01,0x04,0x04,0x82,0x03,0x01,0x07,0x07,0x9d,0x05,0x01,0x06,0x06,0x84,0x05,0x00,0x06,0x89,0x05,0x02,0x06,0x05,0x05,0x8b,0x06,0x08,0x05,0x06,0x05,0x05,0x06,0x06,0x05,0x00,0x00,0x02,0x00,0x00,0x05,0x82,0x06,0x01,0x05,0x06,0x9b,0x05,0x04,0x06,0x05,0x05,0x04,0x04,0x82,0x05,0x00,0x06, +0xa1,0x05,0x04,0x06,0x05,0x05,0x04,0x04,0x85,0x03,0x04,0x07,0x07,0x05,0x05,0x06,0x91,0x05,0x05,0x04,0x04,0x03,0x03,0x07,0x07,0x9e,0x05,0x00,0x06,0x85,0x05,0x00,0x06,0x8a,0x05,0x02,0x06,0x06,0x05,0x8a,0x06,0x01,0x05,0x05,0x82,0x06,0x00,0x05,0x82,0x00,0x02,0x00,0x05,0x05,0x85,0x06,0x99,0x05,0x09,0x06,0x05,0x05,0x06,0x04,0x04,0x06,0x05,0x05,0x06,0xa1,0x05,0x02,0x06,0x05,0x05,0x82,0x04,0x84,0x03,0x04,0x07,0x05,0x05,0x06,0x06,0x91,0x05,0x04,0x04,0x04,0x03,0x07,0x07,0x82,0x05,0x00,0x06,0x9b,0x05,0x07,0x06,0x05,0x05,0x06,0x06,0x05,0x05,0x06,0x87,0x05,0x01,0x06,0x05,0x90,0x06,0x03,0x05,0x06,0x06,0x05,0x82,0x00,0x02,0x00,0x05,0x05,0x85,0x06, +0x01,0x05,0x06,0x97,0x05,0x02,0x06,0x05,0x05,0x82,0x04,0x03,0x07,0x05,0x05,0x06,0xa2,0x05,0x04,0x06,0x05,0x05,0x04,0x04,0x83,0x03,0x04,0x07,0x07,0x05,0x05,0x06,0x8f,0x05,0x0a,0x06,0x05,0x05,0x04,0x04,0x03,0x07,0x06,0x05,0x05,0x06,0x9b,0x05,0x08,0x06,0x05,0x05,0x06,0x04,0x07,0x05,0x05,0x06,0x8a,0x05,0x91,0x06,0x00,0x05,0x83,0x00,0x01,0x05,0x05,0x88,0x06,0x82,0x05,0x8e,0x06,0x00,0x05,0x85,0x06,0x01,0x05,0x05,0x82,0x04,0x03,0x07,0x05,0x05,0x06,0x89,0x05,0x8d,0x06,0x8a,0x05,0x04,0x06,0x05,0x05,0x04,0x04,0x83,0x03,0x04,0x07,0x05,0x05,0x06,0x06,0x8f,0x05,0x09,0x06,0x05,0x05,0x04,0x04,0x07,0x07,0x05,0x05,0x06,0x8d,0x05,0x8f,0x06,0x07,0x05, +0x05,0x04,0x07,0x07,0x05,0x05,0x06,0x86,0x05,0x01,0x06,0x05,0x93,0x06,0x00,0x05,0x83,0x00,0x01,0x05,0x05,0x88,0x06,0x02,0x05,0x06,0x06,0x96,0x05,0x83,0x04,0x03,0x07,0x05,0x05,0x06,0x88,0x05,0x00,0x06,0x8c,0x05,0x82,0x06,0x88,0x05,0x04,0x06,0x06,0x05,0x04,0x04,0x82,0x03,0x06,0x07,0x07,0x05,0x05,0x06,0x05,0x06,0x8e,0x05,0x09,0x06,0x05,0x05,0x04,0x04,0x07,0x07,0x05,0x05,0x06,0x8a,0x05,0x82,0x06,0x90,0x05,0x06,0x06,0x04,0x07,0x07,0x05,0x05,0x06,0x87,0x05,0x01,0x06,0x06,0x92,0x05,0x84,0x00,0x01,0x05,0x05,0x8a,0x06,0x96,0x05,0x08,0x06,0x04,0x04,0x03,0x04,0x07,0x05,0x05,0x06,0x83,0x05,0x05,0x06,0x05,0x06,0x05,0x06,0x06,0x8e,0x05,0x00,0x06, +0x88,0x05,0x02,0x06,0x06,0x05,0x82,0x04,0x0c,0x03,0x03,0x07,0x05,0x05,0x06,0x06,0x05,0x06,0x06,0x05,0x06,0x06,0x8a,0x05,0x08,0x06,0x05,0x05,0x04,0x07,0x07,0x05,0x05,0x06,0x8a,0x05,0x01,0x06,0x06,0x92,0x05,0x00,0x04,0x82,0x07,0x02,0x05,0x05,0x06,0x86,0x05,0x83,0x06,0x01,0x05,0x05,0x85,0x00,0x87,0x05,0x86,0x00,0x01,0x05,0x05,0x8a,0x06,0x03,0x05,0x05,0x06,0x06,0x84,0x07,0x00,0x06,0x8a,0x07,0x00,0x06,0x83,0x04,0x05,0x03,0x04,0x07,0x05,0x05,0x06,0x82,0x05,0x86,0x06,0x82,0x05,0x03,0x06,0x06,0x07,0x07,0x83,0x06,0x84,0x05,0x82,0x06,0x82,0x05,0x0f,0x06,0x05,0x05,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x07,0x06,0x05,0x05,0x06,0x05,0x8a,0x06,0x85, +0x05,0x08,0x06,0x05,0x05,0x04,0x06,0x07,0x05,0x05,0x06,0x89,0x05,0x01,0x06,0x06,0x83,0x05,0x82,0x06,0x82,0x05,0x01,0x06,0x05,0x84,0x06,0x03,0x05,0x07,0x04,0x03,0x82,0x07,0x02,0x05,0x05,0x06,0x84,0x05,0x85,0x06,0x00,0x05,0x95,0x00,0x01,0x05,0x05,0x89,0x06,0x03,0x05,0x05,0x04,0x04,0x8b,0x03,0x00,0x04,0x82,0x03,0x00,0x04,0x83,0x03,0x09,0x04,0x04,0x03,0x03,0x07,0x05,0x05,0x06,0x06,0x05,0x87,0x06,0x82,0x05,0x03,0x04,0x04,0x03,0x03,0x83,0x04,0x01,0x06,0x06,0x82,0x05,0x8a,0x06,0x07,0x05,0x05,0x04,0x04,0x07,0x07,0x05,0x05,0x8f,0x06,0x83,0x05,0x08,0x06,0x05,0x05,0x04,0x06,0x06,0x05,0x06,0x06,0x88,0x05,0x01,0x06,0x06,0x82,0x05,0x0a,0x06,0x06, +0x07,0x07,0x06,0x05,0x05,0x06,0x07,0x06,0x06,0x82,0x07,0x03,0x06,0x06,0x07,0x07,0x82,0x03,0x03,0x07,0x05,0x05,0x06,0x82,0x05,0x87,0x06,0x00,0x05,0x95,0x00,0x01,0x05,0x05,0x89,0x06,0x01,0x05,0x05,0x82,0x04,0x97,0x03,0x04,0x07,0x05,0x05,0x06,0x05,0x88,0x06,0x04,0x05,0x04,0x05,0x06,0x04,0x82,0x03,0x83,0x04,0x03,0x06,0x06,0x05,0x05,0x8a,0x06,0x07,0x05,0x06,0x04,0x04,0x07,0x06,0x05,0x05,0x94,0x06,0x0c,0x05,0x05,0x04,0x07,0x05,0x05,0x06,0x06,0x05,0x06,0x05,0x06,0x05,0x84,0x06,0x13,0x05,0x05,0x06,0x04,0x06,0x07,0x03,0x06,0x05,0x05,0x06,0x07,0x06,0x06,0x07,0x07,0x04,0x06,0x06,0x07,0x83,0x03,0x05,0x07,0x07,0x05,0x05,0x06,0x05,0x89,0x06,0x96, +0x00,0x01,0x05,0x05,0x8a,0x06,0x01,0x05,0x05,0x91,0x04,0x87,0x03,0x02,0x07,0x05,0x05,0x8a,0x06,0x07,0x05,0x04,0x05,0x05,0x04,0x04,0x03,0x03,0x84,0x04,0x02,0x06,0x06,0x05,0x8a,0x06,0x06,0x05,0x05,0x04,0x04,0x07,0x05,0x05,0x95,0x06,0x05,0x05,0x05,0x04,0x07,0x05,0x05,0x8b,0x06,0x08,0x05,0x05,0x04,0x07,0x07,0x03,0x07,0x05,0x05,0x82,0x06,0x06,0x07,0x07,0x04,0x07,0x07,0x06,0x07,0x85,0x03,0x02,0x07,0x05,0x05,0x8b,0x06,0x00,0x05,0x95,0x00,0x01,0x05,0x05,0x8a,0x06,0x90,0x05,0x00,0x06,0x85,0x04,0x83,0x03,0x02,0x07,0x05,0x05,0x8a,0x06,0x05,0x05,0x04,0x04,0x05,0x06,0x04,0x82,0x03,0x83,0x04,0x02,0x06,0x05,0x05,0x8a,0x06,0x06,0x05,0x05,0x04,0x07, +0x06,0x05,0x05,0x95,0x06,0x05,0x05,0x05,0x04,0x06,0x05,0x05,0x8a,0x06,0x01,0x05,0x05,0x82,0x04,0x0d,0x03,0x07,0x06,0x05,0x05,0x07,0x07,0x06,0x07,0x07,0x04,0x07,0x06,0x07,0x86,0x03,0x02,0x07,0x05,0x05,0x8b,0x06,0x00,0x05,0x95,0x00,0x01,0x05,0x05,0x8c,0x06,0x92,0x05,0x82,0x04,0x83,0x03,0x02,0x07,0x05,0x05,0x82,0x06,0x82,0x05,0x84,0x06,0x00,0x05,0x82,0x04,0x04,0x05,0x04,0x04,0x03,0x03,0x82,0x04,0x00,0x06,0x82,0x05,0x8a,0x06,0x05,0x05,0x05,0x04,0x06,0x05,0x05,0x96,0x06,0x04,0x05,0x05,0x04,0x06,0x05,0x8b,0x06,0x09,0x05,0x05,0x04,0x07,0x03,0x03,0x07,0x05,0x05,0x06,0x82,0x07,0x04,0x04,0x07,0x07,0x06,0x07,0x87,0x03,0x02,0x07,0x05,0x05,0x8a, +0x06,0x8f,0x05,0x02,0x06,0x06,0x05,0x84,0x00,0x01,0x00,0x05,0x9d,0x06,0x83,0x05,0x82,0x04,0x04,0x03,0x03,0x07,0x05,0x05,0x83,0x06,0x01,0x05,0x05,0x84,0x06,0x05,0x05,0x06,0x04,0x06,0x05,0x06,0x84,0x04,0x00,0x06,0x82,0x05,0x8b,0x06,0x02,0x05,0x05,0x06,0x82,0x05,0x8a,0x06,0x00,0x05,0x8a,0x06,0x04,0x05,0x05,0x06,0x05,0x05,0x8b,0x06,0x08,0x05,0x06,0x04,0x07,0x03,0x07,0x06,0x05,0x05,0x82,0x07,0x00,0x04,0x84,0x07,0x87,0x03,0x02,0x07,0x05,0x05,0x8a,0x06,0x01,0x05,0x05,0x8f,0x06,0x00,0x05,0x84,0x00,0x02,0x00,0x05,0x05,0x91,0x06,0x00,0x05,0x82,0x06,0x04,0x05,0x05,0x06,0x05,0x05,0x84,0x06,0x82,0x05,0x05,0x04,0x04,0x03,0x07,0x05,0x05,0x84,0x06, +0x00,0x05,0x84,0x06,0x8e,0x05,0x8b,0x06,0x04,0x05,0x06,0x06,0x05,0x05,0x8b,0x06,0x00,0x05,0x8a,0x06,0x04,0x05,0x05,0x06,0x05,0x05,0x8b,0x06,0x10,0x05,0x04,0x04,0x03,0x03,0x06,0x06,0x05,0x07,0x04,0x07,0x04,0x03,0x07,0x07,0x06,0x07,0x88,0x03,0x02,0x07,0x05,0x05,0x9c,0x06,0x00,0x05,0x84,0x00,0x02,0x00,0x05,0x05,0xa0,0x06,0x82,0x05,0x04,0x04,0x04,0x07,0x05,0x05,0x8a,0x06,0x00,0x05,0x87,0x06,0x83,0x05,0x8d,0x06,0x84,0x05,0x8a,0x06,0x01,0x05,0x05,0x8a,0x06,0x04,0x05,0x05,0x04,0x05,0x05,0x8a,0x06,0x02,0x05,0x05,0x04,0x82,0x03,0x05,0x06,0x05,0x06,0x07,0x04,0x04,0x82,0x03,0x01,0x06,0x07,0x89,0x03,0x02,0x07,0x07,0x05,0x89,0x06,0x00,0x05,0x91, +0x06,0x00,0x05,0x84,0x00,0x02,0x00,0x05,0x05,0x82,0x06,0x00,0x05,0x9d,0x06,0x06,0x05,0x05,0x04,0x04,0x07,0x05,0x05,0x93,0x06,0x83,0x05,0x8c,0x06,0x84,0x05,0x8b,0x06,0x01,0x05,0x05,0x8a,0x06,0x04,0x05,0x05,0x04,0x05,0x05,0x8a,0x06,0x0f,0x05,0x05,0x04,0x03,0x03,0x07,0x06,0x05,0x07,0x07,0x04,0x07,0x03,0x03,0x07,0x07,0x8a,0x03,0x02,0x07,0x05,0x05,0x88,0x06,0x82,0x05,0x90,0x06,0x00,0x05,0x84,0x00,0x03,0x00,0x00,0x05,0x05,0xa1,0x06,0x05,0x05,0x05,0x04,0x07,0x05,0x05,0xa4,0x06,0x83,0x05,0x8b,0x06,0x82,0x05,0x8a,0x06,0x04,0x05,0x05,0x06,0x05,0x05,0x8a,0x06,0x0e,0x05,0x05,0x04,0x04,0x03,0x06,0x05,0x06,0x07,0x04,0x04,0x03,0x03,0x07,0x06,0x8b, +0x03,0x02,0x07,0x05,0x05,0x88,0x06,0x82,0x05,0x90,0x06,0x00,0x05,0x84,0x00,0x03,0x00,0x00,0x05,0x05,0x82,0x06,0x82,0x07,0x01,0x02,0x02,0x93,0x07,0x0b,0x03,0x02,0x07,0x02,0x07,0x06,0x06,0x05,0x06,0x06,0x05,0x05,0x83,0x02,0x00,0x03,0x84,0x02,0x01,0x07,0x06,0x8a,0x02,0x00,0x03,0x8a,0x02,0x00,0x07,0x84,0x05,0x01,0x06,0x06,0x88,0x07,0x83,0x05,0x88,0x07,0x09,0x06,0x06,0x05,0x05,0x06,0x05,0x05,0x06,0x07,0x07,0x87,0x02,0x0d,0x06,0x05,0x04,0x04,0x07,0x05,0x06,0x07,0x04,0x07,0x03,0x03,0x07,0x06,0x8c,0x03,0x03,0x07,0x07,0x05,0x07,0x92,0x06,0x85,0x07,0x82,0x02,0x00,0x06,0x84,0x00,0x82,0x00,0x02,0x05,0x05,0x02,0x90,0x01,0x00,0x02,0x86,0x01,0x85, +0x00,0x06,0x01,0x02,0x05,0x05,0x06,0x05,0x06,0x89,0x00,0x02,0x02,0x06,0x01,0x95,0x00,0x00,0x07,0x83,0x05,0x01,0x07,0x02,0x88,0x01,0x00,0x02,0x83,0x05,0x00,0x02,0x88,0x01,0x07,0x02,0x06,0x05,0x06,0x05,0x05,0x02,0x01,0x88,0x00,0x0d,0x07,0x05,0x04,0x04,0x06,0x05,0x07,0x03,0x04,0x07,0x03,0x03,0x07,0x07,0x8c,0x03,0x02,0x07,0x05,0x06,0x87,0x02,0x00,0x07,0x82,0x06,0x01,0x07,0x07,0x85,0x02,0x85,0x01,0x82,0x00,0x00,0x06,0x84,0x00,0x83,0x00,0x04,0x05,0x05,0x02,0x01,0x00,0x8e,0x01,0x82,0x02,0x83,0x01,0x86,0x00,0x01,0x01,0x06,0x82,0x05,0x00,0x06,0x89,0x00,0x02,0x02,0x05,0x06,0x94,0x00,0x00,0x02,0x83,0x05,0x01,0x06,0x02,0x89,0x01,0x00,0x06,0x82, +0x05,0x00,0x06,0x89,0x01,0x06,0x02,0x06,0x05,0x06,0x05,0x05,0x02,0x89,0x00,0x0c,0x07,0x05,0x04,0x06,0x05,0x06,0x07,0x04,0x04,0x03,0x03,0x07,0x07,0x8d,0x03,0x03,0x07,0x05,0x06,0x01,0x87,0x02,0x02,0x03,0x07,0x07,0x87,0x02,0x84,0x01,0x83,0x00,0x00,0x06,0x84,0x00,0x84,0x00,0x02,0x05,0x05,0x07,0x8d,0x01,0x83,0x02,0x02,0x03,0x02,0x02,0x82,0x01,0x85,0x00,0x01,0x01,0x02,0x82,0x05,0x00,0x06,0x89,0x00,0x03,0x02,0x05,0x05,0x02,0x91,0x00,0x01,0x01,0x02,0x84,0x05,0x01,0x02,0x02,0x88,0x01,0x05,0x02,0x05,0x05,0x06,0x05,0x05,0x8a,0x01,0x05,0x06,0x05,0x06,0x05,0x05,0x02,0x89,0x00,0x04,0x02,0x05,0x06,0x05,0x05,0x84,0x07,0x01,0x04,0x06,0x8e,0x03,0x02, +0x07,0x05,0x06,0x89,0x02,0x00,0x03,0x88,0x02,0x85,0x01,0x82,0x00,0x00,0x06,0x84,0x00,0x85,0x00,0x82,0x05,0x00,0x06,0x82,0x02,0x83,0x01,0x86,0x02,0x04,0x03,0x06,0x06,0x03,0x02,0x84,0x01,0x83,0x00,0x01,0x01,0x02,0x82,0x05,0x00,0x06,0x89,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x8f,0x00,0x01,0x01,0x07,0x84,0x05,0x01,0x06,0x02,0x89,0x01,0x05,0x06,0x05,0x06,0x06,0x05,0x06,0x8a,0x01,0x05,0x06,0x05,0x06,0x05,0x05,0x02,0x88,0x00,0x01,0x01,0x02,0x82,0x05,0x07,0x06,0x07,0x04,0x04,0x07,0x07,0x06,0x07,0x8e,0x03,0x02,0x07,0x05,0x06,0x95,0x02,0x86,0x01,0x00,0x06,0x84,0x00,0x87,0x00,0x84,0x05,0x8d,0x06,0x02,0x07,0x02,0x02,0x89,0x01,0x82,0x05,0x00,0x06, +0x89,0x00,0x00,0x02,0x82,0x05,0x00,0x06,0x8b,0x00,0x82,0x01,0x01,0x02,0x06,0x82,0x05,0x04,0x06,0x05,0x05,0x02,0x02,0x88,0x01,0x07,0x02,0x05,0x05,0x04,0x07,0x05,0x05,0x02,0x89,0x01,0x05,0x06,0x05,0x04,0x06,0x05,0x02,0x85,0x01,0x0e,0x00,0x01,0x00,0x01,0x01,0x06,0x05,0x06,0x04,0x07,0x04,0x04,0x03,0x06,0x06,0x8f,0x03,0x02,0x07,0x05,0x06,0x8a,0x02,0x00,0x06,0x8e,0x05,0x02,0x06,0x06,0x05,0x84,0x00,0x91,0x00,0x89,0x05,0x01,0x07,0x02,0x89,0x01,0x82,0x05,0x0b,0x06,0x01,0x01,0x00,0x01,0x01,0x00,0x01,0x00,0x00,0x01,0x02,0x83,0x05,0x00,0x03,0x8c,0x02,0x00,0x06,0x82,0x05,0x04,0x06,0x07,0x05,0x05,0x06,0x82,0x02,0x00,0x01,0x86,0x02,0x06,0x06,0x05, +0x04,0x04,0x07,0x05,0x05,0x83,0x02,0x86,0x01,0x05,0x06,0x05,0x04,0x06,0x05,0x07,0x8a,0x01,0x09,0x06,0x05,0x06,0x04,0x07,0x04,0x04,0x07,0x06,0x07,0x8f,0x03,0x02,0x07,0x05,0x06,0x8a,0x02,0x02,0x06,0x05,0x05,0x94,0x00,0x99,0x00,0x82,0x05,0x84,0x02,0x85,0x01,0x03,0x06,0x05,0x05,0x06,0x89,0x01,0x00,0x02,0x93,0x05,0x06,0x06,0x04,0x04,0x07,0x05,0x05,0x03,0x89,0x02,0x07,0x07,0x05,0x05,0x04,0x03,0x07,0x05,0x05,0x87,0x02,0x82,0x01,0x05,0x06,0x05,0x04,0x07,0x05,0x06,0x89,0x01,0x03,0x02,0x02,0x05,0x05,0x83,0x04,0x01,0x06,0x07,0x90,0x03,0x02,0x07,0x05,0x06,0x88,0x02,0x03,0x03,0x02,0x06,0x05,0x95,0x00,0x9a,0x00,0x02,0x05,0x05,0x06,0x87,0x02,0x05, +0x01,0x01,0x06,0x05,0x05,0x06,0x89,0x01,0x02,0x02,0x05,0x06,0x89,0x00,0x01,0x05,0x05,0x82,0x06,0x09,0x05,0x06,0x06,0x04,0x04,0x07,0x06,0x05,0x06,0x07,0x89,0x02,0x07,0x05,0x05,0x04,0x04,0x03,0x07,0x05,0x05,0x8a,0x02,0x06,0x06,0x05,0x04,0x07,0x05,0x05,0x02,0x83,0x01,0x01,0x02,0x02,0x82,0x01,0x08,0x02,0x02,0x06,0x05,0x06,0x04,0x07,0x06,0x06,0x91,0x03,0x02,0x07,0x05,0x06,0x85,0x02,0x83,0x03,0x01,0x02,0x06,0x96,0x00,0x9a,0x00,0x02,0x05,0x05,0x06,0x89,0x02,0x03,0x06,0x05,0x05,0x06,0x8a,0x02,0x00,0x05,0x8b,0x00,0x03,0x05,0x06,0x04,0x03,0x83,0x04,0x05,0x06,0x06,0x05,0x05,0x07,0x07,0x88,0x02,0x08,0x06,0x05,0x05,0x04,0x04,0x03,0x07,0x05,0x05, +0x8a,0x02,0x05,0x06,0x05,0x04,0x07,0x05,0x05,0x8b,0x02,0x06,0x07,0x05,0x05,0x06,0x04,0x06,0x04,0x91,0x03,0x02,0x07,0x05,0x06,0x83,0x02,0x02,0x07,0x03,0x03,0x82,0x07,0x01,0x02,0x06,0x96,0x00,0x9a,0x00,0x03,0x05,0x05,0x06,0x03,0x88,0x02,0x82,0x05,0x00,0x06,0x8a,0x02,0x00,0x05,0x8b,0x00,0x03,0x05,0x06,0x04,0x03,0x82,0x04,0x08,0x06,0x06,0x05,0x05,0x06,0x06,0x07,0x07,0x03,0x86,0x02,0x01,0x05,0x05,0x82,0x04,0x03,0x03,0x07,0x05,0x05,0x8a,0x02,0x06,0x06,0x05,0x04,0x07,0x06,0x05,0x06,0x8a,0x02,0x01,0x07,0x06,0x82,0x05,0x02,0x06,0x04,0x04,0x87,0x03,0x0c,0x04,0x04,0x03,0x04,0x07,0x04,0x03,0x03,0x07,0x07,0x05,0x06,0x02,0x88,0x07,0x02,0x03,0x06, +0x05,0x95,0x00,0x99,0x00,0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x82,0x03,0x84,0x02,0x82,0x05,0x00,0x06,0x89,0x02,0x01,0x03,0x05,0x8c,0x00,0x00,0x05,0x84,0x04,0x00,0x06,0x82,0x05,0x82,0x06,0x83,0x07,0x04,0x03,0x07,0x03,0x03,0x06,0x82,0x05,0x82,0x06,0x82,0x05,0x00,0x02,0x84,0x03,0x84,0x02,0x06,0x06,0x05,0x04,0x07,0x07,0x05,0x05,0x8a,0x02,0x02,0x07,0x06,0x06,0x97,0x05,0x01,0x06,0x02,0x82,0x07,0x02,0x06,0x07,0x07,0x82,0x06,0x03,0x07,0x06,0x05,0x05,0x94,0x00,0x00,0x00,0x99,0x05,0x82,0x06,0x87,0x07,0x01,0x03,0x03,0x82,0x05,0x07,0x06,0x02,0x03,0x03,0x02,0x03,0x02,0x03,0x82,0x02,0x01,0x07,0x05,0x8d,0x00,0x00,0x05,0x82,0x04,0x01,0x06,0x06,0x82, +0x05,0x86,0x06,0x03,0x07,0x06,0x07,0x06,0x89,0x05,0x00,0x06,0x88,0x07,0x08,0x03,0x06,0x05,0x04,0x03,0x07,0x05,0x05,0x06,0x82,0x02,0x07,0x03,0x03,0x07,0x03,0x07,0x03,0x07,0x03,0x97,0x06,0x82,0x05,0x00,0x02,0x9e,0x06,0x02,0x05,0x00,0x00,0x02,0x05,0x05,0x03,0x9f,0x06,0x82,0x07,0x01,0x03,0x06,0x83,0x05,0x00,0x02,0x87,0x07,0x02,0x03,0x07,0x05,0x8d,0x00,0x04,0x05,0x06,0x04,0x04,0x06,0x82,0x05,0x96,0x06,0x02,0x07,0x04,0x06,0x85,0x07,0x08,0x03,0x05,0x05,0x04,0x03,0x07,0x07,0x05,0x05,0x8b,0x07,0x95,0x06,0x04,0x07,0x06,0x05,0x05,0x07,0x9d,0x06,0x03,0x02,0x05,0x00,0x00,0x02,0x05,0x05,0x07,0xa1,0x06,0x02,0x04,0x07,0x06,0x83,0x05,0x05,0x07,0x07, +0x06,0x07,0x07,0x06,0x83,0x07,0x01,0x06,0x05,0x8e,0x00,0x03,0x05,0x04,0x04,0x06,0x83,0x05,0x9d,0x06,0x0a,0x07,0x07,0x05,0x05,0x04,0x04,0x07,0x07,0x05,0x05,0x06,0x82,0x07,0x01,0x06,0x07,0x9d,0x06,0x02,0x05,0x05,0x07,0x9d,0x06,0x03,0x07,0x05,0x00,0x00,0x02,0x05,0x05,0x07,0xa2,0x06,0x00,0x07,0x84,0x05,0x00,0x07,0x89,0x06,0x00,0x05,0x8e,0x00,0x00,0x05,0x82,0x06,0x84,0x05,0x9d,0x06,0x09,0x07,0x05,0x05,0x04,0x03,0x03,0x07,0x07,0x05,0x05,0xa2,0x06,0x02,0x05,0x05,0x07,0x9d,0x06,0x03,0x07,0x05,0x00,0x00,0x01,0x05,0x05,0xa4,0x06,0x05,0x05,0x05,0x06,0x05,0x05,0x07,0x89,0x06,0x00,0x05,0x8f,0x00,0x01,0x05,0x06,0x84,0x05,0x88,0x06,0x00,0x05,0x95, +0x06,0x02,0x05,0x05,0x04,0x82,0x03,0x03,0x07,0x06,0x05,0x05,0xa1,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0xa3,0x06,0x00,0x05,0x82,0x00,0x01,0x05,0x05,0x8a,0x06,0x00,0x05,0x90,0x00,0x85,0x05,0x87,0x06,0x82,0x05,0x94,0x06,0x07,0x05,0x05,0x04,0x04,0x03,0x03,0x07,0x07,0x82,0x05,0xa0,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0xa2,0x06,0x01,0x05,0x05,0x82,0x00,0x01,0x05,0x05,0x8a,0x06,0x00,0x05,0x90,0x00,0x83,0x05,0x89,0x06,0x82,0x05,0x94,0x06,0x02,0x05,0x05,0x04,0x82,0x03,0x82,0x07,0x82,0x05,0x9f,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0xa1,0x06,0x01,0x05,0x05,0x83, +0x00,0x01,0x05,0x05,0x8a,0x06,0x00,0x05,0x8f,0x00,0x85,0x05,0x87,0x06,0x84,0x05,0x93,0x06,0x03,0x05,0x05,0x04,0x04,0x82,0x03,0x02,0x07,0x07,0x06,0x82,0x05,0x9e,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0xa0,0x06,0x01,0x05,0x05,0x84,0x00,0x01,0x05,0x05,0x8a,0x06,0x00,0x05,0x8f,0x00,0x84,0x05,0x87,0x06,0x82,0x05,0x02,0x06,0x05,0x05,0x93,0x06,0x02,0x05,0x05,0x04,0x83,0x03,0x01,0x07,0x06,0x85,0x05,0x9c,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0x9e,0x06,0x82,0x05,0x85,0x00,0x01,0x05,0x05,0x8a,0x06,0x00,0x05,0x8e,0x00,0x87,0x05,0x85,0x06,0x06,0x05,0x05,0x06,0x07,0x06,0x05,0x05,0x92,0x06,0x02, +0x05,0x05,0x04,0x82,0x03,0x05,0x07,0x04,0x06,0x05,0x06,0x07,0x84,0x05,0x9a,0x06,0x01,0x05,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x01,0x05,0x05,0x9b,0x06,0x83,0x05,0x87,0x00,0x01,0x05,0x05,0x89,0x06,0x01,0x05,0x05,0x8e,0x00,0x8b,0x05,0x00,0x06,0x82,0x05,0x02,0x04,0x07,0x07,0x82,0x05,0x91,0x06,0x09,0x05,0x05,0x04,0x03,0x03,0x07,0x03,0x06,0x05,0x05,0x82,0x07,0x88,0x05,0x94,0x06,0x82,0x05,0x9f,0x06,0x02,0x05,0x00,0x00,0x00,0x00,0x9e,0x05,0x89,0x00,0x8c,0x05,0x8f,0x00,0x8e,0x05,0x03,0x04,0x03,0x03,0x07,0x96,0x05,0x00,0x04,0x82,0x03,0x06,0x04,0x06,0x05,0x04,0x03,0x04,0x06,0x83,0x00,0xbd,0x05,0x01,0x00,0x00,0xcb,0x00,0x88,0x05,0x01,0x06,0x04, +0x82,0x03,0x00,0x07,0x94,0x05,0x0a,0x06,0x04,0x03,0x07,0x03,0x04,0x05,0x06,0x04,0x04,0x07,0xc4,0x00,0xcc,0x00,0x02,0x05,0x06,0x07,0x83,0x06,0x88,0x03,0x91,0x07,0x84,0x03,0x05,0x07,0x05,0x06,0x07,0x07,0x04,0xc5,0x00,0xcd,0x00,0x00,0x05,0x85,0x04,0x9e,0x03,0x05,0x06,0x05,0x06,0x03,0x04,0x04,0xc5,0x00,0xce,0x00,0x00,0x06,0x84,0x04,0x9d,0x03,0x02,0x07,0x05,0x06,0x82,0x04,0xc6,0x00,0xce,0x00,0x00,0x05,0x84,0x04,0x9c,0x03,0x05,0x04,0x06,0x05,0x04,0x03,0x04,0xc7,0x00,0xcf,0x00,0x00,0x06,0x84,0x04,0x9b,0x03,0x05,0x06,0x05,0x06,0x07,0x04,0x07,0xc7,0x00,0xcf,0x00,0x01,0x05,0x06,0x83,0x04,0x8d,0x03,0x00,0x02,0x8b,0x03,0x05,0x04,0x06,0x05,0x07, +0x03,0x04,0xc8,0x00,0xd0,0x00,0x00,0x06,0x84,0x04,0x99,0x03,0x04,0x06,0x05,0x04,0x03,0x04,0xc9,0x00,0xd1,0x00,0x00,0x06,0x82,0x04,0x99,0x03,0x05,0x07,0x05,0x05,0x04,0x04,0x07,0xc9,0x00,0xd1,0x00,0x00,0x05,0x84,0x04,0x96,0x03,0x05,0x04,0x06,0x05,0x04,0x03,0x07,0xca,0x00,0xd0,0x00,0x08,0x06,0x05,0x05,0x06,0x04,0x04,0x03,0x03,0x04,0x87,0x07,0x87,0x03,0x01,0x07,0x07,0x85,0x06,0x02,0x07,0x04,0x06,0xca,0x00,0xcc,0x00,0x86,0x05,0x00,0x06,0x82,0x04,0x01,0x07,0x06,0x87,0x05,0x01,0x06,0x07,0x83,0x03,0x02,0x07,0x06,0x06,0x85,0x05,0x01,0x06,0x07,0x82,0x06,0x83,0x05,0x8b,0x00,0x83,0x05,0xb5,0x00,0xbb,0x00,0x88,0x05,0x86,0x00,0x88,0x05,0x03,0x06, +0x04,0x06,0x06,0x89,0x05,0x00,0x06,0x83,0x03,0x00,0x06,0x88,0x05,0x03,0x06,0x06,0x07,0x06,0x88,0x05,0x84,0x00,0x87,0x05,0xb3,0x00,0xbb,0x00,0x89,0x05,0x84,0x00,0x89,0x05,0x03,0x06,0x06,0x04,0x06,0x89,0x05,0x04,0x06,0x07,0x03,0x07,0x07,0x89,0x05,0x02,0x06,0x06,0x07,0x89,0x05,0x83,0x00,0x88,0x05,0xb3,0x00,0xba,0x00,0x8a,0x05,0x84,0x00,0x8a,0x05,0x82,0x06,0x8a,0x05,0x03,0x07,0x03,0x07,0x06,0x8a,0x05,0x01,0x00,0x00,0x89,0x05,0x83,0x00,0x89,0x05,0xb2,0x00,0xba,0x00,0x84,0x05,0x00,0x00,0x84,0x05,0x83,0x00,0x84,0x05,0x00,0x00,0x85,0x05,0x01,0x06,0x06,0x84,0x05,0x00,0x00,0x84,0x05,0x03,0x06,0x07,0x03,0x07,0x84,0x05,0x01,0x00,0x00,0x84,0x05, +0x83,0x00,0x86,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0xb2,0x00,0xba,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x02,0x06,0x05,0x06,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x03,0x06,0x04,0x03,0x07,0x83,0x05,0x82,0x00,0x84,0x05,0x84,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0xb3,0x00,0xba,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x02,0x06,0x05,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x00,0x06,0x82,0x07,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0xb3,0x00,0xba,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83, +0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x02,0x07,0x06,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x03,0x06,0x07,0x03,0x07,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0xb3,0x00,0xba,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x83,0x00,0x84,0x05,0x01,0x00,0x00,0x84,0x05,0x02,0x07,0x07,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x03,0x07,0x07,0x04,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0xb9,0x00,0xba,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x84,0x05,0x02,0x00,0x07,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x03,0x07,0x03,0x04,0x06,0x83,0x05,0x82,0x00, +0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0xb9,0x00,0xba,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x82,0x00,0x00,0x06,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x02,0x07,0x03,0x07,0x84,0x05,0x82,0x00,0x83,0x05,0x84,0x00,0x84,0x05,0x85,0x00,0x83,0x05,0xb9,0x00,0xba,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x82,0x00,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x03,0x06,0x04,0x03,0x07,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x86,0x00,0x84,0x05,0xb8,0x00,0xb9,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x89,0x05,0x03,0x06, +0x03,0x03,0x07,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x86,0x00,0x84,0x05,0xb8,0x00,0xb9,0x00,0x8a,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x83,0x00,0x88,0x05,0x04,0x06,0x07,0x03,0x03,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x87,0x00,0x84,0x05,0xb7,0x00,0xb9,0x00,0x89,0x05,0x84,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x83,0x00,0x89,0x05,0x04,0x07,0x04,0x03,0x07,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x88,0x00,0x84,0x05,0xb6,0x00,0xb9,0x00,0x88,0x05,0x85,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x8a,0x05,0x03,0x07,0x03,0x07,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83, +0x05,0x89,0x00,0x84,0x05,0xb5,0x00,0xb9,0x00,0x88,0x05,0x85,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x03,0x07,0x03,0x07,0x06,0x83,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x8a,0x00,0x83,0x05,0xb5,0x00,0xb9,0x00,0x88,0x05,0x84,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x02,0x07,0x03,0x07,0x84,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x82,0x05,0x8b,0x00,0x83,0x05,0xb5,0x00,0xb9,0x00,0x82,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x84,0x05,0x02,0x07,0x04,0x06,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x85, +0x00,0x83,0x05,0x8b,0x00,0x83,0x05,0xb5,0x00,0xb8,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x02,0x06,0x07,0x07,0x84,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x8c,0x00,0x82,0x05,0xb5,0x00,0xb8,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x83,0x05,0x82,0x00,0x83,0x05,0x83,0x00,0x82,0x05,0x82,0x00,0x83,0x05,0x82,0x06,0x84,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x86,0x00,0x01,0x05,0x05,0x82,0x00,0x83,0x05,0xb5,0x00,0xb8,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x82,0x05,0x82,0x00,0x83, +0x05,0x01,0x06,0x06,0x85,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0xb5,0x00,0xb8,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x84,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x82,0x00,0x85,0x05,0x00,0x06,0x84,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0xb5,0x00,0xb8,0x00,0x83,0x05,0x01,0x00,0x00,0x83,0x05,0x83,0x00,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x83,0x00,0x83,0x05,0x01,0x00,0x00,0x86,0x05,0x00,0x06,0x84,0x05,0x82,0x00,0x83,0x05,0x85,0x00,0x82,0x05,0x85,0x00,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0xb5,0x00,0xb8,0x00,0x82,0x05, +0x82,0x00,0x84,0x05,0x82,0x00,0x84,0x05,0x00,0x00,0x84,0x05,0x83,0x00,0x8b,0x05,0x01,0x00,0x00,0x84,0x05,0x01,0x00,0x00,0x83,0x05,0x86,0x00,0x82,0x05,0x85,0x00,0x84,0x05,0x00,0x06,0x84,0x05,0xb5,0x00,0xb7,0x00,0x83,0x05,0x82,0x00,0x84,0x05,0x82,0x00,0x8a,0x05,0x83,0x00,0x8a,0x05,0x83,0x00,0x89,0x05,0x85,0x00,0x83,0x05,0x85,0x00,0x89,0x05,0xb6,0x00,0xb7,0x00,0x83,0x05,0x82,0x00,0x84,0x05,0x83,0x00,0x88,0x05,0x84,0x00,0x89,0x05,0x84,0x00,0x89,0x05,0x85,0x00,0x83,0x05,0x86,0x00,0x88,0x05,0xb6,0x00,0xb8,0x00,0x82,0x05,0x83,0x00,0x83,0x05,0x84,0x00,0x86,0x05,0x85,0x00,0x87,0x05,0x87,0x00,0x86,0x05,0x87,0x00,0x83,0x05,0x87,0x00,0x85,0x05, +0xb8,0x00,0xca,0x00,0x82,0x05,0x99,0x00,0x82,0x05,0x97,0x00,0x82,0x05,0xb9,0x00,0xff,0x00,0xbf,0x00,0xff,0x00,0xbf,0x00,0xff,0x00,0xbf,0x00 +}; + +// http://paulbourke.net/dataformats/tga/ +typedef struct { + char idlength; + char colourmaptype; + char datatypecode; + short colourmaporigin; + short colourmaplength; + char colourmapdepth; + short x_origin; + short y_origin; + short width; + short height; + char bitsperpixel; + char imagedescriptor; + struct { byte r,g,b; } palette[8]; + byte data[0]; +} TGAHeader; + +void draw_tga(const byte* tgadata, byte cenx, byte ceny) { + const TGAHeader* hdr = (TGAHeader*) tgadata; + const byte* src = hdr->data; + const width = swapw(hdr->width); + const height = swapw(hdr->height); + byte* dest = &vidmem[cenx-width/4][ceny-height/2]; + byte i,j,lastbyte; + // set palette from TGA + for (i=0; i<8; i++) { + byte pal = 0; + pal |= (hdr->palette[i].r >> 5); + pal |= (hdr->palette[i].g >> 2) & 0x38; + pal |= (hdr->palette[i].b) & 0xc0; + palette[i] = pal; + } + // iterate over height of image + for (j=0; j HICHAR) return 1; + shape = FONT_TABLE[ch - LOCHAR]; + draw_copy_solid((byte)x, y - (shape[1]>>4), + shape[0] & 0xf, shape[1] & 0xf, + shape+2, color); + return shape[0] >> 4; +} + +void draw_string(const char* str, word x, byte y, byte color) { + while (*str) { + x += draw_char(*str++, x, y, color); + } +} diff --git a/presets/williams/font.h b/presets/williams/font.h new file mode 100644 index 00000000..52adcbde --- /dev/null +++ b/presets/williams/font.h @@ -0,0 +1,4 @@ + +byte draw_char(char ch, word x, byte y, byte color); + +void draw_string(const char* str, word x, byte y, byte color); diff --git a/presets/williams/fonttest.c b/presets/williams/fonttest.c new file mode 100644 index 00000000..b5bc8101 --- /dev/null +++ b/presets/williams/fonttest.c @@ -0,0 +1,30 @@ + +#include "williams.h" +//#link "williams.c" + +#include "font.h" +//#link "font.c" + +// 256x304x4bpp video memory + +int main(void) { + byte i; + rom_select = 1; + blit_solid(0, 0, 152, 255, 0x00); + for (i=0; i<16; i++) + palette[i] = (byte)(i*7); + for (i=0; i<152; i++) { + vidmem[0][i] = 16; + vidmem[i][2] = 32; + draw_pixel(i, i, 0x77); + draw_pixel(i+1, i, 0x33); + } + while (1) { + for (i=0; i<16; i++) { + watchdog0x39 = 0x39; + draw_string("Hello World, this proportional font is the jam!!", + 20, i*17+8, i+i*16); + } + } + return 0; +} diff --git a/presets/williams/game1.c b/presets/williams/game1.c new file mode 100644 index 00000000..75cfef54 --- /dev/null +++ b/presets/williams/game1.c @@ -0,0 +1,653 @@ + + +#include "williams.h" +//#link "williams.c" + +#include "stdlib.h" + +//#link "font.c" +#include "font.h" + +// for CMOC (??) +void stkcheck() { } + +// GRAPHIC DATA + +const byte palette_data[16] = {/*{pal:332,n:16}*/ + 0x00, 0x03, 0x19, 0x50, 0x52, 0x07, 0x1f, 0x37, 0xe0, 0xa4, 0xfd, 0xff, 0x38, 0x70, 0x7f, 0xf8, }; + +const byte laser_vert[2+1*8] = { + 1,8, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, +}; + +const byte laser_horiz[2+4*2] = { + 4,2, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, +}; + + +const byte playersprite1[] = { +7,16,/*{w:14,h:16,bpp:4,brev:1}*/ +0x00,0x00,0xEF,0xEF,0xE0,0x00,0x00, +0x00,0xEE,0xEE,0xFE,0xEE,0xE0,0x00, +0x0E,0xED,0xEF,0xEF,0xED,0xEE,0x00, +0x0E,0xEE,0xDD,0xDD,0xDE,0xEE,0x00, +0x0E,0xEE,0xEC,0xDC,0xEE,0xEE,0x00, +0x00,0xEE,0xEE,0xDE,0xEE,0xE0,0x00, +0x00,0xEE,0xEE,0xDE,0xEE,0xE0,0x00, +0x00,0x00,0xED,0xDD,0xE0,0x00,0x00, +0xDD,0xDD,0xEE,0xEE,0xED,0xDD,0xD0, +0x0C,0xEE,0xEE,0xEE,0xEE,0xEC,0x00, +0x0E,0xE0,0xEE,0xEE,0xE0,0xEE,0x00, +0x0E,0xE0,0xEE,0xEE,0xE0,0xEE,0x00, +0x0E,0xE0,0xDD,0xDD,0xD0,0xDE,0x00, +0x0D,0x00,0xEE,0x0E,0xE0,0x0D,0x00, +0x00,0x00,0xEC,0x0C,0xE0,0x00,0x00, +0x00,0x0D,0xDD,0x0D,0xDD,0x00,0x00, +}; + +const byte sprite1[2+16*16/2] = { +8,16,/*{w:16,h:16,bpp:4,brev:1}*/ +0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00, +0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00, +0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90, +0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49, +0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99, +0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90, +0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00, +0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00, +0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00, +0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00, +0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00, +0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00, +0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30, +0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00, +0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00, +0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00, +}; + +const byte sprite2[2+16*16/2] = { +8,16,/*{w:16,h:16,bpp:4,brev:1}*/ +0x00,0x08,0x80,0x40,0x00,0x00,0x8D,0x00, +0x80,0x94,0x88,0x90,0x09,0x48,0x89,0x00, +0x08,0x49,0x48,0x66,0x66,0x98,0x94,0x98, +0x94,0x89,0x66,0x66,0x66,0x66,0x98,0x89, +0x99,0x66,0x67,0x76,0x67,0x76,0x69,0x98, +0x88,0x67,0x77,0x66,0x66,0x77,0x74,0x90, +0x09,0x97,0x74,0x46,0x64,0x47,0x78,0x88, +0x09,0x89,0x43,0x96,0x69,0x34,0x99,0x90, +0x08,0x89,0xBB,0x39,0x93,0xBB,0x98,0x90, +0x80,0x99,0x3B,0x33,0x33,0xB0,0x99,0x88, +0x00,0x09,0x9C,0xC3,0x3C,0xC8,0x99,0x08, +0x00,0x00,0x03,0xC3,0x8C,0x30,0x00,0x00, +0x00,0x00,0x0D,0xD3,0x3D,0x00,0x00,0x00, +0x00,0x00,0x0D,0x00,0x0D,0xD0,0x00,0x00, +0x00,0x00,0xDD,0x30,0x03,0xD0,0x00,0x00, +0x00,0x00,0xD0,0x40,0x00,0xD0,0x00,0x00, +}; + +const byte sprite3[2+16*16/2] = { +8,16,/*{w:16,h:16,bpp:4,brev:1}*/ +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x00,0x00,0x11,0x11,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x11,0x10,0x01,0x10,0x01,0x11,0x00, +0x11,0x00,0x10,0x11,0x11,0x01,0x00,0x11, +0x10,0x00,0x11,0x11,0x11,0x11,0x00,0x01, +0x10,0x00,0x00,0x11,0x11,0x00,0x00,0x01, +0x00,0x01,0x10,0x11,0x41,0x01,0x10,0x00, +0x00,0x10,0x11,0x11,0x11,0x11,0x01,0x00, +0x01,0x00,0x00,0x51,0x15,0x00,0x00,0x10, +0x01,0x00,0x01,0x10,0x01,0x10,0x00,0x10, +0x01,0x00,0x10,0x00,0x00,0x01,0x00,0x10, +0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00, +0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00, +0x00,0x01,0x10,0x00,0x00,0x01,0x10,0x00, +}; + +const byte sprite4[2+16*16/2] = { +8,16,/*{w:16,h:16,bpp:4,brev:1}*/ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00, +0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00, +0x00,0x00,0xbb,0xbb,0xbb,0xbb,0x00,0x00, +0x00,0x0b,0x4b,0xbb,0xbb,0xb4,0xb0,0x00, +0x00,0x0b,0x44,0xbb,0xbb,0x49,0xb0,0x00, +0x00,0xbb,0x99,0x4b,0xb4,0x99,0xbb,0x00, +0x00,0x4b,0xb9,0x9b,0xb4,0x4b,0xb4,0x00, +0x00,0x04,0xbb,0x4b,0xb9,0xbb,0x40,0x00, +0x00,0x00,0x4b,0xbb,0xbb,0xb4,0x00,0x00, +0x11,0x00,0x0b,0xbb,0xbb,0xb0,0x00,0x11, +0x10,0x10,0x0b,0x41,0x14,0xb0,0x01,0x01, +0x10,0x00,0x05,0x11,0x11,0x50,0x00,0x01, +0x01,0x00,0x01,0x51,0x15,0x10,0x00,0x10, +0x00,0x10,0x01,0x10,0x01,0x10,0x01,0x00, +0x01,0x01,0x10,0x10,0x01,0x01,0x10,0x10, +}; + +const byte sprite5[2+16*16/2] = { +8,16, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x22,0x00,0x00,0x22,0x00,0x00, +0x00,0x20,0x20,0x00,0x00,0x02,0x02,0x00, +0x02,0x22,0x12,0x00,0x00,0x21,0x22,0x20, +0x00,0x02,0x11,0x00,0x00,0x11,0x20,0x00, +0x00,0x00,0x02,0x11,0x11,0x20,0x00,0x00, +0x00,0x00,0x02,0x22,0x22,0x20,0x00,0x00, +0x00,0x00,0x21,0x22,0x22,0x12,0x00,0x00, +0x00,0x00,0x22,0x12,0x21,0x22,0x00,0x00, +0x02,0x00,0x22,0x12,0x21,0x22,0x00,0x20, +0x20,0x02,0x21,0x11,0x11,0x12,0x20,0x02, +0x02,0x22,0x15,0x12,0x21,0x51,0x22,0x20, +0x02,0x11,0x15,0x52,0x25,0x51,0x11,0x20, +0x20,0x00,0x22,0x12,0x21,0x22,0x00,0x02, +0x20,0x02,0x20,0x20,0x02,0x02,0x20,0x02, +0x02,0x02,0x00,0x20,0x02,0x00,0x20,0x20, +}; + +const byte sprite6[2+10*16/2] = { +8,10,/*{w:16,h:10,bpp:4,brev:1}*/ +0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00, +0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x40, +0x00,0x00,0x04,0x04,0x49,0x49,0x99,0x44, +0x00,0x00,0x44,0x44,0x99,0x94,0x44,0x40, +0x00,0x04,0x49,0x99,0x94,0x49,0x99,0x40, +0x00,0x44,0x99,0x94,0x49,0x99,0x44,0x00, +0x04,0x49,0x44,0x99,0x99,0x44,0x00,0x00, +0x04,0x44,0x00,0x49,0x44,0x40,0x00,0x00, +0x04,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +const byte sprite7[2+14*16/2] = { +8,14,/*{w:16,h:14,bpp:4,brev:1}*/ +0x00,0x60,0x00,0x00,0x00,0x00,0x06,0x00, +0x60,0x60,0x00,0x00,0x00,0x00,0x06,0x06, +0x60,0x60,0x50,0x00,0x00,0x05,0x06,0x06, +0x60,0x60,0x06,0x00,0x00,0x60,0x06,0x06, +0x66,0x60,0x06,0x06,0x60,0x60,0x06,0x66, +0x66,0x60,0x66,0x66,0x66,0x66,0x06,0x66, +0x66,0x60,0x6b,0x6b,0xb6,0xb6,0x06,0x66, +0x06,0x66,0x66,0xb6,0x6b,0x66,0x66,0x60, +0x00,0x67,0x66,0x66,0x66,0x66,0x66,0x00, +0x00,0x11,0x11,0x66,0x66,0x11,0x11,0x00, +0x01,0x11,0x21,0x11,0x11,0x12,0x11,0x10, +0x00,0x10,0x01,0x01,0x10,0x10,0x01,0x00, +0x00,0x10,0x11,0x00,0x00,0x11,0x01,0x00, +0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x00, +}; + +const byte sprite8[2+15*16/2] = { +8,15,/*{w:16,h:15,bpp:4,brev:1}*/ +0x00,0x00,0x11,0x11,0x11,0x11,0x00,0x00, +0x00,0x01,0x61,0x11,0x21,0x12,0x10,0x00, +0x00,0x11,0x12,0x11,0x61,0x11,0x11,0x00, +0x00,0x11,0x71,0x21,0x61,0x17,0x11,0x00, +0x00,0x11,0x77,0x11,0x12,0x77,0x11,0x00, +0x00,0x11,0x17,0x17,0x71,0x72,0x11,0x00, +0x00,0x16,0x21,0x78,0x87,0x11,0x11,0x00, +0x00,0x01,0x81,0x88,0x88,0x18,0x10,0x00, +0x00,0x08,0x18,0x58,0x85,0x81,0x80,0x00, +0x00,0x88,0x01,0x88,0x88,0x10,0x88,0x00, +0x00,0x08,0x07,0x78,0x87,0x70,0x80,0x00, +0x08,0x80,0x07,0x80,0x08,0x70,0x08,0x80, +0x88,0x00,0x88,0x00,0x00,0x88,0x00,0x88, +0x80,0x00,0x08,0x80,0x08,0x80,0x00,0x08, +0x00,0x00,0x00,0x80,0x08,0x00,0x00,0x00, +}; + +const byte sprite9[2+13*16/2] = { +8,13,/*{w:16,h:13,bpp:4,brev:1}*/ +0x00,0x00,0xaa,0x00,0x00,0xaa,0x00,0x00, +0x00,0x00,0xa0,0x0a,0xa0,0x0a,0x00,0x00, +0x0a,0xaa,0xa4,0xaa,0xaa,0x3a,0xaa,0xa0, +0x00,0x0a,0x3a,0x9a,0xa9,0xa3,0xa0,0x00, +0x00,0x0a,0xaa,0x99,0xa4,0xaa,0xa0,0x00, +0x00,0x0a,0xaa,0x99,0x94,0xaa,0xa0,0x00, +0x00,0xaa,0x33,0xaa,0xaa,0x43,0xaa,0x00, +0x0a,0x3a,0xaa,0x3a,0xa3,0xaa,0xa3,0xa0, +0x00,0xaa,0xaa,0x30,0x03,0xaa,0xaa,0x00, +0x00,0x0a,0xa0,0x30,0x03,0x0a,0xa0,0x00, +0x00,0xa3,0xa0,0x00,0x00,0x0a,0x4a,0x00, +0x00,0xaa,0xa0,0x00,0x00,0x0a,0xaa,0x00, +0x00,0x0a,0xa0,0x00,0x00,0x0a,0xa0,0x00, +}; + +const byte* const all_sprites[9] = { + sprite1, + sprite2, + sprite3, + sprite4, + sprite5, + sprite6, + sprite7, + sprite8, + sprite9, +}; + +// GAME CODE + +typedef struct Actor { + struct Actor* next; + struct Actor** prevptr; + byte x,y; + const byte* shape; + void (*update)(struct Actor* a); + void (*draw)(struct Actor* a); + union u { + struct { sbyte dx,dy; } laser; + struct { byte exploding; } enemy; + } u; +} Actor; + +#define MAX_ACTORS 128 + +static Actor actors[MAX_ACTORS]; +static Actor* player_list; +static Actor* fast_list; +static Actor* slow_lists[4]; +static Actor* obstacle_list; +static Actor* free_list; +static Actor* effects_list; +static byte frame; + +static word score; // bcd score + +#define PLAYER 1 +#define LASER 2 + +void add_actor(Actor** list, Actor* a) { + if (*list) (*list)->prevptr = &a->next; + a->next = *list; + a->prevptr = list; + *list = a; +} + +void remove_actor(Actor* a) { + if (a->next) a->next->prevptr = a->prevptr; + *a->prevptr = a->next; +} + +void draw_actor_normal(Actor* a) { + blit_sprite(a->shape, a->x, a->y); +} + +void draw_actor_exploding(Actor* a) { + unblit_sprite_strided(a->shape, a->x, a->y, a->u.enemy.exploding); + if (a->u.enemy.exploding > 10) { + a->draw = NULL; + } else { + blit_sprite_strided(a->shape, a->x, a->y, ++a->u.enemy.exploding); + } +} + +void update_actor(Actor* a) { + // if NULL shape, we don't have anything + if (a->shape) { + // erase the sprite + blit_sprite_solid(a->shape, a->x, a->y, 0); + // call update callback + if (a->update) { + a->update(a); + } + // did we delete it? + if (a->shape) { + // draw the sprite + if (a->draw) { + a->draw(a); + } + } else { + // shape became null, remove from list + remove_actor(a); + } + } +} + +// + +word lfsr = 1; + +word xrand() { + byte lsb = (byte)lfsr & 1; + lfsr >>= 1; + if (lsb) lfsr ^= 0xd400; + return lfsr; +} + +signed char random_dir() { + byte x = (byte)xrand(); + if (x < 85) return 0; + else if (x < 85*2) return -1; + else return 1; +} + +void update_actor_list(Actor* a) { + while (a) { + update_actor(a); + a = a->next; + } +} + +static byte g_section; + +void update_actors_partial(Actor* a) { + while (a) { + if (g_section ^ (a->y < 0x80)) { + update_actor(a); + } + a = a->next; + } +} + +void update_screen_section(byte section) { + g_section = section; + update_actors_partial(player_list); + update_actors_partial(fast_list); + update_actors_partial(slow_lists[frame & 3]); +} + +static Actor* test_actor; +static byte test_x, test_y; + +byte minbyte(byte a, byte b) { return ab?a:b; } + +bool test_actor_pixels(Actor* a) { + if (a->shape) { + byte x,y; + const byte *p1, *p2; + byte x1 = maxbyte(test_actor->x, a->x); + byte y1 = maxbyte(test_actor->y, a->y); + byte x2 = minbyte(test_actor->x + test_actor->shape[0]*2, + a->x + a->shape[0]*2); + byte y2 = minbyte(test_actor->y + test_actor->shape[1], + a->y + a->shape[1]); + if (x2 < x1) x2 = 255; // clip to 8-bit coord. + if (y2 < y1) y2 = 255; // clip to 8-bit coord. + if (x2 <= x1 || y2 <= y1) return false; + //draw_box(x1,y1,x2,y2,0xff); + p1 = &test_actor->shape[2+(y1-test_actor->y)*test_actor->shape[0]]; + p2 = &a->shape[2+(y1-a->y)*a->shape[0]]; + p1 += (x1 - test_actor->x) >> 1; + p2 += (x1 - a->x) >> 1; + for (y=y1; yshape[0]; + p2 += a->shape[0]; + } + } + return false; +} + +bool test_collision_actor(Actor* a) { + return ((byte)(test_y - a->y + 16) < 32 && + (byte)(test_x - a->x + 16) < 32 && + test_actor_pixels(a)); +} + +Actor* test_collisions(Actor* a) { + while (a) { + if (test_collision_actor(a)) { + return a; + } + a = a->next; + } + return NULL; +} + +void setup_collision(Actor* a) { + test_actor = a; + test_x = a->x; + test_y = a->y; +} + +void destroy_player() { + Actor* a = &actors[PLAYER]; + byte i; + sound_pia = 1; // play sound + for (i=0; i<60; i++) { + WATCHDOG; + while (video_counter != 0xfc) ; + blit_sprite_solid(a->shape, a->x, a->y, i); + while (video_counter == 0xfc) ; + } + for (i=1; i<60; i++) { + WATCHDOG; + while (video_counter != 0xfc) ; + blit_sprite_strided(a->shape, a->x+i, a->y, i); + blit_sprite_strided(a->shape, a->x-i, a->y, i); + while (video_counter == 0xfc) ; + } +} + +void random_walk(Actor* a) { + a->x += random_dir(); + a->y += random_dir(); + setup_collision(a); + if (actors[PLAYER].shape && test_collision_actor(&actors[PLAYER])) { + destroy_player(); + actors[PLAYER].shape = NULL; + } +} + +void laser_move(Actor* a) { + // did we hit something? + Actor* collided; + setup_collision(a); + collided = test_collisions(fast_list); + if (!collided) collided = test_collisions(slow_lists[0]); + if (!collided) collided = test_collisions(slow_lists[1]); + if (!collided) collided = test_collisions(slow_lists[2]); + if (!collided) collided = test_collisions(slow_lists[3]); + if (collided) { + // get rid of laser (we can do this in our 'update' fn) + a->shape = NULL; + // set exploding counter for enemy, change fn pointers + collided->draw = draw_actor_exploding; + collided->update = NULL; + collided->u.enemy.exploding = 1; + // move enemy to effects list + remove_actor(collided); + add_actor(&effects_list, collided); + // play sound + sound_pia = 2; + // add score + score = bcd_add(score, 5); + return; + } + // move laser + // check for wall collisions + a->x += a->u.laser.dx; + if (a->u.laser.dx > 0 && a->x < 8) a->shape = NULL; + if (a->u.laser.dx < 0 && a->x > 255-8) a->shape = NULL; + a->y += a->u.laser.dy; + if (a->y > 255-8) a->shape = NULL; +} + +void shoot_laser(sbyte dx, sbyte dy, const byte* shape) { + Actor* a = &actors[LASER]; + a->shape = (byte*) shape; + a->x = actors[PLAYER].x + 6; + a->y = actors[PLAYER].y + 8; + a->u.laser.dx = dx; + a->u.laser.dy = dy; + add_actor(&player_list, a); +} + +void player_laser() { + // is the laser being used? + if (actors[LASER].shape == NULL) { // no, check controls + if (UP2) shoot_laser(0,-8,laser_vert); + else if (DOWN2) shoot_laser(0,8,laser_vert); + else if (LEFT2) shoot_laser(-8,0,laser_horiz); + else if (RIGHT2) shoot_laser(8,0,laser_horiz); + } +} + +void player_move(Actor* a) { + byte x = a->x; + byte y = a->y; + if (UP1) y-=1; + if (DOWN1) y+=1; + if (LEFT1) x-=1; + if (RIGHT1) x+=1; + a->x = x; + a->y = y; + player_laser(); +} + +static Actor* current_effect; + +void effects_new_frame() { + current_effect = effects_list; +} + +void effects_next() { + if (current_effect) { + if (current_effect->draw) { + current_effect->draw(current_effect); + } else { + remove_actor(current_effect); + } + current_effect = current_effect->next; + } +} + +Actor* new_actor() { + Actor* a = free_list; + remove_actor(a); + a->draw = draw_actor_normal; + return a; +} + +Actor* new_effect(void (*draw)(struct Actor *)) { + Actor* a = new_actor(); + a->draw = draw; + add_actor(&effects_list, a); + return a; +} + +void init() { + byte i; + blit_solid(0, 0, 255, 255, 0); + memset(actors, 0, sizeof(actors)); + memcpy(palette, palette_data, 16); + player_list = fast_list = obstacle_list = free_list = NULL; + memset(slow_lists, 0, sizeof(slow_lists)); + // add all actors to free list + for (i=MAX_ACTORS-1; i>0; i--) { + add_actor(&free_list, &actors[i]); + } + score = 0; +} + +void make_player_actors() { + // make player + Actor* a = new_actor(); + a->x = 128; + a->y = 120; + a->shape = (byte*) playersprite1; + a->update = player_move; + add_actor(&player_list, a); + // make laser + a = new_actor(); + a->update = laser_move; + a->shape = NULL; +} + +void make_enemy_actors() { + byte i; + const byte num_actors = 32; + for (i=3; ix = (byte)xrand(); + a->y = (byte)xrand() + 24; + } while ((byte)(a->x - 96) < 64 && (byte)(a->y - 96) < 64); + a->shape = (byte*) all_sprites[i%9]; + a->update = random_walk; + a->draw = draw_actor_normal; + if (i < 5) add_actor(&fast_list, a); + else add_actor(&slow_lists[i&3], a); + WATCHDOG; + } +} + +void draw_bcd_word(word bcd, word x, byte y, byte color) { + byte j; + x += 4*4; + for (j=0; j<4; j++) { + x -= 4; + draw_char('0'+((byte)bcd & 0xf), x, y, color); + bcd >>= 4; + } +} + +void draw_score(Actor* a) { + a; + draw_string("Plyr 1", 278, 8, 0xee); + // draw digits in color 0 so the background is erased + draw_bcd_word(score, 278, 20, 0); + // last two digits of score are "00" + draw_char('0', 278+16, 20, 0); + draw_char('0', 278+20, 20, 0); +} + +void draw_playfield(Actor* a) { +// draw_box(0,0,275,255,0x11); +} + +int main() { + init(); + make_player_actors(); + make_enemy_actors(); + // add low-priority effects here, because new effects + // are added to the head of the list + new_effect(draw_score); + new_effect(draw_playfield); + // main loop + while (actors[PLAYER].shape) { + WATCHDOG; + effects_new_frame(); + while (video_counter >= 0x90) effects_next(); + update_screen_section(1); + while (video_counter < 0x90) effects_next(); + update_screen_section(0); + switch (frame & 7) { + case 0: + break; + } + score = bcd_add(score, 1); + frame++; + } + return 0; +} + +// SOUND ROM +/* +const byte __at(0x9000) SOUND_ROM[] = { +0xdb,0x00,0xb7,0x20,0x01,0x76,0x31,0x00,0x80,0xf3,0x11,0x00,0x40,0xdb,0x00,0x4f,0x0d,0x06,0x00,0x69,0x60,0x29,0x09,0x29,0x29,0x01,0x2b,0x01,0x09,0x01,0x0c,0x00,0xed,0xb0,0xcd,0xb5,0x01,0x3e,0x00,0xd3,0x00,0x76,0xc9,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0xc0,0x40,0x00,0x03,0x06,0x09,0x0c,0x10,0x13,0x16,0x19,0x1c,0x1f,0x22,0x25,0x28,0x2b,0x2e,0x31,0x33,0x36,0x39,0x3c, +0x3f,0x41,0x44,0x47,0x49,0x4c,0x4e,0x51,0x53,0x55,0x58,0x5a,0x5c,0x5e,0x60,0x62,0x64,0x66,0x68,0x6a,0x6b,0x6d,0x6f,0x70,0x71,0x73,0x74,0x75,0x76,0x78,0x79,0x7a,0x7a,0x7b,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,0x7c,0x7b,0x7a,0x7a,0x79,0x78,0x76,0x75,0x74,0x73,0x71,0x70,0x6f,0x6d,0x6b,0x6a,0x68,0x66,0x64,0x62,0x60,0x5e,0x5c,0x5a,0x58,0x55,0x53,0x51,0x4e,0x4c,0x49,0x47,0x44,0x41,0x3f,0x3c,0x39,0x36,0x33,0x31,0x2e,0x2b,0x28,0x25,0x22,0x1f,0x1c,0x19,0x16,0x13,0x10,0x0c,0x09,0x06,0x03,0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0x00,0x08,0x10,0x18,0x20, +0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,0x60,0x37,0x3f,0x5c,0x16,0xca,0xc2,0xa5,0xfe,0xba,0x77,0x89,0xaa,0x77,0x13,0xd8,0xae,0x82,0xfd,0x22,0x9c,0x46,0xde,0x14,0x50,0xb4,0x97,0x46,0x54,0x9d,0x60,0x2b,0xb0,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x0b,0x01,0xff,0x00,0xfa,0x00,0x00,0x00,0xe8,0x03,0xfc,0xff,0x6b,0x00,0x7f,0x00,0xf4,0x01,0x00,0x00,0xe8,0x03,0x02,0x00,0xeb,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0xff,0xff,0x2b,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0xff,0xff,0x4b,0x00,0x1f,0x00,0x58,0x02,0x00,0x00,0xb8,0x0b,0x01,0x00,0x2b,0x00,0x3f,0x00,0xb0,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x6b,0x00,0x7f,0x01,0xdd, +0xe5,0xdd,0x21,0x00,0x00,0xdd,0x39,0x3b,0xed,0x5b,0x08,0x40,0xed,0x4b,0x02,0x40,0xdd,0x70,0xff,0x3a,0x0a,0x40,0xdd,0xa6,0xff,0x6f,0x26,0x00,0x19,0x5e,0x3a,0x0c,0x40,0x93,0x38,0x03,0x7b,0xd3,0x00,0x2a,0x04,0x40,0x09,0x4d,0x44,0xed,0x43,0x02,0x40,0x33,0xdd,0xe1,0xc9,0x21,0x0c,0x40,0x36,0xff,0xed,0x4b,0x00,0x40,0x59,0x50,0x1b,0xed,0x53,0x00,0x40,0x78,0xb1,0xc8,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xcd,0x7f,0x01,0xed,0x4b,0x04,0x40,0x2a,0x06,0x40,0x09,0x4d,0x44,0xed,0x43,0x04,0x40,0xed,0x4b,0x06,0x40,0x3a,0x0b,0x40,0x6f,0x17,0x9f,0x67,0x09,0x4d,0x44,0xed,0x43,0x06,0x40, +0x2a,0x00,0x40,0x3e,0xff,0xbd,0x3e,0x00,0x9c,0x38,0xaf,0xfd,0x21,0x0c,0x40,0xfd,0x75,0x00,0x18,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +*/ diff --git a/presets/williams/gfxtest.c b/presets/williams/gfxtest.c index fb9f4614..ea9b4a6e 100644 --- a/presets/williams/gfxtest.c +++ b/presets/williams/gfxtest.c @@ -67,13 +67,13 @@ int main(void) { for (i=0; i<152; i++) { vidmem[0][i] = 16; vidmem[i][2] = 32; - blit_pixel(i, i, 0x77); - blit_pixel(i+1, i, 0x33); + draw_pixel(i, i, 0x77); + draw_pixel(i+1, i, 0x33); } while (1) { watchdog0x39 = 0x39; - draw_sprite(sprite1, 35, 20); - draw_sprite_solid(sprite1, 55, 20, 0x24); + blit_sprite(sprite1, 35, 20); + blit_sprite_solid(sprite1, 55, 20, 0x24); blit_solid(75, 20, 40, 20, 0x35); draw_string("HELLO WORLD", 20, 5, 0x88); } diff --git a/presets/williams/sprites.c b/presets/williams/sprites.c new file mode 100644 index 00000000..5c5bcddf --- /dev/null +++ b/presets/williams/sprites.c @@ -0,0 +1,334 @@ + +#include "williams.h" +//#link "williams.c" + +#include "stdlib.h" + +const byte palette_data[16] = { + 0x00, 0x03, 0x19, 0x50, 0x52, 0x07, 0x1f, 0x37, 0xe0, 0xa4, 0xfd, 0xff, 0x00, 0x00, 0x00, 0xf8, }; + +const byte sprite1[2+16*16/2] = { +8,16, +0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00, +0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00, +0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90, +0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49, +0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99, +0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90, +0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00, +0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00, +0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00, +0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00, +0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00, +0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00, +0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30, +0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00, +0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00, +0x00,0x09,0x99,0x00,0x00,0x99,0x90,0x00, +}; + +const byte sprite2[2+16*15/2] = { +8,16, +0x00,0x94,0x94,0x90,0x09,0x49,0x49,0x00, +0x04,0x49,0x49,0x90,0x09,0x94,0x94,0x90, +0x94,0x99,0x94,0x90,0x09,0x49,0x99,0x49, +0x99,0x99,0x49,0x93,0x39,0x94,0x99,0x99, +0x04,0x49,0x99,0x94,0x49,0x99,0x94,0x90, +0x00,0x94,0x94,0x43,0x34,0x49,0x49,0x00, +0x00,0x09,0x43,0x94,0x49,0x34,0x90,0x00, +0x00,0x90,0x00,0x39,0x93,0x00,0x09,0x00, +0x00,0x09,0x83,0x33,0x33,0x33,0x90,0x00, +0x00,0x09,0x32,0x23,0x32,0x23,0x90,0x00, +0x00,0x03,0x03,0x23,0x82,0x30,0x30,0x00, +0x03,0x30,0x00,0x33,0x33,0x00,0x03,0x30, +0x00,0x30,0x03,0x00,0x00,0x30,0x03,0x00, +0x00,0x00,0x00,0x30,0x03,0x00,0x00,0x00, +0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00, +}; + +const byte sprite3[2+16*16/2] = { +8,16, +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x00,0x00,0x11,0x11,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x00, +0x00,0x11,0x10,0x01,0x10,0x01,0x11,0x00, +0x11,0x00,0x10,0x11,0x11,0x01,0x00,0x11, +0x10,0x00,0x11,0x11,0x11,0x11,0x00,0x01, +0x10,0x00,0x00,0x11,0x11,0x00,0x00,0x01, +0x00,0x01,0x10,0x11,0x41,0x01,0x10,0x00, +0x00,0x10,0x11,0x11,0x11,0x11,0x01,0x00, +0x01,0x00,0x00,0x51,0x15,0x00,0x00,0x10, +0x01,0x00,0x01,0x10,0x01,0x10,0x00,0x10, +0x01,0x00,0x10,0x00,0x00,0x01,0x00,0x10, +0x00,0x10,0x01,0x00,0x00,0x10,0x01,0x00, +0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00, +0x00,0x01,0x10,0x00,0x00,0x01,0x10,0x00, +}; + +const byte sprite4[2+16*16/2] = { +8,16, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00, +0x00,0x00,0x00,0xbb,0xbb,0x00,0x00,0x00, +0x00,0x00,0xbb,0xbb,0xbb,0xbb,0x00,0x00, +0x00,0x0b,0x4b,0xbb,0xbb,0xb4,0xb0,0x00, +0x00,0x0b,0x44,0xbb,0xbb,0x49,0xb0,0x00, +0x00,0xbb,0x99,0x4b,0xb4,0x99,0xbb,0x00, +0x00,0x4b,0xb9,0x9b,0xb4,0x4b,0xb4,0x00, +0x00,0x04,0xbb,0x4b,0xb9,0xbb,0x40,0x00, +0x00,0x00,0x4b,0xbb,0xbb,0xb4,0x00,0x00, +0x11,0x00,0x0b,0xbb,0xbb,0xb0,0x00,0x11, +0x10,0x10,0x0b,0x41,0x14,0xb0,0x01,0x01, +0x10,0x00,0x05,0x11,0x11,0x50,0x00,0x01, +0x01,0x00,0x01,0x51,0x15,0x10,0x00,0x10, +0x00,0x10,0x01,0x10,0x01,0x10,0x01,0x00, +0x01,0x01,0x10,0x10,0x01,0x01,0x10,0x10, +}; + +const byte sprite5[2+16*16/2] = { +8,16, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x22,0x00,0x00,0x22,0x00,0x00, +0x00,0x20,0x20,0x00,0x00,0x02,0x02,0x00, +0x02,0x22,0x12,0x00,0x00,0x21,0x22,0x20, +0x00,0x02,0x11,0x00,0x00,0x11,0x20,0x00, +0x00,0x00,0x02,0x11,0x11,0x20,0x00,0x00, +0x00,0x00,0x02,0x22,0x22,0x20,0x00,0x00, +0x00,0x00,0x21,0x22,0x22,0x12,0x00,0x00, +0x00,0x00,0x22,0x12,0x21,0x22,0x00,0x00, +0x02,0x00,0x22,0x12,0x21,0x22,0x00,0x20, +0x20,0x02,0x21,0x11,0x11,0x12,0x20,0x02, +0x02,0x22,0x15,0x12,0x21,0x51,0x22,0x20, +0x02,0x11,0x15,0x52,0x25,0x51,0x11,0x20, +0x20,0x00,0x22,0x12,0x21,0x22,0x00,0x02, +0x20,0x02,0x20,0x20,0x02,0x02,0x20,0x02, +0x02,0x02,0x00,0x20,0x02,0x00,0x20,0x20, +}; + +const byte sprite6[2+16*10/2] = { +8,10, +0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00, +0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x40, +0x00,0x00,0x04,0x04,0x49,0x49,0x99,0x44, +0x00,0x00,0x44,0x44,0x99,0x94,0x44,0x40, +0x00,0x04,0x49,0x99,0x94,0x49,0x99,0x40, +0x00,0x44,0x99,0x94,0x49,0x99,0x44,0x00, +0x04,0x49,0x44,0x99,0x99,0x44,0x00,0x00, +0x04,0x44,0x00,0x49,0x44,0x40,0x00,0x00, +0x04,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +const byte sprite7[2+16*14/2] = { +8,14, +0x00,0x60,0x00,0x00,0x00,0x00,0x06,0x00, +0x60,0x60,0x00,0x00,0x00,0x00,0x06,0x06, +0x60,0x60,0x50,0x00,0x00,0x05,0x06,0x06, +0x60,0x60,0x06,0x00,0x00,0x60,0x06,0x06, +0x66,0x60,0x06,0x06,0x60,0x60,0x06,0x66, +0x66,0x60,0x66,0x66,0x66,0x66,0x06,0x66, +0x66,0x60,0x6b,0x6b,0xb6,0xb6,0x06,0x66, +0x06,0x66,0x66,0xb6,0x6b,0x66,0x66,0x60, +0x00,0x67,0x66,0x66,0x66,0x66,0x66,0x00, +0x00,0x11,0x11,0x66,0x66,0x11,0x11,0x00, +0x01,0x11,0x21,0x11,0x11,0x12,0x11,0x10, +0x00,0x10,0x01,0x01,0x10,0x10,0x01,0x00, +0x00,0x10,0x11,0x00,0x00,0x11,0x01,0x00, +0x00,0x00,0x10,0x00,0x00,0x01,0x00,0x00, +}; + +const byte sprite8[2+16*15/2] = { +8,15, +0x00,0x00,0x11,0x11,0x11,0x11,0x00,0x00, +0x00,0x01,0x61,0x11,0x21,0x12,0x10,0x00, +0x00,0x11,0x12,0x11,0x61,0x11,0x11,0x00, +0x00,0x11,0x71,0x21,0x61,0x17,0x11,0x00, +0x00,0x11,0x77,0x11,0x12,0x77,0x11,0x00, +0x00,0x11,0x17,0x17,0x71,0x72,0x11,0x00, +0x00,0x16,0x21,0x78,0x87,0x11,0x11,0x00, +0x00,0x01,0x81,0x88,0x88,0x18,0x10,0x00, +0x00,0x08,0x18,0x58,0x85,0x81,0x80,0x00, +0x00,0x88,0x01,0x88,0x88,0x10,0x88,0x00, +0x00,0x08,0x07,0x78,0x87,0x70,0x80,0x00, +0x08,0x80,0x07,0x80,0x08,0x70,0x08,0x80, +0x88,0x00,0x88,0x00,0x00,0x88,0x00,0x88, +0x80,0x00,0x08,0x80,0x08,0x80,0x00,0x08, +0x00,0x00,0x00,0x80,0x08,0x00,0x00,0x00, +}; + +const byte sprite9[2+13*16/2] = { +8,13, +0x00,0x00,0xaa,0x00,0x00,0xaa,0x00,0x00, +0x00,0x00,0xa0,0x0a,0xa0,0x0a,0x00,0x00, +0x0a,0xaa,0xa4,0xaa,0xaa,0x3a,0xaa,0xa0, +0x00,0x0a,0x3a,0x9a,0xa9,0xa3,0xa0,0x00, +0x00,0x0a,0xaa,0x99,0xa4,0xaa,0xa0,0x00, +0x00,0x0a,0xaa,0x99,0x94,0xaa,0xa0,0x00, +0x00,0xaa,0x33,0xaa,0xaa,0x43,0xaa,0x00, +0x0a,0x3a,0xaa,0x3a,0xa3,0xaa,0xa3,0xa0, +0x00,0xaa,0xaa,0x30,0x03,0xaa,0xaa,0x00, +0x00,0x0a,0xa0,0x30,0x03,0x0a,0xa0,0x00, +0x00,0xa3,0xa0,0x00,0x00,0x0a,0x4a,0x00, +0x00,0xaa,0xa0,0x00,0x00,0x0a,0xaa,0x00, +0x00,0x0a,0xa0,0x00,0x00,0x0a,0xa0,0x00, +}; + +const byte* const all_sprites[9] = { + sprite1, + sprite2, + sprite3, + sprite4, + sprite5, + sprite6, + sprite7, + sprite8, + sprite9, +}; + +//typedef void ActorUpdateFn(struct Actor* a); +//typedef void ActorDrawFn(struct Actor* a); +//typedef void ActorEnumerateFn(struct Actor* a); + +typedef struct Actor { + byte grid_index; + byte next_actor; + byte x,y; + byte* shape; + void (*update)(struct Actor* a); + void (*draw)(struct Actor* a); +} Actor; + +#define GBITS 3 +#define GDIM (1<> (8-GBITS)) | (y & ((GDIM-1) << GBITS)); +} + +void insert_into_grid(byte gi, byte actor_index) { + struct Actor* a = &actors[actor_index]; + a->grid_index = gi; + a->next_actor = grid[gi]; + grid[gi] = actor_index; +} + +void delete_from_grid(byte gi, byte actor_index) { + byte i = grid[gi]; + byte next = actors[actor_index].next_actor; + // is actor to delete at head of list? + if (i == actor_index) { + grid[gi] = next; + } else { + // iterate through the list + do { + byte j = actors[i].next_actor; + if (j == actor_index) { + actors[i].next_actor = next; + break; + } + i = j; + } while (1); // watchdog reset if actor not found to delete + } + actors[actor_index].next_actor = 0; + actors[actor_index].grid_index = 0; +} + +void draw_actor(struct Actor* a) { + blit_sprite(a->shape, a->x, a->y); +} + +void draw_actor_debug(struct Actor* a) { + blit_sprite_solid(a->shape, a->x, a->y, a->next_actor?0xff:0x33); +} + +byte update_actor(byte actor_index) { + struct Actor* a = &actors[actor_index]; + byte next_actor; + byte gi0,gi1; + if (!a->shape) return 0; + next_actor = a->next_actor; + gi0 = a->grid_index; + blit_sprite_solid(a->shape, a->x, a->y, 0); + if (a->update) a->update(a); + if (a->draw) a->draw(a); + //draw_sprite_strided(a->shape, a->x, a->y, 2); + gi1 = xy2grid(a->x, a->y); + if (gi0 != gi1) { + delete_from_grid(gi0, actor_index); + insert_into_grid(gi1, actor_index); + } + return next_actor; +} + +// + +word lfsr = 1; + +word xrand() { + byte lsb = (byte)(lfsr & 1); + lfsr >>= 1; + if (lsb) lfsr ^= 0xd400; + return lfsr; +} + +signed char random_dir() { + byte x = (byte)xrand(); + if (x < 85) return 0; + else if (x < 85*2) return -1; + else return 1; +} + +void random_walk(Actor* a) { + a->x += random_dir(); + a->y += random_dir(); +} + +void update_grid_cell(byte grid_index) { + byte actor_index = grid[grid_index]; + while (actor_index) { + actor_index = update_actor(actor_index); + } +} + +void update_grid_rows(byte row_start, byte row_end) { + byte i0 = row_start * GDIM; + byte i1 = row_end * GDIM; + byte i; + for (i=i0; i!=i1; i++) { + update_grid_cell(i); + } +} + +int main() { + byte i; + byte num_actors = 32; + blit_solid(0, 0, 255, 255, 0); + memset(grid, 0, sizeof(grid)); + memset(actors, 0, sizeof(actors)); + memcpy(palette, palette_data, 16); + for (i=1; ix = (i & 3) * 16 + 32; + a->y = (i / 4) * 16 + 64; + a->shape = (byte*) all_sprites[i%9]; + a->update = random_walk; + a->draw = draw_actor; // draw_actor_debug; + insert_into_grid(xy2grid(a->x, a->y), i); + watchdog0x39 = 0x39; + } + while (1) { + // update top half while drawing bottom half + while (video_counter < 0x80) ; + update_grid_rows(0,GDIM/2); + // update bottom half while drawing top half + while (video_counter >= 0x80) ; + update_grid_rows(GDIM/2,GDIM); + watchdog0x39 = 0x39; + } + return 0; +} diff --git a/presets/williams/williams.c b/presets/williams/williams.c index 1bad3294..df7d8261 100644 --- a/presets/williams/williams.c +++ b/presets/williams/williams.c @@ -1,8 +1,12 @@ #include "williams.h" +// bias sprites by +4 pixels +#define XBIAS 2 + // 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; @@ -26,44 +30,39 @@ void blit_copy_solid(byte x1, byte y1, byte w, byte h, const byte* data, byte so blitter.sstart = (word)data; blitter.dstart = ((word)x1<<8)+y1; // swapped blitter.solid = solid; - blitter.flags = DSTSCREEN|FGONLY|SOLID; + if (solid) + blitter.flags = DSTSCREEN|FGONLY|SOLID; + else + blitter.flags = DSTSCREEN; } -void draw_sprite(const byte* data, byte x, byte y) { +void blit_sprite(const byte* data, byte x, byte y) { blitter.width = data[0]^4; blitter.height = data[1]^4; blitter.sstart = (word)(data+2); - blitter.dstart = ((word)x<<8)+y; // swapped + blitter.dstart = ((word)(x+XBIAS)<<8)+y; // swapped blitter.solid = 0; blitter.flags = DSTSCREEN|FGONLY; } -void blit_pixel(word xx, byte y, byte color) { - blitter.width = 1^4; - blitter.height = 1^4; - blitter.dstart = (((xx>>1)&0xff)<<8)+y; // swapped - blitter.solid = color; - blitter.flags = (xx&1) ? SOLID|ODDONLY : SOLID|EVENONLY; -} - -void draw_sprite_solid(const byte* data, byte x, byte y, byte color) { +void blit_sprite_solid(const byte* data, byte x, byte y, byte color) { blitter.width = data[0]^4; blitter.height = data[1]^4; blitter.sstart = (word)(data+2); - blitter.dstart = ((word)x<<8)+y; // swapped + blitter.dstart = ((word)(x+XBIAS)<<8)+y; // swapped blitter.solid = color; blitter.flags = DSTSCREEN|FGONLY|SOLID; } -void erase_sprite_rect(const byte* data, byte x, byte y) { +void unblit_sprite_rect(const byte* data, byte x, byte y) { blitter.width = data[0]^4; blitter.height = data[1]^4; - blitter.dstart = ((word)x<<8)+y; // swapped + blitter.dstart = ((word)(x+XBIAS)<<8)+y; // swapped blitter.solid = 0; blitter.flags = DSTSCREEN|SOLID; } -void draw_sprite_strided(const byte* data, byte x, byte y, byte stride) { +void blit_sprite_strided(const byte* data, byte x, byte y, byte stride) { const byte* src = data+2; byte height = data[1]^4; byte width = data[0]^4; @@ -73,3 +72,74 @@ void draw_sprite_strided(const byte* data, byte x, byte y, byte stride) { src += width; } } + +void unblit_sprite_strided(const byte* data, byte x, byte y, byte stride) { + byte height = data[1]^4; + byte width = data[0]^4; + while (height--) { + blit_solid(x, y, width, 1, 0); + y += stride; + } +} + +void blit_vline(word x1, byte y1, byte h, byte color) { + blitter.width = 1^4; + blitter.height = h^4; + blitter.dstart = ((word)x1<<8)+y1; // swapped + blitter.solid = color; + blitter.flags = (x1&1) ? DSTSCREEN|SOLID|ODDONLY : DSTSCREEN|SOLID|EVENONLY; +} + +// x: 0-303 + +void draw_solid(word xx, byte y, byte w, byte h, byte color) { + blitter.width = w^4; + blitter.height = h^4; + blitter.dstart = ((xx<<7)&0xff00)+y; // swapped + blitter.solid = color; + blitter.flags = (xx&1) ? DSTSCREEN|SOLID|RSHIFT : DSTSCREEN|SOLID; +} + +void draw_vline(word xx, byte y, byte h, byte color) { + blitter.width = 1^4; + blitter.height = h^4; + blitter.dstart = ((xx<<7)&0xff00)+y; // swapped + blitter.solid = color; + blitter.flags = (xx&1) ? DSTSCREEN|SOLID|ODDONLY : DSTSCREEN|SOLID|EVENONLY; +} + +void draw_copy_solid(word xx, byte y, byte w, byte h, const byte* data, byte solid) { + blitter.width = w^4; + blitter.height = h^4; + blitter.solid = solid; + blitter.sstart = data; + blitter.dstart = ((xx<<7)&0xff00)+y; // swapped + if (solid) + blitter.flags = (xx&1) ? DSTSCREEN|FGONLY|SOLID|RSHIFT : DSTSCREEN|FGONLY|SOLID; + else + blitter.flags = (xx&1) ? DSTSCREEN|RSHIFT : DSTSCREEN; +} + +void draw_pixel(word xx, byte y, byte color) { + blitter.width = 1^4; + blitter.height = 1^4; + blitter.dstart = (((xx>>1)&0xff)<<8)+y; // swapped + blitter.solid = color; + blitter.flags = (xx&1) ? SOLID|ODDONLY : SOLID|EVENONLY; +} + + +// BCD + +asm word bcd_add(word a, word b) { + asm { + lda 3,s + adda 5,s + daa + exg b,a + lda 2,s + adca 4,s + daa + } +} + diff --git a/presets/williams/williams.h b/presets/williams/williams.h index 36ec034c..1e82a0df 100644 --- a/presets/williams/williams.h +++ b/presets/williams/williams.h @@ -3,8 +3,12 @@ #define _WILLIAMS_H typedef unsigned char byte; +typedef unsigned char bool; +typedef signed char sbyte; typedef unsigned short word; +enum { false=0, true=1 }; + byte* palette = 0xc000; byte* nvram = 0xcc00; @@ -16,6 +20,8 @@ byte* nvram = 0xcc00; #define video_counter *((byte*)0xcb00) #define watchdog0x39 *((byte*)0xcbff) +#define WATCHDOG (watchdog0x39 = 0x39) + // switch flags #define UP1 (input0 & 0x1) @@ -85,16 +91,27 @@ void blit_copy(byte x1, byte y1, byte w, byte h, const byte* data); void blit_copy_solid(byte x1, byte y1, byte w, byte h, const byte* data, byte solid); -void draw_sprite(const byte* data, byte x, byte y); +void blit_sprite(const byte* data, byte x, byte y); -void draw_sprite_solid(const byte* data, byte x, byte y, byte color); +void blit_sprite_solid(const byte* data, byte x, byte y, byte color); -void erase_sprite_rect(const byte* data, byte x, byte y); +void unblit_sprite_rect(const byte* data, byte x, byte y); -void draw_sprite_strided(const byte* data, byte x, byte y, byte stride); +void blit_sprite_strided(const byte* data, byte x, byte y, byte stride); + +void unblit_sprite_strided(const byte* data, byte x, byte y, byte stride); // x1: 0-303 // y1: 0-255 -void blit_pixel(word xx, byte y, byte color); +void draw_pixel(word xx, byte y, byte color); + +void draw_solid(word x, byte y, byte w, byte h, byte color); + +void draw_vline(word x, byte y, byte h, byte color); + +void draw_copy_solid(word x, byte y, byte w, byte h, const byte* data, byte solid); + +// BCD +asm word bcd_add(word a, word b); #endif diff --git a/src/common/workertypes.ts b/src/common/workertypes.ts index 07fbc2ff..44972162 100644 --- a/src/common/workertypes.ts +++ b/src/common/workertypes.ts @@ -7,6 +7,8 @@ export interface SourceLocation { path?: string; // TODO: make mandatory? start?: number; end?: number; + segment?:string; + func?:string; } // actually it's a kind of SourceSnippet .. can have multiple per line diff --git a/src/worker/tools/m6809.ts b/src/worker/tools/m6809.ts index ead8f41c..760872eb 100644 --- a/src/worker/tools/m6809.ts +++ b/src/worker/tools/m6809.ts @@ -220,7 +220,11 @@ export function linkLWLINK(step: BuildStep): BuildStepResult { if (toks[0] == 'Symbol:') { let ident = toks[1]; let ofs = parseInt(toks[4], 16); - if (ident && ofs >= 0 && !ident.startsWith("l_") && !/^L\d+$/.test(ident)) { + if (ident && ofs >= 0 + && !ident.startsWith("l_") + //&& !/^L\d+$/.test(ident) + && !ident.startsWith('funcsize_') + && !ident.startsWith('funcend_')) { symbolmap[ident] = ofs; } } @@ -232,14 +236,22 @@ export function linkLWLINK(step: BuildStep): BuildStepResult { } } // build listings + const re_segment = /\s*SECTION\s+(\w+)/i; + const re_function = /\s*([0-9a-f]+).+?(\w+)\s+EQU\s+[*]/i; var listings: CodeListingMap = {}; for (var fn of step.files) { if (fn.endsWith('.lst')) { // TODO var lstout = FS.readFile(fn, { encoding: 'utf8' }); - var asmlines = parseListing(lstout, /^([0-9A-F]+)\s+([0-9A-F]+)\s+[(]\s*(.+?)[)]:(\d+) (.*)/i, 4, 1, 2, 3); + var asmlines = parseListing(lstout, /^([0-9A-F]+)\s+([0-9A-F]+)\s+[(]\s*(.+?)[)]:(\d+) (.*)/i, 4, 1, 2, 3, re_function, re_segment); + for (let l of asmlines) { + l.offset += symbolmap[l.func] || 0; + } // * Line //threed.c:117: init of variable e - var srclines = parseSourceLines(lstout, /Line .+?:(\d+)/i, /^([0-9A-F]{4})/i); + var srclines = parseSourceLines(lstout, /Line .+?:(\d+)/i, /^([0-9A-F]{4})/i, re_function, re_segment); + for (let l of srclines) { + l.offset += symbolmap[l.func] || 0; + } putWorkFile(fn, lstout); // strip out left margin lstout = lstout.split('\n').map(l => l.substring(0,15) + l.substring(56)).join('\n') diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index fc5347f4..6533fc00 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -886,10 +886,20 @@ export const re_crlf = /\r?\n/; // 1 %line 16+1 hello.asm export const re_lineoffset = /\s*(\d+)\s+[%]line\s+(\d+)\+(\d+)\s+(.+)/; -export function parseListing(code:string, lineMatch, iline:number, ioffset:number, iinsns:number, icycles?:number) : SourceLine[] { +export function parseListing(code:string, + lineMatch, iline:number, ioffset:number, iinsns:number, icycles?:number, + funcMatch?, segMatch?) : SourceLine[] { var lines : SourceLine[] = []; var lineofs = 0; + var segment = ''; + var func = ''; + var funcbase = 0; code.split(re_crlf).forEach((line, lineindex) => { + let segm = segMatch && segMatch.exec(line); + if (segm) { segment = segm[1]; } + let funcm = funcMatch && funcMatch.exec(line); + if (funcm) { funcbase = parseInt(funcm[1],16); func = funcm[2]; } + var linem = lineMatch.exec(line); if (linem && linem[1]) { var linenum = iline < 0 ? lineindex : parseInt(linem[iline]); @@ -899,11 +909,13 @@ export function parseListing(code:string, lineMatch, iline:number, ioffset:numbe var iscode = cycles > 0; if (insns) { lines.push({ - line:linenum + lineofs, - offset:offset, - insns:insns, - cycles:cycles, - iscode:iscode + line: linenum + lineofs, + offset: offset - funcbase, + insns, + cycles, + iscode, + segment, + func }); } } else { @@ -917,10 +929,18 @@ export function parseListing(code:string, lineMatch, iline:number, ioffset:numbe return lines; } -export function parseSourceLines(code:string, lineMatch, offsetMatch) { +export function parseSourceLines(code:string, lineMatch, offsetMatch, funcMatch?, segMatch?) { var lines = []; var lastlinenum = 0; + var segment = ''; + var func = ''; + var funcbase = 0; for (var line of code.split(re_crlf)) { + let segm = segMatch && segMatch.exec(line); + if (segm) { segment = segm[1]; } + let funcm = funcMatch && funcMatch.exec(line); + if (funcm) { funcbase = parseInt(funcm[1],16); func = funcm[2]; } + var linem = lineMatch.exec(line); if (linem && linem[1]) { lastlinenum = parseInt(linem[1]); @@ -929,8 +949,10 @@ export function parseSourceLines(code:string, lineMatch, offsetMatch) { if (linem && linem[1]) { var offset = parseInt(linem[1], 16); lines.push({ - line:lastlinenum, - offset:offset, + line: lastlinenum, + offset: offset - funcbase, + segment, + func }); lastlinenum = 0; } diff --git a/test/cli/testworker.js b/test/cli/testworker.js index 493183fa..43fd983c 100644 --- a/test/cli/testworker.js +++ b/test/cli/testworker.js @@ -262,5 +262,10 @@ describe('Worker', function() { it('should compile CC65 flags', function(done) { compile('cc65', '#define CC65_FLAGS -Or,-g,-j\nint main() {\nint x=1;\nreturn x+2;\n}', 'apple2', done, 416, 3); }); + /* + it('should compile CMOC', function(done) { + compile('cmoc', 'int foo=0; // comment\n#if defined(__8BITWORKSHOP__) && defined(__MAIN__)\nint main(int argc) {\nint x=1;\nint y=2+argc;\nreturn x+y+argc;\n}\n#endif\n', 'williams', done, 8192, 3, 0, {filename:'test.c'}); + }); + */ });