package sim_8086 import "core:os" import "core:fmt" import "core:math" import "core:strings" import "core:reflect" get_operand_value :: proc(operand: Operand) -> u16 { #partial switch opr in operand { case Immediate: return opr.value case RegisterId: reg_val := CPU.registers[opr.idx] switch opr.access { case .Low, .High: return u16(opr.access == .Low ? reg_val.low : reg_val.high) case .Full: return reg_val.full } } return 0 } set_register_value :: proc(reg: RegisterId, value: u16) { switch reg.access { case .Low: CPU.registers[reg.idx].low = u8(value) case .High: CPU.registers[reg.idx].high = u8(value) case .Full: CPU.registers[reg.idx].full = u16(value) } } get_cpu_register_by_name :: proc(cpu: ^Cpu, name: string) -> ^RegisterValue { reg,_ := reflect.enum_from_name(Register, name) return &cpu.registers[int(reg)] } 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 := CPU.registers[reg.idx].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 := CPU.registers[reg.idx].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 := CPU.registers[reg.idx].full - src_val check_zero_flag(val) check_sign_flag(val) } } }