85 lines
2.5 KiB
Odin
85 lines
2.5 KiB
Odin
package sim_8086
|
|
|
|
import "core:os"
|
|
import path "core:path/filepath"
|
|
import "core:fmt"
|
|
import "core:math"
|
|
import "core:strings"
|
|
import "core:reflect"
|
|
|
|
CPU := Cpu {
|
|
memory = make([dynamic]u8, 65536),
|
|
}
|
|
|
|
main :: proc() {
|
|
f,err := os.open(os.args[1])
|
|
if err != os.ERROR_NONE {
|
|
fmt.eprintln("ERROR:", err)
|
|
os.exit(1)
|
|
}
|
|
defer os.close(f)
|
|
|
|
what_to_print := len(os.args) >= 3 ? os.args[2] : ""
|
|
|
|
data := make([]u8, 1024)
|
|
bytes_read, err2 := os.read(f, data)
|
|
if err2 != nil {
|
|
// ...
|
|
os.exit(1)
|
|
}
|
|
|
|
// asdf :u16 = 0b00000110_11011101
|
|
// asdf2 :i16 = (i16)(asdf)
|
|
// fmt.printfln("%d", asdf2)
|
|
print_at_end := false
|
|
line_count := 0
|
|
instruction_list := make([dynamic]string, 0, 512)
|
|
instructions_list := make([dynamic]Instruction, 0, 512)
|
|
|
|
decode_data(&instructions_list, data[:], bytes_read)
|
|
|
|
for inst in instructions_list {
|
|
execute_instruction(inst)
|
|
}
|
|
|
|
if what_to_print == "registers" || what_to_print == "all" {
|
|
fmt.println("Registers")
|
|
for reg_val,name in CPU.registers {
|
|
full := fmt.aprintf("%s: %d ", name, i16(reg_val.full))
|
|
hex := fmt.aprintf("0x%04x ", u16(reg_val.full))
|
|
fmt.printf("%s %*[1]s %s %*[4]s %08b %08b",
|
|
full, 18 - len(full), "|", hex, 10 - len(hex), "|", reg_val.high, reg_val.low)
|
|
fmt.println()
|
|
}
|
|
fmt.println("\nFlags")
|
|
for state,flag in CPU.flags {
|
|
fmt.printf("%c:%d ",reflect.enum_string(flag)[0], state ? 1 : 0)
|
|
}
|
|
fmt.println()
|
|
|
|
failed_ref: bool
|
|
path,ok := strings.replace(os.args[1], ".bin", ".txt", 1)
|
|
ref_cpu,_ := extract_reference_cpu_state(path)
|
|
for reg_val,name in ref_cpu.registers {
|
|
if CPU.registers[name].full != reg_val.full {
|
|
msg := "%s register does not match reference - Expected 0x%04x | Actual 0x%04x"
|
|
fmt.printfln(msg, name, reg_val.full, CPU.registers[name].full)
|
|
failed_ref = true
|
|
}
|
|
}
|
|
for f in Flag {
|
|
if ref_cpu.flags[f] != CPU.flags[f] {
|
|
msg := "%s flag does not match reference - Expected %d | Actual %d"
|
|
fmt.printfln(msg, f, ref_cpu.flags[f] ? 1 : 0, CPU.flags[f] ? 1 : 0)
|
|
failed_ref = true
|
|
}
|
|
}
|
|
if failed_ref {
|
|
os.exit(1)
|
|
}
|
|
}
|
|
if what_to_print == "instructions" || what_to_print == "all" {
|
|
print_instructions_stdout(instructions_list[:])
|
|
}
|
|
}
|