diff --git a/src/apu.zig b/src/apu.zig index f79a29a..c130ef7 100644 --- a/src/apu.zig +++ b/src/apu.zig @@ -30,6 +30,8 @@ pub const Apu = struct { cnt: io.SoundControl, sampling_cycle: u2, + + // TODO: Research whether we can have Atomic Pointers stream: *SDL.SDL_AudioStream, sched: *Scheduler, diff --git a/src/cpu/arm/psr_transfer.zig b/src/cpu/arm/psr_transfer.zig index 0ac0595..1049a21 100644 --- a/src/cpu/arm/psr_transfer.zig +++ b/src/cpu/arm/psr_transfer.zig @@ -24,12 +24,15 @@ pub fn psrTransfer(comptime I: bool, comptime R: bool, comptime kind: u2) InstrF // MSR const field_mask = @truncate(u4, opcode >> 16 & 0xF); const rm_idx = opcode & 0xF; - const right = if (I) rotr(u32, opcode & 0xFF, (opcode >> 8 & 0xF) << 1) else cpu.r[rm_idx]; + const right = if (I) rotr(u32, opcode & 0xFF, (opcode >> 8 & 0xF) * 2) else cpu.r[rm_idx]; if (R and !cpu.hasSPSR()) log.err("Tried to write to SPSR in User/System Mode", .{}); if (R) { - if (cpu.isPrivileged()) cpu.spsr.raw = fieldMask(&cpu.spsr, field_mask, right); + // arm.gba seems to expect the SPSR to do somethign in SYS mode, + // so we just assume that despite writing to the SPSR in USR or SYS mode + // being UNPREDICTABLE, it just magically has a working SPSR somehow + cpu.spsr.raw = fieldMask(&cpu.spsr, field_mask, right); } else { if (cpu.isPrivileged()) cpu.setCpsr(fieldMask(&cpu.cpsr, field_mask, right)); } @@ -41,6 +44,8 @@ pub fn psrTransfer(comptime I: bool, comptime R: bool, comptime kind: u2) InstrF } fn fieldMask(psr: *const PSR, field_mask: u4, right: u32) u32 { + // This bitwise ORs bits 3 and 0 of the field mask into a u2 + // We do this because we only care about bits 7:0 and 31:28 of the CPSR const bits = @truncate(u2, (field_mask >> 2 & 0x2) | (field_mask & 1)); const mask: u32 = switch (bits) { diff --git a/src/main.zig b/src/main.zig index 4ca2075..0f7b1ca 100644 --- a/src/main.zig +++ b/src/main.zig @@ -266,6 +266,7 @@ fn initAudio(apu: *Apu) SDL.SDL_AudioDeviceID { return dev; } +// FIXME: Sometimes, we hear garbage upon program start. Why? export fn audioCallback(userdata: ?*anyopaque, stream: [*c]u8, len: c_int) void { const apu = @ptrCast(*Apu, @alignCast(8, userdata)); _ = SDL.SDL_AudioStreamGet(apu.stream, stream, len);