From da78d875c1bdccd5a6eae12cb4fdfea38dad826a Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Fri, 21 Mar 2025 20:47:42 +0700 Subject: [PATCH] Effective address movs work, but at what cost? --- execution.odin | 52 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/execution.odin b/execution.odin index ad551e8..4cbb5ce 100644 --- a/execution.odin +++ b/execution.odin @@ -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