Deploying to gh-pages from @ sehugg/8bitworkshop@698f3cd7cb 🚀

This commit is contained in:
sehugg committed 2026-03-18 11:52:42 +00:00
1 parent 7ec02dbc31
commit fcae982211
53 files changed
+3928 -258

No files matched your search

@@ -1,4 +1,4 @@
import{b as E}from"./chunk-3FIVEUG2.js";import{a as S,t as y}from"./chunk-IBRDAYM2.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-R5KWJQBC.js";import"./chunk-GTDJ7CMC.js";import{B as c,K as f,T as d,U as v,a as g}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";function O(u){return u.value!=null}function k(u){return u.name!=null}function N(u){return u.op!=null&&u.left!=null&&u.right!=null}function I(u){return u.op!=null&&u.expr!=null}var m=class{randomize(){this.seed(Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647)}constructor(){(()=>{var r,e,i,n;this.seed=function(s,a,h,o){r=s,e=a,i=h,n=o},this.seedfloat=function(s){this.seed(s,s*4294,s*429496,s*4294967296),this.next(),this.next(),this.next()},this.next=function(){r>>>=0,e>>>=0,i>>>=0,n>>>=0;var s=r+e|0;return r=e^e>>>9,e=i+(i<<3)|0,i=i<<21|i>>>11,n=n+1|0,s=s+n|0,i=i+s|0,(s>>>0)/4294967296}})(),this.seedfloat(-1)}},L=1024*1024,l=class u{constructor(){this.margin=80;this.running=!1;this.exited=!0;this.trace=!1}load(t){let r=null,e=0;if(this.pc2label!=null){let s=this.curpc;for(;s>0&&(r=this.pc2label.get(s))==null;)s--;e=this.curpc-s,console.log("oldpc=",this.curpc,"restart @ label",r,"+",e)}this.program=t,this.opts=t.opts,this.opts.maxArrayElements||(this.opts.maxArrayElements=L),this.allstmts=t.stmts,this.label2pc=t.labels,this.label2dataptr={},this.pc2label=new Map,this.datums=[],this.subroutines={},this.builtins=this.getBuiltinFunctions();for(var i in t.labels){var n=t.labels[i];this.pc2label.set(n,i)}return this.allstmts.forEach((s,a)=>{this.curpc=a+1,this.compileStatement(s),s.command=="DATA"&&(this.label2dataptr[s.$loc.label]=this.datums.length,s.datums.forEach(h=>{this.curpc=s.$loc.offset,this.datums.push(h)}))}),this.label2pc[r]!=null?(this.curpc=this.label2pc[r]+e,!0):(this.curpc=0,!1)}reset(){this.curpc=0,this.dataptr=0,this.clearVars(),this.returnStack=[],this.column=0,this.running=!0,this.exited=!1}clearVars(){this.globals=this.vars={},this.arrays={},this.defs={},this.forLoops={},this.forLoopStack=[],this.whileLoops=[],this.rng=new m,this.opts&&this.opts.staticArrays&&this.allstmts.filter(t=>t.command=="DIM").forEach(t=>{t.args.forEach(r=>this.compileJS(this._DIM(r))())})}saveState(){return $.extend(!0,{},this)}loadState(t){$.extend(!0,this,t)}getBuiltinFunctions(){var t=this.program&&this.opts.validFunctions;t||(t=Object.getOwnPropertyNames(u.prototype).filter(i=>/^[A-Z]{3,}[$]?$/.test(i)));var r={};for(var e of t)this.supportsFunction(e)&&(r[e]=this[e].bind(this));return r}supportsFunction(t){return typeof this[t]=="function"}runtimeError(t){throw this.curpc--,new d(t,this.getCurrentSourceLocation())}dialectError(t){this.runtimeError(`I can't ${t} in this dialect of BASIC.`)}getLineForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.line}getLabelForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.label}getCurrentSourceLocation(){var t=this.getStatement();return t&&t.$loc}getCurrentLabel(){var t=this.getCurrentSourceLocation();return t&&t.label}getStatement(){return this.allstmts[this.curpc]}step(){if(!this.running)return!1;var t=this.getStatement();return t?(this.trace&&console.log(this.curpc,t,this.vars,Object.keys(this.arrays)),this.curpc++,this.executeStatement(t),this.running):(this.running=!1,this.exited=!0,!1)}compileStatement(t){if(t.$run==null)try{var r=this["do__"+t.command];r==null&&this.runtimeError(`I don't know how to "${t.command}".`);var e=r.bind(this)(t);this.trace&&console.log(e),t.$run=this.compileJS(e)}catch(i){throw e&&console.log(e),i}}compileJS(t){return new Function(t).bind(this)}executeStatement(t){this.compileStatement(t),t.$run()}skipToEOL(){do this.curpc++;while(this.curpc<this.allstmts.length&&!this.pc2label.get(this.curpc))}skipToElse(){for(;this.curpc<this.allstmts.length;){var t=this.allstmts[this.curpc].command;if(t=="ELSE"){this.curpc++;break}else if(t=="IF")return this.skipToEOL();if(this.curpc++,this.pc2label.get(this.curpc))break}}skipToEOF(){this.curpc=this.allstmts.length}skipToAfterNext(t){for(var r=this.curpc;r<this.allstmts.length;){var e=this.allstmts[r];if(e.command=="NEXT"){var i=e.lexpr;if(i&&i.name==t){this.curpc=r+1;return}}r++}this.runtimeError(`I couldn't find a matching NEXT ${t} to skip this for loop.`)}skipToAfterWend(){for(var t=this.curpc-1,r=0;t<this.allstmts.length;){var e=this.allstmts[t];if(e.command=="WHILE")r++;else if(e.command=="WEND"&&(r--,r==0)){this.curpc=t+1;return}t++}this.runtimeError("I couldn't find a matching WEND for this WHILE.")}gotoLabel(t){var r=this.label2pc[t];r>=0?this.curpc=r:this.runtimeError(`I tried to go to the label "${t}" but couldn't find it.`)}newLocalScope(){this.vars=Object.create(this.vars)}popLocalScope(){this.vars!==this.globals&&(this.vars=Object.getPrototypeOf(this.vars))}gosubLabel(t){this.returnStack.length>32767&&this.runtimeError("I did too many GOSUBs without a RETURN."),this.returnStack.push(this.curpc),this.gotoLabel(t)}returnFromGosub(){this.returnLine truncated
import{b as E}from"./chunk-3FIVEUG2.js";import{a as S,t as y}from"./chunk-2DVTTN6M.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-7WOMNSMI.js";import"./chunk-GTDJ7CMC.js";import{B as c,K as f,T as d,U as v,a as g}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";function O(u){return u.value!=null}function k(u){return u.name!=null}function N(u){return u.op!=null&&u.left!=null&&u.right!=null}function I(u){return u.op!=null&&u.expr!=null}var m=class{randomize(){this.seed(Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647,Math.random()*2147483647)}constructor(){(()=>{var r,e,i,n;this.seed=function(s,a,h,o){r=s,e=a,i=h,n=o},this.seedfloat=function(s){this.seed(s,s*4294,s*429496,s*4294967296),this.next(),this.next(),this.next()},this.next=function(){r>>>=0,e>>>=0,i>>>=0,n>>>=0;var s=r+e|0;return r=e^e>>>9,e=i+(i<<3)|0,i=i<<21|i>>>11,n=n+1|0,s=s+n|0,i=i+s|0,(s>>>0)/4294967296}})(),this.seedfloat(-1)}},L=1024*1024,l=class u{constructor(){this.margin=80;this.running=!1;this.exited=!0;this.trace=!1}load(t){let r=null,e=0;if(this.pc2label!=null){let s=this.curpc;for(;s>0&&(r=this.pc2label.get(s))==null;)s--;e=this.curpc-s,console.log("oldpc=",this.curpc,"restart @ label",r,"+",e)}this.program=t,this.opts=t.opts,this.opts.maxArrayElements||(this.opts.maxArrayElements=L),this.allstmts=t.stmts,this.label2pc=t.labels,this.label2dataptr={},this.pc2label=new Map,this.datums=[],this.subroutines={},this.builtins=this.getBuiltinFunctions();for(var i in t.labels){var n=t.labels[i];this.pc2label.set(n,i)}return this.allstmts.forEach((s,a)=>{this.curpc=a+1,this.compileStatement(s),s.command=="DATA"&&(this.label2dataptr[s.$loc.label]=this.datums.length,s.datums.forEach(h=>{this.curpc=s.$loc.offset,this.datums.push(h)}))}),this.label2pc[r]!=null?(this.curpc=this.label2pc[r]+e,!0):(this.curpc=0,!1)}reset(){this.curpc=0,this.dataptr=0,this.clearVars(),this.returnStack=[],this.column=0,this.running=!0,this.exited=!1}clearVars(){this.globals=this.vars={},this.arrays={},this.defs={},this.forLoops={},this.forLoopStack=[],this.whileLoops=[],this.rng=new m,this.opts&&this.opts.staticArrays&&this.allstmts.filter(t=>t.command=="DIM").forEach(t=>{t.args.forEach(r=>this.compileJS(this._DIM(r))())})}saveState(){return $.extend(!0,{},this)}loadState(t){$.extend(!0,this,t)}getBuiltinFunctions(){var t=this.program&&this.opts.validFunctions;t||(t=Object.getOwnPropertyNames(u.prototype).filter(i=>/^[A-Z]{3,}[$]?$/.test(i)));var r={};for(var e of t)this.supportsFunction(e)&&(r[e]=this[e].bind(this));return r}supportsFunction(t){return typeof this[t]=="function"}runtimeError(t){throw this.curpc--,new d(t,this.getCurrentSourceLocation())}dialectError(t){this.runtimeError(`I can't ${t} in this dialect of BASIC.`)}getLineForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.line}getLabelForPC(t){var r=this.allstmts[t];return r&&r.$loc&&r.$loc.label}getCurrentSourceLocation(){var t=this.getStatement();return t&&t.$loc}getCurrentLabel(){var t=this.getCurrentSourceLocation();return t&&t.label}getStatement(){return this.allstmts[this.curpc]}step(){if(!this.running)return!1;var t=this.getStatement();return t?(this.trace&&console.log(this.curpc,t,this.vars,Object.keys(this.arrays)),this.curpc++,this.executeStatement(t),this.running):(this.running=!1,this.exited=!0,!1)}compileStatement(t){if(t.$run==null)try{var r=this["do__"+t.command];r==null&&this.runtimeError(`I don't know how to "${t.command}".`);var e=r.bind(this)(t);this.trace&&console.log(e),t.$run=this.compileJS(e)}catch(i){throw e&&console.log(e),i}}compileJS(t){return new Function(t).bind(this)}executeStatement(t){this.compileStatement(t),t.$run()}skipToEOL(){do this.curpc++;while(this.curpc<this.allstmts.length&&!this.pc2label.get(this.curpc))}skipToElse(){for(;this.curpc<this.allstmts.length;){var t=this.allstmts[this.curpc].command;if(t=="ELSE"){this.curpc++;break}else if(t=="IF")return this.skipToEOL();if(this.curpc++,this.pc2label.get(this.curpc))break}}skipToEOF(){this.curpc=this.allstmts.length}skipToAfterNext(t){for(var r=this.curpc;r<this.allstmts.length;){var e=this.allstmts[r];if(e.command=="NEXT"){var i=e.lexpr;if(i&&i.name==t){this.curpc=r+1;return}}r++}this.runtimeError(`I couldn't find a matching NEXT ${t} to skip this for loop.`)}skipToAfterWend(){for(var t=this.curpc-1,r=0;t<this.allstmts.length;){var e=this.allstmts[t];if(e.command=="WHILE")r++;else if(e.command=="WEND"&&(r--,r==0)){this.curpc=t+1;return}t++}this.runtimeError("I couldn't find a matching WEND for this WHILE.")}gotoLabel(t){var r=this.label2pc[t];r>=0?this.curpc=r:this.runtimeError(`I tried to go to the label "${t}" but couldn't find it.`)}newLocalScope(){this.vars=Object.create(this.vars)}popLocalScope(){this.vars!==this.globals&&(this.vars=Object.getPrototypeOf(this.vars))}gosubLabel(t){this.returnStack.length>32767&&this.runtimeError("I did too many GOSUBs without a RETURN."),this.returnStack.push(this.curpc),this.gotoLabel(t)}returnFromGosub(){this.returnLine truncated
`)this.column=0,e=t;else if(t==" "){var n=this.opts.printZoneLength,s=Math.floor(this.column/n),a=(s+1)*this.opts.printZoneLength;a+n>this.margin?(this.column=0,e=`
`):e=this.TAB(a)}else e=`${t}`;return e}float2str(t,r){var e=t.toString().toUpperCase();if(r>0){for(var i=r;e.length>r;)e=t.toPrecision(i--);e.startsWith("0.")?e=e.substr(1):e.startsWith("-0.")&&(e="-"+e.substr(2))}return e}printExpr(t){var r=this.valueToString(t,this.opts.numericPadding);this.column+=r.length,this.print(r)}print(t){console.log(t)}async input(t,r){return{line:"",vals:[]}}resume(){}expr2js(t,r){if(r||(r={}),O(t))return JSON.stringify(t.value);if(k(t)){if(!t.args&&r.locals&&r.locals.indexOf(t.name)>=0)return t.name;{r.isconst&&this.runtimeError("I expected a constant value here.");var e="",i=JSON.stringify(t.name);let h=t.args?t.args.map(o=>this.expr2js(o,r)).join(", "):[];return t.name.startsWith("FN")?e+=`this.getDef(${i})(${h})`:this.builtins[t.name]?(this.checkFuncArgs(t,this.builtins[t.name]),e+=`this.builtins.${t.name}(${h})`):t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?e+=`this.getStringSlice(this.vars.${t.name}, ${h})`:e+=`this.arrayGet(${i}, ${h})`:e+=`this.vars.${t.name}`,r.novalid?e:`this.checkValue(${e}, ${i})`}}else if(N(t)){var n=this.expr2js(t.left,r),s=this.expr2js(t.right,r);return`this.${t.op}(${n}, ${s})`}else if(I(t)){var a=this.expr2js(t.expr,r);return`this.${t.op}(${a})`}}assign2js(t,r){r||(r={});var e="";return(t.name.startsWith("FN")||this.builtins[t.name])&&this.runtimeError("I can't call a function here."),t.args?this.opts.arraysContainChars&&t.name.endsWith("$")?this.runtimeError("I can't set array slices via this command yet."):e+=this.array2js(t,r):e=`this.globals.${t.name}`,e}array2js(t,r){var e=JSON.stringify(t.name),i=t.args||[];return this.expr2js(t,{novalid:!0})+`;this.getArray(${e}, ${i.length})`+i.map(n=>"[this.ROUND("+this.expr2js(n,r)+")]").join("")}checkFuncArgs(t,r){var e=t.args?t.args.length:0;t.name=="RND"&&e==0||t.name=="MID$"&&e==2||t.name=="INSTR"&&e==2||r.length!=e&&this.runtimeError(`I expected ${r.length} arguments for the ${t.name} function, but I got ${e}.`)}startForLoop(t,r,e,i,n){var s=this.curpc-1,a=this.pc2label.get(s);i||(i=1),this.vars[t]=r,this.trace&&console.log(`FOR ${t} = ${r} TO ${e} STEP ${i}`);var h=()=>i>=0?this.vars[t]>e:this.vars[t]<e;this.opts.testInitialFor&&h()&&(n!=null?this.curpc=n+1:this.skipToAfterNext(t)),this.forLoopStack[t]!=null&&(this.forLoopStack=this.forLoopStack.filter(o=>o==t)),this.forLoopStack.push(t),this.forLoops[t]={$next:o=>{o&&t!=o&&this.runtimeError(`I executed NEXT "${o}", but the last FOR was for "${t}".`),this.vars[t]+=i;var b=h();b?(this.forLoopStack.pop(),delete this.forLoops[t]):this.curpc=(a!=null&&this.label2pc[a]||s)+1,this.trace&&console.log(`NEXT ${t}: ${this.vars[t]} TO ${e} STEP ${i} DONE=${b}`)}}}nextForLoop(t){var r=this.forLoops[t||this.opts.optionalNextVar&&this.forLoopStack[this.forLoopStack.length-1]];r||this.runtimeError("I couldn't find a matching FOR for this NEXT."),r.$next(t)}whileLoop(t){t?this.whileLoops.push(this.curpc-1):this.skipToAfterWend()}nextWhileLoop(){var t=this.whileLoops.pop();t==null?this.runtimeError("I couldn't find a matching WHILE for this WEND."):this.curpc=t}assign(t,r,e){return e&&t.endsWith("$")?this.checkValue(this.convert(t,r),t):t.endsWith("$")?this.convertToString(r,t):this.convertToNumber(r,t)}convert(t,r){return t.endsWith("$")?r==null?"":r.toString():typeof r=="number"?r:parseFloat(r+"")}convertToString(t,r){if(typeof t!="string")this.runtimeError(`I can't convert ${t} to a string.`);else return t}convertToNumber(t,r){if(typeof t!="number")this.runtimeError(`I can't convert ${t} to a number.`);else return this.checkNum(t)}dimArray(t,...r){if(r=r.map(Math.round),this.arrays[t]!=null){if(this.opts.staticArrays)return;this.runtimeError(`I already dimensioned this array (${t}) earlier.`)}var e=this.getTotalArrayLength(r);e>this.opts.maxArrayElements&&this.runtimeError("I can't create an array with this many elements.");var i=t.endsWith("$"),n=i?Array:Float64Array;if(r.length==1)this.arrays[t]=new n(r[0]+1);else if(r.length==2){this.arrays[t]=new Array(r[0]+1);for(var s=0;s<r[0]+1;s++)this.arrays[t][s]=new n(r[1]+1)}else this.runtimeError("I only support arrays of one or two dimensions.")}getTotalArrayLength(t){for(var r=1,e=0;e<t.length;e++)t[e]<this.opts.defaultArrayBase&&this.runtimeError(`I can't create an array with a dimension less than ${this.opts.defaultArrayBase}.`),r*=t[e];return r}getArray(t,r){return this.arrays[t]||(this.opts.defaultArraySize==0&&this.dialectError("automatically declare arrays without a DIM statement (or did you mean to call a function?)"),r==1?this.dimArray(t,this.opts.defaultArraySize-1):r==2?this.dimArray(t,this.opts.defaultArraySize-1,this.opts.defaultArraySize-1):this.runtimeError("I only support arrays of one or two dimensions.")),this.arrays[t]}arrayGet(t,...r){var e=this.getArray(t,r.length);r=r.map(this.ROUND.bind(this));for(var i=e,n=0;n<r.length;n++){var s=r[n];c(i)||this.runtimeError(`I tried to lookup ${t}(${r}) but used too many dimensions.`),s<this.opts.defaultArrayBase&&this.runtimeError(`I triedLine truncated
var value = this.convert(${JSON.stringify(n.name)}, response.vals[${s}]);
@@ -34,4 +34,4 @@ import{b as E}from"./chunk-3FIVEUG2.js";import{a as S,t as y}from"./chunk-IBRDAY
`),this.tty.addtext("*** END OF PROGRAM ***",1),this.tty.showPrintHead(!1)}loadROM(t,r){var e=this.runtime.exited;this.program=r;var i=this.runtime.load(r);this.tty.uppercaseOnly=!0,S.input=this.program.opts.uppercaseOnly?n=>n.toUpperCase():null,(!this.hotReload||e||!i)&&this.reset()}getROMExtension(){return".json"}reset(){this.tty.clear(),this.runtime.reset(),this.clock=0,this.transcript=[]}pause(){this.timer.stop()}resume(){this.isBlocked()||(this.animcount=0,this.timer.start())}isBlocked(){return this.tty.waitingfor!=null||this.runtime.exited}isRunning(){return this.timer.isRunning()}getDefaultExtensions(){return[".bas"]}getToolForFilename(){return"basic"}getPresets(){return T}getPC(){return this.runtime.curpc}getSP(){return 4096-this.runtime.returnStack.length}isStable(){return!0}getCPUState(){return{PC:this.getPC(),SP:this.getSP()}}saveState(){return{c:this.getCPUState(),rt:this.runtime.saveState()}}loadState(t){this.runtime.loadState(t)}getDebugTree(){return{CurrentLine:this.runtime.getCurrentLabel(),Variables:this.runtime.vars,Arrays:this.runtime.arrays,Functions:this.runtime.defs,ForLoops:this.runtime.forLoops,WhileLoops:this.runtime.whileLoops,ReturnStack:this.runtime.returnStack,NextDatum:this.runtime.datums[this.runtime.dataptr],Clock:this.clock,Options:this.runtime.opts,Internals:this.runtime}}inspect(t){let r=this.runtime.vars[t];if(r!=null)return`${t} = ${r}`}showHelp(){return"https://8bitworkshop.com/docs/platforms/basic/"}getDebugCategories(){return["Variables"]}getDebugInfo(t,r){switch(t){case"Variables":return this.varsToLongString()}}varsToLongString(){var t="",r=Object.keys(this.runtime.vars);r.sort();for(var e of r){var i=this.runtime.vars[e],n=JSON.stringify(i);n.length>24&&(n=`${n.substr(0,24)}...(${n.length})`),t+=g(e,3)+" = "+n+`
`}return t}setupDebug(t){this.onBreakpointHit=t}clearDebug(){this.onBreakpointHit=null,this.debugTrap=null}checkDebugTrap(){return this.debugTrap&&this.debugTrap()?(this.pause(),this.break(),!0):!1}break(){this.onBreakpointHit&&this.onBreakpointHit(this.saveState())}step(){var t=this.clock;this.debugTrap=()=>this.clock>t,this.resume()}stepOver(){var t=this.runtime.getStatement();if(t&&(t.command=="GOSUB"||t.command=="ONGOSUB")){var r=this.getPC()+1;this.runEval(()=>this.getPC()==r)}else this.step()}runUntilReturn(){var t=this.getSP();this.runEval(()=>this.getSP()>t)}runEval(t){this.debugTrap=()=>t(this.getCPUState()),this.resume()}restartAtPC(t){return t=Math.round(t),t>=0&&t<this.runtime.allstmts.length?(this.runtime.curpc=t,this.tty.cancelinput(),this.clock=0,!0):!1}readFile(t){return this.internalFiles[t]}writeFile(t,r){return this.internalFiles[t]=r,!0}didExit(){this.internalFiles["stdout.txt"]=this.transcript.join(""),y()}};f.basic=p;
//# sourceMappingURL=basic-6XAR7ABN.js.map
//# sourceMappingURL=basic-Z6JCRUQB.js.map
File renamed without changes.
+17
View File
@@ -0,0 +1,17 @@
import{H as R,q as D}from"./chunk-GTDJ7CMC.js";import{$ as P,K as S,W as n,aa as A,g as h,s as p}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var I=1,d=2,k=4,b=8,u=16,l=class{constructor(){this.PC0=0;this.PC1=0;this.DC0=0;this.DC1=0;this.A=0;this.W=0;this.IS=0;this.R=new Uint8Array(64);this.o=0;this.stable=!0;this.irqRequest=!1}connectMemoryBus(s){this.bus=s}connectIOBus(s){this.iobus=s}reset(){this.PC0=0,this.PC1=0,this.DC0=0,this.DC1=0,this.A=0,this.W=0,this.IS=0,this.R.fill(0),this.irqRequest=!1}interrupt(s){this.irqRequest=!0}getPC(){return this.PC0}getSP(){return this.PC1}isStable(){return this.stable}saveState(){return{PC:this.PC0,PC0:this.PC0,PC1:this.PC1,DC0:this.DC0,DC1:this.DC1,A:this.A,W:this.W,IS:this.IS,R:Array.from(this.R),o:this.o,irq:this.irqRequest}}loadState(s){var e;this.PC0=(e=s.PC0)!=null?e:s.PC,this.PC1=s.PC1,this.DC0=s.DC0,this.DC1=s.DC1,this.A=s.A,this.W=s.W,this.IS=s.IS;for(let r=0;r<64;r++)this.R[r]=s.R[r];this.o=s.o,this.irqRequest=s.irq}fetchPC0(){let s=this.bus.read(this.PC0);return this.PC0=this.PC0+1&65535,s}fetchDC0(){let s=this.bus.read(this.DC0);return this.DC0=this.DC0+1&65535,s}storeDC0(s){this.bus.write(this.DC0,s),this.DC0=this.DC0+1&65535}clrOZCS(){this.W&=~(b|k|d|I)}setSZ(s){(s&255)===0&&(this.W|=k),(s&128)===0&&(this.W|=I)}doAdd(s,e,r=0){let t=(s&255)+(e&255)+(r&1);return t&256&&(this.W|=d),((s^t)&(e^t)&128)!==0&&(this.W|=b),t&255}doAddDecimal(s,e){let r=(s&15)+(e&15),t=r>9?1:0;r=(s>>4)+(e>>4)+t;let i=r>9?1:0;this.clrOZCS();let x=this.doAdd(s,e);this.setSZ(x);let c=0;return i&&(c|=160),t&&(c|=10),c&&(this.clrOZCS(),x=this.doAdd(x,c),this.setSZ(x)),x}getScratchpadIndex(s){if(s<12)return s;if(s===12)return this.IS&63;if(s===13){let e=this.IS&63;return this.IS=this.IS&56|this.IS+1&7,e}if(s===14){let e=this.IS&63;return this.IS=this.IS&56|this.IS-1&7,e}return 0}advanceInsn(){if(this.irqRequest&&this.W&u)return this.irqRequest=!1,this.PC1=this.PC0,this.PC0=this.bus.read(4094)<<8|this.bus.read(4095),this.W&=~u,6;let s=this.fetchPC0();this.o=s,this.stable=!0;let e=4,r,t;switch(s){case 0:this.A=this.R[12];break;case 1:this.A=this.R[13];break;case 2:this.A=this.R[14];break;case 3:this.A=this.R[15];break;case 4:this.R[12]=this.A;break;case 5:this.R[13]=this.A;break;case 6:this.R[14]=this.A;break;case 7:this.R[15]=this.A;break;case 8:this.R[12]=this.PC1>>8&255,this.R[13]=this.PC1&255,e=8;break;case 9:this.PC1=this.R[12]<<8|this.R[13],e=8;break;case 10:this.A=this.IS&63;break;case 11:this.IS=this.A&63;break;case 12:this.PC1=this.PC0,this.PC0=this.R[12]<<8|this.R[13],e=8;break;case 13:this.PC0=this.R[14]<<8|this.R[15],e=8;break;case 14:this.R[14]=this.DC0>>8&255,this.R[15]=this.DC0&255,e=8;break;case 15:this.DC0=this.R[14]<<8|this.R[15],e=8;break;case 16:this.DC0=this.R[10]<<8|this.R[11],e=8;break;case 17:this.R[10]=this.DC0>>8&255,this.R[11]=this.DC0&255,e=8;break;case 18:this.A=this.A>>1&255,this.clrOZCS(),this.setSZ(this.A);break;case 19:this.A=this.A<<1&255,this.clrOZCS(),this.setSZ(this.A);break;case 20:this.A=this.A>>4&255,this.clrOZCS(),this.setSZ(this.A);break;case 21:this.A=this.A<<4&255,this.clrOZCS(),this.setSZ(this.A);break;case 22:this.A=this.fetchDC0(),e=6;break;case 23:this.storeDC0(this.A),e=6;break;case 24:this.A=~this.A&255,this.clrOZCS(),this.setSZ(this.A);break;case 25:r=this.W&d?1:0,this.clrOZCS(),this.A=this.doAdd(this.A,r),this.setSZ(this.A);break;case 26:this.W&=~u;break;case 27:this.W|=u;break;case 28:this.PC0=this.PC1;break;case 29:this.W=this.R[9]&31;break;case 30:this.R[9]=this.W&31;break;case 31:this.clrOZCS(),this.A=this.doAdd(this.A,1),this.setSZ(this.A);break;case 32:this.A=this.fetchPC0(),e=6;break;case 33:r=this.fetchPC0(),this.A=this.A&r,this.clrOZCS(),this.setSZ(this.A),e=6;break;case 34:r=this.fetchPC0(),this.A=this.A|r,this.clrOZCS(),this.setSZ(this.A),e=6;break;case 35:r=this.fetchPC0(),this.A=this.A^r,this.clrOZCS(),this.setSZ(this.A),e=6;break;case 36:r=this.fetchPC0(),this.clrOZCS(),this.A=this.doAdd(this.A,r),this.setSZ(this.A),e=6;break;case 37:r=this.fetchPC0(),this.clrOZCS(),this.doAdd(~this.A&255,r,1),this.setSZ(this.doAdd(~this.A&255,r,1)),e=6;break;case 38:r=this.fetchPC0(),this.A=this.iobus.read(r)&255,this.clrOZCS(),this.setSZ(this.A),e=8;break;case 39:r=this.fetchPC0(),this.iobus.write(r,this.A),e=8;break;case 40:{let i=this.fetchPC0(),x=this.fetchPC0();this.PC1=this.PC0,this.PC0=i<<8|x,e=12;break}case 41:{let i=this.fetchPC0(),x=this.fetchPC0();this.PC0=i<<8|x,e=10;break}case 42:{let i=this.fetchPC0(),x=this.fetchPC0();this.DC0=i<<8|x,e=10;break}case 43:break;case 44:r=this.DC0,this.DC0=this.DC1,this.DC1=r;break;case 45:case 46:case 47:break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 58:case 59:case 60:case 61:case 62:t=this.getScratchpadIndex(s&15),this.clrOZCS(),this.R[t]=this.doAdd(this.R[t],255),this.setSZ(this.R[t]),e=6;break;case 63:break;case 64:case 65:case 66:case 67:case 68:case 69:case 70:case 71:case 72:case 73:case 74:case 75:case 76:case 77:case 78:t=this.getScraLine truncated
DC0 = `+h(a.DC0,4)+" DC1 = "+h(a.DC1,4)+`
A = `+h(a.A,2)+" W = "+h(a.W,2)+`
IS = `+h(a.IS,2)+`
`+p(a.W,["S","C","Z","O","I"],!0)+`
R0-R3: `+a.R.slice(0,4).map(s=>h(s,2)).join(" ")+`
R4-R7: `+a.R.slice(4,8).map(s=>h(s,2)).join(" ")+`
R8/J/H: `+a.R.slice(8,12).map(s=>h(s,2)).join(" ")+`
K/Q: `+a.R.slice(12,16).map(s=>h(s,2)).join(" ")+`
`}var m=class extends R{newMachine(){return new C}getPresets(){return W}getDefaultExtensions(){return[".dasm"]}getToolForFilename(s){return s.endsWith(".c")?"cc65":s.endsWith(".s")||s.endsWith(".ca65")?"ca65":"dasm"}readAddress(s){return this.machine.readConst(s)}disassemble(s,e){return w(s,e(s),e(s+1),e(s+2))}getDebugCategories(){return["CPU","I/O","VRAM"]}getDebugInfo(s,e){switch(s){case"CPU":return U(e.c);case"I/O":return"Port 0: "+h(e.port0||0,2)+`
Port 1: `+h(e.port1||0,2)+`
Port 4: `+h(e.port4||0,2)+`
Port 5: `+h(e.port5||0,2)+`
Row: `+h(e.row_reg||0,2)+`
Col: `+h(e.col_reg||0,2)+`
`;case"VRAM":return"";default:return""}}getMemoryMap(){return{main:[{name:"BIOS",start:0,size:2048,type:"rom"},{name:"Cart ROM",start:2048,size:30720,type:"rom"}]}}};S.channelf=m;
//# sourceMappingURL=channelf-RLYU47L6.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/common/cpu/F8.ts", "../src/machine/channelf.ts", "../src/common/cpu/disasmF8.ts", "../src/platform/channelf.ts"],
"sourcesContent": ["// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp\n// license:BSD-3-Clause\n// copyright-holders:Juergen Buchmueller\n// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp\n// license:GPL-2.0+\n// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle\n\nimport { Bus, CPU, InstructionBased, SavesState, Interruptable, MemoryBusConnected } from \"../devices\";\n\nexport interface F8State {\n PC: number; // alias for PC0 (required by CpuState)\n PC0: number; // program counter\n PC1: number; // saved program counter (stack)\n DC0: number; // data counter\n DC1: number; // alternate data counter\n A: number; // accumulator\n W: number; // status register (flags)\n IS: number; // indirect scratchpad address register (6-bit)\n R: number[]; // 64-byte scratchpad RAM\n o: number; // last opcode\n irq: boolean;\n}\n\n// Status register flag bits\nconst FLAG_S = 0x01; // Sign (complementary: set when positive)\nconst FLAG_C = 0x02; // Carry\nconst FLAG_Z = 0x04; // Zero\nconst FLAG_O = 0x08; // Overflow\nconst FLAG_I = 0x10; // Interrupt Control Bit\n\nexport class F8CPU implements CPU, InstructionBased, SavesState<F8State>, Interruptable<number>, MemoryBusConnected {\n\n // Registers\n PC0: number = 0; // active program counter\n PC1: number = 0; // saved program counter\n DC0: number = 0; // active data counter\n DC1: number = 0; // alternate data counter\n A: number = 0; // accumulator\n W: number = 0; // status/flags\n IS: number = 0; // indirect scratchpad address (6-bit)\n R: Uint8Array = new Uint8Array(64); // scratchpad RAM\n\n bus: Bus;\n iobus: Bus;\n o: number = 0; // last opcode\n stable: boolean = true;\n irqRequest: boolean = false;\n\n connectMemoryBus(bus: Bus): void {\n this.bus = bus;\n }\n connectIOBus(bus: Bus): void {\n this.iobus = bus;\n }\n\n reset(): void {\n this.PC0 = 0;\n this.PC1 = 0;\n this.DC0 = 0;\n this.DC1 = 0;\n this.A = 0;\n this.W = 0;\n this.IS = 0;\n this.R.fill(0);\n this.irqRequest = false;\n }\n\n interrupt(type: number): void {\n this.irqRequest = true;\n }\n\n getPC(): number { return this.PC0; }\n getSP(): number { return this.PC1; }\n isStable(): boolean { return this.stable; }\n\n saveState(): F8State {\n return {\n PC: this.PC0,\n PC0: this.PC0,\n PC1: this.PC1,\n DC0: this.DC0,\n DC1: this.DC1,\n A: this.A,\n W: this.W,\n IS: this.IS,\n R: Array.from(this.R),\n o: this.o,\n irq: this.irqRequest,\n };\n }\n\n loadState(state: F8State): void {\n this.PC0 = state.PC0 ?? state.PC;\n this.PC1 = state.PC1;\n this.DC0 = state.DC0;\n this.DC1 = state.DC1;\n this.A = state.A;\n this.W = state.W;\n this.IS = state.IS;\n for (let i = 0; i < 64; i++) this.R[i] = state.R[i];\n this.o = state.o;\n this.irqRequest = state.irq;\n }\n\n // Read byte at PC0, increment PC0\n private fetchPC0(): number {\n const val = this.bus.read(this.PC0);\n this.PC0 = (this.PC0 + 1) & 0xFFFF;\n return val;\n }\n\n // Read byte at DC0, increment DC0\n private fetchDC0(): number {\n const val = this.bus.read(this.DC0);\n this.DC0 = (this.DC0 + 1) & 0xFFFF;\n return val;\n }\n\n // Write byte at DC0, increment DC0\n private storeDC0(val: number): void {\n this.bus.write(this.DC0, val);\n this.DC0 = (this.DC0 + 1) & 0xFFFF;\n }\n\n // Clear O, Z, C, S flags\n private clrOZCS(): void {\n this.W &= ~(FLAG_O | FLAG_Z | FLAG_C | FLAG_S);\n }\n\n // Set Sign and Zero flags from value\n // Note: F8 sign flag is COMPLEMENTARY - set when bit 7 is CLEAR (positive)\n private setSZ(val: number): void {\n if ((val & 0xFF) === 0) this.W |= FLAG_Z;\n if ((val & 0x80) === 0) this.W |= FLAG_S; // complementary sign\n }\n\n // Addition with carry/overflow detection\n private doAdd(a: number, b: number, carry: number = 0): number {\n const result = (a & 0xFF) + (b & 0xFF) + (carry & 1);\n // Set carry if overflow past 8 bits\n if (result & 0x100) this.W |= FLAG_C;\n // Set overflow using XOR method\n if (((a ^ result) & (b ^ result) & 0x80) !== 0) this.W |= FLAG_O;\n return result & 0xFF;\n }\n\n // BCD addition\n private doAddDecimal(augend: number, addend: number): number {\n let tmp = (augend & 0x0F) + (addend & 0x0F);\n let c1 = (tmp > 9) ? 1 : 0;\n tmp = (augend >> 4) + (addend >> 4) + c1;\n let c2 = (tmp > 9) ? 1 : 0;\n\n // Do binary add for flags\n this.clrOZCS();\n let result = this.doAdd(augend, addend);\n this.setSZ(result);\n\n // Apply BCD correction\n let correction = 0;\n if (c2) correction |= 0xA0;\n if (c1) correction |= 0x0A;\n if (correction) {\n this.clrOZCS();\n result = this.doAdd(result, correction);\n this.setSZ(result);\n }\n return resulLine truncated
"mappings": "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 truncated
"names": ["FLAG_S", "FLAG_C", "FLAG_Z", "FLAG_O", "FLAG_I", "F8CPU", "bus", "type", "state", "_a", "i", "val", "a", "b", "carry", "result", "augend", "addend", "tmp", "c1", "c2", "correction", "r", "idx", "opcode", "cycles", "hi", "lo", "mask", "offset", "cmp", "CHANNELF_COLORMAP", "INPUT_RIGHT", "INPUT_LEFT", "INPUT_BACK", "INPUT_FORWARD", "INPUT_CCW", "INPUT_CW", "INPUT_PULL", "INPUT_PUSH", "ChannelF", "BasicMachine", "F8CPU", "newAddressDecoder", "a", "v", "port", "val", "row", "col", "color", "addr", "data", "padBytes", "trap", "clock", "targetClocks", "y", "palOffset", "p125", "p126", "rgba", "cycles", "samplesPerFrame", "i", "sample", "freq", "period", "key", "code", "flags", "pressed", "released", "Keys", "state", "regName", "r", "disassembleF8", "pc", "b0", "b1", "b2", "mn", "args", "nb", "isaddr", "regs", "hex", "offset", "mask", "CHANNELF_PRESETS", "cpuStateToLongString_F8", "c", "hex", "printFlags", "v", "ChannelFPlatform", "BaseMachinePlatform", "ChannelF", "fn", "a", "pc", "read", "disassembleF8", "category", "state", "PLATFORMS"]
}
@@ -1,4 +1,4 @@
import{a as lc,b as ko,c as pw}from"./chunk-JSIZCY7X.js";import{a as $g}from"./chunk-LNOKARBD.js";import{a as wg,b as Pg,c as mw}from"./chunk-R5KWJQBC.js";import{D as Qu,J as yu,t as xg,u as vg}from"./chunk-GTDJ7CMC.js";import{A as Zs,E as hr,F as gu,G as Po,I as oc,J as Sg,K as bu,T as Su,V as Qg,a as ln,b as ma,ba as ac,ca as yg,d as ai,da as ba,e as mu,f as li,g as ut,k as pg,m as tc,n as ic,o as rc,p as Es,q as mg,t as nc,w as gg,x as bg,y as sc,z as Qi}from"./chunk-MZ4MJULD.js";import{a as zi,b as ec,c as pa,d as du,e as pu}from"./chunk-KT7KMEQC.js";var vu=du((kg,xu)=>{(function(i){if(typeof kg=="object"&&typeof xu!="undefined")xu.exports=i();else if(typeof define=="function"&&define.amd)define([],i);else{var e;typeof window!="undefined"?e=window:typeof global!="undefined"?e=global:typeof self!="undefined"?e=self:e=this,e.localforage=i()}})(function(){var i,e,t;return(function r(n,s,o){function a(h,O){if(!s[h]){if(!n[h]){var m=typeof pa=="function"&&pa;if(!O&&m)return m(h,!0);if(l)return l(h,!0);var b=new Error("Cannot find module '"+h+"'");throw b.code="MODULE_NOT_FOUND",b}var y=s[h]={exports:{}};n[h][0].call(y.exports,function(P){var X=n[h][1][P];return a(X||P)},y,y.exports,r,n,s,o)}return s[h].exports}for(var l=typeof pa=="function"&&pa,f=0;f<o.length;f++)a(o[f]);return a})({1:[function(r,n,s){(function(o){"use strict";var a=o.MutationObserver||o.WebKitMutationObserver,l;if(a){var f=0,h=new a(P),O=o.document.createTextNode("");h.observe(O,{characterData:!0}),l=function(){O.data=f=++f%2}}else if(!o.setImmediate&&typeof o.MessageChannel!="undefined"){var m=new o.MessageChannel;m.port1.onmessage=P,l=function(){m.port2.postMessage(0)}}else"document"in o&&"onreadystatechange"in o.document.createElement("script")?l=function(){var Y=o.document.createElement("script");Y.onreadystatechange=function(){P(),Y.onreadystatechange=null,Y.parentNode.removeChild(Y),Y=null},o.document.documentElement.appendChild(Y)}:l=function(){setTimeout(P,0)};var b,y=[];function P(){b=!0;for(var Y,G,q=y.length;q;){for(G=y,y=[],Y=-1;++Y<q;)G[Y]();q=y.length}b=!1}n.exports=X;function X(Y){y.push(Y)===1&&!b&&l()}}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],2:[function(r,n,s){"use strict";var o=r(1);function a(){}var l={},f=["REJECTED"],h=["FULFILLED"],O=["PENDING"];n.exports=m;function m(d){if(typeof d!="function")throw new TypeError("resolver must be a function");this.state=O,this.queue=[],this.outcome=void 0,d!==a&&X(this,d)}m.prototype.catch=function(d){return this.then(null,d)},m.prototype.then=function(d,j){if(typeof d!="function"&&this.state===h||typeof j!="function"&&this.state===f)return this;var H=new this.constructor(a);if(this.state!==O){var Oe=this.state===h?d:j;y(H,Oe,this.outcome)}else this.queue.push(new b(H,d,j));return H};function b(d,j,H){this.promise=d,typeof j=="function"&&(this.onFulfilled=j,this.callFulfilled=this.otherCallFulfilled),typeof H=="function"&&(this.onRejected=H,this.callRejected=this.otherCallRejected)}b.prototype.callFulfilled=function(d){l.resolve(this.promise,d)},b.prototype.otherCallFulfilled=function(d){y(this.promise,this.onFulfilled,d)},b.prototype.callRejected=function(d){l.reject(this.promise,d)},b.prototype.otherCallRejected=function(d){y(this.promise,this.onRejected,d)};function y(d,j,H){o(function(){var Oe;try{Oe=j(H)}catch(Ee){return l.reject(d,Ee)}Oe===d?l.reject(d,new TypeError("Cannot resolve promise with itself")):l.resolve(d,Oe)})}l.resolve=function(d,j){var H=Y(P,j);if(H.status==="error")return l.reject(d,H.value);var Oe=H.value;if(Oe)X(d,Oe);else{d.state=h,d.outcome=j;for(var Ee=-1,ge=d.queue.length;++Ee<ge;)d.queue[Ee].callFulfilled(j)}return d},l.reject=function(d,j){d.state=f,d.outcome=j;for(var H=-1,Oe=d.queue.length;++H<Oe;)d.queue[H].callRejected(j);return d};function P(d){var j=d&&d.then;if(d&&(typeof d=="object"||typeof d=="function")&&typeof j=="function")return function(){j.apply(d,arguments)}}function X(d,j){var H=!1;function Oe(ke){H||(H=!0,l.reject(d,ke))}function Ee(ke){H||(H=!0,l.resolve(d,ke))}function ge(){j(Ee,Oe)}var ie=Y(ge);ie.status==="error"&&Oe(ie.value)}function Y(d,j){var H={};try{H.value=d(j),H.status="success"}catch(Oe){H.status="error",H.value=Oe}return H}m.resolve=G;function G(d){return d instanceof this?d:l.resolve(new this(a),d)}m.reject=q;function q(d){var j=new this(a);return l.reject(j,d)}m.all=N;function N(d){var j=this;if(Object.prototype.toString.call(d)!=="[object Array]")return this.reject(new TypeError("must be an array"));var H=d.length,Oe=!1;if(!H)return this.resolve([]);for(var Ee=new Array(H),ge=0,ie=-1,ke=new this(a);++ie<H;)Ze(d[ie],ie);return ke;function Ze(Be,te){j.resolve(Be).then(ye,function(ce){Oe||(Oe=!0,l.reject(ke,ce))});function ye(ce){Ee[te]=ce,++ge===H&&!Oe&&(Oe=!0,l.resolve(ke,Ee))}}}m.race=V;function V(d){var j=this;if(Object.prototype.toString.call(d)!=="[object Array]")return this.reject(new TypeError("must be an array"));var H=d.length,Oe=!1;iLine truncated
import{a as lc,b as ko,c as pw}from"./chunk-JSIZCY7X.js";import{a as $g}from"./chunk-LNOKARBD.js";import{a as wg,b as Pg,c as mw}from"./chunk-7WOMNSMI.js";import{D as Qu,J as yu,t as xg,u as vg}from"./chunk-GTDJ7CMC.js";import{A as Zs,E as hr,F as gu,G as Po,I as oc,J as Sg,K as bu,T as Su,V as Qg,a as ln,b as ma,ba as ac,ca as yg,d as ai,da as ba,e as mu,f as li,g as ut,k as pg,m as tc,n as ic,o as rc,p as Es,q as mg,t as nc,w as gg,x as bg,y as sc,z as Qi}from"./chunk-MZ4MJULD.js";import{a as zi,b as ec,c as pa,d as du,e as pu}from"./chunk-KT7KMEQC.js";var vu=du((kg,xu)=>{(function(i){if(typeof kg=="object"&&typeof xu!="undefined")xu.exports=i();else if(typeof define=="function"&&define.amd)define([],i);else{var e;typeof window!="undefined"?e=window:typeof global!="undefined"?e=global:typeof self!="undefined"?e=self:e=this,e.localforage=i()}})(function(){var i,e,t;return(function r(n,s,o){function a(h,O){if(!s[h]){if(!n[h]){var m=typeof pa=="function"&&pa;if(!O&&m)return m(h,!0);if(l)return l(h,!0);var b=new Error("Cannot find module '"+h+"'");throw b.code="MODULE_NOT_FOUND",b}var y=s[h]={exports:{}};n[h][0].call(y.exports,function(P){var X=n[h][1][P];return a(X||P)},y,y.exports,r,n,s,o)}return s[h].exports}for(var l=typeof pa=="function"&&pa,f=0;f<o.length;f++)a(o[f]);return a})({1:[function(r,n,s){(function(o){"use strict";var a=o.MutationObserver||o.WebKitMutationObserver,l;if(a){var f=0,h=new a(P),O=o.document.createTextNode("");h.observe(O,{characterData:!0}),l=function(){O.data=f=++f%2}}else if(!o.setImmediate&&typeof o.MessageChannel!="undefined"){var m=new o.MessageChannel;m.port1.onmessage=P,l=function(){m.port2.postMessage(0)}}else"document"in o&&"onreadystatechange"in o.document.createElement("script")?l=function(){var Y=o.document.createElement("script");Y.onreadystatechange=function(){P(),Y.onreadystatechange=null,Y.parentNode.removeChild(Y),Y=null},o.document.documentElement.appendChild(Y)}:l=function(){setTimeout(P,0)};var b,y=[];function P(){b=!0;for(var Y,G,q=y.length;q;){for(G=y,y=[],Y=-1;++Y<q;)G[Y]();q=y.length}b=!1}n.exports=X;function X(Y){y.push(Y)===1&&!b&&l()}}).call(this,typeof global!="undefined"?global:typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{}],2:[function(r,n,s){"use strict";var o=r(1);function a(){}var l={},f=["REJECTED"],h=["FULFILLED"],O=["PENDING"];n.exports=m;function m(d){if(typeof d!="function")throw new TypeError("resolver must be a function");this.state=O,this.queue=[],this.outcome=void 0,d!==a&&X(this,d)}m.prototype.catch=function(d){return this.then(null,d)},m.prototype.then=function(d,j){if(typeof d!="function"&&this.state===h||typeof j!="function"&&this.state===f)return this;var H=new this.constructor(a);if(this.state!==O){var Oe=this.state===h?d:j;y(H,Oe,this.outcome)}else this.queue.push(new b(H,d,j));return H};function b(d,j,H){this.promise=d,typeof j=="function"&&(this.onFulfilled=j,this.callFulfilled=this.otherCallFulfilled),typeof H=="function"&&(this.onRejected=H,this.callRejected=this.otherCallRejected)}b.prototype.callFulfilled=function(d){l.resolve(this.promise,d)},b.prototype.otherCallFulfilled=function(d){y(this.promise,this.onFulfilled,d)},b.prototype.callRejected=function(d){l.reject(this.promise,d)},b.prototype.otherCallRejected=function(d){y(this.promise,this.onRejected,d)};function y(d,j,H){o(function(){var Oe;try{Oe=j(H)}catch(Ee){return l.reject(d,Ee)}Oe===d?l.reject(d,new TypeError("Cannot resolve promise with itself")):l.resolve(d,Oe)})}l.resolve=function(d,j){var H=Y(P,j);if(H.status==="error")return l.reject(d,H.value);var Oe=H.value;if(Oe)X(d,Oe);else{d.state=h,d.outcome=j;for(var Ee=-1,ge=d.queue.length;++Ee<ge;)d.queue[Ee].callFulfilled(j)}return d},l.reject=function(d,j){d.state=f,d.outcome=j;for(var H=-1,Oe=d.queue.length;++H<Oe;)d.queue[H].callRejected(j);return d};function P(d){var j=d&&d.then;if(d&&(typeof d=="object"||typeof d=="function")&&typeof j=="function")return function(){j.apply(d,arguments)}}function X(d,j){var H=!1;function Oe(ke){H||(H=!0,l.reject(d,ke))}function Ee(ke){H||(H=!0,l.resolve(d,ke))}function ge(){j(Ee,Oe)}var ie=Y(ge);ie.status==="error"&&Oe(ie.value)}function Y(d,j){var H={};try{H.value=d(j),H.status="success"}catch(Oe){H.status="error",H.value=Oe}return H}m.resolve=G;function G(d){return d instanceof this?d:l.resolve(new this(a),d)}m.reject=q;function q(d){var j=new this(a);return l.reject(j,d)}m.all=N;function N(d){var j=this;if(Object.prototype.toString.call(d)!=="[object Array]")return this.reject(new TypeError("must be an array"));var H=d.length,Oe=!1;if(!H)return this.resolve([]);for(var Ee=new Array(H),ge=0,ie=-1,ke=new this(a);++ie<H;)Ze(d[ie],ie);return ke;function Ze(Be,te){j.resolve(Be).then(ye,function(ce){Oe||(Oe=!0,l.reject(ke,ce))});function ye(ce){Ee[te]=ce,++ge===H&&!Oe&&(Oe=!0,l.resolve(ke,Ee))}}}m.race=V;function V(d){var j=this;if(Object.prototype.toString.call(d)!=="[object Array]")return this.reject(new TypeError("must be an array"));var H=d.length,Oe=!1;iLine truncated
`):c)),u};var eu=/^(?:focusinfocus|focusoutblur)$/,Gl=function(c){c.stopPropagation()};d.extend(d.event,{trigger:function(c,u,p,g){var S,Q,v,R,_,z,B,ee,W=[p||X],oe=h.call(c,"type")?c.type:c,Ve=h.call(c,"namespace")?c.namespace.split("."):[];if(Q=ee=v=p=p||X,!(p.nodeType===3||p.nodeType===8)&&!eu.test(oe+d.event.triggered)&&(oe.indexOf(".")>-1&&(Ve=oe.split("."),oe=Ve.shift(),Ve.sort()),_=oe.indexOf(":")<0&&"on"+oe,c=c[d.expando]?c:new d.Event(oe,typeof c=="object"&&c),c.isTrigger=g?2:3,c.namespace=Ve.join("."),c.rnamespace=c.namespace?new RegExp("(^|\\.)"+Ve.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,c.result=void 0,c.target||(c.target=p),u=u==null?[c]:d.makeArray(u,[c]),B=d.event.special[oe]||{},!(!g&&B.trigger&&B.trigger.apply(p,u)===!1))){if(!g&&!B.noBubble&&!P(p)){for(R=B.delegateType||oe,eu.test(R+oe)||(Q=Q.parentNode);Q;Q=Q.parentNode)W.push(Q),v=Q;v===(p.ownerDocument||X)&&W.push(v.defaultView||v.parentWindow||i)}for(S=0;(Q=W[S++])&&!c.isPropagationStopped();)ee=Q,c.type=S>1?R:B.bindType||oe,z=(we.get(Q,"events")||Object.create(null))[c.type]&&we.get(Q,"handle"),z&&z.apply(Q,u),z=_&&Q[_],z&&z.apply&&nr(Q)&&(c.result=z.apply(Q,u),c.result===!1&&c.preventDefault());return c.type=oe,!g&&!c.isDefaultPrevented()&&(!B._default||B._default.apply(W.pop(),u)===!1)&&nr(p)&&_&&y(p[oe])&&!P(p)&&(v=p[_],v&&(p[_]=null),d.event.triggered=oe,c.isPropagationStopped()&&ee.addEventListener(oe,Gl),p[oe](),c.isPropagationStopped()&&ee.removeEventListener(oe,Gl),d.event.triggered=void 0,v&&(p[_]=v)),c.result}},simulate:function(c,u,p){var g=d.extend(new d.Event,p,{type:c,isSimulated:!0});d.event.trigger(g,null,u)}}),d.fn.extend({trigger:function(c,u){return this.each(function(){d.event.trigger(c,u,this)})},triggerHandler:function(c,u){var p=this[0];if(p)return d.event.trigger(c,u,p,!0)}});var tu=/\[\]$/,fa=/\r?\n/g,N1=/^(?:submit|button|image|reset|file)$/i,B1=/^(?:input|select|textarea|keygen)/i;function iu(c,u,p,g){var S;if(Array.isArray(u))d.each(u,function(Q,v){p||tu.test(c)?g(c,v):iu(c+"["+(typeof v=="object"&&v!=null?Q:"")+"]",v,p,g)});else if(!p&&q(u)==="object")for(S in u)iu(c+"["+S+"]",u[S],p,g);else g(c,u)}d.param=function(c,u){var p,g=[],S=function(Q,v){var R=y(v)?v():v;g[g.length]=encodeURIComponent(Q)+"="+encodeURIComponent(R==null?"":R)};if(c==null)return"";if(Array.isArray(c)||c.jquery&&!d.isPlainObject(c))d.each(c,function(){S(this.name,this.value)});else for(p in c)iu(p,c[p],u,S);return g.join("&")},d.fn.extend({serialize:function(){return d.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var c=d.prop(this,"elements");return c?d.makeArray(c):this}).filter(function(){var c=this.type;return this.name&&!d(this).is(":disabled")&&B1.test(this.nodeName)&&!N1.test(c)&&(this.checked||!Wt.test(c))}).map(function(c,u){var p=d(this).val();return p==null?null:Array.isArray(p)?d.map(p,function(g){return{name:u.name,value:g.replace(fa,`\r
`)}}):{name:u.name,value:p.replace(fa,`\r
`)}}).get()}});var G1=/%20/g,F1=/#.*$/,H1=/([?&])_=[^&]*/,K1=/^(.*?):[ \t]*([^\r\n]*)$/mg,J1=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ew=/^(?:GET|HEAD)$/,tw=/^\/\//,ag={},ru={},lg="*/".concat("*"),nu=X.createElement("a");nu.href=vn.href;function cg(c){return function(u,p){typeof u!="string"&&(p=u,u="*");var g,S=0,Q=u.toLowerCase().match(Oi)||[];if(y(p))for(;g=Q[S++];)g[0]==="+"?(g=g.slice(1)||"*",(c[g]=c[g]||[]).unshift(p)):(c[g]=c[g]||[]).push(p)}}function fg(c,u,p,g){var S={},Q=c===ru;function v(R){var _;return S[R]=!0,d.each(c[R]||[],function(z,B){var ee=B(u,p,g);if(typeof ee=="string"&&!Q&&!S[ee])return u.dataTypes.unshift(ee),v(ee),!1;if(Q)return!(_=ee)}),_}return v(u.dataTypes[0])||!S["*"]&&v("*")}function su(c,u){var p,g,S=d.ajaxSettings.flatOptions||{};for(p in u)u[p]!==void 0&&((S[p]?c:g||(g={}))[p]=u[p]);return g&&d.extend(!0,c,g),c}function iw(c,u,p){for(var g,S,Q,v,R=c.contents,_=c.dataTypes;_[0]==="*";)_.shift(),g===void 0&&(g=c.mimeType||u.getResponseHeader("Content-Type"));if(g){for(S in R)if(R[S]&&R[S].test(g)){_.unshift(S);break}}if(_[0]in p)Q=_[0];else{for(S in p){if(!_[0]||c.converters[S+" "+_[0]]){Q=S;break}v||(v=S)}Q=Q||v}if(Q)return Q!==_[0]&&_.unshift(Q),p[Q]}function rw(c,u,p,g){var S,Q,v,R,_,z={},B=c.dataTypes.slice();if(B[1])for(v in c.converters)z[v.toLowerCase()]=c.converters[v];for(Q=B.shift();Q;)if(c.responseFields[Q]&&(p[c.responseFields[Q]]=u),!_&&g&&c.dataFilter&&(u=c.dataFilter(u,c.dataType)),_=Q,Q=B.shift(),Q){if(Q==="*")Q=_;else if(_!=="*"&&_!==Q){if(v=z[_+" "+Q]||z["* "+Q],!v){for(S in z)if(R=S.split(" "),R[1]===Q&&(v=z[_+" "+R[0]]||z["* "+R[0]],v)){v===!0?v=z[S]:z[S]!==!0&&(Q=R[0],B.unshift(R[1]));break}}if(v!==!0)if(v&&c.throws)u=v(u);else try{u=v(u)}catch(ee){return{state:"parsererror",error:v?ee:"No conversion from "+_+" to "+Q}}}}return{state:"success",data:u}}d.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:vn.href,type:"GET",isLocal:J1.test(vn.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":lg,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":d.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(c,u){return u?su(su(c,d.ajaxSettings),u):su(d.ajaxSettings,c)},ajaxPrefilter:cg(ag),ajaxTransport:cg(ru),ajax:function(c,u){typeof c=="object"&&(u=c,c=void 0),u=u||{};var p,g,S,Q,v,R,_,z,B,ee,W=d.ajaxSetup({},u),oe=W.context||W,Ve=W.context&&(oe.nodeType||oe.jquery)?d(oe):d.event,st=d.Deferred(),Ie=d.Callbacks("once memory"),Jt=W.statusCode||{},qt={},rn={},nn="canceled",et={readyState:0,getResponseHeader:function(ct){var Yt;if(_){if(!Q)for(Q={};Yt=K1.exec(S);)Q[Yt[1].toLowerCase()+" "]=(Q[Yt[1].toLowerCase()+" "]||[]).concat(Yt[2]);Yt=Q[ct.toLowerCase()+" "]}return Yt==null?null:Yt.join(", ")},getAllResponseHeaders:function(){return _?S:null},setRequestHeader:function(ct,Yt){return _==null&&(ct=rn[ct.toLowerCase()]=rn[ct.toLowerCase()]||ct,qt[ct]=Yt),this},overrideMimeType:function(ct){return _==null&&(W.mimeType=ct),this},statusCode:function(ct){var Yt;if(ct)if(_)et.always(ct[et.status]);else for(Yt in ct)Jt[Yt]=[Jt[Yt],ct[Yt]];return this},abort:function(ct){var Yt=ct||nn;return p&&p.abort(Yt),As(0,Yt),this}};if(st.promise(et),W.url=((c||W.url||vn.href)+"").replace(tw,vn.protocol+"//"),W.type=u.method||u.type||W.method||W.type,W.dataTypes=(W.dataType||"*").toLowerCase().match(Oi)||[""],W.crossDomain==null){R=X.createElement("a");try{R.href=W.url,R.href=R.href,W.crossDomain=nu.protocol+"//"+nu.host!=R.protocol+"//"+R.host}catch(ct){W.crossDomain=!0}}if(W.data&&W.processData&&typeof W.data!="string"&&(W.data=d.param(W.data,W.traditional)),fg(ag,W,u,et),_)return et;z=d.event&&W.global,z&&d.active++===0&&d.event.trigger("ajaxStart"),W.type=W.type.toUpperCase(),W.hasContent=!ew.test(W.type),g=W.url.replace(F1,""),W.hasContent?W.data&&W.processData&&(W.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&(W.data=W.data.replace(G1,"+")):(ee=W.url.slice(g.length),W.data&&(W.processData||typeof W.data=="string")&&(g+=(Cs.test(g)?"&":"?")+W.data,delete W.data),W.cache===!1&&(g=g.replace(H1,"$1"),ee=(Cs.test(g)?"&":"?")+"_="+Bl.guid+++ee),W.url=g+ee),W.ifModified&&(d.lastModified[g]&&et.setRequestHeader("If-Modified-Since",d.lastModified[g]),d.etag[g]&&et.setRequestHeader("If-None-Match",d.etag[g])),(W.data&&W.hasContent&&W.contentType!==!1||u.contentType)&&et.setRequestHeader("Content-Type",W.contentType),et.setRequestHeader("Accept",W.dataTypes[0]&&W.accepts[W.dataTypes[0]]?W.accepts[W.dataTypes[0]]+(W.dataTypes[0]!=="*"?", "+lg+"; q=0.01":""):W.accepts["*"]);for(B in W.headers)et.setRequestHeader(B,W.headers[B]);if(W.beforeSend&&(W.beforeSend.call(oe,et,W)===!1||_))return et.abort();if(nn="ab Line truncated
@@ -96,4 +96,4 @@ jquery/dist/jquery.js:
dompurify/dist/purify.cjs.js:
(*! @license DOMPurify 3.3.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.1/LICENSE *)
*/
//# sourceMappingURL=chunk-IBRDAYM2.js.map
//# sourceMappingURL=chunk-2DVTTN6M.js.map
File renamed without changes.
@@ -1,2 +1,2 @@
import{M as b,N as w}from"./chunk-MZ4MJULD.js";import{d as E}from"./chunk-KT7KMEQC.js";var y=E((d,v)=>{(function(l,e){typeof define=="function"&&define.amd?define([],e):typeof d!="undefined"?e():(e(),l.FileSaver={})})(d,function(){"use strict";function l(t,r){return typeof r=="undefined"?r={autoBom:!1}:typeof r!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),r={autoBom:!r}),r.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob(["\uFEFF",t],{type:t.type}):t}function e(t,r,c){var a=new XMLHttpRequest;a.open("GET",t),a.responseType="blob",a.onload=function(){h(a.response,r,c)},a.onerror=function(){console.error("could not download file")},a.send()}function n(t){var r=new XMLHttpRequest;r.open("HEAD",t,!1);try{r.send()}catch(c){}return 200<=r.status&&299>=r.status}function i(t){try{t.dispatchEvent(new MouseEvent("click"))}catch(c){var r=document.createEvent("MouseEvents");r.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),t.dispatchEvent(r)}}var o=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,u=o.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),h=o.saveAs||(typeof window!="object"||window!==o?function(){}:"download"in HTMLAnchorElement.prototype&&!u?function(t,r,c){var a=o.URL||o.webkitURL,s=document.createElement("a");r=r||t.name||"download",s.download=r,s.rel="noopener",typeof t=="string"?(s.href=t,s.origin===location.origin?i(s):n(s.href)?e(t,r,c):i(s,s.target="_blank")):(s.href=a.createObjectURL(t),setTimeout(function(){a.revokeObjectURL(s.href)},4e4),setTimeout(function(){i(s)},0))}:"msSaveOrOpenBlob"in navigator?function(t,r,c){if(r=r||t.name||"download",typeof t!="string")navigator.msSaveOrOpenBlob(l(t,c),r);else if(n(t))e(t,r,c);else{var a=document.createElement("a");a.href=t,a.target="_blank",setTimeout(function(){i(a)})}}:function(t,r,c,a){if(a=a||open("","_blank"),a&&(a.document.title=a.document.body.innerText="downloading..."),typeof t=="string")return e(t,r,c);var s=t.type==="application/octet-stream",C=/constructor/i.test(o.HTMLElement)||o.safari,S=/CriOS\/[\d]+/.test(navigator.userAgent);if((S||s&&C||u)&&typeof FileReader!="undefined"){var p=new FileReader;p.onloadend=function(){var m=p.result;m=S?m:m.replace(/^data:[^;]*;/,"data:attachment/file;"),a?a.location.href=m:location=m,a=null},p.readAsDataURL(t)}else{var k=o.URL||o.webkitURL,f=k.createObjectURL(t);a?a.location=f:location.href=f,a=null,setTimeout(function(){k.revokeObjectURL(f)},4e4)}});o.saveAs=h.saveAs=h,typeof v!="undefined"&&(v.exports=h)})});var g=class{constructor(e){this.checkpointInterval=10;this.maxCheckpoints=300;this.reset(),this.platform=e}reset(){this.checkpoints=[],this.framerecs=[],this.frameCount=0,this.lastSeekFrame=0,this.lastSeekStep=0,this.lastStepCount=0,this.callbackStateChanged&&this.callbackStateChanged()}frameRequested(){var e={controls:this.platform.saveControlsState(),seed:b()},n=!1;return this.lastSeekFrame<this.frameCount?this.loadControls(this.lastSeekFrame):(this.platform.saveControlsState&&this.framerecs.push(e),n=this.frameCount++%this.checkpointInterval==0),this.lastSeekFrame++,this.lastSeekStep=0,this.callbackStateChanged&&this.callbackStateChanged(),n}numFrames(){return this.frameCount}currentFrame(){return this.lastSeekFrame}currentStep(){return this.lastSeekStep}recordFrame(e){this.checkpoints.push(e),this.callbackNewCheckpoint&&this.callbackNewCheckpoint(e),this.checkpoints.length>this.maxCheckpoints&&(this.checkpoints.shift(),this.framerecs=this.framerecs.slice(this.checkpointInterval),this.lastSeekFrame-=this.checkpointInterval,this.frameCount-=this.checkpointInterval,this.callbackStateChanged&&this.callbackStateChanged())}getStateAtOrBefore(e){if(e<=0&&this.checkpoints.length>0)return{frame:0,state:this.checkpoints[0]};var n=Math.floor(e/this.checkpointInterval),i=n<this.checkpoints.length?n:this.checkpoints.length-1,o=i*this.checkpointInterval;return{frame:o,state:this.checkpoints[i]}}loadFrame(e,n){if(e|=0,n|=0,e==this.lastSeekFrame&&n==this.lastSeekStep)return e;let{frame:i,state:o}=this.getStateAtOrBefore(e-1);if(o){var u=0;for(this.platform.pause(),this.platform.loadState(o);i<e;)i<this.framerecs.length&&this.loadControls(i),i++,u=this.platform.advance(i<e);return i==0&&(u=this.platform.advance(!0),this.platform.loadState(o)),n>0&&this.platform.advanceFrameClock&&(n=this.platform.advanceFrameClock(null,n)),this.lastSeekFrame=e,this.lastSeekStep=n,this.lastStepCount=u,e}else return-1}loadControls(e){this.platform.loadControlsState&&this.platform.loadControlsState(this.framerecs[e].controls),w(this.framerecs[e].seed)}getLastCheckpoint(){return this.checkpoints.length&&this.checkpoints[this.checkpoints.length-1]}};function R(l){switch(l){case"apple2":return import("./apple2-FRA6FPGL.js");case"arm32"Line truncated
//# sourceMappingURL=chunk-R5KWJQBC.js.map
import{M as b,N as w}from"./chunk-MZ4MJULD.js";import{d as E}from"./chunk-KT7KMEQC.js";var y=E((d,v)=>{(function(l,e){typeof define=="function"&&define.amd?define([],e):typeof d!="undefined"?e():(e(),l.FileSaver={})})(d,function(){"use strict";function l(t,r){return typeof r=="undefined"?r={autoBom:!1}:typeof r!="object"&&(console.warn("Deprecated: Expected third argument to be a object"),r={autoBom:!r}),r.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob(["\uFEFF",t],{type:t.type}):t}function e(t,r,c){var a=new XMLHttpRequest;a.open("GET",t),a.responseType="blob",a.onload=function(){h(a.response,r,c)},a.onerror=function(){console.error("could not download file")},a.send()}function n(t){var r=new XMLHttpRequest;r.open("HEAD",t,!1);try{r.send()}catch(c){}return 200<=r.status&&299>=r.status}function i(t){try{t.dispatchEvent(new MouseEvent("click"))}catch(c){var r=document.createEvent("MouseEvents");r.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),t.dispatchEvent(r)}}var o=typeof window=="object"&&window.window===window?window:typeof self=="object"&&self.self===self?self:typeof global=="object"&&global.global===global?global:void 0,u=o.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),h=o.saveAs||(typeof window!="object"||window!==o?function(){}:"download"in HTMLAnchorElement.prototype&&!u?function(t,r,c){var a=o.URL||o.webkitURL,s=document.createElement("a");r=r||t.name||"download",s.download=r,s.rel="noopener",typeof t=="string"?(s.href=t,s.origin===location.origin?i(s):n(s.href)?e(t,r,c):i(s,s.target="_blank")):(s.href=a.createObjectURL(t),setTimeout(function(){a.revokeObjectURL(s.href)},4e4),setTimeout(function(){i(s)},0))}:"msSaveOrOpenBlob"in navigator?function(t,r,c){if(r=r||t.name||"download",typeof t!="string")navigator.msSaveOrOpenBlob(l(t,c),r);else if(n(t))e(t,r,c);else{var a=document.createElement("a");a.href=t,a.target="_blank",setTimeout(function(){i(a)})}}:function(t,r,c,a){if(a=a||open("","_blank"),a&&(a.document.title=a.document.body.innerText="downloading..."),typeof t=="string")return e(t,r,c);var s=t.type==="application/octet-stream",C=/constructor/i.test(o.HTMLElement)||o.safari,S=/CriOS\/[\d]+/.test(navigator.userAgent);if((S||s&&C||u)&&typeof FileReader!="undefined"){var p=new FileReader;p.onloadend=function(){var m=p.result;m=S?m:m.replace(/^data:[^;]*;/,"data:attachment/file;"),a?a.location.href=m:location=m,a=null},p.readAsDataURL(t)}else{var k=o.URL||o.webkitURL,f=k.createObjectURL(t);a?a.location=f:location.href=f,a=null,setTimeout(function(){k.revokeObjectURL(f)},4e4)}});o.saveAs=h.saveAs=h,typeof v!="undefined"&&(v.exports=h)})});var g=class{constructor(e){this.checkpointInterval=10;this.maxCheckpoints=300;this.reset(),this.platform=e}reset(){this.checkpoints=[],this.framerecs=[],this.frameCount=0,this.lastSeekFrame=0,this.lastSeekStep=0,this.lastStepCount=0,this.callbackStateChanged&&this.callbackStateChanged()}frameRequested(){var e={controls:this.platform.saveControlsState(),seed:b()},n=!1;return this.lastSeekFrame<this.frameCount?this.loadControls(this.lastSeekFrame):(this.platform.saveControlsState&&this.framerecs.push(e),n=this.frameCount++%this.checkpointInterval==0),this.lastSeekFrame++,this.lastSeekStep=0,this.callbackStateChanged&&this.callbackStateChanged(),n}numFrames(){return this.frameCount}currentFrame(){return this.lastSeekFrame}currentStep(){return this.lastSeekStep}recordFrame(e){this.checkpoints.push(e),this.callbackNewCheckpoint&&this.callbackNewCheckpoint(e),this.checkpoints.length>this.maxCheckpoints&&(this.checkpoints.shift(),this.framerecs=this.framerecs.slice(this.checkpointInterval),this.lastSeekFrame-=this.checkpointInterval,this.frameCount-=this.checkpointInterval,this.callbackStateChanged&&this.callbackStateChanged())}getStateAtOrBefore(e){if(e<=0&&this.checkpoints.length>0)return{frame:0,state:this.checkpoints[0]};var n=Math.floor(e/this.checkpointInterval),i=n<this.checkpoints.length?n:this.checkpoints.length-1,o=i*this.checkpointInterval;return{frame:o,state:this.checkpoints[i]}}loadFrame(e,n){if(e|=0,n|=0,e==this.lastSeekFrame&&n==this.lastSeekStep)return e;let{frame:i,state:o}=this.getStateAtOrBefore(e-1);if(o){var u=0;for(this.platform.pause(),this.platform.loadState(o);i<e;)i<this.framerecs.length&&this.loadControls(i),i++,u=this.platform.advance(i<e);return i==0&&(u=this.platform.advance(!0),this.platform.loadState(o)),n>0&&this.platform.advanceFrameClock&&(n=this.platform.advanceFrameClock(null,n)),this.lastSeekFrame=e,this.lastSeekStep=n,this.lastStepCount=u,e}else return-1}loadControls(e){this.platform.loadControlsState&&this.platform.loadControlsState(this.framerecs[e].controls),w(this.framerecs[e].seed)}getLastCheckpoint(){return this.checkpoints.length&&this.checkpoints[this.checkpoints.length-1]}};function R(l){switch(l){case"apple2":return import("./apple2-FRA6FPGL.js");case"arm32"Line truncated
//# sourceMappingURL=chunk-7WOMNSMI.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../node_modules/file-saver/src/FileSaver.js", "../src/common/recorder.ts", "../src/platform/_index.ts"],
"sourcesContent": ["/*\n* FileSaver.js\n* A saveAs() FileSaver implementation.\n*\n* By Eli Grey, http://eligrey.com\n*\n* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)\n* source : http://purl.eligrey.com/github/FileSaver.js\n*/\n\n// The one and only way of getting global scope in all environments\n// https://stackoverflow.com/q/3277182/1008999\nvar _global = typeof window === 'object' && window.window === window\n ? window : typeof self === 'object' && self.self === self\n ? self : typeof global === 'object' && global.global === global\n ? global\n : this\n\nfunction bom (blob, opts) {\n if (typeof opts === 'undefined') opts = { autoBom: false }\n else if (typeof opts !== 'object') {\n console.warn('Deprecated: Expected third argument to be a object')\n opts = { autoBom: !opts }\n }\n\n // prepend BOM for UTF-8 XML and text/* types (including HTML)\n // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })\n }\n return blob\n}\n\nfunction download (url, name, opts) {\n var xhr = new XMLHttpRequest()\n xhr.open('GET', url)\n xhr.responseType = 'blob'\n xhr.onload = function () {\n saveAs(xhr.response, name, opts)\n }\n xhr.onerror = function () {\n console.error('could not download file')\n }\n xhr.send()\n}\n\nfunction corsEnabled (url) {\n var xhr = new XMLHttpRequest()\n // use sync to avoid popup blocker\n xhr.open('HEAD', url, false)\n try {\n xhr.send()\n } catch (e) {}\n return xhr.status >= 200 && xhr.status <= 299\n}\n\n// `a.click()` doesn't work for all browsers (#465)\nfunction click (node) {\n try {\n node.dispatchEvent(new MouseEvent('click'))\n } catch (e) {\n var evt = document.createEvent('MouseEvents')\n evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,\n 20, false, false, false, false, 0, null)\n node.dispatchEvent(evt)\n }\n}\n\n// Detect WebView inside a native macOS app by ruling out all browsers\n// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too\n// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos\nvar isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)\n\nvar saveAs = _global.saveAs || (\n // probably in some web worker\n (typeof window !== 'object' || window !== _global)\n ? function saveAs () { /* noop */ }\n\n // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView\n : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)\n ? function saveAs (blob, name, opts) {\n var URL = _global.URL || _global.webkitURL\n var a = document.createElement('a')\n name = name || blob.name || 'download'\n\n a.download = name\n a.rel = 'noopener' // tabnabbing\n\n // TODO: detect chrome extensions & packaged apps\n // a.target = '_blank'\n\n if (typeof blob === 'string') {\n // Support regular links\n a.href = blob\n if (a.origin !== location.origin) {\n corsEnabled(a.href)\n ? download(blob, name, opts)\n : click(a, a.target = '_blank')\n } else {\n click(a)\n }\n } else {\n // Support blobs\n a.href = URL.createObjectURL(blob)\n setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s\n setTimeout(function () { click(a) }, 0)\n }\n }\n\n // Use msSaveOrOpenBlob as a second approach\n : 'msSaveOrOpenBlob' in navigator\n ? function saveAs (blob, name, opts) {\n name = name || blob.name || 'download'\n\n if (typeof blob === 'string') {\n if (corsEnabled(blob)) {\n download(blob, name, opts)\n } else {\n var a = document.createElement('a')\n a.href = blob\n a.target = '_blank'\n setTimeout(function () { click(a) })\n }\n } else {\n navigator.msSaveOrOpenBlob(bom(blob, opts), name)\n }\n }\n\n // Fallback to using FileReader and a popup\n : function saveAs (blob, name, opts, popup) {\n // Open a popup immediately do go around popup blocker\n // Mostly only available on user interaction and the fileReader is async so...\n popup = popup || open('', '_blank')\n if (popup) {\n popup.document.title =\n popup.document.body.innerText = 'downloading...'\n }\n\n if (typeof blob === 'string') return download(blob, name, opts)\n\n var force = blob.type === 'application/octet-stream'\n var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari\n var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent)\n\n if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefiLine truncated
"mappings": "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 truncated
"sourcesContent": ["/*\n* FileSaver.js\n* A saveAs() FileSaver implementation.\n*\n* By Eli Grey, http://eligrey.com\n*\n* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)\n* source : http://purl.eligrey.com/github/FileSaver.js\n*/\n\n// The one and only way of getting global scope in all environments\n// https://stackoverflow.com/q/3277182/1008999\nvar _global = typeof window === 'object' && window.window === window\n ? window : typeof self === 'object' && self.self === self\n ? self : typeof global === 'object' && global.global === global\n ? global\n : this\n\nfunction bom (blob, opts) {\n if (typeof opts === 'undefined') opts = { autoBom: false }\n else if (typeof opts !== 'object') {\n console.warn('Deprecated: Expected third argument to be a object')\n opts = { autoBom: !opts }\n }\n\n // prepend BOM for UTF-8 XML and text/* types (including HTML)\n // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })\n }\n return blob\n}\n\nfunction download (url, name, opts) {\n var xhr = new XMLHttpRequest()\n xhr.open('GET', url)\n xhr.responseType = 'blob'\n xhr.onload = function () {\n saveAs(xhr.response, name, opts)\n }\n xhr.onerror = function () {\n console.error('could not download file')\n }\n xhr.send()\n}\n\nfunction corsEnabled (url) {\n var xhr = new XMLHttpRequest()\n // use sync to avoid popup blocker\n xhr.open('HEAD', url, false)\n try {\n xhr.send()\n } catch (e) {}\n return xhr.status >= 200 && xhr.status <= 299\n}\n\n// `a.click()` doesn't work for all browsers (#465)\nfunction click (node) {\n try {\n node.dispatchEvent(new MouseEvent('click'))\n } catch (e) {\n var evt = document.createEvent('MouseEvents')\n evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,\n 20, false, false, false, false, 0, null)\n node.dispatchEvent(evt)\n }\n}\n\n// Detect WebView inside a native macOS app by ruling out all browsers\n// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too\n// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos\nvar isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)\n\nvar saveAs = _global.saveAs || (\n // probably in some web worker\n (typeof window !== 'object' || window !== _global)\n ? function saveAs () { /* noop */ }\n\n // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView\n : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)\n ? function saveAs (blob, name, opts) {\n var URL = _global.URL || _global.webkitURL\n var a = document.createElement('a')\n name = name || blob.name || 'download'\n\n a.download = name\n a.rel = 'noopener' // tabnabbing\n\n // TODO: detect chrome extensions & packaged apps\n // a.target = '_blank'\n\n if (typeof blob === 'string') {\n // Support regular links\n a.href = blob\n if (a.origin !== location.origin) {\n corsEnabled(a.href)\n ? download(blob, name, opts)\n : click(a, a.target = '_blank')\n } else {\n click(a)\n }\n } else {\n // Support blobs\n a.href = URL.createObjectURL(blob)\n setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s\n setTimeout(function () { click(a) }, 0)\n }\n }\n\n // Use msSaveOrOpenBlob as a second approach\n : 'msSaveOrOpenBlob' in navigator\n ? function saveAs (blob, name, opts) {\n name = name || blob.name || 'download'\n\n if (typeof blob === 'string') {\n if (corsEnabled(blob)) {\n download(blob, name, opts)\n } else {\n var a = document.createElement('a')\n a.href = blob\n a.target = '_blank'\n setTimeout(function () { click(a) })\n }\n } else {\n navigator.msSaveOrOpenBlob(bom(blob, opts), name)\n }\n }\n\n // Fallback to using FileReader and a popup\n : function saveAs (blob, name, opts, popup) {\n // Open a popup immediately do go around popup blocker\n // Mostly only available on user interaction and the fileReader is async so...\n popup = popup || open('', '_blank')\n if (popup) {\n popup.document.title =\n popup.document.body.innerText = 'downloading...'\n }\n\n if (typeof blob === 'string') return download(blob, name, opts)\n\n var force = blob.type === 'application/octet-stream'\n var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari\n var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent)\n\n if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefiLine truncated
"mappings": "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 truncated
"names": ["b", "a", "c", "d", "g", "e", "f", "h", "i", "j", "k", "l", "m", "module", "StateRecorderImpl", "platform", "controls", "getNoiseSeed", "requested", "state", "frame", "bufidx", "foundidx", "foundframe", "seekframe", "seekstep", "numSteps", "setNoiseSeed", "importPlatform", "name"]
}
+795
View File
@@ -0,0 +1,795 @@
"use strict";
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
Object.defineProperty(exports, "__esModule", { value: true });
exports.F8CPU = void 0;
// Status register flag bits
const FLAG_S = 0x01; // Sign (complementary: set when positive)
const FLAG_C = 0x02; // Carry
const FLAG_Z = 0x04; // Zero
const FLAG_O = 0x08; // Overflow
const FLAG_I = 0x10; // Interrupt Control Bit
class F8CPU {
constructor() {
// Registers
this.PC0 = 0; // active program counter
this.PC1 = 0; // saved program counter
this.DC0 = 0; // active data counter
this.DC1 = 0; // alternate data counter
this.A = 0; // accumulator
this.W = 0; // status/flags
this.IS = 0; // indirect scratchpad address (6-bit)
this.R = new Uint8Array(64); // scratchpad RAM
this.o = 0; // last opcode
this.stable = true;
this.irqRequest = false;
}
connectMemoryBus(bus) {
this.bus = bus;
}
connectIOBus(bus) {
this.iobus = bus;
}
reset() {
this.PC0 = 0;
this.PC1 = 0;
this.DC0 = 0;
this.DC1 = 0;
this.A = 0;
this.W = 0;
this.IS = 0;
this.R.fill(0);
this.irqRequest = false;
}
interrupt(type) {
this.irqRequest = true;
}
getPC() { return this.PC0; }
getSP() { return this.PC1; }
isStable() { return this.stable; }
saveState() {
return {
PC: this.PC0,
PC0: this.PC0,
PC1: this.PC1,
DC0: this.DC0,
DC1: this.DC1,
A: this.A,
W: this.W,
IS: this.IS,
R: Array.from(this.R),
o: this.o,
irq: this.irqRequest,
};
}
loadState(state) {
var _a;
this.PC0 = (_a = state.PC0) !== null && _a !== void 0 ? _a : state.PC;
this.PC1 = state.PC1;
this.DC0 = state.DC0;
this.DC1 = state.DC1;
this.A = state.A;
this.W = state.W;
this.IS = state.IS;
for (let i = 0; i < 64; i++)
this.R[i] = state.R[i];
this.o = state.o;
this.irqRequest = state.irq;
}
// Read byte at PC0, increment PC0
fetchPC0() {
const val = this.bus.read(this.PC0);
this.PC0 = (this.PC0 + 1) & 0xFFFF;
return val;
}
// Read byte at DC0, increment DC0
fetchDC0() {
const val = this.bus.read(this.DC0);
this.DC0 = (this.DC0 + 1) & 0xFFFF;
return val;
}
// Write byte at DC0, increment DC0
storeDC0(val) {
this.bus.write(this.DC0, val);
this.DC0 = (this.DC0 + 1) & 0xFFFF;
}
// Clear O, Z, C, S flags
clrOZCS() {
this.W &= ~(FLAG_O | FLAG_Z | FLAG_C | FLAG_S);
}
// Set Sign and Zero flags from value
// Note: F8 sign flag is COMPLEMENTARY - set when bit 7 is CLEAR (positive)
setSZ(val) {
if ((val & 0xFF) === 0)
this.W |= FLAG_Z;
if ((val & 0x80) === 0)
this.W |= FLAG_S; // complementary sign
}
// Addition with carry/overflow detection
doAdd(a, b, carry = 0) {
const result = (a & 0xFF) + (b & 0xFF) + (carry & 1);
// Set carry if overflow past 8 bits
if (result & 0x100)
this.W |= FLAG_C;
// Set overflow using XOR method
if (((a ^ result) & (b ^ result) & 0x80) !== 0)
this.W |= FLAG_O;
return result & 0xFF;
}
// BCD addition
doAddDecimal(augend, addend) {
let tmp = (augend & 0x0F) + (addend & 0x0F);
let c1 = (tmp > 9) ? 1 : 0;
tmp = (augend >> 4) + (addend >> 4) + c1;
let c2 = (tmp > 9) ? 1 : 0;
// Do binary add for flags
this.clrOZCS();
let result = this.doAdd(augend, addend);
this.setSZ(result);
// Apply BCD correction
let correction = 0;
if (c2)
correction |= 0xA0;
if (c1)
correction |= 0x0A;
if (correction) {
this.clrOZCS();
result = this.doAdd(result, correction);
this.setSZ(result);
}
return result;
}
// Get scratchpad register for operand (0-11 direct, 12=ISAR, 13=ISAR++, 14=ISAR--)
getScratchpadIndex(r) {
if (r < 12)
return r;
if (r === 12)
return this.IS & 0x3F;
if (r === 13) {
const idx = this.IS & 0x3F;
// Increment lower 3 bits of IS
this.IS = (this.IS & 0x38) | ((this.IS + 1) & 0x07);
return idx;
}
if (r === 14) {
const idx = this.IS & 0x3F;
// Decrement lower 3 bits of IS
this.IS = (this.IS & 0x38) | ((this.IS - 1) & 0x07);
return idx;
}
return 0; // illegal
}
advanceInsn() {
// Check for interrupts
if (this.irqRequest && (this.W & FLAG_I)) {
this.irqRequest = false;
// Save PC0 to PC1
this.PC1 = this.PC0;
// Load interrupt vector (at address 0x0020 typically)
this.PC0 = (this.bus.read(0x0FFE) << 8) | this.bus.read(0x0FFF);
// Clear interrupt enable
this.W &= ~FLAG_I;
return 6;
}
const opcode = this.fetchPC0();
this.o = opcode;
this.stable = true;
let cycles = 4; // short cycle default
let tmp;
let r;
switch (opcode) {
// 0x00: LR A,KU
case 0x00:
this.A = this.R[12];
break;
// 0x01: LR A,KL
case 0x01:
this.A = this.R[13];
break;
// 0x02: LR A,QU
case 0x02:
this.A = this.R[14];
break;
// 0x03: LR A,QL
case 0x03:
this.A = this.R[15];
break;
// 0x04: LR KU,A
case 0x04:
this.R[12] = this.A;
break;
// 0x05: LR KL,A
case 0x05:
this.R[13] = this.A;
break;
// 0x06: LR QU,A
case 0x06:
this.R[14] = this.A;
break;
// 0x07: LR QL,A
case 0x07:
this.R[15] = this.A;
break;
// 0x08: LR K,P (K <- PC1)
case 0x08:
this.R[12] = (this.PC1 >> 8) & 0xFF;
this.R[13] = this.PC1 & 0xFF;
cycles = 8;
break;
// 0x09: LR P,K (PC1 <- K)
case 0x09:
this.PC1 = (this.R[12] << 8) | this.R[13];
cycles = 8;
break;
// 0x0A: LR A,IS
case 0x0A:
this.A = this.IS & 0x3F;
break;
// 0x0B: LR IS,A
case 0x0B:
this.IS = this.A & 0x3F;
break;
// 0x0C: PK (Push K to PC: PC1<-PC0+1, PC0<-K)
case 0x0C:
this.PC1 = this.PC0;
this.PC0 = (this.R[12] << 8) | this.R[13];
cycles = 8;
break;
// 0x0D: LR P0,Q (PC0 <- Q)
case 0x0D:
this.PC0 = (this.R[14] << 8) | this.R[15];
cycles = 8;
break;
// 0x0E: LR Q,DC (Q <- DC0)
case 0x0E:
this.R[14] = (this.DC0 >> 8) & 0xFF;
this.R[15] = this.DC0 & 0xFF;
cycles = 8;
break;
// 0x0F: LR DC,Q (DC0 <- Q)
case 0x0F:
this.DC0 = (this.R[14] << 8) | this.R[15];
cycles = 8;
break;
// 0x10: LR DC,H (DC0 <- H)
case 0x10:
this.DC0 = (this.R[10] << 8) | this.R[11];
cycles = 8;
break;
// 0x11: LR H,DC (H <- DC0)
case 0x11:
this.R[10] = (this.DC0 >> 8) & 0xFF;
this.R[11] = this.DC0 & 0xFF;
cycles = 8;
break;
// 0x12: SR 1 (shift right 1)
case 0x12:
this.A = (this.A >> 1) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x13: SL 1 (shift left 1)
case 0x13:
this.A = (this.A << 1) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x14: SR 4 (shift right 4)
case 0x14:
this.A = (this.A >> 4) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x15: SL 4 (shift left 4)
case 0x15:
this.A = (this.A << 4) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x16: LM (load A from memory at DC0, increment DC0)
case 0x16:
this.A = this.fetchDC0();
cycles = 6;
break;
// 0x17: ST (store A to memory at DC0, increment DC0)
case 0x17:
this.storeDC0(this.A);
cycles = 6;
break;
// 0x18: COM (complement A)
case 0x18:
this.A = (~this.A) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x19: LNK (add carry to A)
case 0x19:
tmp = (this.W & FLAG_C) ? 1 : 0;
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
break;
// 0x1A: DI (disable interrupts)
case 0x1A:
this.W &= ~FLAG_I;
break;
// 0x1B: EI (enable interrupts)
case 0x1B:
this.W |= FLAG_I;
break;
// 0x1C: POP (PC0 <- PC1)
case 0x1C:
this.PC0 = this.PC1;
break;
// 0x1D: LR W,J (W <- scratchpad[9])
case 0x1D:
this.W = this.R[9] & 0x1F;
break;
// 0x1E: LR J,W (scratchpad[9] <- W)
case 0x1E:
this.R[9] = this.W & 0x1F;
break;
// 0x1F: INC (increment A)
case 0x1F:
this.clrOZCS();
this.A = this.doAdd(this.A, 1);
this.setSZ(this.A);
break;
// 0x20: LI immediate
case 0x20:
this.A = this.fetchPC0();
cycles = 6;
break;
// 0x21: NI immediate (AND)
case 0x21:
tmp = this.fetchPC0();
this.A = this.A & tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x22: OI immediate (OR)
case 0x22:
tmp = this.fetchPC0();
this.A = this.A | tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x23: XI immediate (XOR)
case 0x23:
tmp = this.fetchPC0();
this.A = this.A ^ tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x24: AI immediate (ADD)
case 0x24:
tmp = this.fetchPC0();
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
cycles = 6;
break;
// 0x25: CI immediate (compare: sets flags from ~A + immediate + 1)
case 0x25:
tmp = this.fetchPC0();
this.clrOZCS();
this.doAdd((~this.A) & 0xFF, tmp, 1);
this.setSZ(this.doAdd((~this.A) & 0xFF, tmp, 1));
cycles = 6;
break;
// 0x26: IN immediate (input from port)
case 0x26:
tmp = this.fetchPC0();
this.A = this.iobus.read(tmp) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
cycles = 8;
break;
// 0x27: OUT immediate (output to port)
case 0x27:
tmp = this.fetchPC0();
this.iobus.write(tmp, this.A);
cycles = 8;
break;
// 0x28: PI (push and jump immediate: PC1<-PC0, PC0<-address)
case 0x28: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.PC1 = this.PC0;
this.PC0 = (hi << 8) | lo;
cycles = 12;
break;
}
// 0x29: JMP (jump immediate)
case 0x29: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.PC0 = (hi << 8) | lo;
cycles = 10;
break;
}
// 0x2A: DCI (load DC0 immediate)
case 0x2A: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.DC0 = (hi << 8) | lo;
cycles = 10;
break;
}
// 0x2B: NOP
case 0x2B: break;
// 0x2C: XDC (exchange DC0 and DC1)
case 0x2C:
tmp = this.DC0;
this.DC0 = this.DC1;
this.DC1 = tmp;
break;
// 0x2D-0x2F: illegal
case 0x2D:
case 0x2E:
case 0x2F: break;
// 0x30-0x3E: DS (decrement scratchpad register, skip if zero)
case 0x30:
case 0x31:
case 0x32:
case 0x33:
case 0x34:
case 0x35:
case 0x36:
case 0x37:
case 0x38:
case 0x39:
case 0x3A:
case 0x3B:
case 0x3C:
case 0x3D:
case 0x3E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.clrOZCS();
this.R[r] = this.doAdd(this.R[r], 0xFF);
this.setSZ(this.R[r]);
cycles = 6;
break;
case 0x3F: break; // illegal
// 0x40-0x4E: LR A,r (load A from scratchpad)
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
case 0x48:
case 0x49:
case 0x4A:
case 0x4B:
case 0x4C:
case 0x4D:
case 0x4E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = this.R[r];
break;
case 0x4F: break; // illegal
// 0x50-0x5E: LR r,A (store A to scratchpad)
case 0x50:
case 0x51:
case 0x52:
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
case 0x58:
case 0x59:
case 0x5A:
case 0x5B:
case 0x5C:
case 0x5D:
case 0x5E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.R[r] = this.A;
break;
case 0x5F: break; // illegal
// 0x60-0x67: LISU (load IS upper 3 bits)
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x66:
case 0x67:
this.IS = (this.IS & 0x07) | ((opcode & 0x07) << 3);
break;
// 0x68-0x6F: LISL (load IS lower 3 bits)
case 0x68:
case 0x69:
case 0x6A:
case 0x6B:
case 0x6C:
case 0x6D:
case 0x6E:
case 0x6F:
this.IS = (this.IS & 0x38) | (opcode & 0x07);
break;
// 0x70-0x7F: LIS (load A with 4-bit immediate)
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77:
case 0x78:
case 0x79:
case 0x7A:
case 0x7B:
case 0x7C:
case 0x7D:
case 0x7E:
case 0x7F:
this.A = opcode & 0x0F;
break;
// 0x80-0x87: BT (branch if flag test true)
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x87: {
const mask = opcode & 0x07;
const offset = this.fetchPC0();
if (this.W & mask) {
// Sign-extend offset and add to PC0
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
cycles = 6;
}
else {
cycles = 6;
}
break;
}
// 0x88: AM (add memory at DC0 to A)
case 0x88:
tmp = this.fetchDC0();
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
cycles = 6;
break;
// 0x89: AMD (decimal add memory at DC0 to A)
case 0x89:
tmp = this.fetchDC0();
this.A = this.doAddDecimal(this.A, tmp);
cycles = 6;
break;
// 0x8A: NM (AND memory at DC0)
case 0x8A:
tmp = this.fetchDC0();
this.A = this.A & tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8B: OM (OR memory at DC0)
case 0x8B:
tmp = this.fetchDC0();
this.A = this.A | tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8C: XM (XOR memory at DC0)
case 0x8C:
tmp = this.fetchDC0();
this.A = this.A ^ tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8D: CM (compare memory at DC0)
case 0x8D:
tmp = this.fetchDC0();
this.clrOZCS();
{
const cmp = this.doAdd((~this.A) & 0xFF, tmp, 1);
this.setSZ(cmp);
}
cycles = 6;
break;
// 0x8E: ADC (add accumulator to DC0)
case 0x8E:
this.DC0 = (this.DC0 + ((this.A & 0x80) ? (this.A - 256) : this.A)) & 0xFFFF;
cycles = 6;
break;
// 0x8F: BR7 (branch if IS lower 3 bits != 7)
case 0x8F: {
const offset = this.fetchPC0();
if ((this.IS & 0x07) !== 7) {
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
}
cycles = 6;
break;
}
// 0x90-0x9F: BF (branch if flag false)
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
case 0x98:
case 0x99:
case 0x9A:
case 0x9B:
case 0x9C:
case 0x9D:
case 0x9E:
case 0x9F: {
const mask = opcode & 0x0F;
const offset = this.fetchPC0();
if (mask === 0 || !(this.W & mask)) {
// BF 0 is unconditional branch (BR)
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
}
cycles = 6;
break;
}
// 0xA0-0xA1: INS 0-1 (input from port 0/1, direct)
case 0xA0:
case 0xA1:
this.A = this.iobus.read(opcode & 0x01) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0xA2-0xA3: illegal
case 0xA2:
case 0xA3: break;
// 0xA4-0xAF: INS 4-F (input from addressed port)
case 0xA4:
case 0xA5:
case 0xA6:
case 0xA7:
case 0xA8:
case 0xA9:
case 0xAA:
case 0xAB:
case 0xAC:
case 0xAD:
case 0xAE:
case 0xAF:
this.A = this.iobus.read(opcode & 0x0F) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
cycles = 8;
break;
// 0xB0-0xB1: OUTS 0-1 (output to port 0/1, direct)
case 0xB0:
case 0xB1:
this.iobus.write(opcode & 0x01, this.A);
break;
// 0xB2-0xB3: illegal
case 0xB2:
case 0xB3: break;
// 0xB4-0xBF: OUTS 4-F (output to addressed port)
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF:
this.iobus.write(opcode & 0x0F, this.A);
cycles = 8;
break;
// 0xC0-0xCE: AS (add scratchpad to A)
case 0xC0:
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
case 0xC6:
case 0xC7:
case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.clrOZCS();
this.A = this.doAdd(this.A, this.R[r]);
this.setSZ(this.A);
break;
case 0xCF: break; // illegal
// 0xD0-0xDE: ASD (decimal add scratchpad to A)
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
case 0xD8:
case 0xD9:
case 0xDA:
case 0xDB:
case 0xDC:
case 0xDD:
case 0xDE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = this.doAddDecimal(this.A, this.R[r]);
cycles = 8;
break;
case 0xDF: break; // illegal
// 0xE0-0xEE: XS (XOR scratchpad with A)
case 0xE0:
case 0xE1:
case 0xE2:
case 0xE3:
case 0xE4:
case 0xE5:
case 0xE6:
case 0xE7:
case 0xE8:
case 0xE9:
case 0xEA:
case 0xEB:
case 0xEC:
case 0xED:
case 0xEE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = (this.A ^ this.R[r]) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
case 0xEF: break; // illegal
// 0xF0-0xFE: NS (AND scratchpad with A)
case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF6:
case 0xF7:
case 0xF8:
case 0xF9:
case 0xFA:
case 0xFB:
case 0xFC:
case 0xFD:
case 0xFE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = (this.A & this.R[r]) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
case 0xFF: break; // illegal
}
return cycles;
}
}
exports.F8CPU = F8CPU;
//# sourceMappingURL=F8.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"F8.js","sourceRoot":"","sources":["../../../src/common/cpu/F8.ts"],"names":[],"mappings":"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 truncated
+333
View File
@@ -0,0 +1,333 @@
"use strict";
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
Object.defineProperty(exports, "__esModule", { value: true });
exports.disassembleF8 = disassembleF8;
const util_1 = require("../util");
// Scratchpad register names for operands 0-14
function regName(r) {
if (r < 9)
return 'r' + r;
if (r === 9)
return 'J';
if (r === 10)
return 'HU';
if (r === 11)
return 'HL';
if (r === 12)
return 'S'; // ISAR
if (r === 13)
return 'I'; // ISAR++
if (r === 14)
return 'D'; // ISAR--
return '?';
}
function disassembleF8(pc, b0, b1, b2) {
let mn = '';
let args = '';
let nb = 1;
let isaddr = false;
if (b0 <= 0x07) {
const regs = ['KU', 'KL', 'QU', 'QL'];
if (b0 < 4) {
mn = 'LR';
args = 'A,' + regs[b0];
}
else {
mn = 'LR';
args = regs[b0 - 4] + ',A';
}
}
else if (b0 === 0x08) {
mn = 'LR';
args = 'K,P';
}
else if (b0 === 0x09) {
mn = 'LR';
args = 'P,K';
}
else if (b0 === 0x0A) {
mn = 'LR';
args = 'A,IS';
}
else if (b0 === 0x0B) {
mn = 'LR';
args = 'IS,A';
}
else if (b0 === 0x0C) {
mn = 'PK';
}
else if (b0 === 0x0D) {
mn = 'LR';
args = 'P0,Q';
}
else if (b0 === 0x0E) {
mn = 'LR';
args = 'Q,DC';
}
else if (b0 === 0x0F) {
mn = 'LR';
args = 'DC,Q';
}
else if (b0 === 0x10) {
mn = 'LR';
args = 'DC,H';
}
else if (b0 === 0x11) {
mn = 'LR';
args = 'H,DC';
}
else if (b0 === 0x12) {
mn = 'SR';
args = '1';
}
else if (b0 === 0x13) {
mn = 'SL';
args = '1';
}
else if (b0 === 0x14) {
mn = 'SR';
args = '4';
}
else if (b0 === 0x15) {
mn = 'SL';
args = '4';
}
else if (b0 === 0x16) {
mn = 'LM';
}
else if (b0 === 0x17) {
mn = 'ST';
}
else if (b0 === 0x18) {
mn = 'COM';
}
else if (b0 === 0x19) {
mn = 'LNK';
}
else if (b0 === 0x1A) {
mn = 'DI';
}
else if (b0 === 0x1B) {
mn = 'EI';
}
else if (b0 === 0x1C) {
mn = 'POP';
}
else if (b0 === 0x1D) {
mn = 'LR';
args = 'W,J';
}
else if (b0 === 0x1E) {
mn = 'LR';
args = 'J,W';
}
else if (b0 === 0x1F) {
mn = 'INC';
}
else if (b0 === 0x20) {
mn = 'LI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x21) {
mn = 'NI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x22) {
mn = 'OI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x23) {
mn = 'XI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x24) {
mn = 'AI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x25) {
mn = 'CI';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x26) {
mn = 'IN';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x27) {
mn = 'OUT';
args = '$' + (0, util_1.hex)(b1, 2);
nb = 2;
}
else if (b0 === 0x28) {
mn = 'PI';
args = '$' + (0, util_1.hex)((b1 << 8) | b2, 4);
nb = 3;
isaddr = true;
}
else if (b0 === 0x29) {
mn = 'JMP';
args = '$' + (0, util_1.hex)((b1 << 8) | b2, 4);
nb = 3;
isaddr = true;
}
else if (b0 === 0x2A) {
mn = 'DCI';
args = '$' + (0, util_1.hex)((b1 << 8) | b2, 4);
nb = 3;
isaddr = true;
}
else if (b0 === 0x2B) {
mn = 'NOP';
}
else if (b0 === 0x2C) {
mn = 'XDC';
}
else if (b0 <= 0x2F) {
mn = '???';
}
else if (b0 >= 0x30 && b0 <= 0x3E) {
mn = 'DS';
args = regName(b0 & 0x0F);
nb = 1;
}
else if (b0 === 0x3F) {
mn = '???';
}
else if (b0 >= 0x40 && b0 <= 0x4E) {
mn = 'LR';
args = 'A,' + regName(b0 & 0x0F);
}
else if (b0 === 0x4F) {
mn = '???';
}
else if (b0 >= 0x50 && b0 <= 0x5E) {
mn = 'LR';
args = regName(b0 & 0x0F) + ',A';
}
else if (b0 === 0x5F) {
mn = '???';
}
else if (b0 >= 0x60 && b0 <= 0x67) {
mn = 'LISU';
args = '' + (b0 & 0x07);
}
else if (b0 >= 0x68 && b0 <= 0x6F) {
mn = 'LISL';
args = '' + (b0 & 0x07);
}
else if (b0 >= 0x70 && b0 <= 0x7F) {
mn = 'LIS';
args = '' + (b0 & 0x0F);
}
else if (b0 >= 0x80 && b0 <= 0x87) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
mn = 'BT';
args = '' + (b0 & 0x07) + ',$' + (0, util_1.hex)(offset & 0xFFFF, 4);
nb = 2;
isaddr = true;
}
else if (b0 === 0x88) {
mn = 'AM';
}
else if (b0 === 0x89) {
mn = 'AMD';
}
else if (b0 === 0x8A) {
mn = 'NM';
}
else if (b0 === 0x8B) {
mn = 'OM';
}
else if (b0 === 0x8C) {
mn = 'XM';
}
else if (b0 === 0x8D) {
mn = 'CM';
}
else if (b0 === 0x8E) {
mn = 'ADC';
}
else if (b0 === 0x8F) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
mn = 'BR7';
args = '$' + (0, util_1.hex)(offset & 0xFFFF, 4);
nb = 2;
isaddr = true;
}
else if (b0 >= 0x90 && b0 <= 0x9F) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
const mask = b0 & 0x0F;
if (mask === 0)
mn = 'BR';
else
mn = 'BF';
if (mask !== 0)
args = '' + mask + ',';
args += '$' + (0, util_1.hex)(offset & 0xFFFF, 4);
nb = 2;
isaddr = true;
}
else if (b0 >= 0xA0 && b0 <= 0xA1) {
mn = 'INS';
args = '' + (b0 & 0x0F);
}
else if (b0 >= 0xA2 && b0 <= 0xA3) {
mn = '???';
}
else if (b0 >= 0xA4 && b0 <= 0xAF) {
mn = 'INS';
args = '' + (b0 & 0x0F);
}
else if (b0 >= 0xB0 && b0 <= 0xB1) {
mn = 'OUTS';
args = '' + (b0 & 0x0F);
}
else if (b0 >= 0xB2 && b0 <= 0xB3) {
mn = '???';
}
else if (b0 >= 0xB4 && b0 <= 0xBF) {
mn = 'OUTS';
args = '' + (b0 & 0x0F);
}
else if (b0 >= 0xC0 && b0 <= 0xCE) {
mn = 'AS';
args = regName(b0 & 0x0F);
}
else if (b0 === 0xCF) {
mn = '???';
}
else if (b0 >= 0xD0 && b0 <= 0xDE) {
mn = 'ASD';
args = regName(b0 & 0x0F);
}
else if (b0 === 0xDF) {
mn = '???';
}
else if (b0 >= 0xE0 && b0 <= 0xEE) {
mn = 'XS';
args = regName(b0 & 0x0F);
}
else if (b0 === 0xEF) {
mn = '???';
}
else if (b0 >= 0xF0 && b0 <= 0xFE) {
mn = 'NS';
args = regName(b0 & 0x0F);
}
else {
mn = '???';
}
return { line: mn + (args ? ' ' + args : ''), nbytes: nb, isaddr: isaddr };
}
//# sourceMappingURL=disasmF8.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"disasmF8.js","sourceRoot":"","sources":["../../../src/common/cpu/disasmF8.ts"],"names":[],"mappings":"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 truncated
@@ -1,2 +1,2 @@
import{a as x}from"./chunk-3FIVEUG2.js";import{t as y}from"./chunk-IBRDAYM2.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-R5KWJQBC.js";import{I as m,m as c,p}from"./chunk-GTDJ7CMC.js";import{C as d,K as f,aa as a,n as h}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var n=31,s=class extends p{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new c;this.ram=new Uint8Array(16384);this.read=a([[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=a([[0,16383,16383,(e,r)=>{this.ram[e]=r}],[16387,16387,65535,(e,r)=>this.serial.sendByte(r)],[16399,16399,65535,(e,r)=>{this.inputs[n]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var r=0;r<this.cpuFrequency/60&&!(e&&e());)r+=this.advanceCPU();return r}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[n]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[n]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],l=class{constructor(t){t.style.overflowY="auto";var e=$('<div id="gameport"/>').appendTo(t);$('<p class="transcript-header">Serial Output</p>').appendTo(e);var r=$('<div id="windowport" class="transcript"/>').appendTo(e);this.div=r[0]}start(){this.tty=new x(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(t){this.tty.loadState(t)}};function v(i){return i==10?"":i<32?String.fromCharCode(i+9216):String.fromCharCode(i)}var u=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(t){this.clearToSend()&&(this.outputBytes.push(t),this.viewer.tty.addtext(v(t),34),t==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 t=this.readIndex();this.inputIndex=t;var e=(this.inputBytes&&this.inputBytes[t])|0;return this.viewer.tty.addtext(v(e),18),e==10&&this.viewer.tty.newline(),e}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(t){this.clk+=t}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(t){this.clk=t.clk,this.inputIndex=t.idx,this.outputBytes=t.out.slice()}},o=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 l(e)}async start(){super.start(),this.serial=new u,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=d(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=h(this.serial.outputBytes),y(),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 s}getPresets(){return S}readAddress(e){return this.machine.readConst(e)}};f["devel-6502"]=o;export{u as SerialTestHarness};
//# sourceMappingURL=devel-WKD7YYYS.js.map
import{a as x}from"./chunk-3FIVEUG2.js";import{t as y}from"./chunk-2DVTTN6M.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-7WOMNSMI.js";import{I as m,m as c,p}from"./chunk-GTDJ7CMC.js";import{C as d,K as f,aa as a,n as h}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var n=31,s=class extends p{constructor(){super();this.cpuFrequency=1e6;this.defaultROMSize=32768;this.cpu=new c;this.ram=new Uint8Array(16384);this.read=a([[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=a([[0,16383,16383,(e,r)=>{this.ram[e]=r}],[16387,16387,65535,(e,r)=>this.serial.sendByte(r)],[16399,16399,65535,(e,r)=>{this.inputs[n]=1}]]);this.connectCPUMemoryBus(this)}connectSerialIO(e){this.serial=e}readConst(e){return this.read(e)}advanceFrame(e){for(var r=0;r<this.cpuFrequency/60&&!(e&&e());)r+=this.advanceCPU();return r}advanceCPU(){if(this.isHalted())return 1;var e=super.advanceCPU();return this.serial&&this.serial.advance(e),e}reset(){this.inputs[n]=0,super.reset(),this.serial&&this.serial.reset()}isHalted(){return this.inputs[n]!=0}};var S=[{id:"hello.dasm",name:"Hello World (ASM)"}],l=class{constructor(t){t.style.overflowY="auto";var e=$('<div id="gameport"/>').appendTo(t);$('<p class="transcript-header">Serial Output</p>').appendTo(e);var r=$('<div id="windowport" class="transcript"/>').appendTo(e);this.div=r[0]}start(){this.tty=new x(this.div,!1)}reset(){this.tty.clear()}saveState(){return this.tty.saveState()}loadState(t){this.tty.loadState(t)}};function v(i){return i==10?"":i<32?String.fromCharCode(i+9216):String.fromCharCode(i)}var u=class{constructor(){this.bufferedRead=!0;this.cyclesPerByte=1e6/(57600/8);this.maxOutputBytes=4096}clearToSend(){return this.outputBytes.length<this.maxOutputBytes}sendByte(t){this.clearToSend()&&(this.outputBytes.push(t),this.viewer.tty.addtext(v(t),34),t==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 t=this.readIndex();this.inputIndex=t;var e=(this.inputBytes&&this.inputBytes[t])|0;return this.viewer.tty.addtext(v(e),18),e==10&&this.viewer.tty.newline(),e}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(t){this.clk+=t}saveState(){return{clk:this.clk,idx:this.inputIndex,out:this.outputBytes.slice()}}loadState(t){this.clk=t.clk,this.inputIndex=t.idx,this.outputBytes=t.out.slice()}},o=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 l(e)}async start(){super.start(),this.serial=new u,this.serial.viewer=this.serview,this.serview.start(),this.machine.connectSerialIO(this.serial)}reset(){this.serial.inputBytes=d(this.internalFiles["serialin.dat"]),super.reset(),this.serview.reset()}isBlocked(){return this.machine.isHalted()}advance(e){return this.isBlocked()?(this.internalFiles["serialout.dat"]=h(this.serial.outputBytes),y(),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 s}getPresets(){return S}readAddress(e){return this.machine.readConst(e)}};f["devel-6502"]=o;export{u as SerialTestHarness};
//# sourceMappingURL=devel-CIOOAUIW.js.map
File renamed without changes.
+1 -1
View File
@@ -1,2 +1,2 @@
import{b as v,c as P}from"./chunk-R5KWJQBC.js";import{A as p,E as w,K as c,l as u,m,y as g}from"./chunk-MZ4MJULD.js";import{e as I}from"./chunk-KT7KMEQC.js";var k=I(P()),i,a,l,h=(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 x(){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 y(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){w("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=>{y(r,f)},"arraybuffer"),!0;if(n){var s=m(atob(n));t=new u().decode(s)}return M(),y(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 v(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){x(),h.p&&b(h)}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,k.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 v,c as P}from"./chunk-7WOMNSMI.js";import{A as p,E as w,K as c,l as u,m,y as g}from"./chunk-MZ4MJULD.js";import{e as I}from"./chunk-KT7KMEQC.js";var k=I(P()),i,a,l,h=(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 x(){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 y(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){w("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=>{y(r,f)},"arraybuffer"),!0;if(n){var s=m(atob(n));t=new u().decode(s)}return M(),y(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 v(p(i));console.log("starting platform",i),await S(e)}catch(t){console.log(t),alert('Platform "'+i+'" not supported.')}}function F(){x(),h.p&&b(h)}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,k.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
+15
View File
@@ -0,0 +1,15 @@
import{C as K,E as $,G as Y,H as J,r as Z,u as W}from"./chunk-GTDJ7CMC.js";import{K as H,T as z,W as f,X as O,Z as N,aa as j,g as x}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var b=class b{constructor(){this.A=0;this.F=0;this.B=0;this.C=0;this.D=0;this.E=0;this.H=0;this.L=0;this.SP=65534;this.PC=256;this.ime=!1;this.imeDelay=!1;this.halted=!1;this.interruptFlags=0;this.cyclesPerInsn=0;this.o=0;this.stable=!0}connectMemoryBus(t){this.bus=t}reset(){this.A=1,this.F=176,this.B=0,this.C=19,this.D=0,this.E=216,this.H=1,this.L=77,this.SP=65534,this.PC=256,this.ime=!1,this.imeDelay=!1,this.halted=!1,this.interruptFlags=0}interrupt(t){this.interruptFlags|=t}getPC(){return this.PC}getSP(){return this.SP}isStable(){return this.stable}saveState(){return{PC:this.PC,SP:this.SP,AF:this.A<<8|this.F,BC:this.B<<8|this.C,DE:this.D<<8|this.E,HL:this.H<<8|this.L,o:this.o,ime:this.ime?1:0,halted:this.halted,interrupt:this.interruptFlags}}loadState(t){this.PC=t.PC,this.SP=t.SP,this.A=t.AF>>8&255,this.F=t.AF&240,this.B=t.BC>>8&255,this.C=t.BC&255,this.D=t.DE>>8&255,this.E=t.DE&255,this.H=t.HL>>8&255,this.L=t.HL&255,this.o=t.o,this.ime=!!t.ime,this.halted=t.halted,this.interruptFlags=t.interrupt}getAF(){return this.A<<8|this.F&240}getBC(){return this.B<<8|this.C}getDE(){return this.D<<8|this.E}getHL(){return this.H<<8|this.L}setAF(t){this.A=t>>8&255,this.F=t&240}setBC(t){this.B=t>>8&255,this.C=t&255}setDE(t){this.D=t>>8&255,this.E=t&255}setHL(t){this.H=t>>8&255,this.L=t&255}read(t){return this.bus.read(t&65535)}write(t,e){this.bus.write(t&65535,e&255)}readWord(t){return this.read(t)|this.read(t+1)<<8}writeWord(t,e){this.write(t,e&255),this.write(t+1,e>>8&255)}fetchByte(){var t=this.read(this.PC);return this.PC=this.PC+1&65535,t}fetchWord(){var t=this.fetchByte(),e=this.fetchByte();return e<<8|t}fetchSignedByte(){var t=this.fetchByte();return t<128?t:t-256}pushWord(t){this.SP=this.SP-1&65535,this.write(this.SP,t>>8&255),this.SP=this.SP-1&65535,this.write(this.SP,t&255)}popWord(){var t=this.read(this.SP);this.SP=this.SP+1&65535;var e=this.read(this.SP);return this.SP=this.SP+1&65535,e<<8|t}getZ(){return!!(this.F&b.FLAG_Z)}getN(){return!!(this.F&b.FLAG_N)}getH(){return!!(this.F&b.FLAG_H)}getC(){return!!(this.F&b.FLAG_C)}setZ(t){t?this.F|=b.FLAG_Z:this.F&=~b.FLAG_Z}setN(t){t?this.F|=b.FLAG_N:this.F&=~b.FLAG_N}setH(t){t?this.F|=b.FLAG_H:this.F&=~b.FLAG_H}setC(t){t?this.F|=b.FLAG_C:this.F&=~b.FLAG_C}setFlags(t,e,s,i){this.F=(t?b.FLAG_Z:0)|(e?b.FLAG_N:0)|(s?b.FLAG_H:0)|(i?b.FLAG_C:0)}getReg(t){switch(t){case 0:return this.B;case 1:return this.C;case 2:return this.D;case 3:return this.E;case 4:return this.H;case 5:return this.L;case 6:return this.read(this.getHL());case 7:return this.A}return 0}setReg(t,e){switch(e&=255,t){case 0:this.B=e;break;case 1:this.C=e;break;case 2:this.D=e;break;case 3:this.E=e;break;case 4:this.H=e;break;case 5:this.L=e;break;case 6:this.write(this.getHL(),e);break;case 7:this.A=e;break}}getReg16(t){switch(t){case 0:return this.getBC();case 1:return this.getDE();case 2:return this.getHL();case 3:return this.SP}return 0}setReg16(t,e){switch(e&=65535,t){case 0:this.setBC(e);break;case 1:this.setDE(e);break;case 2:this.setHL(e);break;case 3:this.SP=e;break}}getReg16AF(t){switch(t){case 0:return this.getBC();case 1:return this.getDE();case 2:return this.getHL();case 3:return this.getAF()}return 0}setReg16AF(t,e){switch(e&=65535,t){case 0:this.setBC(e);break;case 1:this.setDE(e);break;case 2:this.setHL(e);break;case 3:this.setAF(e);break}}checkCondition(t){switch(t){case 0:return!this.getZ();case 1:return this.getZ();case 2:return!this.getC();case 3:return this.getC()}return!1}addA(t){var e=this.A+t;this.setFlags((e&255)===0,!1,(this.A&15)+(t&15)>15,e>255),this.A=e&255}adcA(t){var e=this.getC()?1:0,s=this.A+t+e;this.setFlags((s&255)===0,!1,(this.A&15)+(t&15)+e>15,s>255),this.A=s&255}subA(t){var e=this.A-t;this.setFlags((e&255)===0,!0,(this.A&15)<(t&15),e<0),this.A=e&255}sbcA(t){var e=this.getC()?1:0,s=this.A-t-e;this.setFlags((s&255)===0,!0,(this.A&15)<(t&15)+e,s<0),this.A=s&255}andA(t){this.A&=t,this.setFlags(this.A===0,!1,!0,!1)}xorA(t){this.A^=t,this.A&=255,this.setFlags(this.A===0,!1,!1,!1)}orA(t){this.A|=t,this.A&=255,this.setFlags(this.A===0,!1,!1,!1)}cpA(t){var e=this.A-t;this.setFlags((e&255)===0,!0,(this.A&15)<(t&15),e<0)}aluOp(t,e){switch(t){case 0:this.addA(e);break;case 1:this.adcA(e);break;case 2:this.subA(e);break;case 3:this.sbcA(e);break;case 4:this.andA(e);break;case 5:this.xorA(e);break;case 6:this.orA(e);break;case 7:this.cpA(e);break}}inc8(t){var e=t+1&255;return this.setZ(e===0),this.setN(!1),this.setH((t&15)===15),e}dec8(t){var e=t-1&255;return this.setZ(e===0),this.setN(!0),this.setH((t&15)===0),e}addHL(t){var e=this.getHL(),s=e+t;this.setN(!1),this.setH((e&4095)+(t&4095)>4095),this.setC(s>65535),this.setHL(s&65535)}daa(){var t=this.A;this.getN()?(this.getC()&&(t-=96),this.getH()&&(t-=6)):((this.getC()||t>153)&&(t+=96,this.setC(!0)),(this.getH()||(t&15)>9)&&(t+=6)),t&=255,this.setZ(tLine truncated
LY `+x(this.ly,2)+" LYC "+x(this.lyc,2)+`
SCX `+x(this.scx,2)+" SCY "+x(this.scy,2)+`
WX `+x(this.wx,2)+" WY "+x(this.wy,2)+`
BGP `+x(this.bgp,2)+" OBP0 "+x(this.obp0,2)+`
OBP1 `+x(this.obp1,2)+" DMA "+x(this.dma,2)+`
IF `+x(this.iflag,2)+" IE "+x(this.ie,2)+`
DIV `+x(this.divCounter>>8&255,2)+" TIMA "+x(this.tima,2)+`
TMA `+x(this.tma,2)+" TAC "+x(this.tac,2)+`
Bank `+this.romBank+`
`;return this.cgbMode&&(i+=`--- CGB ---
VBK `+this.vramBankSelect+" SVBK "+this.wramBankSelect+`
SPD `+(this.doubleSpeed?"2x":"1x")+`
`),i}}};var he=["nop","ld bc,xx","ld (bc),a","inc bc","inc b","dec b","ld b,x","rlca","ld (xx),sp","add hl,bc","ld a,(bc)","dec bc","inc c","dec c","ld c,x","rrca","stop x","ld de,xx","ld (de),a","inc de","inc d","dec d","ld d,x","rla","jr x","add hl,de","ld a,(de)","dec de","inc e","dec e","ld e,x","rra","jr nz,x","ld hl,xx","ld (hl+),a","inc hl","inc h","dec h","ld h,x","daa","jr z,x","add hl,hl","ld a,(hl+)","dec hl","inc l","dec l","ld l,x","cpl","jr nc,x","ld sp,xx","ld (hl-),a","inc sp","inc (hl)","dec (hl)","ld (hl),x","scf","jr c,x","add hl,sp","ld a,(hl-)","dec sp","inc a","dec a","ld a,x","ccf","ld b,b","ld b,c","ld b,d","ld b,e","ld b,h","ld b,l","ld b,(hl)","ld b,a","ld c,b","ld c,c","ld c,d","ld c,e","ld c,h","ld c,l","ld c,(hl)","ld c,a","ld d,b","ld d,c","ld d,d","ld d,e","ld d,h","ld d,l","ld d,(hl)","ld d,a","ld e,b","ld e,c","ld e,d","ld e,e","ld e,h","ld e,l","ld e,(hl)","ld e,a","ld h,b","ld h,c","ld h,d","ld h,e","ld h,h","ld h,l","ld h,(hl)","ld h,a","ld l,b","ld l,c","ld l,d","ld l,e","ld l,h","ld l,l","ld l,(hl)","ld l,a","ld (hl),b","ld (hl),c","ld (hl),d","ld (hl),e","ld (hl),h","ld (hl),l","halt","ld (hl),a","ld a,b","ld a,c","ld a,d","ld a,e","ld a,h","ld a,l","ld a,(hl)","ld a,a","add a,b","add a,c","add a,d","add a,e","add a,h","add a,l","add a,(hl)","add a,a","adc a,b","adc a,c","adc a,d","adc a,e","adc a,h","adc a,l","adc a,(hl)","adc a,a","sub b","sub c","sub d","sub e","sub h","sub l","sub (hl)","sub a","sbc a,b","sbc a,c","sbc a,d","sbc a,e","sbc a,h","sbc a,l","sbc a,(hl)","sbc a,a","and b","and c","and d","and e","and h","and l","and (hl)","and a","xor b","xor c","xor d","xor e","xor h","xor l","xor (hl)","xor a","or b","or c","or d","or e","or h","or l","or (hl)","or a","cp b","cp c","cp d","cp e","cp h","cp l","cp (hl)","cp a","ret nz","pop bc","jp nz,xx","jp xx","call nz,xx","push bc","add a,x","rst 00h","ret z","ret","jp z,xx","xxCBxx","call z,xx","call xx","adc a,x","rst 08h","ret nc","pop de","jp nc,xx","??","call nc,xx","push de","sub x","rst 10h","ret c","reti","jp c,xx","??","call c,xx","??","sbc a,x","rst 18h","ldh (x),a","pop hl","ld (c),a","??","??","push hl","and x","rst 20h","add sp,x","jp (hl)","ld (xx),a","??","??","??","xor x","rst 28h","ldh a,(x)","pop af","ld a,(c)","di","??","push af","or x","rst 30h","ld hl,sp+x","ld sp,hl","ld a,(xx)","ei","??","??","cp x","rst 38h"],re=["rlc b","rlc c","rlc d","rlc e","rlc h","rlc l","rlc (hl)","rlc a","rrc b","rrc c","rrc d","rrc e","rrc h","rrc l","rrc (hl)","rrc a","rl b","rl c","rl d","rl e","rl h","rl l","rl (hl)","rl a","rr b","rr c","rr d","rr e","rr h","rr l","rr (hl)","rr a","sla b","sla c","sla d","sla e","sla h","sla l","sla (hl)","sla a","sra b","sra c","sra d","sra e","sra h","sra l","sra (hl)","sra a","swap b","swap c","swap d","swap e","swap h","swap l","swap (hl)","swap a","srl b","srl c","srl d","srl e","srl h","srl l","srl (hl)","srl a","bit 0,b","bit 0,c","bit 0,d","bit 0,e","bit 0,h","bit 0,l","bit 0,(hl)","bit 0,a","bit 1,b","bit 1,c","bit 1,d","bit 1,e","bit 1,h","bit 1,l","bit 1,(hl)","bit 1,a","bit 2,b","bit 2,c","bit 2,d","bit 2,e","bit 2,h","bit 2,l","bit 2,(hl)","bit 2,a","bit 3,b","bit 3,c","bit 3,d","bit 3,e","bit 3,h","bit 3,l","bit 3,(hl)","bit 3,a","bit 4,b","bit 4,c","bit 4,d","bit 4,e","bit 4,h","bit 4,l","bit 4,(hl)","bit 4,a","bit 5,b","bit 5,c","bit 5,d","bit 5,e","bit 5,h","bit 5,l","bit 5,(hl)","bit 5,a","bit 6,b","bit 6,c","bit 6,d","bit 6,e","bit 6,h","bit 6,l","bit 6,(hl)","bit 6,a","bit 7,b","bit 7,c","bit 7,d","bit 7,e","bit 7,h","bit 7,l","bit 7,(hl)","bit 7,a","res 0,b","res 0,c","res 0,d","res 0,e","res 0,h","res 0,l","res 0,(hl)","res 0,a","res 1,b","res 1,c","res 1,d","res 1,e","res 1,h","res 1,l","res 1,(hl)","res 1,a","res 2,b","res 2,c","res 2,d","res 2,e","res 2,h","res 2,l","res 2,(hl)","res 2,a","res 3,b","res 3,c","res 3,d","res 3,e","res 3,h","res 3,l","res 3,(hl)","res 3,a","res 4,b","res 4,c","res 4,d","res 4,e","res 4,h","res 4,l","res 4,(hl)","res 4,a","res 5,b","res 5,c","res 5,d","res 5,e","res 5,h","res 5,l","res 5,(hl)","res 5,a","res 6,b","res 6,c","res 6,d","res 6,e","res 6,h","res 6,l","res 6,(hl)","res 6,a","res 7,b","res 7,c","res 7,d","res 7,e","res 7,h","res 7,l","res 7,(hl)","res 7,a","set 0,b","set 0,c","set 0,d","set 0,e","set 0,h","set 0,l","set 0,(hl)","set 0,a","set 1,b","set 1,c","set 1,d","set 1,e","set 1,h","set 1,l","set 1,(hl)","set 1,a","set 2,b","set 2,c","set 2,d","set 2,e","set 2,h","set 2,l","set 2,(hl)","set 2,a","set 3,b","set 3,c","set 3,d","set 3,e","set 3,h","set 3,l","set 3,(hl)","set 3,a","set 4,b","set 4,c","set 4,d","set 4,e","set 4,h","set 4,l","set 4,(hl)","set 4,a","set 5,b","set 5,c","set 5,d","set 5,e","set 5,h","set 5,l","set 5,(hl)","set 5,a","set 6,b","set 6,c","set 6,d","set 6,e","set 6,h","set 6,l","set 6,(hl)","set 6,a","set 7,b","set 7,c","set 7,d","set 7,e","set 7,h","set 7,l","set 7,(hl)","set 7,a"];function X(A,t,e,s){var i,h=1,r=!1;if(t===203?(i=re[e],h=2):i=he[t],(!i||!i.length||i==="??")&&(i="??"),/\bLine truncated
//# sourceMappingURL=gb-CFUFZHGK.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/common/cpu/SM83.ts", "../src/machine/gb.ts", "../src/common/cpu/disasmSM83.ts", "../src/platform/gb.ts"],
"sourcesContent": ["\nimport { Bus, CPU, InstructionBased, Interruptable, MemoryBusConnected, SavesState } from \"../devices\";\n\nexport interface SM83State {\n PC: number;\n SP: number;\n AF: number;\n BC: number;\n DE: number;\n HL: number;\n o: number; // last opcode\n ime: number;\n halted: boolean;\n interrupt: number;\n}\n\n// SM83 CPU \u2014 the Game Boy's modified Z80\n// No IX/IY, no shadow registers, no I/R, no IO bus\n// 4 flags only: Z(7), N(6), H(5), C(4) in F register\n// CB prefix for bit ops + SWAP\n// Single IME flag, memory-mapped IF/IE\n\nexport class SM83 implements CPU, InstructionBased, SavesState<SM83State>, Interruptable<number>, MemoryBusConnected {\n\n // Registers\n A: number = 0;\n F: number = 0;\n B: number = 0;\n C: number = 0;\n D: number = 0;\n E: number = 0;\n H: number = 0;\n L: number = 0;\n SP: number = 0xFFFE;\n PC: number = 0x0100;\n\n // Interrupt master enable\n ime: boolean = false;\n imeDelay: boolean = false; // EI delays by one instruction\n halted: boolean = false;\n // Pending interrupt request (set by machine via interrupt())\n interruptFlags: number = 0;\n\n bus: Bus;\n cyclesPerInsn: number = 0;\n o: number = 0; // last opcode\n stable: boolean = true;\n\n // Flag bit positions in F register\n static FLAG_Z = 0x80;\n static FLAG_N = 0x40;\n static FLAG_H = 0x20;\n static FLAG_C = 0x10;\n\n connectMemoryBus(bus: Bus): void {\n this.bus = bus;\n }\n\n reset(): void {\n // After boot ROM, typical state:\n this.A = 0x01;\n this.F = 0xB0;\n this.B = 0x00;\n this.C = 0x13;\n this.D = 0x00;\n this.E = 0xD8;\n this.H = 0x01;\n this.L = 0x4D;\n this.SP = 0xFFFE;\n this.PC = 0x0100;\n this.ime = false;\n this.imeDelay = false;\n this.halted = false;\n this.interruptFlags = 0;\n }\n\n interrupt(type: number): void {\n this.interruptFlags |= type;\n }\n\n getPC(): number { return this.PC; }\n getSP(): number { return this.SP; }\n isStable(): boolean { return this.stable; }\n\n saveState(): SM83State {\n return {\n PC: this.PC,\n SP: this.SP,\n AF: (this.A << 8) | this.F,\n BC: (this.B << 8) | this.C,\n DE: (this.D << 8) | this.E,\n HL: (this.H << 8) | this.L,\n o: this.o,\n ime: this.ime ? 1 : 0,\n halted: this.halted,\n interrupt: this.interruptFlags,\n };\n }\n\n loadState(state: SM83State): void {\n this.PC = state.PC;\n this.SP = state.SP;\n this.A = (state.AF >> 8) & 0xFF;\n this.F = state.AF & 0xF0; // lower 4 bits always 0\n this.B = (state.BC >> 8) & 0xFF;\n this.C = state.BC & 0xFF;\n this.D = (state.DE >> 8) & 0xFF;\n this.E = state.DE & 0xFF;\n this.H = (state.HL >> 8) & 0xFF;\n this.L = state.HL & 0xFF;\n this.o = state.o;\n this.ime = !!state.ime;\n this.halted = state.halted;\n this.interruptFlags = state.interrupt;\n }\n\n // Helper accessors for 16-bit register pairs\n getAF(): number { return (this.A << 8) | (this.F & 0xF0); }\n getBC(): number { return (this.B << 8) | this.C; }\n getDE(): number { return (this.D << 8) | this.E; }\n getHL(): number { return (this.H << 8) | this.L; }\n\n setAF(v: number): void { this.A = (v >> 8) & 0xFF; this.F = v & 0xF0; }\n setBC(v: number): void { this.B = (v >> 8) & 0xFF; this.C = v & 0xFF; }\n setDE(v: number): void { this.D = (v >> 8) & 0xFF; this.E = v & 0xFF; }\n setHL(v: number): void { this.H = (v >> 8) & 0xFF; this.L = v & 0xFF; }\n\n // Memory helpers\n read(addr: number): number {\n return this.bus.read(addr & 0xFFFF);\n }\n write(addr: number, val: number): void {\n this.bus.write(addr & 0xFFFF, val & 0xFF);\n }\n readWord(addr: number): number {\n return this.read(addr) | (this.read(addr + 1) << 8);\n }\n writeWord(addr: number, val: number): void {\n this.write(addr, val & 0xFF);\n this.write(addr + 1, (val >> 8) & 0xFF);\n }\n\n // Fetch byte at PC, advance PC\n fetchByte(): number {\n var v = this.read(this.PC);\n this.PC = (this.PC + 1) & 0xFFFF;\n return v;\n }\n fetchWord(): number {\n var lo = this.fetchByte();\n var hi = this.fetchByte();\n return (hi << 8) | lo;\n }\n fetchSignedByte(): number {\n var v = this.fetchByte();\n return v < 128 ? v : v - 256;\n }\n\n // Stack helpers\n pushWord(val: number): void {\n this.SP = (this.SP - 1) & 0xFFFF;\n this.write(this.SP, (val >> 8) & 0xFF);\n this.SP = (this.SP - 1) & 0xFFFF;\n this.write(this.SP, val & 0xFF);\n }\n popWord(): number {\n var lo = this.read(this.SP);\n this.SP = (this.SP + 1) & 0xFFFF;\n var hi = this.read(this.SP);\n this.SP = (this.SP + 1) & 0xFFFF;\n return (hi << 8) | lo;\n }\n\n // Flag helpers\n getZ(): boolean { return !!(this.F & SM83.FLAG_Z); }\n getN(): boolean { return !!(this.F & SM83.FLAG_N); }\n getH(): boolean { return !!(this.F & SM83.FLAG_H); }\n getC(): boolean { return !!(this.F & SM83.FLAG_C); }\n\n setZ(b: boolean): Line truncated
"mappings": "0LAsBO,IAAMA,EAAN,MAAMA,CAAwG,CAA9G,cAGL,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,OAAY,EACZ,QAAa,MACb,QAAa,IAGb,SAAe,GACf,cAAoB,GACpB,YAAkB,GAElB,oBAAyB,EAGzB,mBAAwB,EACxB,OAAY,EACZ,YAAkB,GAQlB,iBAAiBC,EAAgB,CAC/B,KAAK,IAAMA,CACb,CAEA,OAAc,CAEZ,KAAK,EAAI,EACT,KAAK,EAAI,IACT,KAAK,EAAI,EACT,KAAK,EAAI,GACT,KAAK,EAAI,EACT,KAAK,EAAI,IACT,KAAK,EAAI,EACT,KAAK,EAAI,GACT,KAAK,GAAK,MACV,KAAK,GAAK,IACV,KAAK,IAAM,GACX,KAAK,SAAW,GAChB,KAAK,OAAS,GACd,KAAK,eAAiB,CACxB,CAEA,UAAUC,EAAoB,CAC5B,KAAK,gBAAkBA,CACzB,CAEA,OAAgB,CAAE,OAAO,KAAK,EAAI,CAClC,OAAgB,CAAE,OAAO,KAAK,EAAI,CAClC,UAAoB,CAAE,OAAO,KAAK,MAAQ,CAE1C,WAAuB,CACrB,MAAO,CACL,GAAI,KAAK,GACT,GAAI,KAAK,GACT,GAAK,KAAK,GAAK,EAAK,KAAK,EACzB,GAAK,KAAK,GAAK,EAAK,KAAK,EACzB,GAAK,KAAK,GAAK,EAAK,KAAK,EACzB,GAAK,KAAK,GAAK,EAAK,KAAK,EACzB,EAAG,KAAK,EACR,IAAK,KAAK,IAAM,EAAI,EACpB,OAAQ,KAAK,OACb,UAAW,KAAK,cAClB,CACF,CAEA,UAAUC,EAAwB,CAChC,KAAK,GAAKA,EAAM,GAChB,KAAK,GAAKA,EAAM,GAChB,KAAK,EAAKA,EAAM,IAAM,EAAK,IAC3B,KAAK,EAAIA,EAAM,GAAK,IACpB,KAAK,EAAKA,EAAM,IAAM,EAAK,IAC3B,KAAK,EAAIA,EAAM,GAAK,IACpB,KAAK,EAAKA,EAAM,IAAM,EAAK,IAC3B,KAAK,EAAIA,EAAM,GAAK,IACpB,KAAK,EAAKA,EAAM,IAAM,EAAK,IAC3B,KAAK,EAAIA,EAAM,GAAK,IACpB,KAAK,EAAIA,EAAM,EACf,KAAK,IAAM,CAAC,CAACA,EAAM,IACnB,KAAK,OAASA,EAAM,OACpB,KAAK,eAAiBA,EAAM,SAC9B,CAGA,OAAgB,CAAE,OAAQ,KAAK,GAAK,EAAM,KAAK,EAAI,GAAO,CAC1D,OAAgB,CAAE,OAAQ,KAAK,GAAK,EAAK,KAAK,CAAG,CACjD,OAAgB,CAAE,OAAQ,KAAK,GAAK,EAAK,KAAK,CAAG,CACjD,OAAgB,CAAE,OAAQ,KAAK,GAAK,EAAK,KAAK,CAAG,CAEjD,MAAMC,EAAiB,CAAE,KAAK,EAAKA,GAAK,EAAK,IAAM,KAAK,EAAIA,EAAI,GAAM,CACtE,MAAMA,EAAiB,CAAE,KAAK,EAAKA,GAAK,EAAK,IAAM,KAAK,EAAIA,EAAI,GAAM,CACtE,MAAMA,EAAiB,CAAE,KAAK,EAAKA,GAAK,EAAK,IAAM,KAAK,EAAIA,EAAI,GAAM,CACtE,MAAMA,EAAiB,CAAE,KAAK,EAAKA,GAAK,EAAK,IAAM,KAAK,EAAIA,EAAI,GAAM,CAGtE,KAAKC,EAAsB,CACzB,OAAO,KAAK,IAAI,KAAKA,EAAO,KAAM,CACpC,CACA,MAAMA,EAAcC,EAAmB,CACrC,KAAK,IAAI,MAAMD,EAAO,MAAQC,EAAM,GAAI,CAC1C,CACA,SAASD,EAAsB,CAC7B,OAAO,KAAK,KAAKA,CAAI,EAAK,KAAK,KAAKA,EAAO,CAAC,GAAK,CACnD,CACA,UAAUA,EAAcC,EAAmB,CACzC,KAAK,MAAMD,EAAMC,EAAM,GAAI,EAC3B,KAAK,MAAMD,EAAO,EAAIC,GAAO,EAAK,GAAI,CACxC,CAGA,WAAoB,CAClB,IAAIF,EAAI,KAAK,KAAK,KAAK,EAAE,EACzB,YAAK,GAAM,KAAK,GAAK,EAAK,MACnBA,CACT,CACA,WAAoB,CAClB,IAAIG,EAAK,KAAK,UAAU,EACpBC,EAAK,KAAK,UAAU,EACxB,OAAQA,GAAM,EAAKD,CACrB,CACA,iBAA0B,CACxB,IAAIH,EAAI,KAAK,UAAU,EACvB,OAAOA,EAAI,IAAMA,EAAIA,EAAI,GAC3B,CAGA,SAASE,EAAmB,CAC1B,KAAK,GAAM,KAAK,GAAK,EAAK,MAC1B,KAAK,MAAM,KAAK,GAAKA,GAAO,EAAK,GAAI,EACrC,KAAK,GAAM,KAAK,GAAK,EAAK,MAC1B,KAAK,MAAM,KAAK,GAAIA,EAAM,GAAI,CAChC,CACA,SAAkB,CAChB,IAAIC,EAAK,KAAK,KAAK,KAAK,EAAE,EAC1B,KAAK,GAAM,KAAK,GAAK,EAAK,MAC1B,IAAIC,EAAK,KAAK,KAAK,KAAK,EAAE,EAC1B,YAAK,GAAM,KAAK,GAAK,EAAK,MAClBA,GAAM,EAAKD,CACrB,CAGA,MAAgB,CAAE,MAAO,CAAC,EAAE,KAAK,EAAIP,EAAK,OAAS,CACnD,MAAgB,CAAE,MAAO,CAAC,EAAE,KAAK,EAAIA,EAAK,OAAS,CACnD,MAAgB,CAAE,MAAO,CAAC,EAAE,KAAK,EAAIA,EAAK,OAAS,CACnD,MAAgB,CAAE,MAAO,CAAC,EAAE,KAAK,EAAIA,EAAK,OAAS,CAEnD,KAAKS,EAAkB,CAAMA,EAAG,KAAK,GAAKT,EAAK,OAAa,KAAK,GAAK,CAACA,EAAK,MAAQ,CACpF,KAAKS,EAAkB,CAAMA,EAAG,KAAK,GAAKT,EAAK,OAAa,KAAK,GAAK,CAACA,EAAK,MAAQ,CACpF,KAAKS,EAAkB,CAAMA,EAAG,KAAK,GAAKT,EAAK,OAAa,KAAK,GAAK,CAACA,EAAK,MAAQ,CACpF,KAAKS,EAAkB,CAAMA,EAAG,KAAK,GAAKT,EAAK,OAAa,KAAK,GAAK,CAACA,EAAK,MAAQ,CAEpF,SAASU,EAAYC,EAAYC,EAAYC,EAAkB,CAC7D,KAAK,GAAKH,EAAIV,EAAK,OAAS,IAAMW,EAAIX,EAAK,OAAS,IAAMY,EAAIZ,EAAK,OAAS,IAAMa,EAAIb,EAAK,OAAS,EACtG,CAIA,OAAOc,EAAmB,CACxB,OAAQA,EAAG,CACT,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,EACpB,IAAK,GAAG,OAAO,KAAK,KAAK,KAAK,MAAM,CAAC,EACrC,IAAK,GAAG,OAAO,KAAK,CACtB,CACA,MAAO,EACT,CACA,OAAOA,EAAWV,EAAiB,CAEjC,OADAA,GAAK,IACGU,EAAG,CACT,IAAK,GAAG,KAAK,EAAIV,EAAG,MACpB,IAAK,GAAG,KAAK,EAAIA,EAAG,MACpB,IAAK,GAAG,KAAK,EAAIA,EAAG,MACpB,IAAK,GAAG,KAAK,EAAIA,EAAG,MACpB,IAAK,GAAG,KAAK,EAAIA,EAAG,MACpB,IAAK,GAAG,KAAK,EAAIA,EAAG,MACpB,IAAK,GAAG,KAAK,MAAM,KAAK,MAAM,EAAGA,CAAC,EAAG,MACrC,IAAK,GAAG,KAAK,EAAIA,EAAG,KACtB,CACF,CAIA,SAASU,EAAmB,CAC1B,OAAQA,EAAG,CACT,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,EACtB,CACA,MAAO,EACT,CACA,SAASA,EAAWV,EAAiB,CAEnC,OADAA,GAAK,MACGU,EAAG,CACT,IAAK,GAAG,KAAK,MAAMV,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,MAAMA,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,MAAMA,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,GAAKA,EAAG,KACvB,CACF,CAGA,WAAWU,EAAmB,CAC5B,OAAQA,EAAG,CACT,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,MAAM,EAC1B,IAAK,GAAG,OAAO,KAAK,MAAM,CAC5B,CACA,MAAO,EACT,CACA,WAAWA,EAAWV,EAAiB,CAErC,OADAA,GAAK,MACGU,EAAG,CACT,IAAK,GAAG,KAAK,MAAMV,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,MAAMA,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,MAAMA,CAAC,EAAG,MACvB,IAAK,GAAG,KAAK,MAAMA,CAAC,EAAG,KACzB,CACF,CAIA,eAAeW,EAAqB,CAClC,OAAQA,EAAI,CACV,IAAK,GAAG,MAAO,CAAC,KAAK,KAAK,EAC1B,IAAK,GAAG,OAAO,KAAK,KAAK,EACzB,IAAK,GAAG,MAAO,CAAC,KAAK,KAAK,EAC1B,IAAK,GAAG,OAAO,KAAK,KAAK,CAC3B,CACA,MAAO,EACT,CAGA,KAAKT,EAAmB,CACtB,IAAIU,EAAS,KAAK,EAAIV,EACtB,KAAK,UACFU,EAAS,OAAU,EACpB,IACE,KAAK,Line truncated
"names": ["_SM83", "bus", "type", "state", "v", "addr", "val", "lo", "hi", "b", "z", "n", "h", "c", "i", "cc", "result", "carry", "op", "hl", "a", "opcode", "reg", "cycles", "bit", "intCycles", "x", "y", "p", "q", "e", "bit7", "bit0", "cbop", "SM83", "DMG_PALETTE", "cgbColorToARGB", "lo", "hi", "r5", "g5", "b5", "r8", "g8", "b8", "GB_KEYCODE_MAP", "makeKeycodeMap", "Keys", "DUTY_TABLE", "NR_READ_MASKS", "GameBoyAPU", "addr", "val", "regIndex", "wasEnabled", "divisor", "newFreq", "tCycles", "t", "sampleByte", "xor", "ch1out", "ch2out", "ch3out", "ch4out", "waveSample", "dac1", "dac2", "dac3", "dac4", "left", "right", "leftVol", "rightVol", "state", "GameBoyMachine", "BasicScanlineMachine", "SM83", "newAddressDecoder", "a", "v", "newKeyboardHandler", "bank", "fullAddr", "offset", "result", "srcBase", "length", "src", "dst", "i", "cycles", "timerPeriod", "pending", "handled", "oldFlags", "c", "n", "samplePeriod", "oldMode", "mCycles", "lineOffset", "x", "palette", "colorIndex", "shade", "cram", "paletteNum", "idx", "tileMap", "signed", "y", "tileRow", "tileYOffset", "scrolledX", "tileCol", "tileXBit", "mapOffset", "tileIndex", "tileAddr", "attr", "cgbPalette", "vramBank", "xFlip", "yFlip", "bgPri", "tileY", "tileBit", "wxAdjusted", "winY", "drawn", "winX", "spriteHeight", "spritesOnLine", "sprites", "b", "si", "spriteIndex", "yPos", "xPos", "flags", "bgPriority", "spriteVramBank", "px", "screenX", "bit", "bgMaster", "bgColor", "data", "title", "cartType", "EmuHalt", "cgbFlag", "numBanks", "io", "cgb", "category", "s", "hex", "SM83_OPS", "SM83_OPS_CB", "disassembleSM83", "pc", "b0", "b1", "b2", "am", "n", "isaddr", "hex", "operand", "offset", "GB_PRESETS", "GameBoyPlatform", "BaseMachinePlatform", "getToolForFilename_z80", "GameBoyMachine", "a", "isDebuggable", "category", "state", "cpuStateToLongString_SM83", "sp", "start", "end", "dumpStackToString", "pc", "read", "disassembleSM83", "GBC_PRESETS", "GameBoyColorPlatform", "m", "PLATFORMS"]
}
-12
View File
@@ -1,12 +0,0 @@
import{C as U,E as j,G as z,H as N,r as G,u as D}from"./chunk-GTDJ7CMC.js";import{K as B,T as W,W as o,X as V,Z as O,aa as M,g as n}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var x=class x{constructor(){this.A=0;this.F=0;this.B=0;this.C=0;this.D=0;this.E=0;this.H=0;this.L=0;this.SP=65534;this.PC=256;this.ime=!1;this.imeDelay=!1;this.halted=!1;this.interruptFlags=0;this.cyclesPerInsn=0;this.o=0;this.stable=!0}connectMemoryBus(t){this.bus=t}reset(){this.A=1,this.F=176,this.B=0,this.C=19,this.D=0,this.E=216,this.H=1,this.L=77,this.SP=65534,this.PC=256,this.ime=!1,this.imeDelay=!1,this.halted=!1,this.interruptFlags=0}interrupt(t){this.interruptFlags|=t}getPC(){return this.PC}getSP(){return this.SP}isStable(){return this.stable}saveState(){return{PC:this.PC,SP:this.SP,AF:this.A<<8|this.F,BC:this.B<<8|this.C,DE:this.D<<8|this.E,HL:this.H<<8|this.L,o:this.o,ime:this.ime?1:0,halted:this.halted,interrupt:this.interruptFlags}}loadState(t){this.PC=t.PC,this.SP=t.SP,this.A=t.AF>>8&255,this.F=t.AF&240,this.B=t.BC>>8&255,this.C=t.BC&255,this.D=t.DE>>8&255,this.E=t.DE&255,this.H=t.HL>>8&255,this.L=t.HL&255,this.o=t.o,this.ime=!!t.ime,this.halted=t.halted,this.interruptFlags=t.interrupt}getAF(){return this.A<<8|this.F&240}getBC(){return this.B<<8|this.C}getDE(){return this.D<<8|this.E}getHL(){return this.H<<8|this.L}setAF(t){this.A=t>>8&255,this.F=t&240}setBC(t){this.B=t>>8&255,this.C=t&255}setDE(t){this.D=t>>8&255,this.E=t&255}setHL(t){this.H=t>>8&255,this.L=t&255}read(t){return this.bus.read(t&65535)}write(t,e){this.bus.write(t&65535,e&255)}readWord(t){return this.read(t)|this.read(t+1)<<8}writeWord(t,e){this.write(t,e&255),this.write(t+1,e>>8&255)}fetchByte(){var t=this.read(this.PC);return this.PC=this.PC+1&65535,t}fetchWord(){var t=this.fetchByte(),e=this.fetchByte();return e<<8|t}fetchSignedByte(){var t=this.fetchByte();return t<128?t:t-256}pushWord(t){this.SP=this.SP-1&65535,this.write(this.SP,t>>8&255),this.SP=this.SP-1&65535,this.write(this.SP,t&255)}popWord(){var t=this.read(this.SP);this.SP=this.SP+1&65535;var e=this.read(this.SP);return this.SP=this.SP+1&65535,e<<8|t}getZ(){return!!(this.F&x.FLAG_Z)}getN(){return!!(this.F&x.FLAG_N)}getH(){return!!(this.F&x.FLAG_H)}getC(){return!!(this.F&x.FLAG_C)}setZ(t){t?this.F|=x.FLAG_Z:this.F&=~x.FLAG_Z}setN(t){t?this.F|=x.FLAG_N:this.F&=~x.FLAG_N}setH(t){t?this.F|=x.FLAG_H:this.F&=~x.FLAG_H}setC(t){t?this.F|=x.FLAG_C:this.F&=~x.FLAG_C}setFlags(t,e,s,h){this.F=(t?x.FLAG_Z:0)|(e?x.FLAG_N:0)|(s?x.FLAG_H:0)|(h?x.FLAG_C:0)}getReg(t){switch(t){case 0:return this.B;case 1:return this.C;case 2:return this.D;case 3:return this.E;case 4:return this.H;case 5:return this.L;case 6:return this.read(this.getHL());case 7:return this.A}return 0}setReg(t,e){switch(e&=255,t){case 0:this.B=e;break;case 1:this.C=e;break;case 2:this.D=e;break;case 3:this.E=e;break;case 4:this.H=e;break;case 5:this.L=e;break;case 6:this.write(this.getHL(),e);break;case 7:this.A=e;break}}getReg16(t){switch(t){case 0:return this.getBC();case 1:return this.getDE();case 2:return this.getHL();case 3:return this.SP}return 0}setReg16(t,e){switch(e&=65535,t){case 0:this.setBC(e);break;case 1:this.setDE(e);break;case 2:this.setHL(e);break;case 3:this.SP=e;break}}getReg16AF(t){switch(t){case 0:return this.getBC();case 1:return this.getDE();case 2:return this.getHL();case 3:return this.getAF()}return 0}setReg16AF(t,e){switch(e&=65535,t){case 0:this.setBC(e);break;case 1:this.setDE(e);break;case 2:this.setHL(e);break;case 3:this.setAF(e);break}}checkCondition(t){switch(t){case 0:return!this.getZ();case 1:return this.getZ();case 2:return!this.getC();case 3:return this.getC()}return!1}addA(t){var e=this.A+t;this.setFlags((e&255)===0,!1,(this.A&15)+(t&15)>15,e>255),this.A=e&255}adcA(t){var e=this.getC()?1:0,s=this.A+t+e;this.setFlags((s&255)===0,!1,(this.A&15)+(t&15)+e>15,s>255),this.A=s&255}subA(t){var e=this.A-t;this.setFlags((e&255)===0,!0,(this.A&15)<(t&15),e<0),this.A=e&255}sbcA(t){var e=this.getC()?1:0,s=this.A-t-e;this.setFlags((s&255)===0,!0,(this.A&15)<(t&15)+e,s<0),this.A=s&255}andA(t){this.A&=t,this.setFlags(this.A===0,!1,!0,!1)}xorA(t){this.A^=t,this.A&=255,this.setFlags(this.A===0,!1,!1,!1)}orA(t){this.A|=t,this.A&=255,this.setFlags(this.A===0,!1,!1,!1)}cpA(t){var e=this.A-t;this.setFlags((e&255)===0,!0,(this.A&15)<(t&15),e<0)}aluOp(t,e){switch(t){case 0:this.addA(e);break;case 1:this.adcA(e);break;case 2:this.subA(e);break;case 3:this.sbcA(e);break;case 4:this.andA(e);break;case 5:this.xorA(e);break;case 6:this.orA(e);break;case 7:this.cpA(e);break}}inc8(t){var e=t+1&255;return this.setZ(e===0),this.setN(!1),this.setH((t&15)===15),e}dec8(t){var e=t-1&255;return this.setZ(e===0),this.setN(!0),this.setH((t&15)===0),e}addHL(t){var e=this.getHL(),s=e+t;this.setN(!1),this.setH((e&4095)+(t&4095)>4095),this.setC(s>65535),this.setHL(s&65535)}daa(){var t=this.A;this.getN()?(this.getC()&&(t-=96),this.getH()&&(t-=6)):((this.getC()||t>153)&&(t+=96,this.setC(!0)),(this.getH()||(t&15)>9)&&(t+=6)),t&=255,this.setZ(tLine truncated
LY `+n(this.ly,2)+" LYC "+n(this.lyc,2)+`
SCX `+n(this.scx,2)+" SCY "+n(this.scy,2)+`
WX `+n(this.wx,2)+" WY "+n(this.wy,2)+`
BGP `+n(this.bgp,2)+" OBP0 "+n(this.obp0,2)+`
OBP1 `+n(this.obp1,2)+" DMA "+n(this.dma,2)+`
IF `+n(this.iflag,2)+" IE "+n(this.ie,2)+`
DIV `+n(this.divCounter>>8&255,2)+" TIMA "+n(this.tima,2)+`
TMA `+n(this.tma,2)+" TAC "+n(this.tac,2)+`
Bank `+this.romBank+`
`}}};var X=["nop","ld bc,xx","ld (bc),a","inc bc","inc b","dec b","ld b,x","rlca","ld (xx),sp","add hl,bc","ld a,(bc)","dec bc","inc c","dec c","ld c,x","rrca","stop x","ld de,xx","ld (de),a","inc de","inc d","dec d","ld d,x","rla","jr x","add hl,de","ld a,(de)","dec de","inc e","dec e","ld e,x","rra","jr nz,x","ld hl,xx","ld (hl+),a","inc hl","inc h","dec h","ld h,x","daa","jr z,x","add hl,hl","ld a,(hl+)","dec hl","inc l","dec l","ld l,x","cpl","jr nc,x","ld sp,xx","ld (hl-),a","inc sp","inc (hl)","dec (hl)","ld (hl),x","scf","jr c,x","add hl,sp","ld a,(hl-)","dec sp","inc a","dec a","ld a,x","ccf","ld b,b","ld b,c","ld b,d","ld b,e","ld b,h","ld b,l","ld b,(hl)","ld b,a","ld c,b","ld c,c","ld c,d","ld c,e","ld c,h","ld c,l","ld c,(hl)","ld c,a","ld d,b","ld d,c","ld d,d","ld d,e","ld d,h","ld d,l","ld d,(hl)","ld d,a","ld e,b","ld e,c","ld e,d","ld e,e","ld e,h","ld e,l","ld e,(hl)","ld e,a","ld h,b","ld h,c","ld h,d","ld h,e","ld h,h","ld h,l","ld h,(hl)","ld h,a","ld l,b","ld l,c","ld l,d","ld l,e","ld l,h","ld l,l","ld l,(hl)","ld l,a","ld (hl),b","ld (hl),c","ld (hl),d","ld (hl),e","ld (hl),h","ld (hl),l","halt","ld (hl),a","ld a,b","ld a,c","ld a,d","ld a,e","ld a,h","ld a,l","ld a,(hl)","ld a,a","add a,b","add a,c","add a,d","add a,e","add a,h","add a,l","add a,(hl)","add a,a","adc a,b","adc a,c","adc a,d","adc a,e","adc a,h","adc a,l","adc a,(hl)","adc a,a","sub b","sub c","sub d","sub e","sub h","sub l","sub (hl)","sub a","sbc a,b","sbc a,c","sbc a,d","sbc a,e","sbc a,h","sbc a,l","sbc a,(hl)","sbc a,a","and b","and c","and d","and e","and h","and l","and (hl)","and a","xor b","xor c","xor d","xor e","xor h","xor l","xor (hl)","xor a","or b","or c","or d","or e","or h","or l","or (hl)","or a","cp b","cp c","cp d","cp e","cp h","cp l","cp (hl)","cp a","ret nz","pop bc","jp nz,xx","jp xx","call nz,xx","push bc","add a,x","rst 00h","ret z","ret","jp z,xx","xxCBxx","call z,xx","call xx","adc a,x","rst 08h","ret nc","pop de","jp nc,xx","??","call nc,xx","push de","sub x","rst 10h","ret c","reti","jp c,xx","??","call c,xx","??","sbc a,x","rst 18h","ldh (x),a","pop hl","ld (c),a","??","??","push hl","and x","rst 20h","add sp,x","jp (hl)","ld (xx),a","??","??","??","xor x","rst 28h","ldh a,(x)","pop af","ld a,(c)","di","??","push af","or x","rst 30h","ld hl,sp+x","ld sp,hl","ld a,(xx)","ei","??","??","cp x","rst 38h"],ee=["rlc b","rlc c","rlc d","rlc e","rlc h","rlc l","rlc (hl)","rlc a","rrc b","rrc c","rrc d","rrc e","rrc h","rrc l","rrc (hl)","rrc a","rl b","rl c","rl d","rl e","rl h","rl l","rl (hl)","rl a","rr b","rr c","rr d","rr e","rr h","rr l","rr (hl)","rr a","sla b","sla c","sla d","sla e","sla h","sla l","sla (hl)","sla a","sra b","sra c","sra d","sra e","sra h","sra l","sra (hl)","sra a","swap b","swap c","swap d","swap e","swap h","swap l","swap (hl)","swap a","srl b","srl c","srl d","srl e","srl h","srl l","srl (hl)","srl a","bit 0,b","bit 0,c","bit 0,d","bit 0,e","bit 0,h","bit 0,l","bit 0,(hl)","bit 0,a","bit 1,b","bit 1,c","bit 1,d","bit 1,e","bit 1,h","bit 1,l","bit 1,(hl)","bit 1,a","bit 2,b","bit 2,c","bit 2,d","bit 2,e","bit 2,h","bit 2,l","bit 2,(hl)","bit 2,a","bit 3,b","bit 3,c","bit 3,d","bit 3,e","bit 3,h","bit 3,l","bit 3,(hl)","bit 3,a","bit 4,b","bit 4,c","bit 4,d","bit 4,e","bit 4,h","bit 4,l","bit 4,(hl)","bit 4,a","bit 5,b","bit 5,c","bit 5,d","bit 5,e","bit 5,h","bit 5,l","bit 5,(hl)","bit 5,a","bit 6,b","bit 6,c","bit 6,d","bit 6,e","bit 6,h","bit 6,l","bit 6,(hl)","bit 6,a","bit 7,b","bit 7,c","bit 7,d","bit 7,e","bit 7,h","bit 7,l","bit 7,(hl)","bit 7,a","res 0,b","res 0,c","res 0,d","res 0,e","res 0,h","res 0,l","res 0,(hl)","res 0,a","res 1,b","res 1,c","res 1,d","res 1,e","res 1,h","res 1,l","res 1,(hl)","res 1,a","res 2,b","res 2,c","res 2,d","res 2,e","res 2,h","res 2,l","res 2,(hl)","res 2,a","res 3,b","res 3,c","res 3,d","res 3,e","res 3,h","res 3,l","res 3,(hl)","res 3,a","res 4,b","res 4,c","res 4,d","res 4,e","res 4,h","res 4,l","res 4,(hl)","res 4,a","res 5,b","res 5,c","res 5,d","res 5,e","res 5,h","res 5,l","res 5,(hl)","res 5,a","res 6,b","res 6,c","res 6,d","res 6,e","res 6,h","res 6,l","res 6,(hl)","res 6,a","res 7,b","res 7,c","res 7,d","res 7,e","res 7,h","res 7,l","res 7,(hl)","res 7,a","set 0,b","set 0,c","set 0,d","set 0,e","set 0,h","set 0,l","set 0,(hl)","set 0,a","set 1,b","set 1,c","set 1,d","set 1,e","set 1,h","set 1,l","set 1,(hl)","set 1,a","set 2,b","set 2,c","set 2,d","set 2,e","set 2,h","set 2,l","set 2,(hl)","set 2,a","set 3,b","set 3,c","set 3,d","set 3,e","set 3,h","set 3,l","set 3,(hl)","set 3,a","set 4,b","set 4,c","set 4,d","set 4,e","set 4,h","set 4,l","set 4,(hl)","set 4,a","set 5,b","set 5,c","set 5,d","set 5,e","set 5,h","set 5,l","set 5,(hl)","set 5,a","set 6,b","set 6,c","set 6,d","set 6,e","set 6,h","set 6,l","set 6,(hl)","set 6,a","set 7,b","set 7,c","set 7,d","set 7,e","set 7,h","set 7,l","set 7,(hl)","set 7,a"];function K(v,t,e,s){var h,r=1,i=!1;if(t===203?(h=ee[e],r=2):h=X[t],(!h||!h.length||h==="??")&&(h="??"),/\bxx\b/ Line truncated
//# sourceMappingURL=gb-YCJUD6HA.js.map
-7
View File
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": ["../src/common/cpu/SM83.ts", "../src/machine/gb.ts", "../src/common/cpu/disasmSM83.ts", "../src/platform/gb.ts"],
"sourcesContent": ["\nimport { Bus, CPU, InstructionBased, Interruptable, MemoryBusConnected, SavesState } from \"../devices\";\n\nexport interface SM83State {\n PC: number;\n SP: number;\n AF: number;\n BC: number;\n DE: number;\n HL: number;\n o: number; // last opcode\n ime: number;\n halted: boolean;\n interrupt: number;\n}\n\n// SM83 CPU \u2014 the Game Boy's modified Z80\n// No IX/IY, no shadow registers, no I/R, no IO bus\n// 4 flags only: Z(7), N(6), H(5), C(4) in F register\n// CB prefix for bit ops + SWAP\n// Single IME flag, memory-mapped IF/IE\n\nexport class SM83 implements CPU, InstructionBased, SavesState<SM83State>, Interruptable<number>, MemoryBusConnected {\n\n // Registers\n A: number = 0;\n F: number = 0;\n B: number = 0;\n C: number = 0;\n D: number = 0;\n E: number = 0;\n H: number = 0;\n L: number = 0;\n SP: number = 0xFFFE;\n PC: number = 0x0100;\n\n // Interrupt master enable\n ime: boolean = false;\n imeDelay: boolean = false; // EI delays by one instruction\n halted: boolean = false;\n // Pending interrupt request (set by machine via interrupt())\n interruptFlags: number = 0;\n\n bus: Bus;\n cyclesPerInsn: number = 0;\n o: number = 0; // last opcode\n stable: boolean = true;\n\n // Flag bit positions in F register\n static FLAG_Z = 0x80;\n static FLAG_N = 0x40;\n static FLAG_H = 0x20;\n static FLAG_C = 0x10;\n\n connectMemoryBus(bus: Bus): void {\n this.bus = bus;\n }\n\n reset(): void {\n // After boot ROM, typical state:\n this.A = 0x01;\n this.F = 0xB0;\n this.B = 0x00;\n this.C = 0x13;\n this.D = 0x00;\n this.E = 0xD8;\n this.H = 0x01;\n this.L = 0x4D;\n this.SP = 0xFFFE;\n this.PC = 0x0100;\n this.ime = false;\n this.imeDelay = false;\n this.halted = false;\n this.interruptFlags = 0;\n }\n\n interrupt(type: number): void {\n this.interruptFlags |= type;\n }\n\n getPC(): number { return this.PC; }\n getSP(): number { return this.SP; }\n isStable(): boolean { return this.stable; }\n\n saveState(): SM83State {\n return {\n PC: this.PC,\n SP: this.SP,\n AF: (this.A << 8) | this.F,\n BC: (this.B << 8) | this.C,\n DE: (this.D << 8) | this.E,\n HL: (this.H << 8) | this.L,\n o: this.o,\n ime: this.ime ? 1 : 0,\n halted: this.halted,\n interrupt: this.interruptFlags,\n };\n }\n\n loadState(state: SM83State): void {\n this.PC = state.PC;\n this.SP = state.SP;\n this.A = (state.AF >> 8) & 0xFF;\n this.F = state.AF & 0xF0; // lower 4 bits always 0\n this.B = (state.BC >> 8) & 0xFF;\n this.C = state.BC & 0xFF;\n this.D = (state.DE >> 8) & 0xFF;\n this.E = state.DE & 0xFF;\n this.H = (state.HL >> 8) & 0xFF;\n this.L = state.HL & 0xFF;\n this.o = state.o;\n this.ime = !!state.ime;\n this.halted = state.halted;\n this.interruptFlags = state.interrupt;\n }\n\n // Helper accessors for 16-bit register pairs\n getAF(): number { return (this.A << 8) | (this.F & 0xF0); }\n getBC(): number { return (this.B << 8) | this.C; }\n getDE(): number { return (this.D << 8) | this.E; }\n getHL(): number { return (this.H << 8) | this.L; }\n\n setAF(v: number): void { this.A = (v >> 8) & 0xFF; this.F = v & 0xF0; }\n setBC(v: number): void { this.B = (v >> 8) & 0xFF; this.C = v & 0xFF; }\n setDE(v: number): void { this.D = (v >> 8) & 0xFF; this.E = v & 0xFF; }\n setHL(v: number): void { this.H = (v >> 8) & 0xFF; this.L = v & 0xFF; }\n\n // Memory helpers\n read(addr: number): number {\n return this.bus.read(addr & 0xFFFF);\n }\n write(addr: number, val: number): void {\n this.bus.write(addr & 0xFFFF, val & 0xFF);\n }\n readWord(addr: number): number {\n return this.read(addr) | (this.read(addr + 1) << 8);\n }\n writeWord(addr: number, val: number): void {\n this.write(addr, val & 0xFF);\n this.write(addr + 1, (val >> 8) & 0xFF);\n }\n\n // Fetch byte at PC, advance PC\n fetchByte(): number {\n var v = this.read(this.PC);\n this.PC = (this.PC + 1) & 0xFFFF;\n return v;\n }\n fetchWord(): number {\n var lo = this.fetchByte();\n var hi = this.fetchByte();\n return (hi << 8) | lo;\n }\n fetchSignedByte(): number {\n var v = this.fetchByte();\n return v < 128 ? v : v - 256;\n }\n\n // Stack helpers\n pushWord(val: number): void {\n this.SP = (this.SP - 1) & 0xFFFF;\n this.write(this.SP, (val >> 8) & 0xFF);\n this.SP = (this.SP - 1) & 0xFFFF;\n this.write(this.SP, val & 0xFF);\n }\n popWord(): number {\n var lo = this.read(this.SP);\n this.SP = (this.SP + 1) & 0xFFFF;\n var hi = this.read(this.SP);\n this.SP = (this.SP + 1) & 0xFFFF;\n return (hi << 8) | lo;\n }\n\n // Flag helpers\n getZ(): boolean { return !!(this.F & SM83.FLAG_Z); }\n getN(): boolean { return !!(this.F & SM83.FLAG_N); }\n getH(): boolean { return !!(this.F & SM83.FLAG_H); }\n getC(): boolean { return !!(this.F & SM83.FLAG_C); }\n\n setZ(b: boolean): Line truncated
"mappings": "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 truncated
"names": ["_SM83", "bus", "type", "state", "v", "addr", "val", "lo", "hi", "b", "z", "n", "h", "c", "i", "cc", "result", "carry", "op", "hl", "a", "opcode", "reg", "cycles", "bit", "intCycles", "x", "y", "p", "q", "e", "bit7", "bit0", "cbop", "SM83", "DMG_PALETTE", "GB_KEYCODE_MAP", "makeKeycodeMap", "Keys", "DUTY_TABLE", "NR_READ_MASKS", "GameBoyAPU", "addr", "val", "regIndex", "wasEnabled", "i", "divisor", "newFreq", "tCycles", "t", "sampleByte", "xor", "ch1out", "ch2out", "ch3out", "ch4out", "waveSample", "dac1", "dac2", "dac3", "dac4", "left", "right", "leftVol", "rightVol", "state", "GameBoyMachine", "BasicScanlineMachine", "SM83", "newAddressDecoder", "a", "v", "newKeyboardHandler", "bank", "fullAddr", "offset", "result", "srcBase", "cycles", "timerPeriod", "pending", "handled", "oldFlags", "c", "n", "samplePeriod", "oldMode", "mCycles", "lineOffset", "x", "palette", "colorIndex", "shade", "tileMap", "tileData", "signed", "y", "tileRow", "tileYOffset", "scrolledX", "tileCol", "tileXBit", "tileIndex", "tileAddr", "lo", "hi", "wxAdjusted", "winY", "drawn", "winX", "spriteHeight", "spritesOnLine", "sprites", "b", "si", "spriteIndex", "yPos", "xPos", "flags", "xFlip", "yFlip", "bgPriority", "tileY", "px", "screenX", "bit", "bgColor", "data", "title", "cartType", "EmuHalt", "numBanks", "io", "category", "hex", "SM83_OPS", "SM83_OPS_CB", "disassembleSM83", "pc", "b0", "b1", "b2", "am", "n", "isaddr", "hex", "operand", "offset", "GB_PRESETS", "GameBoyPlatform", "BaseMachinePlatform", "getToolForFilename_z80", "GameBoyMachine", "a", "isDebuggable", "category", "state", "cpuStateToLongString_SM83", "sp", "start", "end", "dumpStackToString", "pc", "read", "disassembleSM83", "PLATFORMS"]
}
+377
View File
@@ -0,0 +1,377 @@
"use strict";
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChannelF = void 0;
const F8_1 = require("../common/cpu/F8");
const devices_1 = require("../common/devices");
const emu_1 = require("../common/emu");
// Channel F color palette (RGBA)
const CHANNELF_COLORS = [
0xFF484848, // 0: dark gray/background (approximation for "field" color)
0xFF5050FF, // 1: blue
0xFF50FF50, // 2: green -> actually the red
0xFF808080, // 3: gray
0xFFFFFFFF, // 4: white (BG palette)
0xFF50FF50, // 5: green
0xFFFF5050, // 6: red
0xFFC8C8C8, // 7: light gray
];
// Full 16-entry color map (4 palette banks x 4 colors)
const CHANNELF_COLORMAP = [
// Palette 0 (default)
0xFF484848, // 0: background
0xFF50FF50, // 1: green
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 1
0xFFFF5050, // 0: red (background)
0xFF50FF50, // 1: green
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 2
0xFF484848, // 0: background
0xFFFF5050, // 1: red
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 3
0xFF484848, // 0: background
0xFF50FF50, // 1: green
0xFFFF5050, // 2: red
0xFF808080, // 3: gray
];
// Input port bit definitions
const INPUT_RIGHT = 0x01;
const INPUT_LEFT = 0x02;
const INPUT_BACK = 0x04;
const INPUT_FORWARD = 0x08;
const INPUT_CCW = 0x10; // counter-clockwise
const INPUT_CW = 0x20; // clockwise
const INPUT_PULL = 0x40;
const INPUT_PUSH = 0x80;
class ChannelF extends devices_1.BasicMachine {
constructor() {
super();
this.cpuFrequency = 1789773; // NTSC: 3.579545 MHz / 2
this.defaultROMSize = 0x10000;
// Video params
this.canvasWidth = 128;
this.numVisibleScanlines = 64;
this.numTotalScanlines = 64;
this.cpuCyclesPerLine = this.cpuFrequency / 60 / 64; // ~466 cycles per line
this.sampleRate = this.cpuFrequency / 2; // audio sample rate
this.cpu = new F8_1.F8CPU();
this.ram = new Uint8Array(0x10000); // address space (ROM + VRAM)
this.vram = new Uint8Array(0x2000); // 8KB video RAM (128x64, 2 bits per pixel)
// I/O port latches
this.port0 = 0; // console switches
this.port1 = 0; // right controller
this.port4 = 0; // left controller
this.port5 = 0; // row/column/sound
// Video registers
this.row_reg = 0;
this.col_reg = 0;
this.color = 0;
// Audio state
this.soundMode = 0;
this.soundCounter = 0;
this.soundEnvelope = 0;
this.soundOnTime = 0;
this.read = (0, emu_1.newAddressDecoder)([
[0x0000, 0x07FF, 0x07FF, (a) => { return this.bios[a]; }],
[0x0800, 0xFFFF, 0xFFFF, (a) => { return this.rom ? (this.rom[a - 0x0800] || 0) : 0; }],
], { gmask: 0xFFFF });
this.write = (0, emu_1.newAddressDecoder)([
// Channel F has no writable main memory in the base config
// Some cartridges have RAM at 0x2800-0x2FFF
[0x2800, 0x2FFF, 0x07FF, (a, v) => { if (this.rom)
this.rom[a - 0x0800] = v; }],
], { gmask: 0xFFFF });
this.bios = new Uint8Array(0x800); // 2KB BIOS
this.connectCPUMemoryBus(this);
this.cpu.connectIOBus(this.newIOBus());
}
newIOBus() {
return this.probeIOBus({
read: (port) => {
return this.readPort(port);
},
write: (port, val) => {
this.writePort(port, val);
}
});
}
readPort(port) {
switch (port & 0xFF) {
case 0:
// Console switches: TIME(0), MODE(1), HOLD(2), START(3)
return (~this.inputs[0]) & 0xFF;
case 1:
// Right controller
return (~this.inputs[1]) & 0xFF;
case 4:
// Left controller
return (~this.inputs[2]) & 0xFF;
default:
return 0xFF;
}
}
writePort(port, val) {
switch (port & 0xFF) {
case 0:
this.port0 = val;
break;
case 1:
this.port1 = val;
// The right controller port is also used for video column
this.col_reg = val;
break;
case 4:
this.port4 = val;
break;
case 5:
this.port5 = val;
// Upper 2 bits control sound
this.soundMode = (val >> 6) & 3;
if (this.soundMode > 0) {
this.soundEnvelope = 0x3FF; // reset envelope on new sound
this.soundOnTime = 60; // minimum on time (~2ms)
}
// Lower 6 bits control video row
this.row_reg = val & 0x3F;
// Write pixel to VRAM when both row and column are set
this.writePixel();
break;
}
}
writePixel() {
const row = this.row_reg;
const col = this.col_reg & 0x7F;
if (row < 64 && col < 128) {
// Color comes from port 1 upper bits
const color = (this.port1 >> 6) & 0x03;
const addr = row * 128 + col;
this.vram[addr] = color;
}
}
readConst(a) {
if (a < 0x0800)
return this.bios[a];
return this.rom ? (this.rom[a - 0x0800] || 0) : 0;
}
loadROM(data) {
if (!this.rom)
this.rom = new Uint8Array(this.defaultROMSize);
this.rom.set(data);
this.reset();
}
loadBIOS(data) {
this.bios = (0, emu_1.padBytes)(data, 0x800);
this.reset();
}
reset() {
super.reset();
this.vram.fill(0);
this.port0 = 0;
this.port1 = 0;
this.port4 = 0;
this.port5 = 0;
this.row_reg = 0;
this.col_reg = 0;
this.soundMode = 0;
this.soundCounter = 0;
this.soundEnvelope = 0;
}
advanceFrame(trap) {
var clock = 0;
var targetClocks = this.cpuFrequency / 60;
this.probe.logNewFrame();
while (clock < targetClocks) {
if (trap && trap())
break;
clock += this.advanceCPU();
}
this.renderFrame();
this.generateAudio(targetClocks);
return clock;
}
renderFrame() {
if (!this.pixels)
return;
// Determine palette offset from VRAM locations 125 and 126 of row 0
// (simplified - uses palette 0 by default)
for (let y = 0; y < 64; y++) {
// Palette selection per row from vram[y*128 + 125] and [y*128 + 126]
let palOffset = 0;
const p125 = this.vram[y * 128 + 125];
const p126 = this.vram[y * 128 + 126];
palOffset = ((p125 & 2) | ((p126 & 2) >> 1)) * 4;
for (let x = 0; x < 128; x++) {
const color = this.vram[y * 128 + x] & 0x03;
const rgba = CHANNELF_COLORMAP[palOffset + color];
// Double vertical: each Channel F row maps to 4 display rows (NTSC)
this.pixels[y * 128 + x] = rgba;
}
}
}
generateAudio(cycles) {
if (!this.audio)
return;
// Simple tone generation based on sound mode
const samplesPerFrame = Math.floor(this.sampleRate / 60);
for (let i = 0; i < samplesPerFrame; i++) {
let sample = 0;
if (this.soundMode > 0 && this.soundEnvelope > 0) {
// Generate square wave at appropriate frequency
let freq;
switch (this.soundMode) {
case 1:
freq = 1000;
break; // ~1000 Hz
case 2:
freq = 500;
break; // ~500 Hz
case 3:
freq = 120;
break; // ~120 Hz
default: freq = 0;
}
if (freq > 0) {
const period = Math.floor(this.sampleRate / freq);
this.soundCounter = (this.soundCounter + 1) % period;
sample = this.soundCounter < period / 2 ? 0.3 : -0.3;
sample *= this.soundEnvelope / 0x3FF;
}
// Decay envelope
if (this.soundOnTime > 0) {
this.soundOnTime--;
}
else {
this.soundEnvelope -= 2;
if (this.soundEnvelope < 0)
this.soundEnvelope = 0;
}
}
this.audio.feedSample(sample, 1);
}
}
setKeyInput(key, code, flags) {
// inputs[0] = console switches
// inputs[1] = right controller
// inputs[2] = left controller
const pressed = !!(flags & emu_1.KeyFlags.KeyDown);
const released = !!(flags & emu_1.KeyFlags.KeyUp);
// Console buttons (mapped to number keys)
if (key === emu_1.Keys.VK_1.c) { // TIME
if (pressed)
this.inputs[0] |= 0x01;
else if (released)
this.inputs[0] &= ~0x01;
}
if (key === emu_1.Keys.VK_2.c) { // MODE
if (pressed)
this.inputs[0] |= 0x02;
else if (released)
this.inputs[0] &= ~0x02;
}
if (key === emu_1.Keys.VK_3.c) { // HOLD
if (pressed)
this.inputs[0] |= 0x04;
else if (released)
this.inputs[0] &= ~0x04;
}
if (key === emu_1.Keys.VK_4.c) { // START
if (pressed)
this.inputs[0] |= 0x08;
else if (released)
this.inputs[0] &= ~0x08;
}
// Right controller (WASD + QE for twist + RF for push/pull)
if (key === emu_1.Keys.VK_UP.c || key === emu_1.Keys.VK_W.c) {
if (pressed)
this.inputs[1] |= INPUT_FORWARD;
else if (released)
this.inputs[1] &= ~INPUT_FORWARD;
}
if (key === emu_1.Keys.VK_DOWN.c || key === emu_1.Keys.VK_S.c) {
if (pressed)
this.inputs[1] |= INPUT_BACK;
else if (released)
this.inputs[1] &= ~INPUT_BACK;
}
if (key === emu_1.Keys.VK_LEFT.c || key === emu_1.Keys.VK_A.c) {
if (pressed)
this.inputs[1] |= INPUT_LEFT;
else if (released)
this.inputs[1] &= ~INPUT_LEFT;
}
if (key === emu_1.Keys.VK_RIGHT.c || key === emu_1.Keys.VK_D.c) {
if (pressed)
this.inputs[1] |= INPUT_RIGHT;
else if (released)
this.inputs[1] &= ~INPUT_RIGHT;
}
if (key === emu_1.Keys.VK_Q.c) { // CCW twist
if (pressed)
this.inputs[1] |= INPUT_CCW;
else if (released)
this.inputs[1] &= ~INPUT_CCW;
}
if (key === emu_1.Keys.VK_E.c) { // CW twist
if (pressed)
this.inputs[1] |= INPUT_CW;
else if (released)
this.inputs[1] &= ~INPUT_CW;
}
if (key === emu_1.Keys.VK_R.c) { // Push
if (pressed)
this.inputs[1] |= INPUT_PUSH;
else if (released)
this.inputs[1] &= ~INPUT_PUSH;
}
if (key === emu_1.Keys.VK_F.c) { // Pull
if (pressed)
this.inputs[1] |= INPUT_PULL;
else if (released)
this.inputs[1] &= ~INPUT_PULL;
}
}
saveState() {
return {
c: this.cpu.saveState(),
ram: this.ram.slice(0),
inputs: this.inputs.slice(0),
vram: this.vram.slice(0),
port0: this.port0,
port1: this.port1,
port4: this.port4,
port5: this.port5,
row_reg: this.row_reg,
col_reg: this.col_reg,
soundMode: this.soundMode,
soundCounter: this.soundCounter,
soundEnvelope: this.soundEnvelope,
};
}
loadState(state) {
this.cpu.loadState(state.c);
this.ram.set(state.ram);
this.inputs.set(state.inputs);
this.vram.set(state.vram);
this.port0 = state.port0;
this.port1 = state.port1;
this.port4 = state.port4;
this.port5 = state.port5;
this.row_reg = state.row_reg;
this.col_reg = state.col_reg;
this.soundMode = state.soundMode;
this.soundCounter = state.soundCounter;
this.soundEnvelope = state.soundEnvelope;
}
}
exports.ChannelF = ChannelF;
//# sourceMappingURL=channelf.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"channelf.js","sourceRoot":"","sources":["../../src/machine/channelf.ts"],"names":[],"mappings":"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 truncated
+451 -60
View File
@@ -12,6 +12,17 @@ const DMG_PALETTE = [
0xFF526b34, // Dark Mid
0xFF2d3122, // Darkest (Deep Olive)
];
// Convert GBC 15-bit RGB (xBBBBBGGGGGRRRRR) to 32-bit ARGB
function cgbColorToARGB(lo, hi) {
var r5 = lo & 0x1F;
var g5 = ((lo >> 5) | ((hi & 0x03) << 3)) & 0x1F;
var b5 = (hi >> 2) & 0x1F;
// Scale 5-bit to 8-bit with GBC gamma correction (approximate)
var r8 = (r5 * 527 + 23) >> 6;
var g8 = (g5 * 527 + 23) >> 6;
var b8 = (b5 * 527 + 23) >> 6;
return 0xFF000000 | (b8 << 16) | (g8 << 8) | r8;
}
var GB_KEYCODE_MAP = (0, emu_1.makeKeycodeMap)([
// D-pad
[emu_1.Keys.RIGHT, 0, 0x01],
@@ -740,6 +751,27 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.oam = new Uint8Array(0xA0); // OAM (FE00-FE9F)
this.hram = new Uint8Array(0x80); // High RAM (FF80-FFFE)
this.extram = new Uint8Array(0x2000); // External/cartridge RAM (A000-BFFF)
// GBC mode
this.cgbMode = false; // True when running in CGB mode
this.forceColor = false; // True when platform requests CGB mode
this.vramBank1 = new Uint8Array(0x2000); // VRAM bank 1 (CGB only)
this.vramBankSelect = 0; // FF4F - VBK: VRAM bank select (0 or 1)
this.wramBanks = new Uint8Array(0x7000); // WRAM banks 1-7 (CGB: 7×4KB at D000-DFFF)
this.wramBankSelect = 1; // FF70 - SVBK: WRAM bank select (1-7)
this.bgCRAM = new Uint8Array(64); // BG color palette RAM (8 palettes × 4 colors × 2 bytes)
this.objCRAM = new Uint8Array(64); // OBJ color palette RAM
this.bgCRAMIndex = 0; // FF68 - BCPS: BG palette index
this.bgCRAMAutoInc = false; // FF68 bit 7: auto-increment
this.objCRAMIndex = 0; // FF6A - OCPS: OBJ palette index
this.objCRAMAutoInc = false; // FF6A bit 7: auto-increment
this.doubleSpeed = false; // CGB double-speed mode active
this.speedSwitchArmed = false; // FF4D bit 0: prepare speed switch
// HDMA (HBlank DMA)
this.hdmaSrc = 0; // FF51-FF52: source address
this.hdmaDst = 0; // FF53-FF54: destination address
this.hdmaLength = 0xFF; // FF55: length/mode/start
this.hdmaActive = false; // General-purpose HDMA active flag
this.hdmaHblank = false; // HBlank DMA mode active
// IO registers
this.joyp = 0xCF; // FF00 - Joypad
this.sb = 0; // FF01 - Serial transfer data
@@ -770,8 +802,8 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.ppuMode = 0; // 0=HBlank, 1=VBlank, 2=OAM, 3=Transfer
this.ppuDot = 0; // Dot counter within scanline
this.windowLine = 0; // Internal window line counter
// MBC1 state
this.mbcType = 0; // 0=ROM only, 1=MBC1
// MBC state
this.mbcType = 0; // 0=ROM only, 1=MBC1, 3=MBC3, 5=MBC5
this.romBank = 1;
this.ramBank = 0;
this.ramEnabled = false;
@@ -780,10 +812,12 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.read = (0, emu_1.newAddressDecoder)([
[0x0000, 0x3FFF, 0x3FFF, (a) => { return this.rom ? this.rom[a] : 0xFF; }],
[0x4000, 0x7FFF, 0x3FFF, (a) => { return this.readBankedROM(a); }],
[0x8000, 0x9FFF, 0x1FFF, (a) => { return this.vram[a]; }],
[0x8000, 0x9FFF, 0x1FFF, (a) => { return this.readVRAM(a); }],
[0xA000, 0xBFFF, 0x1FFF, (a) => { return this.readExtRAM(a); }],
[0xC000, 0xDFFF, 0x1FFF, (a) => { return this.ram[a]; }],
[0xE000, 0xFDFF, 0x1FFF, (a) => { return this.ram[a]; }], // Echo RAM
[0xC000, 0xCFFF, 0x0FFF, (a) => { return this.ram[a]; }],
[0xD000, 0xDFFF, 0x0FFF, (a) => { return this.readWRAMBank(a); }],
[0xE000, 0xEFFF, 0x0FFF, (a) => { return this.ram[a]; }], // Echo RAM
[0xF000, 0xFDFF, 0x0FFF, (a) => { return this.readWRAMBank(a); }], // Echo RAM
[0xFE00, 0xFE9F, 0xFF, (a) => { return this.oam[a]; }],
[0xFEA0, 0xFEFF, 0xFF, (a) => { return 0xFF; }], // Unusable
[0xFF00, 0xFF7F, 0x7F, (a) => { return this.readIO(a); }],
@@ -795,10 +829,12 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
[0x2000, 0x3FFF, 0x1FFF, (a, v) => { this.writeMBC(0x2000 + a, v); }],
[0x4000, 0x5FFF, 0x1FFF, (a, v) => { this.writeMBC(0x4000 + a, v); }],
[0x6000, 0x7FFF, 0x1FFF, (a, v) => { this.writeMBC(0x6000 + a, v); }],
[0x8000, 0x9FFF, 0x1FFF, (a, v) => { this.vram[a] = v; }],
[0x8000, 0x9FFF, 0x1FFF, (a, v) => { this.writeVRAM(a, v); }],
[0xA000, 0xBFFF, 0x1FFF, (a, v) => { this.writeExtRAM(a, v); }],
[0xC000, 0xDFFF, 0x1FFF, (a, v) => { this.ram[a] = v; }],
[0xE000, 0xFDFF, 0x1FFF, (a, v) => { this.ram[a] = v; }], // Echo RAM
[0xC000, 0xCFFF, 0x0FFF, (a, v) => { this.ram[a] = v; }],
[0xD000, 0xDFFF, 0x0FFF, (a, v) => { this.writeWRAMBank(a, v); }],
[0xE000, 0xEFFF, 0x0FFF, (a, v) => { this.ram[a] = v; }], // Echo RAM
[0xF000, 0xFDFF, 0x0FFF, (a, v) => { this.writeWRAMBank(a, v); }], // Echo RAM
[0xFE00, 0xFE9F, 0xFF, (a, v) => { this.oam[a] = v; }],
[0xFEA0, 0xFEFF, 0xFF, (a, v) => { }],
[0xFF00, 0xFF7F, 0x7F, (a, v) => { this.writeIO(a, v); }],
@@ -807,10 +843,37 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
]);
// Timer tracking with proper sub-cycle accuracy
this.timerSubCycles = 0;
// Per-pixel BG priority tracking for CGB sprite priority
this.bgPriorityLine = new Uint8Array(160); // stores BG color index per pixel
this.bgAttrPriLine = new Uint8Array(160); // stores BG-over-OBJ bit per pixel
this.handler = (0, emu_1.newKeyboardHandler)(this.inputs, this.getKeyboardMap());
this.connectCPUMemoryBus(this);
}
// MBC1 ROM banking
// VRAM bank-aware read/write
readVRAM(a) {
if (this.cgbMode && this.vramBankSelect)
return this.vramBank1[a];
return this.vram[a];
}
writeVRAM(a, v) {
if (this.cgbMode && this.vramBankSelect)
this.vramBank1[a] = v;
else
this.vram[a] = v;
}
// WRAM bank-aware read/write (D000-DFFF)
readWRAMBank(a) {
if (!this.cgbMode || this.wramBankSelect <= 1)
return this.ram[0x1000 + a];
return this.wramBanks[(this.wramBankSelect - 1) * 0x1000 + a];
}
writeWRAMBank(a, v) {
if (!this.cgbMode || this.wramBankSelect <= 1)
this.ram[0x1000 + a] = v;
else
this.wramBanks[(this.wramBankSelect - 1) * 0x1000 + a] = v;
}
// ROM banking (supports MBC1, MBC3, MBC5)
readBankedROM(a) {
if (!this.rom)
return 0xFF;
@@ -823,31 +886,70 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
writeMBC(fullAddr, v) {
if (this.mbcType === 0)
return; // ROM-only, ignore writes
if (this.mbcType === 5) {
// MBC5
this.writeMBC5(fullAddr, v);
return;
}
// MBC1 / MBC3
if (fullAddr < 0x2000) {
// RAM enable
this.ramEnabled = (v & 0x0F) === 0x0A;
}
else if (fullAddr < 0x4000) {
// ROM bank number (lower 5 bits)
var bank = v & 0x1F;
if (bank === 0)
bank = 1;
this.romBank = (this.romBank & 0x60) | bank;
this.romBank &= this.romBankMask;
}
else if (fullAddr < 0x6000) {
// RAM bank / upper ROM bank bits
if (this.mbcMode === 0) {
this.romBank = (this.romBank & 0x1F) | ((v & 0x03) << 5);
this.romBank &= this.romBankMask;
if (this.mbcType === 3) {
// MBC3: 7-bit ROM bank
var bank = v & 0x7F;
if (bank === 0)
bank = 1;
this.romBank = bank & this.romBankMask;
}
else {
this.ramBank = v & 0x03;
// MBC1: lower 5 bits
var bank = v & 0x1F;
if (bank === 0)
bank = 1;
this.romBank = (this.romBank & 0x60) | bank;
this.romBank &= this.romBankMask;
}
}
else if (fullAddr < 0x6000) {
if (this.mbcType === 3) {
// MBC3: RAM bank 0-3 (or RTC register select)
this.ramBank = v & 0x0F;
}
else {
// MBC1: RAM bank / upper ROM bank bits
if (this.mbcMode === 0) {
this.romBank = (this.romBank & 0x1F) | ((v & 0x03) << 5);
this.romBank &= this.romBankMask;
}
else {
this.ramBank = v & 0x03;
}
}
}
else {
// Banking mode select
this.mbcMode = v & 0x01;
// MBC1: banking mode select; MBC3: latch clock data (ignored)
if (this.mbcType === 1)
this.mbcMode = v & 0x01;
}
}
writeMBC5(fullAddr, v) {
if (fullAddr < 0x2000) {
this.ramEnabled = (v & 0x0F) === 0x0A;
}
else if (fullAddr < 0x3000) {
// Low 8 bits of ROM bank
this.romBank = (this.romBank & 0x100) | v;
this.romBank &= this.romBankMask;
}
else if (fullAddr < 0x4000) {
// Bit 8 of ROM bank
this.romBank = (this.romBank & 0xFF) | ((v & 0x01) << 8);
this.romBank &= this.romBankMask;
}
else if (fullAddr < 0x6000) {
this.ramBank = v & 0x0F;
}
}
readExtRAM(a) {
@@ -928,6 +1030,15 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
case 0x49: return this.obp1;
case 0x4A: return this.wy;
case 0x4B: return this.wx;
// GBC registers
case 0x4D: return this.cgbMode ? ((this.doubleSpeed ? 0x80 : 0) | (this.speedSwitchArmed ? 0x01 : 0) | 0x7E) : 0xFF;
case 0x4F: return this.cgbMode ? (this.vramBankSelect | 0xFE) : 0xFF;
case 0x55: return this.cgbMode ? this.hdmaLength : 0xFF;
case 0x68: return this.cgbMode ? (this.bgCRAMIndex | (this.bgCRAMAutoInc ? 0x80 : 0)) : 0xFF;
case 0x69: return this.cgbMode ? this.bgCRAM[this.bgCRAMIndex & 0x3F] : 0xFF;
case 0x6A: return this.cgbMode ? (this.objCRAMIndex | (this.objCRAMAutoInc ? 0x80 : 0)) : 0xFF;
case 0x6B: return this.cgbMode ? this.objCRAM[this.objCRAMIndex & 0x3F] : 0xFF;
case 0x70: return this.cgbMode ? this.wramBankSelect : 0xFF;
default: return 0xFF;
}
}
@@ -1042,6 +1153,68 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
case 0x4B:
this.wx = v;
break;
// GBC registers
case 0x4D:
if (this.cgbMode)
this.speedSwitchArmed = !!(v & 0x01);
break;
case 0x4F:
if (this.cgbMode)
this.vramBankSelect = v & 0x01;
break;
case 0x51:
if (this.cgbMode)
this.hdmaSrc = (this.hdmaSrc & 0x00FF) | (v << 8);
break;
case 0x52:
if (this.cgbMode)
this.hdmaSrc = (this.hdmaSrc & 0xFF00) | (v & 0xF0);
break;
case 0x53:
if (this.cgbMode)
this.hdmaDst = (this.hdmaDst & 0x00FF) | ((v & 0x1F) << 8);
break;
case 0x54:
if (this.cgbMode)
this.hdmaDst = (this.hdmaDst & 0xFF00) | (v & 0xF0);
break;
case 0x55:
if (this.cgbMode)
this.startHDMA(v);
break;
case 0x68:
if (this.cgbMode) {
this.bgCRAMIndex = v & 0x3F;
this.bgCRAMAutoInc = !!(v & 0x80);
}
break;
case 0x69:
if (this.cgbMode) {
this.bgCRAM[this.bgCRAMIndex & 0x3F] = v;
if (this.bgCRAMAutoInc)
this.bgCRAMIndex = (this.bgCRAMIndex + 1) & 0x3F;
}
break;
case 0x6A:
if (this.cgbMode) {
this.objCRAMIndex = v & 0x3F;
this.objCRAMAutoInc = !!(v & 0x80);
}
break;
case 0x6B:
if (this.cgbMode) {
this.objCRAM[this.objCRAMIndex & 0x3F] = v;
if (this.objCRAMAutoInc)
this.objCRAMIndex = (this.objCRAMIndex + 1) & 0x3F;
}
break;
case 0x70:
if (this.cgbMode) {
this.wramBankSelect = v & 0x07;
if (this.wramBankSelect === 0)
this.wramBankSelect = 1;
}
break;
}
}
// Joypad reading (FF00)
@@ -1066,6 +1239,62 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.oam[i] = this.read(srcBase + i);
}
}
// HDMA transfer (CGB)
startHDMA(v) {
if (this.hdmaActive && !(v & 0x80)) {
// Cancel active HBlank DMA
this.hdmaActive = false;
this.hdmaLength = v | 0x80;
return;
}
var length = ((v & 0x7F) + 1) * 0x10;
if (v & 0x80) {
// HBlank DMA — transfer 0x10 bytes per HBlank
this.hdmaActive = true;
this.hdmaHblank = true;
this.hdmaLength = v & 0x7F;
}
else {
// General-purpose DMA — transfer all at once
this.performHDMABlock(length);
this.hdmaLength = 0xFF;
}
}
performHDMABlock(length) {
var src = this.hdmaSrc & 0xFFF0;
var dst = (this.hdmaDst & 0x1FF0);
for (var i = 0; i < length; i++) {
var val = this.read(src + i);
if (this.vramBankSelect)
this.vramBank1[dst + i] = val;
else
this.vram[dst + i] = val;
}
this.hdmaSrc += length;
this.hdmaDst += length;
}
// Called during HBlank for HBlank DMA
tickHDMA() {
if (!this.hdmaActive || !this.hdmaHblank)
return;
this.performHDMABlock(0x10);
if (this.hdmaLength === 0) {
this.hdmaActive = false;
this.hdmaLength = 0xFF;
}
else {
this.hdmaLength--;
}
}
// CGB speed switch (executed during STOP instruction)
performSpeedSwitch() {
if (this.cgbMode && this.speedSwitchArmed) {
this.doubleSpeed = !this.doubleSpeed;
this.speedSwitchArmed = false;
// In double speed, CPU runs at 8 MHz but PPU stays at normal speed
// We handle this by doubling T-cycles returned from advanceCPU
}
}
// Timer update — called per CPU cycle (M-cycle)
updateTimer(cycles) {
// DIV increments at 16384 Hz = every 256 T-cycles = 64 M-cycles
@@ -1168,6 +1397,9 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
// Fire STAT interrupts on mode transitions
if (this.ppuMode === 0 && (this.stat & 0x08)) {
this.iflag |= 0x02; // HBlank STAT interrupt
// CGB HBlank DMA
if (this.cgbMode)
this.tickHDMA();
}
else if (this.ppuMode === 2 && (this.stat & 0x20)) {
this.iflag |= 0x02; // OAM STAT interrupt
@@ -1244,16 +1476,20 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
return; // VBlank, nothing to draw
var lineOffset = this.scanline * 160;
// Draw background
if (this.lcdc & 0x01) {
// In CGB mode, LCDC bit 0 controls BG/sprite priority, not BG enable
if ((this.lcdc & 0x01) || this.cgbMode) {
this.drawBGLine(lineOffset);
}
else {
// BG disabled — fill with color 0
// BG disabled (DMG only) — fill with color 0
for (var x = 0; x < 160; x++) {
this.pixels[lineOffset + x] = DMG_PALETTE[0];
this.bgPriorityLine[x] = 0;
this.bgAttrPriLine[x] = 0;
}
}
// Draw window
// In CGB mode, window is always available when LCDC bit 5 is set
if ((this.lcdc & 0x20) && this.scanline >= this.wy) {
this.drawWindowLine(lineOffset);
}
@@ -1262,16 +1498,20 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.drawSpriteLine(lineOffset);
}
}
// Get color from palette register
// Get DMG color from palette register
getPaletteColor(palette, colorIndex) {
var shade = (palette >> (colorIndex * 2)) & 0x03;
return DMG_PALETTE[shade];
}
// Get CGB color from color palette RAM
getCGBColor(cram, paletteNum, colorIndex) {
var idx = paletteNum * 8 + colorIndex * 2;
return cgbColorToARGB(cram[idx], cram[idx + 1]);
}
// Draw one line of background
drawBGLine(lineOffset) {
var tileMap = (this.lcdc & 0x08) ? 0x1C00 : 0x1800; // BG tile map select
var tileData = (this.lcdc & 0x10) ? 0x0000 : 0x0800; // BG & Window tile data select
var signed = !(this.lcdc & 0x10); // Use signed tile indices when bit 4 is 0
var tileMap = (this.lcdc & 0x08) ? 0x1C00 : 0x1800;
var signed = !(this.lcdc & 0x10);
var y = (this.scanline + this.scy) & 0xFF;
var tileRow = (y >> 3) & 31;
var tileYOffset = y & 7;
@@ -1279,21 +1519,42 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
var scrolledX = (x + this.scx) & 0xFF;
var tileCol = (scrolledX >> 3) & 31;
var tileXBit = 7 - (scrolledX & 7);
// Get tile index from map
var tileIndex = this.vram[tileMap + tileRow * 32 + tileCol];
var mapOffset = tileMap + tileRow * 32 + tileCol;
// Get tile index from map (VRAM bank 0)
var tileIndex = this.vram[mapOffset];
var tileAddr;
if (signed) {
// Signed: tile 0 is at 0x9000 (VRAM offset 0x1000)
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16); // sign extend
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16);
}
else {
tileAddr = tileIndex * 16;
}
// Get pixel from tile data (2bpp)
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
if (this.cgbMode) {
// CGB: read attributes from VRAM bank 1
var attr = this.vramBank1[mapOffset];
var cgbPalette = attr & 0x07;
var vramBank = (attr & 0x08) ? 1 : 0;
var xFlip = !!(attr & 0x20);
var yFlip = !!(attr & 0x40);
var bgPri = !!(attr & 0x80);
var tileY = yFlip ? (7 - tileYOffset) : tileYOffset;
var tileBit = xFlip ? (scrolledX & 7) : tileXBit;
var bank = vramBank ? this.vramBank1 : this.vram;
var lo = bank[tileAddr + tileY * 2];
var hi = bank[tileAddr + tileY * 2 + 1];
var colorIndex = ((hi >> tileBit) & 1) << 1 | ((lo >> tileBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = bgPri ? 1 : 0;
this.pixels[lineOffset + x] = this.getCGBColor(this.bgCRAM, cgbPalette, colorIndex);
}
else {
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = 0;
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
}
}
}
// Draw one line of window
@@ -1301,8 +1562,7 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
var wxAdjusted = this.wx - 7;
if (wxAdjusted >= 160)
return;
var tileMap = (this.lcdc & 0x40) ? 0x1C00 : 0x1800; // Window tile map select
var tileData = (this.lcdc & 0x10) ? 0x0000 : 0x0800;
var tileMap = (this.lcdc & 0x40) ? 0x1C00 : 0x1800;
var signed = !(this.lcdc & 0x10);
var winY = this.windowLine;
var tileRow = (winY >> 3) & 31;
@@ -1312,7 +1572,8 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
var winX = x - wxAdjusted;
var tileCol = (winX >> 3) & 31;
var tileXBit = 7 - (winX & 7);
var tileIndex = this.vram[tileMap + tileRow * 32 + tileCol];
var mapOffset = tileMap + tileRow * 32 + tileCol;
var tileIndex = this.vram[mapOffset];
var tileAddr;
if (signed) {
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16);
@@ -1320,10 +1581,31 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
else {
tileAddr = tileIndex * 16;
}
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
if (this.cgbMode) {
var attr = this.vramBank1[mapOffset];
var cgbPalette = attr & 0x07;
var vramBank = (attr & 0x08) ? 1 : 0;
var xFlip = !!(attr & 0x20);
var yFlip = !!(attr & 0x40);
var bgPri = !!(attr & 0x80);
var tileY = yFlip ? (7 - tileYOffset) : tileYOffset;
var tileBit = xFlip ? (winX & 7) : tileXBit;
var bank = vramBank ? this.vramBank1 : this.vram;
var lo = bank[tileAddr + tileY * 2];
var hi = bank[tileAddr + tileY * 2 + 1];
var colorIndex = ((hi >> tileBit) & 1) << 1 | ((lo >> tileBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = bgPri ? 1 : 0;
this.pixels[lineOffset + x] = this.getCGBColor(this.bgCRAM, cgbPalette, colorIndex);
}
else {
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = 0;
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
}
drawn = true;
}
if (drawn)
@@ -1344,7 +1626,10 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
}
}
// Sort by X coordinate (lower X = higher priority, ties broken by OAM index)
sprites.sort((a, b) => a.x !== b.x ? a.x - b.x : a.index - b.index);
// CGB: no X priority sorting, only OAM index order
if (!this.cgbMode) {
sprites.sort((a, b) => a.x !== b.x ? a.x - b.x : a.index - b.index);
}
// Draw sprites in reverse order (lowest priority first, so higher priority overwrites)
for (var si = sprites.length - 1; si >= 0; si--) {
var spriteIndex = sprites[si].index;
@@ -1352,18 +1637,19 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
var xPos = this.oam[spriteIndex * 4 + 1] - 8;
var tileIndex = this.oam[spriteIndex * 4 + 2];
var flags = this.oam[spriteIndex * 4 + 3];
var palette = (flags & 0x10) ? this.obp1 : this.obp0;
var xFlip = !!(flags & 0x20);
var yFlip = !!(flags & 0x40);
var bgPriority = !!(flags & 0x80);
if (spriteHeight === 16)
tileIndex &= 0xFE; // Ignore bit 0 for 8x16 sprites
tileIndex &= 0xFE;
var tileY = this.scanline - yPos;
if (yFlip)
tileY = spriteHeight - 1 - tileY;
var tileAddr = tileIndex * 16 + tileY * 2;
var lo = this.vram[tileAddr];
var hi = this.vram[tileAddr + 1];
// CGB: sprites can use VRAM bank 0 or 1
var spriteVramBank = (this.cgbMode && (flags & 0x08)) ? this.vramBank1 : this.vram;
var lo = spriteVramBank[tileAddr];
var hi = spriteVramBank[tileAddr + 1];
for (var px = 0; px < 8; px++) {
var screenX = xPos + px;
if (screenX < 0 || screenX >= 160)
@@ -1372,13 +1658,29 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
var colorIndex = ((hi >> bit) & 1) << 1 | ((lo >> bit) & 1);
if (colorIndex === 0)
continue; // Transparent
// BG priority: sprite hidden behind BG colors 1-3
if (bgPriority) {
var bgColor = this.pixels[lineOffset + screenX];
if (bgColor !== DMG_PALETTE[(this.bgp & 0x03)])
continue; // BG color 0 check
if (this.cgbMode) {
// CGB priority: BG attribute bit 7 overrides sprite if BG color != 0
// Also OAM bit 7 (bgPriority) can hide sprite behind BG
var bgMaster = this.lcdc & 0x01; // LCDC bit 0 = BG/Window master priority
if (bgMaster) {
if (this.bgAttrPriLine[screenX] && this.bgPriorityLine[screenX] !== 0)
continue;
if (bgPriority && this.bgPriorityLine[screenX] !== 0)
continue;
}
var cgbPalette = flags & 0x07;
this.pixels[lineOffset + screenX] = this.getCGBColor(this.objCRAM, cgbPalette, colorIndex);
}
else {
// DMG priority
if (bgPriority) {
var bgColor = this.pixels[lineOffset + screenX];
if (bgColor !== DMG_PALETTE[(this.bgp & 0x03)])
continue;
}
var palette = (flags & 0x10) ? this.obp1 : this.obp0;
this.pixels[lineOffset + screenX] = this.getPaletteColor(palette, colorIndex);
}
this.pixels[lineOffset + screenX] = this.getPaletteColor(palette, colorIndex);
}
}
}
@@ -1395,13 +1697,34 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
case 0x03:
this.mbcType = 1;
break; // MBC1
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
this.mbcType = 3;
break; // MBC3
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1E:
this.mbcType = 5;
break; // MBC5
default:
console.log(`Invalid cartridge type @ 0x147: ${data[0x147]}`);
console.log(`Unhandled cartridge type 0x${cartType.toString(16)} @ 0x147, treating as MBC5`);
this.mbcType = 5;
break;
}
}
else
throw new emu_1.EmuHalt("ROM not long enough for header");
// Detect CGB mode from header byte 0x143
if (data.length > 0x143) {
var cgbFlag = data[0x143];
this.cgbMode = this.forceColor || cgbFlag === 0x80 || cgbFlag === 0xC0;
}
// Determine ROM size and bank mask
this.rom = new Uint8Array(Math.max(data.length, 0x8000));
this.rom.set(data);
@@ -1465,11 +1788,36 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
this.timerSubCycles = 0;
this.apuCycleAccum = 0;
this.apu.reset();
// GBC state
this.vramBank1.fill(0);
this.vramBankSelect = 0;
this.wramBanks.fill(0);
this.wramBankSelect = 1;
this.bgCRAM.fill(0xFF);
this.objCRAM.fill(0xFF);
this.bgCRAMIndex = 0;
this.bgCRAMAutoInc = false;
this.objCRAMIndex = 0;
this.objCRAMAutoInc = false;
this.doubleSpeed = false;
this.speedSwitchArmed = false;
this.hdmaSrc = 0;
this.hdmaDst = 0;
this.hdmaLength = 0xFF;
this.hdmaActive = false;
this.hdmaHblank = false;
// CGB boot ROM leaves A=0x11 so games can detect CGB hardware
if (this.cgbMode) {
this.cpu.A = 0x11;
}
}
preFrame() {
this.windowLine = 0;
}
readVRAMAddress(a) {
// For debug views: addresses 0x0000-0x1FFF = bank 0, 0x2000-0x3FFF = bank 1
if (this.cgbMode && a >= 0x2000)
return this.vramBank1[a & 0x1FFF];
return this.vram[a & 0x1FFF];
}
// Save/load state
@@ -1494,6 +1842,22 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
};
state['apu'] = this.apu.saveState();
state['apuCycleAccum'] = this.apuCycleAccum;
// GBC state
if (this.cgbMode) {
state['cgb'] = {
vramBank1: this.vramBank1.slice(0),
vramBankSelect: this.vramBankSelect,
wramBanks: this.wramBanks.slice(0),
wramBankSelect: this.wramBankSelect,
bgCRAM: this.bgCRAM.slice(0),
objCRAM: this.objCRAM.slice(0),
bgCRAMIndex: this.bgCRAMIndex, bgCRAMAutoInc: this.bgCRAMAutoInc,
objCRAMIndex: this.objCRAMIndex, objCRAMAutoInc: this.objCRAMAutoInc,
doubleSpeed: this.doubleSpeed, speedSwitchArmed: this.speedSwitchArmed,
hdmaSrc: this.hdmaSrc, hdmaDst: this.hdmaDst,
hdmaLength: this.hdmaLength, hdmaActive: this.hdmaActive, hdmaHblank: this.hdmaHblank,
};
}
return state;
}
loadState(state) {
@@ -1536,6 +1900,27 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
if (state.apu)
this.apu.loadState(state.apu);
this.apuCycleAccum = state.apuCycleAccum || 0;
// GBC state
if (state.cgb) {
var cgb = state.cgb;
this.vramBank1.set(cgb.vramBank1);
this.vramBankSelect = cgb.vramBankSelect;
this.wramBanks.set(cgb.wramBanks);
this.wramBankSelect = cgb.wramBankSelect;
this.bgCRAM.set(cgb.bgCRAM);
this.objCRAM.set(cgb.objCRAM);
this.bgCRAMIndex = cgb.bgCRAMIndex;
this.bgCRAMAutoInc = cgb.bgCRAMAutoInc;
this.objCRAMIndex = cgb.objCRAMIndex;
this.objCRAMAutoInc = cgb.objCRAMAutoInc;
this.doubleSpeed = cgb.doubleSpeed;
this.speedSwitchArmed = cgb.speedSwitchArmed;
this.hdmaSrc = cgb.hdmaSrc;
this.hdmaDst = cgb.hdmaDst;
this.hdmaLength = cgb.hdmaLength;
this.hdmaActive = cgb.hdmaActive;
this.hdmaHblank = cgb.hdmaHblank;
}
}
getDebugCategories() {
return ['CPU', 'Stack', 'PPU'];
@@ -1543,7 +1928,7 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
getDebugInfo(category, state) {
switch (category) {
case 'PPU':
return "LCDC " + (0, util_1.hex)(this.lcdc, 2) + " STAT " + (0, util_1.hex)(this.stat, 2) + "\n"
var s = "LCDC " + (0, util_1.hex)(this.lcdc, 2) + " STAT " + (0, util_1.hex)(this.stat, 2) + "\n"
+ "LY " + (0, util_1.hex)(this.ly, 2) + " LYC " + (0, util_1.hex)(this.lyc, 2) + "\n"
+ "SCX " + (0, util_1.hex)(this.scx, 2) + " SCY " + (0, util_1.hex)(this.scy, 2) + "\n"
+ "WX " + (0, util_1.hex)(this.wx, 2) + " WY " + (0, util_1.hex)(this.wy, 2) + "\n"
@@ -1553,6 +1938,12 @@ class GameBoyMachine extends devices_1.BasicScanlineMachine {
+ "DIV " + (0, util_1.hex)((this.divCounter >> 8) & 0xFF, 2) + " TIMA " + (0, util_1.hex)(this.tima, 2) + "\n"
+ "TMA " + (0, util_1.hex)(this.tma, 2) + " TAC " + (0, util_1.hex)(this.tac, 2) + "\n"
+ "Bank " + this.romBank + "\n";
if (this.cgbMode) {
s += "--- CGB ---\n"
+ "VBK " + this.vramBankSelect + " SVBK " + this.wramBankSelect + "\n"
+ "SPD " + (this.doubleSpeed ? "2x" : "1x") + "\n";
}
return s;
}
}
}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"gb.js","sourceRoot":"","sources":["../../src/machine/gb.ts"],"names":[],"mappings":"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 truncated
{"version":3,"file":"gb.js","sourceRoot":"","sources":["../../src/machine/gb.ts"],"names":[],"mappings":"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 truncated
+40 -43
View File
@@ -1,4 +1,7 @@
"use strict";
// based on https://raw.githubusercontent.com/mamedev/mame/refs/heads/master/src/mame/midway/mcr.cpp
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
Object.defineProperty(exports, "__esModule", { value: true });
exports.MCR2Machine = void 0;
const ZilogZ80_1 = require("../common/cpu/ZilogZ80");
@@ -15,7 +18,7 @@ const MCR2_FPS = 30;
const MCR2_CYCLES_PER_LINE = Math.floor(MCR2_CPU_FREQ / (MCR2_NUM_TOTAL_SCANLINES * MCR2_FPS));
const MCR2_TILE_COLS = 32;
const MCR2_TILE_ROWS = 30;
const MCR2_TILE_SIZE = 16;
const MCR2_TILE_SIZE = 8; // double-pixels for BG
const INITIAL_WATCHDOG = 16;
function pal3bit(v) {
v &= 7;
@@ -40,11 +43,11 @@ const MCR2_KEYCODE_MAP = (0, emu_1.makeKeycodeMap)([
]);
// ROM blob layout
const ROM_PROGRAM_START = 0x0;
const ROM_PROGRAM_SIZE = 0xC000;
const ROM_BG_GFX_START = 0xC000;
const ROM_PROGRAM_SIZE = 0xE000;
const ROM_BG_GFX_START = ROM_PROGRAM_SIZE;
const ROM_BG_GFX_SIZE = 0x4000; // 16KB background tiles (2 bitplanes × 8KB)
const ROM_SPR_GFX_START = 0x12000;
const ROM_SPR_GFX_SIZE = 2 * 0x8000; // 32KB sprites (4 bitplanes × 8KB)
const ROM_SPR_GFX_START = ROM_BG_GFX_START + ROM_BG_GFX_SIZE;
const ROM_SPR_GFX_SIZE = 0x8000; // 32KB sprites (4 bitplanes × 8KB)
const SSIO_ROM_SIZE = 0x4000;
const ROM_TOTAL_SIZE = ROM_PROGRAM_SIZE + ROM_BG_GFX_SIZE + ROM_SPR_GFX_SIZE + SSIO_ROM_SIZE;
class MCR2Machine extends devices_1.BasicScanlineMachine {
@@ -68,16 +71,16 @@ class MCR2Machine extends devices_1.BasicScanlineMachine {
this.ctcVector = 0;
// Main CPU memory read
this.read = (0, emu_1.newAddressDecoder)([
[0x0000, 0xBFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],
[0xC000, 0xDFFF, 0x7FF, (a) => { return this.ram[a]; }],
[0xE000, 0xE7FF, 0x1FF, (a) => { return this.sprram[a]; }],
[0x0000, 0xDFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],
[0xE000, 0xE7FF, 0x7FF, (a) => { return this.ram[a]; }],
[0xE800, 0xEFFF, 0x1FF, (a) => { return this.sprram[a]; }],
[0xF000, 0xF7FF, 0x7FF, (a) => { return this.vram[a]; }],
[0xF800, 0xFFFF, 0x7F, (a) => { return this.palram[a]; }],
]);
// Main CPU memory write
this.write = (0, emu_1.newAddressDecoder)([
[0xC000, 0xDFFF, 0x7FF, (a, v) => { this.ram[a] = v; }],
[0xE000, 0xE7FF, 0x1FF, (a, v) => { this.sprram[a] = v; }],
[0xE000, 0xE7FF, 0x7FF, (a, v) => { this.ram[a] = v; }],
[0xE800, 0xEFFF, 0x1FF, (a, v) => { this.sprram[a] = v; }],
[0xF000, 0xF7FF, 0x7FF, (a, v) => { this.vram[a] = v; }],
[0xF800, 0xFFFF, 0x7F, (a, v) => {
this.palram[a] = v;
@@ -157,22 +160,25 @@ class MCR2Machine extends devices_1.BasicScanlineMachine {
if (sl >= MCR2_NUM_VISIBLE_SCANLINES)
return;
let pixofs = sl * MCR2_CANVAS_WIDTH;
let tileRow = Math.floor(sl / MCR2_TILE_SIZE);
let tileY = sl % MCR2_TILE_SIZE;
// Draw background tiles
if (tileRow < MCR2_TILE_ROWS) {
for (let tileCol = 0; tileCol < MCR2_TILE_COLS; tileCol++) {
let vramOfs = (tileRow * MCR2_TILE_COLS + tileCol) * 2;
let byte0 = this.vram[vramOfs];
let byte1 = this.vram[vramOfs + 1];
// 91490 tile format
let tileCode = byte0 | ((byte1 & 0x03) << 8);
let tilePalette = (byte1 >> 4) & 0x03;
let flipX = (byte1 & 0x04) != 0;
let flipY = (byte1 & 0x08) != 0;
let ty = flipY ? (15 - tileY) : tileY;
let pixX = tileCol * MCR2_TILE_SIZE;
this.drawTileLine(pixofs + pixX, tileCode, ty, tilePalette, flipX);
if ((sl & 1) == 0) {
sl >>= 1;
let tileRow = Math.floor(sl / MCR2_TILE_SIZE);
let tileY = sl % MCR2_TILE_SIZE;
// Draw background tiles
if (tileRow < MCR2_TILE_ROWS) {
for (let tileCol = 0; tileCol < MCR2_TILE_COLS; tileCol++) {
let vramOfs = (tileRow * MCR2_TILE_COLS + tileCol) * 2;
let byte0 = this.vram[vramOfs];
let byte1 = this.vram[vramOfs + 1];
// 91490 tile format
let tileCode = byte0 | ((byte1 & 0x03) << 8);
let tilePalette = (byte1 >> 4) & 0x03;
let flipX = (byte1 & 0x04) != 0;
let flipY = (byte1 & 0x08) != 0;
let ty = flipY ? (15 - tileY) : tileY;
let pixX = tileCol * MCR2_TILE_SIZE * 2;
this.drawTileLine(pixofs + pixX, tileCode, ty, tilePalette, flipX);
}
}
}
// Draw sprites on this scanline
@@ -182,28 +188,19 @@ class MCR2Machine extends devices_1.BasicScanlineMachine {
drawTileLine(outOfs, tileCode, row, palette, flipX) {
let gfxBase = ROM_BG_GFX_START;
let halfSize = ROM_BG_GFX_SIZE / 2; // 8KB per bitplane
// Tile layout: 32 bytes per tile per bitplane
// Left 8 pixels in bytes 0-15 (one byte per row), right 8 pixels in bytes 16-31
// Tile layout: 8 bytes per tile per bitplane
let tileOfs = tileCode * 32;
let leftByteOfs = tileOfs + (row < 8 ? row : row); // rows 0-15
let rightByteOfs = tileOfs + 16 + (row < 8 ? row : row);
let p0L = this.rom[gfxBase + leftByteOfs] || 0;
let p1L = this.rom[gfxBase + halfSize + leftByteOfs] || 0;
let p0R = this.rom[gfxBase + rightByteOfs] || 0;
let p1R = this.rom[gfxBase + halfSize + rightByteOfs] || 0;
let byteOfs = tileOfs + (row < 8 ? row : row); // rows 0-15
let p0L = this.rom[gfxBase + byteOfs] || 0;
let p1L = this.rom[gfxBase + halfSize + byteOfs] || 0;
let colorBase = palette * 4;
// Draw 16 pixels (left 8 + right 8)
for (let x = 0; x < 8; x++) {
let bit = 7 - x;
let srcX = flipX ? (15 - x) : x;
let srcX = flipX ? (14 - x * 2) : x * 2;
let color = ((p0L >> bit) & 1) | (((p1L >> bit) & 1) << 1);
this.pixels[outOfs + srcX] = this.palette[colorBase + color];
}
for (let x = 0; x < 8; x++) {
let bit = 7 - x;
let srcX = flipX ? (7 - x) : (8 + x);
let color = ((p0R >> bit) & 1) | (((p1R >> bit) & 1) << 1);
this.pixels[outOfs + srcX] = this.palette[colorBase + color];
this.pixels[outOfs + srcX] = this.pixels[outOfs + srcX + 512]
= this.pixels[outOfs + srcX + 1] = this.pixels[outOfs + srcX + 513]
= this.palette[colorBase + color];
}
}
// Render sprites intersecting a given scanline (91464 sprite board, 4bpp)
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"mcr.js","sourceRoot":"","sources":["../../src/machine/mcr.ts"],"names":[],"mappings":"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 truncated
{"version":3,"file":"mcr.js","sourceRoot":"","sources":["../../src/machine/mcr.ts"],"names":[],"mappings":"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 truncated
+2
View File
@@ -0,0 +1,2 @@
import{J as X,c as v,d as Y,e as P,k as z,r as D}from"./chunk-GTDJ7CMC.js";import{$ as U,K as B,T as G,W as s,X as N,Z as V,aa as w}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var st=19968e3,W=st/4,Z=480,g=525,T=512,K=30,it=Math.floor(W/(g*K)),H=32,at=30,C=8,O=16;function E(c){return c&=7,c<<5|c<<2|c>>1}var nt=V([[s.SELECT,0,1],[s.START,0,4],[s.VK_2,0,8],[s.UP,1,1],[s.DOWN,1,2],[s.LEFT,1,4],[s.RIGHT,1,8],[s.A,1,16],[s.B,1,32],[s.P2_UP,2,1],[s.P2_DOWN,2,2],[s.P2_LEFT,2,4],[s.P2_RIGHT,2,8],[s.P2_A,2,16],[s.P2_B,2,32]]);var k=57344,q=k,y=16384,lt=q+y,Q=32768,ot=16384,pt=k+y+Q+ot,A=class extends D{constructor(){super();this.cpuFrequency=W;this.canvasWidth=T;this.numVisibleScanlines=Z;this.numTotalScanlines=g;this.cpuCyclesPerLine=it;this.defaultROMSize=pt;this.sampleRate=K*g*2;this.cpu=new v;this.ram=new Uint8Array(2048);this.sprram=new Uint8Array(512);this.vram=new Uint8Array(2048);this.palram=new Uint8Array(128);this.palette=new Uint32Array(64);this.interruptEnabled=!1;this.watchdog_counter=O;this.ctcVector=0;this.read=w([[0,57343,65535,t=>this.rom?this.rom[t]:0],[57344,59391,2047,t=>this.ram[t]],[59392,61439,511,t=>this.sprram[t]],[61440,63487,2047,t=>this.vram[t]],[63488,65535,127,t=>this.palram[t]]]);this.write=w([[57344,59391,2047,(t,e)=>{this.ram[t]=e}],[59392,61439,511,(t,e)=>{this.sprram[t]=e}],[61440,63487,2047,(t,e)=>{this.vram[t]=e}],[63488,65535,127,(t,e)=>{this.palram[t]=e,this.updatePalette(t)}]]);var t=new Y;this.psg1=new P(t),this.psg2=new P(t),this.audioadapter=new z([this.psg1.psg,this.psg2.psg],2,this.sampleRate),this.connectCPUMemoryBus(this),this.connectCPUIOBus(this.newIOBus()),this.inputs.set([0,0,0,255,255]),this.handler=N(this.inputs,nt)}readConst(t){return this.read(t)}newIOBus(){return{read:t=>(t&=255,t<=4?this.inputs[t]:t>=8&&t<=15?this.inputs[3]:(t>=240&&t<=243,0)),write:(t,e)=>{t&=255,t==224&&(this.watchdog_counter=O),t>=240&&t<=243&&((t&3)==0&&!(e&1)||(e&1)==0&&(this.ctcVector=e&248)),t>=0&&t<=7}}}updatePalette(t){let e=t>>1;if(e>=64)return;let r=this.palram[e*2+1],n=E(r>>6&3),i=E(r&7),a=E(r>>3&7),o=(this.palram[e*2]&1)<<2;n=E(o|r>>6&3),this.palette[e]=4278190080|a<<16|i<<8|n}drawScanline(){let t=this.scanline;if(t>=Z)return;let e=t*T;if((t&1)==0){t>>=1;let r=Math.floor(t/C),n=t%C;if(r<at)for(let i=0;i<H;i++){let a=(r*H+i)*2,o=this.vram[a],l=this.vram[a+1],x=o|(l&3)<<8,h=l>>4&3,F=(l&4)!=0,m=(l&8)!=0?15-n:n,u=i*C*2;this.drawTileLine(e+u,x,m,h,F)}}this.drawSpriteScanline(t,e)}drawTileLine(t,e,r,n,i){let a=q,o=y/2,x=e*32+(r<8,r),h=this.rom[a+x]||0,F=this.rom[a+o+x]||0,d=n*4;for(let m=0;m<8;m++){let u=7-m,p=i?14-m*2:m*2,b=h>>u&1|(F>>u&1)<<1;this.pixels[t+p]=this.pixels[t+p+512]=this.pixels[t+p+1]=this.pixels[t+p+513]=this.palette[d+b]}}drawSpriteScanline(t,e){let r=lt,n=Q/4;for(let i=31;i>=0;i--){let a=i*4,o=this.sprram[a]-2&255;o=496-o;let l=this.sprram[a+1],x=this.sprram[a+2]|(l&8?256:0),h=this.sprram[a+3]-3&511,F=(l&16)!=0,d=(l&32)!=0,u=16+(l&3)*16,p=t-o;if(p<0||p>=32)continue;let b=d?31-p:p,J=x*128+b;for(let f=0;f<4;f++){let M=J+f*32,$=this.rom[r+M]||0,tt=this.rom[r+n+M]||0,et=this.rom[r+n*2+M]||0,rt=this.rom[r+n*3+M]||0;for(let _=0;_<8;_++){let S=7-_,L=$>>S&1|(tt>>S&1)<<1|(et>>S&1)<<2|(rt>>S&1)<<3;if(L==0)continue;let R;F?R=h+31-(f*8+_):R=h+f*8+_,R>=0&&R<T&&(this.pixels[e+R]=this.palette[u+L])}}}}startScanline(){this.audio&&this.audioadapter&&this.audioadapter.generate(this.audio)}advanceFrame(t){var e=super.advanceFrame(t);if(this.watchdog_counter--<=0)throw new G("WATCHDOG FIRED");return this.cpu.interrupt(this.ctcVector),e}reset(){super.reset(),this.watchdog_counter=O,this.interruptEnabled=!1,this.ctcVector=0,this.psg1.reset(),this.psg2.reset()}loadROM(t){this.rom=U(t,this.defaultROMSize);for(let e=0;e<64;e++)this.updatePalette(e*2)}loadState(t){super.loadState(t),this.sprram.set(t.sprram),this.vram.set(t.vram),this.palram.set(t.palram),this.watchdog_counter=t.wdc,this.interruptEnabled=t.ie,this.ctcVector=t.ctcv;for(let e=0;e<64;e++)this.updatePalette(e*2)}saveState(){var t=super.saveState();return t.sprram=this.sprram.slice(0),t.vram=this.vram.slice(0),t.palram=this.palram.slice(0),t.wdc=this.watchdog_counter,t.ie=this.interruptEnabled,t.ctcv=this.ctcVector,t}};var mt=[{id:"minimal.c",name:"Minimal Example"},{id:"gfxtest.c",name:"Graphics Test"}],I=class extends X{constructor(){super(...arguments);this.getMemoryMap=function(){return{main:[{name:"Program ROM",start:0,size:57344,type:"rom"},{name:"NVRAM",start:57344,size:2048,type:"ram"},{name:"Sprite RAM",start:59392,size:512,type:"ram"},{name:"Video RAM",start:61440,size:2048,type:"ram"},{name:"Palette RAM",start:63488,size:128,type:"ram"}]}}}newMachine(){return new A}getPresets(){return mt}readAddress(t){return this.machine.readConst(t)}readVRAMAddress(t){return t<512?this.machine.sprram[t]:t<2560?this.machine.vram[t-512]:this.machine.palram[t-2560&127]}};B.mcr=I;
//# sourceMappingURL=mcr-FYCFELOC.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/machine/mcr.ts", "../src/platform/mcr.ts"],
"sourcesContent": ["// based on https://raw.githubusercontent.com/mamedev/mame/refs/heads/master/src/mame/midway/mcr.cpp\n// license:BSD-3-Clause\n// copyright-holders:Aaron Giles\n\nimport { Z80, Z80State } from \"../common/cpu/ZilogZ80\";\nimport { BasicScanlineMachine } from \"../common/devices\";\nimport { KeyFlags, newAddressDecoder, padBytes, Keys, makeKeycodeMap, newKeyboardHandler, EmuHalt } from \"../common/emu\";\nimport { MasterAudio, AY38910_Audio, TssChannelAdapter } from \"../common/audio\";\n\n// MCR-II constants (91490 CPU board)\nconst MCR2_XTAL = 19968000;\nconst MCR2_CPU_FREQ = MCR2_XTAL / 4; // ~4.992 MHz\nconst MCR2_NUM_VISIBLE_SCANLINES = 480;\nconst MCR2_NUM_TOTAL_SCANLINES = 525;\nconst MCR2_CANVAS_WIDTH = 512;\nconst MCR2_FPS = 30;\nconst MCR2_CYCLES_PER_LINE = Math.floor(MCR2_CPU_FREQ / (MCR2_NUM_TOTAL_SCANLINES * MCR2_FPS));\n\nconst MCR2_TILE_COLS = 32;\nconst MCR2_TILE_ROWS = 30;\nconst MCR2_TILE_SIZE = 8; // double-pixels for BG\n\nconst INITIAL_WATCHDOG = 16;\n\nfunction pal3bit(v: number): number {\n v &= 7;\n return (v << 5) | (v << 2) | (v >> 1);\n}\n\nconst MCR2_KEYCODE_MAP = makeKeycodeMap([\n [Keys.SELECT, 0, 0x1], // Coin 1\n [Keys.START, 0, 0x4], // 1P Start\n [Keys.VK_2, 0, 0x8], // 2P Start\n [Keys.UP, 1, 0x1], // P1 Up\n [Keys.DOWN, 1, 0x2], // P1 Down\n [Keys.LEFT, 1, 0x4], // P1 Left\n [Keys.RIGHT, 1, 0x8], // P1 Right\n [Keys.A, 1, 0x10], // P1 Button 1\n [Keys.B, 1, 0x20], // P1 Button 2\n [Keys.P2_UP, 2, 0x1], // P2 Up\n [Keys.P2_DOWN, 2, 0x2], // P2 Down\n [Keys.P2_LEFT, 2, 0x4], // P2 Left\n [Keys.P2_RIGHT, 2, 0x8], // P2 Right\n [Keys.P2_A, 2, 0x10], // P2 Button 1\n [Keys.P2_B, 2, 0x20], // P2 Button 2\n]);\n\n// ROM blob layout\nconst ROM_PROGRAM_START = 0x0;\nconst ROM_PROGRAM_SIZE = 0xE000;\nconst ROM_BG_GFX_START = ROM_PROGRAM_SIZE;\nconst ROM_BG_GFX_SIZE = 0x4000; // 16KB background tiles (2 bitplanes \u00D7 8KB)\nconst ROM_SPR_GFX_START = ROM_BG_GFX_START + ROM_BG_GFX_SIZE;\nconst ROM_SPR_GFX_SIZE = 0x8000; // 32KB sprites (4 bitplanes \u00D7 8KB)\nconst SSIO_ROM_SIZE = 0x4000;\nconst ROM_TOTAL_SIZE = ROM_PROGRAM_SIZE + ROM_BG_GFX_SIZE + ROM_SPR_GFX_SIZE + SSIO_ROM_SIZE;\n\nexport class MCR2Machine extends BasicScanlineMachine {\n\n cpuFrequency = MCR2_CPU_FREQ;\n canvasWidth = MCR2_CANVAS_WIDTH;\n numVisibleScanlines = MCR2_NUM_VISIBLE_SCANLINES;\n numTotalScanlines = MCR2_NUM_TOTAL_SCANLINES;\n cpuCyclesPerLine = MCR2_CYCLES_PER_LINE;\n defaultROMSize = ROM_TOTAL_SIZE;\n sampleRate = MCR2_FPS * MCR2_NUM_TOTAL_SCANLINES * 2;\n\n cpu = new Z80();\n ram = new Uint8Array(0x800); // E000-E7FF (NVRAM)\n sprram = new Uint8Array(0x200); // E800-E9FF (sprite RAM)\n vram = new Uint8Array(0x800); // F000-F7FF (video RAM)\n palram = new Uint8Array(0x80); // F800-F87F (palette RAM)\n\n palette = new Uint32Array(64);\n\n interruptEnabled = false;\n watchdog_counter = INITIAL_WATCHDOG;\n ctcVector = 0;\n\n audioadapter: TssChannelAdapter;\n psg1: AY38910_Audio;\n psg2: AY38910_Audio;\n\n constructor() {\n super();\n var audio = new MasterAudio();\n this.psg1 = new AY38910_Audio(audio);\n this.psg2 = new AY38910_Audio(audio);\n this.audioadapter = new TssChannelAdapter(\n [this.psg1.psg, this.psg2.psg], 2, this.sampleRate\n );\n\n this.connectCPUMemoryBus(this);\n this.connectCPUIOBus(this.newIOBus());\n this.inputs.set([0, 0, 0, 0xff, 0xff]); // inputs + DIP switches\n this.handler = newKeyboardHandler(this.inputs, MCR2_KEYCODE_MAP);\n }\n\n // Main CPU memory read\n read = newAddressDecoder([\n [0x0000, 0xDFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],\n [0xE000, 0xE7FF, 0x7FF, (a) => { return this.ram[a]; }],\n [0xE800, 0xEFFF, 0x1FF, (a) => { return this.sprram[a]; }],\n [0xF000, 0xF7FF, 0x7FF, (a) => { return this.vram[a]; }],\n [0xF800, 0xFFFF, 0x7F, (a) => { return this.palram[a]; }],\n ]);\n\n readConst(a: number): number | null {\n return this.read(a);\n }\n\n // Main CPU memory write\n write = newAddressDecoder([\n [0xE000, 0xE7FF, 0x7FF, (a, v) => { this.ram[a] = v; }],\n [0xE800, 0xEFFF, 0x1FF, (a, v) => { this.sprram[a] = v; }],\n [0xF000, 0xF7FF, 0x7FF, (a, v) => { this.vram[a] = v; }],\n [0xF800, 0xFFFF, 0x7F, (a, v) => {\n this.palram[a] = v;\n this.updatePalette(a);\n }],\n ]);\n\n // I/O bus\n newIOBus() {\n return {\n read: (addr: number) => {\n addr &= 0xFF;\n if (addr <= 0x04) {\n return this.inputs[addr]; // SSIO input ports\n }\n if (addr >= 0x08 && addr <= 0x0F) {\n return this.inputs[3]; // DIP switches\n Line truncated
"mappings": "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 truncated
"names": ["MCR2_XTAL", "MCR2_CPU_FREQ", "MCR2_NUM_VISIBLE_SCANLINES", "MCR2_NUM_TOTAL_SCANLINES", "MCR2_CANVAS_WIDTH", "MCR2_FPS", "MCR2_CYCLES_PER_LINE", "MCR2_TILE_COLS", "MCR2_TILE_ROWS", "MCR2_TILE_SIZE", "INITIAL_WATCHDOG", "pal3bit", "v", "MCR2_KEYCODE_MAP", "makeKeycodeMap", "Keys", "ROM_PROGRAM_SIZE", "ROM_BG_GFX_START", "ROM_BG_GFX_SIZE", "ROM_SPR_GFX_START", "ROM_SPR_GFX_SIZE", "SSIO_ROM_SIZE", "ROM_TOTAL_SIZE", "MCR2Machine", "BasicScanlineMachine", "MCR2_CPU_FREQ", "MCR2_CANVAS_WIDTH", "MCR2_NUM_VISIBLE_SCANLINES", "MCR2_NUM_TOTAL_SCANLINES", "MCR2_CYCLES_PER_LINE", "MCR2_FPS", "Z80", "INITIAL_WATCHDOG", "newAddressDecoder", "a", "v", "audio", "MasterAudio", "AY38910_Audio", "TssChannelAdapter", "newKeyboardHandler", "MCR2_KEYCODE_MAP", "addr", "val", "offset", "i", "pal", "r", "pal3bit", "g", "b", "r_msb", "sl", "pixofs", "tileRow", "MCR2_TILE_SIZE", "tileY", "MCR2_TILE_ROWS", "tileCol", "MCR2_TILE_COLS", "vramOfs", "byte0", "byte1", "tileCode", "tilePalette", "flipX", "ty", "pixX", "outOfs", "row", "palette", "gfxBase", "halfSize", "byteOfs", "p0L", "p1L", "colorBase", "x", "bit", "srcX", "color", "scanline", "planeSize", "sprNum", "base", "sy", "attrib", "code", "sx", "flipY", "relY", "sprOfs", "col", "p0", "p1", "p2", "p3", "px", "trap", "steps", "EmuHalt", "data", "padBytes", "state", "MCR2_PRESETS", "MCR2Platform", "BaseZ80MachinePlatform", "MCR2Machine", "a", "PLATFORMS"]
}
-2
View File
@@ -1,2 +0,0 @@
import{J as X,c as B,d as D,e as P,k as Y,r as z}from"./chunk-GTDJ7CMC.js";import{$ as U,K as v,T as G,W as s,X as N,Z as V,aa as O}from"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";var et=19968e3,W=et/4,Z=480,y=525,T=512,K=30,rt=Math.floor(W/(y*K)),H=32,st=30,w=16,g=16;function C(F){return F&=7,F<<5|F<<2|F>>1}var it=V([[s.SELECT,0,1],[s.START,0,4],[s.VK_2,0,8],[s.UP,1,1],[s.DOWN,1,2],[s.LEFT,1,4],[s.RIGHT,1,8],[s.A,1,16],[s.B,1,32],[s.P2_UP,2,1],[s.P2_DOWN,2,2],[s.P2_LEFT,2,4],[s.P2_RIGHT,2,8],[s.P2_A,2,16],[s.P2_B,2,32]]);var at=49152,nt=49152,k=16384,lt=73728,q=2*32768,ot=16384,mt=at+k+q+ot,b=class extends z{constructor(){super();this.cpuFrequency=W;this.canvasWidth=T;this.numVisibleScanlines=Z;this.numTotalScanlines=y;this.cpuCyclesPerLine=rt;this.defaultROMSize=mt;this.sampleRate=K*y*2;this.cpu=new B;this.ram=new Uint8Array(2048);this.sprram=new Uint8Array(512);this.vram=new Uint8Array(2048);this.palram=new Uint8Array(128);this.palette=new Uint32Array(64);this.interruptEnabled=!1;this.watchdog_counter=g;this.ctcVector=0;this.read=O([[0,49151,65535,t=>this.rom?this.rom[t]:0],[49152,57343,2047,t=>this.ram[t]],[57344,59391,511,t=>this.sprram[t]],[61440,63487,2047,t=>this.vram[t]],[63488,65535,127,t=>this.palram[t]]]);this.write=O([[49152,57343,2047,(t,e)=>{this.ram[t]=e}],[57344,59391,511,(t,e)=>{this.sprram[t]=e}],[61440,63487,2047,(t,e)=>{this.vram[t]=e}],[63488,65535,127,(t,e)=>{this.palram[t]=e,this.updatePalette(t)}]]);var t=new D;this.psg1=new P(t),this.psg2=new P(t),this.audioadapter=new Y([this.psg1.psg,this.psg2.psg],2,this.sampleRate),this.connectCPUMemoryBus(this),this.connectCPUIOBus(this.newIOBus()),this.inputs.set([0,0,0,255,255]),this.handler=N(this.inputs,it)}readConst(t){return this.read(t)}newIOBus(){return{read:t=>(t&=255,t<=4?this.inputs[t]:t>=8&&t<=15?this.inputs[3]:(t>=240&&t<=243,0)),write:(t,e)=>{t&=255,t==224&&(this.watchdog_counter=g),t>=240&&t<=243&&((t&3)==0&&!(e&1)||(e&1)==0&&(this.ctcVector=e&248)),t>=0&&t<=7}}}updatePalette(t){let e=t>>1;if(e>=64)return;let r=this.palram[e*2+1],o=C(r>>6&3),a=C(r&7),i=C(r>>3&7),m=(this.palram[e*2]&1)<<2;o=C(m|r>>6&3),this.palette[e]=4278190080|i<<16|a<<8|o}drawScanline(){let t=this.scanline;if(t>=Z)return;let e=t*T,r=Math.floor(t/w),o=t%w;if(r<st)for(let a=0;a<H;a++){let i=(r*H+a)*2,m=this.vram[i],l=this.vram[i+1],f=m|(l&3)<<8,x=l>>4&3,_=(l&4)!=0,A=(l&8)!=0?15-o:o,R=a*w;this.drawTileLine(e+R,f,A,x,_)}this.drawSpriteScanline(t,e)}drawTileLine(t,e,r,o,a){let i=nt,m=k/2,l=e*32,f=l+(r<8,r),x=l+16+(r<8,r),_=this.rom[i+f]||0,S=this.rom[i+m+f]||0,A=this.rom[i+x]||0,R=this.rom[i+m+x]||0,h=o*4;for(let n=0;n<8;n++){let u=7-n,p=a?15-n:n,c=_>>u&1|(S>>u&1)<<1;this.pixels[t+p]=this.palette[h+c]}for(let n=0;n<8;n++){let u=7-n,p=a?7-n:8+n,c=A>>u&1|(R>>u&1)<<1;this.pixels[t+p]=this.palette[h+c]}}drawSpriteScanline(t,e){let r=lt,o=q/4;for(let a=31;a>=0;a--){let i=a*4,m=this.sprram[i]-2&255;m=496-m;let l=this.sprram[i+1],f=this.sprram[i+2]|(l&8?256:0),x=this.sprram[i+3]-3&511,_=(l&16)!=0,S=(l&32)!=0,R=16+(l&3)*16,h=t-m;if(h<0||h>=32)continue;let n=S?31-h:h,u=f*128+n;for(let p=0;p<4;p++){let c=u+p*32,j=this.rom[r+c]||0,J=this.rom[r+o+c]||0,$=this.rom[r+o*2+c]||0,tt=this.rom[r+o*3+c]||0;for(let d=0;d<8;d++){let E=7-d,L=j>>E&1|(J>>E&1)<<1|($>>E&1)<<2|(tt>>E&1)<<3;if(L==0)continue;let M;_?M=x+31-(p*8+d):M=x+p*8+d,M>=0&&M<T&&(this.pixels[e+M]=this.palette[R+L])}}}}startScanline(){this.audio&&this.audioadapter&&this.audioadapter.generate(this.audio)}advanceFrame(t){var e=super.advanceFrame(t);if(this.watchdog_counter--<=0)throw new G("WATCHDOG FIRED");return this.cpu.interrupt(this.ctcVector),e}reset(){super.reset(),this.watchdog_counter=g,this.interruptEnabled=!1,this.ctcVector=0,this.psg1.reset(),this.psg2.reset()}loadROM(t){this.rom=U(t,this.defaultROMSize);for(let e=0;e<64;e++)this.updatePalette(e*2)}loadState(t){super.loadState(t),this.sprram.set(t.sprram),this.vram.set(t.vram),this.palram.set(t.palram),this.watchdog_counter=t.wdc,this.interruptEnabled=t.ie,this.ctcVector=t.ctcv;for(let e=0;e<64;e++)this.updatePalette(e*2)}saveState(){var t=super.saveState();return t.sprram=this.sprram.slice(0),t.vram=this.vram.slice(0),t.palram=this.palram.slice(0),t.wdc=this.watchdog_counter,t.ie=this.interruptEnabled,t.ctcv=this.ctcVector,t}};var pt=[{id:"minimal.c",name:"Minimal Example"},{id:"gfxtest.c",name:"Graphics Test"}],I=class extends X{constructor(){super(...arguments);this.getMemoryMap=function(){return{main:[{name:"Program ROM",start:0,size:57344,type:"rom"},{name:"NVRAM",start:57344,size:2048,type:"ram"},{name:"Sprite RAM",start:59392,size:512,type:"ram"},{name:"Video RAM",start:61440,size:2048,type:"ram"},{name:"Palette RAM",start:63488,size:128,type:"ram"}]}}}newMachine(){return new b}getPresets(){return pt}readAddress(t){return this.machine.readConst(t)}readVRAMAddress(t){return t<512?this.machine.sprram[t]:t<2560?this.machine.vram[t-512]:this.machine.palram[t-2560&127]}};v.mcr=I;
//# sourceMappingURL=mcr-VN2VYZMU.js.map
-7
View File
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": ["../src/machine/mcr.ts", "../src/platform/mcr.ts"],
"sourcesContent": ["\nimport { Z80, Z80State } from \"../common/cpu/ZilogZ80\";\nimport { BasicScanlineMachine } from \"../common/devices\";\nimport { KeyFlags, newAddressDecoder, padBytes, Keys, makeKeycodeMap, newKeyboardHandler, EmuHalt } from \"../common/emu\";\nimport { MasterAudio, AY38910_Audio, TssChannelAdapter } from \"../common/audio\";\n\n// MCR-II constants (91490 CPU board)\nconst MCR2_XTAL = 19968000;\nconst MCR2_CPU_FREQ = MCR2_XTAL / 4; // ~4.992 MHz\nconst MCR2_NUM_VISIBLE_SCANLINES = 480;\nconst MCR2_NUM_TOTAL_SCANLINES = 525;\nconst MCR2_CANVAS_WIDTH = 512;\nconst MCR2_FPS = 30;\nconst MCR2_CYCLES_PER_LINE = Math.floor(MCR2_CPU_FREQ / (MCR2_NUM_TOTAL_SCANLINES * MCR2_FPS));\n\nconst MCR2_TILE_COLS = 32;\nconst MCR2_TILE_ROWS = 30;\nconst MCR2_TILE_SIZE = 16;\n\nconst INITIAL_WATCHDOG = 16;\n\nfunction pal3bit(v: number): number {\n v &= 7;\n return (v << 5) | (v << 2) | (v >> 1);\n}\n\nconst MCR2_KEYCODE_MAP = makeKeycodeMap([\n [Keys.SELECT, 0, 0x1], // Coin 1\n [Keys.START, 0, 0x4], // 1P Start\n [Keys.VK_2, 0, 0x8], // 2P Start\n [Keys.UP, 1, 0x1], // P1 Up\n [Keys.DOWN, 1, 0x2], // P1 Down\n [Keys.LEFT, 1, 0x4], // P1 Left\n [Keys.RIGHT, 1, 0x8], // P1 Right\n [Keys.A, 1, 0x10], // P1 Button 1\n [Keys.B, 1, 0x20], // P1 Button 2\n [Keys.P2_UP, 2, 0x1], // P2 Up\n [Keys.P2_DOWN, 2, 0x2], // P2 Down\n [Keys.P2_LEFT, 2, 0x4], // P2 Left\n [Keys.P2_RIGHT, 2, 0x8], // P2 Right\n [Keys.P2_A, 2, 0x10], // P2 Button 1\n [Keys.P2_B, 2, 0x20], // P2 Button 2\n]);\n\n// ROM blob layout\nconst ROM_PROGRAM_START = 0x0;\nconst ROM_PROGRAM_SIZE = 0xC000;\nconst ROM_BG_GFX_START = 0xC000;\nconst ROM_BG_GFX_SIZE = 0x4000; // 16KB background tiles (2 bitplanes \u00D7 8KB)\nconst ROM_SPR_GFX_START = 0x12000;\nconst ROM_SPR_GFX_SIZE = 2 * 0x8000; // 32KB sprites (4 bitplanes \u00D7 8KB)\nconst SSIO_ROM_SIZE = 0x4000;\nconst ROM_TOTAL_SIZE = ROM_PROGRAM_SIZE + ROM_BG_GFX_SIZE + ROM_SPR_GFX_SIZE + SSIO_ROM_SIZE;\n\nexport class MCR2Machine extends BasicScanlineMachine {\n\n cpuFrequency = MCR2_CPU_FREQ;\n canvasWidth = MCR2_CANVAS_WIDTH;\n numVisibleScanlines = MCR2_NUM_VISIBLE_SCANLINES;\n numTotalScanlines = MCR2_NUM_TOTAL_SCANLINES;\n cpuCyclesPerLine = MCR2_CYCLES_PER_LINE;\n defaultROMSize = ROM_TOTAL_SIZE;\n sampleRate = MCR2_FPS * MCR2_NUM_TOTAL_SCANLINES * 2;\n\n cpu = new Z80();\n ram = new Uint8Array(0x800); // E000-E7FF (NVRAM)\n sprram = new Uint8Array(0x200); // E800-E9FF (sprite RAM)\n vram = new Uint8Array(0x800); // F000-F7FF (video RAM)\n palram = new Uint8Array(0x80); // F800-F87F (palette RAM)\n\n palette = new Uint32Array(64);\n\n interruptEnabled = false;\n watchdog_counter = INITIAL_WATCHDOG;\n ctcVector = 0;\n\n audioadapter: TssChannelAdapter;\n psg1: AY38910_Audio;\n psg2: AY38910_Audio;\n\n constructor() {\n super();\n var audio = new MasterAudio();\n this.psg1 = new AY38910_Audio(audio);\n this.psg2 = new AY38910_Audio(audio);\n this.audioadapter = new TssChannelAdapter(\n [this.psg1.psg, this.psg2.psg], 2, this.sampleRate\n );\n\n this.connectCPUMemoryBus(this);\n this.connectCPUIOBus(this.newIOBus());\n this.inputs.set([0, 0, 0, 0xff, 0xff]); // inputs + DIP switches\n this.handler = newKeyboardHandler(this.inputs, MCR2_KEYCODE_MAP);\n }\n\n // Main CPU memory read\n read = newAddressDecoder([\n [0x0000, 0xBFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],\n [0xC000, 0xDFFF, 0x7FF, (a) => { return this.ram[a]; }],\n [0xE000, 0xE7FF, 0x1FF, (a) => { return this.sprram[a]; }],\n [0xF000, 0xF7FF, 0x7FF, (a) => { return this.vram[a]; }],\n [0xF800, 0xFFFF, 0x7F, (a) => { return this.palram[a]; }],\n ]);\n\n readConst(a: number): number | null {\n return this.read(a);\n }\n\n // Main CPU memory write\n write = newAddressDecoder([\n [0xC000, 0xDFFF, 0x7FF, (a, v) => { this.ram[a] = v; }],\n [0xE000, 0xE7FF, 0x1FF, (a, v) => { this.sprram[a] = v; }],\n [0xF000, 0xF7FF, 0x7FF, (a, v) => { this.vram[a] = v; }],\n [0xF800, 0xFFFF, 0x7F, (a, v) => {\n this.palram[a] = v;\n this.updatePalette(a);\n }],\n ]);\n\n // I/O bus\n newIOBus() {\n return {\n read: (addr: number) => {\n addr &= 0xFF;\n if (addr <= 0x04) {\n return this.inputs[addr]; // SSIO input ports\n }\n if (addr >= 0x08 && addr <= 0x0F) {\n return this.inputs[3]; // DIP switches\n }\n if (addr >= 0xF0 && addr <= 0xF3) {\n return 0; // CTC read\n }\n return 0;\n },\n write: (addr: number, val: number)Line truncated
"mappings": "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 truncated
"names": ["MCR2_XTAL", "MCR2_CPU_FREQ", "MCR2_NUM_VISIBLE_SCANLINES", "MCR2_NUM_TOTAL_SCANLINES", "MCR2_CANVAS_WIDTH", "MCR2_FPS", "MCR2_CYCLES_PER_LINE", "MCR2_TILE_COLS", "MCR2_TILE_ROWS", "MCR2_TILE_SIZE", "INITIAL_WATCHDOG", "pal3bit", "v", "MCR2_KEYCODE_MAP", "makeKeycodeMap", "Keys", "ROM_PROGRAM_SIZE", "ROM_BG_GFX_START", "ROM_BG_GFX_SIZE", "ROM_SPR_GFX_START", "ROM_SPR_GFX_SIZE", "SSIO_ROM_SIZE", "ROM_TOTAL_SIZE", "MCR2Machine", "BasicScanlineMachine", "MCR2_CPU_FREQ", "MCR2_CANVAS_WIDTH", "MCR2_NUM_VISIBLE_SCANLINES", "MCR2_NUM_TOTAL_SCANLINES", "MCR2_CYCLES_PER_LINE", "MCR2_FPS", "Z80", "INITIAL_WATCHDOG", "newAddressDecoder", "a", "v", "audio", "MasterAudio", "AY38910_Audio", "TssChannelAdapter", "newKeyboardHandler", "MCR2_KEYCODE_MAP", "addr", "val", "offset", "i", "pal", "r", "pal3bit", "g", "b", "r_msb", "sl", "pixofs", "tileRow", "MCR2_TILE_SIZE", "tileY", "MCR2_TILE_ROWS", "tileCol", "MCR2_TILE_COLS", "vramOfs", "byte0", "byte1", "tileCode", "tilePalette", "flipX", "ty", "pixX", "outOfs", "row", "palette", "gfxBase", "halfSize", "tileOfs", "leftByteOfs", "rightByteOfs", "p0L", "p1L", "p0R", "p1R", "colorBase", "x", "bit", "srcX", "color", "scanline", "planeSize", "sprNum", "base", "sy", "attrib", "code", "sx", "flipY", "relY", "sprOfs", "col", "byteOfs", "p0", "p1", "p2", "p3", "px", "trap", "steps", "EmuHalt", "data", "padBytes", "state", "MCR2_PRESETS", "MCR2Platform", "BaseZ80MachinePlatform", "MCR2Machine", "a", "PLATFORMS"]
}
+1
View File
@@ -44,6 +44,7 @@ function importPlatform(name) {
case "atari8": return Promise.resolve().then(() => __importStar(require("../platform/atari8")));
case "basic": return Promise.resolve().then(() => __importStar(require("../platform/basic")));
case "c64": return Promise.resolve().then(() => __importStar(require("../platform/c64")));
case "channelf": return Promise.resolve().then(() => __importStar(require("../platform/channelf")));
case "coleco": return Promise.resolve().then(() => __importStar(require("../platform/coleco")));
case "cpc": return Promise.resolve().then(() => __importStar(require("../platform/cpc")));
case "devel": return Promise.resolve().then(() => __importStar(require("../platform/devel")));
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"_index.js","sourceRoot":"","sources":["../../src/platform/_index.ts"],"names":[],"mappings":";AAAA,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtD,wCAsCG;AAtCH,SAAgB,cAAc,CAAC,IAAY;IACvC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,WAAW,CAAC,CAAC,yDAAc,uBAAuB,IAAE;QACzD,KAAK,WAAW,CAAC,CAAC,yDAAc,uBAAuB,IAAE;QACzD,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,IAAI,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAC3C,KAAK,SAAS,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAChD,KAAK,MAAM,CAAC,CAAC,yDAAc,kBAAkB,IAAE;QAC/C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,cAAc,CAAC,CAAC,yDAAc,0BAA0B,IAAE;QAC/D,KAAK,gBAAgB,CAAC,CAAC,yDAAc,4BAA4B,IAAE;QACnE,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,IAAI,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAC3C,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAAA;IAChE,CAAC;AACH,CAAC"}
{"version":3,"file":"_index.js","sourceRoot":"","sources":["../../src/platform/_index.ts"],"names":[],"mappings":";AAAA,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtD,wCAuCG;AAvCH,SAAgB,cAAc,CAAC,IAAY;IACvC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,WAAW,CAAC,CAAC,yDAAc,uBAAuB,IAAE;QACzD,KAAK,WAAW,CAAC,CAAC,yDAAc,uBAAuB,IAAE;QACzD,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,IAAI,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAC3C,KAAK,SAAS,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAChD,KAAK,MAAM,CAAC,CAAC,yDAAc,kBAAkB,IAAE;QAC/C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,cAAc,CAAC,CAAC,yDAAc,0BAA0B,IAAE;QAC/D,KAAK,gBAAgB,CAAC,CAAC,yDAAc,4BAA4B,IAAE;QACnE,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,QAAQ,CAAC,CAAC,yDAAc,oBAAoB,IAAE;QACnD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,OAAO,CAAC,CAAC,yDAAc,mBAAmB,IAAE;QACjD,KAAK,SAAS,CAAC,CAAC,yDAAc,qBAAqB,IAAE;QACrD,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,KAAK,CAAC,CAAC,yDAAc,iBAAiB,IAAE;QAC7C,KAAK,UAAU,CAAC,CAAC,yDAAc,sBAAsB,IAAE;QACvD,KAAK,IAAI,CAAC,CAAC,yDAAc,gBAAgB,IAAE;QAC3C,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAAA;IAChE,CAAC;AACH,CAAC"}
+70
View File
@@ -0,0 +1,70 @@
"use strict";
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
Object.defineProperty(exports, "__esModule", { value: true });
const baseplatform_1 = require("../common/baseplatform");
const emu_1 = require("../common/emu");
const channelf_1 = require("../machine/channelf");
const disasmF8_1 = require("../common/cpu/disasmF8");
const util_1 = require("../common/util");
var CHANNELF_PRESETS = [
{ id: 'hello.dasm', name: 'Hello World (ASM)' },
];
function cpuStateToLongString_F8(c) {
return "PC0 = " + (0, util_1.hex)(c.PC0, 4) + " PC1 = " + (0, util_1.hex)(c.PC1, 4) + "\n"
+ "DC0 = " + (0, util_1.hex)(c.DC0, 4) + " DC1 = " + (0, util_1.hex)(c.DC1, 4) + "\n"
+ " A = " + (0, util_1.hex)(c.A, 2) + " W = " + (0, util_1.hex)(c.W, 2) + "\n"
+ " IS = " + (0, util_1.hex)(c.IS, 2) + "\n"
+ (0, util_1.printFlags)(c.W, ['S', 'C', 'Z', 'O', 'I'], true) + "\n"
+ " R0-R3: " + c.R.slice(0, 4).map(v => (0, util_1.hex)(v, 2)).join(' ') + "\n"
+ " R4-R7: " + c.R.slice(4, 8).map(v => (0, util_1.hex)(v, 2)).join(' ') + "\n"
+ " R8/J/H: " + c.R.slice(8, 12).map(v => (0, util_1.hex)(v, 2)).join(' ') + "\n"
+ " K/Q: " + c.R.slice(12, 16).map(v => (0, util_1.hex)(v, 2)).join(' ') + "\n";
}
class ChannelFPlatform extends baseplatform_1.BaseMachinePlatform {
newMachine() { return new channelf_1.ChannelF(); }
getPresets() { return CHANNELF_PRESETS; }
getDefaultExtensions() { return [".dasm"]; }
getToolForFilename(fn) {
if (fn.endsWith(".c"))
return "cc65";
if (fn.endsWith(".s") || fn.endsWith(".ca65"))
return "ca65";
return "dasm";
}
readAddress(a) { return this.machine.readConst(a); }
disassemble(pc, read) {
return (0, disasmF8_1.disassembleF8)(pc, read(pc), read(pc + 1), read(pc + 2));
}
getDebugCategories() {
return ['CPU', 'I/O', 'VRAM'];
}
getDebugInfo(category, state) {
switch (category) {
case 'CPU': return cpuStateToLongString_F8(state.c);
case 'I/O':
return "Port 0: " + (0, util_1.hex)(state.port0 || 0, 2) + "\n"
+ "Port 1: " + (0, util_1.hex)(state.port1 || 0, 2) + "\n"
+ "Port 4: " + (0, util_1.hex)(state.port4 || 0, 2) + "\n"
+ "Port 5: " + (0, util_1.hex)(state.port5 || 0, 2) + "\n"
+ "Row: " + (0, util_1.hex)(state.row_reg || 0, 2) + "\n"
+ "Col: " + (0, util_1.hex)(state.col_reg || 0, 2) + "\n";
case 'VRAM': return '';
default: return '';
}
}
getMemoryMap() {
return {
main: [
{ name: 'BIOS', start: 0x0000, size: 0x0800, type: 'rom' },
{ name: 'Cart ROM', start: 0x0800, size: 0x7800, type: 'rom' },
]
};
}
}
emu_1.PLATFORMS['channelf'] = ChannelFPlatform;
//# sourceMappingURL=channelf.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"channelf.js","sourceRoot":"","sources":["../../src/platform/channelf.ts"],"names":[],"mappings":"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"}
+33 -1
View File
@@ -68,6 +68,38 @@ class GameBoyPlatform extends baseplatform_1.BaseMachinePlatform {
return "https://8bitworkshop.com/docs/platforms/gameboy/";
}
}
const GBC_PRESETS = [
{ id: 'hello_color.c', name: 'Hello Color World (C)' },
];
class GameBoyColorPlatform extends GameBoyPlatform {
newMachine() {
var m = new gb_1.GameBoyMachine();
m.forceColor = true;
return m;
}
getPresets() { return GBC_PRESETS; }
getROMExtension() {
return ".gbc";
}
getMemoryMap() {
return {
main: [
{ name: 'ROM Bank 0', start: 0x0000, size: 0x4000, type: 'rom' },
{ name: 'ROM Bank 1+', start: 0x4000, size: 0x4000, type: 'rom' },
{ name: 'Video RAM B0', start: 0x8000, size: 0x2000, type: 'ram' },
{ name: 'External RAM', start: 0xA000, size: 0x2000, type: 'ram' },
{ name: 'Work RAM 0', start: 0xC000, size: 0x1000, type: 'ram' },
{ name: 'Work RAM 1-7', start: 0xD000, size: 0x1000, type: 'ram' },
{ name: 'OAM', start: 0xFE00, size: 0xA0, type: 'ram' },
{ name: 'I/O Registers', start: 0xFF00, size: 0x80, type: 'io' },
{ name: 'High RAM', start: 0xFF80, size: 0x7F, type: 'ram' },
]
};
}
showHelp() {
return "https://8bitworkshop.com/docs/platforms/gameboy/";
}
}
emu_1.PLATFORMS['gb'] = GameBoyPlatform;
emu_1.PLATFORMS['gameboy'] = GameBoyPlatform;
emu_1.PLATFORMS['gb.color'] = GameBoyColorPlatform;
//# sourceMappingURL=gb.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"gb.js","sourceRoot":"","sources":["../../src/platform/gb.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"gb.js","sourceRoot":"","sources":["../../src/platform/gb.ts"],"names":[],"mappings":"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"}
+3
View File
@@ -1,4 +1,7 @@
"use strict";
// based on https://raw.githubusercontent.com/mamedev/mame/refs/heads/master/src/mame/midway/mcr.cpp
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
Object.defineProperty(exports, "__esModule", { value: true });
const mcr_1 = require("../machine/mcr");
const baseplatform_1 = require("../common/baseplatform");
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"mcr.js","sourceRoot":"","sources":["../../src/platform/mcr.ts"],"names":[],"mappings":";;AACA,wCAA6C;AAC7C,yDAAgE;AAEhE,uCAA0C;AAE1C,MAAM,YAAY,GAAG;IACjB,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE;IAC5C,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE;CAC7C,CAAC;AAEF,MAAM,YAAa,SAAQ,qCAAmC;IAA9D;;QAUI,iBAAY,GAAG;YAAa,OAAO,EAAE,IAAI,EAAC;oBACtC,EAAC,IAAI,EAAC,aAAa,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAC;oBAC3D,EAAC,IAAI,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACpD,EAAC,IAAI,EAAC,YAAY,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACzD,EAAC,IAAI,EAAC,WAAW,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACxD,EAAC,IAAI,EAAC,aAAa,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,IAAI,EAAE,IAAI,EAAC,KAAK,EAAC;iBAC5D,EAAE,CAAA;QAAC,CAAC,CAAC;IACV,CAAC;IAfG,UAAU,KAAc,OAAO,IAAI,iBAAW,EAAE,CAAC,CAAC,CAAC;IACnD,UAAU,KAAc,OAAO,YAAY,CAAC,CAAC,CAAC;IAC9C,WAAW,CAAC,CAAC,IAAW,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;CAQJ;AAED,eAAS,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC"}
{"version":3,"file":"mcr.js","sourceRoot":"","sources":["../../src/platform/mcr.ts"],"names":[],"mappings":";AAAA,oGAAoG;AACpG,uBAAuB;AACvB,gCAAgC;;AAEhC,wCAA6C;AAC7C,yDAAgE;AAEhE,uCAA0C;AAE1C,MAAM,YAAY,GAAG;IACjB,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE;IAC5C,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE;CAC7C,CAAC;AAEF,MAAM,YAAa,SAAQ,qCAAmC;IAA9D;;QAUI,iBAAY,GAAG;YAAa,OAAO,EAAE,IAAI,EAAC;oBACtC,EAAC,IAAI,EAAC,aAAa,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAC;oBAC3D,EAAC,IAAI,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACpD,EAAC,IAAI,EAAC,YAAY,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACzD,EAAC,IAAI,EAAC,WAAW,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,KAAK,EAAE,IAAI,EAAC,KAAK,EAAC;oBACxD,EAAC,IAAI,EAAC,aAAa,EAAE,KAAK,EAAC,MAAM,EAAE,IAAI,EAAC,IAAI,EAAE,IAAI,EAAC,KAAK,EAAC;iBAC5D,EAAE,CAAA;QAAC,CAAC,CAAC;IACV,CAAC;IAfG,UAAU,KAAc,OAAO,IAAI,iBAAW,EAAE,CAAC,CAAC,CAAC;IACnD,UAAU,KAAc,OAAO,YAAY,CAAC,CAAC,CAAC;IAC9C,WAAW,CAAC,CAAC,IAAW,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,eAAe,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;CAQJ;AAED,eAAS,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC"}
+1 -1
View File
@@ -1 +1 @@
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/mcr.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/mcr.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/8bws.ts","../src/tools/nodemock.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/tools/termimage.ts","../src/tools/testlib.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workerlib.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.ts","../src/worker/tools/remote.ts","../src/worker/tools/sdcc.ts","../src/worker/tools/verilog.ts","../src/worker/tooLine truncated
{"root":["../src/common/analysis.ts","../src/common/audio.ts","../src/common/baseplatform.ts","../src/common/binutils.ts","../src/common/devices.ts","../src/common/emu.ts","../src/common/mameplatform.ts","../src/common/probe.ts","../src/common/recorder.ts","../src/common/teletype.ts","../src/common/tokenizer.ts","../src/common/util.ts","../src/common/vlist.ts","../src/common/wasmplatform.ts","../src/common/workertypes.ts","../src/common/audio/CommodoreTape.ts","../src/common/basic/compiler.ts","../src/common/basic/fuzz.ts","../src/common/basic/run.ts","../src/common/basic/runtime.ts","../src/common/cpu/6809.ts","../src/common/cpu/ARM.ts","../src/common/cpu/F8.ts","../src/common/cpu/MOS6502.ts","../src/common/cpu/SM83.ts","../src/common/cpu/ZilogZ80.ts","../src/common/cpu/disasm6502.ts","../src/common/cpu/disasmF8.ts","../src/common/cpu/disasmHuC6280.ts","../src/common/cpu/disasmSM83.ts","../src/common/cpu/disasmz80.ts","../src/common/ecs/binpack.ts","../src/common/ecs/compiler.ts","../src/common/ecs/decoder.ts","../src/common/ecs/ecs.ts","../src/common/ecs/main.ts","../src/common/hdl/fuzz.ts","../src/common/hdl/hdlruntime.ts","../src/common/hdl/hdltypes.ts","../src/common/hdl/hdlwasm.ts","../src/common/hdl/vxmlparser.ts","../src/common/hdl/vxmltest.ts","../src/common/video/tms9918a.ts","../src/common/wasi/libretro.ts","../src/common/wasi/wasishim.ts","../src/ide/analytics.ts","../src/ide/dialogs.ts","../src/ide/embedui.ts","../src/ide/pixeleditor.ts","../src/ide/project.ts","../src/ide/services.ts","../src/ide/shareexport.ts","../src/ide/sync.ts","../src/ide/toolbar.ts","../src/ide/ui.ts","../src/ide/waveform.ts","../src/ide/windows.ts","../src/ide/views/asseteditor.ts","../src/ide/views/baseviews.ts","../src/ide/views/debug.ts","../src/ide/views/debugviews.ts","../src/ide/views/editors.ts","../src/ide/views/filters.ts","../src/ide/views/gutter.ts","../src/ide/views/tabs.ts","../src/ide/views/traceviews.ts","../src/ide/views/treeviews.ts","../src/ide/views/visuals.ts","../src/machine/apple2.ts","../src/machine/arm32.ts","../src/machine/astrocade.ts","../src/machine/atari7800.ts","../src/machine/atari8.ts","../src/machine/c64.ts","../src/machine/channelf.ts","../src/machine/coleco.ts","../src/machine/cpc.ts","../src/machine/devel.ts","../src/machine/exidy.ts","../src/machine/galaxian.ts","../src/machine/gb.ts","../src/machine/kim1.ts","../src/machine/mcr.ts","../src/machine/msx.ts","../src/machine/mw8080bw.ts","../src/machine/sms.ts","../src/machine/vdp_z80.ts","../src/machine/vic20.ts","../src/machine/vicdual.ts","../src/machine/williams.ts","../src/machine/zx.ts","../src/machine/chips/antic.ts","../src/machine/chips/gtia.ts","../src/machine/chips/pokey.ts","../src/parser/lang-6502.ts","../src/parser/lang-basic.ts","../src/parser/lang-bataribasic.ts","../src/parser/lang-fastbasic.ts","../src/parser/lang-inform6.ts","../src/parser/lang-verilog.ts","../src/parser/lang-wiz.ts","../src/parser/lang-z80.ts","../src/parser/tokens-6502.ts","../src/platform/_index.ts","../src/platform/apple2.ts","../src/platform/arm32.ts","../src/platform/astrocade.ts","../src/platform/atari7800.ts","../src/platform/atari8.ts","../src/platform/basic.ts","../src/platform/c64.ts","../src/platform/channelf.ts","../src/platform/coleco.ts","../src/platform/cpc.ts","../src/platform/devel.ts","../src/platform/exidy.ts","../src/platform/galaxian.ts","../src/platform/gb.ts","../src/platform/kim1.ts","../src/platform/markdown.ts","../src/platform/mcr.ts","../src/platform/msx.ts","../src/platform/mw8080bw.ts","../src/platform/nes.ts","../src/platform/pce.ts","../src/platform/sms.ts","../src/platform/sound_konami.ts","../src/platform/sound_williams.ts","../src/platform/vcs.ts","../src/platform/vector.ts","../src/platform/vectrex.ts","../src/platform/verilog.ts","../src/platform/vic20.ts","../src/platform/vicdual.ts","../src/platform/williams.ts","../src/platform/x86.ts","../src/platform/zmachine.ts","../src/platform/zx.ts","../src/themes/cobalt.ts","../src/themes/disassemblyTheme.ts","../src/themes/editorTheme.ts","../src/themes/mbo.ts","../src/tools/8bws.ts","../src/tools/nodemock.ts","../src/tools/runmachine.ts","../src/tools/sim6502.ts","../src/tools/termimage.ts","../src/tools/testlib.ts","../src/worker/assembler.ts","../src/worker/builder.ts","../src/worker/listingutils.ts","../src/worker/platforms.ts","../src/worker/wasiutils.ts","../src/worker/wasmutils.ts","../src/worker/workerlib.ts","../src/worker/workermain.ts","../src/worker/workertools.ts","../src/worker/server/buildenv.ts","../src/worker/server/clang.ts","../src/worker/server/server.ts","../src/worker/tools/acme.ts","../src/worker/tools/arm.ts","../src/worker/tools/bataribasic.ts","../src/worker/tools/cc2600.ts","../src/worker/tools/cc65.ts","../src/worker/tools/cc7800.ts","../src/worker/tools/dasm.ts","../src/worker/tools/ecs.ts","../src/worker/tools/m6502.ts","../src/worker/tools/m6809.ts","../src/worker/tools/mcpp.ts","../src/worker/tools/misc.ts","../src/worker/tools/oscar64.Line truncated
+1 -1
View File
@@ -1,2 +1,2 @@
import{A as z,B as A,C as B,D as C,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,y as x,z as y}from"./chunk-IBRDAYM2.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-R5KWJQBC.js";import"./chunk-GTDJ7CMC.js";import"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";export{q as clearBreakpoint,f as current_project,A as emulationHalted,n as getCurrentEditorFilename,m as getCurrentMainFilename,k as getCurrentOutput,j as getCurrentProject,v as getPlatformAndRepo,i as getPlatformStore,z as getSaveState,y as getTestOutput,l as getWorkerParams,t as gotoNewLocation,s as haltEmulation,C as highlightSearch,h as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,B as reloadWorkspaceFile,d as repo_id,p as runToPC,r as setFrameRateUI,x as setTestInput,o as setupBreakpoint,u as setupSplits,w as startUI,c as store_id};
import{A as z,B as A,C as B,D as C,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,y as x,z as y}from"./chunk-2DVTTN6M.js";import"./chunk-JSIZCY7X.js";import"./chunk-LNOKARBD.js";import"./chunk-7WOMNSMI.js";import"./chunk-GTDJ7CMC.js";import"./chunk-MZ4MJULD.js";import"./chunk-KT7KMEQC.js";export{q as clearBreakpoint,f as current_project,A as emulationHalted,n as getCurrentEditorFilename,m as getCurrentMainFilename,k as getCurrentOutput,j as getCurrentProject,v as getPlatformAndRepo,i as getPlatformStore,z as getSaveState,y as getTestOutput,l as getWorkerParams,t as gotoNewLocation,s as haltEmulation,C as highlightSearch,h as lastDebugState,e as platform,b as platform_id,g as projectWindows,a as qs,B as reloadWorkspaceFile,d as repo_id,p as runToPC,r as setFrameRateUI,x as setTestInput,o as setupBreakpoint,u as setupSplits,w as startUI,c as store_id};
//# sourceMappingURL=ui.js.map
+2 -1
View File
@@ -5233,10 +5233,11 @@
"mcr": {
arch: "z80",
code_start: 0,
rom_size: 57344,
rom_size: 57344 + 16384 + 32768,
data_start: 57344,
data_size: 2048,
stack_end: 59392
// TODO: IHX can't handle > 64 KB, so ihx2sms looks for segments in a certain order
}
};
PLATFORM_PARAMS["sms-sms-libcv"] = PLATFORM_PARAMS["sms-sg1000-libcv"];
+2 -2
View File
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../../node_modules/jszip/dist/jszip.min.js", "../../src/common/util.ts", "../../src/common/basic/compiler.ts", "../../src/worker/platforms.ts", "../../src/worker/builder.ts", "../../src/worker/wasmutils.ts", "../../src/worker/listingutils.ts", "../../src/worker/tools/misc.ts", "../../src/worker/tools/cc65.ts", "../../src/common/wasi/wasishim.ts", "../../src/worker/tools/dasm.ts", "../../src/worker/tools/mcpp.ts", "../../src/worker/tools/sdcc.ts", "../../src/worker/assembler.ts", "../../src/common/hdl/hdltypes.ts", "../../src/common/hdl/vxmlparser.ts", "../../src/worker/tools/verilog.ts", "../../src/worker/tools/m6809.ts", "../../src/worker/tools/m6502.ts", "../../src/worker/tools/z80.ts", "../../src/worker/tools/x86.ts", "../../src/common/binutils.ts", "../../src/worker/wasiutils.ts", "../../src/worker/tools/arm.ts", "../../src/common/tokenizer.ts", "../../src/common/ecs/binpack.ts", "../../src/common/ecs/ecs.ts", "../../src/common/ecs/decoder.ts", "../../src/common/ecs/compiler.ts", "../../src/worker/tools/ecs.ts", "../../src/common/workertypes.ts", "../../src/worker/tools/remote.ts", "../../src/worker/tools/acme.ts", "../../src/worker/tools/cc7800.ts", "../../src/worker/tools/cc2600.ts", "../../src/worker/tools/bataribasic.ts", "../../src/worker/tools/oscar64.ts", "../../src/worker/workertools.ts", "../../src/worker/workermain.ts"],
"sourcesContent": ["/*!\n\nJSZip v3.10.1 - A JavaScript class for generating and reading zip files\n<http://stuartk.com/jszip>\n\n(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>\nDual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown.\n\nJSZip uses the library pako released under the MIT license :\nhttps://github.com/nodeca/pako/blob/main/LICENSE\n*/\n\n!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{(\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error(\"Cannot find module '\"+r+\"'\");throw n.code=\"MODULE_NOT_FOUND\",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l=\"function\"==typeof require&&require,e=0;e<h.length;e++)u(h[e]);return u}({1:[function(e,t,r){\"use strict\";var d=e(\"./utils\"),c=e(\"./support\"),p=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";r.encode=function(e){for(var t,r,n,i,s,a,o,h=[],u=0,l=e.length,f=l,c=\"string\"!==d.getTypeOf(e);u<e.length;)f=l-u,n=c?(t=e[u++],r=u<l?e[u++]:0,u<l?e[u++]:0):(t=e.charCodeAt(u++),r=u<l?e.charCodeAt(u++):0,u<l?e.charCodeAt(u++):0),i=t>>2,s=(3&t)<<4|r>>4,a=1<f?(15&r)<<2|n>>6:64,o=2<f?63&n:64,h.push(p.charAt(i)+p.charAt(s)+p.charAt(a)+p.charAt(o));return h.join(\"\")},r.decode=function(e){var t,r,n,i,s,a,o=0,h=0,u=\"data:\";if(e.substr(0,u.length)===u)throw new Error(\"Invalid base64 input, it looks like a data url.\");var l,f=3*(e=e.replace(/[^A-Za-z0-9+/=]/g,\"\")).length/4;if(e.charAt(e.length-1)===p.charAt(64)&&f--,e.charAt(e.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error(\"Invalid base64 input, bad content length.\");for(l=c.uint8array?new Uint8Array(0|f):new Array(0|f);o<e.length;)t=p.indexOf(e.charAt(o++))<<2|(i=p.indexOf(e.charAt(o++)))>>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{\"./support\":30,\"./utils\":32}],2:[function(e,t,r){\"use strict\";var n=e(\"./external\"),i=e(\"./stream/DataWorker\"),s=e(\"./stream/Crc32Probe\"),a=e(\"./stream/DataLengthProbe\");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a(\"data_length\")),t=this;return e.on(\"end\",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error(\"Bug : uncompressed data size mismatch\")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo(\"compressedSize\",this.compressedSize).withStreamInfo(\"uncompressedSize\",this.uncompressedSize).withStreamInfo(\"crc32\",this.crc32).withStreamInfo(\"compression\",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a(\"uncompressedSize\")).pipe(t.compressWorker(r)).pipe(new a(\"compressedSize\")).withStreamInfo(\"compression\",t)},t.exports=o},{\"./external\":6,\"./stream/Crc32Probe\":25,\"./stream/DataLengthProbe\":26,\"./stream/DataWorker\":27}],3:[function(e,t,r){\"use strict\";var n=e(\"./stream/GenericWorker\");r.STORE={magic:\"\\0\\0\",compressWorker:function(){return new n(\"STORE compression\")},uncompressWorker:function(){return new n(\"STORE decompression\")}},r.DEFLATE=e(\"./flate\")},{\"./flate\":7,\"./stream/GenericWorker\":28}],4:[function(e,t,r){\"use strict\";var n=e(\"./utils\");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?\"string\"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{\"./utils\":32}],5:[function(e,t,r){\"use strict\";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){\"use strict\";var n=null;n=\"undefined\"!=typeof Promise?Promise:e(\"lie\"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){\"use strict\";var n=\"undefined\"!=typeof Uint8Array&&\"undefined\"!=typeof Uint16Array&&\"undefined\"!=typeof Uint32Array,i=e(\"pako\"),s=e(\"./utils\"),a=e(\"./stream/GenericWorker\"),o=n?\"uint8array\":\"array\";function h(e,t){a.call(this,\"FlateWorker/\"+e),this._pako=null,this._pakoActioLine truncated
"mappings": "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 truncated
"sourcesContent": ["/*!\n\nJSZip v3.10.1 - A JavaScript class for generating and reading zip files\n<http://stuartk.com/jszip>\n\n(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>\nDual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown.\n\nJSZip uses the library pako released under the MIT license :\nhttps://github.com/nodeca/pako/blob/main/LICENSE\n*/\n\n!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{(\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t=\"function\"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error(\"Cannot find module '\"+r+\"'\");throw n.code=\"MODULE_NOT_FOUND\",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l=\"function\"==typeof require&&require,e=0;e<h.length;e++)u(h[e]);return u}({1:[function(e,t,r){\"use strict\";var d=e(\"./utils\"),c=e(\"./support\"),p=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";r.encode=function(e){for(var t,r,n,i,s,a,o,h=[],u=0,l=e.length,f=l,c=\"string\"!==d.getTypeOf(e);u<e.length;)f=l-u,n=c?(t=e[u++],r=u<l?e[u++]:0,u<l?e[u++]:0):(t=e.charCodeAt(u++),r=u<l?e.charCodeAt(u++):0,u<l?e.charCodeAt(u++):0),i=t>>2,s=(3&t)<<4|r>>4,a=1<f?(15&r)<<2|n>>6:64,o=2<f?63&n:64,h.push(p.charAt(i)+p.charAt(s)+p.charAt(a)+p.charAt(o));return h.join(\"\")},r.decode=function(e){var t,r,n,i,s,a,o=0,h=0,u=\"data:\";if(e.substr(0,u.length)===u)throw new Error(\"Invalid base64 input, it looks like a data url.\");var l,f=3*(e=e.replace(/[^A-Za-z0-9+/=]/g,\"\")).length/4;if(e.charAt(e.length-1)===p.charAt(64)&&f--,e.charAt(e.length-2)===p.charAt(64)&&f--,f%1!=0)throw new Error(\"Invalid base64 input, bad content length.\");for(l=c.uint8array?new Uint8Array(0|f):new Array(0|f);o<e.length;)t=p.indexOf(e.charAt(o++))<<2|(i=p.indexOf(e.charAt(o++)))>>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{\"./support\":30,\"./utils\":32}],2:[function(e,t,r){\"use strict\";var n=e(\"./external\"),i=e(\"./stream/DataWorker\"),s=e(\"./stream/Crc32Probe\"),a=e(\"./stream/DataLengthProbe\");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a(\"data_length\")),t=this;return e.on(\"end\",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error(\"Bug : uncompressed data size mismatch\")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo(\"compressedSize\",this.compressedSize).withStreamInfo(\"uncompressedSize\",this.uncompressedSize).withStreamInfo(\"crc32\",this.crc32).withStreamInfo(\"compression\",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a(\"uncompressedSize\")).pipe(t.compressWorker(r)).pipe(new a(\"compressedSize\")).withStreamInfo(\"compression\",t)},t.exports=o},{\"./external\":6,\"./stream/Crc32Probe\":25,\"./stream/DataLengthProbe\":26,\"./stream/DataWorker\":27}],3:[function(e,t,r){\"use strict\";var n=e(\"./stream/GenericWorker\");r.STORE={magic:\"\\0\\0\",compressWorker:function(){return new n(\"STORE compression\")},uncompressWorker:function(){return new n(\"STORE decompression\")}},r.DEFLATE=e(\"./flate\")},{\"./flate\":7,\"./stream/GenericWorker\":28}],4:[function(e,t,r){\"use strict\";var n=e(\"./utils\");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?\"string\"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a<s;a++)e=e>>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{\"./utils\":32}],5:[function(e,t,r){\"use strict\";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){\"use strict\";var n=null;n=\"undefined\"!=typeof Promise?Promise:e(\"lie\"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){\"use strict\";var n=\"undefined\"!=typeof Uint8Array&&\"undefined\"!=typeof Uint16Array&&\"undefined\"!=typeof Uint32Array,i=e(\"pako\"),s=e(\"./utils\"),a=e(\"./stream/GenericWorker\"),o=n?\"uint8array\":\"array\";function h(e,t){a.call(this,\"FlateWorker/\"+e),this._pako=null,this._pakoActioLine truncated
"mappings": "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 truncated
"names": ["exports", "e", "t", "r", "c", "n", "i", "s", "a", "o", "h", "u", "l", "f", "d", "p", "m", "attrs", "s", "debug", "s", "s", "hex", "CompileError", "s", "code", "s", "s", "m", "lst", "DwarfTag", "DwarfAttribute", "JSZip", "line", "m", "CompileError", "mergeLocs", "CompileError", "debug", "debug", "isLiteral", "isBinOp", "isUnOp", "e", "isLiteral", "OPERATORS", "getOperator", "getPrecedence", "mergeLocs", "tok", "isLiteral", "getPrecedence", "getOperator", "valtype", "CompileError", "wasiModule", "exports", "ENVIRONMENT_IS_WORKER", "e"]
}
+2 -1
View File
@@ -385,10 +385,11 @@ exports.PLATFORM_PARAMS = {
'mcr': {
arch: 'z80',
code_start: 0x0,
rom_size: 0xe000,
rom_size: 0xe000 + 0x4000 + 0x8000,
data_start: 0xe000,
data_size: 0x800,
stack_end: 0xe800,
// TODO: IHX can't handle > 64 KB, so ihx2sms looks for segments in a certain order
},
};
exports.PLATFORM_PARAMS['sms-sms-libcv'] = exports.PLATFORM_PARAMS['sms-sg1000-libcv'];
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../../src/worker/platforms.ts"],"names":[],"mappings":"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 truncated
{"version":3,"file":"platforms.js","sourceRoot":"","sources":["../../src/worker/platforms.ts"],"names":[],"mappings":"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 truncated
+691
View File
@@ -0,0 +1,691 @@
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
import { Bus, CPU, InstructionBased, SavesState, Interruptable, MemoryBusConnected } from "../devices";
export interface F8State {
PC: number; // alias for PC0 (required by CpuState)
PC0: number; // program counter
PC1: number; // saved program counter (stack)
DC0: number; // data counter
DC1: number; // alternate data counter
A: number; // accumulator
W: number; // status register (flags)
IS: number; // indirect scratchpad address register (6-bit)
R: number[]; // 64-byte scratchpad RAM
o: number; // last opcode
irq: boolean;
}
// Status register flag bits
const FLAG_S = 0x01; // Sign (complementary: set when positive)
const FLAG_C = 0x02; // Carry
const FLAG_Z = 0x04; // Zero
const FLAG_O = 0x08; // Overflow
const FLAG_I = 0x10; // Interrupt Control Bit
export class F8CPU implements CPU, InstructionBased, SavesState<F8State>, Interruptable<number>, MemoryBusConnected {
// Registers
PC0: number = 0; // active program counter
PC1: number = 0; // saved program counter
DC0: number = 0; // active data counter
DC1: number = 0; // alternate data counter
A: number = 0; // accumulator
W: number = 0; // status/flags
IS: number = 0; // indirect scratchpad address (6-bit)
R: Uint8Array = new Uint8Array(64); // scratchpad RAM
bus: Bus;
iobus: Bus;
o: number = 0; // last opcode
stable: boolean = true;
irqRequest: boolean = false;
connectMemoryBus(bus: Bus): void {
this.bus = bus;
}
connectIOBus(bus: Bus): void {
this.iobus = bus;
}
reset(): void {
this.PC0 = 0;
this.PC1 = 0;
this.DC0 = 0;
this.DC1 = 0;
this.A = 0;
this.W = 0;
this.IS = 0;
this.R.fill(0);
this.irqRequest = false;
}
interrupt(type: number): void {
this.irqRequest = true;
}
getPC(): number { return this.PC0; }
getSP(): number { return this.PC1; }
isStable(): boolean { return this.stable; }
saveState(): F8State {
return {
PC: this.PC0,
PC0: this.PC0,
PC1: this.PC1,
DC0: this.DC0,
DC1: this.DC1,
A: this.A,
W: this.W,
IS: this.IS,
R: Array.from(this.R),
o: this.o,
irq: this.irqRequest,
};
}
loadState(state: F8State): void {
this.PC0 = state.PC0 ?? state.PC;
this.PC1 = state.PC1;
this.DC0 = state.DC0;
this.DC1 = state.DC1;
this.A = state.A;
this.W = state.W;
this.IS = state.IS;
for (let i = 0; i < 64; i++) this.R[i] = state.R[i];
this.o = state.o;
this.irqRequest = state.irq;
}
// Read byte at PC0, increment PC0
private fetchPC0(): number {
const val = this.bus.read(this.PC0);
this.PC0 = (this.PC0 + 1) & 0xFFFF;
return val;
}
// Read byte at DC0, increment DC0
private fetchDC0(): number {
const val = this.bus.read(this.DC0);
this.DC0 = (this.DC0 + 1) & 0xFFFF;
return val;
}
// Write byte at DC0, increment DC0
private storeDC0(val: number): void {
this.bus.write(this.DC0, val);
this.DC0 = (this.DC0 + 1) & 0xFFFF;
}
// Clear O, Z, C, S flags
private clrOZCS(): void {
this.W &= ~(FLAG_O | FLAG_Z | FLAG_C | FLAG_S);
}
// Set Sign and Zero flags from value
// Note: F8 sign flag is COMPLEMENTARY - set when bit 7 is CLEAR (positive)
private setSZ(val: number): void {
if ((val & 0xFF) === 0) this.W |= FLAG_Z;
if ((val & 0x80) === 0) this.W |= FLAG_S; // complementary sign
}
// Addition with carry/overflow detection
private doAdd(a: number, b: number, carry: number = 0): number {
const result = (a & 0xFF) + (b & 0xFF) + (carry & 1);
// Set carry if overflow past 8 bits
if (result & 0x100) this.W |= FLAG_C;
// Set overflow using XOR method
if (((a ^ result) & (b ^ result) & 0x80) !== 0) this.W |= FLAG_O;
return result & 0xFF;
}
// BCD addition
private doAddDecimal(augend: number, addend: number): number {
let tmp = (augend & 0x0F) + (addend & 0x0F);
let c1 = (tmp > 9) ? 1 : 0;
tmp = (augend >> 4) + (addend >> 4) + c1;
let c2 = (tmp > 9) ? 1 : 0;
// Do binary add for flags
this.clrOZCS();
let result = this.doAdd(augend, addend);
this.setSZ(result);
// Apply BCD correction
let correction = 0;
if (c2) correction |= 0xA0;
if (c1) correction |= 0x0A;
if (correction) {
this.clrOZCS();
result = this.doAdd(result, correction);
this.setSZ(result);
}
return result;
}
// Get scratchpad register for operand (0-11 direct, 12=ISAR, 13=ISAR++, 14=ISAR--)
private getScratchpadIndex(r: number): number {
if (r < 12) return r;
if (r === 12) return this.IS & 0x3F;
if (r === 13) {
const idx = this.IS & 0x3F;
// Increment lower 3 bits of IS
this.IS = (this.IS & 0x38) | ((this.IS + 1) & 0x07);
return idx;
}
if (r === 14) {
const idx = this.IS & 0x3F;
// Decrement lower 3 bits of IS
this.IS = (this.IS & 0x38) | ((this.IS - 1) & 0x07);
return idx;
}
return 0; // illegal
}
advanceInsn(): number {
// Check for interrupts
if (this.irqRequest && (this.W & FLAG_I)) {
this.irqRequest = false;
// Save PC0 to PC1
this.PC1 = this.PC0;
// Load interrupt vector (at address 0x0020 typically)
this.PC0 = (this.bus.read(0x0FFE) << 8) | this.bus.read(0x0FFF);
// Clear interrupt enable
this.W &= ~FLAG_I;
return 6;
}
const opcode = this.fetchPC0();
this.o = opcode;
this.stable = true;
let cycles = 4; // short cycle default
let tmp: number;
let r: number;
switch (opcode) {
// 0x00: LR A,KU
case 0x00: this.A = this.R[12]; break;
// 0x01: LR A,KL
case 0x01: this.A = this.R[13]; break;
// 0x02: LR A,QU
case 0x02: this.A = this.R[14]; break;
// 0x03: LR A,QL
case 0x03: this.A = this.R[15]; break;
// 0x04: LR KU,A
case 0x04: this.R[12] = this.A; break;
// 0x05: LR KL,A
case 0x05: this.R[13] = this.A; break;
// 0x06: LR QU,A
case 0x06: this.R[14] = this.A; break;
// 0x07: LR QL,A
case 0x07: this.R[15] = this.A; break;
// 0x08: LR K,P (K <- PC1)
case 0x08:
this.R[12] = (this.PC1 >> 8) & 0xFF;
this.R[13] = this.PC1 & 0xFF;
cycles = 8;
break;
// 0x09: LR P,K (PC1 <- K)
case 0x09:
this.PC1 = (this.R[12] << 8) | this.R[13];
cycles = 8;
break;
// 0x0A: LR A,IS
case 0x0A: this.A = this.IS & 0x3F; break;
// 0x0B: LR IS,A
case 0x0B: this.IS = this.A & 0x3F; break;
// 0x0C: PK (Push K to PC: PC1<-PC0+1, PC0<-K)
case 0x0C:
this.PC1 = this.PC0;
this.PC0 = (this.R[12] << 8) | this.R[13];
cycles = 8;
break;
// 0x0D: LR P0,Q (PC0 <- Q)
case 0x0D:
this.PC0 = (this.R[14] << 8) | this.R[15];
cycles = 8;
break;
// 0x0E: LR Q,DC (Q <- DC0)
case 0x0E:
this.R[14] = (this.DC0 >> 8) & 0xFF;
this.R[15] = this.DC0 & 0xFF;
cycles = 8;
break;
// 0x0F: LR DC,Q (DC0 <- Q)
case 0x0F:
this.DC0 = (this.R[14] << 8) | this.R[15];
cycles = 8;
break;
// 0x10: LR DC,H (DC0 <- H)
case 0x10:
this.DC0 = (this.R[10] << 8) | this.R[11];
cycles = 8;
break;
// 0x11: LR H,DC (H <- DC0)
case 0x11:
this.R[10] = (this.DC0 >> 8) & 0xFF;
this.R[11] = this.DC0 & 0xFF;
cycles = 8;
break;
// 0x12: SR 1 (shift right 1)
case 0x12:
this.A = (this.A >> 1) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x13: SL 1 (shift left 1)
case 0x13:
this.A = (this.A << 1) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x14: SR 4 (shift right 4)
case 0x14:
this.A = (this.A >> 4) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x15: SL 4 (shift left 4)
case 0x15:
this.A = (this.A << 4) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x16: LM (load A from memory at DC0, increment DC0)
case 0x16:
this.A = this.fetchDC0();
cycles = 6;
break;
// 0x17: ST (store A to memory at DC0, increment DC0)
case 0x17:
this.storeDC0(this.A);
cycles = 6;
break;
// 0x18: COM (complement A)
case 0x18:
this.A = (~this.A) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0x19: LNK (add carry to A)
case 0x19:
tmp = (this.W & FLAG_C) ? 1 : 0;
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
break;
// 0x1A: DI (disable interrupts)
case 0x1A:
this.W &= ~FLAG_I;
break;
// 0x1B: EI (enable interrupts)
case 0x1B:
this.W |= FLAG_I;
break;
// 0x1C: POP (PC0 <- PC1)
case 0x1C:
this.PC0 = this.PC1;
break;
// 0x1D: LR W,J (W <- scratchpad[9])
case 0x1D:
this.W = this.R[9] & 0x1F;
break;
// 0x1E: LR J,W (scratchpad[9] <- W)
case 0x1E:
this.R[9] = this.W & 0x1F;
break;
// 0x1F: INC (increment A)
case 0x1F:
this.clrOZCS();
this.A = this.doAdd(this.A, 1);
this.setSZ(this.A);
break;
// 0x20: LI immediate
case 0x20:
this.A = this.fetchPC0();
cycles = 6;
break;
// 0x21: NI immediate (AND)
case 0x21:
tmp = this.fetchPC0();
this.A = this.A & tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x22: OI immediate (OR)
case 0x22:
tmp = this.fetchPC0();
this.A = this.A | tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x23: XI immediate (XOR)
case 0x23:
tmp = this.fetchPC0();
this.A = this.A ^ tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x24: AI immediate (ADD)
case 0x24:
tmp = this.fetchPC0();
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
cycles = 6;
break;
// 0x25: CI immediate (compare: sets flags from ~A + immediate + 1)
case 0x25:
tmp = this.fetchPC0();
this.clrOZCS();
this.doAdd((~this.A) & 0xFF, tmp, 1);
this.setSZ(this.doAdd((~this.A) & 0xFF, tmp, 1));
cycles = 6;
break;
// 0x26: IN immediate (input from port)
case 0x26:
tmp = this.fetchPC0();
this.A = this.iobus.read(tmp) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
cycles = 8;
break;
// 0x27: OUT immediate (output to port)
case 0x27:
tmp = this.fetchPC0();
this.iobus.write(tmp, this.A);
cycles = 8;
break;
// 0x28: PI (push and jump immediate: PC1<-PC0, PC0<-address)
case 0x28: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.PC1 = this.PC0;
this.PC0 = (hi << 8) | lo;
cycles = 12;
break;
}
// 0x29: JMP (jump immediate)
case 0x29: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.PC0 = (hi << 8) | lo;
cycles = 10;
break;
}
// 0x2A: DCI (load DC0 immediate)
case 0x2A: {
const hi = this.fetchPC0();
const lo = this.fetchPC0();
this.DC0 = (hi << 8) | lo;
cycles = 10;
break;
}
// 0x2B: NOP
case 0x2B: break;
// 0x2C: XDC (exchange DC0 and DC1)
case 0x2C:
tmp = this.DC0;
this.DC0 = this.DC1;
this.DC1 = tmp;
break;
// 0x2D-0x2F: illegal
case 0x2D: case 0x2E: case 0x2F: break;
// 0x30-0x3E: DS (decrement scratchpad register, skip if zero)
case 0x30: case 0x31: case 0x32: case 0x33:
case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3A: case 0x3B:
case 0x3C: case 0x3D: case 0x3E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.clrOZCS();
this.R[r] = this.doAdd(this.R[r], 0xFF);
this.setSZ(this.R[r]);
cycles = 6;
break;
case 0x3F: break; // illegal
// 0x40-0x4E: LR A,r (load A from scratchpad)
case 0x40: case 0x41: case 0x42: case 0x43:
case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B:
case 0x4C: case 0x4D: case 0x4E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = this.R[r];
break;
case 0x4F: break; // illegal
// 0x50-0x5E: LR r,A (store A to scratchpad)
case 0x50: case 0x51: case 0x52: case 0x53:
case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5A: case 0x5B:
case 0x5C: case 0x5D: case 0x5E:
r = this.getScratchpadIndex(opcode & 0x0F);
this.R[r] = this.A;
break;
case 0x5F: break; // illegal
// 0x60-0x67: LISU (load IS upper 3 bits)
case 0x60: case 0x61: case 0x62: case 0x63:
case 0x64: case 0x65: case 0x66: case 0x67:
this.IS = (this.IS & 0x07) | ((opcode & 0x07) << 3);
break;
// 0x68-0x6F: LISL (load IS lower 3 bits)
case 0x68: case 0x69: case 0x6A: case 0x6B:
case 0x6C: case 0x6D: case 0x6E: case 0x6F:
this.IS = (this.IS & 0x38) | (opcode & 0x07);
break;
// 0x70-0x7F: LIS (load A with 4-bit immediate)
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: case 0x7B:
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
this.A = opcode & 0x0F;
break;
// 0x80-0x87: BT (branch if flag test true)
case 0x80: case 0x81: case 0x82: case 0x83:
case 0x84: case 0x85: case 0x86: case 0x87: {
const mask = opcode & 0x07;
const offset = this.fetchPC0();
if (this.W & mask) {
// Sign-extend offset and add to PC0
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
cycles = 6;
} else {
cycles = 6;
}
break;
}
// 0x88: AM (add memory at DC0 to A)
case 0x88:
tmp = this.fetchDC0();
this.clrOZCS();
this.A = this.doAdd(this.A, tmp);
this.setSZ(this.A);
cycles = 6;
break;
// 0x89: AMD (decimal add memory at DC0 to A)
case 0x89:
tmp = this.fetchDC0();
this.A = this.doAddDecimal(this.A, tmp);
cycles = 6;
break;
// 0x8A: NM (AND memory at DC0)
case 0x8A:
tmp = this.fetchDC0();
this.A = this.A & tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8B: OM (OR memory at DC0)
case 0x8B:
tmp = this.fetchDC0();
this.A = this.A | tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8C: XM (XOR memory at DC0)
case 0x8C:
tmp = this.fetchDC0();
this.A = this.A ^ tmp;
this.clrOZCS();
this.setSZ(this.A);
cycles = 6;
break;
// 0x8D: CM (compare memory at DC0)
case 0x8D:
tmp = this.fetchDC0();
this.clrOZCS();
{ const cmp = this.doAdd((~this.A) & 0xFF, tmp, 1); this.setSZ(cmp); }
cycles = 6;
break;
// 0x8E: ADC (add accumulator to DC0)
case 0x8E:
this.DC0 = (this.DC0 + ((this.A & 0x80) ? (this.A - 256) : this.A)) & 0xFFFF;
cycles = 6;
break;
// 0x8F: BR7 (branch if IS lower 3 bits != 7)
case 0x8F: {
const offset = this.fetchPC0();
if ((this.IS & 0x07) !== 7) {
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
}
cycles = 6;
break;
}
// 0x90-0x9F: BF (branch if flag false)
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9A: case 0x9B:
case 0x9C: case 0x9D: case 0x9E: case 0x9F: {
const mask = opcode & 0x0F;
const offset = this.fetchPC0();
if (mask === 0 || !(this.W & mask)) {
// BF 0 is unconditional branch (BR)
this.PC0 = (this.PC0 + ((offset & 0x80) ? (offset - 256) : offset)) & 0xFFFF;
}
cycles = 6;
break;
}
// 0xA0-0xA1: INS 0-1 (input from port 0/1, direct)
case 0xA0: case 0xA1:
this.A = this.iobus.read(opcode & 0x01) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
// 0xA2-0xA3: illegal
case 0xA2: case 0xA3: break;
// 0xA4-0xAF: INS 4-F (input from addressed port)
case 0xA4: case 0xA5: case 0xA6: case 0xA7:
case 0xA8: case 0xA9: case 0xAA: case 0xAB:
case 0xAC: case 0xAD: case 0xAE: case 0xAF:
this.A = this.iobus.read(opcode & 0x0F) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
cycles = 8;
break;
// 0xB0-0xB1: OUTS 0-1 (output to port 0/1, direct)
case 0xB0: case 0xB1:
this.iobus.write(opcode & 0x01, this.A);
break;
// 0xB2-0xB3: illegal
case 0xB2: case 0xB3: break;
// 0xB4-0xBF: OUTS 4-F (output to addressed port)
case 0xB4: case 0xB5: case 0xB6: case 0xB7:
case 0xB8: case 0xB9: case 0xBA: case 0xBB:
case 0xBC: case 0xBD: case 0xBE: case 0xBF:
this.iobus.write(opcode & 0x0F, this.A);
cycles = 8;
break;
// 0xC0-0xCE: AS (add scratchpad to A)
case 0xC0: case 0xC1: case 0xC2: case 0xC3:
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
case 0xC8: case 0xC9: case 0xCA: case 0xCB:
case 0xCC: case 0xCD: case 0xCE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.clrOZCS();
this.A = this.doAdd(this.A, this.R[r]);
this.setSZ(this.A);
break;
case 0xCF: break; // illegal
// 0xD0-0xDE: ASD (decimal add scratchpad to A)
case 0xD0: case 0xD1: case 0xD2: case 0xD3:
case 0xD4: case 0xD5: case 0xD6: case 0xD7:
case 0xD8: case 0xD9: case 0xDA: case 0xDB:
case 0xDC: case 0xDD: case 0xDE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = this.doAddDecimal(this.A, this.R[r]);
cycles = 8;
break;
case 0xDF: break; // illegal
// 0xE0-0xEE: XS (XOR scratchpad with A)
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
case 0xE8: case 0xE9: case 0xEA: case 0xEB:
case 0xEC: case 0xED: case 0xEE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = (this.A ^ this.R[r]) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
case 0xEF: break; // illegal
// 0xF0-0xFE: NS (AND scratchpad with A)
case 0xF0: case 0xF1: case 0xF2: case 0xF3:
case 0xF4: case 0xF5: case 0xF6: case 0xF7:
case 0xF8: case 0xF9: case 0xFA: case 0xFB:
case 0xFC: case 0xFD: case 0xFE:
r = this.getScratchpadIndex(opcode & 0x0F);
this.A = (this.A & this.R[r]) & 0xFF;
this.clrOZCS();
this.setSZ(this.A);
break;
case 0xFF: break; // illegal
}
return cycles;
}
}
+139
View File
@@ -0,0 +1,139 @@
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
import { hex } from "../util";
// Scratchpad register names for operands 0-14
function regName(r: number): string {
if (r < 9) return 'r' + r;
if (r === 9) return 'J';
if (r === 10) return 'HU';
if (r === 11) return 'HL';
if (r === 12) return 'S'; // ISAR
if (r === 13) return 'I'; // ISAR++
if (r === 14) return 'D'; // ISAR--
return '?';
}
export function disassembleF8(pc: number, b0: number, b1: number, b2: number): { line: string, nbytes: number, isaddr: boolean } {
let mn = '';
let args = '';
let nb = 1;
let isaddr = false;
if (b0 <= 0x07) {
const regs = ['KU', 'KL', 'QU', 'QL'];
if (b0 < 4) { mn = 'LR'; args = 'A,' + regs[b0]; }
else { mn = 'LR'; args = regs[b0 - 4] + ',A'; }
} else if (b0 === 0x08) { mn = 'LR'; args = 'K,P'; }
else if (b0 === 0x09) { mn = 'LR'; args = 'P,K'; }
else if (b0 === 0x0A) { mn = 'LR'; args = 'A,IS'; }
else if (b0 === 0x0B) { mn = 'LR'; args = 'IS,A'; }
else if (b0 === 0x0C) { mn = 'PK'; }
else if (b0 === 0x0D) { mn = 'LR'; args = 'P0,Q'; }
else if (b0 === 0x0E) { mn = 'LR'; args = 'Q,DC'; }
else if (b0 === 0x0F) { mn = 'LR'; args = 'DC,Q'; }
else if (b0 === 0x10) { mn = 'LR'; args = 'DC,H'; }
else if (b0 === 0x11) { mn = 'LR'; args = 'H,DC'; }
else if (b0 === 0x12) { mn = 'SR'; args = '1'; }
else if (b0 === 0x13) { mn = 'SL'; args = '1'; }
else if (b0 === 0x14) { mn = 'SR'; args = '4'; }
else if (b0 === 0x15) { mn = 'SL'; args = '4'; }
else if (b0 === 0x16) { mn = 'LM'; }
else if (b0 === 0x17) { mn = 'ST'; }
else if (b0 === 0x18) { mn = 'COM'; }
else if (b0 === 0x19) { mn = 'LNK'; }
else if (b0 === 0x1A) { mn = 'DI'; }
else if (b0 === 0x1B) { mn = 'EI'; }
else if (b0 === 0x1C) { mn = 'POP'; }
else if (b0 === 0x1D) { mn = 'LR'; args = 'W,J'; }
else if (b0 === 0x1E) { mn = 'LR'; args = 'J,W'; }
else if (b0 === 0x1F) { mn = 'INC'; }
else if (b0 === 0x20) { mn = 'LI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x21) { mn = 'NI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x22) { mn = 'OI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x23) { mn = 'XI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x24) { mn = 'AI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x25) { mn = 'CI'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x26) { mn = 'IN'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x27) { mn = 'OUT'; args = '$' + hex(b1, 2); nb = 2; }
else if (b0 === 0x28) {
mn = 'PI'; args = '$' + hex((b1 << 8) | b2, 4); nb = 3; isaddr = true;
}
else if (b0 === 0x29) {
mn = 'JMP'; args = '$' + hex((b1 << 8) | b2, 4); nb = 3; isaddr = true;
}
else if (b0 === 0x2A) {
mn = 'DCI'; args = '$' + hex((b1 << 8) | b2, 4); nb = 3; isaddr = true;
}
else if (b0 === 0x2B) { mn = 'NOP'; }
else if (b0 === 0x2C) { mn = 'XDC'; }
else if (b0 <= 0x2F) { mn = '???'; }
else if (b0 >= 0x30 && b0 <= 0x3E) {
mn = 'DS'; args = regName(b0 & 0x0F); nb = 1;
}
else if (b0 === 0x3F) { mn = '???'; }
else if (b0 >= 0x40 && b0 <= 0x4E) {
mn = 'LR'; args = 'A,' + regName(b0 & 0x0F);
}
else if (b0 === 0x4F) { mn = '???'; }
else if (b0 >= 0x50 && b0 <= 0x5E) {
mn = 'LR'; args = regName(b0 & 0x0F) + ',A';
}
else if (b0 === 0x5F) { mn = '???'; }
else if (b0 >= 0x60 && b0 <= 0x67) {
mn = 'LISU'; args = '' + (b0 & 0x07);
}
else if (b0 >= 0x68 && b0 <= 0x6F) {
mn = 'LISL'; args = '' + (b0 & 0x07);
}
else if (b0 >= 0x70 && b0 <= 0x7F) {
mn = 'LIS'; args = '' + (b0 & 0x0F);
}
else if (b0 >= 0x80 && b0 <= 0x87) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
mn = 'BT'; args = '' + (b0 & 0x07) + ',$' + hex(offset & 0xFFFF, 4);
nb = 2; isaddr = true;
}
else if (b0 === 0x88) { mn = 'AM'; }
else if (b0 === 0x89) { mn = 'AMD'; }
else if (b0 === 0x8A) { mn = 'NM'; }
else if (b0 === 0x8B) { mn = 'OM'; }
else if (b0 === 0x8C) { mn = 'XM'; }
else if (b0 === 0x8D) { mn = 'CM'; }
else if (b0 === 0x8E) { mn = 'ADC'; }
else if (b0 === 0x8F) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
mn = 'BR7'; args = '$' + hex(offset & 0xFFFF, 4);
nb = 2; isaddr = true;
}
else if (b0 >= 0x90 && b0 <= 0x9F) {
const offset = (b1 & 0x80) ? (pc + 2 + b1 - 256) : (pc + 2 + b1);
const mask = b0 & 0x0F;
if (mask === 0) mn = 'BR';
else mn = 'BF';
if (mask !== 0) args = '' + mask + ',';
args += '$' + hex(offset & 0xFFFF, 4);
nb = 2; isaddr = true;
}
else if (b0 >= 0xA0 && b0 <= 0xA1) { mn = 'INS'; args = '' + (b0 & 0x0F); }
else if (b0 >= 0xA2 && b0 <= 0xA3) { mn = '???'; }
else if (b0 >= 0xA4 && b0 <= 0xAF) { mn = 'INS'; args = '' + (b0 & 0x0F); }
else if (b0 >= 0xB0 && b0 <= 0xB1) { mn = 'OUTS'; args = '' + (b0 & 0x0F); }
else if (b0 >= 0xB2 && b0 <= 0xB3) { mn = '???'; }
else if (b0 >= 0xB4 && b0 <= 0xBF) { mn = 'OUTS'; args = '' + (b0 & 0x0F); }
else if (b0 >= 0xC0 && b0 <= 0xCE) { mn = 'AS'; args = regName(b0 & 0x0F); }
else if (b0 === 0xCF) { mn = '???'; }
else if (b0 >= 0xD0 && b0 <= 0xDE) { mn = 'ASD'; args = regName(b0 & 0x0F); }
else if (b0 === 0xDF) { mn = '???'; }
else if (b0 >= 0xE0 && b0 <= 0xEE) { mn = 'XS'; args = regName(b0 & 0x0F); }
else if (b0 === 0xEF) { mn = '???'; }
else if (b0 >= 0xF0 && b0 <= 0xFE) { mn = 'NS'; args = regName(b0 & 0x0F); }
else { mn = '???'; }
return { line: mn + (args ? ' ' + args : ''), nbytes: nb, isaddr: isaddr };
}
+357
View File
@@ -0,0 +1,357 @@
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
import { F8CPU, F8State } from "../common/cpu/F8";
import { BasicMachine, Bus, SampledAudioSink } from "../common/devices";
import { KeyFlags, Keys, newAddressDecoder, padBytes } from "../common/emu";
import { hex } from "../common/util";
// Channel F color palette (RGBA)
const CHANNELF_COLORS = [
0xFF484848, // 0: dark gray/background (approximation for "field" color)
0xFF5050FF, // 1: blue
0xFF50FF50, // 2: green -> actually the red
0xFF808080, // 3: gray
0xFFFFFFFF, // 4: white (BG palette)
0xFF50FF50, // 5: green
0xFFFF5050, // 6: red
0xFFC8C8C8, // 7: light gray
];
// Full 16-entry color map (4 palette banks x 4 colors)
const CHANNELF_COLORMAP = [
// Palette 0 (default)
0xFF484848, // 0: background
0xFF50FF50, // 1: green
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 1
0xFFFF5050, // 0: red (background)
0xFF50FF50, // 1: green
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 2
0xFF484848, // 0: background
0xFFFF5050, // 1: red
0xFF5050FF, // 2: blue
0xFF808080, // 3: gray
// Palette 3
0xFF484848, // 0: background
0xFF50FF50, // 1: green
0xFFFF5050, // 2: red
0xFF808080, // 3: gray
];
// Input port bit definitions
const INPUT_RIGHT = 0x01;
const INPUT_LEFT = 0x02;
const INPUT_BACK = 0x04;
const INPUT_FORWARD = 0x08;
const INPUT_CCW = 0x10; // counter-clockwise
const INPUT_CW = 0x20; // clockwise
const INPUT_PULL = 0x40;
const INPUT_PUSH = 0x80;
export class ChannelF extends BasicMachine {
cpuFrequency = 1789773; // NTSC: 3.579545 MHz / 2
defaultROMSize = 0x10000;
// Video params
canvasWidth = 128;
numVisibleScanlines = 64;
numTotalScanlines = 64;
cpuCyclesPerLine = this.cpuFrequency / 60 / 64; // ~466 cycles per line
sampleRate = this.cpuFrequency / 2; // audio sample rate
cpu = new F8CPU();
ram = new Uint8Array(0x10000); // address space (ROM + VRAM)
vram = new Uint8Array(0x2000); // 8KB video RAM (128x64, 2 bits per pixel)
bios: Uint8Array;
// I/O port latches
port0: number = 0; // console switches
port1: number = 0; // right controller
port4: number = 0; // left controller
port5: number = 0; // row/column/sound
// Video registers
row_reg: number = 0;
col_reg: number = 0;
color: number = 0;
// Audio state
soundMode: number = 0;
soundCounter: number = 0;
soundEnvelope: number = 0;
soundOnTime: number = 0;
constructor() {
super();
this.bios = new Uint8Array(0x800); // 2KB BIOS
this.connectCPUMemoryBus(this);
this.cpu.connectIOBus(this.newIOBus());
}
newIOBus(): Bus {
return this.probeIOBus({
read: (port: number): number => {
return this.readPort(port);
},
write: (port: number, val: number): void => {
this.writePort(port, val);
}
});
}
readPort(port: number): number {
switch (port & 0xFF) {
case 0:
// Console switches: TIME(0), MODE(1), HOLD(2), START(3)
return (~this.inputs[0]) & 0xFF;
case 1:
// Right controller
return (~this.inputs[1]) & 0xFF;
case 4:
// Left controller
return (~this.inputs[2]) & 0xFF;
default:
return 0xFF;
}
}
writePort(port: number, val: number): void {
switch (port & 0xFF) {
case 0:
this.port0 = val;
break;
case 1:
this.port1 = val;
// The right controller port is also used for video column
this.col_reg = val;
break;
case 4:
this.port4 = val;
break;
case 5:
this.port5 = val;
// Upper 2 bits control sound
this.soundMode = (val >> 6) & 3;
if (this.soundMode > 0) {
this.soundEnvelope = 0x3FF; // reset envelope on new sound
this.soundOnTime = 60; // minimum on time (~2ms)
}
// Lower 6 bits control video row
this.row_reg = val & 0x3F;
// Write pixel to VRAM when both row and column are set
this.writePixel();
break;
}
}
writePixel(): void {
const row = this.row_reg;
const col = this.col_reg & 0x7F;
if (row < 64 && col < 128) {
// Color comes from port 1 upper bits
const color = (this.port1 >> 6) & 0x03;
const addr = row * 128 + col;
this.vram[addr] = color;
}
}
read = newAddressDecoder([
[0x0000, 0x07FF, 0x07FF, (a) => { return this.bios[a]; }],
[0x0800, 0xFFFF, 0xFFFF, (a) => { return this.rom ? (this.rom[a - 0x0800] || 0) : 0; }],
], { gmask: 0xFFFF });
write = newAddressDecoder([
// Channel F has no writable main memory in the base config
// Some cartridges have RAM at 0x2800-0x2FFF
[0x2800, 0x2FFF, 0x07FF, (a, v) => { if (this.rom) this.rom[a - 0x0800] = v; }],
], { gmask: 0xFFFF });
readConst(a: number): number {
if (a < 0x0800) return this.bios[a];
return this.rom ? (this.rom[a - 0x0800] || 0) : 0;
}
loadROM(data: Uint8Array): void {
if (!this.rom) this.rom = new Uint8Array(this.defaultROMSize);
this.rom.set(data);
this.reset();
}
loadBIOS(data: Uint8Array): void {
this.bios = padBytes(data, 0x800);
this.reset();
}
reset(): void {
super.reset();
this.vram.fill(0);
this.port0 = 0;
this.port1 = 0;
this.port4 = 0;
this.port5 = 0;
this.row_reg = 0;
this.col_reg = 0;
this.soundMode = 0;
this.soundCounter = 0;
this.soundEnvelope = 0;
}
advanceFrame(trap): number {
var clock = 0;
var targetClocks = this.cpuFrequency / 60;
this.probe.logNewFrame();
while (clock < targetClocks) {
if (trap && trap()) break;
clock += this.advanceCPU();
}
this.renderFrame();
this.generateAudio(targetClocks);
return clock;
}
renderFrame(): void {
if (!this.pixels) return;
// Determine palette offset from VRAM locations 125 and 126 of row 0
// (simplified - uses palette 0 by default)
for (let y = 0; y < 64; y++) {
// Palette selection per row from vram[y*128 + 125] and [y*128 + 126]
let palOffset = 0;
const p125 = this.vram[y * 128 + 125];
const p126 = this.vram[y * 128 + 126];
palOffset = ((p125 & 2) | ((p126 & 2) >> 1)) * 4;
for (let x = 0; x < 128; x++) {
const color = this.vram[y * 128 + x] & 0x03;
const rgba = CHANNELF_COLORMAP[palOffset + color];
// Double vertical: each Channel F row maps to 4 display rows (NTSC)
this.pixels[y * 128 + x] = rgba;
}
}
}
generateAudio(cycles: number): void {
if (!this.audio) return;
// Simple tone generation based on sound mode
const samplesPerFrame = Math.floor(this.sampleRate / 60);
for (let i = 0; i < samplesPerFrame; i++) {
let sample = 0;
if (this.soundMode > 0 && this.soundEnvelope > 0) {
// Generate square wave at appropriate frequency
let freq: number;
switch (this.soundMode) {
case 1: freq = 1000; break; // ~1000 Hz
case 2: freq = 500; break; // ~500 Hz
case 3: freq = 120; break; // ~120 Hz
default: freq = 0;
}
if (freq > 0) {
const period = Math.floor(this.sampleRate / freq);
this.soundCounter = (this.soundCounter + 1) % period;
sample = this.soundCounter < period / 2 ? 0.3 : -0.3;
sample *= this.soundEnvelope / 0x3FF;
}
// Decay envelope
if (this.soundOnTime > 0) {
this.soundOnTime--;
} else {
this.soundEnvelope -= 2;
if (this.soundEnvelope < 0) this.soundEnvelope = 0;
}
}
this.audio.feedSample(sample, 1);
}
}
setKeyInput(key: number, code: number, flags: number): void {
// inputs[0] = console switches
// inputs[1] = right controller
// inputs[2] = left controller
const pressed = !!(flags & KeyFlags.KeyDown);
const released = !!(flags & KeyFlags.KeyUp);
// Console buttons (mapped to number keys)
if (key === Keys.VK_1.c) { // TIME
if (pressed) this.inputs[0] |= 0x01; else if (released) this.inputs[0] &= ~0x01;
}
if (key === Keys.VK_2.c) { // MODE
if (pressed) this.inputs[0] |= 0x02; else if (released) this.inputs[0] &= ~0x02;
}
if (key === Keys.VK_3.c) { // HOLD
if (pressed) this.inputs[0] |= 0x04; else if (released) this.inputs[0] &= ~0x04;
}
if (key === Keys.VK_4.c) { // START
if (pressed) this.inputs[0] |= 0x08; else if (released) this.inputs[0] &= ~0x08;
}
// Right controller (WASD + QE for twist + RF for push/pull)
if (key === Keys.VK_UP.c || key === Keys.VK_W.c) {
if (pressed) this.inputs[1] |= INPUT_FORWARD; else if (released) this.inputs[1] &= ~INPUT_FORWARD;
}
if (key === Keys.VK_DOWN.c || key === Keys.VK_S.c) {
if (pressed) this.inputs[1] |= INPUT_BACK; else if (released) this.inputs[1] &= ~INPUT_BACK;
}
if (key === Keys.VK_LEFT.c || key === Keys.VK_A.c) {
if (pressed) this.inputs[1] |= INPUT_LEFT; else if (released) this.inputs[1] &= ~INPUT_LEFT;
}
if (key === Keys.VK_RIGHT.c || key === Keys.VK_D.c) {
if (pressed) this.inputs[1] |= INPUT_RIGHT; else if (released) this.inputs[1] &= ~INPUT_RIGHT;
}
if (key === Keys.VK_Q.c) { // CCW twist
if (pressed) this.inputs[1] |= INPUT_CCW; else if (released) this.inputs[1] &= ~INPUT_CCW;
}
if (key === Keys.VK_E.c) { // CW twist
if (pressed) this.inputs[1] |= INPUT_CW; else if (released) this.inputs[1] &= ~INPUT_CW;
}
if (key === Keys.VK_R.c) { // Push
if (pressed) this.inputs[1] |= INPUT_PUSH; else if (released) this.inputs[1] &= ~INPUT_PUSH;
}
if (key === Keys.VK_F.c) { // Pull
if (pressed) this.inputs[1] |= INPUT_PULL; else if (released) this.inputs[1] &= ~INPUT_PULL;
}
}
saveState() {
return {
c: this.cpu.saveState(),
ram: this.ram.slice(0),
inputs: this.inputs.slice(0),
vram: this.vram.slice(0),
port0: this.port0,
port1: this.port1,
port4: this.port4,
port5: this.port5,
row_reg: this.row_reg,
col_reg: this.col_reg,
soundMode: this.soundMode,
soundCounter: this.soundCounter,
soundEnvelope: this.soundEnvelope,
};
}
loadState(state) {
this.cpu.loadState(state.c);
this.ram.set(state.ram);
this.inputs.set(state.inputs);
this.vram.set(state.vram);
this.port0 = state.port0;
this.port1 = state.port1;
this.port4 = state.port4;
this.port5 = state.port5;
this.row_reg = state.row_reg;
this.col_reg = state.col_reg;
this.soundMode = state.soundMode;
this.soundCounter = state.soundCounter;
this.soundEnvelope = state.soundEnvelope;
}
}
+393 -58
View File
@@ -12,6 +12,18 @@ const DMG_PALETTE: number[] = [
0xFF2d3122, // Darkest (Deep Olive)
];
// Convert GBC 15-bit RGB (xBBBBBGGGGGRRRRR) to 32-bit ARGB
function cgbColorToARGB(lo: number, hi: number): number {
var r5 = lo & 0x1F;
var g5 = ((lo >> 5) | ((hi & 0x03) << 3)) & 0x1F;
var b5 = (hi >> 2) & 0x1F;
// Scale 5-bit to 8-bit with GBC gamma correction (approximate)
var r8 = (r5 * 527 + 23) >> 6;
var g8 = (g5 * 527 + 23) >> 6;
var b8 = (b5 * 527 + 23) >> 6;
return 0xFF000000 | (b8 << 16) | (g8 << 8) | r8;
}
var GB_KEYCODE_MAP = makeKeycodeMap([
// D-pad
[Keys.RIGHT, 0, 0x01],
@@ -676,6 +688,28 @@ export class GameBoyMachine extends BasicScanlineMachine {
hram = new Uint8Array(0x80); // High RAM (FF80-FFFE)
extram = new Uint8Array(0x2000); // External/cartridge RAM (A000-BFFF)
// GBC mode
cgbMode: boolean = false; // True when running in CGB mode
forceColor: boolean = false; // True when platform requests CGB mode
vramBank1 = new Uint8Array(0x2000); // VRAM bank 1 (CGB only)
vramBankSelect: number = 0; // FF4F - VBK: VRAM bank select (0 or 1)
wramBanks = new Uint8Array(0x7000); // WRAM banks 1-7 (CGB: 7×4KB at D000-DFFF)
wramBankSelect: number = 1; // FF70 - SVBK: WRAM bank select (1-7)
bgCRAM = new Uint8Array(64); // BG color palette RAM (8 palettes × 4 colors × 2 bytes)
objCRAM = new Uint8Array(64); // OBJ color palette RAM
bgCRAMIndex: number = 0; // FF68 - BCPS: BG palette index
bgCRAMAutoInc: boolean = false; // FF68 bit 7: auto-increment
objCRAMIndex: number = 0; // FF6A - OCPS: OBJ palette index
objCRAMAutoInc: boolean = false; // FF6A bit 7: auto-increment
doubleSpeed: boolean = false; // CGB double-speed mode active
speedSwitchArmed: boolean = false; // FF4D bit 0: prepare speed switch
// HDMA (HBlank DMA)
hdmaSrc: number = 0; // FF51-FF52: source address
hdmaDst: number = 0; // FF53-FF54: destination address
hdmaLength: number = 0xFF; // FF55: length/mode/start
hdmaActive: boolean = false; // General-purpose HDMA active flag
hdmaHblank: boolean = false; // HBlank DMA mode active
// IO registers
joyp: number = 0xCF; // FF00 - Joypad
sb: number = 0; // FF01 - Serial transfer data
@@ -710,8 +744,8 @@ export class GameBoyMachine extends BasicScanlineMachine {
ppuDot: number = 0; // Dot counter within scanline
windowLine: number = 0; // Internal window line counter
// MBC1 state
mbcType: number = 0; // 0=ROM only, 1=MBC1
// MBC state
mbcType: number = 0; // 0=ROM only, 1=MBC1, 3=MBC3, 5=MBC5
romBank: number = 1;
ramBank: number = 0;
ramEnabled: boolean = false;
@@ -729,10 +763,12 @@ export class GameBoyMachine extends BasicScanlineMachine {
read = newAddressDecoder([
[0x0000, 0x3FFF, 0x3FFF, (a) => { return this.rom ? this.rom[a] : 0xFF; }],
[0x4000, 0x7FFF, 0x3FFF, (a) => { return this.readBankedROM(a); }],
[0x8000, 0x9FFF, 0x1FFF, (a) => { return this.vram[a]; }],
[0x8000, 0x9FFF, 0x1FFF, (a) => { return this.readVRAM(a); }],
[0xA000, 0xBFFF, 0x1FFF, (a) => { return this.readExtRAM(a); }],
[0xC000, 0xDFFF, 0x1FFF, (a) => { return this.ram[a]; }],
[0xE000, 0xFDFF, 0x1FFF, (a) => { return this.ram[a]; }], // Echo RAM
[0xC000, 0xCFFF, 0x0FFF, (a) => { return this.ram[a]; }],
[0xD000, 0xDFFF, 0x0FFF, (a) => { return this.readWRAMBank(a); }],
[0xE000, 0xEFFF, 0x0FFF, (a) => { return this.ram[a]; }], // Echo RAM
[0xF000, 0xFDFF, 0x0FFF, (a) => { return this.readWRAMBank(a); }], // Echo RAM
[0xFE00, 0xFE9F, 0xFF, (a) => { return this.oam[a]; }],
[0xFEA0, 0xFEFF, 0xFF, (a) => { return 0xFF; }], // Unusable
[0xFF00, 0xFF7F, 0x7F, (a) => { return this.readIO(a); }],
@@ -745,10 +781,12 @@ export class GameBoyMachine extends BasicScanlineMachine {
[0x2000, 0x3FFF, 0x1FFF, (a, v) => { this.writeMBC(0x2000 + a, v); }],
[0x4000, 0x5FFF, 0x1FFF, (a, v) => { this.writeMBC(0x4000 + a, v); }],
[0x6000, 0x7FFF, 0x1FFF, (a, v) => { this.writeMBC(0x6000 + a, v); }],
[0x8000, 0x9FFF, 0x1FFF, (a, v) => { this.vram[a] = v; }],
[0x8000, 0x9FFF, 0x1FFF, (a, v) => { this.writeVRAM(a, v); }],
[0xA000, 0xBFFF, 0x1FFF, (a, v) => { this.writeExtRAM(a, v); }],
[0xC000, 0xDFFF, 0x1FFF, (a, v) => { this.ram[a] = v; }],
[0xE000, 0xFDFF, 0x1FFF, (a, v) => { this.ram[a] = v; }], // Echo RAM
[0xC000, 0xCFFF, 0x0FFF, (a, v) => { this.ram[a] = v; }],
[0xD000, 0xDFFF, 0x0FFF, (a, v) => { this.writeWRAMBank(a, v); }],
[0xE000, 0xEFFF, 0x0FFF, (a, v) => { this.ram[a] = v; }], // Echo RAM
[0xF000, 0xFDFF, 0x0FFF, (a, v) => { this.writeWRAMBank(a, v); }], // Echo RAM
[0xFE00, 0xFE9F, 0xFF, (a, v) => { this.oam[a] = v; }],
[0xFEA0, 0xFEFF, 0xFF, (a, v) => { /* unusable */ }],
[0xFF00, 0xFF7F, 0x7F, (a, v) => { this.writeIO(a, v); }],
@@ -756,7 +794,27 @@ export class GameBoyMachine extends BasicScanlineMachine {
[0xFFFF, 0xFFFF, 0, (a, v) => { this.ie = v; }],
]);
// MBC1 ROM banking
// VRAM bank-aware read/write
readVRAM(a: number): number {
if (this.cgbMode && this.vramBankSelect) return this.vramBank1[a];
return this.vram[a];
}
writeVRAM(a: number, v: number): void {
if (this.cgbMode && this.vramBankSelect) this.vramBank1[a] = v;
else this.vram[a] = v;
}
// WRAM bank-aware read/write (D000-DFFF)
readWRAMBank(a: number): number {
if (!this.cgbMode || this.wramBankSelect <= 1) return this.ram[0x1000 + a];
return this.wramBanks[(this.wramBankSelect - 1) * 0x1000 + a];
}
writeWRAMBank(a: number, v: number): void {
if (!this.cgbMode || this.wramBankSelect <= 1) this.ram[0x1000 + a] = v;
else this.wramBanks[(this.wramBankSelect - 1) * 0x1000 + a] = v;
}
// ROM banking (supports MBC1, MBC3, MBC5)
readBankedROM(a: number): number {
if (!this.rom) return 0xFF;
var bank = this.romBank;
@@ -767,26 +825,61 @@ export class GameBoyMachine extends BasicScanlineMachine {
writeMBC(fullAddr: number, v: number): void {
if (this.mbcType === 0) return; // ROM-only, ignore writes
if (this.mbcType === 5) {
// MBC5
this.writeMBC5(fullAddr, v);
return;
}
// MBC1 / MBC3
if (fullAddr < 0x2000) {
// RAM enable
this.ramEnabled = (v & 0x0F) === 0x0A;
} else if (fullAddr < 0x4000) {
// ROM bank number (lower 5 bits)
var bank = v & 0x1F;
if (bank === 0) bank = 1;
this.romBank = (this.romBank & 0x60) | bank;
this.romBank &= this.romBankMask;
} else if (fullAddr < 0x6000) {
// RAM bank / upper ROM bank bits
if (this.mbcMode === 0) {
this.romBank = (this.romBank & 0x1F) | ((v & 0x03) << 5);
this.romBank &= this.romBankMask;
if (this.mbcType === 3) {
// MBC3: 7-bit ROM bank
var bank = v & 0x7F;
if (bank === 0) bank = 1;
this.romBank = bank & this.romBankMask;
} else {
this.ramBank = v & 0x03;
// MBC1: lower 5 bits
var bank = v & 0x1F;
if (bank === 0) bank = 1;
this.romBank = (this.romBank & 0x60) | bank;
this.romBank &= this.romBankMask;
}
} else if (fullAddr < 0x6000) {
if (this.mbcType === 3) {
// MBC3: RAM bank 0-3 (or RTC register select)
this.ramBank = v & 0x0F;
} else {
// MBC1: RAM bank / upper ROM bank bits
if (this.mbcMode === 0) {
this.romBank = (this.romBank & 0x1F) | ((v & 0x03) << 5);
this.romBank &= this.romBankMask;
} else {
this.ramBank = v & 0x03;
}
}
} else {
// Banking mode select
this.mbcMode = v & 0x01;
// MBC1: banking mode select; MBC3: latch clock data (ignored)
if (this.mbcType === 1) this.mbcMode = v & 0x01;
}
}
writeMBC5(fullAddr: number, v: number): void {
if (fullAddr < 0x2000) {
this.ramEnabled = (v & 0x0F) === 0x0A;
} else if (fullAddr < 0x3000) {
// Low 8 bits of ROM bank
this.romBank = (this.romBank & 0x100) | v;
this.romBank &= this.romBankMask;
} else if (fullAddr < 0x4000) {
// Bit 8 of ROM bank
this.romBank = (this.romBank & 0xFF) | ((v & 0x01) << 8);
this.romBank &= this.romBankMask;
} else if (fullAddr < 0x6000) {
this.ramBank = v & 0x0F;
}
}
@@ -837,6 +930,15 @@ export class GameBoyMachine extends BasicScanlineMachine {
case 0x49: return this.obp1;
case 0x4A: return this.wy;
case 0x4B: return this.wx;
// GBC registers
case 0x4D: return this.cgbMode ? ((this.doubleSpeed ? 0x80 : 0) | (this.speedSwitchArmed ? 0x01 : 0) | 0x7E) : 0xFF;
case 0x4F: return this.cgbMode ? (this.vramBankSelect | 0xFE) : 0xFF;
case 0x55: return this.cgbMode ? this.hdmaLength : 0xFF;
case 0x68: return this.cgbMode ? (this.bgCRAMIndex | (this.bgCRAMAutoInc ? 0x80 : 0)) : 0xFF;
case 0x69: return this.cgbMode ? this.bgCRAM[this.bgCRAMIndex & 0x3F] : 0xFF;
case 0x6A: return this.cgbMode ? (this.objCRAMIndex | (this.objCRAMAutoInc ? 0x80 : 0)) : 0xFF;
case 0x6B: return this.cgbMode ? this.objCRAM[this.objCRAMIndex & 0x3F] : 0xFF;
case 0x70: return this.cgbMode ? this.wramBankSelect : 0xFF;
default: return 0xFF;
}
}
@@ -886,6 +988,41 @@ export class GameBoyMachine extends BasicScanlineMachine {
case 0x49: this.obp1 = v; break;
case 0x4A: this.wy = v; break;
case 0x4B: this.wx = v; break;
// GBC registers
case 0x4D:
if (this.cgbMode) this.speedSwitchArmed = !!(v & 0x01);
break;
case 0x4F:
if (this.cgbMode) this.vramBankSelect = v & 0x01;
break;
case 0x51: if (this.cgbMode) this.hdmaSrc = (this.hdmaSrc & 0x00FF) | (v << 8); break;
case 0x52: if (this.cgbMode) this.hdmaSrc = (this.hdmaSrc & 0xFF00) | (v & 0xF0); break;
case 0x53: if (this.cgbMode) this.hdmaDst = (this.hdmaDst & 0x00FF) | ((v & 0x1F) << 8); break;
case 0x54: if (this.cgbMode) this.hdmaDst = (this.hdmaDst & 0xFF00) | (v & 0xF0); break;
case 0x55:
if (this.cgbMode) this.startHDMA(v);
break;
case 0x68:
if (this.cgbMode) { this.bgCRAMIndex = v & 0x3F; this.bgCRAMAutoInc = !!(v & 0x80); }
break;
case 0x69:
if (this.cgbMode) {
this.bgCRAM[this.bgCRAMIndex & 0x3F] = v;
if (this.bgCRAMAutoInc) this.bgCRAMIndex = (this.bgCRAMIndex + 1) & 0x3F;
}
break;
case 0x6A:
if (this.cgbMode) { this.objCRAMIndex = v & 0x3F; this.objCRAMAutoInc = !!(v & 0x80); }
break;
case 0x6B:
if (this.cgbMode) {
this.objCRAM[this.objCRAMIndex & 0x3F] = v;
if (this.objCRAMAutoInc) this.objCRAMIndex = (this.objCRAMIndex + 1) & 0x3F;
}
break;
case 0x70:
if (this.cgbMode) { this.wramBankSelect = v & 0x07; if (this.wramBankSelect === 0) this.wramBankSelect = 1; }
break;
}
}
@@ -913,6 +1050,61 @@ export class GameBoyMachine extends BasicScanlineMachine {
}
}
// HDMA transfer (CGB)
startHDMA(v: number): void {
if (this.hdmaActive && !(v & 0x80)) {
// Cancel active HBlank DMA
this.hdmaActive = false;
this.hdmaLength = v | 0x80;
return;
}
var length = ((v & 0x7F) + 1) * 0x10;
if (v & 0x80) {
// HBlank DMA — transfer 0x10 bytes per HBlank
this.hdmaActive = true;
this.hdmaHblank = true;
this.hdmaLength = v & 0x7F;
} else {
// General-purpose DMA — transfer all at once
this.performHDMABlock(length);
this.hdmaLength = 0xFF;
}
}
performHDMABlock(length: number): void {
var src = this.hdmaSrc & 0xFFF0;
var dst = (this.hdmaDst & 0x1FF0);
for (var i = 0; i < length; i++) {
var val = this.read(src + i);
if (this.vramBankSelect) this.vramBank1[dst + i] = val;
else this.vram[dst + i] = val;
}
this.hdmaSrc += length;
this.hdmaDst += length;
}
// Called during HBlank for HBlank DMA
tickHDMA(): void {
if (!this.hdmaActive || !this.hdmaHblank) return;
this.performHDMABlock(0x10);
if (this.hdmaLength === 0) {
this.hdmaActive = false;
this.hdmaLength = 0xFF;
} else {
this.hdmaLength--;
}
}
// CGB speed switch (executed during STOP instruction)
performSpeedSwitch(): void {
if (this.cgbMode && this.speedSwitchArmed) {
this.doubleSpeed = !this.doubleSpeed;
this.speedSwitchArmed = false;
// In double speed, CPU runs at 8 MHz but PPU stays at normal speed
// We handle this by doubling T-cycles returned from advanceCPU
}
}
// Timer update — called per CPU cycle (M-cycle)
updateTimer(cycles: number): void {
// DIV increments at 16384 Hz = every 256 T-cycles = 64 M-cycles
@@ -1006,6 +1198,8 @@ export class GameBoyMachine extends BasicScanlineMachine {
// Fire STAT interrupts on mode transitions
if (this.ppuMode === 0 && (this.stat & 0x08)) {
this.iflag |= 0x02; // HBlank STAT interrupt
// CGB HBlank DMA
if (this.cgbMode) this.tickHDMA();
} else if (this.ppuMode === 2 && (this.stat & 0x20)) {
this.iflag |= 0x02; // OAM STAT interrupt
}
@@ -1081,16 +1275,20 @@ export class GameBoyMachine extends BasicScanlineMachine {
var lineOffset = this.scanline * 160;
// Draw background
if (this.lcdc & 0x01) {
// In CGB mode, LCDC bit 0 controls BG/sprite priority, not BG enable
if ((this.lcdc & 0x01) || this.cgbMode) {
this.drawBGLine(lineOffset);
} else {
// BG disabled — fill with color 0
// BG disabled (DMG only) — fill with color 0
for (var x = 0; x < 160; x++) {
this.pixels[lineOffset + x] = DMG_PALETTE[0];
this.bgPriorityLine[x] = 0;
this.bgAttrPriLine[x] = 0;
}
}
// Draw window
// In CGB mode, window is always available when LCDC bit 5 is set
if ((this.lcdc & 0x20) && this.scanline >= this.wy) {
this.drawWindowLine(lineOffset);
}
@@ -1102,17 +1300,26 @@ export class GameBoyMachine extends BasicScanlineMachine {
}
// Get color from palette register
// Get DMG color from palette register
getPaletteColor(palette: number, colorIndex: number): number {
var shade = (palette >> (colorIndex * 2)) & 0x03;
return DMG_PALETTE[shade];
}
// Get CGB color from color palette RAM
getCGBColor(cram: Uint8Array, paletteNum: number, colorIndex: number): number {
var idx = paletteNum * 8 + colorIndex * 2;
return cgbColorToARGB(cram[idx], cram[idx + 1]);
}
// Per-pixel BG priority tracking for CGB sprite priority
private bgPriorityLine = new Uint8Array(160); // stores BG color index per pixel
private bgAttrPriLine = new Uint8Array(160); // stores BG-over-OBJ bit per pixel
// Draw one line of background
drawBGLine(lineOffset: number): void {
var tileMap = (this.lcdc & 0x08) ? 0x1C00 : 0x1800; // BG tile map select
var tileData = (this.lcdc & 0x10) ? 0x0000 : 0x0800; // BG & Window tile data select
var signed = !(this.lcdc & 0x10); // Use signed tile indices when bit 4 is 0
var tileMap = (this.lcdc & 0x08) ? 0x1C00 : 0x1800;
var signed = !(this.lcdc & 0x10);
var y = (this.scanline + this.scy) & 0xFF;
var tileRow = (y >> 3) & 31;
@@ -1122,23 +1329,44 @@ export class GameBoyMachine extends BasicScanlineMachine {
var scrolledX = (x + this.scx) & 0xFF;
var tileCol = (scrolledX >> 3) & 31;
var tileXBit = 7 - (scrolledX & 7);
var mapOffset = tileMap + tileRow * 32 + tileCol;
// Get tile index from map
var tileIndex = this.vram[tileMap + tileRow * 32 + tileCol];
// Get tile index from map (VRAM bank 0)
var tileIndex = this.vram[mapOffset];
var tileAddr: number;
if (signed) {
// Signed: tile 0 is at 0x9000 (VRAM offset 0x1000)
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16); // sign extend
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16);
} else {
tileAddr = tileIndex * 16;
}
// Get pixel from tile data (2bpp)
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
if (this.cgbMode) {
// CGB: read attributes from VRAM bank 1
var attr = this.vramBank1[mapOffset];
var cgbPalette = attr & 0x07;
var vramBank = (attr & 0x08) ? 1 : 0;
var xFlip = !!(attr & 0x20);
var yFlip = !!(attr & 0x40);
var bgPri = !!(attr & 0x80);
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
var tileY = yFlip ? (7 - tileYOffset) : tileYOffset;
var tileBit = xFlip ? (scrolledX & 7) : tileXBit;
var bank = vramBank ? this.vramBank1 : this.vram;
var lo = bank[tileAddr + tileY * 2];
var hi = bank[tileAddr + tileY * 2 + 1];
var colorIndex = ((hi >> tileBit) & 1) << 1 | ((lo >> tileBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = bgPri ? 1 : 0;
this.pixels[lineOffset + x] = this.getCGBColor(this.bgCRAM, cgbPalette, colorIndex);
} else {
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = 0;
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
}
}
}
@@ -1147,8 +1375,7 @@ export class GameBoyMachine extends BasicScanlineMachine {
var wxAdjusted = this.wx - 7;
if (wxAdjusted >= 160) return;
var tileMap = (this.lcdc & 0x40) ? 0x1C00 : 0x1800; // Window tile map select
var tileData = (this.lcdc & 0x10) ? 0x0000 : 0x0800;
var tileMap = (this.lcdc & 0x40) ? 0x1C00 : 0x1800;
var signed = !(this.lcdc & 0x10);
var winY = this.windowLine;
@@ -1160,8 +1387,9 @@ export class GameBoyMachine extends BasicScanlineMachine {
var winX = x - wxAdjusted;
var tileCol = (winX >> 3) & 31;
var tileXBit = 7 - (winX & 7);
var mapOffset = tileMap + tileRow * 32 + tileCol;
var tileIndex = this.vram[tileMap + tileRow * 32 + tileCol];
var tileIndex = this.vram[mapOffset];
var tileAddr: number;
if (signed) {
tileAddr = 0x1000 + (((tileIndex << 24) >> 24) * 16);
@@ -1169,11 +1397,32 @@ export class GameBoyMachine extends BasicScanlineMachine {
tileAddr = tileIndex * 16;
}
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
if (this.cgbMode) {
var attr = this.vramBank1[mapOffset];
var cgbPalette = attr & 0x07;
var vramBank = (attr & 0x08) ? 1 : 0;
var xFlip = !!(attr & 0x20);
var yFlip = !!(attr & 0x40);
var bgPri = !!(attr & 0x80);
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
var tileY = yFlip ? (7 - tileYOffset) : tileYOffset;
var tileBit = xFlip ? (winX & 7) : tileXBit;
var bank = vramBank ? this.vramBank1 : this.vram;
var lo = bank[tileAddr + tileY * 2];
var hi = bank[tileAddr + tileY * 2 + 1];
var colorIndex = ((hi >> tileBit) & 1) << 1 | ((lo >> tileBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = bgPri ? 1 : 0;
this.pixels[lineOffset + x] = this.getCGBColor(this.bgCRAM, cgbPalette, colorIndex);
} else {
var lo = this.vram[tileAddr + tileYOffset * 2];
var hi = this.vram[tileAddr + tileYOffset * 2 + 1];
var colorIndex = ((hi >> tileXBit) & 1) << 1 | ((lo >> tileXBit) & 1);
this.bgPriorityLine[x] = colorIndex;
this.bgAttrPriLine[x] = 0;
this.pixels[lineOffset + x] = this.getPaletteColor(this.bgp, colorIndex);
}
drawn = true;
}
if (drawn) this.windowLine++;
@@ -1196,7 +1445,10 @@ export class GameBoyMachine extends BasicScanlineMachine {
}
// Sort by X coordinate (lower X = higher priority, ties broken by OAM index)
sprites.sort((a, b) => a.x !== b.x ? a.x - b.x : a.index - b.index);
// CGB: no X priority sorting, only OAM index order
if (!this.cgbMode) {
sprites.sort((a, b) => a.x !== b.x ? a.x - b.x : a.index - b.index);
}
// Draw sprites in reverse order (lowest priority first, so higher priority overwrites)
for (var si = sprites.length - 1; si >= 0; si--) {
@@ -1206,19 +1458,21 @@ export class GameBoyMachine extends BasicScanlineMachine {
var tileIndex = this.oam[spriteIndex * 4 + 2];
var flags = this.oam[spriteIndex * 4 + 3];
var palette = (flags & 0x10) ? this.obp1 : this.obp0;
var xFlip = !!(flags & 0x20);
var yFlip = !!(flags & 0x40);
var bgPriority = !!(flags & 0x80);
if (spriteHeight === 16) tileIndex &= 0xFE; // Ignore bit 0 for 8x16 sprites
if (spriteHeight === 16) tileIndex &= 0xFE;
var tileY = this.scanline - yPos;
if (yFlip) tileY = spriteHeight - 1 - tileY;
var tileAddr = tileIndex * 16 + tileY * 2;
var lo = this.vram[tileAddr];
var hi = this.vram[tileAddr + 1];
// CGB: sprites can use VRAM bank 0 or 1
var spriteVramBank = (this.cgbMode && (flags & 0x08)) ? this.vramBank1 : this.vram;
var lo = spriteVramBank[tileAddr];
var hi = spriteVramBank[tileAddr + 1];
for (var px = 0; px < 8; px++) {
var screenX = xPos + px;
@@ -1228,13 +1482,25 @@ export class GameBoyMachine extends BasicScanlineMachine {
var colorIndex = ((hi >> bit) & 1) << 1 | ((lo >> bit) & 1);
if (colorIndex === 0) continue; // Transparent
// BG priority: sprite hidden behind BG colors 1-3
if (bgPriority) {
var bgColor = this.pixels[lineOffset + screenX];
if (bgColor !== DMG_PALETTE[(this.bgp & 0x03)]) continue; // BG color 0 check
if (this.cgbMode) {
// CGB priority: BG attribute bit 7 overrides sprite if BG color != 0
// Also OAM bit 7 (bgPriority) can hide sprite behind BG
var bgMaster = this.lcdc & 0x01; // LCDC bit 0 = BG/Window master priority
if (bgMaster) {
if (this.bgAttrPriLine[screenX] && this.bgPriorityLine[screenX] !== 0) continue;
if (bgPriority && this.bgPriorityLine[screenX] !== 0) continue;
}
var cgbPalette = flags & 0x07;
this.pixels[lineOffset + screenX] = this.getCGBColor(this.objCRAM, cgbPalette, colorIndex);
} else {
// DMG priority
if (bgPriority) {
var bgColor = this.pixels[lineOffset + screenX];
if (bgColor !== DMG_PALETTE[(this.bgp & 0x03)]) continue;
}
var palette = (flags & 0x10) ? this.obp1 : this.obp0;
this.pixels[lineOffset + screenX] = this.getPaletteColor(palette, colorIndex);
}
this.pixels[lineOffset + screenX] = this.getPaletteColor(palette, colorIndex);
}
}
}
@@ -1246,10 +1512,18 @@ export class GameBoyMachine extends BasicScanlineMachine {
switch (cartType) {
case 0x00: this.mbcType = 0; break; // ROM only
case 0x01: case 0x02: case 0x03: this.mbcType = 1; break; // MBC1
default: console.log(`Invalid cartridge type @ 0x147: ${data[0x147]}`); break;
case 0x0F: case 0x10: case 0x11: case 0x12: case 0x13: this.mbcType = 3; break; // MBC3
case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: this.mbcType = 5; break; // MBC5
default: console.log(`Unhandled cartridge type 0x${cartType.toString(16)} @ 0x147, treating as MBC5`); this.mbcType = 5; break;
}
} else throw new EmuHalt("ROM not long enough for header");
// Detect CGB mode from header byte 0x143
if (data.length > 0x143) {
var cgbFlag = data[0x143];
this.cgbMode = this.forceColor || cgbFlag === 0x80 || cgbFlag === 0xC0;
}
// Determine ROM size and bank mask
this.rom = new Uint8Array(Math.max(data.length, 0x8000));
this.rom.set(data);
@@ -1304,6 +1578,28 @@ export class GameBoyMachine extends BasicScanlineMachine {
this.timerSubCycles = 0;
this.apuCycleAccum = 0;
this.apu.reset();
// GBC state
this.vramBank1.fill(0);
this.vramBankSelect = 0;
this.wramBanks.fill(0);
this.wramBankSelect = 1;
this.bgCRAM.fill(0xFF);
this.objCRAM.fill(0xFF);
this.bgCRAMIndex = 0;
this.bgCRAMAutoInc = false;
this.objCRAMIndex = 0;
this.objCRAMAutoInc = false;
this.doubleSpeed = false;
this.speedSwitchArmed = false;
this.hdmaSrc = 0;
this.hdmaDst = 0;
this.hdmaLength = 0xFF;
this.hdmaActive = false;
this.hdmaHblank = false;
// CGB boot ROM leaves A=0x11 so games can detect CGB hardware
if (this.cgbMode) {
this.cpu.A = 0x11;
}
}
preFrame(): void {
@@ -1311,6 +1607,8 @@ export class GameBoyMachine extends BasicScanlineMachine {
}
readVRAMAddress(a: number): number {
// For debug views: addresses 0x0000-0x1FFF = bank 0, 0x2000-0x3FFF = bank 1
if (this.cgbMode && a >= 0x2000) return this.vramBank1[a & 0x1FFF];
return this.vram[a & 0x1FFF];
}
@@ -1336,6 +1634,22 @@ export class GameBoyMachine extends BasicScanlineMachine {
};
state['apu'] = this.apu.saveState();
state['apuCycleAccum'] = this.apuCycleAccum;
// GBC state
if (this.cgbMode) {
state['cgb'] = {
vramBank1: this.vramBank1.slice(0),
vramBankSelect: this.vramBankSelect,
wramBanks: this.wramBanks.slice(0),
wramBankSelect: this.wramBankSelect,
bgCRAM: this.bgCRAM.slice(0),
objCRAM: this.objCRAM.slice(0),
bgCRAMIndex: this.bgCRAMIndex, bgCRAMAutoInc: this.bgCRAMAutoInc,
objCRAMIndex: this.objCRAMIndex, objCRAMAutoInc: this.objCRAMAutoInc,
doubleSpeed: this.doubleSpeed, speedSwitchArmed: this.speedSwitchArmed,
hdmaSrc: this.hdmaSrc, hdmaDst: this.hdmaDst,
hdmaLength: this.hdmaLength, hdmaActive: this.hdmaActive, hdmaHblank: this.hdmaHblank,
};
}
return state;
}
@@ -1359,6 +1673,21 @@ export class GameBoyMachine extends BasicScanlineMachine {
this.timerSubCycles = io.timerSubCycles;
if (state.apu) this.apu.loadState(state.apu);
this.apuCycleAccum = state.apuCycleAccum || 0;
// GBC state
if (state.cgb) {
var cgb = state.cgb;
this.vramBank1.set(cgb.vramBank1);
this.vramBankSelect = cgb.vramBankSelect;
this.wramBanks.set(cgb.wramBanks);
this.wramBankSelect = cgb.wramBankSelect;
this.bgCRAM.set(cgb.bgCRAM);
this.objCRAM.set(cgb.objCRAM);
this.bgCRAMIndex = cgb.bgCRAMIndex; this.bgCRAMAutoInc = cgb.bgCRAMAutoInc;
this.objCRAMIndex = cgb.objCRAMIndex; this.objCRAMAutoInc = cgb.objCRAMAutoInc;
this.doubleSpeed = cgb.doubleSpeed; this.speedSwitchArmed = cgb.speedSwitchArmed;
this.hdmaSrc = cgb.hdmaSrc; this.hdmaDst = cgb.hdmaDst;
this.hdmaLength = cgb.hdmaLength; this.hdmaActive = cgb.hdmaActive; this.hdmaHblank = cgb.hdmaHblank;
}
}
getDebugCategories() {
@@ -1368,7 +1697,7 @@ export class GameBoyMachine extends BasicScanlineMachine {
getDebugInfo(category, state) {
switch (category) {
case 'PPU':
return "LCDC " + hex(this.lcdc, 2) + " STAT " + hex(this.stat, 2) + "\n"
var s = "LCDC " + hex(this.lcdc, 2) + " STAT " + hex(this.stat, 2) + "\n"
+ "LY " + hex(this.ly, 2) + " LYC " + hex(this.lyc, 2) + "\n"
+ "SCX " + hex(this.scx, 2) + " SCY " + hex(this.scy, 2) + "\n"
+ "WX " + hex(this.wx, 2) + " WY " + hex(this.wy, 2) + "\n"
@@ -1378,6 +1707,12 @@ export class GameBoyMachine extends BasicScanlineMachine {
+ "DIV " + hex((this.divCounter >> 8) & 0xFF, 2) + " TIMA " + hex(this.tima, 2) + "\n"
+ "TMA " + hex(this.tma, 2) + " TAC " + hex(this.tac, 2) + "\n"
+ "Bank " + this.romBank + "\n";
if (this.cgbMode) {
s += "--- CGB ---\n"
+ "VBK " + this.vramBankSelect + " SVBK " + this.wramBankSelect + "\n"
+ "SPD " + (this.doubleSpeed ? "2x" : "1x") + "\n";
}
return s;
}
}
}
+41 -43
View File
@@ -1,3 +1,6 @@
// based on https://raw.githubusercontent.com/mamedev/mame/refs/heads/master/src/mame/midway/mcr.cpp
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
import { Z80, Z80State } from "../common/cpu/ZilogZ80";
import { BasicScanlineMachine } from "../common/devices";
@@ -15,7 +18,7 @@ const MCR2_CYCLES_PER_LINE = Math.floor(MCR2_CPU_FREQ / (MCR2_NUM_TOTAL_SCANLINE
const MCR2_TILE_COLS = 32;
const MCR2_TILE_ROWS = 30;
const MCR2_TILE_SIZE = 16;
const MCR2_TILE_SIZE = 8; // double-pixels for BG
const INITIAL_WATCHDOG = 16;
@@ -44,11 +47,11 @@ const MCR2_KEYCODE_MAP = makeKeycodeMap([
// ROM blob layout
const ROM_PROGRAM_START = 0x0;
const ROM_PROGRAM_SIZE = 0xC000;
const ROM_BG_GFX_START = 0xC000;
const ROM_PROGRAM_SIZE = 0xE000;
const ROM_BG_GFX_START = ROM_PROGRAM_SIZE;
const ROM_BG_GFX_SIZE = 0x4000; // 16KB background tiles (2 bitplanes × 8KB)
const ROM_SPR_GFX_START = 0x12000;
const ROM_SPR_GFX_SIZE = 2 * 0x8000; // 32KB sprites (4 bitplanes × 8KB)
const ROM_SPR_GFX_START = ROM_BG_GFX_START + ROM_BG_GFX_SIZE;
const ROM_SPR_GFX_SIZE = 0x8000; // 32KB sprites (4 bitplanes × 8KB)
const SSIO_ROM_SIZE = 0x4000;
const ROM_TOTAL_SIZE = ROM_PROGRAM_SIZE + ROM_BG_GFX_SIZE + ROM_SPR_GFX_SIZE + SSIO_ROM_SIZE;
@@ -95,9 +98,9 @@ export class MCR2Machine extends BasicScanlineMachine {
// Main CPU memory read
read = newAddressDecoder([
[0x0000, 0xBFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],
[0xC000, 0xDFFF, 0x7FF, (a) => { return this.ram[a]; }],
[0xE000, 0xE7FF, 0x1FF, (a) => { return this.sprram[a]; }],
[0x0000, 0xDFFF, 0xFFFF, (a) => { return this.rom ? this.rom[a] : 0; }],
[0xE000, 0xE7FF, 0x7FF, (a) => { return this.ram[a]; }],
[0xE800, 0xEFFF, 0x1FF, (a) => { return this.sprram[a]; }],
[0xF000, 0xF7FF, 0x7FF, (a) => { return this.vram[a]; }],
[0xF800, 0xFFFF, 0x7F, (a) => { return this.palram[a]; }],
]);
@@ -108,8 +111,8 @@ export class MCR2Machine extends BasicScanlineMachine {
// Main CPU memory write
write = newAddressDecoder([
[0xC000, 0xDFFF, 0x7FF, (a, v) => { this.ram[a] = v; }],
[0xE000, 0xE7FF, 0x1FF, (a, v) => { this.sprram[a] = v; }],
[0xE000, 0xE7FF, 0x7FF, (a, v) => { this.ram[a] = v; }],
[0xE800, 0xEFFF, 0x1FF, (a, v) => { this.sprram[a] = v; }],
[0xF000, 0xF7FF, 0x7FF, (a, v) => { this.vram[a] = v; }],
[0xF800, 0xFFFF, 0x7F, (a, v) => {
this.palram[a] = v;
@@ -178,25 +181,29 @@ export class MCR2Machine extends BasicScanlineMachine {
if (sl >= MCR2_NUM_VISIBLE_SCANLINES) return;
let pixofs = sl * MCR2_CANVAS_WIDTH;
let tileRow = Math.floor(sl / MCR2_TILE_SIZE);
let tileY = sl % MCR2_TILE_SIZE;
// Draw background tiles
if (tileRow < MCR2_TILE_ROWS) {
for (let tileCol = 0; tileCol < MCR2_TILE_COLS; tileCol++) {
let vramOfs = (tileRow * MCR2_TILE_COLS + tileCol) * 2;
let byte0 = this.vram[vramOfs];
let byte1 = this.vram[vramOfs + 1];
if ((sl & 1) == 0) {
sl >>= 1;
let tileRow = Math.floor(sl / MCR2_TILE_SIZE);
let tileY = sl % MCR2_TILE_SIZE;
// 91490 tile format
let tileCode = byte0 | ((byte1 & 0x03) << 8);
let tilePalette = (byte1 >> 4) & 0x03;
let flipX = (byte1 & 0x04) != 0;
let flipY = (byte1 & 0x08) != 0;
// Draw background tiles
if (tileRow < MCR2_TILE_ROWS) {
for (let tileCol = 0; tileCol < MCR2_TILE_COLS; tileCol++) {
let vramOfs = (tileRow * MCR2_TILE_COLS + tileCol) * 2;
let byte0 = this.vram[vramOfs];
let byte1 = this.vram[vramOfs + 1];
let ty = flipY ? (15 - tileY) : tileY;
let pixX = tileCol * MCR2_TILE_SIZE;
this.drawTileLine(pixofs + pixX, tileCode, ty, tilePalette, flipX);
// 91490 tile format
let tileCode = byte0 | ((byte1 & 0x03) << 8);
let tilePalette = (byte1 >> 4) & 0x03;
let flipX = (byte1 & 0x04) != 0;
let flipY = (byte1 & 0x08) != 0;
let ty = flipY ? (15 - tileY) : tileY;
let pixX = tileCol * MCR2_TILE_SIZE * 2;
this.drawTileLine(pixofs + pixX, tileCode, ty, tilePalette, flipX);
}
}
}
@@ -209,31 +216,22 @@ export class MCR2Machine extends BasicScanlineMachine {
let gfxBase = ROM_BG_GFX_START;
let halfSize = ROM_BG_GFX_SIZE / 2; // 8KB per bitplane
// Tile layout: 32 bytes per tile per bitplane
// Left 8 pixels in bytes 0-15 (one byte per row), right 8 pixels in bytes 16-31
// Tile layout: 8 bytes per tile per bitplane
let tileOfs = tileCode * 32;
let leftByteOfs = tileOfs + (row < 8 ? row : row); // rows 0-15
let rightByteOfs = tileOfs + 16 + (row < 8 ? row : row);
let byteOfs = tileOfs + (row < 8 ? row : row); // rows 0-15
let p0L = this.rom[gfxBase + leftByteOfs] || 0;
let p1L = this.rom[gfxBase + halfSize + leftByteOfs] || 0;
let p0R = this.rom[gfxBase + rightByteOfs] || 0;
let p1R = this.rom[gfxBase + halfSize + rightByteOfs] || 0;
let p0L = this.rom[gfxBase + byteOfs] || 0;
let p1L = this.rom[gfxBase + halfSize + byteOfs] || 0;
let colorBase = palette * 4;
// Draw 16 pixels (left 8 + right 8)
for (let x = 0; x < 8; x++) {
let bit = 7 - x;
let srcX = flipX ? (15 - x) : x;
let srcX = flipX ? (14 - x * 2) : x * 2;
let color = ((p0L >> bit) & 1) | (((p1L >> bit) & 1) << 1);
this.pixels[outOfs + srcX] = this.palette[colorBase + color];
}
for (let x = 0; x < 8; x++) {
let bit = 7 - x;
let srcX = flipX ? (7 - x) : (8 + x);
let color = ((p0R >> bit) & 1) | (((p1R >> bit) & 1) << 1);
this.pixels[outOfs + srcX] = this.palette[colorBase + color];
this.pixels[outOfs + srcX] = this.pixels[outOfs + srcX + 512]
= this.pixels[outOfs + srcX + 1] = this.pixels[outOfs + srcX + 513]
= this.palette[colorBase + color];
}
}
+1
View File
@@ -9,6 +9,7 @@ export function importPlatform(name: string) : Promise<any> {
case "atari8": return import("../platform/atari8");
case "basic": return import("../platform/basic");
case "c64": return import("../platform/c64");
case "channelf": return import("../platform/channelf");
case "coleco": return import("../platform/coleco");
case "cpc": return import("../platform/cpc");
case "devel": return import("../platform/devel");
+75
View File
@@ -0,0 +1,75 @@
// based on https://github.com/mamedev/mame/blob/master/src/devices/cpu/f8/f8.cpp
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
// and https://raw.githubusercontent.com/mamedev/mame/master/src/mame/fairchild/channelf.cpp
// license:GPL-2.0+
// copyright-holders:Juergen Buchmueller, Frank Palazzolo, Sean Riddle
import { Platform, BaseMachinePlatform, DisasmLine } from "../common/baseplatform";
import { PLATFORMS } from "../common/emu";
import { ChannelF } from "../machine/channelf";
import { disassembleF8 } from "../common/cpu/disasmF8";
import { hex, printFlags } from "../common/util";
var CHANNELF_PRESETS = [
{ id: 'hello.dasm', name: 'Hello World (ASM)' },
];
function cpuStateToLongString_F8(c): string {
return "PC0 = " + hex(c.PC0, 4) + " PC1 = " + hex(c.PC1, 4) + "\n"
+ "DC0 = " + hex(c.DC0, 4) + " DC1 = " + hex(c.DC1, 4) + "\n"
+ " A = " + hex(c.A, 2) + " W = " + hex(c.W, 2) + "\n"
+ " IS = " + hex(c.IS, 2) + "\n"
+ printFlags(c.W, ['S', 'C', 'Z', 'O', 'I'], true) + "\n"
+ " R0-R3: " + c.R.slice(0, 4).map(v => hex(v, 2)).join(' ') + "\n"
+ " R4-R7: " + c.R.slice(4, 8).map(v => hex(v, 2)).join(' ') + "\n"
+ " R8/J/H: " + c.R.slice(8, 12).map(v => hex(v, 2)).join(' ') + "\n"
+ " K/Q: " + c.R.slice(12, 16).map(v => hex(v, 2)).join(' ') + "\n";
}
class ChannelFPlatform extends BaseMachinePlatform<ChannelF> implements Platform {
newMachine() { return new ChannelF(); }
getPresets() { return CHANNELF_PRESETS; }
getDefaultExtensions() { return [".dasm"]; }
getToolForFilename(fn: string): string {
if (fn.endsWith(".c")) return "cc65";
if (fn.endsWith(".s") || fn.endsWith(".ca65")) return "ca65";
return "dasm";
}
readAddress(a) { return this.machine.readConst(a); }
disassemble(pc: number, read: (addr: number) => number): DisasmLine {
return disassembleF8(pc, read(pc), read(pc + 1), read(pc + 2));
}
getDebugCategories() {
return ['CPU', 'I/O', 'VRAM'];
}
getDebugInfo(category: string, state): string {
switch (category) {
case 'CPU': return cpuStateToLongString_F8(state.c);
case 'I/O':
return "Port 0: " + hex(state.port0 || 0, 2) + "\n"
+ "Port 1: " + hex(state.port1 || 0, 2) + "\n"
+ "Port 4: " + hex(state.port4 || 0, 2) + "\n"
+ "Port 5: " + hex(state.port5 || 0, 2) + "\n"
+ "Row: " + hex(state.row_reg || 0, 2) + "\n"
+ "Col: " + hex(state.col_reg || 0, 2) + "\n";
case 'VRAM': return '';
default: return '';
}
}
getMemoryMap() {
return {
main: [
{ name: 'BIOS', start: 0x0000, size: 0x0800, type: 'rom' },
{ name: 'Cart ROM', start: 0x0800, size: 0x7800, type: 'rom' },
]
};
}
}
PLATFORMS['channelf'] = ChannelFPlatform;
+39 -1
View File
@@ -73,5 +73,43 @@ class GameBoyPlatform extends BaseMachinePlatform<GameBoyMachine> implements Pla
}
}
const GBC_PRESETS: Preset[] = [
{ id: 'hello_color.c', name: 'Hello Color World (C)' },
];
class GameBoyColorPlatform extends GameBoyPlatform {
newMachine() {
var m = new GameBoyMachine();
m.forceColor = true;
return m;
}
getPresets() { return GBC_PRESETS; }
getROMExtension() {
return ".gbc";
}
getMemoryMap() {
return {
main: [
{ name: 'ROM Bank 0', start: 0x0000, size: 0x4000, type: 'rom' },
{ name: 'ROM Bank 1+', start: 0x4000, size: 0x4000, type: 'rom' },
{ name: 'Video RAM B0', start: 0x8000, size: 0x2000, type: 'ram' },
{ name: 'External RAM', start: 0xA000, size: 0x2000, type: 'ram' },
{ name: 'Work RAM 0', start: 0xC000, size: 0x1000, type: 'ram' },
{ name: 'Work RAM 1-7', start: 0xD000, size: 0x1000, type: 'ram' },
{ name: 'OAM', start: 0xFE00, size: 0xA0, type: 'ram' },
{ name: 'I/O Registers', start: 0xFF00, size: 0x80, type: 'io' },
{ name: 'High RAM', start: 0xFF80, size: 0x7F, type: 'ram' },
]
};
}
showHelp() {
return "https://8bitworkshop.com/docs/platforms/gameboy/";
}
}
PLATFORMS['gb'] = GameBoyPlatform;
PLATFORMS['gameboy'] = GameBoyPlatform;
PLATFORMS['gb.color'] = GameBoyColorPlatform;
+3
View File
@@ -1,3 +1,6 @@
// based on https://raw.githubusercontent.com/mamedev/mame/refs/heads/master/src/mame/midway/mcr.cpp
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
import { MCR2Machine } from "../machine/mcr";
import { BaseZ80MachinePlatform } from "../common/baseplatform";
+2 -1
View File
@@ -383,10 +383,11 @@ export var PLATFORM_PARAMS = {
'mcr': {
arch: 'z80',
code_start: 0x0,
rom_size: 0xe000,
rom_size: 0xe000 + 0x4000 + 0x8000,
data_start: 0xe000,
data_size: 0x800,
stack_end: 0xe800,
// TODO: IHX can't handle > 64 KB, so ihx2sms looks for segments in a certain order
},
};