This commit is contained in:
Polprzewodnikowy 2022-01-11 23:41:13 +01:00
parent 8615b7668b
commit 1be4836288
9 changed files with 66 additions and 38 deletions

6
.vscode/launch.json vendored
View File

@ -40,17 +40,15 @@
"linux": { "linux": {
"args": [ "args": [
"-f", "/dev/ttyUSB0", "-f", "/dev/ttyUSB0",
"-b", "3", "-b", "4",
"-q", "-q",
"sw/n64/build/n64boot.bin",
] ]
}, },
"windows": { "windows": {
"args": [ "args": [
"-f", "\\\\.\\D:", "-f", "\\\\.\\D:",
"-b", "3", "-b", "4",
"-q", "-q",
"sw/n64/build/n64boot.bin",
] ]
} }
}, },

View File

@ -2,7 +2,7 @@
#include "exception.h" #include "exception.h"
void error_display (const char *message) { void error_display (const char *fmt, ...) {
EXCEPTION_TRIGGER(TRIGGER_CODE_ERROR); EXCEPTION_TRIGGER(TRIGGER_CODE_ERROR);
while (1); while (1);
} }

View File

@ -2,7 +2,7 @@
#define ERROR_H__ #define ERROR_H__
void error_display (const char *message); void error_display (const char *fmt, ...);
#endif #endif

View File

@ -147,21 +147,29 @@ static void exception_draw_character (int x, int y, char c) {
} }
} }
static void exception_print_string (int x, int y, const char *s) { static void exception_print_string (int *x, int *y, const char *s) {
int line_x = *x;
while (*s != '\0') { while (*s != '\0') {
exception_draw_character(x, y, *s++); if (*s == '\n') {
x += FONT_WIDTH; line_x = BORDER_WIDTH;
*y += LINE_HEIGHT;
s++;
} else {
exception_draw_character(line_x, *y, *s++);
line_x += FONT_WIDTH;
}
} }
} }
static void exception_print (int *x, int *y, const char* fmt, ...) { static void exception_print (int *x, int *y, const char* fmt, ...) {
char line[80]; char line[256];
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
vsniprintf(line, sizeof(line), fmt, args); vsniprintf(line, sizeof(line), fmt, args);
exception_print_string(*x, *y, line); exception_print_string(x, y, line);
*y += LINE_HEIGHT; *y += LINE_HEIGHT;
va_end(args); va_end(args);
@ -199,8 +207,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
exception_init_screen(); exception_init_screen();
exception_print(&x, &y, "%s at pc: 0x%08lX", exception_get_description(exception_code), e->epc.u32); exception_print(&x, &y, "%s at pc: 0x%08lX\n", exception_get_description(exception_code), e->epc.u32);
exception_print(&x, &y, "");
exception_print(&x, &y, "sr: 0x%08lX, cr: 0x%08lX", e->sr, e->cr); exception_print(&x, &y, "sr: 0x%08lX, cr: 0x%08lX", e->sr, e->cr);
exception_print(&x, &y, "zr: 0x%08lX, at: 0x%08lX, v0: 0x%08lX, v1: 0x%08lX", e->zr.u32, e->at.u32, e->v0.u32, e->v1.u32); exception_print(&x, &y, "zr: 0x%08lX, at: 0x%08lX, v0: 0x%08lX, v1: 0x%08lX", e->zr.u32, e->at.u32, e->v0.u32, e->v1.u32);
exception_print(&x, &y, "a0: 0x%08lX, a1: 0x%08lX, a2: 0x%08lX, a3: 0x%08lX", e->a0.u32, e->a1.u32, e->a2.u32, e->a3.u32); exception_print(&x, &y, "a0: 0x%08lX, a1: 0x%08lX, a2: 0x%08lX, a3: 0x%08lX", e->a0.u32, e->a1.u32, e->a2.u32, e->a3.u32);
@ -209,12 +216,9 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
exception_print(&x, &y, "s0: 0x%08lX, s1: 0x%08lX, s2: 0x%08lX, s3: 0x%08lX", e->s0.u32, e->s1.u32, e->s2.u32, e->s3.u32); exception_print(&x, &y, "s0: 0x%08lX, s1: 0x%08lX, s2: 0x%08lX, s3: 0x%08lX", e->s0.u32, e->s1.u32, e->s2.u32, e->s3.u32);
exception_print(&x, &y, "s4: 0x%08lX, s5: 0x%08lX, s6: 0x%08lX, s7: 0x%08lX", e->s4.u32, e->s5.u32, e->s6.u32, e->s7.u32); exception_print(&x, &y, "s4: 0x%08lX, s5: 0x%08lX, s6: 0x%08lX, s7: 0x%08lX", e->s4.u32, e->s5.u32, e->s6.u32, e->s7.u32);
exception_print(&x, &y, "t8: 0x%08lX, t9: 0x%08lX, k0: 0x%08lX, k1: 0x%08lX", e->t8.u32, e->t9.u32, e->k0.u32, e->k1.u32); exception_print(&x, &y, "t8: 0x%08lX, t9: 0x%08lX, k0: 0x%08lX, k1: 0x%08lX", e->t8.u32, e->t9.u32, e->k0.u32, e->k1.u32);
exception_print(&x, &y, "gp: 0x%08lX, sp: 0x%08lX, fp: 0x%08lX, ra: 0x%08lX", e->gp.u32, e->sp.u32, e->fp.u32, e->ra.u32); exception_print(&x, &y, "gp: 0x%08lX, sp: 0x%08lX, fp: 0x%08lX, ra: 0x%08lX\n", e->gp.u32, e->sp.u32, e->fp.u32, e->ra.u32);
exception_print(&x, &y, ""); exception_print(&x, &y, "0x%08lX: 0x%08lX = [%4s]\n", (uint32_t) (&SC64->VERSION), sc64_version, (char *) (&sc64_version));
exception_print(&x, &y, "0x%08lX: 0x%08lX = [%4s]", (uint32_t) (&SC64->VERSION), sc64_version, (char *) (&sc64_version)); exception_print(&x, &y, "------------------------------------------------------------------------\n");
exception_print(&x, &y, "");
exception_print(&x, &y, "------------------------------------------------------------------------");
exception_print(&x, &y, "");
if (exception_code == EXCEPTION_INTERRUPT) { if (exception_code == EXCEPTION_INTERRUPT) {
if (interrupt_mask & INTERRUPT_MASK_TIMER) { if (interrupt_mask & INTERRUPT_MASK_TIMER) {
@ -224,14 +228,12 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
uint32_t code = (((*instruction_address) & SYSCALL_CODE_MASK) >> SYSCALL_CODE_BIT); uint32_t code = (((*instruction_address) & SYSCALL_CODE_MASK) >> SYSCALL_CODE_BIT);
if (code == TRIGGER_CODE_ERROR) { if (code == TRIGGER_CODE_ERROR) {
const char *message = (const char *) (e->a0.u32); exception_print(&x, &y, (const char *) (e->a0.u32), e->a1.u32, e->a2.u32, e->a3.u32);
exception_print(&x, &y, "%s", message);
} else if (code == TRIGGER_CODE_ASSERT) { } else if (code == TRIGGER_CODE_ASSERT) {
const char *file = (const char *) (e->a0.u32); const char *file = (const char *) (e->a0.u32);
int line = (int) (e->a1.u32); int line = (int) (e->a1.u32);
const char *func = (const char *) (e->a2.u32); const char *func = (const char *) (e->a2.u32);
const char *failedexpr = (const char *) (e->a3.u32); const char *failedexpr = (const char *) (e->a3.u32);
exception_print(&x, &y, "Assertion \"%s\" failed:", failedexpr); exception_print(&x, &y, "Assertion \"%s\" failed:", failedexpr);
exception_print(&x, &y, " file \"%s\", line %d, %s%s", file, line, func ? "function: " : "", func); exception_print(&x, &y, " file \"%s\", line %d, %s%s", file, line, func ? "function: " : "", func);
} }

View File

@ -4,8 +4,8 @@
#define EXCEPTION_TRIGGER(code) { asm volatile ("syscall %[c]\n" :: [c] "i" (code)); } #define EXCEPTION_TRIGGER(code) { asm volatile ("syscall %[c]\n" :: [c] "i" (code)); }
#define TRIGGER_CODE_ERROR (0) #define TRIGGER_CODE_ERROR (0)
#define TRIGGER_CODE_ASSERT (1) #define TRIGGER_CODE_ASSERT (16)
#endif #endif

View File

@ -25,12 +25,12 @@ void main (void) {
boot_info.device_type = BOOT_DEVICE_TYPE_DD; boot_info.device_type = BOOT_DEVICE_TYPE_DD;
break; break;
case BOOT_MODE_DIRECT: case BOOT_MODE_MENU_USB:
storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info); storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info);
break; break;
default: default:
error_display("Unknown boot mode selected"); error_display("Unknown boot mode selected [%d]", sc64_info.boot_mode);
break; break;
} }

View File

@ -71,6 +71,7 @@ typedef enum {
BOOT_MODE_ROM = 1, BOOT_MODE_ROM = 1,
BOOT_MODE_DDIPL = 2, BOOT_MODE_DDIPL = 2,
BOOT_MODE_DIRECT = 3, BOOT_MODE_DIRECT = 3,
BOOT_MODE_MENU_USB = 4,
} boot_mode_t; } boot_mode_t;
typedef struct { typedef struct {

View File

@ -5,9 +5,35 @@
#include "fatfs/ff.h" #include "fatfs/ff.h"
#define FF_CHECK(x) { \ static const char *fatfs_error_codes[] = {
"Succeeded [0]",
"A hard error occurred in the low level disk I/O layer [1]",
"Assertion failed [2]",
"The physical drive cannot work [3]",
"Could not find the file [4]",
"Could not find the path [5]",
"The path name format is invalid [6]",
"Access denied due to prohibited access or directory full [7]",
"Access denied due to prohibited access [8]",
"The file/directory object is invalid [9]",
"The physical drive is write protected [10]",
"The logical drive number is invalid [11]",
"The volume has no work area [12]",
"There is no valid FAT volume [13]",
"The f_mkfs() aborted due to any problem [14]",
"Could not get a grant to access the volume within defined period [15]",
"The operation is rejected according to the file sharing policy [16]",
"LFN working buffer could not be allocated [17]",
"Number of open files > FF_FS_LOCK [18]",
"Given parameter is invalid [19]",
};
#define FF_CHECK(x, message) { \
FRESULT fatfs_result = x; \ FRESULT fatfs_result = x; \
assert(fatfs_result == FR_OK); \ if (fatfs_result != FR_OK) { \
error_display("%s:\n %s", message, fatfs_error_codes[fatfs_result]); \
} \
} }
@ -16,20 +42,20 @@ void storage_run_menu (storage_backend_t storage_backend, boot_info_t *boot_info
FIL fil; FIL fil;
if (storage_backend == STORAGE_BACKEND_SD) { if (storage_backend == STORAGE_BACKEND_SD) {
FF_CHECK(f_mount(&fs, "0:", 1)); FF_CHECK(f_mount(&fs, "0:", 1), "Couldn't mount SD drive");
FF_CHECK(f_chdrive("0:")); FF_CHECK(f_chdrive("0:"), "Couldn't chdrive to SD drive");
} else if (storage_backend == STORAGE_BACKEND_USB) { } else if (storage_backend == STORAGE_BACKEND_USB) {
FF_CHECK(f_mount(&fs, "1:", 1)); FF_CHECK(f_mount(&fs, "1:", 1), "Couldn't mount USB drive");
FF_CHECK(f_chdrive("1:")); FF_CHECK(f_chdrive("1:"), "Couldn't chdrive to USB drive");
} else { } else {
error_display("Unknown storage backend"); error_display("Unknown storage backend [%d]", storage_backend);
} }
FF_CHECK(f_open(&fil, "sc64menu.elf", FA_READ)); FF_CHECK(f_open(&fil, "sc64menu.elf", FA_READ), "Couldn't open menu file");
// TODO: Implement ELF loader here // TODO: Implement ELF loader here
FF_CHECK(f_close(&fil)); FF_CHECK(f_close(&fil), "Couldn't close menu file");
// TODO: Execute ELF here // TODO: Execute ELF here
// menu(&boot_info, &sc64_info); // menu(&boot_info, &sc64_info);

View File

@ -264,20 +264,21 @@ class SC64:
def set_boot_mode(self, mode: int) -> None: def set_boot_mode(self, mode: int) -> None:
if (mode >= 0 and mode <= 3): if (mode >= 0 and mode <= 4):
self.__change_config(self.__CFG_ID_BOOT_MODE, mode) self.__change_config(self.__CFG_ID_BOOT_MODE, mode)
else: else:
raise SC64Exception("Boot mode outside of supported values") raise SC64Exception("Boot mode outside of supported values")
def get_boot_mode_label(self, mode: int) -> None: def get_boot_mode_label(self, mode: int) -> None:
if (mode < 0 or mode > 3): if (mode < 0 or mode > 4):
return "Unknown" return "Unknown"
return { return {
0: "Load menu from SD card", 0: "Load menu from SD card",
1: "Load ROM from SDRAM through bootloader", 1: "Load ROM from SDRAM through bootloader",
2: "Load DDIPL from SDRAM", 2: "Load DDIPL from SDRAM",
3: "Load ROM from SDRAM directly without bootloader" 3: "Load ROM from SDRAM directly without bootloader",
4: "Load menu from USB",
}[mode] }[mode]