vcs: supercharger export; apple2: merlin32

This commit is contained in:
Steven Hugg 2020-07-25 18:33:55 -05:00
parent 82c18e04aa
commit a5c69fa274
10 changed files with 5752 additions and 14 deletions

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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
;

View File

@ -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]);
}

View File

@ -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();

View File

@ -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);
}
}
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -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 = {