var STR_PAD_LEFT = 1; var STR_PAD_RIGHT = 2; var STR_PAD_BOTH = 3; function pad(str, len, pad, dir) { if (typeof(len) == "undefined") { var len = 0; } if (typeof(pad) == "undefined") { var pad = ' '; } if (typeof(dir) == "undefined") { var dir = STR_PAD_RIGHT; } if (len + 1 >= str.length) { switch (dir){ case STR_PAD_LEFT: str = Array(len + 1 - str.length).join(pad) + str; break; case STR_PAD_BOTH: var right = Math.ceil((padlen = len - str.length) / 2); var left = padlen - right; str = Array(left+1).join(pad) + str + Array(right+1).join(pad); break; default: str = str + Array(len + 1 - str.length).join(pad); break; } // switch } return str; } function Disassembler(memCtrl) { this.memCtrl = memCtrl; this.regPC = 0x0000; // program counter this.disassemble = function(startloc, nbytes) { var bytecount = 0; this.regPC = startloc; do { dissambly = this.opToStr(); bytecount += dissambly.numBytes; console.log(dissambly.text); } while (bytecount < nbytes); }; this.opToStr = function() { var numbytes = 0; var startpos = 0; var mem_dump; var opcode = this.memCtrl.getData(this.regPC); var am_string = this.optable[opcode][1]; // Get the hex address of the opcode and the opcode hex code mem_dump = "$" + this.regPC.toString(16) + ": " + opcode.toString(16); this.regPC = (this.regPC + 1) & 0xFFFF; numbytes++; var pos = am_string.indexOf("ADDR", startpos); if (pos != -1) { mem_dump += " " + this.memCtrl.getData(this.regPC).toString(16); mem_dump += " " + this.memCtrl.getData((this.regPC + 1) & 0xFFFF).toString(16); am_string = am_string.replace("ADDR", this.memCtrl.getAddr(this.regPC).toString(16)); startpos += 4; this.regPC = (this.regPC + 2) & 0xFFFF; numbytes += 2; } pos = am_string.indexOf("BIT", startpos); if (pos != -1) { var bitStr = (((opcode & 0xF0) >> 4) % 8).toString(); am_string = am_string.replace("BIT", bitStr); startpos += 1; } pos = am_string.indexOf("BYTE", startpos); if (pos != -1) { mem_dump += " " + this.memCtrl.getData(this.regPC).toString(16); am_string = am_string.replace("BYTE", this.memCtrl.getData(this.regPC).toString(16)); startpos += 2; this.regPC = (this.regPC + 1) & 0xFFFF; numbytes++; } pos = am_string.indexOf("BYTE", startpos); if (pos != -1) { mem_dump += " " + this.memCtrl.getData(this.regPC).toString(16); am_string = am_string.replace("BYTE", this.memCtrl.getData(this.regPC).toString(16)); this.regPC += (this.regPC + 1) & 0xFFFF; numbytes++; } mem_dump = pad(mem_dump, 20, ' ', STR_PAD_RIGHT).toUpperCase(); var finalStr = mem_dump + this.optable[opcode][0] + " " + am_string.toUpperCase(); return {numBytes: numbytes, text: finalStr}; }; this.optable = new Array(256); this.optable[0x00] = ["BRK", ""]; this.optable[0x01] = ["ORA", "($BYTE,X)"]; this.optable[0x02] = ["NOP", ""]; this.optable[0x03] = ["NOP", ""]; this.optable[0x04] = ["TSB", "$BYTE"]; this.optable[0x05] = ["ORA", "$BYTE"]; this.optable[0x06] = ["ASL", "$BYTE"]; this.optable[0x07] = ["RMB", "BIT,$BYTE"]; this.optable[0x08] = ["PHP", ""]; this.optable[0x09] = ["ORA", "#BYTE"]; this.optable[0x0A] = ["ASL", "A"]; this.optable[0x0B] = ["NOP", ""]; this.optable[0x0C] = ["TSB", "$ADDR"]; this.optable[0x0D] = ["ORA", "$ADDR"]; this.optable[0x0E] = ["ASL", "$ADDR"]; this.optable[0x0F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x10] = ["BPL", "BYTE"]; this.optable[0x11] = ["ORA", "($BYTE),Y"]; this.optable[0x12] = ["ORA", "($BYTE)"]; this.optable[0x13] = ["NOP", ""]; this.optable[0x14] = ["TRB", "$BYTE"]; this.optable[0x15] = ["ORA", "$BYTE,X"]; this.optable[0x16] = ["ASL", "$BYTE,X"]; this.optable[0x17] = ["RMB", "BIT,$BYTE"]; this.optable[0x18] = ["CLC", ""]; this.optable[0x19] = ["ORA", "$ADDR,Y"]; this.optable[0x1A] = ["INA", "A"]; this.optable[0x1B] = ["NOP", ""]; this.optable[0x1C] = ["TRB", "$ADDR"]; this.optable[0x1D] = ["ORA", "$ADDR,X"]; this.optable[0x1E] = ["ASL", "$ADDR,X"]; this.optable[0x1F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x20] = ["JSR", "$ADDR"]; this.optable[0x21] = ["AND", "($BYTE,X)"]; this.optable[0x22] = ["NOP", ""]; this.optable[0x23] = ["NOP", ""]; this.optable[0x24] = ["BIT", "$BYTE"]; this.optable[0x25] = ["AND", "$BYTE"]; this.optable[0x26] = ["ROL", "$BYTE"]; this.optable[0x27] = ["RMB", "BIT,$BYTE"]; this.optable[0x28] = ["PLP", ""]; this.optable[0x29] = ["AND", "#BYTE"]; this.optable[0x2A] = ["ROL", "A"]; this.optable[0x2B] = ["NOP", ""]; this.optable[0x2C] = ["BIT", "$ADDR"]; this.optable[0x2D] = ["AND", "$ADDR"]; this.optable[0x2E] = ["ROL", "$ADDR"]; this.optable[0x2F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x30] = ["BMI", "BYTE"]; this.optable[0x31] = ["AND", "($BYTE),Y"]; this.optable[0x32] = ["AND", "($BYTE)"]; this.optable[0x33] = ["NOP", ""]; this.optable[0x34] = ["BIT", "$BYTE,X"]; this.optable[0x35] = ["AND", "$BYTE,X"]; this.optable[0x36] = ["ROL", "$BYTE,X"]; this.optable[0x37] = ["RMB", "BIT,$BYTE"]; this.optable[0x38] = ["SEC", ""]; this.optable[0x39] = ["AND", "$ADDR,Y"]; this.optable[0x3A] = ["DEA", "A"]; this.optable[0x3B] = ["NOP", ""]; this.optable[0x3C] = ["BIT", "$ADDR,X"]; this.optable[0x3D] = ["AND", "$ADDR,X"]; this.optable[0x3E] = ["ROL", "$ADDR,X"]; this.optable[0x3F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x40] = ["RTI", ""]; this.optable[0x41] = ["EOR", "($BYTE,X)"]; this.optable[0x42] = ["NOP", ""]; this.optable[0x43] = ["NOP", ""]; this.optable[0x44] = ["NOP", ""]; this.optable[0x45] = ["EOR", "$BYTE"]; this.optable[0x46] = ["LSR", "$BYTE"]; this.optable[0x47] = ["RMB", "BIT,$BYTE"]; this.optable[0x48] = ["PHA", ""]; this.optable[0x49] = ["EOR", "#BYTE"]; this.optable[0x4A] = ["LSR", "A"]; this.optable[0x4B] = ["NOP", ""]; this.optable[0x4C] = ["JMP", "$ADDR"]; this.optable[0x4D] = ["EOR", "$ADDR"]; this.optable[0x4E] = ["LSR", "$ADDR"]; this.optable[0x4F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x50] = ["BVC", "BYTE"]; this.optable[0x51] = ["EOR", "($BYTE),Y"]; this.optable[0x52] = ["EOR", "($BYTE)"]; this.optable[0x53] = ["NOP", ""]; this.optable[0x54] = ["NOP", ""]; this.optable[0x55] = ["EOR", "$BYTE,X"]; this.optable[0x56] = ["LSR", "$BYTE,X"]; this.optable[0x57] = ["RMB", "BIT,$BYTE"]; this.optable[0x58] = ["CLI", ""]; this.optable[0x59] = ["EOR", "$ADDR,Y"]; this.optable[0x5A] = ["PHY", ""]; this.optable[0x5B] = ["NOP", ""]; this.optable[0x5C] = ["NOP", ""]; this.optable[0x5D] = ["EOR", "$ADDR,X"]; this.optable[0x5E] = ["LSR", "$ADDR,X"]; this.optable[0x5F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x60] = ["RTS", ""]; this.optable[0x61] = ["ADC", "($BYTE,X)"]; this.optable[0x62] = ["NOP", ""]; this.optable[0x63] = ["NOP", ""]; this.optable[0x64] = ["STZ", "$BYTE"]; this.optable[0x65] = ["ADC", "$BYTE"]; this.optable[0x66] = ["ROR", "$BYTE"]; this.optable[0x67] = ["RMB", "BIT,$BYTE"]; this.optable[0x68] = ["PLA", ""]; this.optable[0x69] = ["ADC", "#BYTE"]; this.optable[0x6A] = ["ROR", "A"]; this.optable[0x6B] = ["NOP", ""]; this.optable[0x6C] = ["JMP", "($ADDR)"]; this.optable[0x6D] = ["ADC", "$ADDR"]; this.optable[0x6E] = ["ROR", "$ADDR"]; this.optable[0x6F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x70] = ["BVS", "BYTE"]; this.optable[0x71] = ["ADC", "($BYTE),Y"]; this.optable[0x72] = ["ADC", "($BYTE)"]; this.optable[0x73] = ["NOP", ""]; this.optable[0x74] = ["STZ", "$BYTE,X"]; this.optable[0x75] = ["ADC", "$BYTE,X"]; this.optable[0x76] = ["ROR", "$BYTE,X"]; this.optable[0x77] = ["RMB", "BIT,$BYTE"]; this.optable[0x78] = ["SEI", ""]; this.optable[0x79] = ["ADC", "$ADDR,Y"]; this.optable[0x7A] = ["PLY", ""]; this.optable[0x7B] = ["NOP", ""]; this.optable[0x7C] = ["JMP", "($ADDR,X)"]; this.optable[0x7D] = ["ADC", "$ADDR,X"]; this.optable[0x7E] = ["ROR", "$ADDR,X"]; this.optable[0x7F] = ["BBR", "BIT,$BYTE,BYTE"]; this.optable[0x80] = ["BRA", "BYTE"]; this.optable[0x81] = ["STA", "($BYTE,X)"]; this.optable[0x82] = ["NOP", ""]; this.optable[0x83] = ["NOP", ""]; this.optable[0x84] = ["STY", "$BYTE"]; this.optable[0x85] = ["STA", "$BYTE"]; this.optable[0x86] = ["STX", "$BYTE"]; this.optable[0x87] = ["SMB", "BIT,$BYTE"]; this.optable[0x88] = ["DEY", ""]; this.optable[0x89] = ["BIT", "#BYTE"]; this.optable[0x8A] = ["TXA", ""]; this.optable[0x8B] = ["NOP", ""]; this.optable[0x8C] = ["STY", "$ADDR"]; this.optable[0x8D] = ["STA", "$ADDR"]; this.optable[0x8E] = ["STX", "$ADDR"]; this.optable[0x8F] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0x90] = ["BCC", "BYTE"]; this.optable[0x91] = ["STA", "($BYTE),Y"]; this.optable[0x92] = ["STA", "($BYTE)"]; this.optable[0x93] = ["NOP", ""]; this.optable[0x94] = ["STY", "$BYTE,X"]; this.optable[0x95] = ["STA", "$BYTE,X"]; this.optable[0x96] = ["STX", "$BYTE,Y"]; this.optable[0x97] = ["SMB", "BIT,$BYTE"]; this.optable[0x98] = ["TYA", ""]; this.optable[0x99] = ["STA", "$ADDR,Y"]; this.optable[0x9A] = ["TXS", ""]; this.optable[0x9B] = ["NOP", ""]; this.optable[0x9C] = ["STZ", "$ADDR"]; this.optable[0x9D] = ["STA", "$ADDR,X"]; this.optable[0x9E] = ["STZ", "$ADDR,X"]; this.optable[0x9F] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xA0] = ["LDY", "#BYTE"]; this.optable[0xA1] = ["LDA", "($BYTE,X)"]; this.optable[0xA2] = ["LDX", "#BYTE"]; this.optable[0xA3] = ["NOP", ""]; this.optable[0xA4] = ["LDY", "$BYTE"]; this.optable[0xA5] = ["LDA", "$BYTE"]; this.optable[0xA6] = ["LDX", "$BYTE"]; this.optable[0xA7] = ["SMB", "BIT,$BYTE"]; this.optable[0xA8] = ["TAY", ""]; this.optable[0xA9] = ["LDA", "#BYTE"]; this.optable[0xAA] = ["TAX", ""]; this.optable[0xAB] = ["NOP", ""]; this.optable[0xAC] = ["LDY", "$ADDR"]; this.optable[0xAD] = ["LDA", "$ADDR"]; this.optable[0xAE] = ["LDX", "$ADDR"]; this.optable[0xAF] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xB0] = ["BCS", "BYTE"]; this.optable[0xB1] = ["LDA", "($BYTE),Y"]; this.optable[0xB2] = ["LDA", "($BYTE)"]; this.optable[0xB3] = ["NOP", ""]; this.optable[0xB4] = ["LDY", "$BYTE,X"]; this.optable[0xB5] = ["LDA", "$BYTE,X"]; this.optable[0xB6] = ["LDX", "$BYTE,Y"]; this.optable[0xB7] = ["SMB", "BIT,$BYTE"]; this.optable[0xB8] = ["CLV", ""]; this.optable[0xB9] = ["LDA", "$ADDR,Y"]; this.optable[0xBA] = ["TSX", ""]; this.optable[0xBB] = ["NOP", ""]; this.optable[0xBC] = ["LDY", "$ADDR,X"]; this.optable[0xBD] = ["LDA", "$ADDR,X"]; this.optable[0xBE] = ["LDX", "$ADDR,Y"]; this.optable[0xBF] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xC0] = ["CPY", "#BYTE"]; this.optable[0xC1] = ["CMP", "($BYTE,X)"]; this.optable[0xC2] = ["NOP", ""]; this.optable[0xC3] = ["NOP", ""]; this.optable[0xC4] = ["CPY", "$BYTE"]; this.optable[0xC5] = ["CMP", "$BYTE"]; this.optable[0xC6] = ["DEC", "$BYTE"]; this.optable[0xC7] = ["SMB", "BIT,$BYTE"]; this.optable[0xC8] = ["INY", ""]; this.optable[0xC9] = ["CMP", "#BYTE"]; this.optable[0xCA] = ["DEX", ""]; this.optable[0xCB] = ["WAI", ""]; this.optable[0xCC] = ["CPY", "$ADDR"]; this.optable[0xCD] = ["CMP", "$ADDR"]; this.optable[0xCE] = ["DEC", "$ADDR"]; this.optable[0xCF] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xD0] = ["BNE", "BYTE"]; this.optable[0xD1] = ["CMP", "($BYTE),Y"]; this.optable[0xD2] = ["CMP", "($BYTE)"]; this.optable[0xD3] = ["NOP", ""]; this.optable[0xD4] = ["NOP", ""]; this.optable[0xD5] = ["CMP", "$BYTE,X"]; this.optable[0xD6] = ["DEC", "$BYTE,X"]; this.optable[0xD7] = ["SMB", "BIT,$BYTE"]; this.optable[0xD8] = ["CLD", ""]; this.optable[0xD9] = ["CMP", "$ADDR,Y"]; this.optable[0xDA] = ["PHX", ""]; this.optable[0xDB] = ["STP", ""]; this.optable[0xDC] = ["NOP", ""]; this.optable[0xDD] = ["CMP", "$ADDR,X"]; this.optable[0xDE] = ["DEC", "$ADDR,X"]; this.optable[0xDF] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xE0] = ["CPX", "#BYTE"]; this.optable[0xE1] = ["SBC", "($BYTE,X)"]; this.optable[0xE2] = ["NOP", ""]; this.optable[0xE3] = ["NOP", ""]; this.optable[0xE4] = ["CPX", "$BYTE"]; this.optable[0xE5] = ["SBC", "$BYTE"]; this.optable[0xE6] = ["INC", "$BYTE"]; this.optable[0xE7] = ["SMB", "BIT,$BYTE"]; this.optable[0xE8] = ["INX", ""]; this.optable[0xE9] = ["SBC", "#BYTE"]; this.optable[0xEA] = ["NOP", ""]; this.optable[0xEB] = ["NOP", ""]; this.optable[0xEC] = ["CPX", "$ADDR"]; this.optable[0xED] = ["SBC", "$ADDR"]; this.optable[0xEE] = ["INC", "$ADDR"]; this.optable[0xEF] = ["BBS", "BIT,$BYTE,BYTE"]; this.optable[0xF0] = ["BEQ", "BYTE"]; this.optable[0xF1] = ["SBC", "($BYTE),Y"]; this.optable[0xF2] = ["SBC", "($BYTE)"]; this.optable[0xF3] = ["NOP", ""]; this.optable[0xF4] = ["NOP", ""]; this.optable[0xF5] = ["SBC", "$BYTE,X"]; this.optable[0xF6] = ["INC", "$BYTE,X"]; this.optable[0xF7] = ["SMB", "BIT,$BYTE"]; this.optable[0xF8] = ["SED", ""]; this.optable[0xF9] = ["SBC", "$ADDR,Y"]; this.optable[0xFA] = ["PLX", ""]; this.optable[0xFB] = ["NOP", ""]; this.optable[0xFC] = ["NOP", ""]; this.optable[0xFD] = ["SBC", "$ADDR,X"]; this.optable[0xFE] = ["INC", "$ADDR,X"]; this.optable[0xFF] = ["BBS", "BIT,$BYTE,BYTE"]; }