@davidmorgan/nes-vue
Version:
依据于nes-js项目,使用vue3 版本重写了Nes模拟器。
1,115 lines • 166 kB
JavaScript
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