package sim_8086 Register :: enum { ax, cx, dx, bx, sp, bp, si, di, es, cs, ss, ds, ip, } RegisterValue :: struct #raw_union { using _: struct { low, high: byte, }, full: i16, } Flag :: enum { OF, SF, ZF, AF, PF, CF, // NOTE: These are the control flags, previous are status flags, justing noting in // case we have to make that distinction in later modeling TF, DF, IF, } WordSize :: enum { None, LastBit, FourthBit, Always8, Always16, } None :: struct {} RegisterAccess :: enum { Full, Low, High, } RegisterId :: struct { name: Register, access: RegisterAccess, } ImmediateSize :: enum { Signed8, Unsigned8, Signed16, } Immediate :: struct { value: i16, size: ImmediateSize, } MemoryAddr :: struct { addr_id: u8, displacement_value: i16, displacement_size: ImmediateSize, } DirectAddress :: distinct i16 Jump :: distinct i8 Repeat :: string Intersegment :: struct { ip: i16, cs: i16, } Operand :: union { None, RegisterId, Immediate, MemoryAddr, DirectAddress, Jump, Repeat, Intersegment, } OperandInfo :: enum { None, Register, SegmentRegister, RegisterMemory, Immediate, ImmediateUnsigned, Accumulator, DirectAddress, Jump, VariablePort, ShiftRotate, Repeat, DirectWithinSegment, Intersegment, } RegisterEncodingBits :: enum { None, FirstByteLast3, SecondByteMiddle3, SecondByteLast3, FirstByteMiddle3, } InstructionInfo :: struct { mask: u8, encoding: u8, opname: Op, desc: string, src: OperandInfo, dst: OperandInfo, word_size: WordSize, reg_info: RegisterEncodingBits, has_flip: bool, has_sign_extension: bool, check_second_encoding: bool, consume_extra_bytes: int, shift_rotate_flag: bool, } Instruction :: struct { opname: Op, src: Operand, dst: Operand, info: InstructionInfo, is_word: bool, indirect_intersegment: bool, // TODO: This is trickier than I thought, it's more than just the one instruction // that uses it has_segment: Maybe(RegisterId), has_lock: bool, bytes_read: int, segment_offset: int, raw_data: []u8, debug_msg: string, } DecodedInstructions :: struct { inst_list: [dynamic]Instruction, inst_map: map[int]Instruction, total_bytes_decoded: int } Cpu :: struct { flags: [Flag]bool, registers: [Register]RegisterValue, memory: [dynamic]u8, }