chore: misc pipeline fixes
This commit is contained in:
parent
69cf5b12f1
commit
6da9e965bb
|
@ -329,8 +329,8 @@ pub const Arm7tdmi = struct {
|
||||||
if (!self.bus.io.ime or self.cpsr.i.read()) return;
|
if (!self.bus.io.ime or self.cpsr.i.read()) return;
|
||||||
// log.debug("An interrupt was Handled!", .{});
|
// log.debug("An interrupt was Handled!", .{});
|
||||||
|
|
||||||
// retAddr.gba says r15 on it's own is off by -04h in both ARM and THUMB mode
|
// FIXME: Is the return address ahead?
|
||||||
const r15 = self.r[15] + 4;
|
const r15 = self.r[15];
|
||||||
const cpsr = self.cpsr.raw;
|
const cpsr = self.cpsr.raw;
|
||||||
|
|
||||||
self.changeMode(.Irq);
|
self.changeMode(.Irq);
|
||||||
|
@ -354,10 +354,6 @@ pub const Arm7tdmi = struct {
|
||||||
return self.bus.read(T, self.r[15]);
|
return self.bus.read(T, self.r[15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fakePC(self: *const Self) u32 {
|
|
||||||
return self.r[15] + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_log(self: *const Self, file: *const File, opcode: u32) void {
|
fn debug_log(self: *const Self, file: *const File, opcode: u32) void {
|
||||||
if (self.binary_log) {
|
if (self.binary_log) {
|
||||||
self.skyLog(file) catch unreachable;
|
self.skyLog(file) catch unreachable;
|
||||||
|
|
|
@ -55,8 +55,10 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
|
||||||
|
|
||||||
if (L) {
|
if (L) {
|
||||||
cpu.r[15] = bus.read(u32, und_addr);
|
cpu.r[15] = bus.read(u32, und_addr);
|
||||||
|
cpu.pipe.flush();
|
||||||
} else {
|
} else {
|
||||||
bus.write(u32, und_addr, cpu.r[15] + 8);
|
// FIXME: Should r15 on write be +12 ahead?
|
||||||
|
bus.write(u32, und_addr, cpu.r[15] + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.r[rn] = if (U) cpu.r[rn] + 0x40 else cpu.r[rn] - 0x40;
|
cpu.r[rn] = if (U) cpu.r[rn] + 0x40 else cpu.r[rn] - 0x40;
|
||||||
|
@ -100,9 +102,9 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
|
||||||
// Always Transfer User mode Registers
|
// Always Transfer User mode Registers
|
||||||
// This happens regardless if r15 is in the list
|
// This happens regardless if r15 is in the list
|
||||||
const value = cpu.getUserModeRegister(i);
|
const value = cpu.getUserModeRegister(i);
|
||||||
bus.write(u32, address, value + if (i == 0xF) 8 else @as(u32, 0)); // PC is already 4 ahead to make 12
|
bus.write(u32, address, value + if (i == 0xF) 4 else @as(u32, 0)); // PC is already 8 ahead to make 12
|
||||||
} else {
|
} else {
|
||||||
bus.write(u32, address, cpu.r[i] + if (i == 0xF) 8 else @as(u32, 0));
|
bus.write(u32, address, cpu.r[i] + if (i == 0xF) 4 else @as(u32, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,20 +15,8 @@ pub fn halfAndSignedDataTransfer(comptime P: bool, comptime U: bool, comptime I:
|
||||||
const rm = opcode & 0xF;
|
const rm = opcode & 0xF;
|
||||||
const imm_offset_high = opcode >> 8 & 0xF;
|
const imm_offset_high = opcode >> 8 & 0xF;
|
||||||
|
|
||||||
var base: u32 = undefined;
|
const base = cpu.r[rn] + if (!L) 4 else @as(u32, 0);
|
||||||
if (rn == 0xF) {
|
const offset = if (I) imm_offset_high << 4 | rm else cpu.r[rm];
|
||||||
base = cpu.fakePC();
|
|
||||||
if (!L) base += 4;
|
|
||||||
} else {
|
|
||||||
base = cpu.r[rn];
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset: u32 = undefined;
|
|
||||||
if (I) {
|
|
||||||
offset = imm_offset_high << 4 | rm;
|
|
||||||
} else {
|
|
||||||
offset = cpu.r[rm];
|
|
||||||
}
|
|
||||||
|
|
||||||
const modified_base = if (U) base +% offset else base -% offset;
|
const modified_base = if (U) base +% offset else base -% offset;
|
||||||
var address = if (P) modified_base else base;
|
var address = if (P) modified_base else base;
|
||||||
|
|
|
@ -14,8 +14,8 @@ pub fn singleDataTransfer(comptime I: bool, comptime P: bool, comptime U: bool,
|
||||||
const rn = opcode >> 16 & 0xF;
|
const rn = opcode >> 16 & 0xF;
|
||||||
const rd = opcode >> 12 & 0xF;
|
const rd = opcode >> 12 & 0xF;
|
||||||
|
|
||||||
// If L is set, there is an offset of 12 from the instruction to the PC
|
// rn is r15 and L is not set, the PC is 12 ahead
|
||||||
const base = cpu.r[rn] + if (!L) 4 else @as(u32, 0);
|
const base = cpu.r[rn] + if (!L and rn == 0xF) 4 else @as(u32, 0);
|
||||||
|
|
||||||
const offset = if (I) shifter.immShift(false, cpu, opcode) else opcode & 0xFFF;
|
const offset = if (I) shifter.immShift(false, cpu, opcode) else opcode & 0xFFF;
|
||||||
|
|
||||||
|
@ -35,11 +35,11 @@ pub fn singleDataTransfer(comptime I: bool, comptime P: bool, comptime U: bool,
|
||||||
} else {
|
} else {
|
||||||
if (B) {
|
if (B) {
|
||||||
// STRB
|
// STRB
|
||||||
const value = if (rd == 0xF) cpu.r[rd] + 8 else cpu.r[rd];
|
const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0); // PC is 12 ahead
|
||||||
bus.write(u8, address, @truncate(u8, value));
|
bus.write(u8, address, @truncate(u8, value));
|
||||||
} else {
|
} else {
|
||||||
// STR
|
// STR
|
||||||
const value = if (rd == 0xF) cpu.r[rd] + 8 else cpu.r[rd];
|
const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0);
|
||||||
bus.write(u32, address, value);
|
bus.write(u32, address, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue