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": {
"args": [
"-f", "/dev/ttyUSB0",
"-b", "3",
"-b", "4",
"-q",
"sw/n64/build/n64boot.bin",
]
},
"windows": {
"args": [
"-f", "\\\\.\\D:",
"-b", "3",
"-b", "4",
"-q",
"sw/n64/build/n64boot.bin",
]
}
},

View File

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

View File

@ -2,7 +2,7 @@
#define ERROR_H__
void error_display (const char *message);
void error_display (const char *fmt, ...);
#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') {
exception_draw_character(x, y, *s++);
x += FONT_WIDTH;
if (*s == '\n') {
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, ...) {
char line[80];
char line[256];
va_list args;
va_start(args, fmt);
vsniprintf(line, sizeof(line), fmt, args);
exception_print_string(*x, *y, line);
exception_print_string(x, y, line);
*y += LINE_HEIGHT;
va_end(args);
@ -199,8 +207,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
exception_init_screen();
exception_print(&x, &y, "%s at pc: 0x%08lX", exception_get_description(exception_code), e->epc.u32);
exception_print(&x, &y, "");
exception_print(&x, &y, "%s at pc: 0x%08lX\n", exception_get_description(exception_code), e->epc.u32);
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, "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, "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, "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, "");
exception_print(&x, &y, "0x%08lX: 0x%08lX = [%4s]", (uint32_t) (&SC64->VERSION), sc64_version, (char *) (&sc64_version));
exception_print(&x, &y, "");
exception_print(&x, &y, "------------------------------------------------------------------------");
exception_print(&x, &y, "");
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, "0x%08lX: 0x%08lX = [%4s]\n", (uint32_t) (&SC64->VERSION), sc64_version, (char *) (&sc64_version));
exception_print(&x, &y, "------------------------------------------------------------------------\n");
if (exception_code == EXCEPTION_INTERRUPT) {
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);
if (code == TRIGGER_CODE_ERROR) {
const char *message = (const char *) (e->a0.u32);
exception_print(&x, &y, "%s", message);
exception_print(&x, &y, (const char *) (e->a0.u32), e->a1.u32, e->a2.u32, e->a3.u32);
} else if (code == TRIGGER_CODE_ASSERT) {
const char *file = (const char *) (e->a0.u32);
int line = (int) (e->a1.u32);
const char *func = (const char *) (e->a2.u32);
const char *failedexpr = (const char *) (e->a3.u32);
exception_print(&x, &y, "Assertion \"%s\" failed:", failedexpr);
exception_print(&x, &y, " file \"%s\", line %d, %s%s", file, line, func ? "function: " : "", func);
}

View File

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

View File

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

View File

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

View File

@ -5,9 +5,35 @@
#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; \
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;
if (storage_backend == STORAGE_BACKEND_SD) {
FF_CHECK(f_mount(&fs, "0:", 1));
FF_CHECK(f_chdrive("0:"));
FF_CHECK(f_mount(&fs, "0:", 1), "Couldn't mount SD drive");
FF_CHECK(f_chdrive("0:"), "Couldn't chdrive to SD drive");
} else if (storage_backend == STORAGE_BACKEND_USB) {
FF_CHECK(f_mount(&fs, "1:", 1));
FF_CHECK(f_chdrive("1:"));
FF_CHECK(f_mount(&fs, "1:", 1), "Couldn't mount USB drive");
FF_CHECK(f_chdrive("1:"), "Couldn't chdrive to USB drive");
} 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
FF_CHECK(f_close(&fil));
FF_CHECK(f_close(&fil), "Couldn't close menu file");
// TODO: Execute ELF here
// menu(&boot_info, &sc64_info);

View File

@ -264,20 +264,21 @@ class SC64:
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)
else:
raise SC64Exception("Boot mode outside of supported values")
def get_boot_mode_label(self, mode: int) -> None:
if (mode < 0 or mode > 3):
if (mode < 0 or mode > 4):
return "Unknown"
return {
0: "Load menu from SD card",
1: "Load ROM from SDRAM through bootloader",
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]