From 7f6ab626d9abfa7638c456ba07b03e7d6c66ae4a Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 14 Jan 2022 03:43:03 -0400 Subject: [PATCH] fix(cpu): resolve off-by-one error when executing LDM --- src/cpu/block_data_transfer.zig | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/cpu/block_data_transfer.zig b/src/cpu/block_data_transfer.zig index 638043f..1ca46a1 100644 --- a/src/cpu/block_data_transfer.zig +++ b/src/cpu/block_data_transfer.zig @@ -12,9 +12,10 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c if (S and opcode >> 15 & 1 == 0) std.debug.panic("[CPU] TODO: STM/LDM with S set but R15 not in transfer list", .{}); + var address: u32 = undefined; if (U) { // Increment - var address = if (P) base + 4 else base; + address = if (P) base + 4 else base; var i: u5 = 0; while (i < 0x10) : (i += 1) { @@ -23,24 +24,22 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c address += 4; } } - - if (W and P or !P) cpu.r[rn] = address - 4; } else { // Decrement - var address = if (P) base - 4 else base; + address = if (P) base - 4 else base; var i: u5 = 0x10; while (i > 0) : (i -= 1) { - const reg_idx = i - 1; + const j = i - 1; - if (opcode >> reg_idx & 1 == 1) { - transfer(cpu, bus, reg_idx, address); + if (opcode >> j & 1 == 1) { + transfer(cpu, bus, j, address); address -= 4; } } - - if (W and P or !P) cpu.r[rn] = address + 4; } + + if (W and P or !P) cpu.r[rn] = if (U) address else address + 4; } fn transfer(cpu: *Arm7tdmi, bus: *Bus, i: u5, address: u32) void {