Skip to content

Instantly share code, notes, and snippets.

@jocull
Created May 15, 2012 19:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jocull/2704564 to your computer and use it in GitHub Desktop.
Save jocull/2704564 to your computer and use it in GitHub Desktop.
var windowingInitialized = !1,
inFullscreen = !1,
shortcutHashes = [
["PokemonRed", 25, "PokemonRed.gb"],
["PokemonBlue", 26, "PokemonBlue.gb"],
["PokemonYellow", 27, "PokemonYellow.gbc"],
["PokemonSilver", 28, "PokemonSilver.gbc"],
["PokemonGold", 29, "PokemonGold.gbc"],
["PokemonCrystal", 30, "PokemonCrystal.gbc"],
["PokemonPinball", 31, "PokemonPinball.gbc"],
["PokemonTradingCardGame", 32, "PokemonTradingCardGame.gbc"],
["PokemonTradingCardGame2", 33, "PokemonCardGame2.gbc"]
];
function windowingPreInitUnsafe() {
windowingInitialized || (windowingInitialized = !0, windowingInitialize())
}
function windowingPreInitSafe() {
("undefined" == typeof document.readyState || "complete" == document.readyState) && windowingPreInitUnsafe()
}
function windowingInitUnload() {
removeEvent("DOMContentLoaded", document, windowingPreInitUnsafe);
removeEvent("readystatechange", document, windowingPreInitSafe);
removeEvent("load", document, windowingPreInitUnsafe)
}
function windowingInitialize() {
windowingInitUnload();
try {
registerGUIEvents(), matchHashbang()
} catch (a) {
alert('Fatal initialization error: "' + a.message + '" file:' + a.fileName + " line: " + a.lineNumber, 2)
}
}
function matchHashbang() {
for (var a = shortcutHashes.length, b = 0; b < a; ++b) if (window.location.hash == "#" + shortcutHashes[b][0]) {
runShortcut(shortcutHashes[b]);
return
}
document.getElementById("dropdown_select").selectedIndex = 0
}
function runShortcut(a) {
document.getElementById("dropdown_select").selectedIndex = a[1];
try {
document.getElementById("dropdown_progress").style.display = "block", new Ajax({
URL: "./romStorage/" + a[2] + ".txt",
Accept: "TEXT",
Cached: !0,
Complete: function (a, b) {
try {
initPlayer(), start(document.getElementById("game_canvas"), base64_decode(b))
} catch (f) {
alert(f.message + " file: " + f.fileName + " line: " + f.lineNumber)
}
}
})
} catch (b) {
alert(b.message + " file: " + b.fileName + " line: " + b.lineNumber)
}
}
function keyCodeOverride(a) {
switch (a.keyCode) {
case 74:
case 88:
settings[3][4] = a.keyCode;
break;
case 81:
case 89:
case 90:
settings[3][5] = a.keyCode
}
return a
}
function registerGUIEvents() {
document.getElementById("enable_sound").checked = settings[0];
document.getElementById("gb_boot_rom_utilized").checked = settings[11];
addEvent("keydown", document, function (a) {
switch (a.keyCode) {
case 27:
fullscreenPlayer();
break;
case 68:
lowerVolume();
break;
case 82:
raiseVolume();
break;
default:
GameBoyKeyDown(keyCodeOverride(a))
}
});
addEvent("keyup", document, function (a) {
GameBoyKeyUp(keyCodeOverride(a))
});
addEvent("MozOrientation", window, GameBoyGyroSignalHandler);
addEvent("deviceorientation", window, GameBoyGyroSignalHandler);
var a = document.getElementById("dropdown_select");
a.value = "none";
addEvent("change", a, function () {
var b = this.value;
if ("none" != b) try {
document.getElementById("dropdown_progress").style.display = "block", new Ajax({
URL: "./romStorage/" + b + ".txt",
Accept: "TEXT",
Cached: !0,
Complete: function (a, b) {
try {
initPlayer(), start(document.getElementById("game_canvas"), base64_decode(b))
} catch (c) {
alert(c.message + " file: " + c.fileName + " line: " + c.lineNumber)
}
}
}), a.blur()
} catch (c) {
alert(c.message + " file: " + c.fileName + " line: " + c.lineNumber)
}
});
addEvent("dragover", document.getElementById("gameboy"), stopDragPropagation);
addEvent("drop", document.getElementById("gameboy"), function (a) {
stopDragPropagation(a);
if (a.dataTransfer && a.dataTransfer.files && 0 < a.dataTransfer.files.length) try {
var c = new FileReader;
c.readAsBinaryString(a.dataTransfer.files[0]);
c.onload = function (a) {
try {
initPlayer(), start(document.getElementById("game_canvas"), a.target.result)
} catch (b) {
alert(b.message + " file: " + b.fileName + " line: " + b.lineNumber)
}
}
} catch (e) {
alert(e.message + " file: " + e.fileName + " line: " + e.lineNumber)
}
});
addEvent("click", document.getElementById("enable_sound"), function () {
settings[0] = document.getElementById("enable_sound").checked;
GameBoyEmulatorInitialized() && gameboy.initSound()
});
addEvent("click", document.getElementById("gb_boot_rom_utilized"), function () {
settings[11] = document.getElementById("gb_boot_rom_utilized").checked
});
addEvent("unload", window, function () {
autoSave()
})
}
function lowerVolume() {
settings[13] = Math.max(settings[13] - 0.04, 0);
GameBoyEmulatorInitialized() && gameboy.changeVolume()
}
function raiseVolume() {
settings[13] = Math.min(settings[13] + 0.04, 1);
GameBoyEmulatorInitialized() && gameboy.changeVolume()
}
function stopDragPropagation(a) {
a.stopPropagation();
a.preventDefault()
}
function initPlayer() {
document.getElementById("dropdown_progress").style.display = "none";
document.getElementById("master_container").style.display = "inline-block";
document.getElementById("fullscreenCanvas").style.display = "none"
}
function fullscreenPlayer() {
GameBoyEmulatorInitialized() ? (inFullscreen ? (gameboy.canvas = document.getElementById("game_canvas"), document.getElementById("fullscreenCanvas").style.display = "none", document.getElementById("master_container").style.display = "inline-block") : (gameboy.canvas = document.getElementById("fullscreenCanvas"), gameboy.canvas.style.display = "block", document.getElementById("master_container").style.display = "none"), gameboy.initLCD(), inFullscreen = !inFullscreen) : cout("Cannot go into fullscreen mode.", 2)
}
function findValue(a) {
try {
if (null != window.localStorage.getItem(a)) return JSON.parse(window.localStorage.getItem(a))
} catch (b) {
if (null != window.globalStorage[location.hostname].getItem(a)) return JSON.parse(window.globalStorage[location.hostname].getItem(a))
}
return null
}
function setValue(a, b) {
try {
window.localStorage.setItem(a, JSON.stringify(b))
} catch (c) {
window.globalStorage[location.hostname].setItem(a, JSON.stringify(b))
}
}
function deleteValue(a) {
try {
window.localStorage.removeItem(a)
} catch (b) {
window.globalStorage[location.hostname].removeItem(a)
}
}
function addEvent(a, b, c) {
try {
b.addEventListener(a, c, !1), cout('In addEvent() : Standard addEventListener() called to add a(n) "' + a + '" event.', -1)
} catch (e) {
b.attachEvent("on" + a, c), cout('In addEvent() : Nonstandard attachEvent() called to add an "on' + a + '" event.', -1)
}
}
function removeEvent(a, b, c) {
try {
b.removeEventListener(a, c, !1), cout('In removeEvent() : Standard removeEventListener() called to remove a(n) "' + a + '" event.', -1)
} catch (e) {
b.detachEvent("on" + a, c), cout('In removeEvent() : Nonstandard detachEvent() called to remove an "on' + a + '" event.', -1)
}
}
function cout(a, b) {
switch (b) {
case 0:
outputMessage("<DEBUG>: " + a, "white");
break;
case 1:
outputMessage("<WARNING>: " + a, "yellow");
break;
case 2:
outputMessage("<ERROR>: " + a, "red")
}
}
function outputMessage(a, b) {
var c = document.getElementById("debug_log"),
e = document.createTextNode(a),
f = document.createElement("div");
f.appendChild(e);
f.style.color = b;
c.appendChild(f);
c.style.display = "block"
}
var toBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split(""),
fromBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function base64(a) {
try {
var b = window.btoa(a)
} catch (c) {
var b = "",
e = a.length;
if (0 < e) {
for (var f = [0, 0, 0], g = 0, d = e % 3; 0 < a.length % 3;) a[a.length] = " ";
for (; g < e;) f = [a.charCodeAt(g++) & 255, a.charCodeAt(g++) & 255, a.charCodeAt(g++) & 255], b += toBase64[f[0] >> 2] + toBase64[(f[0] & 3) << 4 | f[1] >> 4] + toBase64[(f[1] & 15) << 2 | f[2] >> 6] + toBase64[f[2] & 63];
0 < d && (b[b.length - 1] = "=", 2 == d ? (b[b.length - 2] = "=", b[b.length - 3] = toBase64[(f[0] & 3) << 4]) : b[b.length - 2] = toBase64[(f[1] & 15) << 2])
}
}
return b
}
function base64_decode(a) {
try {
var b = window.atob(a)
} catch (c) {
var b = "",
e = a.length;
if (3 < e && 0 == e % 4) {
for (var f = [0, 0, 0, 0], g = 0; g < e;) f = [fromBase64.indexOf(a.charAt(g++)), fromBase64.indexOf(a.charAt(g++)), fromBase64.indexOf(a.charAt(g++)), fromBase64.indexOf(a.charAt(g++))], b += String.fromCharCode(f[0] << 2 | f[1] >> 4) + String.fromCharCode((f[1] & 15) << 4 | f[2] >> 2) + String.fromCharCode((f[2] & 3) << 6 | f[3]);
64 <= f[3] && (b.length -= 1, 64 <= f[2] && (b.length -= 1))
}
}
return b
}
function to_little_endian_dword(a) {
return to_little_endian_word(a) + String.fromCharCode(a >> 16 & 255, a >> 24 & 255)
}
function to_little_endian_word(a) {
return to_byte(a) + String.fromCharCode(a >> 8 & 255)
}
function to_byte(a) {
return String.fromCharCode(a & 255)
}
function arrayToBase64(a) {
for (var b = "", c = a.length, e = 0; e < c; ++e) "number" == typeof a[e] && (b += String.fromCharCode(a[e]));
return base64(b)
}
function base64ToArray(a) {
for (var a = base64_decode(a), b = [], c = a.length, e = 0; e < c;) b.push(a.charCodeAt(e++) & 255);
return b
}
function Ajax(a) {
this.typeCheck("object", a);
if (null != a) {
this.Method = 3;
this.MethodCodes = ["XMLHttpRequest", "ActiveXObject", "iFrameMethod", "NONE"];
this.Status = 0;
this.StatusCodes = ["initializing", "loading", "complete", "failed"];
this.pArguments = null;
this.sSelectedURL = this.sActiveXURL = this.sIFrameURL = this.sXMLURL = this.sURL = "";
this.bReadyStateChangeSupported = !1;
this.bAsynchronous = !0;
this.bEmptyResponseAllowed = this.bCached = !1;
this.fFail = function () {};
this.fLoading = function () {};
this.bAcceptEnforce = !0;
this.sAcceptType = "AUTO";
this.ajaxHandle = null;
this.fComplete = function () {};
this.aPost = [];
this.aGet = [];
this.nTimeout = 60;
this.aOrder = [0, 1, 2];
this.bRetryAllowed = !0;
this.nIFrameSafeTimeout = 1E3;
this.aXMLPost = [];
this.aActiveXPost = [];
this.aIFramePost = [];
this.aXMLGet = [];
this.aActiveXGet = [];
this.aIFrameGet = [];
this.aSelectedGet = [];
this.aSelectedPost = [];
this.sIFrameAcceptType = this.sActiveXAcceptType = this.sXMLAcceptType = this.sSelectedAcceptType = "AUTO";
this.StartTime = this.timestamp();
var b = null;
for (b in a) {
switch (b) {
case "URL":
case "XMLURL":
case "ActiveXURL":
case "IFrameURL":
case "Accept":
case "XMLAccept":
case "ActiveXAccept":
case "IFrameAccept":
this.typeCheck("string", a[b]);
break;
case "Asynchronous":
case "Cached":
case "EmptyResponseAllowed":
case "AcceptEnforce":
case "TryBackup":
this.typeCheck("boolean", a[b]);
break;
case "Fail":
case "Loading":
case "Complete":
this.typeCheck("function", a[b]);
break;
case "POST":
case "XMLPOST":
case "ActiveXPOST":
case "IFramePOST":
case "GET":
case "XMLGET":
case "ActiveXGET":
case "IFrameGET":
case "ORDER":
this.typeCheck("object", a[b]);
break;
case "Timeout":
case "IFrameSafeTimeout":
this.typeCheck("number", a[b])
}
switch (b) {
case "XMLURL":
this.sXMLURL = a[b];
break;
case "IFrameURL":
this.sIFrameURL = a[b];
break;
case "ActiveXURL":
this.sActiveXURL = a[b];
break;
case "URL":
this.sURL = a[b];
break;
case "Accept":
this.sAcceptType = a[b];
break;
case "XMLAccept":
this.sXMLAcceptType = a[b];
break;
case "ActiveXAccept":
this.sActiveXAcceptType = a[b];
break;
case "IFrameAccept":
this.sIFrameAcceptType = a[b];
break;
case "Asynchronous":
this.bAsynchronous = a[b];
break;
case "Cached":
this.bCached = a[b];
break;
case "EmptyResponseAllowed":
this.bEmptyResponseAllowed = a[b];
break;
case "AcceptEnforce":
this.bAcceptEnforce = a[b];
break;
case "TryBackup":
this.bRetryAllowed = a[b];
break;
case "Fail":
this.fFail = a[b];
break;
case "Loading":
this.fLoading = a[b];
break;
case "Complete":
this.fComplete = a[b];
break;
case "POST":
this.aPost = a[b];
break;
case "XMLPOST":
this.aXMLPost = a[b];
break;
case "ActiveXPOST":
this.aActiveXPost = a[b];
break;
case "IFramePOST":
this.aIFramePost = a[b];
break;
case "GET":
this.aGet = a[b];
break;
case "XMLGET":
this.aXMLGet = a[b];
break;
case "ActiveXGET":
this.aActiveXGet = a[b];
break;
case "IFrameGET":
this.aIFrameGet = a[b];
break;
case "ORDER":
this.aOrder = a[b];
break;
case "Timeout":
this.nTimeout = a[b];
break;
case "Arguments":
this.pArguments = a[b];
break;
case "IFrameSafeTimeout":
this.nIFrameSafeTimeout = a[b]
}
}
}
this.launch()
}
Ajax.prototype.typeCheck = function (a, b) {
if (typeof b != a) throw "Type of a variable found is invalid";
};
Ajax.prototype.timestamp = function () {
return (new Date).getTime()
};
Ajax.prototype.status = function () {
return this.StatusCodes[this.Status]
};
Ajax.prototype.abort = function () {
this.ajaxHandle.abort();
this.Status = 2
};
Ajax.prototype.method = function () {
return this.MethodCodes[this.Method]
};
Ajax.prototype.update = function () {
this.Status = 1;
this.StartTime = this.timestamp();
this.run()
};
Ajax.prototype.setupMethodProperties = function () {
this.aSelectedGet = this.aGet;
this.aSelectedPost = this.aPost;
this.sSelectedURL = this.sURL;
this.sSelectedAcceptType = this.sAcceptType;
switch (this.Method) {
case 0:
"" != this.sXMLURL && (this.aSelectedGet = this.aXMLGet, this.aSelectedPost = this.aXMLPost, this.sSelectedURL = this.sXMLURL, this.sSelectedAcceptType = this.sXMLAcceptType);
break;
case 1:
"" != this.sActiveXURL && (this.aSelectedGet = this.aActiveXGet, this.aSelectedPost = this.aActiveXPost, this.sSelectedURL = this.sActiveXURL, this.sSelectedAcceptType = this.sActiveXAcceptType);
break;
case 2:
"" != this.sIFrameURL && (this.aSelectedGet = this.aIFrameGet, this.aSelectedPost = this.aIFramePost, this.sSelectedURL = this.sIFrameURL, this.sSelectedAcceptType = this.sIFrameAcceptType)
}
};
Ajax.prototype.errorCaught = function (a) {
for (var b = 0; b < this.aOrder.length; b++) this.aOrder[b] == this.Method && (this.aOrder[b] = -1);
this.bRetryAllowed && this.lookupMethods() ? (this.ajaxHandle.abort(), this.update()) : (this.Status = 3, this.ajaxHandle.abort(), this.fFail(a, this.pArguments))
};
Ajax.prototype.CheckXMLHttpRequest = function () {
try {
this.ajaxHandle = new XMLHttpRequest
} catch (a) {
return !1
}
this.Method = 0;
return !0
};
Ajax.prototype.CheckActiveXObject = function () {
try {
this.ajaxHandle = new ActiveXObject("Msxml2.XMLHTTP.6.0")
} catch (a) {
try {
this.ajaxHandle = new ActiveXObject("Msxml2.XMLHTTP.3.0")
} catch (b) {
try {
this.ajaxHandle = new ActiveXObject("Msxml2.XMLHTTP")
} catch (c) {
try {
this.ajaxHandle = new ActiveXObject("Microsoft.XMLHTTP")
} catch (e) {
return !1
}
}
}
}
this.Method = 1;
return !0
};
Ajax.prototype.CheckiFrameMethod = function () {
try {
this.ajaxHandle = new iFrameMethod(this)
} catch (a) {
return !1
}
this.Method = 2;
return !0
};
Ajax.prototype.lookupMethods = function () {
for (var a = !1, b = 0; b < this.aOrder.length; b++) {
switch (this.aOrder[b]) {
case 0:
a = this.CheckXMLHttpRequest();
break;
case 1:
a = this.CheckActiveXObject();
break;
case 2:
a = this.CheckiFrameMethod()
}
if (a) return this.setupMethodProperties(), !0
}
return !1
};
Ajax.prototype.launch = function () {
this.lookupMethods() ? (this.Status = 1, this.fLoading(), this.run()) : this.errorCaught("No data transport method could be found.")
};
Ajax.prototype.run = function () {
try {
if (1 >= this.Method) {
this.ajaxHandle.open(0 < this.aSelectedPost.length ? "POST" : "GET", this.sSelectedURL + this.composeGET(), this.bAsynchronous);
0 < this.aSelectedPost.length && this.ajaxHandle.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
"number" == typeof this.ajaxHandle.timeout && (this.ajaxHandle.timeout = 1E3 * this.nTimeout);
if (this.bAsynchronous) if ("undefined" != typeof this.ajaxHandle.onreadystatechange) {
this.bReadyStateChangeSupported = !0;
var a = this;
this.ajaxHandle.onreadystatechange = function () {
a.checkWait()
}
} else this.checkWait();
this.ajaxHandle.send(0 < this.aSelectedPost.length ? this.composePOST() : null);
if (!this.bAsynchronous) {
if (this.checkHTTPCode(this.ajaxHandle)) throw "Target file not found.";
this.lookupResponse()
}
} else this.ajaxHandle.generateFrame()
} catch (b) {
this.errorCaught(b)
}
};
Ajax.prototype.composeGET = function () {
var a = "",
b = this.aSelectedGet.slice(0);
this.bCached || (b[b.length] = "ajaxtimestamp=" + this.timestamp());
for (var c = 0; c < b.length; c++) a += 0 == c ? "?" : "&", a += b[c];
return a
};
Ajax.prototype.composePOST = function () {
for (var a = "", b = 0; b < this.aSelectedPost.length; b++) a += this.aSelectedPost[b], b + 1 < this.aSelectedPost.length && (a += "&");
return a
};
Ajax.prototype.lookupResponse = function () {
var a = null,
b = null,
c = null;
if (1 == this.Status) {
"object" == typeof this.ajaxHandle.responseXML && (a = this.inspectXML(this.ajaxHandle.responseXML));
"object" == typeof this.ajaxHandle.responseHTML && (c = this.inspectXML(this.ajaxHandle.responseHTML));
if ("string" == typeof this.ajaxHandle.responseText) {
if (b = this.ajaxHandle.responseText, null == a) {
a = null;
try {
a = (new DOMParser).parseFromString(this.ajaxHandle.responseText, "text/xml")
} catch (e) {
try {
a = new ActiveXObject("Microsoft.XMLDOM"), a.async = "false", a.loadXML(this.ajaxHandle.responseText)
} catch (f) {}
}
a = this.inspectXML(a)
}
} else if (null != c) try {
null != c.outerHTML && (b = c.outerHTML)
} catch (g) {}
if (null != a || null != b || null != c || this.bEmptyResponseAllowed) {
if (this.bAcceptEnforce && !this.bEmptyResponseAllowed && ("HTML" == this.sSelectedAcceptType || "XML" == this.sSelectedAcceptType || "TEXT" == this.sSelectedAcceptType)) switch (this.sSelectedAcceptType) {
case "HTML":
if (null == c) throw "No HTML output.";
break;
case "TEXT":
if (null == b) throw "No TEXT output.";
break;
case "XML":
if (null == a) throw "No XML output.";
}
this.Status = 2;
try {
this.fComplete(a, b, c, this.pArguments)
} catch (d) {
this.errorCaught(d)
}
} else throw "No data downloaded";
}
};
Ajax.prototype.inspectXML = function (a) {
return "object" == typeof a && null != a && "object" == typeof a.documentElement ? a : null
};
Ajax.prototype.checkHTTPCode = function (a) {
var b = !1;
if (3 <= a.readyState && "number" == typeof a.status && (200 > a.status || 300 <= a.status)) b = !0;
return b
};
Ajax.prototype.checkWait = function () {
try {
if (!(3 == this.Status || 2 == this.Status || "number" != typeof this.ajaxHandle.readyState)) {
if (this.checkHTTPCode(this.ajaxHandle)) throw "Target file not found.";
switch (this.ajaxHandle.readyState) {
case 1:
case 2:
case 3:
if (this.timestamp() - this.StartTime < 1E3 * this.nTimeout) {
if (!this.bReadyStateChangeSupported) {
var a = this;
setTimeout(function () {
a.checkWait()
}, 1)
}
} else throw "Timeout was reached by " + (this.timestamp() - this.StartTime) / 1E3 + " seconds.";
break;
case 4:
this.lookupResponse()
}
}
} catch (b) {
this.errorCaught(b)
}
};
function iFrameMethod(a) {
this.XHRVars = a;
this.formElement = this.iframe = this.responseHTML = this.responseXML = null;
this.count = 0;
this.cleaned = !1
}
iFrameMethod.prototype.generateFrame = function () {
for (; null != document.getElementById("iframe_" + this.count);) this.count++;
this.iframe = document.createElement("iframe");
this.hide(this.iframe);
0 == this.XHRVars.aSelectedPost.length ? this.iframe.src = this.XHRVars.sSelectedURL + this.XHRVars.composeGET() : (this.iframe.id = "iframe_" + this.count, this.iframe.name = "iframe_" + this.count, this.formSetup());
var a = this;
"undefined" != typeof this.iframe.attachEvent ? this.iframe.attachEvent("onload", function () {
a.populateXHR()
}) : "undefined" != typeof this.iframe.onreadystatechange ? this.iframe.onreadystatechange = function () {
a.populateXHR()
} : "undefined" != typeof this.iframe.addEventListener ? this.iframe.addEventListener("load", function () {
a.populateXHR()
}, !1) : this.iframe.onload = function () {
a.populateXHR()
};
document.getElementsByTagName("body")[0].appendChild(this.iframe);
null != this.formElement && ("object" == typeof window.self && null != window.self && ("object" == typeof window.self.frames && null != window.self.frames && "object" == typeof window.self.frames["iframe_" + this.count] && null != window.self.frames["iframe_" + this.count] && window.self.frames["iframe_" + this.count].name != "iframe_" + this.count) && (window.self.frames["iframe_" + this.count].name = "iframe_" + this.count), this.formElement.submit());
setTimeout(function () {
a.errorMessage("iFrame failed to load.")
}, 1E3 * a.XHRVars.nTimeout)
};
iFrameMethod.prototype.formSetup = function () {
this.formElement = document.createElement("form");
this.hide(this.formElement);
this.formElement.action = this.XHRVars.sSelectedURL + this.XHRVars.composeGET();
this.formElement.method = "post";
this.formElement.target = "iframe_" + this.count;
for (var a = this.XHRVars.aSelectedPost, b = 0; b < a.length; b++) {
var c = document.createElement("input");
this.hide(c);
c.type = "hidden";
var e = a[b].split("=");
c.name = unescape(e[0]);
c.value = unescape(e[1]);
this.formElement.appendChild(c)
}
document.getElementsByTagName("body")[0].appendChild(this.formElement)
};
iFrameMethod.prototype.hide = function (a) {
a.style.visibility = "hidden";
a.style.height = "0px";
a.style.width = "0px";
a.margin = "0px";
a.padding = "0px";
a.style.zIndex = 1E5;
a.style.position = "absolute";
a.style.top = "0px";
a.style.left = "0px"
};
iFrameMethod.prototype.errorMessage = function (a) {
1 == this.XHRVars.Status && this.XHRVars.errorCaught(a)
};
iFrameMethod.prototype.finish = function () {
if (1 == this.XHRVars.Status && !this.cleaned) {
this.clean();
try {
this.XHRVars.lookupResponse()
} catch (a) {
this.errorMessage(a)
}
}
};
iFrameMethod.prototype.abort = function () {
this.clean()
};
iFrameMethod.prototype.clean = function () {
!this.cleaned && null != this.iframe && (this.cleaned = !0, null != this.formElement && this.formElement.parentNode.removeChild(this.formElement))
};
iFrameMethod.prototype.isHTML = function (a) {
return null != a && null != a.documentElement && "HTML" == a.documentElement.nodeName.toUpperCase() && 1 == a.getElementsByTagName("body").length ? !0 : !1
};
iFrameMethod.prototype.populateXHR = function () {
try {
if (null != this.iframe && !this.cleaned) {
if (1 == this.XHRVars.Status) {
var a = this;
if ("undefined" != typeof this.iframe.readyState) {
if ("complete" != this.iframe.readyState) {
setTimeout(function () {
a.populateXHR()
}, 1);
return
}
} else if ("undefined" != typeof this.iframe.contentDocument.readyState && "complete" != this.iframe.contentDocument.readyState) {
setTimeout(function () {
a.populateXHR()
}, 1);
return
}
"undefined" != typeof this.iframe.contentWindow ? "undefined" != typeof this.iframe.contentWindow.document ? (this.responseHTML = this.iframe.contentWindow.document, "undefined" != typeof this.iframe.contentWindow.document.XMLDocument ? this.responseXML = this.iframe.contentWindow.document.XMLDocument : "undefined" != typeof this.iframe.contentDocument && (this.responseXML = this.iframe.contentDocument)) : "undefined" != typeof this.iframe.contentDocument && (this.responseXML = this.iframe.contentDocument) : "undefined" != typeof this.iframe.contentDocument && (this.responseXML = this.iframe.contentDocument);
null != this.responseXML && null == this.responseHTML && (this.responseHTML = this.responseXML);
if (null != this.responseXML) if (this.responseXML.hasChildNodes()) this.isHTML(this.responseXML) ? "HTML" == this.XHRVars.sSelectedAcceptType && this.isHTML(this.responseHTML) ? setTimeout(function () {
a.finish()
}, a.XHRVars.nIFrameSafeTimeout) : "undefined" != typeof this.iframe.contentDocument.readyState || "undefined" != typeof this.iframe.readyState ? setTimeout(function () {
a.populateXHR()
}, 1) : setTimeout(function () {
a.populateXHR()
}, a.XHRVars.nIFrameSafeTimeout) : this.finish();
else throw "Browser does not support ajax (DOM did not have root node).";
else if (this.isHTML(this.responseHTML)) setTimeout(function () {
a.finish()
}, a.XHRVars.nIFrameSafeTimeout);
else throw "Browser does not support ajax (DOM was null).";
}
} else throw "Browser does not support ajax (iframe was null).";
} catch (b) {
this.errorMessage(b)
}
};
this.JSON || (this.JSON = {});
(function () {
function a(a) {
return a < 10 ? "0" + a : a
}
function b(a) {
f.lastIndex = 0;
return f.test(a) ? '"' + a.replace(f, function (a) {
var b = h[a];
return typeof b === "string" ? b : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
}) + '"' : '"' + a + '"'
}
function c(a, f) {
var e, h, t, u, z = g,
r, o = f[a];
o && (typeof o === "object" && typeof o.toJSON === "function") && (o = o.toJSON(a));
typeof i === "function" && (o = i.call(f, a, o));
switch (typeof o) {
case "string":
return b(o);
case "number":
return isFinite(o) ? "" + o : "null";
case "boolean":
case "null":
return "" + o;
case "object":
if (!o) return "null";
g = g + d;
r = [];
if (Object.prototype.toString.apply(o) === "[object Array]") {
u = o.length;
for (e = 0; e < u; e = e + 1) r[e] = c(e, o) || "null";
t = r.length === 0 ? "[]" : g ? "[\n" + g + r.join(",\n" + g) + "\n" + z + "]" : "[" + r.join(",") + "]";
g = z;
return t
}
if (i && typeof i === "object") {
u = i.length;
for (e = 0; e < u; e = e + 1) {
h = i[e];
if (typeof h === "string")(t = c(h, o)) && r.push(b(h) + (g ? ": " : ":") + t)
}
} else for (h in o) if (Object.hasOwnProperty.call(o, h))(t = c(h, o)) && r.push(b(h) + (g ? ": " : ":") + t);
t = r.length === 0 ? "{}" : g ? "{\n" + g + r.join(",\n" + g) + "\n" + z + "}" : "{" + r.join(",") + "}";
g = z;
return t
}
}
if (typeof Date.prototype.toJSON !== "function") {
Date.prototype.toJSON = function () {
return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + a(this.getUTCMonth() + 1) + "-" + a(this.getUTCDate()) + "T" + a(this.getUTCHours()) + ":" + a(this.getUTCMinutes()) + ":" + a(this.getUTCSeconds()) + "Z" : null
};
String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function () {
return this.valueOf()
}
}
var e = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
f = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
g, d, h = {
"\u0008": "\\b",
"\t": "\\t",
"\n": "\\n",
"\u000c": "\\f",
"\r": "\\r",
'"': '\\"',
"\\": "\\\\"
},
i;
if (typeof JSON.stringify !== "function") JSON.stringify = function (a, b, e) {
var f;
d = g = "";
if (typeof e === "number") for (f = 0; f < e; f = f + 1) d = d + " ";
else typeof e === "string" && (d = e);
if ((i = b) && typeof b !== "function" && (typeof b !== "object" || typeof b.length !== "number")) throw Error("JSON.stringify");
return c("", {
"": a
})
};
if (typeof JSON.parse !== "function") JSON.parse = function (a, b) {
function c(a, d) {
var e, f, g = a[d];
if (g && typeof g === "object") for (e in g) if (Object.hasOwnProperty.call(g, e)) {
f = c(g, e);
f !== void 0 ? g[e] = f : delete g[e]
}
return b.call(a, d, g)
}
var d, a = "" + a;
e.lastIndex = 0;
e.test(a) && (a = a.replace(e, function (a) {
return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
}));
if (/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
d = eval("(" + a + ")");
return typeof b === "function" ? c({
"": d
}, "") : d
}
throw new SyntaxError("JSON.parse");
}
})();
var swfobject = function () {
function a() {
if (!A) {
try {
var a = m.getElementsByTagName("body")[0].appendChild(m.createElement("span"));
a.parentNode.removeChild(a)
} catch (b) {
return
}
A = true;
for (var a = D.length, c = 0; c < a; c++) D[c]()
}
}
function b(a) {
A ? a() : D[D.length] = a
}
function c(a) {
if (typeof s.addEventListener != p) s.addEventListener("load", a, false);
else if (typeof m.addEventListener != p) m.addEventListener("load", a, false);
else if (typeof s.attachEvent != p) t(s, "onload", a);
else if (typeof s.onload == "function") {
var b = s.onload;
s.onload = function () {
b();
a()
}
} else s.onload = a
}
function e() {
var a = m.getElementsByTagName("body")[0],
b = m.createElement(v);
b.setAttribute("type", E);
var c = a.appendChild(b);
if (c) {
var d = 0;
(function () {
if (typeof c.GetVariable != p) {
var e = c.GetVariable("$version");
if (e) {
e = e.split(" ")[1].split(",");
k.pv = [parseInt(e[0], 10), parseInt(e[1], 10), parseInt(e[2], 10)]
}
} else if (d < 10) {
d++;
setTimeout(arguments.callee, 10);
return
}
a.removeChild(b);
c = null;
f()
})()
} else f()
}
function f() {
var a = x.length;
if (a > 0) for (var b = 0; b < a; b++) {
var c = x[b].id,
e = x[b].callbackFn,
f = {
success: false,
id: c
};
if (k.pv[0] > 0) {
var j = n(c);
if (j) if (u(x[b].swfVersion) && !(k.wk && k.wk < 312)) {
r(c, true);
if (e) {
f.success = true;
f.ref = g(c);
e(f)
}
} else if (x[b].expressInstall && d()) {
f = {};
f.data = x[b].expressInstall;
f.width = j.getAttribute("width") || "0";
f.height = j.getAttribute("height") || "0";
if (j.getAttribute("class")) f.styleclass = j.getAttribute("class");
if (j.getAttribute("align")) f.align = j.getAttribute("align");
for (var l = {}, j = j.getElementsByTagName("param"), m = j.length, o = 0; o < m; o++) j[o].getAttribute("name").toLowerCase() != "movie" && (l[j[o].getAttribute("name")] = j[o].getAttribute("value"));
h(f, l, c, e)
} else {
i(j);
e && e(f)
}
} else {
r(c, true);
if (e) {
if ((c = g(c)) && typeof c.SetVariable != p) {
f.success = true;
f.ref = c
}
e(f)
}
}
}
}
function g(a) {
var b = null;
if ((a = n(a)) && a.nodeName == "OBJECT") if (typeof a.SetVariable != p) b = a;
else(a = a.getElementsByTagName(v)[0]) && (b = a);
return b
}
function d() {
return !F && u("6.0.65") && (k.win || k.mac) && !(k.wk && k.wk < 312)
}
function h(a, b, c, d) {
F = true;
I = d || null;
K = {
success: false,
id: c
};
var e = n(c);
if (e) {
if (e.nodeName == "OBJECT") {
C = j(e);
G = null
} else {
C = e;
G = c
}
a.id = L;
if (typeof a.width == p || !/%$/.test(a.width) && parseInt(a.width, 10) < 310) a.width = "310";
if (typeof a.height == p || !/%$/.test(a.height) && parseInt(a.height, 10) < 137) a.height = "137";
m.title = m.title.slice(0, 47) + " - Flash Player Installation";
d = k.ie && k.win ? "ActiveX" : "PlugIn";
d = "MMredirectURL=" + s.location.toString().replace(/&/g, "%26") + "&MMplayerType=" + d + "&MMdoctitle=" + m.title;
b.flashvars = typeof b.flashvars != p ? b.flashvars + ("&" + d) : d;
if (k.ie && k.win && e.readyState != 4) {
d = m.createElement("div");
c = c + "SWFObjectNew";
d.setAttribute("id", c);
e.parentNode.insertBefore(d, e);
e.style.display = "none";
(function () {
e.readyState == 4 ? e.parentNode.removeChild(e) : setTimeout(arguments.callee, 10)
})()
}
q(a, b, c)
}
}
function i(a) {
if (k.ie && k.win && a.readyState != 4) {
var b = m.createElement("div");
a.parentNode.insertBefore(b, a);
b.parentNode.replaceChild(j(a), b);
a.style.display = "none";
(function () {
a.readyState == 4 ? a.parentNode.removeChild(a) : setTimeout(arguments.callee, 10)
})()
} else a.parentNode.replaceChild(j(a), a)
}
function j(a) {
var b = m.createElement("div");
if (k.win && k.ie) b.innerHTML = a.innerHTML;
else if (a = a.getElementsByTagName(v)[0]) if (a = a.childNodes) for (var c = a.length, d = 0; d < c; d++)!(a[d].nodeType == 1 && a[d].nodeName == "PARAM") && a[d].nodeType != 8 && b.appendChild(a[d].cloneNode(true));
return b
}
function q(a, b, c) {
var d, e = n(c);
if (k.wk && k.wk < 312) return d;
if (e) {
if (typeof a.id == p) a.id = c;
if (k.ie && k.win) {
var f = "",
g;
for (g in a) if (a[g] != Object.prototype[g]) g.toLowerCase() == "data" ? b.movie = a[g] : g.toLowerCase() == "styleclass" ? f = f + (' class="' + a[g] + '"') : g.toLowerCase() != "classid" && (f = f + (" " + g + '="' + a[g] + '"'));
g = "";
for (var h in b) b[h] != Object.prototype[h] && (g = g + ('<param name="' + h + '" value="' + b[h] + '" />'));
e.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + f + ">" + g + "</object>";
H[H.length] = a.id;
d = n(a.id)
} else {
h = m.createElement(v);
h.setAttribute("type", E);
for (var i in a) a[i] != Object.prototype[i] && (i.toLowerCase() == "styleclass" ? h.setAttribute("class", a[i]) : i.toLowerCase() != "classid" && h.setAttribute(i, a[i]));
for (f in b) if (b[f] != Object.prototype[f] && f.toLowerCase() != "movie") {
a = h;
g = f;
i = b[f];
c = m.createElement("param");
c.setAttribute("name", g);
c.setAttribute("value", i);
a.appendChild(c)
}
e.parentNode.replaceChild(h, e);
d = h
}
}
return d
}
function l(a) {
var b = n(a);
if (b && b.nodeName == "OBJECT") if (k.ie && k.win) {
b.style.display = "none";
(function () {
if (b.readyState == 4) {
var c = n(a);
if (c) {
for (var d in c) typeof c[d] == "function" && (c[d] = null);
c.parentNode.removeChild(c)
}
} else setTimeout(arguments.callee, 10)
})()
} else b.parentNode.removeChild(b)
}
function n(a) {
var b = null;
try {
b = m.getElementById(a)
} catch (c) {}
return b
}
function t(a, b, c) {
a.attachEvent(b, c);
B[B.length] = [a, b, c]
}
function u(a) {
var b = k.pv,
a = a.split(".");
a[0] = parseInt(a[0], 10);
a[1] = parseInt(a[1], 10) || 0;
a[2] = parseInt(a[2], 10) || 0;
return b[0] > a[0] || b[0] == a[0] && b[1] > a[1] || b[0] == a[0] && b[1] == a[1] && b[2] >= a[2] ? true : false
}
function z(a, b, c, d) {
if (!k.ie || !k.mac) {
var e = m.getElementsByTagName("head")[0];
if (e) {
c = c && typeof c == "string" ? c : "screen";
if (d) J = w = null;
if (!w || J != c) {
d = m.createElement("style");
d.setAttribute("type", "text/css");
d.setAttribute("media", c);
w = e.appendChild(d);
k.ie && (k.win && typeof m.styleSheets != p && m.styleSheets.length > 0) && (w = m.styleSheets[m.styleSheets.length - 1]);
J = c
}
k.ie && k.win ? w && typeof w.addRule == v && w.addRule(a, b) : w && typeof m.createTextNode != p && w.appendChild(m.createTextNode(a + " {" + b + "}"))
}
}
}
function r(a, b) {
if (M) {
var c = b ? "visible" : "hidden";
A && n(a) ? n(a).style.visibility = c : z("#" + a, "visibility:" + c)
}
}
function o(a) {
return /[\\\"<>\.;]/.exec(a) != null && typeof encodeURIComponent != p ? encodeURIComponent(a) : a
}
var p = "undefined",
v = "object",
E = "application/x-shockwave-flash",
L = "SWFObjectExprInst",
s = window,
m = document,
y = navigator,
N = false,
D = [function () {
N ? e() : f()
}],
x = [],
H = [],
B = [],
C, G, I, K, A = false,
F = false,
w, J, M = true,
k = function () {
var a = typeof m.getElementById != p && typeof m.getElementsByTagName != p && typeof m.createElement != p,
b = y.userAgent.toLowerCase(),
c = y.platform.toLowerCase(),
d = c ? /win/.test(c) : /win/.test(b),
c = c ? /mac/.test(c) : /mac/.test(b),
b = /webkit/.test(b) ? parseFloat(b.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
e = !+"\v1",
f = [0, 0, 0],
g = null;
if (typeof y.plugins != p && typeof y.plugins["Shockwave Flash"] == v) {
if ((g = y.plugins["Shockwave Flash"].description) && !(typeof y.mimeTypes != p && y.mimeTypes[E] && !y.mimeTypes[E].enabledPlugin)) {
N = true;
e = false;
g = g.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
f[0] = parseInt(g.replace(/^(.*)\..*$/, "$1"), 10);
f[1] = parseInt(g.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
f[2] = /[a-zA-Z]/.test(g) ? parseInt(g.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0
}
} else if (typeof s.ActiveXObject != p) try {
var h = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
if (h) if (g = h.GetVariable("$version")) {
e = true;
g = g.split(" ")[1].split(",");
f = [parseInt(g[0], 10), parseInt(g[1], 10), parseInt(g[2], 10)]
}
} catch (i) {}
return {
w3: a,
pv: f,
wk: b,
ie: e,
win: d,
mac: c
}
}();
(function () {
if (k.w3) {
(typeof m.readyState != p && m.readyState == "complete" || typeof m.readyState == p && (m.getElementsByTagName("body")[0] || m.body)) && a();
if (!A) {
typeof m.addEventListener != p && m.addEventListener("DOMContentLoaded", a, false);
if (k.ie && k.win) {
m.attachEvent("onreadystatechange", function () {
if (m.readyState == "complete") {
m.detachEvent("onreadystatechange", arguments.callee);
a()
}
});
s == top &&
function () {
if (!A) {
try {
m.documentElement.doScroll("left")
} catch (b) {
setTimeout(arguments.callee, 0);
return
}
a()
}
}()
}
k.wk &&
function () {
A || (/loaded|complete/.test(m.readyState) ? a() : setTimeout(arguments.callee, 0))
}();
c(a)
}
}
})();
(function () {
k.ie && k.win && window.attachEvent("onunload", function () {
for (var a = B.length, b = 0; b < a; b++) B[b][0].detachEvent(B[b][1], B[b][2]);
a = H.length;
for (b = 0; b < a; b++) l(H[b]);
for (var c in k) k[c] = null;
k = null;
for (var d in swfobject) swfobject[d] = null;
swfobject = null
})
})();
return {
registerObject: function (a, b, c, d) {
if (k.w3 && a && b) {
var e = {};
e.id = a;
e.swfVersion = b;
e.expressInstall = c;
e.callbackFn = d;
x[x.length] = e;
r(a, false)
} else d && d({
success: false,
id: a
})
},
getObjectById: function (a) {
if (k.w3) return g(a)
},
embedSWF: function (a, c, e, f, g, i, j, l, n, m) {
var o = {
success: false,
id: c
};
if (k.w3 && !(k.wk && k.wk < 312) && a && c && e && f && g) {
r(c, false);
b(function () {
e = e + "";
f = f + "";
var b = {};
if (n && typeof n === v) for (var k in n) b[k] = n[k];
b.data = a;
b.width = e;
b.height = f;
k = {};
if (l && typeof l === v) for (var s in l) k[s] = l[s];
if (j && typeof j === v) for (var t in j) k.flashvars = typeof k.flashvars != p ? k.flashvars + ("&" + t + "=" + j[t]) : t + "=" + j[t];
if (u(g)) {
s = q(b, k, c);
b.id == c && r(c, true);
o.success = true;
o.ref = s
} else {
if (i && d()) {
b.data = i;
h(b, k, c, m);
return
}
r(c, true)
}
m && m(o)
})
} else m && m(o)
},
switchOffAutoHideShow: function () {
M = false
},
ua: k,
getFlashPlayerVersion: function () {
return {
major: k.pv[0],
minor: k.pv[1],
release: k.pv[2]
}
},
hasFlashPlayerVersion: u,
createSWF: function (a, b, c) {
if (k.w3) return q(a, b, c)
},
showExpressInstall: function (a, b, c, e) {
k.w3 && d() && h(a, b, c, e)
},
removeSWF: function (a) {
k.w3 && l(a)
},
createCSS: function (a, b, c, d) {
k.w3 && z(a, b, c, d)
},
addDomLoadEvent: b,
addLoadEvent: c,
getQueryParamValue: function (a) {
var b = m.location.search || m.location.hash;
if (b) {
/\?/.test(b) && (b = b.split("?")[1]);
if (a == null) return o(b);
for (var b = b.split("&"), c = 0; c < b.length; c++) if (b[c].substring(0, b[c].indexOf("=")) == a) return o(b[c].substring(b[c].indexOf("=") + 1))
}
return ""
},
expressInstallCallback: function () {
if (F) {
var a = n(L);
if (a && C) {
a.parentNode.replaceChild(C, a);
if (G) {
r(G, true);
if (k.ie && k.win) C.style.display = "block"
}
I && I(K)
}
F = false
}
}
}
}();
function Resampler(a, b, c, e, f) {
this.fromSampleRate = a;
this.toSampleRate = b;
this.channels = c | 0;
this.outputBufferSize = e;
this.noReturn = !! f;
this.initialize()
}
Resampler.prototype.initialize = function () {
if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) if (this.fromSampleRate == this.toSampleRate) {
this.resampler = this.bypassResampler;
this.ratioWeight = 1
} else {
if (this.fromSampleRate < this.toSampleRate) {
this.compileLinearInterpolationFunction();
this.lastWeight = 1
} else {
this.compileMultiTapFunction();
this.tailExists = false;
this.lastWeight = 0
}
this.ratioWeight = this.fromSampleRate / this.toSampleRate;
this.initializeBuffers()
} else throw Error("Invalid settings specified for the resampler.");
};
Resampler.prototype.compileLinearInterpolationFunction = function () {
for (var a = "var bufferLength = buffer.length;var outLength = this.outputBufferSize;if ((bufferLength % " + this.channels + ") == 0) {if (bufferLength > 0) {var ratioWeight = this.ratioWeight;var weight = this.lastWeight;var firstWeight = 0;var secondWeight = 0;var sourceOffset = 0;var outputOffset = 0;var outputBuffer = this.outputBuffer;for (; weight < 1; weight += ratioWeight) {secondWeight = weight % 1;firstWeight = 1 - secondWeight;", b = 0; b < this.channels; ++b) a = a + ("outputBuffer[outputOffset++] = (this.lastOutput[" + b + "] * firstWeight) + (buffer[" + b + "] * secondWeight);");
a = a + ("}weight -= 1;for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; outputOffset < outLength && sourceOffset < bufferLength;) {secondWeight = weight % 1;firstWeight = 1 - secondWeight;");
for (b = 0; b < this.channels; ++b) a = a + ("outputBuffer[outputOffset++] = (buffer[sourceOffset" + (b > 0 ? " + " + b : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + b) + "] * secondWeight);");
a = a + ("weight += ratioWeight;sourceOffset = Math.floor(weight) * " + this.channels + ";}");
for (b = 0; b < this.channels; ++b) a = a + ("this.lastOutput[" + b + "] = buffer[sourceOffset++];");
this.resampler = Function("buffer", a + 'this.lastWeight = weight % 1;return this.bufferSlice(outputOffset);}else {return (this.noReturn) ? 0 : [];}}else {throw(new Error("Buffer was of incorrect sample length."));}')
};
Resampler.prototype.compileMultiTapFunction = function () {
for (var a = "var bufferLength = buffer.length;var outLength = this.outputBufferSize;if ((bufferLength % " + this.channels + ") == 0) {if (bufferLength > 0) {var ratioWeight = this.ratioWeight;var weight = 0;", b = 0; b < this.channels; ++b) a = a + ("var output" + b + " = 0;");
a = a + "var actualPosition = 0;var amountToNext = 0;var alreadyProcessedTail = !this.tailExists;this.tailExists = false;var outputBuffer = this.outputBuffer;var outputOffset = 0;var currentPosition = 0;do {if (alreadyProcessedTail) {weight = ratioWeight;";
for (b = 0; b < this.channels; ++b) a = a + ("output" + b + " = 0;");
a = a + "}else {weight = this.lastWeight;";
for (b = 0; b < this.channels; ++b) a = a + ("output" + b + " = this.lastOutput[" + b + "];");
a = a + "alreadyProcessedTail = true;}while (weight > 0 && actualPosition < bufferLength) {amountToNext = 1 + actualPosition - currentPosition;if (weight >= amountToNext) {";
for (b = 0; b < this.channels; ++b) a = a + ("output" + b + " += buffer[actualPosition++] * amountToNext;");
a = a + "currentPosition = actualPosition;weight -= amountToNext;}else {";
for (b = 0; b < this.channels; ++b) a = a + ("output" + b + " += buffer[actualPosition" + (b > 0 ? " + " + b : "") + "] * weight;");
a = a + "currentPosition += weight;weight = 0;break;}}if (weight == 0) {";
for (b = 0; b < this.channels; ++b) a = a + ("outputBuffer[outputOffset++] = output" + b + " / ratioWeight;");
a = a + "}else {this.lastWeight = weight;";
for (b = 0; b < this.channels; ++b) a = a + ("this.lastOutput[" + b + "] = output" + b + ";");
this.resampler = Function("buffer", a + 'this.tailExists = true;break;}} while (actualPosition < bufferLength && outputOffset < outLength);return this.bufferSlice(outputOffset);}else {return (this.noReturn) ? 0 : [];}}else {throw(new Error("Buffer was of incorrect sample length."));}')
};
Resampler.prototype.bypassResampler = function (a) {
if (this.noReturn) {
this.outputBuffer = a;
return a.length
}
return a
};
Resampler.prototype.bufferSlice = function (a) {
if (this.noReturn) return a;
try {
return this.outputBuffer.subarray(0, a)
} catch (b) {
try {
this.outputBuffer.length = a;
return this.outputBuffer
} catch (c) {
return this.outputBuffer.slice(0, a)
}
}
};
Resampler.prototype.initializeBuffers = function () {
try {
this.outputBuffer = new Float32Array(this.outputBufferSize);
this.lastOutput = new Float32Array(this.channels)
} catch (a) {
this.outputBuffer = [];
this.lastOutput = []
}
};
function XAudioServer(a, b, c, e, f, g) {
this.audioChannels = a == 2 ? 2 : 1;
webAudioMono = this.audioChannels == 1;
XAudioJSSampleRate = Math.abs(b);
webAudioMinBufferSize = c >= samplesPerCallback << this.audioChannels - 1 && c < e ? c & -this.audioChannels : samplesPerCallback << this.audioChannels - 1;
webAudioMaxBufferSize = Math.floor(e) > webAudioMinBufferSize + this.audioChannels ? e & -this.audioChannels : c << this.audioChannels - 1;
this.underRunCallback = typeof f == "function" ? f : function () {};
XAudioJSVolume = g >= 0 && g <= 1 ? g : 1;
this.audioType = -1;
this.mozAudioTail = [];
this.audioHandleFlash = this.audioHandleMoz = null;
this.mozAudioFound = this.flashInitialized = false;
this.initializeAudio()
}
XAudioServer.prototype.MOZWriteAudio = function (a) {
this.MOZWriteAudioNoCallback(a);
this.MOZExecuteCallback()
};
XAudioServer.prototype.MOZWriteAudioNoCallback = function (a) {
this.writeMozAudio(a)
};
XAudioServer.prototype.callbackBasedWriteAudio = function (a) {
this.callbackBasedWriteAudioNoCallback(a);
this.callbackBasedExecuteCallback()
};
XAudioServer.prototype.callbackBasedWriteAudioNoCallback = function (a) {
for (var b = a.length, c = 0; c < b && audioBufferSize < webAudioMaxBufferSize;) audioContextSampleBuffer[audioBufferSize++] = a[c++]
};
XAudioServer.prototype.writeAudio = function (a) {
this.audioType == 0 ? this.MOZWriteAudio(a) : this.audioType == 1 ? this.callbackBasedWriteAudio(a) : this.audioType == 2 && (this.checkFlashInit() || launchedContext ? this.callbackBasedWriteAudio(a) : this.mozAudioFound && this.MOZWriteAudio(a))
};
XAudioServer.prototype.writeAudioNoCallback = function (a) {
this.audioType == 0 ? this.MOZWriteAudioNoCallback(a) : this.audioType == 1 ? this.callbackBasedWriteAudioNoCallback(a) : this.audioType == 2 && (this.checkFlashInit() || launchedContext ? this.callbackBasedWriteAudioNoCallback(a) : this.mozAudioFound && this.MOZWriteAudioNoCallback(a))
};
XAudioServer.prototype.remainingBuffer = function () {
if (this.audioType == 0) return this.samplesAlreadyWritten - this.audioHandleMoz.mozCurrentSampleOffset();
if (this.audioType == 1) return (resampledSamplesLeft() * resampleControl.ratioWeight >> this.audioChannels - 1 << this.audioChannels - 1) + audioBufferSize;
if (this.audioType == 2) {
if (this.checkFlashInit() || launchedContext) return (resampledSamplesLeft() * resampleControl.ratioWeight >> this.audioChannels - 1 << this.audioChannels - 1) + audioBufferSize;
if (this.mozAudioFound) return this.samplesAlreadyWritten - this.audioHandleMoz.mozCurrentSampleOffset()
}
return 0
};
XAudioServer.prototype.MOZExecuteCallback = function () {
var a = webAudioMinBufferSize - this.remainingBuffer();
a > 0 && this.writeMozAudio(this.underRunCallback(a))
};
XAudioServer.prototype.callbackBasedExecuteCallback = function () {
var a = webAudioMinBufferSize - this.remainingBuffer();
a > 0 && this.callbackBasedWriteAudioNoCallback(this.underRunCallback(a))
};
XAudioServer.prototype.executeCallback = function () {
this.audioType == 0 ? this.MOZExecuteCallback() : this.audioType == 1 ? this.callbackBasedExecuteCallback() : this.audioType == 2 && (this.checkFlashInit() || launchedContext ? this.callbackBasedExecuteCallback() : this.mozAudioFound && this.MOZExecuteCallback())
};
XAudioServer.prototype.initializeAudio = function () {
try {
this.preInitializeMozAudio();
if (navigator.platform == "Linux i686") throw Error("");
this.initializeMozAudio()
} catch (a) {
try {
this.initializeWebAudio()
} catch (b) {
try {
this.initializeFlashAudio()
} catch (c) {
throw Error("Browser does not support real time audio output.");
}
}
}
};
XAudioServer.prototype.preInitializeMozAudio = function () {
this.audioHandleMoz = new Audio;
this.audioHandleMoz.mozSetup(this.audioChannels, XAudioJSSampleRate);
this.samplesAlreadyWritten = 0;
var a = this.audioChannels == 2 ? [0, 0] : [0],
b = 0;
if (navigator.platform != "MacIntel" && navigator.platform != "MacPPC") {
for (; this.audioHandleMoz.mozCurrentSampleOffset() == 0;) b = b + this.audioHandleMoz.mozWriteAudio(a);
for (var c = b / this.audioChannels, e = 0; e < c; e++) this.samplesAlreadyWritten = this.samplesAlreadyWritten + this.audioHandleMoz.mozWriteAudio(a)
}
this.samplesAlreadyWritten = this.samplesAlreadyWritten + b;
webAudioMinBufferSize = webAudioMinBufferSize + this.samplesAlreadyWritten;
this.mozAudioFound = true
};
XAudioServer.prototype.initializeMozAudio = function () {
this.writeMozAudio(getFloat32(webAudioMinBufferSize));
this.audioType = 0
};
XAudioServer.prototype.initializeWebAudio = function () {
if (launchedContext) {
resetCallbackAPIAudioBuffer(webAudioActualSampleRate, samplesPerCallback);
this.audioType = 1
} else throw Error("");
};
XAudioServer.prototype.initializeFlashAudio = function () {
var a = document.getElementById("XAudioJS");
if (a == null) {
var b = this,
a = document.createElement("div");
a.setAttribute("style", "position: fixed; bottom: 0px; right: 0px; margin: 0px; padding: 0px; border: none; width: 8px; height: 8px; overflow: hidden; z-index: -1000; ");
var c = document.createElement("div");
c.setAttribute("style", "position: static; border: none; width: 0px; height: 0px; visibility: hidden; margin: 8px; padding: 0px;");
c.setAttribute("id", "XAudioJS");
a.appendChild(c);
document.getElementsByTagName("body")[0].appendChild(a);
swfobject.embedSWF("XAudioJS.swf", "XAudioJS", "8", "8", "9.0.0", "", {}, {
allowscriptaccess: "always"
}, {
style: "position: static; visibility: hidden; margin: 8px; padding: 0px; border: none"
}, function (a) {
a.success ? b.audioHandleFlash = a.ref : b.audioType = 1
})
} else this.audioHandleFlash = a;
this.audioType = 2
};
XAudioServer.prototype.changeVolume = function (a) {
if (a >= 0 && a <= 1) {
XAudioJSVolume = a;
this.checkFlashInit() && this.audioHandleFlash.changeVolume(XAudioJSVolume);
if (this.mozAudioFound) this.audioHandleMoz.volume = XAudioJSVolume
}
};
XAudioServer.prototype.writeMozAudio = function (a) {
var b = this.mozAudioTail.length;
if (b > 0) {
var c = this.audioHandleMoz.mozWriteAudio(this.mozAudioTail);
this.samplesAlreadyWritten = this.samplesAlreadyWritten + c;
this.mozAudioTail.splice(0, c)
}
b = Math.min(a.length, webAudioMaxBufferSize - this.samplesAlreadyWritten + this.audioHandleMoz.mozCurrentSampleOffset());
c = this.audioHandleMoz.mozWriteAudio(a);
this.samplesAlreadyWritten = this.samplesAlreadyWritten + c;
for (var e = 0; b > c; --b) this.mozAudioTail.push(a[e++])
};
XAudioServer.prototype.checkFlashInit = function () {
if (!this.flashInitialized && this.audioHandleFlash && this.audioHandleFlash.initialize) {
this.flashInitialized = true;
this.audioHandleFlash.initialize(this.audioChannels, XAudioJSVolume);
resetCallbackAPIAudioBuffer(44100, samplesPerCallback)
}
return this.flashInitialized
};
function getFloat32(a) {
try {
return new Float32Array(a)
} catch (b) {
return Array(a)
}
}
function getFloat32Flat(a) {
try {
var b = new Float32Array(a)
} catch (c) {
var b = Array(a),
e = 0;
do b[e] = 0;
while (++e < a)
}
return b
}
var samplesPerCallback = 2048,
outputConvert = null;
function audioOutputFlashEvent() {
resampleRefill();
return outputConvert()
}
function generateFlashStereoString() {
for (var a = "", b = "", c = 0; c < samplesPerCallback && resampleBufferStart != resampleBufferEnd; ++c) {
a = a + String.fromCharCode((Math.min(Math.max(resampled[resampleBufferStart++] + 1, 0), 2) * 16383 | 0) + 12288);
b = b + String.fromCharCode((Math.min(Math.max(resampled[resampleBufferStart++] + 1, 0), 2) * 16383 | 0) + 12288);
resampleBufferStart == resampleBufferSize && (resampleBufferStart = 0)
}
return a + b
}
function generateFlashMonoString() {
for (var a = "", b = 0; b < samplesPerCallback && resampleBufferStart != resampleBufferEnd; ++b) {
a = a + String.fromCharCode((Math.min(Math.max(resampled[resampleBufferStart++] + 1, 0), 2) * 16383 | 0) + 12288);
resampleBufferStart == resampleBufferSize && (resampleBufferStart = 0)
}
return a
}
var audioContextHandle = null,
audioNode = null,
audioSource = null,
launchedContext = !1,
audioContextSampleBuffer = [],
resampled = [],
webAudioMinBufferSize = 15E3,
webAudioMaxBufferSize = 25E3,
webAudioActualSampleRate = 44100,
XAudioJSSampleRate = 0,
webAudioMono = !1,
XAudioJSVolume = 1,
resampleControl = null,
audioBufferSize = 0,
resampleBufferStart = 0,
resampleBufferEnd = 0,
resampleBufferSize = 2;
function audioOutputEvent(a) {
var b = 0,
c = a.outputBuffer.getChannelData(0),
a = a.outputBuffer.getChannelData(1);
resampleRefill();
if (webAudioMono) for (; b < samplesPerCallback && resampleBufferStart != resampleBufferEnd;) {
a[b] = c[b] = resampled[resampleBufferStart++] * XAudioJSVolume;
++b;
resampleBufferStart == resampleBufferSize && (resampleBufferStart = 0)
} else for (; b < samplesPerCallback && resampleBufferStart != resampleBufferEnd;) {
c[b] = resampled[resampleBufferStart++] * XAudioJSVolume;
a[b++] = resampled[resampleBufferStart++] * XAudioJSVolume;
resampleBufferStart == resampleBufferSize && (resampleBufferStart = 0)
}
for (; b < samplesPerCallback;) {
a[b] = c[b] = 0;
++b
}
}
function resampleRefill() {
if (audioBufferSize > 0) {
for (var a = resampleControl.resampler(getBufferSamples()), b = resampleControl.outputBuffer, c = 0; c < a; ++c) {
resampled[resampleBufferEnd++] = b[c];
resampleBufferEnd == resampleBufferSize && (resampleBufferEnd = 0);
if (resampleBufferStart == resampleBufferEnd) {
++resampleBufferStart;
resampleBufferStart == resampleBufferSize && (resampleBufferStart = 0)
}
}
audioBufferSize = 0
}
}
function resampledSamplesLeft() {
return (resampleBufferStart <= resampleBufferEnd ? 0 : resampleBufferSize) + resampleBufferEnd - resampleBufferStart
}
function getBufferSamples() {
try {
return audioContextSampleBuffer.subarray(0, audioBufferSize)
} catch (a) {
try {
audioContextSampleBuffer.length = audioBufferSize;
return audioContextSampleBuffer
} catch (b) {
return audioContextSampleBuffer.slice(0, audioBufferSize)
}
}
}
function resetCallbackAPIAudioBuffer(a) {
audioContextSampleBuffer = getFloat32(webAudioMaxBufferSize);
audioBufferSize = resampleBufferEnd = resampleBufferStart = 0;
if (webAudioMono) {
resampleBufferSize = Math.max(webAudioMaxBufferSize * Math.ceil(a / XAudioJSSampleRate) + 1, samplesPerCallback);
resampleControl = new Resampler(XAudioJSSampleRate, a, 1, resampleBufferSize, true);
outputConvert = generateFlashMonoString
} else {
resampleBufferSize = Math.max(webAudioMaxBufferSize * Math.ceil(a / XAudioJSSampleRate) + 2, samplesPerCallback << 1);
resampleControl = new Resampler(XAudioJSSampleRate, a, 2, resampleBufferSize, true);
outputConvert = generateFlashStereoString
}
resampled = getFloat32Flat(resampleBufferSize)
}
(function () {
if (!launchedContext) {
try {
audioContextHandle = new webkitAudioContext
} catch (a) {
try {
audioContextHandle = new AudioContext
} catch (b) {
return
}
}
try {
audioSource = audioContextHandle.createBufferSource();
audioSource.loop = false;
XAudioJSSampleRate = webAudioActualSampleRate = audioContextHandle.sampleRate;
audioSource.buffer = audioContextHandle.createBuffer(1, 1, webAudioActualSampleRate);
audioNode = audioContextHandle.createJavaScriptNode(samplesPerCallback, 1, 2);
audioNode.onaudioprocess = audioOutputEvent;
audioSource.connect(audioNode);
audioNode.connect(audioContextHandle.destination);
audioSource.noteOn(0)
} catch (c) {
return
}
launchedContext = true
}
})();
function Resize(a, b, c, e, f, g) {
this.widthOriginal = Math.abs(parseInt(a) || 0);
this.heightOriginal = Math.abs(parseInt(b) || 0);
this.targetWidth = Math.abs(parseInt(c) || 0);
this.targetHeight = Math.abs(parseInt(e) || 0);
this.colorChannels = f ? 4 : 3;
this.interpolationPass = !! g;
this.targetWidthMultipliedByChannels = this.targetWidth * this.colorChannels;
this.originalWidthMultipliedByChannels = this.widthOriginal * this.colorChannels;
this.originalHeightMultipliedByChannels = this.heightOriginal * this.colorChannels;
this.widthPassResultSize = this.targetWidthMultipliedByChannels * this.heightOriginal;
this.finalResultSize = this.targetWidthMultipliedByChannels * this.targetHeight;
this.initialize()
}
Resize.prototype.initialize = function () {
if (this.widthOriginal > 0 && this.heightOriginal > 0 && this.targetWidth > 0 && this.targetHeight > 0) {
if (this.widthOriginal == this.targetWidth) this.resizeWidth = this.bypassResizer;
else {
this.ratioWeightWidthPass = this.widthOriginal / this.targetWidth;
if (this.ratioWeightWidthPass < 1 && this.interpolationPass) {
this.initializeFirstPassBuffers(true);
this.resizeWidth = this.colorChannels == 4 ? this.resizeWidthInterpolatedRGBA : this.resizeWidthInterpolatedRGB
} else {
this.initializeFirstPassBuffers(false);
this.resizeWidth = this.colorChannels == 4 ? this.resizeWidthRGBA : this.resizeWidthRGB
}
}
if (this.heightOriginal == this.targetHeight) this.resizeHeight = this.bypassResizer;
else {
this.ratioWeightHeightPass = this.heightOriginal / this.targetHeight;
if (this.ratioWeightHeightPass < 1 && this.interpolationPass) {
this.initializeSecondPassBuffers(true);
this.resizeHeight = this.resizeHeightInterpolated
} else {
this.initializeSecondPassBuffers(false);
this.resizeHeight = this.colorChannels == 4 ? this.resizeHeightRGBA : this.resizeHeightRGB
}
}
} else throw Error("Invalid settings specified for the resizer.");
};
Resize.prototype.resizeWidthRGB = function (a) {
var b = this.ratioWeightWidthPass,
c = 0,
e = 0,
f = 0,
g = 0,
d = 0,
h = 0,
i = 0,
j = this.originalWidthMultipliedByChannels - 2,
q = this.targetWidthMultipliedByChannels - 2,
l = this.outputWidthWorkBench,
n = this.widthBuffer;
do {
for (d = 0; d < this.originalHeightMultipliedByChannels;) {
l[d++] = 0;
l[d++] = 0;
l[d++] = 0
}
c = b;
do {
e = 1 + f - g;
if (c >= e) {
d = 0;
for (h = f; d < this.originalHeightMultipliedByChannels; h = h + j) {
l[d++] += a[h++] * e;
l[d++] += a[h++] * e;
l[d++] += a[h] * e
}
g = f = f + 3;
c = c - e
} else {
d = 0;
for (h = f; d < this.originalHeightMultipliedByChannels; h = h + j) {
l[d++] += a[h++] * c;
l[d++] += a[h++] * c;
l[d++] += a[h] * c
}
g = g + c;
break
}
} while (c > 0 && f < this.originalWidthMultipliedByChannels);
d = 0;
for (h = i; d < this.originalHeightMultipliedByChannels; h = h + q) {
n[h++] = l[d++] / b;
n[h++] = l[d++] / b;
n[h] = l[d++] / b
}
i = i + 3
} while (i < this.targetWidthMultipliedByChannels);
return n
};
Resize.prototype.resizeWidthInterpolatedRGB = function (a) {
for (var b = this.ratioWeightWidthPass, c = 0, e = 0, f = 0, g = 0, d = 0, h = this.widthBuffer, i = 0; c < 0.25; i = i + 3, c = c + b) {
e = i;
for (f = 0; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f];
h[e + 1] = a[f + 1];
h[e + 2] = a[f + 2]
}
}
for (var c = c - 0.25, j = this.widthOriginal - 1; c < j; i = i + 3, c = c + b) {
d = c % 1;
g = 1 - d;
e = i;
for (f = Math.floor(c) * 3; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f] * g + a[f + 3] * d;
h[e + 1] = a[f + 1] * g + a[f + 4] * d;
h[e + 2] = a[f + 2] * g + a[f + 5] * d
}
}
for (j = this.originalWidthMultipliedByChannels - 3; i < this.targetWidthMultipliedByChannels; i = i + 3) {
e = i;
for (f = j; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f];
h[e + 1] = a[f + 1];
h[e + 2] = a[f + 2]
}
}
return h
};
Resize.prototype.resizeWidthRGBA = function (a) {
var b = this.ratioWeightWidthPass,
c = 0,
e = 0,
f = 0,
g = 0,
d = 0,
h = 0,
i = 0,
j = this.originalWidthMultipliedByChannels - 3,
q = this.targetWidthMultipliedByChannels - 3,
l = this.outputWidthWorkBench,
n = this.widthBuffer;
do {
for (d = 0; d < this.originalHeightMultipliedByChannels;) {
l[d++] = 0;
l[d++] = 0;
l[d++] = 0;
l[d++] = 0
}
c = b;
do {
e = 1 + f - g;
if (c >= e) {
d = 0;
for (h = f; d < this.originalHeightMultipliedByChannels; h = h + j) {
l[d++] += a[h++] * e;
l[d++] += a[h++] * e;
l[d++] += a[h++] * e;
l[d++] += a[h] * e
}
g = f = f + 4;
c = c - e
} else {
d = 0;
for (h = f; d < this.originalHeightMultipliedByChannels; h = h + j) {
l[d++] += a[h++] * c;
l[d++] += a[h++] * c;
l[d++] += a[h++] * c;
l[d++] += a[h] * c
}
g = g + c;
break
}
} while (c > 0 && f < this.originalWidthMultipliedByChannels);
d = 0;
for (h = i; d < this.originalHeightMultipliedByChannels; h = h + q) {
n[h++] = l[d++] / b;
n[h++] = l[d++] / b;
n[h++] = l[d++] / b;
n[h] = l[d++] / b
}
i = i + 4
} while (i < this.targetWidthMultipliedByChannels);
return n
};
Resize.prototype.resizeWidthInterpolatedRGBA = function (a) {
for (var b = this.ratioWeightWidthPass, c = 0, e = 0, f = 0, g = 0, d = 0, h = this.widthBuffer, i = 0; c < 0.25; i = i + 4, c = c + b) {
e = i;
for (f = 0; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f];
h[e + 1] = a[f + 1];
h[e + 2] = a[f + 2];
h[e + 3] = a[f + 3]
}
}
for (var c = c - 0.25, j = this.widthOriginal - 1; c < j; i = i + 4, c = c + b) {
d = c % 1;
g = 1 - d;
e = i;
for (f = Math.floor(c) * 4; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f] * g + a[f + 4] * d;
h[e + 1] = a[f + 1] * g + a[f + 5] * d;
h[e + 2] = a[f + 2] * g + a[f + 6] * d;
h[e + 3] = a[f + 3] * g + a[f + 7] * d
}
}
for (j = this.originalWidthMultipliedByChannels - 4; i < this.targetWidthMultipliedByChannels; i = i + 4) {
e = i;
for (f = j; e < this.widthPassResultSize; f = f + this.originalWidthMultipliedByChannels, e = e + this.targetWidthMultipliedByChannels) {
h[e] = a[f];
h[e + 1] = a[f + 1];
h[e + 2] = a[f + 2];
h[e + 3] = a[f + 3]
}
}
return h
};
Resize.prototype.resizeHeightRGB = function (a) {
var b = this.ratioWeightHeightPass,
c = 0,
e = 0,
f = 0,
g = 0,
d = 0,
h = 0,
i = this.outputHeightWorkBench,
j = this.heightBuffer;
do {
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
i[d++] = 0;
i[d++] = 0;
i[d++] = 0
}
c = b;
do {
e = 1 + f - g;
if (c >= e) {
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
i[d++] += a[f++] * e;
i[d++] += a[f++] * e;
i[d++] += a[f++] * e
}
g = f;
c = c - e
} else {
d = 0;
for (e = f; d < this.targetWidthMultipliedByChannels;) {
i[d++] += a[e++] * c;
i[d++] += a[e++] * c;
i[d++] += a[e++] * c
}
g = g + c;
break
}
} while (c > 0 && f < this.widthPassResultSize);
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
j[h++] = Math.round(i[d++] / b);
j[h++] = Math.round(i[d++] / b);
j[h++] = Math.round(i[d++] / b)
}
} while (h < this.finalResultSize);
return j
};
Resize.prototype.resizeHeightInterpolated = function (a) {
for (var b = this.ratioWeightHeightPass, c = 0, e = 0, f = 0, g = 0, d = 0, h = 0, i = 0, j = this.heightBuffer; c < 0.25; c = c + b) for (f = 0; f < this.targetWidthMultipliedByChannels;) j[e++] = a[f++];
for (var c = c - 0.25, q = this.heightOriginal - 1; c < q; c = c + b) {
i = c % 1;
h = 1 - i;
g = Math.floor(c) * this.targetWidthMultipliedByChannels;
d = g + this.targetWidthMultipliedByChannels;
for (f = 0; f < this.targetWidthMultipliedByChannels; ++f) j[e++] = a[g + f] * h + a[d + f] * i
}
for (; e < this.finalResultSize;) {
f = 0;
for (g = q * this.targetWidthMultipliedByChannels; f < this.targetWidthMultipliedByChannels; ++f) j[e++] = a[g++]
}
return j
};
Resize.prototype.resizeHeightRGBA = function (a) {
var b = this.ratioWeightHeightPass,
c = 0,
e = 0,
f = 0,
g = 0,
d = 0,
h = 0,
i = this.outputHeightWorkBench,
j = this.heightBuffer;
do {
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
i[d++] = 0;
i[d++] = 0;
i[d++] = 0;
i[d++] = 0
}
c = b;
do {
e = 1 + f - g;
if (c >= e) {
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
i[d++] += a[f++] * e;
i[d++] += a[f++] * e;
i[d++] += a[f++] * e;
i[d++] += a[f++] * e
}
g = f;
c = c - e
} else {
d = 0;
for (e = f; d < this.targetWidthMultipliedByChannels;) {
i[d++] += a[e++] * c;
i[d++] += a[e++] * c;
i[d++] += a[e++] * c;
i[d++] += a[e++] * c
}
g = g + c;
break
}
} while (c > 0 && f < this.widthPassResultSize);
for (d = 0; d < this.targetWidthMultipliedByChannels;) {
j[h++] = Math.round(i[d++] / b);
j[h++] = Math.round(i[d++] / b);
j[h++] = Math.round(i[d++] / b);
j[h++] = Math.round(i[d++] / b)
}
} while (h < this.finalResultSize);
return j
};
Resize.prototype.resize = function (a) {
return this.resizeHeight(this.resizeWidth(a))
};
Resize.prototype.bypassResizer = function (a) {
return a
};
Resize.prototype.initializeFirstPassBuffers = function (a) {
this.widthBuffer = this.generateFloatBuffer(this.widthPassResultSize);
if (!a) this.outputWidthWorkBench = this.generateFloatBuffer(this.originalHeightMultipliedByChannels)
};
Resize.prototype.initializeSecondPassBuffers = function (a) {
this.heightBuffer = this.generateUint8Buffer(this.finalResultSize);
if (!a) this.outputHeightWorkBench = this.generateFloatBuffer(this.targetWidthMultipliedByChannels)
};
Resize.prototype.generateFloatBuffer = function (a) {
try {
return new Float32Array(a)
} catch (b) {
return []
}
};
Resize.prototype.generateUint8Buffer = function (a) {
try {
return this.checkForOperaMathBug(new Uint8Array(a))
} catch (b) {
return []
}
};
Resize.prototype.checkForOperaMathBug = function (a) {
a[0] = -1;
a[0] = a[0] >> 0;
return a[0] != 255 ? [] : a
};
function GameBoyCore(a, b) {
this.canvas = a;
this.drawContext = null;
this.ROMImage = b;
this.registerA = 1;
this.FZero = true;
this.FSubtract = false;
this.FCarry = this.FHalfCarry = true;
this.registerB = 0;
this.registerC = 19;
this.registerD = 0;
this.registerE = 216;
this.registersHL = 333;
this.stackPointer = 65534;
this.programCounter = 256;
this.remainingClocks = this.baseCPUCyclesPerIteration = this.CPUCyclesTotalRoundoff = this.CPUCyclesTotalCurrent = this.CPUCyclesTotalBase = this.CPUCyclesTotal = 0;
this.inBootstrap = true;
this.skipPCIncrement = this.halt = this.usedGBCBootROM = this.usedBootROM = false;
this.stopEmulator = 3;
this.IME = true;
this.interruptsEnabled = this.interruptsRequested = this.IRQLineMatched = 0;
this.hdmaRunning = false;
this.doubleSpeedShifter = this.CPUTicks = 0;
this.JoyPad = 255;
this.CPUStopped = false;
this.memoryReader = [];
this.memoryWriter = [];
this.memoryHighReader = [];
this.memoryHighWriter = [];
this.ROM = [];
this.memory = [];
this.MBCRam = [];
this.VRAM = [];
this.GBCMemory = [];
this.MBCRAMBanksEnabled = this.MBC1Mode = false;
this.currMBCRAMBank = 0;
this.currMBCRAMBankPosition = -40960;
this.cGBC = false;
this.gbcRamBank = 1;
this.gbcRamBankPosition = -53248;
this.gbcRamBankPositionECHO = -61440;
this.RAMBanks = [0, 1, 2, 4, 16];
this.cartridgeType = this.currentROMBank = this.ROMBank1offs = 0;
this.gameCode = this.name = "";
this.fromSaveState = false;
this.savedStateFileName = "";
this.modeSTAT = this.STATTracker = 0;
this.spriteCount = 252;
this.LCDisOn = this.mode0TriggerSTAT = this.mode1TriggerSTAT = this.mode2TriggerSTAT = this.LYCMatchTriggerSTAT = false;
this.LINECONTROL = [];
this.DISPLAYOFFCONTROL = [function () {}];
this.LCDCONTROL = null;
this.initializeLCDController();
this.RTCisLatched = false;
this.RTCDays = this.RTCHours = this.RTCMinutes = this.RTCSeconds = this.latchedHDays = this.latchedLDays = this.latchedHours = this.latchedMinutes = this.latchedSeconds = 0;
this.RTCHALT = this.RTCDayOverFlow = false;
this.lowY = this.highY = this.lowX = this.highX = 127;
this.audioHandle = null;
this.sampleSize = this.numSamplesTotal = 0;
this.dutyLookup = [
[false, false, false, false, false, false, false, true],
[true, false, false, false, false, false, false, true],
[true, false, false, false, false, true, true, true],
[false, true, true, true, true, true, true, false]
];
this.currentBuffer = [];
this.bufferContainAmount = 0;
this.noiseSampleTable = this.LSFR7Table = this.LSFR15Table = null;
this.initializeAudioStartState();
this.soundMasterEnabled = false;
this.channel3PCM = null;
this.VinRightChannelMasterVolume = this.VinLeftChannelMasterVolume = 8;
this.rightChannel4 = this.rightChannel3 = this.rightChannel2 = this.rightChannel1 = this.leftChannel4 = this.leftChannel3 = this.leftChannel2 = this.leftChannel1 = false;
this.mixerOutputCache = this.channel2currentSampleRightTrimary = this.channel2currentSampleLeftTrimary = this.channel1currentSampleRightTrimary = this.channel1currentSampleLeftTrimary = this.channel4currentSampleRightSecondary = this.channel4currentSampleLeftSecondary = this.channel3currentSampleRightSecondary = this.channel3currentSampleLeftSecondary = this.channel2currentSampleRightSecondary = this.channel2currentSampleLeftSecondary = this.channel1currentSampleRightSecondary = this.channel1currentSampleLeftSecondary = this.channel4currentSampleRight = this.channel4currentSampleLeft = this.channel3currentSampleRight = this.channel3currentSampleLeft = this.channel2currentSampleRight = this.channel2currentSampleLeft = this.channel1currentSampleRight = this.channel1currentSampleLeft = 0;
this.initializeTiming();
this.emulatorTicks = this.rollover = this.audioIndex = this.audioTicks = this.machineOut = 0;
this.DIVTicks = 56;
this.LCDTicks = 60;
this.timerTicks = 0;
this.TIMAEnabled = false;
this.TACClocker = 1024;
this.IRQEnableDelay = this.serialShiftTimerAllocated = this.serialShiftTimer = this.serialTimer = 0;
var c = new Date;
this.lastIteration = c.getTime();
c = new Date;
this.firstIteration = c.getTime();
this.haltPostClocks = this.totalLinesPassed = this.queuedScanLines = this.lastUnrenderedLine = this.actualScanLine = this.iterations = 0;
this.cTIMER = this.cHuC1 = this.cHuC3 = this.cTAMA5 = this.cCamera = this.cRUMBLE = this.cMMMO1 = this.cSRAM = this.cMBC7 = this.cMBC5 = this.cMBC3 = this.cMBC2 = this.cMBC1 = false;
this.ROMBanks = [2, 4, 8, 16, 32, 64, 128, 256, 512];
this.ROMBanks[82] = 72;
this.ROMBanks[83] = 80;
this.ROMBanks[84] = 96;
this.backgroundY = this.backgroundX = this.currVRAMBank = this.numRAMBanks = 0;
this.gfxSpriteShow = this.gfxWindowDisplay = false;
this.BGPriorityEnabled = this.bgEnabled = this.gfxSpriteNormalHeight = true;
this.gfxBackgroundCHRBankPosition = this.gfxWindowCHRBankPosition = 0;
this.gfxBackgroundBankOffset = 128;
this.drewBlank = this.windowX = this.windowY = 0;
this.drewFrame = false;
this.midScanlineOffset = -1;
this.currentX = this.pixelEnd = 0;
this.tileCache = this.BGCHRCurrentBank = this.BGCHRBank2 = this.BGCHRBank1 = null;
this.colors = [15728606, 11392916, 5411443, 1586242];
this.cachedOBJPaletteConversion = this.cachedBGPaletteConversion = this.gbOBJColorizedPalette = this.gbBGColorizedPalette = this.gbcBGPalette = this.gbcOBJPalette = this.gbBGPalette = this.gbOBJPalette = this.gbcBGRawPalette = this.gbcOBJRawPalette = this.BGPalette = this.OBJPalette = null;
this.updateGBBGPalette = this.updateGBRegularBGPalette;
this.updateGBOBJPalette = this.updateGBRegularOBJPalette;
this.colorizedGBPalettes = false;
this.SpriteLayerRender = this.WindowLayerRender = this.BGLayerRender = null;
this.frameBuffer = [];
this.canvasBuffer = this.swizzledFrame = null;
this.pixelStart = 0;
this.onscreenWidth = this.offscreenWidth = 160;
this.onscreenHeight = this.offScreenheight = 144;
this.offscreenRGBCount = this.onscreenWidth * this.onscreenHeight * 4;
this.intializeWhiteNoise()
}
GameBoyCore.prototype.GBBOOTROM = [49, 254, 255, 175, 33, 255, 159, 50, 203, 124, 32, 251, 33, 38, 255, 14, 17, 62, 128, 50, 226, 12, 62, 243, 226, 50, 62, 119, 119, 62, 252, 224, 71, 17, 4, 1, 33, 16, 128, 26, 205, 149, 0, 205, 150, 0, 19, 123, 254, 52, 32, 243, 17, 216, 0, 6, 8, 26, 19, 34, 35, 5, 32, 249, 62, 25, 234, 16, 153, 33, 47, 153, 14, 12, 61, 40, 8, 50, 13, 32, 249, 46, 15, 24, 243, 103, 62, 100, 87, 224, 66, 62, 145, 224, 64, 4, 30, 2, 14, 12, 240, 68, 254, 144, 32, 250, 13, 32, 247, 29, 32, 242, 14, 19, 36, 124, 30, 131, 254, 98, 40, 6, 30, 193, 254, 100, 32, 6, 123, 226, 12, 62, 135, 226, 240, 66, 144, 224, 66, 21, 32, 210, 5, 32, 79, 22, 32, 24, 203, 79, 6, 4, 197, 203, 17, 23, 193, 203, 17, 23, 5, 32, 245, 34, 35, 34, 35, 201, 206, 237, 102, 102, 204, 13, 0, 11, 3, 115, 0, 131, 0, 12, 0, 13, 0, 8, 17, 31, 136, 137, 0, 14, 220, 204, 110, 230, 221, 221, 217, 153, 187, 187, 103, 99, 110, 14, 236, 204, 221, 220, 153, 159, 187, 185, 51, 62, 60, 66, 185, 165, 185, 165, 66, 60, 33, 4, 1, 17, 168, 0, 26, 19, 190, 32, 254, 35, 125, 254, 52, 32, 245, 6, 25, 120, 134, 35, 5, 32, 251, 134, 32, 254, 62, 1, 224, 80];
GameBoyCore.prototype.GBCBOOTROM = [49, 254, 255, 62, 2, 195, 124, 0, 211, 0, 152, 160, 18, 211, 0, 128, 0, 64, 30, 83, 208, 0, 31, 66, 28, 0, 20, 42, 77, 25, 140, 126, 0, 124, 49, 110, 74, 69, 82, 74, 0, 0, 255, 83, 31, 124, 255, 3, 31, 0, 255, 31, 167, 0, 239, 27, 31, 0, 239, 27, 0, 124, 0, 0, 255, 3, 206, 237, 102, 102, 204, 13, 0, 11, 3, 115, 0, 131, 0, 12, 0, 13, 0, 8, 17, 31, 136, 137, 0, 14, 220, 204, 110, 230, 221, 221, 217, 153, 187, 187, 103, 99, 110, 14, 236, 204, 221, 220, 153, 159, 187, 185, 51, 62, 60, 66, 185, 165, 185, 165, 66, 60, 88, 67, 224, 112, 62, 252, 224, 71, 205, 117, 2, 205, 0, 2, 38, 208, 205, 3, 2, 33, 0, 254, 14, 160, 175, 34, 13, 32, 252, 17, 4, 1, 33, 16, 128, 76, 26, 226, 12, 205, 198, 3, 205, 199, 3, 19, 123, 254, 52, 32, 241, 17, 114, 0, 6, 8, 26, 19, 34, 35, 5, 32, 249, 205, 240, 3, 62, 1, 224, 79, 62, 145, 224, 64, 33, 178, 152, 6, 78, 14, 68, 205, 145, 2, 175, 224, 79, 14, 128, 33, 66, 0, 6, 24, 242, 12, 190, 32, 254, 35, 5, 32, 247, 33, 52, 1, 6, 25, 120, 134, 44, 5, 32, 251, 134, 32, 254, 205, 28, 3, 24, 2, 0, 0, 205, 208, 5, 175, 224, 112, 62, 17, 224, 80, 33, 0, 128, 175, 34, 203, 108, 40, 251, 201, 42, 18, 19, 13, 32, 250, 201, 229, 33, 15, 255, 203, 134, 203, 70, 40, 252, 225, 201, 17, 0, 255, 33, 3, 208, 14, 15, 62, 48, 18, 62, 32, 18, 26, 47, 161, 203, 55, 71, 62, 16, 18, 26, 47, 161, 176, 79, 126, 169, 230, 240, 71, 42, 169, 161, 176, 50, 71, 121, 119, 62, 48, 18, 201, 62, 128, 224, 104, 224, 106, 14, 107, 42, 226, 5, 32, 251, 74, 9, 67, 14, 105, 42, 226, 5, 32, 251, 201, 197, 213, 229, 33, 0, 216, 6, 1, 22, 63, 30, 64, 205, 74, 2, 225, 209, 193, 201, 62, 128, 224, 38, 224, 17, 62, 243, 224, 18, 224, 37, 62, 119, 224, 36, 33, 48, 255, 175, 14, 16, 34, 47, 13, 32, 251, 201, 205, 17, 2, 205, 98, 2, 121, 254, 56, 32, 20, 229, 175, 224, 79, 33, 167, 153, 62, 56, 34, 60, 254, 63, 32, 250, 62, 1, 224, 79, 225, 197, 229, 33, 67, 1, 203, 126, 204, 137, 5, 225, 193, 205, 17, 2, 121, 214, 48, 210, 6, 3, 121, 254, 1, 202, 6, 3, 125, 254, 209, 40, 33, 197, 6, 3, 14, 1, 22, 3, 126, 230, 248, 177, 34, 21, 32, 248, 12, 121, 254, 6, 32, 240, 17, 17, 0, 25, 5, 32, 231, 17, 161, 255, 25, 193, 4, 120, 30, 131, 254, 98, 40, 6, 30, 193, 254, 100, 32, 7, 123, 224, 19, 62, 135, 224, 20, 250, 2, 208, 254, 0, 40, 10, 61, 234, 2, 208, 121, 254, 1, 202, 145, 2, 13, 194, 145, 2, 201, 14, 38, 205, 74, 3, 205, 17, 2, 205, 98, 2, 13, 32, 244, 205, 17, 2, 62, 1, 224, 79, 205, 62, 3, 205, 65, 3, 175, 224, 79, 205, 62, 3, 201, 33, 8, 0, 17, 81, 255, 14, 5, 205, 10, 2, 201, 197, 213, 229, 33, 64, 216, 14, 32, 126, 230, 31, 254, 31, 40, 1, 60, 87, 42, 7, 7, 7, 230, 7, 71, 58, 7, 7, 7, 230, 24, 176, 254, 31, 40, 1, 60, 15, 15, 15, 71, 230, 224, 178, 34, 120, 230, 3, 95, 126, 15, 15, 230, 31, 254, 31, 40, 1, 60, 7, 7, 179, 34, 13, 32, 199, 225, 209, 193, 201, 14, 0, 26, 230, 240, 203, 73, 40, 2, 203, 55, 71, 35, 126, 176, 34, 26, 230, 15, 203, 73, 32, 2, 203, 55, 71, 35, 126, 176, 34, 19, 203, 65, 40, 13, 213, 17, 248, 255, 203, 73, 40, 3, 17, 8, 0, 25, 209, 12, 121, 254, 24, 32, 204, 201, 71, 213, 22, 4, 88, 203, 16, 23, 203, 19, 23, 21, 32, 246, 209, 34, 35, 34, 35, 201, 62, 25, 234, 16, 153, 33, 47, 153, 14, 12, 61, 40, 8, 50, 13, 32, 249, 46, 15, 24, 243, 201, 62, 1, 224, 79, 205, 0, 2, 17, 7, 6, 33, 128, 128, 14, 192, 26, 34, 35, 34, 35, 19, 13, 32, 247, 17, 4, 1, 205, 143, 3, 1, 168, 255, 9, 205, 143, 3, 1, 248, 255, 9, 17, 114, 0, 14, 8, 35, 26, 34, 19, 13, 32, 249, 33, 194, 152, 6, 8, 62, 8, 14, 16, 34, 13, 32, 252, 17, 16, 0, 25, 5, 32, 243, 175, 224, 79, 33, 194, 152, 62, 8, 34, 60, 254, 24, 32, 2, 46, 226, 254, 40, 32, 3, 33, 2, 153, 254, 56, 32, 237, 33, 216, 8, 17, 64, 216, 6, 8, 62, 255, 18, 19, 18, 19, 14, 2, 205, 10, 2, 62, 0, 18, 19, 18, 19, 19, 19, 5, 32, 234, 205, 98, 2, 33, 75, 1, 126, 254, 51, 32, 11, 46, 68, 30, 48, 42, 187, 32, 73, 28, 24, 4, 46, 75, 30, 1, 42, 187, 32, 62, 46, 52, 1, 16, 0, 42, 128, 71, 13, 32, 250, 234, 0, 208, 33, 199, 6, 14, 0, 42, 184, 40, 8, 12, 121, 254, 79, 32, 246, 24, 31, 121, 214, 65, 56, 28, 33, 22, 7, 22, 0, 95, 25, 250, 55, 1, 87, 126, 186, 40, 13, 17, 14, 0, 25, 121, 131, 79, 214, 94, 56, 237, 14, 0, 33, 51, 7, 6, 0, 9, 126, 230, 31, 234, 8, 208, 126, 230, 224, 7, 7, 7, 234, 11, 208, 205, 233, 4, 201, 17, 145, 7, 33, 0, 217, 250, 11, 208, 71, 14, 30, 203, 64, 32, 2, 19, 19, 26, 34, 32, 2, 27, 27, 203, 72, 32, 2, 19, 19, 26, 34, 19, 19, 32, 2, 27, 27, 203, 80, 40, 5, 27, 43, 26, 34, 19, 26, 34, 19, 13, 32, 215, 33, 0, 217, 17, 0, 218, 205, 100, 5, 201, 33, 18, 0, 250, 5, 208, 7, 7, 6, 0, 79, 9, 17, 64, 216, 6, 8, 229, 14, 2, 205, 10, 2, 19, 19, 19, 19, 19, 19, 225, 5, 32, 240, 17, 66, 216, 14, 2, 205, 10, 2, 17, 74, 216, 14, 2, 205, 10, 2, 43, 43, 17, 68, 216, 14, 2, 205, 10, 2, 201, 14, 96, 42, 229, 197, 33, 232, 7, 6, 0, 79, 9, 14, 8, 205, 10, 2, 193, 225, 13, 32, 236, 201, 250, 8, 208, 17, 24, 0, 60, 61, 40, 3, 25, 32, 250, 201, 205, 29, 2, 120, 230, 255, 40, 15, 33, 228, 8, 6, 0, 42, 185, 40, 8, 4, 120, 254, 12, 32, 246, 24, 45, 120, 234, 5, 208, 62, 30, 234, 2, 208, 17, 11, 0, 25, 86, 122, 230, 31, 95, 33, 8, 208, 58, 34, 123, 119, 122, 230, 224, 7, 7, 7, 95, 33, 11, 208, 58, 34, 123, 119, 205, 233, 4, 205, 40, 5, 201, 205, 17, 2, 250, 67, 1, 203, 127, 40, 4, 224, 76, 24, 40, 62, 4, 224, 76, 62, 1, 224, 108, 33, 0, 218, 205, 123, 5, 6, 16, 22, 0, 30, 8, 205, 74, 2, 33, 122, 0, 250, 0, 208, 71, 14, 2, 42, 184, 204, 218, 3, 13, 32, 248, 201, 1, 15, 63, 126, 255, 255, 192, 0, 192, 240, 241, 3, 124, 252, 254, 254, 3, 7, 7, 15, 224, 224, 240, 240, 30, 62, 126, 254, 15, 15, 31, 31, 255, 255, 0, 0, 1, 1, 1, 3, 255, 255, 225, 224, 192, 240, 249, 251, 31, 127, 248, 224, 243, 253, 62, 30, 224, 240, 249, 127, 62, 124, 248, 224, 248, 240, 240, 248, 0, 0, 127, 127, 7, 15, 159, 191, 158, 31, 255, 255, 15, 30, 62, 60, 241, 251, 127, 127, 254, 222, 223, 159, 31, 63, 62, 60, 248, 248, 0, 0, 3, 3, 7, 7, 255, 255, 193, 192, 243, 231, 247, 243, 192, 192, 192, 192, 31, 31, 30, 62, 63, 31, 62, 62, 128, 0, 0, 0, 124, 31, 7, 0, 15, 255, 254, 0, 124, 248, 240, 0, 31, 15, 15, 0, 124, 248, 248, 0, 63, 62, 28, 0, 15, 15, 15, 0, 124, 255, 255, 0, 0, 248, 248, 0, 7, 15, 15, 0, 129, 255, 255, 0, 243, 225, 128, 0, 224, 255, 127, 0, 252, 240, 192, 0, 62, 124, 124, 0, 0, 0, 0, 0, 0, 136, 22, 54, 209, 219, 242, 60, 140, 146, 61, 92, 88, 201, 62, 112, 29, 89, 105, 25, 53, 168, 20, 170, 117, 149, 153, 52, 111, 21, 255, 151, 75, 144, 23, 16, 57, 247, 246, 162, 73, 78, 67, 104, 224, 139, 240, 206, 12, 41, 232, 183, 134, 154, 82, 1, 157, 113, 156, 189, 93, 109, 103, 63, 107, 179, 70, 40, 165, 198, 211, 39, 97, 24, 102, 106, 191, 13, 244, 66, 69, 70, 65, 65, 82, 66, 69, 75, 69, 75, 32, 82, 45, 85, 82, 65, 82, 32, 73, 78, 65, 73, 76, 73, 67, 69, 32, 82, 124, 8, 18, 163, 162, 7, 135, 75, 32, 18, 101, 168, 22, 169, 134, 177, 104, 160, 135, 102, 18, 161, 48, 60, 18, 133, 18, 100, 27, 7, 6, 111, 110, 110, 174, 175, 111, 178, 175, 178, 168, 171, 111, 175, 134, 174, 162, 162, 18, 175, 19, 18, 161, 110, 175, 175, 173, 6, 76, 110, 175, 175, 18, 124, 172, 168, 106, 110, 19, 160, 45, 168, 43, 172, 100, 172, 109, 135, 188, 96, 180, 19, 114, 124, 181, 174, 174, 124, 124, 101, 162, 108, 100, 133, 128, 176, 64, 136, 32, 104, 222, 0, 112, 222, 32, 120, 32, 32, 56, 32, 176, 144, 32, 176, 160, 224, 176, 192, 152, 182, 72, 128, 224, 80, 30, 30, 88, 32, 184, 224, 136, 176, 16, 32, 0, 16, 32, 224, 24, 224, 24, 0, 24, 224, 32, 168, 224, 32, 24, 224, 0, 32, 24, 216, 200, 24, 224, 0, 224, 64, 40, 40, 40, 24, 224, 96, 32, 24, 224, 0, 0, 8, 224, 24, 48, 208, 208, 208, 32, 224, 232, 255, 127, 191, 50, 208, 0, 0, 0, 159, 99, 121, 66, 176, 21, 203, 4, 255, 127, 49, 110, 74, 69, 0, 0, 255, 127, 239, 27, 0, 2, 0, 0, 255, 127, 31, 66, 242, 28, 0, 0, 255, 127, 148, 82, 74, 41, 0, 0, 255, 127, 255, 3, 47, 1, 0, 0, 255, 127, 239, 3, 214, 1, 0, 0, 255, 127, 181, 66, 200, 61, 0, 0, 116, 126, 255, 3, 128, 1, 0, 0, 255, 103, 172, 119, 19, 26, 107, 45, 214, 126, 255, 75, 117, 33, 0, 0, 255, 83, 95, 74, 82, 126, 0, 0, 255, 79, 210, 126, 76, 58, 224, 28, 237, 3, 255, 127, 95, 37, 0, 0, 106, 3, 31, 2, 255, 3, 255, 127, 255, 127, 223, 1, 18, 1, 0, 0, 31, 35, 95, 3, 242, 0, 9, 0, 255, 127, 234, 3, 31, 1, 0, 0, 159, 41, 26, 0, 12, 0, 0, 0, 255, 127, 127, 2, 31, 0, 0, 0, 255, 127, 224, 3, 6, 2, 32, 1, 255, 127, 235, 126, 31, 0, 0, 124, 255, 127, 255, 63, 0, 126, 31, 0, 255, 127, 255, 3, 31, 0, 0, 0, 255, 3, 31, 0, 12, 0, 0, 0, 255, 127, 63, 3, 147, 1, 0, 0, 0, 0, 0, 66, 127, 3, 255, 127, 255, 127, 140, 126, 0, 124, 0, 0, 255, 127, 239, 27, 128, 97, 0, 0, 255, 127, 0, 124, 224, 3, 31, 124, 31, 0, 255, 3, 64, 65, 66, 32, 33, 34, 128, 129, 130, 16, 17, 18, 18, 176, 121, 184, 173, 22, 23, 7, 186, 5, 124, 19, 0, 0, 0, 0];
GameBoyCore.prototype.ffxxDump = [15, 0, 124, 255, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 1, 128, 191, 243, 255, 191, 255, 63, 0, 255, 191, 127, 255, 159, 255, 191, 255, 255, 0, 0, 191, 119, 243, 241, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 145, 128, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 255, 126, 255, 254, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 192, 255, 193, 0, 254, 255, 255, 255, 248, 255, 0, 0, 0, 143, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 206, 237, 102, 102, 204, 13, 0, 11, 3, 115, 0, 131, 0, 12, 0, 13, 0, 8, 17, 31, 136, 137, 0, 14, 220, 204, 110, 230, 221, 221, 217, 153, 187, 187, 103, 99, 110, 14, 236, 204, 221, 220, 153, 159, 187, 185, 51, 62, 69, 236, 82, 250, 8, 183, 7, 93, 1, 253, 192, 255, 8, 252, 0, 229, 11, 248, 194, 206, 244, 249, 15, 127, 69, 109, 61, 254, 70, 151, 51, 94, 8, 239, 241, 255, 134, 131, 36, 116, 18, 252, 0, 159, 180, 183, 6, 213, 208, 122, 0, 158, 4, 95, 65, 47, 29, 119, 54, 117, 129, 170, 112, 58, 152, 209, 113, 2, 77, 1, 193, 255, 13, 0, 211, 5, 249, 0, 11, 0];
GameBoyCore.prototype.OPCODE = [function () {}, function (a) {
a.registerC = a.memoryReader[a.programCounter](a, a.programCounter);
a.registerB = a.memoryRead(a.programCounter + 1 & 65535);
a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
a.memoryWrite(a.registerB << 8 | a.registerC, a.registerA)
}, function (a) {
var b = (a.registerB << 8 | a.registerC) + 1;
a.registerB = b >> 8 & 255;
a.registerC = b & 255
}, function (a) {
a.registerB = a.registerB + 1 & 255;
a.FZero = a.registerB == 0;
a.FHalfCarry = (a.registerB & 15) == 0;
a.FSubtract = false
}, function (a) {
a.registerB = a.registerB - 1 & 255;
a.FZero = a.registerB == 0;
a.FHalfCarry = (a.registerB & 15) == 15;
a.FSubtract = true
}, function (a) {
a.registerB = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.FCarry = a.registerA > 127;
a.registerA = a.registerA << 1 & 255 | a.registerA >> 7;
a.FZero = a.FSubtract = a.FHalfCarry = false
}, function (a) {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.memoryWrite(b, a.stackPointer & 255);
a.memoryWrite(b + 1 & 65535, a.stackPointer >> 8)
}, function (a) {
var b = a.registersHL + (a.registerB << 8 | a.registerC);
a.FHalfCarry = (a.registersHL & 4095) > (b & 4095);
a.FCarry = b > 65535;
a.registersHL = b & 65535;
a.FSubtract = false
}, function (a) {
a.registerA = a.memoryRead(a.registerB << 8 | a.registerC)
}, function (a) {
var b = (a.registerB << 8 | a.registerC) - 1 & 65535;
a.registerB = b >> 8;
a.registerC = b & 255
}, function (a) {
a.registerC = a.registerC + 1 & 255;
a.FZero = a.registerC == 0;
a.FHalfCarry = (a.registerC & 15) == 0;
a.FSubtract = false
}, function (a) {
a.registerC = a.registerC - 1 & 255;
a.FZero = a.registerC == 0;
a.FHalfCarry = (a.registerC & 15) == 15;
a.FSubtract = true
}, function (a) {
a.registerC = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.registerA = a.registerA >> 1 | (a.registerA & 1) << 7;
a.FCarry = a.registerA > 127;
a.FZero = a.FSubtract = a.FHalfCarry = false
}, function (a) {
if (a.cGBC) if ((a.memory[65357] & 1) == 1) {
if (a.memory[65357] > 127) {
cout("Going into single clock speed mode.", 0);
a.doubleSpeedShifter = 0;
a.memory[65357] = a.memory[65357] & 127
} else {
cout("Going into double clock speed mode.", 0);
a.doubleSpeedShifter = 1;
a.memory[65357] = a.memory[65357] | 128
}
a.memory[65357] = a.memory[65357] & 254
} else a.handleSTOP();
else a.handleSTOP()
}, function (a) {
a.registerE = a.memoryReader[a.programCounter](a, a.programCounter);
a.registerD = a.memoryRead(a.programCounter + 1 & 65535);
a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
a.memoryWrite(a.registerD << 8 | a.registerE, a.registerA)
}, function (a) {
var b = (a.registerD << 8 | a.registerE) + 1;
a.registerD = b >> 8 & 255;
a.registerE = b & 255
}, function (a) {
a.registerD = a.registerD + 1 & 255;
a.FZero = a.registerD == 0;
a.FHalfCarry = (a.registerD & 15) == 0;
a.FSubtract = false
}, function (a) {
a.registerD = a.registerD - 1 & 255;
a.FZero = a.registerD == 0;
a.FHalfCarry = (a.registerD & 15) == 15;
a.FSubtract = true
}, function (a) {
a.registerD = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
var b = a.FCarry ? 1 : 0;
a.FCarry = a.registerA > 127;
a.registerA = a.registerA << 1 & 255 | b;
a.FZero = a.FSubtract = a.FHalfCarry = false
}, function (a) {
a.programCounter = a.programCounter + (a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24) + 1 & 65535
}, function (a) {
var b = a.registersHL + (a.registerD << 8 | a.registerE);
a.FHalfCarry = (a.registersHL & 4095) > (b & 4095);
a.FCarry = b > 65535;
a.registersHL = b & 65535;
a.FSubtract = false
}, function (a) {
a.registerA = a.memoryRead(a.registerD << 8 | a.registerE)
}, function (a) {
var b = (a.registerD << 8 | a.registerE) - 1 & 65535;
a.registerD = b >> 8;
a.registerE = b & 255
}, function (a) {
a.registerE = a.registerE + 1 & 255;
a.FZero = a.registerE == 0;
a.FHalfCarry = (a.registerE & 15) == 0;
a.FSubtract = false
}, function (a) {
a.registerE = a.registerE - 1 & 255;
a.FZero = a.registerE == 0;
a.FHalfCarry = (a.registerE & 15) == 15;
a.FSubtract = true
}, function (a) {
a.registerE = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
var b = a.FCarry ? 128 : 0;
a.FCarry = (a.registerA & 1) == 1;
a.registerA = a.registerA >> 1 | b;
a.FZero = a.FSubtract = a.FHalfCarry = false
}, function (a) {
if (a.FZero) a.programCounter = a.programCounter + 1 & 65535;
else {
a.programCounter = a.programCounter + (a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24) + 1 & 65535;
a.CPUTicks = a.CPUTicks + 4
}
}, function (a) {
a.registersHL = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerA);
a.registersHL = a.registersHL + 1 & 65535
}, function (a) {
a.registersHL = a.registersHL + 1 & 65535
}, function (a) {
var b = (a.registersHL >> 8) + 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 0;
a.FSubtract = false;
a.registersHL = b << 8 | a.registersHL & 255
}, function (a) {
var b = (a.registersHL >> 8) - 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 15;
a.FSubtract = true;
a.registersHL = b << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.memoryReader[a.programCounter](a, a.programCounter) << 8 | a.registersHL & 255;
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
if (a.FSubtract) if (a.FCarry && a.FHalfCarry) {
a.registerA = a.registerA + 154 & 255;
a.FHalfCarry = false
} else if (a.FCarry) a.registerA = a.registerA + 160 & 255;
else {
if (a.FHalfCarry) {
a.registerA = a.registerA + 250 & 255;
a.FHalfCarry = false
}
} else {
if (a.FCarry || a.registerA > 153) {
a.registerA = a.registerA + 96 & 255;
a.FCarry = true
}
if (a.FHalfCarry || (a.registerA & 15) > 9) {
a.registerA = a.registerA + 6 & 255;
a.FHalfCarry = false
}
}
a.FZero = a.registerA == 0
}, function (a) {
if (a.FZero) {
a.programCounter = a.programCounter + (a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24) + 1 & 65535;
a.CPUTicks = a.CPUTicks + 4
} else a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.FHalfCarry = (a.registersHL & 4095) > 2047;
a.FCarry = a.registersHL > 32767;
a.registersHL = a.registersHL << 1 & 65535;
a.FSubtract = false
}, function (a) {
a.registerA = a.memoryReader[a.registersHL](a, a.registersHL);
a.registersHL = a.registersHL + 1 & 65535
}, function (a) {
a.registersHL = a.registersHL - 1 & 65535
}, function (a) {
var b = a.registersHL + 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 0;
a.FSubtract = false;
a.registersHL = a.registersHL & 65280 | b
}, function (a) {
var b = a.registersHL - 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 15;
a.FSubtract = true;
a.registersHL = a.registersHL & 65280 | b
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.registerA = a.registerA ^ 255;
a.FSubtract = a.FHalfCarry = true
}, function (a) {
if (a.FCarry) a.programCounter = a.programCounter + 1 & 65535;
else {
a.programCounter = a.programCounter + (a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24) + 1 & 65535;
a.CPUTicks = a.CPUTicks + 4
}
}, function (a) {
a.stackPointer = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerA);
a.registersHL = a.registersHL - 1 & 65535
}, function (a) {
a.stackPointer = a.stackPointer + 1 & 65535
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL) + 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 0;
a.FSubtract = false;
a.memoryWriter[a.registersHL](a, a.registersHL, b)
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL) - 1 & 255;
a.FZero = b == 0;
a.FHalfCarry = (b & 15) == 15;
a.FSubtract = true;
a.memoryWriter[a.registersHL](a, a.registersHL, b)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.programCounter](a, a.programCounter));
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.FCarry = true;
a.FSubtract = a.FHalfCarry = false
}, function (a) {
if (a.FCarry) {
a.programCounter = a.programCounter + (a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24) + 1 & 65535;
a.CPUTicks = a.CPUTicks + 4
} else a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
var b = a.registersHL + a.stackPointer;
a.FHalfCarry = (a.registersHL & 4095) > (b & 4095);
a.FCarry = b > 65535;
a.registersHL = b & 65535;
a.FSubtract = false
}, function (a) {
a.registerA = a.memoryReader[a.registersHL](a, a.registersHL);
a.registersHL = a.registersHL - 1 & 65535
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535
}, function (a) {
a.registerA = a.registerA + 1 & 255;
a.FZero = a.registerA == 0;
a.FHalfCarry = (a.registerA & 15) == 0;
a.FSubtract = false
}, function (a) {
a.registerA = a.registerA - 1 & 255;
a.FZero = a.registerA == 0;
a.FHalfCarry = (a.registerA & 15) == 15;
a.FSubtract = true
}, function (a) {
a.registerA = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.FCarry = !a.FCarry;
a.FSubtract = a.FHalfCarry = false
}, function () {}, function (a) {
a.registerB = a.registerC
}, function (a) {
a.registerB = a.registerD
}, function (a) {
a.registerB = a.registerE
}, function (a) {
a.registerB = a.registersHL >> 8
}, function (a) {
a.registerB = a.registersHL & 255
}, function (a) {
a.registerB = a.memoryReader[a.registersHL](a, a.registersHL)
}, function (a) {
a.registerB = a.registerA
}, function (a) {
a.registerC = a.registerB
}, function () {}, function (a) {
a.registerC = a.registerD
}, function (a) {
a.registerC = a.registerE
}, function (a) {
a.registerC = a.registersHL >> 8
}, function (a) {
a.registerC = a.registersHL & 255
}, function (a) {
a.registerC = a.memoryReader[a.registersHL](a, a.registersHL)
}, function (a) {
a.registerC = a.registerA
}, function (a) {
a.registerD = a.registerB
}, function (a) {
a.registerD = a.registerC
}, function () {}, function (a) {
a.registerD = a.registerE
}, function (a) {
a.registerD = a.registersHL >> 8
}, function (a) {
a.registerD = a.registersHL & 255
}, function (a) {
a.registerD = a.memoryReader[a.registersHL](a, a.registersHL)
}, function (a) {
a.registerD = a.registerA
}, function (a) {
a.registerE = a.registerB
}, function (a) {
a.registerE = a.registerC
}, function (a) {
a.registerE = a.registerD
}, function () {}, function (a) {
a.registerE = a.registersHL >> 8
}, function (a) {
a.registerE = a.registersHL & 255
}, function (a) {
a.registerE = a.memoryReader[a.registersHL](a, a.registersHL)
}, function (a) {
a.registerE = a.registerA
}, function (a) {
a.registersHL = a.registerB << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.registerC << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.registerD << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.registerE << 8 | a.registersHL & 255
}, function () {}, function (a) {
a.registersHL = (a.registersHL & 255) * 257
}, function (a) {
a.registersHL = a.memoryReader[a.registersHL](a, a.registersHL) << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.registerA << 8 | a.registersHL & 255
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registerB
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registerC
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registerD
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registerE
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registersHL >> 8
}, function () {}, function (a) {
a.registersHL = a.registersHL & 65280 | a.memoryReader[a.registersHL](a, a.registersHL)
}, function (a) {
a.registersHL = a.registersHL & 65280 | a.registerA
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerB)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerC)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerD)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerE)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registersHL >> 8)
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registersHL & 255)
}, function (a) {
(a.interruptsEnabled & a.interruptsRequested & 31) > 0 ? !a.cGBC && !a.usedBootROM ? a.skipPCIncrement = true : a.CPUTicks = a.CPUTicks + 4 : a.calculateHALTPeriod()
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.registerA)
}, function (a) {
a.registerA = a.registerB
}, function (a) {
a.registerA = a.registerC
}, function (a) {
a.registerA = a.registerD
}, function (a) {
a.registerA = a.registerE
}, function (a) {
a.registerA = a.registersHL >> 8
}, function (a) {
a.registerA = a.registersHL & 255
}, function (a) {
a.registerA = a.memoryReader[a.registersHL](a, a.registersHL)
}, function () {}, function (a) {
var b = a.registerA + a.registerB;
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerC;
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerD;
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerE;
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + (a.registersHL >> 8);
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + (a.registersHL & 255);
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.memoryReader[a.registersHL](a, a.registersHL);
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
a.FHalfCarry = (a.registerA & 8) == 8;
a.FCarry = a.registerA > 127;
a.registerA = a.registerA << 1 & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerB + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (a.registerB & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerC + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (a.registerC & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerD + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (a.registerD & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA + a.registerE + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (a.registerE & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registersHL >> 8,
c = a.registerA + b + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (b & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = c > 255;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registersHL & 255,
c = a.registerA + b + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (b & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = c > 255;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL),
c = a.registerA + b + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (b & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = c > 255;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA << 1 | (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA << 1 & 30 | (a.FCarry ? 1 : 0)) > 15;
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
var b = a.registerA - a.registerB;
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerC;
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerD;
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerE;
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - (a.registersHL >> 8);
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - (a.registersHL & 255);
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.memoryReader[a.registersHL](a, a.registersHL);
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
a.registerA = 0;
a.FHalfCarry = a.FCarry = false;
a.FZero = a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerB - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (a.registerB & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerC - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (a.registerC & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerD - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (a.registerD & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerE - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (a.registerE & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.registersHL >> 8,
c = a.registerA - b - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (b & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = c < 0;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - (a.registersHL & 255) - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (a.registersHL & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL),
c = a.registerA - b - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (b & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = c < 0;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
if (a.FCarry) {
a.FZero = false;
a.FSubtract = a.FHalfCarry = a.FCarry = true;
a.registerA = 255
} else {
a.FHalfCarry = a.FCarry = false;
a.FSubtract = a.FZero = true;
a.registerA = 0
}
}, function (a) {
a.registerA = a.registerA & a.registerB;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.registerC;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.registerD;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.registerE;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.registersHL >> 8;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.registersHL;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA & a.memoryReader[a.registersHL](a, a.registersHL);
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registerB;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registerC;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registerD;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registerE;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registersHL >> 8;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.registersHL & 255;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA ^ a.memoryReader[a.registersHL](a, a.registersHL);
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = 0;
a.FZero = true;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.registerA = a.registerA | a.registerB;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.registerC;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.registerD;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.registerE;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.registersHL >> 8;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.registersHL & 255;
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.registerA = a.registerA | a.memoryReader[a.registersHL](a, a.registersHL);
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.FZero = a.registerA == 0;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
var b = a.registerA - a.registerB;
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerC;
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerD;
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.registerE;
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - (a.registersHL >> 8);
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - (a.registersHL & 255);
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
var b = a.registerA - a.memoryReader[a.registersHL](a, a.registersHL);
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
a.FHalfCarry = a.FCarry = false;
a.FZero = a.FSubtract = true
}, function (a) {
if (!a.FZero) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.registerC = a.memoryReader[a.stackPointer](a, a.stackPointer);
a.registerB = a.memoryRead(a.stackPointer + 1 & 65535);
a.stackPointer = a.stackPointer + 2 & 65535
}, function (a) {
if (a.FZero) a.programCounter = a.programCounter + 2 & 65535;
else {
a.programCounter = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.CPUTicks = a.CPUTicks + 4
}
}, function (a) {
a.programCounter = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter)
}, function (a) {
if (a.FZero) a.programCounter = a.programCounter + 2 & 65535;
else {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = b;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registerB);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registerC)
}, function (a) {
var b = a.registerA + a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.FHalfCarry = (b & 15) < (a.registerA & 15);
a.FCarry = b > 255;
a.registerA = b & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 0
}, function (a) {
if (a.FZero) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535
}, function (a) {
if (a.FZero) {
a.programCounter = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.CPUTicks = a.CPUTicks + 4
} else a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
var b = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.CPUTicks = a.CPUTicks + a.SecondaryTICKTable[b];
a.CBOPCODE[b](a)
}, function (a) {
if (a.FZero) {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = b;
a.CPUTicks = a.CPUTicks + 12
} else a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = b
}, function (a) {
var b = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
var c = a.registerA + b + (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) + (b & 15) + (a.FCarry ? 1 : 0) > 15;
a.FCarry = c > 255;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = false
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 8
}, function (a) {
if (!a.FCarry) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.registerE = a.memoryReader[a.stackPointer](a, a.stackPointer);
a.registerD = a.memoryRead(a.stackPointer + 1 & 65535);
a.stackPointer = a.stackPointer + 2 & 65535
}, function (a) {
if (a.FCarry) a.programCounter = a.programCounter + 2 & 65535;
else {
a.programCounter = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.CPUTicks = a.CPUTicks + 4
}
}, function () {
cout("Illegal op code 0xD3 called, pausing emulation.", 2);
pause()
}, function (a) {
if (a.FCarry) a.programCounter = a.programCounter + 2 & 65535;
else {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = b;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registerD);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registerE)
}, function (a) {
var b = a.registerA - a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.FHalfCarry = (a.registerA & 15) < (b & 15);
a.FCarry = b < 0;
a.registerA = b & 255;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 16
}, function (a) {
if (a.FCarry) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535;
a.CPUTicks = a.CPUTicks + 12
}
}, function (a) {
a.programCounter = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535;
a.IRQEnableDelay = a.IRQEnableDelay == 2 || a.memoryReader[a.programCounter](a, a.programCounter) == 118 ? 1 : 2
}, function (a) {
if (a.FCarry) {
a.programCounter = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.CPUTicks = a.CPUTicks + 4
} else a.programCounter = a.programCounter + 2 & 65535
}, function () {
cout("Illegal op code 0xDB called, pausing emulation.", 2);
pause()
}, function (a) {
if (a.FCarry) {
var b = a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 2 & 65535;
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = b;
a.CPUTicks = a.CPUTicks + 12
} else a.programCounter = a.programCounter + 2 & 65535
}, function () {
cout("Illegal op code 0xDD called, pausing emulation.", 2);
pause()
}, function (a) {
var b = a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
var c = a.registerA - b - (a.FCarry ? 1 : 0);
a.FHalfCarry = (a.registerA & 15) - (b & 15) - (a.FCarry ? 1 : 0) < 0;
a.FCarry = c < 0;
a.registerA = c & 255;
a.FZero = a.registerA == 0;
a.FSubtract = true
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 24
}, function (a) {
a.memoryHighWrite(a.memoryReader[a.programCounter](a, a.programCounter), a.registerA);
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
a.registersHL = a.memoryRead(a.stackPointer + 1 & 65535) << 8 | a.memoryReader[a.stackPointer](a, a.stackPointer);
a.stackPointer = a.stackPointer + 2 & 65535
}, function (a) {
a.memoryHighWriter[a.registerC](a, a.registerC, a.registerA)
}, function () {
cout("Illegal op code 0xE3 called, pausing emulation.", 2);
pause()
}, function () {
cout("Illegal op code 0xE4 called, pausing emulation.", 2);
pause()
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registersHL >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registersHL & 255)
}, function (a) {
a.registerA = a.registerA & a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.FZero = a.registerA == 0;
a.FHalfCarry = true;
a.FSubtract = a.FCarry = false
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 32
}, function (a) {
var b = a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24;
a.programCounter = a.programCounter + 1 & 65535;
var c = a.stackPointer + b & 65535,
b = a.stackPointer ^ b ^ c;
a.stackPointer = c;
a.FCarry = (b & 256) == 256;
a.FHalfCarry = (b & 16) == 16;
a.FZero = a.FSubtract = false
}, function (a) {
a.programCounter = a.registersHL
}, function (a) {
a.memoryWrite(a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter), a.registerA);
a.programCounter = a.programCounter + 2 & 65535
}, function () {
cout("Illegal op code 0xEB called, pausing emulation.", 2);
pause()
}, function () {
cout("Illegal op code 0xEC called, pausing emulation.", 2);
pause()
}, function () {
cout("Illegal op code 0xED called, pausing emulation.", 2);
pause()
}, function (a) {
a.registerA = a.registerA ^ a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.FZero = a.registerA == 0;
a.FSubtract = a.FHalfCarry = a.FCarry = false
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 40
}, function (a) {
a.registerA = a.memoryHighRead(a.memoryReader[a.programCounter](a, a.programCounter));
a.programCounter = a.programCounter + 1 & 65535
}, function (a) {
var b = a.memoryReader[a.stackPointer](a, a.stackPointer);
a.FZero = b > 127;
a.FSubtract = (b & 64) == 64;
a.FHalfCarry = (b & 32) == 32;
a.FCarry = (b & 16) == 16;
a.registerA = a.memoryRead(a.stackPointer + 1 & 65535);
a.stackPointer = a.stackPointer + 2 & 65535
}, function (a) {
a.registerA = a.memoryHighReader[a.registerC](a, a.registerC)
}, function (a) {
a.IME = false;
a.IRQEnableDelay = 0
}, function () {
cout("Illegal op code 0xF4 called, pausing emulation.", 2);
pause()
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.registerA);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, (a.FZero ? 128 : 0) | (a.FSubtract ? 64 : 0) | (a.FHalfCarry ? 32 : 0) | (a.FCarry ? 16 : 0))
}, function (a) {
a.registerA = a.registerA | a.memoryReader[a.programCounter](a, a.programCounter);
a.FZero = a.registerA == 0;
a.programCounter = a.programCounter + 1 & 65535;
a.FSubtract = a.FCarry = a.FHalfCarry = false
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 48
}, function (a) {
var b = a.memoryReader[a.programCounter](a, a.programCounter) << 24 >> 24;
a.programCounter = a.programCounter + 1 & 65535;
a.registersHL = a.stackPointer + b & 65535;
b = a.stackPointer ^ b ^ a.registersHL;
a.FCarry = (b & 256) == 256;
a.FHalfCarry = (b & 16) == 16;
a.FZero = a.FSubtract = false
}, function (a) {
a.stackPointer = a.registersHL
}, function (a) {
a.registerA = a.memoryRead(a.memoryRead(a.programCounter + 1 & 65535) << 8 | a.memoryReader[a.programCounter](a, a.programCounter));
a.programCounter = a.programCounter + 2 & 65535
}, function (a) {
a.IRQEnableDelay = a.IRQEnableDelay == 2 || a.memoryReader[a.programCounter](a, a.programCounter) == 118 ? 1 : 2
}, function () {
cout("Illegal op code 0xFC called, pausing emulation.", 2);
pause()
}, function () {
cout("Illegal op code 0xFD called, pausing emulation.", 2);
pause()
}, function (a) {
var b = a.registerA - a.memoryReader[a.programCounter](a, a.programCounter);
a.programCounter = a.programCounter + 1 & 65535;
a.FHalfCarry = (b & 15) > (a.registerA & 15);
a.FCarry = b < 0;
a.FZero = b == 0;
a.FSubtract = true
}, function (a) {
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter >> 8);
a.stackPointer = a.stackPointer - 1 & 65535;
a.memoryWriter[a.stackPointer](a, a.stackPointer, a.programCounter & 255);
a.programCounter = 56
}];
GameBoyCore.prototype.CBOPCODE = [function (a) {
a.FCarry = a.registerB > 127;
a.registerB = a.registerB << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
a.FCarry = a.registerC > 127;
a.registerC = a.registerC << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
a.FCarry = a.registerD > 127;
a.registerD = a.registerD << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
a.FCarry = a.registerE > 127;
a.registerE = a.registerE << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
a.FCarry = a.registersHL > 32767;
a.registersHL = a.registersHL << 1 & 65024 | (a.FCarry ? 256 : 0) | a.registersHL & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
a.FCarry = (a.registersHL & 128) == 128;
a.registersHL = a.registersHL & 65280 | a.registersHL << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL);
a.FCarry = b > 127;
b = b << 1 & 255 | (a.FCarry ? 1 : 0);
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
a.FCarry = a.registerA > 127;
a.registerA = a.registerA << 1 & 255 | (a.FCarry ? 1 : 0);
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
a.FCarry = (a.registerB & 1) == 1;
a.registerB = (a.FCarry ? 128 : 0) | a.registerB >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
a.FCarry = (a.registerC & 1) == 1;
a.registerC = (a.FCarry ? 128 : 0) | a.registerC >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
a.FCarry = (a.registerD & 1) == 1;
a.registerD = (a.FCarry ? 128 : 0) | a.registerD >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
a.FCarry = (a.registerE & 1) == 1;
a.registerE = (a.FCarry ? 128 : 0) | a.registerE >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
a.FCarry = (a.registersHL & 256) == 256;
a.registersHL = (a.FCarry ? 32768 : 0) | a.registersHL >> 1 & 65280 | a.registersHL & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
a.FCarry = (a.registersHL & 1) == 1;
a.registersHL = a.registersHL & 65280 | (a.FCarry ? 128 : 0) | (a.registersHL & 255) >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL);
a.FCarry = (b & 1) == 1;
b = (a.FCarry ? 128 : 0) | b >> 1;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
a.FCarry = (a.registerA & 1) == 1;
a.registerA = (a.FCarry ? 128 : 0) | a.registerA >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
var b = a.registerB > 127;
a.registerB = a.registerB << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
var b = a.registerC > 127;
a.registerC = a.registerC << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
var b = a.registerD > 127;
a.registerD = a.registerD << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
var b = a.registerE > 127;
a.registerE = a.registerE << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
var b = a.registersHL > 32767;
a.registersHL = a.registersHL << 1 & 65024 | (a.FCarry ? 256 : 0) | a.registersHL & 255;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
var b = (a.registersHL & 128) == 128;
a.registersHL = a.registersHL & 65280 | a.registersHL << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL),
c = b > 127,
b = b << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = c;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
var b = a.registerA > 127;
a.registerA = a.registerA << 1 & 255 | (a.FCarry ? 1 : 0);
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
var b = (a.registerB & 1) == 1;
a.registerB = (a.FCarry ? 128 : 0) | a.registerB >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
var b = (a.registerC & 1) == 1;
a.registerC = (a.FCarry ? 128 : 0) | a.registerC >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
var b = (a.registerD & 1) == 1;
a.registerD = (a.FCarry ? 128 : 0) | a.registerD >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
var b = (a.registerE & 1) == 1;
a.registerE = (a.FCarry ? 128 : 0) | a.registerE >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
var b = (a.registersHL & 256) == 256;
a.registersHL = (a.FCarry ? 32768 : 0) | a.registersHL >> 1 & 65280 | a.registersHL & 255;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
var b = (a.registersHL & 1) == 1;
a.registersHL = a.registersHL & 65280 | (a.FCarry ? 128 : 0) | (a.registersHL & 255) >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL),
c = (b & 1) == 1,
b = (a.FCarry ? 128 : 0) | b >> 1;
a.FCarry = c;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
var b = (a.registerA & 1) == 1;
a.registerA = (a.FCarry ? 128 : 0) | a.registerA >> 1;
a.FCarry = b;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
a.FCarry = a.registerB > 127;
a.registerB = a.registerB << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
a.FCarry = a.registerC > 127;
a.registerC = a.registerC << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
a.FCarry = a.registerD > 127;
a.registerD = a.registerD << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
a.FCarry = a.registerE > 127;
a.registerE = a.registerE << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
a.FCarry = a.registersHL > 32767;
a.registersHL = a.registersHL << 1 & 65024 | a.registersHL & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
a.FCarry = (a.registersHL & 128) == 128;
a.registersHL = a.registersHL & 65280 | a.registersHL << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL);
a.FCarry = b > 127;
b = b << 1 & 255;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
a.FCarry = a.registerA > 127;
a.registerA = a.registerA << 1 & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
a.FCarry = (a.registerB & 1) == 1;
a.registerB = a.registerB & 128 | a.registerB >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
a.FCarry = (a.registerC & 1) == 1;
a.registerC = a.registerC & 128 | a.registerC >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
a.FCarry = (a.registerD & 1) == 1;
a.registerD = a.registerD & 128 | a.registerD >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
a.FCarry = (a.registerE & 1) == 1;
a.registerE = a.registerE & 128 | a.registerE >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
a.FCarry = (a.registersHL & 256) == 256;
a.registersHL = a.registersHL >> 1 & 65280 | a.registersHL & 33023;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
a.FCarry = (a.registersHL & 1) == 1;
a.registersHL = a.registersHL & 65408 | (a.registersHL & 255) >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL);
a.FCarry = (b & 1) == 1;
b = b & 128 | b >> 1;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b == 0
}, function (a) {
a.FCarry = (a.registerA & 1) == 1;
a.registerA = a.registerA & 128 | a.registerA >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
a.registerB = (a.registerB & 15) << 4 | a.registerB >> 4;
a.FZero = a.registerB == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registerC = (a.registerC & 15) << 4 | a.registerC >> 4;
a.FZero = a.registerC == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registerD = (a.registerD & 15) << 4 | a.registerD >> 4;
a.FZero = a.registerD == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registerE = (a.registerE & 15) << 4 | a.registerE >> 4;
a.FZero = a.registerE == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registersHL = (a.registersHL & 3840) << 4 | (a.registersHL & 61440) >> 4 | a.registersHL & 255;
a.FZero = a.registersHL < 256;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registersHL = a.registersHL & 65280 | (a.registersHL & 15) << 4 | (a.registersHL & 240) >> 4;
a.FZero = (a.registersHL & 255) == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL),
b = (b & 15) << 4 | b >> 4;
a.memoryWriter[a.registersHL](a, a.registersHL, b);
a.FZero = b == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.registerA = (a.registerA & 15) << 4 | a.registerA >> 4;
a.FZero = a.registerA == 0;
a.FCarry = a.FHalfCarry = a.FSubtract = false
}, function (a) {
a.FCarry = (a.registerB & 1) == 1;
a.registerB = a.registerB >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerB == 0
}, function (a) {
a.FCarry = (a.registerC & 1) == 1;
a.registerC = a.registerC >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerC == 0
}, function (a) {
a.FCarry = (a.registerD & 1) == 1;
a.registerD = a.registerD >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerD == 0
}, function (a) {
a.FCarry = (a.registerE & 1) == 1;
a.registerE = a.registerE >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerE == 0
}, function (a) {
a.FCarry = (a.registersHL & 256) == 256;
a.registersHL = a.registersHL >> 1 & 65280 | a.registersHL & 255;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registersHL < 256
}, function (a) {
a.FCarry = (a.registersHL & 1) == 1;
a.registersHL = a.registersHL & 65280 | (a.registersHL & 255) >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = (a.registersHL & 255) == 0
}, function (a) {
var b = a.memoryReader[a.registersHL](a, a.registersHL);
a.FCarry = (b & 1) == 1;
a.memoryWriter[a.registersHL](a, a.registersHL, b >> 1);
a.FHalfCarry = a.FSubtract = false;
a.FZero = b < 2
}, function (a) {
a.FCarry = (a.registerA & 1) == 1;
a.registerA = a.registerA >> 1;
a.FHalfCarry = a.FSubtract = false;
a.FZero = a.registerA == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 256) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 1) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 512) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 2) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 1024) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 4) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 2048) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 8) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 4096) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 16) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 8192) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 32) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 16384) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 64) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerB & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerC & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerD & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerE & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 32768) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registersHL & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.memoryReader[a.registersHL](a, a.registersHL) & 128) == 0
}, function (a) {
a.FHalfCarry = true;
a.FSubtract = false;
a.FZero = (a.registerA & 128) == 0
}, function (a) {
a.registerB = a.registerB & 254
}, function (a) {
a.registerC = a.registerC & 254
}, function (a) {
a.registerD = a.registerD & 254
}, function (a) {
a.registerE = a.registerE & 254
}, function (a) {
a.registersHL = a.registersHL & 65279
}, function (a) {
a.registersHL = a.registersHL & 65534
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 254)
}, function (a) {
a.registerA = a.registerA & 254
}, function (a) {
a.registerB = a.registerB & 253
}, function (a) {
a.registerC = a.registerC & 253
}, function (a) {
a.registerD = a.registerD & 253
}, function (a) {
a.registerE = a.registerE & 253
}, function (a) {
a.registersHL = a.registersHL & 65023
}, function (a) {
a.registersHL = a.registersHL & 65533
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 253)
}, function (a) {
a.registerA = a.registerA & 253
}, function (a) {
a.registerB = a.registerB & 251
}, function (a) {
a.registerC = a.registerC & 251
}, function (a) {
a.registerD = a.registerD & 251
}, function (a) {
a.registerE = a.registerE & 251
}, function (a) {
a.registersHL = a.registersHL & 64511
}, function (a) {
a.registersHL = a.registersHL & 65531
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 251)
}, function (a) {
a.registerA = a.registerA & 251
}, function (a) {
a.registerB = a.registerB & 247
}, function (a) {
a.registerC = a.registerC & 247
}, function (a) {
a.registerD = a.registerD & 247
}, function (a) {
a.registerE = a.registerE & 247
}, function (a) {
a.registersHL = a.registersHL & 63487
}, function (a) {
a.registersHL = a.registersHL & 65527
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 247)
}, function (a) {
a.registerA = a.registerA & 247
}, function (a) {
a.registerB = a.registerB & 239
}, function (a) {
a.registerC = a.registerC & 239
}, function (a) {
a.registerD = a.registerD & 239
}, function (a) {
a.registerE = a.registerE & 239
}, function (a) {
a.registersHL = a.registersHL & 61439
}, function (a) {
a.registersHL = a.registersHL & 65519
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 239)
}, function (a) {
a.registerA = a.registerA & 239
}, function (a) {
a.registerB = a.registerB & 223
}, function (a) {
a.registerC = a.registerC & 223
}, function (a) {
a.registerD = a.registerD & 223
}, function (a) {
a.registerE = a.registerE & 223
}, function (a) {
a.registersHL = a.registersHL & 57343
}, function (a) {
a.registersHL = a.registersHL & 65503
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 223)
}, function (a) {
a.registerA = a.registerA & 223
}, function (a) {
a.registerB = a.registerB & 191
}, function (a) {
a.registerC = a.registerC & 191
}, function (a) {
a.registerD = a.registerD & 191
}, function (a) {
a.registerE = a.registerE & 191
}, function (a) {
a.registersHL = a.registersHL & 49151
}, function (a) {
a.registersHL = a.registersHL & 65471
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 191)
}, function (a) {
a.registerA = a.registerA & 191
}, function (a) {
a.registerB = a.registerB & 127
}, function (a) {
a.registerC = a.registerC & 127
}, function (a) {
a.registerD = a.registerD & 127
}, function (a) {
a.registerE = a.registerE & 127
}, function (a) {
a.registersHL = a.registersHL & 32767
}, function (a) {
a.registersHL = a.registersHL & 65407
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) & 127)
}, function (a) {
a.registerA = a.registerA & 127
}, function (a) {
a.registerB = a.registerB | 1
}, function (a) {
a.registerC = a.registerC | 1
}, function (a) {
a.registerD = a.registerD | 1
}, function (a) {
a.registerE = a.registerE | 1
}, function (a) {
a.registersHL = a.registersHL | 256
}, function (a) {
a.registersHL = a.registersHL | 1
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 1)
}, function (a) {
a.registerA = a.registerA | 1
}, function (a) {
a.registerB = a.registerB | 2
}, function (a) {
a.registerC = a.registerC | 2
}, function (a) {
a.registerD = a.registerD | 2
}, function (a) {
a.registerE = a.registerE | 2
}, function (a) {
a.registersHL = a.registersHL | 512
}, function (a) {
a.registersHL = a.registersHL | 2
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 2)
}, function (a) {
a.registerA = a.registerA | 2
}, function (a) {
a.registerB = a.registerB | 4
}, function (a) {
a.registerC = a.registerC | 4
}, function (a) {
a.registerD = a.registerD | 4
}, function (a) {
a.registerE = a.registerE | 4
}, function (a) {
a.registersHL = a.registersHL | 1024
}, function (a) {
a.registersHL = a.registersHL | 4
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 4)
}, function (a) {
a.registerA = a.registerA | 4
}, function (a) {
a.registerB = a.registerB | 8
}, function (a) {
a.registerC = a.registerC | 8
}, function (a) {
a.registerD = a.registerD | 8
}, function (a) {
a.registerE = a.registerE | 8
}, function (a) {
a.registersHL = a.registersHL | 2048
}, function (a) {
a.registersHL = a.registersHL | 8
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 8)
}, function (a) {
a.registerA = a.registerA | 8
}, function (a) {
a.registerB = a.registerB | 16
}, function (a) {
a.registerC = a.registerC | 16
}, function (a) {
a.registerD = a.registerD | 16
}, function (a) {
a.registerE = a.registerE | 16
}, function (a) {
a.registersHL = a.registersHL | 4096
}, function (a) {
a.registersHL = a.registersHL | 16
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 16)
}, function (a) {
a.registerA = a.registerA | 16
}, function (a) {
a.registerB = a.registerB | 32
}, function (a) {
a.registerC = a.registerC | 32
}, function (a) {
a.registerD = a.registerD | 32
}, function (a) {
a.registerE = a.registerE | 32
}, function (a) {
a.registersHL = a.registersHL | 8192
}, function (a) {
a.registersHL = a.registersHL | 32
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 32)
}, function (a) {
a.registerA = a.registerA | 32
}, function (a) {
a.registerB = a.registerB | 64
}, function (a) {
a.registerC = a.registerC | 64
}, function (a) {
a.registerD = a.registerD | 64
}, function (a) {
a.registerE = a.registerE | 64
}, function (a) {
a.registersHL = a.registersHL | 16384
}, function (a) {
a.registersHL = a.registersHL | 64
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 64)
}, function (a) {
a.registerA = a.registerA | 64
}, function (a) {
a.registerB = a.registerB | 128
}, function (a) {
a.registerC = a.registerC | 128
}, function (a) {
a.registerD = a.registerD | 128
}, function (a) {
a.registerE = a.registerE | 128
}, function (a) {
a.registersHL = a.registersHL | 32768
}, function (a) {
a.registersHL = a.registersHL | 128
}, function (a) {
a.memoryWriter[a.registersHL](a, a.registersHL, a.memoryReader[a.registersHL](a, a.registersHL) | 128)
}, function (a) {
a.registerA = a.registerA | 128
}];
GameBoyCore.prototype.TICKTable = [4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4, 4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4, 8, 12, 8, 8, 4, 4, 8, 4, 8, 8, 8, 8, 4, 4, 8, 4, 8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, 8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 0, 12, 24, 8, 16, 8, 12, 12, 4, 12, 16, 8, 16, 8, 16, 12, 4, 12, 4, 8, 16, 12, 12, 8, 4, 4, 16, 8, 16, 16, 4, 16, 4, 4, 4, 8, 16, 12, 12, 8, 4, 4, 16, 8, 16, 12, 8, 16, 4, 0, 4, 8, 16];
GameBoyCore.prototype.SecondaryTICKTable = [8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8];
GameBoyCore.prototype.saveSRAMState = function () {
return !this.cBATT || this.MBCRam.length == 0 ? [] : this.fromTypedArray(this.MBCRam)
};
GameBoyCore.prototype.saveRTCState = function () {
return this.cTIMER ? [this.lastIteration, this.RTCisLatched, this.latchedSeconds, this.latchedMinutes, this.latchedHours, this.latchedLDays, this.latchedHDays, this.RTCSeconds, this.RTCMinutes, this.RTCHours, this.RTCDays, this.RTCDayOverFlow, this.RTCHALT] : []
};
GameBoyCore.prototype.saveState = function () {
return [this.fromTypedArray(this.ROM), this.inBootstrap, this.registerA, this.FZero, this.FSubtract, this.FHalfCarry, this.FCarry, this.registerB, this.registerC, this.registerD, this.registerE, this.registersHL, this.stackPointer, this.programCounter, this.halt, this.IME, this.hdmaRunning, this.CPUTicks, this.doubleSpeedShifter, this.fromTypedArray(this.memory), this.fromTypedArray(this.MBCRam), this.fromTypedArray(this.VRAM), this.currVRAMBank, this.fromTypedArray(this.GBCMemory), this.MBC1Mode, this.MBCRAMBanksEnabled, this.currMBCRAMBank, this.currMBCRAMBankPosition, this.cGBC, this.gbcRamBank, this.gbcRamBankPosition, this.ROMBank1offs, this.currentROMBank, this.cartridgeType, this.name, this.gameCode, this.modeSTAT, this.LYCMatchTriggerSTAT, this.mode2TriggerSTAT, this.mode1TriggerSTAT, this.mode0TriggerSTAT, this.LCDisOn, this.gfxWindowCHRBankPosition, this.gfxWindowDisplay, this.gfxSpriteShow, this.gfxSpriteNormalHeight, this.gfxBackgroundCHRBankPosition, this.gfxBackgroundBankOffset, this.TIMAEnabled, this.DIVTicks, this.LCDTicks, this.timerTicks, this.TACClocker, this.serialTimer, this.serialShiftTimer, this.serialShiftTimerAllocated, this.IRQEnableDelay, this.lastIteration, this.cMBC1, this.cMBC2, this.cMBC3, this.cMBC5, this.cMBC7, this.cSRAM, this.cMMMO1, this.cRUMBLE, this.cCamera, this.cTAMA5, this.cHuC3, this.cHuC1, this.drewBlank, this.fromTypedArray(this.frameBuffer), this.bgEnabled, this.BGPriorityEnabled, this.channel1FrequencyTracker, this.channel1FrequencyCounter, this.channel1totalLength, this.channel1envelopeVolume, this.channel1envelopeType, this.channel1envelopeSweeps, this.channel1envelopeSweepsLast, this.channel1consecutive, this.channel1frequency, this.channel1SweepFault, this.channel1ShadowFrequency, this.channel1timeSweep, this.channel1lastTimeSweep, this.channel1numSweep, this.channel1frequencySweepDivider, this.channel1decreaseSweep, this.channel2FrequencyTracker, this.channel2FrequencyCounter, this.channel2totalLength, this.channel2envelopeVolume, this.channel2envelopeType, this.channel2envelopeSweeps, this.channel2envelopeSweepsLast, this.channel2consecutive, this.channel2frequency, this.channel3canPlay, this.channel3totalLength, this.channel3patternType, this.channel3frequency, this.channel3consecutive, this.fromTypedArray(this.channel3PCM), this.channel4FrequencyPeriod, this.channel4lastSampleLookup, this.channel4totalLength, this.channel4envelopeVolume, this.channel4currentVolume, this.channel4envelopeType, this.channel4envelopeSweeps, this.channel4envelopeSweepsLast, this.channel4consecutive, this.channel4BitRange, this.soundMasterEnabled, this.VinLeftChannelMasterVolume, this.VinRightChannelMasterVolume, this.leftChannel1, this.leftChannel2, this.leftChannel3, this.leftChannel4, this.rightChannel1, this.rightChannel2, this.rightChannel3, this.rightChannel4, this.channel1currentSampleLeft, this.channel1currentSampleRight, this.channel2currentSampleLeft, this.channel2currentSampleRight, this.channel3currentSampleLeft, this.channel3currentSampleRight, this.channel4currentSampleLeft, this.channel4currentSampleRight, this.channel1currentSampleLeftSecondary, this.channel1currentSampleRightSecondary, this.channel2currentSampleLeftSecondary, this.channel2currentSampleRightSecondary, this.channel3currentSampleLeftSecondary, this.channel3currentSampleRightSecondary, this.channel4currentSampleLeftSecondary, this.channel4currentSampleRightSecondary, this.channel1currentSampleLeftTrimary, this.channel1currentSampleRightTrimary, this.channel2currentSampleLeftTrimary, this.channel2currentSampleRightTrimary, this.mixerOutputCache, this.channel1DutyTracker, this.channel1CachedDuty, this.channel2DutyTracker, this.channel2CachedDuty, this.channel1Enabled, this.channel2Enabled, this.channel3Enabled, this.channel4Enabled, this.sequencerClocks, this.sequencePosition, this.channel3Counter, this.channel4Counter, this.cachedChannel3Sample, this.cachedChannel4Sample, this.channel3FrequencyPeriod, this.channel3lastSampleLookup, this.actualScanLine, this.lastUnrenderedLine, this.queuedScanLines, this.RTCisLatched, this.latchedSeconds, this.latchedMinutes, this.latchedHours, this.latchedLDays, this.latchedHDays, this.RTCSeconds, this.RTCMinutes, this.RTCHours, this.RTCDays, this.RTCDayOverFlow, this.RTCHALT, this.usedBootROM, this.skipPCIncrement, this.STATTracker, this.gbcRamBankPositionECHO, this.numRAMBanks, this.windowY, this.windowX, this.fromTypedArray(this.gbcOBJRawPalette), this.fromTypedArray(this.gbcBGRawPalette), this.fromTypedArray(this.gbOBJPalette), this.fromTypedArray(this.gbBGPalette), this.fromTypedArray(this.gbcOBJPalette), this.fromTypedArray(this.gbcBGPalette), this.fromTypedArray(this.gbBGColorizedPalette), this.fromTypedArray(this.gbOBJColorizedPalette), this.fromTypedArray(this.cachedBGPaletteConversion), this.fromTypedArray(this.cachedOBJPaletteConversion), this.fromTypedArray(this.BGCHRBank1), this.fromTypedArray(this.BGCHRBank2), this.haltPostClocks, this.interruptsRequested, this.interruptsEnabled, this.remainingClocks, this.colorizedGBPalettes, this.backgroundY, this.backgroundX, this.CPUStopped]
};
GameBoyCore.prototype.returnFromState = function (a) {
var b = 0,
a = a.slice(0);
this.ROM = this.toTypedArray(a[b++], "uint8");
this.ROMBankEdge = Math.floor(this.ROM.length / 16384);
this.inBootstrap = a[b++];
this.registerA = a[b++];
this.FZero = a[b++];
this.FSubtract = a[b++];
this.FHalfCarry = a[b++];
this.FCarry = a[b++];
this.registerB = a[b++];
this.registerC = a[b++];
this.registerD = a[b++];
this.registerE = a[b++];
this.registersHL = a[b++];
this.stackPointer = a[b++];
this.programCounter = a[b++];
this.halt = a[b++];
this.IME = a[b++];
this.hdmaRunning = a[b++];
this.CPUTicks = a[b++];
this.doubleSpeedShifter = a[b++];
this.memory = this.toTypedArray(a[b++], "uint8");
this.MBCRam = this.toTypedArray(a[b++], "uint8");
this.VRAM = this.toTypedArray(a[b++], "uint8");
this.currVRAMBank = a[b++];
this.GBCMemory = this.toTypedArray(a[b++], "uint8");
this.MBC1Mode = a[b++];
this.MBCRAMBanksEnabled = a[b++];
this.currMBCRAMBank = a[b++];
this.currMBCRAMBankPosition = a[b++];
this.cGBC = a[b++];
this.gbcRamBank = a[b++];
this.gbcRamBankPosition = a[b++];
this.ROMBank1offs = a[b++];
this.currentROMBank = a[b++];
this.cartridgeType = a[b++];
this.name = a[b++];
this.gameCode = a[b++];
this.modeSTAT = a[b++];
this.LYCMatchTriggerSTAT = a[b++];
this.mode2TriggerSTAT = a[b++];
this.mode1TriggerSTAT = a[b++];
this.mode0TriggerSTAT = a[b++];
this.LCDisOn = a[b++];
this.gfxWindowCHRBankPosition = a[b++];
this.gfxWindowDisplay = a[b++];
this.gfxSpriteShow = a[b++];
this.gfxSpriteNormalHeight = a[b++];
this.gfxBackgroundCHRBankPosition = a[b++];
this.gfxBackgroundBankOffset = a[b++];
this.TIMAEnabled = a[b++];
this.DIVTicks = a[b++];
this.LCDTicks = a[b++];
this.timerTicks = a[b++];
this.TACClocker = a[b++];
this.serialTimer = a[b++];
this.serialShiftTimer = a[b++];
this.serialShiftTimerAllocated = a[b++];
this.IRQEnableDelay = a[b++];
this.lastIteration = a[b++];
this.cMBC1 = a[b++];
this.cMBC2 = a[b++];
this.cMBC3 = a[b++];
this.cMBC5 = a[b++];
this.cMBC7 = a[b++];
this.cSRAM = a[b++];
this.cMMMO1 = a[b++];
this.cRUMBLE = a[b++];
this.cCamera = a[b++];
this.cTAMA5 = a[b++];
this.cHuC3 = a[b++];
this.cHuC1 = a[b++];
this.drewBlank = a[b++];
this.frameBuffer = this.toTypedArray(a[b++], "int32");
this.bgEnabled = a[b++];
this.BGPriorityEnabled = a[b++];
this.channel1FrequencyTracker = a[b++];
this.channel1FrequencyCounter = a[b++];
this.channel1totalLength = a[b++];
this.channel1envelopeVolume = a[b++];
this.channel1envelopeType = a[b++];
this.channel1envelopeSweeps = a[b++];
this.channel1envelopeSweepsLast = a[b++];
this.channel1consecutive = a[b++];
this.channel1frequency = a[b++];
this.channel1SweepFault = a[b++];
this.channel1ShadowFrequency = a[b++];
this.channel1timeSweep = a[b++];
this.channel1lastTimeSweep = a[b++];
this.channel1numSweep = a[b++];
this.channel1frequencySweepDivider = a[b++];
this.channel1decreaseSweep = a[b++];
this.channel2FrequencyTracker = a[b++];
this.channel2FrequencyCounter = a[b++];
this.channel2totalLength = a[b++];
this.channel2envelopeVolume = a[b++];
this.channel2envelopeType = a[b++];
this.channel2envelopeSweeps = a[b++];
this.channel2envelopeSweepsLast = a[b++];
this.channel2consecutive = a[b++];
this.channel2frequency = a[b++];
this.channel3canPlay = a[b++];
this.channel3totalLength = a[b++];
this.channel3patternType = a[b++];
this.channel3frequency = a[b++];
this.channel3consecutive = a[b++];
this.channel3PCM = this.toTypedArray(a[b++], "int8");
this.channel4FrequencyPeriod = a[b++];
this.channel4lastSampleLookup = a[b++];
this.channel4totalLength = a[b++];
this.channel4envelopeVolume = a[b++];
this.channel4currentVolume = a[b++];
this.channel4envelopeType = a[b++];
this.channel4envelopeSweeps = a[b++];
this.channel4envelopeSweepsLast = a[b++];
this.channel4consecutive = a[b++];
this.channel4BitRange = a[b++];
this.soundMasterEnabled = a[b++];
this.VinLeftChannelMasterVolume = a[b++];
this.VinRightChannelMasterVolume = a[b++];
this.leftChannel1 = a[b++];
this.leftChannel2 = a[b++];
this.leftChannel3 = a[b++];
this.leftChannel4 = a[b++];
this.rightChannel1 = a[b++];
this.rightChannel2 = a[b++];
this.rightChannel3 = a[b++];
this.rightChannel4 = a[b++];
this.channel1currentSampleLeft = a[b++];
this.channel1currentSampleRight = a[b++];
this.channel2currentSampleLeft = a[b++];
this.channel2currentSampleRight = a[b++];
this.channel3currentSampleLeft = a[b++];
this.channel3currentSampleRight = a[b++];
this.channel4currentSampleLeft = a[b++];
this.channel4currentSampleRight = a[b++];
this.channel1currentSampleLeftSecondary = a[b++];
this.channel1currentSampleRightSecondary = a[b++];
this.channel2currentSampleLeftSecondary = a[b++];
this.channel2currentSampleRightSecondary = a[b++];
this.channel3currentSampleLeftSecondary = a[b++];
this.channel3currentSampleRightSecondary = a[b++];
this.channel4currentSampleLeftSecondary = a[b++];
this.channel4currentSampleRightSecondary = a[b++];
this.channel1currentSampleLeftTrimary = a[b++];
this.channel1currentSampleRightTrimary = a[b++];
this.channel2currentSampleLeftTrimary = a[b++];
this.channel2currentSampleRightTrimary = a[b++];
this.mixerOutputCache = a[b++];
this.channel1DutyTracker = a[b++];
this.channel1CachedDuty = a[b++];
this.channel2DutyTracker = a[b++];
this.channel2CachedDuty = a[b++];
this.channel1Enabled = a[b++];
this.channel2Enabled = a[b++];
this.channel3Enabled = a[b++];
this.channel4Enabled = a[b++];
this.sequencerClocks = a[b++];
this.sequencePosition = a[b++];
this.channel3Counter = a[b++];
this.channel4Counter = a[b++];
this.cachedChannel3Sample = a[b++];
this.cachedChannel4Sample = a[b++];
this.channel3FrequencyPeriod = a[b++];
this.channel3lastSampleLookup = a[b++];
this.actualScanLine = a[b++];
this.lastUnrenderedLine = a[b++];
this.queuedScanLines = a[b++];
this.RTCisLatched = a[b++];
this.latchedSeconds = a[b++];
this.latchedMinutes = a[b++];
this.latchedHours = a[b++];
this.latchedLDays = a[b++];
this.latchedHDays = a[b++];
this.RTCSeconds = a[b++];
this.RTCMinutes = a[b++];
this.RTCHours = a[b++];
this.RTCDays = a[b++];
this.RTCDayOverFlow = a[b++];
this.RTCHALT = a[b++];
this.usedBootROM = a[b++];
this.skipPCIncrement = a[b++];
this.STATTracker = a[b++];
this.gbcRamBankPositionECHO = a[b++];
this.numRAMBanks = a[b++];
this.windowY = a[b++];
this.windowX = a[b++];
this.gbcOBJRawPalette = this.toTypedArray(a[b++], "uint8");
this.gbcBGRawPalette = this.toTypedArray(a[b++], "uint8");
this.gbOBJPalette = this.toTypedArray(a[b++], "int32");
this.gbBGPalette = this.toTypedArray(a[b++], "int32");
this.gbcOBJPalette = this.toTypedArray(a[b++], "int32");
this.gbcBGPalette = this.toTypedArray(a[b++], "int32");
this.gbBGColorizedPalette = this.toTypedArray(a[b++], "int32");
this.gbOBJColorizedPalette = this.toTypedArray(a[b++], "int32");
this.cachedBGPaletteConversion = this.toTypedArray(a[b++], "int32");
this.cachedOBJPaletteConversion = this.toTypedArray(a[b++], "int32");
this.BGCHRBank1 = this.toTypedArray(a[b++], "uint8");
this.BGCHRBank2 = this.toTypedArray(a[b++], "uint8");
this.haltPostClocks = a[b++];
this.interruptsRequested = a[b++];
this.interruptsEnabled = a[b++];
this.checkIRQMatching();
this.remainingClocks = a[b++];
this.colorizedGBPalettes = a[b++];
this.backgroundY = a[b++];
this.backgroundX = a[b++];
this.CPUStopped = a[b];
this.fromSaveState = true;
this.TICKTable = this.toTypedArray(this.TICKTable, "uint8");
this.SecondaryTICKTable = this.toTypedArray(this.SecondaryTICKTable, "uint8");
this.initializeReferencesFromSaveState();
this.memoryReadJumpCompile();
this.memoryWriteJumpCompile();
this.initLCD();
this.initSound();
this.noiseSampleTable = this.channel4BitRange == 32767 ? this.LSFR15Table : this.LSFR7Table;
this.channel4VolumeShifter = this.channel4BitRange == 32767 ? 15 : 7
};
GameBoyCore.prototype.returnFromRTCState = function () {
if (typeof this.openRTC == "function" && this.cTIMER) {
var a = this.openRTC(this.name),
b = 0;
this.lastIteration = a[b++];
this.RTCisLatched = a[b++];
this.latchedSeconds = a[b++];
this.latchedMinutes = a[b++];
this.latchedHours = a[b++];
this.latchedLDays = a[b++];
this.latchedHDays = a[b++];
this.RTCSeconds = a[b++];
this.RTCMinutes = a[b++];
this.RTCHours = a[b++];
this.RTCDays = a[b++];
this.RTCDayOverFlow = a[b++];
this.RTCHALT = a[b]
}
};
GameBoyCore.prototype.start = function () {
this.initMemory();
this.ROMLoad();
this.initLCD();
this.initSound();
this.run()
};
GameBoyCore.prototype.initMemory = function () {
this.memory = this.getTypedArray(65536, 0, "uint8");
this.frameBuffer = this.getTypedArray(23040, 16316664, "int32");
this.BGCHRBank1 = this.getTypedArray(2048, 0, "uint8");
this.TICKTable = this.toTypedArray(this.TICKTable, "uint8");
this.SecondaryTICKTable = this.toTypedArray(this.SecondaryTICKTable, "uint8");
this.channel3PCM = this.getTypedArray(32, 0, "int8")
};
GameBoyCore.prototype.generateCacheArray = function (a) {
for (var b = [], c = 0; c < a;) b[c++] = this.getTypedArray(64, 0, "uint8");
return b
};
GameBoyCore.prototype.initSkipBootstrap = function () {
for (var a = 255; a >= 0;) {
if (a >= 48 && a < 64) this.memoryWrite(65280 | a, this.ffxxDump[a]);
else switch (a) {
case 0:
case 1:
case 2:
case 5:
case 7:
case 15:
case 255:
this.memoryWrite(65280 | a, this.ffxxDump[a]);
break;
default:
this.memory[65280 | a] = this.ffxxDump[a]
}--a
}
if (this.cGBC) {
this.memory[65388] = 254;
this.memory[65396] = 254
} else {
this.memory[65352] = 255;
this.memory[65353] = 255;
this.memory[65388] = 255;
this.memory[65396] = 255
}
cout("Starting without the GBC boot ROM.", 0);
this.registerA = this.cGBC ? 17 : 1;
this.registerB = 0;
this.registerC = 19;
this.registerD = 0;
this.registerE = 216;
this.FZero = true;
this.FSubtract = false;
this.FCarry = this.FHalfCarry = true;
this.registersHL = 333;
this.LCDCONTROL = this.LINECONTROL;
this.IME = false;
this.IRQLineMatched = 0;
this.interruptsRequested = 225;
this.interruptsEnabled = 0;
this.hdmaRunning = false;
this.CPUTicks = 12;
this.STATTracker = 0;
this.modeSTAT = 1;
this.spriteCount = 252;
this.mode0TriggerSTAT = this.mode1TriggerSTAT = this.mode2TriggerSTAT = this.LYCMatchTriggerSTAT = false;
this.LCDisOn = true;
this.channel1FrequencyTracker = 8192;
this.channel1DutyTracker = 0;
this.channel1CachedDuty = this.dutyLookup[2];
this.channel1envelopeVolume = this.channel1totalLength = 0;
this.channel1envelopeType = false;
this.channel1envelopeSweepsLast = this.channel1envelopeSweeps = 0;
this.channel1consecutive = true;
this.channel1frequency = 1985;
this.channel1SweepFault = true;
this.channel1ShadowFrequency = 1985;
this.channel1timeSweep = 1;
this.channel1frequencySweepDivider = this.channel1numSweep = this.channel1lastTimeSweep = 0;
this.channel1decreaseSweep = false;
this.channel2FrequencyTracker = 8192;
this.channel2DutyTracker = 0;
this.channel2CachedDuty = this.dutyLookup[2];
this.channel2envelopeVolume = this.channel2totalLength = 0;
this.channel2envelopeType = false;
this.channel2envelopeSweepsLast = this.channel2envelopeSweeps = 0;
this.channel2consecutive = true;
this.channel2frequency = 0;
this.channel3canPlay = false;
this.channel3totalLength = 0;
this.channel3patternType = 4;
this.channel3frequency = 0;
this.channel3consecutive = true;
this.channel3Counter = 1048;
this.channel4FrequencyPeriod = 8;
this.channel4currentVolume = this.channel4envelopeVolume = this.channel4totalLength = 0;
this.channel4envelopeType = false;
this.channel4envelopeSweepsLast = this.channel4envelopeSweeps = 0;
this.channel4consecutive = true;
this.channel4BitRange = 32767;
this.channel4VolumeShifter = 15;
this.channel2FrequencyCounter = this.channel1FrequencyCounter = 512;
this.channel3FrequencyPeriod = this.channel3Counter = 2048;
this.channel4lastSampleLookup = this.channel3lastSampleLookup = 0;
this.VinRightChannelMasterVolume = this.VinLeftChannelMasterVolume = 1;
this.rightChannel2 = this.rightChannel1 = this.leftChannel4 = this.leftChannel3 = this.leftChannel2 = this.leftChannel1 = this.soundMasterEnabled = true;
this.rightChannel4 = this.rightChannel3 = false;
this.DIVTicks = 27044;
this.LCDTicks = 160;
this.timerTicks = 0;
this.TIMAEnabled = false;
this.TACClocker = 1024;
this.IRQEnableDelay = this.serialShiftTimerAllocated = this.serialShiftTimer = this.serialTimer = 0;
this.actualScanLine = 144;
this.lastUnrenderedLine = 0;
this.gfxSpriteShow = this.gfxWindowDisplay = false;
this.BGPriorityEnabled = this.bgEnabled = this.gfxSpriteNormalHeight = true;
this.drewBlank = this.windowX = this.windowY = this.gfxBackgroundBankOffset = this.gfxBackgroundCHRBankPosition = this.gfxWindowCHRBankPosition = 0;
this.midScanlineOffset = -1;
this.currentX = 0
};
GameBoyCore.prototype.initBootstrap = function () {
cout("Starting the selected boot ROM.", 0);
this.stackPointer = this.programCounter = 0;
this.IME = false;
this.registerE = this.registerD = this.registerC = this.registerB = this.registerA = this.DIVTicks = this.LCDTicks = 0;
this.FZero = this.FSubtract = this.FHalfCarry = this.FCarry = false;
this.registersHL = 0;
this.rightChannel4 = this.rightChannel3 = this.rightChannel2 = this.rightChannel1 = this.leftChannel4 = this.leftChannel3 = this.leftChannel2 = this.leftChannel1 = false;
this.channel2frequency = this.channel1frequency = 0;
this.channel4consecutive = this.channel2consecutive = this.channel1consecutive = false;
this.VinRightChannelMasterVolume = this.VinLeftChannelMasterVolume = 8;
this.memory[65280] = 15
};
GameBoyCore.prototype.ROMLoad = function () {
this.ROM = [];
this.usedBootROM = settings[1];
var a = this.ROMImage.length;
if (a < 16384) throw Error("ROM image size too small.");
this.ROM = this.getTypedArray(a, 0, "uint8");
var b = 0;
if (this.usedBootROM) if (settings[11]) for (; b < 256; ++b) {
this.memory[b] = this.GBBOOTROM[b];
this.ROM[b] = this.ROMImage.charCodeAt(b) & 255
} else {
for (; b < 256; ++b) {
this.memory[b] = this.GBCBOOTROM[b];
this.ROM[b] = this.ROMImage.charCodeAt(b) & 255
}
for (; b < 512; ++b) this.memory[b] = this.ROM[b] = this.ROMImage.charCodeAt(b) & 255;
for (; b < 2304; ++b) {
this.memory[b] = this.GBCBOOTROM[b - 256];
this.ROM[b] = this.ROMImage.charCodeAt(b) & 255
}
this.usedGBCBootROM = true
}
for (; b < 16384; ++b) this.memory[b] = this.ROM[b] = this.ROMImage.charCodeAt(b) & 255;
for (; b < a; ++b) this.ROM[b] = this.ROMImage.charCodeAt(b) & 255;
this.ROMBankEdge = Math.floor(this.ROM.length / 16384);
this.interpretCartridge();
this.checkIRQMatching()
};
GameBoyCore.prototype.getROMImage = function () {
if (this.ROMImage.length > 0) return this.ROMImage.length;
for (var a = this.ROM.length, b = 0; b < a; b++) this.ROMImage = this.ROMImage + String.fromCharCode(this.ROM[b]);
return this.ROMImage
};
GameBoyCore.prototype.interpretCartridge = function () {
for (var a = 308; a < 319; a++) if (this.ROMImage.charCodeAt(a) > 0) this.name = this.name + this.ROMImage[a];
for (a = 319; a < 323; a++) if (this.ROMImage.charCodeAt(a) > 0) this.gameCode = this.gameCode + this.ROMImage[a];
cout("Game Title: " + this.name + "[" + this.gameCode + "][" + this.ROMImage[323] + "]", 0);
cout("Game Code: " + this.gameCode, 0);
this.cartridgeType = this.ROM[327];
cout("Cartridge type #" + this.cartridgeType, 0);
a = "";
switch (this.cartridgeType) {
case 0:
if (!settings[9]) {
a = "ROM";
break
}
case 1:
this.cMBC1 = true;
a = "MBC1";
break;
case 2:
this.cSRAM = this.cMBC1 = true;
a = "MBC1 + SRAM";
break;
case 3:
this.cBATT = this.cSRAM = this.cMBC1 = true;
a = "MBC1 + SRAM + BATT";
break;
case 5:
this.cMBC2 = true;
a = "MBC2";
break;
case 6:
this.cBATT = this.cMBC2 = true;
a = "MBC2 + BATT";
break;
case 8:
this.cSRAM = true;
a = "ROM + SRAM";
break;
case 9:
this.cBATT = this.cSRAM = true;
a = "ROM + SRAM + BATT";
break;
case 11:
this.cMMMO1 = true;
a = "MMMO1";
break;
case 12:
this.cSRAM = this.cMMMO1 = true;
a = "MMMO1 + SRAM";
break;
case 13:
this.cBATT = this.cSRAM = this.cMMMO1 = true;
a = "MMMO1 + SRAM + BATT";
break;
case 15:
this.cBATT = this.cTIMER = this.cMBC3 = true;
a = "MBC3 + TIMER + BATT";
break;
case 16:
this.cSRAM = this.cBATT = this.cTIMER = this.cMBC3 = true;
a = "MBC3 + TIMER + BATT + SRAM";
break;
case 17:
this.cMBC3 = true;
a = "MBC3";
break;
case 18:
this.cSRAM = this.cMBC3 = true;
a = "MBC3 + SRAM";
break;
case 19:
this.cBATT = this.cSRAM = this.cMBC3 = true;
a = "MBC3 + SRAM + BATT";
break;
case 25:
this.cMBC5 = true;
a = "MBC5";
break;
case 26:
this.cSRAM = this.cMBC5 = true;
a = "MBC5 + SRAM";
break;
case 27:
this.cBATT = this.cSRAM = this.cMBC5 = true;
a = "MBC5 + SRAM + BATT";
break;
case 28:
this.cRUMBLE = true;
a = "RUMBLE";
break;
case 29:
this.cSRAM = this.cRUMBLE = true;
a = "RUMBLE + SRAM";
break;
case 30:
this.cBATT = this.cSRAM = this.cRUMBLE = true;
a = "RUMBLE + SRAM + BATT";
break;
case 31:
this.cCamera = true;
a = "GameBoy Camera";
break;
case 34:
this.cBATT = this.cSRAM = this.cMBC7 = true;
a = "MBC7 + SRAM + BATT";
break;
case 253:
this.cTAMA5 = true;
a = "TAMA5";
break;
case 254:
this.cHuC3 = true;
a = "HuC3";
break;
case 255:
this.cHuC1 = true;
a = "HuC1";
break;
default:
a = "Unknown";
cout("Cartridge type is unknown.", 2);
pause()
}
cout("Cartridge Type: " + a + ".", 0);
this.numROMBanks = this.ROMBanks[this.ROM[328]];
cout(this.numROMBanks + " ROM banks.", 0);
switch (this.RAMBanks[this.ROM[329]]) {
case 0:
cout("No RAM banking requested for allocation or MBC is of type 2.", 0);
break;
case 2:
cout("1 RAM bank requested for allocation.", 0);
break;
case 3:
cout("4 RAM banks requested for allocation.", 0);
break;
case 4:
cout("16 RAM banks requested for allocation.", 0);
break;
default:
cout("RAM bank amount requested is unknown, will use maximum allowed by specified MBC type.", 0)
}
if (this.usedBootROM) {
this.cGBC = this.usedGBCBootROM;
this.setupRAM();
this.initBootstrap()
} else {
switch (this.ROM[323]) {
case 0:
this.cGBC = false;
cout("Only GB mode detected.", 0);
break;
case 50:
if (!settings[2] && this.name + this.gameCode + this.ROM[323] == "Game and Watch 50") {
this.cGBC = true;
cout("Created a boot exception for Game and Watch Gallery 2 (GBC ID byte is wrong on the cartridge).", 1)
} else this.cGBC = false;
break;
case 128:
this.cGBC = !settings[2];
cout("GB and GBC mode detected.", 0);
break;
case 192:
this.cGBC = true;
cout("Only GBC mode detected.", 0);
break;
default:
this.cGBC = false;
cout("Unknown GameBoy game type code #" + this.ROM[323] + ", defaulting to GB mode (Old games don't have a type code).", 1)
}
this.inBootstrap = false;
this.setupRAM();
this.initSkipBootstrap()
}
this.initializeModeSpecificArrays();
var a = this.ROM[331],
b = this.ROM[324] & 65280 | this.ROM[325] & 255;
a != 51 ? cout("Old style license code: " + a, 0) : cout("New style license code: " + b, 0);
this.ROMImage = ""
};
GameBoyCore.prototype.disableBootROM = function () {
for (var a = 0; a < 256; ++a) this.memory[a] = this.ROM[a];
if (this.usedGBCBootROM) {
for (a = 512; a < 2304; ++a) this.memory[a] = this.ROM[a];
this.cGBC ? this.recompileBootIOWriteHandling() : this.GBCtoGBModeAdjust()
} else this.recompileBootIOWriteHandling()
};
GameBoyCore.prototype.initializeTiming = function () {
this.baseCPUCyclesPerIteration = 4194.304 * settings[6];
this.CPUCyclesTotalRoundoff = this.baseCPUCyclesPerIteration % 4;
this.CPUCyclesTotalBase = this.CPUCyclesTotal = this.baseCPUCyclesPerIteration - this.CPUCyclesTotalRoundoff | 0;
this.CPUCyclesTotalCurrent = 0
};
GameBoyCore.prototype.setupRAM = function () {
if (this.cMBC2) this.numRAMBanks = 0.0625;
else if (this.cMBC1 || this.cRUMBLE || this.cMBC3 || this.cHuC3) this.numRAMBanks = 4;
else if (this.cMBC5) this.numRAMBanks = 16;
else if (this.cSRAM) this.numRAMBanks = 1;
if (this.numRAMBanks > 0) {
if (!this.MBCRAMUtilized()) this.MBCRAMBanksEnabled = true;
var a = typeof this.openMBC == "function" ? this.openMBC(this.name) : [];
this.MBCRam = a.length > 0 ? this.toTypedArray(a, "uint8") : this.getTypedArray(this.numRAMBanks * 8192, 0, "uint8")
}
cout("Actual bytes of MBC RAM allocated: " + this.numRAMBanks * 8192, 0);
this.returnFromRTCState();
if (this.cGBC) {
this.VRAM = this.getTypedArray(8192, 0, "uint8");
this.GBCMemory = this.getTypedArray(28672, 0, "uint8")
}
this.memoryReadJumpCompile();
this.memoryWriteJumpCompile()
};
GameBoyCore.prototype.MBCRAMUtilized = function () {
return this.cMBC1 || this.cMBC2 || this.cMBC3 || this.cMBC5 || this.cMBC7 || this.cRUMBLE
};
GameBoyCore.prototype.recomputeDimension = function () {
initNewCanvas();
this.onscreenWidth = this.canvas.width;
this.onscreenHeight = this.canvas.height;
if (window && window.mozRequestAnimationFrame) {
this.canvas.width = this.onscreenWidth = !settings[12] ? 160 : this.canvas.width;
this.canvas.height = this.onscreenHeight = !settings[12] ? 144 : this.canvas.height
} else {
this.onscreenWidth = this.canvas.width;
this.onscreenHeight = this.canvas.height
}
this.offscreenWidth = !settings[12] ? 160 : this.canvas.width;
this.offscreenHeight = !settings[12] ? 144 : this.canvas.height;
this.offscreenRGBCount = this.offscreenWidth * this.offscreenHeight * 4
};
GameBoyCore.prototype.initLCD = function () {
this.recomputeDimension();
this.offscreenRGBCount != 92160 ? this.compileResizeFrameBufferFunction() : this.resizer = null;
try {
this.canvasOffscreen = document.createElement("canvas");
this.canvasOffscreen.width = this.offscreenWidth;
this.canvasOffscreen.height = this.offscreenHeight;
this.drawContextOffscreen = this.canvasOffscreen.getContext("2d");
this.drawContextOnscreen = this.canvas.getContext("2d");
try {
this.canvasBuffer = this.drawContextOffscreen.createImageData(this.offscreenWidth, this.offscreenHeight)
} catch (a) {
cout('Falling back to the getImageData initialization (Error "' + a.message + '").', 1);
this.canvasBuffer = this.drawContextOffscreen.getImageData(0, 0, this.offscreenWidth, this.offscreenHeight)
}
for (var b = this.offscreenRGBCount; b > 0;) {
this.canvasBuffer.data[b = b - 4] = 248;
this.canvasBuffer.data[b + 1] = 248;
this.canvasBuffer.data[b + 2] = 248;
this.canvasBuffer.data[b + 3] = 255
}
this.graphicsBlit();
this.canvas.style.visibility = "visible";
if (this.swizzledFrame == null) this.swizzledFrame = this.getTypedArray(69120, 255, "uint8");
this.drewFrame = true;
this.requestDraw()
} catch (c) {
throw Error("HTML5 Canvas support required: " + c.message + "file: " + c.fileName + ", line: " + c.lineNumber);
}
};
GameBoyCore.prototype.graphicsBlit = function () {
if (this.offscreenWidth == this.onscreenWidth && this.offscreenHeight == this.onscreenHeight) this.drawContextOnscreen.putImageData(this.canvasBuffer, 0, 0);
else {
this.drawContextOffscreen.putImageData(this.canvasBuffer, 0, 0);
this.drawContextOnscreen.drawImage(this.canvasOffscreen, 0, 0, this.onscreenWidth, this.onscreenHeight)
}
};
GameBoyCore.prototype.JoyPadEvent = function (a, b) {
if (b) {
this.JoyPad = this.JoyPad & (255 ^ 1 << a);
if (!this.cGBC && (!this.usedBootROM || !this.usedGBCBootROM)) {
this.interruptsRequested = this.interruptsRequested | 16;
this.remainingClocks = 0;
this.checkIRQMatching()
}
} else this.JoyPad = this.JoyPad | 1 << a;
this.memory[65280] = (this.memory[65280] & 48) + (((this.memory[65280] & 32) == 0 ? this.JoyPad >> 4 : 15) & ((this.memory[65280] & 16) == 0 ? this.JoyPad & 15 : 15));
this.CPUStopped = false
};
GameBoyCore.prototype.GyroEvent = function (a, b) {
a = a * -100 + 2047;
this.highX = a >> 8;
this.lowX = a & 255;
b = b * -100 + 2047;
this.highY = b >> 8;
this.lowY = b & 255
};
GameBoyCore.prototype.initSound = function () {
this.sampleSize = 4194.304 * settings[6];
this.machineOut = this.audioResamplerFirstPassFactor = Math.floor(95.10893424036281);
if (settings[0]) try {
this.audioHandle = new XAudioServer(2, 4194304 / this.audioResamplerFirstPassFactor, 0, Math.max(this.sampleSize * settings[8] / this.audioResamplerFirstPassFactor, 8192) << 1, null, settings[13]);
this.initAudioBuffer()
} catch (a) {
cout("Audio system cannot run: " + a.message, 2);
settings[0] = false
} else if (this.audioHandle) try {
this.audioHandle.changeVolume(0)
} catch (b) {}
};
GameBoyCore.prototype.changeVolume = function () {
if (settings[0] && this.audioHandle) try {
this.audioHandle.changeVolume(settings[13])
} catch (a) {}
};
GameBoyCore.prototype.initAudioBuffer = function () {
this.audioIndex = 0;
this.bufferContainAmount = Math.max(this.sampleSize * settings[7] / this.audioResamplerFirstPassFactor, 4096) << 1;
this.numSamplesTotal = this.sampleSize - this.sampleSize % this.audioResamplerFirstPassFactor | 0;
this.currentBuffer = this.getTypedArray(this.numSamplesTotal, 0, "int32");
this.secondaryBuffer = this.getTypedArray((this.numSamplesTotal << 1) / this.audioResamplerFirstPassFactor, 0, "float32")
};
GameBoyCore.prototype.intializeWhiteNoise = function () {
var a = 1;
this.LSFR15Table = this.getTypedArray(524288, 0, "int8");
for (var b = 32767, a = 16383, c = 0; c < 32768; ++c) {
a = 1 - (b & 1);
this.LSFR15Table[32768 | c] = a;
this.LSFR15Table[65536 | c] = a * 2;
this.LSFR15Table[98304 | c] = a * 3;
this.LSFR15Table[131072 | c] = a * 4;
this.LSFR15Table[163840 | c] = a * 5;
this.LSFR15Table[196608 | c] = a * 6;
this.LSFR15Table[229376 | c] = a * 7;
this.LSFR15Table[262144 | c] = a * 8;
this.LSFR15Table[294912 | c] = a * 9;
this.LSFR15Table[327680 | c] = a * 10;
this.LSFR15Table[360448 | c] = a * 11;
this.LSFR15Table[393216 | c] = a * 12;
this.LSFR15Table[425984 | c] = a * 13;
this.LSFR15Table[458752 | c] = a * 14;
this.LSFR15Table[491520 | c] = a * 15;
a = b >> 1;
b = a | ((a ^ b) & 1) << 14
}
this.LSFR7Table = this.getTypedArray(2048, 0, "int8");
b = 127;
for (c = 0; c < 128; ++c) {
a = 1 - (b & 1);
this.LSFR7Table[128 | c] = a;
this.LSFR7Table[256 | c] = a * 2;
this.LSFR7Table[384 | c] = a * 3;
this.LSFR7Table[512 | c] = a * 4;
this.LSFR7Table[640 | c] = a * 5;
this.LSFR7Table[768 | c] = a * 6;
this.LSFR7Table[896 | c] = a * 7;
this.LSFR7Table[1024 | c] = a * 8;
this.LSFR7Table[1152 | c] = a * 9;
this.LSFR7Table[1280 | c] = a * 10;
this.LSFR7Table[1408 | c] = a * 11;
this.LSFR7Table[1536 | c] = a * 12;
this.LSFR7Table[1664 | c] = a * 13;
this.LSFR7Table[1792 | c] = a * 14;
this.LSFR7Table[1920 | c] = a * 15;
a = b >> 1;
b = a | ((a ^ b) & 1) << 6
}
if (!this.noiseSampleTable && this.memory.length == 65536) this.noiseSampleTable = (this.memory[65314] & 8) == 8 ? this.LSFR7Table : this.LSFR15Table
};
GameBoyCore.prototype.audioUnderrunAdjustment = function () {
if (settings[0]) {
var a = this.bufferContainAmount - this.audioHandle.remainingBuffer();
if (a > 0) {
this.CPUCyclesTotalCurrent = this.CPUCyclesTotalCurrent + (a >> 1) * this.machineOut;
this.recalculateIterationClockLimit()
}
}
};
GameBoyCore.prototype.initializeAudioStartState = function () {
this.channel1FrequencyTracker = 8192;
this.channel1DutyTracker = 0;
this.channel1CachedDuty = this.dutyLookup[2];
this.channel1envelopeVolume = this.channel1totalLength = 0;
this.channel1envelopeType = false;
this.channel1envelopeSweepsLast = this.channel1envelopeSweeps = 0;
this.channel1consecutive = true;
this.channel1frequency = 0;
this.channel1SweepFault = false;
this.channel1ShadowFrequency = 0;
this.channel1timeSweep = 1;
this.channel1frequencySweepDivider = this.channel1numSweep = this.channel1lastTimeSweep = 0;
this.channel1decreaseSweep = false;
this.channel2FrequencyTracker = 8192;
this.channel2DutyTracker = 0;
this.channel2CachedDuty = this.dutyLookup[2];
this.channel2envelopeVolume = this.channel2totalLength = 0;
this.channel2envelopeType = false;
this.channel2envelopeSweepsLast = this.channel2envelopeSweeps = 0;
this.channel2consecutive = true;
this.channel2frequency = 0;
this.channel3canPlay = false;
this.channel3totalLength = 0;
this.channel3patternType = 4;
this.channel3frequency = 0;
this.channel3consecutive = true;
this.channel3Counter = 2048;
this.channel4FrequencyPeriod = 8;
this.channel4currentVolume = this.channel4envelopeVolume = this.channel4totalLength = 0;
this.channel4envelopeType = false;
this.channel4envelopeSweepsLast = this.channel4envelopeSweeps = 0;
this.channel4consecutive = true;
this.channel4BitRange = 32767;
this.noiseSampleTable = this.LSFR15Table;
this.channel4VolumeShifter = 15;
this.channel2FrequencyCounter = this.channel1FrequencyCounter = 8192;
this.channel3FrequencyPeriod = this.channel3Counter = 2048;
this.channel4lastSampleLookup = this.channel3lastSampleLookup = 0;
this.VinRightChannelMasterVolume = this.VinLeftChannelMasterVolume = 8;
this.mixerOutputCache = 0;
this.sequencerClocks = 8192;
this.sequencePosition = 0;
this.channel4Counter = this.channel4FrequencyPeriod = 8;
this.cachedChannel4Sample = this.cachedChannel3Sample = 0;
this.channel4canPlay = this.channel2canPlay = this.channel1canPlay = this.channel4Enabled = this.channel3Enabled = this.channel2Enabled = this.channel1Enabled = false;
this.channel1OutputLevelCache();
this.channel2OutputLevelCache();
this.channel3OutputLevelCache();
this.channel4OutputLevelCache()
};
GameBoyCore.prototype.outputAudio = function () {
for (var a = 0, b = 0, c = 0, e = 0, f = 0, g = this.audioResamplerFirstPassFactor * 240, d = 0; d < this.numSamplesTotal;) {
for (a = c = e = 0; a < this.audioResamplerFirstPassFactor; ++a) {
b = this.currentBuffer[d++];
c = c + (b >> 9);
e = e + (b & 511)
}
this.secondaryBuffer[f++] = c / g - 1;
this.secondaryBuffer[f++] = e / g - 1
}
this.audioHandle.writeAudioNoCallback(this.secondaryBuffer)
};
GameBoyCore.prototype.generateAudio = function (a) {
if (this.soundMasterEnabled && !this.CPUStopped) for (var b = 0; a > 0;) {
b = a < this.sequencerClocks ? a : this.sequencerClocks;
this.sequencerClocks = this.sequencerClocks - b;
for (a = a - b; --b > -1;) {
this.computeAudioChannels();
this.currentBuffer[this.audioIndex++] = this.mixerOutputCache;
if (this.audioIndex == this.numSamplesTotal) {
this.audioIndex = 0;
this.outputAudio()
}
}
if (this.sequencerClocks == 0) {
this.audioComputeSequencer();
this.sequencerClocks = 8192
}
} else for (; --a > -1;) {
this.currentBuffer[this.audioIndex++] = 0;
if (this.audioIndex == this.numSamplesTotal) {
this.audioIndex = 0;
this.outputAudio()
}
}
};
GameBoyCore.prototype.generateAudioFake = function (a) {
if (this.soundMasterEnabled && !this.CPUStopped) for (; --a > -1;) {
this.computeAudioChannels();
if (--this.sequencerClocks == 0) {
this.audioComputeSequencer();
this.sequencerClocks = 8192
}
}
};
GameBoyCore.prototype.audioJIT = function () {
settings[0] ? this.generateAudio(this.audioTicks) : this.generateAudioFake(this.audioTicks);
this.audioTicks = 0
};
GameBoyCore.prototype.audioComputeSequencer = function () {
switch (this.sequencePosition++) {
case 0:
this.clockAudioLength();
break;
case 2:
this.clockAudioLength();
this.clockAudioSweep();
break;
case 4:
this.clockAudioLength();
break;
case 6:
this.clockAudioLength();
this.clockAudioSweep();
break;
case 7:
this.clockAudioEnvelope();
this.sequencePosition = 0
}
};
GameBoyCore.prototype.clockAudioLength = function () {
if (this.channel1totalLength > 1)--this.channel1totalLength;
else if (this.channel1totalLength == 1) {
this.channel1totalLength = 0;
this.channel1EnableCheck();
this.memory[65318] = this.memory[65318] & 254
}
if (this.channel2totalLength > 1)--this.channel2totalLength;
else if (this.channel2totalLength == 1) {
this.channel2totalLength = 0;
this.channel2EnableCheck();
this.memory[65318] = this.memory[65318] & 253
}
if (this.channel3totalLength > 1)--this.channel3totalLength;
else if (this.channel3totalLength == 1) {
this.channel3totalLength = 0;
this.channel3EnableCheck();
this.memory[65318] = this.memory[65318] & 251
}
if (this.channel4totalLength > 1)--this.channel4totalLength;
else if (this.channel4totalLength == 1) {
this.channel4totalLength = 0;
this.channel4EnableCheck();
this.memory[65318] = this.memory[65318] & 247
}
};
GameBoyCore.prototype.clockAudioSweep = function () {
!this.channel1SweepFault && this.channel1timeSweep > 0 && --this.channel1timeSweep == 0 && this.runAudioSweep()
};
GameBoyCore.prototype.runAudioSweep = function () {
if (this.channel1lastTimeSweep > 0) if (this.channel1frequencySweepDivider > 0) {
if (this.channel1numSweep > 0) {
--this.channel1numSweep;
if (this.channel1decreaseSweep) {
this.channel1ShadowFrequency = this.channel1ShadowFrequency - (this.channel1ShadowFrequency >> this.channel1frequencySweepDivider);
this.channel1frequency = this.channel1ShadowFrequency & 2047;
this.channel1FrequencyTracker = 2048 - this.channel1frequency << 2
} else {
this.channel1frequency = this.channel1ShadowFrequency = this.channel1ShadowFrequency + (this.channel1ShadowFrequency >> this.channel1frequencySweepDivider);
if (this.channel1ShadowFrequency <= 2047) {
this.channel1FrequencyTracker = 2048 - this.channel1frequency << 2;
if (this.channel1ShadowFrequency + (this.channel1ShadowFrequency >> this.channel1frequencySweepDivider) > 2047) {
this.channel1SweepFault = true;
this.channel1EnableCheck();
this.memory[65318] = this.memory[65318] & 254
}
} else {
this.channel1frequency = this.channel1frequency & 2047;
this.channel1SweepFault = true;
this.channel1EnableCheck();
this.memory[65318] = this.memory[65318] & 254
}
}
}
this.channel1timeSweep = this.channel1lastTimeSweep
} else {
this.channel1SweepFault = true;
this.channel1EnableCheck()
}
};
GameBoyCore.prototype.channel1AudioSweepPerformDummy = function () {
if (this.channel1numSweep > 0 && !this.channel1decreaseSweep) {
var a = this.channel1ShadowFrequency + (this.channel1ShadowFrequency >> this.channel1frequencySweepDivider);
if (a <= 2047) {
if (a + (a >> this.channel1frequencySweepDivider) > 2047) {
this.channel1SweepFault = true;
this.channel1EnableCheck();
this.memory[65318] = this.memory[65318] & 254
}
} else {
this.channel1SweepFault = true;
this.channel1EnableCheck();
this.memory[65318] = this.memory[65318] & 254
}
}
};
GameBoyCore.prototype.clockAudioEnvelope = function () {
if (this.channel1envelopeSweepsLast > -1) if (this.channel1envelopeSweeps > 0)--this.channel1envelopeSweeps;
else if (this.channel1envelopeType) if (this.channel1envelopeVolume < 15) {
++this.channel1envelopeVolume;
this.channel1envelopeSweeps = this.channel1envelopeSweepsLast;
this.channel1OutputLevelCache()
} else this.channel1envelopeSweepsLast = -1;
else if (this.channel1envelopeVolume > 0) {
--this.channel1envelopeVolume;
this.channel1envelopeSweeps = this.channel1envelopeSweepsLast;
this.channel1OutputLevelCache()
} else this.channel1envelopeSweepsLast = -1;
if (this.channel2envelopeSweepsLast > -1) if (this.channel2envelopeSweeps > 0)--this.channel2envelopeSweeps;
else if (this.channel2envelopeType) if (this.channel2envelopeVolume < 15) {
++this.channel2envelopeVolume;
this.channel2envelopeSweeps = this.channel2envelopeSweepsLast;
this.channel2OutputLevelCache()
} else this.channel2envelopeSweepsLast = -1;
else if (this.channel2envelopeVolume > 0) {
--this.channel2envelopeVolume;
this.channel2envelopeSweeps = this.channel2envelopeSweepsLast;
this.channel2OutputLevelCache()
} else this.channel2envelopeSweepsLast = -1;
if (this.channel4envelopeSweepsLast > -1) if (this.channel4envelopeSweeps > 0)--this.channel4envelopeSweeps;
else if (this.channel4envelopeType) if (this.channel4envelopeVolume < 15) {
this.channel4currentVolume = ++this.channel4envelopeVolume << this.channel4VolumeShifter;
this.channel4envelopeSweeps = this.channel4envelopeSweepsLast;
this.channel4UpdateCache()
} else this.channel4envelopeSweepsLast = -1;
else if (this.channel4envelopeVolume > 0) {
this.channel4currentVolume = --this.channel4envelopeVolume << this.channel4VolumeShifter;
this.channel4envelopeSweeps = this.channel4envelopeSweepsLast;
this.channel4UpdateCache()
} else this.channel4envelopeSweepsLast = -1
};
GameBoyCore.prototype.computeAudioChannels = function () {
if (--this.channel1FrequencyCounter == 0) {
this.channel1FrequencyCounter = this.channel1FrequencyTracker;
this.channel1DutyTracker = this.channel1DutyTracker + 1 & 7;
this.channel1OutputLevelTrimaryCache()
}
if (--this.channel2FrequencyCounter == 0) {
this.channel2FrequencyCounter = this.channel2FrequencyTracker;
this.channel2DutyTracker = this.channel2DutyTracker + 1 & 7;
this.channel2OutputLevelTrimaryCache()
}
if (--this.channel3Counter == 0) {
if (this.channel3canPlay) this.channel3lastSampleLookup = this.channel3lastSampleLookup + 1 & 31;
this.channel3Counter = this.channel3FrequencyPeriod;
this.channel3UpdateCache()
}
if (--this.channel4Counter == 0) {
this.channel4lastSampleLookup = this.channel4lastSampleLookup + 1 & this.channel4BitRange;
this.channel4Counter = this.channel4FrequencyPeriod;
this.channel4UpdateCache()
}
};
GameBoyCore.prototype.channel1EnableCheck = function () {
this.channel1Enabled = (this.channel1consecutive || this.channel1totalLength > 0) && !this.channel1SweepFault && this.channel1canPlay;
this.channel1OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel1VolumeEnableCheck = function () {
this.channel1canPlay = this.memory[65298] > 7;
this.channel1EnableCheck();
this.channel1OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel1OutputLevelCache = function () {
this.channel1currentSampleLeft = this.leftChannel1 ? this.channel1envelopeVolume : 0;
this.channel1currentSampleRight = this.rightChannel1 ? this.channel1envelopeVolume : 0;
this.channel1OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel1OutputLevelSecondaryCache = function () {
if (this.channel1Enabled) {
this.channel1currentSampleLeftSecondary = this.channel1currentSampleLeft;
this.channel1currentSampleRightSecondary = this.channel1currentSampleRight
} else this.channel1currentSampleRightSecondary = this.channel1currentSampleLeftSecondary = 0;
this.channel1OutputLevelTrimaryCache()
};
GameBoyCore.prototype.channel1OutputLevelTrimaryCache = function () {
if (this.channel1CachedDuty[this.channel1DutyTracker]) {
this.channel1currentSampleLeftTrimary = this.channel1currentSampleLeftSecondary;
this.channel1currentSampleRightTrimary = this.channel1currentSampleRightSecondary
} else this.channel1currentSampleRightTrimary = this.channel1currentSampleLeftTrimary = 0;
this.mixerOutputLevelCache()
};
GameBoyCore.prototype.channel2EnableCheck = function () {
this.channel2Enabled = (this.channel2consecutive || this.channel2totalLength > 0) && this.channel2canPlay;
this.channel2OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel2VolumeEnableCheck = function () {
this.channel2canPlay = this.memory[65303] > 7;
this.channel2EnableCheck();
this.channel2OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel2OutputLevelCache = function () {
this.channel2currentSampleLeft = this.leftChannel2 ? this.channel2envelopeVolume : 0;
this.channel2currentSampleRight = this.rightChannel2 ? this.channel2envelopeVolume : 0;
this.channel2OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel2OutputLevelSecondaryCache = function () {
if (this.channel2Enabled) {
this.channel2currentSampleLeftSecondary = this.channel2currentSampleLeft;
this.channel2currentSampleRightSecondary = this.channel2currentSampleRight
} else this.channel2currentSampleRightSecondary = this.channel2currentSampleLeftSecondary = 0;
this.channel2OutputLevelTrimaryCache()
};
GameBoyCore.prototype.channel2OutputLevelTrimaryCache = function () {
if (this.channel2CachedDuty[this.channel2DutyTracker]) {
this.channel2currentSampleLeftTrimary = this.channel2currentSampleLeftSecondary;
this.channel2currentSampleRightTrimary = this.channel2currentSampleRightSecondary
} else this.channel2currentSampleRightTrimary = this.channel2currentSampleLeftTrimary = 0;
this.mixerOutputLevelCache()
};
GameBoyCore.prototype.channel3EnableCheck = function () {
this.channel3Enabled = this.channel3consecutive || this.channel3totalLength > 0;
this.channel3OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel3OutputLevelCache = function () {
this.channel3currentSampleLeft = this.leftChannel3 ? this.cachedChannel3Sample : 0;
this.channel3currentSampleRight = this.rightChannel3 ? this.cachedChannel3Sample : 0;
this.channel3OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel3OutputLevelSecondaryCache = function () {
if (this.channel3Enabled) {
this.channel3currentSampleLeftSecondary = this.channel3currentSampleLeft;
this.channel3currentSampleRightSecondary = this.channel3currentSampleRight
} else this.channel3currentSampleRightSecondary = this.channel3currentSampleLeftSecondary = 0;
this.mixerOutputLevelCache()
};
GameBoyCore.prototype.channel4EnableCheck = function () {
this.channel4Enabled = (this.channel4consecutive || this.channel4totalLength > 0) && this.channel4canPlay;
this.channel4OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel4VolumeEnableCheck = function () {
this.channel4canPlay = this.memory[65313] > 7;
this.channel4EnableCheck();
this.channel4OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel4OutputLevelCache = function () {
this.channel4currentSampleLeft = this.leftChannel4 ? this.cachedChannel4Sample : 0;
this.channel4currentSampleRight = this.rightChannel4 ? this.cachedChannel4Sample : 0;
this.channel4OutputLevelSecondaryCache()
};
GameBoyCore.prototype.channel4OutputLevelSecondaryCache = function () {
if (this.channel4Enabled) {
this.channel4currentSampleLeftSecondary = this.channel4currentSampleLeft;
this.channel4currentSampleRightSecondary = this.channel4currentSampleRight
} else this.channel4currentSampleRightSecondary = this.channel4currentSampleLeftSecondary = 0;
this.mixerOutputLevelCache()
};
GameBoyCore.prototype.mixerOutputLevelCache = function () {
this.mixerOutputCache = ((this.channel1currentSampleLeftTrimary + this.channel2currentSampleLeftTrimary + this.channel3currentSampleLeftSecondary + this.channel4currentSampleLeftSecondary) * this.VinLeftChannelMasterVolume << 9) + (this.channel1currentSampleRightTrimary + this.channel2currentSampleRightTrimary + this.channel3currentSampleRightSecondary + this.channel4currentSampleRightSecondary) * this.VinRightChannelMasterVolume
};
GameBoyCore.prototype.channel3UpdateCache = function () {
this.cachedChannel3Sample = this.channel3PCM[this.channel3lastSampleLookup] >> this.channel3patternType;
this.channel3OutputLevelCache()
};
GameBoyCore.prototype.channel3WriteRAM = function (a, b) {
this.channel3canPlay && this.audioJIT();
this.memory[65328 | a] = b;
a = a << 1;
this.channel3PCM[a] = b >> 4;
this.channel3PCM[a | 1] = b & 15
};
GameBoyCore.prototype.channel4UpdateCache = function () {
this.cachedChannel4Sample = this.noiseSampleTable[this.channel4currentVolume | this.channel4lastSampleLookup];
this.channel4OutputLevelCache()
};
GameBoyCore.prototype.run = function () {
if ((this.stopEmulator & 2) == 0) if ((this.stopEmulator & 1) == 1) if (this.CPUStopped) {
this.audioUnderrunAdjustment();
this.audioTicks = this.audioTicks + this.CPUCyclesTotal;
this.audioJIT();
this.stopEmulator = this.stopEmulator | 1
} else {
this.stopEmulator = 0;
this.drewFrame = false;
this.audioUnderrunAdjustment();
this.clockUpdate();
if (this.halt) {
this.CPUTicks = 0;
this.calculateHALTPeriod();
this.halt ? this.updateCoreFull() : this.executeIteration()
} else this.executeIteration();
this.requestDraw()
} else {
cout("Iterator restarted a faulted core.", 2);
pause()
}
};
GameBoyCore.prototype.executeIteration = function () {
for (var a = 0, a = 0; this.stopEmulator == 0;) {
switch (this.IRQEnableDelay) {
case 1:
this.IME = true;
this.checkIRQMatching();
case 2:
--this.IRQEnableDelay
}
this.IRQLineMatched > 0 && this.launchIRQ();
a = this.memoryReader[this.programCounter](this, this.programCounter);
this.programCounter = this.programCounter + 1 & 65535;
if (this.skipPCIncrement) {
this.programCounter = this.programCounter - 1 & 65535;
this.skipPCIncrement = false
}
this.CPUTicks = this.TICKTable[a];
this.OPCODE[a](this);
this.LCDTicks = this.LCDTicks + (this.CPUTicks >> this.doubleSpeedShifter);
this.LCDCONTROL[this.actualScanLine](this);
a = this.CPUTicks >> this.doubleSpeedShifter;
this.audioTicks = this.audioTicks + a;
this.emulatorTicks = this.emulatorTicks + a;
this.DIVTicks = this.DIVTicks + this.CPUTicks;
if (this.TIMAEnabled) for (this.timerTicks = this.timerTicks + this.CPUTicks; this.timerTicks >= this.TACClocker;) {
this.timerTicks = this.timerTicks - this.TACClocker;
if (++this.memory[65285] == 256) {
this.memory[65285] = this.memory[65286];
this.interruptsRequested = this.interruptsRequested | 4;
this.checkIRQMatching()
}
}
if (this.serialTimer > 0) {
this.serialTimer = this.serialTimer - this.CPUTicks;
if (this.serialTimer <= 0) {
this.interruptsRequested = this.interruptsRequested | 8;
this.checkIRQMatching()
}
this.serialShiftTimer = this.serialShiftTimer - this.CPUTicks;
if (this.serialShiftTimer <= 0) {
this.serialShiftTimer = this.serialShiftTimerAllocated;
this.memory[65281] = this.memory[65281] << 1 & 254 | 1
}
}
this.emulatorTicks >= this.CPUCyclesTotal && this.iterationEndRoutine()
}
};
GameBoyCore.prototype.iterationEndRoutine = function () {
if ((this.stopEmulator & 1) == 0) {
this.audioJIT();
this.memory[65284] = this.memory[65284] + (this.DIVTicks >> 8) & 255;
this.DIVTicks = this.DIVTicks & 255;
this.stopEmulator = this.stopEmulator | 1;
this.emulatorTicks = this.emulatorTicks - this.CPUCyclesTotal;
this.CPUCyclesTotalCurrent = this.CPUCyclesTotalCurrent + this.CPUCyclesTotalRoundoff;
this.recalculateIterationClockLimit()
}
};
GameBoyCore.prototype.handleSTOP = function () {
this.CPUStopped = true;
this.iterationEndRoutine();
if (this.emulatorTicks < 0) {
this.audioTicks = this.audioTicks - this.emulatorTicks;
this.audioJIT()
}
};
GameBoyCore.prototype.recalculateIterationClockLimit = function () {
var a = this.CPUCyclesTotalCurrent % 4;
this.CPUCyclesTotal = this.CPUCyclesTotalBase + this.CPUCyclesTotalCurrent - a;
this.CPUCyclesTotalCurrent = a
};
GameBoyCore.prototype.scanLineMode2 = function () {
if (this.STATTracker != 1) {
if (this.mode2TriggerSTAT) {
this.interruptsRequested = this.interruptsRequested | 2;
this.checkIRQMatching()
}
this.STATTracker = 1;
this.modeSTAT = 2
}
};
GameBoyCore.prototype.scanLineMode3 = function () {
if (this.modeSTAT != 3) {
if (this.STATTracker == 0 && this.mode2TriggerSTAT) {
this.interruptsRequested = this.interruptsRequested | 2;
this.checkIRQMatching()
}
this.STATTracker = 1;
this.modeSTAT = 3
}
};
GameBoyCore.prototype.scanLineMode0 = function () {
if (this.modeSTAT != 0) {
if (this.STATTracker != 2) {
if (this.STATTracker == 0) {
if (this.mode2TriggerSTAT) {
this.interruptsRequested = this.interruptsRequested | 2;
this.checkIRQMatching()
}
this.modeSTAT = 3
}
this.incrementScanLineQueue();
this.updateSpriteCount(this.actualScanLine);
this.STATTracker = 2
}
if (this.LCDTicks >= this.spriteCount) {
this.hdmaRunning && this.executeHDMA();
if (this.mode0TriggerSTAT) {
this.interruptsRequested = this.interruptsRequested | 2;
this.checkIRQMatching()
}
this.STATTracker = 3;
this.modeSTAT = 0
}
}
};
GameBoyCore.prototype.clocksUntilLYCMatch = function () {
return this.memory[65349] != 0 ? this.memory[65349] > this.actualScanLine ? 456 * (this.memory[65349] - this.actualScanLine) : 456 * (154 - this.actualScanLine + this.memory[65349]) : 456 * (this.actualScanLine == 153 && this.memory[65348] == 0 ? 154 : 153 - this.actualScanLine) + 8
};
GameBoyCore.prototype.clocksUntilMode0 = function () {
switch (this.modeSTAT) {
case 0:
if (this.actualScanLine == 143) {
this.updateSpriteCount(0);
return this.spriteCount + 5016
}
this.updateSpriteCount(this.actualScanLine + 1);
return this.spriteCount + 456;
case 2:
case 3:
this.updateSpriteCount(this.actualScanLine);
return this.spriteCount;
case 1:
this.updateSpriteCount(0);
return this.spriteCount + 456 * (154 - this.actualScanLine)
}
};
GameBoyCore.prototype.updateSpriteCount = function (a) {
this.spriteCount = 252;
if (this.cGBC && this.gfxSpriteShow) for (var a = a + 16, b = 0, c = this.gfxSpriteNormalHeight ? 8 : 16, e = 65024; e < 65184 && this.spriteCount < 312; e = e + 4) {
b = a - this.memory[e];
if (b > -1 && b < c) this.spriteCount = this.spriteCount + 6
}
};
GameBoyCore.prototype.matchLYC = function () {
if (this.memory[65348] == this.memory[65349]) {
this.memory[65345] = this.memory[65345] | 4;
if (this.LYCMatchTriggerSTAT) {
this.interruptsRequested = this.interruptsRequested | 2;
this.checkIRQMatching()
}
} else this.memory[65345] = this.memory[65345] & 123
};
GameBoyCore.prototype.updateCore = function () {
this.LCDTicks = this.LCDTicks + (this.CPUTicks >> this.doubleSpeedShifter);
this.LCDCONTROL[this.actualScanLine](this);
var a = this.CPUTicks >> this.doubleSpeedShifter;
this.audioTicks = this.audioTicks + a;
this.emulatorTicks = this.emulatorTicks + a;
this.DIVTicks = this.DIVTicks + this.CPUTicks;
if (this.TIMAEnabled) for (this.timerTicks = this.timerTicks + this.CPUTicks; this.timerTicks >= this.TACClocker;) {
this.timerTicks = this.timerTicks - this.TACClocker;
if (++this.memory[65285] == 256) {
this.memory[65285] = this.memory[65286];
this.interruptsRequested = this.interruptsRequested | 4;
this.checkIRQMatching()
}
}
if (this.serialTimer > 0) {
this.serialTimer = this.serialTimer - this.CPUTicks;
if (this.serialTimer <= 0) {
this.interruptsRequested = this.interruptsRequested | 8;
this.checkIRQMatching()
}
this.serialShiftTimer = this.serialShiftTimer - this.CPUTicks;
if (this.serialShiftTimer <= 0) {
this.serialShiftTimer = this.serialShiftTimerAllocated;
this.memory[65281] = this.memory[65281] << 1 & 254 | 1
}
}
};
GameBoyCore.prototype.updateCoreFull = function () {
this.updateCore();
this.emulatorTicks >= this.CPUCyclesTotal && this.iterationEndRoutine()
};
GameBoyCore.prototype.initializeLCDController = function () {
for (var a = 0; a < 154;) {
a < 143 ? this.LINECONTROL[a] = function (a) {
if (a.LCDTicks < 80) a.scanLineMode2();
else if (a.LCDTicks < 252) a.scanLineMode3();
else if (a.LCDTicks < 456) a.scanLineMode0();
else {
a.LCDTicks = a.LCDTicks - 456;
if (a.STATTracker != 3) {
if (a.STATTracker != 2) {
if (a.STATTracker == 0 && a.mode2TriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2;
a.incrementScanLineQueue()
}
a.hdmaRunning && a.executeHDMA();
if (a.mode0TriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2
}
a.actualScanLine = ++a.memory[65348];
if (a.actualScanLine == a.memory[65349]) {
a.memory[65345] = a.memory[65345] | 4;
if (a.LYCMatchTriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2
} else a.memory[65345] = a.memory[65345] & 123;
a.checkIRQMatching();
a.STATTracker = 0;
a.modeSTAT = 2;
a.LINECONTROL[a.actualScanLine](a)
}
} : a == 143 ? this.LINECONTROL[143] = function (a) {
if (a.LCDTicks < 80) a.scanLineMode2();
else if (a.LCDTicks < 252) a.scanLineMode3();
else if (a.LCDTicks < 456) a.scanLineMode0();
else {
a.LCDTicks = a.LCDTicks - 456;
if (a.STATTracker != 3) {
if (a.STATTracker != 2) {
if (a.STATTracker == 0 && a.mode2TriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2;
a.incrementScanLineQueue()
}
a.hdmaRunning && a.executeHDMA();
if (a.mode0TriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2
}
a.actualScanLine = a.memory[65348] = 144;
if (a.memory[65349] == 144) {
a.memory[65345] = a.memory[65345] | 4;
if (a.LYCMatchTriggerSTAT) a.interruptsRequested = a.interruptsRequested | 2
} else a.memory[65345] = a.memory[65345] & 123;
a.STATTracker = 0;
a.modeSTAT = 1;
a.interruptsRequested = a.interruptsRequested | (a.mode1TriggerSTAT ? 3 : 1);
a.checkIRQMatching();
if (a.drewBlank == 0) {
if (a.totalLinesPassed < 144 || a.totalLinesPassed == 144 && a.midScanlineOffset > -1) {
a.graphicsJITVBlank();
a.prepareFrame()
}
} else --a.drewBlank;
a.LINECONTROL[144](a)
}
} : a < 153 ? this.LINECONTROL[a] = function (a) {
if (a.LCDTicks >= 456) {
a.LCDTicks = a.LCDTicks - 456;
a.actualScanLine = ++a.memory[65348];
if (a.actualScanLine == a.memory[65349]) {
a.memory[65345] = a.memory[65345] | 4;
if (a.LYCMatchTriggerSTAT) {
a.interruptsRequested = a.interruptsRequested | 2;
a.checkIRQMatching()
}
} else a.memory[65345] = a.memory[65345] & 123;
a.LINECONTROL[a.actualScanLine](a)
}
} : this.LINECONTROL[153] = function (a) {
if (a.LCDTicks >= 8) {
if (a.STATTracker != 4 && a.memory[65348] == 153) {
a.memory[65348] = 0;
if (a.memory[65349] == 0) {
a.memory[65345] = a.memory[65345] | 4;
if (a.LYCMatchTriggerSTAT) {
a.interruptsRequested = a.interruptsRequested | 2;
a.checkIRQMatching()
}
} else a.memory[65345] = a.memory[65345] & 123;
a.STATTracker = 4
}
if (a.LCDTicks >= 456) {
a.LCDTicks = a.LCDTicks - 456;
a.STATTracker = a.actualScanLine = 0;
a.LINECONTROL[0](a)
}
}
};
++a
}
};
GameBoyCore.prototype.DisplayShowOff = function () {
if (this.drewBlank == 0) {
this.clearFrameBuffer();
this.drewFrame = true
}
this.drewBlank = 2
};
GameBoyCore.prototype.executeHDMA = function () {
this.DMAWrite(1);
if (this.halt) {
if (this.LCDTicks - this.spriteCount < (4 >> this.doubleSpeedShifter | 32)) {
this.CPUTicks = 4 + (32 + this.spriteCount << this.doubleSpeedShifter);
this.LCDTicks = this.spriteCount + (4 >> this.doubleSpeedShifter | 32)
}
} else this.LCDTicks = this.LCDTicks + (4 >> this.doubleSpeedShifter | 32);
if (this.memory[65365] == 0) {
this.hdmaRunning = false;
this.memory[65365] = 255
} else --this.memory[65365]
};
GameBoyCore.prototype.clockUpdate = function () {
if (this.cTIMER) {
var a = (new Date).getTime(),
b = a - this.lastIteration;
this.lastIteration = a;
if (this.cTIMER && !this.RTCHALT) for (this.RTCSeconds = this.RTCSeconds + b / 1E3; this.RTCSeconds >= 60;) {
this.RTCSeconds = this.RTCSeconds - 60;
++this.RTCMinutes;
if (this.RTCMinutes >= 60) {
this.RTCMinutes = this.RTCMinutes - 60;
++this.RTCHours;
if (this.RTCHours >= 24) {
this.RTCHours = this.RTCHours - 24;
++this.RTCDays;
if (this.RTCDays >= 512) {
this.RTCDays = this.RTCDays - 512;
this.RTCDayOverFlow = true
}
}
}
}
}
};
GameBoyCore.prototype.prepareFrame = function () {
this.swizzleFrameBuffer();
this.drewFrame = true
};
GameBoyCore.prototype.requestDraw = function () {
this.drewFrame && this.dispatchDraw()
};
GameBoyCore.prototype.dispatchDraw = function () {
var a = this.offscreenRGBCount;
if (a > 0) {
for (var b = a == 92160 ? this.swizzledFrame : this.resizeFrameBuffer(), c = this.canvasBuffer.data, e = 0, f = 0; f < a; ++f) {
c[f++] = b[e++];
c[f++] = b[e++];
c[f++] = b[e++]
}
this.graphicsBlit()
}
};
GameBoyCore.prototype.swizzleFrameBuffer = function () {
for (var a = this.frameBuffer, b = this.swizzledFrame, c = 0, e = 0; e < 69120;) {
b[e++] = a[c] >> 16 & 255;
b[e++] = a[c] >> 8 & 255;
b[e++] = a[c++] & 255
}
};
GameBoyCore.prototype.clearFrameBuffer = function () {
var a = 0,
b = this.swizzledFrame;
if (this.cGBC || this.colorizedGBPalettes) for (; a < 69120;) b[a++] = 248;
else for (; a < 69120;) {
b[a++] = 239;
b[a++] = 255;
b[a++] = 222
}
};
GameBoyCore.prototype.resizeFrameBuffer = function () {
return this.resizer.resize(this.swizzledFrame)
};
GameBoyCore.prototype.compileResizeFrameBufferFunction = function () {
if (this.offscreenRGBCount > 0) this.resizer = new Resize(160, 144, this.offscreenWidth, this.offscreenHeight, false, true)
};
GameBoyCore.prototype.renderScanLine = function (a) {
this.pixelStart = a * 160;
if (this.bgEnabled) {
this.pixelEnd = 160;
this.BGLayerRender(a);
this.WindowLayerRender(a)
} else for (var b = (a + 1) * 160, c = this.cGBC || this.colorizedGBPalettes ? 16316664 : 15728606, e = a * 160 + this.currentX; e < b; e++) this.frameBuffer[e] = c;
this.SpriteLayerRender(a);
this.currentX = 0;
this.midScanlineOffset = -1
};
GameBoyCore.prototype.renderMidScanLine = function () {
if (this.actualScanLine < 144 && this.modeSTAT == 3) {
if (this.midScanlineOffset == -1) this.midScanlineOffset = this.backgroundX & 7;
if (this.LCDTicks >= 82) {
this.pixelEnd = this.LCDTicks - 74;
this.pixelEnd = Math.min(this.pixelEnd - this.midScanlineOffset - this.pixelEnd % 8, 160);
if (this.bgEnabled) {
this.pixelStart = this.lastUnrenderedLine * 160;
this.BGLayerRender(this.lastUnrenderedLine);
this.WindowLayerRender(this.lastUnrenderedLine)
} else for (var a = this.lastUnrenderedLine * 160 + this.pixelEnd, b = this.cGBC || this.colorizedGBPalettes ? 16316664 : 15728606, c = this.lastUnrenderedLine * 160 + this.currentX; c < a; c++) this.frameBuffer[c] = b;
this.currentX = this.pixelEnd
}
}
};
GameBoyCore.prototype.initializeModeSpecificArrays = function () {
this.LCDCONTROL = this.LCDisOn ? this.LINECONTROL : this.DISPLAYOFFCONTROL;
if (this.cGBC) {
this.gbcOBJRawPalette = this.getTypedArray(64, 0, "uint8");
this.gbcBGRawPalette = this.getTypedArray(64, 0, "uint8");
this.gbcOBJPalette = this.getTypedArray(32, 16777216, "int32");
this.gbcBGPalette = this.getTypedArray(64, 0, "int32");
this.BGCHRBank2 = this.getTypedArray(2048, 0, "uint8");
this.BGCHRCurrentBank = this.currVRAMBank > 0 ? this.BGCHRBank2 : this.BGCHRBank1;
this.tileCache = this.generateCacheArray(3968)
} else {
this.gbOBJPalette = this.getTypedArray(8, 0, "int32");
this.BGPalette = this.gbBGPalette = this.getTypedArray(4, 0, "int32");
this.OBJPalette = this.gbOBJPalette;
this.tileCache = this.generateCacheArray(1792);
this.sortBuffer = this.getTypedArray(256, 0, "uint8");
this.OAMAddressCache = this.getTypedArray(10, 0, "int32")
}
this.renderPathBuild()
};
GameBoyCore.prototype.GBCtoGBModeAdjust = function () {
cout("Stepping down from GBC mode.", 0);
this.VRAM = this.GBCMemory = this.BGCHRCurrentBank = this.BGCHRBank2 = null;
this.tileCache.length = 1792;
if (settings[4]) {
this.gbBGColorizedPalette = this.getTypedArray(4, 0, "int32");
this.gbOBJColorizedPalette = this.getTypedArray(8, 0, "int32");
this.cachedBGPaletteConversion = this.getTypedArray(4, 0, "int32");
this.cachedOBJPaletteConversion = this.getTypedArray(8, 0, "int32");
this.BGPalette = this.gbBGColorizedPalette;
this.OBJPalette = this.gbOBJColorizedPalette;
this.gbOBJPalette = this.gbBGPalette = null;
this.getGBCColor()
} else {
this.gbOBJPalette = this.getTypedArray(8, 0, "int32");
this.BGPalette = this.gbBGPalette = this.getTypedArray(4, 0, "int32");
this.OBJPalette = this.gbOBJPalette
}
this.sortBuffer = this.getTypedArray(256, 0, "uint8");
this.OAMAddressCache = this.getTypedArray(10, 0, "int32");
this.renderPathBuild();
this.memoryReadJumpCompile();
this.memoryWriteJumpCompile()
};
GameBoyCore.prototype.renderPathBuild = function () {
if (this.cGBC) {
this.priorityFlaggingPathRebuild();
this.SpriteLayerRender = this.SpriteGBCLayerRender
} else {
this.BGLayerRender = this.BGGBLayerRender;
this.WindowLayerRender = this.WindowGBLayerRender;
this.SpriteLayerRender = this.SpriteGBLayerRender
}
};
GameBoyCore.prototype.priorityFlaggingPathRebuild = function () {
if (this.BGPriorityEnabled) {
this.BGLayerRender = this.BGGBCLayerRender;
this.WindowLayerRender = this.WindowGBCLayerRender
} else {
this.BGLayerRender = this.BGGBCLayerRenderNoPriorityFlagging;
this.WindowLayerRender = this.WindowGBCLayerRenderNoPriorityFlagging
}
};
GameBoyCore.prototype.initializeReferencesFromSaveState = function () {
this.LCDCONTROL = this.LCDisOn ? this.LINECONTROL : this.DISPLAYOFFCONTROL;
var a = 0;
if (this.cGBC) {
this.BGCHRCurrentBank = this.currVRAMBank > 0 ? this.BGCHRBank2 : this.BGCHRBank1;
for (this.tileCache = this.generateCacheArray(3968); a < 6144; a = a + 16) {
this.generateGBCTileBank1(a);
this.generateGBCTileBank2(a)
}
} else {
if (this.colorizedGBPalettes) {
this.BGPalette = this.gbBGColorizedPalette;
this.OBJPalette = this.gbOBJColorizedPalette;
this.updateGBBGPalette = this.updateGBColorizedBGPalette;
this.updateGBOBJPalette = this.updateGBColorizedOBJPalette
} else {
this.BGPalette = this.gbBGPalette;
this.OBJPalette = this.gbOBJPalette
}
this.tileCache = this.generateCacheArray(1792);
for (a = 32768; a < 36864; a = a + 2) this.generateGBOAMTileLine(a);
for (a = 36864; a < 38912; a = a + 2) this.generateGBTileLine(a);
this.sortBuffer = this.getTypedArray(256, 0, "uint8");
this.OAMAddressCache = this.getTypedArray(10, 0, "int32")
}
this.renderPathBuild()
};
GameBoyCore.prototype.RGBTint = function (a) {
var b = a & 31,
c = a >> 5 & 31,
a = a >> 10 & 31;
return b * 13 + c * 2 + a >> 1 << 16 | c * 3 + a << 9 | b * 3 + c * 2 + a * 11 >> 1
};
GameBoyCore.prototype.getGBCColor = function () {
for (var a = 0; a < 4; a++) {
var b = a << 1;
this.cachedBGPaletteConversion[a] = this.RGBTint(this.gbcBGRawPalette[b | 1] << 8 | this.gbcBGRawPalette[b]);
this.cachedOBJPaletteConversion[a] = this.RGBTint(this.gbcOBJRawPalette[b | 1] << 8 | this.gbcOBJRawPalette[b])
}
for (a = 4; a < 8; a++) {
b = a << 1;
this.cachedOBJPaletteConversion[a] = this.RGBTint(this.gbcOBJRawPalette[b | 1] << 8 | this.gbcOBJRawPalette[b])
}
this.updateGBBGPalette = this.updateGBColorizedBGPalette;
this.updateGBOBJPalette = this.updateGBColorizedOBJPalette;
this.updateGBBGPalette(this.memory[65351]);
this.updateGBOBJPalette(0, this.memory[65352]);
this.updateGBOBJPalette(1, this.memory[65353]);
this.colorizedGBPalettes = true
};
GameBoyCore.prototype.updateGBRegularBGPalette = function (a) {
this.gbBGPalette[0] = this.colors[a & 3] | 33554432;
this.gbBGPalette[1] = this.colors[a >> 2 & 3];
this.gbBGPalette[2] = this.colors[a >> 4 & 3];
this.gbBGPalette[3] = this.colors[a >> 6]
};
GameBoyCore.prototype.updateGBColorizedBGPalette = function (a) {
this.gbBGColorizedPalette[0] = this.cachedBGPaletteConversion[a & 3] | 33554432;
this.gbBGColorizedPalette[1] = this.cachedBGPaletteConversion[a >> 2 & 3];
this.gbBGColorizedPalette[2] = this.cachedBGPaletteConversion[a >> 4 & 3];
this.gbBGColorizedPalette[3] = this.cachedBGPaletteConversion[a >> 6]
};
GameBoyCore.prototype.updateGBRegularOBJPalette = function (a, b) {
this.gbOBJPalette[a | 1] = this.colors[b >> 2 & 3];
this.gbOBJPalette[a | 2] = this.colors[b >> 4 & 3];
this.gbOBJPalette[a | 3] = this.colors[b >> 6]
};
GameBoyCore.prototype.updateGBColorizedOBJPalette = function (a, b) {
this.gbOBJColorizedPalette[a | 1] = this.cachedOBJPaletteConversion[a | b >> 2 & 3];
this.gbOBJColorizedPalette[a | 2] = this.cachedOBJPaletteConversion[a | b >> 4 & 3];
this.gbOBJColorizedPalette[a | 3] = this.cachedOBJPaletteConversion[a | b >> 6]
};
GameBoyCore.prototype.updateGBCBGPalette = function (a, b) {
if (this.gbcBGRawPalette[a] != b) {
this.midScanLineJIT();
this.gbcBGRawPalette[a] = b;
b = (a & 6) == 0 ? 33554432 | this.RGBTint(this.gbcBGRawPalette[a | 1] << 8 | this.gbcBGRawPalette[a & 62]) : this.RGBTint(this.gbcBGRawPalette[a | 1] << 8 | this.gbcBGRawPalette[a & 62]);
a = a >> 1;
this.gbcBGPalette[a] = b;
this.gbcBGPalette[32 | a] = 16777216 | b
}
};
GameBoyCore.prototype.updateGBCOBJPalette = function (a, b) {
if (this.gbcOBJRawPalette[a] != b) {
this.gbcOBJRawPalette[a] = b;
if ((a & 6) > 0) {
this.midScanLineJIT();
this.gbcOBJPalette[a >> 1] = 16777216 | this.RGBTint(this.gbcOBJRawPalette[a | 1] << 8 | this.gbcOBJRawPalette[a & 62])
}
}
};
GameBoyCore.prototype.BGGBLayerRender = function (a) {
var b = this.backgroundY + a & 255,
c = (b & 7) << 3,
b = this.gfxBackgroundCHRBankPosition | (b & 248) << 2,
e = this.backgroundX + this.currentX & 255,
f = this.pixelStart + this.currentX,
a = this.pixelStart + (this.gfxWindowDisplay && a - this.windowY >= 0 ? Math.min(Math.max(this.windowX, 0) + this.currentX, this.pixelEnd) : this.pixelEnd),
g = b + (e >> 3),
d = this.BGCHRBank1[g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
for (var d = this.tileCache[d], h = e & 7; h < 8 && f < a && e < 256; ++e) this.frameBuffer[f++] = this.BGPalette[d[c | h++]];
for (var i = Math.min(a - f, 256 - e) >> 3, e = e + (i << 3), i = i + g; g < i;) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
d = this.tileCache[d];
h = c;
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h]]
}
if (f < a) {
if (e < 256) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
d = this.tileCache[d];
for (h = c - 1; f < a && e < 256; ++e) this.frameBuffer[f++] = this.BGPalette[d[++h]]
}
for (i = (a - f >> 3) + b; b < i;) {
d = this.BGCHRBank1[b++];
d < this.gfxBackgroundBankOffset && (d = d | 256);
d = this.tileCache[d];
h = c;
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h++]];
this.frameBuffer[f++] = this.BGPalette[d[h]]
}
if (f < a) {
d = this.BGCHRBank1[b];
d < this.gfxBackgroundBankOffset && (d = d | 256);
d = this.tileCache[d];
switch (a - f) {
case 7:
this.frameBuffer[f + 6] = this.BGPalette[d[c | 6]];
case 6:
this.frameBuffer[f + 5] = this.BGPalette[d[c | 5]];
case 5:
this.frameBuffer[f + 4] = this.BGPalette[d[c | 4]];
case 4:
this.frameBuffer[f + 3] = this.BGPalette[d[c | 3]];
case 3:
this.frameBuffer[f + 2] = this.BGPalette[d[c | 2]];
case 2:
this.frameBuffer[f + 1] = this.BGPalette[d[c | 1]];
case 1:
this.frameBuffer[f] = this.BGPalette[d[c]]
}
}
}
};
GameBoyCore.prototype.BGGBCLayerRender = function (a) {
var b = this.backgroundY + a & 255,
c = (b & 7) << 3,
b = this.gfxBackgroundCHRBankPosition | (b & 248) << 2,
e = this.backgroundX + this.currentX & 255,
f = this.pixelStart + this.currentX,
a = this.pixelStart + (this.gfxWindowDisplay && a - this.windowY >= 0 ? Math.min(Math.max(this.windowX, 0) + this.currentX, this.pixelEnd) : this.pixelEnd),
g = b + (e >> 3),
d = this.BGCHRBank1[g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
for (var h = this.BGCHRBank2[g], d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d], h = (h & 7) << 2 | (h & 128) >> 2, i = e & 7; i < 8 && f < a && e < 256; ++e) this.frameBuffer[f++] = this.gbcBGPalette[h | d[c | i++]];
for (var j = Math.min(a - f, 256 - e) >> 3, e = e + (j << 3), j = j + g; g < j;) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[g];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2 | (h & 128) >> 2;
i = c;
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i]]
}
if (f < a) {
if (e < 256) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[g];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2 | (h & 128) >> 2;
for (i = c - 1; f < a && e < 256; ++e) this.frameBuffer[f++] = this.gbcBGPalette[h | d[++i]]
}
for (j = (a - f >> 3) + b; b < j;) {
d = this.BGCHRBank1[b];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[b++];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2 | (h & 128) >> 2;
i = c;
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i]]
}
if (f < a) {
d = this.BGCHRBank1[b];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[b];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2 | (h & 128) >> 2;
switch (a - f) {
case 7:
this.frameBuffer[f + 6] = this.gbcBGPalette[h | d[c | 6]];
case 6:
this.frameBuffer[f + 5] = this.gbcBGPalette[h | d[c | 5]];
case 5:
this.frameBuffer[f + 4] = this.gbcBGPalette[h | d[c | 4]];
case 4:
this.frameBuffer[f + 3] = this.gbcBGPalette[h | d[c | 3]];
case 3:
this.frameBuffer[f + 2] = this.gbcBGPalette[h | d[c | 2]];
case 2:
this.frameBuffer[f + 1] = this.gbcBGPalette[h | d[c | 1]];
case 1:
this.frameBuffer[f] = this.gbcBGPalette[h | d[c]]
}
}
}
};
GameBoyCore.prototype.BGGBCLayerRenderNoPriorityFlagging = function (a) {
var b = this.backgroundY + a & 255,
c = (b & 7) << 3,
b = this.gfxBackgroundCHRBankPosition | (b & 248) << 2,
e = this.backgroundX + this.currentX & 255,
f = this.pixelStart + this.currentX,
a = this.pixelStart + (this.gfxWindowDisplay && a - this.windowY >= 0 ? Math.min(Math.max(this.windowX, 0) + this.currentX, this.pixelEnd) : this.pixelEnd),
g = b + (e >> 3),
d = this.BGCHRBank1[g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
for (var h = this.BGCHRBank2[g], d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d], h = (h & 7) << 2, i = e & 7; i < 8 && f < a && e < 256; ++e) this.frameBuffer[f++] = this.gbcBGPalette[h | d[c | i++]];
for (var j = Math.min(a - f, 256 - e) >> 3, e = e + (j << 3), j = j + g; g < j;) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[g];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2;
i = c;
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i]]
}
if (f < a) {
if (e < 256) {
d = this.BGCHRBank1[++g];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[g];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2;
for (i = c - 1; f < a && e < 256; ++e) this.frameBuffer[f++] = this.gbcBGPalette[h | d[++i]]
}
for (j = (a - f >> 3) + b; b < j;) {
d = this.BGCHRBank1[b];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[b++];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2;
i = c;
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i++]];
this.frameBuffer[f++] = this.gbcBGPalette[h | d[i]]
}
if (f < a) {
d = this.BGCHRBank1[b];
d < this.gfxBackgroundBankOffset && (d = d | 256);
h = this.BGCHRBank2[b];
d = this.tileCache[(h & 8) << 8 | (h & 96) << 4 | d];
h = (h & 7) << 2;
switch (a - f) {
case 7:
this.frameBuffer[f + 6] = this.gbcBGPalette[h | d[c | 6]];
case 6:
this.frameBuffer[f + 5] = this.gbcBGPalette[h | d[c | 5]];
case 5:
this.frameBuffer[f + 4] = this.gbcBGPalette[h | d[c | 4]];
case 4:
this.frameBuffer[f + 3] = this.gbcBGPalette[h | d[c | 3]];
case 3:
this.frameBuffer[f + 2] = this.gbcBGPalette[h | d[c | 2]];
case 2:
this.frameBuffer[f + 1] = this.gbcBGPalette[h | d[c | 1]];
case 1:
this.frameBuffer[f] = this.gbcBGPalette[h | d[c]]
}
}
}
};
GameBoyCore.prototype.WindowGBLayerRender = function (a) {
if (this.gfxWindowDisplay) {
var b = a - this.windowY;
if (b >= 0) {
var a = this.windowX > 0 ? this.windowX + this.currentX : this.currentX,
c = this.pixelStart + a,
e = this.pixelStart + this.pixelEnd;
if (c < e) {
var f = (b & 7) << 3,
b = (this.gfxWindowCHRBankPosition | (b & 248) << 2) + (this.currentX >> 3),
g = this.BGCHRBank1[b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
for (var g = this.tileCache[g], d = a - this.windowX & 7, a = Math.min(8, d + e - c); d < a;) this.frameBuffer[c++] = this.BGPalette[g[f | d++]];
for (a = b + (e - c >> 3); b < a;) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
g = this.tileCache[g];
d = f;
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d++]];
this.frameBuffer[c++] = this.BGPalette[g[d]]
}
if (c < e) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
g = this.tileCache[g];
switch (e - c) {
case 7:
this.frameBuffer[c + 6] = this.BGPalette[g[f | 6]];
case 6:
this.frameBuffer[c + 5] = this.BGPalette[g[f | 5]];
case 5:
this.frameBuffer[c + 4] = this.BGPalette[g[f | 4]];
case 4:
this.frameBuffer[c + 3] = this.BGPalette[g[f | 3]];
case 3:
this.frameBuffer[c + 2] = this.BGPalette[g[f | 2]];
case 2:
this.frameBuffer[c + 1] = this.BGPalette[g[f | 1]];
case 1:
this.frameBuffer[c] = this.BGPalette[g[f]]
}
}
}
}
}
};
GameBoyCore.prototype.WindowGBCLayerRender = function (a) {
if (this.gfxWindowDisplay) {
var b = a - this.windowY;
if (b >= 0) {
var a = this.windowX > 0 ? this.windowX + this.currentX : this.currentX,
c = this.pixelStart + a,
e = this.pixelStart + this.pixelEnd;
if (c < e) {
var f = (b & 7) << 3,
b = (this.gfxWindowCHRBankPosition | (b & 248) << 2) + (this.currentX >> 3),
g = this.BGCHRBank1[b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
for (var d = this.BGCHRBank2[b], g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g], d = (d & 7) << 2 | (d & 128) >> 2, h = a - this.windowX & 7, a = Math.min(8, h + e - c); h < a;) this.frameBuffer[c++] = this.gbcBGPalette[d | g[f | h++]];
for (a = b + (e - c >> 3); b < a;) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
d = this.BGCHRBank2[b];
g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g];
d = (d & 7) << 2 | (d & 128) >> 2;
h = f;
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h]]
}
if (c < e) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
d = this.BGCHRBank2[b];
g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g];
d = (d & 7) << 2 | (d & 128) >> 2;
switch (e - c) {
case 7:
this.frameBuffer[c + 6] = this.gbcBGPalette[d | g[f | 6]];
case 6:
this.frameBuffer[c + 5] = this.gbcBGPalette[d | g[f | 5]];
case 5:
this.frameBuffer[c + 4] = this.gbcBGPalette[d | g[f | 4]];
case 4:
this.frameBuffer[c + 3] = this.gbcBGPalette[d | g[f | 3]];
case 3:
this.frameBuffer[c + 2] = this.gbcBGPalette[d | g[f | 2]];
case 2:
this.frameBuffer[c + 1] = this.gbcBGPalette[d | g[f | 1]];
case 1:
this.frameBuffer[c] = this.gbcBGPalette[d | g[f]]
}
}
}
}
}
};
GameBoyCore.prototype.WindowGBCLayerRenderNoPriorityFlagging = function (a) {
if (this.gfxWindowDisplay) {
var b = a - this.windowY;
if (b >= 0) {
var a = this.windowX > 0 ? this.windowX + this.currentX : this.currentX,
c = this.pixelStart + a,
e = this.pixelStart + this.pixelEnd;
if (c < e) {
var f = (b & 7) << 3,
b = (this.gfxWindowCHRBankPosition | (b & 248) << 2) + (this.currentX >> 3),
g = this.BGCHRBank1[b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
for (var d = this.BGCHRBank2[b], g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g], d = (d & 7) << 2, h = a - this.windowX & 7, a = Math.min(8, h + e - c); h < a;) this.frameBuffer[c++] = this.gbcBGPalette[d | g[f | h++]];
for (a = b + (e - c >> 3); b < a;) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
d = this.BGCHRBank2[b];
g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g];
d = (d & 7) << 2;
h = f;
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h++]];
this.frameBuffer[c++] = this.gbcBGPalette[d | g[h]]
}
if (c < e) {
g = this.BGCHRBank1[++b];
g < this.gfxBackgroundBankOffset && (g = g | 256);
d = this.BGCHRBank2[b];
g = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | g];
d = (d & 7) << 2;
switch (e - c) {
case 7:
this.frameBuffer[c + 6] = this.gbcBGPalette[d | g[f | 6]];
case 6:
this.frameBuffer[c + 5] = this.gbcBGPalette[d | g[f | 5]];
case 5:
this.frameBuffer[c + 4] = this.gbcBGPalette[d | g[f | 4]];
case 4:
this.frameBuffer[c + 3] = this.gbcBGPalette[d | g[f | 3]];
case 3:
this.frameBuffer[c + 2] = this.gbcBGPalette[d | g[f | 2]];
case 2:
this.frameBuffer[c + 1] = this.gbcBGPalette[d | g[f | 1]];
case 1:
this.frameBuffer[c] = this.gbcBGPalette[d | g[f]]
}
}
}
}
}
};
GameBoyCore.prototype.SpriteGBLayerRender = function (a) {
if (this.gfxSpriteShow) {
for (var a = a + 16, b = 65024, c = 0, b = 1, e = 0, f = 0, g = 0, d = 0, h = null, i = 0, j = 0, q = 0, l = 0, n = 0; b < 168;) this.sortBuffer[b++] = 255;
if (this.gfxSpriteNormalHeight) for (q = this.findLowestSpriteDrawable(a, 7); j < q; ++j) {
b = this.OAMAddressCache[j];
c = a - this.memory[b] << 3;
g = this.memory[b | 3];
d = (g & 16) >> 2;
h = this.tileCache[(g & 96) << 4 | this.memory[b | 2]];
n = e = this.memory[b | 1];
f = Math.min(168 - n, 8);
b = n > 7 ? 0 : 8 - n;
for (l = this.pixelStart + (n > 8 ? n - 8 : 0); b < f; ++b, ++l, ++n) if (this.sortBuffer[n] > e) if (this.frameBuffer[l] >= 33554432) {
i = h[c | b];
if (i > 0) {
this.frameBuffer[l] = this.OBJPalette[d | i];
this.sortBuffer[n] = e
}
} else if (this.frameBuffer[l] < 16777216) {
i = h[c | b];
if (i > 0 && g < 128) {
this.frameBuffer[l] = this.OBJPalette[d | i];
this.sortBuffer[n] = e
}
}
} else for (q = this.findLowestSpriteDrawable(a, 15); j < q; ++j) {
b = this.OAMAddressCache[j];
c = a - this.memory[b] << 3;
g = this.memory[b | 3];
d = (g & 16) >> 2;
h = (g & 64) == (64 & c) ? this.tileCache[(g & 96) << 4 | this.memory[b | 2] & 254] : this.tileCache[(g & 96) << 4 | this.memory[b | 2] | 1];
c = c & 63;
n = e = this.memory[b | 1];
f = Math.min(168 - n, 8);
b = n > 7 ? 0 : 8 - n;
for (l = this.pixelStart + (n > 8 ? n - 8 : 0); b < f; ++b, ++l, ++n) if (this.sortBuffer[n] > e) if (this.frameBuffer[l] >= 33554432) {
i = h[c | b];
if (i > 0) {
this.frameBuffer[l] = this.OBJPalette[d | i];
this.sortBuffer[n] = e
}
} else if (this.frameBuffer[l] < 16777216) {
i = h[c | b];
if (i > 0 && g < 128) {
this.frameBuffer[l] = this.OBJPalette[d | i];
this.sortBuffer[n] = e
}
}
}
}
};
GameBoyCore.prototype.findLowestSpriteDrawable = function (a, b) {
for (var c = 65024, e = 0, f = 0; c < 65184 && e < 10;) {
f = a - this.memory[c];
(f & b) == f && (this.OAMAddressCache[e++] = c);
c = c + 4
}
return e
};
GameBoyCore.prototype.SpriteGBCLayerRender = function (a) {
if (this.gfxSpriteShow) {
var b = 65024,
a = a + 16,
c = 0,
e = 0,
f = 0,
g = 0,
d = 0,
h = 0,
i = null,
j = c = 0,
q = 0;
if (this.gfxSpriteNormalHeight) for (; b < 65184 && q < 10; b = b + 4) {
c = a - this.memory[b];
if ((c & 7) == c) {
e = this.memory[b | 1] - 8;
f = Math.min(160, e + 8);
d = this.memory[b | 3];
h = (d & 7) << 2;
i = this.tileCache[(d & 8) << 8 | (d & 96) << 4 | this.memory[b | 2]];
g = e > 0 ? e : 0;
e = e - (c << 3);
for (j = this.pixelStart + g; g < f; ++g, ++j) if (this.frameBuffer[j] >= 33554432) {
c = i[g - e];
c > 0 && (this.frameBuffer[j] = this.gbcOBJPalette[h | c])
} else if (this.frameBuffer[j] < 16777216) {
c = i[g - e];
c > 0 && d < 128 && (this.frameBuffer[j] = this.gbcOBJPalette[h | c])
}++q
}
} else for (; b < 65184 && q < 10; b = b + 4) {
c = a - this.memory[b];
if ((c & 15) == c) {
e = this.memory[b | 1] - 8;
f = Math.min(160, e + 8);
d = this.memory[b | 3];
h = (d & 7) << 2;
i = (d & 64) == (64 & c << 3) ? this.tileCache[(d & 8) << 8 | (d & 96) << 4 | this.memory[b | 2] & 254] : this.tileCache[(d & 8) << 8 | (d & 96) << 4 | this.memory[b | 2] | 1];
g = e > 0 ? e : 0;
e = e - ((c & 7) << 3);
for (j = this.pixelStart + g; g < f; ++g, ++j) if (this.frameBuffer[j] >= 33554432) {
c = i[g - e];
c > 0 && (this.frameBuffer[j] = this.gbcOBJPalette[h | c])
} else if (this.frameBuffer[j] < 16777216) {
c = i[g - e];
c > 0 && d < 128 && (this.frameBuffer[j] = this.gbcOBJPalette[h | c])
}++q
}
}
}
};
GameBoyCore.prototype.generateGBTileLine = function (a) {
var b = this.memory[1 | a] << 8 | this.memory[40958 & a],
c = this.tileCache[(a & 8176) >> 4],
a = (a & 14) << 2;
c[a | 7] = (b & 256) >> 7 | b & 1;
c[a | 6] = (b & 512) >> 8 | (b & 2) >> 1;
c[a | 5] = (b & 1024) >> 9 | (b & 4) >> 2;
c[a | 4] = (b & 2048) >> 10 | (b & 8) >> 3;
c[a | 3] = (b & 4096) >> 11 | (b & 16) >> 4;
c[a | 2] = (b & 8192) >> 12 | (b & 32) >> 5;
c[a | 1] = (b & 16384) >> 13 | (b & 64) >> 6;
c[a] = (b & 32768) >> 14 | (b & 128) >> 7
};
GameBoyCore.prototype.generateGBCTileLineBank1 = function (a) {
var b = this.memory[1 | a] << 8 | this.memory[40958 & a],
a = a & 8190,
c = this.tileCache[a >> 4],
e = this.tileCache[512 | a >> 4],
f = this.tileCache[1024 | a >> 4],
g = this.tileCache[1536 | a >> 4],
a = (a & 14) << 2,
d = 56 - a;
g[d] = e[a] = f[d | 7] = c[a | 7] = (b & 256) >> 7 | b & 1;
g[d | 1] = e[a | 1] = f[d | 6] = c[a | 6] = (b & 512) >> 8 | (b & 2) >> 1;
g[d | 2] = e[a | 2] = f[d | 5] = c[a | 5] = (b & 1024) >> 9 | (b & 4) >> 2;
g[d | 3] = e[a | 3] = f[d | 4] = c[a | 4] = (b & 2048) >> 10 | (b & 8) >> 3;
g[d | 4] = e[a | 4] = f[d | 3] = c[a | 3] = (b & 4096) >> 11 | (b & 16) >> 4;
g[d | 5] = e[a | 5] = f[d | 2] = c[a | 2] = (b & 8192) >> 12 | (b & 32) >> 5;
g[d | 6] = e[a | 6] = f[d | 1] = c[a | 1] = (b & 16384) >> 13 | (b & 64) >> 6;
g[d | 7] = e[a | 7] = f[d] = c[a] = (b & 32768) >> 14 | (b & 128) >> 7
};
GameBoyCore.prototype.generateGBCTileBank1 = function (a) {
var b = a >> 4,
c = this.tileCache[b],
e = this.tileCache[512 | b],
f = this.tileCache[1024 | b],
g = this.tileCache[1536 | b],
d = 0,
a = a | 32768,
b = 0,
h = 56;
do {
d = this.memory[1 | a] << 8 | this.memory[a];
g[h] = e[b] = f[h | 7] = c[b | 7] = (d & 256) >> 7 | d & 1;
g[h | 1] = e[b | 1] = f[h | 6] = c[b | 6] = (d & 512) >> 8 | (d & 2) >> 1;
g[h | 2] = e[b | 2] = f[h | 5] = c[b | 5] = (d & 1024) >> 9 | (d & 4) >> 2;
g[h | 3] = e[b | 3] = f[h | 4] = c[b | 4] = (d & 2048) >> 10 | (d & 8) >> 3;
g[h | 4] = e[b | 4] = f[h | 3] = c[b | 3] = (d & 4096) >> 11 | (d & 16) >> 4;
g[h | 5] = e[b | 5] = f[h | 2] = c[b | 2] = (d & 8192) >> 12 | (d & 32) >> 5;
g[h | 6] = e[b | 6] = f[h | 1] = c[b | 1] = (d & 16384) >> 13 | (d & 64) >> 6;
g[h | 7] = e[b | 7] = f[h] = c[b] = (d & 32768) >> 14 | (d & 128) >> 7;
b = b + 8;
h = h - 8;
a = a + 2
} while (h > -1)
};
GameBoyCore.prototype.generateGBCTileLineBank2 = function (a) {
var b = this.VRAM[1 | a] << 8 | this.VRAM[8190 & a],
c = this.tileCache[2048 | a >> 4],
e = this.tileCache[2560 | a >> 4],
f = this.tileCache[3072 | a >> 4],
g = this.tileCache[3584 | a >> 4],
a = (a & 14) << 2,
d = 56 - a;
g[d] = e[a] = f[d | 7] = c[a | 7] = (b & 256) >> 7 | b & 1;
g[d | 1] = e[a | 1] = f[d | 6] = c[a | 6] = (b & 512) >> 8 | (b & 2) >> 1;
g[d | 2] = e[a | 2] = f[d | 5] = c[a | 5] = (b & 1024) >> 9 | (b & 4) >> 2;
g[d | 3] = e[a | 3] = f[d | 4] = c[a | 4] = (b & 2048) >> 10 | (b & 8) >> 3;
g[d | 4] = e[a | 4] = f[d | 3] = c[a | 3] = (b & 4096) >> 11 | (b & 16) >> 4;
g[d | 5] = e[a | 5] = f[d | 2] = c[a | 2] = (b & 8192) >> 12 | (b & 32) >> 5;
g[d | 6] = e[a | 6] = f[d | 1] = c[a | 1] = (b & 16384) >> 13 | (b & 64) >> 6;
g[d | 7] = e[a | 7] = f[d] = c[a] = (b & 32768) >> 14 | (b & 128) >> 7
};
GameBoyCore.prototype.generateGBCTileBank2 = function (a) {
var b = a >> 4,
c = this.tileCache[2048 | b],
e = this.tileCache[2560 | b],
f = this.tileCache[3072 | b],
g = this.tileCache[3584 | b],
d = 0,
b = 0,
h = 56;
do {
d = this.VRAM[1 | a] << 8 | this.VRAM[a];
g[h] = e[b] = f[h | 7] = c[b | 7] = (d & 256) >> 7 | d & 1;
g[h | 1] = e[b | 1] = f[h | 6] = c[b | 6] = (d & 512) >> 8 | (d & 2) >> 1;
g[h | 2] = e[b | 2] = f[h | 5] = c[b | 5] = (d & 1024) >> 9 | (d & 4) >> 2;
g[h | 3] = e[b | 3] = f[h | 4] = c[b | 4] = (d & 2048) >> 10 | (d & 8) >> 3;
g[h | 4] = e[b | 4] = f[h | 3] = c[b | 3] = (d & 4096) >> 11 | (d & 16) >> 4;
g[h | 5] = e[b | 5] = f[h | 2] = c[b | 2] = (d & 8192) >> 12 | (d & 32) >> 5;
g[h | 6] = e[b | 6] = f[h | 1] = c[b | 1] = (d & 16384) >> 13 | (d & 64) >> 6;
g[h | 7] = e[b | 7] = f[h] = c[b] = (d & 32768) >> 14 | (d & 128) >> 7;
b = b + 8;
h = h - 8;
a = a + 2
} while (h > -1)
};
GameBoyCore.prototype.generateGBOAMTileLine = function (a) {
var b = this.memory[1 | a] << 8 | this.memory[40958 & a],
a = a & 8190,
c = this.tileCache[a >> 4],
e = this.tileCache[512 | a >> 4],
f = this.tileCache[1024 | a >> 4],
g = this.tileCache[1536 | a >> 4],
a = (a & 14) << 2,
d = 56 - a;
g[d] = e[a] = f[d | 7] = c[a | 7] = (b & 256) >> 7 | b & 1;
g[d | 1] = e[a | 1] = f[d | 6] = c[a | 6] = (b & 512) >> 8 | (b & 2) >> 1;
g[d | 2] = e[a | 2] = f[d | 5] = c[a | 5] = (b & 1024) >> 9 | (b & 4) >> 2;
g[d | 3] = e[a | 3] = f[d | 4] = c[a | 4] = (b & 2048) >> 10 | (b & 8) >> 3;
g[d | 4] = e[a | 4] = f[d | 3] = c[a | 3] = (b & 4096) >> 11 | (b & 16) >> 4;
g[d | 5] = e[a | 5] = f[d | 2] = c[a | 2] = (b & 8192) >> 12 | (b & 32) >> 5;
g[d | 6] = e[a | 6] = f[d | 1] = c[a | 1] = (b & 16384) >> 13 | (b & 64) >> 6;
g[d | 7] = e[a | 7] = f[d] = c[a] = (b & 32768) >> 14 | (b & 128) >> 7
};
GameBoyCore.prototype.graphicsJIT = function () {
if (this.LCDisOn) {
this.totalLinesPassed = 0;
this.graphicsJITScanlineGroup()
}
};
GameBoyCore.prototype.graphicsJITVBlank = function () {
this.totalLinesPassed = this.totalLinesPassed + this.queuedScanLines;
this.graphicsJITScanlineGroup()
};
GameBoyCore.prototype.graphicsJITScanlineGroup = function () {
for (; this.queuedScanLines > 0;) {
this.renderScanLine(this.lastUnrenderedLine);
this.lastUnrenderedLine < 143 ? ++this.lastUnrenderedLine : this.lastUnrenderedLine = 0;
--this.queuedScanLines
}
};
GameBoyCore.prototype.incrementScanLineQueue = function () {
if (this.queuedScanLines < 144)++this.queuedScanLines;
else {
this.currentX = 0;
this.midScanlineOffset = -1;
this.lastUnrenderedLine < 143 ? ++this.lastUnrenderedLine : this.lastUnrenderedLine = 0
}
};
GameBoyCore.prototype.midScanLineJIT = function () {
this.graphicsJIT();
this.renderMidScanLine()
};
GameBoyCore.prototype.launchIRQ = function () {
var a = 0,
b = 1;
do {
if ((b & this.IRQLineMatched) == b) {
this.IME = false;
this.interruptsRequested = this.interruptsRequested - b;
this.IRQLineMatched = 0;
this.CPUTicks = 20;
this.stackPointer = this.stackPointer - 1 & 65535;
this.memoryWriter[this.stackPointer](this, this.stackPointer, this.programCounter >> 8);
this.stackPointer = this.stackPointer - 1 & 65535;
this.memoryWriter[this.stackPointer](this, this.stackPointer, this.programCounter & 255);
this.programCounter = 64 | a << 3;
this.updateCore();
break
}
b = 1 << ++a
} while (a < 5)
};
GameBoyCore.prototype.checkIRQMatching = function () {
if (this.IME) this.IRQLineMatched = this.interruptsEnabled & this.interruptsRequested & 31
};
GameBoyCore.prototype.calculateHALTPeriod = function () {
if (this.halt) a = this.remainingClocks;
else {
this.halt = true;
var a = -1,
b = 0;
if (this.LCDisOn) {
(this.interruptsEnabled & 1) == 1 && (a = 456 * ((this.modeSTAT == 1 ? 298 : 144) - this.actualScanLine) - this.LCDTicks << this.doubleSpeedShifter);
if ((this.interruptsEnabled & 2) == 2) {
if (this.mode0TriggerSTAT) {
b = this.clocksUntilMode0() - this.LCDTicks << this.doubleSpeedShifter;
if (b <= a || a == -1) a = b
}
if (this.mode1TriggerSTAT && (this.interruptsEnabled & 1) == 0) {
b = 456 * ((this.modeSTAT == 1 ? 298 : 144) - this.actualScanLine) - this.LCDTicks << this.doubleSpeedShifter;
if (b <= a || a == -1) a = b
}
if (this.mode2TriggerSTAT) {
b = (this.actualScanLine >= 143 ? 456 * (154 - this.actualScanLine) : 456) - this.LCDTicks << this.doubleSpeedShifter;
if (b <= a || a == -1) a = b
}
if (this.LYCMatchTriggerSTAT && this.memory[65349] <= 153) {
b = this.clocksUntilLYCMatch() - this.LCDTicks << this.doubleSpeedShifter;
if (b <= a || a == -1) a = b
}
}
}
if (this.TIMAEnabled && (this.interruptsEnabled & 4) == 4) {
b = (256 - this.memory[65285]) * this.TACClocker - this.timerTicks;
if (b <= a || a == -1) a = b
}
if (this.serialTimer > 0 && (this.interruptsEnabled & 8) == 8 && (this.serialTimer <= a || a == -1)) a = this.serialTimer
}
b = this.CPUCyclesTotal - this.emulatorTicks << this.doubleSpeedShifter;
if (a >= 0) if (a <= b) {
this.CPUTicks = Math.max(a, this.CPUTicks);
this.updateCoreFull();
this.halt = false;
this.CPUTicks = 0
} else {
this.CPUTicks = Math.max(b, this.CPUTicks);
this.remainingClocks = a - this.CPUTicks
} else this.CPUTicks = this.CPUTicks + b
};
GameBoyCore.prototype.memoryRead = function (a) {
return this.memoryReader[a](this, a)
};
GameBoyCore.prototype.memoryHighRead = function (a) {
return this.memoryHighReader[a](this, a)
};
GameBoyCore.prototype.memoryReadJumpCompile = function () {
for (var a = 0; a <= 65535; a++) if (a < 16384) this.memoryReader[a] = this.memoryReadNormal;
else if (a < 32768) this.memoryReader[a] = this.memoryReadROM;
else if (a < 38912) this.memoryReader[a] = this.cGBC ? this.VRAMDATAReadCGBCPU : this.VRAMDATAReadDMGCPU;
else if (a < 40960) this.memoryReader[a] = this.cGBC ? this.VRAMCHRReadCGBCPU : this.VRAMCHRReadDMGCPU;
else if (a >= 40960 && a < 49152) this.memoryReader[a] = this.numRAMBanks == 0.0625 && a < 41472 || this.numRAMBanks >= 1 ? this.cMBC7 ? this.memoryReadMBC7 : this.cMBC3 ? this.memoryReadMBC3 : this.memoryReadMBC : this.memoryReadBAD;
else if (a >= 49152 && a < 57344) this.memoryReader[a] = !this.cGBC || a < 53248 ? this.memoryReadNormal : this.memoryReadGBCMemory;
else if (a >= 57344 && a < 65024) this.memoryReader[a] = !this.cGBC || a < 61440 ? this.memoryReadECHONormal : this.memoryReadECHOGBCMemory;
else if (a < 65184) this.memoryReader[a] = this.memoryReadOAM;
else if (this.cGBC && a >= 65184 && a < 65280) this.memoryReader[a] = this.memoryReadNormal;
else if (a >= 65280) switch (a) {
case 65280:
this.memoryHighReader[0] = this.memoryReader[65280] = function (a) {
return 192 | a.memory[65280]
};
break;
case 65281:
this.memoryHighReader[1] = this.memoryReader[65281] = function (a) {
return a.memory[65282] < 128 ? a.memory[65281] : 255
};
break;
case 65282:
this.memoryHighReader[2] = this.cGBC ? this.memoryReader[65282] = function (a) {
return (a.serialTimer <= 0 ? 124 : 252) | a.memory[65282]
} : this.memoryReader[65282] = function (a) {
return (a.serialTimer <= 0 ? 126 : 254) | a.memory[65282]
};
break;
case 65284:
this.memoryHighReader[4] = this.memoryReader[65284] = function (a) {
a.memory[65284] = a.memory[65284] + (a.DIVTicks >> 8) & 255;
a.DIVTicks = a.DIVTicks & 255;
return a.memory[65284]
};
break;
case 65287:
this.memoryHighReader[7] = this.memoryReader[65287] = function (a) {
return 248 | a.memory[65287]
};
break;
case 65295:
this.memoryHighReader[15] = this.memoryReader[65295] = function (a) {
return 224 | a.interruptsRequested
};
break;
case 65296:
this.memoryHighReader[16] = this.memoryReader[65296] = function (a) {
return 128 | a.memory[65296]
};
break;
case 65297:
this.memoryHighReader[17] = this.memoryReader[65297] = function (a) {
return 63 | a.memory[65297]
};
break;
case 65299:
this.memoryHighReader[19] = this.memoryReader[65299] = this.memoryReadBAD;
break;
case 65300:
this.memoryHighReader[20] = this.memoryReader[65300] = function (a) {
return 191 | a.memory[65300]
};
break;
case 65302:
this.memoryHighReader[22] = this.memoryReader[65302] = function (a) {
return 63 | a.memory[65302]
};
break;
case 65304:
this.memoryHighReader[24] = this.memoryReader[65304] = this.memoryReadBAD;
break;
case 65305:
this.memoryHighReader[25] = this.memoryReader[65305] = function (a) {
return 191 | a.memory[65305]
};
break;
case 65306:
this.memoryHighReader[26] = this.memoryReader[65306] = function (a) {
return 127 | a.memory[65306]
};
break;
case 65307:
this.memoryHighReader[27] = this.memoryReader[65307] = this.memoryReadBAD;
break;
case 65308:
this.memoryHighReader[28] = this.memoryReader[65308] = function (a) {
return 159 | a.memory[65308]
};
break;
case 65309:
this.memoryHighReader[29] = this.memoryReader[65309] = function () {
return 255
};
break;
case 65310:
this.memoryHighReader[30] = this.memoryReader[65310] = function (a) {
return 191 | a.memory[65310]
};
break;
case 65311:
case 65312:
this.memoryHighReader[a & 255] = this.memoryReader[a] = this.memoryReadBAD;
break;
case 65315:
this.memoryHighReader[35] = this.memoryReader[65315] = function (a) {
return 191 | a.memory[65315]
};
break;
case 65318:
this.memoryHighReader[38] = this.memoryReader[65318] = function (a) {
a.audioJIT();
return 112 | a.memory[65318]
};
break;
case 65319:
case 65320:
case 65321:
case 65322:
case 65323:
case 65324:
case 65325:
case 65326:
case 65327:
this.memoryHighReader[a & 255] = this.memoryReader[a] = this.memoryReadBAD;
break;
case 65328:
case 65329:
case 65330:
case 65331:
case 65332:
case 65333:
case 65334:
case 65335:
case 65336:
case 65337:
case 65338:
case 65339:
case 65340:
case 65341:
case 65342:
case 65343:
this.memoryReader[a] = function (a, c) {
return a.channel3canPlay ? a.memory[65280 | a.channel3lastSampleLookup >> 1] : a.memory[c]
};
this.memoryHighReader[a & 255] = function (a, c) {
return a.channel3canPlay ? a.memory[65280 | a.channel3lastSampleLookup >> 1] : a.memory[65280 | c]
};
break;
case 65345:
this.memoryHighReader[65] = this.memoryReader[65345] = function (a) {
return 128 | a.memory[65345] | a.modeSTAT
};
break;
case 65346:
this.memoryHighReader[66] = this.memoryReader[65346] = function (a) {
return a.backgroundY
};
break;
case 65347:
this.memoryHighReader[67] = this.memoryReader[65347] = function (a) {
return a.backgroundX
};
break;
case 65348:
this.memoryHighReader[68] = this.memoryReader[65348] = function (a) {
return a.LCDisOn ? a.memory[65348] : 0
};
break;
case 65354:
this.memoryHighReader[74] = this.memoryReader[65354] = function (a) {
return a.windowY
};
break;
case 65359:
this.memoryHighReader[79] = this.memoryReader[65359] = function (a) {
return a.currVRAMBank
};
break;
case 65365:
if (this.cGBC) this.memoryHighReader[85] = this.memoryReader[65365] = function (a) {
if (!a.LCDisOn && a.hdmaRunning) {
a.DMAWrite((a.memory[65365] & 127) + 1);
a.memory[65365] = 255;
a.hdmaRunning = false
}
return a.memory[65365]
};
else {
this.memoryReader[65365] = this.memoryReadNormal;
this.memoryHighReader[85] = this.memoryHighReadNormal
}
break;
case 65366:
if (this.cGBC) this.memoryHighReader[86] = this.memoryReader[65366] = function (a) {
return 60 | (a.memory[65366] >= 192 ? 2 | a.memory[65366] & 193 : a.memory[65366] & 195)
};
else {
this.memoryReader[65366] = this.memoryReadNormal;
this.memoryHighReader[86] = this.memoryHighReadNormal
}
break;
case 65388:
this.memoryHighReader[108] = this.cGBC ? this.memoryReader[65388] = function (a) {
return 254 | a.memory[65388]
} : this.memoryReader[65388] = this.memoryReadBAD;
break;
case 65392:
this.memoryHighReader[112] = this.cGBC ? this.memoryReader[65392] = function (a) {
return 64 | a.memory[65392]
} : this.memoryReader[65392] = this.memoryReadBAD;
break;
case 65397:
this.memoryHighReader[117] = this.memoryReader[65397] = function (a) {
return 143 | a.memory[65397]
};
break;
case 65398:
case 65399:
this.memoryHighReader[a & 255] = this.memoryReader[a] = function () {
return 0
};
break;
case 65535:
this.memoryHighReader[255] = this.memoryReader[65535] = function (a) {
return a.interruptsEnabled
};
break;
default:
this.memoryReader[a] = this.memoryReadNormal;
this.memoryHighReader[a & 255] = this.memoryHighReadNormal
} else this.memoryReader[a] = this.memoryReadBAD
};
GameBoyCore.prototype.memoryReadNormal = function (a, b) {
return a.memory[b]
};
GameBoyCore.prototype.memoryHighReadNormal = function (a, b) {
return a.memory[65280 | b]
};
GameBoyCore.prototype.memoryReadROM = function (a, b) {
return a.ROM[a.currentROMBank + b]
};
GameBoyCore.prototype.memoryReadMBC = function (a, b) {
return a.MBCRAMBanksEnabled || settings[10] ? a.MBCRam[b + a.currMBCRAMBankPosition] : 255
};
GameBoyCore.prototype.memoryReadMBC7 = function (a, b) {
if (a.MBCRAMBanksEnabled || settings[10]) switch (b) {
case 40960:
case 41056:
case 41072:
return 0;
case 41088:
return 0;
case 41040:
return a.highY;
case 41024:
return a.lowY;
case 41008:
return a.highX;
case 40992:
return a.lowX;
default:
return a.MBCRam[b + a.currMBCRAMBankPosition]
}
return 255
};
GameBoyCore.prototype.memoryReadMBC3 = function (a, b) {
if (a.MBCRAMBanksEnabled || settings[10]) switch (a.currMBCRAMBank) {
case 0:
case 1:
case 2:
case 3:
return a.MBCRam[b + a.currMBCRAMBankPosition];
case 8:
return a.latchedSeconds;
case 9:
return a.latchedMinutes;
case 10:
return a.latchedHours;
case 11:
return a.latchedLDays;
case 12:
return (a.RTCDayOverFlow ? 128 : 0) + (a.RTCHALT ? 64 : 0) + a.latchedHDays
}
return 255
};
GameBoyCore.prototype.memoryReadGBCMemory = function (a, b) {
return a.GBCMemory[b + a.gbcRamBankPosition]
};
GameBoyCore.prototype.memoryReadOAM = function (a, b) {
return a.modeSTAT > 1 ? 255 : a.memory[b]
};
GameBoyCore.prototype.memoryReadECHOGBCMemory = function (a, b) {
return a.GBCMemory[b + a.gbcRamBankPositionECHO]
};
GameBoyCore.prototype.memoryReadECHONormal = function (a, b) {
return a.memory[b - 8192]
};
GameBoyCore.prototype.memoryReadBAD = function () {
return 255
};
GameBoyCore.prototype.VRAMDATAReadCGBCPU = function (a, b) {
return a.modeSTAT > 2 ? 255 : a.currVRAMBank == 0 ? a.memory[b] : a.VRAM[b & 8191]
};
GameBoyCore.prototype.VRAMDATAReadDMGCPU = function (a, b) {
return a.modeSTAT > 2 ? 255 : a.memory[b]
};
GameBoyCore.prototype.VRAMCHRReadCGBCPU = function (a, b) {
return a.modeSTAT > 2 ? 255 : a.BGCHRCurrentBank[b & 2047]
};
GameBoyCore.prototype.VRAMCHRReadDMGCPU = function (a, b) {
return a.modeSTAT > 2 ? 255 : a.BGCHRBank1[b & 2047]
};
GameBoyCore.prototype.setCurrentMBC1ROMBank = function () {
switch (this.ROMBank1offs) {
case 0:
case 32:
case 64:
case 96:
this.currentROMBank = this.ROMBank1offs % this.ROMBankEdge << 14;
break;
default:
this.currentROMBank = this.ROMBank1offs % this.ROMBankEdge - 1 << 14
}
};
GameBoyCore.prototype.setCurrentMBC2AND3ROMBank = function () {
this.currentROMBank = Math.max(this.ROMBank1offs % this.ROMBankEdge - 1, 0) << 14
};
GameBoyCore.prototype.setCurrentMBC5ROMBank = function () {
this.currentROMBank = this.ROMBank1offs % this.ROMBankEdge - 1 << 14
};
GameBoyCore.prototype.memoryWrite = function (a, b) {
this.memoryWriter[a](this, a, b)
};
GameBoyCore.prototype.memoryHighWrite = function (a, b) {
this.memoryHighWriter[a](this, a, b)
};
GameBoyCore.prototype.memoryWriteJumpCompile = function () {
for (var a = 0; a <= 65535; a++) if (a < 32768) this.memoryWriter[a] = this.cMBC1 ? a < 8192 ? this.MBCWriteEnable : a < 16384 ? this.MBC1WriteROMBank : a < 24576 ? this.MBC1WriteRAMBank : this.MBC1WriteType : this.cMBC2 ? a < 4096 ? this.MBCWriteEnable : a >= 8448 && a < 8704 ? this.MBC2WriteROMBank : this.cartIgnoreWrite : this.cMBC3 ? a < 8192 ? this.MBCWriteEnable : a < 16384 ? this.MBC3WriteROMBank : a < 24576 ? this.MBC3WriteRAMBank : this.MBC3WriteRTCLatch : this.cMBC5 || this.cRUMBLE || this.cMBC7 ? a < 8192 ? this.MBCWriteEnable : a < 12288 ? this.MBC5WriteROMBankLow : a < 16384 ? this.MBC5WriteROMBankHigh : a < 24576 ? this.cRUMBLE ? this.RUMBLEWriteRAMBank : this.MBC5WriteRAMBank : this.cartIgnoreWrite : this.cHuC3 ? a < 8192 ? this.MBCWriteEnable : a < 16384 ? this.MBC3WriteROMBank : a < 24576 ? this.HuC3WriteRAMBank : this.cartIgnoreWrite : this.cartIgnoreWrite;
else if (a < 36864) this.memoryWriter[a] = this.cGBC ? this.VRAMGBCDATAWrite : this.VRAMGBDATAWrite;
else if (a < 38912) this.memoryWriter[a] = this.cGBC ? this.VRAMGBCDATAWrite : this.VRAMGBDATAUpperWrite;
else if (a < 40960) this.memoryWriter[a] = this.cGBC ? this.VRAMGBCCHRMAPWrite : this.VRAMGBCHRMAPWrite;
else if (a < 49152) this.memoryWriter[a] = this.numRAMBanks == 0.0625 && a < 41472 || this.numRAMBanks >= 1 ? this.cMBC3 ? this.memoryWriteMBC3RAM : this.memoryWriteMBCRAM : this.cartIgnoreWrite;
else if (a < 57344) this.memoryWriter[a] = this.cGBC && a >= 53248 ? this.memoryWriteGBCRAM : this.memoryWriteNormal;
else if (a < 65024) this.memoryWriter[a] = this.cGBC && a >= 61440 ? this.memoryWriteECHOGBCRAM : this.memoryWriteECHONormal;
else if (a <= 65184) this.memoryWriter[a] = this.memoryWriteOAMRAM;
else if (a < 65280) this.memoryWriter[a] = this.cGBC ? this.memoryWriteNormal : this.cartIgnoreWrite;
else {
this.memoryWriter[a] = this.memoryWriteNormal;
this.memoryHighWriter[a & 255] = this.memoryHighWriteNormal
}
this.registerWriteJumpCompile()
};
GameBoyCore.prototype.MBCWriteEnable = function (a, b, c) {
a.MBCRAMBanksEnabled = (c & 15) == 10
};
GameBoyCore.prototype.MBC1WriteROMBank = function (a, b, c) {
a.ROMBank1offs = a.ROMBank1offs & 96 | c & 31;
a.setCurrentMBC1ROMBank()
};
GameBoyCore.prototype.MBC1WriteRAMBank = function (a, b, c) {
if (a.MBC1Mode) {
a.currMBCRAMBank = c & 3;
a.currMBCRAMBankPosition = (a.currMBCRAMBank << 13) - 40960
} else {
a.ROMBank1offs = (c & 3) << 5 | a.ROMBank1offs & 31;
a.setCurrentMBC1ROMBank()
}
};
GameBoyCore.prototype.MBC1WriteType = function (a, b, c) {
a.MBC1Mode = (c & 1) == 1;
if (a.MBC1Mode) {
a.ROMBank1offs = a.ROMBank1offs & 31;
a.setCurrentMBC1ROMBank()
} else {
a.currMBCRAMBank = 0;
a.currMBCRAMBankPosition = -40960
}
};
GameBoyCore.prototype.MBC2WriteROMBank = function (a, b, c) {
a.ROMBank1offs = c & 15;
a.setCurrentMBC2AND3ROMBank()
};
GameBoyCore.prototype.MBC3WriteROMBank = function (a, b, c) {
a.ROMBank1offs = c & 127;
a.setCurrentMBC2AND3ROMBank()
};
GameBoyCore.prototype.MBC3WriteRAMBank = function (a, b, c) {
a.currMBCRAMBank = c;
if (c < 4) a.currMBCRAMBankPosition = (a.currMBCRAMBank << 13) - 40960
};
GameBoyCore.prototype.MBC3WriteRTCLatch = function (a, b, c) {
if (c == 0) a.RTCisLatched = false;
else if (!a.RTCisLatched) {
a.RTCisLatched = true;
a.latchedSeconds = a.RTCSeconds | 0;
a.latchedMinutes = a.RTCMinutes;
a.latchedHours = a.RTCHours;
a.latchedLDays = a.RTCDays & 255;
a.latchedHDays = a.RTCDays >> 8
}
};
GameBoyCore.prototype.MBC5WriteROMBankLow = function (a, b, c) {
a.ROMBank1offs = a.ROMBank1offs & 256 | c;
a.setCurrentMBC5ROMBank()
};
GameBoyCore.prototype.MBC5WriteROMBankHigh = function (a, b, c) {
a.ROMBank1offs = (c & 1) << 8 | a.ROMBank1offs & 255;
a.setCurrentMBC5ROMBank()
};
GameBoyCore.prototype.MBC5WriteRAMBank = function (a, b, c) {
a.currMBCRAMBank = c & 15;
a.currMBCRAMBankPosition = (a.currMBCRAMBank << 13) - 40960
};
GameBoyCore.prototype.RUMBLEWriteRAMBank = function (a, b, c) {
a.currMBCRAMBank = c & 3;
a.currMBCRAMBankPosition = (a.currMBCRAMBank << 13) - 40960
};
GameBoyCore.prototype.HuC3WriteRAMBank = function (a, b, c) {
a.currMBCRAMBank = c & 3;
a.currMBCRAMBankPosition = (a.currMBCRAMBank << 13) - 40960
};
GameBoyCore.prototype.cartIgnoreWrite = function () {};
GameBoyCore.prototype.memoryWriteNormal = function (a, b, c) {
a.memory[b] = c
};
GameBoyCore.prototype.memoryHighWriteNormal = function (a, b, c) {
a.memory[65280 | b] = c
};
GameBoyCore.prototype.memoryWriteMBCRAM = function (a, b, c) {
if (a.MBCRAMBanksEnabled || settings[10]) a.MBCRam[b + a.currMBCRAMBankPosition] = c
};
GameBoyCore.prototype.memoryWriteMBC3RAM = function (a, b, c) {
if (a.MBCRAMBanksEnabled || settings[10]) switch (a.currMBCRAMBank) {
case 0:
case 1:
case 2:
case 3:
a.MBCRam[b + a.currMBCRAMBankPosition] = c;
break;
case 8:
c < 60 ? a.RTCSeconds = c : cout("(Bank #" + a.currMBCRAMBank + ") RTC write out of range: " + c, 1);
break;
case 9:
c < 60 ? a.RTCMinutes = c : cout("(Bank #" + a.currMBCRAMBank + ") RTC write out of range: " + c, 1);
break;
case 10:
c < 24 ? a.RTCHours = c : cout("(Bank #" + a.currMBCRAMBank + ") RTC write out of range: " + c, 1);
break;
case 11:
a.RTCDays = c & 255 | a.RTCDays & 256;
break;
case 12:
a.RTCDayOverFlow = c > 127;
a.RTCHalt = (c & 64) == 64;
a.RTCDays = (c & 1) << 8 | a.RTCDays & 255;
break;
default:
cout("Invalid MBC3 bank address selected: " + a.currMBCRAMBank, 0)
}
};
GameBoyCore.prototype.memoryWriteGBCRAM = function (a, b, c) {
a.GBCMemory[b + a.gbcRamBankPosition] = c
};
GameBoyCore.prototype.memoryWriteOAMRAM = function (a, b, c) {
if (a.modeSTAT < 2 && a.memory[b] != c) {
a.graphicsJIT();
a.memory[b] = c
}
};
GameBoyCore.prototype.memoryWriteECHOGBCRAM = function (a, b, c) {
a.GBCMemory[b + a.gbcRamBankPositionECHO] = c
};
GameBoyCore.prototype.memoryWriteECHONormal = function (a, b, c) {
a.memory[b - 8192] = c
};
GameBoyCore.prototype.VRAMGBDATAWrite = function (a, b, c) {
if (a.modeSTAT < 3 && a.memory[b] != c) {
a.graphicsJIT();
a.memory[b] = c;
a.generateGBOAMTileLine(b)
}
};
GameBoyCore.prototype.VRAMGBDATAUpperWrite = function (a, b, c) {
if (a.modeSTAT < 3 && a.memory[b] != c) {
a.graphicsJIT();
a.memory[b] = c;
a.generateGBTileLine(b)
}
};
GameBoyCore.prototype.VRAMGBCDATAWrite = function (a, b, c) {
if (a.modeSTAT < 3) if (a.currVRAMBank == 0) {
if (a.memory[b] != c) {
a.graphicsJIT();
a.memory[b] = c;
a.generateGBCTileLineBank1(b)
}
} else {
b = b & 8191;
if (a.VRAM[b] != c) {
a.graphicsJIT();
a.VRAM[b] = c;
a.generateGBCTileLineBank2(b)
}
}
};
GameBoyCore.prototype.VRAMGBCHRMAPWrite = function (a, b, c) {
if (a.modeSTAT < 3) {
b = b & 2047;
if (a.BGCHRBank1[b] != c) {
a.graphicsJIT();
a.BGCHRBank1[b] = c
}
}
};
GameBoyCore.prototype.VRAMGBCCHRMAPWrite = function (a, b, c) {
if (a.modeSTAT < 3) {
b = b & 2047;
if (a.BGCHRCurrentBank[b] != c) {
a.graphicsJIT();
a.BGCHRCurrentBank[b] = c
}
}
};
GameBoyCore.prototype.DMAWrite = function (a) {
if (!this.halt) this.CPUTicks = this.CPUTicks + (4 | a << 5 << this.doubleSpeedShifter);
var b = this.memory[65361] << 8 | this.memory[65362],
c = this.memory[65363] << 8 | this.memory[65364],
e = this.memoryReader;
this.graphicsJIT();
var f = this.memory;
if (this.currVRAMBank == 0) {
do {
if (c < 6144) {
f[32768 | c] = e[b](this, b++);
f[32769 | c] = e[b](this, b++);
f[32770 | c] = e[b](this, b++);
f[32771 | c] = e[b](this, b++);
f[32772 | c] = e[b](this, b++);
f[32773 | c] = e[b](this, b++);
f[32774 | c] = e[b](this, b++);
f[32775 | c] = e[b](this, b++);
f[32776 | c] = e[b](this, b++);
f[32777 | c] = e[b](this, b++);
f[32778 | c] = e[b](this, b++);
f[32779 | c] = e[b](this, b++);
f[32780 | c] = e[b](this, b++);
f[32781 | c] = e[b](this, b++);
f[32782 | c] = e[b](this, b++);
f[32783 | c] = e[b](this, b++);
this.generateGBCTileBank1(c);
c = c + 16
} else {
c = c & 2032;
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
this.BGCHRBank1[c++] = e[b](this, b++);
c = c + 6144 & 8176
}
b = b & 65520;--a
} while (a > 0)
} else {
var g = this.VRAM;
do {
if (c < 6144) {
g[c] = e[b](this, b++);
g[c | 1] = e[b](this, b++);
g[c | 2] = e[b](this, b++);
g[c | 3] = e[b](this, b++);
g[c | 4] = e[b](this, b++);
g[c | 5] = e[b](this, b++);
g[c | 6] = e[b](this, b++);
g[c | 7] = e[b](this, b++);
g[c | 8] = e[b](this, b++);
g[c | 9] = e[b](this, b++);
g[c | 10] = e[b](this, b++);
g[c | 11] = e[b](this, b++);
g[c | 12] = e[b](this, b++);
g[c | 13] = e[b](this, b++);
g[c | 14] = e[b](this, b++);
g[c | 15] = e[b](this, b++);
this.generateGBCTileBank2(c);
c = c + 16
} else {
c = c & 2032;
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
this.BGCHRBank2[c++] = e[b](this, b++);
c = c + 6144 & 8176
}
b = b & 65520;--a
} while (a > 0)
}
f[65361] = b >> 8;
f[65362] = b & 240;
f[65363] = c >> 8;
f[65364] = c & 240
};
GameBoyCore.prototype.registerWriteJumpCompile = function () {
this.memoryHighWriter[0] = this.memoryWriter[65280] = function (a, b, c) {
a.memory[65280] = c & 48 | ((c & 32) == 0 ? a.JoyPad >> 4 : 15) & ((c & 16) == 0 ? a.JoyPad & 15 : 15)
};
this.memoryHighWriter[1] = this.memoryWriter[65281] = function (a, b, c) {
a.memory[65282] < 128 && (a.memory[65281] = c)
};
this.memoryHighWriter[4] = this.memoryWriter[65284] = function (a) {
a.DIVTicks = a.DIVTicks & 255;
a.memory[65284] = 0
};
this.memoryHighWriter[5] = this.memoryWriter[65285] = function (a, b, c) {
a.memory[65285] = c
};
this.memoryHighWriter[6] = this.memoryWriter[65286] = function (a, b, c) {
a.memory[65286] = c
};
this.memoryHighWriter[7] = this.memoryWriter[65287] = function (a, b, c) {
a.memory[65287] = c & 7;
a.TIMAEnabled = (c & 4) == 4;
a.TACClocker = Math.pow(4, (c & 3) != 0 ? c & 3 : 4) << 2
};
this.memoryHighWriter[15] = this.memoryWriter[65295] = function (a, b, c) {
a.interruptsRequested = c;
a.checkIRQMatching()
};
this.memoryHighWriter[16] = this.memoryWriter[65296] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (a.channel1decreaseSweep && (c & 8) == 0 && a.channel1numSweep != a.channel1frequencySweepDivider) a.channel1SweepFault = true;
a.channel1lastTimeSweep = (c & 112) >> 4;
a.channel1frequencySweepDivider = c & 7;
a.channel1decreaseSweep = (c & 8) == 8;
a.memory[65296] = c;
a.channel1EnableCheck()
}
};
this.memoryHighWriter[17] = this.memoryWriter[65297] = function (a, b, c) {
if (a.soundMasterEnabled || !a.cGBC) {
a.soundMasterEnabled ? a.audioJIT() : c = c & 63;
a.channel1CachedDuty = a.dutyLookup[c >> 6];
a.channel1totalLength = 64 - (c & 63);
a.memory[65297] = c & 192;
a.channel1EnableCheck()
}
};
this.memoryHighWriter[18] = this.memoryWriter[65298] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (a.channel1Enabled && a.channel1envelopeSweeps == 0) {
if (((a.memory[65298] ^ c) & 8) == 8) {
if ((a.memory[65298] & 8) == 0)(a.memory[65298] & 7) == 7 ? a.channel1envelopeVolume = a.channel1envelopeVolume + 2 : ++a.channel1envelopeVolume;
a.channel1envelopeVolume = 16 - a.channel1envelopeVolume & 15
} else if ((a.memory[65298] & 15) == 8) a.channel1envelopeVolume = 1 + a.channel1envelopeVolume & 15;
a.channel1OutputLevelCache()
}
a.channel1envelopeType = (c & 8) == 8;
a.memory[65298] = c;
a.channel1VolumeEnableCheck()
}
};
this.memoryHighWriter[19] = this.memoryWriter[65299] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.channel1frequency = a.channel1frequency & 1792 | c;
a.channel1FrequencyTracker = 2048 - a.channel1frequency << 2;
a.memory[65299] = c
}
};
this.memoryHighWriter[20] = this.memoryWriter[65300] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.channel1consecutive = (c & 64) == 0;
a.channel1frequency = (c & 7) << 8 | a.channel1frequency & 255;
a.channel1FrequencyTracker = 2048 - a.channel1frequency << 2;
if (c > 127) {
a.channel1timeSweep = a.channel1lastTimeSweep;
a.channel1numSweep = a.channel1frequencySweepDivider;
b = a.memory[65298];
a.channel1envelopeVolume = b >> 4;
a.channel1OutputLevelCache();
a.channel1envelopeSweepsLast = (b & 7) - 1;
if (a.channel1totalLength == 0) a.channel1totalLength = 64;
a.memory[65318] = a.channel1lastTimeSweep > 0 || a.channel1frequencySweepDivider > 0 ? a.memory[65318] | 1 : a.memory[65318] & 254;
(c & 64) == 64 && (a.memory[65318] = a.memory[65318] | 1);
a.channel1ShadowFrequency = a.channel1frequency;
a.channel1SweepFault = false;
a.channel1AudioSweepPerformDummy()
}
a.channel1EnableCheck();
a.memory[65300] = c & 64
}
};
this.memoryHighWriter[22] = this.memoryWriter[65302] = function (a, b, c) {
if (a.soundMasterEnabled || !a.cGBC) {
a.soundMasterEnabled ? a.audioJIT() : c = c & 63;
a.channel2CachedDuty = a.dutyLookup[c >> 6];
a.channel2totalLength = 64 - (c & 63);
a.memory[65302] = c & 192;
a.channel2EnableCheck()
}
};
this.memoryHighWriter[23] = this.memoryWriter[65303] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (a.channel2Enabled && a.channel2envelopeSweeps == 0) {
if (((a.memory[65303] ^ c) & 8) == 8) {
if ((a.memory[65303] & 8) == 0)(a.memory[65303] & 7) == 7 ? a.channel2envelopeVolume = a.channel2envelopeVolume + 2 : ++a.channel2envelopeVolume;
a.channel2envelopeVolume = 16 - a.channel2envelopeVolume & 15
} else if ((a.memory[65303] & 15) == 8) a.channel2envelopeVolume = 1 + a.channel2envelopeVolume & 15;
a.channel2OutputLevelCache()
}
a.channel2envelopeType = (c & 8) == 8;
a.memory[65303] = c;
a.channel2VolumeEnableCheck()
}
};
this.memoryHighWriter[24] = this.memoryWriter[65304] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.channel2frequency = a.channel2frequency & 1792 | c;
a.channel2FrequencyTracker = 2048 - a.channel2frequency << 2;
a.memory[65304] = c
}
};
this.memoryHighWriter[25] = this.memoryWriter[65305] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (c > 127) {
b = a.memory[65303];
a.channel2envelopeVolume = b >> 4;
a.channel2OutputLevelCache();
a.channel2envelopeSweepsLast = (b & 7) - 1;
if (a.channel2totalLength == 0) a.channel2totalLength = 64;
(c & 64) == 64 && (a.memory[65318] = a.memory[65318] | 2)
}
a.channel2consecutive = (c & 64) == 0;
a.channel2frequency = (c & 7) << 8 | a.channel2frequency & 255;
a.channel2FrequencyTracker = 2048 - a.channel2frequency << 2;
a.memory[65305] = c & 64;
a.channel2EnableCheck()
}
};
this.memoryHighWriter[26] = this.memoryWriter[65306] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (!a.channel3canPlay && c >= 128) {
a.channel3lastSampleLookup = 0;
a.channel3UpdateCache()
}
a.channel3canPlay = c > 127;
a.channel3canPlay && (a.memory[65306] > 127 && !a.channel3consecutive) && (a.memory[65318] = a.memory[65318] | 4);
a.memory[65306] = c & 128
}
};
this.memoryHighWriter[27] = this.memoryWriter[65307] = function (a, b, c) {
if (a.soundMasterEnabled || !a.cGBC) {
a.soundMasterEnabled && a.audioJIT();
a.channel3totalLength = 256 - c;
a.memory[65307] = c;
a.channel3EnableCheck()
}
};
this.memoryHighWriter[28] = this.memoryWriter[65308] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
c = c & 96;
a.memory[65308] = c;
a.channel3patternType = c == 0 ? 4 : (c >> 5) - 1
}
};
this.memoryHighWriter[29] = this.memoryWriter[65309] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.channel3frequency = a.channel3frequency & 1792 | c;
a.channel3FrequencyPeriod = 2048 - a.channel3frequency << 1;
a.memory[65309] = c
}
};
this.memoryHighWriter[30] = this.memoryWriter[65310] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (c > 127) {
if (a.channel3totalLength == 0) a.channel3totalLength = 256;
a.channel3lastSampleLookup = 0;
(c & 64) == 64 && (a.memory[65318] = a.memory[65318] | 4)
}
a.channel3consecutive = (c & 64) == 0;
a.channel3frequency = (c & 7) << 8 | a.channel3frequency & 255;
a.channel3FrequencyPeriod = 2048 - a.channel3frequency << 1;
a.memory[65310] = c & 64;
a.channel3EnableCheck()
}
};
this.memoryHighWriter[32] = this.memoryWriter[65312] = function (a, b, c) {
if (a.soundMasterEnabled || !a.cGBC) {
a.soundMasterEnabled && a.audioJIT();
a.channel4totalLength = 64 - (c & 63);
a.memory[65312] = c | 192;
a.channel4EnableCheck()
}
};
this.memoryHighWriter[33] = this.memoryWriter[65313] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
if (a.channel4Enabled && a.channel4envelopeSweeps == 0) {
if (((a.memory[65313] ^ c) & 8) == 8) {
if ((a.memory[65313] & 8) == 0)(a.memory[65313] & 7) == 7 ? a.channel4envelopeVolume = a.channel4envelopeVolume + 2 : ++a.channel4envelopeVolume;
a.channel4envelopeVolume = 16 - a.channel4envelopeVolume & 15
} else if ((a.memory[65313] & 15) == 8) a.channel4envelopeVolume = 1 + a.channel4envelopeVolume & 15;
a.channel4currentVolume = a.channel4envelopeVolume << a.channel4VolumeShifter
}
a.channel4envelopeType = (c & 8) == 8;
a.memory[65313] = c;
a.channel4UpdateCache();
a.channel4VolumeEnableCheck()
}
};
this.memoryHighWriter[34] = this.memoryWriter[65314] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.channel4FrequencyPeriod = Math.max((c & 7) << 4, 8) << (c >> 4);
b = c & 8;
if (b == 8 && a.channel4BitRange == 32767 || b == 0 && a.channel4BitRange == 127) {
a.channel4lastSampleLookup = 0;
a.channel4BitRange = b == 8 ? 127 : 32767;
a.channel4VolumeShifter = b == 8 ? 7 : 15;
a.channel4currentVolume = a.channel4envelopeVolume << a.channel4VolumeShifter;
a.noiseSampleTable = b == 8 ? a.LSFR7Table : a.LSFR15Table
}
a.memory[65314] = c;
a.channel4UpdateCache()
}
};
this.memoryHighWriter[35] = this.memoryWriter[65315] = function (a, b, c) {
if (a.soundMasterEnabled) {
a.audioJIT();
a.memory[65315] = c;
a.channel4consecutive = (c & 64) == 0;
if (c > 127) {
b = a.memory[65313];
a.channel4envelopeVolume = b >> 4;
a.channel4currentVolume = a.channel4envelopeVolume << a.channel4VolumeShifter;
a.channel4envelopeSweepsLast = (b & 7) - 1;
if (a.channel4totalLength == 0) a.channel4totalLength = 64;
(c & 64) == 64 && (a.memory[65318] = a.memory[65318] | 8)
}
a.channel4EnableCheck()
}
};
this.memoryHighWriter[36] = this.memoryWriter[65316] = function (a, b, c) {
if (a.soundMasterEnabled && a.memory[65316] != c) {
a.audioJIT();
a.memory[65316] = c;
a.VinLeftChannelMasterVolume = (c >> 4 & 7) + 1;
a.VinRightChannelMasterVolume = (c & 7) + 1;
a.mixerOutputLevelCache()
}
};
this.memoryHighWriter[37] = this.memoryWriter[65317] = function (a, b, c) {
if (a.soundMasterEnabled && a.memory[65317] != c) {
a.audioJIT();
a.memory[65317] = c;
a.rightChannel1 = (c & 1) == 1;
a.rightChannel2 = (c & 2) == 2;
a.rightChannel3 = (c & 4) == 4;
a.rightChannel4 = (c & 8) == 8;
a.leftChannel1 = (c & 16) == 16;
a.leftChannel2 = (c & 32) == 32;
a.leftChannel3 = (c & 64) == 64;
a.leftChannel4 = c > 127;
a.channel1OutputLevelCache();
a.channel2OutputLevelCache();
a.channel3OutputLevelCache();
a.channel4OutputLevelCache()
}
};
this.memoryHighWriter[38] = this.memoryWriter[65318] = function (a, b, c) {
a.audioJIT();
if (!a.soundMasterEnabled && c > 127) {
a.memory[65318] = 128;
a.soundMasterEnabled = true;
a.initializeAudioStartState()
} else if (a.soundMasterEnabled && c < 128) {
a.memory[65318] = 0;
a.soundMasterEnabled = false;
for (b = 65296; b < 65318; b++) a.memoryWriter[b](a, b, 0)
}
};
this.memoryHighWriter[39] = this.memoryWriter[65319] = this.cartIgnoreWrite;
this.memoryHighWriter[40] = this.memoryWriter[65320] = this.cartIgnoreWrite;
this.memoryHighWriter[41] = this.memoryWriter[65321] = this.cartIgnoreWrite;
this.memoryHighWriter[42] = this.memoryWriter[65322] = this.cartIgnoreWrite;
this.memoryHighWriter[43] = this.memoryWriter[65323] = this.cartIgnoreWrite;
this.memoryHighWriter[44] = this.memoryWriter[65324] = this.cartIgnoreWrite;
this.memoryHighWriter[45] = this.memoryWriter[65325] = this.cartIgnoreWrite;
this.memoryHighWriter[46] = this.memoryWriter[65326] = this.cartIgnoreWrite;
this.memoryHighWriter[47] = this.memoryWriter[65327] = this.cartIgnoreWrite;
this.memoryHighWriter[48] = this.memoryWriter[65328] = function (a, b, c) {
a.channel3WriteRAM(0, c)
};
this.memoryHighWriter[49] = this.memoryWriter[65329] = function (a, b, c) {
a.channel3WriteRAM(1, c)
};
this.memoryHighWriter[50] = this.memoryWriter[65330] = function (a, b, c) {
a.channel3WriteRAM(2, c)
};
this.memoryHighWriter[51] = this.memoryWriter[65331] = function (a, b, c) {
a.channel3WriteRAM(3, c)
};
this.memoryHighWriter[52] = this.memoryWriter[65332] = function (a, b, c) {
a.channel3WriteRAM(4, c)
};
this.memoryHighWriter[53] = this.memoryWriter[65333] = function (a, b, c) {
a.channel3WriteRAM(5, c)
};
this.memoryHighWriter[54] = this.memoryWriter[65334] = function (a, b, c) {
a.channel3WriteRAM(6, c)
};
this.memoryHighWriter[55] = this.memoryWriter[65335] = function (a, b, c) {
a.channel3WriteRAM(7, c)
};
this.memoryHighWriter[56] = this.memoryWriter[65336] = function (a, b, c) {
a.channel3WriteRAM(8, c)
};
this.memoryHighWriter[57] = this.memoryWriter[65337] = function (a, b, c) {
a.channel3WriteRAM(9, c)
};
this.memoryHighWriter[58] = this.memoryWriter[65338] = function (a, b, c) {
a.channel3WriteRAM(10, c)
};
this.memoryHighWriter[59] = this.memoryWriter[65339] = function (a, b, c) {
a.channel3WriteRAM(11, c)
};
this.memoryHighWriter[60] = this.memoryWriter[65340] = function (a, b, c) {
a.channel3WriteRAM(12, c)
};
this.memoryHighWriter[61] = this.memoryWriter[65341] = function (a, b, c) {
a.channel3WriteRAM(13, c)
};
this.memoryHighWriter[62] = this.memoryWriter[65342] = function (a, b, c) {
a.channel3WriteRAM(14, c)
};
this.memoryHighWriter[63] = this.memoryWriter[65343] = function (a, b, c) {
a.channel3WriteRAM(15, c)
};
this.memoryHighWriter[66] = this.memoryWriter[65346] = function (a, b, c) {
if (a.backgroundY != c) {
a.midScanLineJIT();
a.backgroundY = c
}
};
this.memoryHighWriter[67] = this.memoryWriter[65347] = function (a, b, c) {
if (a.backgroundX != c) {
a.midScanLineJIT();
a.backgroundX = c
}
};
this.memoryHighWriter[68] = this.memoryWriter[65348] = function (a) {
if (a.LCDisOn) {
a.modeSTAT = 2;
a.midScanlineOffset = -1;
a.totalLinesPassed = a.currentX = a.queuedScanLines = a.lastUnrenderedLine = a.LCDTicks = a.STATTracker = a.actualScanLine = a.memory[65348] = 0
}
};
this.memoryHighWriter[69] = this.memoryWriter[65349] = function (a, b, c) {
if (a.memory[65349] != c) {
a.memory[65349] = c;
a.LCDisOn && a.matchLYC()
}
};
this.memoryHighWriter[74] = this.memoryWriter[65354] = function (a, b, c) {
if (a.windowY != c) {
a.midScanLineJIT();
a.windowY = c
}
};
this.memoryHighWriter[75] = this.memoryWriter[65355] = function (a, b, c) {
if (a.memory[65355] != c) {
a.midScanLineJIT();
a.memory[65355] = c;
a.windowX = c - 7
}
};
this.memoryHighWriter[114] = this.memoryWriter[65394] = function (a, b, c) {
a.memory[65394] = c
};
this.memoryHighWriter[115] = this.memoryWriter[65395] = function (a, b, c) {
a.memory[65395] = c
};
this.memoryHighWriter[117] = this.memoryWriter[65397] = function (a, b, c) {
a.memory[65397] = c
};
this.memoryHighWriter[118] = this.memoryWriter[65398] = this.cartIgnoreWrite;
this.memoryHighWriter[119] = this.memoryWriter[65399] = this.cartIgnoreWrite;
this.memoryHighWriter[255] = this.memoryWriter[65535] = function (a, b, c) {
a.interruptsEnabled = c;
a.checkIRQMatching()
};
this.recompileModelSpecificIOWriteHandling();
this.recompileBootIOWriteHandling()
};
GameBoyCore.prototype.recompileModelSpecificIOWriteHandling = function () {
if (this.cGBC) {
this.memoryHighWriter[2] = this.memoryWriter[65282] = function (a, b, c) {
if ((c & 1) == 1) {
a.memory[65282] = c & 127;
a.serialTimer = (c & 2) == 0 ? 4096 : 128;
a.serialShiftTimer = a.serialShiftTimerAllocated = (c & 2) == 0 ? 512 : 16
} else {
a.memory[65282] = c;
a.serialShiftTimer = a.serialShiftTimerAllocated = a.serialTimer = 0
}
};
this.memoryHighWriter[64] = this.memoryWriter[65344] = function (a, b, c) {
if (a.memory[65344] != c) {
a.midScanLineJIT();
b = c > 127;
if (b != a.LCDisOn) {
a.LCDisOn = b;
a.memory[65345] = a.memory[65345] & 120;
a.midScanlineOffset = -1;
a.totalLinesPassed = a.currentX = a.queuedScanLines = a.lastUnrenderedLine = a.STATTracker = a.LCDTicks = a.actualScanLine = a.memory[65348] = 0;
if (a.LCDisOn) {
a.modeSTAT = 2;
a.matchLYC();
a.LCDCONTROL = a.LINECONTROL
} else {
a.modeSTAT = 0;
a.LCDCONTROL = a.DISPLAYOFFCONTROL;
a.DisplayShowOff()
}
a.interruptsRequested = a.interruptsRequested & 253
}
a.gfxWindowCHRBankPosition = (c & 64) == 64 ? 1024 : 0;
a.gfxWindowDisplay = (c & 32) == 32;
a.gfxBackgroundBankOffset = (c & 16) == 16 ? 0 : 128;
a.gfxBackgroundCHRBankPosition = (c & 8) == 8 ? 1024 : 0;
a.gfxSpriteNormalHeight = (c & 4) == 0;
a.gfxSpriteShow = (c & 2) == 2;
a.BGPriorityEnabled = (c & 1) == 1;
a.priorityFlaggingPathRebuild();
a.memory[65344] = c
}
};
this.memoryHighWriter[65] = this.memoryWriter[65345] = function (a, b, c) {
a.LYCMatchTriggerSTAT = (c & 64) == 64;
a.mode2TriggerSTAT = (c & 32) == 32;
a.mode1TriggerSTAT = (c & 16) == 16;
a.mode0TriggerSTAT = (c & 8) == 8;
a.memory[65345] = c & 120
};
this.memoryHighWriter[70] = this.memoryWriter[65350] = function (a, b, c) {
a.memory[65350] = c;
if (c < 224) {
var c = c << 8,
b = 65024,
e = a.modeSTAT,
f = a.modeSTAT = 0;
do {
f = a.memoryReader[c](a, c++);
if (f != a.memory[b]) {
a.modeSTAT = e;
a.graphicsJIT();
a.modeSTAT = 0;
a.memory[b++] = f;
break
}
} while (++b < 65184);
if (b < 65184) {
do {
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++)
} while (b < 65184)
}
a.modeSTAT = e
}
};
this.memoryHighWriter[77] = this.memoryWriter[65357] = function (a, b, c) {
a.memory[65357] = c & 127 | a.memory[65357] & 128
};
this.memoryHighWriter[79] = this.memoryWriter[65359] = function (a, b, c) {
a.currVRAMBank = c & 1;
a.BGCHRCurrentBank = a.currVRAMBank > 0 ? a.BGCHRBank2 : a.BGCHRBank1
};
this.memoryHighWriter[81] = this.memoryWriter[65361] = function (a, b, c) {
a.hdmaRunning || (a.memory[65361] = c)
};
this.memoryHighWriter[82] = this.memoryWriter[65362] = function (a, b, c) {
a.hdmaRunning || (a.memory[65362] = c & 240)
};
this.memoryHighWriter[83] = this.memoryWriter[65363] = function (a, b, c) {
a.hdmaRunning || (a.memory[65363] = c & 31)
};
this.memoryHighWriter[84] = this.memoryWriter[65364] = function (a, b, c) {
a.hdmaRunning || (a.memory[65364] = c & 240)
};
this.memoryHighWriter[85] = this.memoryWriter[65365] = function (a, b, c) {
if (a.hdmaRunning) if ((c & 128) == 0) {
a.hdmaRunning = false;
a.memory[65365] = a.memory[65365] | 128
} else a.memory[65365] = c & 127;
else if ((c & 128) == 0) {
a.DMAWrite((c & 127) + 1);
a.memory[65365] = 255
} else {
a.hdmaRunning = true;
a.memory[65365] = c & 127
}
};
this.memoryHighWriter[104] = this.memoryWriter[65384] = function (a, b, c) {
a.memory[65385] = a.gbcBGRawPalette[c & 63];
a.memory[65384] = c
};
this.memoryHighWriter[105] = this.memoryWriter[65385] = function (a, b, c) {
a.updateGBCBGPalette(a.memory[65384] & 63, c);
if (a.memory[65384] > 127) {
b = a.memory[65384] + 1 & 63;
a.memory[65384] = b | 128;
a.memory[65385] = a.gbcBGRawPalette[b]
} else a.memory[65385] = c
};
this.memoryHighWriter[106] = this.memoryWriter[65386] = function (a, b, c) {
a.memory[65387] = a.gbcOBJRawPalette[c & 63];
a.memory[65386] = c
};
this.memoryHighWriter[107] = this.memoryWriter[65387] = function (a, b, c) {
a.updateGBCOBJPalette(a.memory[65386] & 63, c);
if (a.memory[65386] > 127) {
b = a.memory[65386] + 1 & 63;
a.memory[65386] = b | 128;
a.memory[65387] = a.gbcOBJRawPalette[b]
} else a.memory[65387] = c
};
this.memoryHighWriter[112] = this.memoryWriter[65392] = function (a, b, c) {
b = a.memory[65361] << 8 | a.memory[65362];
if (!a.hdmaRunning || b < 53248 || b >= 57344) {
a.gbcRamBank = Math.max(c & 7, 1);
a.gbcRamBankPosition = (a.gbcRamBank - 1 << 12) - 53248;
a.gbcRamBankPositionECHO = a.gbcRamBankPosition - 8192
}
a.memory[65392] = c
};
this.memoryHighWriter[116] = this.memoryWriter[65396] = function (a, b, c) {
a.memory[65396] = c
}
} else {
this.memoryHighWriter[2] = this.memoryWriter[65282] = function (a, b, c) {
if ((c & 1) == 1) {
a.memory[65282] = c & 127;
a.serialTimer = 4096;
a.serialShiftTimer = a.serialShiftTimerAllocated = 512
} else {
a.memory[65282] = c;
a.serialShiftTimer = a.serialShiftTimerAllocated = a.serialTimer = 0
}
};
this.memoryHighWriter[64] = this.memoryWriter[65344] = function (a, b, c) {
if (a.memory[65344] != c) {
a.midScanLineJIT();
b = c > 127;
if (b != a.LCDisOn) {
a.LCDisOn = b;
a.memory[65345] = a.memory[65345] & 120;
a.midScanlineOffset = -1;
a.totalLinesPassed = a.currentX = a.queuedScanLines = a.lastUnrenderedLine = a.STATTracker = a.LCDTicks = a.actualScanLine = a.memory[65348] = 0;
if (a.LCDisOn) {
a.modeSTAT = 2;
a.matchLYC();
a.LCDCONTROL = a.LINECONTROL
} else {
a.modeSTAT = 0;
a.LCDCONTROL = a.DISPLAYOFFCONTROL;
a.DisplayShowOff()
}
a.interruptsRequested = a.interruptsRequested & 253
}
a.gfxWindowCHRBankPosition = (c & 64) == 64 ? 1024 : 0;
a.gfxWindowDisplay = (c & 32) == 32;
a.gfxBackgroundBankOffset = (c & 16) == 16 ? 0 : 128;
a.gfxBackgroundCHRBankPosition = (c & 8) == 8 ? 1024 : 0;
a.gfxSpriteNormalHeight = (c & 4) == 0;
a.gfxSpriteShow = (c & 2) == 2;
a.bgEnabled = (c & 1) == 1;
a.memory[65344] = c
}
};
this.memoryHighWriter[65] = this.memoryWriter[65345] = function (a, b, c) {
a.LYCMatchTriggerSTAT = (c & 64) == 64;
a.mode2TriggerSTAT = (c & 32) == 32;
a.mode1TriggerSTAT = (c & 16) == 16;
a.mode0TriggerSTAT = (c & 8) == 8;
a.memory[65345] = c & 120;
if ((!a.usedBootROM || !a.usedGBCBootROM) && a.LCDisOn && a.modeSTAT < 2) {
a.interruptsRequested = a.interruptsRequested | 2;
a.checkIRQMatching()
}
};
this.memoryHighWriter[70] = this.memoryWriter[65350] = function (a, b, c) {
a.memory[65350] = c;
if (c > 127 && c < 224) {
var c = c << 8,
b = 65024,
e = a.modeSTAT,
f = a.modeSTAT = 0;
do {
f = a.memoryReader[c](a, c++);
if (f != a.memory[b]) {
a.modeSTAT = e;
a.graphicsJIT();
a.modeSTAT = 0;
a.memory[b++] = f;
break
}
} while (++b < 65184);
if (b < 65184) {
do {
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++);
a.memory[b++] = a.memoryReader[c](a, c++)
} while (b < 65184)
}
a.modeSTAT = e
}
};
this.memoryHighWriter[71] = this.memoryWriter[65351] = function (a, b, c) {
if (a.memory[65351] != c) {
a.midScanLineJIT();
a.updateGBBGPalette(c);
a.memory[65351] = c
}
};
this.memoryHighWriter[72] = this.memoryWriter[65352] = function (a, b, c) {
if (a.memory[65352] != c) {
a.midScanLineJIT();
a.updateGBOBJPalette(0, c);
a.memory[65352] = c
}
};
this.memoryHighWriter[73] = this.memoryWriter[65353] = function (a, b, c) {
if (a.memory[65353] != c) {
a.midScanLineJIT();
a.updateGBOBJPalette(4, c);
a.memory[65353] = c
}
};
this.memoryHighWriter[77] = this.memoryWriter[65357] = function (a, b, c) {
a.memory[65357] = c
};
this.memoryHighWriter[79] = this.memoryWriter[65359] = this.cartIgnoreWrite;
this.memoryHighWriter[85] = this.memoryWriter[65365] = this.cartIgnoreWrite;
this.memoryHighWriter[104] = this.memoryWriter[65384] = this.cartIgnoreWrite;
this.memoryHighWriter[105] = this.memoryWriter[65385] = this.cartIgnoreWrite;
this.memoryHighWriter[106] = this.memoryWriter[65386] = this.cartIgnoreWrite;
this.memoryHighWriter[107] = this.memoryWriter[65387] = this.cartIgnoreWrite;
this.memoryHighWriter[108] = this.memoryWriter[65388] = this.cartIgnoreWrite;
this.memoryHighWriter[112] = this.memoryWriter[65392] = this.cartIgnoreWrite;
this.memoryHighWriter[116] = this.memoryWriter[65396] = this.cartIgnoreWrite
}
};
GameBoyCore.prototype.recompileBootIOWriteHandling = function () {
if (this.inBootstrap) {
this.memoryHighWriter[80] = this.memoryWriter[65360] = function (a, b, c) {
cout("Boot ROM reads blocked: Bootstrap process has ended.", 0);
a.inBootstrap = false;
a.disableBootROM();
a.memory[65360] = c
};
this.cGBC && (this.memoryHighWriter[108] = this.memoryWriter[65388] = function (a, b, c) {
if (a.inBootstrap) {
a.cGBC = (c & 1) == 0;
if (a.name + a.gameCode + a.ROM[323] == "Game and Watch 50") {
a.cGBC = true;
cout("Created a boot exception for Game and Watch Gallery 2 (GBC ID byte is wrong on the cartridge).", 1)
}
cout("Booted to GBC Mode: " + a.cGBC, 0)
}
a.memory[65388] = c
})
} else this.memoryHighWriter[80] = this.memoryWriter[65360] = this.cartIgnoreWrite
};
GameBoyCore.prototype.toTypedArray = function (a, b) {
try {
if (settings[5] || b != "float32" && window.opera && this.checkForOperaMathBug()) return a;
if (!a || !a.length) return [];
var c = a.length;
switch (b) {
case "uint8":
var e = new Uint8Array(c);
break;
case "int8":
e = new Int8Array(c);
break;
case "int32":
e = new Int32Array(c);
break;
case "float32":
e = new Float32Array(c)
}
for (var f = 0; f < c; f++) e[f] = a[f];
return e
} catch (g) {
cout("Could not convert an array to a typed array: " + g.message, 1);
return a
}
};
GameBoyCore.prototype.fromTypedArray = function (a) {
try {
if (!a || !a.length) return [];
for (var b = [], c = 0; c < a.length; ++c) b[c] = a[c];
return b
} catch (e) {
cout("Conversion from a typed array failed: " + e.message, 1);
return a
}
};
GameBoyCore.prototype.getTypedArray = function (a, b, c) {
try {
if (settings[5]) throw Error("");
if (c != "float32" && window.opera && this.checkForOperaMathBug()) throw Error("");
switch (c) {
case "int8":
var e = new Int8Array(a);
break;
case "uint8":
e = new Uint8Array(a);
break;
case "int32":
e = new Int32Array(a);
break;
case "float32":
e = new Float32Array(a)
}
if (b != 0) for (c = 0; c < a;) e[c++] = b
} catch (f) {
cout("Could not convert an array to a typed array: " + f.message, 1);
e = [];
for (c = 0; c < a;) e[c++] = b
}
return e
};
GameBoyCore.prototype.checkForOperaMathBug = function () {
var a = new Uint8Array(1);
a[0] = -1;
a[0] = a[0] >> 0;
if (a[0] != 255) {
cout("Detected faulty math by your browser.", 2);
return true
}
return false
};
var gameboy = null,
gbRunInterval = null,
settings = [!0, !0, !1, [39, 37, 38, 40, 88, 90, 16, 13], !0, !1, 4, 15, 30, !1, !1, !1, !1, 1];
function start(a, b) {
clearLastEmulation();
autoSave();
gameboy = new GameBoyCore(a, b);
gameboy.openMBC = openSRAM;
gameboy.openRTC = openRTC;
gameboy.start();
run()
}
function run() {
if (GameBoyEmulatorInitialized()) if (GameBoyEmulatorPlaying()) cout("The GameBoy core is already running.", 1);
else {
gameboy.stopEmulator = gameboy.stopEmulator & 1;
cout("Starting the iterator.", 0);
gameboy.firstIteration = (new Date).getTime();
gameboy.iterations = 0;
gbRunInterval = setInterval(function () {
!document.hidden && (!document.msHidden && !document.mozHidden && !document.webkitHidden) && gameboy.run()
}, settings[6])
} else cout("GameBoy core cannot run while it has not been initialized.", 1)
}
function pause() {
GameBoyEmulatorInitialized() ? GameBoyEmulatorPlaying() ? clearLastEmulation() : cout("GameBoy core has already been paused.", 1) : cout("GameBoy core cannot be paused while it has not been initialized.", 1)
}
function clearLastEmulation() {
if (GameBoyEmulatorInitialized() && GameBoyEmulatorPlaying()) {
clearInterval(gbRunInterval);
gameboy.stopEmulator = gameboy.stopEmulator | 2;
cout("The previous emulation has been cleared.", 0)
} else cout("No previous emulation was found to be cleared.", 0)
}
function save() {
if (GameBoyEmulatorInitialized()) try {
for (var a = 0; findValue("FREEZE_" + gameboy.name + "_" + a) != null;) a++;
setValue("FREEZE_" + gameboy.name + "_" + a, gameboy.saveState());
cout("Saved the current state as: FREEZE_" + gameboy.name + "_" + a, 0)
} catch (b) {
cout('Could not save the current emulation state("' + b.message + '").', 2)
} else cout("GameBoy core cannot be saved while it has not been initialized.", 1)
}
function saveSRAM() {
if (GameBoyEmulatorInitialized()) {
if (gameboy.cBATT) try {
var a = gameboy.saveSRAMState();
if (a.length > 0) {
cout("Saving the SRAM...", 0);
if (findValue("SRAM_" + gameboy.name) != null) {
cout("Deleting the old SRAM save due to outdated format.", 0);
deleteValue("SRAM_" + gameboy.name)
}
setValue("B64_SRAM_" + gameboy.name, arrayToBase64(a))
} else cout("SRAM could not be saved because it was empty.", 1)
} catch (b) {
cout('Could not save the current emulation state("' + b.message + '").', 2)
} else cout("Cannot save a game that does not have battery backed SRAM specified.", 1);
saveRTC()
} else cout("GameBoy core cannot be saved while it has not been initialized.", 1)
}
function saveRTC() {
if (GameBoyEmulatorInitialized()) {
if (gameboy.cTIMER) try {
cout("Saving the RTC...", 0);
setValue("RTC_" + gameboy.name, gameboy.saveRTCState())
} catch (a) {
cout('Could not save the RTC of the current emulation state("' + a.message + '").', 2)
}
} else cout("GameBoy core cannot be saved while it has not been initialized.", 1)
}
function autoSave() {
if (GameBoyEmulatorInitialized()) {
cout("Automatically saving the SRAM.", 0);
saveSRAM();
saveRTC()
}
}
function openSRAM(a) {
try {
if (findValue("B64_SRAM_" + a) != null) {
cout("Found a previous SRAM state (Will attempt to load).", 0);
return base64ToArray(findValue("B64_SRAM_" + a))
}
if (findValue("SRAM_" + a) != null) {
cout("Found a previous SRAM state (Will attempt to load).", 0);
return findValue("SRAM_" + a)
}
cout("Could not find any previous SRAM copy for the current ROM.", 0)
} catch (b) {
cout("Could not open the SRAM of the saved emulation state.", 2)
}
return []
}
function openRTC(a) {
try {
if (findValue("RTC_" + a) != null) {
cout("Found a previous RTC state (Will attempt to load).", 0);
return findValue("RTC_" + a)
}
cout("Could not find any previous RTC copy for the current ROM.", 0)
} catch (b) {
cout("Could not open the RTC data of the saved emulation state.", 2)
}
return []
}
function openState(a, b) {
try {
if (findValue(a) != null) try {
clearLastEmulation();
cout("Attempting to run a saved emulation state.", 0);
gameboy = new GameBoyCore(b, "");
gameboy.savedStateFileName = a;
gameboy.returnFromState(findValue(a));
run()
} catch (c) {
alert(c.message + " file: " + c.fileName + " line: " + c.lineNumber)
} else cout("Could not find the save state " + a + '".', 2)
} catch (e) {
cout("Could not open the saved emulation state.", 2)
}
}
function import_save(a) {
if ((a = decodeBlob(a)) && a.blobs) if (a.blobs.length > 0) for (var b = 0; b < a.blobs.length; ++b) {
cout('Importing blob "' + a.blobs[b].blobID + '"', 0);
a.blobs[b].blobContent ? a.blobs[b].blobID.substring(0, 5) == "SRAM_" ? setValue("B64_" + a.blobs[b].blobID, base64(a.blobs[b].blobContent)) : setValue(a.blobs[b].blobID, JSON.parse(a.blobs[b].blobContent)) : a.blobs[b].blobID ? cout('Save file imported had blob "' + a.blobs[b].blobID + '" with no blob data interpretable.', 2) : cout("Blob chunk information missing completely.", 2)
} else cout("Could not decode the imported file.", 2);
else cout("Could not decode the imported file.", 2)
}
function generateBlob(a, b) {
var c = "EMULATOR_DATA",
c = c + to_little_endian_dword(c.length + 4 + 8 + (1 + a.length + (4 + b.length))),
c = c + to_byte(7),
c = c + "GameBoy" + to_byte(a.length),
c = c + a + to_little_endian_dword(b.length);
return c + b
}
function generateMultiBlob(a) {
for (var b = 25, c = to_byte(7), c = c + "GameBoy", e = "", f = "", g = 0; g < a.length; ++g) {
e = a[g][0];
f = a[g][1];
c = c + to_byte(e.length);
c = c + e;
c = c + to_little_endian_dword(f.length);
c = c + f;
b = b + (1 + e.length + 4 + f.length)
}
return c = "EMULATOR_DATA" + to_little_endian_dword(b) + c
}
function decodeBlob(a) {
var b = a.length,
c = {
consoleID: null
},
e = -1;
c.blobs = [];
if (b > 17 && a.substring(0, 13) == "EMULATOR_DATA") {
var b = Math.min((a.charCodeAt(16) & 255) << 24 | (a.charCodeAt(15) & 255) << 16 | (a.charCodeAt(14) & 255) << 8 | a.charCodeAt(13) & 255, b),
f = a.charCodeAt(17) & 255;
if (b > 17 + f) {
c.consoleID = a.substring(18, 18 + f);
for (var g = 0, g = 0, f = 18 + f; f < b;) {
g = a.charCodeAt(f++) & 255;
if (f + g < b) {
c.blobs[++e] = {};
c.blobs[e].blobID = a.substring(f, f + g);
f = f + g;
if (f + 4 < b) {
g = (a.charCodeAt(f + 3) & 255) << 24 | (a.charCodeAt(f + 2) & 255) << 16 | (a.charCodeAt(f + 1) & 255) << 8 | a.charCodeAt(f) & 255;
f = f + 4;
if (f + g <= b) {
c.blobs[e].blobContent = a.substring(f, f + g);
f = f + g
} else {
cout("Blob length check failed, blob determined to be incomplete.", 2);
break
}
} else {
cout("Blob was incomplete, bailing out.", 2);
break
}
} else {
cout("Blob was incomplete, bailing out.", 2);
break
}
}
}
}
return c
}
function matchKey(a) {
for (var b = 0; b < settings[3].length; b++) if (settings[3][b] == a) return b;
return -1
}
function GameBoyEmulatorInitialized() {
return typeof gameboy == "object" && gameboy != null
}
function GameBoyEmulatorPlaying() {
return (gameboy.stopEmulator & 2) == 0
}
function GameBoyKeyDown(a) {
if (GameBoyEmulatorInitialized() && GameBoyEmulatorPlaying()) {
var b = matchKey(a.keyCode);
if (b >= 0 && b < 8) {
gameboy.JoyPadEvent(b, true);
try {
a.preventDefault()
} catch (c) {}
}
}
}
function GameBoyKeyUp(a) {
if (GameBoyEmulatorInitialized() && GameBoyEmulatorPlaying()) {
var b = matchKey(a.keyCode);
if (b >= 0 && b < 8) {
gameboy.JoyPadEvent(b, false);
try {
a.preventDefault()
} catch (c) {}
}
}
}
function GameBoyGyroSignalHandler(a) {
if (GameBoyEmulatorInitialized() && GameBoyEmulatorPlaying()) {
a.gamma || a.beta ? gameboy.GyroEvent(a.gamma * Math.PI / 180, a.beta * Math.PI / 180) : gameboy.GyroEvent(a.x, a.y);
try {
a.preventDefault()
} catch (b) {}
}
}
function initNewCanvas() {
if (GameBoyEmulatorInitialized()) {
gameboy.canvas.width = gameboy.canvas.clientWidth;
gameboy.canvas.height = gameboy.canvas.clientHeight
}
}
function initNewCanvasSize() {
GameBoyEmulatorInitialized() && (settings[12] ? (gameboy.onscreenWidth != gameboy.canvas.clientWidth || gameboy.onscreenHeight != gameboy.canvas.clientHeight) && gameboy.initLCD() : (gameboy.onscreenWidth != 160 || gameboy.onscreenHeight != 144) && gameboy.initLCD())
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment