From 9d037fdc3e5ce7e169a0bd094fbc3e925c0ab2d8 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Wed, 27 Jul 2022 13:10:58 -0300 Subject: [PATCH] feat: move thumb instr decoding to module --- src/core/cpu.zig | 243 ++++++++++----------- src/core/cpu/thumb/alu.zig | 4 +- src/core/cpu/thumb/block_data_transfer.zig | 6 +- src/core/cpu/thumb/branch.zig | 8 +- src/core/cpu/thumb/data_processing.zig | 42 +++- src/core/cpu/thumb/data_transfer.zig | 12 +- src/core/cpu/thumb/processing_branch.zig | 36 --- src/core/cpu/thumb/software_interrupt.zig | 4 +- 8 files changed, 169 insertions(+), 186 deletions(-) delete mode 100644 src/core/cpu/thumb/processing_branch.zig diff --git a/src/core/cpu.zig b/src/core/cpu.zig index a68ede9..c8d1f66 100644 --- a/src/core/cpu.zig +++ b/src/core/cpu.zig @@ -16,7 +16,7 @@ const psrTransfer = @import("cpu/arm/psr_transfer.zig").psrTransfer; const singleDataTransfer = @import("cpu/arm/single_data_transfer.zig").singleDataTransfer; const halfAndSignedDataTransfer = @import("cpu/arm/half_signed_data_transfer.zig").halfAndSignedDataTransfer; const blockDataTransfer = @import("cpu/arm/block_data_transfer.zig").blockDataTransfer; -const branch = @import("cpu/arm/branch.zig").branch; +const armBranch = @import("cpu/arm/branch.zig").branch; const branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange; const armSoftwareInterrupt = @import("cpu/arm/software_interrupt.zig").armSoftwareInterrupt; const singleDataSwap = @import("cpu/arm/single_data_swap.zig").singleDataSwap; @@ -25,33 +25,126 @@ const multiply = @import("cpu/arm/multiply.zig").multiply; const multiplyLong = @import("cpu/arm/multiply.zig").multiplyLong; // THUMB Instruction Groups -const format1 = @import("cpu/thumb/data_processing.zig").format1; -const format2 = @import("cpu/thumb/data_processing.zig").format2; -const format3 = @import("cpu/thumb/data_processing.zig").format3; -const format12 = @import("cpu/thumb/data_processing.zig").format12; -const format13 = @import("cpu/thumb/data_processing.zig").format13; -const format4 = @import("cpu/thumb/alu.zig").format4; -const format5 = @import("cpu/thumb/processing_branch.zig").format5; +pub const thumb = struct { + pub const InstrFn = fn (*Arm7tdmi, *Bus, u16) void; + const lut: [0x400]InstrFn = populate(); -const format6 = @import("cpu/thumb/data_transfer.zig").format6; -const format78 = @import("cpu/thumb/data_transfer.zig").format78; -const format9 = @import("cpu/thumb/data_transfer.zig").format9; -const format10 = @import("cpu/thumb/data_transfer.zig").format10; -const format11 = @import("cpu/thumb/data_transfer.zig").format11; -const format14 = @import("cpu/thumb/block_data_transfer.zig").format14; -const format15 = @import("cpu/thumb/block_data_transfer.zig").format15; + const processing = @import("cpu/thumb/data_processing.zig"); + const alu = @import("cpu/thumb/alu.zig").fmt4; + const transfer = @import("cpu/thumb/data_transfer.zig"); + const block_transfer = @import("cpu/thumb/block_data_transfer.zig"); + const swi = @import("cpu/thumb/software_interrupt.zig").fmt17; + const branch = @import("cpu/thumb/branch.zig"); -const format16 = @import("cpu/thumb/branch.zig").format16; -const format18 = @import("cpu/thumb/branch.zig").format18; -const format19 = @import("cpu/thumb/branch.zig").format19; + /// Undefined THUMB Instruction Handler + fn und(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { + const id = thumbIdx(opcode); + cpu.panic("[CPU/Decode] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode }); + } -const thumbSoftwareInterrupt = @import("cpu/thumb/software_interrupt.zig").thumbSoftwareInterrupt; + fn populate() [0x400]InstrFn { + return comptime { + @setEvalBranchQuota(5025); // This is exact + var ret = [_]InstrFn{und} ** 0x400; + + var i: usize = 0; + while (i < ret.len) : (i += 1) { + ret[i] = switch (@as(u3, i >> 7 & 0x7)) { + 0b000 => if (i >> 5 & 0x3 == 0b11) blk: { + const I = i >> 4 & 1 == 1; + const is_sub = i >> 3 & 1 == 1; + const rn = i & 0x7; + break :blk processing.fmt2(I, is_sub, rn); + } else blk: { + const op = i >> 5 & 0x3; + const offset = i & 0x1F; + break :blk processing.fmt1(op, offset); + }, + 0b001 => blk: { + const op = i >> 5 & 0x3; + const rd = i >> 2 & 0x7; + break :blk processing.fmt3(op, rd); + }, + 0b010 => switch (@as(u2, i >> 5 & 0x3)) { + 0b00 => if (i >> 4 & 1 == 1) blk: { + const op = i >> 2 & 0x3; + const h1 = i >> 1 & 1; + const h2 = i & 1; + break :blk processing.fmt5(op, h1, h2); + } else blk: { + const op = i & 0xF; + break :blk alu(op); + }, + 0b01 => blk: { + const rd = i >> 2 & 0x7; + break :blk transfer.fmt6(rd); + }, + else => blk: { + const op = i >> 4 & 0x3; + const T = i >> 3 & 1 == 1; + break :blk transfer.fmt78(op, T); + }, + }, + 0b011 => blk: { + const B = i >> 6 & 1 == 1; + const L = i >> 5 & 1 == 1; + const offset = i & 0x1F; + break :blk transfer.fmt9(B, L, offset); + }, + else => switch (@as(u3, i >> 6 & 0x7)) { + // MSB is guaranteed to be 1 + 0b000 => blk: { + const L = i >> 5 & 1 == 1; + const offset = i & 0x1F; + break :blk transfer.fmt10(L, offset); + }, + 0b001 => blk: { + const L = i >> 5 & 1 == 1; + const rd = i >> 2 & 0x7; + break :blk transfer.fmt11(L, rd); + }, + 0b010 => blk: { + const isSP = i >> 5 & 1 == 1; + const rd = i >> 2 & 0x7; + break :blk processing.fmt12(isSP, rd); + }, + 0b011 => if (i >> 4 & 1 == 1) blk: { + const L = i >> 5 & 1 == 1; + const R = i >> 2 & 1 == 1; + break :blk block_transfer.fmt14(L, R); + } else blk: { + const S = i >> 1 & 1 == 1; + break :blk processing.fmt13(S); + }, + 0b100 => blk: { + const L = i >> 5 & 1 == 1; + const rb = i >> 2 & 0x7; + + break :blk block_transfer.fmt15(L, rb); + }, + 0b101 => if (i >> 2 & 0xF == 0b1111) blk: { + break :blk thumb.swi(); + } else blk: { + const cond = i >> 2 & 0xF; + break :blk branch.fmt16(cond); + }, + 0b110 => branch.fmt18(), + 0b111 => blk: { + const is_low = i >> 5 & 1 == 1; + break :blk branch.fmt19(is_low); + }, + }, + }; + } + + return ret; + }; + } +}; pub const ArmInstrFn = fn (*Arm7tdmi, *Bus, u32) void; -pub const ThumbInstrFn = fn (*Arm7tdmi, *Bus, u16) void; const arm_lut: [0x1000]ArmInstrFn = armPopulate(); -const thumb_lut: [0x400]ThumbInstrFn = thumbPopulate(); const enable_logging = false; const log = std.log.scoped(.Arm7Tdmi); @@ -260,7 +353,7 @@ pub const Arm7tdmi = struct { const opcode = self.fetch(u16); if (enable_logging) if (self.log_file) |file| self.debug_log(file, opcode); - thumb_lut[thumbIdx(opcode)](self, &self.bus, opcode); + thumb.lut[thumbIdx(opcode)](self, &self.bus, opcode); } else { const opcode = self.fetch(u32); if (enable_logging) if (self.log_file) |file| self.debug_log(file, opcode); @@ -497,105 +590,6 @@ pub fn checkCond(cpsr: PSR, cond: u4) bool { }; } -fn thumbPopulate() [0x400]ThumbInstrFn { - return comptime { - @setEvalBranchQuota(5025); // This is exact - var lut = [_]ThumbInstrFn{thumbUndefined} ** 0x400; - - var i: usize = 0; - while (i < lut.len) : (i += 1) { - lut[i] = switch (@as(u3, i >> 7 & 0x7)) { - 0b000 => if (i >> 5 & 0x3 == 0b11) blk: { - const I = i >> 4 & 1 == 1; - const is_sub = i >> 3 & 1 == 1; - const rn = i & 0x7; - break :blk format2(I, is_sub, rn); - } else blk: { - const op = i >> 5 & 0x3; - const offset = i & 0x1F; - break :blk format1(op, offset); - }, - 0b001 => blk: { - const op = i >> 5 & 0x3; - const rd = i >> 2 & 0x7; - break :blk format3(op, rd); - }, - 0b010 => switch (@as(u2, i >> 5 & 0x3)) { - 0b00 => if (i >> 4 & 1 == 1) blk: { - const op = i >> 2 & 0x3; - const h1 = i >> 1 & 1; - const h2 = i & 1; - break :blk format5(op, h1, h2); - } else blk: { - const op = i & 0xF; - break :blk format4(op); - }, - 0b01 => blk: { - const rd = i >> 2 & 0x7; - break :blk format6(rd); - }, - else => blk: { - const op = i >> 4 & 0x3; - const T = i >> 3 & 1 == 1; - break :blk format78(op, T); - }, - }, - 0b011 => blk: { - const B = i >> 6 & 1 == 1; - const L = i >> 5 & 1 == 1; - const offset = i & 0x1F; - break :blk format9(B, L, offset); - }, - else => switch (@as(u3, i >> 6 & 0x7)) { - // MSB is guaranteed to be 1 - 0b000 => blk: { - const L = i >> 5 & 1 == 1; - const offset = i & 0x1F; - break :blk format10(L, offset); - }, - 0b001 => blk: { - const L = i >> 5 & 1 == 1; - const rd = i >> 2 & 0x7; - break :blk format11(L, rd); - }, - 0b010 => blk: { - const isSP = i >> 5 & 1 == 1; - const rd = i >> 2 & 0x7; - break :blk format12(isSP, rd); - }, - 0b011 => if (i >> 4 & 1 == 1) blk: { - const L = i >> 5 & 1 == 1; - const R = i >> 2 & 1 == 1; - break :blk format14(L, R); - } else blk: { - const S = i >> 1 & 1 == 1; - break :blk format13(S); - }, - 0b100 => blk: { - const L = i >> 5 & 1 == 1; - const rb = i >> 2 & 0x7; - - break :blk format15(L, rb); - }, - 0b101 => if (i >> 2 & 0xF == 0b1111) blk: { - break :blk thumbSoftwareInterrupt(); - } else blk: { - const cond = i >> 2 & 0xF; - break :blk format16(cond); - }, - 0b110 => format18(), - 0b111 => blk: { - const is_low = i >> 5 & 1 == 1; - break :blk format19(is_low); - }, - }, - }; - } - - return lut; - }; -} - fn armPopulate() [0x1000]ArmInstrFn { return comptime { @setEvalBranchQuota(0xE000); @@ -657,7 +651,7 @@ fn armPopulate() [0x1000]ArmInstrFn { }, 0b01 => blk: { const L = i >> 8 & 1 == 1; - break :blk branch(L); + break :blk armBranch(L); }, 0b10 => armUndefined, // COP Data Transfer 0b11 => if (i >> 8 & 1 == 1) armSoftwareInterrupt() else armUndefined, // COP Data Operation + Register Transfer @@ -708,8 +702,3 @@ fn armUndefined(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void { const id = armIdx(opcode); cpu.panic("[CPU/Decode] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode }); } - -fn thumbUndefined(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { - const id = thumbIdx(opcode); - cpu.panic("[CPU/Decode] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode }); -} diff --git a/src/core/cpu/thumb/alu.zig b/src/core/cpu/thumb/alu.zig index f7921e8..0113860 100644 --- a/src/core/cpu/thumb/alu.zig +++ b/src/core/cpu/thumb/alu.zig @@ -1,6 +1,6 @@ const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; const adc = @import("../arm/data_processing.zig").adc; const sbc = @import("../arm/data_processing.zig").sbc; @@ -15,7 +15,7 @@ const logicalRight = @import("../barrel_shifter.zig").logicalRight; const arithmeticRight = @import("../barrel_shifter.zig").arithmeticRight; const rotateRight = @import("../barrel_shifter.zig").rotateRight; -pub fn format4(comptime op: u4) InstrFn { +pub fn fmt4(comptime op: u4) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { const rs = opcode >> 3 & 0x7; diff --git a/src/core/cpu/thumb/block_data_transfer.zig b/src/core/cpu/thumb/block_data_transfer.zig index 8596bc8..c2df7e6 100644 --- a/src/core/cpu/thumb/block_data_transfer.zig +++ b/src/core/cpu/thumb/block_data_transfer.zig @@ -1,8 +1,8 @@ const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; -pub fn format14(comptime L: bool, comptime R: bool) InstrFn { +pub fn fmt14(comptime L: bool, comptime R: bool) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { const count = @boolToInt(R) + countRlist(opcode); @@ -45,7 +45,7 @@ pub fn format14(comptime L: bool, comptime R: bool) InstrFn { }.inner; } -pub fn format15(comptime L: bool, comptime rb: u3) InstrFn { +pub fn fmt15(comptime L: bool, comptime rb: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { var address = cpu.r[rb]; diff --git a/src/core/cpu/thumb/branch.zig b/src/core/cpu/thumb/branch.zig index 2515910..015137a 100644 --- a/src/core/cpu/thumb/branch.zig +++ b/src/core/cpu/thumb/branch.zig @@ -1,11 +1,11 @@ const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; const checkCond = @import("../../cpu.zig").checkCond; const sext = @import("../../util.zig").sext; -pub fn format16(comptime cond: u4) InstrFn { +pub fn fmt16(comptime cond: u4) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { // B @@ -23,7 +23,7 @@ pub fn format16(comptime cond: u4) InstrFn { }.inner; } -pub fn format18() InstrFn { +pub fn fmt18() InstrFn { return struct { // B but conditional fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { @@ -33,7 +33,7 @@ pub fn format18() InstrFn { }.inner; } -pub fn format19(comptime is_low: bool) InstrFn { +pub fn fmt19(comptime is_low: bool) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { // BL diff --git a/src/core/cpu/thumb/data_processing.zig b/src/core/cpu/thumb/data_processing.zig index 0fdc653..d352147 100644 --- a/src/core/cpu/thumb/data_processing.zig +++ b/src/core/cpu/thumb/data_processing.zig @@ -2,7 +2,7 @@ const std = @import("std"); const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; const shifter = @import("../barrel_shifter.zig"); const add = @import("../arm/data_processing.zig").add; @@ -12,7 +12,7 @@ const setLogicOpFlags = @import("../arm/data_processing.zig").setLogicOpFlags; const log = std.log.scoped(.Thumb1); -pub fn format1(comptime op: u2, comptime offset: u5) InstrFn { +pub fn fmt1(comptime op: u2, comptime offset: u5) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { const rs = opcode >> 3 & 0x7; @@ -55,7 +55,37 @@ pub fn format1(comptime op: u2, comptime offset: u5) InstrFn { }.inner; } -pub fn format2(comptime I: bool, is_sub: bool, rn: u3) InstrFn { +pub fn fmt5(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 = 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]; + + switch (op) { + 0b00 => { + // ADD + const sum = add(false, cpu, dst, src); + cpu.r[dst_idx] = if (dst_idx == 0xF) sum & 0xFFFF_FFFE else sum; + }, + 0b01 => cmp(cpu, dst, src), // CMP + 0b10 => { + // MOV + cpu.r[dst_idx] = if (dst_idx == 0xF) src & 0xFFFF_FFFE else src; + }, + 0b11 => { + // BX + cpu.cpsr.t.write(src & 1 == 1); + cpu.r[15] = src & 0xFFFF_FFFE; + }, + } + } + }.inner; +} + +pub fn fmt2(comptime I: bool, is_sub: bool, rn: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { const rs = opcode >> 3 & 0x7; @@ -80,7 +110,7 @@ pub fn format2(comptime I: bool, is_sub: bool, rn: u3) InstrFn { }.inner; } -pub fn format3(comptime op: u2, comptime rd: u3) InstrFn { +pub fn fmt3(comptime op: u2, comptime rd: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { const offset = @truncate(u8, opcode); @@ -99,7 +129,7 @@ pub fn format3(comptime op: u2, comptime rd: u3) InstrFn { }.inner; } -pub fn format12(comptime isSP: bool, comptime rd: u3) InstrFn { +pub fn fmt12(comptime isSP: bool, comptime rd: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { // ADD @@ -111,7 +141,7 @@ pub fn format12(comptime isSP: bool, comptime rd: u3) InstrFn { }.inner; } -pub fn format13(comptime S: bool) InstrFn { +pub fn fmt13(comptime S: bool) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void { // ADD diff --git a/src/core/cpu/thumb/data_transfer.zig b/src/core/cpu/thumb/data_transfer.zig index ced9813..481e3e5 100644 --- a/src/core/cpu/thumb/data_transfer.zig +++ b/src/core/cpu/thumb/data_transfer.zig @@ -2,11 +2,11 @@ const std = @import("std"); const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; const rotr = @import("../../util.zig").rotr; -pub fn format6(comptime rd: u3) InstrFn { +pub fn fmt6(comptime rd: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { // LDR @@ -18,7 +18,7 @@ pub fn format6(comptime rd: u3) InstrFn { const sext = @import("../../util.zig").sext; -pub fn format78(comptime op: u2, comptime T: bool) InstrFn { +pub fn fmt78(comptime op: u2, comptime T: bool) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { const ro = opcode >> 6 & 0x7; @@ -78,7 +78,7 @@ pub fn format78(comptime op: u2, comptime T: bool) InstrFn { }.inner; } -pub fn format9(comptime B: bool, comptime L: bool, comptime offset: u5) InstrFn { +pub fn fmt9(comptime B: bool, comptime L: bool, comptime offset: u5) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { const rb = opcode >> 3 & 0x7; @@ -110,7 +110,7 @@ pub fn format9(comptime B: bool, comptime L: bool, comptime offset: u5) InstrFn }.inner; } -pub fn format10(comptime L: bool, comptime offset: u5) InstrFn { +pub fn fmt10(comptime L: bool, comptime offset: u5) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { const rb = opcode >> 3 & 0x7; @@ -130,7 +130,7 @@ pub fn format10(comptime L: bool, comptime offset: u5) InstrFn { }.inner; } -pub fn format11(comptime L: bool, comptime rd: u3) InstrFn { +pub fn fmt11(comptime L: bool, comptime rd: u3) InstrFn { return struct { fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u16) void { const offset = (opcode & 0xFF) << 2; diff --git a/src/core/cpu/thumb/processing_branch.zig b/src/core/cpu/thumb/processing_branch.zig deleted file mode 100644 index c30d7e4..0000000 --- a/src/core/cpu/thumb/processing_branch.zig +++ /dev/null @@ -1,36 +0,0 @@ -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 = 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]; - - switch (op) { - 0b00 => { - // ADD - const sum = add(false, cpu, dst, src); - cpu.r[dst_idx] = if (dst_idx == 0xF) sum & 0xFFFF_FFFE else sum; - }, - 0b01 => cmp(cpu, dst, src), // CMP - 0b10 => { - // MOV - cpu.r[dst_idx] = if (dst_idx == 0xF) src & 0xFFFF_FFFE else src; - }, - 0b11 => { - // BX - cpu.cpsr.t.write(src & 1 == 1); - cpu.r[15] = src & 0xFFFF_FFFE; - }, - } - } - }.inner; -} diff --git a/src/core/cpu/thumb/software_interrupt.zig b/src/core/cpu/thumb/software_interrupt.zig index daa4f34..abb69ba 100644 --- a/src/core/cpu/thumb/software_interrupt.zig +++ b/src/core/cpu/thumb/software_interrupt.zig @@ -1,8 +1,8 @@ const Bus = @import("../../Bus.zig"); const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi; -const InstrFn = @import("../../cpu.zig").ThumbInstrFn; +const InstrFn = @import("../../cpu.zig").thumb.InstrFn; -pub fn thumbSoftwareInterrupt() InstrFn { +pub fn fmt17() InstrFn { return struct { fn inner(cpu: *Arm7tdmi, _: *Bus, _: u16) void { // Copy Values from Current Mode