diff --git a/src/cpu/arm/data_processing.zig b/src/cpu/arm/data_processing.zig index 597ab68..e34114a 100644 --- a/src/cpu/arm/data_processing.zig +++ b/src/cpu/arm/data_processing.zig @@ -67,39 +67,31 @@ pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime instrKind: u4 }, 0x8 => { // TST - if (rd == 0xF) { - undefinedTestBehaviour(cpu); - return; - } + if (rd == 0xF) + return undefinedTestBehaviour(cpu); const result = op1 & op2; setTestOpFlags(S, cpu, opcode, result); }, 0x9 => { // TEQ - if (rd == 0xF) { - undefinedTestBehaviour(cpu); - return; - } + if (rd == 0xF) + return undefinedTestBehaviour(cpu); const result = op1 ^ op2; setTestOpFlags(S, cpu, opcode, result); }, 0xA => { // CMP - if (rd == 0xF) { - undefinedTestBehaviour(cpu); - return; - } + if (rd == 0xF) + return undefinedTestBehaviour(cpu); cmp(cpu, op1, op2); }, 0xB => { // CMN - if (rd == 0xF) { - undefinedTestBehaviour(cpu); - return; - } + if (rd == 0xF) + return undefinedTestBehaviour(cpu); cmn(cpu, op1, op2); }, diff --git a/src/cpu/thumb/block_data_transfer.zig b/src/cpu/thumb/block_data_transfer.zig index 8596bc8..0275488 100644 --- a/src/cpu/thumb/block_data_transfer.zig +++ b/src/cpu/thumb/block_data_transfer.zig @@ -33,7 +33,8 @@ pub fn format14(comptime L: bool, comptime R: bool) InstrFn { if (R) { if (L) { const value = bus.read(u32, address); - cpu.r[15] = value & 0xFFFF_FFFE; + cpu.r[15] = value & ~@as(u32, 1); + cpu.pipe.flush(); } else { bus.write(u32, address, cpu.r[14]); } @@ -52,7 +53,13 @@ pub fn format15(comptime L: bool, comptime rb: u3) InstrFn { const end_address = cpu.r[rb] + 4 * countRlist(opcode); if (opcode & 0xFF == 0) { - if (L) cpu.r[15] = bus.read(u32, address) else bus.write(u32, address, cpu.r[15] + 4); + if (L) { + cpu.r[15] = bus.read(u32, address); + cpu.pipe.flush(); + } else { + bus.write(u32, address, cpu.r[15] + 2); + } + cpu.r[rb] += 0x40; return; } diff --git a/src/cpu/thumb/data_processing.zig b/src/cpu/thumb/data_processing.zig index 0fdc653..359af59 100644 --- a/src/cpu/thumb/data_processing.zig +++ b/src/cpu/thumb/data_processing.zig @@ -99,14 +99,13 @@ pub fn format3(comptime op: u2, comptime rd: u3) InstrFn { }.inner; } -pub fn format12(comptime isSP: bool, comptime rd: u3) InstrFn { +pub fn format12(comptime SP: bool, comptime rd: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { // ADD - const left = if (isSP) cpu.r[13] else (cpu.r[15] + 2) & 0xFFFF_FFFD; + const left = if (SP) cpu.r[13] else cpu.r[15] & ~@as(u32, 2); const right = (opcode & 0xFF) << 2; - const result = left + right; - cpu.r[rd] = result; + cpu.r[rd] = left + right; } }.inner; } diff --git a/src/cpu/thumb/processing_branch.zig b/src/cpu/thumb/processing_branch.zig index c41d75a..f7ab769 100644 --- a/src/cpu/thumb/processing_branch.zig +++ b/src/cpu/thumb/processing_branch.zig @@ -11,19 +11,22 @@ pub fn format5(comptime op: u2, comptime h1: u1, comptime h2: u1) InstrFn { const src_idx = @as(u4, h2) << 3 | (opcode >> 3 & 0x7); const dst_idx = @as(u4, h1) << 3 | (opcode & 0x7); - const src = if (src_idx == 0xF) (cpu.r[src_idx] + 2) & 0xFFFF_FFFE else cpu.r[src_idx]; - const dst = if (dst_idx == 0xF) (cpu.r[dst_idx] + 2) & 0xFFFF_FFFE else cpu.r[dst_idx]; + const src_mask = if (src_idx == 0xF) ~@as(u32, 1) else ~@as(u32, 0); + const dst_mask = if (dst_idx == 0xF) ~@as(u32, 1) else ~@as(u32, 0); + + const src = cpu.r[src_idx] & src_mask; + const dst = cpu.r[dst_idx] & dst_mask; switch (op) { 0b00 => { // ADD const sum = add(false, cpu, dst, src); - cpu.r[dst_idx] = if (dst_idx == 0xF) sum & 0xFFFF_FFFE else sum; + cpu.r[dst_idx] = sum & dst_mask; }, 0b01 => cmp(cpu, dst, src), // CMP 0b10 => { // MOV - cpu.r[dst_idx] = if (dst_idx == 0xF) src & 0xFFFF_FFFE else src; + cpu.r[dst_idx] = src & dst_mask; }, 0b11 => { // BX @@ -32,6 +35,8 @@ pub fn format5(comptime op: u2, comptime h1: u1, comptime h2: u1) InstrFn { cpu.pipe.flush(); }, } + + if (dst_idx == 0xF) cpu.pipe.flush(); } }.inner; }