chore: more detailed panic message
This commit is contained in:
		
							
								
								
									
										70
									
								
								src/cpu.zig
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								src/cpu.zig
									
									
									
									
									
								
							@@ -109,14 +109,16 @@ pub const Arm7tdmi = struct {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub inline fn hasSPSR(self: *const Self) bool {
 | 
			
		||||
        return switch (getMode(self.cpsr.mode.read())) {
 | 
			
		||||
        const mode = getMode(self.cpsr.mode.read()) orelse unreachable;
 | 
			
		||||
        return switch (mode) {
 | 
			
		||||
            .System, .User => false,
 | 
			
		||||
            else => true,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub inline fn isPrivileged(self: *const Self) bool {
 | 
			
		||||
        return switch (getMode(self.cpsr.mode.read())) {
 | 
			
		||||
        const mode = getMode(self.cpsr.mode.read()) orelse unreachable;
 | 
			
		||||
        return switch (mode) {
 | 
			
		||||
            .User => false,
 | 
			
		||||
            else => true,
 | 
			
		||||
        };
 | 
			
		||||
@@ -128,11 +130,12 @@ pub const Arm7tdmi = struct {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn changeModeFromIdx(self: *Self, next: u5) void {
 | 
			
		||||
        self.changeMode(getMode(next));
 | 
			
		||||
        const mode = getMode(next) orelse unreachable;
 | 
			
		||||
        self.changeMode(mode);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn changeMode(self: *Self, next: Mode) void {
 | 
			
		||||
        const now = getMode(self.cpsr.mode.read());
 | 
			
		||||
        const now = getMode(self.cpsr.mode.read()) orelse unreachable;
 | 
			
		||||
 | 
			
		||||
        // Bank R8 -> r12
 | 
			
		||||
        var r: usize = 8;
 | 
			
		||||
@@ -233,6 +236,53 @@ pub const Arm7tdmi = struct {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn panic(self: *const Self, comptime format: []const u8, args: anytype) noreturn {
 | 
			
		||||
        var i: usize = 0;
 | 
			
		||||
        while (i < 16) : (i += 4) {
 | 
			
		||||
            const i_1 = i + 1;
 | 
			
		||||
            const i_2 = i + 2;
 | 
			
		||||
            const i_3 = i + 3;
 | 
			
		||||
            std.debug.print("R{}: 0x{X:0>8}\tR{}: 0x{X:0>8}\tR{}: 0x{X:0>8}\tR{}: 0x{X:0>8}\n", .{ i, self.r[i], i_1, self.r[i_1], i_2, self.r[i_2], i_3, self.r[i_3] });
 | 
			
		||||
        }
 | 
			
		||||
        std.debug.print("cpsr: 0x{X:0>8} ", .{self.cpsr.raw});
 | 
			
		||||
        prettyPrintPsr(&self.cpsr);
 | 
			
		||||
 | 
			
		||||
        std.debug.print("spsr: 0x{X:0>8} ", .{self.spsr.raw});
 | 
			
		||||
        prettyPrintPsr(&self.spsr);
 | 
			
		||||
 | 
			
		||||
        std.debug.print("tick: {}\n\n", .{self.sched.tick});
 | 
			
		||||
 | 
			
		||||
        std.debug.panic(format, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn prettyPrintPsr(psr: *const PSR) void {
 | 
			
		||||
        std.debug.print("[", .{});
 | 
			
		||||
 | 
			
		||||
        if (psr.n.read()) std.debug.print("N", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.z.read()) std.debug.print("Z", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.c.read()) std.debug.print("C", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.v.read()) std.debug.print("V", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.i.read()) std.debug.print("I", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.f.read()) std.debug.print("F", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        if (psr.t.read()) std.debug.print("T", .{}) else std.debug.print("-", .{});
 | 
			
		||||
        std.debug.print("|", .{});
 | 
			
		||||
        if (getMode(psr.mode.read())) |mode| std.debug.print("{s}", .{modeString(mode)}) else std.debug.print("---", .{});
 | 
			
		||||
 | 
			
		||||
        std.debug.print("]\n", .{});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn modeString(mode: Mode) []const u8 {
 | 
			
		||||
        return switch (mode) {
 | 
			
		||||
            .User => "usr",
 | 
			
		||||
            .Fiq => "fiq",
 | 
			
		||||
            .Irq => "irq",
 | 
			
		||||
            .Supervisor => "svc",
 | 
			
		||||
            .Abort => "abt",
 | 
			
		||||
            .Undefined => "und",
 | 
			
		||||
            .System => "sys",
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn skyLog(self: *const Self, file: *const File) !void {
 | 
			
		||||
        var buf: [18 * @sizeOf(u32)]u8 = undefined;
 | 
			
		||||
 | 
			
		||||
@@ -533,16 +583,16 @@ const Mode = enum(u5) {
 | 
			
		||||
    System = 0b11111,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn getMode(bits: u5) Mode {
 | 
			
		||||
    return std.meta.intToEnum(Mode, bits) catch unreachable;
 | 
			
		||||
pub fn getMode(bits: u5) ?Mode {
 | 
			
		||||
    return std.meta.intToEnum(Mode, bits) catch null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn armUndefined(_: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
fn armUndefined(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
    const id = armIdx(opcode);
 | 
			
		||||
    std.debug.panic("[CPU:ARM] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode });
 | 
			
		||||
    cpu.panic("[CPU:ARM] ID: 0x{X:0>3} 0x{X:0>8} is an illegal opcode", .{ id, opcode });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn thumbUndefined(_: *Arm7tdmi, _: *Bus, opcode: u16) void {
 | 
			
		||||
fn thumbUndefined(cpu: *Arm7tdmi, _: *Bus, opcode: u16) void {
 | 
			
		||||
    const id = thumbIdx(opcode);
 | 
			
		||||
    std.debug.panic("[CPU:THUMB] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode });
 | 
			
		||||
    cpu.panic("[CPU:THUMB] ID: 0b{b:0>10} 0x{X:0>2} is an illegal opcode", .{ id, opcode });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
 | 
			
		||||
            const rn = opcode >> 16 & 0xF;
 | 
			
		||||
            const base = cpu.r[rn];
 | 
			
		||||
 | 
			
		||||
            if (S and opcode >> 15 & 1 == 0) std.debug.panic("[CPU] TODO: STM/LDM with S set but R15 not in transfer list", .{});
 | 
			
		||||
            if (S and opcode >> 15 & 1 == 0) cpu.panic("[CPU] TODO: STM/LDM with S set but R15 not in transfer list", .{});
 | 
			
		||||
 | 
			
		||||
            var address: u32 = undefined;
 | 
			
		||||
            if (U) {
 | 
			
		||||
@@ -45,14 +45,14 @@ pub fn blockDataTransfer(comptime P: bool, comptime U: bool, comptime S: bool, c
 | 
			
		||||
        fn transfer(cpu: *Arm7tdmi, bus: *Bus, i: u5, address: u32) void {
 | 
			
		||||
            if (L) {
 | 
			
		||||
                cpu.r[i] = bus.read32(address);
 | 
			
		||||
                if (S and i == 0xF) std.debug.panic("[CPU] TODO: SPSR_<mode> is transferred to CPSR", .{});
 | 
			
		||||
                if (S and i == 0xF) cpu.panic("[CPU] TODO: SPSR_<mode> is transferred to CPSR", .{});
 | 
			
		||||
            } else {
 | 
			
		||||
                if (i == 0xF) {
 | 
			
		||||
                    if (!S) {
 | 
			
		||||
                        // TODO: Assure that this is Address of STM instruction + 12
 | 
			
		||||
                        bus.write32(address, cpu.r[i] + (12 - 4));
 | 
			
		||||
                    } else {
 | 
			
		||||
                        std.debug.panic("[CPU] TODO: STM with S set and R15 in transfer list", .{});
 | 
			
		||||
                        cpu.panic("[CPU] TODO: STM with S set and R15 in transfer list", .{});
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    bus.write32(address, cpu.r[i]);
 | 
			
		||||
 
 | 
			
		||||
@@ -47,12 +47,12 @@ pub fn halfAndSignedDataTransfer(comptime P: bool, comptime U: bool, comptime I:
 | 
			
		||||
                    0b10 => {
 | 
			
		||||
                        // LDRSB
 | 
			
		||||
                        cpu.r[rd] = util.u32SignExtend(8, @as(u32, bus.read8(address)));
 | 
			
		||||
                        std.debug.panic("[CPU|ARM|LDRSB] TODO: Affect the CPSR", .{});
 | 
			
		||||
                        cpu.panic("[CPU|ARM|LDRSB] TODO: Affect the CPSR", .{});
 | 
			
		||||
                    },
 | 
			
		||||
                    0b11 => {
 | 
			
		||||
                        // LDRSH
 | 
			
		||||
                        cpu.r[rd] = util.u32SignExtend(16, @as(u32, bus.read16(address)));
 | 
			
		||||
                        std.debug.panic("[CPU|ARM|LDRSH] TODO: Affect the CPSR", .{});
 | 
			
		||||
                        cpu.panic("[CPU|ARM|LDRSH] TODO: Affect the CPSR", .{});
 | 
			
		||||
                    },
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ pub fn psrTransfer(comptime I: bool, comptime R: bool, comptime kind: u2) InstrF
 | 
			
		||||
                        if (cpu.isPrivileged()) cpu.setCpsr(fieldMask(&cpu.cpsr, field_mask, right));
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                else => std.debug.panic("[CPU/PSR Transfer] Bits 21:220 of {X:0>8} are undefined", .{opcode}),
 | 
			
		||||
                else => cpu.panic("[CPU/PSR Transfer] Bits 21:220 of {X:0>8} are undefined", .{opcode}),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }.inner;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ pub fn format1(comptime op: u2, comptime offset: u5) InstrFn {
 | 
			
		||||
                0b00 => shifter.logicalLeft(true, &cpu.cpsr, cpu.r[rs], offset), // LSL
 | 
			
		||||
                0b01 => shifter.logicalRight(true, &cpu.cpsr, cpu.r[rs], offset), // LSR
 | 
			
		||||
                0b10 => shifter.arithmeticRight(true, &cpu.cpsr, cpu.r[rs], offset), // ASR
 | 
			
		||||
                else => std.debug.panic("[CPU|THUMB|Fmt1] {} is an invalid op", .{op}),
 | 
			
		||||
                else => cpu.panic("[CPU|THUMB|Fmt1] {} is an invalid op", .{op}),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Equivalent to an ARM MOVS
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@ const InstrFn = @import("../../cpu.zig").ThumbInstrFn;
 | 
			
		||||
 | 
			
		||||
pub fn format13(comptime _: bool) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn inner(_: *Arm7tdmi, _: *Bus, _: u16) void {
 | 
			
		||||
            std.debug.panic("[CPU|THUMB|Fmt13] Implement Format 13 THUMB Instructions", .{});
 | 
			
		||||
        fn inner(cpu: *Arm7tdmi, _: *Bus, _: u16) void {
 | 
			
		||||
            cpu.panic("[CPU|THUMB|Fmt13] Implement Format 13 THUMB Instructions", .{});
 | 
			
		||||
        }
 | 
			
		||||
    }.inner;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ pub fn format16(comptime cond: u4) InstrFn {
 | 
			
		||||
            const offset = u32SignExtend(8, opcode & 0xFF) << 1;
 | 
			
		||||
 | 
			
		||||
            const should_execute = switch (cond) {
 | 
			
		||||
                0xE, 0xF => std.debug.panic("[CPU/THUMB] Undefined conditional branch with condition {}", .{cond}),
 | 
			
		||||
                0xE, 0xF => cpu.panic("[CPU/THUMB] Undefined conditional branch with condition {}", .{cond}),
 | 
			
		||||
                else => checkCond(cpu.cpsr, cond),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ pub fn format5(comptime op: u2, comptime h1: u1, comptime h2: u1) InstrFn {
 | 
			
		||||
                    cpu.cpsr.t.write(cpu.r[src] & 1 == 1);
 | 
			
		||||
                    cpu.r[15] = cpu.r[src] & 0xFFFF_FFFE;
 | 
			
		||||
                },
 | 
			
		||||
                else => std.debug.panic("[CPU|THUMB|Fmt5] {} is an invalid op", .{op}),
 | 
			
		||||
                else => cpu.panic("[CPU|THUMB|Fmt5] {} is an invalid op", .{op}),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }.inner;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user