diff --git a/Makefile b/Makefile index 9b5a8336..890078eb 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ SRCS = \ boot/boot.c \ boot/crc32.c \ boot/ipl2.S \ + flashcart/flashcart_utils.c \ flashcart/flashcart.c \ flashcart/sc64/sc64_internal.c \ flashcart/sc64/sc64.c \ diff --git a/src/flashcart/flashcart.c b/src/flashcart/flashcart.c index a8635059..52529f1e 100644 --- a/src/flashcart/flashcart.c +++ b/src/flashcart/flashcart.c @@ -1,5 +1,6 @@ #include +#include #include #include @@ -40,16 +41,27 @@ static flashcart_t *flashcart = &((flashcart_t) { flashcart_error_t flashcart_init (void) { flashcart_error_t error; - if (usb_initialize() == CART_NONE) { + // HACK: Because libcart reads PI config from address 0x10000000 when initializing + // we need to write safe value before running any libcart function. + // Data in SDRAM can be undefined on some flashcarts at this point + // and might result in setting incorrect PI config. + extern uint32_t cart_dom1; + cart_dom1 = 0x80371240; + + if (!debug_init_sdfs("sd:/", -1)) { return FLASHCART_ERROR_NOT_DETECTED; } - switch (usb_getcart()) { - case CART_64DRIVE: - case CART_EVERDRIVE: + // NOTE: Flashcart model is extracted from libcart after debug_init_sdfs call is made + extern int cart_type; + + switch (cart_type) { + case CART_CI: // 64drive + case CART_ED: // Original EverDrive-64 + case CART_EDX: // Series X EverDrive-64 break; - case CART_SC64: + case CART_SC: // SC64 flashcart = sc64_get_flashcart(); break; @@ -61,12 +73,9 @@ flashcart_error_t flashcart_init (void) { return error; } - if (!debug_init_sdfs("sd:/", -1)) { - return FLASHCART_ERROR_SD_CARD_ERROR; - } - -#ifndef NDEBUG - assertf(debug_init_usblog(), "Couldn't initialize USB debugging"); +#ifndef MENU_NO_USB_LOG + // NOTE: Some flashcarts doesn't have USB port, can't throw error here + debug_init_usblog(); #endif return FLASHCART_OK; @@ -80,10 +89,23 @@ flashcart_error_t flashcart_deinit (void) { } flashcart_error_t flashcart_load_rom (char *rom_path, bool byte_swap) { + flashcart_error_t error; + if ((rom_path == NULL) || (!file_exists(rom_path)) || (file_get_size(rom_path) < KiB(4))) { return FLASHCART_ERROR_ARGS; } - return flashcart->load_rom(rom_path, byte_swap); + + if (cart_card_byteswap(byte_swap)) { + return FLASHCART_ERROR_INT; + } + + error = flashcart->load_rom(rom_path); + + if (cart_card_byteswap(false)) { + return FLASHCART_ERROR_INT; + } + + return error; } flashcart_error_t flashcart_load_save (char *save_path, flashcart_save_type_t save_type) { diff --git a/src/flashcart/flashcart.h b/src/flashcart/flashcart.h index cb92e089..3138fef9 100644 --- a/src/flashcart/flashcart.h +++ b/src/flashcart/flashcart.h @@ -16,7 +16,6 @@ typedef enum { FLASHCART_OK, FLASHCART_ERROR_NOT_DETECTED, - FLASHCART_ERROR_SD_CARD_ERROR, FLASHCART_ERROR_UNSUPPORTED, FLASHCART_ERROR_OUTDATED, FLASHCART_ERROR_ARGS, @@ -40,7 +39,7 @@ typedef enum { typedef struct { flashcart_error_t (*init) (void); flashcart_error_t (*deinit) (void); - flashcart_error_t (*load_rom) (char *rom_path, bool byte_swap); + flashcart_error_t (*load_rom) (char *rom_path); flashcart_error_t (*load_save) (char *save_path); flashcart_error_t (*set_save_type) (flashcart_save_type_t save_type); flashcart_error_t (*set_save_writeback) (uint32_t *sectors); diff --git a/src/flashcart/flashcart_utils.c b/src/flashcart/flashcart_utils.c new file mode 100644 index 00000000..765a2408 --- /dev/null +++ b/src/flashcart/flashcart_utils.c @@ -0,0 +1,11 @@ +#include "flashcart_utils.h" +#include "utils/fs.h" +#include "utils/utils.h" + + +void fix_file_size (FIL *fil) { + // HACK: Align file size to the SD sector size to prevent FatFs from doing partial sector load. + // We are relying on direct transfer from SD to SDRAM without CPU intervention. + // Sending some extra bytes isn't an issue here. + fil->obj.objsize = ALIGN(f_size(fil), FS_SECTOR_SIZE); +} diff --git a/src/flashcart/flashcart_utils.h b/src/flashcart/flashcart_utils.h new file mode 100644 index 00000000..036e54d9 --- /dev/null +++ b/src/flashcart/flashcart_utils.h @@ -0,0 +1,17 @@ +/** + * @file flashcart_utils.h + * @brief Flashcart utilities + * @ingroup flashcart + */ + +#ifndef FLASHCART_UTILS_H__ +#define FLASHCART_UTILS_H__ + + +#include + + +void fix_file_size (FIL *fil); + + +#endif diff --git a/src/flashcart/sc64/sc64.c b/src/flashcart/sc64/sc64.c index 77ed5ad6..65d00917 100644 --- a/src/flashcart/sc64/sc64.c +++ b/src/flashcart/sc64/sc64.c @@ -8,6 +8,7 @@ #include "utils/fs.h" #include "utils/utils.h" +#include "../flashcart_utils.h" #include "sc64_internal.h" #include "sc64.h" @@ -51,22 +52,10 @@ static flashcart_error_t load_to_flash (FIL *fil, void *address, size_t size, UI return FLASHCART_OK; } -static void load_cleanup (FIL *fil) { - sc64_sd_set_byte_swap(false); - f_close(fil); -} - - static flashcart_error_t sc64_init (void) { uint16_t major; uint16_t minor; - // HACK: Because libcart reads PI config from address 0x10000000 when initializing - // we need to write safe value before running any libcart function. - // Data in SDRAM can be undefined at this point and result in setting incorrect PI config. - extern uint32_t cart_dom1; - cart_dom1 = 0x80371240; - sc64_unlock(); if (!sc64_check_presence()) { @@ -127,7 +116,7 @@ static flashcart_error_t sc64_deinit (void) { return FLASHCART_OK; } -static flashcart_error_t sc64_load_rom (char *rom_path, bool byte_swap) { +static flashcart_error_t sc64_load_rom (char *rom_path) { FIL fil; UINT br; @@ -135,10 +124,7 @@ static flashcart_error_t sc64_load_rom (char *rom_path, bool byte_swap) { return FLASHCART_ERROR_LOAD; } - // HACK: Align file size to the SD sector size to prevent FatFs from doing partial sector load. - // We are relying on direct transfer from SD to SDRAM without CPU intervention. - // Sending some extra bytes isn't an issue here. - fil.obj.objsize = ALIGN(f_size(&fil), FS_SECTOR_SIZE); + fix_file_size(&fil); size_t rom_size = f_size(&fil); @@ -147,11 +133,6 @@ static flashcart_error_t sc64_load_rom (char *rom_path, bool byte_swap) { return FLASHCART_ERROR_LOAD; } - if (sc64_sd_set_byte_swap(byte_swap) != SC64_OK) { - load_cleanup(&fil); - return FLASHCART_ERROR_INT; - } - bool shadow_enabled = (rom_size > (MiB(64) - KiB(128))); bool extended_enabled = (rom_size > MiB(64)); @@ -160,53 +141,48 @@ static flashcart_error_t sc64_load_rom (char *rom_path, bool byte_swap) { size_t extended_size = extended_enabled ? rom_size - MiB(64) : 0; if (f_read(&fil, (void *) (ROM_ADDRESS), sdram_size, &br) != FR_OK) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_LOAD; } if (br != sdram_size) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_LOAD; } if (sc64_set_config(CFG_ROM_SHADOW_ENABLE, shadow_enabled) != SC64_OK) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_INT; } if (shadow_enabled) { flashcart_error_t error = load_to_flash(&fil, (void *) (SHADOW_ADDRESS), shadow_size, &br); if (error != FLASHCART_OK) { - load_cleanup(&fil); + f_close(&fil); return error; } if (br != shadow_size) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_LOAD; } } if (sc64_set_config(CFG_ROM_EXTENDED_ENABLE, extended_enabled) != SC64_OK) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_INT; } if (extended_enabled) { flashcart_error_t error = load_to_flash(&fil, (void *) (EXTENDED_ADDRESS), extended_size, &br); if (error != FLASHCART_OK) { - load_cleanup(&fil); + f_close(&fil); return error; } if (br != extended_size) { - load_cleanup(&fil); + f_close(&fil); return FLASHCART_ERROR_LOAD; } } - if (sc64_sd_set_byte_swap(false) != SC64_OK) { - load_cleanup(&fil); - return FLASHCART_ERROR_INT; - } - if (f_close(&fil) != FR_OK) { return FLASHCART_ERROR_LOAD; } diff --git a/src/menu/views/fault.c b/src/menu/views/fault.c index cd7a2c7b..959da0ab 100644 --- a/src/menu/views/fault.c +++ b/src/menu/views/fault.c @@ -11,8 +11,6 @@ static char *format_flashcart_error (flashcart_error_t error) { return "No error"; case FLASHCART_ERROR_NOT_DETECTED: return "No flashcart hardware was detected"; - case FLASHCART_ERROR_SD_CARD_ERROR: - return "Error during SD card initialization"; case FLASHCART_ERROR_UNSUPPORTED: return "Unsupported flashcart"; case FLASHCART_ERROR_OUTDATED: