diff --git a/decode.c b/decode.c index e28eaf7..ef81c69 100644 --- a/decode.c +++ b/decode.c @@ -52,6 +52,43 @@ char* memory[65536]; // void inst_mov_rgmm_reg() +/// Get Effective Address Calculation Registers +char* get_eac_registers(char rm) +{ + char *reg_name; + switch (rm) + { + case 0b000: + reg_name = "bx + si"; + break; + case 0b001: + reg_name = "bx + di"; + break; + case 0b010: + reg_name = "bp + si"; + break; + case 0b011: + reg_name = "bp + di"; + break; + case 0b100: + reg_name = "si"; + break; + case 0b101: + reg_name = "di"; + break; + case 0b110: + reg_name = "bp"; + break; + case 0b111: + reg_name = "bx"; + break; + default: + perror("Invalid R/M value"); + exit(1); + } + return reg_name; +} + int main(int argc, char** argv) { if (argc < 2) @@ -108,34 +145,7 @@ int main(int argc, char** argv) { dst_name = w == 1 ? src_reg.fullname : src_reg.bytename; } - char* src_name; - switch (rm) - { - case 0b000: - src_name = "bx + si"; - break; - case 0b001: - src_name = "bx + di"; - break; - case 0b010: - src_name = "bp + si"; - break; - case 0b011: - src_name = "bp + di"; - break; - case 0b100: - src_name = "si"; - break; - case 0b101: - src_name = "di"; - break; - case 0b110: - src_name = "bp"; - break; - case 0b111: - src_name = "bx"; - break; - } + char* src_name = get_eac_registers(rm); if (mod == MODE_MEM_DIS_16) { bytes_read = fread(buf, sizeof(char), 2, f); @@ -148,10 +158,6 @@ int main(int argc, char** argv) { printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w); } - char disp_lo = buf[0]; - char disp_hi = buf[1]; - (void)disp_lo; - (void)disp_hi; } else if (mod == MODE_MEM_DIS_08) { @@ -181,7 +187,22 @@ int main(int argc, char** argv) // Immediate to register/memory else if ((inst & ~0x1) == (char)0b11000110) { - printf("mov imm to reg/mem"); + char w = inst & 0b00000001; + bytes_read = fread(buf, sizeof(char), 1, f); + char mod = (buf[0] & 0b11000000) >> 6; + char rm = (buf[0] & 0b00000111); + int bytes_to_read = 1; + bytes_to_read += w == 0 ? 0 : 1; + // This is a trick because mod == 1 and mod == 2 will displace one and two bytes + // respectively but mod == 3 wraps to 0 since it doesn't displace + bytes_to_read += mod % 3; + bytes_read = fread(buf, sizeof(char), bytes_to_read, f); + char *eac_name = get_eac_registers(rm); + char *data_ptr = (char*)buf + (char)bytes_to_read - (w == 0 ? 1 : 2); + i16 data = w == 0 ? data_ptr[0] : (i16)data_ptr[1] << 8 | data_ptr[0]; + char *word = w == 0 ? "byte" : "word"; + char *disp = mod == 1 || mod == 2 ? sprintf(); + printf("mov [%s], %s %d w %d mod %d rm %d", eac_name, word, data, w, mod, rm); } // Immediate to register else if ((inst & ~0xF) == (char)0b10110000)