diff --git a/decoding.odin b/decoding.odin index 06e78c7..32b5bcf 100644 --- a/decoding.odin +++ b/decoding.odin @@ -4,6 +4,8 @@ import "core:fmt" import "core:math" import "core:strings" +SEGMENT_REGISTER_START :: 8 + get_i16 :: proc(data: []u8) -> i16 { return (i16)(data[1]) << 8 | (i16)(data[0]) } @@ -201,7 +203,7 @@ decode_data :: proc(inst_list: ^[dynamic]Instruction, data: []u8, bytes_to_read: continue } else if inst.opname == .SEGMENT { reg := (curr_byte & 0b11000) >> 3 - has_segment = registers[SEGMENT_REGISTER_START+reg] + has_segment = CPU.registers[SEGMENT_REGISTER_START+reg] idx += 1 continue } else if inst.opname == .AAM { diff --git a/execution.odin b/execution.odin index 795d05e..94cd283 100644 --- a/execution.odin +++ b/execution.odin @@ -12,10 +12,10 @@ get_operand_value :: proc(operand: Operand) -> u16 { case RegisterId: switch opr.access { case .Low, .High: - val := opr.access == .Low ? registers[opr.id].value.low : registers[opr.id].value.high + val := opr.access == .Low ? CPU.registers[opr.id].value.low : CPU.registers[opr.id].value.high return u16(val) case .Full: - return registers[opr.id].value.full + return CPU.registers[opr.id].value.full } } return 0 @@ -24,11 +24,11 @@ get_operand_value :: proc(operand: Operand) -> u16 { set_register_value :: proc(reg_id: RegisterId, value: u16) { switch reg_id.access { case .Low: - registers[reg_id.id].value.low = u8(value) + CPU.registers[reg_id.id].value.low = u8(value) case .High: - registers[reg_id.id].value.high = u8(value) + CPU.registers[reg_id.id].value.high = u8(value) case .Full: - registers[reg_id.id].value.full = u16(value) + CPU.registers[reg_id.id].value.full = u16(value) } } @@ -48,19 +48,19 @@ execute_instruction :: proc(inst: Instruction) { set_register_value(reg, src_val) case .ADD: src_val := get_operand_value(inst.src) - val := registers[reg.id].value.full + src_val + val := CPU.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 + val := CPU.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 + val := CPU.registers[reg.id].value.full - src_val check_zero_flag(val) check_sign_flag(val) } diff --git a/printing.odin b/printing.odin index 9da9bb8..9282772 100644 --- a/printing.odin +++ b/printing.odin @@ -78,7 +78,7 @@ get_register_name :: proc(reg_id: RegisterId) -> string { low_names := [?]string{"al", "cl", "dl", "bl"} high_names := [?]string{"ah", "ch", "dh", "bh"} switch reg_id.access { - case .Full: return registers[reg_id.id].fullname + case .Full: return CPU.registers[reg_id.id].fullname case .Low: return low_names[reg_id.id] case .High: return high_names[reg_id.id % 4] } diff --git a/sim8086.odin b/sim8086.odin index af61fc2..19891b2 100644 --- a/sim8086.odin +++ b/sim8086.odin @@ -1,33 +1,32 @@ package sim_8086 import "core:os" +import "core:path" import "core:fmt" import "core:math" import "core:strings" -registers := [?]Register { - {fullname = "ax", code = 0b000}, - {fullname = "cx", code = 0b001}, - {fullname = "dx", code = 0b010}, - {fullname = "bx", code = 0b011}, - {fullname = "sp", code = 0b100}, - {fullname = "bp", code = 0b101}, - {fullname = "si", code = 0b110}, - {fullname = "di", code = 0b111}, - {fullname = "es", code = 0b000}, - {fullname = "cs", code = 0b001}, - {fullname = "ss", code = 0b010}, - {fullname = "ds", code = 0b011}, -} - -variable_port := registers[2] - -SEGMENT_REGISTER_START :: 8 - CPU := Cpu { - memory = make([dynamic]u8, 65536) + registers = [12]Register { + {fullname = "ax", code = 0b000}, + {fullname = "cx", code = 0b001}, + {fullname = "dx", code = 0b010}, + {fullname = "bx", code = 0b011}, + {fullname = "sp", code = 0b100}, + {fullname = "bp", code = 0b101}, + {fullname = "si", code = 0b110}, + {fullname = "di", code = 0b111}, + {fullname = "es", code = 0b000}, + {fullname = "cs", code = 0b001}, + {fullname = "ss", code = 0b010}, + {fullname = "ds", code = 0b011}, + }, + memory = make([dynamic]u8, 65536), } +variable_port := CPU.registers[2] + + main :: proc() { f,err := os.open(os.args[1]) if err != os.ERROR_NONE { @@ -67,9 +66,15 @@ main :: proc() { full, 18 - len(full), "|", hex, 10 - len(hex), "|", reg.value.high, reg.value.low) fmt.println() } - for reg in registers { + for reg in CPU.registers { print_reg(reg) } + // fmt.println("Checking Against Expected State") + + // fmt.println(os.args[1]) + // path := path.base_no_ext(os.args[1]) + // fmt.println(path) + // extract_expected_cpu_state(path) } if what_to_print == "instructions" || what_to_print == "all" { print_instructions_stdout(instructions_list[:]) diff --git a/testing.odin b/testing.odin new file mode 100644 index 0000000..ee6a34e --- /dev/null +++ b/testing.odin @@ -0,0 +1,38 @@ +package sim_8086 + +import "core:os" +import "core:fmt" +import "core:math" +import "core:strings" +import "core:text/regex" + +extract_expected_cpu_state :: proc(listing_num: int) -> (Cpu, bool) { + cpu: Cpu + + // filename := fmt.aprintf("./asm_files/list-%04d.txt", listing_num) + // fmt.println(filename) + // data,ok := os.read_entire_file(filename) + // if !ok { + // return cpu, false + // } + // defer delete(data) + + // content := string(data) + // lines := strings.split(content, "\n") + // defer delete(lines) + + // for line in lines { + // for c in line { + // if c != ' ' { + // continue + // } else { + // fmt.print(c) + // } + // } + // fmt.println() + // } + + + // cpu.registers[] + return cpu, true +} diff --git a/types.odin b/types.odin index d7ade7f..10cec11 100644 --- a/types.odin +++ b/types.odin @@ -134,6 +134,7 @@ Instruction :: struct { Cpu :: struct { flags: Flags, + registers: [12]Register, memory: [dynamic]u8, total_bytes_processed: int }