diff --git a/src/arm/cpu/arm/block_data_transfer.zig b/src/arm/cpu/arm/block_data_transfer.zig index 6c9a8f1..574fd3d 100644 --- a/src/arm/cpu/arm/block_data_transfer.zig +++ b/src/arm/cpu/arm/block_data_transfer.zig @@ -111,10 +111,13 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b cpu.r[i] = value; if (i == 0xF) { - cpu.r[i] &= ~@as(u32, 3); // Align r15 - cpu.pipe.reload(cpu); + const mask: u32 = if (Arm32.arch == .v5te) 1 else 3; + cpu.r[i] &= ~mask; - if (S) cpu.setCpsr(cpu.spsr.raw); + if (Arm32.arch == .v5te) cpu.cpsr.t.write(value & 1 == 1); + if (S) cpu.setCpsr(cpu.spsr.raw); // FIXME: before or after the reload? + + cpu.pipe.reload(cpu); } } } else { diff --git a/src/arm/cpu/arm/single_data_transfer.zig b/src/arm/cpu/arm/single_data_transfer.zig index 6d8520e..41121a7 100644 --- a/src/arm/cpu/arm/single_data_transfer.zig +++ b/src/arm/cpu/arm/single_data_transfer.zig @@ -49,7 +49,15 @@ pub fn singleDataTransfer(comptime InstrFn: type, comptime I: bool, comptime P: if (L) { // This emulates the LDR rd == rn behaviour cpu.r[rd] = result; - if (rd == 0xF) cpu.pipe.reload(cpu); + + if (rd == 0xF) { + if (Arm32.arch == .v5te) { + cpu.r[rd] &= ~@as(u32, 1); + cpu.cpsr.t.write(result & 1 == 1); + } + + cpu.pipe.reload(cpu); + } } } }.inner; diff --git a/src/arm/cpu/thumb/block_data_transfer.zig b/src/arm/cpu/thumb/block_data_transfer.zig index 18d49da..60a1441 100644 --- a/src/arm/cpu/thumb/block_data_transfer.zig +++ b/src/arm/cpu/thumb/block_data_transfer.zig @@ -32,6 +32,8 @@ pub fn fmt14(comptime InstrFn: type, comptime L: bool, comptime R: bool) InstrFn if (L) { const value = cpu.read(u32, address); cpu.r[15] = value & ~@as(u32, 1); + + if (Arm32.arch == .v5te) cpu.cpsr.t.write(value & 1 == 1); cpu.pipe.reload(cpu); } else { cpu.write(u32, address, cpu.r[14]);