mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
npm test w/ mocha
This commit is contained in:
parent
72a835f8f9
commit
18c1028250
56
doc/compilers.txt
Normal file
56
doc/compilers.txt
Normal 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
|
30
package.json
30
package.json
@ -1,10 +1,30 @@
|
|||||||
{
|
{
|
||||||
"name": "RetroConsole",
|
"name": "8bitworkshop",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"author": "Steven Hugg",
|
"author": "Steven Hugg",
|
||||||
"dependencies": {
|
"dependencies": {},
|
||||||
},
|
|
||||||
"devDependencies": {
|
"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"
|
||||||
}
|
}
|
||||||
|
10
src/emu.js
10
src/emu.js
@ -319,7 +319,6 @@ var Base6502Platform = function() {
|
|||||||
var debugBreakState = null;
|
var debugBreakState = null;
|
||||||
var debugTargetClock = 0;
|
var debugTargetClock = 0;
|
||||||
var debugClock = 0;
|
var debugClock = 0;
|
||||||
var debugFrameStartClock = 0;
|
|
||||||
|
|
||||||
this.setDebugCondition = function(debugCond) {
|
this.setDebugCondition = function(debugCond) {
|
||||||
if (debugSavedState) {
|
if (debugSavedState) {
|
||||||
@ -331,6 +330,13 @@ var Base6502Platform = function() {
|
|||||||
debugCondition = debugCond;
|
debugCondition = debugCond;
|
||||||
this.resume();
|
this.resume();
|
||||||
}
|
}
|
||||||
|
this.restartDebugState = function() {
|
||||||
|
if (debugCondition && !debugBreakState) {
|
||||||
|
debugSavedState = this.saveState();
|
||||||
|
debugTargetClock -= debugClock;
|
||||||
|
debugClock = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.getDebugCallback = function() {
|
this.getDebugCallback = function() {
|
||||||
return debugCondition;
|
return debugCondition;
|
||||||
}
|
}
|
||||||
@ -341,7 +347,6 @@ var Base6502Platform = function() {
|
|||||||
debugSavedState = null;
|
debugSavedState = null;
|
||||||
debugTargetClock = 0;
|
debugTargetClock = 0;
|
||||||
debugClock = 0;
|
debugClock = 0;
|
||||||
debugFrameStartClock = 0;
|
|
||||||
onBreakpointHit = null;
|
onBreakpointHit = null;
|
||||||
debugCondition = null;
|
debugCondition = null;
|
||||||
}
|
}
|
||||||
@ -354,6 +359,7 @@ var Base6502Platform = function() {
|
|||||||
onBreakpointHit(debugBreakState);
|
onBreakpointHit(debugBreakState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: lower bound of clock value
|
||||||
this.step = function() {
|
this.step = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var previousPC = -1;
|
var previousPC = -1;
|
||||||
|
@ -175,7 +175,7 @@ var Apple2Platform = function(mainElement) {
|
|||||||
ap2disp.updateScreen();
|
ap2disp.updateScreen();
|
||||||
video.updateFrame();
|
video.updateFrame();
|
||||||
soundstate = 0; // to prevent clicking
|
soundstate = 0; // to prevent clicking
|
||||||
// TODO: reset debug state
|
self.restartDebugState(); // reset debug start state
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ var AtariVectorPlatform = function(mainElement) {
|
|||||||
cpu.clockPulse();
|
cpu.clockPulse();
|
||||||
//cpu.executeInstruction();
|
//cpu.executeInstruction();
|
||||||
}
|
}
|
||||||
|
self.restartDebugState();
|
||||||
});
|
});
|
||||||
video.setKeyboardEvents(function(key,code,flags) {
|
video.setKeyboardEvents(function(key,code,flags) {
|
||||||
var KEY2ADDR = {
|
var KEY2ADDR = {
|
||||||
|
@ -36,7 +36,7 @@ var fsMeta, fsBlob;
|
|||||||
xhr.open("GET", "fs65.js.metadata", false); // synchronous request
|
xhr.open("GET", "fs65.js.metadata", false); // synchronous request
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
fsMeta = xhr.response;
|
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
|
// mount the filesystem at /share
|
||||||
@ -339,9 +339,10 @@ var tools = {
|
|||||||
|
|
||||||
onmessage = function(e) {
|
onmessage = function(e) {
|
||||||
var code = e.data.code;
|
var code = e.data.code;
|
||||||
|
var platform = e.data.platform;
|
||||||
var toolfn = tools[e.data.tool];
|
var toolfn = tools[e.data.tool];
|
||||||
if (!toolfn) throw "no tool named " + e.data.tool;
|
if (!toolfn) throw "no tool named " + e.data.tool;
|
||||||
var result = toolfn(code);
|
var result = toolfn(code, platform);
|
||||||
if (result) {
|
if (result) {
|
||||||
postMessage(result);
|
postMessage(result);
|
||||||
}
|
}
|
||||||
|
66
test/worker.js
Normal file
66
test/worker.js
Normal 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);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user