diff --git a/css/ui.css b/css/ui.css
index 227774e1..f3ca98bf 100644
--- a/css/ui.css
+++ b/css/ui.css
@@ -193,6 +193,8 @@ a.dropdown-toggle {
margin-bottom: 20px;
background: #000;
outline-color: #666;
+ width: 100%;
+ height: 100%;
}
canvas.pixelated {
image-rendering: optimizeSpeed; /* Older versions of FF */
diff --git a/emsrc/sdcc/Makefile.local b/emsrc/sdcc/Makefile.local
index 5f46f438..dee5ef5e 100644
--- a/emsrc/sdcc/Makefile.local
+++ b/emsrc/sdcc/Makefile.local
@@ -29,3 +29,9 @@ debugjs/%.js: js/%.bc
-s FORCE_FILESYSTEM=1 \
$< -o $@ $(ARGS_$*) \
+js/fssdcc.js:
+ ln -s ./sdcc/device/include include
+ ln -s ./sdcc/device/lib/build lib
+ python $(EMSCRIPTEN)/tools/file_packager.py js/fssdcc.data \
+ --preload include lib/z80 \
+ --separate-metadata --js-output=js/fssdcc.js
diff --git a/mame/cfg/coleco.cfg b/mame/cfg/coleco.cfg
new file mode 100644
index 00000000..9a8877e0
--- /dev/null
+++ b/mame/cfg/coleco.cfg
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+ KEYCODE_0
+
+
+
+
+ KEYCODE_1
+
+
+
+
+ KEYCODE_2
+
+
+
+
+ KEYCODE_3
+
+
+
+
+ KEYCODE_4
+
+
+
+
+ KEYCODE_5
+
+
+
+
+ KEYCODE_6
+
+
+
+
+ KEYCODE_7
+
+
+
+
+ KEYCODE_8
+
+
+
+
+ KEYCODE_9
+
+
+
+
+ KEYCODE_MINUS
+
+
+
+
+ KEYCODE_EQUALS
+
+
+
+
+
diff --git a/src/emu.js b/src/emu.js
index f1d09664..761d38a5 100644
--- a/src/emu.js
+++ b/src/emu.js
@@ -19,8 +19,6 @@ function __createCanvas(mainElement, width, height) {
canvas.width = width;
canvas.height = height;
canvas.classList.add("emuvideo");
- canvas.style.width = "100%";
- canvas.style.height = "100%";
canvas.tabIndex = "-1"; // Make it focusable
fsElement.appendChild(canvas);
@@ -594,17 +592,19 @@ var BaseZ80Platform = function() {
this.cpuStateToLongString = function(c) {
return cpuStateToLongString_Z80(c);
}
- this.getToolForFilename = function(fn) {
- if (fn.endsWith(".c")) return "sdcc";
- if (fn.endsWith(".s")) return "sdasz80";
- if (fn.endsWith(".ns")) return "naken";
- return "z80asm";
- }
+ this.getToolForFilename = getToolForFilename_z80;
this.getDefaultExtension = function() { return ".c"; };
// TODO
//this.getOpcodeMetadata = function() { }
}
+function getToolForFilename_z80(fn) {
+ if (fn.endsWith(".c")) return "sdcc";
+ if (fn.endsWith(".s")) return "sdasz80";
+ if (fn.endsWith(".ns")) return "naken";
+ return "z80asm";
+}
+
////// 6809
function cpuStateToLongString_6809(c) {
@@ -862,3 +862,120 @@ var BusProbe = function(bus) {
bus.write(a,v);
}
}
+
+/// MAME SUPPORT
+
+var BaseMAMEPlatform = function() {
+ var self = this;
+
+ var loaded = false;
+ var romfn;
+ var romdata;
+ var video;
+ var preload_files;
+
+ this.luacall = function(s) {
+ //console.log(s);
+ Module.ccall('_Z13js_lua_stringPKc', 'void', ['string'], [s+""]);
+ }
+
+ this.clearDebug = function() {
+ //TODO
+ }
+
+ this.pause = function() {
+ if (loaded) this.luacall('emu.pause()');
+ }
+
+ this.resume = function() {
+ if (loaded) this.luacall('emu.unpause()');
+ }
+
+ this.reset = function() {
+ this.luacall('manager:machine():soft_reset()');
+ }
+
+ this.isRunning = function() {
+ // TODO
+ }
+
+ this.startModule = function(mainElement, opts) {
+ romfn = opts.romfn;
+ if (!romdata) romdata = new RAM(opts.romsize).mem;
+ // create canvas
+ video = new RasterVideo(mainElement, opts.width, opts.height);
+ video.create();
+ $(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, '-verbose', '-window', '-nokeepaspect', '-resolution', canvas.width+'x'+canvas.height, '-cart', romfn],
+ screenIsReadOnly: true,
+ print: function (text) { console.log(text); },
+ canvas:video.canvas,
+ doNotCaptureKeyboard:true,
+ keyboardListeningElement:video.canvas,
+ preInit: function () {
+ console.log("loading FS");
+ ENV.SDL_EMSCRIPTEN_KEYBOARD_ELEMENT = 'canvas';
+ if (opts.cfgfile) {
+ FS.mkdir('/cfg');
+ FS.writeFile('/cfg/' + opts.cfgfile, opts.cfgdata, {encoding:'utf8'});
+ }
+ if (opts.biosfile) {
+ FS.mkdir('/roms');
+ FS.mkdir('/roms/' + opts.driver);
+ FS.writeFile('/roms/' + opts.biosfile, opts.biosdata, {encoding:'binary'});
+ }
+ FS.mkdir('/emulator');
+ FS.writeFile(romfn, romdata, {encoding:'binary'});
+ if (opts.preInit) {
+ opts.preInit(self);
+ }
+ $(video.canvas).click(function(e) {
+ video.canvas.focus();
+ });
+ loaded = true;
+ }
+ };
+ // preload files
+ // TODO: ensure loaded
+ if (opts.cfgfile) {
+ $.get('mame/cfg/' + opts.cfgfile, function(data) {
+ opts.cfgdata = data;
+ console.log("loaded " + opts.cfgfile);
+ }, 'text');
+ }
+ 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);
+ };
+ oReq.send();
+ }
+ // start loading script
+ script.src = 'mame/' + opts.jsfile;
+ document.getElementsByTagName('head')[0].appendChild(script);
+ }
+
+ this.loadRegion = function(region, data) {
+ romdata = data;
+ if (loaded) {
+ FS.writeFile(romfn, data, {encoding:'binary'});
+ //self.luacall('cart=manager:machine().images["cart"]\nprint(cart:filename())\ncart:load("' + romfn + '")\n');
+ var s = 'mem = manager:machine():memory().regions["' + region + '"]\n';
+ for (var i=0; i= visibleScanlinesPerFrame) return;
+ var pixofs = sl * 256;
+ var outi = pixofs; // starting output pixel in frame buffer
+ var vramofs = (sl>>3)<<5; // offset in VRAM
+ var yy = sl & 7; // y offset within tile
+ for (var xx=0; xx<32; xx++) {
+ var code = ram.mem[vramofs+xx];
+ var data = ram.mem[0x800 + (code<<3) + yy];
+ var col = (code>>5) + (palbank<<3);
+ var color1 = palette[col&15];
+ var color2 = 0;
+ for (var i=0; i<8; i++) {
+ var bm = 128>>i;
+ pixels[outi] = (data&bm) ? color2 : color1;
+ outi++;
+ }
+ }
+ }
+
+ var CARNIVAL_KEYCODE_MAP = makeKeycodeMap([
+ [Keys.VK_SPACE, 2, -0x20],
+ [Keys.VK_SHIFT, 2, -0x40],
+ [Keys.VK_LEFT, 1, -0x10],
+ [Keys.VK_RIGHT, 1, -0x20],
+ [Keys.VK_UP, 1, -0x40],
+ [Keys.VK_DOWN, 1, -0x80],
+ [Keys.VK_1, 2, -0x10],
+ [Keys.VK_2, 3, -0x20],
+ [Keys.VK_5, 3, 0x8],
+ ]);
+
+ this.getPresets = function() {
+ return ColecoVision_PRESETS;
+ }
+
+ this.start = function() {
+ ram = new RAM(0x400);
+ //bios = COLECO_BIOS;
+ membus = {
+ read: new AddressDecoder([
+ [0x0000, 0x1fff, 0x1fff, function(a) { return bios ? bios[a] : null; }],
+ [0x6000, 0x7fff, 0x3ff, function(a) { return ram.mem[a]; }],
+ ]),
+ write: new AddressDecoder([
+ [0x6000, 0x7fff, 0x3ff, function(a,v) { ram.mem[a] = v; }],
+ ]),
+ isContended: function() { return false; },
+ };
+ this.readAddress = membus.read;
+ iobus = {
+ read: function(addr) {
+ return inputs[addr&3];
+ },
+ write: function(addr, val) {
+ console.log(addr,val);
+ }
+ };
+ cpu = this.newCPU(membus, iobus);
+ video = new RasterVideo(mainElement,visiblePixelsPerScanline,visibleScanlinesPerFrame);
+ audio = new MasterAudio();
+ psg = new AY38910_Audio(audio);
+ //var speech = new VotraxSpeech();
+ //audio.master.addChannel(speech);
+ video.create();
+ var idata = video.getFrameData();
+ setKeyboardFromMap(video, inputs, CARNIVAL_KEYCODE_MAP);
+ pixels = video.getFrameData();
+ timer = new AnimationTimer(60, function() {
+ if (!self.isRunning())
+ return;
+ var debugCond = self.getDebugCallback();
+ var targetTstates = cpu.getTstates();
+ for (var sl=0; sl