UNPKG

@davidmorgan/nes-vue

Version:

依据于nes-js项目,使用vue3 版本重写了Nes模拟器。

1,115 lines 166 kB
var Ii = Object.defineProperty; var Ni = (a, h, s) => h in a ? Ii(a, h, { enumerable: !0, configurable: !0, writable: !0, value: s }) : a[h] = s; var x = (a, h, s) => Ni(a, typeof h != "symbol" ? h + "" : h, s); import { computed as J, watch as H, onMounted as ti, onBeforeUnmount as ii, ref as ei, defineComponent as Ei, effect as Ti, nextTick as Oi, openBlock as Ot, createElementBlock as Ft, normalizeStyle as Fi, createElementVNode as Mt, unref as yt, withDirectives as Mi, vShow as yi, toDisplayString as Pi, createCommentVNode as vi } from "vue"; class ki { /** * 这是 IndexedDB 数据库的构造函数,用于创建对象存储。 * @param dbName - 将创建或访问的 IndexedDB 数据库的名称。 * @param storeName - 将在 IndexedDB 数据库中创建或访问的存储对象的名称。 * @param version - 存储对象的版本。 * @returns DB类的实例 */ constructor(h, s, t) { x(this, "_dataFactory", window.indexedDB); x(this, "_dbName"); x(this, "_storeName"); x(this, "_database"); x(this, "_res"); this._dataFactory = window.indexedDB, this._dbName = h, this._storeName = s, this._res = this._dataFactory.open(this._dbName, t), this._res.addEventListener("success", () => { this._database = this._res.result, this._database.objectStoreNames.contains(this._storeName) || this._database.createObjectStore(this._storeName, { keyPath: "id" }); }), this._res.addEventListener("error", () => { console.error("indexedDB load error"); }), this._res.addEventListener("upgradeneeded", () => { this._database = this._res.result, this._database.objectStoreNames.contains(this._storeName) || this._database.createObjectStore(this._storeName, { keyPath: "id" }); }); } get _store() { return this._database.transaction([this._storeName], "readwrite").objectStore(this._storeName); } /** * 将对象存储中的数据写入 IndexedDB 数据库。 * @param id - 数据的唯一标识。 * @param data - 数据。 */ set_item(h, s) { this._store.put({ id: h, data: s }); } /** * 从对象存储中读取数据。 * @param id - 数据的唯一标识。 * @returns 数据,它是一个Promise。 * */ get_item(h) { const s = this._store.get(h); return new Promise((t, o) => { s.addEventListener("success", () => { t(s.result.data); }), s.addEventListener("error", o); }); } /** * 从对象存储中删除数据。 * @param id - 数据的唯一标识。 */ remove_item(h) { this._store.delete(h); } /** * 清空对象存储中的所有数据。 */ clear() { this._store.clear(); } } function Li(a, h) { return new ki(a, h); } function gt(a, h, s) { return h > s && ([h, s] = [s, h]), Math.min(s, Math.max(h, a)); } function U(a) { return Array(a).fill(!1); } function wi(a) { return a.filter(Boolean); } function Bi() { return D(32768, 0).map((a, h) => h); } function B(a) { const h = []; let s = a[0], t = 1; for (let o = 1; o < a.length; o++) a[o] === s ? t++ : (t > 1 ? (h.push(t), h.push(s)) : h.push(-s - 1), s = a[o], t = 1); return h.push(t), h.push(s), h; } function V(a) { const h = []; for (let s = 0; s < a.length; ) if (a[s] < 0) h.push(-a[s] - 1), s++; else { const t = a[s], o = a[s + 1]; for (let e = 0; e < t; e++) h.push(o); s += 2; } return h; } function Vi(a) { const h = [], s = []; for (let t = 0; t < a.length; t++) { for (let o = 0; o < a[t].opaque.length; o++) a[t].opaque[o] === !1 ? h.push(0) : h.push(1); s.push(...a[t].pix); } return [B(h), B(s)]; } function Gi(a) { const h = []; let s = Array(8), t = []; const o = V(a[0]), e = V(a[1]); for (let i = 0; i < 512; i += 1) { for (let r = 0; r < 8; r += 1) o[i * 8 + r] === 0 && (s[r] = !1); for (let r = 0; r < 64; r += 1) t[r] = e[i * 64 + r]; h.push({ opaque: s, pix: t }), s = Array(8), t = []; } return h; } function qi(a) { const h = [], s = []; return a.reduce((t, o) => (h.push(...o.tile), s.push(...o.attrib), t), h), [B(h), B(s)]; } function Xi(a) { const h = []; let s = [], t = []; const o = V(a[0]), e = V(a[1]); for (let i = 0; i < 1024 * 4; i += 1) s.push(o[i]), t.push(e[i]), (i + 1) % 1024 === 0 && (h.push({ tile: s, attrib: t }), s = [], t = []); return h; } function Z(a) { return +`0x${a}`; } function D(a, h) { return Array.from({ length: a }).fill(h); } function rt(a) { return Object.entries(a); } function Yi(a) { return a && a.__esModule && Object.prototype.hasOwnProperty.call(a, "default") ? a.default : a; } var nt, Pt; function si() { if (Pt) return nt; Pt = 1; var a = function() { this.state = new Array(8); for (var h = 0; h < this.state.length; h++) this.state[h] = 64; }; return a.BUTTON_A = 0, a.BUTTON_B = 1, a.BUTTON_SELECT = 2, a.BUTTON_START = 3, a.BUTTON_UP = 4, a.BUTTON_DOWN = 5, a.BUTTON_LEFT = 6, a.BUTTON_RIGHT = 7, a.prototype = { buttonDown: function(h) { this.state[h] = 65; }, buttonUp: function(h) { this.state[h] = 64; } }, nt = a, nt; } var at, vt; function At() { return vt || (vt = 1, at = { copyArrayElements: function(a, h, s, t, o) { for (var e = 0; e < o; ++e) s[t + e] = a[h + e]; }, copyArray: function(a) { return a.slice(0); }, fromJSON: function(a, h) { for (var s = 0; s < a.JSON_PROPERTIES.length; s++) a[a.JSON_PROPERTIES[s]] = h[a.JSON_PROPERTIES[s]]; }, toJSON: function(a) { for (var h = {}, s = 0; s < a.JSON_PROPERTIES.length; s++) h[a.JSON_PROPERTIES[s]] = a[a.JSON_PROPERTIES[s]]; return h; } }), at; } var ot, kt; function Hi() { if (kt) return ot; kt = 1; var a = At(), h = function(t) { this.nes = t, this.mem = null, this.REG_ACC = null, this.REG_X = null, this.REG_Y = null, this.REG_SP = null, this.REG_PC = null, this.REG_PC_NEW = null, this.REG_STATUS = null, this.F_CARRY = null, this.F_DECIMAL = null, this.F_INTERRUPT = null, this.F_INTERRUPT_NEW = null, this.F_OVERFLOW = null, this.F_SIGN = null, this.F_ZERO = null, this.F_NOTUSED = null, this.F_NOTUSED_NEW = null, this.F_BRK = null, this.F_BRK_NEW = null, this.opdata = null, this.cyclesToHalt = null, this.crash = null, this.irqRequested = null, this.irqType = null, this.reset(); }; h.prototype = { // IRQ Types IRQ_NORMAL: 0, IRQ_NMI: 1, IRQ_RESET: 2, reset: function() { this.mem = new Array(65536); for (var t = 0; t < 8192; t++) this.mem[t] = 255; for (var o = 0; o < 4; o++) { var e = o * 2048; this.mem[e + 8] = 247, this.mem[e + 9] = 239, this.mem[e + 10] = 223, this.mem[e + 15] = 191; } for (var i = 8193; i < this.mem.length; i++) this.mem[i] = 0; this.REG_ACC = 0, this.REG_X = 0, this.REG_Y = 0, this.REG_SP = 511, this.REG_PC = 32767, this.REG_PC_NEW = 32767, this.REG_STATUS = 40, this.setStatus(40), this.F_CARRY = 0, this.F_DECIMAL = 0, this.F_INTERRUPT = 1, this.F_INTERRUPT_NEW = 1, this.F_OVERFLOW = 0, this.F_SIGN = 0, this.F_ZERO = 1, this.F_NOTUSED = 1, this.F_NOTUSED_NEW = 1, this.F_BRK = 1, this.F_BRK_NEW = 1, this.opdata = new s().opdata, this.cyclesToHalt = 0, this.crash = !1, this.irqRequested = !1, this.irqType = null; }, // Emulates a single CPU instruction, returns the number of cycles emulate: function() { var t, o; if (this.irqRequested) { switch (t = this.F_CARRY | (this.F_ZERO === 0 ? 1 : 0) << 1 | this.F_INTERRUPT << 2 | this.F_DECIMAL << 3 | this.F_BRK << 4 | this.F_NOTUSED << 5 | this.F_OVERFLOW << 6 | this.F_SIGN << 7, this.REG_PC_NEW = this.REG_PC, this.F_INTERRUPT_NEW = this.F_INTERRUPT, this.irqType) { case 0: { if (this.F_INTERRUPT !== 0) break; this.doIrq(t); break; } case 1: { this.doNonMaskableInterrupt(t); break; } case 2: { this.doResetInterrupt(); break; } } this.REG_PC = this.REG_PC_NEW, this.F_INTERRUPT = this.F_INTERRUPT_NEW, this.F_BRK = this.F_BRK_NEW, this.irqRequested = !1; } var e = this.opdata[this.nes.mmap.load(this.REG_PC + 1)], i = e >> 24, r = 0, n = e >> 8 & 255, u = this.REG_PC; this.REG_PC += e >> 16 & 255; var l = 0; switch (n) { case 0: { l = this.load(u + 2); break; } case 1: { l = this.load(u + 2), l < 128 ? l += this.REG_PC : l += this.REG_PC - 256; break; } case 2: break; case 3: { l = this.load16bit(u + 2); break; } case 4: { l = this.REG_ACC; break; } case 5: { l = this.REG_PC; break; } case 6: { l = this.load(u + 2) + this.REG_X & 255; break; } case 7: { l = this.load(u + 2) + this.REG_Y & 255; break; } case 8: { l = this.load16bit(u + 2), (l & 65280) !== (l + this.REG_X & 65280) && (r = 1), l += this.REG_X; break; } case 9: { l = this.load16bit(u + 2), (l & 65280) !== (l + this.REG_Y & 65280) && (r = 1), l += this.REG_Y; break; } case 10: { l = this.load(u + 2), (l & 65280) !== (l + this.REG_X & 65280) && (r = 1), l += this.REG_X, l &= 255, l = this.load16bit(l); break; } case 11: { l = this.load16bit(this.load(u + 2)), (l & 65280) !== (l + this.REG_Y & 65280) && (r = 1), l += this.REG_Y; break; } case 12: { l = this.load16bit(u + 2), l < 8191 ? l = this.mem[l] + (this.mem[l & 65280 | (l & 255) + 1 & 255] << 8) : l = this.nes.mmap.load(l) + (this.nes.mmap.load( l & 65280 | (l & 255) + 1 & 255 ) << 8); break; } } switch (l &= 65535, e & 255) { case 0: { t = this.REG_ACC + this.load(l) + this.F_CARRY, !((this.REG_ACC ^ this.load(l)) & 128) && (this.REG_ACC ^ t) & 128 ? this.F_OVERFLOW = 1 : this.F_OVERFLOW = 0, this.F_CARRY = t > 255 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, this.REG_ACC = t & 255, i += r; break; } case 1: { this.REG_ACC = this.REG_ACC & this.load(l), this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, n !== 11 && (i += r); break; } case 2: { n === 4 ? (this.F_CARRY = this.REG_ACC >> 7 & 1, this.REG_ACC = this.REG_ACC << 1 & 255, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC) : (t = this.load(l), this.F_CARRY = t >> 7 & 1, t = t << 1 & 255, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t, this.write(l, t)); break; } case 3: { this.F_CARRY === 0 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 4: { this.F_CARRY === 1 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 5: { this.F_ZERO === 0 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 6: { t = this.load(l), this.F_SIGN = t >> 7 & 1, this.F_OVERFLOW = t >> 6 & 1, t &= this.REG_ACC, this.F_ZERO = t; break; } case 7: { this.F_SIGN === 1 && (i++, this.REG_PC = l); break; } case 8: { this.F_ZERO !== 0 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 9: { this.F_SIGN === 0 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 10: { this.REG_PC += 2, this.push(this.REG_PC >> 8 & 255), this.push(this.REG_PC & 255), this.F_BRK = 1, this.push( this.F_CARRY | (this.F_ZERO === 0 ? 1 : 0) << 1 | this.F_INTERRUPT << 2 | this.F_DECIMAL << 3 | this.F_BRK << 4 | this.F_NOTUSED << 5 | this.F_OVERFLOW << 6 | this.F_SIGN << 7 ), this.F_INTERRUPT = 1, this.REG_PC = this.load16bit(65534), this.REG_PC--; break; } case 11: { this.F_OVERFLOW === 0 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 12: { this.F_OVERFLOW === 1 && (i += (u & 65280) !== (l & 65280) ? 2 : 1, this.REG_PC = l); break; } case 13: { this.F_CARRY = 0; break; } case 14: { this.F_DECIMAL = 0; break; } case 15: { this.F_INTERRUPT = 0; break; } case 16: { this.F_OVERFLOW = 0; break; } case 17: { t = this.REG_ACC - this.load(l), this.F_CARRY = t >= 0 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, i += r; break; } case 18: { t = this.REG_X - this.load(l), this.F_CARRY = t >= 0 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255; break; } case 19: { t = this.REG_Y - this.load(l), this.F_CARRY = t >= 0 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255; break; } case 20: { t = this.load(l) - 1 & 255, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t, this.write(l, t); break; } case 21: { this.REG_X = this.REG_X - 1 & 255, this.F_SIGN = this.REG_X >> 7 & 1, this.F_ZERO = this.REG_X; break; } case 22: { this.REG_Y = this.REG_Y - 1 & 255, this.F_SIGN = this.REG_Y >> 7 & 1, this.F_ZERO = this.REG_Y; break; } case 23: { this.REG_ACC = (this.load(l) ^ this.REG_ACC) & 255, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, i += r; break; } case 24: { t = this.load(l) + 1 & 255, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t, this.write(l, t & 255); break; } case 25: { this.REG_X = this.REG_X + 1 & 255, this.F_SIGN = this.REG_X >> 7 & 1, this.F_ZERO = this.REG_X; break; } case 26: { this.REG_Y++, this.REG_Y &= 255, this.F_SIGN = this.REG_Y >> 7 & 1, this.F_ZERO = this.REG_Y; break; } case 27: { this.REG_PC = l - 1; break; } case 28: { this.push(this.REG_PC >> 8 & 255), this.push(this.REG_PC & 255), this.REG_PC = l - 1; break; } case 29: { this.REG_ACC = this.load(l), this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, i += r; break; } case 30: { this.REG_X = this.load(l), this.F_SIGN = this.REG_X >> 7 & 1, this.F_ZERO = this.REG_X, i += r; break; } case 31: { this.REG_Y = this.load(l), this.F_SIGN = this.REG_Y >> 7 & 1, this.F_ZERO = this.REG_Y, i += r; break; } case 32: { n === 4 ? (t = this.REG_ACC & 255, this.F_CARRY = t & 1, t >>= 1, this.REG_ACC = t) : (t = this.load(l) & 255, this.F_CARRY = t & 1, t >>= 1, this.write(l, t)), this.F_SIGN = 0, this.F_ZERO = t; break; } case 33: break; case 34: { t = (this.load(l) | this.REG_ACC) & 255, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t, this.REG_ACC = t, n !== 11 && (i += r); break; } case 35: { this.push(this.REG_ACC); break; } case 36: { this.F_BRK = 1, this.push( this.F_CARRY | (this.F_ZERO === 0 ? 1 : 0) << 1 | this.F_INTERRUPT << 2 | this.F_DECIMAL << 3 | this.F_BRK << 4 | this.F_NOTUSED << 5 | this.F_OVERFLOW << 6 | this.F_SIGN << 7 ); break; } case 37: { this.REG_ACC = this.pull(), this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC; break; } case 38: { t = this.pull(), this.F_CARRY = t & 1, this.F_ZERO = (t >> 1 & 1) === 1 ? 0 : 1, this.F_INTERRUPT = t >> 2 & 1, this.F_DECIMAL = t >> 3 & 1, this.F_BRK = t >> 4 & 1, this.F_NOTUSED = t >> 5 & 1, this.F_OVERFLOW = t >> 6 & 1, this.F_SIGN = t >> 7 & 1, this.F_NOTUSED = 1; break; } case 39: { n === 4 ? (t = this.REG_ACC, o = this.F_CARRY, this.F_CARRY = t >> 7 & 1, t = (t << 1 & 255) + o, this.REG_ACC = t) : (t = this.load(l), o = this.F_CARRY, this.F_CARRY = t >> 7 & 1, t = (t << 1 & 255) + o, this.write(l, t)), this.F_SIGN = t >> 7 & 1, this.F_ZERO = t; break; } case 40: { n === 4 ? (o = this.F_CARRY << 7, this.F_CARRY = this.REG_ACC & 1, t = (this.REG_ACC >> 1) + o, this.REG_ACC = t) : (t = this.load(l), o = this.F_CARRY << 7, this.F_CARRY = t & 1, t = (t >> 1) + o, this.write(l, t)), this.F_SIGN = t >> 7 & 1, this.F_ZERO = t; break; } case 41: { if (t = this.pull(), this.F_CARRY = t & 1, this.F_ZERO = t >> 1 & 1 ? 0 : 1, this.F_INTERRUPT = t >> 2 & 1, this.F_DECIMAL = t >> 3 & 1, this.F_BRK = t >> 4 & 1, this.F_NOTUSED = t >> 5 & 1, this.F_OVERFLOW = t >> 6 & 1, this.F_SIGN = t >> 7 & 1, this.REG_PC = this.pull(), this.REG_PC += this.pull() << 8, this.REG_PC === 65535) return; this.REG_PC--, this.F_NOTUSED = 1; break; } case 42: { if (this.REG_PC = this.pull(), this.REG_PC += this.pull() << 8, this.REG_PC === 65535) return; break; } case 43: { t = this.REG_ACC - this.load(l) - (1 - this.F_CARRY), this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, (this.REG_ACC ^ t) & 128 && (this.REG_ACC ^ this.load(l)) & 128 ? this.F_OVERFLOW = 1 : this.F_OVERFLOW = 0, this.F_CARRY = t < 0 ? 0 : 1, this.REG_ACC = t & 255, n !== 11 && (i += r); break; } case 44: { this.F_CARRY = 1; break; } case 45: { this.F_DECIMAL = 1; break; } case 46: { this.F_INTERRUPT = 1; break; } case 47: { this.write(l, this.REG_ACC); break; } case 48: { this.write(l, this.REG_X); break; } case 49: { this.write(l, this.REG_Y); break; } case 50: { this.REG_X = this.REG_ACC, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC; break; } case 51: { this.REG_Y = this.REG_ACC, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC; break; } case 52: { this.REG_X = this.REG_SP - 256, this.F_SIGN = this.REG_SP >> 7 & 1, this.F_ZERO = this.REG_X; break; } case 53: { this.REG_ACC = this.REG_X, this.F_SIGN = this.REG_X >> 7 & 1, this.F_ZERO = this.REG_X; break; } case 54: { this.REG_SP = this.REG_X + 256, this.stackWrap(); break; } case 55: { this.REG_ACC = this.REG_Y, this.F_SIGN = this.REG_Y >> 7 & 1, this.F_ZERO = this.REG_Y; break; } case 56: { t = this.REG_ACC & this.load(l), this.F_CARRY = t & 1, this.REG_ACC = this.F_ZERO = t >> 1, this.F_SIGN = 0; break; } case 57: { this.REG_ACC = this.F_ZERO = this.REG_ACC & this.load(l), this.F_CARRY = this.F_SIGN = this.REG_ACC >> 7 & 1; break; } case 58: { t = this.REG_ACC & this.load(l), this.REG_ACC = this.F_ZERO = (t >> 1) + (this.F_CARRY << 7), this.F_SIGN = this.F_CARRY, this.F_CARRY = t >> 7 & 1, this.F_OVERFLOW = (t >> 7 ^ t >> 6) & 1; break; } case 59: { t = (this.REG_X & this.REG_ACC) - this.load(l), this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, (this.REG_X ^ t) & 128 && (this.REG_X ^ this.load(l)) & 128 ? this.F_OVERFLOW = 1 : this.F_OVERFLOW = 0, this.F_CARRY = t < 0 ? 0 : 1, this.REG_X = t & 255; break; } case 60: { this.REG_ACC = this.REG_X = this.F_ZERO = this.load(l), this.F_SIGN = this.REG_ACC >> 7 & 1, i += r; break; } case 61: { this.write(l, this.REG_ACC & this.REG_X); break; } case 62: { t = this.load(l) - 1 & 255, this.write(l, t), t = this.REG_ACC - t, this.F_CARRY = t >= 0 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, n !== 11 && (i += r); break; } case 63: { t = this.load(l) + 1 & 255, this.write(l, t), t = this.REG_ACC - t - (1 - this.F_CARRY), this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, (this.REG_ACC ^ t) & 128 && (this.REG_ACC ^ this.load(l)) & 128 ? this.F_OVERFLOW = 1 : this.F_OVERFLOW = 0, this.F_CARRY = t < 0 ? 0 : 1, this.REG_ACC = t & 255, n !== 11 && (i += r); break; } case 64: { t = this.load(l), o = this.F_CARRY, this.F_CARRY = t >> 7 & 1, t = (t << 1 & 255) + o, this.write(l, t), this.REG_ACC = this.REG_ACC & t, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, n !== 11 && (i += r); break; } case 65: { t = this.load(l), o = this.F_CARRY << 7, this.F_CARRY = t & 1, t = (t >> 1) + o, this.write(l, t), t = this.REG_ACC + this.load(l) + this.F_CARRY, !((this.REG_ACC ^ this.load(l)) & 128) && (this.REG_ACC ^ t) & 128 ? this.F_OVERFLOW = 1 : this.F_OVERFLOW = 0, this.F_CARRY = t > 255 ? 1 : 0, this.F_SIGN = t >> 7 & 1, this.F_ZERO = t & 255, this.REG_ACC = t & 255, n !== 11 && (i += r); break; } case 66: { t = this.load(l), this.F_CARRY = t >> 7 & 1, t = t << 1 & 255, this.write(l, t), this.REG_ACC = this.REG_ACC | t, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, n !== 11 && (i += r); break; } case 67: { t = this.load(l) & 255, this.F_CARRY = t & 1, t >>= 1, this.write(l, t), this.REG_ACC = this.REG_ACC ^ t, this.F_SIGN = this.REG_ACC >> 7 & 1, this.F_ZERO = this.REG_ACC, n !== 11 && (i += r); break; } case 68: break; case 69: { this.load(l), n !== 11 && (i += r); break; } default: { this.nes.stop(), this.nes.crashMessage = "Game crashed, invalid opcode at address $" + u.toString(16); break; } } return i; }, load: function(t) { return t < 8192 ? this.mem[t & 2047] : this.nes.mmap.load(t); }, load16bit: function(t) { return t < 8191 ? this.mem[t & 2047] | this.mem[t + 1 & 2047] << 8 : this.nes.mmap.load(t) | this.nes.mmap.load(t + 1) << 8; }, write: function(t, o) { t < 8192 ? this.mem[t & 2047] = o : this.nes.mmap.write(t, o); }, requestIrq: function(t) { this.irqRequested && t === this.IRQ_NORMAL || (this.irqRequested = !0, this.irqType = t); }, push: function(t) { this.nes.mmap.write(this.REG_SP, t), this.REG_SP--, this.REG_SP = 256 | this.REG_SP & 255; }, stackWrap: function() { this.REG_SP = 256 | this.REG_SP & 255; }, pull: function() { return this.REG_SP++, this.REG_SP = 256 | this.REG_SP & 255, this.nes.mmap.load(this.REG_SP); }, pageCrossed: function(t, o) { return (t & 65280) !== (o & 65280); }, haltCycles: function(t) { this.cyclesToHalt += t; }, doNonMaskableInterrupt: function(t) { this.nes.mmap.load(8192) & 128 && (this.REG_PC_NEW++, this.push(this.REG_PC_NEW >> 8 & 255), this.push(this.REG_PC_NEW & 255), this.push(t), this.REG_PC_NEW = this.nes.mmap.load(65530) | this.nes.mmap.load(65531) << 8, this.REG_PC_NEW--); }, doResetInterrupt: function() { this.REG_PC_NEW = this.nes.mmap.load(65532) | this.nes.mmap.load(65533) << 8, this.REG_PC_NEW--; }, doIrq: function(t) { this.REG_PC_NEW++, this.push(this.REG_PC_NEW >> 8 & 255), this.push(this.REG_PC_NEW & 255), this.push(t), this.F_INTERRUPT_NEW = 1, this.F_BRK_NEW = 0, this.REG_PC_NEW = this.nes.mmap.load(65534) | this.nes.mmap.load(65535) << 8, this.REG_PC_NEW--; }, getStatus: function() { return this.F_CARRY | this.F_ZERO << 1 | this.F_INTERRUPT << 2 | this.F_DECIMAL << 3 | this.F_BRK << 4 | this.F_NOTUSED << 5 | this.F_OVERFLOW << 6 | this.F_SIGN << 7; }, setStatus: function(t) { this.F_CARRY = t & 1, this.F_ZERO = t >> 1 & 1, this.F_INTERRUPT = t >> 2 & 1, this.F_DECIMAL = t >> 3 & 1, this.F_BRK = t >> 4 & 1, this.F_NOTUSED = t >> 5 & 1, this.F_OVERFLOW = t >> 6 & 1, this.F_SIGN = t >> 7 & 1; }, JSON_PROPERTIES: [ "mem", "cyclesToHalt", "irqRequested", "irqType", // Registers "REG_ACC", "REG_X", "REG_Y", "REG_SP", "REG_PC", "REG_PC_NEW", "REG_STATUS", // Status "F_CARRY", "F_DECIMAL", "F_INTERRUPT", "F_INTERRUPT_NEW", "F_OVERFLOW", "F_SIGN", "F_ZERO", "F_NOTUSED", "F_NOTUSED_NEW", "F_BRK", "F_BRK_NEW" ], toJSON: function() { return a.toJSON(this); }, fromJSON: function(t) { a.fromJSON(this, t); } }; var s = function() { this.opdata = new Array(256); for (var t = 0; t < 256; t++) this.opdata[t] = 255; this.setOp(this.INS_ADC, 105, this.ADDR_IMM, 2, 2), this.setOp(this.INS_ADC, 101, this.ADDR_ZP, 2, 3), this.setOp(this.INS_ADC, 117, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_ADC, 109, this.ADDR_ABS, 3, 4), this.setOp(this.INS_ADC, 125, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_ADC, 121, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_ADC, 97, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_ADC, 113, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_AND, 41, this.ADDR_IMM, 2, 2), this.setOp(this.INS_AND, 37, this.ADDR_ZP, 2, 3), this.setOp(this.INS_AND, 53, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_AND, 45, this.ADDR_ABS, 3, 4), this.setOp(this.INS_AND, 61, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_AND, 57, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_AND, 33, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_AND, 49, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_ASL, 10, this.ADDR_ACC, 1, 2), this.setOp(this.INS_ASL, 6, this.ADDR_ZP, 2, 5), this.setOp(this.INS_ASL, 22, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_ASL, 14, this.ADDR_ABS, 3, 6), this.setOp(this.INS_ASL, 30, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_BCC, 144, this.ADDR_REL, 2, 2), this.setOp(this.INS_BCS, 176, this.ADDR_REL, 2, 2), this.setOp(this.INS_BEQ, 240, this.ADDR_REL, 2, 2), this.setOp(this.INS_BIT, 36, this.ADDR_ZP, 2, 3), this.setOp(this.INS_BIT, 44, this.ADDR_ABS, 3, 4), this.setOp(this.INS_BMI, 48, this.ADDR_REL, 2, 2), this.setOp(this.INS_BNE, 208, this.ADDR_REL, 2, 2), this.setOp(this.INS_BPL, 16, this.ADDR_REL, 2, 2), this.setOp(this.INS_BRK, 0, this.ADDR_IMP, 1, 7), this.setOp(this.INS_BVC, 80, this.ADDR_REL, 2, 2), this.setOp(this.INS_BVS, 112, this.ADDR_REL, 2, 2), this.setOp(this.INS_CLC, 24, this.ADDR_IMP, 1, 2), this.setOp(this.INS_CLD, 216, this.ADDR_IMP, 1, 2), this.setOp(this.INS_CLI, 88, this.ADDR_IMP, 1, 2), this.setOp(this.INS_CLV, 184, this.ADDR_IMP, 1, 2), this.setOp(this.INS_CMP, 201, this.ADDR_IMM, 2, 2), this.setOp(this.INS_CMP, 197, this.ADDR_ZP, 2, 3), this.setOp(this.INS_CMP, 213, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_CMP, 205, this.ADDR_ABS, 3, 4), this.setOp(this.INS_CMP, 221, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_CMP, 217, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_CMP, 193, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_CMP, 209, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_CPX, 224, this.ADDR_IMM, 2, 2), this.setOp(this.INS_CPX, 228, this.ADDR_ZP, 2, 3), this.setOp(this.INS_CPX, 236, this.ADDR_ABS, 3, 4), this.setOp(this.INS_CPY, 192, this.ADDR_IMM, 2, 2), this.setOp(this.INS_CPY, 196, this.ADDR_ZP, 2, 3), this.setOp(this.INS_CPY, 204, this.ADDR_ABS, 3, 4), this.setOp(this.INS_DEC, 198, this.ADDR_ZP, 2, 5), this.setOp(this.INS_DEC, 214, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_DEC, 206, this.ADDR_ABS, 3, 6), this.setOp(this.INS_DEC, 222, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_DEX, 202, this.ADDR_IMP, 1, 2), this.setOp(this.INS_DEY, 136, this.ADDR_IMP, 1, 2), this.setOp(this.INS_EOR, 73, this.ADDR_IMM, 2, 2), this.setOp(this.INS_EOR, 69, this.ADDR_ZP, 2, 3), this.setOp(this.INS_EOR, 85, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_EOR, 77, this.ADDR_ABS, 3, 4), this.setOp(this.INS_EOR, 93, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_EOR, 89, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_EOR, 65, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_EOR, 81, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_INC, 230, this.ADDR_ZP, 2, 5), this.setOp(this.INS_INC, 246, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_INC, 238, this.ADDR_ABS, 3, 6), this.setOp(this.INS_INC, 254, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_INX, 232, this.ADDR_IMP, 1, 2), this.setOp(this.INS_INY, 200, this.ADDR_IMP, 1, 2), this.setOp(this.INS_JMP, 76, this.ADDR_ABS, 3, 3), this.setOp(this.INS_JMP, 108, this.ADDR_INDABS, 3, 5), this.setOp(this.INS_JSR, 32, this.ADDR_ABS, 3, 6), this.setOp(this.INS_LDA, 169, this.ADDR_IMM, 2, 2), this.setOp(this.INS_LDA, 165, this.ADDR_ZP, 2, 3), this.setOp(this.INS_LDA, 181, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_LDA, 173, this.ADDR_ABS, 3, 4), this.setOp(this.INS_LDA, 189, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_LDA, 185, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_LDA, 161, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_LDA, 177, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_LDX, 162, this.ADDR_IMM, 2, 2), this.setOp(this.INS_LDX, 166, this.ADDR_ZP, 2, 3), this.setOp(this.INS_LDX, 182, this.ADDR_ZPY, 2, 4), this.setOp(this.INS_LDX, 174, this.ADDR_ABS, 3, 4), this.setOp(this.INS_LDX, 190, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_LDY, 160, this.ADDR_IMM, 2, 2), this.setOp(this.INS_LDY, 164, this.ADDR_ZP, 2, 3), this.setOp(this.INS_LDY, 180, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_LDY, 172, this.ADDR_ABS, 3, 4), this.setOp(this.INS_LDY, 188, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_LSR, 74, this.ADDR_ACC, 1, 2), this.setOp(this.INS_LSR, 70, this.ADDR_ZP, 2, 5), this.setOp(this.INS_LSR, 86, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_LSR, 78, this.ADDR_ABS, 3, 6), this.setOp(this.INS_LSR, 94, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_NOP, 26, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 58, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 90, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 122, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 218, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 234, this.ADDR_IMP, 1, 2), this.setOp(this.INS_NOP, 250, this.ADDR_IMP, 1, 2), this.setOp(this.INS_ORA, 9, this.ADDR_IMM, 2, 2), this.setOp(this.INS_ORA, 5, this.ADDR_ZP, 2, 3), this.setOp(this.INS_ORA, 21, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_ORA, 13, this.ADDR_ABS, 3, 4), this.setOp(this.INS_ORA, 29, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_ORA, 25, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_ORA, 1, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_ORA, 17, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_PHA, 72, this.ADDR_IMP, 1, 3), this.setOp(this.INS_PHP, 8, this.ADDR_IMP, 1, 3), this.setOp(this.INS_PLA, 104, this.ADDR_IMP, 1, 4), this.setOp(this.INS_PLP, 40, this.ADDR_IMP, 1, 4), this.setOp(this.INS_ROL, 42, this.ADDR_ACC, 1, 2), this.setOp(this.INS_ROL, 38, this.ADDR_ZP, 2, 5), this.setOp(this.INS_ROL, 54, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_ROL, 46, this.ADDR_ABS, 3, 6), this.setOp(this.INS_ROL, 62, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_ROR, 106, this.ADDR_ACC, 1, 2), this.setOp(this.INS_ROR, 102, this.ADDR_ZP, 2, 5), this.setOp(this.INS_ROR, 118, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_ROR, 110, this.ADDR_ABS, 3, 6), this.setOp(this.INS_ROR, 126, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_RTI, 64, this.ADDR_IMP, 1, 6), this.setOp(this.INS_RTS, 96, this.ADDR_IMP, 1, 6), this.setOp(this.INS_SBC, 233, this.ADDR_IMM, 2, 2), this.setOp(this.INS_SBC, 229, this.ADDR_ZP, 2, 3), this.setOp(this.INS_SBC, 245, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_SBC, 237, this.ADDR_ABS, 3, 4), this.setOp(this.INS_SBC, 253, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_SBC, 249, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_SBC, 225, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_SBC, 241, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_SEC, 56, this.ADDR_IMP, 1, 2), this.setOp(this.INS_SED, 248, this.ADDR_IMP, 1, 2), this.setOp(this.INS_SEI, 120, this.ADDR_IMP, 1, 2), this.setOp(this.INS_STA, 133, this.ADDR_ZP, 2, 3), this.setOp(this.INS_STA, 149, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_STA, 141, this.ADDR_ABS, 3, 4), this.setOp(this.INS_STA, 157, this.ADDR_ABSX, 3, 5), this.setOp(this.INS_STA, 153, this.ADDR_ABSY, 3, 5), this.setOp(this.INS_STA, 129, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_STA, 145, this.ADDR_POSTIDXIND, 2, 6), this.setOp(this.INS_STX, 134, this.ADDR_ZP, 2, 3), this.setOp(this.INS_STX, 150, this.ADDR_ZPY, 2, 4), this.setOp(this.INS_STX, 142, this.ADDR_ABS, 3, 4), this.setOp(this.INS_STY, 132, this.ADDR_ZP, 2, 3), this.setOp(this.INS_STY, 148, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_STY, 140, this.ADDR_ABS, 3, 4), this.setOp(this.INS_TAX, 170, this.ADDR_IMP, 1, 2), this.setOp(this.INS_TAY, 168, this.ADDR_IMP, 1, 2), this.setOp(this.INS_TSX, 186, this.ADDR_IMP, 1, 2), this.setOp(this.INS_TXA, 138, this.ADDR_IMP, 1, 2), this.setOp(this.INS_TXS, 154, this.ADDR_IMP, 1, 2), this.setOp(this.INS_TYA, 152, this.ADDR_IMP, 1, 2), this.setOp(this.INS_ALR, 75, this.ADDR_IMM, 2, 2), this.setOp(this.INS_ANC, 11, this.ADDR_IMM, 2, 2), this.setOp(this.INS_ANC, 43, this.ADDR_IMM, 2, 2), this.setOp(this.INS_ARR, 107, this.ADDR_IMM, 2, 2), this.setOp(this.INS_AXS, 203, this.ADDR_IMM, 2, 2), this.setOp(this.INS_LAX, 163, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_LAX, 167, this.ADDR_ZP, 2, 3), this.setOp(this.INS_LAX, 175, this.ADDR_ABS, 3, 4), this.setOp(this.INS_LAX, 179, this.ADDR_POSTIDXIND, 2, 5), this.setOp(this.INS_LAX, 183, this.ADDR_ZPY, 2, 4), this.setOp(this.INS_LAX, 191, this.ADDR_ABSY, 3, 4), this.setOp(this.INS_SAX, 131, this.ADDR_PREIDXIND, 2, 6), this.setOp(this.INS_SAX, 135, this.ADDR_ZP, 2, 3), this.setOp(this.INS_SAX, 143, this.ADDR_ABS, 3, 4), this.setOp(this.INS_SAX, 151, this.ADDR_ZPY, 2, 4), this.setOp(this.INS_DCP, 195, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_DCP, 199, this.ADDR_ZP, 2, 5), this.setOp(this.INS_DCP, 207, this.ADDR_ABS, 3, 6), this.setOp(this.INS_DCP, 211, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_DCP, 215, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_DCP, 219, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_DCP, 223, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_ISC, 227, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_ISC, 231, this.ADDR_ZP, 2, 5), this.setOp(this.INS_ISC, 239, this.ADDR_ABS, 3, 6), this.setOp(this.INS_ISC, 243, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_ISC, 247, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_ISC, 251, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_ISC, 255, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_RLA, 35, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_RLA, 39, this.ADDR_ZP, 2, 5), this.setOp(this.INS_RLA, 47, this.ADDR_ABS, 3, 6), this.setOp(this.INS_RLA, 51, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_RLA, 55, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_RLA, 59, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_RLA, 63, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_RRA, 99, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_RRA, 103, this.ADDR_ZP, 2, 5), this.setOp(this.INS_RRA, 111, this.ADDR_ABS, 3, 6), this.setOp(this.INS_RRA, 115, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_RRA, 119, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_RRA, 123, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_RRA, 127, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_SLO, 3, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_SLO, 7, this.ADDR_ZP, 2, 5), this.setOp(this.INS_SLO, 15, this.ADDR_ABS, 3, 6), this.setOp(this.INS_SLO, 19, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_SLO, 23, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_SLO, 27, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_SLO, 31, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_SRE, 67, this.ADDR_PREIDXIND, 2, 8), this.setOp(this.INS_SRE, 71, this.ADDR_ZP, 2, 5), this.setOp(this.INS_SRE, 79, this.ADDR_ABS, 3, 6), this.setOp(this.INS_SRE, 83, this.ADDR_POSTIDXIND, 2, 8), this.setOp(this.INS_SRE, 87, this.ADDR_ZPX, 2, 6), this.setOp(this.INS_SRE, 91, this.ADDR_ABSY, 3, 7), this.setOp(this.INS_SRE, 95, this.ADDR_ABSX, 3, 7), this.setOp(this.INS_SKB, 128, this.ADDR_IMM, 2, 2), this.setOp(this.INS_SKB, 130, this.ADDR_IMM, 2, 2), this.setOp(this.INS_SKB, 137, this.ADDR_IMM, 2, 2), this.setOp(this.INS_SKB, 194, this.ADDR_IMM, 2, 2), this.setOp(this.INS_SKB, 226, this.ADDR_IMM, 2, 2), this.setOp(this.INS_IGN, 12, this.ADDR_ABS, 3, 4), this.setOp(this.INS_IGN, 28, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 60, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 92, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 124, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 220, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 252, this.ADDR_ABSX, 3, 4), this.setOp(this.INS_IGN, 4, this.ADDR_ZP, 2, 3), this.setOp(this.INS_IGN, 68, this.ADDR_ZP, 2, 3), this.setOp(this.INS_IGN, 100, this.ADDR_ZP, 2, 3), this.setOp(this.INS_IGN, 20, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_IGN, 52, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_IGN, 84, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_IGN, 116, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_IGN, 212, this.ADDR_ZPX, 2, 4), this.setOp(this.INS_IGN, 244, this.ADDR_ZPX, 2, 4), this.cycTable = new Array( /*0x00*/ 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /*0x10*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /*0x20*/ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /*0x30*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /*0x40*/ 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /*0x50*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /*0x60*/ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /*0x70*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /*0x80*/ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /*0x90*/ 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /*0xA0*/ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /*0xB0*/ 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /*0xC0*/ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /*0xD0*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /*0xE0*/ 2, 6, 3, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /*0xF0*/ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 ), this.instname = new Array(70), this.instname[0] = "ADC", this.instname[1] = "AND", this.instname[2] = "ASL", this.instname[3] = "BCC", this.instname[4] = "BCS", this.instname[5] = "BEQ", this.instname[6] = "BIT", this.instname[7] = "BMI", this.instname[8] = "BNE", this.instname[9] = "BPL", this.instname[10] = "BRK", this.instname[11] = "BVC", this.instname[12] = "BVS", this.instname[13] = "CLC", this.instname[14] = "CLD", this.instname[15] = "CLI", this.instname[16] = "CLV", this.instname[17] = "CMP", this.instname[18] = "CPX", this.instname[19] = "CPY", this.instname[20] = "DEC", this.instname[21] = "DEX", this.instname[22] = "DEY", this.instname[23] = "EOR", this.instname[24] = "INC", this.instname[25] = "INX", this.instname[26] = "INY", this.instname[27] = "JMP", this.instname[28] = "JSR", this.instname[29] = "LDA", this.instname[30] = "LDX", this.instname[31] = "LDY", this.instname[32] = "LSR", this.instname[33] = "NOP", this.instname[34] = "ORA", this.instname[35] = "PHA", this.instname[36] = "PHP", this.instname[37] = "PLA", this.instname[38] = "PLP", this.instname[39] = "ROL", this.instname[40] = "ROR", this.instname[41] = "RTI", this.instname[42] = "RTS", this.instname[43] = "SBC", this.instname[44] = "SEC", this.instname[45] = "SED", this.instname[46] = "SEI", this.instname[47] = "STA", this.instname[48] = "STX", this.instname[49] = "STY", this.instname[50] = "TAX", this.instname[51] = "TAY", this.instname[52] = "TSX", this.instname[53] = "TXA", this.instname[54] = "TXS", this.instname[55] = "TYA", this.instname[56] = "ALR", this.instname[57] = "ANC", this.instname[58] = "ARR", this.instname[59] = "AXS", this.instname[60] = "LAX", this.instname[61] = "SAX", this.instname[62] = "DCP", this.instname[63] = "ISC", this.instname[64] = "RLA", this.instname[65] = "RRA", this.instname[66] = "SLO", this.instname[67] = "SRE", this.instname[68] = "SKB", this.instname[69] = "IGN", this.addrDesc = new Array( "Zero Page ", "Relative ", "Implied ", "Absolute ", "Accumulator ", "Immediate ", "Zero Page,X ", "Zero Page,Y ", "Absolute,X ", "Absolute,Y ", "Preindexed Indirect ", "Postindexed Indirect", "Indirect Absolute " ); }; return s.prototype = { INS_ADC: 0, INS_AND: 1, INS_ASL: 2, INS_BCC: 3, INS_BCS: 4, INS_BEQ: 5, INS_BIT: 6, INS_BMI: 7, INS_BNE: 8, INS_BPL: 9, INS_BRK: 10, INS_BVC: 11, INS_BVS: 12, INS_CLC: 13, INS_CLD: 14, INS_CLI: 15, INS_CLV: 16, INS_CMP: 17, INS_CPX: 18, INS_CPY: 19, INS_DEC: 20, INS_DEX: 21, INS_DEY: 22, INS_EOR: 23, INS_INC: 24, INS_INX: 25, INS_INY: 26, INS_JMP: 27, INS_JSR: 28, INS_LDA: 29, INS_LDX: 30, INS_LDY: 31, INS_LSR: 32, INS_NOP: 33, INS_ORA: 34, INS_PHA: 35, INS_PHP: 36, INS_PLA: 37, INS_PLP: 38, INS_ROL: 39, INS_ROR: 40, INS_RTI: 41, INS_RTS: 42, INS_SBC: 43, INS_SEC: 44, INS_SED: 45, INS_SEI: 46, INS_STA: 47, INS_STX: 48, INS_STY: 49, INS_TAX: 50, INS_TAY: 51, INS_TSX: 52, INS_TXA: 53, INS_TXS: 54, INS_TYA: 55, INS_ALR: 56, INS_ANC: 57, INS_ARR: 58, INS_AXS: 59, INS_LAX: 60, INS_SAX: 61, INS_DCP: 62, INS_ISC: 63, INS_RLA: 64, INS_RRA: 65, INS_SLO: 66, INS_SRE: 67, INS_SKB: 68, INS_IGN: 69, INS_DUMMY: 70, // dummy instruction used for 'halting' the processor some cycles // -------------------------------- // // Addressing modes: ADDR_ZP: 0, ADDR_REL: 1, ADDR_IMP: 2, ADDR_ABS: 3, ADDR_ACC: 4, ADDR_IMM: 5, ADDR_ZPX: 6, ADDR_ZPY: 7, ADDR_ABSX: 8, ADDR_ABSY: 9, ADDR_PREIDXIND: 10, ADDR_POSTIDXIND: 11, ADDR_INDABS: 12, setOp: function(t, o, e, i, r) { this.opdata[o] = t & 255 | (e & 255) << 8 | (i & 255) << 16 | (r & 255) << 24; } }, ot = h, ot; } var lt, Lt; function hi() { if (Lt) return lt; Lt = 1; var a = function() { this.pix = new Array(64), this.fbIndex = null, this.tIndex = null, this.x = null, this.y = null, this.w = null, this.h = null, this.incX = null, this.incY = null, this.palIndex = null, this.tpri = null, this.c = null, this.initialized = !1, this.opaque = new Array(8); }; return a.prototype = { setBuffer: function(h) { for (this.y = 0; this.y < 8; this.y++) this.setScanline(this.y, h[this.y], h[this.y + 8]); }, setScanline: function(h, s, t) { for (this.initialized = !0, this.tIndex = h << 3, this.x = 0; this.x < 8; this.x++) this.pix[this.tIndex + this.x] = (s >> 7 - this.x & 1) + ((t >> 7 - this.x & 1) << 1), this.pix[this.tIndex + this.x] === 0 && (this.opaque[h] = !1); }, render: function(h, s, t, o, e, i, r, n, u, l, f, p, R) { if (!(i < -7 || i >= 256 || r < -7 || r >= 240)) if (this.w = o - s, this.h = e - t, i < 0 && (s -= i), i + o >= 256 && (o = 256 - i), r < 0 && (t -= r), r + e >= 240 && (e = 240 - r), !l && !f) for (this.fbIndex = (r << 8) + i, this.tIndex = 0, this.y = 0; this.y < 8; this.y++) { for (this.x = 0; this.x < 8; this.x++) this.x >= s && this.x < o && this.y >= t && this.y < e && (this.palIndex = this.pix[this.tIndex], this.tpri = R[this.fbIndex], this.palIndex !== 0 && p <= (this.tpri & 255) && (h[this.fbIndex] = u[this.palIndex + n], this.tpri = this.tpri & 3840 | p, R[this.fbIndex] = this.tpri)), this.fbIndex++, this.tIndex++; this.fbIndex -= 8, this.fbIndex += 256; } else if (l && !f) for (this.fbIndex = (r << 8) + i, this.tIndex = 7, this.y = 0; this.y < 8; this.y++) { for (this.x = 0; this.x < 8; this.x++) this.x >= s && this.x < o && this.y >= t && this.y < e && (this.palIndex = this.pix[this.tIndex], this.tpri = R[this.fbIndex], this.palIndex !== 0 && p <= (this.tpri & 255) && (h[this.fbIndex] = u[this.palIndex + n], this.tpri = this.tpri & 3840 | p, R[this.fbIndex] = this.tpri)), this.fbIndex++, this.tIndex--; this.fbIndex -= 8, this.fbIndex += 256, this.tIndex += 16; } else if (f && !l) for (this.fbIndex = (r << 8) + i, this.tIndex = 56, this.y = 0; this.y < 8; this.y++) { for (this.x = 0; this.x < 8; this.x++) this.x >= s && this.x < o && this.y >= t && this.y < e && (this.palIndex = this.pix[this.tIndex], this.tpri = R[this.fbIndex], this.palIndex !== 0 && p <= (this.tpri & 255) && (h[this.fbIndex] = u[this.palIndex + n], this.tpri = this.tpri & 3840 | p, R[this.fbIndex] = this.tpri)), this.fbIndex++, this.tIndex++; this.fbIndex -= 8, this.fbIndex += 256, this.tIndex -= 16; } else for (this.fbIndex = (r << 8) + i, this.tIndex = 63, this.y = 0; this.y < 8; this.y++) { for (this.x = 0; this.x < 8; this.x++) this.x >= s && this.x < o && this.y >= t && this.y < e && (this.palIndex = this.pix[this.tIndex], this.tpri = R[this.fbIndex], this.palIndex !== 0 && p <= (this.tpri & 255) && (h[this.fbIndex] = u[this.palIndex + n], this.tpri = this.tpri & 3840 | p, R[this.fbIndex] = this.tpri)), this.fbIndex++, this.tIndex--; this.fbIndex -= 8, this.fbIndex += 256; } }, isTransparent: function(h, s) { return this.pix[(s << 3) + h] === 0; }, toJSON: function() { return { opaque: this.opaque, pix: this.pix }; }, fromJSON: function(h) { this.opaque = h.opaque, this.pix = h.pix; } }, lt = a, lt; } var ut, wt; function Wi() { if (wt) return ut; wt = 1; var a = hi(), h = At(), s = function(e) { this.nes = e, this.vramMem = null, this.spriteMem = null, this.vramAddress = null, this.vramTmpAddress = null, this.vramBufferedReadValue = null, this.firstWrite = null, this.sramAddress = null, this.currentMirroring = null, this.requestEndFrame = null, this.nmiOk = null, this.dummyCycleToggle = null, this.validTileData = null, this.nmiCounter = null, this.scanlineAlreadyRendered = null, this.f_nmiOnVblank = null, this.f_spriteSize = null, this.f_bgPatternTable = null, this.f_spPatternTable = null, this.f_addrInc = null, this.f_nTblAddress = null, this.f_color = null, this.f_spVisibility = null, this.f_bgVisibility = null, this.f_spClipping = null, this.f_bgClipping = null, this.f_dispType = null, this.cntFV = null, this.cntV = null, this.cntH = null, this.cntVT = null, this.cntHT = null, this.regFV = null, this.regV = null, this.regH = null, this.regVT = null, this.regHT = null, this.regFH = null, this.regS = null, this.curNt = null, this.attrib = null, this.buffer = null, this.bgbuffer = null, this.pixrendered = null, this.validTileData = null, this.scantile = null, this.scanline = null, this.lastRenderedScanline = null, this.curX = null, this.sprX = null, this.sprY = null, this.sprTile = null, this.sprCol = null, this.vertFlip = null, this.horiFlip = null, this.bgPriority = null, this.spr0HitX = null, this.spr0HitY = null, this.hitSpr0 = null, this.sprPalette = null, this.imgPalette = null, this.ptTile = null, this.ntable1 = null, this.currentMirroring = null, this.nameTable = null, this.vramMirrorTable = null, this.palTable = null, this.showSpr0Hit = !1, this.clipToTvSize = !0, this.reset(); }; s.prototype = { // Status flags: STATUS_VRAMWRITE: 4, STATUS_SLSPRITECOUNT: 5, STATUS_SPRITE0HIT: 6, STATUS_VBLANK: 7, reset: function() { var e; for (this.vramMem = new Array(32768), this.spriteMem = new Array(256), e = 0; e < this.vramM