Compare commits

...

4 Commits

8 changed files with 45 additions and 48 deletions

View File

@ -1,19 +1,19 @@
const std = @import("std");
const util = @import("util.zig");
const BarrelShifter = @import("cpu/barrel_shifter.zig");
const BarrelShifter = @import("cpu/arm/barrel_shifter.zig");
const Bus = @import("Bus.zig");
const Bit = @import("bitfield").Bit;
const Bitfield = @import("bitfield").Bitfield;
const Scheduler = @import("scheduler.zig").Scheduler;
const dataProcessing = @import("cpu/data_processing.zig").dataProcessing;
const psrTransfer = @import("cpu/psr_transfer.zig").psrTransfer;
const singleDataTransfer = @import("cpu/single_data_transfer.zig").singleDataTransfer;
const halfAndSignedDataTransfer = @import("cpu/half_signed_data_transfer.zig").halfAndSignedDataTransfer;
const blockDataTransfer = @import("cpu/block_data_transfer.zig").blockDataTransfer;
const branch = @import("cpu/branch.zig").branch;
const branchAndExchange = @import("cpu/branch.zig").branchAndExchange;
const dataProcessing = @import("cpu/arm/data_processing.zig").dataProcessing;
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 branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange;
pub const InstrFn = fn (*Arm7tdmi, *Bus, u32) void;
const arm_lut: [0x1000]InstrFn = populate();
@ -102,7 +102,7 @@ fn checkCond(cpsr: *const PSR, opcode: u32) bool {
// TODO: Should I implement an enum?
return switch (@truncate(u4, opcode >> 28)) {
0x0 => cpsr.z.read(), // EQ - Equal
0x1 => !cpsr.z.read(), // NEQ - Not equal
0x1 => !cpsr.z.read(), // NE - Not equal
0x2 => cpsr.c.read(), // CS - Unsigned higher or same
0x3 => !cpsr.c.read(), // CC - Unsigned lower
0x4 => cpsr.n.read(), // MI - Negative
@ -113,7 +113,7 @@ fn checkCond(cpsr: *const PSR, opcode: u32) bool {
0x9 => !cpsr.c.read() and cpsr.z.read(), // LS - unsigned lower or same
0xA => cpsr.n.read() == cpsr.v.read(), // GE - Greater or equal
0xB => cpsr.n.read() != cpsr.v.read(), // LT - Less than
0xC => !cpsr.z.read() and (cpsr.n.read() == cpsr.z.read()), // GT - Greater than
0xC => !cpsr.z.read() and (cpsr.n.read() == cpsr.v.read()), // GT - Greater than
0xD => cpsr.z.read() or (cpsr.n.read() != cpsr.v.read()), // LE - Less than or equal
0xE => true, // AL - Always
0xF => std.debug.panic("[CPU] 0xF is a reserved condition field", .{}),

View File

@ -1,7 +1,7 @@
const std = @import("std");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const CPSR = @import("../cpu.zig").PSR;
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const CPSR = @import("../../cpu.zig").PSR;
pub fn exec(comptime S: bool, cpu: *Arm7tdmi, opcode: u32) u32 {
var shift_amt: u8 = undefined;

View File

@ -1,8 +1,8 @@
const std = @import("std");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, comptime W: bool, comptime L: bool) InstrFn {
return struct {
@ -12,9 +12,10 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
if (S and opcode >> 15 & 1 == 0) std.debug.panic("[CPU] TODO: STM/LDM with S set but R15 not in transfer list", .{});
var address: u32 = undefined;
if (U) {
// Increment
var address = if (P) base + 4 else base;
address = if (P) base + 4 else base;
var i: u5 = 0;
while (i < 0x10) : (i += 1) {
@ -23,24 +24,22 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
address += 4;
}
}
if (W and P or !P) cpu.r[rn] = address - 4;
} else {
// Decrement
var address = if (P) base - 4 else base;
address = if (P) base - 4 else base;
var i: u5 = 0x10;
while (i > 0) : (i -= 1) {
const reg_idx = i - 1;
const j = i - 1;
if (opcode >> reg_idx & 1 == 1) {
transfer(cpu, bus, reg_idx, address);
if (opcode >> j & 1 == 1) {
transfer(cpu, bus, j, address);
address -= 4;
}
}
if (W and P or !P) cpu.r[rn] = address + 4;
}
if (W and P or !P) cpu.r[rn] = if (U) address else address + 4;
}
fn transfer(cpu: *Arm7tdmi, bus: *Bus, i: u5, address: u32) void {

View File

@ -1,9 +1,9 @@
const std = @import("std");
const util = @import("../util.zig");
const util = @import("../../util.zig");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn branch(comptime L: bool) InstrFn {
return struct {

View File

@ -1,9 +1,9 @@
const std = @import("std");
const BarrelShifter = @import("barrel_shifter.zig");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime instrKind: u4) InstrFn {
return struct {

View File

@ -1,9 +1,9 @@
const std = @import("std");
const util = @import("../util.zig");
const util = @import("../../util.zig");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn halfAndSignedDataTransfer(comptime P: bool, comptime U: bool, comptime I: bool, comptime W: bool, comptime L: bool) InstrFn {
return struct {

View File

@ -1,8 +1,8 @@
const std = @import("std");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn psrTransfer(comptime I: bool, comptime isSpsr: bool) InstrFn {
return struct {
@ -24,15 +24,13 @@ pub fn psrTransfer(comptime I: bool, comptime isSpsr: bool) InstrFn {
switch (@truncate(u3, opcode >> 16)) {
0b000 => {
const right = if (I) std.math.rotr(u32, opcode & 0xFF, opcode >> 8 & 0xF) else cpu.r[rm];
const right = if (I) std.math.rotr(u32, opcode & 0xFF, opcode >> 7 & 0xF) else cpu.r[rm];
if (isSpsr) {
std.debug.panic("[CPU] TODO: MSR (flags only) on SPSR_<current_mode> is unimplemented", .{});
} else {
cpu.cpsr.n.write(right >> 31 & 1 == 1);
cpu.cpsr.z.write(right >> 30 & 1 == 1);
cpu.cpsr.c.write(right >> 29 & 1 == 1);
cpu.cpsr.v.write(right >> 28 & 1 == 1);
const mask: u32 = 0xF000_0000;
cpu.cpsr.raw = (cpu.cpsr.raw & ~mask) | (right & mask);
}
},
0b001 => {

View File

@ -1,11 +1,11 @@
const std = @import("std");
const util = @import("../util.zig");
const util = @import("../../util.zig");
const BarrelShifter = @import("barrel_shifter.zig");
const Bus = @import("../Bus.zig");
const Arm7tdmi = @import("../cpu.zig").Arm7tdmi;
const CPSR = @import("../cpu.zig").PSR;
const InstrFn = @import("../cpu.zig").InstrFn;
const Bus = @import("../../Bus.zig");
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
const CPSR = @import("../../cpu.zig").PSR;
const InstrFn = @import("../../cpu.zig").InstrFn;
pub fn singleDataTransfer(comptime I: bool, comptime P: bool, comptime U: bool, comptime B: bool, comptime W: bool, comptime L: bool) InstrFn {
return struct {