1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2026-04-20 15:16:38 +00:00

started on mame WASM, debugging support, colecovision

This commit is contained in:
Steven Hugg
2018-06-18 04:12:52 -04:00
parent 495896c43d
commit ef561b4425
11 changed files with 258 additions and 54 deletions
+70
View File
@@ -0,0 +1,70 @@
-- JS debug support for MAME using -debugger none
mamedbg = {}
local debugging = false
local stopped = false
function mamedbg.init()
cpu = manager:machine().devices[":maincpu"]
mem = cpu.spaces["program"]
debugger = manager:machine():debugger()
mamedbg.reset()
emu.register_periodic(function ()
if debugging then
if not stopped then
--debugger:command("symlist")
--log = debugger.consolelog
--for i=1,#log do print(log[i]) end
--print(string.format("%4x", cpu.state["PC"].value))
--manager:machine():save("state")
emu.pause()
stopped = true
-- callback to JS via console i/o
mamedbg.printstate()
print(">>>debug_stopped")
print("1")
end
end
end)
end
function mamedbg.printstate()
for k,v in pairs(cpu.state) do print(">>>cpu_"..k); print(v.value) end
end
function mamedbg.reset()
debugging = false
stopped = false
end
function mamedbg.start()
debugging = true
stopped = false
end
function mamedbg.is_stopped()
return debugging and stopped
end
function mamedbg.runTo(addr)
debugger:command("g " .. string.format("%x", addr))
mamedbg.start()
end
function mamedbg.runToVsync(addr)
debugger:command("gv")
mamedbg.start()
end
function mamedbg.runUntilReturn(addr)
debugger:command("out")
mamedbg.start()
end
function mamedbg.step()
debugger:command("step")
mamedbg.start()
end
print("parsed Lua debugger script")
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
+4
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
+112 -36
View File
@@ -903,6 +903,8 @@ var BaseMAMEPlatform = function() {
var console_vars = {};
var console_varname;
var initluavars = false;
var luadebugscript;
var js_lua_string;
this.luareset = function() {
console_vars = {};
@@ -911,11 +913,9 @@ var BaseMAMEPlatform = function() {
// http://docs.mamedev.org/techspecs/luaengine.html
this.luacall = function(s) {
console_varname = null;
Module.ccall('_Z13js_lua_stringPKc', 'void', ['string'], [s+""]);
}
this.clearDebug = function() {
//TODO
//Module.ccall('_Z13js_lua_stringPKc', 'void', ['string'], [s+""]);
if (!js_lua_string) js_lua_string = Module.cwrap('_Z13js_lua_stringPKc', 'void', ['string']);
js_lua_string(s || "");
}
this.pause = function() {
@@ -926,7 +926,7 @@ var BaseMAMEPlatform = function() {
}
this.resume = function() {
if (loaded && !running) {
if (loaded && !running) { // TODO
this.luacall('emu.unpause()');
running = true;
}
@@ -949,6 +949,13 @@ var BaseMAMEPlatform = function() {
if (console_varname) console_vars[console_varname] = [];
} else if (console_varname) {
console_vars[console_varname].push(s);
if (console_varname == 'debug_stopped') {
var debugSaveState = self.preserveState();
self.pause();
if (onBreakpointHit) {
onBreakpointHit(debugSaveState);
}
}
} else {
console.log(s);
}
@@ -964,10 +971,14 @@ var BaseMAMEPlatform = function() {
$(video.canvas).attr('id','canvas');
// load asm.js module
console.log("loading", opts.jsfile);
var script = document.createElement('script');
window.JSMESS = {};
window.Module = {
arguments: [opts.driver, '-debug', '-verbose', '-window', '-nokeepaspect', '-resolution', canvas.width+'x'+canvas.height, '-cart', romfn],
arguments: [opts.driver,
'-debug',
'-debugger', 'none',
'-verbose', '-window', '-nokeepaspect',
'-resolution', canvas.width+'x'+canvas.height,
'-cart', romfn],
screenIsReadOnly: true,
print: bufferConsoleOutput,
canvas:video.canvas,
@@ -986,38 +997,72 @@ var BaseMAMEPlatform = function() {
FS.writeFile('/roms/' + opts.biosfile, opts.biosdata, {encoding:'binary'});
}
FS.mkdir('/emulator');
FS.writeFile(romfn, romdata, {encoding:'binary'});
FS.writeFile('/debug.ini', 'debugger none\n', {encoding:'utf8'});
if (romfn) FS.writeFile(romfn, new Uint8Array(romdata), {encoding:'binary'});
//FS.writeFile('/debug.ini', 'debugger none\n', {encoding:'utf8'});
if (opts.preInit) {
opts.preInit(self);
}
$(video.canvas).click(function(e) {
video.canvas.focus();
});
loaded = true;
}
},
preRun: [
function() {
$(video.canvas).click(function(e) {
video.canvas.focus();
});
loaded = true;
console.log("about to run...");
}
]
};
// preload files
// TODO: ensure loaded
var fetch_cfg, fetch_lua;
var fetch_bios = $.Deferred();
var fetch_wasm = $.Deferred();
// fetch config file
if (opts.cfgfile) {
$.get('mame/cfg/' + opts.cfgfile, function(data) {
fetch_cfg = $.get('mame/cfg/' + opts.cfgfile, function(data) {
opts.cfgdata = data;
console.log("loaded " + opts.cfgfile);
}, 'text');
}
// fetch BIOS file
if (opts.biosfile) {
var oReq = new XMLHttpRequest();
oReq.open("GET", 'mame/roms/' + opts.biosfile, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(oEvent) {
console.log("loaded " + opts.biosfile);
opts.biosdata = new Uint8Array(oReq.response);
var oReq1 = new XMLHttpRequest();
oReq1.open("GET", 'mame/roms/' + opts.biosfile, true);
oReq1.responseType = "arraybuffer";
oReq1.onload = function(oEvent) {
opts.biosdata = new Uint8Array(oReq1.response);
console.log("loaded " + opts.biosfile + " (" + oEvent.total + " bytes)");
fetch_bios.resolve();
};
oReq.send();
oReq1.send();
} else {
fetch_bios.resolve();
}
// load debugger Lua script
fetch_lua = $.get('mame/debugger.lua', function(data) {
luadebugscript = data;
console.log("loaded debugger.lua");
}, 'text');
// load WASM
{
var oReq2 = new XMLHttpRequest();
oReq2.open("GET", 'mame/' + opts.jsfile.replace('.js','.wasm'), true);
oReq2.responseType = "arraybuffer";
oReq2.onload = function(oEvent) {
console.log("loaded WASM file");
window.Module.wasmBinary = new Uint8Array(oReq2.response);
fetch_wasm.resolve();
};
oReq2.send();
}
// start loading script
script.src = 'mame/' + opts.jsfile;
document.getElementsByTagName('head')[0].appendChild(script);
$.when(fetch_lua, fetch_cfg, fetch_bios, fetch_wasm).done(function() {
var script = document.createElement('script');
script.src = 'mame/' + opts.jsfile;
document.getElementsByTagName('head')[0].appendChild(script);
console.log("created script element");
});
}
this.loadROMFile = function(data) {
@@ -1041,9 +1086,7 @@ var BaseMAMEPlatform = function() {
}
}
this.saveState = function() {
this.luareset();
this.luacall('cpu = manager:machine().devices[":maincpu"]\nfor k,v in pairs(cpu.state) do print(">>>cpu_"..k); print(v.value) end');
this.preserveState = function() {
var state = {c:{}};
for (var k in console_vars) {
if (k.startsWith("cpu_")) {
@@ -1051,15 +1094,26 @@ var BaseMAMEPlatform = function() {
state.c[k.slice(4)] = v;
}
}
// TODO
// TODO: memory?
return state;
}
this.readAddress = function(a) {
this.saveState = function() {
this.luareset();
this.luacall('mamedbg.printstate()');
return self.preserveState();
}
this.initlua = function() {
if (!initluavars) {
self.luacall('cpu = manager:machine().devices[":maincpu"]\nmem = cpu.spaces["program"]\n')
self.luacall(luadebugscript);
self.luacall('mamedbg.init()')
initluavars = true;
}
}
this.readAddress = function(a) {
self.initlua();
self.luacall('print(">>>v"); print(mem:read_u8(' + a + '))');
return parseInt(console_vars.v[0]);
}
@@ -1068,17 +1122,39 @@ var BaseMAMEPlatform = function() {
var onBreakpointHit;
this.clearDebug = function() {
onBreakpointHit = null;
}
this.getDebugCallback = function() {
// TODO
return onBreakpointHit;
}
this.setupDebug = function(callback) {
self.initlua();
self.luareset();
onBreakpointHit = callback;
}
this.runToPC = function(pc) {
self.luacall('mamedbg.runTo(' + pc + ')');
self.resume();
}
this.runToVsync = function() {
self.luacall('mamedbg.runToVsync()');
self.resume();
}
this.runUntilReturn = function() {
self.luacall('mamedbg.runUntilReturn()');
self.resume();
}
this.step = function() {
self.readAddress(0);
//self.luacall('cpu.debug()\n')
self.luacall('debugger = manager:machine().debugger()')
self.luacall('print(debugger)') // TODO
self.luacall('mamedbg.step()');
self.resume();
}
// TODO: other than z80
this.cpuStateToLongString = function(c) {
if (c.HL)
return cpuStateToLongString_Z80(c);
else
return null; // TODO
}
}
+35
View File
@@ -956,4 +956,39 @@ var APPLEIIGO_LZG = [
76,237,253,165,72,72,165,69,166,70,164,71,52,110,22,52,62,27,59,30,59,14,245,3,251,3,98,250,98,250
];
/// MAME support
var Apple2MAMEPlatform = function(mainElement) {
var self = this;
this.__proto__ = new BaseMAMEPlatform();
this.start = function() {
self.startModule(mainElement, {
jsfile:'mameapple2e.js',
//cfgfile:'nes.cfg',
driver:'apple2e',
width:256*2,
height:240*2,
//romfn:'/emulator/cart.nes',
//romsize:romSize,
//romdata:new lzgmini().decode(lzgRom).slice(0, romSize),
preInit:function(_self) {
},
});
}
this.getOpcodeMetadata = Javatari.getOpcodeMetadata;
this.getToolForFilename = getToolForFilename_6502;
this.getDefaultExtension = function() { return ".c"; };
this.getPresets = function() { return APPLE2_PRESETS; }
this.loadROM = function(title, data) {
this.loadROMFile(data);
this.loadRegion(":nes_slot:cart:prg_rom", data.slice(0x10, 0x8010));
this.loadRegion(":nes_slot:cart:chr_rom", data.slice(0x8010, 0xa010));
}
}
PLATFORMS['apple2'] = Apple2Platform;
PLATFORMS['apple2-e'] = Apple2MAMEPlatform;
+10 -7
View File
@@ -590,9 +590,8 @@ var lastDebugInfo;
var lastDebugState;
function showMemory(state) {
var s = "";
if (state && platform.cpuStateToLongString) {
s = platform.cpuStateToLongString(state.c);
var s = state && platform.cpuStateToLongString && platform.cpuStateToLongString(state.c);
if (s) {
if (platform.getRasterPosition) {
var pos = platform.getRasterPosition();
s += "H:" + pos.x + " V:" + pos.y + "\n"; // TODO: padding
@@ -700,9 +699,13 @@ function runToCursor() {
var pc = getCurrentPC();
if (pc >= 0) {
console.log("Run to", pc.toString(16));
platform.runEval(function(c) {
return c.PC == pc;
});
if (platform.runToPC) {
platform.runToPC(pc);
} else {
platform.runEval(function(c) {
return c.PC == pc;
});
}
}
}
@@ -1282,7 +1285,7 @@ function setupDebugControls(){
$("#dbg_tovsync").click(singleFrameStep).show();
else
$("#dbg_tovsync").hide();
if (platform.runEval && platform_id != 'verilog')
if ((platform.runEval || platform.runToPC) && platform_id != 'verilog')
$("#dbg_toline").click(runToCursor).show();
else
$("#dbg_toline").hide();
+19 -11
View File
@@ -60,6 +60,7 @@ var PLATFORM_PARAMS = {
'coleco': {
rom_start: 0x8000,
code_start: 0x8100,
code_offset: 0x8147, // TODO: right after cv_start()
rom_size: 0x8000,
data_start: 0x7000,
data_size: 0x400,
@@ -71,8 +72,8 @@ var PLATFORM_PARAMS = {
'main.rel'],
},
'nes-conio': {
define: '__NES__',
cfgfile: 'nes.cfg',
define: '__NES__',
libargs: ['nes.lib'],
},
'nes-lib': {
@@ -85,6 +86,11 @@ var PLATFORM_PARAMS = {
cfgfile: 'apple2.cfg',
libargs: ['apple2.lib'],
},
'apple2-e': {
define: '__APPLE2__',
cfgfile: 'apple2.cfg',
libargs: ['apple2.lib'],
},
'verilog': {
},
};
@@ -289,8 +295,9 @@ function extractErrors(regex, strings) {
return errors;
}
function parseListing(code, lineMatch, iline, ioffset, iinsns) {
function parseListing(code, lineMatch, iline, ioffset, iinsns, origin) {
var lines = [];
origin |= 0;
for (var line of code.split(/\r?\n/)) {
var linem = lineMatch.exec(line);
if (linem && linem[1]) {
@@ -300,7 +307,7 @@ function parseListing(code, lineMatch, iline, ioffset, iinsns) {
if (insns) {
lines.push({
line:linenum,
offset:offset,
offset:offset + origin,
insns:insns,
});
}
@@ -309,9 +316,10 @@ function parseListing(code, lineMatch, iline, ioffset, iinsns) {
return lines;
}
function parseSourceLines(code, lineMatch, offsetMatch) {
function parseSourceLines(code, lineMatch, offsetMatch, origin) {
var lines = [];
var lastlinenum = 0;
origin |= 0;
for (var line of code.split(/\r?\n/)) {
var linem = lineMatch.exec(line);
if (linem && linem[1]) {
@@ -322,7 +330,7 @@ function parseSourceLines(code, lineMatch, offsetMatch) {
var offset = parseInt(linem[1], 16);
lines.push({
line:lastlinenum,
offset:offset,
offset:offset + origin,
});
lastlinenum = 0;
}
@@ -686,7 +694,7 @@ l_main00101 = 0003, L: test
*/
var amap = FS.readFile("main.map", {'encoding':'utf8'}); // TODO
var aout = FS.readFile("main.bin", {'encoding':'binary'});
var asmlines = parseListing(alst, /^(\d+)\s+([0-9A-F]+)\s+([0-9A-F][0-9A-F ]*[0-9A-F])\s+/i, 1, 2, 3, 4);
var asmlines = parseListing(alst, /^(\d+)\s+([0-9A-F]+)\s+([0-9A-F][0-9A-F ]*[0-9A-F])\s+/i, 1, 2, 3, params.rom_start|0);
var srclines = parseListing(alst, /^(\d+)\s+([0-9A-F]+)\s+;[(]null[)]:(\d+)/i, 3, 2, 1);
return {
output:aout,
@@ -813,9 +821,9 @@ function assemblelinkSDASZ80(code, platform) {
var rstout = updateListing ? FS.readFile("main.rst", {encoding:'utf8'}) : lstout;
//var dbgout = FS.readFile("main.cdb", {encoding:'utf8'});
// 0000 21 02 00 [10] 52 ld hl, #2
// TODO: offset by start address?
var asmlines = parseListing(lstout, /^\s*([0-9A-F]+)\s+([0-9A-F][0-9A-F r]*[0-9A-F])\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 4, 1, 2, 5, 3);
var srclines = parseSourceLines(lstout, /^\s+\d+ ;<stdin>:(\d+):/i, /^\s*([0-9A-F]{4})/i);
// TODO: use map to find code_offset
var asmlines = parseListing(lstout, /^\s*([0-9A-F]+)\s+([0-9A-F][0-9A-F r]*[0-9A-F])\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 4, 1, 2, params.code_offset); //, 5, 3);
var srclines = parseSourceLines(lstout, /^\s+\d+ ;<stdin>:(\d+):/i, /^\s*([0-9A-F]{4})/i, params.code_offset);
// parse symbol map
var symbolmap = {};
for (var s of mapout.split("\n")) {
@@ -935,7 +943,7 @@ function assembleXASM6809(code, platform) {
try {
var aout = FS.readFile("main.bin", {encoding:'binary'});
// 00001 0000 [ 2] 1048 asld
var asmlines = parseListing(alst, /^\s*([0-9A-F]+)\s+([0-9A-F]+)\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 1, 2, 4, 5, 3);
var asmlines = parseListing(alst, /^\s*([0-9A-F]+)\s+([0-9A-F]+)\s+\[([0-9 ]+)\]\s+(\d+) (.*)/i, 1, 2, 4, params.code_offset); //, 5, 3);
return {
output:aout,
errors:msvc_errors,
@@ -1015,7 +1023,7 @@ function assembleNAKEN(code, platform) {
var alst = FS.readFile("out.lst", {encoding:'utf8'});
//console.log(alst);
// 0x0000: 77 ld (hl),a cycles: 4
var asmlines = parseListing(alst, /^0x([0-9a-f]+):\s+([0-9a-f]+)\s+(.+)cycles: (\d+)/i, 0, 1, 2, 3);
var asmlines = parseListing(alst, /^0x([0-9a-f]+):\s+([0-9a-f]+)\s+(.+)cycles: (\d+)/i, 0, 1, 2); //, 3);
return {
output:aout,
errors:errors,