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

npm upgrade, started oscar64

This commit is contained in:
Steven Hugg
2024-10-14 12:28:24 -05:00
parent f5d2c654fc
commit 87ae81cecd
12 changed files with 179 additions and 68 deletions
+2 -2
View File
File diff suppressed because one or more lines are too long
+20 -19
View File
@@ -593,16 +593,16 @@
}
},
"node_modules/@types/mocha": {
"version": "10.0.8",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz",
"integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==",
"version": "10.0.9",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz",
"integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
"version": "22.7.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
"devOptional": true,
"license": "MIT",
"dependencies": {
@@ -1364,9 +1364,9 @@
}
},
"node_modules/chromedriver": {
"version": "129.0.1",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-129.0.1.tgz",
"integrity": "sha512-thJqK3c7p9rIhmjBvs/cgaK0Hk30g7LbnmMXQ2aLnn75ZOiEl/2GBcgc6fw+4GIw1SmOYhnNmaEI1iTP3qob0w==",
"version": "129.0.4",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-129.0.4.tgz",
"integrity": "sha512-j5I55cQwodFJUaYa1tWUmj2ss9KcPRBWmUa5Qonq3X8kqv2ASPyTboFYb4YB/YLztkYTUUw2E43txXw0wYzT/A==",
"hasInstallScript": true,
"license": "Apache-2.0",
"optional": true,
@@ -1703,10 +1703,11 @@
"optional": true
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -2352,9 +2353,9 @@
}
},
"node_modules/express": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
"version": "4.21.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2363,7 +2364,7 @@
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -7174,9 +7175,9 @@
}
},
"node_modules/typescript": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
+16 -16
View File
@@ -5,15 +5,16 @@ For more information, see "Making Arcade Games in C".
#include "common.h"
// BASL = text address of cursor position
static byte** BASL = (byte**) 0xD1;
// BASL = text address of start of cursor line
byte** BASL = (byte**) 0xD1;
// get the character at a specfic x/y position
byte readcharxy(byte x, byte y) {
gotoxy(x,y); // set cursor position
return (*BASL)[x]; // lookup value @ cursor address
gotoxy(x,y); // set BASL
return (*BASL)[x]; // read character at (x,y)
}
// delay for 'count' frames
void delay(byte count) {
while (count--) {
waitvsync();
@@ -23,19 +24,18 @@ void delay(byte count) {
////////// GAME DATA
typedef struct {
byte x;
byte y;
byte dir;
word score;
char head_attr;
char tail_attr;
int collided:1;
int human:1;
byte x; // x coordinate
byte y; // y coordinate
byte dir; // direction (0-3)
word score; // current score
char head_attr; // char to draw player
char tail_attr; // char to draw trail
int collided:1; // did we collide? (boolean)
int human:1; // is this player a human? (boolean)
} Player;
Player players[2];
Player players[2]; // two player structs
byte credits = 0;
byte frames_per_move;
byte gameover;
@@ -66,8 +66,8 @@ void draw_box(byte x, byte y, byte x2, byte y2, const char* chars) {
void draw_playfield() {
draw_box(0,1,COLS-1,ROWS-1,BOX_CHARS);
cputsxy( 0, 0, "Plyr1:");
cputsxy(20, 0, "Plyr2:");
cputsxy( 0, 0, "plyr1:");
cputsxy(20, 0, "plyr2:");
cputcxy( 7, 0, players[0].score+'0');
cputcxy(27, 0, players[1].score+'0');
}
+3
View File
@@ -443,6 +443,9 @@ export function getToolForFilename_6502(fn:string) : string {
if (fn.endsWith(".acme")) return "acme";
if (fn.endsWith(".wiz")) return "wiz";
if (fn.endsWith(".ecs")) return "ecs";
if (fn.endsWith(".cpp")) return "oscar64";
if (fn.endsWith(".cc")) return "oscar64";
if (fn.endsWith(".o64")) return "oscar64";
return "dasm"; // .a
}
+46 -2
View File
@@ -284,6 +284,14 @@ export class WASIMemoryFilesystem implements WASIFilesystem {
this.files.set(name, file);
return file;
}
putSymbolicLink(name: string, target: string, rights?: number) {
if (!rights) rights = FDRights.PATH_SYMLINK;
const file = new WASIFileDescriptor(name, FDType.SYMBOLIC_LINK, rights);
file.write(new TextEncoder().encode(target));
file.offset = 0;
this.files.set(name, file);
return file;
}
getFile(name: string) {
let file = this.files.get(name);
if (!file) {
@@ -450,6 +458,7 @@ export class WASIRunner {
const bytes = enc.encode(str);
const len = Math.min(bytes.length, maxlen);
this.mem8().set(bytes.subarray(0, len), ptr);
return len;
}
peekUTF8(ptr: number, maxlen: number) {
const bytes = this.mem8().subarray(ptr, ptr + maxlen);
@@ -626,6 +635,39 @@ export class WASIRunner {
this.poke64(filestat_ptr + 48, 0); // mtim
this.poke64(filestat_ptr + 56, 0); // ctim
}
path_readlink(dirfd: number, path_ptr: number, path_len: number, buf_ptr: number, buf_len: number, buf_used_ptr: number) {
const dir = this.fds[dirfd];
if (dir == null) return WASIErrors.BADF;
if (dir.type !== FDType.DIRECTORY) return WASIErrors.NOTDIR;
const filename = this.peekUTF8(path_ptr, path_len);
const path = dir.name + '/' + filename;
const fd = this.fs.getFile(path);
debug("path_readlink", path, fd+"");
if (!fd) return WASIErrors.NOENT;
if (fd.type !== FDType.SYMBOLIC_LINK) return WASIErrors.INVAL;
const target = fd.getBytesAsString();
const len = this.pokeUTF8(target, buf_ptr, buf_len);
this.poke32(buf_used_ptr, len);
debug("path_readlink", path, '->', target);
return WASIErrors.SUCCESS;
}
path_unlink_file(dirfd: number, path_ptr: number, path_len: number) {
const dir = this.fds[dirfd];
if (dir == null) return WASIErrors.BADF;
if (dir.type !== FDType.DIRECTORY) return WASIErrors.NOTDIR;
const filename = this.peekUTF8(path_ptr, path_len);
const path = dir.name + '/' + filename;
const fd = this.fs.getFile(path);
debug("path_unlink_file", dir+"", path, fd+"");
if (!fd) return WASIErrors.NOENT;
this.fs.getFile(path);
return WASIErrors.SUCCESS;
}
clock_time_get(clock_id: number, precision: number, time_ptr: number) {
const time = Date.now();
this.poke64(time_ptr, time);
return WASIErrors.SUCCESS;
}
getWASISnapshotPreview1() {
return {
args_sizes_get: this.args_sizes_get.bind(this),
@@ -643,11 +685,13 @@ export class WASIRunner {
fd_close: this.fd_close.bind(this),
path_filestat_get: this.path_filestat_get.bind(this),
random_get: this.random_get.bind(this),
path_readlink: this.path_readlink.bind(this),
path_unlink_file: this.path_unlink_file.bind(this),
clock_time_get: this.clock_time_get.bind(this),
fd_fdstat_set_flags() { warning("TODO: fd_fdstat_set_flags"); return WASIErrors.NOTSUP; },
fd_readdir() { warning("TODO: fd_readdir"); return WASIErrors.NOTSUP; },
path_unlink_file() { warning("TODO: path_unlink_file"); return WASIErrors.NOTSUP; },
clock_time_get() { warning("TODO: clock_time_get"); return WASIErrors.NOTSUP; },
fd_tell() { warning("TODO: fd_tell"); return WASIErrors.NOTSUP; },
path_remove_directory() { warning("TODO: path_remove_directory"); return 0; },
}
}
getEnv() {
+1
View File
@@ -137,6 +137,7 @@ const TOOL_TO_SOURCE_STYLE = {
'remote:llvm-mos': 'text/x-csrc',
'cc7800': 'text/x-csrc',
'armtcc': 'text/x-csrc',
'oscar64': 'text/x-csrc',
}
// TODO: move into tool class
+1 -1
View File
@@ -6,6 +6,7 @@ import { BaseMAME6502Platform } from "../common/mameplatform";
const C64_PRESETS : Preset[] = [
{id:'helloc.c', name:'Hello World', category:'C'},
{id:'siegegame.c', name:'Siege Game'},
{id:'screen_ram.c', name:'Screen RAM'},
{id:'joymove.c', name:'Sprite Movement'},
{id:'sprite_collision.c', name:'Sprite Collision'},
@@ -32,7 +33,6 @@ const C64_PRESETS : Preset[] = [
{id:'test_border_sprites.c', name:'Sprites in the Borders'},
{id:'sprite_stretch.c', name:'Sprite Stretching'},
{id:'plasma.c', name:'Plasma Demo'},
{id:'siegegame.c', name:'Siege Game'},
{id:'23matches.c', name:'23 Matches'},
{id:'tgidemo.c', name:'TGI Graphics Demo'},
{id:'upandaway.c', name:'Up, Up and Away'},
+25
View File
@@ -1,6 +1,7 @@
import assert from "assert";
import { WASIRunner } from "../common/wasi/wasishim";
import * as fs from "fs";
import { loadWASIFilesystemZip, unzipWASIFilesystem } from "../worker/wasiutils";
async function loadWASM(filename: string) {
const wasmdata = fs.readFileSync(`./src/worker/wasm/${filename}.wasm`);
@@ -15,6 +16,9 @@ async function loadDASM() {
async function loadCC7800() {
return loadWASM('cc7800');
}
async function loadOscar64() {
return loadWASM('oscar64');
}
describe('test WASI DASM', function () {
it('dasm help', async function () {
@@ -78,3 +82,24 @@ describe('test WASI cc7800', function () {
});
});
/*
describe('test WASI oscar64', function () {
it('oscar64 compile', async function () {
let shim = await loadOscar64();
const zipdata = fs.readFileSync(`./src/worker/fs/oscar64-fs.zip`);
shim.fs = await unzipWASIFilesystem(zipdata, "/root/");
shim.fs.putSymbolicLink("/proc/self/exe", "/root/bin/oscar64");
shim.fs.putFile("/root/main.c", "#include <stdio.h>\nint main() { return 0; }");
shim.addPreopenDirectory("");
shim.setArgs(["oscar64", '-v', '-o=foo.prg', '/root/main.c']);
let errno = shim.run();
const stdout = shim.fds[1].getBytesAsString();
console.log(stdout);
const stderr = shim.fds[2].getBytesAsString();
console.log(stderr);
assert.strictEqual(errno, 0);
assert.ok(stdout.indexOf('Starting oscar64') >= 0);
console.log(shim.fs.getFile("./foo.asm").getBytesAsString());
});
});
*/
+39 -22
View File
@@ -8,6 +8,22 @@ import { parseObjDump } from './clang';
import { BuildStep } from '../builder';
import { makeErrorMatcher } from '../listingutils';
interface ServerBuildTool {
name: string;
version: string;
extensions: string[];
archs: string[];
platforms: string[];
platform_configs: { [platform: string]: ServerBuildToolPlatformConfig };
}
interface ServerBuildToolPlatformConfig {
binpath?: string;
command?: string;
args?: string[];
libargs?: string[];
outfile?: string;
}
const LLVM_MOS_TOOL: ServerBuildTool = {
name: 'llvm-mos',
@@ -45,6 +61,24 @@ const LLVM_MOS_TOOL: ServerBuildTool = {
}
}
const OSCAR64_TOOL: ServerBuildTool = {
name: 'oscar64',
version: '',
extensions: ['.c', '.cc', '.cpp'],
archs: ['6502'],
platforms: ['atari8', 'c64', 'nes'],
platform_configs: {
default: {
binpath: 'oscar64/bin',
command: 'oscar64',
args: ['-Os', '-g', '-d__8BITWORKSHOP__', '-o=$OUTFILE', '$INFILES'],
},
c64: {
outfile: 'a.prg',
}
}
}
export function findBestTool(step: BuildStep) {
if (!step?.tool) throw new Error('No tool specified');
const [name, version] = step.tool.split('@');
@@ -58,25 +92,9 @@ export function findBestTool(step: BuildStep) {
export const TOOLS: ServerBuildTool[] = [
Object.assign({}, LLVM_MOS_TOOL, { version: 'latest' }),
Object.assign({}, OSCAR64_TOOL, { version: 'latest' }),
];
interface ServerBuildTool {
name: string;
version: string;
extensions: string[];
archs: string[];
platforms: string[];
platform_configs: { [platform: string]: ServerBuildToolPlatformConfig };
}
interface ServerBuildToolPlatformConfig {
binpath?: string;
command?: string;
args?: string[];
libargs?: string[];
}
export class ServerBuildEnv {
@@ -124,7 +142,7 @@ export class ServerBuildEnv {
let args = config.args.slice(0); //copy array
let command = config.command;
// replace $OUTFILE
let outfile = path.join(this.sessionDir, 'a.out'); // TODO? a.out
let outfile = path.join(this.sessionDir, config.outfile || 'a.out');
for (let i = 0; i < args.length; i++) {
args[i] = args[i].replace(/\$OUTFILE/g, outfile);
args[i] = args[i].replace(/\$WORKDIR/g, this.sessionDir);
@@ -173,7 +191,7 @@ export class ServerBuildEnv {
if (platform === 'debug') {
resolve(this.processDebugInfo(step));
} else {
resolve(this.processOutput(step));
resolve(this.processOutput(step, outfile));
}
} else {
errorData = replaceAll(errorData, this.sessionDir, '');
@@ -200,8 +218,7 @@ export class ServerBuildEnv {
return { errors };
}
async processOutput(step: WorkerBuildStep): Promise<WorkerResult> {
let outfile = path.join(this.sessionDir, 'a.out');
async processOutput(step: WorkerBuildStep, outfile: string): Promise<WorkerResult> {
let output = await fs.promises.readFile(outfile, { encoding: 'base64' });
return { output };
}
@@ -220,7 +237,7 @@ export class ServerBuildEnv {
try {
let result = await this.build(step);
// did we succeed?
if (isOutputResult(result)) {
if (step.tool == 'llvm-mos' && isOutputResult(result)) {
// do the debug info
const debugInfo = await this.build(step, 'debug');
if (isOutputResult(debugInfo)) {
+14 -1
View File
@@ -30,7 +30,7 @@ app.get('/info', (req: Request, res: Response) => {
res.json({ tools: TOOLS });
});
app.get('/test', async (req: Request, res: Response, next) => {
app.get('/test1', async (req: Request, res: Response, next) => {
// quick test of the build
try {
const updates: WorkerFileUpdate[] = [{ path: 'test.c', data: 'int main() { return 0; }' }];
@@ -43,6 +43,19 @@ app.get('/test', async (req: Request, res: Response, next) => {
}
});
app.get('/test2', async (req: Request, res: Response, next) => {
// quick test of the build
try {
const updates: WorkerFileUpdate[] = [{ path: 'test.c', data: 'int main() { return 0; }' }];
const buildStep: WorkerBuildStep = { tool: 'oscar64', platform: 'c64', files: ['test.c'] };
const env = new ServerBuildEnv(SERVER_ROOT, 'test', TOOLS[1]);
const result = await env.compileAndLink(buildStep, updates);
res.json(result);
} catch (err) {
return next(err);
}
});
app.post('/build', async (req: Request, res: Response, next) => {
try {
const updates: WorkerFileUpdate[] = req.body.updates;
+10 -5
View File
@@ -9,11 +9,8 @@ export function loadBlobSync(path: string) {
return xhr.response;
}
export async function loadWASIFilesystemZip(zippath: string) {
export async function unzipWASIFilesystem(zipdata: ArrayBuffer, rootPath: string = "./") {
const jszip = new JSZip();
const path = '../../src/worker/fs/' + zippath;
const zipdata = loadBlobSync(path);
console.log(zippath, zipdata);
await jszip.loadAsync(zipdata);
let fs = new WASIMemoryFilesystem();
let promises = [];
@@ -21,7 +18,7 @@ export async function loadWASIFilesystemZip(zippath: string) {
if (zipEntry.dir) {
fs.putDirectory(relativePath);
} else {
let path = './' + relativePath;
let path = rootPath + relativePath;
let prom = zipEntry.async("uint8array").then((data) => {
fs.putFile(path, data);
});
@@ -31,3 +28,11 @@ export async function loadWASIFilesystemZip(zippath: string) {
await Promise.all(promises);
return fs;
}
export async function loadWASIFilesystemZip(zippath: string, rootPath: string = "./") {
const jszip = new JSZip();
const path = '../../src/worker/fs/' + zippath;
const zipdata = loadBlobSync(path);
console.log(zippath, zipdata);
return unzipWASIFilesystem(zipdata, rootPath);
}
+2
View File
@@ -14,6 +14,7 @@ import * as remote from './tools/remote'
import * as acme from './tools/acme'
import * as cc7800 from './tools/cc7800'
import * as bataribasic from './tools/bataribasic'
import * as oscar64 from './tools/oscar64'
import { PLATFORM_PARAMS } from "./platforms";
export const TOOLS = {
@@ -54,6 +55,7 @@ export const TOOLS = {
'cc7800': cc7800.compileCC7800,
'armtcc': arm.compileARMTCC,
'armtcclink': arm.linkARMTCC,
'oscar64': oscar64.compileOscar64,
}
export const TOOL_PRELOADFS = {