mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-10-08 04:58:54 +00:00
vcs: supercharger export; apple2: merlin32
This commit is contained in:
parent
82c18e04aa
commit
a5c69fa274
@ -134,6 +134,7 @@ TODO:
|
||||
- VCS asm game library
|
||||
- VCS skips step on lsr/lsr after run to line
|
||||
- better VCS single stepping, maybe also listings
|
||||
- upgrade to 4.1 for Supercharger format
|
||||
- upload multiple files/zip file to subdirectory
|
||||
- allow "include graphics.asm" instead of "include project/graphics.asm"
|
||||
- convert more stuff to Promises
|
||||
@ -160,6 +161,7 @@ TODO:
|
||||
- ctrl+alt+l on ubuntu locks screen
|
||||
- alt-D doesn't work anymore
|
||||
- facade/kbd shortcuts for emulators, focus
|
||||
- maybe eat key events? ("'" messes things up)
|
||||
- cookie
|
||||
- list of stuff for policy
|
||||
- popup
|
||||
@ -193,6 +195,7 @@ TODO:
|
||||
- Debug Browser
|
||||
- more stuff like 7800 display lists
|
||||
- don't include start/end line on platforms w/o raster timing
|
||||
- memory map shows subroutine symbol even after RTS
|
||||
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
40
lib/makewav.js
Normal file
40
lib/makewav.js
Normal file
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
; Atari 7800 sprite sample
|
||||
; Written by Daniel Boris (dboris@home.com)
|
||||
; Written by Daniel Boris (danlb_2000@yahoo.com)
|
||||
;
|
||||
; Assemble with DASM
|
||||
;
|
||||
|
@ -104,7 +104,8 @@ export class CodeProject {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
// for XASM only (USE include.ext)
|
||||
let re4 = /^\s+(USE)\s+(\S+[.]\S+)/gm;
|
||||
// for merlin32 (ASM include.ext)
|
||||
let re4 = /^\s+(USE|ASM)\s+(\S+[.]\S+)/gm;
|
||||
while (m = re4.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
|
@ -779,16 +779,8 @@ function get8bitworkshopLink(linkqs : string, fn : string) {
|
||||
return fulllink;
|
||||
}
|
||||
|
||||
function _downloadCassetteFile(e) {
|
||||
if (current_output == null) {
|
||||
alertError("Please fix errors before exporting.");
|
||||
return true;
|
||||
}
|
||||
function _downloadCassetteFile_apple2(e) {
|
||||
var addr = compparams && compparams.code_start;
|
||||
if (addr === undefined) {
|
||||
alertError("Cassette export is not supported on this platform.");
|
||||
return true;
|
||||
}
|
||||
loadScript('lib/c2t.js').then( () => {
|
||||
var stdout = '';
|
||||
var print_fn = function(s) { stdout += s + "\n"; }
|
||||
@ -813,6 +805,53 @@ function _downloadCassetteFile(e) {
|
||||
});
|
||||
}
|
||||
|
||||
function _downloadCassetteFile_vcs(e) {
|
||||
loadScript('lib/makewav.js').then( () => {
|
||||
let stdout = '';
|
||||
let print_fn = function(s) { stdout += s + "\n"; }
|
||||
var prefix = getFilenamePrefix(getCurrentMainFilename());
|
||||
let rompath = prefix + ".bin";
|
||||
let audpath = prefix + ".wav";
|
||||
let _makewav = window['makewav']({
|
||||
noInitialRun:false,
|
||||
print:print_fn,
|
||||
printErr:print_fn,
|
||||
arguments:['-ts', '-f0', '-v10', rompath],
|
||||
preRun: (mod) => {
|
||||
let FS = mod['FS'];
|
||||
FS.writeFile(rompath, current_output, {encoding:'binary'});
|
||||
}
|
||||
});
|
||||
_makewav.ready.then((makewav) => {
|
||||
let args = [rompath];
|
||||
makewav.run(args);
|
||||
console.log(stdout);
|
||||
let FS = makewav['FS'];
|
||||
let audout = FS.readFile(audpath, {'encoding':'binary'});
|
||||
if (audout) {
|
||||
let blob = new Blob([audout], {type: "audio/wav"});
|
||||
saveAs(blob, audpath);
|
||||
stdout += "\nConnect your audio output to the SuperCharger input, turn up the volume, and play the audio file.";
|
||||
alertInfo('<pre style="white-space: pre-wrap">'+stdout+'</pre>');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _downloadCassetteFile(e) {
|
||||
if (current_output == null) {
|
||||
alertError("Please fix errors before exporting.");
|
||||
return true;
|
||||
}
|
||||
var fn = window['_downloadCassetteFile_' + getBasePlatform(platform_id)];
|
||||
if (fn === undefined) {
|
||||
alertError("Cassette export is not supported on this platform.");
|
||||
return true;
|
||||
}
|
||||
fn(e);
|
||||
}
|
||||
|
||||
|
||||
function _revertFile(e) {
|
||||
var wnd = projectWindows.getActive();
|
||||
if (wnd && wnd.setText) {
|
||||
@ -1607,7 +1646,7 @@ function setupDebugControls() {
|
||||
$("#item_download_zip").click(_downloadProjectZipFile);
|
||||
$("#item_download_allzip").click(_downloadAllFilesZipFile);
|
||||
$("#item_record_video").click(_recordVideo);
|
||||
if (platform_id.startsWith('apple2'))
|
||||
if (platform_id.startsWith('apple2') || platform_id.startsWith('vcs')) // TODO: look for function
|
||||
$("#item_export_cassette").click(_downloadCassetteFile);
|
||||
else
|
||||
$("#item_export_cassette").hide();
|
||||
|
@ -270,8 +270,10 @@ export class SourceEditor implements ProjectView {
|
||||
} else if (platform.getOpcodeMetadata) {
|
||||
var opcode = parseInt(info.insns.split(" ")[0], 16);
|
||||
var meta = platform.getOpcodeMetadata(opcode, info.offset);
|
||||
var clockstr = meta.minCycles+"";
|
||||
this.setGutter("gutter-clock", info.line-1, clockstr);
|
||||
if (meta) {
|
||||
var clockstr = meta.minCycles+"";
|
||||
this.setGutter("gutter-clock", info.line-1, clockstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,10 @@ class NewApple2Platform extends Base6502MachinePlatform<AppleII> implements Plat
|
||||
if (rom && rom.length == 35*16*256) return ".dsk"; // DSK image
|
||||
return ".bin";
|
||||
};
|
||||
getToolForFilename = (fn:string) : string => {
|
||||
if (fn.endsWith(".lnk")) return "merlin32";
|
||||
else return getToolForFilename_6502(fn);
|
||||
}
|
||||
/*
|
||||
newCodeAnalyzer() {
|
||||
return new CodeAnalyzer_apple2(this);
|
||||
|
5550
src/worker/wasm/merlin32.js
Normal file
5550
src/worker/wasm/merlin32.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/worker/wasm/merlin32.wasm
Normal file
BIN
src/worker/wasm/merlin32.wasm
Normal file
Binary file not shown.
@ -2515,6 +2515,104 @@ function compileInform6(step:BuildStep) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------+-------------------+-------------+----+---------+------+-----------------------+-------------------------------------------------------------------
|
||||
Line | # File Line | Line Type | MX | Reloc | Size | Address Object Code | Source Code
|
||||
------+-------------------+-------------+----+---------+------+-----------------------+-------------------------------------------------------------------
|
||||
1 | 1 zap.asm 1 | Unknown | ?? | | -1 | 00/FFFF | broak
|
||||
2 | 1 zap.asm 2 | Comment | ?? | | -1 | 00/FFFF | * SPACEGAME
|
||||
|
||||
=> [Error] Impossible to decode address mode for instruction 'BNE KABOOM!' (line 315, file 'zap.asm') : The number of element in 'KABOOM!' is even (should be value [operator value [operator value]...]).
|
||||
=> [Error] Unknown line 'foo' in source file 'zap.asm' (line 315)
|
||||
=> Creating Object file 'pcs.bin'
|
||||
=> Creating Output file 'pcs.bin_S01__Output.txt'
|
||||
|
||||
*/
|
||||
function assembleMerlin32(step:BuildStep) {
|
||||
loadNative("merlin32");
|
||||
var errors = [];
|
||||
var lstfiles = [];
|
||||
gatherFiles(step, {mainFilePath:"main.lnk"});
|
||||
var objpath = step.prefix+".bin";
|
||||
if (staleFiles(step, [objpath])) {
|
||||
var args = [ '-v', step.path ];
|
||||
var merlin32 = emglobal.merlin32({
|
||||
instantiateWasm: moduleInstFn('merlin32'),
|
||||
noInitialRun:true,
|
||||
print:(s:string) => {
|
||||
var m = /\s*=>\s*Creating Output file '(.+?)'/.exec(s);
|
||||
if (m) {
|
||||
lstfiles.push(m[1]);
|
||||
}
|
||||
var errpos = s.indexOf('Error');
|
||||
if (errpos >= 0) {
|
||||
s = s.slice(errpos+6).trim();
|
||||
var mline = /\bline (\d+)\b/.exec(s);
|
||||
var mpath = /\bfile '(.+?)'/.exec(s);
|
||||
errors.push({
|
||||
line:parseInt(mline[1]) || 0,
|
||||
msg:s,
|
||||
path:mpath[1] || step.path,
|
||||
});
|
||||
}
|
||||
},
|
||||
printErr:print_fn,
|
||||
});
|
||||
var FS = merlin32['FS'];
|
||||
populateFiles(step, FS);
|
||||
execMain(step, merlin32, args);
|
||||
if (errors.length)
|
||||
return {errors:errors};
|
||||
|
||||
var errout = null;
|
||||
try {
|
||||
errout = FS.readFile("error_output.txt", {encoding:'utf8'});
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
|
||||
var objout = FS.readFile(objpath, {encoding:'binary'});
|
||||
putWorkFile(objpath, objout);
|
||||
if (!anyTargetChanged(step, [objpath]))
|
||||
return;
|
||||
|
||||
var symbolmap = {};
|
||||
var segments = [];
|
||||
var listings : CodeListingMap = {};
|
||||
lstfiles.forEach((lstfn) => {
|
||||
var lst = FS.readFile(lstfn, {encoding:'utf8'}) as string;
|
||||
lst.split('\n').forEach((line) => {
|
||||
var toks = line.split(/\s*\|\s*/);
|
||||
if (toks && toks[6]) {
|
||||
var toks2 = toks[1].split(/\s+/);
|
||||
var toks3 = toks[6].split(/[:/]/, 4);
|
||||
var path = toks2[1];
|
||||
if (path && toks2[2] && toks3[1]) {
|
||||
var lstline = {
|
||||
line:parseInt(toks2[2]),
|
||||
offset:parseInt(toks3[1].trim(),16),
|
||||
insns:toks3[2],
|
||||
cycles:null,
|
||||
iscode:false // TODO
|
||||
};
|
||||
var lst = listings[path];
|
||||
if (!lst) listings[path] = lst = {lines:[]};
|
||||
lst.lines.push(lstline);
|
||||
//console.log(path,toks2,toks3);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return {
|
||||
output:objout, //.slice(0),
|
||||
listings:listings,
|
||||
errors:errors,
|
||||
symbolmap:symbolmap,
|
||||
segments:segments
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
var TOOLS = {
|
||||
@ -2546,6 +2644,7 @@ var TOOLS = {
|
||||
'markdown': translateShowdown,
|
||||
'js': runJavascript,
|
||||
'inform6': compileInform6,
|
||||
'merlin32': assembleMerlin32,
|
||||
}
|
||||
|
||||
var TOOL_PRELOADFS = {
|
||||
|
Loading…
Reference in New Issue
Block a user