Comparing version 0.2.1 to 0.3.0
@@ -1,1 +0,1 @@ | ||
window.Nes=(()=>{var t={679:(t,e,s)=>{"use strict";s.d(e,{default:()=>ce});s(593);var r=s(87),i=s.n(r);class n extends Error{constructor(t){super(`${t.to(16,2)} is an unknown address`),this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}function a(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}function o(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const h=()=>{};function c(){throw new Error("Unknown mapper")}const l=new Array(255).fill(null).map((()=>c));l[0]=class{constructor({prgRom:t,prgRam:e,chrRxm:s}){a(this,"prgRom",null),a(this,"prgRam",null),a(this,"chrRxm",null),a(this,"prgRomLastPage",0),this.prgRom=t,this.prgRam=e,this.chrRxm=s,this.prgRomLastPage=t.length-1,Object.seal(this)}w8(t,e){if(e<8192){const s=e>>12&1;this.chrRxm[s][4095&e]=t}else{if(e<24576)throw new n(e);if(!(e<32768))throw new n(e);this.prgRam[8191&e]=t}}r8(t){if(t<8192){const e=t>>12&1;return this.chrRxm[e][4095&t]}if(t<24576)throw new n(t);return t<32768?this.prgRam[8191&t]:t<49152?this.prgRom[0][16383&t]:this.prgRom[this.prgRomLastPage][16383&t]}},l[1]=class{constructor({prgRom:t,prgRam:e,chrRxm:s}){o(this,"prgRom",null),o(this,"prgRam",null),o(this,"chrRxm",null),o(this,"prgRomLastPage",0),o(this,"prgRamEnable",!1),o(this,"shift",0),o(this,"shiftCount",0),o(this,"mirroring",0),o(this,"prgRomBankMode",0),o(this,"chrRxmBankMode",0),o(this,"chrRxmBank",[0,0]),o(this,"prgRomBank",0),this.prgRom=t,this.prgRam=e,this.chrRxm=s,this.prgRomLastPage=t.length-1,Object.seal(this)}shiftReset(){this.shift=0,this.shiftCount=0}shiftRight(t){this.shift>>=1,this.shift|=(1&t)<<4,this.shiftCount++}getChrRxmBank(t){return 0==this.chrRxmBankMode?0==t?254&this.chrRxmBank[0]:1|this.chrRxmBank[1]:this.chrRxmBank[t]}getPrgRomBank(t){const e=this.prgRomBankMode;return 0==e||1==e?0==t?254&this.prgRomBank:1|this.prgRomBank:2==e?0==t?0:this.prgRomBank:3==e?0==t?this.prgRomBank:this.prgRomLastPage:void 0}writeRegister(t){if(h("write register: %s, val: %s",(t>>12).to(16),this.shift.to(2)),t<40960)h("set control: %s",this.shift.to(2)),this.mirroring=3&this.shift,this.prgRomBankMode=this.shift>>2&3,this.chrRxmBankMode=this.shift>>4&1;else if(t<57344){const e=t>>14&1;this.chrRxmBank[e]=31&this.shift,h("set bank chr-rxm[%d]: %d",e,this.shift)}else this.prgRamEnable=0==(16&this.shift),this.prgRomBank=15&this.shift,h("set bank prg-rom: %d",this.prgRomBank),h("prg-ram enable",this.prgRamEnable)}w8(t,e){if(e<8192){const s=this.getChrRxmBank(e>>12&1);this.chrRxm[s][4095&e]=t}else{if(e<24576)return;e<32768?this.prgRamEnable&&(this.prgRam[8191&e]=t):128&t?(h("reset control"),this.prgRomBankMode=3,this.shiftReset()):this.shiftCount<4?this.shiftRight(t):(this.shiftRight(t),this.writeRegister(e),this.shiftReset())}}r8(t){if(t<8192){const e=this.getChrRxmBank(t>>12&1);return this.chrRxm[e][4095&t]}if(t<24576)return 0;if(t<32768)return this.prgRam[8191&t];{const e=this.getPrgRomBank(t>>14&1);return this.prgRom[e][16383&t]}}};const u=l;function p(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const m=()=>{};class f{constructor(t){p(this,"nes",null),p(this,"prgRam",new Uint8Array(8192)),p(this,"prgRom",null),p(this,"chrRxm",null),p(this,"mapper",null),p(this,"mirroring",0),p(this,"loaded",!1),Object.seal(this),this.nes=t}static createMemory({data:t,pages:e,size:s}){return new Array(e).fill(null).map(((e,r)=>{const i=r*s,n=new Uint8Array(s);return n.set(t.slice(i,i+s)),n}))}static isInesFormat1(t){const e=2==(t[7]>>2&3);return 78===t[0]&&69===t[1]&&83===t[2]&&26===t[3]&&!e}load(t){f.isInesFormat1(t),t[6];const e=t[4],s=t[5],r=t[6]>>4|240&t[7],i=u[r];m("mapper index: %d, uses: %s",r,i.name),m("prg-rom 16kb size units: %d",e),m("chr-rxm 8kb size units: %d",s),m("mirroring: %d",9&t[6]),m("rom control byte #1: %s",t[6].to(2)),m("rom control byte #2: %s",t[7].to(2)),this.prgRom=f.createMemory({data:t.slice(16),pages:e,size:16384});let n=new Array(8192);s>0&&(n=t.slice(16+16384*e)),this.chrRxm=f.createMemory({data:n,pages:(s||1)<<1,size:4096}),this.chrRxm.forEach(((t,e)=>{t.forEach(((t,s)=>this.nes.video.updatePattern(e,t,s)))})),this.mapper=new i({prgRom:this.prgRom,prgRam:this.prgRam,chrRxm:this.chrRxm}),this.mirroring=9&t[6],this.loaded=!0}r8(t){return this.loaded,this.mapper.r8(t)}w8(t,e){return this.loaded,this.mapper.w8(t,e)}}const d=(t,e)=>function(s,r,i){if(s[t]()==e){const t=r.r8(i);i=s.pc+((128&t)>0?-(1+(255&~t)):t),s.cycles+=s.pageCrossedCycles(i),s.pc=65535&i}},w=t=>function(e,s,r){const i=e[t];let n=s.r8(r);e.carry(i>=n),n=i-n,e.sign(n),e.zero(n)},g=t=>function(e){const s=e[t]-1;e.sign(s),e.zero(s),e[t]=255&s},R=t=>function(e){const s=e[t]+1;e.sign(s),e.zero(s),e[t]=255&s},y=t=>function(e,s,r){const i=s.r8(r);e.sign(i),e.zero(i),e[t]=i};function A(t,e){const s=t.a+e+(t.carry()?1:0);t.zero(s),t.sign(s),t.overflow(~(t.a^e)&(t.a^s)&128),t.carry(s>255),t.a=255&s}const C=(t,e)=>function(s,r){let i=r.r16(s.operand);const n=i>>8,a=255&i;i=a+s[e]>255?((n&s[t])<<8)+a+s[e]:(n<<8)+a+s[e];const o=s[t]&n+1;r.w8(o,i)};function b(t,e){return t.carry(128&e),e=e<<1&255,t.sign(e),t.zero(e),e}function v(t,e){return t.carry(1&e),e>>=1,t.sign(e),t.zero(e),e}function O(t,e){return e<<=1,t.carry()&&(e|=1),t.carry(e>255),e&=255,t.sign(e),t.zero(e),e}function P(t,e){return t.carry()&&(e|=256),t.carry(1&e),e>>=1,t.sign(e),t.zero(e),e}const L=(t,e)=>function(s){const r=s[t];s.sign(r),s.zero(r),s[e]=r},x=(...t)=>function(e,s,r){for(let i=0;i<t.length;i++)t[i](e,s,r)};function S(t){throw new Error(`Invalid opcode: ${t.opcode.to(16)} at ${t.pc.to(16,2)}`)}const k=(t,e,s)=>A(t,e.r8(s));function D(t,e,s){const r=e.r8(s)&t.a;t.sign(r),t.zero(r),t.a=r}function N(t,e,s){10===t.opcode?t.a=b(t,t.a):e.w8(b(t,e.r8(s)),s)}const T=d("carry",!1),B=d("carry",!0),I=d("zero",!0);function E(t,e,s){const r=e.r8(s);t.sign(r),t.overflow(64&r),t.zero(r&t.a)}const X=d("sign",!0),z=d("zero",!1),M=d("sign",!1);const j=d("overflow",!1),F=d("overflow",!0);const U=w("a"),Y=w("x"),K=w("y");function q(t,e,s){const r=e.r8(s)-1;t.sign(r),t.zero(r),e.w8(r,s)}const H=g("x"),V=g("y");function W(t,e,s){const r=e.r8(s)^t.a;t.sign(r),t.zero(r),t.a=r}function J(t,e,s){const r=e.r8(s)+1;t.sign(r),t.zero(r),e.w8(r,s)}const $=R("x"),Q=R("y");function _(t,e,s){t.pc=s}const G=y("a"),Z=y("x"),tt=y("y");function et(t,e,s){74===t.opcode?t.a=v(t,t.a):e.w8(v(t,e.r8(s)),s)}function st(){}function rt(t,e,s){const r=e.r8(s)|t.a;t.sign(r),t.zero(r),t.a=r}function it(t,e,s){42===t.opcode?t.a=O(t,t.a):e.w8(O(t,e.r8(s)),s)}function nt(t,e,s){106===t.opcode?t.a=P(t,t.a):e.w8(P(t,e.r8(s)),s)}function at(t,e,s){A(t,255^e.r8(s))}function ot(t,e,s){e.w8(t.a,s)}function ht(t,e,s){e.w8(t.x,s)}function ct(t,e,s){e.w8(t.y,s)}const lt=L("a","x"),ut=L("a","y"),pt=L("sp","x"),mt=L("x","a");const ft=L("y","a");function dt(t,e,s){D(t,e,s),t.carry(t.sign())}function wt(t,e,s){e.w8(t.a&t.x,s)}function gt(t,e,s){e.w8(t.x&t.a&7,s)}const Rt=x(q,U),yt=x(J,at),At=S;const Ct=x(G,lt),bt=x(it,D),vt=x(nt,k),Ot=x(N,rt),Pt=x(et,W),Lt=C("x","y");const xt=[function(t){t.brk=!0},rt,At,Ot,st,rt,N,Ot,function(t){t.push8(48|t.stat)},rt,N,dt,st,rt,N,Ot,M,rt,At,Ot,st,rt,N,Ot,function(t){t.carry(!1)},rt,st,Ot,st,rt,N,Ot,function(t,e,s){t.push16(t.pc-1),t.pc=s},D,At,bt,E,D,it,bt,function(t){t.stat=207&t.pull8()},D,it,dt,E,D,it,bt,X,D,At,bt,st,D,it,bt,function(t){t.carry(!0)},D,st,bt,st,D,it,bt,function(t){t.stat=207&t.pull8(),t.pc=t.pull16()},W,At,Pt,st,W,et,Pt,function(t){t.push8(t.a)},W,et,function(t,e,s){D(t,e,s),t.a=v(t,t.a)},_,W,et,Pt,j,W,At,Pt,st,W,et,Pt,function(t){t.interrupt(!1)},W,st,Pt,st,W,et,Pt,function(t){t.pc=t.pull16()+1&65535},k,At,vt,st,k,nt,vt,function(t){const e=t.pull8();t.sign(e),t.zero(e),t.a=e},k,nt,function(t,e,s){let r=t.a&e.r8(s);t.carry()&&(r|=256),t.overflow(r>>7&1^r>>6&1),t.carry(128&r),r>>=1,t.zero(r),t.sign(r),t.a=r},_,k,nt,vt,F,k,At,vt,st,k,nt,vt,function(t){t.interrupt(!0)},k,st,vt,st,k,nt,vt,st,ot,st,wt,ct,ot,ht,wt,V,st,mt,S,ct,ot,ht,wt,T,ot,At,gt,ct,ot,ht,wt,ft,ot,function(t){t.sp=t.x},function(t,e,s){t.sp=t.x&t.a;let r=1+(e.r8(s)>>4);r&=t.sp,e.w8(r,s)},C("y","x"),ot,Lt,gt,tt,G,Z,Ct,tt,G,Z,Ct,ut,G,lt,Ct,tt,G,Z,Ct,B,G,At,Ct,tt,G,Z,Ct,function(t){t.overflow(!1)},G,pt,function(t,e,s){const r=t.sp&e.r8(s);t.sign(r),t.zero(r),t.a=t.x=t.sp=r},tt,G,Z,Ct,K,U,st,Rt,K,U,q,Rt,Q,U,H,function(t,e,s){const r=t.x&t.a;let i=e.r8(s);t.carry(r>=i),i=r-i,t.sign(i),t.zero(i),t.x=255&i},K,U,q,Rt,z,U,At,Rt,st,U,q,Rt,function(t){t.decimal(!1)},U,st,Rt,st,U,q,Rt,Y,at,st,yt,Y,at,J,yt,$,at,st,at,Y,at,J,yt,I,at,At,yt,st,at,J,yt,function(t){t.decimal(!0)},at,st,yt,st,at,J,yt],St=[6,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,1,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,6,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,6,7,6,7,11,11,11,11,6,5,4,5,8,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,13,13,6,3,6,3,2,2,3,3,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,13,13,6,3,6,3,2,2,3,3,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2],kt=[2,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,3,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,1,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,1,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3],Dt=[7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7],Nt=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0],Tt=["BRK","ORA","KIL","SLO","NOP","ORA","ASL","SLO","PHP","ORA","ASL","ANC","NOP","ORA","ASL","SLO","BPL","ORA","KIL","SLO","NOP","ORA","ASL","SLO","CLC","ORA","NOP","SLO","NOP","ORA","ASL","SLO","JSR","AND","KIL","RLA","BIT","AND","ROL","RLA","PLP","AND","ROL","ANC","BIT","AND","ROL","RLA","BMI","AND","KIL","RLA","NOP","AND","ROL","RLA","SEC","AND","NOP","RLA","NOP","AND","ROL","RLA","RTI","EOR","KIL","SRE","NOP","EOR","LSR","SRE","PHA","EOR","LSR","ALR","JMP","EOR","LSR","SRE","BVC","EOR","KIL","SRE","NOP","EOR","LSR","SRE","CLI","EOR","NOP","SRE","NOP","EOR","LSR","SRE","RTS","ADC","KIL","RRA","NOP","ADC","ROR","RRA","PLA","ADC","ROR","ARR","JMP","ADC","ROR","RRA","BVS","ADC","KIL","RRA","NOP","ADC","ROR","RRA","SEI","ADC","NOP","RRA","NOP","ADC","ROR","RRA","NOP","STA","NOP","SAX","STY","STA","STX","SAX","DEY","NOP","TXA","XAA","STY","STA","STX","SAX","BCC","STA","KIL","AHX","STY","STA","STX","SAX","TYA","STA","TXS","TAS","SHY","STA","SHX","AHX","LDY","LDA","LDX","LAX","LDY","LDA","LDX","LAX","TAY","LDA","TAX","LAX","LDY","LDA","LDX","LAX","BCS","LDA","KIL","LAX","LDY","LDA","LDX","LAX","CLV","LDA","TSX","LAS","LDY","LDA","LDX","LAX","CPY","CMP","NOP","DCP","CPY","CMP","DEC","DCP","INY","CMP","DEX","AXS","CPY","CMP","DEC","DCP","BNE","CMP","KIL","DCP","NOP","CMP","DEC","DCP","CLD","CMP","NOP","DCP","NOP","CMP","DEC","DCP","CPX","SBC","NOP","ISC","CPX","SBC","INC","ISC","INX","SBC","NOP","SBC","CPX","SBC","INC","ISC","BEQ","SBC","KIL","ISC","NOP","SBC","INC","ISC","SED","SBC","NOP","ISC","NOP","SBC","INC","ISC"],Bt=new Array(256).fill(null).map(((t,e)=>({execute:xt[e],mode:St[e],bytes:kt[e],cycles:Dt[e],branchCycles:Nt[e],mnemonic:Tt[e]}))),It=8192,Et=8193,Xt=8197,zt=16404;function Mt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const jt=()=>{},Ft=()=>{};class Ut{constructor(t){Mt(this,"nes",null),Mt(this,"ram",new Uint8Array(2048)),Mt(this,"apu",new Uint8Array(24)),this.nes=t,Object.seal(this)}r8(t){switch(jt("read at: %s",(t&=65535).to(16,2)),t>>12){case 0:case 1:return this.ram[2047&t];case 2:case 3:return this.nes.ppu.r8(t);default:if(t==zt)this.nes.ppu.r8(t);else{if(16406==t)return this.nes.controller.read();if(t<16408)return this.apu[31&t];if(t<16416)return 0}return this.nes.cart.r8(t)}throw new n(t)}w8(t,e){switch(jt("write at: %s, val: %s",(e&=65535).to(16,2),t.to(16)),e>>12){case 0:case 1:return void(this.ram[2047&e]=t);case 2:case 3:return void this.nes.ppu.w8(t,e);default:if(e==zt)return void this.nes.ppu.w8(t,e);if(16406==e)return void this.nes.controller.write(t);if(e<16408)return void(this.apu[31&e]=t);if(e<16416)return;return e<24580&&Ft("%s: %s",e.to(16),t.to(16)),void this.nes.cart.w8(t,e)}throw new n(e)}r16(t){return this.r8(t)|this.r8(++t)<<8}}function Yt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const Kt=()=>{},qt=()=>{},Ht=()=>{};class Vt{constructor(t){Yt(this,"mem",null),Yt(this,"a",0),Yt(this,"x",0),Yt(this,"y",0),Yt(this,"stat",0),Yt(this,"pc",0),Yt(this,"sp",0),Yt(this,"cycles",0),Yt(this,"haltCycles",0),Yt(this,"irq",!1),Yt(this,"nmi",!1),Yt(this,"brk",!1),Yt(this,"opcode",0),Yt(this,"operand",0),Yt(this,"branchCycles",0),this.mem=t,Object.seal(this)}push8(t){t&=255;const e=256|this.sp;Ht("push to: %s, val: %s",e.to(16,2),t.to(16)),this.mem.w8(t,e),this.sp=255&--this.sp}push16(t){this.push8(t>>8),this.push8(t)}pull8(){this.sp=255&++this.sp;const t=256|this.sp,e=this.mem.r8(t);return Ht("pull from: %s, val: %s",t.to(16,2),e.to(16)),e}pull16(){return this.pull8()|this.pull8()<<8}carry(t){return void 0!==t&&(t?this.stat|=1:this.stat&=-2),!!(1&this.stat)}zero(t){return void 0!==t&&(0==(255&t)?this.stat|=2:this.stat&=-3),!!(2&this.stat)}interrupt(t){return void 0!==t&&(t?this.stat|=4:this.stat&=-5),!!(4&this.stat)}decimal(t){return void 0!==t&&(t?this.stat|=8:this.stat&=-9),!!(8&this.stat)}overflow(t){return void 0!==t&&(t?this.stat|=64:this.stat&=-65),!!(64&this.stat)}sign(t){return void 0!==t&&((128&t)>0?this.stat|=128:this.stat&=-129),!!(128&this.stat)}reset(){const t=this.mem.r16(65532);Kt("reset addr: %s",t.to(16,2)),this.pc=t,this.sp=511}step(){return this.cycles=0,this.handleInterrupts(),0==this.haltCycles?(this.runCycle(),this.cycles):(this.haltCycles--,1)}handleInterrupts(){let t,e=this.stat;if(this.nmi)t=65530,e=-17&(32|e),this.nmi=!1;else if(this.irq&&!this.interrupt())t=65534,e=-17&(32|e),this.irq=!1,this.interrupt(!0);else{if(!this.brk)return;t=65534,e|=48,this.brk=!1,this.interrupt(!0)}this.push16(this.pc),this.push8(e),this.pc=this.mem.r16(t),this.cycles+=7,qt("pc: %s",this.pc.to(16))}pageCrossedCycles(t){return(65280&this.pc)!=(65280&t)?this.branchCycles:0}runCycle(){const t=this.mem.r8(this.pc),e=Bt[t];let s;this.opcode=t,this.operand=this.pc+1,this.branchCycles=e.branchCycles,Kt("pc: %s, op: %s[%s]",this.pc.to(16,2),this.opcode.to(16),e.mnemonic);let r=e.cycles;switch(e.mode){case 4:case 6:break;case 10:case 5:s=this.operand;break;case 1:s=this.mem.r16(this.operand);break;case 2:s=this.mem.r16(this.operand)+this.x,r+=this.pageCrossedCycles(s);break;case 3:s=this.mem.r16(this.operand)+this.y,r+=this.pageCrossedCycles(s);break;case 8:{const t=this.mem.r16(this.operand),e=65280&t|t+1&255;s=this.mem.r8(t)|this.mem.r8(e)<<8;break}case 7:{const t=this.mem.r8(this.operand)+this.x&255,e=t+1&255;s=this.mem.r8(t)|this.mem.r8(e)<<8;break}case 9:{const t=this.mem.r8(this.operand),e=t+1&255;s=(this.mem.r8(t)|this.mem.r8(e)<<8)+this.y,r+=this.pageCrossedCycles(s);break}case 11:s=this.mem.r8(this.operand);break;case 12:s=this.mem.r8(this.operand)+this.x&255;break;case 13:s=this.mem.r8(this.operand)+this.y&255;break;default:throw new Error("Unknown addressing mode")}this.pc=this.pc+e.bytes&65535,this.cycles+=r,e.execute(this,this.mem,s)}}function Wt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class Jt{constructor(t){Wt(this,"nes",null),Wt(this,"vram",[new Uint8Array(1024),new Uint8Array(1024),new Uint8Array(1024),new Uint8Array(1024)]),Wt(this,"palette",new Uint8Array(32)),this.nes=t,Object.seal(this)}r8(t){switch(t>>12){case 0:case 1:return this.nes.cart.r8(t);case 2:case 3:return t<16128?this.vram[t>>10&3][1023&t]:this.palette[31&t]}throw new n(t)}w8(t,e){switch(e>>12){case 0:case 1:{const s=e>>12&1;return this.nes.video.updatePattern(s,t,e),void this.nes.cart.w8(t,e)}case 2:case 3:if(e<16128){const s=e>>10&3;if((1023&e)<960){this.nes.video.tilemap[s][e>>5&31][31&e]=t}else{const r=this.nes.video.attribute[s][e>>3&7][7&e];for(let e=0;e<r.length;e++)r[e]=t>>(e<<1)&3}this.vram[s][1023&e]=t}else{const s=(3&e)-1;16128==e?this.nes.video.bkgPalette=t:s>-1&&(this.nes.video.palette[e>>2&7][s]=t),this.palette[31&e]=t}return}throw new n(e)}}function $t(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const Qt=()=>{};class _t{constructor(t){$t(this,"nes",null),$t(this,"mem",null),$t(this,"oam",new Uint8Array(256)),$t(this,"ctrl",0),$t(this,"mask",0),$t(this,"stat",0),$t(this,"scroll",[0,0]),$t(this,"scanline",241),$t(this,"cycles",0),$t(this,"resetCycles",0),$t(this,"resetIgnoreWrites",!0),$t(this,"writeCount",0),$t(this,"latch",0),$t(this,"oamAddr",0),$t(this,"vramAddr",0),$t(this,"renderFrame",!1),$t(this,"isOddFrame",!0),this.nes=t,this.mem=new Jt(t),Object.seal(this)}reset(){this.ctrl=0,this.mask=0,this.stat&=128,this.scroll=[0,0],this.cycles=0,this.scanline=0,this.resetCycles=0,this.resetIgnoreWrites=!0,this.writeCount=0,this.latch=0,this.vramAddr=0,this.renderFrame=!1,this.isOddFrame=!1}incrementVramAddress(){this.vramAddr+=0==(4&this.ctrl)?1:32,this.vramAddr&=16383}step(){this.resetIgnoreWrites&&(this.resetCycles++,this.resetCycles>29780&&(this.resetCycles=0,this.resetIgnoreWrites=!1)),1==this.cycles?241==this.scanline?(this.nes.cpu.nmi=(128&this.ctrl)>0,this.stat|=128):261==this.scanline&&(this.stat&=-225):339==this.cycles&&261==this.scanline&&this.isOddFrame&&24&this.mask&&this.cycles++,340==this.cycles&&(this.renderScanline(),this.isOddFrame=!this.isOddFrame,this.cycles=-1),this.cycles++}renderScanline(){this.scanline<240?this.nes.video.drawLine():261==this.scanline&&(this.renderFrame=!0,this.scanline=-1),this.scanline++}r8(t){switch(Qt("read at: %s",t.to(16,2)),8192|7&t){case 8194:{const t=this.stat;this.stat&=-129,this.writeCount=0,this.latch=224&t|31&this.latch;break}case 8196:this.latch=this.oam[this.oamAddr];break;case 8199:this.latch=this.mem.r8(this.vramAddr),this.incrementVramAddress()}return this.latch}w8(t,e){const s=61447&e;if(this.resetIgnoreWrites&&8197&s)Qt("write at: %s ignored",s.to(16,2));else{if(t&=255,Qt("write at: %s, val: %s",e.to(16,2),t.to(16)),this.latch=t,e!=zt){switch(s){case It:return void(this.ctrl=t);case Et:return void(this.mask=t);case 8195:return void(this.oamAddr=t);case 8196:{const e=this.oamAddr++;return this.nes.video.sprites[e>>2][3&e]=this.oam[e]=t,void(this.oamAddr&=255)}case Xt:return this.scroll[this.writeCount++]=t,void(this.writeCount&=1);case 8198:return 0===this.writeCount?this.vramAddr=t<<8:this.vramAddr|=t,this.vramAddr&=16383,this.writeCount++,void(this.writeCount&=1);case 8199:return this.mem.w8(t,this.vramAddr),void this.incrementVramAddress()}throw new n(e)}for(let e=0;e<256;e++){const s=this.nes.cpu.mem.r8(t<<8|e);this.nes.video.sprites[e>>2][3&e]=this.oam[e]=s}this.nes.cpu.haltCycles+=513}}}const Gt=[[124,124,124],[0,0,252],[0,0,188],[68,40,188],[148,0,132],[168,0,32],[168,16,0],[136,20,0],[80,48,0],[0,120,0],[0,104,0],[0,88,0],[0,64,88],[0,0,0],[0,0,0],[0,0,0],[188,188,188],[0,120,248],[0,88,248],[104,68,252],[216,0,204],[228,0,88],[248,56,0],[228,92,16],[172,124,0],[0,184,0],[0,168,0],[0,168,68],[0,136,136],[0,0,0],[0,0,0],[0,0,0],[248,248,248],[60,188,252],[104,136,252],[152,120,248],[248,120,248],[248,88,152],[248,120,88],[252,160,68],[248,184,0],[184,248,24],[88,216,84],[88,248,152],[0,232,216],[120,120,120],[0,0,0],[0,0,0],[252,252,252],[164,228,252],[184,184,248],[216,184,248],[248,184,248],[248,164,192],[240,208,176],[252,224,168],[248,216,120],[216,248,120],[184,248,184],[184,248,216],[0,252,252],[248,216,248],[0,0,0],[0,0,0]];function Zt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const te=()=>{},ee=256,se=240;class re{constructor(t,e){Zt(this,"nes",null),Zt(this,"onFrame",(()=>{})),Zt(this,"bkgPalette",0),Zt(this,"nametables",[]),Zt(this,"linePtrn",new Array(ee).fill(0)),Zt(this,"lineColor",new Array(ee)),Zt(this,"canvas",function(t,e){const s=document.createElement("canvas");return s.width=t,s.height=e,s}(ee,se)),Zt(this,"ctx",this.canvas.getContext("2d",{alpha:!1,pixelFormat:"RGB24"})),Zt(this,"image",this.ctx.getImageData(0,0,ee,se)),Zt(this,"data",this.image.data),Zt(this,"tilemap",new Array(4).fill().map((()=>new Array(30).fill().map((()=>new Uint8Array(32)))))),Zt(this,"attribute",new Array(4).fill().map((()=>new Array(8).fill().map((()=>new Array(8).fill().map((()=>new Array(4).fill(0)))))))),Zt(this,"pattern",new Array(2).fill().map((()=>new Array(256).fill().map((()=>new Array(8).fill().map((()=>new Uint8Array(8)))))))),Zt(this,"palette",new Array(8).fill().map((()=>new Array(3).fill(0)))),Zt(this,"sprites",new Array(64).fill().map((()=>new Uint8Array(4)))),this.nes=t,this.onFrame=e,this.ctx.patternQuality="fast",this.ctx.quality="fast",this.ctx.textDrawingMode="path",this.ctx.antialias="none",Object.seal(this)}updateNametableIndexes(t){this.nametables=8&t?[0,1,2,3]:1&t?[0,1,0,1]:[0,0,2,2]}updatePattern(t,e,s){const r=this.pattern[t][s>>4&255][7&s],i=s>>3&1;for(let t=0;t<r.length;t++){const s=7-t;i||(r[s]=0),r[s]|=(e>>t&1)<<i}}drawBackground(){let[t,e]=this.nes.ppu.scroll;const s=e+this.nes.ppu.scanline,r=7&s,i=(s>>3)%30,n=(16&this.nes.ppu.ctrl)>>4;let a=3&this.nes.ppu.ctrl;s>=se&&(a^=2);for(let e=(2&this.nes.ppu.mask)<<2^8;e<ee;e++){const s=t+e;let o=a;s>=ee&&(o=1^a);const h=this.nametables[o],c=s>>3&31,l=this.tilemap[h][i][c],u=this.pattern[n][l][r][7&s];if(this.linePtrn[e]=u,!u)continue;const p=this.attribute[h][i>>2][c>>2],m=this.palette[p[2&i|c>>1&1]][u-1];this.lineColor[e]=m}}drawSprites(){const t=this.pattern[(8&this.nes.ppu.ctrl)>>3];let e=[];for(let t=0;t<this.sprites.length;t++)this.nes.ppu.scanline>this.sprites[t][0]&&this.nes.ppu.scanline<=this.sprites[t][0]+8&&this.sprites[t][0]<239&&e.push(t);e.length>8&&(this.nes.ppu.stat|=32);const s=(this.nes.ppu.mask>>1&3^3)>0;for(let r=Math.min(8,e.length)-1;r>-1;r--){const i=this.sprites[e[r]],n=i[2]>>5&1,a=i[2]>>6&1,o=i[2]>>7,h=i[3],c=this.nes.ppu.scanline-i[0]-1,l=o?7-c:c;for(let o=h;o<h+8&&o<ee;o++){const c=a?7-(o-h):o-h,u=t[i[1]][l][c];if(!u)continue;const p=this.palette[4|3&i[2]][u-1];!e[r]&&p&&this.linePtrn[o]&&(o>7&&o<255||o<7&&!s)&&(this.nes.ppu.stat|=64),n&&this.linePtrn[o]||(this.lineColor[o]=p)}}}drawLine(){te("drawing scanline: %d",this.nes.ppu.scanline),this.linePtrn.fill(0),this.lineColor.fill(this.bkgPalette),8&this.nes.ppu.mask&&this.drawBackground(),16&this.nes.ppu.mask&&this.drawSprites();let t=this.nes.ppu.scanline*ee*4;for(let e=0;e<ee;e++)this.data[t++]=Gt[this.lineColor[e]][0],this.data[t++]=Gt[this.lineColor[e]][1],this.data[t++]=Gt[this.lineColor[e]][2],this.data[t++]=255}render(){this.ctx.clearRect(0,0,ee,se),this.ctx.putImageData(this.image,0,0),this.onFrame(this.canvas)}}function ie(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const ne={40:5,13:3,38:4,16:2,37:6,90:1,39:7,88:0};class ae{constructor(){ie(this,"state",new Array(8).fill(64)),ie(this,"strobe",0),ie(this,"bit",0),Object.seal(this)}write(t){this.strobe||(this.bit=0),this.strobe=1&t}read(){return this.bit>8?65:this.state[this.bit++]}keyDown(t){null!=ne[t]&&(this.state[ne[t]]=65)}keyUp(t){null!=ne[t]&&(this.state[ne[t]]=64)}}function oe(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const he=()=>{};class ce{constructor({onFrame:t}){oe(this,"video",null),oe(this,"cart",new f(this)),oe(this,"ppu",new _t(this)),oe(this,"cpu",new Vt(new Ut(this))),oe(this,"controller",new ae),oe(this,"loop",null),oe(this,"frameCycles",0),this.video=new re(this,t),Object.seal(this)}loadCart(t){he("loading cart"),this.cart.load(new Uint8Array(t)),this.video.updateNametableIndexes(this.cart.mirroring)}runFrame(){let t;t:for(;;)for(t=this.cpu.step(),this.frameCycles+=t,t*=3;t>0;t--)if(this.ppu.step(),this.ppu.renderFrame)break t;this.ppu.renderFrame=!1,this.video.render(),he("cycles: %d, pc: %s",this.frameCycles,this.cpu.pc.to(16)),this.frameCycles=0}reset(){he("reset"),i().cancel(this.loop),this.frameCycles=0,this.cart.loaded&&this.cpu.reset(),this.ppu.reset()}start(){this.reset();const t=()=>{this.runFrame(),this.loop=i()(t)};this.loop=i()(t)}}},593:()=>{"use strict";Number.prototype.to=function(){}},155:t=>{var e,s,r=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function a(t){if(e===setTimeout)return setTimeout(t,0);if((e===i||!e)&&setTimeout)return e=setTimeout,setTimeout(t,0);try{return e(t,0)}catch(s){try{return e.call(null,t,0)}catch(s){return e.call(this,t,0)}}}!function(){try{e="function"==typeof setTimeout?setTimeout:i}catch(t){e=i}try{s="function"==typeof clearTimeout?clearTimeout:n}catch(t){s=n}}();var o,h=[],c=!1,l=-1;function u(){c&&o&&(c=!1,o.length?h=o.concat(h):l=-1,h.length&&p())}function p(){if(!c){var t=a(u);c=!0;for(var e=h.length;e;){for(o=h,h=[];++l<e;)o&&o[l].run();l=-1,e=h.length}o=null,c=!1,function(t){if(s===clearTimeout)return clearTimeout(t);if((s===n||!s)&&clearTimeout)return s=clearTimeout,clearTimeout(t);try{s(t)}catch(e){try{return s.call(null,t)}catch(e){return s.call(this,t)}}}(t)}}function m(t,e){this.fun=t,this.array=e}function f(){}r.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var s=1;s<arguments.length;s++)e[s-1]=arguments[s];h.push(new m(t,e)),1!==h.length||c||a(p)},m.prototype.run=function(){this.fun.apply(null,this.array)},r.title="browser",r.browser=!0,r.env={},r.argv=[],r.version="",r.versions={},r.on=f,r.addListener=f,r.once=f,r.off=f,r.removeListener=f,r.removeAllListeners=f,r.emit=f,r.prependListener=f,r.prependOnceListener=f,r.listeners=function(t){return[]},r.binding=function(t){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(t){throw new Error("process.chdir is not supported")},r.umask=function(){return 0}},87:(t,e,s)=>{for(var r=s(407),i="undefined"==typeof window?s.g:window,n=["moz","webkit"],a="AnimationFrame",o=i["request"+a],h=i["cancel"+a]||i["cancelRequest"+a],c=0;!o&&c<n.length;c++)o=i[n[c]+"Request"+a],h=i[n[c]+"Cancel"+a]||i[n[c]+"CancelRequest"+a];if(!o||!h){var l=0,u=0,p=[];o=function(t){if(0===p.length){var e=r(),s=Math.max(0,16.666666666666668-(e-l));l=s+e,setTimeout((function(){var t=p.slice(0);p.length=0;for(var e=0;e<t.length;e++)if(!t[e].cancelled)try{t[e].callback(l)}catch(t){setTimeout((function(){throw t}),0)}}),Math.round(s))}return p.push({handle:++u,callback:t,cancelled:!1}),u},h=function(t){for(var e=0;e<p.length;e++)p[e].handle===t&&(p[e].cancelled=!0)}}t.exports=function(t){return o.call(i,t)},t.exports.cancel=function(){h.apply(i,arguments)},t.exports.polyfill=function(t){t||(t=i),t.requestAnimationFrame=o,t.cancelAnimationFrame=h}},407:function(t,e,s){var r=s(155);(function(){var e,s,i,n,a,o;"undefined"!=typeof performance&&null!==performance&&performance.now?t.exports=function(){return performance.now()}:null!=r&&r.hrtime?(t.exports=function(){return(e()-a)/1e6},s=r.hrtime,n=(e=function(){var t;return 1e9*(t=s())[0]+t[1]})(),o=1e9*r.uptime(),a=n-o):Date.now?(t.exports=function(){return Date.now()-i},i=Date.now()):(t.exports=function(){return(new Date).getTime()-i},i=(new Date).getTime())}).call(this)}},e={};function s(r){if(e[r])return e[r].exports;var i=e[r]={exports:{}};return t[r].call(i.exports,i,i.exports,s),i.exports}return s.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return s.d(e,{a:e}),e},s.d=(t,e)=>{for(var r in e)s.o(e,r)&&!s.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s(679)})().default; | ||
window.Nes=(()=>{var t={679:(t,e,s)=>{"use strict";s.d(e,{default:()=>ce});s(593);var r=s(87),i=s.n(r);class n extends Error{constructor(t){super(`${t.to(16,2)} is an unknown address`),this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}function a(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}function o(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const h=()=>{};function c(){throw new Error("Unknown mapper")}const l=new Array(255).fill(null).map((()=>c));l[0]=class{constructor({prgRom:t,prgRam:e,chrRxm:s}){a(this,"prgRom",null),a(this,"prgRam",null),a(this,"chrRxm",null),a(this,"prgRomLastPage",0),this.prgRom=t,this.prgRam=e,this.chrRxm=s,this.prgRomLastPage=t.length-1,Object.seal(this)}w8(t,e){if(e<8192){const s=e>>12&1;this.chrRxm[s][4095&e]=t}else{if(e<24576)throw new n(e);if(!(e<32768))throw new n(e);this.prgRam[8191&e]=t}}r8(t){if(t<8192){const e=t>>12&1;return this.chrRxm[e][4095&t]}if(t<24576)throw new n(t);return t<32768?this.prgRam[8191&t]:t<49152?this.prgRom[0][16383&t]:this.prgRom[this.prgRomLastPage][16383&t]}},l[1]=class{constructor({prgRom:t,prgRam:e,chrRxm:s}){o(this,"prgRom",null),o(this,"prgRam",null),o(this,"chrRxm",null),o(this,"prgRomLastPage",0),o(this,"prgRamEnable",!1),o(this,"shift",0),o(this,"shiftCount",0),o(this,"mirroring",0),o(this,"prgRomBankMode",0),o(this,"chrRxmBankMode",0),o(this,"chrRxmBank",[0,0]),o(this,"prgRomBank",0),this.prgRom=t,this.prgRam=e,this.chrRxm=s,this.prgRomLastPage=t.length-1,Object.seal(this)}shiftReset(){this.shift=0,this.shiftCount=0}shiftRight(t){this.shift>>=1,this.shift|=(1&t)<<4,this.shiftCount++}getChrRxmBank(t){return 0==this.chrRxmBankMode?0==t?254&this.chrRxmBank[0]:1|this.chrRxmBank[1]:this.chrRxmBank[t]}getPrgRomBank(t){const e=this.prgRomBankMode;return 0==e||1==e?0==t?254&this.prgRomBank:1|this.prgRomBank:2==e?0==t?0:this.prgRomBank:3==e?0==t?this.prgRomBank:this.prgRomLastPage:void 0}writeRegister(t){if(h("write register: %s, val: %s",(t>>12).to(16),this.shift.to(2)),t<40960)h("set control: %s",this.shift.to(2)),this.mirroring=3&this.shift,this.prgRomBankMode=this.shift>>2&3,this.chrRxmBankMode=this.shift>>4&1;else if(t<57344){const e=t>>14&1;this.chrRxmBank[e]=31&this.shift,h("set bank chr-rxm[%d]: %d",e,this.shift)}else this.prgRamEnable=0==(16&this.shift),this.prgRomBank=15&this.shift,h("set bank prg-rom: %d",this.prgRomBank),h("prg-ram enable",this.prgRamEnable)}w8(t,e){if(e<8192){const s=this.getChrRxmBank(e>>12&1);this.chrRxm[s][4095&e]=t}else{if(e<24576)return;e<32768?this.prgRamEnable&&(this.prgRam[8191&e]=t):128&t?(h("reset control"),this.prgRomBankMode=3,this.shiftReset()):this.shiftCount<4?this.shiftRight(t):(this.shiftRight(t),this.writeRegister(e),this.shiftReset())}}r8(t){if(t<8192){const e=this.getChrRxmBank(t>>12&1);return this.chrRxm[e][4095&t]}if(t<24576)return 0;if(t<32768)return this.prgRam[8191&t];{const e=this.getPrgRomBank(t>>14&1);return this.prgRom[e][16383&t]}}};const u=l;function p(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const m=()=>{};class f{constructor(t){p(this,"nes",null),p(this,"prgRam",new Uint8Array(8192)),p(this,"prgRom",null),p(this,"chrRxm",null),p(this,"mapper",null),p(this,"mirroring",0),p(this,"loaded",!1),Object.seal(this),this.nes=t}static createMemory({data:t,pages:e,size:s}){return new Array(e).fill(null).map(((e,r)=>{const i=r*s,n=new Uint8Array(s);return n.set(t.slice(i,i+s)),n}))}static isInesFormat1(t){const e=2==(t[7]>>2&3);return 78===t[0]&&69===t[1]&&83===t[2]&&26===t[3]&&!e}load(t){f.isInesFormat1(t),t[6];const e=t[4],s=t[5],r=t[6]>>4|240&t[7],i=u[r];m("mapper index: %d, uses: %s",r,i.name),m("prg-rom 16kb size units: %d",e),m("chr-rxm 8kb size units: %d",s),m("mirroring: %d",9&t[6]),m("rom control byte #1: %s",t[6].to(2)),m("rom control byte #2: %s",t[7].to(2)),this.prgRom=f.createMemory({data:t.slice(16),pages:e,size:16384});let n=new Array(8192);s>0&&(n=t.slice(16+16384*e)),this.chrRxm=f.createMemory({data:n,pages:(s||1)<<1,size:4096}),this.chrRxm.forEach(((t,e)=>{t.forEach(((t,s)=>this.nes.video.updatePattern(e,t,s)))})),this.mapper=new i({prgRom:this.prgRom,prgRam:this.prgRam,chrRxm:this.chrRxm}),this.mirroring=9&t[6],this.loaded=!0}r8(t){return this.loaded,this.mapper.r8(t)}w8(t,e){return this.loaded,this.mapper.w8(t,e)}}const d=(t,e)=>function(s,r,i){if(s[t]()==e){const t=r.r8(i);i=s.pc+((128&t)>0?-(1+(255&~t)):t),s.cycles+=s.pageCrossedCycles(i),s.pc=65535&i}},w=t=>function(e,s,r){const i=e[t];let n=s.r8(r);e.carry(i>=n),n=i-n,e.sign(n),e.zero(n)},g=t=>function(e){const s=e[t]-1;e.sign(s),e.zero(s),e[t]=255&s},R=t=>function(e){const s=e[t]+1;e.sign(s),e.zero(s),e[t]=255&s},y=t=>function(e,s,r){const i=s.r8(r);e.sign(i),e.zero(i),e[t]=i};function A(t,e){const s=t.a+e+(t.carry()?1:0);t.zero(s),t.sign(s),t.overflow(~(t.a^e)&(t.a^s)&128),t.carry(s>255),t.a=255&s}const C=(t,e)=>function(s,r){let i=r.r16(s.operand);const n=i>>8,a=255&i;i=a+s[e]>255?((n&s[t])<<8)+a+s[e]:(n<<8)+a+s[e];const o=s[t]&n+1;r.w8(o,i)};function b(t,e){return t.carry(128&e),e=e<<1&255,t.sign(e),t.zero(e),e}function v(t,e){return t.carry(1&e),e>>=1,t.sign(e),t.zero(e),e}function O(t,e){return e<<=1,t.carry()&&(e|=1),t.carry(e>255),e&=255,t.sign(e),t.zero(e),e}function P(t,e){return t.carry()&&(e|=256),t.carry(1&e),e>>=1,t.sign(e),t.zero(e),e}const L=(t,e)=>function(s){const r=s[t];s.sign(r),s.zero(r),s[e]=r},x=(...t)=>function(e,s,r){for(let i=0;i<t.length;i++)t[i](e,s,r)};function S(t){throw new Error(`Invalid opcode: ${t.opcode.to(16)} at ${t.pc.to(16,2)}`)}const k=(t,e,s)=>A(t,e.r8(s));function D(t,e,s){const r=e.r8(s)&t.a;t.sign(r),t.zero(r),t.a=r}function N(t,e,s){10===t.opcode?t.a=b(t,t.a):e.w8(b(t,e.r8(s)),s)}const T=d("carry",!1),B=d("carry",!0),I=d("zero",!0);function E(t,e,s){const r=e.r8(s);t.sign(r),t.overflow(64&r),t.zero(r&t.a)}const X=d("sign",!0),z=d("zero",!1),M=d("sign",!1);const j=d("overflow",!1),F=d("overflow",!0);const U=w("a"),Y=w("x"),K=w("y");function q(t,e,s){const r=e.r8(s)-1;t.sign(r),t.zero(r),e.w8(r,s)}const H=g("x"),V=g("y");function W(t,e,s){const r=e.r8(s)^t.a;t.sign(r),t.zero(r),t.a=r}function J(t,e,s){const r=e.r8(s)+1;t.sign(r),t.zero(r),e.w8(r,s)}const $=R("x"),Q=R("y");function _(t,e,s){t.pc=s}const G=y("a"),Z=y("x"),tt=y("y");function et(t,e,s){74===t.opcode?t.a=v(t,t.a):e.w8(v(t,e.r8(s)),s)}function st(){}function rt(t,e,s){const r=e.r8(s)|t.a;t.sign(r),t.zero(r),t.a=r}function it(t,e,s){42===t.opcode?t.a=O(t,t.a):e.w8(O(t,e.r8(s)),s)}function nt(t,e,s){106===t.opcode?t.a=P(t,t.a):e.w8(P(t,e.r8(s)),s)}function at(t,e,s){A(t,255^e.r8(s))}function ot(t,e,s){e.w8(t.a,s)}function ht(t,e,s){e.w8(t.x,s)}function ct(t,e,s){e.w8(t.y,s)}const lt=L("a","x"),ut=L("a","y"),pt=L("sp","x"),mt=L("x","a");const ft=L("y","a");function dt(t,e,s){D(t,e,s),t.carry(t.sign())}function wt(t,e,s){e.w8(t.a&t.x,s)}function gt(t,e,s){e.w8(t.x&t.a&7,s)}const Rt=x(q,U),yt=x(J,at),At=S;const Ct=x(G,lt),bt=x(it,D),vt=x(nt,k),Ot=x(N,rt),Pt=x(et,W),Lt=C("x","y");const xt=[function(t){t.brk=!0},rt,At,Ot,st,rt,N,Ot,function(t){t.push8(48|t.stat)},rt,N,dt,st,rt,N,Ot,M,rt,At,Ot,st,rt,N,Ot,function(t){t.carry(!1)},rt,st,Ot,st,rt,N,Ot,function(t,e,s){t.push16(t.pc-1),t.pc=s},D,At,bt,E,D,it,bt,function(t){t.stat=207&t.pull8()},D,it,dt,E,D,it,bt,X,D,At,bt,st,D,it,bt,function(t){t.carry(!0)},D,st,bt,st,D,it,bt,function(t){t.stat=207&t.pull8(),t.pc=t.pull16()},W,At,Pt,st,W,et,Pt,function(t){t.push8(t.a)},W,et,function(t,e,s){D(t,e,s),t.a=v(t,t.a)},_,W,et,Pt,j,W,At,Pt,st,W,et,Pt,function(t){t.interrupt(!1)},W,st,Pt,st,W,et,Pt,function(t){t.pc=t.pull16()+1&65535},k,At,vt,st,k,nt,vt,function(t){const e=t.pull8();t.sign(e),t.zero(e),t.a=e},k,nt,function(t,e,s){let r=t.a&e.r8(s);t.carry()&&(r|=256),t.overflow(r>>7&1^r>>6&1),t.carry(128&r),r>>=1,t.zero(r),t.sign(r),t.a=r},_,k,nt,vt,F,k,At,vt,st,k,nt,vt,function(t){t.interrupt(!0)},k,st,vt,st,k,nt,vt,st,ot,st,wt,ct,ot,ht,wt,V,st,mt,S,ct,ot,ht,wt,T,ot,At,gt,ct,ot,ht,wt,ft,ot,function(t){t.sp=t.x},function(t,e,s){t.sp=t.x&t.a;let r=1+(e.r8(s)>>4);r&=t.sp,e.w8(r,s)},C("y","x"),ot,Lt,gt,tt,G,Z,Ct,tt,G,Z,Ct,ut,G,lt,Ct,tt,G,Z,Ct,B,G,At,Ct,tt,G,Z,Ct,function(t){t.overflow(!1)},G,pt,function(t,e,s){const r=t.sp&e.r8(s);t.sign(r),t.zero(r),t.a=t.x=t.sp=r},tt,G,Z,Ct,K,U,st,Rt,K,U,q,Rt,Q,U,H,function(t,e,s){const r=t.x&t.a;let i=e.r8(s);t.carry(r>=i),i=r-i,t.sign(i),t.zero(i),t.x=255&i},K,U,q,Rt,z,U,At,Rt,st,U,q,Rt,function(t){t.decimal(!1)},U,st,Rt,st,U,q,Rt,Y,at,st,yt,Y,at,J,yt,$,at,st,at,Y,at,J,yt,I,at,At,yt,st,at,J,yt,function(t){t.decimal(!0)},at,st,yt,st,at,J,yt],St=[6,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,1,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,6,7,6,7,11,11,11,11,6,5,4,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,6,7,6,7,11,11,11,11,6,5,4,5,8,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,13,13,6,3,6,3,2,2,3,3,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,13,13,6,3,6,3,2,2,3,3,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2,5,7,5,7,11,11,11,11,6,5,6,5,1,1,1,1,10,9,6,9,12,12,12,12,6,3,6,3,2,2,2,2],kt=[2,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,3,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,1,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,1,2,1,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3,2,2,2,2,2,2,2,2,1,2,1,2,3,3,3,3,2,2,1,2,2,2,2,2,1,3,1,3,3,3,3,3],Dt=[7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7],Nt=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,0,0],Tt=["BRK","ORA","KIL","SLO","NOP","ORA","ASL","SLO","PHP","ORA","ASL","ANC","NOP","ORA","ASL","SLO","BPL","ORA","KIL","SLO","NOP","ORA","ASL","SLO","CLC","ORA","NOP","SLO","NOP","ORA","ASL","SLO","JSR","AND","KIL","RLA","BIT","AND","ROL","RLA","PLP","AND","ROL","ANC","BIT","AND","ROL","RLA","BMI","AND","KIL","RLA","NOP","AND","ROL","RLA","SEC","AND","NOP","RLA","NOP","AND","ROL","RLA","RTI","EOR","KIL","SRE","NOP","EOR","LSR","SRE","PHA","EOR","LSR","ALR","JMP","EOR","LSR","SRE","BVC","EOR","KIL","SRE","NOP","EOR","LSR","SRE","CLI","EOR","NOP","SRE","NOP","EOR","LSR","SRE","RTS","ADC","KIL","RRA","NOP","ADC","ROR","RRA","PLA","ADC","ROR","ARR","JMP","ADC","ROR","RRA","BVS","ADC","KIL","RRA","NOP","ADC","ROR","RRA","SEI","ADC","NOP","RRA","NOP","ADC","ROR","RRA","NOP","STA","NOP","SAX","STY","STA","STX","SAX","DEY","NOP","TXA","XAA","STY","STA","STX","SAX","BCC","STA","KIL","AHX","STY","STA","STX","SAX","TYA","STA","TXS","TAS","SHY","STA","SHX","AHX","LDY","LDA","LDX","LAX","LDY","LDA","LDX","LAX","TAY","LDA","TAX","LAX","LDY","LDA","LDX","LAX","BCS","LDA","KIL","LAX","LDY","LDA","LDX","LAX","CLV","LDA","TSX","LAS","LDY","LDA","LDX","LAX","CPY","CMP","NOP","DCP","CPY","CMP","DEC","DCP","INY","CMP","DEX","AXS","CPY","CMP","DEC","DCP","BNE","CMP","KIL","DCP","NOP","CMP","DEC","DCP","CLD","CMP","NOP","DCP","NOP","CMP","DEC","DCP","CPX","SBC","NOP","ISC","CPX","SBC","INC","ISC","INX","SBC","NOP","SBC","CPX","SBC","INC","ISC","BEQ","SBC","KIL","ISC","NOP","SBC","INC","ISC","SED","SBC","NOP","ISC","NOP","SBC","INC","ISC"],Bt=new Array(256).fill(null).map(((t,e)=>({execute:xt[e],mode:St[e],bytes:kt[e],cycles:Dt[e],branchCycles:Nt[e],mnemonic:Tt[e]}))),It=8192,Et=8193,Xt=8197,zt=16404;function Mt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const jt=()=>{},Ft=()=>{};class Ut{constructor(t){Mt(this,"nes",null),Mt(this,"ram",new Uint8Array(2048)),Mt(this,"apu",new Uint8Array(24)),this.nes=t,Object.seal(this)}r8(t){switch(jt("read at: %s",(t&=65535).to(16,2)),t>>12){case 0:case 1:return this.ram[2047&t];case 2:case 3:return this.nes.ppu.r8(t);default:if(t==zt)this.nes.ppu.r8(t);else{if(16406==t)return this.nes.controller.read();if(t<16408)return this.apu[31&t];if(t<16416)return 0}return this.nes.cart.r8(t)}throw new n(t)}w8(t,e){switch(jt("write at: %s, val: %s",(e&=65535).to(16,2),t.to(16)),e>>12){case 0:case 1:return void(this.ram[2047&e]=t);case 2:case 3:return void this.nes.ppu.w8(t,e);default:if(e==zt)return void this.nes.ppu.w8(t,e);if(16406==e)return void this.nes.controller.write(t);if(e<16408)return void(this.apu[31&e]=t);if(e<16416)return;return e<24580&&Ft("%s: %s",e.to(16),t.to(16)),void this.nes.cart.w8(t,e)}throw new n(e)}r16(t){return this.r8(t)|this.r8(++t)<<8}}function Yt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const Kt=()=>{},qt=()=>{},Ht=()=>{};class Vt{constructor(t){Yt(this,"mem",null),Yt(this,"a",0),Yt(this,"x",0),Yt(this,"y",0),Yt(this,"stat",0),Yt(this,"pc",0),Yt(this,"sp",0),Yt(this,"cycles",0),Yt(this,"haltCycles",0),Yt(this,"irq",!1),Yt(this,"nmi",!1),Yt(this,"brk",!1),Yt(this,"opcode",0),Yt(this,"operand",0),Yt(this,"branchCycles",0),this.mem=t,Object.seal(this)}push8(t){t&=255;const e=256|this.sp;Ht("push to: %s, val: %s",e.to(16,2),t.to(16)),this.mem.w8(t,e),this.sp=255&--this.sp}push16(t){this.push8(t>>8),this.push8(t)}pull8(){this.sp=255&++this.sp;const t=256|this.sp,e=this.mem.r8(t);return Ht("pull from: %s, val: %s",t.to(16,2),e.to(16)),e}pull16(){return this.pull8()|this.pull8()<<8}carry(t){return void 0!==t&&(t?this.stat|=1:this.stat&=-2),!!(1&this.stat)}zero(t){return void 0!==t&&(0==(255&t)?this.stat|=2:this.stat&=-3),!!(2&this.stat)}interrupt(t){return void 0!==t&&(t?this.stat|=4:this.stat&=-5),!!(4&this.stat)}decimal(t){return void 0!==t&&(t?this.stat|=8:this.stat&=-9),!!(8&this.stat)}overflow(t){return void 0!==t&&(t?this.stat|=64:this.stat&=-65),!!(64&this.stat)}sign(t){return void 0!==t&&((128&t)>0?this.stat|=128:this.stat&=-129),!!(128&this.stat)}reset(){const t=this.mem.r16(65532);Kt("reset addr: %s",t.to(16,2)),this.pc=t,this.sp=511}step(){return this.cycles=0,this.handleInterrupts(),0==this.haltCycles?(this.runCycle(),this.cycles):(this.haltCycles--,1)}handleInterrupts(){let t,e=this.stat;if(this.nmi)t=65530,e=-17&(32|e),this.nmi=!1;else if(this.irq&&!this.interrupt())t=65534,e=-17&(32|e),this.irq=!1,this.interrupt(!0);else{if(!this.brk)return;t=65534,e|=48,this.brk=!1,this.interrupt(!0)}this.push16(this.pc),this.push8(e),this.pc=this.mem.r16(t),this.cycles+=7,qt("pc: %s",this.pc.to(16))}pageCrossedCycles(t){return(65280&this.pc)!=(65280&t)?this.branchCycles:0}runCycle(){const t=this.mem.r8(this.pc),e=Bt[t];let s;this.opcode=t,this.operand=this.pc+1,this.branchCycles=e.branchCycles,Kt("pc: %s, op: %s[%s]",this.pc.to(16,2),this.opcode.to(16),e.mnemonic);let r=e.cycles;switch(e.mode){case 4:case 6:break;case 10:case 5:s=this.operand;break;case 1:s=this.mem.r16(this.operand);break;case 2:s=this.mem.r16(this.operand)+this.x,r+=this.pageCrossedCycles(s);break;case 3:s=this.mem.r16(this.operand)+this.y,r+=this.pageCrossedCycles(s);break;case 8:{const t=this.mem.r16(this.operand),e=65280&t|t+1&255;s=this.mem.r8(t)|this.mem.r8(e)<<8;break}case 7:{const t=this.mem.r8(this.operand)+this.x&255,e=t+1&255;s=this.mem.r8(t)|this.mem.r8(e)<<8;break}case 9:{const t=this.mem.r8(this.operand),e=t+1&255;s=(this.mem.r8(t)|this.mem.r8(e)<<8)+this.y,r+=this.pageCrossedCycles(s);break}case 11:s=this.mem.r8(this.operand);break;case 12:s=this.mem.r8(this.operand)+this.x&255;break;case 13:s=this.mem.r8(this.operand)+this.y&255;break;default:throw new Error("Unknown addressing mode")}this.pc=this.pc+e.bytes&65535,this.cycles+=r,e.execute(this,this.mem,s)}}function Wt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}class Jt{constructor(t){Wt(this,"nes",null),Wt(this,"vram",[new Uint8Array(1024),new Uint8Array(1024),new Uint8Array(1024),new Uint8Array(1024)]),Wt(this,"palette",new Uint8Array(32)),this.nes=t,Object.seal(this)}r8(t){switch(t>>12){case 0:case 1:return this.nes.cart.r8(t);case 2:case 3:return t<16128?this.vram[t>>10&3][1023&t]:this.palette[31&t]}throw new n(t)}w8(t,e){switch(e>>12){case 0:case 1:{const s=e>>12&1;return this.nes.video.updatePattern(s,t,e),void this.nes.cart.w8(t,e)}case 2:case 3:if(e<16128){const s=e>>10&3;if((1023&e)<960){this.nes.video.tilemap[s][e>>5&31][31&e]=t}else{const r=this.nes.video.attribute[s][e>>3&7][7&e];for(let e=0;e<r.length;e++)r[e]=t>>(e<<1)&3}this.vram[s][1023&e]=t}else{const s=(3&e)-1;16128==e?this.nes.video.bkgPalette=t:s>-1&&(this.nes.video.palette[e>>2&7][s]=t),this.palette[31&e]=t}return}throw new n(e)}}function $t(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const Qt=()=>{};class _t{constructor(t){$t(this,"nes",null),$t(this,"mem",null),$t(this,"oam",new Uint8Array(256)),$t(this,"ctrl",0),$t(this,"mask",0),$t(this,"stat",0),$t(this,"scroll",[0,0]),$t(this,"scanline",241),$t(this,"cycles",0),$t(this,"resetCycles",0),$t(this,"resetIgnoreWrites",!0),$t(this,"writeCount",0),$t(this,"latch",0),$t(this,"oamAddr",0),$t(this,"vramAddr",0),$t(this,"renderFrame",!1),$t(this,"isOddFrame",!0),this.nes=t,this.mem=new Jt(t),Object.seal(this)}reset(){this.ctrl=0,this.mask=0,this.stat&=128,this.scroll=[0,0],this.cycles=0,this.scanline=0,this.resetCycles=0,this.resetIgnoreWrites=!0,this.writeCount=0,this.latch=0,this.vramAddr=0,this.renderFrame=!1,this.isOddFrame=!1}incrementVramAddress(){this.vramAddr+=0==(4&this.ctrl)?1:32,this.vramAddr&=16383}step(){this.resetIgnoreWrites&&(this.resetCycles++,this.resetCycles>29780&&(this.resetCycles=0,this.resetIgnoreWrites=!1)),1==this.cycles?241==this.scanline?(this.nes.cpu.nmi=(128&this.ctrl)>0,this.stat|=128):261==this.scanline&&(this.stat&=-225):339==this.cycles&&261==this.scanline&&this.isOddFrame&&24&this.mask&&this.cycles++,340==this.cycles&&(this.renderScanline(),this.isOddFrame=!this.isOddFrame,this.cycles=-1),this.cycles++}renderScanline(){this.scanline<240?this.nes.video.drawLine():261==this.scanline&&(this.renderFrame=!0,this.scanline=-1),this.scanline++}r8(t){switch(Qt("read at: %s",t.to(16,2)),8192|7&t){case 8194:{const t=this.stat;this.stat&=-129,this.writeCount=0,this.latch=224&t|31&this.latch;break}case 8196:this.latch=this.oam[this.oamAddr];break;case 8199:this.latch=this.mem.r8(this.vramAddr),this.incrementVramAddress()}return this.latch}w8(t,e){const s=61447&e;if(this.resetIgnoreWrites&&8197&s)Qt("write at: %s ignored",s.to(16,2));else{if(t&=255,Qt("write at: %s, val: %s",e.to(16,2),t.to(16)),this.latch=t,e!=zt){switch(s){case It:return void(this.ctrl=t);case Et:return void(this.mask=t);case 8195:return void(this.oamAddr=t);case 8196:{const e=this.oamAddr++;return this.nes.video.sprites[e>>2][3&e]=this.oam[e]=t,void(this.oamAddr&=255)}case Xt:return this.scroll[this.writeCount++]=t,void(this.writeCount&=1);case 8198:return 0===this.writeCount?this.vramAddr=t<<8:this.vramAddr|=t,this.vramAddr&=16383,this.writeCount++,void(this.writeCount&=1);case 8199:return this.mem.w8(t,this.vramAddr),void this.incrementVramAddress()}throw new n(e)}for(let e=0;e<256;e++){const s=this.nes.cpu.mem.r8(t<<8|e);this.nes.video.sprites[e>>2][3&e]=this.oam[e]=s}this.nes.cpu.haltCycles+=513}}}const Gt=[[124,124,124],[0,0,252],[0,0,188],[68,40,188],[148,0,132],[168,0,32],[168,16,0],[136,20,0],[80,48,0],[0,120,0],[0,104,0],[0,88,0],[0,64,88],[0,0,0],[0,0,0],[0,0,0],[188,188,188],[0,120,248],[0,88,248],[104,68,252],[216,0,204],[228,0,88],[248,56,0],[228,92,16],[172,124,0],[0,184,0],[0,168,0],[0,168,68],[0,136,136],[0,0,0],[0,0,0],[0,0,0],[248,248,248],[60,188,252],[104,136,252],[152,120,248],[248,120,248],[248,88,152],[248,120,88],[252,160,68],[248,184,0],[184,248,24],[88,216,84],[88,248,152],[0,232,216],[120,120,120],[0,0,0],[0,0,0],[252,252,252],[164,228,252],[184,184,248],[216,184,248],[248,184,248],[248,164,192],[240,208,176],[252,224,168],[248,216,120],[216,248,120],[184,248,184],[184,248,216],[0,252,252],[248,216,248],[0,0,0],[0,0,0]];function Zt(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const te=()=>{},ee=256,se=240;class re{constructor(t,e){Zt(this,"nes",null),Zt(this,"onFrame",(()=>{})),Zt(this,"bkgPalette",0),Zt(this,"nametables",[]),Zt(this,"linePtrn",new Array(ee).fill(0)),Zt(this,"lineColor",new Array(ee)),Zt(this,"canvas",function(t,e){const s=document.createElement("canvas");return s.width=t,s.height=e,s}(ee,se)),Zt(this,"ctx",this.canvas.getContext("2d",{alpha:!1,pixelFormat:"RGB24"})),Zt(this,"image",this.ctx.getImageData(0,0,ee,se)),Zt(this,"data",this.image.data),Zt(this,"tilemap",new Array(4).fill().map((()=>new Array(30).fill().map((()=>new Uint8Array(32)))))),Zt(this,"attribute",new Array(4).fill().map((()=>new Array(8).fill().map((()=>new Array(8).fill().map((()=>new Array(4).fill(0)))))))),Zt(this,"pattern",new Array(2).fill().map((()=>new Array(256).fill().map((()=>new Array(8).fill().map((()=>new Uint8Array(8)))))))),Zt(this,"palette",new Array(8).fill().map((()=>new Array(3).fill(0)))),Zt(this,"sprites",new Array(64).fill().map((()=>new Uint8Array(4)))),this.nes=t,this.onFrame=e,this.ctx.patternQuality="fast",this.ctx.quality="fast",this.ctx.antialias="none",Object.seal(this)}updateNametableIndexes(t){this.nametables=8&t?[0,1,2,3]:1&t?[0,1,0,1]:[0,0,2,2]}updatePattern(t,e,s){const r=this.pattern[t][s>>4&255][7&s],i=s>>3&1;for(let t=0;t<r.length;t++){const s=7-t;i||(r[s]=0),r[s]|=(e>>t&1)<<i}}drawBackground(){const[t,e]=this.nes.ppu.scroll,s=e+this.nes.ppu.scanline,r=7&s,i=(s>>3)%30,n=(16&this.nes.ppu.ctrl)>>4;let a=3&this.nes.ppu.ctrl;s>=se&&(a^=2);for(let e=(2&this.nes.ppu.mask)<<2^8;e<ee;e++){const s=t+e;let o=a;s>=ee&&(o=1^a);const h=this.nametables[o],c=s>>3&31,l=this.tilemap[h][i][c],u=this.pattern[n][l][r][7&s];if(this.linePtrn[e]=u,!u)continue;const p=this.attribute[h][i>>2][c>>2],m=this.palette[p[2&i|c>>1&1]][u-1];this.lineColor[e]=m}}drawSprites(){const t=this.pattern[(8&this.nes.ppu.ctrl)>>3];let e=[];for(let t=0;t<this.sprites.length;t++)this.nes.ppu.scanline>this.sprites[t][0]&&this.nes.ppu.scanline<=this.sprites[t][0]+8&&this.sprites[t][0]<239&&e.push(t);e.length>8&&(this.nes.ppu.stat|=32);const s=(this.nes.ppu.mask>>1&3^3)>0;for(let r=Math.min(8,e.length)-1;r>-1;r--){const i=this.sprites[e[r]],n=i[2]>>5&1,a=i[2]>>6&1,o=i[2]>>7,h=i[3],c=this.nes.ppu.scanline-i[0]-1,l=o?7-c:c;for(let o=h;o<h+8&&o<ee;o++){const c=a?7-(o-h):o-h,u=t[i[1]][l][c];if(!u)continue;const p=this.palette[4|3&i[2]][u-1];!e[r]&&p&&this.linePtrn[o]&&(o>7&&o<255||o<7&&!s)&&(this.nes.ppu.stat|=64),n&&this.linePtrn[o]||(this.lineColor[o]=p)}}}drawLine(){te("drawing scanline: %d",this.nes.ppu.scanline),this.linePtrn.fill(0),this.lineColor.fill(this.bkgPalette),8&this.nes.ppu.mask&&this.drawBackground(),16&this.nes.ppu.mask&&this.drawSprites();let t=this.nes.ppu.scanline*ee*4;for(let e=0;e<ee;e++)this.data[t++]=Gt[this.lineColor[e]][0],this.data[t++]=Gt[this.lineColor[e]][1],this.data[t++]=Gt[this.lineColor[e]][2],this.data[t++]=255}render(){this.ctx.clearRect(0,0,ee,se),this.ctx.putImageData(this.image,0,0),this.onFrame(this.canvas)}}function ie(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const ne={40:5,13:3,38:4,16:2,37:6,90:1,39:7,88:0};class ae{constructor(){ie(this,"state",new Array(8).fill(64)),ie(this,"strobe",0),ie(this,"bit",0),Object.seal(this)}write(t){this.strobe||(this.bit=0),this.strobe=1&t}read(){return this.bit>8?65:this.state[this.bit++]}keyDown(t){null!=ne[t]&&(this.state[ne[t]]=65)}keyUp(t){null!=ne[t]&&(this.state[ne[t]]=64)}}function oe(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}const he=()=>{};class ce{constructor({onFrame:t}){oe(this,"video",null),oe(this,"cart",new f(this)),oe(this,"ppu",new _t(this)),oe(this,"cpu",new Vt(new Ut(this))),oe(this,"controller",new ae),oe(this,"loop",null),oe(this,"frameCycles",0),this.video=new re(this,t),Object.seal(this)}loadCart(t){he("loading cart"),this.cart.load(new Uint8Array(t)),this.video.updateNametableIndexes(this.cart.mirroring)}runFrame(){let t;t:for(;;)for(t=this.cpu.step(),this.frameCycles+=t,t*=4;t>0;t--)if(this.ppu.step(),this.ppu.renderFrame)break t;this.ppu.renderFrame=!1,this.video.render(),he("cycles: %d, pc: %s",this.frameCycles,this.cpu.pc.to(16)),this.frameCycles=0}reset(){he("reset"),i().cancel(this.loop),this.frameCycles=0,this.cart.loaded&&this.cpu.reset(),this.ppu.reset()}start(){this.reset();const t=()=>{this.runFrame(),this.loop=i()(t)};this.loop=i()(t)}}},593:()=>{"use strict";Number.prototype.to=function(){}},155:t=>{var e,s,r=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function a(t){if(e===setTimeout)return setTimeout(t,0);if((e===i||!e)&&setTimeout)return e=setTimeout,setTimeout(t,0);try{return e(t,0)}catch(s){try{return e.call(null,t,0)}catch(s){return e.call(this,t,0)}}}!function(){try{e="function"==typeof setTimeout?setTimeout:i}catch(t){e=i}try{s="function"==typeof clearTimeout?clearTimeout:n}catch(t){s=n}}();var o,h=[],c=!1,l=-1;function u(){c&&o&&(c=!1,o.length?h=o.concat(h):l=-1,h.length&&p())}function p(){if(!c){var t=a(u);c=!0;for(var e=h.length;e;){for(o=h,h=[];++l<e;)o&&o[l].run();l=-1,e=h.length}o=null,c=!1,function(t){if(s===clearTimeout)return clearTimeout(t);if((s===n||!s)&&clearTimeout)return s=clearTimeout,clearTimeout(t);try{s(t)}catch(e){try{return s.call(null,t)}catch(e){return s.call(this,t)}}}(t)}}function m(t,e){this.fun=t,this.array=e}function f(){}r.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var s=1;s<arguments.length;s++)e[s-1]=arguments[s];h.push(new m(t,e)),1!==h.length||c||a(p)},m.prototype.run=function(){this.fun.apply(null,this.array)},r.title="browser",r.browser=!0,r.env={},r.argv=[],r.version="",r.versions={},r.on=f,r.addListener=f,r.once=f,r.off=f,r.removeListener=f,r.removeAllListeners=f,r.emit=f,r.prependListener=f,r.prependOnceListener=f,r.listeners=function(t){return[]},r.binding=function(t){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(t){throw new Error("process.chdir is not supported")},r.umask=function(){return 0}},87:(t,e,s)=>{for(var r=s(407),i="undefined"==typeof window?s.g:window,n=["moz","webkit"],a="AnimationFrame",o=i["request"+a],h=i["cancel"+a]||i["cancelRequest"+a],c=0;!o&&c<n.length;c++)o=i[n[c]+"Request"+a],h=i[n[c]+"Cancel"+a]||i[n[c]+"CancelRequest"+a];if(!o||!h){var l=0,u=0,p=[];o=function(t){if(0===p.length){var e=r(),s=Math.max(0,16.666666666666668-(e-l));l=s+e,setTimeout((function(){var t=p.slice(0);p.length=0;for(var e=0;e<t.length;e++)if(!t[e].cancelled)try{t[e].callback(l)}catch(t){setTimeout((function(){throw t}),0)}}),Math.round(s))}return p.push({handle:++u,callback:t,cancelled:!1}),u},h=function(t){for(var e=0;e<p.length;e++)p[e].handle===t&&(p[e].cancelled=!0)}}t.exports=function(t){return o.call(i,t)},t.exports.cancel=function(){h.apply(i,arguments)},t.exports.polyfill=function(t){t||(t=i),t.requestAnimationFrame=o,t.cancelAnimationFrame=h}},407:function(t,e,s){var r=s(155);(function(){var e,s,i,n,a,o;"undefined"!=typeof performance&&null!==performance&&performance.now?t.exports=function(){return performance.now()}:null!=r&&r.hrtime?(t.exports=function(){return(e()-a)/1e6},s=r.hrtime,n=(e=function(){var t;return 1e9*(t=s())[0]+t[1]})(),o=1e9*r.uptime(),a=n-o):Date.now?(t.exports=function(){return Date.now()-i},i=Date.now()):(t.exports=function(){return(new Date).getTime()-i},i=(new Date).getTime())}).call(this)}},e={};function s(r){if(e[r])return e[r].exports;var i=e[r]={exports:{}};return t[r].call(i.exports,i,i.exports,s),i.exports}return s.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return s.d(e,{a:e}),e},s.d=(t,e)=>{for(var r in e)s.o(e,r)&&!s.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s(679)})().default; |
{ | ||
"name": "nessie", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "An NES emulator written in JavaScript", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -38,3 +38,7 @@ import './number'; | ||
this.frameCycles += cycles; | ||
for (cycles *= 3; cycles > 0; cycles--) { | ||
// WTF(nakardo): ntsc ppu should run at 3 times the cpu rate? | ||
// See: | ||
// - https://wiki.nesdev.com/w/index.php?title=PPU_frame_timing#CPU-PPU_Clock_Alignment | ||
// - https://wiki.nesdev.com/w/index.php?title=CPU#Notes | ||
for (cycles *= 4; cycles > 0; cycles--) { | ||
this.ppu.step(); | ||
@@ -41,0 +45,0 @@ if (this.ppu.renderFrame) { |
@@ -51,3 +51,2 @@ import {debug as Debug} from 'debug'; | ||
this.ctx.quality = 'fast'; | ||
this.ctx.textDrawingMode = 'path'; | ||
this.ctx.antialias = 'none'; | ||
@@ -78,3 +77,3 @@ | ||
drawBackground() { | ||
let [xscroll, yscroll] = this.nes.ppu.scroll; | ||
const [xscroll, yscroll] = this.nes.ppu.scroll; | ||
const yoffset = yscroll + this.nes.ppu.scanline; | ||
@@ -81,0 +80,0 @@ const ysprite = yoffset & 7; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
263616
5632