const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; const InstrFn = @import("../../cpu.zig").ThumbInstrFn; const cmp = @import("../arm/data_processing.zig").cmp; const add = @import("../arm/data_processing.zig").add; pub fn format5(comptime op: u2, comptime h1: u1, comptime h2: u1) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { const src_idx = @as(u4, h2) << 3 | (opcode >> 3 & 0x7); const dst_idx = @as(u4, h1) << 3 | (opcode & 0x7); 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] = sum & dst_mask; }, 0b01 => cmp(cpu, dst, src), // CMP 0b10 => { // MOV cpu.r[dst_idx] = src & dst_mask; }, 0b11 => { // BX cpu.cpsr.t.write(src & 1 == 1); cpu.r[15] = src & ~@as(u32, 1); cpu.pipe.flush(); }, } if (dst_idx == 0xF) cpu.pipe.flush(); } }.inner; }