8bitworkshop/gen/arm32-R5NJVEXG.js.map

8 lines
192 KiB
Plaintext

{
"version": 3,
"sources": ["../src/common/cpu/ARM.ts", "../src/machine/arm32.ts", "../src/platform/arm32.ts"],
"sourcesContent": ["/*\nFrom: https://github.com/endrift/gbajs\n\nCopyright \u00A9 2012 \u2013 2013, Jeffrey Pfau\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n*/\n\nimport { Bus, CPU, InstructionBased, SavesState } from \"../devices\";\nimport { EmuHalt } from \"../emu\";\nimport { hex } from \"../util\";\n\ninterface AddressFunction extends Function {\n writesPC? : boolean;\n fixedJump? : boolean;\n}\n\ninterface ARMIRQInterface {\n\tclear() : void;\n\tswi(opcode : number) : void;\n\tswi32(opcode : number) : void;\n\tupdateTimers() : void;\n\ttestIRQ() : void;\n}\n\ninterface ARMMemoryRegion {\n\tPAGE_MASK : number;\n\tICACHE_PAGE_BITS : number;\n\ticache : ARMMemoryPage[];\n}\n\ninterface ARMOperation {\n\tnext : ARMOperation;\n\tpage : ARMMemoryPage;\n\taddress : number;\n\topcode : number;\n}\n\ninterface ARMMemoryPage {\n\tarm : ARMOperation[];\n\tthumb : ARMOperation[];\n\tinvalid : boolean;\n}\n\ninterface ARMMMUInterface {\n\tmemory : ARMMemoryRegion[];\n\tBASE_OFFSET : number;\n\tOFFSET_MASK : number;\n\n\tload8(a: number) : number;\n\tloadU8(a: number) : number;\n\tload16(a: number) : number;\n\tloadU16(a: number) : number;\n\tload32(a: number) : number;\n\tstore8(a: number, v: number) : void;\n\tstore16(a: number, v: number) : void;\n\tstore32(a: number, v: number) : void;\n\n\twait(a: number) : void;\n\twait32(a: number) : void;\n\twaitSeq32(a: number) : void;\n\twaitMul(a: number) : void;\n\twaitMulti32(a: number, total: number) : void;\n\twaitPrefetch(a: number) : void;\n\twaitPrefetch32(a: number) : void;\n\n\taddressToPage(region: number, address: number) : number;\n\taccessPage(region: number, pageId: number) : ARMMemoryPage;\n}\n\nexport interface ARMCoreState {\n\tPC: number,\n\tSP: number,\n\tgprs: number[],\n\tmode: number,\n\tcpsrI: boolean,\n\tcpsrF: boolean,\n\tcpsrV: boolean,\n\tcpsrC: boolean,\n\tcpsrZ: boolean,\n\tcpsrN: boolean,\n\tbankedRegisters: number[][],\n\tspsr: number,\n\tbankedSPSRs: number[],\n\tcycles: number,\n\tinstructionWidth: 2 | 4\n}\n\ninterface ARMCoreType {\n\tgprs: Int32Array;\n\tPC: number;\n\tSP: number;\n\tLR: number;\n\tcycles: number;\n\tmode: number;\n\tshifterOperand: number;\n\tshifterCarryOut: number|boolean;\n\tcpsrN: number|boolean;\n\tcpsrC: number|boolean;\n\tcpsrZ: number|boolean;\n\tcpsrV: number|boolean;\n\tcpsrI: number|boolean;\n\tcpsrF: number|boolean;\n\tspsr: number;\n\tmmu: ARMMMUInterface;\n\tirq : ARMIRQInterface;\n\tinstructionWidth: 2 | 4;\n\n\thasSPSR() : boolean;\n\tunpackCPSR(v : number) : void;\n\tswitchMode(mode : number) : void;\n\tswitchExecMode(mode : number) : void;\n\tpackCPSR() : number;\n\n\tstep() : void;\n\tresetCPU(startOffset : number) : void;\n\tfreeze() : ARMCoreState;\n\tdefrost(state: ARMCoreState) : void;\n\n\traiseIRQ() : void;\n\traiseTrap(irqType? : number) : void;\n}\n\nexport enum ARMMode {\n\tMODE_ARM = 0,\n\tMODE_THUMB = 1,\n\t\n\tMODE_USER = 0x10,\n\tMODE_FIQ = 0x11,\n\tMODE_IRQ = 0x12,\n\tMODE_SUPERVISOR = 0x13,\n\tMODE_ABORT = 0x17,\n\tMODE_UNDEFINED = 0x1B,\n\tMODE_SYSTEM = 0x1F\n}\n\nexport enum ARMRegs {\n\tSP = 13,\n\tLR = 14,\n\tPC = 15,\n}\n\nexport enum ARMConstants {\n\n\tBANK_NONE = 0,\n\tBANK_FIQ = 1,\n\tBANK_IRQ = 2,\n\tBANK_SUPERVISOR = 3,\n\tBANK_ABORT = 4,\n\tBANK_UNDEFINED = 5,\n\n\tWORD_SIZE_ARM = 4,\n\tWORD_SIZE_THUMB = 2,\n\n\tBASE_RESET = 0x00000000,\n\tBASE_UNDEF = 0x00000004,\n\tBASE_SWI = 0x00000008,\n\tBASE_PABT = 0x0000000C,\n\tBASE_DABT = 0x00000010,\n\tBASE_IRQ = 0x00000018,\n\tBASE_FIQ = 0x0000001C,\n}\n\nconst UNALLOC_MASK = 0x0FFFFF00;\nconst USER_MASK = 0xF0000000;\nconst PRIV_MASK = 0x000000DF; // This is out of spec? (SEH)\nconst STATE_MASK = 0x00000020;\n\n\n///////////////////////////////////////////////////////////////////////////\n\nfunction ARMCoreArm(cpu: ARMCoreType) {\n\tthis.cpu = cpu;\n\n\tthis.addressingMode23Immediate = [\n\t\t// 000x0\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] -= offset;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\t// 000xW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// 00Ux0\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] += offset;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\t// 00UxW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// 0P0x0\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\treturn /* addr = */ gprs[rn] - offset;\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// 0P0xW\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn] - offset;\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull,\n\n\t\t// 0PUx0\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\treturn /* addr = */ gprs[rn] + offset;\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// 0PUxW\n\t\tfunction(rn, offset, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn] + offset;\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull,\n\t];\n\n\tthis.addressingMode23Register = [\n\t\t// I00x0\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] -= gprs[rm];\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\t// I00xW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// I0Ux0\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] += gprs[rm];\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\t// I0UxW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// IP0x0\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\treturn gprs[rn] - gprs[rm];\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// IP0xW\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn] - gprs[rm];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull,\n\n\t\t// IPUx0\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn] + gprs[rm];\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// IPUxW\n\t\tfunction(rn, rm, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn] + gprs[rm];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull\n\t];\n\n\tthis.addressingMode2RegisterShifted = [\n\t\t// I00x0\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tshiftOp();\n\t\t\t\t\tgprs[rn] -= cpu.shifterOperand;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\t// I00xW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// I0Ux0\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tvar addr = gprs[rn];\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tshiftOp();\n\t\t\t\t\tgprs[rn] += cpu.shifterOperand;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\t\t// I0UxW\n\t\tnull,\n\n\t\tnull,\n\t\tnull,\n\n\t\t// IP0x0\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tshiftOp();\n\t\t\t\treturn gprs[rn] - cpu.shifterOperand;\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// IP0xW\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tshiftOp();\n\t\t\t\tvar addr = gprs[rn] - cpu.shifterOperand;\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull,\n\n\t\t// IPUx0\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tshiftOp();\n\t\t\t\treturn gprs[rn] + cpu.shifterOperand;\n\t\t\t};\n\t\t\taddress.writesPC = false;\n\t\t\treturn address;\n\t\t},\n\n\t\t// IPUxW\n\t\tfunction(rn, shiftOp, condOp) {\n\t\t\tvar gprs = cpu.gprs;\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tshiftOp();\n\t\t\t\tvar addr = gprs[rn] + cpu.shifterOperand;\n\t\t\t\tif (!condOp || condOp()) {\n\t\t\t\t\tgprs[rn] = addr;\n\t\t\t\t}\n\t\t\t\treturn addr;\n\t\t\t};\n\t\t\taddress.writesPC = rn == ARMRegs.PC;\n\t\t\treturn address;\n\t\t},\n\n\t\tnull,\n\t\tnull,\n\t];\n}\n\nARMCoreArm.prototype.constructAddressingMode1ASR = function(rs, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\t++cpu.cycles;\n\t\tvar shift = gprs[rs];\n\t\tif (rs == ARMRegs.PC) {\n\t\t\tshift += 4;\n\t\t}\n\t\tshift &= 0xFF;\n\t\tvar shiftVal = gprs[rm];\n\t\tif (rm == ARMRegs.PC) {\n\t\t\tshiftVal += 4;\n\t\t}\n\t\tif (shift == 0) {\n\t\t\tcpu.shifterOperand = shiftVal;\n\t\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t\t} else if (shift < 32) {\n\t\t\tcpu.shifterOperand = shiftVal >> shift;\n\t\t\tcpu.shifterCarryOut = shiftVal & (1 << (shift - 1));\n\t\t} else if (gprs[rm] >> 31) {\n\t\t\tcpu.shifterOperand = 0xFFFFFFFF;\n\t\t\tcpu.shifterCarryOut = 0x80000000;\n\t\t} else {\n\t\t\tcpu.shifterOperand = 0;\n\t\t\tcpu.shifterCarryOut = 0;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructAddressingMode1Immediate = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\treturn function() {\n\t\tcpu.shifterOperand = immediate;\n\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t};\n};\n\nARMCoreArm.prototype.constructAddressingMode1ImmediateRotate = function(immediate, rotate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\treturn function() {\n\t\tcpu.shifterOperand = (immediate >>> rotate) | (immediate << (32 - rotate));\n\t\tcpu.shifterCarryOut = cpu.shifterOperand >> 31;\n\t}\n};\n\nARMCoreArm.prototype.constructAddressingMode1LSL = function(rs, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\t++cpu.cycles;\n\t\tvar shift = gprs[rs];\n\t\tif (rs == ARMRegs.PC) {\n\t\t\tshift += 4;\n\t\t}\n\t\tshift &= 0xFF;\n\t\tvar shiftVal = gprs[rm];\n\t\tif (rm == ARMRegs.PC) {\n\t\t\tshiftVal += 4;\n\t\t}\n\t\tif (shift == 0) {\n\t\t\tcpu.shifterOperand = shiftVal;\n\t\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t\t} else if (shift < 32) {\n\t\t\tcpu.shifterOperand = shiftVal << shift;\n\t\t\tcpu.shifterCarryOut = shiftVal & (1 << (32 - shift));\n\t\t} else if (shift == 32) {\n\t\t\tcpu.shifterOperand = 0;\n\t\t\tcpu.shifterCarryOut = shiftVal & 1;\n\t\t} else {\n\t\t\tcpu.shifterOperand = 0;\n\t\t\tcpu.shifterCarryOut = 0;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructAddressingMode1LSR = function(rs, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\t++cpu.cycles;\n\t\tvar shift = gprs[rs];\n\t\tif (rs == ARMRegs.PC) {\n\t\t\tshift += 4;\n\t\t}\n\t\tshift &= 0xFF;\n\t\tvar shiftVal = gprs[rm];\n\t\tif (rm == ARMRegs.PC) {\n\t\t\tshiftVal += 4;\n\t\t}\n\t\tif (shift == 0) {\n\t\t\tcpu.shifterOperand = shiftVal;\n\t\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t\t} else if (shift < 32) {\n\t\t\tcpu.shifterOperand = shiftVal >>> shift;\n\t\t\tcpu.shifterCarryOut = shiftVal & (1 << (shift - 1));\n\t\t} else if (shift == 32) {\n\t\t\tcpu.shifterOperand = 0;\n\t\t\tcpu.shifterCarryOut = shiftVal >> 31;\n\t\t} else {\n\t\t\tcpu.shifterOperand = 0;\n\t\t\tcpu.shifterCarryOut = 0;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructAddressingMode1ROR = function(rs, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\t++cpu.cycles;\n\t\tvar shift = gprs[rs];\n\t\tif (rs == ARMRegs.PC) {\n\t\t\tshift += 4;\n\t\t}\n\t\tshift &= 0xFF;\n\t\tvar shiftVal = gprs[rm];\n\t\tif (rm == ARMRegs.PC) {\n\t\t\tshiftVal += 4;\n\t\t}\n\t\tvar rotate = shift & 0x1F;\n\t\tif (shift == 0) {\n\t\t\tcpu.shifterOperand = shiftVal;\n\t\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t\t} else if (rotate) {\n\t\t\tcpu.shifterOperand = (gprs[rm] >>> rotate) | (gprs[rm] << (32 - rotate));\n\t\t\tcpu.shifterCarryOut = shiftVal & (1 << (rotate - 1));\n\t\t} else {\n\t\t\tcpu.shifterOperand = shiftVal;\n\t\t\tcpu.shifterCarryOut = shiftVal >> 31;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructAddressingMode23Immediate = function(instruction, immediate, condOp) {\n\tvar rn = (instruction & 0x000F0000) >> 16;\n\treturn this.addressingMode23Immediate[(instruction & 0x01A00000) >> 21](rn, immediate, condOp);\n};\n\nARMCoreArm.prototype.constructAddressingMode23Register = function(instruction, rm, condOp) {\n\tvar rn = (instruction & 0x000F0000) >> 16;\n\treturn this.addressingMode23Register[(instruction & 0x01A00000) >> 21](rn, rm, condOp);\n};\n\nARMCoreArm.prototype.constructAddressingMode2RegisterShifted = function(instruction, shiftOp, condOp) {\n\tvar rn = (instruction & 0x000F0000) >> 16;\n\treturn this.addressingMode2RegisterShifted[(instruction & 0x01A00000) >> 21](rn, shiftOp, condOp);\n};\n\nARMCoreArm.prototype.constructAddressingMode4 = function(immediate, rn) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar addr = gprs[rn] + immediate;\n\t\treturn addr;\n\t}\n};\n\nARMCoreArm.prototype.constructAddressingMode4Writeback = function(immediate, offset, rn, overlap) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function(writeInitial) {\n\t\tvar addr = gprs[rn] + immediate;\n\t\tif (writeInitial && overlap) {\n\t\t\tcpu.mmu.store32(gprs[rn] + immediate - 4, gprs[rn]);\n\t\t}\n\t\tgprs[rn] += offset;\n\t\treturn addr;\n\t}\n};\n\nARMCoreArm.prototype.constructADC = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar shifterOperand = (cpu.shifterOperand >>> 0) + (cpu.cpsrC ? 1 : 0);\n\t\tgprs[rd] = (gprs[rn] >>> 0) + shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructADCS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar shifterOperand = (cpu.shifterOperand >>> 0) + (cpu.cpsrC ? 1 : 0);\n\t\tvar d = (gprs[rn] >>> 0) + shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\t\tcpu.cpsrV = (gprs[rn] >> 31) == (shifterOperand >> 31) &&\n\t\t\t\t\t\t(gprs[rn] >> 31) != (d >> 31) &&\n\t\t\t\t\t\t(shifterOperand >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructADD = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = (gprs[rn] >>> 0) + (cpu.shifterOperand >>> 0);\n\t};\n};\n\nARMCoreArm.prototype.constructADDS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar d = (gprs[rn] >>> 0) + (cpu.shifterOperand >>> 0);\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\t\tcpu.cpsrV = (gprs[rn] >> 31) == (cpu.shifterOperand >> 31) &&\n\t\t\t\t\t\t(gprs[rn] >> 31) != (d >> 31) &&\n\t\t\t\t\t\t(cpu.shifterOperand >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructAND = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] & cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructANDS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] & cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructB = function(immediate, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tgprs[ARMRegs.PC] += immediate;\n\t};\n};\n\nARMCoreArm.prototype.constructBIC = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] & ~cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructBICS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] & ~cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructBL = function(immediate, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tgprs[ARMRegs.LR] = gprs[ARMRegs.PC] - 4;\n\t\tgprs[ARMRegs.PC] += immediate;\n\t};\n};\n\nARMCoreArm.prototype.constructBX = function(rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tcpu.switchExecMode(gprs[rm] & 0x00000001);\n\t\tgprs[ARMRegs.PC] = gprs[rm] & 0xFFFFFFFE;\n\t};\n};\n\nARMCoreArm.prototype.constructCMN = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar aluOut = (gprs[rn] >>> 0) + (cpu.shifterOperand >>> 0);\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = aluOut > 0xFFFFFFFF;\n\t\tcpu.cpsrV = (gprs[rn] >> 31) == (cpu.shifterOperand >> 31) &&\n\t\t\t\t\t(gprs[rn] >> 31) != (aluOut >> 31) &&\n\t\t\t\t\t(cpu.shifterOperand >> 31) != (aluOut >> 31);\n\t};\n};\n\nARMCoreArm.prototype.constructCMP = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar aluOut = gprs[rn] - cpu.shifterOperand;\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= (cpu.shifterOperand >>> 0);\n\t\tcpu.cpsrV = (gprs[rn] >> 31) != (cpu.shifterOperand >> 31) &&\n\t\t\t\t\t(gprs[rn] >> 31) != (aluOut >> 31);\n\t};\n};\n\nARMCoreArm.prototype.constructEOR = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] ^ cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructEORS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] ^ cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructLDM = function(rs, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\tvar mmu = cpu.mmu;\n\treturn function() {\n\t\tmmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address(false);\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tfor (m = rs, i = 0; m; m >>= 1, ++i) {\n\t\t\tif (m & 1) {\n\t\t\t\tgprs[i] = mmu.load32(addr & 0xFFFFFFFC);\n\t\t\t\taddr += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tmmu.waitMulti32(addr, total);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDMS = function(rs, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\tvar mmu = cpu.mmu;\n\treturn function() {\n\t\tmmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address(false);\n\t\tvar total = 0;\n\t\tvar mode = cpu.mode;\n\t\tcpu.switchMode(ARMMode.MODE_SYSTEM);\n\t\tvar m, i;\n\t\tfor (m = rs, i = 0; m; m >>= 1, ++i) {\n\t\t\tif (m & 1) {\n\t\t\t\tgprs[i] = mmu.load32(addr & 0xFFFFFFFC);\n\t\t\t\taddr += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tcpu.switchMode(mode);\n\t\tmmu.waitMulti32(addr, total);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDR = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tgprs[rd] = cpu.mmu.load32(addr);\n\t\tcpu.mmu.wait32(addr);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDRB = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tgprs[rd] = cpu.mmu.loadU8(addr);\n\t\tcpu.mmu.wait(addr);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDRH = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tgprs[rd] = cpu.mmu.loadU16(addr);\n\t\tcpu.mmu.wait(addr);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDRSB = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tgprs[rd] = cpu.mmu.load8(addr);\n\t\tcpu.mmu.wait(addr);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructLDRSH = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tgprs[rd] = cpu.mmu.load16(addr);\n\t\tcpu.mmu.wait(addr);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreArm.prototype.constructMLA = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(rs);\n\t\tif ((gprs[rm] & 0xFFFF0000) && (gprs[rs] & 0xFFFF0000)) {\n\t\t\t// Our data type is a double--we'll lose bits if we do it all at once!\n\t\t\tvar hi = ((gprs[rm] & 0xFFFF0000) * gprs[rs]) & 0xFFFFFFFF;\n\t\t\tvar lo = ((gprs[rm] & 0x0000FFFF) * gprs[rs]) & 0xFFFFFFFF;\n\t\t\tgprs[rd] = (hi + lo + gprs[rn]) & 0xFFFFFFFF;\n\t\t} else {\n\t\t\tgprs[rd] = gprs[rm] * gprs[rs] + gprs[rn];\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructMLAS = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(rs);\n\t\tif ((gprs[rm] & 0xFFFF0000) && (gprs[rs] & 0xFFFF0000)) {\n\t\t\t// Our data type is a double--we'll lose bits if we do it all at once!\n\t\t\tvar hi = ((gprs[rm] & 0xFFFF0000) * gprs[rs]) & 0xFFFFFFFF;\n\t\t\tvar lo = ((gprs[rm] & 0x0000FFFF) * gprs[rs]) & 0xFFFFFFFF;\n\t\t\tgprs[rd] = (hi + lo + gprs[rn]) & 0xFFFFFFFF;\n\t\t} else {\n\t\t\tgprs[rd] = gprs[rm] * gprs[rs] + gprs[rn];\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreArm.prototype.constructMOV = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructMOVS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructMRS = function(rd, r, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tif (r) {\n\t\t\tgprs[rd] = cpu.spsr;\n\t\t} else {\n\t\t\tgprs[rd] = cpu.packCPSR();\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructMSR = function(rm, r, instruction, immediate, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\tvar c = instruction & 0x00010000;\n\t//var x = instruction & 0x00020000;\n\t//var s = instruction & 0x00040000;\n\tvar f = instruction & 0x00080000;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tvar operand;\n\t\tif (instruction & 0x02000000) {\n\t\t\toperand = immediate;\n\t\t} else {\n\t\t\toperand = gprs[rm];\n\t\t}\n\t\tvar mask = (c ? 0x000000FF : 0x00000000) |\n\t\t\t\t //(x ? 0x0000FF00 : 0x00000000) | // Irrelevant on ARMv4T\n\t\t\t\t //(s ? 0x00FF0000 : 0x00000000) | // Irrelevant on ARMv4T\n\t\t\t\t (f ? 0xFF000000 : 0x00000000);\n\t\tif (r) {\n\t\t\tmask &= USER_MASK | PRIV_MASK | STATE_MASK;\n\t\t\t//console.log(hex(r), hex(mask & 0x7fffffff), hex(cpu.spsr), hex(operand));\n\t\t\tcpu.spsr = (cpu.spsr & ~mask) | (operand & mask);\n\t\t} else {\n\t\t\tif (mask & USER_MASK) {\n\t\t\t\tcpu.cpsrN = operand >> 31;\n\t\t\t\tcpu.cpsrZ = operand & 0x40000000;\n\t\t\t\tcpu.cpsrC = operand & 0x20000000;\n\t\t\t\tcpu.cpsrV = operand & 0x10000000;\n\t\t\t}\n\t\t\tif (cpu.mode != ARMMode.MODE_USER && (mask & PRIV_MASK)) {\n\t\t\t\tcpu.switchMode((operand & 0x0000000F) | 0x00000010);\n\t\t\t\tcpu.cpsrI = operand & 0x00000080;\n\t\t\t\tcpu.cpsrF = operand & 0x00000040;\n\t\t\t}\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructMUL = function(rd, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tif ((gprs[rm] & 0xFFFF0000) && (gprs[rs] & 0xFFFF0000)) {\n\t\t\t// Our data type is a double--we'll lose bits if we do it all at once!\n\t\t\tvar hi = ((gprs[rm] & 0xFFFF0000) * gprs[rs]) | 0;\n\t\t\tvar lo = ((gprs[rm] & 0x0000FFFF) * gprs[rs]) | 0;\n\t\t\tgprs[rd] = hi + lo;\n\t\t} else {\n\t\t\tgprs[rd] = gprs[rm] * gprs[rs];\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructMULS = function(rd, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tif ((gprs[rm] & 0xFFFF0000) && (gprs[rs] & 0xFFFF0000)) {\n\t\t\t// Our data type is a double--we'll lose bits if we do it all at once!\n\t\t\tvar hi = ((gprs[rm] & 0xFFFF0000) * gprs[rs]) | 0;\n\t\t\tvar lo = ((gprs[rm] & 0x0000FFFF) * gprs[rs]) | 0;\n\t\t\tgprs[rd] = hi + lo;\n\t\t} else {\n\t\t\tgprs[rd] = gprs[rm] * gprs[rs];\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreArm.prototype.constructMVN = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = ~cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructMVNS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = ~cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructORR = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] | cpu.shifterOperand;\n\t}\n};\n\nARMCoreArm.prototype.constructORRS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] | cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t\t}\n\t};\n};\n\nARMCoreArm.prototype.constructRSB = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = cpu.shifterOperand - gprs[rn];\n\t};\n};\n\nARMCoreArm.prototype.constructRSBS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar d = cpu.shifterOperand - gprs[rn];\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = (cpu.shifterOperand >>> 0) >= (gprs[rn] >>> 0);\n\t\t\tcpu.cpsrV = (cpu.shifterOperand >> 31) != (gprs[rn] >> 31) &&\n\t\t\t\t\t\t(cpu.shifterOperand >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructRSC = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar n = (gprs[rn] >>> 0) + (cpu.cpsrC ? 0 : 1);\n\t\tgprs[rd] = (cpu.shifterOperand >>> 0) - n;\n\t};\n};\n\nARMCoreArm.prototype.constructRSCS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar n = (gprs[rn] >>> 0) + (cpu.cpsrC ? 0 : 1);\n\t\tvar d = (cpu.shifterOperand >>> 0) - n;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = (cpu.shifterOperand >>> 0) >= (d >>> 0);\n\t\t\tcpu.cpsrV = (cpu.shifterOperand >> 31) != (n >> 31) &&\n\t\t\t\t\t\t(cpu.shifterOperand >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructSBC = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar shifterOperand = (cpu.shifterOperand >>> 0) + (cpu.cpsrC ? 0 : 1);\n\t\tgprs[rd] = (gprs[rn] >>> 0) - shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructSBCS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar shifterOperand = (cpu.shifterOperand >>> 0) + (cpu.cpsrC ? 0 : 1);\n\t\tvar d = (gprs[rn] >>> 0) - shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= (d >>> 0);\n\t\t\tcpu.cpsrV = (gprs[rn] >> 31) != (shifterOperand >> 31) &&\n\t\t\t\t\t\t(gprs[rn] >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructSMLAL = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.cycles += 2;\n\t\tcpu.mmu.waitMul(rs);\n\t\tvar hi = (gprs[rm] & 0xFFFF0000) * gprs[rs];\n\t\tvar lo = (gprs[rm] & 0x0000FFFF) * gprs[rs];\n\t\tvar carry = (gprs[rn] >>> 0) + hi + lo;\n\t\tgprs[rn] = carry;\n\t\tgprs[rd] += Math.floor(carry * SHIFT_32);\n\t};\n};\n\nARMCoreArm.prototype.constructSMLALS = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.cycles += 2;\n\t\tcpu.mmu.waitMul(rs);\n\t\tvar hi = (gprs[rm] & 0xFFFF0000) * gprs[rs];\n\t\tvar lo = (gprs[rm] & 0x0000FFFF) * gprs[rs];\n\t\tvar carry = (gprs[rn] >>> 0) + hi + lo;\n\t\tgprs[rn] = carry;\n\t\tgprs[rd] += Math.floor(carry * SHIFT_32);\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !((gprs[rd] & 0xFFFFFFFF) || (gprs[rn] & 0xFFFFFFFF));\n\t};\n};\n\nARMCoreArm.prototype.constructSMULL = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >> 0) * (gprs[rs] >> 0);\n\t\tvar lo = ((gprs[rm] & 0x0000FFFF) >> 0) * (gprs[rs] >> 0);\n\t\tgprs[rn] = ((hi & 0xFFFFFFFF) + (lo & 0xFFFFFFFF)) & 0xFFFFFFFF;\n\t\tgprs[rd] = Math.floor(hi * SHIFT_32 + lo * SHIFT_32);\n\t};\n};\n\nARMCoreArm.prototype.constructSMULLS = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >> 0) * (gprs[rs] >> 0);\n\t\tvar lo = ((gprs[rm] & 0x0000FFFF) >> 0) * (gprs[rs] >> 0);\n\t\tgprs[rn] = ((hi & 0xFFFFFFFF) + (lo & 0xFFFFFFFF)) & 0xFFFFFFFF;\n\t\tgprs[rd] = Math.floor(hi * SHIFT_32 + lo * SHIFT_32);\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !((gprs[rd] & 0xFFFFFFFF) || (gprs[rn] & 0xFFFFFFFF));\n\t};\n};\n\nARMCoreArm.prototype.constructSTM = function(rs, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\tvar mmu = cpu.mmu;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tmmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tmmu.wait32(gprs[ARMRegs.PC]);\n\t\tvar addr = address(true);\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tfor (m = rs, i = 0; m; m >>= 1, ++i) {\n\t\t\tif (m & 1) {\n\t\t\t\tmmu.store32(addr, gprs[i]);\n\t\t\t\taddr += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tmmu.waitMulti32(addr, total);\n\t};\n};\n\nARMCoreArm.prototype.constructSTMS = function(rs, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\tvar mmu = cpu.mmu;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tmmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tmmu.wait32(gprs[ARMRegs.PC]);\n\t\tvar mode = cpu.mode;\n\t\tvar addr = address(true);\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tcpu.switchMode(ARMMode.MODE_SYSTEM);\n\t\tfor (m = rs, i = 0; m; m >>= 1, ++i) {\n\t\t\tif (m & 1) {\n\t\t\t\tmmu.store32(addr, gprs[i]);\n\t\t\t\taddr += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tcpu.switchMode(mode);\n\t\tmmu.waitMulti32(addr, total);\n\t};\n};\n\nARMCoreArm.prototype.constructSTR = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tcpu.mmu.store32(addr, gprs[rd]);\n\t\tcpu.mmu.wait32(addr);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.PC]);\n\t};\n};\n\nARMCoreArm.prototype.constructSTRB = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tcpu.mmu.store8(addr, gprs[rd]);\n\t\tcpu.mmu.wait(addr);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.PC]);\n\t};\n};\n\nARMCoreArm.prototype.constructSTRH = function(rd, address, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tvar addr = address();\n\t\tcpu.mmu.store16(addr, gprs[rd]);\n\t\tcpu.mmu.wait(addr);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.PC]);\n\t};\n};\n\nARMCoreArm.prototype.constructSUB = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tgprs[rd] = gprs[rn] - cpu.shifterOperand;\n\t};\n};\n\nARMCoreArm.prototype.constructSUBS = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar d = gprs[rn] - cpu.shifterOperand;\n\t\tif (rd == ARMRegs.PC && cpu.hasSPSR()) {\n\t\t\tcpu.unpackCPSR(cpu.spsr);\n\t\t} else {\n\t\t\tcpu.cpsrN = d >> 31;\n\t\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= (cpu.shifterOperand >>> 0);\n\t\t\tcpu.cpsrV = (gprs[rn] >> 31) != (cpu.shifterOperand >> 31) &&\n\t\t\t\t\t\t(gprs[rn] >> 31) != (d >> 31);\n\t\t}\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreArm.prototype.constructSWI = function(immediate, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tif (condOp && !condOp()) {\n\t\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\t\treturn;\n\t\t}\n\t\tcpu.irq.swi32(immediate);\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t};\n};\n\nARMCoreArm.prototype.constructSWP = function(rd, rn, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.wait32(gprs[rn]);\n\t\tcpu.mmu.wait32(gprs[rn]);\n\t\tvar d = cpu.mmu.load32(gprs[rn]);\n\t\tcpu.mmu.store32(gprs[rn], gprs[rm]);\n\t\tgprs[rd] = d;\n\t\t++cpu.cycles;\n\t}\n};\n\nARMCoreArm.prototype.constructSWPB = function(rd, rn, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.mmu.wait(gprs[rn]);\n\t\tcpu.mmu.wait(gprs[rn]);\n\t\tvar d = cpu.mmu.loadU8(gprs[rn]);\n\t\tcpu.mmu.store8(gprs[rn], gprs[rm]);\n\t\tgprs[rd] = d;\n\t\t++cpu.cycles;\n\t}\n};\n\nARMCoreArm.prototype.constructTEQ = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar aluOut = gprs[rn] ^ cpu.shifterOperand;\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t};\n};\n\nARMCoreArm.prototype.constructTST = function(rd, rn, shiftOp, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tshiftOp();\n\t\tvar aluOut = gprs[rn] & cpu.shifterOperand;\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = cpu.shifterCarryOut;\n\t};\n};\n\nARMCoreArm.prototype.constructUMLAL = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.cycles += 2;\n\t\tcpu.mmu.waitMul(rs);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >>> 0) * (gprs[rs] >>> 0);\n\t\tvar lo = (gprs[rm] & 0x0000FFFF) * (gprs[rs] >>> 0);\n\t\tvar carry = (gprs[rn] >>> 0) + hi + lo;\n\t\tgprs[rn] = carry;\n\t\tgprs[rd] += carry * SHIFT_32;\n\t};\n};\n\nARMCoreArm.prototype.constructUMLALS = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\tcpu.cycles += 2;\n\t\tcpu.mmu.waitMul(rs);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >>> 0) * (gprs[rs] >>> 0);\n\t\tvar lo = (gprs[rm] & 0x0000FFFF) * (gprs[rs] >>> 0);\n\t\tvar carry = (gprs[rn] >>> 0) + hi + lo;\n\t\tgprs[rn] = carry;\n\t\tgprs[rd] += carry * SHIFT_32;\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !((gprs[rd] & 0xFFFFFFFF) || (gprs[rn] & 0xFFFFFFFF));\n\t};\n};\n\nARMCoreArm.prototype.constructUMULL = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >>> 0) * (gprs[rs] >>> 0);\n\t\tvar lo = ((gprs[rm] & 0x0000FFFF) >>> 0) * (gprs[rs] >>> 0);\n\t\tgprs[rn] = ((hi & 0xFFFFFFFF) + (lo & 0xFFFFFFFF)) & 0xFFFFFFFF;\n\t\tgprs[rd] = (hi * SHIFT_32 + lo * SHIFT_32) >>> 0;\n\t};\n};\n\nARMCoreArm.prototype.constructUMULLS = function(rd, rn, rs, rm, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar SHIFT_32 = 1/0x100000000;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch32(gprs[ARMRegs.PC]);\n\t\tif (condOp && !condOp()) {\n\t\t\treturn;\n\t\t}\n\t\t++cpu.cycles;\n\t\tcpu.mmu.waitMul(gprs[rs]);\n\t\tvar hi = ((gprs[rm] & 0xFFFF0000) >>> 0) * (gprs[rs] >>> 0);\n\t\tvar lo = ((gprs[rm] & 0x0000FFFF) >>> 0) * (gprs[rs] >>> 0);\n\t\tgprs[rn] = ((hi & 0xFFFFFFFF) + (lo & 0xFFFFFFFF)) & 0xFFFFFFFF;\n\t\tgprs[rd] = (hi * SHIFT_32 + lo * SHIFT_32) >>> 0;\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !((gprs[rd] & 0xFFFFFFFF) || (gprs[rn] & 0xFFFFFFFF));\n\t};\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nfunction ARMCoreThumb(cpu) {\n\tthis.cpu = cpu;\n};\n\nARMCoreThumb.prototype.constructADC = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar m = (gprs[rm] >>> 0) + (cpu.cpsrC ? 1 : 0);\n\t\tvar oldD = gprs[rd];\n\t\tvar d = (oldD >>> 0) + m;\n\t\tvar oldDn = oldD >> 31;\n\t\tvar dn = d >> 31;\n\t\tvar mn = m >> 31;\n\t\tcpu.cpsrN = dn;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\tcpu.cpsrV = oldDn == mn && oldDn != dn && mn != dn;\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = (gprs[rn] >>> 0) + immediate;\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\tcpu.cpsrV = !(gprs[rn] >> 31) && ((gprs[rn] >> 31 ^ d) >> 31) && (d >> 31);\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD2 = function(rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = (gprs[rn] >>> 0) + immediate;\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\tcpu.cpsrV = !(gprs[rn] >> 31) && ((gprs[rn] ^ d) >> 31) && ((immediate ^ d) >> 31);\n\t\tgprs[rn] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD3 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = (gprs[rn] >>> 0) + (gprs[rm] >>> 0);\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = d > 0xFFFFFFFF;\n\t\tcpu.cpsrV = !((gprs[rn] ^ gprs[rm]) >> 31) && ((gprs[rn] ^ d) >> 31) && ((gprs[rm] ^ d) >> 31);\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD4 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] += gprs[rm];\n\t};\n};\n\nARMCoreThumb.prototype.constructADD5 = function(rd, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = (gprs[ARMRegs.PC] & 0xFFFFFFFC) + immediate;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD6 = function(rd, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[ARMRegs.SP] + immediate;\n\t};\n};\n\nARMCoreThumb.prototype.constructADD7 = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[ARMRegs.SP] += immediate;\n\t};\n};\n\nARMCoreThumb.prototype.constructAND = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[rd] & gprs[rm];\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructASR1 = function(rd, rm, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tif (immediate == 0) {\n\t\t\tcpu.cpsrC = gprs[rm] >> 31;\n\t\t\tif (cpu.cpsrC) {\n\t\t\t\tgprs[rd] = 0xFFFFFFFF;\n\t\t\t} else {\n\t\t\t\tgprs[rd] = 0;\n\t\t\t}\n\t\t} else {\n\t\t\tcpu.cpsrC = gprs[rm] & (1 << (immediate - 1));\n\t\t\tgprs[rd] = gprs[rm] >> immediate;\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructASR2 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar rs = gprs[rm] & 0xFF;\n\t\tif (rs) {\n\t\t\tif (rs < 32) {\n\t\t\t\tcpu.cpsrC = gprs[rd] & (1 << (rs - 1));\n\t\t\t\tgprs[rd] >>= rs;\n\t\t\t} else {\n\t\t\t\tcpu.cpsrC = gprs[rd] >> 31;\n\t\t\t\tif (cpu.cpsrC) {\n\t\t\t\t\tgprs[rd] = 0xFFFFFFFF;\n\t\t\t\t} else {\n\t\t\t\t\tgprs[rd] = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructB1 = function(immediate, condOp) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tif (condOp()) {\n\t\t\tgprs[ARMRegs.PC] += immediate;\n\t\t}\n\t};\n};\n\nARMCoreThumb.prototype.constructB2 = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[ARMRegs.PC] += immediate;\n\t};\n};\n\nARMCoreThumb.prototype.constructBIC = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[rd] & ~gprs[rm];\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructBL1 = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[ARMRegs.LR] = gprs[ARMRegs.PC] + immediate;\n\t}\n};\n\nARMCoreThumb.prototype.constructBL2 = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar pc = gprs[ARMRegs.PC];\n\t\tgprs[ARMRegs.PC] = gprs[ARMRegs.LR] + (immediate << 1);\n\t\tgprs[ARMRegs.LR] = pc - 1;\n\t}\n};\n\nARMCoreThumb.prototype.constructBX = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tcpu.switchExecMode(gprs[rm] & 0x00000001);\n\t\tvar misalign = 0;\n\t\tif (rm == 15) {\n\t\t\tmisalign = gprs[rm] & 0x00000002;\n\t\t}\n\t\tgprs[ARMRegs.PC] = gprs[rm] & 0xFFFFFFFE - misalign;\n\t};\n};\n\nARMCoreThumb.prototype.constructCMN = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar aluOut = (gprs[rd] >>> 0) + (gprs[rm] >>> 0);\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = aluOut > 0xFFFFFFFF;\n\t\tcpu.cpsrV = (gprs[rd] >> 31) == (gprs[rm] >> 31) &&\n\t\t\t\t\t(gprs[rd] >> 31) != (aluOut >> 31) &&\n\t\t\t\t\t(gprs[rm] >> 31) != (aluOut >> 31);\n\t};\n};\n\nARMCoreThumb.prototype.constructCMP1 = function(rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar aluOut = gprs[rn] - immediate;\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= immediate;\n\t\tcpu.cpsrV = (gprs[rn] >> 31) && ((gprs[rn] ^ aluOut) >> 31);\n\t};\n}\n\nARMCoreThumb.prototype.constructCMP2 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = gprs[rd];\n\t\tvar m = gprs[rm];\n\t\tvar aluOut = d - m;\n\t\tvar an = aluOut >> 31;\n\t\tvar dn = d >> 31;\n\t\tcpu.cpsrN = an;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (d >>> 0) >= (m >>> 0);\n\t\tcpu.cpsrV = dn != (m >> 31) && dn != an;\n\t};\n};\n\nARMCoreThumb.prototype.constructCMP3 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar aluOut = gprs[rd] - gprs[rm];\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rd] >>> 0) >= (gprs[rm] >>> 0);\n\t\tcpu.cpsrV = ((gprs[rd] ^ gprs[rm]) >> 31) && ((gprs[rd] ^ aluOut) >> 31);\n\t};\n};\n\nARMCoreThumb.prototype.constructEOR = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[rd] ^ gprs[rm];\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructLDMIA = function(rn, rs) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar address = gprs[rn];\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tfor (m = 0x01, i = 0; i < 8; m <<= 1, ++i) {\n\t\t\tif (rs & m) {\n\t\t\t\tgprs[i] = cpu.mmu.load32(address);\n\t\t\t\taddress += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tcpu.mmu.waitMulti32(address, total);\n\t\tif (!((1 << rn) & rs)) {\n\t\t\tgprs[rn] = address;\n\t\t}\n\t};\n};\n\nARMCoreThumb.prototype.constructLDR1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar n = gprs[rn] + immediate;\n\t\tgprs[rd] = cpu.mmu.load32(n);\n\t\tcpu.mmu.wait32(n);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDR2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.load32(gprs[rn] + gprs[rm]);\n\t\tcpu.mmu.wait32(gprs[rn] + gprs[rm]);\n\t\t++cpu.cycles;\n\t}\n};\n\nARMCoreThumb.prototype.constructLDR3 = function(rd, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.load32((gprs[ARMRegs.PC] & 0xFFFFFFFC) + immediate);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.PC]);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDR4 = function(rd, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.load32(gprs[ARMRegs.SP] + immediate);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.SP] + immediate);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRB1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar n = gprs[rn] + immediate;\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.loadU8(n);\n\t\tcpu.mmu.wait(n);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRB2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.loadU8(gprs[rn] + gprs[rm]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRH1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar n = gprs[rn] + immediate;\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.loadU16(n);\n\t\tcpu.mmu.wait(n);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRH2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.loadU16(gprs[rn] + gprs[rm]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRSB = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.load8(gprs[rn] + gprs[rm]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLDRSH = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = cpu.mmu.load16(gprs[rn] + gprs[rm]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t\t++cpu.cycles;\n\t};\n};\n\nARMCoreThumb.prototype.constructLSL1 = function(rd, rm, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tif (immediate == 0) {\n\t\t\tgprs[rd] = gprs[rm];\n\t\t} else {\n\t\t\tcpu.cpsrC = gprs[rm] & (1 << (32 - immediate));\n\t\t\tgprs[rd] = gprs[rm] << immediate;\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructLSL2 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar rs = gprs[rm] & 0xFF;\n\t\tif (rs) {\n\t\t\tif (rs < 32) {\n\t\t\t\tcpu.cpsrC = gprs[rd] & (1 << (32 - rs));\n\t\t\t\tgprs[rd] <<= rs;\n\t\t\t} else {\n\t\t\t\tif (rs > 32) {\n\t\t\t\t\tcpu.cpsrC = 0;\n\t\t\t\t} else {\n\t\t\t\t\tcpu.cpsrC = gprs[rd] & 0x00000001;\n\t\t\t\t}\n\t\t\t\tgprs[rd] = 0;\n\t\t\t}\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructLSR1 = function(rd, rm, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tif (immediate == 0) {\n\t\t\tcpu.cpsrC = gprs[rm] >> 31;\n\t\t\tgprs[rd] = 0;\n\t\t} else {\n\t\t\tcpu.cpsrC = gprs[rm] & (1 << (immediate - 1));\n\t\t\tgprs[rd] = gprs[rm] >>> immediate;\n\t\t}\n\t\tcpu.cpsrN = 0;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n}\n\nARMCoreThumb.prototype.constructLSR2 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar rs = gprs[rm] & 0xFF;\n\t\tif (rs) {\n\t\t\tif (rs < 32) {\n\t\t\t\tcpu.cpsrC = gprs[rd] & (1 << (rs - 1));\n\t\t\t\tgprs[rd] >>>= rs;\n\t\t\t} else {\n\t\t\t\tif (rs > 32) {\n\t\t\t\t\tcpu.cpsrC = 0;\n\t\t\t\t} else {\n\t\t\t\t\tcpu.cpsrC = gprs[rd] >> 31;\n\t\t\t\t}\n\t\t\t\tgprs[rd] = 0;\n\t\t\t}\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructMOV1 = function(rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rn] = immediate;\n\t\tcpu.cpsrN = immediate >> 31;\n\t\tcpu.cpsrZ = !(immediate & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructMOV2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = gprs[rn];\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = 0;\n\t\tcpu.cpsrV = 0;\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructMOV3 = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[rm];\n\t};\n};\n\nARMCoreThumb.prototype.constructMUL = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.waitMul(gprs[rm]);\n\t\tif ((gprs[rm] & 0xFFFF0000) && (gprs[rd] & 0xFFFF0000)) {\n\t\t\t// Our data type is a double--we'll lose bits if we do it all at once!\n\t\t\tvar hi = ((gprs[rd] & 0xFFFF0000) * gprs[rm]) & 0xFFFFFFFF;\n\t\t\tvar lo = ((gprs[rd] & 0x0000FFFF) * gprs[rm]) & 0xFFFFFFFF;\n\t\t\tgprs[rd] = (hi + lo) & 0xFFFFFFFF;\n\t\t} else {\n\t\t\tgprs[rd] *= gprs[rm];\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructMVN = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = ~gprs[rm];\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructNEG = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = -gprs[rm];\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = 0 >= (d >>> 0);\n\t\tcpu.cpsrV = (gprs[rm] >> 31) && (d >> 31);\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructORR = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tgprs[rd] = gprs[rd] | gprs[rm];\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructPOP = function(rs, r) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\t++cpu.cycles;\n\t\tvar address = gprs[ARMRegs.SP];\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tfor (m = 0x01, i = 0; i < 8; m <<= 1, ++i) {\n\t\t\tif (rs & m) {\n\t\t\t\tcpu.mmu.waitSeq32(address);\n\t\t\t\tgprs[i] = cpu.mmu.load32(address);\n\t\t\t\taddress += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tif (r) {\n\t\t\tgprs[ARMRegs.PC] = cpu.mmu.load32(address) & 0xFFFFFFFE;\n\t\t\taddress += 4;\n\t\t\t++total;\n\t\t}\n\t\tcpu.mmu.waitMulti32(address, total);\n\t\tgprs[ARMRegs.SP] = address;\n\t};\n};\n\nARMCoreThumb.prototype.constructPUSH = function(rs, r) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar address = gprs[ARMRegs.SP] - 4;\n\t\tvar total = 0;\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tif (r) {\n\t\t\tcpu.mmu.store32(address, gprs[ARMRegs.LR]);\n\t\t\taddress -= 4;\n\t\t\t++total;\n\t\t}\n\t\tvar m, i;\n\t\tfor (m = 0x80, i = 7; m; m >>= 1, --i) {\n\t\t\tif (rs & m) {\n\t\t\t\tcpu.mmu.store32(address, gprs[i]);\n\t\t\t\taddress -= 4;\n\t\t\t\t++total;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfor (m >>= 1, --i; m; m >>= 1, --i) {\n\t\t\tif (rs & m) {\n\t\t\t\tcpu.mmu.store32(address, gprs[i]);\n\t\t\t\taddress -= 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tcpu.mmu.waitMulti32(address, total);\n\t\tgprs[ARMRegs.SP] = address + 4;\n\t};\n};\n\nARMCoreThumb.prototype.constructROR = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar rs = gprs[rm] & 0xFF;\n\t\tif (rs) {\n\t\t\tvar r4 = rs & 0x1F;\n\t\t\tif (r4 > 0) {\n\t\t\t\tcpu.cpsrC = gprs[rd] & (1 << (r4 - 1));\n\t\t\t\tgprs[rd] = (gprs[rd] >>> r4) | (gprs[rd] << (32 - r4));\n\t\t\t} else {\n\t\t\t\tcpu.cpsrC = gprs[rd] >> 31;\n\t\t\t}\n\t\t}\n\t\tcpu.cpsrN = gprs[rd] >> 31;\n\t\tcpu.cpsrZ = !(gprs[rd] & 0xFFFFFFFF);\n\t};\n};\n\nARMCoreThumb.prototype.constructSBC = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar m = (gprs[rm] >>> 0) + (cpu.cpsrC ? 0 : 1);\n\t\tvar d = (gprs[rd] >>> 0) - m;\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rd] >>> 0) >= (d >>> 0);\n\t\tcpu.cpsrV = ((gprs[rd] ^ m) >> 31) && ((gprs[rd] ^ d) >> 31);\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructSTMIA = function(rn, rs) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tvar address = gprs[rn];\n\t\tvar total = 0;\n\t\tvar m, i;\n\t\tfor (m = 0x01, i = 0; i < 8; m <<= 1, ++i) {\n\t\t\tif (rs & m) {\n\t\t\t\tcpu.mmu.store32(address, gprs[i]);\n\t\t\t\taddress += 4;\n\t\t\t\t++total;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfor (m <<= 1, ++i; i < 8; m <<= 1, ++i) {\n\t\t\tif (rs & m) {\n\t\t\t\tcpu.mmu.store32(address, gprs[i]);\n\t\t\t\taddress += 4;\n\t\t\t\t++total;\n\t\t\t}\n\t\t}\n\t\tcpu.mmu.waitMulti32(address, total);\n\t\tgprs[rn] = address;\n\t};\n};\n\nARMCoreThumb.prototype.constructSTR1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar n = gprs[rn] + immediate;\n\t\tcpu.mmu.store32(n, gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait32(n);\n\t};\n};\n\nARMCoreThumb.prototype.constructSTR2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.store32(gprs[rn] + gprs[rm], gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait32(gprs[rn] + gprs[rm]);\n\t};\n};\n\nARMCoreThumb.prototype.constructSTR3 = function(rd, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.store32(gprs[ARMRegs.SP] + immediate, gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait32(gprs[ARMRegs.SP] + immediate);\n\t};\n};\n\nARMCoreThumb.prototype.constructSTRB1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar n = gprs[rn] + immediate;\n\t\tcpu.mmu.store8(n, gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait(n);\n\t};\n};\n\nARMCoreThumb.prototype.constructSTRB2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.store8(gprs[rn] + gprs[rm], gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t}\n};\n\nARMCoreThumb.prototype.constructSTRH1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tvar n = gprs[rn] + immediate;\n\t\tcpu.mmu.store16(n, gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait(n);\n\t};\n};\n\nARMCoreThumb.prototype.constructSTRH2 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.store16(gprs[rn] + gprs[rm], gprs[rd]);\n\t\tcpu.mmu.wait(gprs[ARMRegs.PC]);\n\t\tcpu.mmu.wait(gprs[rn] + gprs[rm]);\n\t}\n};\n\nARMCoreThumb.prototype.constructSUB1 = function(rd, rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = gprs[rn] - immediate;\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= immediate;\n\t\tcpu.cpsrV = (gprs[rn] >> 31) && ((gprs[rn] ^ d) >> 31);\n\t\tgprs[rd] = d;\n\t};\n}\n\nARMCoreThumb.prototype.constructSUB2 = function(rn, immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = gprs[rn] - immediate;\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= immediate;\n\t\tcpu.cpsrV = (gprs[rn] >> 31) && ((gprs[rn] ^ d) >> 31);\n\t\tgprs[rn] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructSUB3 = function(rd, rn, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar d = gprs[rn] - gprs[rm];\n\t\tcpu.cpsrN = d >> 31;\n\t\tcpu.cpsrZ = !(d & 0xFFFFFFFF);\n\t\tcpu.cpsrC = (gprs[rn] >>> 0) >= (gprs[rm] >>> 0);\n\t\tcpu.cpsrV = (gprs[rn] >> 31) != (gprs[rm] >> 31) &&\n\t\t\t\t\t(gprs[rn] >> 31) != (d >> 31);\n\t\tgprs[rd] = d;\n\t};\n};\n\nARMCoreThumb.prototype.constructSWI = function(immediate) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.irq.swi(immediate);\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t}\n};\n\nARMCoreThumb.prototype.constructTST = function(rd, rm) {\n\tvar cpu : ARMCoreType = this.cpu;\n\tvar gprs = cpu.gprs;\n\treturn function() {\n\t\tcpu.mmu.waitPrefetch(gprs[ARMRegs.PC]);\n\t\tvar aluOut = gprs[rd] & gprs[rm];\n\t\tcpu.cpsrN = aluOut >> 31;\n\t\tcpu.cpsrZ = !(aluOut & 0xFFFFFFFF);\n\t};\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nfunction ARMCore() {\n\tthis.SP = 13;\n\tthis.LR = 14;\n\tthis.PC = 15;\n\n\tthis.MODE_ARM = 0;\n\tthis.MODE_THUMB = 1;\n\n\tthis.MODE_USER = 0x10;\n\tthis.MODE_FIQ = 0x11;\n\tthis.MODE_IRQ = 0x12;\n\tthis.MODE_SUPERVISOR = 0x13;\n\tthis.MODE_ABORT = 0x17;\n\tthis.MODE_UNDEFINED = 0x1B;\n\tthis.MODE_SYSTEM = 0x1F;\n\n\tthis.BANK_NONE = 0\n\tthis.BANK_FIQ = 1;\n\tthis.BANK_IRQ = 2;\n\tthis.BANK_SUPERVISOR = 3;\n\tthis.BANK_ABORT = 4;\n\tthis.BANK_UNDEFINED = 5;\n\n\tthis.WORD_SIZE_ARM = 4;\n\tthis.WORD_SIZE_THUMB = 2;\n\n\tthis.BASE_RESET = 0x00000000;\n\tthis.BASE_UNDEF = 0x00000004;\n\tthis.BASE_SWI = 0x00000008;\n\tthis.BASE_PABT = 0x0000000C;\n\tthis.BASE_DABT = 0x00000010;\n\tthis.BASE_IRQ = 0x00000018;\n\tthis.BASE_FIQ = 0x0000001C;\n\n\tthis.armCompiler = new ARMCoreArm(this);\n\tthis.thumbCompiler = new ARMCoreThumb(this);\n\tthis.generateConds();\n\n\tthis.gprs = new Int32Array(16);\n};\n\nARMCore.prototype.resetCPU = function(startOffset) {\n\tfor (var i = 0; i < ARMRegs.PC; ++i) {\n\t\tthis.gprs[i] = 0;\n\t}\n\tthis.gprs[ARMRegs.PC] = startOffset + ARMConstants.WORD_SIZE_ARM;\n\n\tthis.loadInstruction = this.loadInstructionArm;\n\tthis.execMode = ARMMode.MODE_ARM;\n\tthis.instructionWidth = ARMConstants.WORD_SIZE_ARM;\n\n\tthis.mode = ARMMode.MODE_SYSTEM;\n\n\tthis.cpsrI = false;\n\tthis.cpsrF = false;\n\n\tthis.cpsrV = false;\n\tthis.cpsrC = false;\n\tthis.cpsrZ = false;\n\tthis.cpsrN = false;\n\n\tthis.bankedRegisters = [\n\t\tnew Int32Array(7),\n\t\tnew Int32Array(7),\n\t\tnew Int32Array(2),\n\t\tnew Int32Array(2),\n\t\tnew Int32Array(2),\n\t\tnew Int32Array(2)\n\t];\n\tthis.spsr = 0;\n\tthis.bankedSPSRs = new Int32Array(6);\n\n\tthis.cycles = 0;\n\n\tthis.shifterOperand = 0;\n\tthis.shifterCarryOut = 0;\n\n\tthis.page = null;\n\tthis.pageId = 0;\n\tthis.pageRegion = -1;\n\n\tthis.instruction = null;\n\n\tthis.irq.clear();\n\n\tvar gprs = this.gprs;\n\tvar mmu = this.mmu as ARMMMUInterface;\n\n\tthis.step = function() {\n\t\tvar instruction = this.instruction || (this.instruction = this.loadInstruction(gprs[ARMRegs.PC] - this.instructionWidth));\n\t\tgprs[ARMRegs.PC] += this.instructionWidth;\n\t\tthis.conditionPassed = true;\n\t\tinstruction();\n\n\t\tif (!instruction.writesPC) {\n\t\t\tif (this.instruction != null) { // We might have gotten an interrupt from the instruction\n\t\t\t\tif (instruction.next == null || instruction.next.page.invalid) {\n\t\t\t\t\tinstruction.next = this.loadInstruction(gprs[ARMRegs.PC] - this.instructionWidth);\n\t\t\t\t}\n\t\t\t\tthis.instruction = instruction.next;\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.conditionPassed) {\n\t\t\t\tvar pc = gprs[ARMRegs.PC] &= 0xFFFFFFFE;\n\t\t\t\tif (this.execMode == ARMMode.MODE_ARM) {\n\t\t\t\t\tmmu.wait32(pc);\n\t\t\t\t\tmmu.waitPrefetch32(pc);\n\t\t\t\t} else {\n\t\t\t\t\tmmu.wait(pc);\n\t\t\t\t\tmmu.waitPrefetch(pc);\n\t\t\t\t}\n\t\t\t\tgprs[ARMRegs.PC] += this.instructionWidth;\n\t\t\t\tif (!instruction.fixedJump) {\n\t\t\t\t\tthis.instruction = null;\n\t\t\t\t} else if (this.instruction != null) {\n\t\t\t\t\tif (instruction.next == null || instruction.next.page.invalid) {\n\t\t\t\t\t\tinstruction.next = this.loadInstruction(gprs[ARMRegs.PC] - this.instructionWidth);\n\t\t\t\t\t}\n\t\t\t\t\tthis.instruction = instruction.next;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.instruction = null;\n\t\t\t}\n\t\t}\n\t\tthis.irq.updateTimers();\n\t};\n};\n\nARMCore.prototype.freeze = function() : ARMCoreState {\n\treturn {\n\t\tPC: this.gprs[15] - this.instructionWidth,\n\t\tSP: this.gprs[13],\n\t\t'gprs': [\n\t\t\tthis.gprs[0],\n\t\t\tthis.gprs[1],\n\t\t\tthis.gprs[2],\n\t\t\tthis.gprs[3],\n\t\t\tthis.gprs[4],\n\t\t\tthis.gprs[5],\n\t\t\tthis.gprs[6],\n\t\t\tthis.gprs[7],\n\t\t\tthis.gprs[8],\n\t\t\tthis.gprs[9],\n\t\t\tthis.gprs[10],\n\t\t\tthis.gprs[11],\n\t\t\tthis.gprs[12],\n\t\t\tthis.gprs[13],\n\t\t\tthis.gprs[14],\n\t\t\tthis.gprs[15],\n\t\t],\n\t\t'mode': this.mode,\n\t\t'cpsrI': this.cpsrI,\n\t\t'cpsrF': this.cpsrF,\n\t\t'cpsrV': this.cpsrV,\n\t\t'cpsrC': this.cpsrC,\n\t\t'cpsrZ': this.cpsrZ,\n\t\t'cpsrN': this.cpsrN,\n\t\t'bankedRegisters': [\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[0][0],\n\t\t\t\tthis.bankedRegisters[0][1],\n\t\t\t\tthis.bankedRegisters[0][2],\n\t\t\t\tthis.bankedRegisters[0][3],\n\t\t\t\tthis.bankedRegisters[0][4],\n\t\t\t\tthis.bankedRegisters[0][5],\n\t\t\t\tthis.bankedRegisters[0][6]\n\t\t\t],\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[1][0],\n\t\t\t\tthis.bankedRegisters[1][1],\n\t\t\t\tthis.bankedRegisters[1][2],\n\t\t\t\tthis.bankedRegisters[1][3],\n\t\t\t\tthis.bankedRegisters[1][4],\n\t\t\t\tthis.bankedRegisters[1][5],\n\t\t\t\tthis.bankedRegisters[1][6]\n\t\t\t],\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[2][0],\n\t\t\t\tthis.bankedRegisters[2][1]\n\t\t\t],\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[3][0],\n\t\t\t\tthis.bankedRegisters[3][1]\n\t\t\t],\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[4][0],\n\t\t\t\tthis.bankedRegisters[4][1]\n\t\t\t],\n\t\t\t[\n\t\t\t\tthis.bankedRegisters[5][0],\n\t\t\t\tthis.bankedRegisters[5][1]\n\t\t\t]\n\t\t],\n\t\t'spsr': this.spsr,\n\t\t'bankedSPSRs': [\n\t\t\tthis.bankedSPSRs[0],\n\t\t\tthis.bankedSPSRs[1],\n\t\t\tthis.bankedSPSRs[2],\n\t\t\tthis.bankedSPSRs[3],\n\t\t\tthis.bankedSPSRs[4],\n\t\t\tthis.bankedSPSRs[5]\n\t\t],\n\t\t'cycles': this.cycles,\n\t\t'instructionWidth': this.instructionWidth,\n\t};\n};\n\nARMCore.prototype.defrost = function(frost: ARMCoreState) {\n\tthis.instruction = null;\n\n\tthis.page = null;\n\tthis.pageId = 0;\n\tthis.pageRegion = -1;\n\n\tthis.gprs[0] = frost.gprs[0];\n\tthis.gprs[1] = frost.gprs[1];\n\tthis.gprs[2] = frost.gprs[2];\n\tthis.gprs[3] = frost.gprs[3];\n\tthis.gprs[4] = frost.gprs[4];\n\tthis.gprs[5] = frost.gprs[5];\n\tthis.gprs[6] = frost.gprs[6];\n\tthis.gprs[7] = frost.gprs[7];\n\tthis.gprs[8] = frost.gprs[8];\n\tthis.gprs[9] = frost.gprs[9];\n\tthis.gprs[10] = frost.gprs[10];\n\tthis.gprs[11] = frost.gprs[11];\n\tthis.gprs[12] = frost.gprs[12];\n\tthis.gprs[13] = frost.gprs[13];\n\tthis.gprs[14] = frost.gprs[14];\n\tthis.gprs[15] = frost.gprs[15];\n\n\tthis.mode = frost.mode;\n\tthis.cpsrI = frost.cpsrI;\n\tthis.cpsrF = frost.cpsrF;\n\tthis.cpsrV = frost.cpsrV;\n\tthis.cpsrC = frost.cpsrC;\n\tthis.cpsrZ = frost.cpsrZ;\n\tthis.cpsrN = frost.cpsrN;\n\n\tthis.bankedRegisters[0][0] = frost.bankedRegisters[0][0];\n\tthis.bankedRegisters[0][1] = frost.bankedRegisters[0][1];\n\tthis.bankedRegisters[0][2] = frost.bankedRegisters[0][2];\n\tthis.bankedRegisters[0][3] = frost.bankedRegisters[0][3];\n\tthis.bankedRegisters[0][4] = frost.bankedRegisters[0][4];\n\tthis.bankedRegisters[0][5] = frost.bankedRegisters[0][5];\n\tthis.bankedRegisters[0][6] = frost.bankedRegisters[0][6];\n\n\tthis.bankedRegisters[1][0] = frost.bankedRegisters[1][0];\n\tthis.bankedRegisters[1][1] = frost.bankedRegisters[1][1];\n\tthis.bankedRegisters[1][2] = frost.bankedRegisters[1][2];\n\tthis.bankedRegisters[1][3] = frost.bankedRegisters[1][3];\n\tthis.bankedRegisters[1][4] = frost.bankedRegisters[1][4];\n\tthis.bankedRegisters[1][5] = frost.bankedRegisters[1][5];\n\tthis.bankedRegisters[1][6] = frost.bankedRegisters[1][6];\n\n\tthis.bankedRegisters[2][0] = frost.bankedRegisters[2][0];\n\tthis.bankedRegisters[2][1] = frost.bankedRegisters[2][1];\n\n\tthis.bankedRegisters[3][0] = frost.bankedRegisters[3][0];\n\tthis.bankedRegisters[3][1] = frost.bankedRegisters[3][1];\n\n\tthis.bankedRegisters[4][0] = frost.bankedRegisters[4][0];\n\tthis.bankedRegisters[4][1] = frost.bankedRegisters[4][1];\n\n\tthis.bankedRegisters[5][0] = frost.bankedRegisters[5][0];\n\tthis.bankedRegisters[5][1] = frost.bankedRegisters[5][1];\n\n\tthis.spsr = frost.spsr;\n\tthis.bankedSPSRs[0] = frost.bankedSPSRs[0];\n\tthis.bankedSPSRs[1] = frost.bankedSPSRs[1];\n\tthis.bankedSPSRs[2] = frost.bankedSPSRs[2];\n\tthis.bankedSPSRs[3] = frost.bankedSPSRs[3];\n\tthis.bankedSPSRs[4] = frost.bankedSPSRs[4];\n\tthis.bankedSPSRs[5] = frost.bankedSPSRs[5];\n\n\tthis.cycles = frost.cycles;\n\n\tthis.instructionWidth = frost.instructionWidth;\n\tthis.loadInstruction = frost.instructionWidth == 2 ? this.loadInstructionThumb : this.loadInstructionArm;\n\tthis.execMode = frost.instructionWidth == 2 ? ARMMode.MODE_THUMB : ARMMode.MODE_ARM;\n};\n\nARMCore.prototype.fetchPage = function(address : number) {\n\tvar mmu = this.mmu;\n\tvar region = address >>> mmu.BASE_OFFSET;\n\tvar pageId = mmu.addressToPage(region, address & mmu.OFFSET_MASK);\n\tif (region == this.pageRegion) {\n\t\tif (pageId == this.pageId && !(this.page as ARMMemoryPage).invalid) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pageId = pageId;\n\t} else {\n\t\tthis.pageMask = mmu.memory[region].PAGE_MASK;\n\t\tthis.pageRegion = region;\n\t\tthis.pageId = pageId;\n\t}\n\n\tthis.page = mmu.accessPage(region, pageId);\n};\n\nARMCore.prototype.loadInstructionArm = function(address : number) {\n\tvar next : ARMOperation = null;\n\tthis.fetchPage(address);\n\tvar offset = (address & this.pageMask) >> 2;\n\tnext = (this.page as ARMMemoryPage).arm[offset];\n\tif (next) {\n\t\treturn next;\n\t}\n\tvar instruction = this.mmu.load32(address) >>> 0;\n\tnext = this.compileArm(instruction);\n\tnext.next = null;\n\tnext.page = this.page;\n\tnext.address = address;\n\tnext.opcode = instruction;\n\t(this.page as ARMMemoryPage).arm[offset] = next;\n\treturn next;\n};\n\nARMCore.prototype.loadInstructionThumb = function(address : number) {\n\tvar next : ARMOperation = null;\n\tthis.fetchPage(address);\n\tvar offset = (address & this.pageMask) >> 1;\n\tnext = (this.page as ARMMemoryPage).thumb[offset];\n\tif (next) {\n\t\treturn next;\n\t}\n\tvar instruction = this.mmu.load16(address);\n\tnext = this.compileThumb(instruction);\n\tnext.next = null;\n\tnext.page = this.page;\n\tnext.address = address;\n\tnext.opcode = instruction;\n\t(this.page as ARMMemoryPage).thumb[offset] = next;\n\treturn next;\n};\n\nARMCore.prototype.selectBank = function(mode : ARMMode) {\n\tswitch (mode) {\n\tcase ARMMode.MODE_USER:\n\tcase ARMMode.MODE_SYSTEM:\n\t\t// No banked registers\n\t\treturn ARMConstants.BANK_NONE;\n\tcase ARMMode.MODE_FIQ:\n\t\treturn ARMConstants.BANK_FIQ;\n\tcase ARMMode.MODE_IRQ:\n\t\treturn ARMConstants.BANK_IRQ;\n\tcase ARMMode.MODE_SUPERVISOR:\n\t\treturn ARMConstants.BANK_SUPERVISOR;\n\tcase ARMMode.MODE_ABORT:\n\t\treturn ARMConstants.BANK_ABORT;\n\tcase ARMMode.MODE_UNDEFINED:\n\t\treturn ARMConstants.BANK_UNDEFINED;\n\tdefault:\n\t\tthrow new EmuHalt(\"Invalid user mode \" + mode + \" passed to selectBank\");\n\t}\n};\n\nARMCore.prototype.switchExecMode = function(newMode) {\n\tif (this.execMode != newMode) {\n\t\tthis.execMode = newMode;\n\t\tif (newMode == ARMMode.MODE_ARM) {\n\t\t\tthis.instructionWidth = ARMConstants.WORD_SIZE_ARM;\n\t\t\tthis.loadInstruction = this.loadInstructionArm;\n\t\t} else {\n\t\t\tthis.instructionWidth = ARMConstants.WORD_SIZE_THUMB;\n\t\t\tthis.loadInstruction = this.loadInstructionThumb;\n\t\t}\n\t}\n\t\n};\n\nARMCore.prototype.switchMode = function(newMode) {\n\tif (newMode == this.mode) {\n\t\t// Not switching modes after all\n\t\treturn;\n\t}\n\tif (newMode != ARMMode.MODE_USER || newMode != ARMMode.MODE_SYSTEM) {\n\t\t// Switch banked registers\n\t\tvar newBank = this.selectBank(newMode);\n\t\tvar oldBank = this.selectBank(this.mode);\n\t\tif (newBank != oldBank) {\n\t\t\t// TODO: support FIQ\n\t\t\tif (newMode == ARMMode.MODE_FIQ || this.mode == ARMMode.MODE_FIQ) {\n\t\t\t\tvar oldFiqBank = (oldBank == ARMConstants.BANK_FIQ) ? 1 : 0;\n\t\t\t\tvar newFiqBank = (newBank == ARMConstants.BANK_FIQ) ? 1 : 0;\n\t\t\t\tthis.bankedRegisters[oldFiqBank][2] = this.gprs[8];\n\t\t\t\tthis.bankedRegisters[oldFiqBank][3] = this.gprs[9];\n\t\t\t\tthis.bankedRegisters[oldFiqBank][4] = this.gprs[10];\n\t\t\t\tthis.bankedRegisters[oldFiqBank][5] = this.gprs[11];\n\t\t\t\tthis.bankedRegisters[oldFiqBank][6] = this.gprs[12];\n\t\t\t\tthis.gprs[8] = this.bankedRegisters[newFiqBank][2];\n\t\t\t\tthis.gprs[9] = this.bankedRegisters[newFiqBank][3];\n\t\t\t\tthis.gprs[10] = this.bankedRegisters[newFiqBank][4];\n\t\t\t\tthis.gprs[11] = this.bankedRegisters[newFiqBank][5];\n\t\t\t\tthis.gprs[12] = this.bankedRegisters[newFiqBank][6];\n\t\t\t}\n\t\t\tthis.bankedRegisters[oldBank][0] = this.gprs[ARMRegs.SP];\n\t\t\tthis.bankedRegisters[oldBank][1] = this.gprs[ARMRegs.LR];\n\t\t\tthis.gprs[ARMRegs.SP] = this.bankedRegisters[newBank][0];\n\t\t\tthis.gprs[ARMRegs.LR] = this.bankedRegisters[newBank][1];\n\n\t\t\tthis.bankedSPSRs[oldBank] = this.spsr;\n\t\t\tthis.spsr = this.bankedSPSRs[newBank];\n\t\t}\n\t}\n\tthis.mode = newMode;\n};\n\nARMCore.prototype.packCPSR = function() {\n\treturn this.mode | (this.execMode << 5) | (this.cpsrF << 6) | (this.cpsrI << 7) |\n\t (this.cpsrN << 31) | (this.cpsrZ << 30) | (this.cpsrC << 29) | (this.cpsrV << 28);\n};\n\nARMCore.prototype.unpackCPSR = function(spsr) {\n\tthis.switchMode(spsr & 0x0000001F);\n\tthis.switchExecMode(!!(spsr & 0x00000020));\n\tthis.cpsrF = spsr & 0x00000040;\n\tthis.cpsrI = spsr & 0x00000080;\n\tthis.cpsrN = spsr & 0x80000000;\n\tthis.cpsrZ = spsr & 0x40000000;\n\tthis.cpsrC = spsr & 0x20000000;\n\tthis.cpsrV = spsr & 0x10000000;\n\n\tthis.irq.testIRQ();\n};\n\nARMCore.prototype.hasSPSR = function() {\n\treturn this.mode != ARMMode.MODE_SYSTEM && this.mode != ARMMode.MODE_USER;\n};\n\nARMCore.prototype.raiseIRQ = function() {\n\tif (this.cpsrI) {\n\t\treturn;\n\t}\n\tvar cpsr = this.packCPSR();\n\tvar instructionWidth = this.instructionWidth;\n\tthis.switchMode(ARMMode.MODE_IRQ);\n\tthis.spsr = cpsr;\n\tthis.gprs[ARMRegs.LR] = this.gprs[ARMRegs.PC] - instructionWidth + 4;\n\tthis.gprs[ARMRegs.PC] = this.BASE_IRQ + ARMConstants.WORD_SIZE_ARM;\n\tthis.instruction = null;\n\tthis.switchExecMode(ARMMode.MODE_ARM);\n\tthis.cpsrI = true;\n};\n\nARMCore.prototype.raiseTrap = function() {\n\tvar cpsr = this.packCPSR();\n\tvar instructionWidth = this.instructionWidth;\n\tthis.switchMode(ARMMode.MODE_SUPERVISOR);\n\tthis.spsr = cpsr;\n\tthis.gprs[ARMRegs.LR] = this.gprs[ARMRegs.PC] - instructionWidth;\n\tthis.gprs[ARMRegs.PC] = this.BASE_SWI + ARMConstants.WORD_SIZE_ARM;\n\tthis.instruction = null;\n\tthis.switchExecMode(ARMMode.MODE_ARM);\n\tthis.cpsrI = true;\n};\n\nARMCore.prototype.badOp = function(instruction) {\n\tvar func : AddressFunction = function() {\n\t\tthrow new EmuHalt(\"Illegal instruction: 0x\" + instruction.toString(16));\n\t};\n\tfunc.writesPC = true;\n\tfunc.fixedJump = false;\n\treturn func;\n};\n\nARMCore.prototype.generateConds = function() {\n\tvar cpu = this;\n\tthis.conds = [\n\t\t// EQ\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrZ;\n\t\t},\n\t\t// NE\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrZ;\n\t\t},\n\t\t// CS\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrC;\n\t\t},\n\t\t// CC\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrC;\n\t\t},\n\t\t// MI\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrN;\n\t\t},\n\t\t// PL\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrN;\n\t\t},\n\t\t// VS\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrV;\n\t\t},\n\t\t// VC\n\t\tfunction() {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrV;\n\t\t},\n\t\t// HI\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrC && !cpu.cpsrZ;\n\t\t},\n\t\t// LS\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrC || cpu.cpsrZ;\n\t\t},\n\t\t// GE\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrN == !cpu.cpsrV;\n\t\t},\n\t\t// LT\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrN != !cpu.cpsrV;\n\t\t},\n\t\t// GT\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = !cpu.cpsrZ && !cpu.cpsrN == !cpu.cpsrV;\n\t\t},\n\t\t// LE\n\t\tfunction () {\n\t\t\treturn cpu.conditionPassed = cpu.cpsrZ || !cpu.cpsrN != !cpu.cpsrV;\n\t\t},\n\t\t// AL\n\t\tnull,\n\t\tnull\n\t]\n}\n\nARMCore.prototype.barrelShiftImmediate = function(shiftType, immediate, rm) {\n\tvar cpu = this;\n\tvar gprs = this.gprs;\n\tvar shiftOp = this.badOp;\n\tswitch (shiftType) {\n\tcase 0x00000000:\n\t\t// LSL\n\t\tif (immediate) {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = gprs[rm] << immediate;\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & (1 << (32 - immediate));\n\t\t\t};\n\t\t} else {\n\t\t\t// This boils down to no shift\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = gprs[rm];\n\t\t\t\tcpu.shifterCarryOut = cpu.cpsrC;\n\t\t\t};\n\t\t}\n\t\tbreak;\n\tcase 0x00000020:\n\t\t// LSR\n\t\tif (immediate) {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = gprs[rm] >>> immediate;\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & (1 << (immediate - 1));\n\t\t\t};\n\t\t} else {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = 0;\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & 0x80000000;\n\t\t\t};\n\t\t}\n\t\tbreak;\n\tcase 0x00000040:\n\t\t// ASR\n\t\tif (immediate) {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = gprs[rm] >> immediate;\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & (1 << (immediate - 1));\n\t\t\t};\n\t\t} else {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & 0x80000000;\n\t\t\t\tif (cpu.shifterCarryOut) {\n\t\t\t\t\tcpu.shifterOperand = 0xFFFFFFFF;\n\t\t\t\t} else {\n\t\t\t\t\tcpu.shifterOperand = 0;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tbreak;\n\tcase 0x00000060:\n\t\t// ROR\n\t\tif (immediate) {\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = (gprs[rm] >>> immediate) | (gprs[rm] << (32 - immediate));\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & (1 << (immediate - 1));\n\t\t\t};\n\t\t} else {\n\t\t\t// RRX\n\t\t\tshiftOp = function() {\n\t\t\t\tcpu.shifterOperand = ((cpu.cpsrC ? 1 : 0) << 31) | (gprs[rm] >>> 1);\n\t\t\t\tcpu.shifterCarryOut = gprs[rm] & 0x00000001;\n\t\t\t};\n\t\t}\n\t\tbreak;\n\t}\n\treturn shiftOp;\n}\n\nARMCore.prototype.compileArm = function(instruction) {\n\tvar op = this.badOp(instruction);\n\tvar i = instruction & 0x0E000000;\n\tvar cpu = this;\n\tvar gprs = this.gprs;\n\n\tvar condOp = this.conds[(instruction & 0xF0000000) >>> 28];\n\tif ((instruction & 0x0FFFFFF0) == 0x012FFF10) {\n\t\t// BX\n\t\tvar rm = instruction & 0xF;\n\t\top = this.armCompiler.constructBX(rm, condOp);\n\t\top.writesPC = true;\n\t\top.fixedJump = false;\n\t} else if (!(instruction & 0x0C000000) && (i == 0x02000000 || (instruction & 0x00000090) != 0x00000090)) {\n\t\tvar opcode = instruction & 0x01E00000;\n\t\tvar s = instruction & 0x00100000;\n\t\tvar shiftsRs = false;\n\t\tif ((opcode & 0x01800000) == 0x01000000 && !s) {\n\t\t\tvar r = instruction & 0x00400000;\n\t\t\tif ((instruction & 0x00B0F000) == 0x0020F000) {\n\t\t\t\t// MSR\n\t\t\t\tvar rm = instruction & 0x0000000F;\n\t\t\t\tvar immediate = instruction & 0x000000FF;\n\t\t\t\tvar rotateImm = (instruction & 0x00000F00) >> 7;\n\t\t\t\timmediate = (immediate >>> rotateImm) | (immediate << (32 - rotateImm));\n\t\t\t\top = this.armCompiler.constructMSR(rm, r, instruction, immediate, condOp);\n\t\t\t\top.writesPC = false;\n\t\t\t} else if ((instruction & 0x00BF0000) == 0x000F0000) {\n\t\t\t\t// MRS\n\t\t\t\tvar rd = (instruction & 0x0000F000) >> 12;\n\t\t\t\top = this.armCompiler.constructMRS(rd, r, condOp);\n\t\t\t\top.writesPC = rd == ARMRegs.PC;\n\t\t\t}\n\t\t} else {\n\t\t\t// Data processing/FSR transfer\n\t\t\tvar rn = (instruction & 0x000F0000) >> 16;\n\t\t\tvar rd = (instruction & 0x0000F000) >> 12;\n\n\t\t\t// Parse shifter operand\n\t\t\tvar shiftType = instruction & 0x00000060;\n\t\t\tvar rm = instruction & 0x0000000F;\n\t\t\tvar shiftOp = function() {\n\t\t\t\tthrow new EmuHalt('BUG: invalid barrel shifter');\n\t\t\t};\n\t\t\tif (instruction & 0x02000000) {\n\t\t\t\tvar immediate = instruction & 0x000000FF;\n\t\t\t\tvar rotate = (instruction & 0x00000F00) >> 7;\n\t\t\t\tif (!rotate) {\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1Immediate(immediate);\n\t\t\t\t} else {\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1ImmediateRotate(immediate, rotate);\n\t\t\t\t}\n\t\t\t} else if (instruction & 0x00000010) {\n\t\t\t\tvar rs = (instruction & 0x00000F00) >> 8;\n\t\t\t\tshiftsRs = true;\n\t\t\t\tswitch (shiftType) {\n\t\t\t\tcase 0x00000000:\n\t\t\t\t\t// LSL\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1LSL(rs, rm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00000020:\n\t\t\t\t\t// LSR\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1LSR(rs, rm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00000040:\n\t\t\t\t\t// ASR\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1ASR(rs, rm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00000060:\n\t\t\t\t\t// ROR\n\t\t\t\t\tshiftOp = this.armCompiler.constructAddressingMode1ROR(rs, rm);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar immediate = (instruction & 0x00000F80) >> 7;\n\t\t\t\tshiftOp = this.barrelShiftImmediate(shiftType, immediate, rm);\n\t\t\t}\n\n\t\t\tswitch (opcode) {\n\t\t\tcase 0x00000000:\n\t\t\t\t// AND\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructANDS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructAND(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00200000:\n\t\t\t\t// EOR\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructEORS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructEOR(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00400000:\n\t\t\t\t// SUB\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructSUBS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructSUB(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00600000:\n\t\t\t\t// RSB\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructRSBS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructRSB(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00800000:\n\t\t\t\t// ADD\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructADDS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructADD(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00A00000:\n\t\t\t\t// ADC\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructADCS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructADC(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00C00000:\n\t\t\t\t// SBC\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructSBCS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructSBC(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x00E00000:\n\t\t\t\t// RSC\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructRSCS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructRSC(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x01000000:\n\t\t\t\t// TST\n\t\t\t\top = this.armCompiler.constructTST(rd, rn, shiftOp, condOp);\n\t\t\t\tbreak;\n\t\t\tcase 0x01200000:\n\t\t\t\t// TEQ\n\t\t\t\top = this.armCompiler.constructTEQ(rd, rn, shiftOp, condOp);\n\t\t\t\tbreak;\n\t\t\tcase 0x01400000:\n\t\t\t\t// CMP\n\t\t\t\top = this.armCompiler.constructCMP(rd, rn, shiftOp, condOp);\n\t\t\t\tbreak;\n\t\t\tcase 0x01600000:\n\t\t\t\t// CMN\n\t\t\t\top = this.armCompiler.constructCMN(rd, rn, shiftOp, condOp);\n\t\t\t\tbreak;\n\t\t\tcase 0x01800000:\n\t\t\t\t// ORR\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructORRS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructORR(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x01A00000:\n\t\t\t\t// MOV\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructMOVS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructMOV(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x01C00000:\n\t\t\t\t// BIC\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructBICS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructBIC(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0x01E00000:\n\t\t\t\t// MVN\n\t\t\t\tif (s) {\n\t\t\t\t\top = this.armCompiler.constructMVNS(rd, rn, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructMVN(rd, rn, shiftOp, condOp);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\top.writesPC = rd == ARMRegs.PC;\n\t\t}\n\t} else if ((instruction & 0x0FB00FF0) == 0x01000090) {\n\t\t// Single data swap\n\t\tvar rm = instruction & 0x0000000F;\n\t\tvar rd = (instruction >> 12) & 0x0000000F;\n\t\tvar rn = (instruction >> 16) & 0x0000000F;\n\t\tif (instruction & 0x00400000) {\n\t\t\top = this.armCompiler.constructSWPB(rd, rn, rm, condOp);\n\t\t} else {\n\t\t\top = this.armCompiler.constructSWP(rd, rn, rm, condOp);\n\t\t}\n\t\top.writesPC = rd == ARMRegs.PC;\n\t} else {\n\t\tswitch (i) {\n\t\tcase 0x00000000:\n\t\t\tif ((instruction & 0x010000F0) == 0x00000090) {\n\t\t\t\t// Multiplies\n\t\t\t\tvar rd = (instruction & 0x000F0000) >> 16;\n\t\t\t\tvar rn = (instruction & 0x0000F000) >> 12;\n\t\t\t\tvar rs = (instruction & 0x00000F00) >> 8;\n\t\t\t\tvar rm = instruction & 0x0000000F;\n\t\t\t\tswitch (instruction & 0x00F00000) {\n\t\t\t\tcase 0x00000000:\n\t\t\t\t\t// MUL\n\t\t\t\t\top = this.armCompiler.constructMUL(rd, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00100000:\n\t\t\t\t\t// MULS\n\t\t\t\t\top = this.armCompiler.constructMULS(rd, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00200000:\n\t\t\t\t\t// MLA\n\t\t\t\t\top = this.armCompiler.constructMLA(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak\n\t\t\t\tcase 0x00300000:\n\t\t\t\t\t// MLAS\n\t\t\t\t\top = this.armCompiler.constructMLAS(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00800000:\n\t\t\t\t\t// UMULL\n\t\t\t\t\top = this.armCompiler.constructUMULL(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00900000:\n\t\t\t\t\t// UMULLS\n\t\t\t\t\top = this.armCompiler.constructUMULLS(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00A00000:\n\t\t\t\t\t// UMLAL\n\t\t\t\t\top = this.armCompiler.constructUMLAL(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00B00000:\n\t\t\t\t\t// UMLALS\n\t\t\t\t\top = this.armCompiler.constructUMLALS(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00C00000:\n\t\t\t\t\t// SMULL\n\t\t\t\t\top = this.armCompiler.constructSMULL(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00D00000:\n\t\t\t\t\t// SMULLS\n\t\t\t\t\top = this.armCompiler.constructSMULLS(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00E00000:\n\t\t\t\t\t// SMLAL\n\t\t\t\t\top = this.armCompiler.constructSMLAL(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x00F00000:\n\t\t\t\t\t// SMLALS\n\t\t\t\t\top = this.armCompiler.constructSMLALS(rd, rn, rs, rm, condOp);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\top.writesPC = rd == ARMRegs.PC;\n\t\t\t} else {\n\t\t\t\t// Halfword and signed byte data transfer\n\t\t\t\tvar load = instruction & 0x00100000;\n\t\t\t\tvar rd = (instruction & 0x0000F000) >> 12;\n\t\t\t\tvar hiOffset = (instruction & 0x00000F00) >> 4;\n\t\t\t\tvar loOffset = rm = instruction & 0x0000000F;\n\t\t\t\tvar h = instruction & 0x00000020;\n\t\t\t\tvar s = instruction & 0x00000040;\n\t\t\t\tvar w = instruction & 0x00200000;\n\t\t\t\tvar i = instruction & 0x00400000;\n\n\t\t\t\tvar address : AddressFunction;\n\t\t\t\tif (i) {\n\t\t\t\t\tvar immediate = loOffset | hiOffset;\n\t\t\t\t\taddress = this.armCompiler.constructAddressingMode23Immediate(instruction, immediate, condOp);\n\t\t\t\t} else {\n\t\t\t\t\taddress = this.armCompiler.constructAddressingMode23Register(instruction, rm, condOp);\n\t\t\t\t}\n\t\t\t\taddress.writesPC = !!w && rn == ARMRegs.PC;\n\n\t\t\t\tif ((instruction & 0x00000090) == 0x00000090) {\n\t\t\t\t\tif (load) {\n\t\t\t\t\t\t// Load [signed] halfword/byte\n\t\t\t\t\t\tif (h) {\n\t\t\t\t\t\t\tif (s) {\n\t\t\t\t\t\t\t\t// LDRSH\n\t\t\t\t\t\t\t\top = this.armCompiler.constructLDRSH(rd, address, condOp);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// LDRH\n\t\t\t\t\t\t\t\top = this.armCompiler.constructLDRH(rd, address, condOp);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (s) {\n\t\t\t\t\t\t\t\t// LDRSB\n\t\t\t\t\t\t\t\top = this.armCompiler.constructLDRSB(rd, address, condOp);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!s && h) {\n\t\t\t\t\t\t// STRH\n\t\t\t\t\t\top = this.armCompiler.constructSTRH(rd, address, condOp);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\top.writesPC = rd == ARMRegs.PC || address.writesPC;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x04000000:\n\t\tcase 0x06000000:\n\t\t\t// LDR/STR\n\t\t\tvar rd = (instruction & 0x0000F000) >> 12;\n\t\t\tvar load = instruction & 0x00100000;\n\t\t\tvar b = instruction & 0x00400000;\n\t\t\tvar i = instruction & 0x02000000;\n\n\t\t\tvar address : AddressFunction = function() {\n\t\t\t\tthrow new EmuHalt(\"Unimplemented memory access: 0x\" + instruction.toString(16));\n\t\t\t};\n\t\t\tif (~instruction & 0x01000000) {\n\t\t\t\t// Clear the W bit if the P bit is clear--we don't support memory translation, so these turn into regular accesses\n\t\t\t\tinstruction &= 0xFFDFFFFF;\n\t\t\t}\n\t\t\tif (i) {\n\t\t\t\t// Register offset\n\t\t\t\tvar rm = instruction & 0x0000000F;\n\t\t\t\tvar shiftType = instruction & 0x00000060;\n\t\t\t\tvar shiftImmediate = (instruction & 0x00000F80) >> 7;\n\t\t\t\t\n\t\t\t\tif (shiftType || shiftImmediate) {\n\t\t\t\t\tshiftOp = this.barrelShiftImmediate(shiftType, shiftImmediate, rm);\n\t\t\t\t\taddress = this.armCompiler.constructAddressingMode2RegisterShifted(instruction, shiftOp, condOp);\n\t\t\t\t} else {\n\t\t\t\t\taddress = this.armCompiler.constructAddressingMode23Register(instruction, rm, condOp);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Immediate\n\t\t\t\tvar offset = instruction & 0x00000FFF;\n\t\t\t\taddress = this.armCompiler.constructAddressingMode23Immediate(instruction, offset, condOp);\n\t\t\t}\n\t\t\tif (load) {\n\t\t\t\tif (b) {\n\t\t\t\t\t// LDRB\n\t\t\t\t\top = this.armCompiler.constructLDRB(rd, address, condOp);\n\t\t\t\t} else {\n\t\t\t\t\t// LDR\n\t\t\t\t\top = this.armCompiler.constructLDR(rd, address, condOp);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (b) {\n\t\t\t\t\t// STRB\n\t\t\t\t\top = this.armCompiler.constructSTRB(rd, address, condOp);\n\t\t\t\t} else {\n\t\t\t\t\t// STR\n\t\t\t\t\top = this.armCompiler.constructSTR(rd, address, condOp);\n\t\t\t\t}\n\t\t\t}\n\t\t\top.writesPC = load && (rd == ARMRegs.PC || address.writesPC); // SEH\n\t\t\tbreak;\n\t\tcase 0x08000000:\n\t\t\t// Block data transfer\n\t\t\tvar load = instruction & 0x00100000;\n\t\t\tvar w = instruction & 0x00200000;\n\t\t\tvar user = instruction & 0x00400000;\n\t\t\tvar u = instruction & 0x00800000;\n\t\t\tvar p = instruction & 0x01000000;\n\t\t\tvar rs = instruction & 0x0000FFFF;\n\t\t\tvar rn = (instruction & 0x000F0000) >> 16;\n\n\t\t\tvar address : AddressFunction;\n\t\t\tvar immediate = 0;\n\t\t\tvar offset = 0;\n\t\t\tvar overlap = false;\n\t\t\tif (u) {\n\t\t\t\tif (p) {\n\t\t\t\t\timmediate = 4;\n\t\t\t\t}\n\t\t\t\tfor (var m = 0x01, i = 0; i < 16; m <<= 1, ++i) {\n\t\t\t\t\tif (rs & m) {\n\t\t\t\t\t\tif (w && i == rn && !offset) {\n\t\t\t\t\t\t\trs &= ~m;\n\t\t\t\t\t\t\timmediate += 4;\n\t\t\t\t\t\t\toverlap = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toffset += 4;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (!p) {\n\t\t\t\t\timmediate = 4;\n\t\t\t\t}\n\t\t\t\tfor (var m = 0x01, i = 0; i < 16; m <<= 1, ++i) {\n\t\t\t\t\tif (rs & m) {\n\t\t\t\t\t\tif (w && i == rn && !offset) {\n\t\t\t\t\t\t\trs &= ~m;\n\t\t\t\t\t\t\timmediate += 4;\n\t\t\t\t\t\t\toverlap = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\timmediate -= 4;\n\t\t\t\t\t\toffset -= 4;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (w) {\n\t\t\t\taddress = this.armCompiler.constructAddressingMode4Writeback(immediate, offset, rn, overlap);\n\t\t\t} else {\n\t\t\t\taddress = this.armCompiler.constructAddressingMode4(immediate, rn);\n\t\t\t}\n\t\t\tif (load) {\n\t\t\t\t// LDM\n\t\t\t\tif (user) {\n\t\t\t\t\top = this.armCompiler.constructLDMS(rs, address, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructLDM(rs, address, condOp);\n\t\t\t\t}\n\t\t\t\top.writesPC = !!(rs & (1 << 15));\n\t\t\t} else {\n\t\t\t\t// STM\n\t\t\t\tif (user) {\n\t\t\t\t\top = this.armCompiler.constructSTMS(rs, address, condOp);\n\t\t\t\t} else {\n\t\t\t\t\top = this.armCompiler.constructSTM(rs, address, condOp);\n\t\t\t\t}\n\t\t\t\top.writesPC = false;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x0A000000:\n\t\t\t// Branch\n\t\t\tvar immediate = instruction & 0x00FFFFFF;\n\t\t\tif (immediate & 0x00800000) {\n\t\t\t\timmediate |= 0xFF000000;\n\t\t\t}\n\t\t\timmediate <<= 2;\n\t\t\tvar link = instruction & 0x01000000;\n\t\t\tif (link) {\n\t\t\t\top = this.armCompiler.constructBL(immediate, condOp);\n\t\t\t} else {\n\t\t\t\top = this.armCompiler.constructB(immediate, condOp);\n\t\t\t}\n\t\t\top.writesPC = true;\n\t\t\top.fixedJump = true;\n\t\t\tbreak;\n\t\tcase 0x0C000000:\n\t\t\t// Coprocessor data transfer\n\t\t\tbreak;\n\t\tcase 0x0E000000:\n\t\t\t// Coprocessor data operation/SWI\n\t\t\tif ((instruction & 0x0F000000) == 0x0F000000) {\n\t\t\t\t// SWI\n\t\t\t\tvar immediate = (instruction & 0x00FFFFFF);\n\t\t\t\top = this.armCompiler.constructSWI(immediate, condOp);\n\t\t\t\top.writesPC = false;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new EmuHalt('Bad opcode: 0x' + instruction.toString(16));\n\t\t}\n\t}\n\n\top.execMode = ARMMode.MODE_ARM;\n\top.fixedJump = op.fixedJump || false;\n\treturn op;\n};\n\nARMCore.prototype.compileThumb = function(instruction) {\n\tvar op = this.badOp(instruction & 0xFFFF);\n\tvar cpu = this;\n\tvar gprs = this.gprs;\n\tif ((instruction & 0xFC00) == 0x4000) {\n\t\t// Data-processing register\n\t\tvar rm = (instruction & 0x0038) >> 3;\n\t\tvar rd = instruction & 0x0007;\n\t\tswitch (instruction & 0x03C0) {\n\t\tcase 0x0000:\n\t\t\t// AND\n\t\t\top = this.thumbCompiler.constructAND(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0040:\n\t\t\t// EOR\n\t\t\top = this.thumbCompiler.constructEOR(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0080:\n\t\t\t// LSL(2)\n\t\t\top = this.thumbCompiler.constructLSL2(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x00C0:\n\t\t\t// LSR(2)\n\t\t\top = this.thumbCompiler.constructLSR2(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0100:\n\t\t\t// ASR(2)\n\t\t\top = this.thumbCompiler.constructASR2(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0140:\n\t\t\t// ADC\n\t\t\top = this.thumbCompiler.constructADC(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0180:\n\t\t\t// SBC\n\t\t\top = this.thumbCompiler.constructSBC(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x01C0:\n\t\t\t// ROR\n\t\t\top = this.thumbCompiler.constructROR(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0200:\n\t\t\t// TST\n\t\t\top = this.thumbCompiler.constructTST(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0240:\n\t\t\t// NEG\n\t\t\top = this.thumbCompiler.constructNEG(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0280:\n\t\t\t// CMP(2)\n\t\t\top = this.thumbCompiler.constructCMP2(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x02C0:\n\t\t\t// CMN\n\t\t\top = this.thumbCompiler.constructCMN(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0300:\n\t\t\t// ORR\n\t\t\top = this.thumbCompiler.constructORR(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0340:\n\t\t\t// MUL\n\t\t\top = this.thumbCompiler.constructMUL(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x0380:\n\t\t\t// BIC\n\t\t\top = this.thumbCompiler.constructBIC(rd, rm);\n\t\t\tbreak;\n\t\tcase 0x03C0:\n\t\t\t// MVN\n\t\t\top = this.thumbCompiler.constructMVN(rd, rm);\n\t\t\tbreak;\n\t\t}\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xFC00) == 0x4400) {\n\t\t// Special data processing / branch/exchange instruction set\n\t\tvar rm = (instruction & 0x0078) >> 3;\n\t\tvar rn = instruction & 0x0007;\n\t\tvar h1 = instruction & 0x0080;\n\t\tvar rd = rn | (h1 >> 4);\n\t\tswitch (instruction & 0x0300) {\n\t\tcase 0x0000:\n\t\t\t// ADD(4)\n\t\t\top = this.thumbCompiler.constructADD4(rd, rm)\n\t\t\top.writesPC = rd == ARMRegs.PC;\n\t\t\tbreak;\n\t\tcase 0x0100:\n\t\t\t// CMP(3)\n\t\t\top = this.thumbCompiler.constructCMP3(rd, rm);\n\t\t\top.writesPC = false;\n\t\t\tbreak;\n\t\tcase 0x0200:\n\t\t\t// MOV(3)\n\t\t\top = this.thumbCompiler.constructMOV3(rd, rm);\n\t\t\top.writesPC = rd == ARMRegs.PC;\n\t\t\tbreak;\n\t\tcase 0x0300:\n\t\t\t// BX\n\t\t\top = this.thumbCompiler.constructBX(rd, rm);\n\t\t\top.writesPC = true;\n\t\t\top.fixedJump = false;\n\t\t\tbreak;\n\t\t}\n\t} else if ((instruction & 0xF800) == 0x1800) {\n\t\t// Add/subtract\n\t\tvar rm = (instruction & 0x01C0) >> 6;\n\t\tvar rn = (instruction & 0x0038) >> 3;\n\t\tvar rd = instruction & 0x0007;\n\t\tswitch (instruction & 0x0600) {\n\t\tcase 0x0000:\n\t\t\t// ADD(3)\n\t\t\top = this.thumbCompiler.constructADD3(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0200:\n\t\t\t// SUB(3)\n\t\t\top = this.thumbCompiler.constructSUB3(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0400:\n\t\t\tvar immediate = (instruction & 0x01C0) >> 6;\n\t\t\tif (immediate) {\n\t\t\t\t// ADD(1)\n\t\t\t\top = this.thumbCompiler.constructADD1(rd, rn, immediate);\n\t\t\t} else {\n\t\t\t\t// MOV(2)\n\t\t\t\top = this.thumbCompiler.constructMOV2(rd, rn, rm);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x0600:\n\t\t\t// SUB(1)\n\t\t\tvar immediate = (instruction & 0x01C0) >> 6;\n\t\t\top = this.thumbCompiler.constructSUB1(rd, rn, immediate);\n\t\t\tbreak;\n\t\t}\n\t\top.writesPC = false;\n\t} else if (!(instruction & 0xE000)) {\n\t\t// Shift by immediate\n\t\tvar rd = instruction & 0x0007;\n\t\tvar rm = (instruction & 0x0038) >> 3;\n\t\tvar immediate = (instruction & 0x07C0) >> 6;\n\t\tswitch (instruction & 0x1800) {\n\t\tcase 0x0000:\n\t\t\t// LSL(1)\n\t\t\top = this.thumbCompiler.constructLSL1(rd, rm, immediate);\n\t\t\tbreak;\n\t\tcase 0x0800:\n\t\t\t// LSR(1)\n\t\t\top = this.thumbCompiler.constructLSR1(rd, rm, immediate);\n\t\t\tbreak;\n\t\tcase 0x1000:\n\t\t\t// ASR(1)\n\t\t\top = this.thumbCompiler.constructASR1(rd, rm, immediate);\n\t\t\tbreak;\n\t\tcase 0x1800:\n\t\t\tbreak;\n\t\t}\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xE000) == 0x2000) {\n\t\t// Add/subtract/compare/move immediate\n\t\tvar immediate = instruction & 0x00FF;\n\t\tvar rn = (instruction & 0x0700) >> 8;\n\t\tswitch (instruction & 0x1800) {\n\t\tcase 0x0000:\n\t\t\t// MOV(1)\n\t\t\top = this.thumbCompiler.constructMOV1(rn, immediate);\n\t\t\tbreak;\n\t\tcase 0x0800:\n\t\t\t// CMP(1)\n\t\t\top = this.thumbCompiler.constructCMP1(rn, immediate);\n\t\t\tbreak;\n\t\tcase 0x1000:\n\t\t\t// ADD(2)\n\t\t\top = this.thumbCompiler.constructADD2(rn, immediate);\n\t\t\tbreak;\n\t\tcase 0x1800:\n\t\t\t// SUB(2)\n\t\t\top = this.thumbCompiler.constructSUB2(rn, immediate);\n\t\t\tbreak;\n\t\t}\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xF800) == 0x4800) {\n\t\t// LDR(3)\n\t\tvar rd = (instruction & 0x0700) >> 8;\n\t\tvar immediate = (instruction & 0x00FF) << 2;\n\t\top = this.thumbCompiler.constructLDR3(rd, immediate);\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xF000) == 0x5000) {\n\t\t// Load and store with relative offset\n\t\tvar rd = instruction & 0x0007;\n\t\tvar rn = (instruction & 0x0038) >> 3;\n\t\tvar rm = (instruction & 0x01C0) >> 6;\n\t\tvar opcode = instruction & 0x0E00;\n\t\tswitch (opcode) {\n\t\tcase 0x0000:\n\t\t\t// STR(2)\n\t\t\top = this.thumbCompiler.constructSTR2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0200:\n\t\t\t// STRH(2)\n\t\t\top = this.thumbCompiler.constructSTRH2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0400:\n\t\t\t// STRB(2)\n\t\t\top = this.thumbCompiler.constructSTRB2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0600:\n\t\t\t// LDRSB\n\t\t\top = this.thumbCompiler.constructLDRSB(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0800:\n\t\t\t// LDR(2)\n\t\t\top = this.thumbCompiler.constructLDR2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0A00:\n\t\t\t// LDRH(2)\n\t\t\top = this.thumbCompiler.constructLDRH2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0C00:\n\t\t\t// LDRB(2)\n\t\t\top = this.thumbCompiler.constructLDRB2(rd, rn, rm);\n\t\t\tbreak;\n\t\tcase 0x0E00:\n\t\t\t// LDRSH\n\t\t\top = this.thumbCompiler.constructLDRSH(rd, rn, rm);\n\t\t\tbreak;\n\t\t}\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xE000) == 0x6000) {\n\t\t// Load and store with immediate offset\n\t\tvar rd = instruction & 0x0007;\n\t\tvar rn = (instruction & 0x0038) >> 3;\n\t\tvar immediate = (instruction & 0x07C0) >> 4;\n\t\tvar b = instruction & 0x1000;\n\t\tif (b) {\n\t\t\timmediate >>= 2;\n\t\t}\n\t\tvar load = instruction & 0x0800;\n\t\tif (load) {\n\t\t\tif (b) {\n\t\t\t\t// LDRB(1)\n\t\t\t\top = this.thumbCompiler.constructLDRB1(rd, rn, immediate);\n\t\t\t} else {\n\t\t\t\t// LDR(1)\n\t\t\t\top = this.thumbCompiler.constructLDR1(rd, rn, immediate);\n\t\t\t}\n\t\t} else {\n\t\t\tif (b) {\n\t\t\t\t// STRB(1)\n\t\t\t\top = this.thumbCompiler.constructSTRB1(rd, rn, immediate);\n\t\t\t} else {\n\t\t\t\t// STR(1)\n\t\t\t\top = this.thumbCompiler.constructSTR1(rd, rn, immediate);\n\t\t\t}\n\t\t}\n\t\top.writesPC = false;\n\t} else if ((instruction & 0xF600) == 0xB400) {\n\t\t// Push and pop registers\n\t\tvar r = !!(instruction & 0x0100);\n\t\tvar rs = instruction & 0x00FF;\n\t\tif (instruction & 0x0800) {\n\t\t\t// POP\n\t\t\top = this.thumbCompiler.constructPOP(rs, r);\n\t\t\top.writesPC = r;\n\t\t\top.fixedJump = false;\n\t\t} else {\n\t\t\t// PUSH\n\t\t\top = this.thumbCompiler.constructPUSH(rs, r);\n\t\t\top.writesPC = false;\n\t\t}\n\t} else if (instruction & 0x8000) {\n\t\tswitch (instruction & 0x7000) {\n\t\tcase 0x0000:\n\t\t\t// Load and store halfword\n\t\t\tvar rd = instruction & 0x0007;\n\t\t\tvar rn = (instruction & 0x0038) >> 3;\n\t\t\tvar immediate = (instruction & 0x07C0) >> 5;\n\t\t\tif (instruction & 0x0800) {\n\t\t\t\t// LDRH(1)\n\t\t\t\top = this.thumbCompiler.constructLDRH1(rd, rn, immediate);\n\t\t\t} else {\n\t\t\t\t// STRH(1)\n\t\t\t\top = this.thumbCompiler.constructSTRH1(rd, rn, immediate);\n\t\t\t}\n\t\t\top.writesPC = false;\n\t\t\tbreak;\n\t\tcase 0x1000:\n\t\t\t// SP-relative load and store\n\t\t\tvar rd = (instruction & 0x0700) >> 8;\n\t\t\tvar immediate = (instruction & 0x00FF) << 2;\n\t\t\tvar load = instruction & 0x0800;\n\t\t\tif (load) {\n\t\t\t\t// LDR(4)\n\t\t\t\top = this.thumbCompiler.constructLDR4(rd, immediate);\n\t\t\t} else {\n\t\t\t\t// STR(3)\n\t\t\t\top = this.thumbCompiler.constructSTR3(rd, immediate);\n\t\t\t}\n\t\t\top.writesPC = false;\n\t\t\tbreak;\n\t\tcase 0x2000:\n\t\t\t// Load address\n\t\t\tvar rd = (instruction & 0x0700) >> 8;\n\t\t\tvar immediate = (instruction & 0x00FF) << 2;\n\t\t\tif (instruction & 0x0800) {\n\t\t\t\t// ADD(6)\n\t\t\t\top = this.thumbCompiler.constructADD6(rd, immediate);\n\t\t\t} else {\n\t\t\t\t// ADD(5)\n\t\t\t\top = this.thumbCompiler.constructADD5(rd, immediate);\n\t\t\t}\n\t\t\top.writesPC = false;\n\t\t\tbreak;\n\t\tcase 0x3000:\n\t\t\t// Miscellaneous\n\t\t\tif (!(instruction & 0x0F00)) {\n\t\t\t\t// Adjust stack pointer\n\t\t\t\t// ADD(7)/SUB(4)\n\t\t\t\tvar b = instruction & 0x0080;\n\t\t\t\tvar immediate = (instruction & 0x7F) << 2;\n\t\t\t\tif (b) {\n\t\t\t\t\timmediate = -immediate;\n\t\t\t\t}\n\t\t\t\top = this.thumbCompiler.constructADD7(immediate)\n\t\t\t\top.writesPC = false;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x4000:\n\t\t\t// Multiple load and store\n\t\t\tvar rn = (instruction & 0x0700) >> 8;\n\t\t\tvar rs = instruction & 0x00FF;\n\t\t\tif (instruction & 0x0800) {\n\t\t\t\t// LDMIA\n\t\t\t\top = this.thumbCompiler.constructLDMIA(rn, rs);\n\t\t\t} else {\n\t\t\t\t// STMIA\n\t\t\t\top = this.thumbCompiler.constructSTMIA(rn, rs);\n\t\t\t}\n\t\t\top.writesPC = false;\n\t\t\tbreak;\n\t\tcase 0x5000:\n\t\t\t// Conditional branch\n\t\t\tvar cond = (instruction & 0x0F00) >> 8;\n\t\t\tvar immediate = (instruction & 0x00FF);\n\t\t\tif (cond == 0xF) {\n\t\t\t\t// SWI\n\t\t\t\top = this.thumbCompiler.constructSWI(immediate);\n\t\t\t\top.writesPC = false;\n\t\t\t} else {\n\t\t\t\t// B(1)\n\t\t\t\tif (instruction & 0x0080) {\n\t\t\t\t\timmediate |= 0xFFFFFF00;\n\t\t\t\t}\n\t\t\t\timmediate <<= 1;\n\t\t\t\tvar condOp = this.conds[cond];\n\t\t\t\top = this.thumbCompiler.constructB1(immediate, condOp);\n\t\t\t\top.writesPC = true;\n\t\t\t\top.fixedJump = true;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 0x6000:\n\t\tcase 0x7000:\n\t\t\t// BL(X)\n\t\t\tvar immediate = instruction & 0x07FF;\n\t\t\tvar h = instruction & 0x1800;\n\t\t\tswitch (h) {\n\t\t\tcase 0x0000:\n\t\t\t\t// B(2)\n\t\t\t\tif (immediate & 0x0400) {\n\t\t\t\t\timmediate |= 0xFFFFF800;\n\t\t\t\t}\n\t\t\t\timmediate <<= 1;\n\t\t\t\top = this.thumbCompiler.constructB2(immediate);\n\t\t\t\top.writesPC = true;\n\t\t\t\top.fixedJump = true;\n\t\t\t\tbreak;\n\t\t\tcase 0x0800:\n\t\t\t\t// BLX (ARMv5T)\n\t\t\t\t/*op = function() {\n\t\t\t\t\tvar pc = gprs[ARMRegs.PC];\n\t\t\t\t\tgprs[ARMRegs.PC] = (gprs[ARMRegs.LR] + (immediate << 1)) & 0xFFFFFFFC;\n\t\t\t\t\tgprs[ARMRegs.LR] = pc - 1;\n\t\t\t\t\tcpu.switchExecMode(cpu.MODE_ARM);\n\t\t\t\t}*/\n\t\t\t\tbreak;\n\t\t\tcase 0x1000:\n\t\t\t\t// BL(1)\n\t\t\t\tif (immediate & 0x0400) {\n\t\t\t\t\timmediate |= 0xFFFFFC00;\n\t\t\t\t}\n\t\t\t\timmediate <<= 12;\n\t\t\t\top = this.thumbCompiler.constructBL1(immediate);\n\t\t\t\top.writesPC = false;\n\t\t\t\tbreak;\n\t\t\tcase 0x1800:\n\t\t\t\t// BL(2)\n\t\t\t\top = this.thumbCompiler.constructBL2(immediate);\n\t\t\t\top.writesPC = true;\n\t\t\t\top.fixedJump = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new EmuHalt(\"Undefined instruction: 0x\" + instruction.toString(16));\n\t\t}\n\t} else {\n\t\tthrow new EmuHalt('Bad opcode: 0x' + instruction.toString(16));\n\t}\n\n\top.execMode = ARMMode.MODE_THUMB;\n\top.fixedJump = op.fixedJump || false;\n\t//console.log(hex(instruction), op);\n\treturn op;\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nexport class ARM32CPU implements CPU, InstructionBased, ARMMMUInterface, ARMIRQInterface, SavesState<ARMCoreState> {\n\n\tcore : ARMCoreType;\n\tbus : Bus;\n\tmemory : ARMMemoryRegion[];\n\n\tBASE_OFFSET = 24;\n\tOFFSET_MASK = 0x00FFFFFF;\n\n\tconstructor() {\n\t\tthis.core = new ARMCore();\n\t\tthis.core.irq = this;\n\t\tthis.core.mmu = this;\n\t\tthis.resetMemory();\n\t}\n\tresetMemory() {\n\t\tthis.memory = []; // TODO\n\t\tfor (var i=0; i<256; i++) {\n\t\t\t// TODO: constant\n\t\t\tvar bits = 10;\n\t\t\tvar size = 0x80000; \n\t\t\tthis.memory[i] = {\n\t\t\t\tPAGE_MASK: (2 << bits) - 1,\n\t\t\t\tICACHE_PAGE_BITS: bits,\n\t\t\t\ticache: new Array() // size >> (bits + 1))\n\t\t\t }; // TODO?\n\t\t}\n\t}\n\tadvanceInsn() : number {\n\t\tvar n = this.core.cycles;\n\t\tthis.core.step();\n\t\tn -= this.core.cycles;\n\t\treturn n > 0 ? n : 1;\n\t}\n\tgetPC(): number {\n\t\treturn this.core.gprs[15] - this.core.instructionWidth;\n\t}\n\tgetSP(): number {\n\t\treturn this.core.gprs[13];\n\t}\n\tisStable(): boolean {\n\t\treturn true; // TODO?\n\t}\n\tconnectMemoryBus(bus: Bus): void {\n\t\tthis.bus = bus;\n\t}\n\treset(): void {\n\t\tthis.resetMemory();\n\t\tthis.core.resetCPU(0);\n\t}\n\tsaveState() : ARMCoreState {\n\t\treturn this.core.freeze();\n\t}\n\tloadState(state: ARMCoreState): void {\n\t\tthis.core.defrost(state);\n\t}\n\n\tload8(a: number): number {\n\t\treturn (this.bus.read(a) << 24) >> 24;\n\t}\n\tloadU8(a: number): number {\n\t\treturn this.bus.read(a) & 0xff;\n\t}\n\tload16(a: number): number {\n\t\treturn (this.loadU16(a) << 16) >> 16;\n\t}\n\tloadU16(a: number): number {\n\t\treturn this.bus.read(a) | (this.bus.read(a+1) << 8);\n\t}\n\tload32(a: number): number {\n\t\tvar v = this.bus.read(a) | (this.bus.read(a+1) << 8) | (this.bus.read(a+2) << 16) | (this.bus.read(a+3) << 24);\n\t\treturn v;\n\t}\n\t// TODO: memory.invalidatePage(maskedOffset);\n\tstore8(a: number, v: number): void {\n\t\tthis.bus.write(a, v & 0xff);\n\t}\n\tstore16(a: number, v: number): void {\n\t\tthis.bus.write(a, v & 0xff);\n\t\tthis.bus.write(a+1, (v >> 8) & 0xff);\n\t}\n\tstore32(a: number, v: number): void {\n\t\tthis.bus.write(a, v & 0xff);\n\t\tthis.bus.write(a+1, (v >> 8) & 0xff);\n\t\tthis.bus.write(a+2, (v >> 16) & 0xff);\n\t\tthis.bus.write(a+3, (v >> 24) & 0xff);\n\t}\n\t// TODO\n\twait(a: number): void {\n\t\t++this.core.cycles;\n\t}\n\twait32(a: number): void {\n\t\t++this.core.cycles;\n\t}\n\twaitSeq32(a: number): void {\n\t\t++this.core.cycles;\n\t}\n\twaitMul(rs: number): void {\n if (((rs & 0xFFFFFF00) == 0xFFFFFF00) || !(rs & 0xFFFFFF00)) {\n\t\t\tthis.core.cycles += 1;\n\t\t} else if (((rs & 0xFFFF0000) == 0xFFFF0000) || !(rs & 0xFFFF0000)) {\n\t\t\t\tthis.core.cycles += 2;\n\t\t} else if (((rs & 0xFF000000) == 0xFF000000) || !(rs & 0xFF000000)) {\n\t\t\t\tthis.core.cycles += 3;\n\t\t} else {\n\t\t\t\tthis.core.cycles += 4;\n\t\t}\n\t}\n\twaitMulti32(a: number, total: number): void {\n\t\tthis.core.cycles += 2;\n\t}\n\twaitPrefetch(a: number): void {\n\t\t++this.core.cycles;\n\t}\n\twaitPrefetch32(a: number): void {\n\t\t++this.core.cycles;\n\t}\n\taddressToPage(region: number, address: number) : number {\n return address >> this.memory[region].ICACHE_PAGE_BITS;\n\t}\n\taccessPage(region: number, pageId: number): ARMMemoryPage {\n\t\tvar memory = this.memory[region];\n\t\tvar page = memory.icache[pageId];\n\t\tif (!page || page.invalid) {\n\t\t\t\tpage = {\n\t\t\t\t\t\tthumb: new Array(1 << (memory.ICACHE_PAGE_BITS)),\n\t\t\t\t\t\tarm: new Array(1 << memory.ICACHE_PAGE_BITS - 1),\n\t\t\t\t\t\tinvalid: false\n\t\t\t\t}\n\t\t\t\tmemory.icache[pageId] = page;\n\t\t}\n\t\treturn page;\n\t}\n\n\tswi(opcode: number): void {\n\t\tthis.core.raiseTrap();\n\t}\n\tswi32(opcode: number): void {\n this.swi(opcode >> 16);\n\t}\n\tclear() : void {\n\t}\n\tupdateTimers() : void {\n\t}\n\ttestIRQ() : void {\n\t}\n\n\tisThumb() : boolean {\n\t\treturn this.core.instructionWidth == 2;\n\t}\n}\n", "\nimport { ARM32CPU, ARMCoreState } from \"../common/cpu/ARM\";\nimport { BasicScanlineMachine, HasSerialIO, SerialEvent, SerialIOInterface } from \"../common/devices\";\nimport { newAddressDecoder, Keys, makeKeycodeMap, newKeyboardHandler, EmuHalt } from \"../common/emu\";\nimport { Debuggable, EmuState } from \"../common/baseplatform\";\nimport { hex, lpad } from \"../common/util\";\n\nvar GBA_KEYCODE_MAP = makeKeycodeMap([\n [Keys.A, 0, 0x1],\n [Keys.B, 0, 0x2],\n [Keys.GP_A, 0, 0x1],\n [Keys.GP_B, 0, 0x2],\n [Keys.SELECT,0, 0x4],\n [Keys.START ,0, 0x8],\n [Keys.RIGHT, 0, 0x10],\n [Keys.LEFT, 0, 0x20],\n [Keys.UP, 0, 0x40],\n [Keys.DOWN, 0, 0x80],\n]);\n\nconst ROM_START = 0x0;\nconst ROM_SIZE = 0x80000;\nconst RAM_START = 0x2000000;\nconst RAM_SIZE = 0x80000;\nconst IO_START = 0x4000000;\nconst IO_SIZE = 0x100;\nconst MAX_SERIAL_CHARS = 1000000;\n\nconst CPU_FREQ = 4000000; // 4 MHz\n\nexport class ARM32Machine extends BasicScanlineMachine implements Debuggable, HasSerialIO {\n\n cpuFrequency = CPU_FREQ; // MHz\n canvasWidth = 160;\n numTotalScanlines = 256;\n numVisibleScanlines = 128;\n cpuCyclesPerLine = Math.floor(CPU_FREQ / (256*60));\n defaultROMSize = 512*1024;\n sampleRate = 1;\n \n cpu: ARM32CPU = new ARM32CPU();\n ram = new Uint8Array(96*1024);\n ram16 = new Uint16Array(this.ram.buffer);\n pixels32 : Uint32Array;\n pixels8 : Uint8Array;\n vidbase : number = 0;\n brightness : number = 255;\n serial : SerialIOInterface;\n serialOut : SerialEvent[];\n serialIn : SerialEvent[];\n\n constructor() {\n super();\n this.connectCPUMemoryBus(this);\n this.handler = newKeyboardHandler(this.inputs, GBA_KEYCODE_MAP);\n }\n\n connectVideo(pixels:Uint32Array) : void {\n super.connectVideo(pixels);\n this.pixels32 = pixels;\n this.pixels8 = new Uint8Array(pixels.buffer);\n }\n\n connectSerialIO(serial: SerialIOInterface) {\n this.serial = serial;\n }\n\n reset() {\n super.reset();\n this.serialOut = [];\n this.serialIn = [];\n }\n\n // TODO: 32-bit bus?\n\n read = newAddressDecoder([\n [ROM_START, ROM_START+ROM_SIZE-1, ROM_SIZE-1, (a) => {\n return this.rom ? this.rom[a] : 0;\n }],\n [RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a) => {\n return this.ram[a];\n }],\n [IO_START, IO_START+IO_SIZE-1, IO_SIZE-1, (a, v) => {\n return this.readIO(a);\n }],\n [0, (1<<31)-1, 0, (a, v) => {\n throw new EmuHalt(`Address read out of bounds: 0x${hex(a)}`);\n }]\n ]);\n\n write = newAddressDecoder([\n [RAM_START, RAM_START+RAM_SIZE-1, RAM_SIZE-1, (a, v) => {\n this.ram[a] = v;\n }],\n [IO_START, IO_START+IO_SIZE-1, IO_SIZE-1, (a, v) => {\n this.writeIO(a, v);\n }],\n ]);\n\n readIO(a : number) : number {\n switch (a) {\n case 0x0:\n return this.inputs[0];\n case 0x40:\n return (this.serial.byteAvailable() ? 0x80 : 0) | (this.serial.clearToSend() ? 0x40 : 0);\n case 0x44:\n let evin = this.serialIn.shift();\n if (evin != null) {\n this.serialOut.push(evin);\n return evin.value;\n } else\n return 0;\n default:\n return 0;\n }\n }\n\n writeIO(a : number, v : number) : void {\n switch (a) {\n case 0x0:\n //this.brightness = v & 0xff;\n break;\n case 0x48:\n if (this.serialOut.length < MAX_SERIAL_CHARS) {\n this.serialOut.push({op:'write', value:v, nbits:8});\n }\n break;\n }\n }\n\n startScanline() {\n }\n\n drawScanline() {\n }\n \n postFrame() {\n var p32 = this.pixels32;\n var vbase = (this.vidbase >> 1) & 0xfffff;\n var mask = this.brightness << 24;\n for (var i=0; i<p32.length; i++) {\n var col = this.ram16[i + vbase];\n // rrrrrgggggbbbbb0 ->\n // 000rrrrr000ggggg000bbbbb00011111111\n p32[i] = mask | ((col&31)<<3) | (((col>>5)&31)<<11) | (((col>>10)&31)<<19);\n }\n }\n\n getDebugCategories() {\n return ['CPU', 'Stack'];\n }\n\n getDebugInfo?(category: string, state: EmuState) : string {\n switch (category) {\n case 'CPU':\n var s = '';\n var c = state.c as ARMCoreState;\n const EXEC_MODE = {2:'Thumb',4:'ARM'};\n const REGNAMES = {15:'PC',14:'LR',13:'SP',12:'IP',11:'FP',9:'SB'};\n for (var i=0; i<16; i++) {\n s += lpad(REGNAMES[i]||'',3) + lpad('r'+i, 5) + ' ' + hex(c.gprs[i],8) + '\\n';\n }\n s += 'Flags ';\n s += c.cpsrN ? \" N\" : \" -\";\n s += c.cpsrV ? \" V\" : \" -\";\n s += c.cpsrF ? \" F\" : \" -\";\n s += c.cpsrZ ? \" Z\" : \" -\";\n s += c.cpsrC ? \" C\" : \" -\";\n s += c.cpsrI ? \" I\" : \" -\";\n s += '\\n';\n s += 'MODE ' + EXEC_MODE[c.instructionWidth] + ' ' + MODE_NAMES[c.mode] + '\\n';\n s += 'SPSR ' + hex(c.spsr,8) + '\\n';\n s += 'cycl ' + c.cycles + '\\n';\n return s;\n }\n }\n\n saveState() {\n var state = super.saveState() as any;\n state.serial = {\n sin: this.serialIn.slice(0),\n sout : this.serialOut.slice(0)\n }\n return state;\n }\n loadState(state) {\n super.loadState(state);\n this.serialIn = state.serial.sin;\n this.serialOut = state.serial.sout;\n }\n}\n\nconst MODE_NAMES = {\n\t0x10: \"USER\",\n 0x11: \"FIQ\",\n 0x12: \"IRQ\",\n 0x13: \"SUPERVISOR\",\n 0x17: \"ABORT\",\n 0x1b: \"UNDEFINED\",\n 0x1f: \"SYSTEM\",\n};\n", "\nimport { BaseDebugPlatform, CpuState, EmuState, Platform, DisasmLine, Debuggable, Machine, BaseMachinePlatform } from \"../common/baseplatform\";\nimport { AnimationTimer, EmuHalt, padBytes, PLATFORMS, RasterVideo } from \"../common/emu\";\nimport { hex, lpad, loadScript } from \"../common/util\";\nimport { ARM32CPU } from \"../common/cpu/ARM\";\nimport { ARM32Machine } from \"../machine/arm32\";\n\ndeclare var uc, cs : any; // Unicorn module\n\nconst ARM32_PRESETS = [\n { id: 'vidfill.vasm', name: 'Video Memory Fill' },\n];\n\nconst SCREEN_WIDTH = 160;\nconst SCREEN_HEIGHT = 128;\nconst ROM_START_ADDR = 0x0;\nconst HIROM_START_ADDR = 0xff800000;\nconst ROM_SIZE = 512*1024;\nconst RAM_START_ADDR = 0x20000000;\nconst RAM_SIZE = 512*1024;\nconst CLOCKS_PER_FRAME = 10000;\n\ninterface ARM32State extends EmuState {\n r: Uint32Array; // registers\n}\n\nexport abstract class BaseARMMachinePlatform<T extends Machine> extends BaseMachinePlatform<T> {\n\n //getOpcodeMetadata = getOpcodeMetadata_z80;\n getToolForFilename(fn: string) {\n if (fn.endsWith('.vasm')) return \"vasmarm\";\n else if (fn.endsWith('.armips')) return \"armips\";\n else return \"vasmarm\";\n }\n getPresets() { return ARM32_PRESETS; }\n getDefaultExtension() { return \".vasm\"; };\n \n }\n \nclass ARM32Platform extends BaseARMMachinePlatform<ARM32Machine> implements Platform {\n\n capstone_arm : any;\n capstone_thumb : any;\n\n async start() {\n super.start();\n console.log(\"Loading Capstone\");\n await loadScript('./lib/capstone-arm.min.js');\n this.capstone_arm = new cs.Capstone(cs.ARCH_ARM, cs.MODE_ARM);\n this.capstone_thumb = new cs.Capstone(cs.ARCH_ARM, cs.MODE_THUMB);\n }\n\n newMachine() { return new ARM32Machine(); }\n readAddress(a) { return this.machine.read(a); }\n getMemoryMap = function() { return { main:[\n {name:'ROM',start:0x0000000,size:0x80000,type:'rom'},\n {name:'RAM',start:0x2000000,size:0x80000,type:'ram'},\n {name:'I/O',start:0x4000000,size:0x100,type:'io'},\n ] } };\n disassemble(pc:number, read:(addr:number)=>number) : DisasmLine {\n var is_thumb = this.machine.cpu.isThumb();\n var capstone = is_thumb ? this.capstone_thumb : this.capstone_arm;\n var buf = [];\n for (var i=0; i<4; i++) {\n buf[i] = read(pc+i);\n }\n var insns = capstone.disasm(buf, pc, 4);\n var i0 = insns && insns[0];\n if (i0) {\n return {\n nbytes: i0.size,\n line: i0.mnemonic + \" \" + i0.op_str,\n isaddr: i0.address > 0\n };\n } else {\n return {\n nbytes: 4,\n line: \"???\",\n isaddr: false\n };\n }\n }\n}\n\n////\n\nPLATFORMS['arm32'] = ARM32Platform;\n"],
"mappings": "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",
"names": []
}