1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2026-04-19 08:27:40 +00:00

Deploying to gh-pages from @ sehugg/8bitworkshop@7cf87649ff 🚀

This commit is contained in:
sehugg
2026-03-03 17:58:04 +00:00
parent 9f8699e466
commit e88f416093
12 changed files with 1246 additions and 1 deletions
+264
View File
@@ -0,0 +1,264 @@
#!/usr/bin/env node
"use strict";
// 8bws - 8bitworkshop CLI tool for compilation, ROM execution, and platform info
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const testlib_1 = require("./testlib");
function outputJSON(result) {
console.log(JSON.stringify(result, null, 2));
}
function usage() {
outputJSON({
success: false,
command: 'help',
data: {
commands: {
'compile': 'compile --tool <tool> --platform <platform> [--output <file>] <source>',
'check': 'check --tool <tool> --platform <platform> <source>',
'run': 'run --platform <platform> [--frames N] <rom>',
'list-tools': 'list-tools',
'list-platforms': 'list-platforms',
}
},
error: 'No command specified'
});
process.exit(1);
}
function parseArgs(argv) {
var command = argv[2];
var args = {};
var positional = [];
for (var i = 3; i < argv.length; i++) {
if (argv[i].startsWith('--')) {
var key = argv[i].substring(2);
if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
args[key] = argv[++i];
}
else {
args[key] = 'true';
}
}
else {
positional.push(argv[i]);
}
}
return { command, args, positional };
}
async function doCompile(args, positional, checkOnly) {
var tool = args['tool'];
var platform = args['platform'];
var outputFile = args['output'];
var sourceFile = positional[0];
if (!tool || !platform || !sourceFile) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
error: 'Required: --tool <tool> --platform <platform> <source>'
});
process.exit(1);
}
if (!testlib_1.TOOLS[tool]) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
error: `Unknown tool: ${tool}. Use list-tools to see available tools.`
});
process.exit(1);
}
// Preload the tool's filesystem if needed
var preloadKey = tool;
if (testlib_1.TOOL_PRELOADFS[tool + '-' + platform]) {
preloadKey = tool;
}
await (0, testlib_1.preload)(tool, platform);
var result = await (0, testlib_1.compileSourceFile)(tool, platform, sourceFile);
if (!result.success) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
data: { errors: result.errors }
});
process.exit(1);
}
if (checkOnly) {
outputJSON({
success: true,
command: 'check',
data: {
tool: tool,
platform: platform,
source: sourceFile,
outputSize: result.output ? (result.output.code ? result.output.code.length : result.output.length) : 0,
}
});
return;
}
// Write output if requested
if (outputFile && result.output) {
var outData = result.output.code || result.output;
if (outData instanceof Uint8Array) {
fs.writeFileSync(outputFile, outData);
}
else if (typeof outData === 'object') {
fs.writeFileSync(outputFile, JSON.stringify(outData));
}
else {
fs.writeFileSync(outputFile, outData);
}
}
var outputSize = 0;
if (result.output) {
outputSize = result.output.code ? result.output.code.length : result.output.length;
}
outputJSON({
success: true,
command: 'compile',
data: {
tool: tool,
platform: platform,
source: sourceFile,
outputSize: outputSize,
outputFile: outputFile || null,
hasListings: result.listings ? Object.keys(result.listings).length > 0 : false,
hasSymbolmap: !!result.symbolmap,
}
});
}
async function doRun(args, positional) {
var platform = args['platform'];
var frames = parseInt(args['frames'] || '1');
var romFile = positional[0];
if (!platform || !romFile) {
outputJSON({
success: false,
command: 'run',
error: 'Required: --platform <platform> <rom>'
});
process.exit(1);
}
// Dynamic import of MachineRunner
try {
var runmachine = require('./runmachine.js');
var MachineRunner = runmachine.MachineRunner;
}
catch (e) {
outputJSON({
success: false,
command: 'run',
error: `Could not load MachineRunner: ${e.message}`
});
process.exit(1);
}
outputJSON({
success: false,
command: 'run',
error: 'Run command not yet fully implemented (requires platform machine loading)'
});
}
function doListTools() {
var tools = (0, testlib_1.listTools)();
outputJSON({
success: true,
command: 'list-tools',
data: {
tools: tools,
count: tools.length
}
});
}
function doListPlatforms() {
var platforms = (0, testlib_1.listPlatforms)();
var details = {};
for (var p of platforms) {
details[p] = {
arch: testlib_1.PLATFORM_PARAMS[p].arch || 'unknown',
};
}
outputJSON({
success: true,
command: 'list-platforms',
data: {
platforms: details,
count: platforms.length
}
});
}
async function main() {
if (process.argv.length < 3) {
usage();
}
var { command, args, positional } = parseArgs(process.argv);
try {
switch (command) {
case 'compile':
await (0, testlib_1.initialize)();
await doCompile(args, positional, false);
break;
case 'check':
await (0, testlib_1.initialize)();
await doCompile(args, positional, true);
break;
case 'run':
await doRun(args, positional);
break;
case 'list-tools':
await (0, testlib_1.initialize)();
doListTools();
break;
case 'list-platforms':
await (0, testlib_1.initialize)();
doListPlatforms();
break;
default:
outputJSON({
success: false,
command: command,
error: `Unknown command: ${command}`
});
process.exit(1);
}
}
catch (e) {
outputJSON({
success: false,
command: command,
error: e.message || String(e)
});
process.exit(1);
}
}
main();
//# sourceMappingURL=8bws.js.map
File diff suppressed because one or more lines are too long
+205
View File
@@ -0,0 +1,205 @@
"use strict";
// testlib - Clean async API for compiling and testing 8bitworkshop projects
// Wraps the worker build system for use in tests and CLI tools
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TOOLS = exports.PLATFORM_PARAMS = exports.TOOL_PRELOADFS = exports.store = void 0;
exports.initialize = initialize;
exports.preload = preload;
exports.compile = compile;
exports.compileFile = compileFile;
exports.compileSourceFile = compileSourceFile;
exports.listTools = listTools;
exports.listPlatforms = listPlatforms;
exports.ab2str = ab2str;
exports.createMockLocalStorage = createMockLocalStorage;
const fs = __importStar(require("fs"));
const workerlib_1 = require("../worker/workerlib");
Object.defineProperty(exports, "store", { enumerable: true, get: function () { return workerlib_1.store; } });
Object.defineProperty(exports, "TOOL_PRELOADFS", { enumerable: true, get: function () { return workerlib_1.TOOL_PRELOADFS; } });
const platforms_1 = require("../worker/platforms");
Object.defineProperty(exports, "PLATFORM_PARAMS", { enumerable: true, get: function () { return platforms_1.PLATFORM_PARAMS; } });
const workertools_1 = require("../worker/workertools");
Object.defineProperty(exports, "TOOLS", { enumerable: true, get: function () { return workertools_1.TOOLS; } });
let initialized = false;
/**
* Initialize the Node.js environment for compilation.
* Must be called once before any compile/preload calls.
*/
async function initialize() {
if (initialized)
return;
(0, workerlib_1.setupNodeEnvironment)();
// The worker tools are already registered through the import chain:
// workerlib -> workertools -> tools/* and builder -> TOOLS
// No need to load the esbuild bundle.
initialized = true;
}
/**
* Preload a tool's filesystem (e.g. CC65 standard libraries).
*/
async function preload(tool, platform) {
await initialize();
var msg = { preload: tool };
if (platform)
msg.platform = platform;
await (0, workerlib_1.handleMessage)(msg);
}
/**
* Compile source code with the specified tool and platform.
*/
async function compile(options) {
await initialize();
// Reset the store for a clean build
await (0, workerlib_1.handleMessage)({ reset: true });
let result;
if (options.files && options.buildsteps) {
// Multi-file build
var msg = {
updates: options.files.map(f => ({ path: f.path, data: f.data })),
buildsteps: options.buildsteps
};
result = await (0, workerlib_1.handleMessage)(msg);
}
else {
// Single-file build
var msg = {
code: options.code,
platform: options.platform,
tool: options.tool,
path: options.path || ('src.' + options.tool),
mainfile: options.mainfile !== false
};
result = await (0, workerlib_1.handleMessage)(msg);
}
return workerResultToCompileResult(result);
}
/**
* Compile a file from the presets directory.
*/
async function compileFile(tool, platform, presetPath) {
await initialize();
var code = fs.readFileSync('presets/' + platform + '/' + presetPath, 'utf-8');
return compile({
tool: tool,
platform: platform,
code: code,
path: presetPath,
});
}
/**
* Compile an arbitrary source file path.
*/
async function compileSourceFile(tool, platform, filePath) {
await initialize();
var code = fs.readFileSync(filePath, 'utf-8');
var basename = filePath.split('/').pop();
return compile({
tool: tool,
platform: platform,
code: code,
path: basename,
});
}
function workerResultToCompileResult(result) {
if (!result) {
return { success: true, unchanged: true };
}
if ('unchanged' in result && result.unchanged) {
return { success: true, unchanged: true };
}
if ('errors' in result && result.errors && result.errors.length > 0) {
return {
success: false,
errors: result.errors,
};
}
if ('output' in result) {
return {
success: true,
output: result.output,
listings: result.listings,
symbolmap: result.symbolmap,
params: result.params,
};
}
return { success: false, errors: [{ line: 0, msg: 'Unknown result format' }] };
}
/**
* List available compilation tools.
*/
function listTools() {
return Object.keys(workertools_1.TOOLS);
}
/**
* List available target platforms.
*/
function listPlatforms() {
return Object.keys(platforms_1.PLATFORM_PARAMS);
}
/**
* Convert a binary buffer to a hex string for display.
*/
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
// Platform test harness utilities
/**
* Create a mock localStorage for tests that need it.
*/
function createMockLocalStorage() {
var items = {};
return {
get length() {
return Object.keys(items).length;
},
clear() {
items = {};
},
getItem(k) {
return items[k] || null;
},
setItem(k, v) {
items[k] = v;
},
removeItem(k) {
delete items[k];
},
key(i) {
return Object.keys(items)[i] || null;
}
};
}
//# sourceMappingURL=testlib.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"testlib.js","sourceRoot":"","sources":["../../src/tools/testlib.ts"],"names":[],"mappings":"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"}
+1 -1
View File
@@ -1 +1 @@
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.ts","../src/worker/tools/remote.ts","../src/worker/tools/sdcc.ts","../src/worker/tools/verilog.ts","../src/worker/tools/x86.ts","../src/worker/tools/z80.ts"],"version":"5.9.3"}
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/8bws.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/tools/testlib.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workerlib.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.ts","../src/worker/tools/remote.ts","../src/worker/tools/sdcc.ts","../src/worker/tools/verilog.ts","../src/worker/tools/x86.ts","../src/worker/tools/z80.ts"],"version":"5.9.3"}
+175
View File
@@ -0,0 +1,175 @@
"use strict";
// workerlib.ts - Node.js-friendly entry point for the worker build system
// Re-exports core worker functionality without Web Worker onmessage/postMessage wiring
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TOOLS = exports.PLATFORM_PARAMS = exports.TOOL_PRELOADFS = exports.builder = exports.store = void 0;
exports.setupNodeEnvironment = setupNodeEnvironment;
exports.handleMessage = handleMessage;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const util_1 = require("../common/util");
const workertools_1 = require("./workertools");
Object.defineProperty(exports, "TOOL_PRELOADFS", { enumerable: true, get: function () { return workertools_1.TOOL_PRELOADFS; } });
const builder_1 = require("./builder");
Object.defineProperty(exports, "store", { enumerable: true, get: function () { return builder_1.store; } });
Object.defineProperty(exports, "builder", { enumerable: true, get: function () { return builder_1.builder; } });
const wasmutils_1 = require("./wasmutils");
const workermain_1 = require("./workermain");
var platforms_1 = require("./platforms");
Object.defineProperty(exports, "PLATFORM_PARAMS", { enumerable: true, get: function () { return platforms_1.PLATFORM_PARAMS; } });
var workertools_2 = require("./workertools");
Object.defineProperty(exports, "TOOLS", { enumerable: true, get: function () { return workertools_2.TOOLS; } });
class Blob {
constructor(data) {
this.data = data;
this.size = data.length;
this.length = data.length;
}
slice(a, b) {
return new Blob(this.data.slice(a, b));
}
arrayBuffer() {
return this.asArrayBuffer();
}
asArrayBuffer() {
var buf = new ArrayBuffer(this.data.length);
var arr = new Uint8Array(buf);
for (var i = 0; i < this.data.length; i++)
arr[i] = this.data.charCodeAt(i);
return arr;
}
}
/**
* Set up the Node.js environment to provide XMLHttpRequest, fetch, and other
* browser globals that the worker build system expects.
* Call this once before using handleMessage/builder.
*/
function setupNodeEnvironment() {
// Basic globals expected by various parts of the worker system
wasmutils_1.emglobal.window = wasmutils_1.emglobal;
wasmutils_1.emglobal.exports = {};
wasmutils_1.emglobal.self = wasmutils_1.emglobal;
wasmutils_1.emglobal.location = { href: '.' };
wasmutils_1.emglobal.path = path;
wasmutils_1.emglobal.btoa = require('btoa');
wasmutils_1.emglobal.atob = require('atob');
try {
wasmutils_1.emglobal.navigator = wasmutils_1.emglobal;
}
catch (e) { /* read-only in newer Node */ }
wasmutils_1.emglobal.ResizeObserver = class {
observe() { }
};
// XMLHttpRequest shim that reads from the local filesystem
wasmutils_1.emglobal.XMLHttpRequest = function () {
this.open = function (method, url, async) {
if (this.responseType == 'json') {
var txt = fs.readFileSync('src/worker/' + url, 'utf-8');
this.response = JSON.parse(txt);
}
else if (this.responseType == 'blob') {
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
this.response = new Blob(data);
}
else if (this.responseType == 'arraybuffer') {
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
this.response = new Blob(data).asArrayBuffer();
}
this.status = this.response ? 200 : 404;
};
this.send = function () { };
};
// FileReaderSync shim
wasmutils_1.emglobal.FileReaderSync = function () {
this.readAsArrayBuffer = function (blob) {
return blob.asArrayBuffer();
};
};
// fetch shim that reads from the local filesystem
wasmutils_1.emglobal.fetch = function (filepath) {
return new Promise((resolve, reject) => {
try {
var bin = fs.readFileSync(filepath, { encoding: 'binary' });
var response = new Blob(bin);
resolve(response);
}
catch (e) {
reject(e);
}
});
};
// importScripts shim - runs scripts in the global context like a web worker would.
// In the web worker, importScripts loads relative to the worker bundle.
// PWORKER is "../../src/worker/", so paths like "../../src/worker/asmjs/dasm.js"
// need to be resolved to the actual file on disk.
var vm = require('vm');
wasmutils_1.emglobal.importScripts = function (scriptPath) {
// Strip the PWORKER prefix and load from src/worker/
var resolved = scriptPath.replace(/^\.\.\/\.\.\//, '');
var fullPath = path.resolve(process.cwd(), resolved);
var code = fs.readFileSync(fullPath, 'utf-8');
vm.runInThisContext(code, fullPath);
};
// Suppress onmessage/postMessage (not used in Node mode)
wasmutils_1.emglobal.onmessage = null;
wasmutils_1.emglobal.postMessage = null;
// Set up the require function for WASM modules
(0, workermain_1.setupRequireFunction)();
}
/**
* Handle a worker message (preload, reset, or build).
* Same logic as workermain.ts handleMessage but exported for direct use.
*/
async function handleMessage(data) {
// preload file system
if (data.preload) {
var fsName = workertools_1.TOOL_PRELOADFS[data.preload];
if (!fsName && data.platform)
fsName = workertools_1.TOOL_PRELOADFS[data.preload + '-' + (0, util_1.getBasePlatform)(data.platform)];
if (!fsName && data.platform)
fsName = workertools_1.TOOL_PRELOADFS[data.preload + '-' + (0, util_1.getRootBasePlatform)(data.platform)];
if (fsName && !wasmutils_1.fsMeta[fsName])
(0, wasmutils_1.loadFilesystem)(fsName);
return;
}
// clear filesystem?
if (data.reset) {
builder_1.store.reset();
return;
}
return builder_1.builder.handleMessage(data);
}
//# sourceMappingURL=workerlib.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"workerlib.js","sourceRoot":"","sources":["../../src/worker/workerlib.ts"],"names":[],"mappings":"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"}
+3
View File
@@ -30,6 +30,9 @@
"octokat": "^0.10.0",
"split.js": "^1.6.2"
},
"bin": {
"8bws": "gen/cli/8bws.js"
},
"devDependencies": {
"@lezer/generator": "^1.8.0",
"@types/bootbox": "^5.1.3",
+4
View File
@@ -9,6 +9,9 @@
"url": "git+https://github.com/sehugg/8bitworkshop.git"
},
"license": "GPL-3.0",
"bin": {
"8bws": "./gen/cli/8bws.js"
},
"dependencies": {
"@codemirror/commands": "^6.10.2",
"@codemirror/lang-cpp": "^6.0.3",
@@ -88,6 +91,7 @@
"fuzzbasic": "jsfuzz gen/common/basic/fuzz.js ~/basic/corpus/ --versifier false",
"fuzzhdl": "jsfuzz -r binaryen gen/common/hdl/fuzz.js ~/verilator/corpus/ --versifier false",
"machine": "node gen/tools/runmachine.js",
"cli": "node gen/tools/8bws.js",
"mkdoc": "typedoc --out web/jsdoc src/common/"
},
"keywords": [
+256
View File
@@ -0,0 +1,256 @@
#!/usr/bin/env node
// 8bws - 8bitworkshop CLI tool for compilation, ROM execution, and platform info
import * as fs from 'fs';
import { initialize, compile, compileSourceFile, preload, listTools, listPlatforms, PLATFORM_PARAMS, TOOLS, TOOL_PRELOADFS } from './testlib';
interface CLIResult {
success: boolean;
command: string;
data?: any;
error?: string;
}
function outputJSON(result: CLIResult): void {
console.log(JSON.stringify(result, null, 2));
}
function usage(): void {
outputJSON({
success: false,
command: 'help',
data: {
commands: {
'compile': 'compile --tool <tool> --platform <platform> [--output <file>] <source>',
'check': 'check --tool <tool> --platform <platform> <source>',
'run': 'run --platform <platform> [--frames N] <rom>',
'list-tools': 'list-tools',
'list-platforms': 'list-platforms',
}
},
error: 'No command specified'
});
process.exit(1);
}
function parseArgs(argv: string[]): { command: string; args: { [key: string]: string }; positional: string[] } {
var command = argv[2];
var args: { [key: string]: string } = {};
var positional: string[] = [];
for (var i = 3; i < argv.length; i++) {
if (argv[i].startsWith('--')) {
var key = argv[i].substring(2);
if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
args[key] = argv[++i];
} else {
args[key] = 'true';
}
} else {
positional.push(argv[i]);
}
}
return { command, args, positional };
}
async function doCompile(args: { [key: string]: string }, positional: string[], checkOnly: boolean): Promise<void> {
var tool = args['tool'];
var platform = args['platform'];
var outputFile = args['output'];
var sourceFile = positional[0];
if (!tool || !platform || !sourceFile) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
error: 'Required: --tool <tool> --platform <platform> <source>'
});
process.exit(1);
}
if (!TOOLS[tool]) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
error: `Unknown tool: ${tool}. Use list-tools to see available tools.`
});
process.exit(1);
}
// Preload the tool's filesystem if needed
var preloadKey = tool;
if (TOOL_PRELOADFS[tool + '-' + platform]) {
preloadKey = tool;
}
await preload(tool, platform);
var result = await compileSourceFile(tool, platform, sourceFile);
if (!result.success) {
outputJSON({
success: false,
command: checkOnly ? 'check' : 'compile',
data: { errors: result.errors }
});
process.exit(1);
}
if (checkOnly) {
outputJSON({
success: true,
command: 'check',
data: {
tool: tool,
platform: platform,
source: sourceFile,
outputSize: result.output ? (result.output.code ? result.output.code.length : result.output.length) : 0,
}
});
return;
}
// Write output if requested
if (outputFile && result.output) {
var outData = result.output.code || result.output;
if (outData instanceof Uint8Array) {
fs.writeFileSync(outputFile, outData);
} else if (typeof outData === 'object') {
fs.writeFileSync(outputFile, JSON.stringify(outData));
} else {
fs.writeFileSync(outputFile, outData);
}
}
var outputSize = 0;
if (result.output) {
outputSize = result.output.code ? result.output.code.length : result.output.length;
}
outputJSON({
success: true,
command: 'compile',
data: {
tool: tool,
platform: platform,
source: sourceFile,
outputSize: outputSize,
outputFile: outputFile || null,
hasListings: result.listings ? Object.keys(result.listings).length > 0 : false,
hasSymbolmap: !!result.symbolmap,
}
});
}
async function doRun(args: { [key: string]: string }, positional: string[]): Promise<void> {
var platform = args['platform'];
var frames = parseInt(args['frames'] || '1');
var romFile = positional[0];
if (!platform || !romFile) {
outputJSON({
success: false,
command: 'run',
error: 'Required: --platform <platform> <rom>'
});
process.exit(1);
}
// Dynamic import of MachineRunner
try {
var runmachine = require('./runmachine.js');
var MachineRunner = runmachine.MachineRunner;
} catch (e) {
outputJSON({
success: false,
command: 'run',
error: `Could not load MachineRunner: ${e.message}`
});
process.exit(1);
}
outputJSON({
success: false,
command: 'run',
error: 'Run command not yet fully implemented (requires platform machine loading)'
});
}
function doListTools(): void {
var tools = listTools();
outputJSON({
success: true,
command: 'list-tools',
data: {
tools: tools,
count: tools.length
}
});
}
function doListPlatforms(): void {
var platforms = listPlatforms();
var details: { [key: string]: any } = {};
for (var p of platforms) {
details[p] = {
arch: PLATFORM_PARAMS[p].arch || 'unknown',
};
}
outputJSON({
success: true,
command: 'list-platforms',
data: {
platforms: details,
count: platforms.length
}
});
}
async function main() {
if (process.argv.length < 3) {
usage();
}
var { command, args, positional } = parseArgs(process.argv);
try {
switch (command) {
case 'compile':
await initialize();
await doCompile(args, positional, false);
break;
case 'check':
await initialize();
await doCompile(args, positional, true);
break;
case 'run':
await doRun(args, positional);
break;
case 'list-tools':
await initialize();
doListTools();
break;
case 'list-platforms':
await initialize();
doListPlatforms();
break;
default:
outputJSON({
success: false,
command: command,
error: `Unknown command: ${command}`
});
process.exit(1);
}
} catch (e) {
outputJSON({
success: false,
command: command,
error: e.message || String(e)
});
process.exit(1);
}
}
main();
+195
View File
@@ -0,0 +1,195 @@
// testlib - Clean async API for compiling and testing 8bitworkshop projects
// Wraps the worker build system for use in tests and CLI tools
import * as fs from 'fs';
import type { WorkerResult, WorkerMessage, WorkerErrorResult, WorkerOutputResult } from "../common/workertypes";
import { setupNodeEnvironment, handleMessage, store, TOOL_PRELOADFS } from "../worker/workerlib";
import { PLATFORM_PARAMS } from "../worker/platforms";
import { TOOLS } from "../worker/workertools";
export { store, TOOL_PRELOADFS, PLATFORM_PARAMS, TOOLS };
export interface CompileOptions {
tool: string;
platform: string;
code?: string;
path?: string;
files?: { path: string; data: string | Uint8Array }[];
buildsteps?: { path: string; platform: string; tool: string }[];
mainfile?: boolean;
}
export interface CompileResult {
success: boolean;
output?: Uint8Array | any;
errors?: { line: number; msg: string; path?: string }[];
listings?: any;
symbolmap?: any;
params?: any;
unchanged?: boolean;
}
let initialized = false;
/**
* Initialize the Node.js environment for compilation.
* Must be called once before any compile/preload calls.
*/
export async function initialize(): Promise<void> {
if (initialized) return;
setupNodeEnvironment();
// The worker tools are already registered through the import chain:
// workerlib -> workertools -> tools/* and builder -> TOOLS
// No need to load the esbuild bundle.
initialized = true;
}
/**
* Preload a tool's filesystem (e.g. CC65 standard libraries).
*/
export async function preload(tool: string, platform?: string): Promise<void> {
await initialize();
var msg: WorkerMessage = { preload: tool } as any;
if (platform) (msg as any).platform = platform;
await handleMessage(msg);
}
/**
* Compile source code with the specified tool and platform.
*/
export async function compile(options: CompileOptions): Promise<CompileResult> {
await initialize();
// Reset the store for a clean build
await handleMessage({ reset: true } as any);
let result: WorkerResult;
if (options.files && options.buildsteps) {
// Multi-file build
var msg: any = {
updates: options.files.map(f => ({ path: f.path, data: f.data })),
buildsteps: options.buildsteps
};
result = await handleMessage(msg);
} else {
// Single-file build
var msg: any = {
code: options.code,
platform: options.platform,
tool: options.tool,
path: options.path || ('src.' + options.tool),
mainfile: options.mainfile !== false
};
result = await handleMessage(msg);
}
return workerResultToCompileResult(result);
}
/**
* Compile a file from the presets directory.
*/
export async function compileFile(tool: string, platform: string, presetPath: string): Promise<CompileResult> {
await initialize();
var code = fs.readFileSync('presets/' + platform + '/' + presetPath, 'utf-8');
return compile({
tool: tool,
platform: platform,
code: code,
path: presetPath,
});
}
/**
* Compile an arbitrary source file path.
*/
export async function compileSourceFile(tool: string, platform: string, filePath: string): Promise<CompileResult> {
await initialize();
var code = fs.readFileSync(filePath, 'utf-8');
var basename = filePath.split('/').pop();
return compile({
tool: tool,
platform: platform,
code: code,
path: basename,
});
}
function workerResultToCompileResult(result: WorkerResult): CompileResult {
if (!result) {
return { success: true, unchanged: true };
}
if ('unchanged' in result && result.unchanged) {
return { success: true, unchanged: true };
}
if ('errors' in result && result.errors && result.errors.length > 0) {
return {
success: false,
errors: result.errors,
};
}
if ('output' in result) {
return {
success: true,
output: result.output,
listings: (result as any).listings,
symbolmap: (result as any).symbolmap,
params: (result as any).params,
};
}
return { success: false, errors: [{ line: 0, msg: 'Unknown result format' }] };
}
/**
* List available compilation tools.
*/
export function listTools(): string[] {
return Object.keys(TOOLS);
}
/**
* List available target platforms.
*/
export function listPlatforms(): string[] {
return Object.keys(PLATFORM_PARAMS);
}
/**
* Convert a binary buffer to a hex string for display.
*/
export function ab2str(buf: Buffer | ArrayBuffer): string {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
// Platform test harness utilities
/**
* Create a mock localStorage for tests that need it.
*/
export function createMockLocalStorage(): Storage {
var items: { [key: string]: string } = {};
return {
get length() {
return Object.keys(items).length;
},
clear() {
items = {};
},
getItem(k: string) {
return items[k] || null;
},
setItem(k: string, v: string) {
items[k] = v;
},
removeItem(k: string) {
delete items[k];
},
key(i: number) {
return Object.keys(items)[i] || null;
}
};
}
+140
View File
@@ -0,0 +1,140 @@
// workerlib.ts - Node.js-friendly entry point for the worker build system
// Re-exports core worker functionality without Web Worker onmessage/postMessage wiring
import * as fs from 'fs';
import * as path from 'path';
import type { WorkerResult, WorkerMessage } from "../common/workertypes";
import { getBasePlatform, getRootBasePlatform } from "../common/util";
import { TOOL_PRELOADFS } from "./workertools";
import { store, builder } from "./builder";
import { emglobal, fsMeta, loadFilesystem } from "./wasmutils";
import { setupRequireFunction } from "./workermain";
export { store, builder, TOOL_PRELOADFS };
export { PLATFORM_PARAMS } from "./platforms";
export { TOOLS } from "./workertools";
class Blob {
private data: string;
size: number;
length: number;
constructor(data: string) {
this.data = data;
this.size = data.length;
this.length = data.length;
}
slice(a: number, b: number): Blob {
return new Blob(this.data.slice(a, b));
}
arrayBuffer(): Uint8Array {
return this.asArrayBuffer();
}
asArrayBuffer(): Uint8Array {
var buf = new ArrayBuffer(this.data.length);
var arr = new Uint8Array(buf);
for (var i = 0; i < this.data.length; i++)
arr[i] = this.data.charCodeAt(i);
return arr;
}
}
/**
* Set up the Node.js environment to provide XMLHttpRequest, fetch, and other
* browser globals that the worker build system expects.
* Call this once before using handleMessage/builder.
*/
export function setupNodeEnvironment() {
// Basic globals expected by various parts of the worker system
emglobal.window = emglobal;
emglobal.exports = {};
emglobal.self = emglobal;
emglobal.location = { href: '.' };
emglobal.path = path;
emglobal.btoa = require('btoa');
emglobal.atob = require('atob');
try { emglobal.navigator = emglobal; } catch (e) { /* read-only in newer Node */ }
emglobal.ResizeObserver = class { observe() { } };
// XMLHttpRequest shim that reads from the local filesystem
emglobal.XMLHttpRequest = function () {
this.open = function (method: string, url: string, async?: boolean) {
if (this.responseType == 'json') {
var txt = fs.readFileSync('src/worker/' + url, 'utf-8');
this.response = JSON.parse(txt);
} else if (this.responseType == 'blob') {
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
this.response = new Blob(data);
} else if (this.responseType == 'arraybuffer') {
var data = fs.readFileSync('src/worker/' + url, { encoding: 'binary' });
this.response = new Blob(data).asArrayBuffer();
}
this.status = this.response ? 200 : 404;
};
this.send = function () { };
};
// FileReaderSync shim
emglobal.FileReaderSync = function () {
this.readAsArrayBuffer = function (blob: any) {
return blob.asArrayBuffer();
};
};
// fetch shim that reads from the local filesystem
emglobal.fetch = function (filepath: string) {
return new Promise((resolve, reject) => {
try {
var bin = fs.readFileSync(filepath, { encoding: 'binary' });
var response = new Blob(bin);
resolve(response);
} catch (e) {
reject(e);
}
});
};
// importScripts shim - runs scripts in the global context like a web worker would.
// In the web worker, importScripts loads relative to the worker bundle.
// PWORKER is "../../src/worker/", so paths like "../../src/worker/asmjs/dasm.js"
// need to be resolved to the actual file on disk.
var vm = require('vm');
emglobal.importScripts = function (scriptPath: string) {
// Strip the PWORKER prefix and load from src/worker/
var resolved = scriptPath.replace(/^\.\.\/\.\.\//, '');
var fullPath = path.resolve(process.cwd(), resolved);
var code = fs.readFileSync(fullPath, 'utf-8');
vm.runInThisContext(code, fullPath);
};
// Suppress onmessage/postMessage (not used in Node mode)
emglobal.onmessage = null;
emglobal.postMessage = null;
// Set up the require function for WASM modules
setupRequireFunction();
}
/**
* Handle a worker message (preload, reset, or build).
* Same logic as workermain.ts handleMessage but exported for direct use.
*/
export async function handleMessage(data: WorkerMessage): Promise<WorkerResult> {
// preload file system
if (data.preload) {
var fsName = TOOL_PRELOADFS[data.preload];
if (!fsName && data.platform)
fsName = TOOL_PRELOADFS[data.preload + '-' + getBasePlatform(data.platform)];
if (!fsName && data.platform)
fsName = TOOL_PRELOADFS[data.preload + '-' + getRootBasePlatform(data.platform)];
if (fsName && !fsMeta[fsName])
loadFilesystem(fsName);
return;
}
// clear filesystem?
if (data.reset) {
store.reset();
return;
}
return builder.handleMessage(data);
}