+/* split a word into the parts of an instruction, and determine how many words it takes up in total */
+static inline
+void instruction_decode_(struct dcpu16 *d, WORD addr, WORD *opcode, WORD *a, WORD *b, unsigned int *instr_len) {
+ *opcode = d->ram[addr] & ((1 << OPCODE_BASIC_BITS) - 1);
+ *a = (d->ram[addr] >> OPCODE_BASIC_BITS) & ((1 << 6) - 1);
+ *b = (d->ram[addr] >> (OPCODE_BASIC_BITS + 6)) & ((1 << 6) - 1);
+ *instr_len = 1;
+ /* both basic and nbi opcodes use their b operand */
+ if ( (*b >= 0x10 && *b <= 0x17) || *b == 0x1e || *b == 0x1f )
+ *instr_len += 1;
+ /* but only basic uses a */
+ if (*opcode
+ && ((*a >= 0x10 && *a <= 0x17) || *a == 0x1e || *a == 0x1f) )
+ *instr_len += 1;
+}
+
+/* dcpu16_disassemble_print
+ print the words of the instruction at addr, followed by its assembly
+ 7c01 0030 ; SET A,
+ 7de1 1000 0020 ; SET [0x1000], 0x0020
+ 7803 1000 ; SUB A,
+ c00d ; IFN A,
+ */
+WORD dcpu16_disassemble_print(struct dcpu16 *d, WORD addr) {