#include "emulator.h" void add_eb_gb() { uint32_t addr = physical_addr(CS, IP); uint8_t modrm_byte = ram[addr]; IP++; ModRM modrm = parse_modrm(modrm_byte); uint8_t gb_value = get_reg_byte(modrm.reg); uint8_t eb_value; uint32_t eb_addr; bool eb_is_mem = false; if (modrm.mod == 3) { // eb is a reg eb_value = get_reg_byte(modrm.rm); } else { // eb is an addr uint32_t eff_addr = calc_effective_addr(modrm); uint16_t segment = (modrm.rm == 2 || modrm.rm == 3 || modrm.rm == 6) ? SS : DS; uint32_t phys_addr = physical_addr(segment, eff_addr); eb_value = ram[phys_addr]; eb_is_mem = true; } uint8_t result = eb_value + gb_value; if (eb_is_mem) { ram[eb_addr] = result; } else { set_reg_byte(modrm.rm, result); } update_flags_add(eb_value, gb_value, result); } void add_ev_gv() { uint32_t addr = physical_addr(CS, IP); uint8_t modrm_byte = ram[addr]; IP ++; ModRM modrm = parse_modrm(modrm_byte); uint16_t gv_value = get_reg_word(modrm.reg); uint16_t ev_value; uint32_t ev_addr; bool ev_is_mem = false; if (modrm.mod == 3) { ev_value = get_reg_word(modrm.rm); } else { uint16_t seg = (modrm.rm == 4 || modrm.rm == 5 || modrm.rm == 6) ? SS : DS; uint16_t eff_addr = calc_effective_addr(modrm); ev_addr = physical_addr(seg, eff_addr); ev_value = ram[ev_addr] | (ram[ev_addr + 1] << 8); ev_is_mem = true; } uint16_t result = ev_value + gv_value; if (ev_is_mem) { ram[ev_addr] = result & 0xFF; ram[ev_addr + 1] = result >> 8; } else { set_reg_word(modrm.rm, result); } update_flags_add16(ev_value, gv_value, result); std::cout << "AX = " << std::hex << AX.value << " (AL=" << (int)AX.low << ")\n"; } void hlt() { std::cout << "HLT\n"; exit(0); } using instrHandler = void(*)(); instrHandler instr_table[256] = { nullptr }; void init_instr_table() { instr_table[0x00] = add_eb_gb; instr_table[0x01] = add_ev_gv; instr_table[0xf4] = hlt; }