diff --git a/presets/vector-z80color/font.c b/presets/vector-z80color/font.c new file mode 100644 index 00000000..00235248 --- /dev/null +++ b/presets/vector-z80color/font.c @@ -0,0 +1,212 @@ + +#include + +typedef unsigned char byte; +typedef unsigned short word; + +void main(); + +void start() { +__asm + LD SP,#0x0 + DI +__endasm; + main(); +} + +int dvgwrofs; // write offset for DVG buffer + +inline word ___swapw(word j) { + return ((j << 8) | (j >> 8)); +} + +word __at(0xa000) dvgram[0x1000]; +byte __at(0x8840) _dvgstart; + +inline void dvgreset() { + dvgwrofs = 0; +} + +inline void dvgstart() { + _dvgstart = 0; +} + +void dvgwrite(word w) { + dvgram[dvgwrofs++] = w; +} + +inline void VCTR(int dx, int dy, byte bright) { + dvgwrite((dx & 0x1fff)); + dvgwrite(((bright & 7) << 13) | (dy & 0x1fff)); +} + +inline void SVEC(signed char dx, signed char dy, byte bright) { + dvgwrite(0x4000 | (dx & 0x1f) | ((bright&7)<<5) | ((dy & 0x1f)<<8)); +} + +inline void JSRL(word offset) { + dvgwrite(0xa000 | offset); +} + +inline void JMPL(word offset) { + dvgwrite(0xe000 | offset); +} + +inline void RTSL() { + dvgwrite(0xc000); +} + +inline void CNTR() { + dvgwrite(0x8000); +} + +inline void HALT() { + dvgwrite(0x2000); +} + +inline void STAT(byte rgb, byte intens) { + dvgwrite(0x6000 | ((intens & 0xf)<<4) | (rgb & 7)); +} + +inline void SCAL(word scale) { + dvgwrite(0x7000 | scale); +} + +enum { + BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE +} Color; + +/// https://trmm.net/Asteroids_font + +#define P(x,y) ((((x) & 0xF) << 4) | (((y) & 0xF) << 0)) +#define FONT_UP 0xFE +#define FONT_LAST 0xFF + +const byte vecfont[95][8] = { + ['0' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), P(8,12), FONT_LAST }, + ['1' - 0x20] = { P(4,0), P(4,12), P(3,10), FONT_LAST }, + ['2' - 0x20] = { P(0,12), P(8,12), P(8,7), P(0,5), P(0,0), P(8,0), FONT_LAST }, + ['3' - 0x20] = { P(0,12), P(8,12), P(8,0), P(0,0), FONT_UP, P(0,6), P(8,6), FONT_LAST }, + ['4' - 0x20] = { P(0,12), P(0,6), P(8,6), FONT_UP, P(8,12), P(8,0), FONT_LAST }, + ['5' - 0x20] = { P(0,0), P(8,0), P(8,6), P(0,7), P(0,12), P(8,12), FONT_LAST }, + ['6' - 0x20] = { P(0,12), P(0,0), P(8,0), P(8,5), P(0,7), FONT_LAST }, + ['7' - 0x20] = { P(0,12), P(8,12), P(8,6), P(4,0), FONT_LAST }, + ['8' - 0x20] = { P(0,0), P(8,0), P(8,12), P(0,12), P(0,0), FONT_UP, P(0,6), P(8,6), }, + ['9' - 0x20] = { P(8,0), P(8,12), P(0,12), P(0,7), P(8,5), FONT_LAST }, + [' ' - 0x20] = { FONT_LAST }, + ['.' - 0x20] = { P(3,0), P(4,0), FONT_LAST }, + [',' - 0x20] = { P(2,0), P(4,2), FONT_LAST }, + ['-' - 0x20] = { P(2,6), P(6,6), FONT_LAST }, + ['+' - 0x20] = { P(1,6), P(7,6), FONT_UP, P(4,9), P(4,3), FONT_LAST }, + ['!' - 0x20] = { P(4,0), P(3,2), P(5,2), P(4,0), FONT_UP, P(4,4), P(4,12), FONT_LAST }, + ['#' - 0x20] = { P(0,4), P(8,4), P(6,2), P(6,10), P(8,8), P(0,8), P(2,10), P(2,2) }, + ['^' - 0x20] = { P(2,6), P(4,12), P(6,6), FONT_LAST }, + ['=' - 0x20] = { P(1,4), P(7,4), FONT_UP, P(1,8), P(7,8), FONT_LAST }, + ['*' - 0x20] = { P(0,0), P(4,12), P(8,0), P(0,8), P(8,8), P(0,0), FONT_LAST }, + ['_' - 0x20] = { P(0,0), P(8,0), FONT_LAST }, + ['/' - 0x20] = { P(0,0), P(8,12), FONT_LAST }, + ['\\' - 0x20] = { P(0,12), P(8,0), FONT_LAST }, + ['@' - 0x20] = { P(8,4), P(4,0), P(0,4), P(0,8), P(4,12), P(8,8), P(4,4), P(3,6) }, + ['$' - 0x20] = { P(6,2), P(2,6), P(6,10), FONT_UP, P(4,12), P(4,0), FONT_LAST }, + ['&' - 0x20] = { P(8,0), P(4,12), P(8,8), P(0,4), P(4,0), P(8,4), FONT_LAST }, + ['[' - 0x20] = { P(6,0), P(2,0), P(2,12), P(6,12), FONT_LAST }, + [']' - 0x20] = { P(2,0), P(6,0), P(6,12), P(2,12), FONT_LAST }, + ['(' - 0x20] = { P(6,0), P(2,4), P(2,8), P(6,12), FONT_LAST }, + [')' - 0x20] = { P(2,0), P(6,4), P(6,8), P(2,12), FONT_LAST }, + ['{' - 0x20] = { P(6,0), P(4,2), P(4,10), P(6,12), FONT_UP, P(2,6), P(4,6), FONT_LAST }, + ['}' - 0x20] = { P(4,0), P(6,2), P(6,10), P(4,12), FONT_UP, P(6,6), P(8,6), FONT_LAST }, + ['%' - 0x20] = { P(0,0), P(8,12), FONT_UP, P(2,10), P(2,8), FONT_UP, P(6,4), P(6,2) }, + ['<' - 0x20] = { P(6,0), P(2,6), P(6,12), FONT_LAST }, + ['>' - 0x20] = { P(2,0), P(6,6), P(2,12), FONT_LAST }, + ['|' - 0x20] = { P(4,0), P(4,5), FONT_UP, P(4,6), P(4,12), FONT_LAST }, + [':' - 0x20] = { P(4,9), P(4,7), FONT_UP, P(4,5), P(4,3), FONT_LAST }, + [';' - 0x20] = { P(4,9), P(4,7), FONT_UP, P(4,5), P(1,2), FONT_LAST }, + ['"' - 0x20] = { P(2,10), P(2,6), FONT_UP, P(6,10), P(6,6), FONT_LAST }, + ['\'' - 0x20] = { P(2,6), P(6,10), FONT_LAST }, + ['`' - 0x20] = { P(2,10), P(6,6), FONT_LAST }, + ['~' - 0x20] = { P(0,4), P(2,8), P(6,4), P(8,8), FONT_LAST }, + ['?' - 0x20] = { P(0,8), P(4,12), P(8,8), P(4,4), FONT_UP, P(4,1), P(4,0), FONT_LAST }, + ['A' - 0x20] = { P(0,0), P(0,8), P(4,12), P(8,8), P(8,0), FONT_UP, P(0,4), P(8,4) }, + ['B' - 0x20] = { P(0,0), P(0,12), P(4,12), P(8,10), P(4,6), P(8,2), P(4,0), P(0,0) }, + ['C' - 0x20] = { P(8,0), P(0,0), P(0,12), P(8,12), FONT_LAST }, + ['D' - 0x20] = { P(0,0), P(0,12), P(4,12), P(8,8), P(8,4), P(4,0), P(0,0), FONT_LAST }, + ['E' - 0x20] = { P(8,0), P(0,0), P(0,12), P(8,12), FONT_UP, P(0,6), P(6,6), FONT_LAST }, + ['F' - 0x20] = { P(0,0), P(0,12), P(8,12), FONT_UP, P(0,6), P(6,6), FONT_LAST }, + ['G' - 0x20] = { P(6,6), P(8,4), P(8,0), P(0,0), P(0,12), P(8,12), FONT_LAST }, + ['H' - 0x20] = { P(0,0), P(0,12), FONT_UP, P(0,6), P(8,6), FONT_UP, P(8,12), P(8,0) }, + ['I' - 0x20] = { P(0,0), P(8,0), FONT_UP, P(4,0), P(4,12), FONT_UP, P(0,12), P(8,12) }, + ['J' - 0x20] = { P(0,4), P(4,0), P(8,0), P(8,12), FONT_LAST }, + ['K' - 0x20] = { P(0,0), P(0,12), FONT_UP, P(8,12), P(0,6), P(6,0), FONT_LAST }, + ['L' - 0x20] = { P(8,0), P(0,0), P(0,12), FONT_LAST }, + ['M' - 0x20] = { P(0,0), P(0,12), P(4,8), P(8,12), P(8,0), FONT_LAST }, + ['N' - 0x20] = { P(0,0), P(0,12), P(8,0), P(8,12), FONT_LAST }, + ['O' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,0), P(0,0), FONT_LAST }, + ['P' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,6), P(0,5), FONT_LAST }, + ['Q' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,4), P(0,0), FONT_UP, P(4,4), P(8,0) }, + ['R' - 0x20] = { P(0,0), P(0,12), P(8,12), P(8,6), P(0,5), FONT_UP, P(4,5), P(8,0) }, + ['S' - 0x20] = { P(0,2), P(2,0), P(8,0), P(8,5), P(0,7), P(0,12), P(6,12), P(8,10) }, + ['T' - 0x20] = { P(0,12), P(8,12), FONT_UP, P(4,12), P(4,0), FONT_LAST }, + ['U' - 0x20] = { P(0,12), P(0,2), P(4,0), P(8,2), P(8,12), FONT_LAST }, + ['V' - 0x20] = { P(0,12), P(4,0), P(8,12), FONT_LAST }, + ['W' - 0x20] = { P(0,12), P(2,0), P(4,4), P(6,0), P(8,12), FONT_LAST }, + ['X' - 0x20] = { P(0,0), P(8,12), FONT_UP, P(0,12), P(8,0), FONT_LAST }, + ['Y' - 0x20] = { P(0,12), P(4,6), P(8,12), FONT_UP, P(4,6), P(4,0), FONT_LAST }, + ['Z' - 0x20] = { P(0,12), P(8,12), P(0,0), P(8,0), FONT_UP, P(2,6), P(6,6), FONT_LAST }, +}; + +//// + +static int frame = 0; + +void draw_char(char ch) { + const byte* p = vecfont[ch-0x20]; + byte bright = 0; + byte x = 0; + byte y = 0; + byte i; + for (i=0; i<8; i++) { + byte b = *p++; + if (b == FONT_LAST) break; // last move + else if (b == FONT_UP) bright = 0; // pen up + else { + byte x2 = b>>4; + byte y2 = b&15; + SVEC((char)(x2-x), (char)(y2-y), bright); + bright = 4; + x = x2; + y = y2; + } + } + SVEC((char)12-x, (char)-y, 0); +} + +void draw_string(const char* str, byte spacing) { + while (*str) { + draw_char(*str++); + if (spacing) SVEC(spacing, 0, 0); + } +} + +void main() { + dvgwrofs = 0x800; + draw_string("HELLO WORLD", 0); + RTSL(); + while (1) { + dvgreset(); + CNTR(); + SCAL(0x7f); + //SCAL(frame & 0xff); + STAT(RED, 0); + VCTR(200, 200, 1); + VCTR(-200, 200, 3); + VCTR(-200, -200, 5); + VCTR(200, -200, 7); + CNTR(); + STAT(GREEN, 0); + VCTR(100, -100, 0); + JSRL(0x800); + HALT(); + dvgstart(); + frame++; + } +} diff --git a/presets/vector-z80color/threed.c b/presets/vector-z80color/threed.c new file mode 100644 index 00000000..ad8564e0 --- /dev/null +++ b/presets/vector-z80color/threed.c @@ -0,0 +1,249 @@ +#include + +typedef unsigned char byte; +typedef signed char sbyte; +typedef unsigned short word; + +word __at(0xa000) dvgram[0x1000]; +byte __at(0x8840) _dvgstart; + +int __at(0x8100) mathbox_sum; +sbyte __at(0x8102) mathbox_arg1; +sbyte __at(0x8103) mathbox_arg2; +byte __at(0x810f) mathbox_go_mul; + +// + +void main(); + +void start() { +__asm + LD SP,#0x0 + DI +__endasm; + main(); +} + +int dvgwrofs; // write offset for DVG buffer + +inline word ___swapw(word j) { + return ((j << 8) | (j >> 8)); +} + +inline void dvgreset() { + dvgwrofs = 0; +} + +inline void dvgstart() { + _dvgstart = 0; +} + +void dvgwrite(word w) { + dvgram[dvgwrofs++] = w; +} + +inline void VCTR(int dx, int dy, byte bright) { + dvgwrite((dx & 0x1fff)); + dvgwrite(((bright & 7) << 13) | (dy & 0x1fff)); +} + +inline void SVEC(sbyte dx, sbyte dy, byte bright) { + dvgwrite(0x4000 | (dx & 0x1f) | ((bright&7)<<5) | ((dy & 0x1f)<<8)); +} + +inline void JSRL(word offset) { + dvgwrite(0xa000 | offset); +} + +inline void JMPL(word offset) { + dvgwrite(0xe000 | offset); +} + +inline void RTSL() { + dvgwrite(0xc000); +} + +inline void CNTR() { + dvgwrite(0x8000); +} + +inline void HALT() { + dvgwrite(0x2000); +} + +inline void STAT(byte rgb, byte intens) { + dvgwrite(0x6000 | ((intens & 0xf)<<4) | (rgb & 7)); +} + +inline void STAT_sparkle(byte intens) { + dvgwrite(0x6800 | ((intens & 0xf)<<4)); +} + +inline void SCAL(word scale) { + dvgwrite(0x7000 | scale); +} + +enum { + BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE +} Color; + +/// + +typedef struct { + sbyte m[3][3]; +} Matrix; + +typedef struct { + sbyte x,y,z; +} Vector8; + +typedef struct { + int x,y,z; +} Vector16; + +typedef struct { + byte numverts; + const Vector8* verts; // array of vertices + const sbyte* edges; // array of vertex indices (edges) +} Wireframe; + +void mat_identity(Matrix* m) { + memset(m, 0, sizeof(*m)); + m->m[0][0] = 127; + m->m[1][1] = 127; + m->m[2][2] = 127; +} + +inline void mul16(sbyte a, sbyte b) { + mathbox_arg1 = a; + mathbox_arg2 = b; + mathbox_go_mul=0; +} + +void vec_mat_transform(Vector16* dest, const Vector8* v, const Matrix* m) { + byte i; + int* result = &dest->x; + const sbyte* mval = &m->m[0][0]; + for (i=0; i<3; i++) { + mathbox_sum = 0; + mul16(*mval++, v->x); + mul16(*mval++, v->y); + mul16(*mval++, v->z); + *result++ = mathbox_sum; + } +} + +/* +void vec_mat_transform2(Vector16* dest, const Vector8* v, const Matrix* m) { + dest->x = v->x*m->m[0][0] + v->y*m->m[0][1] + v->z*m->m[0][2]; + dest->y = v->x*m->m[1][0] + v->y*m->m[1][1] + v->z*m->m[1][2]; + dest->z = v->x*m->m[2][0] + v->y*m->m[2][1] + v->z*m->m[2][2]; +} +*/ + +const sbyte sintbl[64] = { +0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, +49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, +90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116, +117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127, +}; + +sbyte isin(byte x0) { + byte x = x0; + if (x0 & 0x40) x = 127-x; + if (x0 & 0x80) { + return -sintbl[x+128]; + } else { + return sintbl[x]; + } +} + +sbyte icos(byte x) { + return isin(x+64); +} + +void mat_rotate(Matrix* m, byte axis, byte angle) { + sbyte sin = isin(angle); + sbyte cos = icos(angle); + mat_identity(m); + switch (axis) { + case 0: + m->m[1][1] = cos; + m->m[2][1] = sin; + m->m[1][2] = -sin; + m->m[2][2] = cos; + break; + case 1: + m->m[2][2] = cos; + m->m[0][2] = sin; + m->m[2][0] = -sin; + m->m[0][0] = cos; + break; + case 2: + m->m[0][0] = cos; + m->m[1][0] = sin; + m->m[0][1] = -sin; + m->m[1][1] = cos; + break; + } +} + +const Vector8 tetra_v[] = { {0,-86,86},{86,86,86},{-86,86,86},{0,0,-86} }; +const char tetra_e[] = { 0, 1, 2, 0, 3, 1, -1, 3, 2, -2 }; +const Wireframe tetra = { 4, tetra_v, tetra_e }; + +void xform_vertices(Vector16* dest, const Vector8* src, const Matrix* m, byte nv) { + byte i; + for (i=0; iedges; + byte bright = 0; + int x1 = 0; + int y1 = 0; + Vector16 scrnverts[16]; + xform_vertices(scrnverts, wf->verts, m, wf->numverts); + do { + sbyte i = *e++; + if (i == -1) + bright = 0; + else if (i == -2) + break; + else { + int x2 = scrnverts[i].x>>8; + int y2 = scrnverts[i].y>>8; + VCTR(x2-x1, y2-y1, bright); + x1 = x2; + y1 = y2; + } + bright = 2; + } while (1); +} + +/// + +word frame; + +void main() { + int x,y; + Matrix m; + mat_identity(&m); + while (1) { + dvgreset(); + CNTR(); + SCAL(0x1f); + STAT(RED, 5); + x = isin(frame/8); + y = icos(frame/8); + VCTR(x, y, 2); + STAT(GREEN, 15); + mat_rotate(&m, (frame>>8)&3, frame); + draw_wireframe_ortho(&tetra, &m); + HALT(); + dvgstart(); + frame++; + } +} diff --git a/src/emu.js b/src/emu.js index 9c06441c..751c0a32 100644 --- a/src/emu.js +++ b/src/emu.js @@ -125,7 +125,7 @@ mainElement.appendChild(borderElement); var VectorVideo = function(mainElement, width, height) { var self = this; var canvas, ctx; - var persistenceAlpha = 0.5; + var persistenceAlpha = 0.8; var jitter = 1.0; var gamma = 0.8; var sx = width/1024.0; diff --git a/src/platform/vector.js b/src/platform/vector.js index f928e90b..39388cd3 100644 --- a/src/platform/vector.js +++ b/src/platform/vector.js @@ -4,6 +4,8 @@ // http://arcarc.xmission.com/Tech/neilw_xy.txt var VECTOR_PRESETS = [ + {id:'font.c', name:'Vector Fonts'}, + {id:'threed.c', name:'3D Transformations'}, ] var ASTEROIDS_KEYCODE_MAP = makeKeycodeMap([ @@ -316,6 +318,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) { var video, audio, timer; var clock; var switches = new RAM(16).mem; + var mathram = new RAM(16).mem; this.__proto__ = new BaseZ80Platform(); @@ -323,6 +326,18 @@ var Z80ColorVectorPlatform = function(mainElement, proto) { return VECTOR_PRESETS; } + function do_math() { + var sum = (((mathram[0] + (mathram[1]<<8)) << 16) >> 16); + var a = (mathram[2] << 24) >> 24; + var b = (mathram[3] << 24) >> 24; + var d = a!=0 ? (sum/a) : 0; + sum += (a*b) & 0xffff; + mathram[0] = sum & 0xff; + mathram[1] = (sum >> 8) & 0xff; + mathram[4] = d & 0xff; + mathram[5] = (d >> 8) & 0xff; + } + this.start = function() { cpuram = new RAM(0x2000); dvgram = new RAM(0x4000); @@ -332,6 +347,7 @@ var Z80ColorVectorPlatform = function(mainElement, proto) { read: new AddressDecoder([ [0x0, 0x7fff, 0, function(a) { return rom[a]; }], [0x8000, 0x800f, 0xf, function(a) { return switches[a]; }], + [0x8100, 0x810f, 0xf, function(a) { return mathram[a]; } ], [0xa000, 0xdfff, 0x3fff, function(a) { return dvgram.mem[a]; }], [0xe000, 0xffff, 0x1fff, function(a) { return cpuram.mem[a]; }], ]), @@ -339,6 +355,8 @@ var Z80ColorVectorPlatform = function(mainElement, proto) { write: new AddressDecoder([ [0x8000, 0x800f, 0xf, function(a,v) { audio.pokey1.setRegister(a, v); }], [0x8010, 0x801f, 0xf, function(a,v) { audio.pokey2.setRegister(a, v); }], + [0x8100, 0x810e, 0xf, function(a,v) { mathram[a] = v; } ], + [0x810f, 0x810f, 0, function(a,v) { do_math(); } ], [0x8840, 0x8840, 0, function(a,v) { dvg.runUntilHalt(0); }], [0x8880, 0x8880, 0, function(a,v) { dvg.reset(); }], [0xa000, 0xdfff, 0x3fff, function(a,v) { dvgram.mem[a] = v; }], @@ -390,14 +408,16 @@ var Z80ColorVectorPlatform = function(mainElement, proto) { this.loadState = function(state) { cpu.loadState(state.c); - cpuram.mem.set(state.db); + cpuram.mem.set(state.cb); dvgram.mem.set(state.db); + mathram.set(state.mr); } this.saveState = function() { return { c:cpu.saveState(), cb:cpuram.mem.slice(0), db:dvgram.mem.slice(0), + mr:mathram.slice(0), } } this.getCPUState = function() { @@ -524,8 +544,10 @@ var DVGColorStateMachine = function(bus, video, bofs) { var scale = 1.0; var color; var statz; + var sparkle; var pcstack = []; var running = false; + bofs &= 0xffff; function readWord(a) { @@ -543,6 +565,10 @@ var DVGColorStateMachine = function(bus, video, bofs) { return w; } + function sparkle_color() { + return (Math.random() * 256) & 0x7; + } + this.reset = function() { pc = 0; scale = 1.0; @@ -550,6 +576,7 @@ var DVGColorStateMachine = function(bus, video, bofs) { statz = 15; x = 512; y = 512; + sparkle = false; running = false; } @@ -582,6 +609,7 @@ var DVGColorStateMachine = function(bus, video, bofs) { if (z == 2) z = statz; var x2 = x + Math.round(decodeSigned(w2, 12) * scale); var y2 = y + Math.round(decodeSigned(w, 12) * scale); + if (sparkle) color = sparkle_color(); video.drawLine(x, y, x2, y2, z<<4, color); x = x2; y = y2; @@ -595,19 +623,21 @@ var DVGColorStateMachine = function(bus, video, bofs) { var y2 = y + Math.round(decodeSigned(w>>8, 4) * scale * 2); var z = (w >> 5) & 0x7; if (z == 2) z = statz; + if (sparkle) color = sparkle_color(); video.drawLine(x, y, x2, y2, z<<4, color); x = x2; y = y2; break; } case 3: { // STAT/SCAL - if (w & 0x1000) { + if (w & 0x1000) { // SCAL var b = ((w >> 8) & 0x07)+8; var l = (~w) & 0xff; scale = ((l << 16) >> b) / 32768.0; - } else { + } else { // STAT color = w & 7; statz = (w >> 4) & 0xf; + sparkle = (w & 0x800) != 0; } break; } diff --git a/src/ui.js b/src/ui.js index 09c19e3c..5185f0bc 100644 --- a/src/ui.js +++ b/src/ui.js @@ -359,12 +359,11 @@ function arrayCompare(a,b) { return true; } -worker.onmessage = function(e) { - if (pendingWorkerMessages > 1) { - pendingWorkerMessages = 0; - setCode(editor.getValue()); +function setCompileOutput(data) { + sourcefile = new SourceFile(data.lines); + if (data.asmlines) { + assemblyfile = new SourceFile(data.asmlines, data.intermediate.listing); } - pendingWorkerMessages = 0; // errors? var toolbar = $("#controls_top"); function addErrorMarker(line, msg) { @@ -378,15 +377,11 @@ worker.onmessage = function(e) { div.appendChild(tooltip); editor.setGutterMarker(line, "gutter-info", div); } - sourcefile = new SourceFile(e.data.lines); - if (e.data.asmlines) { - assemblyfile = new SourceFile(e.data.asmlines, e.data.intermediate.listing); - } - if (e.data.errors.length > 0) { + if (data.errors.length > 0) { toolbar.addClass("has-errors"); editor.clearGutter("gutter-info"); var numLines = editor.lineCount(); - for (info of e.data.errors) { + for (info of data.errors) { var line = info.line-1; if (line < 0 || line >= numLines) line = numLines-1; addErrorMarker(line, info.msg); @@ -395,7 +390,7 @@ worker.onmessage = function(e) { } else { updatePreset(current_preset_id, editor.getValue()); // update persisted entry // load ROM - var rom = e.data.output; + var rom = data.output; var rom_changed = rom && !arrayCompare(rom, current_output); if (rom_changed) { try { @@ -419,7 +414,7 @@ worker.onmessage = function(e) { editor.clearGutter("gutter-bytes"); editor.clearGutter("gutter-offset"); editor.clearGutter("gutter-clock"); - for (var info of e.data.lines) { + for (var info of data.lines) { if (info.offset >= 0) { var textel = document.createTextNode(hex(info.offset,4)); editor.setGutterMarker(info.line-1, "gutter-offset", textel); @@ -447,6 +442,15 @@ worker.onmessage = function(e) { trace_pending_at_pc = null; } +worker.onmessage = function(e) { + if (pendingWorkerMessages > 1) { + pendingWorkerMessages = 0; + setCode(editor.getValue()); + } + pendingWorkerMessages = 0; + setCompileOutput(e.data); +} + function setCurrentLine(line) { editor.setSelection({line:line,ch:0}, {line:line-1,ch:0}, {scroll:true}); } diff --git a/src/worker/workermain.js b/src/worker/workermain.js index 32edfac1..223da7d2 100644 --- a/src/worker/workermain.js +++ b/src/worker/workermain.js @@ -614,19 +614,22 @@ function assemblelinkSDASZ80(code, platform) { var asmlines = parseListing(lstout, /^\s*([0-9A-F]+)\s+([0-9A-F][0-9A-F r]*[0-9A-F])\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 4, 1, 2, 5, 3); var srclines = parseSourceLines(lstout, /^\s+\d+ ;:(\d+):/i, /^\s*([0-9A-F]{4})/i); // parse symbol map + /* var symbolmap = {}; + console.log(mapout); for (var s of mapout.split("\n")) { var toks = s.split(" "); if (s[0] == 'DEF') { symbolmap[s[1]] = s[2]; } } + */ return { output:parseIHX(hexout, params.code_start, params.code_size), lines:asmlines, srclines:srclines, errors:msvc_errors, // TODO? - symbolmap:symbolmap, + symbolmap:mapout, intermediate:{listing:rstout}, }; } diff --git a/test/cli/6502/test6502disasm.js b/test/cli/6502/test6502disasm.js index 0c92ee0b..eb8b8542 100644 --- a/test/cli/6502/test6502disasm.js +++ b/test/cli/6502/test6502disasm.js @@ -14,7 +14,7 @@ describe('6502 disassembler', function() { assert.deepEqual({line:"BRK ",nbytes:1}, disassemble6502(0, 0, 0, 0)); assert.deepEqual({line:"LDA #$A9",nbytes:2}, disassemble6502(0, 0xa9, 0xa9, 0xa9)); assert.deepEqual({line:"JMP $6010",nbytes:3}, disassemble6502(0, 0x4c, 0x10, 0x60)); - assert.deepEqual({line:"BPL $FFF0",nbytes:2}, disassemble6502(0, 0x10, 0xf0, 0)); - assert.deepEqual({line:"BMI $0010",nbytes:2}, disassemble6502(0, 0x30, 0x10, 0)); + assert.deepEqual({line:"BPL $FFF2",nbytes:2}, disassemble6502(0, 0x10, 0xf0, 0)); + assert.deepEqual({line:"BMI $0012",nbytes:2}, disassemble6502(0, 0x30, 0x10, 0)); }); });