mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
97 lines
3.3 KiB
C
97 lines
3.3 KiB
C
#include "error.h"
|
|
#include "fatfs/ff.h"
|
|
#include "init.h"
|
|
#include "io.h"
|
|
#include "menu.h"
|
|
|
|
|
|
extern const void __bootloader_start __attribute__((section(".data")));
|
|
extern const void __bootloader_end __attribute__((section(".data")));
|
|
|
|
|
|
#define ROM_ENTRY_OFFSET (8)
|
|
#define ROM_CODE_OFFSET (4096)
|
|
#define ROM_MAX_LOAD_SIZE (1 * 1024 * 1024)
|
|
|
|
|
|
static const char *fatfs_error_codes[] = {
|
|
"Succeeded",
|
|
"A hard error occurred in the low level disk I/O layer",
|
|
"Assertion failed",
|
|
"The physical drive cannot work",
|
|
"Could not find the file",
|
|
"Could not find the path",
|
|
"The path name format is invalid",
|
|
"Access denied due to prohibited access or directory full",
|
|
"Access denied due to prohibited access",
|
|
"The file/directory object is invalid",
|
|
"The physical drive is write protected",
|
|
"The logical drive number is invalid",
|
|
"The volume has no work area",
|
|
"There is no valid FAT volume",
|
|
"The f_mkfs() aborted due to any problem",
|
|
"Could not get a grant to access the volume within defined period",
|
|
"The operation is rejected according to the file sharing policy",
|
|
"LFN working buffer could not be allocated",
|
|
"Number of open files > FF_FS_LOCK",
|
|
"Given parameter is invalid",
|
|
};
|
|
|
|
|
|
#define FF_CHECK(x, message, ...) { \
|
|
fresult = x; \
|
|
if (fresult != FR_OK) { \
|
|
error_display(message " [%s]:\n %s\n", __VA_ARGS__ __VA_OPT__(,) #x, fatfs_error_codes[fresult]); \
|
|
} \
|
|
}
|
|
|
|
|
|
static void menu_check_load_address (void *address, size_t size) {
|
|
void *menu_start = address;
|
|
void *menu_end = (address + size);
|
|
void *usable_ram_start = (void *) (0x80000400UL);
|
|
void *usable_ram_end = (void *) (0x80400000UL);
|
|
void *bootloader_start = (void *) (&__bootloader_start);
|
|
void *bootloader_end = (void *) (&__bootloader_end);
|
|
|
|
if ((menu_start < usable_ram_start) || (menu_end > usable_ram_end)) {
|
|
error_display("Incorrect menu load address/size:\n Outside of usable RAM space\n");
|
|
}
|
|
|
|
if ((menu_start < bootloader_end) && (bootloader_start < menu_end)) {
|
|
error_display("Incorrect menu load address/size:\n Overlapping bootloader space\n");
|
|
}
|
|
}
|
|
|
|
|
|
void menu_load_and_run (void) {
|
|
void (* menu)(void);
|
|
FRESULT fresult;
|
|
FATFS fs;
|
|
FIL fil;
|
|
UINT br;
|
|
size_t size = ROM_MAX_LOAD_SIZE;
|
|
|
|
FF_CHECK(f_mount(&fs, "", 1), "Couldn't mount drive");
|
|
FF_CHECK(f_open(&fil, "sc64menu.n64", FA_READ), "Couldn't open menu file");
|
|
FF_CHECK(f_lseek(&fil, ROM_ENTRY_OFFSET), "Couldn't seek to entry point offset");
|
|
FF_CHECK(f_read(&fil, &menu, sizeof(menu), &br), "Couldn't read entry point");
|
|
FF_CHECK(f_lseek(&fil, ROM_CODE_OFFSET), "Couldn't seek to code start offset");
|
|
if ((f_size(&fil) - ROM_CODE_OFFSET) < size) {
|
|
size = (size_t) (f_size(&fil) - ROM_CODE_OFFSET);
|
|
}
|
|
menu_check_load_address(menu, size);
|
|
cache_data_hit_writeback_invalidate(menu, size);
|
|
cache_inst_hit_invalidate(menu, size);
|
|
FF_CHECK(f_read(&fil, menu, size, &br), "Couldn't read menu file");
|
|
FF_CHECK((br != size) ? FR_INT_ERR : FR_OK, "Read size is different than expected");
|
|
FF_CHECK(f_close(&fil), "Couldn't close menu file");
|
|
FF_CHECK(f_unmount(""), "Couldn't unmount drive");
|
|
|
|
deinit();
|
|
|
|
menu();
|
|
|
|
while (1);
|
|
}
|