mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-23 03:29:05 +00:00
serial test harness, readFile/writeFile, tty save/load state
This commit is contained in:
parent
d482145319
commit
244377e2a6
14
css/ui.css
14
css/ui.css
@ -4,9 +4,6 @@
|
||||
.gutter-offset {
|
||||
width: 3em;
|
||||
}
|
||||
.CodeMirror-gutter-elt:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.gutter-bytes {
|
||||
width: 6em;
|
||||
}
|
||||
@ -17,6 +14,10 @@
|
||||
width: 1em;
|
||||
cursor: cell;
|
||||
}
|
||||
.CodeMirror-gutter-elt:hover {
|
||||
text-decoration: underline;
|
||||
cursor: cell;
|
||||
}
|
||||
.currentpc-span {
|
||||
background-color: #7e2a70;
|
||||
}
|
||||
@ -659,6 +660,13 @@ div.asset_toolbar {
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.transcript-style-16 { /* alternate */
|
||||
color: #6666ff;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
.transcript-style-32 { /* alternate 2 */
|
||||
background-color: #eee;
|
||||
}
|
||||
.transcript-reverse {
|
||||
background-color: #666;
|
||||
color: #ddd;
|
||||
|
@ -188,6 +188,7 @@ TODO:
|
||||
- no import in workers
|
||||
- copy to gen/ directory (allowJs is weird)
|
||||
- ca65 line numbers are not aligned with source code
|
||||
- neither are DASM when you change comments
|
||||
- segments not read properly
|
||||
- Debug Browser
|
||||
- more stuff like 7800 display lists
|
||||
@ -197,6 +198,7 @@ TODO:
|
||||
|
||||
Probing
|
||||
- probe log doesn't start @ reset
|
||||
Debug, play then halt cpu doesn't highlight final line
|
||||
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
@ -135,6 +135,9 @@ export interface Platform {
|
||||
stopProbing?() : void;
|
||||
|
||||
isBlocked?() : boolean; // is blocked, halted, or waiting for input?
|
||||
|
||||
readFile?(path: string) : FileData;
|
||||
writeFile?(path: string, data: FileData) : boolean;
|
||||
}
|
||||
|
||||
export interface Preset {
|
||||
@ -186,6 +189,7 @@ export interface EmuRecorder {
|
||||
export abstract class BasePlatform {
|
||||
recorder : EmuRecorder = null;
|
||||
debugSymbols : DebugSymbols;
|
||||
internalFiles : {[path:string] : FileData} = {};
|
||||
|
||||
abstract loadState(state : EmuState) : void;
|
||||
abstract saveState() : EmuState;
|
||||
@ -208,6 +212,13 @@ export abstract class BasePlatform {
|
||||
getDebugTree() : {} {
|
||||
return this.saveState();
|
||||
}
|
||||
readFile(path: string) : FileData {
|
||||
return this.internalFiles[path];
|
||||
}
|
||||
writeFile(path: string, data: FileData) : boolean {
|
||||
this.internalFiles[path] = data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class BaseDebugPlatform extends BasePlatform {
|
||||
@ -283,7 +294,7 @@ export abstract class BaseDebugPlatform extends BasePlatform {
|
||||
}
|
||||
pollControls() {
|
||||
}
|
||||
nextFrame(novideo : boolean) {
|
||||
nextFrame(novideo : boolean) : number {
|
||||
this.pollControls();
|
||||
this.updateRecorder();
|
||||
this.preFrame();
|
||||
@ -1021,7 +1032,7 @@ export function lookupSymbol(platform:Platform, addr:number, extra:boolean) {
|
||||
|
||||
/// new Machine platform adapters
|
||||
|
||||
import { Bus, Resettable, FrameBased, VideoSource, SampledAudioSource, AcceptsROM, AcceptsBIOS, AcceptsKeyInput, SavesState, SavesInputState, HasCPU, TrapCondition, CPU } from "./devices";
|
||||
import { Bus, Resettable, FrameBased, VideoSource, SampledAudioSource, AcceptsROM, AcceptsBIOS, AcceptsKeyInput, SavesState, SavesInputState, HasCPU, TrapCondition, CPU, HasSerialIO, SerialIOInterface } from "./devices";
|
||||
import { Probeable, RasterFrameBased, AcceptsPaddleInput, SampledAudioSink, ProbeAll, NullProbe } from "./devices";
|
||||
import { SampledAudio } from "./audio";
|
||||
import { ProbeRecorder } from "./recorder";
|
||||
@ -1050,6 +1061,9 @@ export function hasProbe(arg:any): arg is Probeable {
|
||||
export function hasBIOS(arg:any): arg is AcceptsBIOS {
|
||||
return typeof arg.loadBIOS == 'function';
|
||||
}
|
||||
export function hasSerialIO(arg:any): arg is HasSerialIO {
|
||||
return typeof arg.connectSerialIO === 'function';
|
||||
}
|
||||
|
||||
export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPlatform implements Platform {
|
||||
machine : T;
|
||||
@ -1123,6 +1137,9 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
|
||||
m.loadBIOS(data, title);
|
||||
};
|
||||
}
|
||||
if (hasSerialIO(m) && this.serialIOInterface) {
|
||||
m.connectSerialIO(this.serialIOInterface);
|
||||
}
|
||||
}
|
||||
|
||||
loadROM(title, data) {
|
||||
@ -1130,7 +1147,9 @@ export abstract class BaseMachinePlatform<T extends Machine> extends BaseDebugPl
|
||||
this.reset();
|
||||
}
|
||||
|
||||
loadBIOS; // only set if hasBIOS() is true
|
||||
loadBIOS : (title, data) => void; // only set if hasBIOS() is true
|
||||
|
||||
serialIOInterface : SerialIOInterface; // set if hasSerialIO() is true
|
||||
|
||||
pollControls() {
|
||||
this.poller && this.poller.poll();
|
||||
|
@ -107,6 +107,26 @@ export interface AcceptsPaddleInput {
|
||||
setPaddleInput(controller:number, value:number) : void;
|
||||
}
|
||||
|
||||
// SERIAL I/O
|
||||
|
||||
export interface SerialIOInterface {
|
||||
// from machine to platform
|
||||
clearToSend() : boolean;
|
||||
sendByte(b : number);
|
||||
// from platform to machine
|
||||
byteAvailable() : boolean;
|
||||
recvByte() : number;
|
||||
// implement these too
|
||||
reset() : void;
|
||||
advance(clocks: number) : void;
|
||||
}
|
||||
|
||||
export interface HasSerialIO {
|
||||
connectSerialIO(serial: SerialIOInterface);
|
||||
}
|
||||
|
||||
/// PROFILER
|
||||
|
||||
export interface Probeable {
|
||||
connectProbe(probe: ProbeAll) : void;
|
||||
}
|
||||
@ -118,8 +138,6 @@ export function xorshift32(x : number) : number {
|
||||
return x;
|
||||
}
|
||||
|
||||
/// PROFILER
|
||||
|
||||
export interface ProbeTime {
|
||||
logClocks(clocks:number);
|
||||
logNewScanline();
|
||||
|
@ -159,6 +159,30 @@ export class TeleType {
|
||||
$(this.page).css('font-size', charwidth + 'px');
|
||||
this.scrollToBottom();
|
||||
}
|
||||
saveState() {
|
||||
return {
|
||||
curstyle: this.curstyle,
|
||||
reverse: this.reverse,
|
||||
col: this.col,
|
||||
row: this.row,
|
||||
ncharsout : this.ncharsout,
|
||||
lines: this.lines.map((line) => line.cloneNode(true)),
|
||||
}
|
||||
}
|
||||
loadState(state) {
|
||||
console.log(state);
|
||||
this.curstyle = state.curstyle;
|
||||
this.reverse = state.reverse;
|
||||
this.col = state.col;
|
||||
this.row = state.row;
|
||||
this.ncharsout = state.ncharsout;
|
||||
$(this.page).empty();
|
||||
for (var i=0; i<state.lines.length; i++) {
|
||||
this.page.appendChild(state.lines[i]);
|
||||
}
|
||||
this.lines = state.lines;
|
||||
this.curline = state.lines[this.row];
|
||||
}
|
||||
}
|
||||
|
||||
export class TeleTypeWithKeyboard extends TeleType {
|
||||
|
@ -487,3 +487,10 @@ export function getRootBasePlatform(platform : string) : string {
|
||||
return getRootPlatform(getBasePlatform(platform));
|
||||
}
|
||||
|
||||
export function convertDataToUint8Array(data: string|Uint8Array) : Uint8Array {
|
||||
return (typeof data === 'string') ? stringToByteArray(data) : data;
|
||||
}
|
||||
|
||||
export function convertDataToString(data: string|Uint8Array) : string {
|
||||
return (data instanceof Uint8Array) ? byteArrayToUTF8(data) : data;
|
||||
}
|
||||
|
@ -1389,10 +1389,14 @@ function clearBreakpoint() {
|
||||
showDebugInfo();
|
||||
}
|
||||
|
||||
function resetPlatform() {
|
||||
platform.reset();
|
||||
}
|
||||
|
||||
function resetAndRun() {
|
||||
if (!checkRunReady()) return;
|
||||
clearBreakpoint();
|
||||
platform.reset();
|
||||
resetPlatform();
|
||||
_resume();
|
||||
}
|
||||
|
||||
@ -1403,11 +1407,11 @@ function resetAndDebug() {
|
||||
if (platform.setupDebug && platform.runEval) { // TODO??
|
||||
clearBreakpoint();
|
||||
_resume();
|
||||
platform.reset();
|
||||
resetPlatform();
|
||||
setupBreakpoint("restart");
|
||||
platform.runEval((c) => { return true; }); // break immediately
|
||||
} else {
|
||||
platform.reset();
|
||||
resetPlatform();
|
||||
_resume();
|
||||
}
|
||||
if (wasRecording) _enableRecording();
|
||||
@ -1930,8 +1934,9 @@ function globalErrorHandler(msgevent) {
|
||||
} else {
|
||||
var err = msgevent.error || msgevent.reason;
|
||||
if (err != null && err instanceof EmuHalt) {
|
||||
msg = (err && err.message) || msg;
|
||||
showExceptionAsError(err, msg);
|
||||
setDebugButtonState("pause", "stopped");
|
||||
emulationHalted(err);
|
||||
// TODO: reset platform?
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2294,6 +2299,23 @@ redirectToHTTPS();
|
||||
|
||||
//// ELECTRON STUFF
|
||||
|
||||
export function setTestInput(path: string, data: FileData) {
|
||||
platform.writeFile(path, data);
|
||||
}
|
||||
|
||||
export function getTestOutput(path: string) : FileData {
|
||||
return platform.readFile(path);
|
||||
}
|
||||
|
||||
export function getSaveState() {
|
||||
return platform.saveState();
|
||||
}
|
||||
|
||||
export function emulationHalted(err: EmuHalt) {
|
||||
var msg = (err && err.message) || msg;
|
||||
showExceptionAsError(err, msg);
|
||||
}
|
||||
|
||||
// get remote file from local fs
|
||||
declare var getWorkspaceFile, putWorkspaceFile;
|
||||
export function getElectronFile(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
|
||||
|
@ -1,30 +1,41 @@
|
||||
|
||||
import { MOS6502 } from "../common/cpu/MOS6502";
|
||||
import { BasicHeadlessMachine } from "../common/devices";
|
||||
import { BasicHeadlessMachine, HasSerialIO, SerialIOInterface } from "../common/devices";
|
||||
import { padBytes, newAddressDecoder } from "../common/emu"; // TODO
|
||||
|
||||
export class Devel6502 extends BasicHeadlessMachine {
|
||||
const INPUT_HALTED = 31;
|
||||
|
||||
export class Devel6502 extends BasicHeadlessMachine implements HasSerialIO {
|
||||
|
||||
cpuFrequency = 1000000;
|
||||
defaultROMSize = 0x8000;
|
||||
|
||||
cpu = new MOS6502();
|
||||
ram = new Uint8Array(0x4000);
|
||||
rom : Uint8Array;
|
||||
|
||||
digits = [];
|
||||
serial : SerialIOInterface;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.connectCPUMemoryBus(this);
|
||||
}
|
||||
|
||||
connectSerialIO(serial: SerialIOInterface) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
read = newAddressDecoder([
|
||||
[0x0000, 0x3fff, 0x3fff, (a) => { return this.ram[a]; }],
|
||||
[0x4000, 0x4000, 0xffff, (a) => { return this.serial.byteAvailable() ? 0x80 : 0 }],
|
||||
[0x4001, 0x4001, 0xffff, (a) => { return this.serial.recvByte() }],
|
||||
[0x4002, 0x4002, 0xffff, (a) => { return this.serial.clearToSend() ? 0x80 : 0 }],
|
||||
[0x8000, 0xffff, 0x7fff, (a) => { return this.rom && this.rom[a]; }],
|
||||
]);
|
||||
|
||||
write = newAddressDecoder([
|
||||
[0x0000, 0x3fff, 0x3fff, (a,v) => { this.ram[a] = v; }],
|
||||
[0x4003, 0x4003, 0xffff, (a,v) => { return this.serial.sendByte(v) }],
|
||||
[0x400f, 0x400f, 0xffff, (a,v) => { this.inputs[INPUT_HALTED] = 1; }],
|
||||
]);
|
||||
|
||||
readConst(a:number) : number {
|
||||
@ -39,5 +50,20 @@ export class Devel6502 extends BasicHeadlessMachine {
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
|
||||
advanceCPU() {
|
||||
if (this.isHalted()) return 1;
|
||||
var n = super.advanceCPU();
|
||||
if (this.serial) this.serial.advance(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.inputs[INPUT_HALTED] = 0;
|
||||
super.reset();
|
||||
if (this.serial) this.serial.reset();
|
||||
}
|
||||
|
||||
isHalted() { return this.inputs[INPUT_HALTED] != 0; }
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,169 @@
|
||||
|
||||
import { Platform, getOpcodeMetadata_6502, getToolForFilename_6502 } from "../common/baseplatform";
|
||||
import { PLATFORMS } from "../common/emu";
|
||||
import { Platform } from "../common/baseplatform";
|
||||
import { EmuHalt, PLATFORMS } from "../common/emu";
|
||||
import { Devel6502 } from "../machine/devel";
|
||||
import { Base6502MachinePlatform } from "../common/baseplatform";
|
||||
import { SerialIOInterface } from "../common/devices";
|
||||
import { convertDataToUint8Array, hex } from "../common/util";
|
||||
import { TeleType } from "../common/teletype";
|
||||
import { emulationHalted, loadScript } from "../ide/ui";
|
||||
|
||||
var DEVEL_6502_PRESETS = [
|
||||
{id:'hello.dasm', name:'Hello World (ASM)'},
|
||||
];
|
||||
|
||||
class SerialInOutViewer {
|
||||
div : HTMLElement;
|
||||
tty : TeleType;
|
||||
|
||||
constructor(div: HTMLElement) {
|
||||
div.style.overflowY = 'auto';
|
||||
var gameport = $('<div id="gameport"/>').appendTo(div);
|
||||
var windowport = $('<div id="windowport" class="transcript"/>').appendTo(gameport);
|
||||
this.div = windowport[0];
|
||||
}
|
||||
start() {
|
||||
this.tty = new TeleType(this.div, false);
|
||||
//this.tty.ncols = 40;
|
||||
}
|
||||
reset() {
|
||||
this.tty.clear();
|
||||
}
|
||||
saveState() {
|
||||
return this.tty.saveState();
|
||||
}
|
||||
loadState(state) {
|
||||
this.tty.loadState(state);
|
||||
}
|
||||
}
|
||||
|
||||
function byteToASCII(b: number) : string {
|
||||
if (b == 10) return '';
|
||||
if (b < 32)
|
||||
return String.fromCharCode(b + 0x2400);
|
||||
else
|
||||
return String.fromCharCode(b);
|
||||
}
|
||||
|
||||
export class SerialTestHarness implements SerialIOInterface {
|
||||
|
||||
viewer : SerialInOutViewer;
|
||||
bufferedRead : boolean = true;
|
||||
cyclesPerByte = 1000000/(57600/8); // 138.88888 cycles
|
||||
maxOutputBytes = 4096;
|
||||
inputBytes : Uint8Array;
|
||||
|
||||
outputBytes : number[];
|
||||
inputIndex : number;
|
||||
clk : number;
|
||||
bufin : string;
|
||||
|
||||
clearToSend(): boolean {
|
||||
return this.outputBytes.length < this.maxOutputBytes;
|
||||
}
|
||||
sendByte(b: number) {
|
||||
if (this.clearToSend()) {
|
||||
this.outputBytes.push(b);
|
||||
this.viewer.tty.addtext(byteToASCII(b), 2|32);
|
||||
if (b == 10) this.viewer.tty.newline();
|
||||
if (!this.clearToSend()) {
|
||||
this.viewer.tty.newline();
|
||||
this.viewer.tty.addtext("⚠️ OUTPUT BUFFER FULL ⚠️", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
byteAvailable(): boolean {
|
||||
return this.readIndex() > this.inputIndex;
|
||||
}
|
||||
recvByte(): number {
|
||||
var index = this.readIndex();
|
||||
this.inputIndex = index;
|
||||
var b = this.inputBytes[index] | 0;
|
||||
//this.bufin += byteToASCII(b);
|
||||
this.viewer.tty.addtext(byteToASCII(b), 2|16);
|
||||
if (b == 10) this.viewer.tty.newline();
|
||||
return b;
|
||||
}
|
||||
readIndex(): number {
|
||||
return this.bufferedRead ? (this.inputIndex+1) : Math.floor(this.clk / this.cyclesPerByte);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.inputIndex = -1;
|
||||
this.clk = 0;
|
||||
this.outputBytes = [];
|
||||
this.bufin = '';
|
||||
}
|
||||
|
||||
advance(clocks: number) {
|
||||
this.clk += clocks;
|
||||
}
|
||||
|
||||
saveState() {
|
||||
return {
|
||||
clk: this.clk,
|
||||
idx: this.inputIndex,
|
||||
out: this.outputBytes.slice()
|
||||
}
|
||||
}
|
||||
loadState(state) {
|
||||
this.clk = state.clk;
|
||||
this.inputIndex = state.idx;
|
||||
this.outputBytes = state.out.slice();
|
||||
}
|
||||
}
|
||||
|
||||
class Devel6502Platform extends Base6502MachinePlatform<Devel6502> implements Platform {
|
||||
|
||||
serial : SerialTestHarness;
|
||||
serview : SerialInOutViewer;
|
||||
|
||||
constructor(mainElement: HTMLElement) {
|
||||
super(mainElement);
|
||||
this.serview = new SerialInOutViewer(mainElement);
|
||||
}
|
||||
|
||||
async start() {
|
||||
super.start();
|
||||
await loadScript('./gen/common/teletype.js');
|
||||
this.serial = new SerialTestHarness();
|
||||
this.serial.viewer = this.serview;
|
||||
this.serview.start();
|
||||
this.machine.connectSerialIO(this.serial);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.serial.inputBytes = convertDataToUint8Array(this.internalFiles['serialin.dat']);
|
||||
super.reset();
|
||||
this.serview.reset();
|
||||
}
|
||||
|
||||
isBlocked() {
|
||||
return this.machine.isHalted();
|
||||
}
|
||||
|
||||
advance(novideo: boolean) {
|
||||
if (this.isBlocked()) {
|
||||
this.internalFiles['serialout.dat'] = new Uint8Array(this.serial.outputBytes);
|
||||
throw new EmuHalt(null); // TODO: throws nasty exception
|
||||
}
|
||||
return super.advance(novideo);
|
||||
}
|
||||
|
||||
saveState() {
|
||||
var state : any = super.saveState();
|
||||
state.serial = this.serial.saveState();
|
||||
state.serview = this.serview.saveState();
|
||||
return state;
|
||||
}
|
||||
|
||||
loadState(state) {
|
||||
super.loadState(state);
|
||||
this.serial.loadState(state.serial);
|
||||
this.serview.loadState(state.serview);
|
||||
// TODO: reload tty UI
|
||||
}
|
||||
|
||||
newMachine() { return new Devel6502(); }
|
||||
getPresets() { return DEVEL_6502_PRESETS; }
|
||||
getDefaultExtension() { return ".dasm"; };
|
||||
|
@ -1,15 +1,67 @@
|
||||
|
||||
import { hasAudio, hasVideo, Machine } from "../common/baseplatform";
|
||||
import { SampledAudioSink } from "../common/devices";
|
||||
import { hasAudio, hasSerialIO, hasVideo, Machine } from "../common/baseplatform";
|
||||
import { SampledAudioSink, SerialIOInterface } from "../common/devices";
|
||||
|
||||
global.atob = require('atob');
|
||||
global.btoa = require('btoa');
|
||||
|
||||
class NullAudio implements SampledAudioSink {
|
||||
feedSample(value: number, count: number): void {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MachineRunner {
|
||||
// TODO: merge with platform
|
||||
class SerialTestHarness implements SerialIOInterface {
|
||||
|
||||
bufferedRead: boolean = true;
|
||||
cyclesPerByte = 1000000 / (57600 / 8); // 138.88888 cycles
|
||||
maxOutputBytes = 4096;
|
||||
inputBytes: Uint8Array;
|
||||
|
||||
outputBytes: number[];
|
||||
inputIndex: number;
|
||||
clk: number;
|
||||
bufin: string;
|
||||
|
||||
clearToSend(): boolean {
|
||||
return this.outputBytes.length < this.maxOutputBytes;
|
||||
}
|
||||
sendByte(b: number) {
|
||||
if (this.clearToSend()) {
|
||||
this.outputBytes.push(b);
|
||||
}
|
||||
}
|
||||
byteAvailable(): boolean {
|
||||
return this.readIndex() > this.inputIndex;
|
||||
}
|
||||
recvByte(): number {
|
||||
var index = this.readIndex();
|
||||
this.inputIndex = index;
|
||||
var b = this.inputBytes[index] | 0;
|
||||
return b;
|
||||
}
|
||||
readIndex(): number {
|
||||
return this.bufferedRead ? (this.inputIndex + 1) : Math.floor(this.clk / this.cyclesPerByte);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.inputIndex = -1;
|
||||
this.clk = 0;
|
||||
this.outputBytes = [];
|
||||
this.bufin = '';
|
||||
}
|
||||
|
||||
advance(clocks: number) {
|
||||
this.clk += clocks;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
export class MachineRunner {
|
||||
machine: Machine;
|
||||
pixels: Uint32Array;
|
||||
serial: SerialTestHarness;
|
||||
|
||||
constructor(machine: Machine) {
|
||||
this.machine = machine;
|
||||
@ -23,6 +75,10 @@ class MachineRunner {
|
||||
if (hasAudio(this.machine)) {
|
||||
this.machine.connectAudio(new NullAudio());
|
||||
}
|
||||
if (hasSerialIO(this.machine)) {
|
||||
this.serial = new SerialTestHarness();
|
||||
this.machine.connectSerialIO(this.serial);
|
||||
}
|
||||
this.machine.reset();
|
||||
}
|
||||
run() {
|
||||
@ -30,8 +86,8 @@ class MachineRunner {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMachine(modname: string, clsname: string) : Promise<Machine> {
|
||||
var mod = await import('../machine/'+modname);
|
||||
async function loadMachine(modname: string, clsname: string): Promise<Machine> {
|
||||
var mod = await import('../machine/' + modname);
|
||||
var cls = mod[clsname];
|
||||
var machine = new cls();
|
||||
return machine;
|
||||
@ -45,7 +101,6 @@ async function runMachine() {
|
||||
console.log(runner.machine.saveState());
|
||||
}
|
||||
|
||||
global.atob = require('atob');
|
||||
global.btoa = require('btoa');
|
||||
runMachine();
|
||||
|
||||
if (require.main === module) {
|
||||
runMachine();
|
||||
}
|
||||
|
@ -267,6 +267,11 @@ var PLATFORM_PARAMS = {
|
||||
extra_link_args: ['crt0-zx.rel'],
|
||||
extra_link_files: ['crt0-zx.rel', 'crt0-zx.lst'],
|
||||
},
|
||||
'devel-6502': {
|
||||
cfgfile: 'devel-6502.cfg',
|
||||
libargs: ['crt0.o', 'sim6502.lib'],
|
||||
extra_link_files: ['crt0.o', 'devel-6502.cfg'],
|
||||
},
|
||||
};
|
||||
|
||||
PLATFORM_PARAMS['sms-sms-libcv'] = PLATFORM_PARAMS['sms-sg1000-libcv'];
|
||||
@ -532,6 +537,7 @@ function setupFS(FS, name:string) {
|
||||
var WORKERFS = FS.filesystems['WORKERFS'];
|
||||
if (name === '65-vector') name = '65-sim6502'; // TODO
|
||||
if (name === '65-atari7800') name = '65-sim6502'; // TODO
|
||||
if (name === '65-devel') name = '65-sim6502'; // TODO
|
||||
if (!fsMeta[name]) throw Error("No filesystem for '" + name + "'");
|
||||
FS.mkdir('/share');
|
||||
FS.mount(WORKERFS, {
|
||||
@ -2712,6 +2718,8 @@ var TOOL_PRELOADFS = {
|
||||
'ca65-vector': '65-sim6502',
|
||||
'cc65-atari7800': '65-sim6502',
|
||||
'ca65-atari7800': '65-sim6502',
|
||||
'cc65-devel': '65-sim6502',
|
||||
'ca65-devel': '65-sim6502',
|
||||
'sdasz80': 'sdcc',
|
||||
'sdcc': 'sdcc',
|
||||
'sccz80': 'sccz80',
|
||||
@ -2788,6 +2796,8 @@ function handleMessage(data : WorkerMessage) : WorkerResult {
|
||||
// preload file system
|
||||
if (data.preload) {
|
||||
var fs = TOOL_PRELOADFS[data.preload];
|
||||
if (!fs && data.platform)
|
||||
fs = TOOL_PRELOADFS[data.preload+'-'+getBasePlatform(data.platform)];
|
||||
if (!fs && data.platform)
|
||||
fs = TOOL_PRELOADFS[data.preload+'-'+getRootBasePlatform(data.platform)];
|
||||
if (fs && !fsMeta[fs])
|
||||
|
Loading…
x
Reference in New Issue
Block a user