working on new unified MAME support

This commit is contained in:
Steven Hugg 2020-07-29 15:21:28 -05:00
parent b344590917
commit 3b13a472bc
17 changed files with 151 additions and 111 deletions

View File

@ -8,31 +8,19 @@ local stopped = false
function mamedbg.init() function mamedbg.init()
cpu = manager:machine().devices[":maincpu"] cpu = manager:machine().devices[":maincpu"]
mem = cpu.spaces["program"] mem = cpu.spaces["program"]
debugger = manager:machine():debugger() machine = manager:machine()
debugger = machine:debugger()
mamedbg.reset() mamedbg.reset()
emu.register_periodic(function () emu.register_periodic(function ()
if debugging then if debugging and not stopped then
if not stopped then --print(debugger.execution_state)
--debugger:command("symlist") lastBreakState = machine.buffer_save()
--log = debugger.consolelog emu.pause()
--for i=1,#log do print(log[i]) end stopped = true
--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) 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() function mamedbg.reset()
debugging = false debugging = false
stopped = false stopped = false
@ -47,8 +35,12 @@ function mamedbg.is_stopped()
return debugging and stopped return debugging and stopped
end end
function mamedbg.continue()
debugger:command("g")
end
function mamedbg.runTo(addr) function mamedbg.runTo(addr)
debugger:command("g " .. string.format("%x", addr)) debugger:command(string.format("g %x", addr))
mamedbg.start() mamedbg.start()
end end
@ -67,4 +59,16 @@ function mamedbg.step()
mamedbg.start() mamedbg.start()
end end
function string.fromhex(str)
return (str:gsub('..', function (cc)
return string.char(tonumber(cc, 16))
end))
end
function string.tohex(str)
return (str:gsub('.', function (c)
return string.format('%02X', string.byte(c))
end))
end
print("parsed Lua debugger script") print("parsed Lua debugger script")

File diff suppressed because one or more lines are too long

BIN
mame/mame8bitws.wasm Normal file

Binary file not shown.

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.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

30
package-lock.json generated
View File

@ -40,7 +40,7 @@
"@types/sizzle": { "@types/sizzle": {
"version": "2.3.2", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
"integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", "integrity": "sha1-qBG4wY4rq6t9VCszZYh64uTZ3kc=",
"dev": true "dev": true
}, },
"abab": { "abab": {
@ -58,7 +58,7 @@
"acorn-globals": { "acorn-globals": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz",
"integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", "integrity": "sha1-47b42jwVUqla5idXH33Wkju1QQM=",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^6.0.1", "acorn": "^6.0.1",
@ -129,7 +129,7 @@
"asn1": { "asn1": {
"version": "0.2.4", "version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
"dev": true, "dev": true,
"requires": { "requires": {
"safer-buffer": "~2.1.0" "safer-buffer": "~2.1.0"
@ -239,7 +239,7 @@
"browser-stdout": { "browser-stdout": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=",
"dev": true "dev": true
}, },
"btoa": { "btoa": {
@ -404,7 +404,7 @@
"cssstyle": { "cssstyle": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz",
"integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", "integrity": "sha1-GLA4qcRNZfeo5CimU7n2/kL69fs=",
"dev": true, "dev": true,
"requires": { "requires": {
"cssom": "0.3.x" "cssom": "0.3.x"
@ -466,7 +466,7 @@
"diff": { "diff": {
"version": "3.5.0", "version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=",
"dev": true "dev": true
}, },
"domexception": { "domexception": {
@ -562,7 +562,7 @@
"escodegen": { "escodegen": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz",
"integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", "integrity": "sha1-snqTiUgdW/1b7Hb3ux6z+PRVZYk=",
"dev": true, "dev": true,
"requires": { "requires": {
"esprima": "^3.1.3", "esprima": "^3.1.3",
@ -593,7 +593,7 @@
"extend": { "extend": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=",
"dev": true "dev": true
}, },
"extsprintf": { "extsprintf": {
@ -756,7 +756,7 @@
"growl": { "growl": {
"version": "1.10.5", "version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=",
"dev": true "dev": true
}, },
"har-schema": { "har-schema": {
@ -1282,7 +1282,7 @@
"oauth-sign": { "oauth-sign": {
"version": "0.9.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=",
"dev": true "dev": true
}, },
"object-inspect": { "object-inspect": {
@ -1422,7 +1422,7 @@
"pngjs": { "pngjs": {
"version": "3.4.0", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", "integrity": "sha1-mcp9clll+2VYFOr2XzjxK72/VV8=",
"dev": true "dev": true
}, },
"prelude-ls": { "prelude-ls": {
@ -1452,7 +1452,7 @@
"qs": { "qs": {
"version": "6.5.2", "version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=",
"dev": true "dev": true
}, },
"readdirp": { "readdirp": {
@ -1472,7 +1472,7 @@
"request": { "request": {
"version": "2.88.0", "version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=",
"dev": true, "dev": true,
"requires": { "requires": {
"aws-sign2": "~0.7.0", "aws-sign2": "~0.7.0",
@ -1583,7 +1583,7 @@
"semver": { "semver": {
"version": "5.7.0", "version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "integrity": "sha1-eQp89v6lRZuslhELKbYEEtyP+Ws=",
"dev": true "dev": true
}, },
"set-blocking": { "set-blocking": {
@ -1794,7 +1794,7 @@
"uuid": { "uuid": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=",
"dev": true "dev": true
}, },
"verror": { "verror": {

View File

@ -645,41 +645,43 @@ export abstract class BaseMAMEPlatform {
romdata : Uint8Array; romdata : Uint8Array;
video; video;
running = false; running = false;
console_vars : {[varname:string]:string} = {};
console_varname : string;
initluavars : boolean = false; initluavars : boolean = false;
luadebugscript : string; luadebugscript : string;
js_lua_string; js_lua_string;
onBreakpointHit; onBreakpointHit;
mainElement : HTMLElement; mainElement : HTMLElement;
timer : AnimationTimer;
constructor(mainElement) { constructor(mainElement) {
this.mainElement = mainElement; this.mainElement = mainElement;
} this.timer = new AnimationTimer(20, this.poll.bind(this));
luareset() {
this.console_vars = {};
} }
// http://docs.mamedev.org/techspecs/luaengine.html // http://docs.mamedev.org/techspecs/luaengine.html
luacall(s) { luacall(s:string) : string {
this.console_varname = null; if (!this.js_lua_string) this.js_lua_string = Module.cwrap('_Z13js_lua_stringPKc', 'string', ['string']);
//Module.ccall('_Z13js_lua_stringPKc', 'void', ['string'], [s+""]); return this.js_lua_string(s || "");
if (!this.js_lua_string) this.js_lua_string = Module.cwrap('_Z13js_lua_stringPKc', 'void', ['string']);
this.js_lua_string(s || "");
} }
_pause() {
this.running = false;
this.timer.stop();
}
pause() { pause() {
if (this.loaded && this.running) { if (this.loaded && this.running) {
this.luacall('emu.pause()'); this.luacall('emu.pause()');
this.running = false; this._pause();
} }
} }
_resume() {
this.luacall('emu.unpause()');
this.running = true;
this.timer.start();
}
resume() { resume() {
if (this.loaded && !this.running) { // TODO if (this.loaded && !this.running) { // TODO
this.luacall('emu.unpause()'); this._resume();
this.running = true;
} }
} }
@ -697,13 +699,7 @@ export abstract class BaseMAMEPlatform {
bufferConsoleOutput(s) { bufferConsoleOutput(s) {
if (typeof s !== 'string') return; if (typeof s !== 'string') return;
if (s.startsWith(">>>")) { console.log(s);
console.log(s);
var toks = s.split(' ', 3);
this.console_vars[toks[1]] = toks[2];
} else {
console.log(s);
}
} }
startModule(mainElement, opts) { startModule(mainElement, opts) {
@ -819,6 +815,11 @@ export abstract class BaseMAMEPlatform {
document.getElementsByTagName('head')[0].appendChild(script); document.getElementsByTagName('head')[0].appendChild(script);
console.log("created script element"); console.log("created script element");
}); });
// for debugging via browser console
window['mamelua'] = (s:string) => {
this.initlua();
return this.luacall(s);
};
} }
loadROMFile(data) { loadROMFile(data) {
@ -842,6 +843,8 @@ export abstract class BaseMAMEPlatform {
} }
} }
// DEBUGGING SUPPORT
initlua() { initlua() {
if (!this.initluavars) { if (!this.initluavars) {
this.luacall(this.luadebugscript); this.luacall(this.luadebugscript);
@ -849,69 +852,117 @@ export abstract class BaseMAMEPlatform {
this.initluavars = true; this.initluavars = true;
} }
} }
// DEBUGGING SUPPORT readAddress(a:number) : number {
/*
readAddress(a) {
this.initlua(); this.initlua();
this.luacall('print(">>> mem8 " .. mem:read_u8(' + a + '))'); return parseInt(this.luacall('return mem:read_u8(' + a + ')'));
return parseInt(this.console_vars.mem8); }
getCPUReg(reg:string) {
this.initlua();
return parseInt(this.luacall('return cpu.state.'+reg+'.value'));
}
getPC() : number {
return this.getCPUReg('PC');
} }
preserveState() { getSP() : number {
var state = {c:{}}; return this.getCPUReg('SP');
for (var k in this.console_vars) { }
if (k.startsWith("cpu_")) {
var v = parseInt(this.console_vars[k][0]); isStable() { return true; }
state.c[k.slice(4)] = v;
} getCPUState() {
return {
PC:this.getPC(),
SP:this.getSP(),
A:this.getCPUReg('A'),
X:this.getCPUReg('X'),
Y:this.getCPUReg('Y'),
//flags:this.getCPUReg('CURFLAGS'),
};
}
grabState(expr:string) {
this.initlua();
return {
c:this.getCPUState(),
buf:this.luacall("return string.tohex(" + expr + ")")
} }
// TODO: memory? }
return state;
saveState() {
return this.grabState("manager:machine():buffer_save()");
} }
saveState() { loadState(state) {
this.luareset(); this.initlua();
this.luacall('mamedbg.printstate()'); return this.luacall("manager:machine():buffer_load(string.fromhex('" + state.buf + "'))");
return this.preserveState(); }
poll() {
if (this.onBreakpointHit && this.luacall("return tostring(mamedbg.is_stopped())") == 'true') {
this._pause();
//this.luacall("manager:machine():buffer_load(lastBreakState)");
var state = this.grabState("lastBreakState");
this.onBreakpointHit(state);
}
} }
clearDebug() { clearDebug() {
this.onBreakpointHit = null; this.onBreakpointHit = null;
if (this.loaded) {
this.initlua();
this.luacall('mamedbg.reset()');
}
} }
getDebugCallback() { getDebugCallback() {
return this.onBreakpointHit;// TODO? return this.onBreakpointHit;// TODO?
} }
setupDebug(callback) { setupDebug(callback) {
if (this.loaded) { // TODO?
this.initlua();
this.luareset();
}
this.onBreakpointHit = callback; this.onBreakpointHit = callback;
} }
debugcmd(s) {
this.initlua()
this.luacall(s);
this._resume();
}
runToPC(pc) { runToPC(pc) {
this.luacall('mamedbg.runTo(' + pc + ')'); this.debugcmd('mamedbg.runTo(' + pc + ')');
this.resume();
} }
runToVsync() { runToVsync() {
this.luacall('mamedbg.runToVsync()'); this.debugcmd('mamedbg.runToVsync()');
this.resume();
} }
runUntilReturn() { runUntilReturn() {
this.luacall('mamedbg.runUntilReturn()'); this.debugcmd('mamedbg.runUntilReturn()');
this.resume(); }
// TODO
runEval() {
this.reset();
this.step();
} }
step() { step() {
this.luacall('mamedbg.step()'); this.debugcmd('mamedbg.step()');
this.resume(); }
getDebugCategories() {
return ['CPU'];
}
getDebugInfo(category:string, state:EmuState) : string {
switch (category) {
case 'CPU': return this.cpuStateToLongString(state.c);
}
} }
// TODO: other than z80 // TODO: other than z80
cpuStateToLongString(c) { cpuStateToLongString(c) {
if (c.HL) if (c.HL)
return cpuStateToLongString_Z80(c); return cpuStateToLongString_Z80(c);
else else
return null; // TODO return cpuStateToLongString_6502(c); // TODO
}
disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {
// TODO: z80
return disassemble6502(pc, read(pc), read(pc+1), read(pc+2));
} }
*/
} }
//TODO: how to get stack_end? //TODO: how to get stack_end?

View File

@ -27,7 +27,7 @@ class Apple2MAMEPlatform extends BaseMAMEPlatform implements Platform {
start () { start () {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile:'mameapple2e.js', jsfile:'mame8bitws.js',
biosfile:['apple2e.zip'], biosfile:['apple2e.zip'],
//cfgfile:'nes.cfg', //cfgfile:'nes.cfg',
driver:'apple2e', driver:'apple2e',

View File

@ -806,7 +806,7 @@ class Atari800MAMEPlatform extends Atari8MAMEPlatform implements Platform {
loadROM(title, data) { loadROM(title, data) {
if (!this.started) { if (!this.started) {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile:'mameatari400.js', jsfile:'mame8bitws.js',
biosfile:'a800xl.zip', biosfile:'a800xl.zip',
cfgfile:'a800xl.cfg', cfgfile:'a800xl.cfg',
driver:'a800xl', driver:'a800xl',
@ -843,7 +843,7 @@ class Atari5200MAMEPlatform extends Atari8MAMEPlatform implements Platform {
loadROM(title, data) { loadROM(title, data) {
if (!this.started) { if (!this.started) {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile:'mameatari400.js', jsfile:'mame8bitws.js',
biosfile:'a5200/5200.rom', biosfile:'a5200/5200.rom',
cfgfile:'a5200.cfg', cfgfile:'a5200.cfg',
driver:'a5200', driver:'a5200',

View File

@ -43,7 +43,7 @@ class ColecoVisionMAMEPlatform extends BaseMAMEPlatform implements Platform {
start() { start() {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile: 'mamecoleco.js', jsfile: 'mame8bitws.js',
cfgfile: 'coleco.cfg', cfgfile: 'coleco.cfg',
biosfile: 'coleco/313 10031-4005 73108a.u2', biosfile: 'coleco/313 10031-4005 73108a.u2',
driver: 'coleco', driver: 'coleco',

View File

@ -496,7 +496,7 @@ class NESMAMEPlatform extends BaseMAMEPlatform implements Platform {
loadROM(title, data) { loadROM(title, data) {
if (!this.started) { if (!this.started) {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile:'mamenes.js', jsfile:'mame8bitws.js',
//cfgfile:'nes.cfg', //cfgfile:'nes.cfg',
driver:'nes', driver:'nes',
width:256, width:256,

View File

@ -405,7 +405,7 @@ class VCSMAMEPlatform extends BaseMAMEPlatform implements Platform {
start = function() { start = function() {
this.startModule(this.mainElement, { this.startModule(this.mainElement, {
jsfile:'mamea2600.js', jsfile:'mame8bitws.js',
driver:'a2600', driver:'a2600',
width:176*2, width:176*2,
height:223, height:223,