diff --git a/src/arm.zig b/src/arm.zig index 0ce93b8..72c8a38 100644 --- a/src/arm.zig +++ b/src/arm.zig @@ -50,6 +50,7 @@ pub fn Arm32(comptime arch: Architecture) type { .v5te => @import("arm/v5te.zig").thumb, }; + // FIXME: What about .v5te? const Pipeline = struct { stage: [2]?u32, flushed: bool, @@ -147,7 +148,7 @@ pub fn Arm32(comptime arch: Architecture) type { }; pub fn init(scheduler: Scheduler, bus: Bus) Self { - return Self{ + return .{ .sched = scheduler, .bus = bus, .cpsr = .{ .raw = 0x0000_001F }, @@ -155,6 +156,16 @@ pub fn Arm32(comptime arch: Architecture) type { }; } + // CPU needs it's own read/write fns due to ICTM and DCTM present in v5te + // I considered implementing Bus.cpu_read and Bus.cpu_write but ended up considering that a bit too leaky + pub fn read(self: *Self, comptime T: type, address: u32) T { + return self.bus.read(T, address); + } + + pub fn write(self: *Self, comptime T: type, address: u32, value: T) void { + return self.bus.write(T, address, value); + } + // FIXME: Resetting disables logging (if enabled) pub fn reset(self: *Self) void { self.* = .{ @@ -276,12 +287,12 @@ pub fn Arm32(comptime arch: Architecture) type { if (self.cpsr.t.read()) { const opcode: u16 = @truncate(self.pipe.step(self, u16) orelse return); - thumb.lut[thumb.idx(opcode)](self, self.bus, opcode); + thumb.lut[thumb.idx(opcode)](self, opcode); } else { const opcode = self.pipe.step(self, u32) orelse return; if (self.cpsr.check(@truncate(opcode >> 28))) { - arm.lut[arm.idx(opcode)](self, self.bus, opcode); + arm.lut[arm.idx(opcode)](self, opcode); } } } @@ -298,7 +309,7 @@ pub fn Arm32(comptime arch: Architecture) type { // const tick_cache = self.sched.tick; // defer self.sched.tick = tick_cache + Bus.fetch_timings[@boolToInt(T == u32)][@truncate(u4, address >> 24)]; - return self.bus.read(T, address); + return self.read(T, address); } pub fn panic(self: *const Self, comptime format: []const u8, args: anytype) noreturn { diff --git a/src/arm/cpu/arm/block_data_transfer.zig b/src/arm/cpu/arm/block_data_transfer.zig index f7e1763..6588174 100644 --- a/src/arm/cpu/arm/block_data_transfer.zig +++ b/src/arm/cpu/arm/block_data_transfer.zig @@ -1,10 +1,8 @@ -const Bus = @import("../../../lib.zig").Bus; - pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: bool, comptime S: bool, comptime W: bool, comptime L: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rn: u4 = @truncate(opcode >> 16 & 0xF); const rlist = opcode & 0xFFFF; const r15 = rlist >> 15 & 1 == 1; @@ -54,10 +52,10 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b } if (L) { - cpu.r[15] = bus.read(u32, und_addr); + cpu.r[15] = cpu.read(u32, und_addr); cpu.pipe.reload(cpu); } else { - bus.write(u32, und_addr, cpu.r[15] + 4); + cpu.write(u32, und_addr, cpu.r[15] + 4); } cpu.r[rn] = if (U) cpu.r[rn] + 0x40 else cpu.r[rn] - 0x40; @@ -67,7 +65,7 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b i = first; while (i < 16) : (i += 1) { if (rlist >> i & 1 == 1) { - transfer(cpu, bus, r15, i, address); + transfer(cpu, r15, i, address); address += 4; if (W and !L and write_to_base) { @@ -80,13 +78,13 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b if (W and L and rlist >> rn & 1 == 0) cpu.r[rn] = new_base; } - fn transfer(cpu: Arm32, bus: Bus, r15_present: bool, i: u5, address: u32) void { + fn transfer(cpu: Arm32, r15_present: bool, i: u5, address: u32) void { if (L) { if (S and !r15_present) { // Always Transfer User mode Registers - cpu.setUserModeRegister(i, bus.read(u32, address)); + cpu.setUserModeRegister(i, cpu.read(u32, address)); } else { - const value = bus.read(u32, address); + const value = cpu.read(u32, address); cpu.r[i] = value; if (i == 0xF) { @@ -101,9 +99,9 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b // Always Transfer User mode Registers // This happens regardless if r15 is in the list const value = cpu.getUserModeRegister(i); - bus.write(u32, address, value + if (i == 0xF) 4 else @as(u32, 0)); // PC is already 8 ahead to make 12 + cpu.write(u32, address, value + if (i == 0xF) 4 else @as(u32, 0)); // PC is already 8 ahead to make 12 } else { - bus.write(u32, address, cpu.r[i] + if (i == 0xF) 4 else @as(u32, 0)); + cpu.write(u32, address, cpu.r[i] + if (i == 0xF) 4 else @as(u32, 0)); } } } diff --git a/src/arm/cpu/arm/branch.zig b/src/arm/cpu/arm/branch.zig index a43b316..7bfd6b8 100644 --- a/src/arm/cpu/arm/branch.zig +++ b/src/arm/cpu/arm/branch.zig @@ -1,11 +1,10 @@ -const Bus = @import("../../../lib.zig").Bus; const sext = @import("zba-util").sext; pub fn branch(comptime InstrFn: type, comptime L: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { if (L) cpu.r[14] = cpu.r[15] - 4; cpu.r[15] +%= sext(u32, u24, opcode) << 2; @@ -18,7 +17,7 @@ pub fn branchAndExchange(comptime InstrFn: type) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - pub fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + pub fn inner(cpu: Arm32, opcode: u32) void { const rn = opcode & 0xF; const thumb = cpu.r[rn] & 1 == 1; diff --git a/src/arm/cpu/arm/coprocessor.zig b/src/arm/cpu/arm/coprocessor.zig index 4f6186b..6a19612 100644 --- a/src/arm/cpu/arm/coprocessor.zig +++ b/src/arm/cpu/arm/coprocessor.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const Bus = @import("../../../lib.zig").Bus; const log = std.log.scoped(.coprocessor_handler); @@ -12,7 +11,7 @@ pub fn dataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: bool, const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { _ = cpu; log.err("TODO: handle 0x{X:0>8} which is a coprocessor data transfer instr", .{opcode}); @@ -27,7 +26,7 @@ pub fn registerTransfer(comptime InstrFn: type, comptime opcode1: u3, comptime L const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { _ = cpu; log.err("TODO: handle 0x{X:0>8} which is a coprocessor register transfer instr", .{opcode}); @@ -41,7 +40,7 @@ pub fn dataProcessing(comptime InstrFn: type, comptime opcode1: u4, comptime opc const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { _ = cpu; log.err("TODO: handle 0x{X:0>8} which is a coprocessor data processing instr", .{opcode}); diff --git a/src/arm/cpu/arm/data_processing.zig b/src/arm/cpu/arm/data_processing.zig index 933ac60..fe899ae 100644 --- a/src/arm/cpu/arm/data_processing.zig +++ b/src/arm/cpu/arm/data_processing.zig @@ -1,5 +1,3 @@ -const Bus = @import("../../../lib.zig").Bus; - const exec = @import("../barrel_shifter.zig").exec; const ror = @import("../barrel_shifter.zig").ror; @@ -7,7 +5,7 @@ pub fn dataProcessing(comptime InstrFn: type, comptime I: bool, comptime S: bool const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rd: u4 = @truncate(opcode >> 12 & 0xF); const rn = opcode >> 16 & 0xF; const old_carry = @intFromBool(cpu.cpsr.c.read()); diff --git a/src/arm/cpu/arm/half_signed_data_transfer.zig b/src/arm/cpu/arm/half_signed_data_transfer.zig index 925b97b..11fe385 100644 --- a/src/arm/cpu/arm/half_signed_data_transfer.zig +++ b/src/arm/cpu/arm/half_signed_data_transfer.zig @@ -1,5 +1,3 @@ -const Bus = @import("../../../lib.zig").Bus; - const sext = @import("zba-util").sext; const rotr = @import("zba-util").rotr; @@ -7,7 +5,7 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rn = opcode >> 16 & 0xF; const rd = opcode >> 12 & 0xF; const rm = opcode & 0xF; @@ -24,16 +22,16 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt switch (@as(u2, @truncate(opcode >> 5))) { 0b01 => { // LDRH - const value = bus.read(u16, address); + const value = cpu.read(u16, address); result = rotr(u32, value, 8 * (address & 1)); }, 0b10 => { // LDRSB - result = sext(u32, u8, bus.read(u8, address)); + result = sext(u32, u8, cpu.read(u8, address)); }, 0b11 => { // LDRSH - const value = bus.read(u16, address); + const value = cpu.read(u16, address); // FIXME: I shouldn't have to use @as(u8, ...) here result = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value); @@ -45,7 +43,7 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt // STRH // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); + cpu.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); } else unreachable; // SWP } diff --git a/src/arm/cpu/arm/multiply.zig b/src/arm/cpu/arm/multiply.zig index c21b20e..8db321e 100644 --- a/src/arm/cpu/arm/multiply.zig +++ b/src/arm/cpu/arm/multiply.zig @@ -1,10 +1,8 @@ -const Bus = @import("../../../lib.zig").Bus; - pub fn multiply(comptime InstrFn: type, comptime A: bool, comptime S: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rd = opcode >> 16 & 0xF; const rn = opcode >> 12 & 0xF; const rs = opcode >> 8 & 0xF; @@ -27,7 +25,7 @@ pub fn multiplyLong(comptime InstrFn: type, comptime U: bool, comptime A: bool, const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rd_hi = opcode >> 16 & 0xF; const rd_lo = opcode >> 12 & 0xF; const rs = opcode >> 8 & 0xF; diff --git a/src/arm/cpu/arm/psr_transfer.zig b/src/arm/cpu/arm/psr_transfer.zig index ea4aaae..f8d881a 100644 --- a/src/arm/cpu/arm/psr_transfer.zig +++ b/src/arm/cpu/arm/psr_transfer.zig @@ -1,6 +1,5 @@ const std = @import("std"); -const Bus = @import("../../../lib.zig").Bus; const PSR = @import("../../../arm.zig").PSR; const log = std.log.scoped(.PsrTransfer); @@ -11,7 +10,7 @@ pub fn psrTransfer(comptime InstrFn: type, comptime I: bool, comptime R: bool, c const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { switch (kind) { 0b00 => { // MRS diff --git a/src/arm/cpu/arm/single_data_swap.zig b/src/arm/cpu/arm/single_data_swap.zig index 1f27e84..db54166 100644 --- a/src/arm/cpu/arm/single_data_swap.zig +++ b/src/arm/cpu/arm/single_data_swap.zig @@ -1,12 +1,10 @@ -const Bus = @import("../../../lib.zig").Bus; - const rotr = @import("zba-util").rotr; pub fn singleDataSwap(comptime InstrFn: type, comptime B: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rn = opcode >> 16 & 0xF; const rd = opcode >> 12 & 0xF; const rm = opcode & 0xF; @@ -15,15 +13,15 @@ pub fn singleDataSwap(comptime InstrFn: type, comptime B: bool) InstrFn { if (B) { // SWPB - const value = bus.read(u8, address); + const value = cpu.read(u8, address); // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u8, address, @as(u8, @truncate(cpu.r[rm]))); + cpu.write(u8, address, @as(u8, @truncate(cpu.r[rm]))); cpu.r[rd] = value; } else { // SWP - const value = rotr(u32, bus.read(u32, address), 8 * (address & 0x3)); - bus.write(u32, address, cpu.r[rm]); + const value = rotr(u32, cpu.read(u32, address), 8 * (address & 0x3)); + cpu.write(u32, address, cpu.r[rm]); cpu.r[rd] = value; } } diff --git a/src/arm/cpu/arm/single_data_transfer.zig b/src/arm/cpu/arm/single_data_transfer.zig index bdb64af..e3bd5a6 100644 --- a/src/arm/cpu/arm/single_data_transfer.zig +++ b/src/arm/cpu/arm/single_data_transfer.zig @@ -1,5 +1,4 @@ const shifter = @import("../barrel_shifter.zig"); -const Bus = @import("../../../lib.zig").Bus; const rotr = @import("zba-util").rotr; @@ -7,7 +6,7 @@ pub fn singleDataTransfer(comptime InstrFn: type, comptime I: bool, comptime P: const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u32) void { + fn inner(cpu: Arm32, opcode: u32) void { const rn = opcode >> 16 & 0xF; const rd = opcode >> 12 & 0xF; @@ -21,10 +20,10 @@ pub fn singleDataTransfer(comptime InstrFn: type, comptime I: bool, comptime P: if (L) { if (B) { // LDRB - result = bus.read(u8, address); + result = cpu.read(u8, address); } else { // LDR - const value = bus.read(u32, address); + const value = cpu.read(u32, address); result = rotr(u32, value, 8 * (address & 0x3)); } } else { @@ -33,11 +32,11 @@ pub fn singleDataTransfer(comptime InstrFn: type, comptime I: bool, comptime P: const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0); // PC is 12 ahead // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u8, address, @as(u8, @truncate(value))); + cpu.write(u8, address, @as(u8, @truncate(value))); } else { // STR const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0); - bus.write(u32, address, value); + cpu.write(u32, address, value); } } diff --git a/src/arm/cpu/arm/software_interrupt.zig b/src/arm/cpu/arm/software_interrupt.zig index c8d703f..5e526e5 100644 --- a/src/arm/cpu/arm/software_interrupt.zig +++ b/src/arm/cpu/arm/software_interrupt.zig @@ -1,10 +1,8 @@ -const Bus = @import("../../../lib.zig").Bus; - pub fn armSoftwareInterrupt(comptime InstrFn: type) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, _: u32) void { + fn inner(cpu: Arm32, _: u32) void { // Copy Values from Current Mode const ret_addr = cpu.r[15] - 4; const cpsr = cpu.cpsr.raw; diff --git a/src/arm/cpu/thumb/alu.zig b/src/arm/cpu/thumb/alu.zig index d7c076e..f4e7ed0 100644 --- a/src/arm/cpu/thumb/alu.zig +++ b/src/arm/cpu/thumb/alu.zig @@ -1,5 +1,3 @@ -const Bus = @import("../../../lib.zig").Bus; - const adc = @import("../arm/data_processing.zig").adc; const sbc = @import("../arm/data_processing.zig").sbc; @@ -12,7 +10,7 @@ pub fn fmt4(comptime InstrFn: type, comptime op: u4) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rs = opcode >> 3 & 0x7; const rd = opcode & 0x7; const carry = @intFromBool(cpu.cpsr.c.read()); diff --git a/src/arm/cpu/thumb/block_data_transfer.zig b/src/arm/cpu/thumb/block_data_transfer.zig index ce5fdc1..e11fd64 100644 --- a/src/arm/cpu/thumb/block_data_transfer.zig +++ b/src/arm/cpu/thumb/block_data_transfer.zig @@ -1,10 +1,8 @@ -const Bus = @import("../../../lib.zig").Bus; - pub fn fmt14(comptime InstrFn: type, comptime L: bool, comptime R: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const count = @intFromBool(R) + countRlist(opcode); const start = cpu.r[13] - if (!L) count * 4 else 0; @@ -21,9 +19,9 @@ pub fn fmt14(comptime InstrFn: type, comptime L: bool, comptime R: bool) InstrFn while (i < 8) : (i += 1) { if (opcode >> i & 1 == 1) { if (L) { - cpu.r[i] = bus.read(u32, address); + cpu.r[i] = cpu.read(u32, address); } else { - bus.write(u32, address, cpu.r[i]); + cpu.write(u32, address, cpu.r[i]); } address += 4; @@ -32,11 +30,11 @@ pub fn fmt14(comptime InstrFn: type, comptime L: bool, comptime R: bool) InstrFn if (R) { if (L) { - const value = bus.read(u32, address); + const value = cpu.read(u32, address); cpu.r[15] = value & ~@as(u32, 1); cpu.pipe.reload(cpu); } else { - bus.write(u32, address, cpu.r[14]); + cpu.write(u32, address, cpu.r[14]); } address += 4; } @@ -50,16 +48,16 @@ pub fn fmt15(comptime InstrFn: type, comptime L: bool, comptime rb: u3) InstrFn const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { var address = cpu.r[rb]; const end_address = cpu.r[rb] + 4 * countRlist(opcode); if (opcode & 0xFF == 0) { if (L) { - cpu.r[15] = bus.read(u32, address); + cpu.r[15] = cpu.read(u32, address); cpu.pipe.reload(cpu); } else { - bus.write(u32, address, cpu.r[15] + 2); + cpu.write(u32, address, cpu.r[15] + 2); } cpu.r[rb] += 0x40; @@ -72,9 +70,9 @@ pub fn fmt15(comptime InstrFn: type, comptime L: bool, comptime rb: u3) InstrFn while (i < 8) : (i += 1) { if (opcode >> i & 1 == 1) { if (L) { - cpu.r[i] = bus.read(u32, address); + cpu.r[i] = cpu.read(u32, address); } else { - bus.write(u32, address, cpu.r[i]); + cpu.write(u32, address, cpu.r[i]); } if (!L and first_write) { diff --git a/src/arm/cpu/thumb/branch.zig b/src/arm/cpu/thumb/branch.zig index 4477bff..c9fe27d 100644 --- a/src/arm/cpu/thumb/branch.zig +++ b/src/arm/cpu/thumb/branch.zig @@ -1,12 +1,10 @@ -const Bus = @import("../../../lib.zig").Bus; - const sext = @import("zba-util").sext; pub fn fmt16(comptime InstrFn: type, comptime cond: u4) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { // B if (cond == 0xE or cond == 0xF) cpu.panic("[CPU/THUMB.16] Undefined conditional branch with condition {}", .{cond}); @@ -24,7 +22,7 @@ pub fn fmt18(comptime InstrFn: type) InstrFn { return struct { // B but conditional - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { cpu.r[15] +%= sext(u32, u11, opcode & 0x7FF) << 1; cpu.pipe.reload(cpu); } @@ -35,7 +33,7 @@ pub fn fmt19(comptime InstrFn: type, comptime is_low: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { // BL const offset = opcode & 0x7FF; diff --git a/src/arm/cpu/thumb/data_processing.zig b/src/arm/cpu/thumb/data_processing.zig index da8b696..2c24419 100644 --- a/src/arm/cpu/thumb/data_processing.zig +++ b/src/arm/cpu/thumb/data_processing.zig @@ -1,5 +1,3 @@ -const Bus = @import("../../../lib.zig").Bus; - const add = @import("../arm/data_processing.zig").add; const lsl = @import("../barrel_shifter.zig").lsl; @@ -10,7 +8,7 @@ pub fn fmt1(comptime InstrFn: type, comptime op: u2, comptime offset: u5) InstrF const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rs = opcode >> 3 & 0x7; const rd = opcode & 0x7; @@ -58,7 +56,7 @@ pub fn fmt5(comptime InstrFn: type, comptime op: u2, comptime h1: u1, comptime h const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rs = @as(u4, h2) << 3 | (opcode >> 3 & 0x7); const rd = @as(u4, h1) << 3 | (opcode & 0x7); @@ -113,7 +111,7 @@ pub fn fmt2(comptime InstrFn: type, comptime I: bool, is_sub: bool, rn: u3) Inst const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rs = opcode >> 3 & 0x7; const rd: u3 = @truncate(opcode); const op1 = cpu.r[rs]; @@ -147,7 +145,7 @@ pub fn fmt3(comptime InstrFn: type, comptime op: u2, comptime rd: u3) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const op1 = cpu.r[rd]; const op2: u32 = opcode & 0xFF; // Offset @@ -187,7 +185,7 @@ pub fn fmt12(comptime InstrFn: type, comptime isSP: bool, comptime rd: u3) Instr const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { // ADD const left = if (isSP) cpu.r[13] else cpu.r[15] & ~@as(u32, 2); const right = (opcode & 0xFF) << 2; @@ -200,7 +198,7 @@ pub fn fmt13(comptime InstrFn: type, comptime S: bool) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { // ADD const offset = (opcode & 0x7F) << 2; cpu.r[13] = if (S) cpu.r[13] - offset else cpu.r[13] + offset; diff --git a/src/arm/cpu/thumb/data_transfer.zig b/src/arm/cpu/thumb/data_transfer.zig index 94d7728..c310f82 100644 --- a/src/arm/cpu/thumb/data_transfer.zig +++ b/src/arm/cpu/thumb/data_transfer.zig @@ -1,5 +1,3 @@ -const Bus = @import("../../../lib.zig").Bus; - const rotr = @import("zba-util").rotr; const sext = @import("zba-util").sext; @@ -7,12 +5,12 @@ pub fn fmt6(comptime InstrFn: type, comptime rd: u3) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { // LDR const offset = (opcode & 0xFF) << 2; // Bit 1 of the PC intentionally ignored - cpu.r[rd] = bus.read(u32, (cpu.r[15] & ~@as(u32, 2)) + offset); + cpu.r[rd] = cpu.read(u32, (cpu.r[15] & ~@as(u32, 2)) + offset); } }.inner; } @@ -21,7 +19,7 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const ro = opcode >> 6 & 0x7; const rb = opcode >> 3 & 0x7; const rd = opcode & 0x7; @@ -35,20 +33,20 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn // STRH // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); + cpu.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); }, 0b01 => { // LDSB - cpu.r[rd] = sext(u32, u8, bus.read(u8, address)); + cpu.r[rd] = sext(u32, u8, cpu.read(u8, address)); }, 0b10 => { // LDRH - const value = bus.read(u16, address); + const value = cpu.read(u16, address); cpu.r[rd] = rotr(u32, value, 8 * (address & 1)); }, 0b11 => { // LDRSH - const value = bus.read(u16, address); + const value = cpu.read(u16, address); // FIXME: I shouldn't have to use @as(u8, ...) here cpu.r[rd] = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value); @@ -59,22 +57,22 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn switch (op) { 0b00 => { // STR - bus.write(u32, address, cpu.r[rd]); + cpu.write(u32, address, cpu.r[rd]); }, 0b01 => { // STRB // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); + cpu.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); }, 0b10 => { // LDR - const value = bus.read(u32, address); + const value = cpu.read(u32, address); cpu.r[rd] = rotr(u32, value, 8 * (address & 0x3)); }, 0b11 => { // LDRB - cpu.r[rd] = bus.read(u8, address); + cpu.r[rd] = cpu.read(u8, address); }, } } @@ -86,7 +84,7 @@ pub fn fmt9(comptime InstrFn: type, comptime B: bool, comptime L: bool, comptime const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rb = opcode >> 3 & 0x7; const rd = opcode & 0x7; @@ -94,11 +92,11 @@ pub fn fmt9(comptime InstrFn: type, comptime B: bool, comptime L: bool, comptime if (B) { // LDRB const address = cpu.r[rb] + offset; - cpu.r[rd] = bus.read(u8, address); + cpu.r[rd] = cpu.read(u8, address); } else { // LDR const address = cpu.r[rb] + (@as(u32, offset) << 2); - const value = bus.read(u32, address); + const value = cpu.read(u32, address); cpu.r[rd] = rotr(u32, value, 8 * (address & 0x3)); } } else { @@ -107,11 +105,11 @@ pub fn fmt9(comptime InstrFn: type, comptime B: bool, comptime L: bool, comptime const address = cpu.r[rb] + offset; // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); + cpu.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); } else { // STR const address = cpu.r[rb] + (@as(u32, offset) << 2); - bus.write(u32, address, cpu.r[rd]); + cpu.write(u32, address, cpu.r[rd]); } } } @@ -122,7 +120,7 @@ pub fn fmt10(comptime InstrFn: type, comptime L: bool, comptime offset: u5) Inst const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const rb = opcode >> 3 & 0x7; const rd = opcode & 0x7; @@ -130,13 +128,13 @@ pub fn fmt10(comptime InstrFn: type, comptime L: bool, comptime offset: u5) Inst if (L) { // LDRH - const value = bus.read(u16, address); + const value = cpu.read(u16, address); cpu.r[rd] = rotr(u32, value, 8 * (address & 1)); } else { // STRH // FIXME: I shouldn't have to use @as(u8, ...) here - bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); + cpu.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); } } }.inner; @@ -146,17 +144,17 @@ pub fn fmt11(comptime InstrFn: type, comptime L: bool, comptime rd: u3) InstrFn const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, bus: Bus, opcode: u16) void { + fn inner(cpu: Arm32, opcode: u16) void { const offset = (opcode & 0xFF) << 2; const address = cpu.r[13] + offset; if (L) { // LDR - const value = bus.read(u32, address); + const value = cpu.read(u32, address); cpu.r[rd] = rotr(u32, value, 8 * (address & 0x3)); } else { // STR - bus.write(u32, address, cpu.r[rd]); + cpu.write(u32, address, cpu.r[rd]); } } }.inner; diff --git a/src/arm/cpu/thumb/software_interrupt.zig b/src/arm/cpu/thumb/software_interrupt.zig index 6ac1ab0..22d5de6 100644 --- a/src/arm/cpu/thumb/software_interrupt.zig +++ b/src/arm/cpu/thumb/software_interrupt.zig @@ -1,10 +1,8 @@ -const Bus = @import("../../../lib.zig").Bus; - pub fn fmt17(comptime InstrFn: type) InstrFn { const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?; return struct { - fn inner(cpu: Arm32, _: Bus, _: u16) void { + fn inner(cpu: Arm32, _: u16) void { // Copy Values from Current Mode const ret_addr = cpu.r[15] - 2; const cpsr = cpu.cpsr.raw; diff --git a/src/arm/v4t.zig b/src/arm/v4t.zig index e131e83..6fb6b21 100644 --- a/src/arm/v4t.zig +++ b/src/arm/v4t.zig @@ -1,8 +1,7 @@ -const Bus = @import("../lib.zig").Bus; const Arm7tdmi = @import("../arm.zig").Arm32(.v4t); pub const arm = struct { - pub const InstrFn = *const fn (*Arm7tdmi, Bus, u32) void; + pub const InstrFn = *const fn (*Arm7tdmi, u32) void; pub const lut: [0x1000]InstrFn = populate(); const processing = @import("cpu/arm/data_processing.zig").dataProcessing; @@ -25,7 +24,7 @@ pub const arm = struct { } // Undefined ARM Instruction handler - fn und(cpu: *Arm7tdmi, _: Bus, opcode: u32) void { + fn und(cpu: *Arm7tdmi, opcode: u32) void { const id = idx(opcode); cpu.panic("[CPU/Decode] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode }); } @@ -104,7 +103,7 @@ pub const arm = struct { }; pub const thumb = struct { - pub const InstrFn = *const fn (*Arm7tdmi, Bus, u16) void; + pub const InstrFn = *const fn (*Arm7tdmi, u16) void; pub const lut: [0x400]InstrFn = populate(); const processing = @import("cpu/thumb/data_processing.zig"); @@ -120,7 +119,7 @@ pub const thumb = struct { } /// Undefined THUMB Instruction Handler - fn und(cpu: *Arm7tdmi, _: Bus, opcode: u16) void { + fn und(cpu: *Arm7tdmi, opcode: u16) void { const id = idx(opcode); cpu.panic("[CPU/Decode] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode }); } diff --git a/src/arm/v5te.zig b/src/arm/v5te.zig index 5880e7c..a20f52e 100644 --- a/src/arm/v5te.zig +++ b/src/arm/v5te.zig @@ -1,8 +1,7 @@ -const Bus = @import("../lib.zig").Bus; const Arm946es = @import("../arm.zig").Arm32(.v5te); pub const arm = struct { - pub const InstrFn = *const fn (*Arm946es, Bus, u32) void; + pub const InstrFn = *const fn (*Arm946es, u32) void; pub const lut: [0x1000]InstrFn = populate(); const processing = @import("cpu/arm/data_processing.zig").dataProcessing; @@ -27,7 +26,7 @@ pub const arm = struct { } // Undefined ARM Instruction handler - fn und(cpu: *Arm946es, _: Bus, opcode: u32) void { + fn und(cpu: *Arm946es, opcode: u32) void { const id = idx(opcode); cpu.panic("[CPU/Decode] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode }); } @@ -127,7 +126,7 @@ pub const arm = struct { }; pub const thumb = struct { - pub const InstrFn = *const fn (*Arm946es, Bus, u16) void; + pub const InstrFn = *const fn (*Arm946es, u16) void; pub const lut: [0x400]InstrFn = populate(); const processing = @import("cpu/thumb/data_processing.zig"); @@ -143,7 +142,7 @@ pub const thumb = struct { } /// Undefined THUMB Instruction Handler - fn und(cpu: *Arm946es, _: Bus, opcode: u16) void { + fn und(cpu: *Arm946es, opcode: u16) void { const id = idx(opcode); cpu.panic("[CPU/Decode] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode }); }