1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-25 18:33:11 +00:00

npm test w/ mocha

This commit is contained in:
Steven Hugg 2017-01-11 21:02:23 -05:00
parent 72a835f8f9
commit 18c1028250
7 changed files with 160 additions and 10 deletions

56
doc/compilers.txt Normal file
View File

@ -0,0 +1,56 @@
cc65 - A fairly mature C compiler + toolchain for the 6502 family with lots of target
platforms and an extensive library. The code generation is
not great, using the AX register pair and a parameter stack for local variables that has to be
indirect-indexed (you can make locals static with an option, but I found
this introduced compiler bugs.)
LCC - A small retargetable C compiler released in 1994, most notoriously
used to compile bytecode for the QuakeC language. It doesn't generate 6502
code, but it probably could -- although optimizations are weak.
There's an older port to the 65C816.
ACK - This ancient compiler used for Minix has a lot of frontends and backends, and is designed
for small-register CISC CPUs. There's a 6500 backend but I couldn't get it
working. Looks like it could be resurrected though. There's an intermediate
file for each step of the pipeline.
PCC - An early C compiler from the days of UNIX, now updated to C99.
There's a 16-bit target (x86) and the backends looks pretty simple.
http://pcc.ludd.ltu.se/internals/pass2/
SDCC - A mature compiler that supports lots of microcontrollers including
the Z80. This is probably the best candidate for porting to 6502,
but the backends are bespoke works of evil genius and there's precious little documentation.
(I wonder if you could post-process the HC08 output to 6502, since they're similar in some ways.)
LLVM-6502 - Someone uploaded this to Github. I got it to build, but the code
generated wasn't comprehensible.
osXdk - A fork of the Oric SDK. The C compiler has a weird design which
emits bytecode and then uses a C preprocessor to expand the macros
into 6502 assembler.
PLASMA - Language + VM, sort of like SWEET16 meets
Java. Simple, concise code base. Pretty fast too, in the same ballpark as
CC65. Focused on the Apple I/II/III family.
Atalan - Rule-based language/assembler with support for multiple 8-bit
platforms. Looks promising, but I had problems with it crashing, and it
lacks documentation/test cases. Atari-focused.
Macross/Slinky - A macro cross-assembler developed by Chip Morningstar at
Lucasfilm Ltd. for use in the game Habitat. Billed as "An assembler for
people who hate assembly language."
NESHLA - A high-level assembler in the same spirit as Macross, but with
NES-specific features.
WLA-DX - Some other weird cross-assembler with lots of CPU targets.
z88dk - A Small C-derived cross-compiler for the Z80, supporting 20 target
machines.
SWEET16 - Woz's tiny bytecode interpreter on the Apple ][ integer BASIC ROM.
Still emcumbered by Apple's copyright for the foreseeable future.
http://6502.org/source/interpreters/sweet16.htm

View File

@ -1,10 +1,30 @@
{
"name": "RetroConsole",
"name": "8bitworkshop",
"version": "0.0.1",
"author": "Steven Hugg",
"dependencies": {
},
"dependencies": {},
"devDependencies": {
"browserify": "^13.0.0"
}
"mocha": "^3.2.0"
},
"description": "8bitworkshop.com",
"main": "main.js",
"directories": {
"doc": "doc",
"test": "tests"
},
"scripts": {
"test": "mocha"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sehugg/8bitworkshop.git"
},
"keywords": [
"8bit"
],
"license": "GPL-3.0",
"bugs": {
"url": "https://github.com/sehugg/8bitworkshop/issues"
},
"homepage": "https://github.com/sehugg/8bitworkshop#readme"
}

View File

@ -319,7 +319,6 @@ var Base6502Platform = function() {
var debugBreakState = null;
var debugTargetClock = 0;
var debugClock = 0;
var debugFrameStartClock = 0;
this.setDebugCondition = function(debugCond) {
if (debugSavedState) {
@ -331,6 +330,13 @@ var Base6502Platform = function() {
debugCondition = debugCond;
this.resume();
}
this.restartDebugState = function() {
if (debugCondition && !debugBreakState) {
debugSavedState = this.saveState();
debugTargetClock -= debugClock;
debugClock = 0;
}
}
this.getDebugCallback = function() {
return debugCondition;
}
@ -341,7 +347,6 @@ var Base6502Platform = function() {
debugSavedState = null;
debugTargetClock = 0;
debugClock = 0;
debugFrameStartClock = 0;
onBreakpointHit = null;
debugCondition = null;
}
@ -354,6 +359,7 @@ var Base6502Platform = function() {
onBreakpointHit(debugBreakState);
}
}
// TODO: lower bound of clock value
this.step = function() {
var self = this;
var previousPC = -1;

View File

@ -175,7 +175,7 @@ var Apple2Platform = function(mainElement) {
ap2disp.updateScreen();
video.updateFrame();
soundstate = 0; // to prevent clicking
// TODO: reset debug state
self.restartDebugState(); // reset debug start state
});
}

View File

@ -87,6 +87,7 @@ var AtariVectorPlatform = function(mainElement) {
cpu.clockPulse();
//cpu.executeInstruction();
}
self.restartDebugState();
});
video.setKeyboardEvents(function(key,code,flags) {
var KEY2ADDR = {

View File

@ -36,7 +36,7 @@ var fsMeta, fsBlob;
xhr.open("GET", "fs65.js.metadata", false); // synchronous request
xhr.send(null);
fsMeta = xhr.response;
console.log("Loaded filesystem", fsMeta.files.length, 'files', fsBlob.size, 'bytes');
console.log("Loaded filesystem", fsMeta.files.length, 'files', fsBlob.size||fsBlob.length, 'bytes');
}
// mount the filesystem at /share
@ -339,9 +339,10 @@ var tools = {
onmessage = function(e) {
var code = e.data.code;
var platform = e.data.platform;
var toolfn = tools[e.data.tool];
if (!toolfn) throw "no tool named " + e.data.tool;
var result = toolfn(code);
var result = toolfn(code, platform);
if (result) {
postMessage(result);
}

66
test/worker.js Normal file
View File

@ -0,0 +1,66 @@
var assert = require('assert');
var fs = require('fs');
var vm = require('vm');
var worker = {};
var includeInThisContext = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
};
global.importScripts = function(path) {
includeInThisContext('src/worker/'+path);
}
global.XMLHttpRequest = function() {
var txt;
this.open = function(a,b,c) {
txt = fs.readFileSync('src/worker/'+b);
if (this.responseType == 'json') {
this.response = JSON.parse(txt);
} else if (this.responseType == 'blob') {
this.response = txt; //new Uint8Array(txt);
//console.log(this.response.slice(0,100));
}
}
this.send = function() { }
}
global.FileReaderSync = function() {
this.readAsArrayBuffer = function(blob) {
return blob.slice(0);
}
}
global.onmessage = null;
global.postMessage = null;
includeInThisContext("src/worker/workermain.js");
function compile(tool, code, callback, outlen) {
global.postMessage = function(msg) {
//console.log(msg);
assert.ok(msg.listing.lines);
assert.equal(msg.listing.errors.length, msg.listing.errors);
assert.equal(msg.output.length, outlen);
callback(null, msg);
};
global.onmessage({
data:{code:code, tool:tool}
});
}
describe('Worker', function() {
it('should compile DASM', function(done) {
compile('dasm', '\tprocessor 6502\n\torg $f000\nfoo lda #0\n', done, 2);
});
it('should compile PLASMA', function(done) {
compile('plasm', 'word x = 0', done, 5);
});
/*
it('should compile CC65', function(done) {
compile('cc65', '#include <stdio.h>\nint main() {\nint x=1;\nreturn x+2;\n}', done, 5);
});
*/
});