From 5851394f40d65e96f40927915220b3857c5cd9b8 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 26 Jan 2017 21:59:34 -0500 Subject: [PATCH] AY38910_Audio --- .gitmodules | 3 +++ package.json | 2 +- src/emu.js | 36 ++++++++++++++++++++++++++++++++++++ src/platform/galaxian.js | 10 +++++++--- src/platform/vcs.js | 1 + src/platform/vicdual.js | 16 +++++++++------- src/ui.js | 8 +++----- tools/parsebdf8.py | 3 ++- tss | 1 + 9 files changed, 63 insertions(+), 17 deletions(-) create mode 160000 tss diff --git a/.gitmodules b/.gitmodules index 0d91be95..f183880a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "octokat.js"] path = octokat.js url = ./octokat.js +[submodule "tss"] + path = tss + url = ./tss diff --git a/package.json b/package.json index 58490e25..ba05287b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "8bitworkshop", - "version": "0.0.2", + "version": "1.0.0", "author": "Steven Hugg", "dependencies": {}, "devDependencies": { diff --git a/src/emu.js b/src/emu.js index 5f924c79..48c1a7fd 100644 --- a/src/emu.js +++ b/src/emu.js @@ -337,6 +337,39 @@ function cpuStateToLongString_6502(c) { + " Y " + hex(c.Y) + " " + "SP " + hex(c.SP) + "\n"; } +var MasterAudio = function() { + this.master = new MasterChannel(); + this.looper = new AudioLooper(512); + this.start = function() { + this.looper.setChannel(this.master); + this.looper.activate(); + } + this.stop = function() { + this.looper.setChannel(null); + } +} + +var AY38910_Audio = function(master) { + this.psg = new PsgDeviceChannel(); + this.psg.setMode(PsgDeviceChannel.MODE_SIGNED); + this.psg.setDevice(PsgDeviceChannel.DEVICE_AY_3_8910); + master.master.addChannel(this.psg); + var curreg = 0; + + this.reset = function() { + for (var i=15; i>=0; i--) { + this.selectRegister(i); + this.setData(0); + } + } + this.selectRegister = function(val) { + curreg = val & 0xf; + } + this.setData = function(val) { + this.psg.writeRegisterAY(curreg, val & 0xff); + } +} + ////// 6502 var Base6502Platform = function() { @@ -823,6 +856,9 @@ function makeKeycodeMap(table) { } function padBytes(data, len) { + if (data.length > len) { + throw Error("Data too long, " + data.length + " > " + len); + } var r = new RAM(len); r.mem.set(data); return r.mem; diff --git a/src/platform/galaxian.js b/src/platform/galaxian.js index dba675e1..0c0c0d25 100644 --- a/src/platform/galaxian.js +++ b/src/platform/galaxian.js @@ -163,7 +163,10 @@ var GalaxianPlatform = function(mainElement) { [0x4000, 0x47ff, 0x3ff, function(a,v) { ram.mem[a] = v; }], [0x5000, 0x57ff, 0x3ff, function(a,v) { vram.mem[a] = v; }], [0x5800, 0x5fff, 0xff, function(a,v) { oram.mem[a] = v; }], - [0x6000, 0x67ff, 0x7, function(a,v) { outlatches.mem[a] = v; }], + [0x6004, 0x6007, 0x3, function(a,v) { }], // lfo freq + [0x6800, 0x6807, 0x7, function(a,v) { }], // sound + [0x7800, 0x7800, 0x7, function(a,v) { }], // pitch + [0x6000, 0x6003, 0x3, function(a,v) { outlatches.mem[a] = v; }], [0x7001, 0x7001, 0, function(a,v) { interruptEnabled = v; }], [0x7004, 0x7004, 0, function(a,v) { starsEnabled = v; }], ]), @@ -184,7 +187,7 @@ var GalaxianPlatform = function(mainElement) { ioBus: iobus }); video = new RasterVideo(mainElement,264,264,{rotate:90}); - audio = new SampleAudio(cpuFrequency); + audio = new MasterAudio(); video.create(); var idata = video.getFrameData(); setKeyboardFromMap(video, inputs, GALAXIAN_KEYCODE_MAP); @@ -227,7 +230,7 @@ var GalaxianPlatform = function(mainElement) { ]; this.loadROM = function(title, data) { - rom = padBytes(data, 0x3820); + rom = padBytes(data, 0x4000); // palette is at 0x3800-0x381f palette = new Uint32Array(new ArrayBuffer(32*4)); for (var i=0; i<32; i++) { @@ -285,6 +288,7 @@ var GalaxianPlatform = function(mainElement) { } this.reset = function() { cpu.reset(); + //audio.reset(); if (!this.getDebugCallback()) cpu.setTstates(0); // TODO? watchdog_counter = INITIAL_WATCHDOG; } diff --git a/src/platform/vcs.js b/src/platform/vcs.js index 22953bb5..08f1d737 100644 --- a/src/platform/vcs.js +++ b/src/platform/vcs.js @@ -43,6 +43,7 @@ var VCSPlatform = function() { this.start = function() { Javatari.start(); + $("#booklink_vcs").show(); } this.loadROM = function(title, data) { diff --git a/src/platform/vicdual.js b/src/platform/vicdual.js index 942364a9..c1299881 100644 --- a/src/platform/vicdual.js +++ b/src/platform/vicdual.js @@ -12,7 +12,7 @@ var VicDualPlatform = function(mainElement) { this.__proto__ = new BaseZ80Platform(); var cpu, ram, membus, iobus, rom; - var video, audio, timer, pixels; + var video, audio, psg, timer, pixels; var inputs = [0xff, 0xff, 0xff, 0xff]; // most things active low var palbank = 0; @@ -58,9 +58,9 @@ var VicDualPlatform = function(mainElement) { var vramofs = (sl>>3)<<5; // offset in VRAM var yy = sl & 7; // y offset within tile for (var xx=0; xx<32; xx++) { - var attrib = ram.mem[vramofs+xx]; - var data = ram.mem[0x800 + (attrib<<3) + yy]; - var col = (attrib>>5) + (palbank<<4); + var code = ram.mem[vramofs+xx]; + var data = ram.mem[0x800 + (code<<3) + yy]; + var col = (code>>5) + (palbank<<4); var color1 = palette[colorprom[col]]; var color2 = palette[colorprom[col+8]]; for (var i=0; i<8; i++) { @@ -99,8 +99,8 @@ var VicDualPlatform = function(mainElement) { iobus = { read: function(addr) { return inputs[addr&3]; }, write: function(addr, val) { - if (addr & 0x1) { }; // audio 1 - if (addr & 0x2) { }; // audio 2 + if (addr & 0x1) { psg.selectRegister(val); }; // audio 1 + if (addr & 0x2) { psg.setData(val); }; // audio 2 if (addr & 0x8) { }; // coin status if (addr & 0x40) { palbank = val & 3; }; // palette } @@ -111,7 +111,8 @@ var VicDualPlatform = function(mainElement) { ioBus: iobus }); video = new RasterVideo(mainElement,256,224,{rotate:-90}); - audio = new SampleAudio(cpuFrequency); + audio = new MasterAudio(); + psg = new AY38910_Audio(audio); video.create(); var idata = video.getFrameData(); setKeyboardFromMap(video, inputs, CARNIVAL_KEYCODE_MAP, function(o) { @@ -185,6 +186,7 @@ var VicDualPlatform = function(mainElement) { } this.reset = function() { cpu.reset(); + psg.reset(); if (!this.getDebugCallback()) cpu.setTstates(0); // TODO? } this.readAddress = function(addr) { diff --git a/src/ui.js b/src/ui.js index 61c28de1..bde2d2cc 100644 --- a/src/ui.js +++ b/src/ui.js @@ -246,14 +246,11 @@ function _shareFile(e) { alert("Please fix errors before sharing."); return true; } - if (!current_preset_id.startsWith("local/")) { - alert("Can only share files created with New File."); - return true; - } var github = new Octokat(); var files = {}; var text = editor.getValue(); - files[current_preset_id.slice(6)] = {"content": text}; + var toks = current_preset_id.split("/"); + files[toks[toks.length-1]] = {"content": text}; var gistdata = { "description": '8bitworkshop.com {"platform":"' + platform_id + '"}', "public": true, @@ -966,6 +963,7 @@ function startUI(loadplatform) { } else { // reset file? if (qs['file'] && qs['reset']) { + initPlatform(); store.deleteFile(qs['file']); qs['reset'] = ''; gotoNewLocation(); diff --git a/tools/parsebdf8.py b/tools/parsebdf8.py index 1f5187f9..f7ba7fb6 100644 --- a/tools/parsebdf8.py +++ b/tools/parsebdf8.py @@ -50,7 +50,8 @@ for ch in range(lochar,hichar+1): rot2output.append(0) for x in range(0,height): for y in range(0,height): - rotoutput[-7+x] |= (((output[-1-y]>>x)&1)<>x)&1)<>x)&1)<>x)&1)<