Segment register for memory addresses and lock string

This commit is contained in:
Joseph Ferano 2025-03-12 11:31:14 +07:00
parent 8967be44a0
commit babb07cb43

View File

@ -97,7 +97,8 @@ Immediate8 :: distinct i8
Immediate16 :: distinct i16
MemoryAddr :: struct {
addr_id: u8,
displacement: Displacement
displacement: Displacement,
segment: Maybe(Register),
}
DirectAddress :: distinct i16
SegmentRegister :: distinct i8
@ -194,35 +195,12 @@ get_memory_string :: proc(memoryAddr: MemoryAddr) -> string {
disp = fmt.aprintf(" %s %d", value > 0 ? "+" : "-", math.abs(value))
}
}
text := fmt.aprintf("[%s%s]", calculate_effective_address(memoryAddr.addr_id), disp)
return text
}
get_operand_string :: proc(operand: Operand, is_word: bool) -> string {
string_val: string
switch val in operand {
case None:
string_val = ""
case RegisterId:
string_val = is_word ? registers[val].fullname : registers[val].bytename
case Immediate8:
string_val = fmt.aprintf("%d", val)
case Immediate16:
string_val = fmt.aprintf("%d", val)
case MemoryAddr:
string_val = get_memory_string(val)
case DirectAddress:
string_val = fmt.aprintf("[%d]", val)
case SegmentRegister:
string_val = segment_registers[val].fullname
case Jump:
string_val = fmt.aprintf("$%s%d", val >= 0 ? "+" : "", val)
case VariablePort:
string_val = variable_port.fullname
case Repeat:
string_val = (string)(val)
seg_string: string
if segreg, ok := memoryAddr.segment.?; ok {
seg_string = fmt.aprintf("%s:", segreg.fullname)
}
return string_val
text := fmt.aprintf("%s[%s%s]", seg_string, calculate_effective_address(memoryAddr.addr_id), disp)
return text
}
get_i16 :: proc(data: []u8) -> i16 {
@ -336,7 +314,7 @@ get_opname :: proc(opname: OpName, data: []u8) -> string {
return name
}
parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, processed: ^int, word: bool) -> Operand {
parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, processed: ^int, word: bool, has_segreg: Maybe(Register)) -> Operand {
operand: Operand = None{}
switch opinfo {
case .None:
@ -383,13 +361,13 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
op = (DirectAddress)(get_i16(data[2:]))
processed^ += 2
} else {
op = MemoryAddr{ addr_id = rm , displacement = None{} }
op = MemoryAddr{ addr_id = rm , displacement = None{} , segment = has_segreg }
}
} else if mod == 1 {
op = MemoryAddr{ addr_id = rm , displacement = (i8)(data[2]) }
op = MemoryAddr{ addr_id = rm , displacement = (i8)(data[2]) , segment = has_segreg }
processed^ += 1
} else if mod == 2 {
op = MemoryAddr{ addr_id = rm , displacement = get_i16(data[2:]) }
op = MemoryAddr{ addr_id = rm , displacement = get_i16(data[2:]) , segment = has_segreg }
processed^ += 2
} else if mod == 3 {
op = (RegisterId)(registers[rm].code)
@ -424,6 +402,33 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
return operand
}
get_operand_string :: proc(operand: Operand, is_word: bool) -> string {
string_val: string
switch val in operand {
case None:
string_val = ""
case RegisterId:
string_val = is_word ? registers[val].fullname : registers[val].bytename
case Immediate8:
string_val = fmt.aprintf("%d", val)
case Immediate16:
string_val = fmt.aprintf("%d", val)
case MemoryAddr:
string_val = get_memory_string(val)
case DirectAddress:
string_val = fmt.aprintf("[%d]", val)
case SegmentRegister:
string_val = segment_registers[val].fullname
case Jump:
string_val = fmt.aprintf("$%s%d", val >= 0 ? "+" : "", val)
case VariablePort:
string_val = variable_port.fullname
case Repeat:
string_val = (string)(val)
}
return string_val
}
main :: proc() {
f,err := os.open(os.args[1])
if err != os.ERROR_NONE {
@ -452,7 +457,7 @@ main :: proc() {
added_label := false
line_count := 0
has_lock: bool
has_segment: bool
has_segment: Maybe(Register)
last_opname: [3]byte
repeating_op_count := 0
instruction_builder := strings.builder_make()
@ -482,11 +487,11 @@ main :: proc() {
idx += 1
continue
} else if inst.opname == .SEGMENT {
has_segment = true
reg := (curr_byte & 0b11000) >> 3
has_segment = segment_registers[reg]
idx += 1
continue
}
has_segment = false
src_opr: Operand
dst_opr: Operand
@ -518,8 +523,8 @@ main :: proc() {
opname = strings.to_lower(fmt.aprintf("%s", inst.opname))
}
dst_opr = parse_operand(inst, inst.dst, data[idx:], &processed, word)
src_opr = parse_operand(inst, inst.src, data[idx:], &processed, word)
dst_opr = parse_operand(inst, inst.dst, data[idx:], &processed, word, has_segment)
src_opr = parse_operand(inst, inst.src, data[idx:], &processed, word, has_segment)
// TODO: This is ugly as hell
_,ok_1 := src_opr.(Immediate8)
@ -558,8 +563,11 @@ main :: proc() {
processed += inst.consume_extra_bytes
// fmt.sbprintf(&instruction_builder, "%s%s%s %*[2]s", lock_string, seg_string, full_inst, RIGHT_ALIGN_AMOUNT - len(full_inst), ";;")
fmt.sbprintf(&instruction_builder, "%s %*[1]s", full_inst, RIGHT_ALIGN_AMOUNT - len(full_inst), ";;")
lock_string: string
if has_lock {
lock_string = "lock "
}
fmt.sbprintf(&instruction_builder, "%s%s %*[2]s", lock_string, full_inst, RIGHT_ALIGN_AMOUNT - len(full_inst), ";;")
for i in 0..<processed {
fmt.sbprintf(&instruction_builder, " %08b", data[idx + i])
}
@ -578,6 +586,8 @@ main :: proc() {
idx += processed
strings.builder_reset(&instruction_builder)
has_lock = false
has_segment = nil
}
if print_at_end {
for i in 0..<line_count {