1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-29 10:29:29 +00:00

Deploying to gh-pages from @ sehugg/8bitworkshop@9f1c5377b3 🚀

This commit is contained in:
sehugg 2022-09-03 23:15:20 +00:00
parent b45725458a
commit 7c36d11d1e
22 changed files with 148 additions and 115 deletions

10
gen/atari8-MIMGHOLP.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
import{a as d}from"./chunk-3XE5YOCV.js";import{o as c}from"./chunk-ZT2WTSS7.js";import"./chunk-YT7MMFDW.js";import"./chunk-5SHCNQ2O.js";import"./chunk-55ZJ2RP7.js";import{J as m,o as u,u as h}from"./chunk-4YPL6KTM.js";import{$ as i,B as o,J as l,m as n}from"./chunk-JC7DT6V7.js";import"./chunk-5XVCUSSZ.js";var s=31,a=class extends u{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new h;this.ram=new Uint8Array(16384);this.read=i([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=i([[0,16383,16383,(e,t)=>{this.ram[e]=t}],[16387,16387,65535,(e,t)=>this.serial.sendByte(t)],[16399,16399,65535,(e,t)=>{this.inputs[s]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var t=0;t<this.cpuFrequency/60&&!(e&&e());)t+=this.advanceCPU();return t}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[s]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[s]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],f=class{constructor(e){e.style.overflowY="auto";var t=$('<div id="gameport"/>').appendTo(e);$('<p class="transcript-header">Serial Output</p>').appendTo(t);var y=$('<div id="windowport" class="transcript"/>').appendTo(t);this.div=y[0]}start(){this.tty=new d(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(e){this.tty.loadState(e)}};function p(r){return r==10?"":r<32?String.fromCharCode(r+9216):String.fromCharCode(r)}var v=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(e){this.clearToSend()&&(this.outputBytes.push(e),this.viewer.tty.addtext(p(e),2|32),e==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var e=this.readIndex();this.inputIndex=e;var t=(this.inputBytes&&this.inputBytes[e])|0;return this.viewer.tty.addtext(p(t),2|16),t==10&&this.viewer.tty.newline(),t}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(e){this.clk+=e}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(e){this.clk=e.clk,this.inputIndex=e.idx,this.outputBytes=e.out.slice()}},x=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new f(e)}async start(){super.start(),this.serial=new v,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=o(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=n(this.serial.outputBytes),c(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new a}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};l["devel-6502"]=x;export{v as SerialTestHarness}; import{a as d}from"./chunk-3XE5YOCV.js";import{o as c}from"./chunk-3Z3BWACQ.js";import"./chunk-YT7MMFDW.js";import"./chunk-5SHCNQ2O.js";import"./chunk-IACSBDWA.js";import{J as m,o as u,u as h}from"./chunk-4YPL6KTM.js";import{$ as i,B as o,J as l,m as n}from"./chunk-JC7DT6V7.js";import"./chunk-5XVCUSSZ.js";var s=31,a=class extends u{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new h;this.ram=new Uint8Array(16384);this.read=i([[0,16383,16383,e=>this.ram[e]],[16384,16384,65535,e=>this.serial.byteAvailable()?128:0],[16385,16385,65535,e=>this.serial.recvByte()],[16386,16386,65535,e=>this.serial.clearToSend()?128:0],[32768,65535,32767,e=>this.rom&&this.rom[e]]]);this.write=i([[0,16383,16383,(e,t)=>{this.ram[e]=t}],[16387,16387,65535,(e,t)=>this.serial.sendByte(t)],[16399,16399,65535,(e,t)=>{this.inputs[s]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var t=0;t<this.cpuFrequency/60&&!(e&&e());)t+=this.advanceCPU();return t}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[s]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[s]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],f=class{constructor(e){e.style.overflowY="auto";var t=$('<div id="gameport"/>').appendTo(e);$('<p class="transcript-header">Serial Output</p>').appendTo(t);var y=$('<div id="windowport" class="transcript"/>').appendTo(t);this.div=y[0]}start(){this.tty=new d(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(e){this.tty.loadState(e)}};function p(r){return r==10?"":r<32?String.fromCharCode(r+9216):String.fromCharCode(r)}var v=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(e){this.clearToSend()&&(this.outputBytes.push(e),this.viewer.tty.addtext(p(e),2|32),e==10&&this.viewer.tty.newline(),this.clearToSend()||(this.viewer.tty.newline(),this.viewer.tty.addtext("\u26A0\uFE0F OUTPUT BUFFER FULL \u26A0\uFE0F",4)))}byteAvailable(){return this.readIndex()>this.inputIndex}recvByte(){var e=this.readIndex();this.inputIndex=e;var t=(this.inputBytes&&this.inputBytes[e])|0;return this.viewer.tty.addtext(p(t),2|16),t==10&&this.viewer.tty.newline(),t}readIndex(){return this.bufferedRead?this.inputIndex+1:Math.floor(this.clk/this.cyclesPerByte)}reset(){this.inputIndex=-1,this.clk=0,this.outputBytes=[],this.bufin=""}advance(e){this.clk+=e}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(e){this.clk=e.clk,this.inputIndex=e.idx,this.outputBytes=e.out.slice()}},x=class extends m{constructor(e){super(e);this.getMemoryMap=function(){return{main:[{name:"RAM",start:0,size:16384,type:"ram"},{name:"ROM",start:32768,size:32768,type:"rom"}]}};this.serview=new f(e)}async start(){super.start(),this.serial=new v,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=o(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=n(this.serial.outputBytes),c(),0):super.advance(e)}saveState(){var e=super.saveState();return e.serial=this.serial.saveState(),e.serview=this.serview.saveState(),e}loadState(e){super.loadState(e),this.serial.loadState(e.serial),this.serview.loadState(e.serview)}newMachine(){return new a}getPresets(){return S}getDefaultExtension(){return".dasm"}readAddress(e){return this.machine.readConst(e)}};l["devel-6502"]=x;export{v as SerialTestHarness};
//# sourceMappingURL=devel-ADHXX4NA.js.map //# sourceMappingURL=devel-D4RUBO3S.js.map

View File

@ -1,2 +1,2 @@
import{b as w,c as x}from"./chunk-55ZJ2RP7.js";import{D as v,J as c,k as m,l as u,x as g,z as p}from"./chunk-JC7DT6V7.js";import{e as I}from"./chunk-5XVCUSSZ.js";var h=I(x()),i,a,l,y=function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r}(window.location.search.substr(1).split("&"));function P(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function k(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){v("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{k(r,f)},"arraybuffer"),!0;if(n){var s=u(atob(n));t=new m().decode(s)}return M(),k(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await w(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){P(),y.p&&b(y)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,h.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder}; import{b as w,c as x}from"./chunk-IACSBDWA.js";import{D as v,J as c,k as m,l as u,x as g,z as p}from"./chunk-JC7DT6V7.js";import{e as I}from"./chunk-5XVCUSSZ.js";var h=I(x()),i,a,l,y=function(e){if(!e||e.length==0)return{};for(var r={},t=0;t<e.length;++t){var o=e[t].split("=",2);o.length==1?r[o[0]]="":r[o[0]]=decodeURIComponent(o[1].replace(/\+/g," "))}return r}(window.location.search.substr(1).split("&"));function P(){typeof window.onerror=="object"&&(window.onerror=function(e,r,t,o,n){var s=e+" "+r+" "+t+":"+o+", "+n;$.get("/error?msg="+encodeURIComponent(s),"text")})}function M(){var e=!1;document.addEventListener("visibilitychange",function(r){document.visibilityState=="hidden"&&a.isRunning()?(a.pause(),e=!0):document.visibilityState=="visible"&&e&&(a.resume(),e=!1)}),$(window).on("focus",function(){e&&(a.resume(),e=!1)}),$(window).on("blur",function(){a.isRunning()&&(a.pause(),e=!0)})}async function k(e,r){if(!r){alert("No ROM found.");return}console.log(r.length+" bytes"),await a.loadROM(e,r),a.resume()}function R(){return $("#emulator").find("canvas")}function E(e,r,t){v("gif.js/dist/gif.js").then(()=>{var o=R()[0];if(!o){alert("Could not find canvas element to record video!");return}var n=0;o.style&&o.style.transform&&(o.style.transform.indexOf("rotate(-90deg)")>=0?n=-1:o.style.transform.indexOf("rotate(90deg)")>=0&&(n=1));var s=new GIF({workerScript:"gif.js/dist/gif.worker.js",workers:4,quality:10,rotate:n});s.on("finished",function(C){console.log("finished encoding GIF"),t(C)}),e=e||100+(Math.random()*256&3),r=r||100+(Math.random()*256&15);var f=0;console.log("Recording video",o);var d=()=>{f++>r?(console.log("Rendering video"),s.render()):(s.addFrame(o,{delay:e,copy:!0}),setTimeout(d,e))};d()})}async function S(e){if(!c[i])throw Error("Invalid platform '"+i+"'.");a=new c[i]($("#emuscreen")[0]),await a.start(),e.rec&&R().on("focus",()=>{a.resume()});var r=e.n||"Game",t,o=e.url,n=e.r;if(o)return console.log(o),g(o,f=>{k(r,f)},"arraybuffer"),!0;if(n){var s=u(atob(n));t=new m().decode(s)}return M(),k(r,t),!0}async function b(e){if(e.data&&(e=e.data),i=e.p,!i)throw new Error("No platform variable!");try{var r=await w(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){P(),y.p&&b(y)}window.addEventListener("message",O,!1);function O(e){if(e.data){var r=e.data.cmd;if(r=="start"&&!a)b(e);else if(r=="reset")a.reset(),l.reset();else if(r=="getReplay"){var t={frameCount:l.frameCount,checkpoints:l.checkpoints,framerecs:l.framerecs,checkpointInterval:l.checkpointInterval,maxCheckpoints:l.maxCheckpoints};e.source.postMessage({ack:r,replay:t},e.origin)}else if(r=="watchState"){var o=new Function("platform","state",e.data.fn);l.callbackNewCheckpoint=n=>{e.source.postMessage({ack:r,state:o(a,n)},e.origin)}}else r=="recordVideo"?E(e.data.intervalMsec,e.data.maxFrames,function(n){e.data.filename&&(0,h.saveAs)(n,e.data.filename),e.source.postMessage({ack:r,gif:n},e.origin)}):console.log("Unknown data.cmd: "+r)}}self===top&&(document.body.style.backgroundColor="#555");F();export{a as platform,i as platform_id,F as startEmbed,l as stateRecorder};
//# sourceMappingURL=embedui.js.map //# sourceMappingURL=embedui.js.map

View File

@ -55,6 +55,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.overscan = true; this.overscan = true;
this.audioOversample = 4; this.audioOversample = 4;
this.sampleRate = this.numTotalScanlines * 60 * this.audioOversample; this.sampleRate = this.numTotalScanlines * 60 * this.audioOversample;
this.run_address = -1;
this.inputs = new Uint8Array(4); this.inputs = new Uint8Array(4);
this.linergb = new Uint32Array(this.canvasWidth); this.linergb = new Uint32Array(this.canvasWidth);
this.lastdmabyte = 0; this.lastdmabyte = 0;
@ -63,6 +64,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.cart_a0 = false; this.cart_a0 = false;
this.xexdata = null; this.xexdata = null;
this.keyboard_active = true; this.keyboard_active = true;
this.d500 = new Uint8Array(0x100);
this.cpu = new MOS6502_1.MOS6502(); this.cpu = new MOS6502_1.MOS6502();
this.ram = new Uint8Array(0x10000); this.ram = new Uint8Array(0x10000);
this.bios = new Uint8Array(0x2800); this.bios = new Uint8Array(0x2800);
@ -78,7 +80,6 @@ class Atari800 extends devices_1.BasicScanlineMachine {
} }
newBus() { newBus() {
return { return {
// TODO: https://github.com/dmlloyd/atari800/blob/master/DOC/cart.txt
read: (0, emu_1.newAddressDecoder)([ read: (0, emu_1.newAddressDecoder)([
[0x0000, 0x7fff, 0xffff, (a) => { return this.ram[a]; }], [0x0000, 0x7fff, 0xffff, (a) => { return this.ram[a]; }],
[0x8000, 0x9fff, 0xffff, (a) => { return this.cart_80 ? this.rom[a - 0x8000] : this.ram[a]; }], [0x8000, 0x9fff, 0xffff, (a) => { return this.cart_80 ? this.rom[a - 0x8000] : this.ram[a]; }],
@ -87,6 +88,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
[0xd200, 0xd2ff, 0xf, (a) => { return this.readPokey(a); }], [0xd200, 0xd2ff, 0xf, (a) => { return this.readPokey(a); }],
[0xd300, 0xd3ff, 0xf, (a) => { return this.readPIA(a); }], [0xd300, 0xd3ff, 0xf, (a) => { return this.readPIA(a); }],
[0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }], [0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }],
[0xd500, 0xd5ff, 0xff, (a) => { return this.d500[a]; }],
[0xd800, 0xffff, 0xffff, (a) => { return this.bios[a - 0xd800]; }], [0xd800, 0xffff, 0xffff, (a) => { return this.bios[a - 0xd800]; }],
]), ]),
write: (0, emu_1.newAddressDecoder)([ write: (0, emu_1.newAddressDecoder)([
@ -107,8 +109,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.antic.reset(); this.antic.reset();
this.gtia.reset(); this.gtia.reset();
this.keycode = 0; this.keycode = 0;
if (this.xexdata) //if (this.xexdata) this.cart_a0 = true; // TODO
this.cart_a0 = true; // TODO
} }
read(a) { read(a) {
// TODO: lastdmabyte? // TODO: lastdmabyte?
@ -122,7 +123,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
return v; return v;
} }
readConst(a) { readConst(a) {
return a < 0xd000 || a >= 0xe000 ? this.bus.read(a) : 0xff; return a < 0xd000 || a >= 0xd500 ? this.bus.read(a) : 0xff;
} }
write(a, v) { write(a, v) {
this.bus.write(a, v); this.bus.write(a, v);
@ -232,6 +233,8 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.irq_pokey.loadState(state.pokey); this.irq_pokey.loadState(state.pokey);
this.lastdmabyte = state.lastdmabyte; this.lastdmabyte = state.lastdmabyte;
this.keycode = state.keycode; this.keycode = state.keycode;
this.cart_80 = state.cart_80;
this.cart_a0 = state.cart_a0;
} }
saveState() { saveState() {
return { return {
@ -243,6 +246,8 @@ class Atari800 extends devices_1.BasicScanlineMachine {
inputs: this.inputs.slice(0), inputs: this.inputs.slice(0),
lastdmabyte: this.lastdmabyte, lastdmabyte: this.lastdmabyte,
keycode: this.keycode, keycode: this.keycode,
cart_80: this.cart_80,
cart_a0: this.cart_a0,
}; };
} }
loadControlsState(state) { loadControlsState(state) {
@ -274,7 +279,7 @@ class Atari800 extends devices_1.BasicScanlineMachine {
if (!this.keyboard_active) if (!this.keyboard_active)
return false; return false;
if (flags & (emu_1.KeyFlags.KeyDown | emu_1.KeyFlags.KeyUp)) { if (flags & (emu_1.KeyFlags.KeyDown | emu_1.KeyFlags.KeyUp)) {
console.log(o, key, code, flags, (0, util_1.hex)(this.keycode)); //console.log(o, key, code, flags, hex(this.keycode));
var keymap = ATARI8_KEYMATRIX_INTL_NOSHIFT; var keymap = ATARI8_KEYMATRIX_INTL_NOSHIFT;
if (key == emu_1.Keys.VK_F9.c) { if (key == emu_1.Keys.VK_F9.c) {
this.irq_pokey.generateIRQ(0x80); // break IRQ this.irq_pokey.generateIRQ(0x80); // break IRQ
@ -309,19 +314,16 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.probe.logInterrupt(1); this.probe.logInterrupt(1);
} }
loadROM(rom, title) { loadROM(rom, title) {
// XEX file? if ((rom[0] == 0xff && rom[1] == 0xff) && !(title === null || title === void 0 ? void 0 : title.endsWith('.rom'))) {
if (title && title.toLowerCase().endsWith('.xex') && rom[0] == 0xff && rom[1] == 0xff) { // XEX file, chill out and wait for BIOS hook
// TODO: we fake a cartridge
this.xexdata = rom; this.xexdata = rom;
let cart = new Uint8Array(0x1000);
cart.set([0x00, 0x01, 0x00, 0x04, 0x00, 0x01], 0xffa);
this.loadCartridge(cart);
} }
else { else {
this.loadCartridge(rom); this.loadCartridge(rom);
} }
} }
loadCartridge(rom) { loadCartridge(rom) {
// TODO: https://github.com/dmlloyd/atari800/blob/master/DOC/cart.txt
// strip off header // strip off header
if (rom[0] == 0x43 && rom[1] == 0x41 && rom[2] == 0x52 && rom[3] == 0x54) { if (rom[0] == 0x43 && rom[1] == 0x41 && rom[2] == 0x52 && rom[3] == 0x54) {
rom = rom.slice(16); rom = rom.slice(16);
@ -334,11 +336,13 @@ class Atari800 extends devices_1.BasicScanlineMachine {
for (let i = 0; i <= rom2.length - rom.length; i += rom.length) { for (let i = 0; i <= rom2.length - rom.length; i += rom.length) {
rom2.set(rom, i); rom2.set(rom, i);
} }
this.run_address = rom2[0x7ffe] + rom2[0x7fff] * 256;
this.cart_a0 = true; // TODO this.cart_a0 = true; // TODO
this.cart_80 = rom.length == 0x4000; this.cart_80 = rom.length == 0x4000;
super.loadROM(rom2); super.loadROM(rom2);
} }
writeMapper(addr, value) { writeMapper(addr, value) {
// TODO
if (addr == 0xff) { if (addr == 0xff) {
if (value == 0x80) if (value == 0x80)
this.cart_80 = false; this.cart_80 = false;
@ -346,49 +350,53 @@ class Atari800 extends devices_1.BasicScanlineMachine {
this.cart_a0 = false; this.cart_a0 = false;
} }
} }
// TODO
loadXEX(rom) { loadXEX(rom) {
let ofs = 2; let ofs = 2;
let cart = this.ram; let stub = this.d500;
let cartofs = 0x100; // stub routine in stack page let stubofs = 0; // stub routine
var runaddr = -1;
// load segments into RAM
while (ofs < rom.length) { while (ofs < rom.length) {
let start = rom[ofs + 0] + rom[ofs + 1] * 256; let start = rom[ofs + 0] + rom[ofs + 1] * 256;
let end = rom[ofs + 2] + rom[ofs + 3] * 256; let end = rom[ofs + 2] + rom[ofs + 3] * 256;
console.log('XEX', ofs, (0, util_1.hex)(start), (0, util_1.hex)(end)); console.log('XEX', (0, util_1.hex)(ofs), (0, util_1.hex)(start), (0, util_1.hex)(end));
ofs += 4; ofs += 4;
for (let i = start; i <= end; i++) { for (let i = start; i <= end; i++) {
this.ram[i] = rom[ofs++]; this.ram[i] = rom[ofs++];
} }
var runaddr = this.ram[0x2e0] + this.ram[0x2e1] * 256; if (start == 0x2e0 && end == 0x2e1) {
var initaddr = this.ram[0x2e2] + this.ram[0x2e3] * 256; runaddr = this.ram[0x2e0] + this.ram[0x2e1] * 256;
console.log('XEX run', (0, util_1.hex)(runaddr), 'init', (0, util_1.hex)(initaddr)); console.log('XEX run', (0, util_1.hex)(runaddr));
if (initaddr) { }
cart[cartofs++] = 0x20; if (start == 0x2e2 && end == 0x2e3) {
cart[cartofs++] = initaddr & 0xff; var initaddr = this.ram[0x2e2] + this.ram[0x2e3] * 256;
cart[cartofs++] = initaddr >> 8; console.log('XEX init', (0, util_1.hex)(initaddr));
stub[stubofs++] = 0x20;
stub[stubofs++] = initaddr & 0xff;
stub[stubofs++] = initaddr >> 8;
} }
if (ofs > rom.length) if (ofs > rom.length)
throw new Error("Bad .XEX file format"); throw new Error("Bad .XEX file format");
} }
if (runaddr) { if (runaddr >= 0) {
cart[cartofs++] = 0xa9; // lda #$a0 // build stub routine at 0xd500
cart[cartofs++] = 0xa0; stub[stubofs++] = 0xa9; // lda #$a0
cart[cartofs++] = 0x8d; // sta $d5ff (disable cart) stub[stubofs++] = 0xa0;
cart[cartofs++] = 0xff; stub[stubofs++] = 0x8d; // sta $d5ff (disable cart)
cart[cartofs++] = 0xd5; stub[stubofs++] = 0xff;
cart[cartofs++] = 0x4c; // jmp runaddr stub[stubofs++] = 0xd5;
cart[cartofs++] = runaddr & 0xff; stub[stubofs++] = 0x4c; // jmp runaddr
cart[cartofs++] = runaddr >> 8; stub[stubofs++] = runaddr & 0xff;
stub[stubofs++] = runaddr >> 8;
// set DOSVEC to 0xd500
this.ram[0xa] = 0x00;
this.ram[0xb] = 0xd5;
this.run_address = 0xd500;
} }
} }
initCartA() { initCartA() {
//console.log('init', hex(this.cpu.getPC())); if (this.cpu.getPC() == 0xf17f && this.xexdata) {
// disable cartridges and load XEX this.loadXEX(this.xexdata);
if (this.cpu.getPC() == 0xf17f) {
if (this.xexdata) {
this.loadXEX(this.xexdata);
}
//this.cart_80 = this.cart_a0 = false;
} }
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -459,6 +459,14 @@ class ANTIC {
} }
case 4: case 4:
case 5: case 5:
{
let v = (this.pfbyte >> 6) & 3;
this.pfbyte <<= 2;
if (this.ch & 0x80)
return [0, 4, 5, 7][v];
else
return [0, 4, 5, 6][v];
}
case 8: case 8:
case 10: case 10:
case 13: case 13:
@ -466,7 +474,7 @@ class ANTIC {
{ {
let v = (this.pfbyte >> 6) & 3; let v = (this.pfbyte >> 6) & 3;
this.pfbyte <<= 2; this.pfbyte <<= 2;
return [0, 4, 5, 6][v]; // TODO: 5th color return [0, 4, 5, 6][v];
} }
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w}from"./chunk-ZT2WTSS7.js";import"./chunk-YT7MMFDW.js";import"./chunk-5SHCNQ2O.js";import"./chunk-55ZJ2RP7.js";import"./chunk-4YPL6KTM.js";import"./chunk-JC7DT6V7.js";import"./chunk-5XVCUSSZ.js";export{l as clearBreakpoint,h as compparams,f as current_project,u as emulationHalted,p as getPlatformAndRepo,t as getSaveState,s as getTestOutput,n as haltEmulation,w as highlightSearch,i as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,v as reloadWorkspaceFile,d as repo_id,k as runToPC,m as setFrameRateUI,r as setTestInput,j as setupBreakpoint,o as setupSplits,q as startUI,c as store_id}; import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t,v as u,w as v,x as w}from"./chunk-3Z3BWACQ.js";import"./chunk-YT7MMFDW.js";import"./chunk-5SHCNQ2O.js";import"./chunk-IACSBDWA.js";import"./chunk-4YPL6KTM.js";import"./chunk-JC7DT6V7.js";import"./chunk-5XVCUSSZ.js";export{l as clearBreakpoint,h as compparams,f as current_project,u as emulationHalted,p as getPlatformAndRepo,t as getSaveState,s as getTestOutput,n as haltEmulation,w as highlightSearch,i as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,v as reloadWorkspaceFile,d as repo_id,k as runToPC,m as setFrameRateUI,r as setTestInput,j as setupBreakpoint,o as setupSplits,q as startUI,c as store_id};
//# sourceMappingURL=ui.js.map //# sourceMappingURL=ui.js.map

View File

@ -26,7 +26,7 @@ var ATARI8_KEYCODE_MAP = makeKeycodeMap([
[Keys.DOWN, 0, 0x2], [Keys.DOWN, 0, 0x2],
[Keys.LEFT, 0, 0x4], [Keys.LEFT, 0, 0x4],
[Keys.RIGHT, 0, 0x8], [Keys.RIGHT, 0, 0x8],
[{c: 16, n: "Shift", plyr:0, button:0}, 2, 0x1], [{ c: 16, n: "Shift", plyr: 0, button: 0 }, 2, 0x1],
/* /*
[Keys.P2_UP, 0, 0x10], [Keys.P2_UP, 0, 0x10],
[Keys.P2_DOWN, 0, 0x20], [Keys.P2_DOWN, 0, 0x20],
@ -55,6 +55,7 @@ export class Atari800 extends BasicScanlineMachine {
overscan = true; overscan = true;
audioOversample = 4; audioOversample = 4;
sampleRate = this.numTotalScanlines * 60 * this.audioOversample; sampleRate = this.numTotalScanlines * 60 * this.audioOversample;
run_address = -1;
cpu: MOS6502; cpu: MOS6502;
ram: Uint8Array; ram: Uint8Array;
@ -73,6 +74,7 @@ export class Atari800 extends BasicScanlineMachine {
cart_a0 = false; cart_a0 = false;
xexdata = null; xexdata = null;
keyboard_active = true; keyboard_active = true;
d500 = new Uint8Array(0x100);
// TODO: save/load vars // TODO: save/load vars
constructor() { constructor() {
@ -90,11 +92,10 @@ export class Atari800 extends BasicScanlineMachine {
this.audioadapter = new TssChannelAdapter(this.audio_pokey.pokey1, this.audioOversample, this.sampleRate); this.audioadapter = new TssChannelAdapter(this.audio_pokey.pokey1, this.audioOversample, this.sampleRate);
this.handler = newKeyboardHandler( this.handler = newKeyboardHandler(
this.inputs, ATARI8_KEYCODE_MAP, this.getKeyboardFunction(), true); this.inputs, ATARI8_KEYCODE_MAP, this.getKeyboardFunction(), true);
} }
newBus() { newBus() {
return { return {
// TODO: https://github.com/dmlloyd/atari800/blob/master/DOC/cart.txt
read: newAddressDecoder([ read: newAddressDecoder([
[0x0000, 0x7fff, 0xffff, (a) => { return this.ram[a]; }], [0x0000, 0x7fff, 0xffff, (a) => { return this.ram[a]; }],
[0x8000, 0x9fff, 0xffff, (a) => { return this.cart_80 ? this.rom[a - 0x8000] : this.ram[a]; }], [0x8000, 0x9fff, 0xffff, (a) => { return this.cart_80 ? this.rom[a - 0x8000] : this.ram[a]; }],
@ -103,6 +104,7 @@ export class Atari800 extends BasicScanlineMachine {
[0xd200, 0xd2ff, 0xf, (a) => { return this.readPokey(a); }], [0xd200, 0xd2ff, 0xf, (a) => { return this.readPokey(a); }],
[0xd300, 0xd3ff, 0xf, (a) => { return this.readPIA(a); }], [0xd300, 0xd3ff, 0xf, (a) => { return this.readPIA(a); }],
[0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }], [0xd400, 0xd4ff, 0xf, (a) => { return this.antic.readReg(a); }],
[0xd500, 0xd5ff, 0xff, (a) => { return this.d500[a]; }],
[0xd800, 0xffff, 0xffff, (a) => { return this.bios[a - 0xd800]; }], [0xd800, 0xffff, 0xffff, (a) => { return this.bios[a - 0xd800]; }],
]), ]),
write: newAddressDecoder([ write: newAddressDecoder([
@ -125,7 +127,7 @@ export class Atari800 extends BasicScanlineMachine {
this.antic.reset(); this.antic.reset();
this.gtia.reset(); this.gtia.reset();
this.keycode = 0; this.keycode = 0;
if (this.xexdata) this.cart_a0 = true; // TODO //if (this.xexdata) this.cart_a0 = true; // TODO
} }
read(a) { read(a) {
@ -140,7 +142,7 @@ export class Atari800 extends BasicScanlineMachine {
return v; return v;
} }
readConst(a) { readConst(a) {
return a < 0xd000 || a >= 0xe000 ? this.bus.read(a) : 0xff; return a < 0xd000 || a >= 0xd500 ? this.bus.read(a) : 0xff;
} }
write(a, v) { write(a, v) {
this.bus.write(a, v); this.bus.write(a, v);
@ -242,6 +244,8 @@ export class Atari800 extends BasicScanlineMachine {
this.irq_pokey.loadState(state.pokey); this.irq_pokey.loadState(state.pokey);
this.lastdmabyte = state.lastdmabyte; this.lastdmabyte = state.lastdmabyte;
this.keycode = state.keycode; this.keycode = state.keycode;
this.cart_80 = state.cart_80;
this.cart_a0 = state.cart_a0;
} }
saveState() { saveState() {
return { return {
@ -253,6 +257,8 @@ export class Atari800 extends BasicScanlineMachine {
inputs: this.inputs.slice(0), inputs: this.inputs.slice(0),
lastdmabyte: this.lastdmabyte, lastdmabyte: this.lastdmabyte,
keycode: this.keycode, keycode: this.keycode,
cart_80: this.cart_80,
cart_a0: this.cart_a0,
}; };
} }
loadControlsState(state) { loadControlsState(state) {
@ -283,7 +289,7 @@ export class Atari800 extends BasicScanlineMachine {
return (o, key, code, flags) => { return (o, key, code, flags) => {
if (!this.keyboard_active) return false; if (!this.keyboard_active) return false;
if (flags & (KeyFlags.KeyDown | KeyFlags.KeyUp)) { if (flags & (KeyFlags.KeyDown | KeyFlags.KeyUp)) {
console.log(o, key, code, flags, hex(this.keycode)); //console.log(o, key, code, flags, hex(this.keycode));
var keymap = ATARI8_KEYMATRIX_INTL_NOSHIFT; var keymap = ATARI8_KEYMATRIX_INTL_NOSHIFT;
if (key == Keys.VK_F9.c) { if (key == Keys.VK_F9.c) {
this.irq_pokey.generateIRQ(0x80); // break IRQ this.irq_pokey.generateIRQ(0x80); // break IRQ
@ -314,19 +320,16 @@ export class Atari800 extends BasicScanlineMachine {
} }
loadROM(rom: Uint8Array, title: string) { loadROM(rom: Uint8Array, title: string) {
// XEX file? if ((rom[0] == 0xff && rom[1] == 0xff) && !title?.endsWith('.rom')) {
if (title && title.toLowerCase().endsWith('.xex') && rom[0] == 0xff && rom[1] == 0xff) { // XEX file, chill out and wait for BIOS hook
// TODO: we fake a cartridge
this.xexdata = rom; this.xexdata = rom;
let cart = new Uint8Array(0x1000);
cart.set([0x00, 0x01, 0x00, 0x04, 0x00, 0x01], 0xffa);
this.loadCartridge(cart);
} else { } else {
this.loadCartridge(rom); this.loadCartridge(rom);
} }
} }
loadCartridge(rom: Uint8Array) { loadCartridge(rom: Uint8Array) {
// TODO: https://github.com/dmlloyd/atari800/blob/master/DOC/cart.txt
// strip off header // strip off header
if (rom[0] == 0x43 && rom[1] == 0x41 && rom[2] == 0x52 && rom[3] == 0x54) { if (rom[0] == 0x43 && rom[1] == 0x41 && rom[2] == 0x52 && rom[3] == 0x54) {
rom = rom.slice(16); rom = rom.slice(16);
@ -339,61 +342,67 @@ export class Atari800 extends BasicScanlineMachine {
for (let i = 0; i <= rom2.length - rom.length; i += rom.length) { for (let i = 0; i <= rom2.length - rom.length; i += rom.length) {
rom2.set(rom, i); rom2.set(rom, i);
} }
this.run_address = rom2[0x7ffe] + rom2[0x7fff]*256;
this.cart_a0 = true; // TODO this.cart_a0 = true; // TODO
this.cart_80 = rom.length == 0x4000; this.cart_80 = rom.length == 0x4000;
super.loadROM(rom2); super.loadROM(rom2);
} }
writeMapper(addr:number, value:number) { writeMapper(addr: number, value: number) {
// TODO
if (addr == 0xff) { if (addr == 0xff) {
if (value == 0x80) this.cart_80 = false; if (value == 0x80) this.cart_80 = false;
if (value == 0xa0) this.cart_a0 = false; if (value == 0xa0) this.cart_a0 = false;
} }
} }
// TODO
loadXEX(rom: Uint8Array) { loadXEX(rom: Uint8Array) {
let ofs = 2; let ofs = 2;
let cart = this.ram; let stub = this.d500;
let cartofs = 0x100; // stub routine in stack page let stubofs = 0; // stub routine
var runaddr = -1;
// load segments into RAM
while (ofs < rom.length) { while (ofs < rom.length) {
let start = rom[ofs+0] + rom[ofs+1] * 256; let start = rom[ofs + 0] + rom[ofs + 1] * 256;
let end = rom[ofs+2] + rom[ofs+3] * 256; let end = rom[ofs + 2] + rom[ofs + 3] * 256;
console.log('XEX', ofs, hex(start), hex(end)); console.log('XEX', hex(ofs), hex(start), hex(end));
ofs += 4; ofs += 4;
for (let i=start; i<=end; i++) { for (let i = start; i <= end; i++) {
this.ram[i] = rom[ofs++]; this.ram[i] = rom[ofs++];
} }
var runaddr = this.ram[0x2e0] + this.ram[0x2e1]*256; if (start == 0x2e0 && end == 0x2e1) {
var initaddr = this.ram[0x2e2] + this.ram[0x2e3]*256; runaddr = this.ram[0x2e0] + this.ram[0x2e1] * 256;
console.log('XEX run', hex(runaddr), 'init', hex(initaddr)); console.log('XEX run', hex(runaddr));
if (initaddr) { }
cart[cartofs++] = 0x20; if (start == 0x2e2 && end == 0x2e3) {
cart[cartofs++] = initaddr & 0xff; var initaddr = this.ram[0x2e2] + this.ram[0x2e3] * 256;
cart[cartofs++] = initaddr >> 8; console.log('XEX init', hex(initaddr));
stub[stubofs++] = 0x20;
stub[stubofs++] = initaddr & 0xff;
stub[stubofs++] = initaddr >> 8;
} }
if (ofs > rom.length) throw new Error("Bad .XEX file format"); if (ofs > rom.length) throw new Error("Bad .XEX file format");
} }
if (runaddr) { if (runaddr >= 0) {
cart[cartofs++] = 0xa9; // lda #$a0 // build stub routine at 0xd500
cart[cartofs++] = 0xa0; stub[stubofs++] = 0xa9; // lda #$a0
cart[cartofs++] = 0x8d; // sta $d5ff (disable cart) stub[stubofs++] = 0xa0;
cart[cartofs++] = 0xff; stub[stubofs++] = 0x8d; // sta $d5ff (disable cart)
cart[cartofs++] = 0xd5; stub[stubofs++] = 0xff;
cart[cartofs++] = 0x4c; // jmp runaddr stub[stubofs++] = 0xd5;
cart[cartofs++] = runaddr & 0xff; stub[stubofs++] = 0x4c; // jmp runaddr
cart[cartofs++] = runaddr >> 8; stub[stubofs++] = runaddr & 0xff;
stub[stubofs++] = runaddr >> 8;
// set DOSVEC to 0xd500
this.ram[0xa] = 0x00;
this.ram[0xb] = 0xd5;
this.run_address = 0xd500;
} }
} }
initCartA() { initCartA() {
//console.log('init', hex(this.cpu.getPC())); if (this.cpu.getPC() == 0xf17f && this.xexdata) {
// disable cartridges and load XEX this.loadXEX(this.xexdata);
if (this.cpu.getPC() == 0xf17f) {
if (this.xexdata) {
this.loadXEX(this.xexdata);
}
//this.cart_80 = this.cart_a0 = false;
} }
} }

View File

@ -434,12 +434,20 @@ export class ANTIC {
return v ? 4 : 0; return v ? 4 : 0;
} }
case 4: case 5: case 4: case 5:
{
let v = (this.pfbyte >> 6) & 3;
this.pfbyte <<= 2;
if (this.ch & 0x80)
return [0, 4, 5, 7][v];
else
return [0, 4, 5, 6][v];
}
case 8: case 10: case 8: case 10:
case 13: case 14: case 13: case 14:
{ {
let v = (this.pfbyte >> 6) & 3; let v = (this.pfbyte >> 6) & 3;
this.pfbyte <<= 2; this.pfbyte <<= 2;
return [0, 4, 5, 6][v]; // TODO: 5th color return [0, 4, 5, 6][v];
} }
} }
} }