diff --git a/decoder8086.odin b/decoder8086.odin index bae618b..98ff8b9 100644 --- a/decoder8086.odin +++ b/decoder8086.odin @@ -17,40 +17,12 @@ Register :: struct { code: u8, } -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}, -} - -segment_registers := [4]Register { - {fullname = "es", code = 0b000}, - {fullname = "cs", code = 0b001}, - {fullname = "ss", code = 0b010}, - {fullname = "ds", code = 0b011}, -} - -variable_port := registers[2] - -total_bytes_processed := 0 - -RegInfo :: struct { - in_first_byte: bool, - shift_offset: u8, -} - WordSize :: enum { None, LastBit, FourthBit, Always8, Always16, - Unsigned8, } None :: struct {} @@ -63,26 +35,6 @@ Displacement :: union { Disp16 } -Value8 :: i8 -Value16 :: i16 -Data :: union { - None, - Value8, - Value16 -} - -ModMemory :: struct {} -Mod8BitDisp :: i8 -Mod16BitDisp :: i16 -ModRegister :: struct {} - -ModMode :: union { - ModMemory, - Mod8BitDisp, - Mod16BitDisp, - ModRegister, -} - RegisterId :: distinct u8 Immediate8 :: distinct i8 Immediate16 :: distinct i16 @@ -163,6 +115,30 @@ InstructionInfo :: struct { RIGHT_ALIGN_AMOUNT := 35 +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}, +} + +segment_registers := [4]Register { + {fullname = "es", code = 0b000}, + {fullname = "cs", code = 0b001}, + {fullname = "ss", code = 0b010}, + {fullname = "ds", code = 0b011}, +} + +variable_port := registers[2] + +total_bytes_processed := 0 + +instruction_builder := strings.builder_make() + get_i16 :: proc(data: []u8) -> i16 { return (i16)(data[1]) << 8 | (i16)(data[0]) } @@ -477,16 +453,12 @@ main :: proc() { // asdf2 :i16 = (i16)(asdf) // fmt.printfln("%d", asdf2) print_at_end := false - read_next := false - src_dst := true idx := 0 - added_label := false line_count := 0 has_lock: bool has_segment: Maybe(Register) last_opname: [3]byte repeating_op_count := 0 - instruction_builder := strings.builder_make() instruction_list := make([dynamic]string, 512) fmt.println("bits 16\n") for idx < bytes_read { @@ -540,17 +512,12 @@ main :: proc() { } opname: string - // TODO: Figure out a way to do this in the string builder if inst.check_second_encoding { - op,interseg := get_opname(inst.opname, data[idx:]) - indirect_intersegment = interseg - opname = strings.to_lower(fmt.aprintf("%s", op)) + opname,indirect_intersegment = get_opname(inst.opname, data[idx:]) // NOTE: This is a special case because it matches the bit pattern of .TBD5, // but the instruction itself is different if opname == "test" && (curr_byte & 0xFF) == 0b11110110 { inst = test_inst - // } else if opname == "neg" { - // inst = neg_inst } } else { opname = strings.to_lower(fmt.aprintf("%s", inst.opname)) diff --git a/instructions.odin b/instructions.odin index ad8f180..f556adf 100644 --- a/instructions.odin +++ b/instructions.odin @@ -96,6 +96,10 @@ OpName :: enum { JCXZ, } +// TODO: We should figure out another way of handling this case. The way we're doing it +// isn't that great; we return a string with the instruction name, but ideally we have all +// the instructions accounted for, because eventually we will need the final parsed +// instruction to contain all the information related to it test_inst := InstructionInfo { opname = .NOT, desc = "", mask = 0b11111110, encoding = 0b11110110, dst = .RegisterMemory, src = .Immediate, word_size = .LastBit @@ -170,12 +174,7 @@ instructions := [?]InstructionInfo { dst = .Accumulator, src = .Register, reg_info = .FirstByteLast3, has_flip = true, word_size = .Always16 }, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11100100, - dst = .Accumulator, src = .ImmediateUnsigned, - // TODO: Everything works just fine, but the problem here is that if you want it to - // show up as an unsigned int, then we have to change the types because the number - // 200, for instance, will show up as a negative, we would have to create an unsigned - // variant of the Immediate value. Maybe we can have the value and the sign as a struct - word_size = .Unsigned8, }, + dst = .Accumulator, src = .ImmediateUnsigned }, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11101100, dst = .Accumulator, src = .VariablePort, word_size = .LastBit, }, @@ -236,7 +235,6 @@ instructions := [?]InstructionInfo { { opname = .STI, desc = "", mask = 0b11111111, encoding = 0b11111011,}, { opname = .HLT, desc = "", mask = 0b11111111, encoding = 0b11110100,}, { opname = .WAIT, desc = "", mask = 0b11111111, encoding = 0b10011011,}, - // { opname = .ESC, desc = "", mask = 0b11111111, encoding = 0b11111000, dst = }, { opname = .LOCK, desc = "", mask = 0b11111111, encoding = 0b11110000,}, { opname = .SEGMENT, desc = "", mask = 0b11100111, encoding = 0b00100110,}, { opname = .CALL, desc = "", mask = 0b11111111, encoding = 0b10011010, src = .Intersegment },