Compare commits
No commits in common. "ae37b1218bc6b4c6b82c41e725f84535158d6878" and "77dba68a0b518ecade9cbdae60071a2d7ef1217a" have entirely different histories.
ae37b1218b
...
77dba68a0b
20
src/cpu.zig
20
src/cpu.zig
|
@ -1,19 +1,19 @@
|
|||
const std = @import("std");
|
||||
const util = @import("util.zig");
|
||||
|
||||
const BarrelShifter = @import("cpu/arm/barrel_shifter.zig");
|
||||
const BarrelShifter = @import("cpu/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/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;
|
||||
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;
|
||||
|
||||
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(), // NE - Not equal
|
||||
0x1 => !cpsr.z.read(), // NEQ - 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.v.read()), // GT - Greater than
|
||||
0xC => !cpsr.z.read() and (cpsr.n.read() == cpsr.z.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", .{}),
|
||||
|
|
|
@ -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;
|
|
@ -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,10 +12,9 @@ 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
|
||||
address = if (P) base + 4 else base;
|
||||
var address = if (P) base + 4 else base;
|
||||
|
||||
var i: u5 = 0;
|
||||
while (i < 0x10) : (i += 1) {
|
||||
|
@ -24,22 +23,24 @@ 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
|
||||
address = if (P) base - 4 else base;
|
||||
var address = if (P) base - 4 else base;
|
||||
|
||||
var i: u5 = 0x10;
|
||||
while (i > 0) : (i -= 1) {
|
||||
const j = i - 1;
|
||||
const reg_idx = i - 1;
|
||||
|
||||
if (opcode >> j & 1 == 1) {
|
||||
transfer(cpu, bus, j, address);
|
||||
if (opcode >> reg_idx & 1 == 1) {
|
||||
transfer(cpu, bus, reg_idx, address);
|
||||
address -= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (W and P or !P) cpu.r[rn] = if (U) address else address + 4;
|
||||
if (W and P or !P) cpu.r[rn] = address + 4;
|
||||
}
|
||||
}
|
||||
|
||||
fn transfer(cpu: *Arm7tdmi, bus: *Bus, i: u5, address: u32) void {
|
|
@ -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 {
|
|
@ -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 {
|
|
@ -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 {
|
|
@ -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,13 +24,15 @@ 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 >> 7 & 0xF) else cpu.r[rm];
|
||||
const right = if (I) std.math.rotr(u32, opcode & 0xFF, opcode >> 8 & 0xF) else cpu.r[rm];
|
||||
|
||||
if (isSpsr) {
|
||||
std.debug.panic("[CPU] TODO: MSR (flags only) on SPSR_<current_mode> is unimplemented", .{});
|
||||
} else {
|
||||
const mask: u32 = 0xF000_0000;
|
||||
cpu.cpsr.raw = (cpu.cpsr.raw & ~mask) | (right & mask);
|
||||
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);
|
||||
}
|
||||
},
|
||||
0b001 => {
|
|
@ -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 {
|
Loading…
Reference in New Issue