1 module dcpu16.asm_.decode; 2 3 import dcpu16.emulator: Memory; 4 import dcpu16.emulator.cpu; 5 6 pure: 7 8 private string explainRegisterOfOperand(ushort operand) 9 { 10 switch(operand) 11 { 12 case 0: return "A"; 13 case 1: return "B"; 14 case 2: return "C"; 15 case 3: return "X"; 16 case 4: return "Y"; 17 case 5: return "Z"; 18 case 6: return "I"; 19 case 7: return "J"; 20 default: assert(false); 21 } 22 } 23 24 private string explainOperand(in Memory mem, ref ushort pc, ushort operand, bool isA) pure 25 { 26 if(operand > 0x3f) 27 throw new Exception("Unknown operand "~operand.fmt, __FILE__, __LINE__); 28 29 switch(operand) 30 { 31 case 0x00: .. case 0x07: // register 32 return explainRegisterOfOperand(operand); 33 34 case 0x08: .. case 0x0f: // [register] 35 return "["~explainRegisterOfOperand(operand & 7)~"]"; 36 37 case 0x10: .. case 0x17: // [register + next word] 38 return "["~explainRegisterOfOperand(operand & 7)~" + "~mem[pc+1].fmt~"]"; 39 40 case 0x18: 41 return isA ? "POP" : "PUSH"; 42 43 case 0x19: 44 return "PEEK"; 45 46 case 0x1a: 47 return "PICK "~mem[pc+1].fmt; 48 49 case 0x1b: 50 return "SP"; 51 52 case 0x1c: 53 return "PC"; 54 55 case 0x1d: 56 return "EX"; 57 58 case 0x1e: // [next word] 59 return "["~mem[++pc].fmt~"]"; 60 61 case 0x1f: // next word (literal) 62 return mem[++pc].fmt; 63 64 default: // literal values 65 assert(isA, "Bigger than 5 bit b operand"); 66 operand -= 0x21; 67 return operand.fmt; 68 } 69 } 70 71 import std.string: format; 72 73 private string explainBasicInstruction(in Memory mem, ushort pc, in Instruction ins) 74 { 75 string a = explainOperand(mem, pc, ins.a, true); 76 string b = explainOperand(mem, pc, ins.b, false); 77 78 import std.conv: to; 79 80 return format("%s %s, %s", ins.basic_opcode.to!string, b, a); 81 } 82 83 private string explainSpecialInstruction(in Memory mem, ushort pc, in Instruction ins) 84 { 85 import std.conv: to; 86 87 string a = explainOperand(mem, pc, ins.a, true); 88 89 return format("%s %s", ins.spec_opcode.to!string, a); 90 } 91 92 private string fmt(T)(T v) 93 { 94 return format("%04#x", v); 95 } 96 97 string explainInstruction(in Memory mem, ushort pc, in Instruction ins) 98 { 99 if(!ins.isSpecialOpcode) 100 return explainBasicInstruction(mem, pc, ins); 101 else 102 return explainSpecialInstruction(mem, pc, ins); 103 }