package decoder_8086 import "core:os" import "core:fmt" Register :: struct { fullname: string, bytename: string, value: struct #raw_union { using _: struct { low, high: byte, }, full: u16, }, code: u8, } RegMemMode :: enum { Memory00 = 0b00, Memory08 = 0b01, Memory16 = 0b10, Register = 0b11, }; registers := [8]Register { {fullname = "ax", bytename = "al", code = 0b000}, {fullname = "cx", bytename = "cl", code = 0b001}, {fullname = "dx", bytename = "dl", code = 0b010}, {fullname = "bx", bytename = "bl", code = 0b011}, {fullname = "sp", bytename = "ah", code = 0b100}, {fullname = "bp", bytename = "ch", code = 0b101}, {fullname = "si", bytename = "dh", code = 0b110}, {fullname = "di", bytename = "bh", code = 0b111}, } Instruction :: struct { mask: u8, encoding: u8, name: string, desc: string, } instructions := [?]Instruction { { mask = 0b11111100, encoding = 0b10001000, name = "mov", desc = "Register/memory to/from register" }, { mask = 0b11111110, encoding = 0b11000110, name = "mov", desc = "Immediate to register/memory" }, { mask = 0b11110000, encoding = 0b10110000, name = "mov", desc = "Immediate to register" }, { mask = 0b11111110, encoding = 0b10100000, name = "mov", desc = "Memory to accumulator" }, { mask = 0b11111110, encoding = 0b10100010, name = "mov", desc = "Accumulator to memory" }, { mask = 0b11111111, encoding = 0b10001110, name = "mov", desc = "Register/memory to segment register" }, { mask = 0b11111111, encoding = 0b10001100, name = "mov", desc = "Segment register to register/memory" }, } inst_map := make(map[u8]Instruction) main :: proc() { ax := registers[0] ax.value.full = 52428 f,err := os.open(len(os.args) > 1 ? os.args[1] : "./asm_files/01-02-39.bin") if err != os.ERROR_NONE { os.exit(1) } defer os.close(f) data := make([]u8, 512) bytes_read, err2 := os.read(f, data) if err2 != nil { // ... os.exit(1) } for inst in instructions { inst_map[inst.encoding] = inst } if true { for i in 0..> 6 reg := (b & 0b00111000) >> 3 rm := b & 0b00000111 src_name := is_word ? registers[reg].fullname : registers[reg].bytename dst_name := is_word ? registers[rm].fullname : registers[rm].bytename fmt.printfln("mov %s, %s ;; %b %b", dst_name, src_name, prev, b) read_next = false continue } if b == 0b10001001 { read_next = true is_word = true } else if b == 0b10001000 { read_next = true is_word = false } prev = b } }