8bitworkshop/gen/nes-Z65S55Q4.js.map

8 lines
320 KiB
Plaintext

{
"version": 3,
"sources": ["../jsnes/src/controller.js", "../jsnes/src/utils.js", "../jsnes/src/cpu.js", "../jsnes/src/tile.js", "../jsnes/src/ppu.js", "../jsnes/src/papu.js", "../jsnes/src/mappers.js", "../jsnes/src/rom.js", "../jsnes/src/nes.js", "../jsnes/src/index.js", "../src/platform/nes.ts"],
"sourcesContent": ["var Controller = function() {\n this.state = new Array(8);\n for (var i = 0; i < this.state.length; i++) {\n this.state[i] = 0x40;\n }\n};\n\nController.BUTTON_A = 0;\nController.BUTTON_B = 1;\nController.BUTTON_SELECT = 2;\nController.BUTTON_START = 3;\nController.BUTTON_UP = 4;\nController.BUTTON_DOWN = 5;\nController.BUTTON_LEFT = 6;\nController.BUTTON_RIGHT = 7;\n\nController.prototype = {\n buttonDown: function(key) {\n this.state[key] = 0x41;\n },\n\n buttonUp: function(key) {\n this.state[key] = 0x40;\n }\n};\n\nmodule.exports = Controller;\n", "module.exports = {\n copyArrayElements: function(src, srcPos, dest, destPos, length) {\n for (var i = 0; i < length; ++i) {\n dest[destPos + i] = src[srcPos + i];\n }\n },\n\n copyArray: function(src) {\n return src.slice(0);\n },\n\n fromJSON: function(obj, state) {\n for (var i = 0; i < obj.JSON_PROPERTIES.length; i++) {\n var key = obj.JSON_PROPERTIES[i];\n if (obj[key] !== null && obj[key].buffer && obj[key].set)\n obj[key].set(state[key]); // set array elements\n else\n obj[key] = state[key]; // replace\n }\n },\n\n toJSON: function(obj) {\n var state = {};\n for (var i = 0; i < obj.JSON_PROPERTIES.length; i++) {\n var key = obj.JSON_PROPERTIES[i];\n state[key] = obj[key];\n }\n return state;\n }\n};\n", "var utils = require(\"./utils\");\n\nvar CPU = function(nes) {\n this.nes = nes;\n\n // Keep Chrome happy\n this.mem = null;\n this.REG_ACC = null;\n this.REG_X = null;\n this.REG_Y = null;\n this.REG_SP = null;\n this.REG_PC = null;\n this.REG_PC_NEW = null;\n this.REG_STATUS = null;\n this.F_CARRY = null;\n this.F_DECIMAL = null;\n this.F_INTERRUPT = null;\n this.F_INTERRUPT_NEW = null;\n this.F_OVERFLOW = null;\n this.F_SIGN = null;\n this.F_ZERO = null;\n this.F_NOTUSED = null;\n this.F_NOTUSED_NEW = null;\n this.F_BRK = null;\n this.F_BRK_NEW = null;\n this.opdata = null;\n this.cyclesToHalt = null;\n this.crash = null;\n this.irqRequested = null;\n this.irqType = null;\n\n this.reset();\n};\n\nCPU.prototype = {\n // IRQ Types\n IRQ_NORMAL: 0,\n IRQ_NMI: 1,\n IRQ_RESET: 2,\n\n reset: function() {\n // Main memory\n this.mem = new Uint8Array(0x10000);\n\n for (var i = 0; i < 0x2000; i++) {\n this.mem[i] = 0xff;\n }\n for (var p = 0; p < 4; p++) {\n var j = p * 0x800;\n this.mem[j + 0x008] = 0xf7;\n this.mem[j + 0x009] = 0xef;\n this.mem[j + 0x00a] = 0xdf;\n this.mem[j + 0x00f] = 0xbf;\n }\n for (var k = 0x2001; k < this.mem.length; k++) {\n this.mem[k] = 0;\n }\n\n // CPU Registers:\n this.REG_ACC = 0;\n this.REG_X = 0;\n this.REG_Y = 0;\n // Reset Stack pointer:\n this.REG_SP = 0x01ff;\n // Reset Program counter:\n this.REG_PC = 0x8000 - 1;\n this.REG_PC_NEW = 0x8000 - 1;\n // Reset Status register:\n this.REG_STATUS = 0x28;\n\n this.setStatus(0x28);\n\n // Set flags:\n this.F_CARRY = 0;\n this.F_DECIMAL = 0;\n this.F_INTERRUPT = 1;\n this.F_INTERRUPT_NEW = 1;\n this.F_OVERFLOW = 0;\n this.F_SIGN = 0;\n this.F_ZERO = 1;\n\n this.F_NOTUSED = 1;\n this.F_NOTUSED_NEW = 1;\n this.F_BRK = 1;\n this.F_BRK_NEW = 1;\n\n this.opdata = new OpData().opdata;\n this.cyclesToHalt = 0;\n\n // Reset crash flag:\n this.crash = false;\n\n // Interrupt notification:\n this.irqRequested = false;\n this.irqType = null;\n },\n\n // Emulates a single CPU instruction, returns the number of cycles\n emulate: function() {\n var temp;\n var add;\n\n // Check interrupts:\n if (this.irqRequested) {\n temp =\n this.F_CARRY |\n ((this.F_ZERO === 0 ? 1 : 0) << 1) |\n (this.F_INTERRUPT << 2) |\n (this.F_DECIMAL << 3) |\n (this.F_BRK << 4) |\n (this.F_NOTUSED << 5) |\n (this.F_OVERFLOW << 6) |\n (this.F_SIGN << 7);\n\n this.REG_PC_NEW = this.REG_PC;\n this.F_INTERRUPT_NEW = this.F_INTERRUPT;\n switch (this.irqType) {\n case 0: {\n // Normal IRQ:\n if (this.F_INTERRUPT !== 0) {\n // console.log(\"Interrupt was masked.\");\n break;\n }\n this.doIrq(temp);\n // console.log(\"Did normal IRQ. I=\"+this.F_INTERRUPT);\n break;\n }\n case 1: {\n // NMI:\n this.doNonMaskableInterrupt(temp);\n break;\n }\n case 2: {\n // Reset:\n this.doResetInterrupt();\n break;\n }\n }\n\n this.REG_PC = this.REG_PC_NEW;\n this.F_INTERRUPT = this.F_INTERRUPT_NEW;\n this.F_BRK = this.F_BRK_NEW;\n this.irqRequested = false;\n }\n\n var opinf = this.opdata[this.nes.mmap.load(this.REG_PC + 1)];\n var cycleCount = opinf >> 24;\n var cycleAdd = 0;\n\n // Find address mode:\n var addrMode = (opinf >> 8) & 0xff;\n\n // Increment PC by number of op bytes:\n var opaddr = this.REG_PC;\n this.REG_PC += (opinf >> 16) & 0xff;\n\n var addr = 0;\n switch (addrMode) {\n case 0: {\n // Zero Page mode. Use the address given after the opcode,\n // but without high byte.\n addr = this.load(opaddr + 2);\n break;\n }\n case 1: {\n // Relative mode.\n addr = this.load(opaddr + 2);\n if (addr < 0x80) {\n addr += this.REG_PC;\n } else {\n addr += this.REG_PC - 256;\n }\n break;\n }\n case 2: {\n // Ignore. Address is implied in instruction.\n break;\n }\n case 3: {\n // Absolute mode. Use the two bytes following the opcode as\n // an address.\n addr = this.load16bit(opaddr + 2);\n break;\n }\n case 4: {\n // Accumulator mode. The address is in the accumulator\n // register.\n addr = this.REG_ACC;\n break;\n }\n case 5: {\n // Immediate mode. The value is given after the opcode.\n addr = this.REG_PC;\n break;\n }\n case 6: {\n // Zero Page Indexed mode, X as index. Use the address given\n // after the opcode, then add the\n // X register to it to get the final address.\n addr = (this.load(opaddr + 2) + this.REG_X) & 0xff;\n break;\n }\n case 7: {\n // Zero Page Indexed mode, Y as index. Use the address given\n // after the opcode, then add the\n // Y register to it to get the final address.\n addr = (this.load(opaddr + 2) + this.REG_Y) & 0xff;\n break;\n }\n case 8: {\n // Absolute Indexed Mode, X as index. Same as zero page\n // indexed, but with the high byte.\n addr = this.load16bit(opaddr + 2);\n if ((addr & 0xff00) !== ((addr + this.REG_X) & 0xff00)) {\n cycleAdd = 1;\n }\n addr += this.REG_X;\n break;\n }\n case 9: {\n // Absolute Indexed Mode, Y as index. Same as zero page\n // indexed, but with the high byte.\n addr = this.load16bit(opaddr + 2);\n if ((addr & 0xff00) !== ((addr + this.REG_Y) & 0xff00)) {\n cycleAdd = 1;\n }\n addr += this.REG_Y;\n break;\n }\n case 10: {\n // Pre-indexed Indirect mode. Find the 16-bit address\n // starting at the given location plus\n // the current X register. The value is the contents of that\n // address.\n addr = this.load(opaddr + 2);\n if ((addr & 0xff00) !== ((addr + this.REG_X) & 0xff00)) {\n cycleAdd = 1;\n }\n addr += this.REG_X;\n addr &= 0xff;\n addr = this.load16bit(addr);\n break;\n }\n case 11: {\n // Post-indexed Indirect mode. Find the 16-bit address\n // contained in the given location\n // (and the one following). Add to that address the contents\n // of the Y register. Fetch the value\n // stored at that adress.\n addr = this.load16bit(this.load(opaddr + 2));\n if ((addr & 0xff00) !== ((addr + this.REG_Y) & 0xff00)) {\n cycleAdd = 1;\n }\n addr += this.REG_Y;\n break;\n }\n case 12: {\n // Indirect Absolute mode. Find the 16-bit address contained\n // at the given location.\n addr = this.load16bit(opaddr + 2); // Find op\n if (addr < 0x1fff) {\n addr =\n this.mem[addr] +\n (this.mem[(addr & 0xff00) | (((addr & 0xff) + 1) & 0xff)] << 8); // Read from address given in op\n } else {\n addr =\n this.nes.mmap.load(addr) +\n (this.nes.mmap.load(\n (addr & 0xff00) | (((addr & 0xff) + 1) & 0xff)\n ) <<\n 8);\n }\n break;\n }\n }\n // Wrap around for addresses above 0xFFFF:\n addr &= 0xffff;\n\n // ----------------------------------------------------------------------------------------------------\n // Decode & execute instruction:\n // ----------------------------------------------------------------------------------------------------\n\n // This should be compiled to a jump table.\n switch (opinf & 0xff) {\n case 0: {\n // *******\n // * ADC *\n // *******\n\n // Add with carry.\n temp = this.REG_ACC + this.load(addr) + this.F_CARRY;\n\n if (\n ((this.REG_ACC ^ this.load(addr)) & 0x80) === 0 &&\n ((this.REG_ACC ^ temp) & 0x80) !== 0\n ) {\n this.F_OVERFLOW = 1;\n } else {\n this.F_OVERFLOW = 0;\n }\n this.F_CARRY = temp > 255 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n this.REG_ACC = temp & 255;\n cycleCount += cycleAdd;\n break;\n }\n case 1: {\n // *******\n // * AND *\n // *******\n\n // AND memory with accumulator.\n this.REG_ACC = this.REG_ACC & this.load(addr);\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 2: {\n // *******\n // * ASL *\n // *******\n\n // Shift left one bit\n if (addrMode === 4) {\n // ADDR_ACC = 4\n\n this.F_CARRY = (this.REG_ACC >> 7) & 1;\n this.REG_ACC = (this.REG_ACC << 1) & 255;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n } else {\n temp = this.load(addr);\n this.F_CARRY = (temp >> 7) & 1;\n temp = (temp << 1) & 255;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n this.write(addr, temp);\n }\n break;\n }\n case 3: {\n // *******\n // * BCC *\n // *******\n\n // Branch on carry clear\n if (this.F_CARRY === 0) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 4: {\n // *******\n // * BCS *\n // *******\n\n // Branch on carry set\n if (this.F_CARRY === 1) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 5: {\n // *******\n // * BEQ *\n // *******\n\n // Branch on zero\n if (this.F_ZERO === 0) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 6: {\n // *******\n // * BIT *\n // *******\n\n temp = this.load(addr);\n this.F_SIGN = (temp >> 7) & 1;\n this.F_OVERFLOW = (temp >> 6) & 1;\n temp &= this.REG_ACC;\n this.F_ZERO = temp;\n break;\n }\n case 7: {\n // *******\n // * BMI *\n // *******\n\n // Branch on negative result\n if (this.F_SIGN === 1) {\n cycleCount++;\n this.REG_PC = addr;\n }\n break;\n }\n case 8: {\n // *******\n // * BNE *\n // *******\n\n // Branch on not zero\n if (this.F_ZERO !== 0) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 9: {\n // *******\n // * BPL *\n // *******\n\n // Branch on positive result\n if (this.F_SIGN === 0) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 10: {\n // *******\n // * BRK *\n // *******\n\n this.REG_PC += 2;\n this.push((this.REG_PC >> 8) & 255);\n this.push(this.REG_PC & 255);\n this.F_BRK = 1;\n\n this.push(\n this.F_CARRY |\n ((this.F_ZERO === 0 ? 1 : 0) << 1) |\n (this.F_INTERRUPT << 2) |\n (this.F_DECIMAL << 3) |\n (this.F_BRK << 4) |\n (this.F_NOTUSED << 5) |\n (this.F_OVERFLOW << 6) |\n (this.F_SIGN << 7)\n );\n\n this.F_INTERRUPT = 1;\n //this.REG_PC = load(0xFFFE) | (load(0xFFFF) << 8);\n this.REG_PC = this.load16bit(0xfffe);\n this.REG_PC--;\n break;\n }\n case 11: {\n // *******\n // * BVC *\n // *******\n\n // Branch on overflow clear\n if (this.F_OVERFLOW === 0) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 12: {\n // *******\n // * BVS *\n // *******\n\n // Branch on overflow set\n if (this.F_OVERFLOW === 1) {\n cycleCount += (opaddr & 0xff00) !== (addr & 0xff00) ? 2 : 1;\n this.REG_PC = addr;\n }\n break;\n }\n case 13: {\n // *******\n // * CLC *\n // *******\n\n // Clear carry flag\n this.F_CARRY = 0;\n break;\n }\n case 14: {\n // *******\n // * CLD *\n // *******\n\n // Clear decimal flag\n this.F_DECIMAL = 0;\n break;\n }\n case 15: {\n // *******\n // * CLI *\n // *******\n\n // Clear interrupt flag\n this.F_INTERRUPT = 0;\n break;\n }\n case 16: {\n // *******\n // * CLV *\n // *******\n\n // Clear overflow flag\n this.F_OVERFLOW = 0;\n break;\n }\n case 17: {\n // *******\n // * CMP *\n // *******\n\n // Compare memory and accumulator:\n temp = this.REG_ACC - this.load(addr);\n this.F_CARRY = temp >= 0 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n cycleCount += cycleAdd;\n break;\n }\n case 18: {\n // *******\n // * CPX *\n // *******\n\n // Compare memory and index X:\n temp = this.REG_X - this.load(addr);\n this.F_CARRY = temp >= 0 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n break;\n }\n case 19: {\n // *******\n // * CPY *\n // *******\n\n // Compare memory and index Y:\n temp = this.REG_Y - this.load(addr);\n this.F_CARRY = temp >= 0 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n break;\n }\n case 20: {\n // *******\n // * DEC *\n // *******\n\n // Decrement memory by one:\n temp = (this.load(addr) - 1) & 0xff;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n this.write(addr, temp);\n break;\n }\n case 21: {\n // *******\n // * DEX *\n // *******\n\n // Decrement index X by one:\n this.REG_X = (this.REG_X - 1) & 0xff;\n this.F_SIGN = (this.REG_X >> 7) & 1;\n this.F_ZERO = this.REG_X;\n break;\n }\n case 22: {\n // *******\n // * DEY *\n // *******\n\n // Decrement index Y by one:\n this.REG_Y = (this.REG_Y - 1) & 0xff;\n this.F_SIGN = (this.REG_Y >> 7) & 1;\n this.F_ZERO = this.REG_Y;\n break;\n }\n case 23: {\n // *******\n // * EOR *\n // *******\n\n // XOR Memory with accumulator, store in accumulator:\n this.REG_ACC = (this.load(addr) ^ this.REG_ACC) & 0xff;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n cycleCount += cycleAdd;\n break;\n }\n case 24: {\n // *******\n // * INC *\n // *******\n\n // Increment memory by one:\n temp = (this.load(addr) + 1) & 0xff;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n this.write(addr, temp & 0xff);\n break;\n }\n case 25: {\n // *******\n // * INX *\n // *******\n\n // Increment index X by one:\n this.REG_X = (this.REG_X + 1) & 0xff;\n this.F_SIGN = (this.REG_X >> 7) & 1;\n this.F_ZERO = this.REG_X;\n break;\n }\n case 26: {\n // *******\n // * INY *\n // *******\n\n // Increment index Y by one:\n this.REG_Y++;\n this.REG_Y &= 0xff;\n this.F_SIGN = (this.REG_Y >> 7) & 1;\n this.F_ZERO = this.REG_Y;\n break;\n }\n case 27: {\n // *******\n // * JMP *\n // *******\n\n // Jump to new location:\n this.REG_PC = addr - 1;\n break;\n }\n case 28: {\n // *******\n // * JSR *\n // *******\n\n // Jump to new location, saving return address.\n // Push return address on stack:\n this.push((this.REG_PC >> 8) & 255);\n this.push(this.REG_PC & 255);\n this.REG_PC = addr - 1;\n break;\n }\n case 29: {\n // *******\n // * LDA *\n // *******\n\n // Load accumulator with memory:\n this.REG_ACC = this.load(addr);\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n cycleCount += cycleAdd;\n break;\n }\n case 30: {\n // *******\n // * LDX *\n // *******\n\n // Load index X with memory:\n this.REG_X = this.load(addr);\n this.F_SIGN = (this.REG_X >> 7) & 1;\n this.F_ZERO = this.REG_X;\n cycleCount += cycleAdd;\n break;\n }\n case 31: {\n // *******\n // * LDY *\n // *******\n\n // Load index Y with memory:\n this.REG_Y = this.load(addr);\n this.F_SIGN = (this.REG_Y >> 7) & 1;\n this.F_ZERO = this.REG_Y;\n cycleCount += cycleAdd;\n break;\n }\n case 32: {\n // *******\n // * LSR *\n // *******\n\n // Shift right one bit:\n if (addrMode === 4) {\n // ADDR_ACC\n\n temp = this.REG_ACC & 0xff;\n this.F_CARRY = temp & 1;\n temp >>= 1;\n this.REG_ACC = temp;\n } else {\n temp = this.load(addr) & 0xff;\n this.F_CARRY = temp & 1;\n temp >>= 1;\n this.write(addr, temp);\n }\n this.F_SIGN = 0;\n this.F_ZERO = temp;\n break;\n }\n case 33: {\n // *******\n // * NOP *\n // *******\n\n // No OPeration.\n // Ignore.\n break;\n }\n case 34: {\n // *******\n // * ORA *\n // *******\n\n // OR memory with accumulator, store in accumulator.\n temp = (this.load(addr) | this.REG_ACC) & 255;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n this.REG_ACC = temp;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 35: {\n // *******\n // * PHA *\n // *******\n\n // Push accumulator on stack\n this.push(this.REG_ACC);\n break;\n }\n case 36: {\n // *******\n // * PHP *\n // *******\n\n // Push processor status on stack\n this.F_BRK = 1;\n this.push(\n this.F_CARRY |\n ((this.F_ZERO === 0 ? 1 : 0) << 1) |\n (this.F_INTERRUPT << 2) |\n (this.F_DECIMAL << 3) |\n (this.F_BRK << 4) |\n (this.F_NOTUSED << 5) |\n (this.F_OVERFLOW << 6) |\n (this.F_SIGN << 7)\n );\n break;\n }\n case 37: {\n // *******\n // * PLA *\n // *******\n\n // Pull accumulator from stack\n this.REG_ACC = this.pull();\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n break;\n }\n case 38: {\n // *******\n // * PLP *\n // *******\n\n // Pull processor status from stack\n temp = this.pull();\n this.F_CARRY = temp & 1;\n this.F_ZERO = ((temp >> 1) & 1) === 1 ? 0 : 1;\n this.F_INTERRUPT = (temp >> 2) & 1;\n this.F_DECIMAL = (temp >> 3) & 1;\n this.F_BRK = (temp >> 4) & 1;\n this.F_NOTUSED = (temp >> 5) & 1;\n this.F_OVERFLOW = (temp >> 6) & 1;\n this.F_SIGN = (temp >> 7) & 1;\n\n this.F_NOTUSED = 1;\n break;\n }\n case 39: {\n // *******\n // * ROL *\n // *******\n\n // Rotate one bit left\n if (addrMode === 4) {\n // ADDR_ACC = 4\n\n temp = this.REG_ACC;\n add = this.F_CARRY;\n this.F_CARRY = (temp >> 7) & 1;\n temp = ((temp << 1) & 0xff) + add;\n this.REG_ACC = temp;\n } else {\n temp = this.load(addr);\n add = this.F_CARRY;\n this.F_CARRY = (temp >> 7) & 1;\n temp = ((temp << 1) & 0xff) + add;\n this.write(addr, temp);\n }\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n break;\n }\n case 40: {\n // *******\n // * ROR *\n // *******\n\n // Rotate one bit right\n if (addrMode === 4) {\n // ADDR_ACC = 4\n\n add = this.F_CARRY << 7;\n this.F_CARRY = this.REG_ACC & 1;\n temp = (this.REG_ACC >> 1) + add;\n this.REG_ACC = temp;\n } else {\n temp = this.load(addr);\n add = this.F_CARRY << 7;\n this.F_CARRY = temp & 1;\n temp = (temp >> 1) + add;\n this.write(addr, temp);\n }\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp;\n break;\n }\n case 41: {\n // *******\n // * RTI *\n // *******\n\n // Return from interrupt. Pull status and PC from stack.\n\n temp = this.pull();\n this.F_CARRY = temp & 1;\n this.F_ZERO = ((temp >> 1) & 1) === 0 ? 1 : 0;\n this.F_INTERRUPT = (temp >> 2) & 1;\n this.F_DECIMAL = (temp >> 3) & 1;\n this.F_BRK = (temp >> 4) & 1;\n this.F_NOTUSED = (temp >> 5) & 1;\n this.F_OVERFLOW = (temp >> 6) & 1;\n this.F_SIGN = (temp >> 7) & 1;\n\n this.REG_PC = this.pull();\n this.REG_PC += this.pull() << 8;\n if (this.REG_PC === 0xffff) {\n return;\n }\n this.REG_PC--;\n this.F_NOTUSED = 1;\n break;\n }\n case 42: {\n // *******\n // * RTS *\n // *******\n\n // Return from subroutine. Pull PC from stack.\n\n this.REG_PC = this.pull();\n this.REG_PC += this.pull() << 8;\n\n if (this.REG_PC === 0xffff) {\n return; // return from NSF play routine:\n }\n break;\n }\n case 43: {\n // *******\n // * SBC *\n // *******\n\n temp = this.REG_ACC - this.load(addr) - (1 - this.F_CARRY);\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n if (\n ((this.REG_ACC ^ temp) & 0x80) !== 0 &&\n ((this.REG_ACC ^ this.load(addr)) & 0x80) !== 0\n ) {\n this.F_OVERFLOW = 1;\n } else {\n this.F_OVERFLOW = 0;\n }\n this.F_CARRY = temp < 0 ? 0 : 1;\n this.REG_ACC = temp & 0xff;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 44: {\n // *******\n // * SEC *\n // *******\n\n // Set carry flag\n this.F_CARRY = 1;\n break;\n }\n case 45: {\n // *******\n // * SED *\n // *******\n\n // Set decimal mode\n this.F_DECIMAL = 1;\n break;\n }\n case 46: {\n // *******\n // * SEI *\n // *******\n\n // Set interrupt disable status\n this.F_INTERRUPT = 1;\n break;\n }\n case 47: {\n // *******\n // * STA *\n // *******\n\n // Store accumulator in memory\n this.write(addr, this.REG_ACC);\n break;\n }\n case 48: {\n // *******\n // * STX *\n // *******\n\n // Store index X in memory\n this.write(addr, this.REG_X);\n break;\n }\n case 49: {\n // *******\n // * STY *\n // *******\n\n // Store index Y in memory:\n this.write(addr, this.REG_Y);\n break;\n }\n case 50: {\n // *******\n // * TAX *\n // *******\n\n // Transfer accumulator to index X:\n this.REG_X = this.REG_ACC;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n break;\n }\n case 51: {\n // *******\n // * TAY *\n // *******\n\n // Transfer accumulator to index Y:\n this.REG_Y = this.REG_ACC;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n break;\n }\n case 52: {\n // *******\n // * TSX *\n // *******\n\n // Transfer stack pointer to index X:\n this.REG_X = this.REG_SP - 0x0100;\n this.F_SIGN = (this.REG_SP >> 7) & 1;\n this.F_ZERO = this.REG_X;\n break;\n }\n case 53: {\n // *******\n // * TXA *\n // *******\n\n // Transfer index X to accumulator:\n this.REG_ACC = this.REG_X;\n this.F_SIGN = (this.REG_X >> 7) & 1;\n this.F_ZERO = this.REG_X;\n break;\n }\n case 54: {\n // *******\n // * TXS *\n // *******\n\n // Transfer index X to stack pointer:\n this.REG_SP = this.REG_X + 0x0100;\n this.stackWrap();\n break;\n }\n case 55: {\n // *******\n // * TYA *\n // *******\n\n // Transfer index Y to accumulator:\n this.REG_ACC = this.REG_Y;\n this.F_SIGN = (this.REG_Y >> 7) & 1;\n this.F_ZERO = this.REG_Y;\n break;\n }\n case 56: {\n // *******\n // * ALR *\n // *******\n\n // Shift right one bit after ANDing:\n temp = this.REG_ACC & this.load(addr);\n this.F_CARRY = temp & 1;\n this.REG_ACC = this.F_ZERO = temp >> 1;\n this.F_SIGN = 0;\n break;\n }\n case 57: {\n // *******\n // * ANC *\n // *******\n\n // AND accumulator, setting carry to bit 7 result.\n this.REG_ACC = this.F_ZERO = this.REG_ACC & this.load(addr);\n this.F_CARRY = this.F_SIGN = (this.REG_ACC >> 7) & 1;\n break;\n }\n case 58: {\n // *******\n // * ARR *\n // *******\n\n // Rotate right one bit after ANDing:\n temp = this.REG_ACC & this.load(addr);\n this.REG_ACC = this.F_ZERO = (temp >> 1) + (this.F_CARRY << 7);\n this.F_SIGN = this.F_CARRY;\n this.F_CARRY = (temp >> 7) & 1;\n this.F_OVERFLOW = ((temp >> 7) ^ (temp >> 6)) & 1;\n break;\n }\n case 59: {\n // *******\n // * AXS *\n // *******\n\n // Set X to (X AND A) - value.\n temp = (this.REG_X & this.REG_ACC) - this.load(addr);\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n if (\n ((this.REG_X ^ temp) & 0x80) !== 0 &&\n ((this.REG_X ^ this.load(addr)) & 0x80) !== 0\n ) {\n this.F_OVERFLOW = 1;\n } else {\n this.F_OVERFLOW = 0;\n }\n this.F_CARRY = temp < 0 ? 0 : 1;\n this.REG_X = temp & 0xff;\n break;\n }\n case 60: {\n // *******\n // * LAX *\n // *******\n\n // Load A and X with memory:\n this.REG_ACC = this.REG_X = this.F_ZERO = this.load(addr);\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n cycleCount += cycleAdd;\n break;\n }\n case 61: {\n // *******\n // * SAX *\n // *******\n\n // Store A AND X in memory:\n this.write(addr, this.REG_ACC & this.REG_X);\n break;\n }\n case 62: {\n // *******\n // * DCP *\n // *******\n\n // Decrement memory by one:\n temp = (this.load(addr) - 1) & 0xff;\n this.write(addr, temp);\n\n // Then compare with the accumulator:\n temp = this.REG_ACC - temp;\n this.F_CARRY = temp >= 0 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 63: {\n // *******\n // * ISC *\n // *******\n\n // Increment memory by one:\n temp = (this.load(addr) + 1) & 0xff;\n this.write(addr, temp);\n\n // Then subtract from the accumulator:\n temp = this.REG_ACC - temp - (1 - this.F_CARRY);\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n if (\n ((this.REG_ACC ^ temp) & 0x80) !== 0 &&\n ((this.REG_ACC ^ this.load(addr)) & 0x80) !== 0\n ) {\n this.F_OVERFLOW = 1;\n } else {\n this.F_OVERFLOW = 0;\n }\n this.F_CARRY = temp < 0 ? 0 : 1;\n this.REG_ACC = temp & 0xff;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 64: {\n // *******\n // * RLA *\n // *******\n\n // Rotate one bit left\n temp = this.load(addr);\n add = this.F_CARRY;\n this.F_CARRY = (temp >> 7) & 1;\n temp = ((temp << 1) & 0xff) + add;\n this.write(addr, temp);\n\n // Then AND with the accumulator.\n this.REG_ACC = this.REG_ACC & temp;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 65: {\n // *******\n // * RRA *\n // *******\n\n // Rotate one bit right\n temp = this.load(addr);\n add = this.F_CARRY << 7;\n this.F_CARRY = temp & 1;\n temp = (temp >> 1) + add;\n this.write(addr, temp);\n\n // Then add to the accumulator\n temp = this.REG_ACC + this.load(addr) + this.F_CARRY;\n\n if (\n ((this.REG_ACC ^ this.load(addr)) & 0x80) === 0 &&\n ((this.REG_ACC ^ temp) & 0x80) !== 0\n ) {\n this.F_OVERFLOW = 1;\n } else {\n this.F_OVERFLOW = 0;\n }\n this.F_CARRY = temp > 255 ? 1 : 0;\n this.F_SIGN = (temp >> 7) & 1;\n this.F_ZERO = temp & 0xff;\n this.REG_ACC = temp & 255;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 66: {\n // *******\n // * SLO *\n // *******\n\n // Shift one bit left\n temp = this.load(addr);\n this.F_CARRY = (temp >> 7) & 1;\n temp = (temp << 1) & 255;\n this.write(addr, temp);\n\n // Then OR with the accumulator.\n this.REG_ACC = this.REG_ACC | temp;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 67: {\n // *******\n // * SRE *\n // *******\n\n // Shift one bit right\n temp = this.load(addr) & 0xff;\n this.F_CARRY = temp & 1;\n temp >>= 1;\n this.write(addr, temp);\n\n // Then XOR with the accumulator.\n this.REG_ACC = this.REG_ACC ^ temp;\n this.F_SIGN = (this.REG_ACC >> 7) & 1;\n this.F_ZERO = this.REG_ACC;\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n case 68: {\n // *******\n // * SKB *\n // *******\n\n // Do nothing\n break;\n }\n case 69: {\n // *******\n // * IGN *\n // *******\n\n // Do nothing but load.\n // TODO: Properly implement the double-reads.\n this.load(addr);\n if (addrMode !== 11) cycleCount += cycleAdd; // PostIdxInd = 11\n break;\n }\n\n default: {\n // *******\n // * ??? *\n // *******\n\n this.nes.stop();\n this.nes.crashMessage =\n \"Game crashed, invalid opcode at address $\" + opaddr.toString(16);\n break;\n }\n } // end of switch\n\n return cycleCount;\n },\n\n load: function(addr) {\n if (addr < 0x2000) {\n return this.mem[addr & 0x7ff];\n } else {\n return this.nes.mmap.load(addr);\n }\n },\n\n load16bit: function(addr) {\n if (addr < 0x1fff) {\n return this.mem[addr & 0x7ff] | (this.mem[(addr + 1) & 0x7ff] << 8);\n } else {\n return this.nes.mmap.load(addr) | (this.nes.mmap.load(addr + 1) << 8);\n }\n },\n\n write: function(addr, val) {\n if (addr < 0x2000) {\n this.mem[addr & 0x7ff] = val;\n } else {\n this.nes.mmap.write(addr, val);\n }\n },\n\n requestIrq: function(type) {\n if (this.irqRequested) {\n if (type === this.IRQ_NORMAL) {\n return;\n }\n // console.log(\"too fast irqs. type=\"+type);\n }\n this.irqRequested = true;\n this.irqType = type;\n },\n\n push: function(value) {\n this.nes.mmap.write(this.REG_SP, value);\n this.REG_SP--;\n this.REG_SP = 0x0100 | (this.REG_SP & 0xff);\n },\n\n stackWrap: function() {\n this.REG_SP = 0x0100 | (this.REG_SP & 0xff);\n },\n\n pull: function() {\n this.REG_SP++;\n this.REG_SP = 0x0100 | (this.REG_SP & 0xff);\n return this.nes.mmap.load(this.REG_SP);\n },\n\n pageCrossed: function(addr1, addr2) {\n return (addr1 & 0xff00) !== (addr2 & 0xff00);\n },\n\n haltCycles: function(cycles) {\n this.cyclesToHalt += cycles;\n },\n\n doNonMaskableInterrupt: function(status) {\n if ((this.nes.mmap.load(0x2000) & 128) !== 0) {\n // Check whether VBlank Interrupts are enabled\n\n this.REG_PC_NEW++;\n this.push((this.REG_PC_NEW >> 8) & 0xff);\n this.push(this.REG_PC_NEW & 0xff);\n //this.F_INTERRUPT_NEW = 1;\n this.push(status);\n\n this.REG_PC_NEW =\n this.nes.mmap.load(0xfffa) | (this.nes.mmap.load(0xfffb) << 8);\n this.REG_PC_NEW--;\n }\n },\n\n doResetInterrupt: function() {\n this.REG_PC_NEW =\n this.nes.mmap.load(0xfffc) | (this.nes.mmap.load(0xfffd) << 8);\n this.REG_PC_NEW--;\n },\n\n doIrq: function(status) {\n this.REG_PC_NEW++;\n this.push((this.REG_PC_NEW >> 8) & 0xff);\n this.push(this.REG_PC_NEW & 0xff);\n this.push(status);\n this.F_INTERRUPT_NEW = 1;\n this.F_BRK_NEW = 0;\n\n this.REG_PC_NEW =\n this.nes.mmap.load(0xfffe) | (this.nes.mmap.load(0xffff) << 8);\n this.REG_PC_NEW--;\n },\n\n getStatus: function() {\n return (\n this.F_CARRY |\n (this.F_ZERO << 1) |\n (this.F_INTERRUPT << 2) |\n (this.F_DECIMAL << 3) |\n (this.F_BRK << 4) |\n (this.F_NOTUSED << 5) |\n (this.F_OVERFLOW << 6) |\n (this.F_SIGN << 7)\n );\n },\n\n setStatus: function(st) {\n this.F_CARRY = st & 1;\n this.F_ZERO = (st >> 1) & 1;\n this.F_INTERRUPT = (st >> 2) & 1;\n this.F_DECIMAL = (st >> 3) & 1;\n this.F_BRK = (st >> 4) & 1;\n this.F_NOTUSED = (st >> 5) & 1;\n this.F_OVERFLOW = (st >> 6) & 1;\n this.F_SIGN = (st >> 7) & 1;\n },\n\n JSON_PROPERTIES: [\n \"mem\",\n \"cyclesToHalt\",\n \"irqRequested\",\n \"irqType\",\n // Registers\n \"REG_ACC\",\n \"REG_X\",\n \"REG_Y\",\n \"REG_SP\",\n \"REG_PC\",\n \"REG_PC_NEW\",\n \"REG_STATUS\",\n // Status\n \"F_CARRY\",\n \"F_DECIMAL\",\n \"F_INTERRUPT\",\n \"F_INTERRUPT_NEW\",\n \"F_OVERFLOW\",\n \"F_SIGN\",\n \"F_ZERO\",\n \"F_NOTUSED\",\n \"F_NOTUSED_NEW\",\n \"F_BRK\",\n \"F_BRK_NEW\"\n ],\n\n toJSON: function() {\n return utils.toJSON(this);\n },\n\n fromJSON: function(s) {\n utils.fromJSON(this, s);\n }\n};\n\n// Generates and provides an array of details about instructions\nvar OpData = function() {\n this.opdata = new Array(256);\n\n // Set all to invalid instruction (to detect crashes):\n for (var i = 0; i < 256; i++) this.opdata[i] = 0xff;\n\n // Now fill in all valid opcodes:\n\n // ADC:\n this.setOp(this.INS_ADC, 0x69, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_ADC, 0x65, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_ADC, 0x75, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_ADC, 0x6d, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_ADC, 0x7d, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_ADC, 0x79, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_ADC, 0x61, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_ADC, 0x71, this.ADDR_POSTIDXIND, 2, 5);\n\n // AND:\n this.setOp(this.INS_AND, 0x29, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_AND, 0x25, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_AND, 0x35, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_AND, 0x2d, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_AND, 0x3d, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_AND, 0x39, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_AND, 0x21, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_AND, 0x31, this.ADDR_POSTIDXIND, 2, 5);\n\n // ASL:\n this.setOp(this.INS_ASL, 0x0a, this.ADDR_ACC, 1, 2);\n this.setOp(this.INS_ASL, 0x06, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_ASL, 0x16, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_ASL, 0x0e, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_ASL, 0x1e, this.ADDR_ABSX, 3, 7);\n\n // BCC:\n this.setOp(this.INS_BCC, 0x90, this.ADDR_REL, 2, 2);\n\n // BCS:\n this.setOp(this.INS_BCS, 0xb0, this.ADDR_REL, 2, 2);\n\n // BEQ:\n this.setOp(this.INS_BEQ, 0xf0, this.ADDR_REL, 2, 2);\n\n // BIT:\n this.setOp(this.INS_BIT, 0x24, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_BIT, 0x2c, this.ADDR_ABS, 3, 4);\n\n // BMI:\n this.setOp(this.INS_BMI, 0x30, this.ADDR_REL, 2, 2);\n\n // BNE:\n this.setOp(this.INS_BNE, 0xd0, this.ADDR_REL, 2, 2);\n\n // BPL:\n this.setOp(this.INS_BPL, 0x10, this.ADDR_REL, 2, 2);\n\n // BRK:\n this.setOp(this.INS_BRK, 0x00, this.ADDR_IMP, 1, 7);\n\n // BVC:\n this.setOp(this.INS_BVC, 0x50, this.ADDR_REL, 2, 2);\n\n // BVS:\n this.setOp(this.INS_BVS, 0x70, this.ADDR_REL, 2, 2);\n\n // CLC:\n this.setOp(this.INS_CLC, 0x18, this.ADDR_IMP, 1, 2);\n\n // CLD:\n this.setOp(this.INS_CLD, 0xd8, this.ADDR_IMP, 1, 2);\n\n // CLI:\n this.setOp(this.INS_CLI, 0x58, this.ADDR_IMP, 1, 2);\n\n // CLV:\n this.setOp(this.INS_CLV, 0xb8, this.ADDR_IMP, 1, 2);\n\n // CMP:\n this.setOp(this.INS_CMP, 0xc9, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_CMP, 0xc5, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_CMP, 0xd5, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_CMP, 0xcd, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_CMP, 0xdd, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_CMP, 0xd9, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_CMP, 0xc1, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_CMP, 0xd1, this.ADDR_POSTIDXIND, 2, 5);\n\n // CPX:\n this.setOp(this.INS_CPX, 0xe0, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_CPX, 0xe4, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_CPX, 0xec, this.ADDR_ABS, 3, 4);\n\n // CPY:\n this.setOp(this.INS_CPY, 0xc0, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_CPY, 0xc4, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_CPY, 0xcc, this.ADDR_ABS, 3, 4);\n\n // DEC:\n this.setOp(this.INS_DEC, 0xc6, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_DEC, 0xd6, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_DEC, 0xce, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_DEC, 0xde, this.ADDR_ABSX, 3, 7);\n\n // DEX:\n this.setOp(this.INS_DEX, 0xca, this.ADDR_IMP, 1, 2);\n\n // DEY:\n this.setOp(this.INS_DEY, 0x88, this.ADDR_IMP, 1, 2);\n\n // EOR:\n this.setOp(this.INS_EOR, 0x49, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_EOR, 0x45, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_EOR, 0x55, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_EOR, 0x4d, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_EOR, 0x5d, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_EOR, 0x59, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_EOR, 0x41, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_EOR, 0x51, this.ADDR_POSTIDXIND, 2, 5);\n\n // INC:\n this.setOp(this.INS_INC, 0xe6, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_INC, 0xf6, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_INC, 0xee, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_INC, 0xfe, this.ADDR_ABSX, 3, 7);\n\n // INX:\n this.setOp(this.INS_INX, 0xe8, this.ADDR_IMP, 1, 2);\n\n // INY:\n this.setOp(this.INS_INY, 0xc8, this.ADDR_IMP, 1, 2);\n\n // JMP:\n this.setOp(this.INS_JMP, 0x4c, this.ADDR_ABS, 3, 3);\n this.setOp(this.INS_JMP, 0x6c, this.ADDR_INDABS, 3, 5);\n\n // JSR:\n this.setOp(this.INS_JSR, 0x20, this.ADDR_ABS, 3, 6);\n\n // LDA:\n this.setOp(this.INS_LDA, 0xa9, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_LDA, 0xa5, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_LDA, 0xb5, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_LDA, 0xad, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_LDA, 0xbd, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_LDA, 0xb9, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_LDA, 0xa1, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_LDA, 0xb1, this.ADDR_POSTIDXIND, 2, 5);\n\n // LDX:\n this.setOp(this.INS_LDX, 0xa2, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_LDX, 0xa6, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_LDX, 0xb6, this.ADDR_ZPY, 2, 4);\n this.setOp(this.INS_LDX, 0xae, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_LDX, 0xbe, this.ADDR_ABSY, 3, 4);\n\n // LDY:\n this.setOp(this.INS_LDY, 0xa0, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_LDY, 0xa4, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_LDY, 0xb4, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_LDY, 0xac, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_LDY, 0xbc, this.ADDR_ABSX, 3, 4);\n\n // LSR:\n this.setOp(this.INS_LSR, 0x4a, this.ADDR_ACC, 1, 2);\n this.setOp(this.INS_LSR, 0x46, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_LSR, 0x56, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_LSR, 0x4e, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_LSR, 0x5e, this.ADDR_ABSX, 3, 7);\n\n // NOP:\n this.setOp(this.INS_NOP, 0x1a, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0x3a, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0x5a, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0x7a, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0xda, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0xea, this.ADDR_IMP, 1, 2);\n this.setOp(this.INS_NOP, 0xfa, this.ADDR_IMP, 1, 2);\n\n // ORA:\n this.setOp(this.INS_ORA, 0x09, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_ORA, 0x05, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_ORA, 0x15, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_ORA, 0x0d, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_ORA, 0x1d, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_ORA, 0x19, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_ORA, 0x01, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_ORA, 0x11, this.ADDR_POSTIDXIND, 2, 5);\n\n // PHA:\n this.setOp(this.INS_PHA, 0x48, this.ADDR_IMP, 1, 3);\n\n // PHP:\n this.setOp(this.INS_PHP, 0x08, this.ADDR_IMP, 1, 3);\n\n // PLA:\n this.setOp(this.INS_PLA, 0x68, this.ADDR_IMP, 1, 4);\n\n // PLP:\n this.setOp(this.INS_PLP, 0x28, this.ADDR_IMP, 1, 4);\n\n // ROL:\n this.setOp(this.INS_ROL, 0x2a, this.ADDR_ACC, 1, 2);\n this.setOp(this.INS_ROL, 0x26, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_ROL, 0x36, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_ROL, 0x2e, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_ROL, 0x3e, this.ADDR_ABSX, 3, 7);\n\n // ROR:\n this.setOp(this.INS_ROR, 0x6a, this.ADDR_ACC, 1, 2);\n this.setOp(this.INS_ROR, 0x66, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_ROR, 0x76, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_ROR, 0x6e, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_ROR, 0x7e, this.ADDR_ABSX, 3, 7);\n\n // RTI:\n this.setOp(this.INS_RTI, 0x40, this.ADDR_IMP, 1, 6);\n\n // RTS:\n this.setOp(this.INS_RTS, 0x60, this.ADDR_IMP, 1, 6);\n\n // SBC:\n this.setOp(this.INS_SBC, 0xe9, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_SBC, 0xe5, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_SBC, 0xf5, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_SBC, 0xed, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_SBC, 0xfd, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_SBC, 0xf9, this.ADDR_ABSY, 3, 4);\n this.setOp(this.INS_SBC, 0xe1, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_SBC, 0xf1, this.ADDR_POSTIDXIND, 2, 5);\n\n // SEC:\n this.setOp(this.INS_SEC, 0x38, this.ADDR_IMP, 1, 2);\n\n // SED:\n this.setOp(this.INS_SED, 0xf8, this.ADDR_IMP, 1, 2);\n\n // SEI:\n this.setOp(this.INS_SEI, 0x78, this.ADDR_IMP, 1, 2);\n\n // STA:\n this.setOp(this.INS_STA, 0x85, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_STA, 0x95, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_STA, 0x8d, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_STA, 0x9d, this.ADDR_ABSX, 3, 5);\n this.setOp(this.INS_STA, 0x99, this.ADDR_ABSY, 3, 5);\n this.setOp(this.INS_STA, 0x81, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_STA, 0x91, this.ADDR_POSTIDXIND, 2, 6);\n\n // STX:\n this.setOp(this.INS_STX, 0x86, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_STX, 0x96, this.ADDR_ZPY, 2, 4);\n this.setOp(this.INS_STX, 0x8e, this.ADDR_ABS, 3, 4);\n\n // STY:\n this.setOp(this.INS_STY, 0x84, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_STY, 0x94, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_STY, 0x8c, this.ADDR_ABS, 3, 4);\n\n // TAX:\n this.setOp(this.INS_TAX, 0xaa, this.ADDR_IMP, 1, 2);\n\n // TAY:\n this.setOp(this.INS_TAY, 0xa8, this.ADDR_IMP, 1, 2);\n\n // TSX:\n this.setOp(this.INS_TSX, 0xba, this.ADDR_IMP, 1, 2);\n\n // TXA:\n this.setOp(this.INS_TXA, 0x8a, this.ADDR_IMP, 1, 2);\n\n // TXS:\n this.setOp(this.INS_TXS, 0x9a, this.ADDR_IMP, 1, 2);\n\n // TYA:\n this.setOp(this.INS_TYA, 0x98, this.ADDR_IMP, 1, 2);\n\n // ALR:\n this.setOp(this.INS_ALR, 0x4b, this.ADDR_IMM, 2, 2);\n\n // ANC:\n this.setOp(this.INS_ANC, 0x0b, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_ANC, 0x2b, this.ADDR_IMM, 2, 2);\n\n // ARR:\n this.setOp(this.INS_ARR, 0x6b, this.ADDR_IMM, 2, 2);\n\n // AXS:\n this.setOp(this.INS_AXS, 0xcb, this.ADDR_IMM, 2, 2);\n\n // LAX:\n this.setOp(this.INS_LAX, 0xa3, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_LAX, 0xa7, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_LAX, 0xaf, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_LAX, 0xb3, this.ADDR_POSTIDXIND, 2, 5);\n this.setOp(this.INS_LAX, 0xb7, this.ADDR_ZPY, 2, 4);\n this.setOp(this.INS_LAX, 0xbf, this.ADDR_ABSY, 3, 4);\n\n // SAX:\n this.setOp(this.INS_SAX, 0x83, this.ADDR_PREIDXIND, 2, 6);\n this.setOp(this.INS_SAX, 0x87, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_SAX, 0x8f, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_SAX, 0x97, this.ADDR_ZPY, 2, 4);\n\n // DCP:\n this.setOp(this.INS_DCP, 0xc3, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_DCP, 0xc7, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_DCP, 0xcf, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_DCP, 0xd3, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_DCP, 0xd7, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_DCP, 0xdb, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_DCP, 0xdf, this.ADDR_ABSX, 3, 7);\n\n // ISC:\n this.setOp(this.INS_ISC, 0xe3, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_ISC, 0xe7, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_ISC, 0xef, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_ISC, 0xf3, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_ISC, 0xf7, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_ISC, 0xfb, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_ISC, 0xff, this.ADDR_ABSX, 3, 7);\n\n // RLA:\n this.setOp(this.INS_RLA, 0x23, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_RLA, 0x27, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_RLA, 0x2f, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_RLA, 0x33, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_RLA, 0x37, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_RLA, 0x3b, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_RLA, 0x3f, this.ADDR_ABSX, 3, 7);\n\n // RRA:\n this.setOp(this.INS_RRA, 0x63, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_RRA, 0x67, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_RRA, 0x6f, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_RRA, 0x73, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_RRA, 0x77, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_RRA, 0x7b, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_RRA, 0x7f, this.ADDR_ABSX, 3, 7);\n\n // SLO:\n this.setOp(this.INS_SLO, 0x03, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_SLO, 0x07, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_SLO, 0x0f, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_SLO, 0x13, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_SLO, 0x17, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_SLO, 0x1b, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_SLO, 0x1f, this.ADDR_ABSX, 3, 7);\n\n // SRE:\n this.setOp(this.INS_SRE, 0x43, this.ADDR_PREIDXIND, 2, 8);\n this.setOp(this.INS_SRE, 0x47, this.ADDR_ZP, 2, 5);\n this.setOp(this.INS_SRE, 0x4f, this.ADDR_ABS, 3, 6);\n this.setOp(this.INS_SRE, 0x53, this.ADDR_POSTIDXIND, 2, 8);\n this.setOp(this.INS_SRE, 0x57, this.ADDR_ZPX, 2, 6);\n this.setOp(this.INS_SRE, 0x5b, this.ADDR_ABSY, 3, 7);\n this.setOp(this.INS_SRE, 0x5f, this.ADDR_ABSX, 3, 7);\n\n // SKB:\n this.setOp(this.INS_SKB, 0x80, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_SKB, 0x82, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_SKB, 0x89, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_SKB, 0xc2, this.ADDR_IMM, 2, 2);\n this.setOp(this.INS_SKB, 0xe2, this.ADDR_IMM, 2, 2);\n\n // SKB:\n this.setOp(this.INS_IGN, 0x0c, this.ADDR_ABS, 3, 4);\n this.setOp(this.INS_IGN, 0x1c, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0x3c, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0x5c, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0x7c, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0xdc, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0xfc, this.ADDR_ABSX, 3, 4);\n this.setOp(this.INS_IGN, 0x04, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_IGN, 0x44, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_IGN, 0x64, this.ADDR_ZP, 2, 3);\n this.setOp(this.INS_IGN, 0x14, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_IGN, 0x34, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_IGN, 0x54, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_IGN, 0x74, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_IGN, 0xd4, this.ADDR_ZPX, 2, 4);\n this.setOp(this.INS_IGN, 0xf4, this.ADDR_ZPX, 2, 4);\n\n // prettier-ignore\n this.cycTable = new Array(\n /*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,\n /*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,\n /*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,\n /*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,\n /*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,\n /*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,\n /*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,\n /*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,\n /*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,\n /*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,\n /*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,\n /*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,\n /*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,\n /*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,\n /*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,\n /*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7\n );\n\n this.instname = new Array(70);\n\n // Instruction Names:\n this.instname[0] = \"ADC\";\n this.instname[1] = \"AND\";\n this.instname[2] = \"ASL\";\n this.instname[3] = \"BCC\";\n this.instname[4] = \"BCS\";\n this.instname[5] = \"BEQ\";\n this.instname[6] = \"BIT\";\n this.instname[7] = \"BMI\";\n this.instname[8] = \"BNE\";\n this.instname[9] = \"BPL\";\n this.instname[10] = \"BRK\";\n this.instname[11] = \"BVC\";\n this.instname[12] = \"BVS\";\n this.instname[13] = \"CLC\";\n this.instname[14] = \"CLD\";\n this.instname[15] = \"CLI\";\n this.instname[16] = \"CLV\";\n this.instname[17] = \"CMP\";\n this.instname[18] = \"CPX\";\n this.instname[19] = \"CPY\";\n this.instname[20] = \"DEC\";\n this.instname[21] = \"DEX\";\n this.instname[22] = \"DEY\";\n this.instname[23] = \"EOR\";\n this.instname[24] = \"INC\";\n this.instname[25] = \"INX\";\n this.instname[26] = \"INY\";\n this.instname[27] = \"JMP\";\n this.instname[28] = \"JSR\";\n this.instname[29] = \"LDA\";\n this.instname[30] = \"LDX\";\n this.instname[31] = \"LDY\";\n this.instname[32] = \"LSR\";\n this.instname[33] = \"NOP\";\n this.instname[34] = \"ORA\";\n this.instname[35] = \"PHA\";\n this.instname[36] = \"PHP\";\n this.instname[37] = \"PLA\";\n this.instname[38] = \"PLP\";\n this.instname[39] = \"ROL\";\n this.instname[40] = \"ROR\";\n this.instname[41] = \"RTI\";\n this.instname[42] = \"RTS\";\n this.instname[43] = \"SBC\";\n this.instname[44] = \"SEC\";\n this.instname[45] = \"SED\";\n this.instname[46] = \"SEI\";\n this.instname[47] = \"STA\";\n this.instname[48] = \"STX\";\n this.instname[49] = \"STY\";\n this.instname[50] = \"TAX\";\n this.instname[51] = \"TAY\";\n this.instname[52] = \"TSX\";\n this.instname[53] = \"TXA\";\n this.instname[54] = \"TXS\";\n this.instname[55] = \"TYA\";\n this.instname[56] = \"ALR\";\n this.instname[57] = \"ANC\";\n this.instname[58] = \"ARR\";\n this.instname[59] = \"AXS\";\n this.instname[60] = \"LAX\";\n this.instname[61] = \"SAX\";\n this.instname[62] = \"DCP\";\n this.instname[63] = \"ISC\";\n this.instname[64] = \"RLA\";\n this.instname[65] = \"RRA\";\n this.instname[66] = \"SLO\";\n this.instname[67] = \"SRE\";\n this.instname[68] = \"SKB\";\n this.instname[69] = \"IGN\";\n\n this.addrDesc = new Array(\n \"Zero Page \",\n \"Relative \",\n \"Implied \",\n \"Absolute \",\n \"Accumulator \",\n \"Immediate \",\n \"Zero Page,X \",\n \"Zero Page,Y \",\n \"Absolute,X \",\n \"Absolute,Y \",\n \"Preindexed Indirect \",\n \"Postindexed Indirect\",\n \"Indirect Absolute \"\n );\n};\n\nOpData.prototype = {\n INS_ADC: 0,\n INS_AND: 1,\n INS_ASL: 2,\n\n INS_BCC: 3,\n INS_BCS: 4,\n INS_BEQ: 5,\n INS_BIT: 6,\n INS_BMI: 7,\n INS_BNE: 8,\n INS_BPL: 9,\n INS_BRK: 10,\n INS_BVC: 11,\n INS_BVS: 12,\n\n INS_CLC: 13,\n INS_CLD: 14,\n INS_CLI: 15,\n INS_CLV: 16,\n INS_CMP: 17,\n INS_CPX: 18,\n INS_CPY: 19,\n\n INS_DEC: 20,\n INS_DEX: 21,\n INS_DEY: 22,\n\n INS_EOR: 23,\n\n INS_INC: 24,\n INS_INX: 25,\n INS_INY: 26,\n\n INS_JMP: 27,\n INS_JSR: 28,\n\n INS_LDA: 29,\n INS_LDX: 30,\n INS_LDY: 31,\n INS_LSR: 32,\n\n INS_NOP: 33,\n\n INS_ORA: 34,\n\n INS_PHA: 35,\n INS_PHP: 36,\n INS_PLA: 37,\n INS_PLP: 38,\n\n INS_ROL: 39,\n INS_ROR: 40,\n INS_RTI: 41,\n INS_RTS: 42,\n\n INS_SBC: 43,\n INS_SEC: 44,\n INS_SED: 45,\n INS_SEI: 46,\n INS_STA: 47,\n INS_STX: 48,\n INS_STY: 49,\n\n INS_TAX: 50,\n INS_TAY: 51,\n INS_TSX: 52,\n INS_TXA: 53,\n INS_TXS: 54,\n INS_TYA: 55,\n\n INS_ALR: 56,\n INS_ANC: 57,\n INS_ARR: 58,\n INS_AXS: 59,\n INS_LAX: 60,\n INS_SAX: 61,\n INS_DCP: 62,\n INS_ISC: 63,\n INS_RLA: 64,\n INS_RRA: 65,\n INS_SLO: 66,\n INS_SRE: 67,\n INS_SKB: 68,\n INS_IGN: 69,\n\n INS_DUMMY: 70, // dummy instruction used for 'halting' the processor some cycles\n\n // -------------------------------- //\n\n // Addressing modes:\n ADDR_ZP: 0,\n ADDR_REL: 1,\n ADDR_IMP: 2,\n ADDR_ABS: 3,\n ADDR_ACC: 4,\n ADDR_IMM: 5,\n ADDR_ZPX: 6,\n ADDR_ZPY: 7,\n ADDR_ABSX: 8,\n ADDR_ABSY: 9,\n ADDR_PREIDXIND: 10,\n ADDR_POSTIDXIND: 11,\n ADDR_INDABS: 12,\n\n setOp: function(inst, op, addr, size, cycles) {\n this.opdata[op] =\n (inst & 0xff) |\n ((addr & 0xff) << 8) |\n ((size & 0xff) << 16) |\n ((cycles & 0xff) << 24);\n }\n};\n\nmodule.exports = CPU;\n", "var Tile = function() {\n // Tile data:\n this.pix = new Uint8Array(64);\n\n this.fbIndex = null;\n this.tIndex = null;\n this.x = null;\n this.y = null;\n this.w = null;\n this.h = null;\n this.incX = null;\n this.incY = null;\n this.palIndex = null;\n this.tpri = null;\n this.c = null;\n this.initialized = false;\n this.opaque = new Array(8);\n};\n\nTile.prototype = {\n setBuffer: function(scanline) {\n for (this.y = 0; this.y < 8; this.y++) {\n this.setScanline(this.y, scanline[this.y], scanline[this.y + 8]);\n }\n },\n\n setScanline: function(sline, b1, b2) {\n this.initialized = true;\n this.tIndex = sline << 3;\n for (this.x = 0; this.x < 8; this.x++) {\n this.pix[this.tIndex + this.x] =\n ((b1 >> (7 - this.x)) & 1) + (((b2 >> (7 - this.x)) & 1) << 1);\n if (this.pix[this.tIndex + this.x] === 0) {\n this.opaque[sline] = false;\n }\n }\n },\n\n render: function(\n buffer,\n srcx1,\n srcy1,\n srcx2,\n srcy2,\n dx,\n dy,\n palAdd,\n palette,\n flipHorizontal,\n flipVertical,\n pri,\n priTable\n ) {\n if (dx < -7 || dx >= 256 || dy < -7 || dy >= 240) {\n return;\n }\n\n this.w = srcx2 - srcx1;\n this.h = srcy2 - srcy1;\n\n if (dx < 0) {\n srcx1 -= dx;\n }\n if (dx + srcx2 >= 256) {\n srcx2 = 256 - dx;\n }\n\n if (dy < 0) {\n srcy1 -= dy;\n }\n if (dy + srcy2 >= 240) {\n srcy2 = 240 - dy;\n }\n\n if (!flipHorizontal && !flipVertical) {\n this.fbIndex = (dy << 8) + dx;\n this.tIndex = 0;\n for (this.y = 0; this.y < 8; this.y++) {\n for (this.x = 0; this.x < 8; this.x++) {\n if (\n this.x >= srcx1 &&\n this.x < srcx2 &&\n this.y >= srcy1 &&\n this.y < srcy2\n ) {\n this.palIndex = this.pix[this.tIndex];\n this.tpri = priTable[this.fbIndex];\n if (this.palIndex !== 0 && pri <= (this.tpri & 0xff)) {\n //console.log(\"Rendering upright tile to buffer\");\n buffer[this.fbIndex] = palette[this.palIndex + palAdd];\n this.tpri = (this.tpri & 0xf00) | pri;\n priTable[this.fbIndex] = this.tpri;\n }\n }\n this.fbIndex++;\n this.tIndex++;\n }\n this.fbIndex -= 8;\n this.fbIndex += 256;\n }\n } else if (flipHorizontal && !flipVertical) {\n this.fbIndex = (dy << 8) + dx;\n this.tIndex = 7;\n for (this.y = 0; this.y < 8; this.y++) {\n for (this.x = 0; this.x < 8; this.x++) {\n if (\n this.x >= srcx1 &&\n this.x < srcx2 &&\n this.y >= srcy1 &&\n this.y < srcy2\n ) {\n this.palIndex = this.pix[this.tIndex];\n this.tpri = priTable[this.fbIndex];\n if (this.palIndex !== 0 && pri <= (this.tpri & 0xff)) {\n buffer[this.fbIndex] = palette[this.palIndex + palAdd];\n this.tpri = (this.tpri & 0xf00) | pri;\n priTable[this.fbIndex] = this.tpri;\n }\n }\n this.fbIndex++;\n this.tIndex--;\n }\n this.fbIndex -= 8;\n this.fbIndex += 256;\n this.tIndex += 16;\n }\n } else if (flipVertical && !flipHorizontal) {\n this.fbIndex = (dy << 8) + dx;\n this.tIndex = 56;\n for (this.y = 0; this.y < 8; this.y++) {\n for (this.x = 0; this.x < 8; this.x++) {\n if (\n this.x >= srcx1 &&\n this.x < srcx2 &&\n this.y >= srcy1 &&\n this.y < srcy2\n ) {\n this.palIndex = this.pix[this.tIndex];\n this.tpri = priTable[this.fbIndex];\n if (this.palIndex !== 0 && pri <= (this.tpri & 0xff)) {\n buffer[this.fbIndex] = palette[this.palIndex + palAdd];\n this.tpri = (this.tpri & 0xf00) | pri;\n priTable[this.fbIndex] = this.tpri;\n }\n }\n this.fbIndex++;\n this.tIndex++;\n }\n this.fbIndex -= 8;\n this.fbIndex += 256;\n this.tIndex -= 16;\n }\n } else {\n this.fbIndex = (dy << 8) + dx;\n this.tIndex = 63;\n for (this.y = 0; this.y < 8; this.y++) {\n for (this.x = 0; this.x < 8; this.x++) {\n if (\n this.x >= srcx1 &&\n this.x < srcx2 &&\n this.y >= srcy1 &&\n this.y < srcy2\n ) {\n this.palIndex = this.pix[this.tIndex];\n this.tpri = priTable[this.fbIndex];\n if (this.palIndex !== 0 && pri <= (this.tpri & 0xff)) {\n buffer[this.fbIndex] = palette[this.palIndex + palAdd];\n this.tpri = (this.tpri & 0xf00) | pri;\n priTable[this.fbIndex] = this.tpri;\n }\n }\n this.fbIndex++;\n this.tIndex--;\n }\n this.fbIndex -= 8;\n this.fbIndex += 256;\n }\n }\n },\n\n isTransparent: function(x, y) {\n return this.pix[(y << 3) + x] === 0;\n },\n\n toJSON: function() {\n return {\n opaque: this.opaque,\n pix: this.pix\n };\n },\n\n fromJSON: function(s) {\n this.opaque = s.opaque;\n this.pix = s.pix;\n }\n};\n\nmodule.exports = Tile;\n", "var Tile = require(\"./tile\");\nvar utils = require(\"./utils\");\n\nvar PPU = function(nes) {\n this.nes = nes;\n\n // Keep Chrome happy\n this.vramMem = null;\n this.spriteMem = null;\n this.vramAddress = null;\n this.vramTmpAddress = null;\n this.vramBufferedReadValue = null;\n this.firstWrite = null;\n this.sramAddress = null;\n this.currentMirroring = null;\n this.requestEndFrame = null;\n this.nmiOk = null;\n this.dummyCycleToggle = null;\n this.validTileData = null;\n this.nmiCounter = null;\n this.scanlineAlreadyRendered = null;\n this.f_nmiOnVblank = null;\n this.f_spriteSize = null;\n this.f_bgPatternTable = null;\n this.f_spPatternTable = null;\n this.f_addrInc = null;\n this.f_nTblAddress = null;\n this.f_color = null;\n this.f_spVisibility = null;\n this.f_bgVisibility = null;\n this.f_spClipping = null;\n this.f_bgClipping = null;\n this.f_dispType = null;\n this.cntFV = null;\n this.cntV = null;\n this.cntH = null;\n this.cntVT = null;\n this.cntHT = null;\n this.regFV = null;\n this.regV = null;\n this.regH = null;\n this.regVT = null;\n this.regHT = null;\n this.regFH = null;\n this.regS = null;\n this.curNt = null;\n this.attrib = null;\n this.buffer = null;\n this.bgbuffer = null;\n this.pixrendered = null;\n\n this.validTileData = null;\n this.scantile = null;\n this.scanline = null;\n this.lastRenderedScanline = null;\n this.curX = null;\n this.sprX = null;\n this.sprY = null;\n this.sprTile = null;\n this.sprCol = null;\n this.vertFlip = null;\n this.horiFlip = null;\n this.bgPriority = null;\n this.spr0HitX = null;\n this.spr0HitY = null;\n this.hitSpr0 = null;\n this.sprPalette = null;\n this.imgPalette = null;\n this.ptTile = null;\n this.ntable1 = null;\n this.currentMirroring = null;\n this.nameTable = null;\n this.vramMirrorTable = null;\n this.palTable = null;\n\n // Rendering Options:\n this.showSpr0Hit = false;\n this.clipToTvSize = true;\n\n this.reset();\n};\n\nPPU.prototype = {\n // Status flags:\n STATUS_VRAMWRITE: 4,\n STATUS_SLSPRITECOUNT: 5,\n STATUS_SPRITE0HIT: 6,\n STATUS_VBLANK: 7,\n\n reset: function() {\n var i;\n\n // Memory\n this.vramMem = new Uint8Array(0x8000);\n this.spriteMem = new Uint8Array(0x100);\n for (i = 0; i < this.vramMem.length; i++) {\n this.vramMem[i] = 0;\n }\n for (i = 0; i < this.spriteMem.length; i++) {\n this.spriteMem[i] = 0;\n }\n\n // VRAM I/O:\n this.vramAddress = null;\n this.vramTmpAddress = null;\n this.vramBufferedReadValue = 0;\n this.firstWrite = true; // VRAM/Scroll Hi/Lo latch\n\n // SPR-RAM I/O:\n this.sramAddress = 0; // 8-bit only.\n\n this.currentMirroring = -1;\n this.requestEndFrame = false;\n this.nmiOk = false;\n this.dummyCycleToggle = false;\n this.validTileData = false;\n this.nmiCounter = 0;\n this.scanlineAlreadyRendered = null;\n\n // Control Flags Register 1:\n this.f_nmiOnVblank = 0; // NMI on VBlank. 0=disable, 1=enable\n this.f_spriteSize = 0; // Sprite size. 0=8x8, 1=8x16\n this.f_bgPatternTable = 0; // Background Pattern Table address. 0=0x0000,1=0x1000\n this.f_spPatternTable = 0; // Sprite Pattern Table address. 0=0x0000,1=0x1000\n this.f_addrInc = 0; // PPU Address Increment. 0=1,1=32\n this.f_nTblAddress = 0; // Name Table Address. 0=0x2000,1=0x2400,2=0x2800,3=0x2C00\n\n // Control Flags Register 2:\n this.f_color = 0; // Background color. 0=black, 1=blue, 2=green, 4=red\n this.f_spVisibility = 0; // Sprite visibility. 0=not displayed,1=displayed\n this.f_bgVisibility = 0; // Background visibility. 0=Not Displayed,1=displayed\n this.f_spClipping = 0; // Sprite clipping. 0=Sprites invisible in left 8-pixel column,1=No clipping\n this.f_bgClipping = 0; // Background clipping. 0=BG invisible in left 8-pixel column, 1=No clipping\n this.f_dispType = 0; // Display type. 0=color, 1=monochrome\n\n // Counters:\n this.cntFV = 0;\n this.cntV = 0;\n this.cntH = 0;\n this.cntVT = 0;\n this.cntHT = 0;\n\n // Registers:\n this.regFV = 0;\n this.regV = 0;\n this.regH = 0;\n this.regVT = 0;\n this.regHT = 0;\n this.regFH = 0;\n this.regS = 0;\n\n // These are temporary variables used in rendering and sound procedures.\n // Their states outside of those procedures can be ignored.\n // TODO: the use of this is a bit weird, investigate\n this.curNt = null;\n\n // Variables used when rendering:\n this.attrib = new Array(32);\n this.buffer = new Uint32Array(256 * 240);\n this.bgbuffer = new Uint32Array(256 * 240);\n this.pixrendered = new Uint32Array(256 * 240);\n\n this.validTileData = null;\n\n this.scantile = new Array(32);\n\n // Initialize misc vars:\n this.scanline = 0;\n this.lastRenderedScanline = -1;\n this.curX = 0;\n\n // Sprite data:\n this.sprX = new Array(64); // X coordinate\n this.sprY = new Array(64); // Y coordinate\n this.sprTile = new Array(64); // Tile Index (into pattern table)\n this.sprCol = new Array(64); // Upper two bits of color\n this.vertFlip = new Array(64); // Vertical Flip\n this.horiFlip = new Array(64); // Horizontal Flip\n this.bgPriority = new Array(64); // Background priority\n this.spr0HitX = 0; // Sprite #0 hit X coordinate\n this.spr0HitY = 0; // Sprite #0 hit Y coordinate\n this.hitSpr0 = false;\n\n // Palette data:\n this.sprPalette = new Uint32Array(16);\n this.imgPalette = new Uint32Array(16);\n\n // Create pattern table tile buffers:\n this.ptTile = new Array(512);\n for (i = 0; i < 512; i++) {\n this.ptTile[i] = new Tile();\n }\n\n // Create nametable buffers:\n // Name table data:\n this.ntable1 = new Array(4);\n this.currentMirroring = -1;\n this.nameTable = new Array(4);\n for (i = 0; i < 4; i++) {\n this.nameTable[i] = new NameTable(32, 32, \"Nt\" + i);\n }\n\n // Initialize mirroring lookup table:\n this.vramMirrorTable = new Uint16Array(0x8000);\n for (i = 0; i < 0x8000; i++) {\n this.vramMirrorTable[i] = i;\n }\n\n this.palTable = new PaletteTable();\n this.palTable.loadNTSCPalette();\n //this.palTable.loadDefaultPalette();\n\n this.updateControlReg1(0);\n this.updateControlReg2(0);\n },\n\n // Sets Nametable mirroring.\n setMirroring: function(mirroring) {\n if (mirroring === this.currentMirroring) {\n return;\n }\n\n this.currentMirroring = mirroring;\n this.triggerRendering();\n\n // Remove mirroring:\n if (this.vramMirrorTable === null) {\n this.vramMirrorTable = new Uint16Array(0x8000);\n }\n for (var i = 0; i < 0x8000; i++) {\n this.vramMirrorTable[i] = i;\n }\n\n // Palette mirroring:\n this.defineMirrorRegion(0x3f20, 0x3f00, 0x20);\n this.defineMirrorRegion(0x3f40, 0x3f00, 0x20);\n this.defineMirrorRegion(0x3f80, 0x3f00, 0x20);\n this.defineMirrorRegion(0x3fc0, 0x3f00, 0x20);\n\n // Additional mirroring:\n this.defineMirrorRegion(0x3000, 0x2000, 0xf00);\n this.defineMirrorRegion(0x4000, 0x0000, 0x4000);\n\n if (mirroring === this.nes.rom.HORIZONTAL_MIRRORING) {\n // Horizontal mirroring.\n\n this.ntable1[0] = 0;\n this.ntable1[1] = 0;\n this.ntable1[2] = 1;\n this.ntable1[3] = 1;\n\n this.defineMirrorRegion(0x2400, 0x2000, 0x400);\n this.defineMirrorRegion(0x2c00, 0x2800, 0x400);\n } else if (mirroring === this.nes.rom.VERTICAL_MIRRORING) {\n // Vertical mirroring.\n\n this.ntable1[0] = 0;\n this.ntable1[1] = 1;\n this.ntable1[2] = 0;\n this.ntable1[3] = 1;\n\n this.defineMirrorRegion(0x2800, 0x2000, 0x400);\n this.defineMirrorRegion(0x2c00, 0x2400, 0x400);\n } else if (mirroring === this.nes.rom.SINGLESCREEN_MIRRORING) {\n // Single Screen mirroring\n\n this.ntable1[0] = 0;\n this.ntable1[1] = 0;\n this.ntable1[2] = 0;\n this.ntable1[3] = 0;\n\n this.defineMirrorRegion(0x2400, 0x2000, 0x400);\n this.defineMirrorRegion(0x2800, 0x2000, 0x400);\n this.defineMirrorRegion(0x2c00, 0x2000, 0x400);\n } else if (mirroring === this.nes.rom.SINGLESCREEN_MIRRORING2) {\n this.ntable1[0] = 1;\n this.ntable1[1] = 1;\n this.ntable1[2] = 1;\n this.ntable1[3] = 1;\n\n this.defineMirrorRegion(0x2400, 0x2400, 0x400);\n this.defineMirrorRegion(0x2800, 0x2400, 0x400);\n this.defineMirrorRegion(0x2c00, 0x2400, 0x400);\n } else {\n // Assume Four-screen mirroring.\n\n this.ntable1[0] = 0;\n this.ntable1[1] = 1;\n this.ntable1[2] = 2;\n this.ntable1[3] = 3;\n }\n },\n\n // Define a mirrored area in the address lookup table.\n // Assumes the regions don't overlap.\n // The 'to' region is the region that is physically in memory.\n defineMirrorRegion: function(fromStart, toStart, size) {\n for (var i = 0; i < size; i++) {\n this.vramMirrorTable[fromStart + i] = toStart + i;\n }\n },\n\n startVBlank: function() {\n // Do NMI:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_NMI);\n\n // Make sure everything is rendered:\n if (this.lastRenderedScanline < 239) {\n this.renderFramePartially(\n this.lastRenderedScanline + 1,\n 240 - this.lastRenderedScanline\n );\n }\n\n // End frame:\n this.endFrame();\n\n // Reset scanline counter:\n this.lastRenderedScanline = -1;\n },\n\n endScanline: function() {\n switch (this.scanline) {\n case 19:\n // Dummy scanline.\n // May be variable length:\n if (this.dummyCycleToggle) {\n // Remove dead cycle at end of scanline,\n // for next scanline:\n this.curX = 1;\n this.dummyCycleToggle = !this.dummyCycleToggle;\n }\n break;\n\n case 20:\n // Clear VBlank flag:\n this.setStatusFlag(this.STATUS_VBLANK, false);\n\n // Clear Sprite #0 hit flag:\n this.setStatusFlag(this.STATUS_SPRITE0HIT, false);\n this.hitSpr0 = false;\n this.spr0HitX = -1;\n this.spr0HitY = -1;\n\n if (this.f_bgVisibility === 1 || this.f_spVisibility === 1) {\n // Update counters:\n this.cntFV = this.regFV;\n this.cntV = this.regV;\n this.cntH = this.regH;\n this.cntVT = this.regVT;\n this.cntHT = this.regHT;\n\n if (this.f_bgVisibility === 1) {\n // Render dummy scanline:\n this.renderBgScanline(false, 0);\n }\n }\n\n if (this.f_bgVisibility === 1 && this.f_spVisibility === 1) {\n // Check sprite 0 hit for first scanline:\n this.checkSprite0(0);\n }\n\n if (this.f_bgVisibility === 1 || this.f_spVisibility === 1) {\n // Clock mapper IRQ Counter:\n this.nes.mmap.clockIrqCounter();\n }\n break;\n\n case 261:\n // Dead scanline, no rendering.\n // Set VINT:\n this.setStatusFlag(this.STATUS_VBLANK, true);\n this.requestEndFrame = true;\n this.nmiCounter = 9;\n\n // Wrap around:\n this.scanline = -1; // will be incremented to 0\n\n break;\n\n default:\n if (this.scanline >= 21 && this.scanline <= 260) {\n // Render normally:\n if (this.f_bgVisibility === 1) {\n if (!this.scanlineAlreadyRendered) {\n // update scroll:\n this.cntHT = this.regHT;\n this.cntH = this.regH;\n this.renderBgScanline(true, this.scanline + 1 - 21);\n }\n this.scanlineAlreadyRendered = false;\n\n // Check for sprite 0 (next scanline):\n if (!this.hitSpr0 && this.f_spVisibility === 1) {\n if (\n this.sprX[0] >= -7 &&\n this.sprX[0] < 256 &&\n this.sprY[0] + 1 <= this.scanline - 20 &&\n this.sprY[0] + 1 + (this.f_spriteSize === 0 ? 8 : 16) >=\n this.scanline - 20\n ) {\n if (this.checkSprite0(this.scanline - 20)) {\n this.hitSpr0 = true;\n }\n }\n }\n }\n\n if (this.f_bgVisibility === 1 || this.f_spVisibility === 1) {\n // Clock mapper IRQ Counter:\n this.nes.mmap.clockIrqCounter();\n }\n }\n }\n\n this.scanline++;\n this.regsToAddress();\n this.cntsToAddress();\n },\n\n startFrame: function() {\n // Set background color:\n var bgColor = 0;\n\n if (this.f_dispType === 0) {\n // Color display.\n // f_color determines color emphasis.\n // Use first entry of image palette as BG color.\n bgColor = this.imgPalette[0];\n } else {\n // Monochrome display.\n // f_color determines the bg color.\n switch (this.f_color) {\n case 0:\n // Black\n bgColor = 0x00000;\n break;\n case 1:\n // Green\n bgColor = 0x00ff00;\n break;\n case 2:\n // Blue\n bgColor = 0xff0000;\n break;\n case 3:\n // Invalid. Use black.\n bgColor = 0x000000;\n break;\n case 4:\n // Red\n bgColor = 0x0000ff;\n break;\n default:\n // Invalid. Use black.\n bgColor = 0x0;\n }\n }\n\n var buffer = this.buffer;\n var i;\n for (i = 0; i < 256 * 240; i++) {\n buffer[i] = bgColor;\n }\n var pixrendered = this.pixrendered;\n for (i = 0; i < pixrendered.length; i++) {\n pixrendered[i] = 65;\n }\n },\n\n endFrame: function() {\n var i, x, y;\n var buffer = this.buffer;\n\n // Draw spr#0 hit coordinates:\n if (this.showSpr0Hit) {\n // Spr 0 position:\n if (\n this.sprX[0] >= 0 &&\n this.sprX[0] < 256 &&\n this.sprY[0] >= 0 &&\n this.sprY[0] < 240\n ) {\n for (i = 0; i < 256; i++) {\n buffer[(this.sprY[0] << 8) + i] = 0xff5555;\n }\n for (i = 0; i < 240; i++) {\n buffer[(i << 8) + this.sprX[0]] = 0xff5555;\n }\n }\n // Hit position:\n if (\n this.spr0HitX >= 0 &&\n this.spr0HitX < 256 &&\n this.spr0HitY >= 0 &&\n this.spr0HitY < 240\n ) {\n for (i = 0; i < 256; i++) {\n buffer[(this.spr0HitY << 8) + i] = 0x55ff55;\n }\n for (i = 0; i < 240; i++) {\n buffer[(i << 8) + this.spr0HitX] = 0x55ff55;\n }\n }\n }\n\n // This is a bit lazy..\n // if either the sprites or the background should be clipped,\n // both are clipped after rendering is finished.\n if (\n this.clipToTvSize ||\n this.f_bgClipping === 0 ||\n this.f_spClipping === 0\n ) {\n // Clip left 8-pixels column:\n for (y = 0; y < 240; y++) {\n for (x = 0; x < 8; x++) {\n buffer[(y << 8) + x] = 0;\n }\n }\n }\n\n if (this.clipToTvSize) {\n // Clip right 8-pixels column too:\n for (y = 0; y < 240; y++) {\n for (x = 0; x < 8; x++) {\n buffer[(y << 8) + 255 - x] = 0;\n }\n }\n }\n\n // Clip top and bottom 8 pixels:\n if (this.clipToTvSize) {\n for (y = 0; y < 8; y++) {\n for (x = 0; x < 256; x++) {\n buffer[(y << 8) + x] = 0;\n buffer[((239 - y) << 8) + x] = 0;\n }\n }\n }\n\n this.nes.ui.writeFrame(buffer);\n },\n\n updateControlReg1: function(value) {\n this.triggerRendering();\n\n this.f_nmiOnVblank = (value >> 7) & 1;\n this.f_spriteSize = (value >> 5) & 1;\n this.f_bgPatternTable = (value >> 4) & 1;\n this.f_spPatternTable = (value >> 3) & 1;\n this.f_addrInc = (value >> 2) & 1;\n this.f_nTblAddress = value & 3;\n\n this.regV = (value >> 1) & 1;\n this.regH = value & 1;\n this.regS = (value >> 4) & 1;\n },\n\n updateControlReg2: function(value) {\n this.triggerRendering();\n\n this.f_color = (value >> 5) & 7;\n this.f_spVisibility = (value >> 4) & 1;\n this.f_bgVisibility = (value >> 3) & 1;\n this.f_spClipping = (value >> 2) & 1;\n this.f_bgClipping = (value >> 1) & 1;\n this.f_dispType = value & 1;\n\n if (this.f_dispType === 0) {\n this.palTable.setEmphasis(this.f_color);\n }\n this.updatePalettes();\n },\n\n setStatusFlag: function(flag, value) {\n var n = 1 << flag;\n this.nes.cpu.mem[0x2002] =\n (this.nes.cpu.mem[0x2002] & (255 - n)) | (value ? n : 0);\n },\n\n // CPU Register $2002:\n // Read the Status Register.\n readStatusRegister: function() {\n var tmp = this.nes.cpu.mem[0x2002];\n\n // Reset scroll & VRAM Address toggle:\n this.firstWrite = true;\n\n // Clear VBlank flag:\n this.setStatusFlag(this.STATUS_VBLANK, false);\n\n // Fetch status data:\n return tmp;\n },\n\n // CPU Register $2003:\n // Write the SPR-RAM address that is used for sramWrite (Register 0x2004 in CPU memory map)\n writeSRAMAddress: function(address) {\n this.sramAddress = address;\n },\n\n // CPU Register $2004 (R):\n // Read from SPR-RAM (Sprite RAM).\n // The address should be set first.\n sramLoad: function() {\n /*short tmp = sprMem.load(sramAddress);\n sramAddress++; // Increment address\n sramAddress%=0x100;\n return tmp;*/\n return this.spriteMem[this.sramAddress];\n },\n\n // CPU Register $2004 (W):\n // Write to SPR-RAM (Sprite RAM).\n // The address should be set first.\n sramWrite: function(value) {\n this.spriteMem[this.sramAddress] = value;\n this.spriteRamWriteUpdate(this.sramAddress, value);\n this.sramAddress++; // Increment address\n this.sramAddress %= 0x100;\n },\n\n // CPU Register $2005:\n // Write to scroll registers.\n // The first write is the vertical offset, the second is the\n // horizontal offset:\n scrollWrite: function(value) {\n this.triggerRendering();\n\n if (this.firstWrite) {\n // First write, horizontal scroll:\n this.regHT = (value >> 3) & 31;\n this.regFH = value & 7;\n } else {\n // Second write, vertical scroll:\n this.regFV = value & 7;\n this.regVT = (value >> 3) & 31;\n }\n this.firstWrite = !this.firstWrite;\n },\n\n // CPU Register $2006:\n // Sets the adress used when reading/writing from/to VRAM.\n // The first write sets the high byte, the second the low byte.\n writeVRAMAddress: function(address) {\n if (this.firstWrite) {\n this.regFV = (address >> 4) & 3;\n this.regV = (address >> 3) & 1;\n this.regH = (address >> 2) & 1;\n this.regVT = (this.regVT & 7) | ((address & 3) << 3);\n } else {\n this.triggerRendering();\n\n this.regVT = (this.regVT & 24) | ((address >> 5) & 7);\n this.regHT = address & 31;\n\n this.cntFV = this.regFV;\n this.cntV = this.regV;\n this.cntH = this.regH;\n this.cntVT = this.regVT;\n this.cntHT = this.regHT;\n\n this.checkSprite0(this.scanline - 20);\n }\n\n this.firstWrite = !this.firstWrite;\n\n // Invoke mapper latch:\n this.cntsToAddress();\n if (this.vramAddress < 0x2000) {\n this.nes.mmap.latchAccess(this.vramAddress);\n }\n },\n\n // CPU Register $2007(R):\n // Read from PPU memory. The address should be set first.\n vramLoad: function() {\n var tmp;\n\n this.cntsToAddress();\n this.regsToAddress();\n\n // If address is in range 0x0000-0x3EFF, return buffered values:\n if (this.vramAddress <= 0x3eff) {\n tmp = this.vramBufferedReadValue;\n\n // Update buffered value:\n if (this.vramAddress < 0x2000) {\n this.vramBufferedReadValue = this.vramMem[this.vramAddress];\n } else {\n this.vramBufferedReadValue = this.mirroredLoad(this.vramAddress);\n }\n\n // Mapper latch access:\n if (this.vramAddress < 0x2000) {\n this.nes.mmap.latchAccess(this.vramAddress);\n }\n\n // Increment by either 1 or 32, depending on d2 of Control Register 1:\n this.vramAddress += this.f_addrInc === 1 ? 32 : 1;\n\n this.cntsFromAddress();\n this.regsFromAddress();\n\n return tmp; // Return the previous buffered value.\n }\n\n // No buffering in this mem range. Read normally.\n tmp = this.mirroredLoad(this.vramAddress);\n\n // Increment by either 1 or 32, depending on d2 of Control Register 1:\n this.vramAddress += this.f_addrInc === 1 ? 32 : 1;\n\n this.cntsFromAddress();\n this.regsFromAddress();\n\n return tmp;\n },\n\n // CPU Register $2007(W):\n // Write to PPU memory. The address should be set first.\n vramWrite: function(value) {\n this.triggerRendering();\n this.cntsToAddress();\n this.regsToAddress();\n\n if (this.vramAddress >= 0x2000) {\n // Mirroring is used.\n this.mirroredWrite(this.vramAddress, value);\n } else {\n // Write normally.\n this.writeMem(this.vramAddress, value);\n\n // Invoke mapper latch:\n this.nes.mmap.latchAccess(this.vramAddress);\n }\n\n // Increment by either 1 or 32, depending on d2 of Control Register 1:\n this.vramAddress += this.f_addrInc === 1 ? 32 : 1;\n this.regsFromAddress();\n this.cntsFromAddress();\n },\n\n // CPU Register $4014:\n // Write 256 bytes of main memory\n // into Sprite RAM.\n sramDMA: function(value) {\n var baseAddress = value * 0x100;\n var data;\n for (var i = this.sramAddress; i < 256; i++) {\n data = this.nes.cpu.mem[baseAddress + i];\n this.spriteMem[i] = data;\n this.spriteRamWriteUpdate(i, data);\n }\n\n this.nes.cpu.haltCycles(513);\n },\n\n // Updates the scroll registers from a new VRAM address.\n regsFromAddress: function() {\n var address = (this.vramTmpAddress >> 8) & 0xff;\n this.regFV = (address >> 4) & 7;\n this.regV = (address >> 3) & 1;\n this.regH = (address >> 2) & 1;\n this.regVT = (this.regVT & 7) | ((address & 3) << 3);\n\n address = this.vramTmpAddress & 0xff;\n this.regVT = (this.regVT & 24) | ((address >> 5) & 7);\n this.regHT = address & 31;\n },\n\n // Updates the scroll registers from a new VRAM address.\n cntsFromAddress: function() {\n var address = (this.vramAddress >> 8) & 0xff;\n this.cntFV = (address >> 4) & 3;\n this.cntV = (address >> 3) & 1;\n this.cntH = (address >> 2) & 1;\n this.cntVT = (this.cntVT & 7) | ((address & 3) << 3);\n\n address = this.vramAddress & 0xff;\n this.cntVT = (this.cntVT & 24) | ((address >> 5) & 7);\n this.cntHT = address & 31;\n },\n\n regsToAddress: function() {\n var b1 = (this.regFV & 7) << 4;\n b1 |= (this.regV & 1) << 3;\n b1 |= (this.regH & 1) << 2;\n b1 |= (this.regVT >> 3) & 3;\n\n var b2 = (this.regVT & 7) << 5;\n b2 |= this.regHT & 31;\n\n this.vramTmpAddress = ((b1 << 8) | b2) & 0x7fff;\n },\n\n cntsToAddress: function() {\n var b1 = (this.cntFV & 7) << 4;\n b1 |= (this.cntV & 1) << 3;\n b1 |= (this.cntH & 1) << 2;\n b1 |= (this.cntVT >> 3) & 3;\n\n var b2 = (this.cntVT & 7) << 5;\n b2 |= this.cntHT & 31;\n\n this.vramAddress = ((b1 << 8) | b2) & 0x7fff;\n },\n\n incTileCounter: function(count) {\n for (var i = count; i !== 0; i--) {\n this.cntHT++;\n if (this.cntHT === 32) {\n this.cntHT = 0;\n this.cntVT++;\n if (this.cntVT >= 30) {\n this.cntH++;\n if (this.cntH === 2) {\n this.cntH = 0;\n this.cntV++;\n if (this.cntV === 2) {\n this.cntV = 0;\n this.cntFV++;\n this.cntFV &= 0x7;\n }\n }\n }\n }\n }\n },\n\n // Reads from memory, taking into account\n // mirroring/mapping of address ranges.\n mirroredLoad: function(address) {\n return this.vramMem[this.vramMirrorTable[address]];\n },\n\n // Writes to memory, taking into account\n // mirroring/mapping of address ranges.\n mirroredWrite: function(address, value) {\n if (address >= 0x3f00 && address < 0x3f20) {\n // Palette write mirroring.\n if (address === 0x3f00 || address === 0x3f10) {\n this.writeMem(0x3f00, value);\n this.writeMem(0x3f10, value);\n } else if (address === 0x3f04 || address === 0x3f14) {\n this.writeMem(0x3f04, value);\n this.writeMem(0x3f14, value);\n } else if (address === 0x3f08 || address === 0x3f18) {\n this.writeMem(0x3f08, value);\n this.writeMem(0x3f18, value);\n } else if (address === 0x3f0c || address === 0x3f1c) {\n this.writeMem(0x3f0c, value);\n this.writeMem(0x3f1c, value);\n } else {\n this.writeMem(address, value);\n }\n } else {\n // Use lookup table for mirrored address:\n if (address < this.vramMirrorTable.length) {\n this.writeMem(this.vramMirrorTable[address], value);\n } else {\n throw new Error(\"Invalid VRAM address: \" + address.toString(16));\n }\n }\n },\n\n triggerRendering: function() {\n if (this.scanline >= 21 && this.scanline <= 260) {\n // Render sprites, and combine:\n this.renderFramePartially(\n this.lastRenderedScanline + 1,\n this.scanline - 21 - this.lastRenderedScanline\n );\n\n // Set last rendered scanline:\n this.lastRenderedScanline = this.scanline - 21;\n }\n },\n\n renderFramePartially: function(startScan, scanCount) {\n if (this.f_spVisibility === 1) {\n this.renderSpritesPartially(startScan, scanCount, true);\n }\n\n if (this.f_bgVisibility === 1) {\n var si = startScan << 8;\n var ei = (startScan + scanCount) << 8;\n if (ei > 0xf000) {\n ei = 0xf000;\n }\n var buffer = this.buffer;\n var bgbuffer = this.bgbuffer;\n var pixrendered = this.pixrendered;\n for (var destIndex = si; destIndex < ei; destIndex++) {\n if (pixrendered[destIndex] > 0xff) {\n buffer[destIndex] = bgbuffer[destIndex];\n }\n }\n }\n\n if (this.f_spVisibility === 1) {\n this.renderSpritesPartially(startScan, scanCount, false);\n }\n\n this.validTileData = false;\n },\n\n renderBgScanline: function(bgbuffer, scan) {\n var baseTile = this.regS === 0 ? 0 : 256;\n var destIndex = (scan << 8) - this.regFH;\n\n this.curNt = this.ntable1[this.cntV + this.cntV + this.cntH];\n\n this.cntHT = this.regHT;\n this.cntH = this.regH;\n this.curNt = this.ntable1[this.cntV + this.cntV + this.cntH];\n\n if (scan < 240 && scan - this.cntFV >= 0) {\n var tscanoffset = this.cntFV << 3;\n var scantile = this.scantile;\n var attrib = this.attrib;\n var ptTile = this.ptTile;\n var nameTable = this.nameTable;\n var imgPalette = this.imgPalette;\n var pixrendered = this.pixrendered;\n var targetBuffer = bgbuffer ? this.bgbuffer : this.buffer;\n\n var t, tpix, att, col;\n\n for (var tile = 0; tile < 32; tile++) {\n if (scan >= 0) {\n // Fetch tile & attrib data:\n if (this.validTileData) {\n // Get data from array:\n t = scantile[tile];\n if (typeof t === \"undefined\") {\n continue;\n }\n tpix = t.pix;\n att = attrib[tile];\n } else {\n // Fetch data:\n t =\n ptTile[\n baseTile +\n nameTable[this.curNt].getTileIndex(this.cntHT, this.cntVT)\n ];\n if (typeof t === \"undefined\") {\n continue;\n }\n tpix = t.pix;\n att = nameTable[this.curNt].getAttrib(this.cntHT, this.cntVT);\n scantile[tile] = t;\n attrib[tile] = att;\n }\n\n // Render tile scanline:\n var sx = 0;\n var x = (tile << 3) - this.regFH;\n\n if (x > -8) {\n if (x < 0) {\n destIndex -= x;\n sx = -x;\n }\n if (t.opaque[this.cntFV]) {\n for (; sx < 8; sx++) {\n targetBuffer[destIndex] =\n imgPalette[tpix[tscanoffset + sx] + att];\n pixrendered[destIndex] |= 256;\n destIndex++;\n }\n } else {\n for (; sx < 8; sx++) {\n col = tpix[tscanoffset + sx];\n if (col !== 0) {\n targetBuffer[destIndex] = imgPalette[col + att];\n pixrendered[destIndex] |= 256;\n }\n destIndex++;\n }\n }\n }\n }\n\n // Increase Horizontal Tile Counter:\n if (++this.cntHT === 32) {\n this.cntHT = 0;\n this.cntH++;\n this.cntH %= 2;\n this.curNt = this.ntable1[(this.cntV << 1) + this.cntH];\n }\n }\n\n // Tile data for one row should now have been fetched,\n // so the data in the array is valid.\n this.validTileData = true;\n }\n\n // update vertical scroll:\n this.cntFV++;\n if (this.cntFV === 8) {\n this.cntFV = 0;\n this.cntVT++;\n if (this.cntVT === 30) {\n this.cntVT = 0;\n this.cntV++;\n this.cntV %= 2;\n this.curNt = this.ntable1[(this.cntV << 1) + this.cntH];\n } else if (this.cntVT === 32) {\n this.cntVT = 0;\n }\n\n // Invalidate fetched data:\n this.validTileData = false;\n }\n },\n\n renderSpritesPartially: function(startscan, scancount, bgPri) {\n if (this.f_spVisibility === 1) {\n for (var i = 0; i < 64; i++) {\n if (\n this.bgPriority[i] === bgPri &&\n this.sprX[i] >= 0 &&\n this.sprX[i] < 256 &&\n this.sprY[i] + 8 >= startscan &&\n this.sprY[i] < startscan + scancount\n ) {\n // Show sprite.\n if (this.f_spriteSize === 0) {\n // 8x8 sprites\n\n this.srcy1 = 0;\n this.srcy2 = 8;\n\n if (this.sprY[i] < startscan) {\n this.srcy1 = startscan - this.sprY[i] - 1;\n }\n\n if (this.sprY[i] + 8 > startscan + scancount) {\n this.srcy2 = startscan + scancount - this.sprY[i] + 1;\n }\n\n if (this.f_spPatternTable === 0) {\n this.ptTile[this.sprTile[i]].render(\n this.buffer,\n 0,\n this.srcy1,\n 8,\n this.srcy2,\n this.sprX[i],\n this.sprY[i] + 1,\n this.sprCol[i],\n this.sprPalette,\n this.horiFlip[i],\n this.vertFlip[i],\n i,\n this.pixrendered\n );\n } else {\n this.ptTile[this.sprTile[i] + 256].render(\n this.buffer,\n 0,\n this.srcy1,\n 8,\n this.srcy2,\n this.sprX[i],\n this.sprY[i] + 1,\n this.sprCol[i],\n this.sprPalette,\n this.horiFlip[i],\n this.vertFlip[i],\n i,\n this.pixrendered\n );\n }\n } else {\n // 8x16 sprites\n var top = this.sprTile[i];\n if ((top & 1) !== 0) {\n top = this.sprTile[i] - 1 + 256;\n }\n\n var srcy1 = 0;\n var srcy2 = 8;\n\n if (this.sprY[i] < startscan) {\n srcy1 = startscan - this.sprY[i] - 1;\n }\n\n if (this.sprY[i] + 8 > startscan + scancount) {\n srcy2 = startscan + scancount - this.sprY[i];\n }\n\n this.ptTile[top + (this.vertFlip[i] ? 1 : 0)].render(\n this.buffer,\n 0,\n srcy1,\n 8,\n srcy2,\n this.sprX[i],\n this.sprY[i] + 1,\n this.sprCol[i],\n this.sprPalette,\n this.horiFlip[i],\n this.vertFlip[i],\n i,\n this.pixrendered\n );\n\n srcy1 = 0;\n srcy2 = 8;\n\n if (this.sprY[i] + 8 < startscan) {\n srcy1 = startscan - (this.sprY[i] + 8 + 1);\n }\n\n if (this.sprY[i] + 16 > startscan + scancount) {\n srcy2 = startscan + scancount - (this.sprY[i] + 8);\n }\n\n this.ptTile[top + (this.vertFlip[i] ? 0 : 1)].render(\n this.buffer,\n 0,\n srcy1,\n 8,\n srcy2,\n this.sprX[i],\n this.sprY[i] + 1 + 8,\n this.sprCol[i],\n this.sprPalette,\n this.horiFlip[i],\n this.vertFlip[i],\n i,\n this.pixrendered\n );\n }\n }\n }\n }\n },\n\n checkSprite0: function(scan) {\n this.spr0HitX = -1;\n this.spr0HitY = -1;\n\n var toffset;\n var tIndexAdd = this.f_spPatternTable === 0 ? 0 : 256;\n var x, y, t, i;\n var bufferIndex;\n\n x = this.sprX[0];\n y = this.sprY[0] + 1;\n\n if (this.f_spriteSize === 0) {\n // 8x8 sprites.\n\n // Check range:\n if (y <= scan && y + 8 > scan && x >= -7 && x < 256) {\n // Sprite is in range.\n // Draw scanline:\n t = this.ptTile[this.sprTile[0] + tIndexAdd];\n\n if (this.vertFlip[0]) {\n toffset = 7 - (scan - y);\n } else {\n toffset = scan - y;\n }\n toffset *= 8;\n\n bufferIndex = scan * 256 + x;\n if (this.horiFlip[0]) {\n for (i = 7; i >= 0; i--) {\n if (x >= 0 && x < 256) {\n if (\n bufferIndex >= 0 &&\n bufferIndex < 61440 &&\n this.pixrendered[bufferIndex] !== 0\n ) {\n if (t.pix[toffset + i] !== 0) {\n this.spr0HitX = bufferIndex % 256;\n this.spr0HitY = scan;\n return true;\n }\n }\n }\n x++;\n bufferIndex++;\n }\n } else {\n for (i = 0; i < 8; i++) {\n if (x >= 0 && x < 256) {\n if (\n bufferIndex >= 0 &&\n bufferIndex < 61440 &&\n this.pixrendered[bufferIndex] !== 0\n ) {\n if (t.pix[toffset + i] !== 0) {\n this.spr0HitX = bufferIndex % 256;\n this.spr0HitY = scan;\n return true;\n }\n }\n }\n x++;\n bufferIndex++;\n }\n }\n }\n } else {\n // 8x16 sprites:\n\n // Check range:\n if (y <= scan && y + 16 > scan && x >= -7 && x < 256) {\n // Sprite is in range.\n // Draw scanline:\n\n if (this.vertFlip[0]) {\n toffset = 15 - (scan - y);\n } else {\n toffset = scan - y;\n }\n\n if (toffset < 8) {\n // first half of sprite.\n t = this.ptTile[\n this.sprTile[0] +\n (this.vertFlip[0] ? 1 : 0) +\n ((this.sprTile[0] & 1) !== 0 ? 255 : 0)\n ];\n } else {\n // second half of sprite.\n t = this.ptTile[\n this.sprTile[0] +\n (this.vertFlip[0] ? 0 : 1) +\n ((this.sprTile[0] & 1) !== 0 ? 255 : 0)\n ];\n if (this.vertFlip[0]) {\n toffset = 15 - toffset;\n } else {\n toffset -= 8;\n }\n }\n toffset *= 8;\n\n bufferIndex = scan * 256 + x;\n if (this.horiFlip[0]) {\n for (i = 7; i >= 0; i--) {\n if (x >= 0 && x < 256) {\n if (\n bufferIndex >= 0 &&\n bufferIndex < 61440 &&\n this.pixrendered[bufferIndex] !== 0\n ) {\n if (t.pix[toffset + i] !== 0) {\n this.spr0HitX = bufferIndex % 256;\n this.spr0HitY = scan;\n return true;\n }\n }\n }\n x++;\n bufferIndex++;\n }\n } else {\n for (i = 0; i < 8; i++) {\n if (x >= 0 && x < 256) {\n if (\n bufferIndex >= 0 &&\n bufferIndex < 61440 &&\n this.pixrendered[bufferIndex] !== 0\n ) {\n if (t.pix[toffset + i] !== 0) {\n this.spr0HitX = bufferIndex % 256;\n this.spr0HitY = scan;\n return true;\n }\n }\n }\n x++;\n bufferIndex++;\n }\n }\n }\n }\n\n return false;\n },\n\n // This will write to PPU memory, and\n // update internally buffered data\n // appropriately.\n writeMem: function(address, value) {\n this.vramMem[address] = value;\n\n // Update internally buffered data:\n if (address < 0x2000) {\n this.vramMem[address] = value;\n this.patternWrite(address, value);\n } else if (address >= 0x2000 && address < 0x23c0) {\n this.nameTableWrite(this.ntable1[0], address - 0x2000, value);\n } else if (address >= 0x23c0 && address < 0x2400) {\n this.attribTableWrite(this.ntable1[0], address - 0x23c0, value);\n } else if (address >= 0x2400 && address < 0x27c0) {\n this.nameTableWrite(this.ntable1[1], address - 0x2400, value);\n } else if (address >= 0x27c0 && address < 0x2800) {\n this.attribTableWrite(this.ntable1[1], address - 0x27c0, value);\n } else if (address >= 0x2800 && address < 0x2bc0) {\n this.nameTableWrite(this.ntable1[2], address - 0x2800, value);\n } else if (address >= 0x2bc0 && address < 0x2c00) {\n this.attribTableWrite(this.ntable1[2], address - 0x2bc0, value);\n } else if (address >= 0x2c00 && address < 0x2fc0) {\n this.nameTableWrite(this.ntable1[3], address - 0x2c00, value);\n } else if (address >= 0x2fc0 && address < 0x3000) {\n this.attribTableWrite(this.ntable1[3], address - 0x2fc0, value);\n } else if (address >= 0x3f00 && address < 0x3f20) {\n this.updatePalettes();\n }\n },\n\n // Reads data from $3f00 to $f20\n // into the two buffered palettes.\n updatePalettes: function() {\n var i;\n\n for (i = 0; i < 16; i++) {\n if (this.f_dispType === 0) {\n this.imgPalette[i] = this.palTable.getEntry(\n this.vramMem[0x3f00 + i] & 63\n );\n } else {\n this.imgPalette[i] = this.palTable.getEntry(\n this.vramMem[0x3f00 + i] & 32\n );\n }\n }\n for (i = 0; i < 16; i++) {\n if (this.f_dispType === 0) {\n this.sprPalette[i] = this.palTable.getEntry(\n this.vramMem[0x3f10 + i] & 63\n );\n } else {\n this.sprPalette[i] = this.palTable.getEntry(\n this.vramMem[0x3f10 + i] & 32\n );\n }\n }\n },\n\n // Updates the internal pattern\n // table buffers with this new byte.\n // In vNES, there is a version of this with 4 arguments which isn't used.\n patternWrite: function(address, value) {\n var tileIndex = Math.floor(address / 16);\n var leftOver = address % 16;\n if (leftOver < 8) {\n this.ptTile[tileIndex].setScanline(\n leftOver,\n value,\n this.vramMem[address + 8]\n );\n } else {\n this.ptTile[tileIndex].setScanline(\n leftOver - 8,\n this.vramMem[address - 8],\n value\n );\n }\n },\n\n // Updates the internal name table buffers\n // with this new byte.\n nameTableWrite: function(index, address, value) {\n this.nameTable[index].tile[address] = value;\n\n // Update Sprite #0 hit:\n //updateSpr0Hit();\n this.checkSprite0(this.scanline - 20);\n },\n\n // Updates the internal pattern\n // table buffers with this new attribute\n // table byte.\n attribTableWrite: function(index, address, value) {\n this.nameTable[index].writeAttrib(address, value);\n },\n\n // Updates the internally buffered sprite\n // data with this new byte of info.\n spriteRamWriteUpdate: function(address, value) {\n var tIndex = Math.floor(address / 4);\n\n if (tIndex === 0) {\n //updateSpr0Hit();\n this.checkSprite0(this.scanline - 20);\n }\n\n if (address % 4 === 0) {\n // Y coordinate\n this.sprY[tIndex] = value;\n } else if (address % 4 === 1) {\n // Tile index\n this.sprTile[tIndex] = value;\n } else if (address % 4 === 2) {\n // Attributes\n this.vertFlip[tIndex] = (value & 0x80) !== 0;\n this.horiFlip[tIndex] = (value & 0x40) !== 0;\n this.bgPriority[tIndex] = (value & 0x20) !== 0;\n this.sprCol[tIndex] = (value & 3) << 2;\n } else if (address % 4 === 3) {\n // X coordinate\n this.sprX[tIndex] = value;\n }\n },\n\n doNMI: function() {\n // Set VBlank flag:\n this.setStatusFlag(this.STATUS_VBLANK, true);\n //nes.getCpu().doNonMaskableInterrupt();\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_NMI);\n },\n\n isPixelWhite: function(x, y) {\n this.triggerRendering();\n return this.nes.ppu.buffer[(y << 8) + x] === 0xffffff;\n },\n\n JSON_PROPERTIES: [\n // Memory\n \"vramMem\",\n \"spriteMem\",\n // Counters\n \"cntFV\",\n \"cntV\",\n \"cntH\",\n \"cntVT\",\n \"cntHT\",\n // Registers\n \"regFV\",\n \"regV\",\n \"regH\",\n \"regVT\",\n \"regHT\",\n \"regFH\",\n \"regS\",\n // VRAM addr\n \"vramAddress\",\n \"vramTmpAddress\",\n // Control/Status registers\n \"f_nmiOnVblank\",\n \"f_spriteSize\",\n \"f_bgPatternTable\",\n \"f_spPatternTable\",\n \"f_addrInc\",\n \"f_nTblAddress\",\n \"f_color\",\n \"f_spVisibility\",\n \"f_bgVisibility\",\n \"f_spClipping\",\n \"f_bgClipping\",\n \"f_dispType\",\n // VRAM I/O\n \"vramBufferedReadValue\",\n \"firstWrite\",\n // Mirroring\n \"currentMirroring\",\n \"vramMirrorTable\",\n \"ntable1\",\n // SPR-RAM I/O\n \"sramAddress\",\n // Sprites. Most sprite data is rebuilt from spriteMem\n \"hitSpr0\",\n // Palettes\n \"sprPalette\",\n \"imgPalette\",\n // Rendering progression\n \"curX\",\n \"scanline\",\n \"lastRenderedScanline\",\n \"curNt\",\n \"scantile\",\n // Used during rendering\n \"attrib\",\n \"buffer\",\n \"bgbuffer\",\n \"pixrendered\",\n // Misc\n \"requestEndFrame\",\n \"nmiOk\",\n \"dummyCycleToggle\",\n \"nmiCounter\",\n \"validTileData\",\n \"scanlineAlreadyRendered\"\n ],\n\n toJSON: function() {\n var i;\n var state = utils.toJSON(this);\n\n state.nameTable = [];\n for (i = 0; i < this.nameTable.length; i++) {\n state.nameTable[i] = this.nameTable[i].toJSON();\n }\n\n state.ptTile = [];\n for (i = 0; i < this.ptTile.length; i++) {\n state.ptTile[i] = this.ptTile[i].toJSON();\n }\n\n return state;\n },\n\n fromJSON: function(state) {\n var i;\n\n utils.fromJSON(this, state);\n\n for (i = 0; i < this.nameTable.length; i++) {\n this.nameTable[i].fromJSON(state.nameTable[i]);\n }\n\n for (i = 0; i < this.ptTile.length; i++) {\n this.ptTile[i].fromJSON(state.ptTile[i]);\n }\n\n // Sprite data:\n for (i = 0; i < this.spriteMem.length; i++) {\n this.spriteRamWriteUpdate(i, this.spriteMem[i]);\n }\n }\n};\n\nvar NameTable = function(width, height, name) {\n this.width = width;\n this.height = height;\n this.name = name;\n\n this.tile = new Uint8Array(width * height);\n this.attrib = new Uint8Array(width * height);\n for (var i = 0; i < width * height; i++) {\n this.tile[i] = 0;\n this.attrib[i] = 0;\n }\n};\n\nNameTable.prototype = {\n getTileIndex: function(x, y) {\n return this.tile[y * this.width + x];\n },\n\n getAttrib: function(x, y) {\n return this.attrib[y * this.width + x];\n },\n\n writeAttrib: function(index, value) {\n var basex = (index % 8) * 4;\n var basey = Math.floor(index / 8) * 4;\n var add;\n var tx, ty;\n var attindex;\n\n for (var sqy = 0; sqy < 2; sqy++) {\n for (var sqx = 0; sqx < 2; sqx++) {\n add = (value >> (2 * (sqy * 2 + sqx))) & 3;\n for (var y = 0; y < 2; y++) {\n for (var x = 0; x < 2; x++) {\n tx = basex + sqx * 2 + x;\n ty = basey + sqy * 2 + y;\n attindex = ty * this.width + tx;\n this.attrib[attindex] = (add << 2) & 12;\n }\n }\n }\n }\n },\n\n toJSON: function() {\n return {\n tile: this.tile,\n attrib: this.attrib\n };\n },\n\n fromJSON: function(s) {\n this.tile = s.tile;\n this.attrib = s.attrib;\n }\n};\n\nvar PaletteTable = function() {\n this.curTable = new Uint32Array(64);\n this.emphTable = new Array(8);\n this.currentEmph = -1;\n};\n\nPaletteTable.prototype = {\n reset: function() {\n this.setEmphasis(0);\n },\n\n loadNTSCPalette: function() {\n // prettier-ignore\n this.curTable = new Uint32Array([0x525252, 0xB40000, 0xA00000, 0xB1003D, 0x740069, 0x00005B, 0x00005F, 0x001840, 0x002F10, 0x084A08, 0x006700, 0x124200, 0x6D2800, 0x000000, 0x000000, 0x000000, 0xC4D5E7, 0xFF4000, 0xDC0E22, 0xFF476B, 0xD7009F, 0x680AD7, 0x0019BC, 0x0054B1, 0x006A5B, 0x008C03, 0x00AB00, 0x2C8800, 0xA47200, 0x000000, 0x000000, 0x000000, 0xF8F8F8, 0xFFAB3C, 0xFF7981, 0xFF5BC5, 0xFF48F2, 0xDF49FF, 0x476DFF, 0x00B4F7, 0x00E0FF, 0x00E375, 0x03F42B, 0x78B82E, 0xE5E218, 0x787878, 0x000000, 0x000000, 0xFFFFFF, 0xFFF2BE, 0xF8B8B8, 0xF8B8D8, 0xFFB6FF, 0xFFC3FF, 0xC7D1FF, 0x9ADAFF, 0x88EDF8, 0x83FFDD, 0xB8F8B8, 0xF5F8AC, 0xFFFFB0, 0xF8D8F8, 0x000000, 0x000000]);\n this.makeTables();\n this.setEmphasis(0);\n },\n\n loadPALPalette: function() {\n // prettier-ignore\n this.curTable = new Uint32Array([0x525252, 0xB40000, 0xA00000, 0xB1003D, 0x740069, 0x00005B, 0x00005F, 0x001840, 0x002F10, 0x084A08, 0x006700, 0x124200, 0x6D2800, 0x000000, 0x000000, 0x000000, 0xC4D5E7, 0xFF4000, 0xDC0E22, 0xFF476B, 0xD7009F, 0x680AD7, 0x0019BC, 0x0054B1, 0x006A5B, 0x008C03, 0x00AB00, 0x2C8800, 0xA47200, 0x000000, 0x000000, 0x000000, 0xF8F8F8, 0xFFAB3C, 0xFF7981, 0xFF5BC5, 0xFF48F2, 0xDF49FF, 0x476DFF, 0x00B4F7, 0x00E0FF, 0x00E375, 0x03F42B, 0x78B82E, 0xE5E218, 0x787878, 0x000000, 0x000000, 0xFFFFFF, 0xFFF2BE, 0xF8B8B8, 0xF8B8D8, 0xFFB6FF, 0xFFC3FF, 0xC7D1FF, 0x9ADAFF, 0x88EDF8, 0x83FFDD, 0xB8F8B8, 0xF5F8AC, 0xFFFFB0, 0xF8D8F8, 0x000000, 0x000000]);\n this.makeTables();\n this.setEmphasis(0);\n },\n\n makeTables: function() {\n var r, g, b, col, i, rFactor, gFactor, bFactor;\n\n // Calculate a table for each possible emphasis setting:\n for (var emph = 0; emph < 8; emph++) {\n // Determine color component factors:\n rFactor = 1.0;\n gFactor = 1.0;\n bFactor = 1.0;\n\n if ((emph & 1) !== 0) {\n rFactor = 0.75;\n bFactor = 0.75;\n }\n if ((emph & 2) !== 0) {\n rFactor = 0.75;\n gFactor = 0.75;\n }\n if ((emph & 4) !== 0) {\n gFactor = 0.75;\n bFactor = 0.75;\n }\n\n this.emphTable[emph] = new Uint32Array(64);\n\n // Calculate table:\n for (i = 0; i < 64; i++) {\n col = this.curTable[i];\n r = Math.floor(this.getRed(col) * rFactor);\n g = Math.floor(this.getGreen(col) * gFactor);\n b = Math.floor(this.getBlue(col) * bFactor);\n this.emphTable[emph][i] = this.getRgb(r, g, b);\n }\n }\n },\n\n setEmphasis: function(emph) {\n if (emph !== this.currentEmph) {\n this.currentEmph = emph;\n for (var i = 0; i < 64; i++) {\n this.curTable[i] = this.emphTable[emph][i];\n }\n }\n },\n\n getEntry: function(yiq) {\n return this.curTable[yiq];\n },\n\n getRed: function(rgb) {\n return (rgb >> 16) & 0xff;\n },\n\n getGreen: function(rgb) {\n return (rgb >> 8) & 0xff;\n },\n\n getBlue: function(rgb) {\n return rgb & 0xff;\n },\n\n getRgb: function(r, g, b) {\n return (r << 16) | (g << 8) | b;\n },\n\n loadDefaultPalette: function() {\n this.curTable[0] = this.getRgb(117, 117, 117);\n this.curTable[1] = this.getRgb(39, 27, 143);\n this.curTable[2] = this.getRgb(0, 0, 171);\n this.curTable[3] = this.getRgb(71, 0, 159);\n this.curTable[4] = this.getRgb(143, 0, 119);\n this.curTable[5] = this.getRgb(171, 0, 19);\n this.curTable[6] = this.getRgb(167, 0, 0);\n this.curTable[7] = this.getRgb(127, 11, 0);\n this.curTable[8] = this.getRgb(67, 47, 0);\n this.curTable[9] = this.getRgb(0, 71, 0);\n this.curTable[10] = this.getRgb(0, 81, 0);\n this.curTable[11] = this.getRgb(0, 63, 23);\n this.curTable[12] = this.getRgb(27, 63, 95);\n this.curTable[13] = this.getRgb(0, 0, 0);\n this.curTable[14] = this.getRgb(0, 0, 0);\n this.curTable[15] = this.getRgb(0, 0, 0);\n this.curTable[16] = this.getRgb(188, 188, 188);\n this.curTable[17] = this.getRgb(0, 115, 239);\n this.curTable[18] = this.getRgb(35, 59, 239);\n this.curTable[19] = this.getRgb(131, 0, 243);\n this.curTable[20] = this.getRgb(191, 0, 191);\n this.curTable[21] = this.getRgb(231, 0, 91);\n this.curTable[22] = this.getRgb(219, 43, 0);\n this.curTable[23] = this.getRgb(203, 79, 15);\n this.curTable[24] = this.getRgb(139, 115, 0);\n this.curTable[25] = this.getRgb(0, 151, 0);\n this.curTable[26] = this.getRgb(0, 171, 0);\n this.curTable[27] = this.getRgb(0, 147, 59);\n this.curTable[28] = this.getRgb(0, 131, 139);\n this.curTable[29] = this.getRgb(0, 0, 0);\n this.curTable[30] = this.getRgb(0, 0, 0);\n this.curTable[31] = this.getRgb(0, 0, 0);\n this.curTable[32] = this.getRgb(255, 255, 255);\n this.curTable[33] = this.getRgb(63, 191, 255);\n this.curTable[34] = this.getRgb(95, 151, 255);\n this.curTable[35] = this.getRgb(167, 139, 253);\n this.curTable[36] = this.getRgb(247, 123, 255);\n this.curTable[37] = this.getRgb(255, 119, 183);\n this.curTable[38] = this.getRgb(255, 119, 99);\n this.curTable[39] = this.getRgb(255, 155, 59);\n this.curTable[40] = this.getRgb(243, 191, 63);\n this.curTable[41] = this.getRgb(131, 211, 19);\n this.curTable[42] = this.getRgb(79, 223, 75);\n this.curTable[43] = this.getRgb(88, 248, 152);\n this.curTable[44] = this.getRgb(0, 235, 219);\n this.curTable[45] = this.getRgb(0, 0, 0);\n this.curTable[46] = this.getRgb(0, 0, 0);\n this.curTable[47] = this.getRgb(0, 0, 0);\n this.curTable[48] = this.getRgb(255, 255, 255);\n this.curTable[49] = this.getRgb(171, 231, 255);\n this.curTable[50] = this.getRgb(199, 215, 255);\n this.curTable[51] = this.getRgb(215, 203, 255);\n this.curTable[52] = this.getRgb(255, 199, 255);\n this.curTable[53] = this.getRgb(255, 199, 219);\n this.curTable[54] = this.getRgb(255, 191, 179);\n this.curTable[55] = this.getRgb(255, 219, 171);\n this.curTable[56] = this.getRgb(255, 231, 163);\n this.curTable[57] = this.getRgb(227, 255, 163);\n this.curTable[58] = this.getRgb(171, 243, 191);\n this.curTable[59] = this.getRgb(179, 255, 207);\n this.curTable[60] = this.getRgb(159, 255, 243);\n this.curTable[61] = this.getRgb(0, 0, 0);\n this.curTable[62] = this.getRgb(0, 0, 0);\n this.curTable[63] = this.getRgb(0, 0, 0);\n\n this.makeTables();\n this.setEmphasis(0);\n }\n};\n\nmodule.exports = PPU;\n", "var CPU_FREQ_NTSC = 1789772.5; //1789772.72727272d;\n// var CPU_FREQ_PAL = 1773447.4;\n\nvar PAPU = function(nes) {\n this.nes = nes;\n\n this.square1 = new ChannelSquare(this, true);\n this.square2 = new ChannelSquare(this, false);\n this.triangle = new ChannelTriangle(this);\n this.noise = new ChannelNoise(this);\n this.dmc = new ChannelDM(this);\n\n this.frameIrqCounter = null;\n this.frameIrqCounterMax = 4;\n this.initCounter = 2048;\n this.channelEnableValue = null;\n\n this.sampleRate = 44100;\n\n this.lengthLookup = null;\n this.dmcFreqLookup = null;\n this.noiseWavelengthLookup = null;\n this.square_table = null;\n this.tnd_table = null;\n\n this.frameIrqEnabled = false;\n this.frameIrqActive = null;\n this.frameClockNow = null;\n this.startedPlaying = false;\n this.recordOutput = false;\n this.initingHardware = false;\n\n this.masterFrameCounter = null;\n this.derivedFrameCounter = null;\n this.countSequence = null;\n this.sampleTimer = null;\n this.frameTime = null;\n this.sampleTimerMax = null;\n this.sampleCount = null;\n this.triValue = 0;\n\n this.smpSquare1 = null;\n this.smpSquare2 = null;\n this.smpTriangle = null;\n this.smpDmc = null;\n this.accCount = null;\n\n // DC removal vars:\n this.prevSampleL = 0;\n this.prevSampleR = 0;\n this.smpAccumL = 0;\n this.smpAccumR = 0;\n\n // DAC range:\n this.dacRange = 0;\n this.dcValue = 0;\n\n // Master volume:\n this.masterVolume = 256;\n\n // Stereo positioning:\n this.stereoPosLSquare1 = null;\n this.stereoPosLSquare2 = null;\n this.stereoPosLTriangle = null;\n this.stereoPosLNoise = null;\n this.stereoPosLDMC = null;\n this.stereoPosRSquare1 = null;\n this.stereoPosRSquare2 = null;\n this.stereoPosRTriangle = null;\n this.stereoPosRNoise = null;\n this.stereoPosRDMC = null;\n\n this.extraCycles = null;\n\n this.maxSample = null;\n this.minSample = null;\n\n // Panning:\n this.panning = [80, 170, 100, 150, 128];\n this.setPanning(this.panning);\n\n // Initialize lookup tables:\n this.initLengthLookup();\n this.initDmcFrequencyLookup();\n this.initNoiseWavelengthLookup();\n this.initDACtables();\n\n // Init sound registers:\n for (var i = 0; i < 0x14; i++) {\n if (i === 0x10) {\n this.writeReg(0x4010, 0x10);\n } else {\n this.writeReg(0x4000 + i, 0);\n }\n }\n\n this.reset();\n};\n\nPAPU.prototype = {\n reset: function() {\n this.sampleRate = this.nes.opts.sampleRate;\n this.sampleTimerMax = Math.floor(\n (1024.0 * CPU_FREQ_NTSC * this.nes.opts.preferredFrameRate) /\n (this.sampleRate * 60.0)\n );\n\n this.frameTime = Math.floor(\n (14915.0 * this.nes.opts.preferredFrameRate) / 60.0\n );\n\n this.sampleTimer = 0;\n\n this.updateChannelEnable(0);\n this.masterFrameCounter = 0;\n this.derivedFrameCounter = 0;\n this.countSequence = 0;\n this.sampleCount = 0;\n this.initCounter = 2048;\n this.frameIrqEnabled = false;\n this.initingHardware = false;\n\n this.resetCounter();\n\n this.square1.reset();\n this.square2.reset();\n this.triangle.reset();\n this.noise.reset();\n this.dmc.reset();\n\n this.accCount = 0;\n this.smpSquare1 = 0;\n this.smpSquare2 = 0;\n this.smpTriangle = 0;\n this.smpDmc = 0;\n\n this.frameIrqEnabled = false;\n this.frameIrqCounterMax = 4;\n\n this.channelEnableValue = 0xff;\n this.startedPlaying = false;\n this.prevSampleL = 0;\n this.prevSampleR = 0;\n this.smpAccumL = 0;\n this.smpAccumR = 0;\n\n this.maxSample = -500000;\n this.minSample = 500000;\n },\n\n // eslint-disable-next-line no-unused-vars\n readReg: function(address) {\n // Read 0x4015:\n var tmp = 0;\n tmp |= this.square1.getLengthStatus();\n tmp |= this.square2.getLengthStatus() << 1;\n tmp |= this.triangle.getLengthStatus() << 2;\n tmp |= this.noise.getLengthStatus() << 3;\n tmp |= this.dmc.getLengthStatus() << 4;\n tmp |= (this.frameIrqActive && this.frameIrqEnabled ? 1 : 0) << 6;\n tmp |= this.dmc.getIrqStatus() << 7;\n\n this.frameIrqActive = false;\n this.dmc.irqGenerated = false;\n\n return tmp & 0xffff;\n },\n\n writeReg: function(address, value) {\n if (address >= 0x4000 && address < 0x4004) {\n // Square Wave 1 Control\n this.square1.writeReg(address, value);\n // console.log(\"Square Write\");\n } else if (address >= 0x4004 && address < 0x4008) {\n // Square 2 Control\n this.square2.writeReg(address, value);\n } else if (address >= 0x4008 && address < 0x400c) {\n // Triangle Control\n this.triangle.writeReg(address, value);\n } else if (address >= 0x400c && address <= 0x400f) {\n // Noise Control\n this.noise.writeReg(address, value);\n } else if (address === 0x4010) {\n // DMC Play mode & DMA frequency\n this.dmc.writeReg(address, value);\n } else if (address === 0x4011) {\n // DMC Delta Counter\n this.dmc.writeReg(address, value);\n } else if (address === 0x4012) {\n // DMC Play code starting address\n this.dmc.writeReg(address, value);\n } else if (address === 0x4013) {\n // DMC Play code length\n this.dmc.writeReg(address, value);\n } else if (address === 0x4015) {\n // Channel enable\n this.updateChannelEnable(value);\n\n if (value !== 0 && this.initCounter > 0) {\n // Start hardware initialization\n this.initingHardware = true;\n }\n\n // DMC/IRQ Status\n this.dmc.writeReg(address, value);\n } else if (address === 0x4017) {\n // Frame counter control\n this.countSequence = (value >> 7) & 1;\n this.masterFrameCounter = 0;\n this.frameIrqActive = false;\n\n if (((value >> 6) & 0x1) === 0) {\n this.frameIrqEnabled = true;\n } else {\n this.frameIrqEnabled = false;\n }\n\n if (this.countSequence === 0) {\n // NTSC:\n this.frameIrqCounterMax = 4;\n this.derivedFrameCounter = 4;\n } else {\n // PAL:\n this.frameIrqCounterMax = 5;\n this.derivedFrameCounter = 0;\n this.frameCounterTick();\n }\n }\n },\n\n resetCounter: function() {\n if (this.countSequence === 0) {\n this.derivedFrameCounter = 4;\n } else {\n this.derivedFrameCounter = 0;\n }\n },\n\n // Updates channel enable status.\n // This is done on writes to the\n // channel enable register (0x4015),\n // and when the user enables/disables channels\n // in the GUI.\n updateChannelEnable: function(value) {\n this.channelEnableValue = value & 0xffff;\n this.square1.setEnabled((value & 1) !== 0);\n this.square2.setEnabled((value & 2) !== 0);\n this.triangle.setEnabled((value & 4) !== 0);\n this.noise.setEnabled((value & 8) !== 0);\n this.dmc.setEnabled((value & 16) !== 0);\n },\n\n // Clocks the frame counter. It should be clocked at\n // twice the cpu speed, so the cycles will be\n // divided by 2 for those counters that are\n // clocked at cpu speed.\n clockFrameCounter: function(nCycles) {\n if (this.initCounter > 0) {\n if (this.initingHardware) {\n this.initCounter -= nCycles;\n if (this.initCounter <= 0) {\n this.initingHardware = false;\n }\n return;\n }\n }\n\n // Don't process ticks beyond next sampling:\n nCycles += this.extraCycles;\n var maxCycles = this.sampleTimerMax - this.sampleTimer;\n if (nCycles << 10 > maxCycles) {\n this.extraCycles = ((nCycles << 10) - maxCycles) >> 10;\n nCycles -= this.extraCycles;\n } else {\n this.extraCycles = 0;\n }\n\n var dmc = this.dmc;\n var triangle = this.triangle;\n var square1 = this.square1;\n var square2 = this.square2;\n var noise = this.noise;\n\n // Clock DMC:\n if (dmc.isEnabled) {\n dmc.shiftCounter -= nCycles << 3;\n while (dmc.shiftCounter <= 0 && dmc.dmaFrequency > 0) {\n dmc.shiftCounter += dmc.dmaFrequency;\n dmc.clockDmc();\n }\n }\n\n // Clock Triangle channel Prog timer:\n if (triangle.progTimerMax > 0) {\n triangle.progTimerCount -= nCycles;\n while (triangle.progTimerCount <= 0) {\n triangle.progTimerCount += triangle.progTimerMax + 1;\n if (triangle.linearCounter > 0 && triangle.lengthCounter > 0) {\n triangle.triangleCounter++;\n triangle.triangleCounter &= 0x1f;\n\n if (triangle.isEnabled) {\n if (triangle.triangleCounter >= 0x10) {\n // Normal value.\n triangle.sampleValue = triangle.triangleCounter & 0xf;\n } else {\n // Inverted value.\n triangle.sampleValue = 0xf - (triangle.triangleCounter & 0xf);\n }\n triangle.sampleValue <<= 4;\n }\n }\n }\n }\n\n // Clock Square channel 1 Prog timer:\n square1.progTimerCount -= nCycles;\n if (square1.progTimerCount <= 0) {\n square1.progTimerCount += (square1.progTimerMax + 1) << 1;\n\n square1.squareCounter++;\n square1.squareCounter &= 0x7;\n square1.updateSampleValue();\n }\n\n // Clock Square channel 2 Prog timer:\n square2.progTimerCount -= nCycles;\n if (square2.progTimerCount <= 0) {\n square2.progTimerCount += (square2.progTimerMax + 1) << 1;\n\n square2.squareCounter++;\n square2.squareCounter &= 0x7;\n square2.updateSampleValue();\n }\n\n // Clock noise channel Prog timer:\n var acc_c = nCycles;\n if (noise.progTimerCount - acc_c > 0) {\n // Do all cycles at once:\n noise.progTimerCount -= acc_c;\n noise.accCount += acc_c;\n noise.accValue += acc_c * noise.sampleValue;\n } else {\n // Slow-step:\n while (acc_c-- > 0) {\n if (--noise.progTimerCount <= 0 && noise.progTimerMax > 0) {\n // Update noise shift register:\n noise.shiftReg <<= 1;\n noise.tmp =\n ((noise.shiftReg << (noise.randomMode === 0 ? 1 : 6)) ^\n noise.shiftReg) &\n 0x8000;\n if (noise.tmp !== 0) {\n // Sample value must be 0.\n noise.shiftReg |= 0x01;\n noise.randomBit = 0;\n noise.sampleValue = 0;\n } else {\n // Find sample value:\n noise.randomBit = 1;\n if (noise.isEnabled && noise.lengthCounter > 0) {\n noise.sampleValue = noise.masterVolume;\n } else {\n noise.sampleValue = 0;\n }\n }\n\n noise.progTimerCount += noise.progTimerMax;\n }\n\n noise.accValue += noise.sampleValue;\n noise.accCount++;\n }\n }\n\n // Frame IRQ handling:\n if (this.frameIrqEnabled && this.frameIrqActive) {\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_NORMAL);\n }\n\n // Clock frame counter at double CPU speed:\n this.masterFrameCounter += nCycles << 1;\n if (this.masterFrameCounter >= this.frameTime) {\n // 240Hz tick:\n this.masterFrameCounter -= this.frameTime;\n this.frameCounterTick();\n }\n\n // Accumulate sample value:\n this.accSample(nCycles);\n\n // Clock sample timer:\n this.sampleTimer += nCycles << 10;\n if (this.sampleTimer >= this.sampleTimerMax) {\n // Sample channels:\n this.sample();\n this.sampleTimer -= this.sampleTimerMax;\n }\n },\n\n accSample: function(cycles) {\n // Special treatment for triangle channel - need to interpolate.\n if (this.triangle.sampleCondition) {\n this.triValue = Math.floor(\n (this.triangle.progTimerCount << 4) / (this.triangle.progTimerMax + 1)\n );\n if (this.triValue > 16) {\n this.triValue = 16;\n }\n if (this.triangle.triangleCounter >= 16) {\n this.triValue = 16 - this.triValue;\n }\n\n // Add non-interpolated sample value:\n this.triValue += this.triangle.sampleValue;\n }\n\n // Now sample normally:\n if (cycles === 2) {\n this.smpTriangle += this.triValue << 1;\n this.smpDmc += this.dmc.sample << 1;\n this.smpSquare1 += this.square1.sampleValue << 1;\n this.smpSquare2 += this.square2.sampleValue << 1;\n this.accCount += 2;\n } else if (cycles === 4) {\n this.smpTriangle += this.triValue << 2;\n this.smpDmc += this.dmc.sample << 2;\n this.smpSquare1 += this.square1.sampleValue << 2;\n this.smpSquare2 += this.square2.sampleValue << 2;\n this.accCount += 4;\n } else {\n this.smpTriangle += cycles * this.triValue;\n this.smpDmc += cycles * this.dmc.sample;\n this.smpSquare1 += cycles * this.square1.sampleValue;\n this.smpSquare2 += cycles * this.square2.sampleValue;\n this.accCount += cycles;\n }\n },\n\n frameCounterTick: function() {\n this.derivedFrameCounter++;\n if (this.derivedFrameCounter >= this.frameIrqCounterMax) {\n this.derivedFrameCounter = 0;\n }\n\n if (this.derivedFrameCounter === 1 || this.derivedFrameCounter === 3) {\n // Clock length & sweep:\n this.triangle.clockLengthCounter();\n this.square1.clockLengthCounter();\n this.square2.clockLengthCounter();\n this.noise.clockLengthCounter();\n this.square1.clockSweep();\n this.square2.clockSweep();\n }\n\n if (this.derivedFrameCounter >= 0 && this.derivedFrameCounter < 4) {\n // Clock linear & decay:\n this.square1.clockEnvDecay();\n this.square2.clockEnvDecay();\n this.noise.clockEnvDecay();\n this.triangle.clockLinearCounter();\n }\n\n if (this.derivedFrameCounter === 3 && this.countSequence === 0) {\n // Enable IRQ:\n this.frameIrqActive = true;\n }\n\n // End of 240Hz tick\n },\n\n // Samples the channels, mixes the output together, then writes to buffer.\n sample: function() {\n var sq_index, tnd_index;\n\n if (this.accCount > 0) {\n this.smpSquare1 <<= 4;\n this.smpSquare1 = Math.floor(this.smpSquare1 / this.accCount);\n\n this.smpSquare2 <<= 4;\n this.smpSquare2 = Math.floor(this.smpSquare2 / this.accCount);\n\n this.smpTriangle = Math.floor(this.smpTriangle / this.accCount);\n\n this.smpDmc <<= 4;\n this.smpDmc = Math.floor(this.smpDmc / this.accCount);\n\n this.accCount = 0;\n } else {\n this.smpSquare1 = this.square1.sampleValue << 4;\n this.smpSquare2 = this.square2.sampleValue << 4;\n this.smpTriangle = this.triangle.sampleValue;\n this.smpDmc = this.dmc.sample << 4;\n }\n\n var smpNoise = Math.floor((this.noise.accValue << 4) / this.noise.accCount);\n this.noise.accValue = smpNoise >> 4;\n this.noise.accCount = 1;\n\n // Stereo sound.\n\n // Left channel:\n sq_index =\n (this.smpSquare1 * this.stereoPosLSquare1 +\n this.smpSquare2 * this.stereoPosLSquare2) >>\n 8;\n tnd_index =\n (3 * this.smpTriangle * this.stereoPosLTriangle +\n (smpNoise << 1) * this.stereoPosLNoise +\n this.smpDmc * this.stereoPosLDMC) >>\n 8;\n if (sq_index >= this.square_table.length) {\n sq_index = this.square_table.length - 1;\n }\n if (tnd_index >= this.tnd_table.length) {\n tnd_index = this.tnd_table.length - 1;\n }\n var sampleValueL =\n this.square_table[sq_index] + this.tnd_table[tnd_index] - this.dcValue;\n\n // Right channel:\n sq_index =\n (this.smpSquare1 * this.stereoPosRSquare1 +\n this.smpSquare2 * this.stereoPosRSquare2) >>\n 8;\n tnd_index =\n (3 * this.smpTriangle * this.stereoPosRTriangle +\n (smpNoise << 1) * this.stereoPosRNoise +\n this.smpDmc * this.stereoPosRDMC) >>\n 8;\n if (sq_index >= this.square_table.length) {\n sq_index = this.square_table.length - 1;\n }\n if (tnd_index >= this.tnd_table.length) {\n tnd_index = this.tnd_table.length - 1;\n }\n var sampleValueR =\n this.square_table[sq_index] + this.tnd_table[tnd_index] - this.dcValue;\n\n // Remove DC from left channel:\n var smpDiffL = sampleValueL - this.prevSampleL;\n this.prevSampleL += smpDiffL;\n this.smpAccumL += smpDiffL - (this.smpAccumL >> 10);\n sampleValueL = this.smpAccumL;\n\n // Remove DC from right channel:\n var smpDiffR = sampleValueR - this.prevSampleR;\n this.prevSampleR += smpDiffR;\n this.smpAccumR += smpDiffR - (this.smpAccumR >> 10);\n sampleValueR = this.smpAccumR;\n\n // Write:\n if (sampleValueL > this.maxSample) {\n this.maxSample = sampleValueL;\n }\n if (sampleValueL < this.minSample) {\n this.minSample = sampleValueL;\n }\n\n if (this.nes.opts.onAudioSample) {\n this.nes.opts.onAudioSample(sampleValueL / 32768, sampleValueR / 32768);\n }\n\n // Reset sampled values:\n this.smpSquare1 = 0;\n this.smpSquare2 = 0;\n this.smpTriangle = 0;\n this.smpDmc = 0;\n },\n\n getLengthMax: function(value) {\n return this.lengthLookup[value >> 3];\n },\n\n getDmcFrequency: function(value) {\n if (value >= 0 && value < 0x10) {\n return this.dmcFreqLookup[value];\n }\n return 0;\n },\n\n getNoiseWaveLength: function(value) {\n if (value >= 0 && value < 0x10) {\n return this.noiseWavelengthLookup[value];\n }\n return 0;\n },\n\n setPanning: function(pos) {\n for (var i = 0; i < 5; i++) {\n this.panning[i] = pos[i];\n }\n this.updateStereoPos();\n },\n\n setMasterVolume: function(value) {\n if (value < 0) {\n value = 0;\n }\n if (value > 256) {\n value = 256;\n }\n this.masterVolume = value;\n this.updateStereoPos();\n },\n\n updateStereoPos: function() {\n this.stereoPosLSquare1 = (this.panning[0] * this.masterVolume) >> 8;\n this.stereoPosLSquare2 = (this.panning[1] * this.masterVolume) >> 8;\n this.stereoPosLTriangle = (this.panning[2] * this.masterVolume) >> 8;\n this.stereoPosLNoise = (this.panning[3] * this.masterVolume) >> 8;\n this.stereoPosLDMC = (this.panning[4] * this.masterVolume) >> 8;\n\n this.stereoPosRSquare1 = this.masterVolume - this.stereoPosLSquare1;\n this.stereoPosRSquare2 = this.masterVolume - this.stereoPosLSquare2;\n this.stereoPosRTriangle = this.masterVolume - this.stereoPosLTriangle;\n this.stereoPosRNoise = this.masterVolume - this.stereoPosLNoise;\n this.stereoPosRDMC = this.masterVolume - this.stereoPosLDMC;\n },\n\n initLengthLookup: function() {\n // prettier-ignore\n this.lengthLookup = [\n 0x0A, 0xFE,\n 0x14, 0x02,\n 0x28, 0x04,\n 0x50, 0x06,\n 0xA0, 0x08,\n 0x3C, 0x0A,\n 0x0E, 0x0C,\n 0x1A, 0x0E,\n 0x0C, 0x10,\n 0x18, 0x12,\n 0x30, 0x14,\n 0x60, 0x16,\n 0xC0, 0x18,\n 0x48, 0x1A,\n 0x10, 0x1C,\n 0x20, 0x1E\n ];\n },\n\n initDmcFrequencyLookup: function() {\n this.dmcFreqLookup = new Array(16);\n\n this.dmcFreqLookup[0x0] = 0xd60;\n this.dmcFreqLookup[0x1] = 0xbe0;\n this.dmcFreqLookup[0x2] = 0xaa0;\n this.dmcFreqLookup[0x3] = 0xa00;\n this.dmcFreqLookup[0x4] = 0x8f0;\n this.dmcFreqLookup[0x5] = 0x7f0;\n this.dmcFreqLookup[0x6] = 0x710;\n this.dmcFreqLookup[0x7] = 0x6b0;\n this.dmcFreqLookup[0x8] = 0x5f0;\n this.dmcFreqLookup[0x9] = 0x500;\n this.dmcFreqLookup[0xa] = 0x470;\n this.dmcFreqLookup[0xb] = 0x400;\n this.dmcFreqLookup[0xc] = 0x350;\n this.dmcFreqLookup[0xd] = 0x2a0;\n this.dmcFreqLookup[0xe] = 0x240;\n this.dmcFreqLookup[0xf] = 0x1b0;\n //for(int i=0;i<16;i++)dmcFreqLookup[i]/=8;\n },\n\n initNoiseWavelengthLookup: function() {\n this.noiseWavelengthLookup = new Array(16);\n\n this.noiseWavelengthLookup[0x0] = 0x004;\n this.noiseWavelengthLookup[0x1] = 0x008;\n this.noiseWavelengthLookup[0x2] = 0x010;\n this.noiseWavelengthLookup[0x3] = 0x020;\n this.noiseWavelengthLookup[0x4] = 0x040;\n this.noiseWavelengthLookup[0x5] = 0x060;\n this.noiseWavelengthLookup[0x6] = 0x080;\n this.noiseWavelengthLookup[0x7] = 0x0a0;\n this.noiseWavelengthLookup[0x8] = 0x0ca;\n this.noiseWavelengthLookup[0x9] = 0x0fe;\n this.noiseWavelengthLookup[0xa] = 0x17c;\n this.noiseWavelengthLookup[0xb] = 0x1fc;\n this.noiseWavelengthLookup[0xc] = 0x2fa;\n this.noiseWavelengthLookup[0xd] = 0x3f8;\n this.noiseWavelengthLookup[0xe] = 0x7f2;\n this.noiseWavelengthLookup[0xf] = 0xfe4;\n },\n\n initDACtables: function() {\n var value, ival, i;\n var max_sqr = 0;\n var max_tnd = 0;\n\n this.square_table = new Float32Array(32 * 16);\n this.tnd_table = new Float32Array(204 * 16);\n\n for (i = 0; i < 32 * 16; i++) {\n value = 95.52 / (8128.0 / (i / 16.0) + 100.0);\n value *= 0.98411;\n value *= 50000.0;\n ival = Math.floor(value);\n\n this.square_table[i] = ival;\n if (ival > max_sqr) {\n max_sqr = ival;\n }\n }\n\n for (i = 0; i < 204 * 16; i++) {\n value = 163.67 / (24329.0 / (i / 16.0) + 100.0);\n value *= 0.98411;\n value *= 50000.0;\n ival = Math.floor(value);\n\n this.tnd_table[i] = ival;\n if (ival > max_tnd) {\n max_tnd = ival;\n }\n }\n\n this.dacRange = max_sqr + max_tnd;\n this.dcValue = this.dacRange / 2;\n }\n};\n\nvar ChannelDM = function(papu) {\n this.papu = papu;\n\n this.MODE_NORMAL = 0;\n this.MODE_LOOP = 1;\n this.MODE_IRQ = 2;\n\n this.isEnabled = null;\n this.hasSample = null;\n this.irqGenerated = false;\n\n this.playMode = null;\n this.dmaFrequency = null;\n this.dmaCounter = null;\n this.deltaCounter = null;\n this.playStartAddress = null;\n this.playAddress = null;\n this.playLength = null;\n this.playLengthCounter = null;\n this.shiftCounter = null;\n this.reg4012 = null;\n this.reg4013 = null;\n this.sample = null;\n this.dacLsb = null;\n this.data = null;\n\n this.reset();\n};\n\nChannelDM.prototype = {\n clockDmc: function() {\n // Only alter DAC value if the sample buffer has data:\n if (this.hasSample) {\n if ((this.data & 1) === 0) {\n // Decrement delta:\n if (this.deltaCounter > 0) {\n this.deltaCounter--;\n }\n } else {\n // Increment delta:\n if (this.deltaCounter < 63) {\n this.deltaCounter++;\n }\n }\n\n // Update sample value:\n this.sample = this.isEnabled ? (this.deltaCounter << 1) + this.dacLsb : 0;\n\n // Update shift register:\n this.data >>= 1;\n }\n\n this.dmaCounter--;\n if (this.dmaCounter <= 0) {\n // No more sample bits.\n this.hasSample = false;\n this.endOfSample();\n this.dmaCounter = 8;\n }\n\n if (this.irqGenerated) {\n this.papu.nes.cpu.requestIrq(this.papu.nes.cpu.IRQ_NORMAL);\n }\n },\n\n endOfSample: function() {\n if (this.playLengthCounter === 0 && this.playMode === this.MODE_LOOP) {\n // Start from beginning of sample:\n this.playAddress = this.playStartAddress;\n this.playLengthCounter = this.playLength;\n }\n\n if (this.playLengthCounter > 0) {\n // Fetch next sample:\n this.nextSample();\n\n if (this.playLengthCounter === 0) {\n // Last byte of sample fetched, generate IRQ:\n if (this.playMode === this.MODE_IRQ) {\n // Generate IRQ:\n this.irqGenerated = true;\n }\n }\n }\n },\n\n nextSample: function() {\n // Fetch byte:\n this.data = this.papu.nes.mmap.load(this.playAddress);\n this.papu.nes.cpu.haltCycles(4);\n\n this.playLengthCounter--;\n this.playAddress++;\n if (this.playAddress > 0xffff) {\n this.playAddress = 0x8000;\n }\n\n this.hasSample = true;\n },\n\n writeReg: function(address, value) {\n if (address === 0x4010) {\n // Play mode, DMA Frequency\n if (value >> 6 === 0) {\n this.playMode = this.MODE_NORMAL;\n } else if (((value >> 6) & 1) === 1) {\n this.playMode = this.MODE_LOOP;\n } else if (value >> 6 === 2) {\n this.playMode = this.MODE_IRQ;\n }\n\n if ((value & 0x80) === 0) {\n this.irqGenerated = false;\n }\n\n this.dmaFrequency = this.papu.getDmcFrequency(value & 0xf);\n } else if (address === 0x4011) {\n // Delta counter load register:\n this.deltaCounter = (value >> 1) & 63;\n this.dacLsb = value & 1;\n this.sample = (this.deltaCounter << 1) + this.dacLsb; // update sample value\n } else if (address === 0x4012) {\n // DMA address load register\n this.playStartAddress = (value << 6) | 0x0c000;\n this.playAddress = this.playStartAddress;\n this.reg4012 = value;\n } else if (address === 0x4013) {\n // Length of play code\n this.playLength = (value << 4) + 1;\n this.playLengthCounter = this.playLength;\n this.reg4013 = value;\n } else if (address === 0x4015) {\n // DMC/IRQ Status\n if (((value >> 4) & 1) === 0) {\n // Disable:\n this.playLengthCounter = 0;\n } else {\n // Restart:\n this.playAddress = this.playStartAddress;\n this.playLengthCounter = this.playLength;\n }\n this.irqGenerated = false;\n }\n },\n\n setEnabled: function(value) {\n if (!this.isEnabled && value) {\n this.playLengthCounter = this.playLength;\n }\n this.isEnabled = value;\n },\n\n getLengthStatus: function() {\n return this.playLengthCounter === 0 || !this.isEnabled ? 0 : 1;\n },\n\n getIrqStatus: function() {\n return this.irqGenerated ? 1 : 0;\n },\n\n reset: function() {\n this.isEnabled = false;\n this.irqGenerated = false;\n this.playMode = this.MODE_NORMAL;\n this.dmaFrequency = 0;\n this.dmaCounter = 0;\n this.deltaCounter = 0;\n this.playStartAddress = 0;\n this.playAddress = 0;\n this.playLength = 0;\n this.playLengthCounter = 0;\n this.sample = 0;\n this.dacLsb = 0;\n this.shiftCounter = 0;\n this.reg4012 = 0;\n this.reg4013 = 0;\n this.data = 0;\n }\n};\n\nvar ChannelNoise = function(papu) {\n this.papu = papu;\n\n this.isEnabled = null;\n this.envDecayDisable = null;\n this.envDecayLoopEnable = null;\n this.lengthCounterEnable = null;\n this.envReset = null;\n this.shiftNow = null;\n\n this.lengthCounter = null;\n this.progTimerCount = null;\n this.progTimerMax = null;\n this.envDecayRate = null;\n this.envDecayCounter = null;\n this.envVolume = null;\n this.masterVolume = null;\n this.shiftReg = 1 << 14;\n this.randomBit = null;\n this.randomMode = null;\n this.sampleValue = null;\n this.accValue = 0;\n this.accCount = 1;\n this.tmp = null;\n\n this.reset();\n};\n\nChannelNoise.prototype = {\n reset: function() {\n this.progTimerCount = 0;\n this.progTimerMax = 0;\n this.isEnabled = false;\n this.lengthCounter = 0;\n this.lengthCounterEnable = false;\n this.envDecayDisable = false;\n this.envDecayLoopEnable = false;\n this.shiftNow = false;\n this.envDecayRate = 0;\n this.envDecayCounter = 0;\n this.envVolume = 0;\n this.masterVolume = 0;\n this.shiftReg = 1;\n this.randomBit = 0;\n this.randomMode = 0;\n this.sampleValue = 0;\n this.tmp = 0;\n },\n\n clockLengthCounter: function() {\n if (this.lengthCounterEnable && this.lengthCounter > 0) {\n this.lengthCounter--;\n if (this.lengthCounter === 0) {\n this.updateSampleValue();\n }\n }\n },\n\n clockEnvDecay: function() {\n if (this.envReset) {\n // Reset envelope:\n this.envReset = false;\n this.envDecayCounter = this.envDecayRate + 1;\n this.envVolume = 0xf;\n } else if (--this.envDecayCounter <= 0) {\n // Normal handling:\n this.envDecayCounter = this.envDecayRate + 1;\n if (this.envVolume > 0) {\n this.envVolume--;\n } else {\n this.envVolume = this.envDecayLoopEnable ? 0xf : 0;\n }\n }\n if (this.envDecayDisable) {\n this.masterVolume = this.envDecayRate;\n } else {\n this.masterVolume = this.envVolume;\n }\n this.updateSampleValue();\n },\n\n updateSampleValue: function() {\n if (this.isEnabled && this.lengthCounter > 0) {\n this.sampleValue = this.randomBit * this.masterVolume;\n }\n },\n\n writeReg: function(address, value) {\n if (address === 0x400c) {\n // Volume/Envelope decay:\n this.envDecayDisable = (value & 0x10) !== 0;\n this.envDecayRate = value & 0xf;\n this.envDecayLoopEnable = (value & 0x20) !== 0;\n this.lengthCounterEnable = (value & 0x20) === 0;\n if (this.envDecayDisable) {\n this.masterVolume = this.envDecayRate;\n } else {\n this.masterVolume = this.envVolume;\n }\n } else if (address === 0x400e) {\n // Programmable timer:\n this.progTimerMax = this.papu.getNoiseWaveLength(value & 0xf);\n this.randomMode = value >> 7;\n } else if (address === 0x400f) {\n // Length counter\n this.lengthCounter = this.papu.getLengthMax(value & 248);\n this.envReset = true;\n }\n // Update:\n //updateSampleValue();\n },\n\n setEnabled: function(value) {\n this.isEnabled = value;\n if (!value) {\n this.lengthCounter = 0;\n }\n this.updateSampleValue();\n },\n\n getLengthStatus: function() {\n return this.lengthCounter === 0 || !this.isEnabled ? 0 : 1;\n }\n};\n\nvar ChannelSquare = function(papu, square1) {\n this.papu = papu;\n\n // prettier-ignore\n this.dutyLookup = [\n 0, 1, 0, 0, 0, 0, 0, 0,\n 0, 1, 1, 0, 0, 0, 0, 0,\n 0, 1, 1, 1, 1, 0, 0, 0,\n 1, 0, 0, 1, 1, 1, 1, 1\n ];\n // prettier-ignore\n this.impLookup = [\n 1,-1, 0, 0, 0, 0, 0, 0,\n 1, 0,-1, 0, 0, 0, 0, 0,\n 1, 0, 0, 0,-1, 0, 0, 0,\n -1, 0, 1, 0, 0, 0, 0, 0\n ];\n\n this.sqr1 = square1;\n this.isEnabled = null;\n this.lengthCounterEnable = null;\n this.sweepActive = null;\n this.envDecayDisable = null;\n this.envDecayLoopEnable = null;\n this.envReset = null;\n this.sweepCarry = null;\n this.updateSweepPeriod = null;\n\n this.progTimerCount = null;\n this.progTimerMax = null;\n this.lengthCounter = null;\n this.squareCounter = null;\n this.sweepCounter = null;\n this.sweepCounterMax = null;\n this.sweepMode = null;\n this.sweepShiftAmount = null;\n this.envDecayRate = null;\n this.envDecayCounter = null;\n this.envVolume = null;\n this.masterVolume = null;\n this.dutyMode = null;\n this.sweepResult = null;\n this.sampleValue = null;\n this.vol = null;\n\n this.reset();\n};\n\nChannelSquare.prototype = {\n reset: function() {\n this.progTimerCount = 0;\n this.progTimerMax = 0;\n this.lengthCounter = 0;\n this.squareCounter = 0;\n this.sweepCounter = 0;\n this.sweepCounterMax = 0;\n this.sweepMode = 0;\n this.sweepShiftAmount = 0;\n this.envDecayRate = 0;\n this.envDecayCounter = 0;\n this.envVolume = 0;\n this.masterVolume = 0;\n this.dutyMode = 0;\n this.vol = 0;\n\n this.isEnabled = false;\n this.lengthCounterEnable = false;\n this.sweepActive = false;\n this.sweepCarry = false;\n this.envDecayDisable = false;\n this.envDecayLoopEnable = false;\n },\n\n clockLengthCounter: function() {\n if (this.lengthCounterEnable && this.lengthCounter > 0) {\n this.lengthCounter--;\n if (this.lengthCounter === 0) {\n this.updateSampleValue();\n }\n }\n },\n\n clockEnvDecay: function() {\n if (this.envReset) {\n // Reset envelope:\n this.envReset = false;\n this.envDecayCounter = this.envDecayRate + 1;\n this.envVolume = 0xf;\n } else if (--this.envDecayCounter <= 0) {\n // Normal handling:\n this.envDecayCounter = this.envDecayRate + 1;\n if (this.envVolume > 0) {\n this.envVolume--;\n } else {\n this.envVolume = this.envDecayLoopEnable ? 0xf : 0;\n }\n }\n\n if (this.envDecayDisable) {\n this.masterVolume = this.envDecayRate;\n } else {\n this.masterVolume = this.envVolume;\n }\n this.updateSampleValue();\n },\n\n clockSweep: function() {\n if (--this.sweepCounter <= 0) {\n this.sweepCounter = this.sweepCounterMax + 1;\n if (\n this.sweepActive &&\n this.sweepShiftAmount > 0 &&\n this.progTimerMax > 7\n ) {\n // Calculate result from shifter:\n this.sweepCarry = false;\n if (this.sweepMode === 0) {\n this.progTimerMax += this.progTimerMax >> this.sweepShiftAmount;\n if (this.progTimerMax > 4095) {\n this.progTimerMax = 4095;\n this.sweepCarry = true;\n }\n } else {\n this.progTimerMax =\n this.progTimerMax -\n ((this.progTimerMax >> this.sweepShiftAmount) -\n (this.sqr1 ? 1 : 0));\n }\n }\n }\n\n if (this.updateSweepPeriod) {\n this.updateSweepPeriod = false;\n this.sweepCounter = this.sweepCounterMax + 1;\n }\n },\n\n updateSampleValue: function() {\n if (this.isEnabled && this.lengthCounter > 0 && this.progTimerMax > 7) {\n if (\n this.sweepMode === 0 &&\n this.progTimerMax + (this.progTimerMax >> this.sweepShiftAmount) > 4095\n ) {\n //if (this.sweepCarry) {\n this.sampleValue = 0;\n } else {\n this.sampleValue =\n this.masterVolume *\n this.dutyLookup[(this.dutyMode << 3) + this.squareCounter];\n }\n } else {\n this.sampleValue = 0;\n }\n },\n\n writeReg: function(address, value) {\n var addrAdd = this.sqr1 ? 0 : 4;\n if (address === 0x4000 + addrAdd) {\n // Volume/Envelope decay:\n this.envDecayDisable = (value & 0x10) !== 0;\n this.envDecayRate = value & 0xf;\n this.envDecayLoopEnable = (value & 0x20) !== 0;\n this.dutyMode = (value >> 6) & 0x3;\n this.lengthCounterEnable = (value & 0x20) === 0;\n if (this.envDecayDisable) {\n this.masterVolume = this.envDecayRate;\n } else {\n this.masterVolume = this.envVolume;\n }\n this.updateSampleValue();\n } else if (address === 0x4001 + addrAdd) {\n // Sweep:\n this.sweepActive = (value & 0x80) !== 0;\n this.sweepCounterMax = (value >> 4) & 7;\n this.sweepMode = (value >> 3) & 1;\n this.sweepShiftAmount = value & 7;\n this.updateSweepPeriod = true;\n } else if (address === 0x4002 + addrAdd) {\n // Programmable timer:\n this.progTimerMax &= 0x700;\n this.progTimerMax |= value;\n } else if (address === 0x4003 + addrAdd) {\n // Programmable timer, length counter\n this.progTimerMax &= 0xff;\n this.progTimerMax |= (value & 0x7) << 8;\n\n if (this.isEnabled) {\n this.lengthCounter = this.papu.getLengthMax(value & 0xf8);\n }\n\n this.envReset = true;\n }\n },\n\n setEnabled: function(value) {\n this.isEnabled = value;\n if (!value) {\n this.lengthCounter = 0;\n }\n this.updateSampleValue();\n },\n\n getLengthStatus: function() {\n return this.lengthCounter === 0 || !this.isEnabled ? 0 : 1;\n }\n};\n\nvar ChannelTriangle = function(papu) {\n this.papu = papu;\n\n this.isEnabled = null;\n this.sampleCondition = null;\n this.lengthCounterEnable = null;\n this.lcHalt = null;\n this.lcControl = null;\n\n this.progTimerCount = null;\n this.progTimerMax = null;\n this.triangleCounter = null;\n this.lengthCounter = null;\n this.linearCounter = null;\n this.lcLoadValue = null;\n this.sampleValue = null;\n this.tmp = null;\n\n this.reset();\n};\n\nChannelTriangle.prototype = {\n reset: function() {\n this.progTimerCount = 0;\n this.progTimerMax = 0;\n this.triangleCounter = 0;\n this.isEnabled = false;\n this.sampleCondition = false;\n this.lengthCounter = 0;\n this.lengthCounterEnable = false;\n this.linearCounter = 0;\n this.lcLoadValue = 0;\n this.lcHalt = true;\n this.lcControl = false;\n this.tmp = 0;\n this.sampleValue = 0xf;\n },\n\n clockLengthCounter: function() {\n if (this.lengthCounterEnable && this.lengthCounter > 0) {\n this.lengthCounter--;\n if (this.lengthCounter === 0) {\n this.updateSampleCondition();\n }\n }\n },\n\n clockLinearCounter: function() {\n if (this.lcHalt) {\n // Load:\n this.linearCounter = this.lcLoadValue;\n this.updateSampleCondition();\n } else if (this.linearCounter > 0) {\n // Decrement:\n this.linearCounter--;\n this.updateSampleCondition();\n }\n if (!this.lcControl) {\n // Clear halt flag:\n this.lcHalt = false;\n }\n },\n\n getLengthStatus: function() {\n return this.lengthCounter === 0 || !this.isEnabled ? 0 : 1;\n },\n\n // eslint-disable-next-line no-unused-vars\n readReg: function(address) {\n return 0;\n },\n\n writeReg: function(address, value) {\n if (address === 0x4008) {\n // New values for linear counter:\n this.lcControl = (value & 0x80) !== 0;\n this.lcLoadValue = value & 0x7f;\n\n // Length counter enable:\n this.lengthCounterEnable = !this.lcControl;\n } else if (address === 0x400a) {\n // Programmable timer:\n this.progTimerMax &= 0x700;\n this.progTimerMax |= value;\n } else if (address === 0x400b) {\n // Programmable timer, length counter\n this.progTimerMax &= 0xff;\n this.progTimerMax |= (value & 0x07) << 8;\n this.lengthCounter = this.papu.getLengthMax(value & 0xf8);\n this.lcHalt = true;\n }\n\n this.updateSampleCondition();\n },\n\n clockProgrammableTimer: function(nCycles) {\n if (this.progTimerMax > 0) {\n this.progTimerCount += nCycles;\n while (\n this.progTimerMax > 0 &&\n this.progTimerCount >= this.progTimerMax\n ) {\n this.progTimerCount -= this.progTimerMax;\n if (\n this.isEnabled &&\n this.lengthCounter > 0 &&\n this.linearCounter > 0\n ) {\n this.clockTriangleGenerator();\n }\n }\n }\n },\n\n clockTriangleGenerator: function() {\n this.triangleCounter++;\n this.triangleCounter &= 0x1f;\n },\n\n setEnabled: function(value) {\n this.isEnabled = value;\n if (!value) {\n this.lengthCounter = 0;\n }\n this.updateSampleCondition();\n },\n\n updateSampleCondition: function() {\n this.sampleCondition =\n this.isEnabled &&\n this.progTimerMax > 7 &&\n this.linearCounter > 0 &&\n this.lengthCounter > 0;\n }\n};\n\nmodule.exports = PAPU;\n", "var utils = require(\"./utils\");\n\nvar Mappers = {};\n\nMappers[0] = function(nes) {\n this.nes = nes;\n};\n\nMappers[0].prototype = {\n reset: function() {\n this.joy1StrobeState = 0;\n this.joy2StrobeState = 0;\n this.joypadLastWrite = 0;\n\n this.zapperFired = false;\n this.zapperX = null;\n this.zapperY = null;\n },\n\n write: function(address, value) {\n if (address < 0x2000) {\n // Mirroring of RAM:\n this.nes.cpu.mem[address & 0x7ff] = value;\n } else if (address > 0x4017) {\n this.nes.cpu.mem[address] = value;\n if (address >= 0x6000 && address < 0x8000) {\n // Write to persistent RAM\n this.nes.opts.onBatteryRamWrite(address, value);\n }\n } else if (address > 0x2007 && address < 0x4000) {\n this.regWrite(0x2000 + (address & 0x7), value);\n } else {\n this.regWrite(address, value);\n }\n },\n\n writelow: function(address, value) {\n if (address < 0x2000) {\n // Mirroring of RAM:\n this.nes.cpu.mem[address & 0x7ff] = value;\n } else if (address > 0x4017) {\n this.nes.cpu.mem[address] = value;\n } else if (address > 0x2007 && address < 0x4000) {\n this.regWrite(0x2000 + (address & 0x7), value);\n } else {\n this.regWrite(address, value);\n }\n },\n\n load: function(address) {\n // Wrap around:\n address &= 0xffff;\n\n // Check address range:\n if (address > 0x4017) {\n // ROM:\n return this.nes.cpu.mem[address];\n } else if (address >= 0x2000) {\n // I/O Ports.\n return this.regLoad(address);\n } else {\n // RAM (mirrored)\n return this.nes.cpu.mem[address & 0x7ff];\n }\n },\n\n regLoad: function(address) {\n switch (\n address >> 12 // use fourth nibble (0xF000)\n ) {\n case 0:\n break;\n\n case 1:\n break;\n\n case 2:\n // Fall through to case 3\n case 3:\n // PPU Registers\n switch (address & 0x7) {\n case 0x0:\n // 0x2000:\n // PPU Control Register 1.\n // (the value is stored both\n // in main memory and in the\n // PPU as flags):\n // (not in the real NES)\n return this.nes.cpu.mem[0x2000];\n\n case 0x1:\n // 0x2001:\n // PPU Control Register 2.\n // (the value is stored both\n // in main memory and in the\n // PPU as flags):\n // (not in the real NES)\n return this.nes.cpu.mem[0x2001];\n\n case 0x2:\n // 0x2002:\n // PPU Status Register.\n // The value is stored in\n // main memory in addition\n // to as flags in the PPU.\n // (not in the real NES)\n return this.nes.ppu.readStatusRegister();\n\n case 0x3:\n return 0;\n\n case 0x4:\n // 0x2004:\n // Sprite Memory read.\n return this.nes.ppu.sramLoad();\n case 0x5:\n return 0;\n\n case 0x6:\n return 0;\n\n case 0x7:\n // 0x2007:\n // VRAM read:\n return this.nes.ppu.vramLoad();\n }\n break;\n case 4:\n // Sound+Joypad registers\n switch (address - 0x4015) {\n case 0:\n // 0x4015:\n // Sound channel enable, DMC Status\n return this.nes.papu.readReg(address);\n\n case 1:\n // 0x4016:\n // Joystick 1 + Strobe\n return this.joy1Read();\n\n case 2:\n // 0x4017:\n // Joystick 2 + Strobe\n // https://wiki.nesdev.com/w/index.php/Zapper\n var w;\n\n if (\n this.zapperX !== null &&\n this.zapperY !== null &&\n this.nes.ppu.isPixelWhite(this.zapperX, this.zapperY)\n ) {\n w = 0;\n } else {\n w = 0x1 << 3;\n }\n\n if (this.zapperFired) {\n w |= 0x1 << 4;\n }\n return (this.joy2Read() | w) & 0xffff;\n }\n break;\n }\n return 0;\n },\n\n regWrite: function(address, value) {\n switch (address) {\n case 0x2000:\n // PPU Control register 1\n this.nes.cpu.mem[address] = value;\n this.nes.ppu.updateControlReg1(value);\n break;\n\n case 0x2001:\n // PPU Control register 2\n this.nes.cpu.mem[address] = value;\n this.nes.ppu.updateControlReg2(value);\n break;\n\n case 0x2003:\n // Set Sprite RAM address:\n this.nes.ppu.writeSRAMAddress(value);\n break;\n\n case 0x2004:\n // Write to Sprite RAM:\n this.nes.ppu.sramWrite(value);\n break;\n\n case 0x2005:\n // Screen Scroll offsets:\n this.nes.ppu.scrollWrite(value);\n break;\n\n case 0x2006:\n // Set VRAM address:\n this.nes.ppu.writeVRAMAddress(value);\n break;\n\n case 0x2007:\n // Write to VRAM:\n this.nes.ppu.vramWrite(value);\n break;\n\n case 0x4014:\n // Sprite Memory DMA Access\n this.nes.ppu.sramDMA(value);\n break;\n\n case 0x4015:\n // Sound Channel Switch, DMC Status\n this.nes.papu.writeReg(address, value);\n break;\n\n case 0x4016:\n // Joystick 1 + Strobe\n if ((value & 1) === 0 && (this.joypadLastWrite & 1) === 1) {\n this.joy1StrobeState = 0;\n this.joy2StrobeState = 0;\n }\n this.joypadLastWrite = value;\n break;\n\n case 0x4017:\n // Sound channel frame sequencer:\n this.nes.papu.writeReg(address, value);\n break;\n\n default:\n // Sound registers\n // console.log(\"write to sound reg\");\n if (address >= 0x4000 && address <= 0x4017) {\n this.nes.papu.writeReg(address, value);\n }\n }\n },\n\n joy1Read: function() {\n var ret;\n\n switch (this.joy1StrobeState) {\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n ret = this.nes.controllers[1].state[this.joy1StrobeState];\n break;\n case 8:\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n ret = 0;\n break;\n case 19:\n ret = 1;\n break;\n default:\n ret = 0;\n }\n\n this.joy1StrobeState++;\n if (this.joy1StrobeState === 24) {\n this.joy1StrobeState = 0;\n }\n\n return ret;\n },\n\n joy2Read: function() {\n var ret;\n\n switch (this.joy2StrobeState) {\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n ret = this.nes.controllers[2].state[this.joy2StrobeState];\n break;\n case 8:\n case 9:\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n ret = 0;\n break;\n case 19:\n ret = 1;\n break;\n default:\n ret = 0;\n }\n\n this.joy2StrobeState++;\n if (this.joy2StrobeState === 24) {\n this.joy2StrobeState = 0;\n }\n\n return ret;\n },\n\n loadROM: function() {\n if (!this.nes.rom.valid || this.nes.rom.romCount < 1) {\n throw new Error(\"NoMapper: Invalid ROM! Unable to load.\");\n }\n\n // Load ROM into memory:\n this.loadPRGROM();\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Load Battery RAM (if present):\n this.loadBatteryRam();\n\n // Reset IRQ:\n //nes.getCpu().doResetInterrupt();\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n },\n\n loadPRGROM: function() {\n if (this.nes.rom.romCount > 1) {\n // Load the two first banks into memory.\n this.loadRomBank(0, 0x8000);\n this.loadRomBank(1, 0xc000);\n } else {\n // Load the one bank into both memory locations:\n this.loadRomBank(0, 0x8000);\n this.loadRomBank(0, 0xc000);\n }\n },\n\n loadCHRROM: function() {\n // console.log(\"Loading CHR ROM..\");\n if (this.nes.rom.vromCount > 0) {\n if (this.nes.rom.vromCount === 1) {\n this.loadVromBank(0, 0x0000);\n this.loadVromBank(0, 0x1000);\n } else {\n this.loadVromBank(0, 0x0000);\n this.loadVromBank(1, 0x1000);\n }\n } else {\n //System.out.println(\"There aren't any CHR-ROM banks..\");\n }\n },\n\n loadBatteryRam: function() {\n if (this.nes.rom.batteryRam) {\n var ram = this.nes.rom.batteryRam;\n if (ram !== null && ram.length === 0x2000) {\n // Load Battery RAM into memory:\n utils.copyArrayElements(ram, 0, this.nes.cpu.mem, 0x6000, 0x2000);\n }\n }\n },\n\n loadRomBank: function(bank, address) {\n // Loads a ROM bank into the specified address.\n bank %= this.nes.rom.romCount;\n //var data = this.nes.rom.rom[bank];\n //cpuMem.write(address,data,data.length);\n utils.copyArrayElements(\n this.nes.rom.rom[bank],\n 0,\n this.nes.cpu.mem,\n address,\n 16384\n );\n },\n\n loadVromBank: function(bank, address) {\n if (this.nes.rom.vromCount === 0) {\n return;\n }\n this.nes.ppu.triggerRendering();\n\n utils.copyArrayElements(\n this.nes.rom.vrom[bank % this.nes.rom.vromCount],\n 0,\n this.nes.ppu.vramMem,\n address,\n 4096\n );\n\n var vromTile = this.nes.rom.vromTile[bank % this.nes.rom.vromCount];\n utils.copyArrayElements(\n vromTile,\n 0,\n this.nes.ppu.ptTile,\n address >> 4,\n 256\n );\n },\n\n load32kRomBank: function(bank, address) {\n this.loadRomBank((bank * 2) % this.nes.rom.romCount, address);\n this.loadRomBank((bank * 2 + 1) % this.nes.rom.romCount, address + 16384);\n },\n\n load8kVromBank: function(bank4kStart, address) {\n if (this.nes.rom.vromCount === 0) {\n return;\n }\n this.nes.ppu.triggerRendering();\n\n this.loadVromBank(bank4kStart % this.nes.rom.vromCount, address);\n this.loadVromBank(\n (bank4kStart + 1) % this.nes.rom.vromCount,\n address + 4096\n );\n },\n\n load1kVromBank: function(bank1k, address) {\n if (this.nes.rom.vromCount === 0) {\n return;\n }\n this.nes.ppu.triggerRendering();\n\n var bank4k = Math.floor(bank1k / 4) % this.nes.rom.vromCount;\n var bankoffset = (bank1k % 4) * 1024;\n utils.copyArrayElements(\n this.nes.rom.vrom[bank4k],\n bankoffset,\n this.nes.ppu.vramMem,\n address,\n 1024\n );\n\n // Update tiles:\n var vromTile = this.nes.rom.vromTile[bank4k];\n var baseIndex = address >> 4;\n for (var i = 0; i < 64; i++) {\n this.nes.ppu.ptTile[baseIndex + i] = vromTile[(bank1k % 4 << 6) + i];\n }\n },\n\n load2kVromBank: function(bank2k, address) {\n if (this.nes.rom.vromCount === 0) {\n return;\n }\n this.nes.ppu.triggerRendering();\n\n var bank4k = Math.floor(bank2k / 2) % this.nes.rom.vromCount;\n var bankoffset = (bank2k % 2) * 2048;\n utils.copyArrayElements(\n this.nes.rom.vrom[bank4k],\n bankoffset,\n this.nes.ppu.vramMem,\n address,\n 2048\n );\n\n // Update tiles:\n var vromTile = this.nes.rom.vromTile[bank4k];\n var baseIndex = address >> 4;\n for (var i = 0; i < 128; i++) {\n this.nes.ppu.ptTile[baseIndex + i] = vromTile[(bank2k % 2 << 7) + i];\n }\n },\n\n load8kRomBank: function(bank8k, address) {\n var bank16k = Math.floor(bank8k / 2) % this.nes.rom.romCount;\n var offset = (bank8k % 2) * 8192;\n\n //this.nes.cpu.mem.write(address,this.nes.rom.rom[bank16k],offset,8192);\n utils.copyArrayElements(\n this.nes.rom.rom[bank16k],\n offset,\n this.nes.cpu.mem,\n address,\n 8192\n );\n },\n\n clockIrqCounter: function() {\n // Does nothing. This is used by the MMC3 mapper.\n },\n\n // eslint-disable-next-line no-unused-vars\n latchAccess: function(address) {\n // Does nothing. This is used by MMC2.\n },\n\n toJSON: function() {\n return {\n joy1StrobeState: this.joy1StrobeState,\n joy2StrobeState: this.joy2StrobeState,\n joypadLastWrite: this.joypadLastWrite\n };\n },\n\n fromJSON: function(s) {\n this.joy1StrobeState = s.joy1StrobeState;\n this.joy2StrobeState = s.joy2StrobeState;\n this.joypadLastWrite = s.joypadLastWrite;\n }\n};\n\nMappers[1] = function(nes) {\n this.nes = nes;\n};\n\nMappers[1].prototype = new Mappers[0]();\n\nMappers[1].prototype.reset = function() {\n Mappers[0].prototype.reset.apply(this);\n\n // 5-bit buffer:\n this.regBuffer = 0;\n this.regBufferCounter = 0;\n\n // Register 0:\n this.mirroring = 0;\n this.oneScreenMirroring = 0;\n this.prgSwitchingArea = 1;\n this.prgSwitchingSize = 1;\n this.vromSwitchingSize = 0;\n\n // Register 1:\n this.romSelectionReg0 = 0;\n\n // Register 2:\n this.romSelectionReg1 = 0;\n\n // Register 3:\n this.romBankSelect = 0;\n};\n\nMappers[1].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n }\n\n // See what should be done with the written value:\n if ((value & 128) !== 0) {\n // Reset buffering:\n this.regBufferCounter = 0;\n this.regBuffer = 0;\n\n // Reset register:\n if (this.getRegNumber(address) === 0) {\n this.prgSwitchingArea = 1;\n this.prgSwitchingSize = 1;\n }\n } else {\n // Continue buffering:\n //regBuffer = (regBuffer & (0xFF-(1<<regBufferCounter))) | ((value & (1<<regBufferCounter))<<regBufferCounter);\n this.regBuffer =\n (this.regBuffer & (0xff - (1 << this.regBufferCounter))) |\n ((value & 1) << this.regBufferCounter);\n this.regBufferCounter++;\n\n if (this.regBufferCounter === 5) {\n // Use the buffered value:\n this.setReg(this.getRegNumber(address), this.regBuffer);\n\n // Reset buffer:\n this.regBuffer = 0;\n this.regBufferCounter = 0;\n }\n }\n};\n\nMappers[1].prototype.setReg = function(reg, value) {\n var tmp;\n\n switch (reg) {\n case 0:\n // Mirroring:\n tmp = value & 3;\n if (tmp !== this.mirroring) {\n // Set mirroring:\n this.mirroring = tmp;\n if ((this.mirroring & 2) === 0) {\n // SingleScreen mirroring overrides the other setting:\n this.nes.ppu.setMirroring(this.nes.rom.SINGLESCREEN_MIRRORING);\n } else if ((this.mirroring & 1) !== 0) {\n // Not overridden by SingleScreen mirroring.\n this.nes.ppu.setMirroring(this.nes.rom.HORIZONTAL_MIRRORING);\n } else {\n this.nes.ppu.setMirroring(this.nes.rom.VERTICAL_MIRRORING);\n }\n }\n\n // PRG Switching Area;\n this.prgSwitchingArea = (value >> 2) & 1;\n\n // PRG Switching Size:\n this.prgSwitchingSize = (value >> 3) & 1;\n\n // VROM Switching Size:\n this.vromSwitchingSize = (value >> 4) & 1;\n\n break;\n\n case 1:\n // ROM selection:\n this.romSelectionReg0 = (value >> 4) & 1;\n\n // Check whether the cart has VROM:\n if (this.nes.rom.vromCount > 0) {\n // Select VROM bank at 0x0000:\n if (this.vromSwitchingSize === 0) {\n // Swap 8kB VROM:\n if (this.romSelectionReg0 === 0) {\n this.load8kVromBank(value & 0xf, 0x0000);\n } else {\n this.load8kVromBank(\n Math.floor(this.nes.rom.vromCount / 2) + (value & 0xf),\n 0x0000\n );\n }\n } else {\n // Swap 4kB VROM:\n if (this.romSelectionReg0 === 0) {\n this.loadVromBank(value & 0xf, 0x0000);\n } else {\n this.loadVromBank(\n Math.floor(this.nes.rom.vromCount / 2) + (value & 0xf),\n 0x0000\n );\n }\n }\n }\n\n break;\n\n case 2:\n // ROM selection:\n this.romSelectionReg1 = (value >> 4) & 1;\n\n // Check whether the cart has VROM:\n if (this.nes.rom.vromCount > 0) {\n // Select VROM bank at 0x1000:\n if (this.vromSwitchingSize === 1) {\n // Swap 4kB of VROM:\n if (this.romSelectionReg1 === 0) {\n this.loadVromBank(value & 0xf, 0x1000);\n } else {\n this.loadVromBank(\n Math.floor(this.nes.rom.vromCount / 2) + (value & 0xf),\n 0x1000\n );\n }\n }\n }\n break;\n\n default:\n // Select ROM bank:\n // -------------------------\n tmp = value & 0xf;\n var bank;\n var baseBank = 0;\n\n if (this.nes.rom.romCount >= 32) {\n // 1024 kB cart\n if (this.vromSwitchingSize === 0) {\n if (this.romSelectionReg0 === 1) {\n baseBank = 16;\n }\n } else {\n baseBank =\n (this.romSelectionReg0 | (this.romSelectionReg1 << 1)) << 3;\n }\n } else if (this.nes.rom.romCount >= 16) {\n // 512 kB cart\n if (this.romSelectionReg0 === 1) {\n baseBank = 8;\n }\n }\n\n if (this.prgSwitchingSize === 0) {\n // 32kB\n bank = baseBank + (value & 0xf);\n this.load32kRomBank(bank, 0x8000);\n } else {\n // 16kB\n bank = baseBank * 2 + (value & 0xf);\n if (this.prgSwitchingArea === 0) {\n this.loadRomBank(bank, 0xc000);\n } else {\n this.loadRomBank(bank, 0x8000);\n }\n }\n }\n};\n\n// Returns the register number from the address written to:\nMappers[1].prototype.getRegNumber = function(address) {\n if (address >= 0x8000 && address <= 0x9fff) {\n return 0;\n } else if (address >= 0xa000 && address <= 0xbfff) {\n return 1;\n } else if (address >= 0xc000 && address <= 0xdfff) {\n return 2;\n } else {\n return 3;\n }\n};\n\nMappers[1].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"MMC1: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.loadRomBank(0, 0x8000); // First ROM bank..\n this.loadRomBank(this.nes.rom.romCount - 1, 0xc000); // ..and last ROM bank.\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Load Battery RAM (if present):\n this.loadBatteryRam();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\n// eslint-disable-next-line no-unused-vars\nMappers[1].prototype.switchLowHighPrgRom = function(oldSetting) {\n // not yet.\n};\n\nMappers[1].prototype.switch16to32 = function() {\n // not yet.\n};\n\nMappers[1].prototype.switch32to16 = function() {\n // not yet.\n};\n\nMappers[1].prototype.toJSON = function() {\n var s = Mappers[0].prototype.toJSON.apply(this);\n s.mirroring = this.mirroring;\n s.oneScreenMirroring = this.oneScreenMirroring;\n s.prgSwitchingArea = this.prgSwitchingArea;\n s.prgSwitchingSize = this.prgSwitchingSize;\n s.vromSwitchingSize = this.vromSwitchingSize;\n s.romSelectionReg0 = this.romSelectionReg0;\n s.romSelectionReg1 = this.romSelectionReg1;\n s.romBankSelect = this.romBankSelect;\n s.regBuffer = this.regBuffer;\n s.regBufferCounter = this.regBufferCounter;\n return s;\n};\n\nMappers[1].prototype.fromJSON = function(s) {\n Mappers[0].prototype.fromJSON.apply(this, arguments);\n this.mirroring = s.mirroring;\n this.oneScreenMirroring = s.oneScreenMirroring;\n this.prgSwitchingArea = s.prgSwitchingArea;\n this.prgSwitchingSize = s.prgSwitchingSize;\n this.vromSwitchingSize = s.vromSwitchingSize;\n this.romSelectionReg0 = s.romSelectionReg0;\n this.romSelectionReg1 = s.romSelectionReg1;\n this.romBankSelect = s.romBankSelect;\n this.regBuffer = s.regBuffer;\n this.regBufferCounter = s.regBufferCounter;\n};\n\nMappers[2] = function(nes) {\n this.nes = nes;\n};\n\nMappers[2].prototype = new Mappers[0]();\n\nMappers[2].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // This is a ROM bank select command.\n // Swap in the given ROM bank at 0x8000:\n this.loadRomBank(value, 0x8000);\n }\n};\n\nMappers[2].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"UNROM: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.loadRomBank(0, 0x8000);\n this.loadRomBank(this.nes.rom.romCount - 1, 0xc000);\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\n/**\n * Mapper 003 (CNROM)\n *\n * @constructor\n * @example Solomon's Key, Arkanoid, Arkista's Ring, Bump 'n' Jump, Cybernoid\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_003\n */\nMappers[3] = function(nes) {\n this.nes = nes;\n};\n\nMappers[3].prototype = new Mappers[0]();\n\nMappers[3].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // This is a ROM bank select command.\n // Swap in the given ROM bank at 0x8000:\n // This is a VROM bank select command.\n // Swap in the given VROM bank at 0x0000:\n var bank = (value % (this.nes.rom.vromCount / 2)) * 2;\n this.loadVromBank(bank, 0x0000);\n this.loadVromBank(bank + 1, 0x1000);\n this.load8kVromBank(value * 2, 0x0000);\n }\n};\n\nMappers[4] = function(nes) {\n this.nes = nes;\n\n this.CMD_SEL_2_1K_VROM_0000 = 0;\n this.CMD_SEL_2_1K_VROM_0800 = 1;\n this.CMD_SEL_1K_VROM_1000 = 2;\n this.CMD_SEL_1K_VROM_1400 = 3;\n this.CMD_SEL_1K_VROM_1800 = 4;\n this.CMD_SEL_1K_VROM_1C00 = 5;\n this.CMD_SEL_ROM_PAGE1 = 6;\n this.CMD_SEL_ROM_PAGE2 = 7;\n\n this.command = null;\n this.prgAddressSelect = null;\n this.chrAddressSelect = null;\n this.irqCounter = 0xff;\n this.irqLatchValue = 0xff;\n this.irqReload = 0;\n this.irqEnable = 0;\n this.prgAddressChanged = false;\n};\n\nMappers[4].prototype = new Mappers[0]();\n\nMappers[4].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n }\n\n switch (address & 0xe001) {\n case 0x8000:\n // Command/Address Select register\n this.command = value & 7;\n var tmp = (value >> 6) & 1;\n if (tmp !== this.prgAddressSelect) {\n this.prgAddressChanged = true;\n }\n this.prgAddressSelect = tmp;\n this.chrAddressSelect = (value >> 7) & 1;\n break;\n\n case 0x8001:\n // Page number for command\n this.executeCommand(this.command, value);\n break;\n\n case 0xa000:\n // Mirroring select\n if ((value & 1) !== 0) {\n this.nes.ppu.setMirroring(this.nes.rom.HORIZONTAL_MIRRORING);\n } else {\n this.nes.ppu.setMirroring(this.nes.rom.VERTICAL_MIRRORING);\n }\n break;\n\n case 0xa001:\n // SaveRAM Toggle\n // TODO\n //nes.getRom().setSaveState((value&1)!=0);\n break;\n\n case 0xc000:\n // IRQ Latch register\n this.irqLatchValue = value;\n break;\n\n case 0xc001:\n // IRQ Reload register (TODO: copy at next rising A12)\n this.irqReload = 1;\n break;\n\n case 0xe000:\n // IRQ Control Reg 0 (disable, ack)\n this.irqEnable = 0;\n break;\n\n case 0xe001:\n // IRQ Control Reg 1 (enable)\n this.irqEnable = 1;\n break;\n\n default:\n // Not a MMC3 register.\n // The game has probably crashed,\n // since it tries to write to ROM..\n // IGNORE.\n }\n};\n\nMappers[4].prototype.executeCommand = function(cmd, arg) {\n switch (cmd) {\n case this.CMD_SEL_2_1K_VROM_0000:\n // Select 2 1KB VROM pages at 0x0000:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x0000);\n this.load1kVromBank(arg + 1, 0x0400);\n } else {\n this.load1kVromBank(arg, 0x1000);\n this.load1kVromBank(arg + 1, 0x1400);\n }\n break;\n\n case this.CMD_SEL_2_1K_VROM_0800:\n // Select 2 1KB VROM pages at 0x0800:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x0800);\n this.load1kVromBank(arg + 1, 0x0c00);\n } else {\n this.load1kVromBank(arg, 0x1800);\n this.load1kVromBank(arg + 1, 0x1c00);\n }\n break;\n\n case this.CMD_SEL_1K_VROM_1000:\n // Select 1K VROM Page at 0x1000:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x1000);\n } else {\n this.load1kVromBank(arg, 0x0000);\n }\n break;\n\n case this.CMD_SEL_1K_VROM_1400:\n // Select 1K VROM Page at 0x1400:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x1400);\n } else {\n this.load1kVromBank(arg, 0x0400);\n }\n break;\n\n case this.CMD_SEL_1K_VROM_1800:\n // Select 1K VROM Page at 0x1800:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x1800);\n } else {\n this.load1kVromBank(arg, 0x0800);\n }\n break;\n\n case this.CMD_SEL_1K_VROM_1C00:\n // Select 1K VROM Page at 0x1C00:\n if (this.chrAddressSelect === 0) {\n this.load1kVromBank(arg, 0x1c00);\n } else {\n this.load1kVromBank(arg, 0x0c00);\n }\n break;\n\n case this.CMD_SEL_ROM_PAGE1:\n if (this.prgAddressChanged) {\n // Load the two hardwired banks:\n if (this.prgAddressSelect === 0) {\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2, 0xc000);\n } else {\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2, 0x8000);\n }\n this.prgAddressChanged = false;\n }\n\n // Select first switchable ROM page:\n if (this.prgAddressSelect === 0) {\n this.load8kRomBank(arg, 0x8000);\n } else {\n this.load8kRomBank(arg, 0xc000);\n }\n break;\n\n case this.CMD_SEL_ROM_PAGE2:\n // Select second switchable ROM page:\n this.load8kRomBank(arg, 0xa000);\n\n // hardwire appropriate bank:\n if (this.prgAddressChanged) {\n // Load the two hardwired banks:\n if (this.prgAddressSelect === 0) {\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2, 0xc000);\n } else {\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2, 0x8000);\n }\n this.prgAddressChanged = false;\n }\n }\n};\n\nMappers[4].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"MMC3: Invalid ROM! Unable to load.\");\n }\n\n // Load hardwired PRG banks (0xC000 and 0xE000):\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2, 0xc000);\n this.load8kRomBank((this.nes.rom.romCount - 1) * 2 + 1, 0xe000);\n\n // Load swappable PRG banks (0x8000 and 0xA000):\n this.load8kRomBank(0, 0x8000);\n this.load8kRomBank(1, 0xa000);\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Load Battery RAM (if present):\n this.loadBatteryRam();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\nMappers[4].prototype.clockIrqCounter = function() {\n if (this.irqReload === 1) {\n this.irqCounter = this.irqLatchValue;\n this.irqReload = 0;\n }\n this.irqCounter--;\n if (this.irqCounter < 0) {\n if (this.irqEnable === 1) {\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_NORMAL);\n }\n this.irqCounter = this.irqLatchValue;\n }\n};\n\nMappers[4].prototype.toJSON = function() {\n var s = Mappers[0].prototype.toJSON.apply(this);\n s.command = this.command;\n s.prgAddressSelect = this.prgAddressSelect;\n s.chrAddressSelect = this.chrAddressSelect;\n s.irqReload = this.irqReload;\n s.irqCounter = this.irqCounter;\n s.irqLatchValue = this.irqLatchValue;\n s.irqEnable = this.irqEnable;\n s.prgAddressChanged = this.prgAddressChanged;\n return s;\n};\n\nMappers[4].prototype.fromJSON = function(s) {\n Mappers[0].prototype.fromJSON.apply(this, arguments);\n this.command = s.command;\n this.prgAddressSelect = s.prgAddressSelect;\n this.chrAddressSelect = s.chrAddressSelect;\n this.irqReload = s.irqReload;\n this.irqCounter = s.irqCounter;\n this.irqLatchValue = s.irqLatchValue;\n this.irqEnable = s.irqEnable;\n this.prgAddressChanged = s.prgAddressChanged;\n};\n\n/**\n * Mapper005 (MMC5,ExROM)\n *\n * @example Castlevania 3, Just Breed, Uncharted Waters, Romance of the 3 Kingdoms 2, Laser Invasion, Metal Slader Glory, Uchuu Keibitai SDF, Shin 4 Nin Uchi Mahjong - Yakuman Tengoku\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_005\n * @constructor\n */\nMappers[5] = function(nes) {\n this.nes = nes;\n};\n\nMappers[5].prototype = new Mappers[0]();\n\nMappers[5].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n } else {\n this.load8kVromBank(value, 0x0000);\n }\n};\n\nMappers[5].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x5000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n }\n\n switch (address) {\n case 0x5100:\n this.prg_size = value & 3;\n break;\n case 0x5101:\n this.chr_size = value & 3;\n break;\n case 0x5102:\n this.sram_we_a = value & 3;\n break;\n case 0x5103:\n this.sram_we_b = value & 3;\n break;\n case 0x5104:\n this.graphic_mode = value & 3;\n break;\n case 0x5105:\n this.nametable_mode = value;\n this.nametable_type[0] = value & 3;\n this.load1kVromBank(value & 3, 0x2000);\n value >>= 2;\n this.nametable_type[1] = value & 3;\n this.load1kVromBank(value & 3, 0x2400);\n value >>= 2;\n this.nametable_type[2] = value & 3;\n this.load1kVromBank(value & 3, 0x2800);\n value >>= 2;\n this.nametable_type[3] = value & 3;\n this.load1kVromBank(value & 3, 0x2c00);\n break;\n case 0x5106:\n this.fill_chr = value;\n break;\n case 0x5107:\n this.fill_pal = value & 3;\n break;\n case 0x5113:\n this.SetBank_SRAM(3, value & 3);\n break;\n case 0x5114:\n case 0x5115:\n case 0x5116:\n case 0x5117:\n this.SetBank_CPU(address, value);\n break;\n case 0x5120:\n case 0x5121:\n case 0x5122:\n case 0x5123:\n case 0x5124:\n case 0x5125:\n case 0x5126:\n case 0x5127:\n this.chr_mode = 0;\n this.chr_page[0][address & 7] = value;\n this.SetBank_PPU();\n break;\n case 0x5128:\n case 0x5129:\n case 0x512a:\n case 0x512b:\n this.chr_mode = 1;\n this.chr_page[1][(address & 3) + 0] = value;\n this.chr_page[1][(address & 3) + 4] = value;\n this.SetBank_PPU();\n break;\n case 0x5200:\n this.split_control = value;\n break;\n case 0x5201:\n this.split_scroll = value;\n break;\n case 0x5202:\n this.split_page = value & 0x3f;\n break;\n case 0x5203:\n this.irq_line = value;\n this.nes.cpu.ClearIRQ();\n break;\n case 0x5204:\n this.irq_enable = value;\n this.nes.cpu.ClearIRQ();\n break;\n case 0x5205:\n this.mult_a = value;\n break;\n case 0x5206:\n this.mult_b = value;\n break;\n default:\n if (address >= 0x5000 && address <= 0x5015) {\n this.nes.papu.exWrite(address, value);\n } else if (address >= 0x5c00 && address <= 0x5fff) {\n if (this.graphic_mode === 2) {\n // ExRAM\n // vram write\n } else if (this.graphic_mode !== 3) {\n // Split,ExGraphic\n if (this.irq_status & 0x40) {\n // vram write\n } else {\n // vram write\n }\n }\n } else if (address >= 0x6000 && address <= 0x7fff) {\n if (this.sram_we_a === 2 && this.sram_we_b === 1) {\n // additional ram write\n }\n }\n break;\n }\n};\n\nMappers[5].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"UNROM: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.load8kRomBank(this.nes.rom.romCount * 2 - 1, 0x8000);\n this.load8kRomBank(this.nes.rom.romCount * 2 - 1, 0xa000);\n this.load8kRomBank(this.nes.rom.romCount * 2 - 1, 0xc000);\n this.load8kRomBank(this.nes.rom.romCount * 2 - 1, 0xe000);\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\n/**\n * Mapper007 (AxROM)\n * @example Battletoads, Time Lord, Marble Madness\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_007\n * @constructor\n */\nMappers[7] = function(nes) {\n this.nes = nes;\n};\n\nMappers[7].prototype = new Mappers[0]();\n\nMappers[7].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n } else {\n this.load32kRomBank(value & 0x7, 0x8000);\n if (value & 0x10) {\n this.nes.ppu.setMirroring(this.nes.rom.SINGLESCREEN_MIRRORING2);\n } else {\n this.nes.ppu.setMirroring(this.nes.rom.SINGLESCREEN_MIRRORING);\n }\n }\n};\n\nMappers[7].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"AOROM: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.loadPRGROM();\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\n/**\n * Mapper 011 (Color Dreams)\n *\n * @description http://wiki.nesdev.com/w/index.php/Color_Dreams\n * @example Crystal Mines, Metal Fighter\n * @constructor\n */\nMappers[11] = function(nes) {\n this.nes = nes;\n};\n\nMappers[11].prototype = new Mappers[0]();\n\nMappers[11].prototype.write = function(address, value) {\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // Swap in the given PRG-ROM bank:\n var prgbank1 = ((value & 0xf) * 2) % this.nes.rom.romCount;\n var prgbank2 = ((value & 0xf) * 2 + 1) % this.nes.rom.romCount;\n\n this.loadRomBank(prgbank1, 0x8000);\n this.loadRomBank(prgbank2, 0xc000);\n\n if (this.nes.rom.vromCount > 0) {\n // Swap in the given VROM bank at 0x0000:\n var bank = ((value >> 4) * 2) % this.nes.rom.vromCount;\n this.loadVromBank(bank, 0x0000);\n this.loadVromBank(bank + 1, 0x1000);\n }\n }\n};\n\n/**\n * Mapper 034 (BNROM, NINA-01)\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_034\n * @example Darkseed, Mashou, Mission Impossible 2\n * @constructor\n */\nMappers[34] = function(nes) {\n this.nes = nes;\n};\n\nMappers[34].prototype = new Mappers[0]();\n\nMappers[34].prototype.write = function(address, value) {\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n this.load32kRomBank(value, 0x8000);\n }\n};\n\n/**\n * Mapper 038\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_038\n * @example Crime Busters\n * @constructor\n */\nMappers[38] = function(nes) {\n this.nes = nes;\n};\n\nMappers[38].prototype = new Mappers[0]();\n\nMappers[38].prototype.write = function(address, value) {\n if (address < 0x7000 || address > 0x7fff) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // Swap in the given PRG-ROM bank at 0x8000:\n this.load32kRomBank(value & 3, 0x8000);\n\n // Swap in the given VROM bank at 0x0000:\n this.load8kVromBank(((value >> 2) & 3) * 2, 0x0000);\n }\n};\n\n/**\n * Mapper 066 (GxROM)\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_066\n * @example Doraemon, Dragon Power, Gumshoe, Thunder & Lightning,\n * Super Mario Bros. + Duck Hunt\n * @constructor\n */\nMappers[66] = function(nes) {\n this.nes = nes;\n};\n\nMappers[66].prototype = new Mappers[0]();\n\nMappers[66].prototype.write = function(address, value) {\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // Swap in the given PRG-ROM bank at 0x8000:\n this.load32kRomBank((value >> 4) & 3, 0x8000);\n\n // Swap in the given VROM bank at 0x0000:\n this.load8kVromBank((value & 3) * 2, 0x0000);\n }\n};\n\n/**\n * Mapper 094 (UN1ROM)\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_094\n * @example Senjou no Ookami\n * @constructor\n */\nMappers[94] = function(nes) {\n this.nes = nes;\n};\n\nMappers[94].prototype = new Mappers[0]();\n\nMappers[94].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // This is a ROM bank select command.\n // Swap in the given ROM bank at 0x8000:\n this.loadRomBank(value >> 2, 0x8000);\n }\n};\n\nMappers[94].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"UN1ROM: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.loadRomBank(0, 0x8000);\n this.loadRomBank(this.nes.rom.romCount - 1, 0xc000);\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\n/**\n * Mapper 140\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_140\n * @example Bio Senshi Dan - Increaser Tono Tatakai\n * @constructor\n */\nMappers[140] = function(nes) {\n this.nes = nes;\n};\n\nMappers[140].prototype = new Mappers[0]();\n\nMappers[140].prototype.write = function(address, value) {\n if (address < 0x6000 || address > 0x7fff) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // Swap in the given PRG-ROM bank at 0x8000:\n this.load32kRomBank((value >> 4) & 3, 0x8000);\n\n // Swap in the given VROM bank at 0x0000:\n this.load8kVromBank((value & 0xf) * 2, 0x0000);\n }\n};\n\n/**\n * Mapper 180\n *\n * @description http://wiki.nesdev.com/w/index.php/INES_Mapper_180\n * @example Crazy Climber\n * @constructor\n */\nMappers[180] = function(nes) {\n this.nes = nes;\n};\n\nMappers[180].prototype = new Mappers[0]();\n\nMappers[180].prototype.write = function(address, value) {\n // Writes to addresses other than MMC registers are handled by NoMapper.\n if (address < 0x8000) {\n Mappers[0].prototype.write.apply(this, arguments);\n return;\n } else {\n // This is a ROM bank select command.\n // Swap in the given ROM bank at 0xc000:\n this.loadRomBank(value, 0xc000);\n }\n};\n\nMappers[180].prototype.loadROM = function() {\n if (!this.nes.rom.valid) {\n throw new Error(\"Mapper 180: Invalid ROM! Unable to load.\");\n }\n\n // Load PRG-ROM:\n this.loadRomBank(0, 0x8000);\n this.loadRomBank(this.nes.rom.romCount - 1, 0xc000);\n\n // Load CHR-ROM:\n this.loadCHRROM();\n\n // Do Reset-Interrupt:\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n};\n\nmodule.exports = Mappers;\n", "var Mappers = require(\"./mappers\");\nvar Tile = require(\"./tile\");\n\nvar ROM = function(nes) {\n this.nes = nes;\n\n this.mapperName = new Array(92);\n\n for (var i = 0; i < 92; i++) {\n this.mapperName[i] = \"Unknown Mapper\";\n }\n this.mapperName[0] = \"Direct Access\";\n this.mapperName[1] = \"Nintendo MMC1\";\n this.mapperName[2] = \"UNROM\";\n this.mapperName[3] = \"CNROM\";\n this.mapperName[4] = \"Nintendo MMC3\";\n this.mapperName[5] = \"Nintendo MMC5\";\n this.mapperName[6] = \"FFE F4xxx\";\n this.mapperName[7] = \"AOROM\";\n this.mapperName[8] = \"FFE F3xxx\";\n this.mapperName[9] = \"Nintendo MMC2\";\n this.mapperName[10] = \"Nintendo MMC4\";\n this.mapperName[11] = \"Color Dreams Chip\";\n this.mapperName[12] = \"FFE F6xxx\";\n this.mapperName[15] = \"100-in-1 switch\";\n this.mapperName[16] = \"Bandai chip\";\n this.mapperName[17] = \"FFE F8xxx\";\n this.mapperName[18] = \"Jaleco SS8806 chip\";\n this.mapperName[19] = \"Namcot 106 chip\";\n this.mapperName[20] = \"Famicom Disk System\";\n this.mapperName[21] = \"Konami VRC4a\";\n this.mapperName[22] = \"Konami VRC2a\";\n this.mapperName[23] = \"Konami VRC2a\";\n this.mapperName[24] = \"Konami VRC6\";\n this.mapperName[25] = \"Konami VRC4b\";\n this.mapperName[32] = \"Irem G-101 chip\";\n this.mapperName[33] = \"Taito TC0190/TC0350\";\n this.mapperName[34] = \"32kB ROM switch\";\n\n this.mapperName[64] = \"Tengen RAMBO-1 chip\";\n this.mapperName[65] = \"Irem H-3001 chip\";\n this.mapperName[66] = \"GNROM switch\";\n this.mapperName[67] = \"SunSoft3 chip\";\n this.mapperName[68] = \"SunSoft4 chip\";\n this.mapperName[69] = \"SunSoft5 FME-7 chip\";\n this.mapperName[71] = \"Camerica chip\";\n this.mapperName[78] = \"Irem 74HC161/32-based\";\n this.mapperName[91] = \"Pirate HK-SF3 chip\";\n};\n\nROM.prototype = {\n // Mirroring types:\n VERTICAL_MIRRORING: 0,\n HORIZONTAL_MIRRORING: 1,\n FOURSCREEN_MIRRORING: 2,\n SINGLESCREEN_MIRRORING: 3,\n SINGLESCREEN_MIRRORING2: 4,\n SINGLESCREEN_MIRRORING3: 5,\n SINGLESCREEN_MIRRORING4: 6,\n CHRROM_MIRRORING: 7,\n\n header: null,\n rom: null,\n vrom: null,\n vromTile: null,\n\n romCount: null,\n vromCount: null,\n mirroring: null,\n batteryRam: null,\n trainer: null,\n fourScreen: null,\n mapperType: null,\n valid: false,\n\n load: function(data) {\n var i, j, v;\n\n if (data.indexOf(\"NES\\x1a\") === -1) {\n throw new Error(\"Not a valid NES ROM.\");\n }\n this.header = new Array(16);\n for (i = 0; i < 16; i++) {\n this.header[i] = data.charCodeAt(i) & 0xff;\n }\n this.romCount = this.header[4];\n this.vromCount = this.header[5] * 2; // Get the number of 4kB banks, not 8kB\n this.mirroring = (this.header[6] & 1) !== 0 ? 1 : 0;\n this.batteryRam = (this.header[6] & 2) !== 0;\n this.trainer = (this.header[6] & 4) !== 0;\n this.fourScreen = (this.header[6] & 8) !== 0;\n this.mapperType = (this.header[6] >> 4) | (this.header[7] & 0xf0);\n /* TODO\n if (this.batteryRam)\n this.loadBatteryRam();*/\n // Check whether byte 8-15 are zero's:\n var foundError = false;\n for (i = 8; i < 16; i++) {\n if (this.header[i] !== 0) {\n foundError = true;\n break;\n }\n }\n if (foundError) {\n this.mapperType &= 0xf; // Ignore byte 7\n }\n // Load PRG-ROM banks:\n this.rom = new Array(this.romCount);\n var offset = 16;\n for (i = 0; i < this.romCount; i++) {\n this.rom[i] = new Uint8Array(16384);\n for (j = 0; j < 16384; j++) {\n if (offset + j >= data.length) {\n break;\n }\n this.rom[i][j] = data.charCodeAt(offset + j) & 0xff;\n }\n offset += 16384;\n }\n // Load CHR-ROM banks:\n this.vrom = new Array(this.vromCount);\n for (i = 0; i < this.vromCount; i++) {\n this.vrom[i] = new Uint8Array(4096);\n for (j = 0; j < 4096; j++) {\n if (offset + j >= data.length) {\n break;\n }\n this.vrom[i][j] = data.charCodeAt(offset + j) & 0xff;\n }\n offset += 4096;\n }\n\n // Create VROM tiles:\n this.vromTile = new Array(this.vromCount);\n for (i = 0; i < this.vromCount; i++) {\n this.vromTile[i] = new Array(256);\n for (j = 0; j < 256; j++) {\n this.vromTile[i][j] = new Tile();\n }\n }\n\n // Convert CHR-ROM banks to tiles:\n var tileIndex;\n var leftOver;\n for (v = 0; v < this.vromCount; v++) {\n for (i = 0; i < 4096; i++) {\n tileIndex = i >> 4;\n leftOver = i % 16;\n if (leftOver < 8) {\n this.vromTile[v][tileIndex].setScanline(\n leftOver,\n this.vrom[v][i],\n this.vrom[v][i + 8]\n );\n } else {\n this.vromTile[v][tileIndex].setScanline(\n leftOver - 8,\n this.vrom[v][i - 8],\n this.vrom[v][i]\n );\n }\n }\n }\n\n this.valid = true;\n },\n\n getMirroringType: function() {\n if (this.fourScreen) {\n return this.FOURSCREEN_MIRRORING;\n }\n if (this.mirroring === 0) {\n return this.HORIZONTAL_MIRRORING;\n }\n return this.VERTICAL_MIRRORING;\n },\n\n getMapperName: function() {\n if (this.mapperType >= 0 && this.mapperType < this.mapperName.length) {\n return this.mapperName[this.mapperType];\n }\n return \"Unknown Mapper, \" + this.mapperType;\n },\n\n mapperSupported: function() {\n return typeof Mappers[this.mapperType] !== \"undefined\";\n },\n\n createMapper: function() {\n if (this.mapperSupported()) {\n return new Mappers[this.mapperType](this.nes);\n } else {\n throw new Error(\n \"This ROM uses a mapper not supported by JSNES: \" +\n this.getMapperName() +\n \"(\" +\n this.mapperType +\n \")\"\n );\n }\n }\n};\n\nmodule.exports = ROM;\n", "var CPU = require(\"./cpu\");\nvar Controller = require(\"./controller\");\nvar PPU = require(\"./ppu\");\nvar PAPU = require(\"./papu\");\nvar ROM = require(\"./rom\");\n\nvar NES = function(opts) {\n this.opts = {\n onFrame: function() {},\n onAudioSample: null,\n onStatusUpdate: function() {},\n onBatteryRamWrite: function() {},\n\n // FIXME: not actually used except for in PAPU\n preferredFrameRate: 60,\n\n emulateSound: true,\n sampleRate: 44100 // Sound sample rate in hz\n };\n if (typeof opts !== \"undefined\") {\n var key;\n for (key in this.opts) {\n if (typeof opts[key] !== \"undefined\") {\n this.opts[key] = opts[key];\n }\n }\n }\n\n this.frameTime = 1000 / this.opts.preferredFrameRate;\n\n this.ui = {\n writeFrame: this.opts.onFrame,\n updateStatus: this.opts.onStatusUpdate\n };\n this.cpu = new CPU(this);\n this.ppu = new PPU(this);\n this.papu = new PAPU(this);\n this.mmap = null; // set in loadROM()\n this.controllers = {\n 1: new Controller(),\n 2: new Controller()\n };\n\n this.ui.updateStatus(\"Ready to load a ROM.\");\n\n this.frame = this.frame.bind(this);\n this.buttonDown = this.buttonDown.bind(this);\n this.buttonUp = this.buttonUp.bind(this);\n this.zapperMove = this.zapperMove.bind(this);\n this.zapperFireDown = this.zapperFireDown.bind(this);\n this.zapperFireUp = this.zapperFireUp.bind(this);\n};\n\nNES.prototype = {\n fpsFrameCount: 0,\n romData: null,\n\n // Resets the system\n reset: function() {\n if (this.mmap !== null) {\n this.mmap.reset();\n }\n\n this.cpu.reset();\n this.ppu.reset();\n this.papu.reset();\n\n this.lastFpsTime = null;\n this.fpsFrameCount = 0;\n },\n\n frame: function() {\n this.ppu.startFrame();\n var cycles = 0;\n var emulateSound = this.opts.emulateSound;\n var cpu = this.cpu;\n var ppu = this.ppu;\n var papu = this.papu;\n FRAMELOOP: for (;;) {\n if (cpu.cyclesToHalt === 0) {\n // Execute a CPU instruction\n cycles = cpu.emulate();\n if (emulateSound) {\n papu.clockFrameCounter(cycles);\n }\n cycles *= 3;\n } else {\n if (cpu.cyclesToHalt > 8) {\n cycles = 24;\n if (emulateSound) {\n papu.clockFrameCounter(8);\n }\n cpu.cyclesToHalt -= 8;\n } else {\n cycles = cpu.cyclesToHalt * 3;\n if (emulateSound) {\n papu.clockFrameCounter(cpu.cyclesToHalt);\n }\n cpu.cyclesToHalt = 0;\n }\n }\n\n for (; cycles > 0; cycles--) {\n if (\n ppu.curX === ppu.spr0HitX &&\n ppu.f_spVisibility === 1 &&\n ppu.scanline - 21 === ppu.spr0HitY\n ) {\n // Set sprite 0 hit flag:\n ppu.setStatusFlag(ppu.STATUS_SPRITE0HIT, true);\n }\n\n if (ppu.requestEndFrame) {\n ppu.nmiCounter--;\n if (ppu.nmiCounter === 0) {\n ppu.requestEndFrame = false;\n ppu.startVBlank();\n break FRAMELOOP;\n }\n }\n\n ppu.curX++;\n if (ppu.curX === 341) {\n ppu.curX = 0;\n ppu.endScanline();\n }\n }\n }\n this.fpsFrameCount++;\n },\n\n buttonDown: function(controller, button) {\n this.controllers[controller].buttonDown(button);\n },\n\n buttonUp: function(controller, button) {\n this.controllers[controller].buttonUp(button);\n },\n\n zapperMove: function(x, y) {\n if (!this.mmap) return;\n this.mmap.zapperX = x;\n this.mmap.zapperY = y;\n },\n\n zapperFireDown: function() {\n if (!this.mmap) return;\n this.mmap.zapperFired = true;\n },\n\n zapperFireUp: function() {\n if (!this.mmap) return;\n this.mmap.zapperFired = false;\n },\n\n getFPS: function() {\n var now = +new Date();\n var fps = null;\n if (this.lastFpsTime) {\n fps = this.fpsFrameCount / ((now - this.lastFpsTime) / 1000);\n }\n this.fpsFrameCount = 0;\n this.lastFpsTime = now;\n return fps;\n },\n\n reloadROM: function() {\n if (this.romData !== null) {\n this.loadROM(this.romData);\n }\n },\n\n // Loads a ROM file into the CPU and PPU.\n // The ROM file is validated first.\n loadROM: function(data) {\n // Load ROM file:\n this.rom = new ROM(this);\n this.rom.load(data);\n\n this.reset();\n this.mmap = this.rom.createMapper();\n this.mmap.loadROM();\n this.ppu.setMirroring(this.rom.getMirroringType());\n this.romData = data;\n },\n\n setFramerate: function(rate) {\n this.opts.preferredFrameRate = rate;\n this.frameTime = 1000 / rate;\n this.papu.setSampleRate(this.opts.sampleRate, false);\n },\n\n toJSON: function() {\n return {\n romData: this.romData,\n cpu: this.cpu.toJSON(),\n mmap: this.mmap.toJSON(),\n ppu: this.ppu.toJSON()\n };\n },\n\n fromJSON: function(s) {\n this.loadROM(s.romData);\n this.cpu.fromJSON(s.cpu);\n this.mmap.fromJSON(s.mmap);\n this.ppu.fromJSON(s.ppu);\n }\n};\n\nmodule.exports = NES;\n", "module.exports = {\n Controller: require(\"./controller\"),\n NES: require(\"./nes\")\n};\n", "\nimport { Platform, Base6502Platform, getOpcodeMetadata_6502, getToolForFilename_6502, Preset } from \"../common/baseplatform\";\nimport { PLATFORMS, setKeyboardFromMap, AnimationTimer, RasterVideo, Keys, makeKeycodeMap, KeyFlags, EmuHalt, ControllerPoller } from \"../common/emu\";\nimport { hex, byteArrayToString } from \"../common/util\";\nimport { CodeAnalyzer_nes } from \"../common/analysis\";\nimport { SampleAudio } from \"../common/audio\";\nimport { ProbeRecorder } from \"../common/probe\";\nimport { NullProbe, Probeable, ProbeAll } from \"../common/devices\";\nimport Mousetrap = require('mousetrap');\nimport jsnes = require('../../jsnes');\nimport { BaseMAME6502Platform } from \"../common/mameplatform\";\n\nconst JSNES_PRESETS : Preset[] = [\n {id:'hello.c', name:'Hello World'},\n {id:'attributes.c', name:'Attribute Table'},\n {id:'scroll.c', name:'Scrolling'},\n {id:'sprites.c', name:'Sprites'},\n {id:'metasprites.c', name:'Metasprites'},\n {id:'flicker.c', name:'Flickering Sprites'},\n {id:'metacursor.c', name:'Controllers'},\n {id:'vrambuffer.c', name:'VRAM Buffer'},\n {id:'statusbar.c', name:'Split Status Bar'},\n {id:'siegegame.c', name:'Siege Game'},\n {id:'tint.c', name:'Color Emphasis'},\n {id:'rletitle.c', name:'Title Screen RLE'},\n {id:'aputest.c', name:'Sound Tester'},\n {id:'music.c', name:'Music Player'},\n {id:'horizscroll.c', name:'Offscreen Scrolling'},\n {id:'monobitmap.c', name:'Monochrome Bitmap'},\n {id:'fami.c', name:'Famitone Demo'},\n {id:'shoot2.c', name:'Solarian Game'},\n {id:'climber.c', name:'Climber Game'},\n {id:'bankswitch.c', name:'Bank Switching'},\n {id:'irq.c', name:'IRQ Scanline Counter'},\n {id:'ex0.dasm', name:'Initialization', category:'Assembly Language (ASM)'},\n {id:'ex1.dasm', name:'Hello World'},\n {id:'ex2.dasm', name:'Scrolling Demo'},\n {id:'ex3.dasm', name:'Sprite Demo'},\n {id:'ex4.dasm', name:'Controller Demo'},\n {id:'musicdemo.dasm', name:'Famitone Demo'},\n {id:'xyscroll.dasm', name:'XY Split Scrolling'},\n// {id:'scrollrt.dasm', name:'Line-by-line Scrolling'},\n {id:'road.dasm', name:'3-D Road Demo'},\n {id:'chase/game.c', name:'Shiru\\'s Chase Game', category:'Other'},\n {id:'hello.wiz', name:'Hello (Wiz)'},\n];\n\n/// JSNES\n\nconst JSNES_KEYCODE_MAP = makeKeycodeMap([\n [Keys.A, 0, 0],\n [Keys.B, 0, 1],\n [Keys.GP_A, 0, 0],\n [Keys.GP_B, 0, 1],\n [Keys.SELECT, 0, 2],\n [Keys.START, 0, 3],\n [Keys.UP, 0, 4],\n [Keys.DOWN, 0, 5],\n [Keys.LEFT, 0, 6],\n [Keys.RIGHT, 0, 7],\n \n [Keys.P2_A, 1, 0],\n [Keys.P2_B, 1, 1],\n [Keys.P2_SELECT, 1, 2],\n [Keys.P2_START, 1, 3],\n [Keys.P2_UP, 1, 4],\n [Keys.P2_DOWN, 1, 5],\n [Keys.P2_LEFT, 1, 6],\n [Keys.P2_RIGHT, 1, 7],\n]);\n\nclass JSNESPlatform extends Base6502Platform implements Platform, Probeable {\n\n mainElement;\n nes;\n video;\n audio;\n timer;\n poller : ControllerPoller;\n audioFrequency = 44030; //44100\n frameindex = 0;\n ntvideo;\n ntlastbuf;\n \n machine = { cpuCyclesPerLine: 114 }; // TODO: hack for width of probe scope\n \n constructor(mainElement) {\n super();\n this.mainElement = mainElement;\n }\n\n getPresets() { return JSNES_PRESETS; }\n\n start() {\n this.debugPCDelta = 1;\n var debugbar = $(\"<div>\").appendTo(this.mainElement);\n this.audio = new SampleAudio(this.audioFrequency);\n this.video = new RasterVideo(this.mainElement,256,224,{overscan:true});\n this.video.create();\n // debugging view\n this.ntvideo = new RasterVideo(this.mainElement,512,480,{overscan:false});\n this.ntvideo.create();\n $(this.ntvideo.canvas).hide();\n this.ntlastbuf = new Uint32Array(0x1000);\n if (Mousetrap.bind) Mousetrap.bind('ctrl+shift+alt+n', () => {\n $(this.video.canvas).toggle()\n $(this.ntvideo.canvas).toggle()\n });\n // toggle buttons (TODO)\n /*\n $('<button>').text(\"Video\").appendTo(debugbar).click(() => { $(this.video.canvas).toggle() });\n $('<button>').text(\"Nametable\").appendTo(debugbar).click(() => { $(this.ntvideo.canvas).toggle() });\n */\n var idata = this.video.getFrameData();\n this.nes = new jsnes.NES({\n onFrame: (frameBuffer : number[]) => {\n for (var i=0; i<frameBuffer.length; i++)\n idata[i] = frameBuffer[i] | 0xff000000;\n this.video.updateFrame();\n this.frameindex++;\n this.updateDebugViews();\n },\n onAudioSample: (left:number, right:number) => {\n if (this.frameindex < 10)\n this.audio.feedSample(0, 1); // avoid popping at powerup\n else\n this.audio.feedSample((left+right)*0.5, 1);\n },\n onStatusUpdate: function(s) {\n console.log(s);\n },\n //TODO: onBatteryRamWrite\n });\n //this.nes.ppu.showSpr0Hit = true;\n //this.nes.ppu.clipToTvSize = false;\n this.nes.stop = () => {\n this.haltAndCatchFire(\"Illegal instruction\");\n throw new EmuHalt(\"CPU STOPPED\"); //TODO: haltEmulation()\n };\n // insert debug hook\n this.nes.cpu._emulate = this.nes.cpu.emulate;\n this.nes.cpu.emulate = () => {\n if (this.nes.cpu.irqRequested) this.probe.logInterrupt(this.nes.cpu.irqType || 0);\n this.probe.logExecute(this.nes.cpu.REG_PC+1, this.nes.cpu.REG_SP);\n var cycles = this.nes.cpu._emulate();\n this.evalDebugCondition();\n this.probe.logClocks(cycles);\n return cycles > 0 ? cycles : 1;\n }\n this.timer = new AnimationTimer(60, this.nextFrame.bind(this));\n // set keyboard map\n this.poller = setKeyboardFromMap(this.video, [], JSNES_KEYCODE_MAP, (o,key,code,flags) => {\n if (flags & KeyFlags.KeyDown)\n this.nes.buttonDown(o.index+1, o.mask); // controller, button\n else if (flags & KeyFlags.KeyUp)\n this.nes.buttonUp(o.index+1, o.mask); // controller, button\n });\n //var s = ''; nes.ppu.palTable.curTable.forEach((rgb) => { s += \"0x\"+hex(rgb,6)+\", \"; }); console.log(s);\n }\n \n pollControls() { this.poller.poll(); }\n\n advance(novideo : boolean) : number {\n this.nes.frame();\n return 29780; //TODO\n }\n\n updateDebugViews() {\n // don't update if view is hidden\n if (! $(this.ntvideo.canvas).is(\":visible\"))\n return;\n var a = 0;\n var attraddr = 0;\n var idata = this.ntvideo.getFrameData();\n var baseTile = this.nes.ppu.regS === 0 ? 0 : 256;\n for (var row=0; row<60; row++) {\n for (var col=0; col<64; col++) {\n a = 0x2000 + (col&31) + ((row%30)*32);\n if (col >= 32) a += 0x400;\n if (row >= 30) a += 0x800;\n var name = this.nes.ppu.mirroredLoad(a) + baseTile;\n var t = this.nes.ppu.ptTile[name];\n attraddr = (a & 0x2c00) | 0x3c0 | (a & 0x0C00) | ((a >> 4) & 0x38) | ((a >> 2) & 0x07);\n var attr = this.nes.ppu.mirroredLoad(attraddr);\n var tag = name ^ (attr<<9) ^ 0x80000000;\n if (tag != this.ntlastbuf[a & 0xfff]) {\n this.ntlastbuf[a & 0xfff] = tag;\n var i = row*64*8*8 + col*8;\n var j = 0;\n var attrshift = (col&2) + ((a&0x40)>>4);\n var coloradd = ((attr >> attrshift) & 3) << 2;\n for (var y=0; y<8; y++) {\n for (var x=0; x<8; x++) {\n var color = t.pix[j++];\n if (color) color += coloradd;\n var rgb = this.nes.ppu.imgPalette[color];\n idata[i++] = rgb | 0xff000000;\n }\n i += 64*8-8;\n }\n }\n }\n }\n this.ntvideo.updateFrame();\n }\n\n loadROM(title, data) {\n var romstr = byteArrayToString(data);\n this.nes.loadROM(romstr);\n this.frameindex = 0;\n this.installIntercepts();\n }\n installIntercepts() {\n // intercept bus calls, unless we did it already\n var mmap = this.nes.mmap;\n if (!mmap.haveProxied) {\n var oldload = mmap.load.bind(mmap);\n var oldwrite = mmap.write.bind(mmap);\n var oldregLoad = mmap.regLoad.bind(mmap);\n var oldregWrite = mmap.regWrite.bind(mmap);\n var lastioaddr = -1;\n mmap.load = (addr) => {\n var val = oldload(addr);\n if (addr != lastioaddr) this.probe.logRead(addr, val);\n return val;\n }\n mmap.write = (addr, val) => {\n if (addr != lastioaddr) this.probe.logWrite(addr, val);\n oldwrite(addr, val);\n }\n // try not to read/write then IOread/IOwrite at same time\n mmap.regLoad = (addr) => {\n var val = oldregLoad(addr);\n this.probe.logIORead(addr, val);\n lastioaddr = addr;\n return val;\n }\n mmap.regWrite = (addr, val) => {\n this.probe.logIOWrite(addr, val);\n lastioaddr = addr;\n oldregWrite(addr, val);\n }\n mmap.haveProxied = true;\n }\n var ppu = this.nes.ppu;\n if (!ppu.haveProxied) {\n var old_endScanline = ppu.endScanline.bind(ppu);\n var old_startFrame = ppu.startFrame.bind(ppu);\n var old_writeMem = ppu.writeMem.bind(ppu);\n ppu.endScanline = () => {\n old_endScanline();\n this.probe.logNewScanline();\n }\n ppu.startFrame = () => {\n old_startFrame();\n this.probe.logNewFrame();\n }\n ppu.writeMem = (a,v) => {\n old_writeMem(a,v);\n this.probe.logVRAMWrite(a,v);\n }\n ppu.haveProxied = true;\n }\n }\n newCodeAnalyzer() {\n return new CodeAnalyzer_nes(this);\n }\n getOriginPC() {\t// TODO: is actually NMI\n return (this.readAddress(0xfffa) | (this.readAddress(0xfffb) << 8)) & 0xffff;\n }\n getDefaultExtension() { return \".c\"; }\n\n getROMExtension() { return \".nes\"; }\n\n reset() {\n //this.nes.cpu.reset(); // doesn't work right, crashes\n this.nes.cpu.requestIrq(this.nes.cpu.IRQ_RESET);\n this.installIntercepts();\n }\n isRunning() {\n return this.timer.isRunning();\n }\n pause() {\n this.timer.stop();\n this.audio.stop();\n }\n resume() {\n this.timer.start();\n this.audio.start();\n }\n\n runToVsync() {\n var frame0 = this.frameindex;\n this.runEval((c) => { return this.frameindex>frame0; });\n }\n\n getRasterScanline() : number {\n return this.nes.ppu.scanline;\n }\n getRasterLineClock() : number {\n return this.nes.ppu.curX;\n }\n\n getCPUState() {\n var c = this.nes.cpu.toJSON();\n this.copy6502REGvars(c);\n return c;\n }\n // TODO don't need to save ROM?\n saveState() {\n //var s = $.extend(true, {}, this.nes);\n var s;\n if (this.nes.mmap) {\n s = this.nes.toJSON();\n } else {\n console.log(\"no nes.mmap!\");\n s = { cpu: this.nes.cpu.toJSON(), ppu: this.nes.ppu.toJSON() };\n }\n s.c = s.cpu;\n this.copy6502REGvars(s.c);\n s.b = s.cpu.mem = s.cpu.mem.slice(0);\n s.ppu.vramMem = s.ppu.vramMem.slice(0);\n s.ppu.spriteMem = s.ppu.spriteMem.slice(0);\n s.ctrl = this.saveControlsState();\n return s;\n }\n loadState(state) {\n this.unfixPC(state.cpu);\n this.nes.fromJSON(state);\n this.fixPC(state.cpu);\n //this.nes.cpu.fromJSON(state.cpu);\n //this.nes.mmap.fromJSON(state.mmap);\n //this.nes.ppu.fromJSON(state.ppu);\n this.nes.cpu.mem = state.cpu.mem.slice(0);\n this.nes.ppu.vramMem = state.ppu.vramMem.slice(0);\n this.nes.ppu.spriteMem = state.ppu.spriteMem.slice(0);\n this.loadControlsState(state.ctrl);\n //$.extend(this.nes, state);\n this.installIntercepts();\n }\n saveControlsState() {\n return {\n c1: this.nes.controllers[1].state.slice(0),\n c2: this.nes.controllers[2].state.slice(0),\n };\n }\n loadControlsState(state) {\n this.nes.controllers[1].state = state.c1;\n this.nes.controllers[2].state = state.c2;\n }\n readAddress(addr) {\n return this.nes.cpu.mem[addr];\n }\n readVRAMAddress(addr : number) : number {\n return this.nes.ppu.vramMem[addr];\n }\n copy6502REGvars(c) {\n c.T = 0;\n c.PC = c.REG_PC;\n this.fixPC(c);\n c.A = c.REG_ACC;\n c.X = c.REG_X;\n c.Y = c.REG_Y;\n c.SP = c.REG_SP & 0xff;\n c.Z = c.F_ZERO;\n c.N = c.F_SIGN;\n c.V = c.F_OVERFLOW;\n c.D = c.F_DECIMAL;\n c.C = c.F_CARRY;\n c.I = c.F_INTERRUPT;\n c.R = 1;\n c.o = this.readAddress(c.PC+1);\n return c;\n }\n\n getDebugCategories() {\n return super.getDebugCategories().concat(['PPU','Mapper']);\n }\n getDebugInfo(category, state) {\n switch (category) {\n case 'PPU': return this.ppuStateToLongString(state.ppu, state.b);\n case 'Mapper': return this.mapperStateToLongString(state.mmap, state.b);\n default: return super.getDebugInfo(category, state);\n }\n }\n ppuStateToLongString(ppu, mem) {\n var s = '';\n var PPUFLAGS = [\n [\"f_nmiOnVblank\",\"NMI_ON_VBLANK\"],\n [\"f_spVisibility\",\"SPRITES\"],\n [\"f_spClipping\",\"NO_CLIP_SPRITES\"],\n [\"f_dispType\",\"MONOCHROME\"],\n [\"f_bgVisibility\",\"BACKGROUND\"],\n [\"f_bgClipping\",\"NO_CLIP_BACKGROUND\"],\n ];\n for (var i=0; i<PPUFLAGS.length; i++) {\n var flag = PPUFLAGS[i];\n s += (ppu[flag[0]] ? flag[1] : \"-\") + \" \";\n if (i==2 || i==5) s += \"\\n\";\n }\n var status = mem[0x2002];\n s += \"\\n Status \";\n s += (status & 0x80) ? \"VBLANK \" : \"- \";\n s += (status & 0x40) ? \"SPRITE0HIT \" : \"- \";\n s += \"\\n\";\n if (ppu.f_color)\n s += \" Tint \" + ((ppu.f_color&1)?\"RED \":\"\") + ((ppu.f_color&2)?\"BLUE \":\"\") + ((ppu.f_color&4)?\"GREEN \":\"\") + \"\\n\";\n if (ppu.f_spVisibility) {\n s += \"SprSize \" + (ppu.f_spriteSize ? \"8x16\" : \"8x8\") + \"\\n\";\n s += \"SprBase $\" + (ppu.f_spPatternTable ? \"1000\" : \"0000\") + \"\\n\";\n }\n if (ppu.f_bgVisibility) {\n s += \" BgBase $\" + (ppu.f_bgPatternTable ? \"1000\" : \"0000\") + \"\\n\";\n s += \" NTBase $\" + hex(ppu.f_nTblAddress*0x400+0x2000) + \"\\n\";\n s += \"AddrInc \" + (ppu.f_addrInc ? \"32\" : \"1\") + \"\\n\";\n }\n var scrollX = ppu.regFH + ppu.regHT*8;\n var scrollY = ppu.regFV + ppu.regVT*8;\n s += \"ScrollX $\" + hex(scrollX) + \" (\" + ppu.regHT + \" * 8 + \" + ppu.regFH + \" = \" + scrollX + \")\\n\";\n s += \"ScrollY $\" + hex(scrollY) + \" (\" + ppu.regVT + \" * 8 + \" + ppu.regFV + \" = \" + scrollY + \")\\n\";\n s += \"\\n\";\n s += \" Scan Y: \" + ppu.scanline + \" X: \" + ppu.curX + \"\\n\";\n s += \"VramCur\" + (ppu.firstWrite?\" \":\"?\") + \"$\" + hex(ppu.vramAddress,4) + \"\\n\";\n s += \"VramTmp $\" + hex(ppu.vramTmpAddress,4) + \"\\n\";\n /*\n var PPUREGS = [\n 'cntFV',\n 'cntV',\n 'cntH',\n 'cntVT',\n 'cntHT',\n 'regV',\n 'regH',\n 'regS',\n ];\n s += \"\\n\";\n for (var i=0; i<PPUREGS.length; i++) {\n var reg = PPUREGS[i];\n s += lpad(reg.toUpperCase(),7) + \" $\" + hex(ppu[reg]) + \" (\" + ppu[reg] + \")\\n\";\n }\n */\n return s;\n }\n mapperStateToLongString(mmap, mem) {\n //console.log(mmap, mem);\n var s = \"\";\n if (this.nes.rom) {\n s += \"Mapper \" + this.nes.rom.mapperType + \"\\n\";\n }\n if (mmap.irqCounter !== undefined) {\n s += \"\\nIRQ Counter: \" + mmap.irqCounter;\n s += \"\\n IRQ Latch: \" + mmap.irqLatchValue;\n s += \"\\n IRQ Reload: \" + mmap.irqReload;\n s += \"\\n IRQ Enable: \" + mmap.irqEnable;\n s += \"\\n PRG Select: \" + mmap.prgAddressSelect;\n s += \"\\n CHR Select: \" + mmap.chrAddressSelect;\n }\n s += \"\\n\";\n return s;\n }\n getToolForFilename = (fn:string) : string => {\n //if (fn.endsWith(\".asm\")) return \"ca65\"; // .asm uses ca65\n if (fn.endsWith(\".nesasm\")) return \"nesasm\";\n else return getToolForFilename_6502(fn);\n }\n \n // probing\n nullProbe = new NullProbe();\n probe : ProbeAll = this.nullProbe;\n\n startProbing?() : ProbeRecorder {\n var rec = new ProbeRecorder(this);\n this.connectProbe(rec);\n return rec;\n }\n stopProbing?() : void {\n this.connectProbe(null);\n }\n connectProbe(probe:ProbeAll) {\n this.probe = probe || this.nullProbe;\n }\n\n getMemoryMap = function() { return { main:[\n {name:'Zero Page RAM',start:0x0,size:0x100,type:'ram'},\n {name:'OAM Buffer',start:0x200,size:0x100,type:'ram'},\n {name:'Work RAM',start:0x300,size:0x1000-0x300,type:'ram'},\n {name:'PPU Registers',start:0x2000,last:0x2008,size:0x2000,type:'io'},\n {name:'APU Registers',start:0x4000,last:0x4020,size:0x2000,type:'io'},\n {name:'Optional Cartridge RAM',start:0x6000,size:0x2000,type:'ram'},\n ] } };\n\n showHelp() {\n return \"https://8bitworkshop.com/docs/platforms/nes/\";\n }\n\n getDebugSymbolFile() {\n var sym = this.debugSymbols.addr2symbol;\n var text = \"\";\n $.each(sym, function(k, v) {\n let symType;\n if (k < 0x2000) {\n k = k % 0x800;\n symType = \"R\";\n } else if (k < 0x6000) symType = \"G\";\n else if (k < 0x8000) {\n k = k - 0x6000;\n symType = \"S\";\n } else { \n k = k - 0x8000;\n symType = \"P\";\n }\n let addr = Number(k).toString(16).padStart(4, '0').toUpperCase();\n // Mesen doesn't allow lables to start with digits\n if (v[0] >= '0' && v[0] <= '9') {\n v = \"L\" + v;\n }\n // nor does it allow dots\n v = (v as any).replaceAll('.', '_');\n text += `${symType}:${addr}:${v}\\n`;\n });\n return {\n extension:\".mlb\", \n blob: new Blob([text], {type:\"text/plain\"})\n };\n }\n}\n\n/// MAME support\n\nclass NESMAMEPlatform extends BaseMAME6502Platform implements Platform {\n\n start() {\n }\n\n loadROM(title, data) {\n if (!this.started) {\n this.startModule(this.mainElement, {\n jsfile:'mame8bitws.js',\n //cfgfile:'nes.cfg',\n driver:'nes',\n width:256,\n height:240,\n romfn:'/emulator/cart.nes',\n romdata:new Uint8Array(data),\n preInit:function(_self) {\n },\n });\n } else {\n // look at iNES header for PRG and CHR ROM lengths\n var prgromlen = data[4] * 0x4000;\n var chrromlen = data[5] * 0x2000;\n this.loadROMFile(data);\n this.loadRegion(\":nes_slot:cart:prg_rom\", data.slice(0x10, 0x10+prgromlen));\n this.loadRegion(\":nes_slot:cart:chr_rom\", data.slice(0x10+prgromlen, 0x10+prgromlen+chrromlen));\n }\n }\n\n getPresets() { return JSNES_PRESETS; }\n getToolForFilename = getToolForFilename_6502;\n getOpcodeMetadata = getOpcodeMetadata_6502;\n getDefaultExtension() { return \".c\"; };\n\n}\n\n///\n\nPLATFORMS['nes'] = JSNESPlatform;\nPLATFORMS['nes-asm'] = JSNESPlatform;\nPLATFORMS['nes.mame'] = NESMAMEPlatform;\n\n"],
"mappings": "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AAU,EAAG,GAGjD,KAAK,SAAW,GAAI,OACT,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC9B,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,E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",
"names": []
}