From 266f7a79004434526bc97088714805e700ba5faf Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 19 Mar 2025 21:10:22 +0700 Subject: [PATCH] Factor out get/set actions to reduce duplication, execute add,sub,cmp and check flags --- execution.odin | 84 +++++++++++++++++++++++++++++++---------------- sim8086.odin | 5 +++ test_registers.sh | 5 +++ types.odin | 10 ++++++ 4 files changed, 76 insertions(+), 28 deletions(-) diff --git a/execution.odin b/execution.odin index 89527aa..795d05e 100644 --- a/execution.odin +++ b/execution.odin @@ -5,36 +5,64 @@ 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) { - #partial switch inst.opname { + if reg,ok := inst.dst.(RegisterId); ok { + #partial switch inst.opname { case .MOV: - if reg_id,ok := inst.dst.(RegisterId); ok { - // val := registers[reg_id.id].value.full - #partial switch val in inst.src { - case Immediate: - if val.size == .Signed16 { - registers[reg_id.id].value.full = (u16)(val.value) - } else { - value := u8(val.value & 0xFF) - if reg_id.access == .Low { - registers[reg_id.id].value.low = value - } else { - registers[reg_id.id].value.high = value - } - } - case RegisterId: - switch val.access { - case .Low, .High: - value := val.access == .Low ? registers[val.id].value.low : registers[val.id].value.high - if reg_id.access == .Low { - registers[reg_id.id].value.low = value - } else { - registers[reg_id.id].value.high = value - } - case .Full: - registers[reg_id.id].value.full = registers[val.id].value.full - } - } + 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) } } } diff --git a/sim8086.odin b/sim8086.odin index 4e20b2c..4f8134a 100644 --- a/sim8086.odin +++ b/sim8086.odin @@ -30,6 +30,11 @@ registers := [?]Register { variable_port := registers[2] SEGMENT_REGISTER_START :: 8 + +CPU := Cpu { + memory = make([dynamic]u8, 65536) +} + // TODO: I don't like this here total_bytes_processed := 0 diff --git a/test_registers.sh b/test_registers.sh index 6370c9f..76549d1 100755 --- a/test_registers.sh +++ b/test_registers.sh @@ -19,5 +19,10 @@ do ./sim8086 asm_files/${asm_listing}.bin registers | awk '{print $1 $4}' | sort > temp1 cat $asm_txt | awk '/Final registers/,0' | tail -n +2 | awk '{print $1 $2}' | sort > temp2 diff -U0 --color temp1 temp2 + if [ $? -eq 1 ]; then + echo Listing $asm_listing Failed! + else + echo Listing $asm_listing Succeded! + fi done rm temp1 temp2 diff --git a/types.odin b/types.odin index c609df3..e432764 100644 --- a/types.odin +++ b/types.odin @@ -11,6 +11,11 @@ Register :: struct { code: u8, } +Flags :: struct { + ZF: bool, + SF: bool, +} + WordSize :: enum { None, LastBit, @@ -126,3 +131,8 @@ Instruction :: struct { raw_data: []u8, debug_msg: string, } + +Cpu :: struct { + flags: Flags, + memory: [dynamic]u8, +}