package sim_8086 import "core:os" import "core:fmt" import "core:math" import "core:strings" get_operand_value :: proc(operand: Operand) -> u16 { #partial switch opr in operand { case Immediate: return opr.value case RegisterId: switch opr.access { case .Low, .High: val := opr.access == .Low ? registers[opr.id].value.low : registers[opr.id].value.high return u16(val) case .Full: return registers[opr.id].value.full } } return 0 } set_register_value :: proc(reg_id: RegisterId, value: u16) { switch reg_id.access { case .Low: registers[reg_id.id].value.low = u8(value) case .High: registers[reg_id.id].value.high = u8(value) case .Full: registers[reg_id.id].value.full = u16(value) } } check_zero_flag :: proc(value: u16) { CPU.flags.ZF = value == 0 } check_sign_flag :: proc(value: u16) { CPU.flags.SF = value >> 15 == 1 } execute_instruction :: proc(inst: Instruction) { if reg,ok := inst.dst.(RegisterId); ok { #partial switch inst.opname { case .MOV: src_val := get_operand_value(inst.src) set_register_value(reg, src_val) case .ADD: src_val := get_operand_value(inst.src) val := registers[reg.id].value.full + src_val set_register_value(reg, val) check_zero_flag(val) check_sign_flag(val) case .SUB: src_val := get_operand_value(inst.src) val := registers[reg.id].value.full - src_val set_register_value(reg, val) check_zero_flag(val) check_sign_flag(val) case .CMP: src_val := get_operand_value(inst.src) val := registers[reg.id].value.full - src_val check_zero_flag(val) check_sign_flag(val) } } }