disassemble(nStart, nStop) {
		let addr = nStart;
		let value = 0x00, lo = 0x00, hi = 0x00;
		let mapLines = [];
		let line_addr = 0;

		// A convenient utility to convert variables into
		// hex strings because "modern C++"'s method with
		// streams is atrocious
		let hex = (n, d) => {
			let s = [];
			for (let i = d - 1; i >= 0; i--, n >>= 4)
				s[i] = "0123456789ABCDEF"[n & 0xF];
			return s.join('');
		};

		// Starting at the specified address we read an instruction
		// byte, which in turn yields information from the lookup table
		// as to how many additional bytes we need to read and what the
		// addressing mode is. I need this info to assemble human readable
		// syntax, which is different depending upon the addressing mode

		// As the instruction is decoded, a std::string is assembled
		// with the readable output
		while (addr <= nStop) {
			line_addr = addr;

			// Prefix line with instruction address
			let sInst = "$" + hex(addr, 4) + ": ";

			// Read instruction, and get its readable name
			let pcode = this.bus.cpuRead(addr, true);
			addr++;

			if (!this.lookup[pcode]) {
				continue;
			}

			sInst += this.lookup[pcode].name + " ";

			// Get oprands from desired locations, and form the
			// instruction based upon its addressing mode. These
			// routines mimmick the actual fetch routine of the
			// 6502 in order to get accurate data as part of the
			// instruction
			if (this.lookup[pcode].addrmode === this.IMP) {
				sInst += " {IMP}";
			} else if (this.lookup[pcode].addrmode === this.IMM) {
				value = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "#$" + hex(value, 2) + " {IMM}";
			} else if (this.lookup[pcode].addrmode === this.ZP0) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + " {ZP0}";
			} else if (this.lookup[pcode].addrmode === this.ZPX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + ", X {ZPX}";
			} else if (this.lookup[pcode].addrmode === this.ZPY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + ", Y {ZPY}";
			} else if (this.lookup[pcode].addrmode === this.IZX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "($" + hex(lo, 2) + ", X) {IZX}";
			} else if (this.lookup[pcode].addrmode === this.IZY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "($" + hex(lo, 2) + "), Y {IZY}";
			} else if (this.lookup[pcode].addrmode === this.ABS) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + " {ABS}";
			} else if (this.lookup[pcode].addrmode === this.ABX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + ", X {ABX}";
			} else if (this.lookup[pcode].addrmode === this.ABY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + ", Y {ABY}";
			} else if (this.lookup[pcode].addrmode === this.IND) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "($" + hex((hi << 8) | lo, 4) + ") {IND}";
			} else if (this.lookup[pcode].addrmode === this.REL) {
				value = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex(value, 2) + " [$" + hex(addr + value, 4) + "] {REL}";
			}

			// Add the formed string to a std::map, using the instruction's
			// address as the key. This makes it convenient to look for later
			// as the instructions are variable in length, so a straight up
			// incremental index is not sufficient.
			mapLines[line_addr] = sInst;
		}

		return mapLines;
	}
// advantage of many of the CPUs internal operations to do this.
advantage of many of the CPUs internal operations to do this.
advantage of many of the CPUs internal operations to do this .
disassemble(nStart, nStop) {
		let addr = nStart;
		let value = 0x00, lo = 0x00, hi = 0x00;
		let mapLines = [];
		let line_addr = 0;
		let hex = (n, d) => {
			let s = [];
			for (let i = d - 1; i >= 0; i--, n >>= 4)
				s[i] = "0123456789ABCDEF"[n & 0xF];
			return s.join('');
		};
		while (addr <= nStop) {
			line_addr = addr;
			let sInst = "$" + hex(addr, 4) + ": ";
			let pcode = this.bus.cpuRead(addr, true);
			addr++;
			if (!this.lookup[pcode]) {
				continue;
			}
			sInst += this.lookup[pcode].name + " ";
			if (this.lookup[pcode].addrmode === this.IMP) {
				sInst += " {IMP}";
			} else if (this.lookup[pcode].addrmode === this.IMM) {
				value = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "#$" + hex(value, 2) + " {IMM}";
			} else if (this.lookup[pcode].addrmode === this.ZP0) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + " {ZP0}";
			} else if (this.lookup[pcode].addrmode === this.ZPX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + ", X {ZPX}";
			} else if (this.lookup[pcode].addrmode === this.ZPY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "$" + hex(lo, 2) + ", Y {ZPY}";
			} else if (this.lookup[pcode].addrmode === this.IZX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "($" + hex(lo, 2) + ", X) {IZX}";
			} else if (this.lookup[pcode].addrmode === this.IZY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = 0x00;
				sInst += "($" + hex(lo, 2) + "), Y {IZY}";
			} else if (this.lookup[pcode].addrmode === this.ABS) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + " {ABS}";
			} else if (this.lookup[pcode].addrmode === this.ABX) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + ", X {ABX}";
			} else if (this.lookup[pcode].addrmode === this.ABY) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex((hi << 8) | lo, 4) + ", Y {ABY}";
			} else if (this.lookup[pcode].addrmode === this.IND) {
				lo = this.bus.cpuRead(addr, true);
				addr++;
				hi = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "($" + hex((hi << 8) | lo, 4) + ") {IND}";
			} else if (this.lookup[pcode].addrmode === this.REL) {
				value = this.bus.cpuRead(addr, true);
				addr++;
				sInst += "$" + hex(value, 2) + " [$" + hex(addr + value, 4) + "] {REL}";
			}
			mapLines[line_addr] = sInst;
		}
		return mapLines;
	}
disassemble ( nStart , nStop ) { let addr = nStart ; let value = 0x00 , lo = 0x00 , hi = 0x00 ; let mapLines = [ ] ; let line_addr = 0 ; let hex = ( n , d ) => { let s = [ ] ; for ( let i = d - 1 ; i >= 0 ; i -- , n >>= 4 ) s [ i ] = "0123456789ABCDEF" [ n & 0xF ] ; return s . join ( '' ) ; } ; while ( addr <= nStop ) { line_addr = addr ; let sInst = "$" + hex ( addr , 4 ) + ": " ; let pcode = this . bus . cpuRead ( addr , true ) ; addr ++ ; if ( ! this . lookup [ pcode ] ) { continue ; } sInst += this . lookup [ pcode ] . name + " " ; if ( this . lookup [ pcode ] . addrmode === this . IMP ) { sInst += " {IMP}" ; } else if ( this . lookup [ pcode ] . addrmode === this . IMM ) { value = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "#$" + hex ( value , 2 ) + " {IMM}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ZP0 ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = 0x00 ; sInst += "$" + hex ( lo , 2 ) + " {ZP0}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ZPX ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = 0x00 ; sInst += "$" + hex ( lo , 2 ) + ", X {ZPX}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ZPY ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = 0x00 ; sInst += "$" + hex ( lo , 2 ) + ", Y {ZPY}" ; } else if ( this . lookup [ pcode ] . addrmode === this . IZX ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = 0x00 ; sInst += "($" + hex ( lo , 2 ) + ", X) {IZX}" ; } else if ( this . lookup [ pcode ] . addrmode === this . IZY ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = 0x00 ; sInst += "($" + hex ( lo , 2 ) + "), Y {IZY}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ABS ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "$" + hex ( ( hi << 8 ) | lo , 4 ) + " {ABS}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ABX ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "$" + hex ( ( hi << 8 ) | lo , 4 ) + ", X {ABX}" ; } else if ( this . lookup [ pcode ] . addrmode === this . ABY ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "$" + hex ( ( hi << 8 ) | lo , 4 ) + ", Y {ABY}" ; } else if ( this . lookup [ pcode ] . addrmode === this . IND ) { lo = this . bus . cpuRead ( addr , true ) ; addr ++ ; hi = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "($" + hex ( ( hi << 8 ) | lo , 4 ) + ") {IND}" ; } else if ( this . lookup [ pcode ] . addrmode === this . REL ) { value = this . bus . cpuRead ( addr , true ) ; addr ++ ; sInst += "$" + hex ( value , 2 ) + " [$" + hex ( addr + value , 4 ) + "] {REL}" ; } mapLines [ line_addr ] = sInst ; } return mapLines ; }
advantage of many of the CPUs internal operations to do this.
advantage of many of the CPUs internal operations to do this .
// A convenient utility to convert variables into // hex strings because "modern C++"'s method with // streams is atrocious // Starting at the specified address we read an instruction // byte, which in turn yields information from the lookup table // as to how many additional bytes we need to read and what the // addressing mode is. I need this info to assemble human readable // syntax, which is different depending upon the addressing mode // As the instruction is decoded, a std::string is assembled // with the readable output // Prefix line with instruction address // Read instruction, and get its readable name // Get oprands from desired locations, and form the // instruction based upon its addressing mode. These // routines mimmick the actual fetch routine of the // 6502 in order to get accurate data as part of the // instruction // Add the formed string to a std::map, using the instruction's // address as the key. This makes it convenient to look for later // as the instructions are variable in length, so a straight up // incremental index is not sufficient.