instr_decode.js
function disasm1(machine_code, offset=0) {
  let di = decode_instruction(machine_code[offset]);

  let opcode, operand;
  let consumed = 1; // 1-tryte opcode, incremented later if operands

  if (di.family === 0) {
    opcode = invertKv(OP)[di.operation]; // inefficient lookup, but probably doesn't matter

    // note: some duplication with cpu read_alu_operand TODO: factor out
    // TODO: handle reading beyond end
    let decoded_operand = decode_operand(di, machine_code, offset);
    operand = stringify_operand(decoded_operand);
    consumed += decoded_operand.consumed;
  } else if (di.family === 1) {
    opcode = 'BR';
    opcode += invertKv(FLAGS)[di.flag];
    opcode += {'-1':'L', 0:'E', 1:'N'}[di.direction];
    opcode += {'-1':'N', 0:'Z', 1:'P'}[di.compare];

    if (invertKv(BRANCH_INSTRUCTION_SHORTHANDS)[opcode]) {
      // prefer the shorthand if there is one (BRSEZ -> BEQ)
      opcode = invertKv(BRANCH_INSTRUCTION_SHORTHANDS)[opcode];
    }

    let rel_address = machine_code[offset + 1];
    if (rel_address === undefined) {
      operand = '???'
    } else {
      if (rel_address > 0) {
        // always add +, since makes relativity clearer
        operand = '#+' + rel_address.toString();
      } else {
        operand = '#' + rel_address.toString();
      }
    }

    consumed += 1;
  } else if (di.family === -1) {
    opcode = invertKv(XOP)[di.operation];
    // TODO: undefined opcodes

    let decoded_operand = decode_operand(di, machine_code, offset);
    operand = stringify_operand(decoded_operand);
    consumed += decoded_operand.consumed;

    console.log('XOP di.operation',di.operation,XOP_TO_ADDR_MODE[di.operation]);
    if (XOP_TO_ADDR_MODE[opcode] !== undefined) {
      // some extended opcodes can disassemble to alu special addressing modes
      opcode = xop_operation_to_assembly_opcode_string(opcode);
    }
  }

  let asm;

  if (operand !== undefined) {
    asm = opcode + ' ' + operand;
  } else {
    asm = opcode;
  }

  return {asm, consumed};
}
function disasm1(machine_code, offset=0) {
  let di = decode_instruction(machine_code[offset]);

  let opcode, operand;
  let consumed = 1; // 1-tryte opcode, incremented later if operands

  if (di.family === 0) {
    opcode = invertKv(OP)[di.operation]; // inefficient lookup, but probably doesn't matter

    // note: some duplication with cpu read_alu_operand TODO: factor out
    // TODO: handle reading beyond end
    let decoded_operand = decode_operand(di, machine_code, offset);
    operand = stringify_operand(decoded_operand);
    consumed += decoded_operand.consumed;
  } else if (di.family === 1) {
    opcode = 'BR';
    opcode += invertKv(FLAGS)[di.flag];
    opcode += {'-1':'L', 0:'E', 1:'N'}[di.direction];
    opcode += {'-1':'N', 0:'Z', 1:'P'}[di.compare];

    if (invertKv(BRANCH_INSTRUCTION_SHORTHANDS)[opcode]) {
      // prefer the shorthand if there is one (BRSEZ -> BEQ)
      opcode = invertKv(BRANCH_INSTRUCTION_SHORTHANDS)[opcode];
    }

    let rel_address = machine_code[offset + 1];
    if (rel_address === undefined) {
      operand = '???'
    } else {
      if (rel_address > 0) {
        // always add +, since makes relativity clearer
        operand = '#+' + rel_address.toString();
      } else {
        operand = '#' + rel_address.toString();
      }
    }

    consumed += 1;
  } else if (di.family === -1) {
    opcode = invertKv(XOP)[di.operation];
    // TODO: undefined opcodes

    let decoded_operand = decode_operand(di, machine_code, offset);
    operand = stringify_operand(decoded_operand);
    consumed += decoded_operand.consumed;

    console.log('XOP di.operation',di.operation,XOP_TO_ADDR_MODE[di.operation]);
    if (XOP_TO_ADDR_MODE[opcode] !== undefined) {
      // some extended opcodes can disassemble to alu special addressing modes
      opcode = xop_operation_to_assembly_opcode_string(opcode);
    }
  }

  let asm;

  if (operand !== undefined) {
    asm = opcode + ' ' + operand;
  } else {
    asm = opcode;
  }

  return {asm, consumed};
}
function disasm1 ( machine_code , offset = 0 ) { let di = decode_instruction ( machine_code [ offset ] ) ; let opcode , operand ; let consumed = 1 ; // 1-tryte opcode, incremented later if operands if ( di . family === 0 ) { opcode = invertKv ( OP ) [ di . operation ] ; // inefficient lookup, but probably doesn't matter // note: some duplication with cpu read_alu_operand TODO: factor out // TODO: handle reading beyond end let decoded_operand = decode_operand ( di , machine_code , offset ) ; operand = stringify_operand ( decoded_operand ) ; consumed += decoded_operand . consumed ; } else if ( di . family === 1 ) { opcode = 'BR' ; opcode += invertKv ( FLAGS ) [ di . flag ] ; opcode += { '-1' : 'L' , 0 : 'E' , 1 : 'N' } [ di . direction ] ; opcode += { '-1' : 'N' , 0 : 'Z' , 1 : 'P' } [ di . compare ] ; if ( invertKv ( BRANCH_INSTRUCTION_SHORTHANDS ) [ opcode ] ) { // prefer the shorthand if there is one (BRSEZ -> BEQ) opcode = invertKv ( BRANCH_INSTRUCTION_SHORTHANDS ) [ opcode ] ; } let rel_address = machine_code [ offset + 1 ] ; if ( rel_address === undefined ) { operand = '???' } else { if ( rel_address > 0 ) { // always add +, since makes relativity clearer operand = '#+' + rel_address . toString ( ) ; } else { operand = '#' + rel_address . toString ( ) ; } } consumed += 1 ; } else if ( di . family === - 1 ) { opcode = invertKv ( XOP ) [ di . operation ] ; // TODO: undefined opcodes let decoded_operand = decode_operand ( di , machine_code , offset ) ; operand = stringify_operand ( decoded_operand ) ; consumed += decoded_operand . consumed ; console . log ( 'XOP di.operation' , di . operation , XOP_TO_ADDR_MODE [ di . operation ] ) ; if ( XOP_TO_ADDR_MODE [ opcode ] !== undefined ) { // some extended opcodes can disassemble to alu special addressing modes opcode = xop_operation_to_assembly_opcode_string ( opcode ) ; } } let asm ; if ( operand !== undefined ) { asm = opcode + ' ' + operand ; } else { asm = opcode ; } return { asm , consumed } ; }
Disassemble one instruction in machine_code
Disassemble one instruction in machine_code