Compare commits
2 Commits
85b9ecb75c
...
b8a7c212b2
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | b8a7c212b2 | |
Rekai Nyangadzayi Musuka | e0d67a9e54 |
41
src/arm.zig
41
src/arm.zig
|
@ -172,6 +172,10 @@ pub fn Arm32(comptime arch: Architecture) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn isHalted(self: *const Self) bool {
|
||||||
|
return self.bus.io.haltcnt == .Halt;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setCpsr(self: *Self, value: u32) void {
|
pub fn setCpsr(self: *Self, value: u32) void {
|
||||||
if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(u5, value & 0x1F));
|
if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(u5, value & 0x1F));
|
||||||
self.cpsr.raw = value;
|
self.cpsr.raw = value;
|
||||||
|
@ -300,6 +304,43 @@ pub fn Arm32(comptime arch: Architecture) type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stepDmaTransfer(self: *Self) bool {
|
||||||
|
inline for (0..4) |i| {
|
||||||
|
if (self.bus.dma[i].in_progress) {
|
||||||
|
self.bus.dma[i].step(self);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handleInterrupt(self: *Self) void {
|
||||||
|
const should_handle = self.bus.io.ie.raw & self.bus.io.irq.raw;
|
||||||
|
|
||||||
|
// Return if IME is disabled, CPSR I is set or there is nothing to handle
|
||||||
|
if (!self.bus.io.ime or self.cpsr.i.read() or should_handle == 0) return;
|
||||||
|
|
||||||
|
// If Pipeline isn't full, we have a bug
|
||||||
|
std.debug.assert(self.pipe.isFull());
|
||||||
|
|
||||||
|
// log.debug("Handling Interrupt!", .{});
|
||||||
|
self.bus.io.haltcnt = .Execute;
|
||||||
|
|
||||||
|
// FIXME: This seems weird, but retAddr.gba suggests I need to make these changes
|
||||||
|
const ret_addr = self.r[15] - if (self.cpsr.t.read()) 0 else @as(u32, 4);
|
||||||
|
const new_spsr = self.cpsr.raw;
|
||||||
|
|
||||||
|
self.changeMode(.Irq);
|
||||||
|
self.cpsr.t.write(false);
|
||||||
|
self.cpsr.i.write(true);
|
||||||
|
|
||||||
|
self.r[14] = ret_addr;
|
||||||
|
self.spsr.raw = new_spsr;
|
||||||
|
self.r[15] = 0x0000_0018;
|
||||||
|
self.pipe.reload(self);
|
||||||
|
}
|
||||||
|
|
||||||
inline fn fetch(self: *Self, comptime T: type, address: u32) T {
|
inline fn fetch(self: *Self, comptime T: type, address: u32) T {
|
||||||
comptime std.debug.assert(T == u32 or T == u16); // Opcode may be 32-bit (ARM) or 16-bit (THUMB)
|
comptime std.debug.assert(T == u32 or T == u16); // Opcode may be 32-bit (ARM) or 16-bit (THUMB)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue