Effective address movs work, but at what cost?

This commit is contained in:
Joseph Ferano 2025-03-21 20:47:42 +07:00
parent 3ca4059c44
commit da78d875c1

View File

@ -8,6 +8,20 @@ import "core:reflect"
get_ip :: proc(cpu: ^Cpu) -> int { return int(cpu.registers[.ip].full) }
get_effective_address_value :: proc(cpu: ^Cpu, id: u8) -> i16 {
switch id {
case 0: return cpu.registers[.bx].full + cpu.registers[.si].full
case 1: return cpu.registers[.bx].full + cpu.registers[.di].full
case 2: return cpu.registers[.bp].full + cpu.registers[.si].full
case 3: return cpu.registers[.bx].full + cpu.registers[.di].full
case 4: return cpu.registers[.si].full
case 5: return cpu.registers[.di].full
case 6: return cpu.registers[.bp].full
case 7: return cpu.registers[.bx].full
}
return -1
}
get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
#partial switch opr in operand {
case Immediate:
@ -23,6 +37,15 @@ get_operand_value :: proc(cpu: ^Cpu, operand: Operand) -> i16 {
case DirectAddress:
value := i16(u16(cpu.memory[opr+1] << 8) | u16(cpu.memory[opr]))
return value
case MemoryAddr:
idx := get_effective_address_value(cpu, opr.addr_id) + opr.displacement_value
value := i16(u16(cpu.memory[idx+1] << 8) | u16(cpu.memory[idx]))
// fmt.println("Checking", idx)
// for i in 0..<6 {
// fmt.printf("%04x ", cpu.memory[int(idx)-3+i])
// }
// fmt.println()
return value
}
return 0
}
@ -124,16 +147,25 @@ execute_instruction :: proc(cpu: ^Cpu, inst: Instruction) {
} else if mem_addr,ok := inst.dst.(MemoryAddr); ok {
#partial switch inst.opname {
case .MOV:
if imm,ok := inst.src.(Immediate); ok {
// TODO: We need a function that returns the registers to check out
addr := cpu.registers[.bx].full + mem_addr.displacement_value
if imm.size == .Signed16 {
cpu.memory[addr] = u8(imm.value & 0x00FF)
cpu.memory[addr+1] = u8((u16(imm.value) & 0xFF00) >> 8)
} else {
cpu.memory[addr] = u8(imm.value)
}
}
value := get_operand_value(cpu, inst.src)
effective_addr_val := get_effective_address_value(cpu, mem_addr.addr_id)
addr := effective_addr_val + mem_addr.displacement_value
cpu.memory[addr] = u8(value & 0x00FF)
cpu.memory[addr+1] = u8((u16(value) & 0xFF00) >> 8)
// TODO: We need a way to detect if it's a byte or a word
// if imm,ok := inst.src.(Immediate); ok {
// // TODO: We need a function that returns the registers to check out
// effective_addr_val := get_effective_address_value(cpu, mem_addr.addr_id)
// addr := effective_addr_val + mem_addr.displacement_value
// if imm.size == .Signed16 {
// cpu.memory[addr] = u8(imm.value & 0x00FF)
// cpu.memory[addr+1] = u8((u16(imm.value) & 0xFF00) >> 8)
// } else {
// cpu.memory[addr] = u8(imm.value)
// }
// }
}
} else if jmp_offset,ok := inst.src.(Jump); ok {
jump: bool