-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds the basic needs to run ROMs on V series hardware.
- Loading branch information
1 parent
7797f74
commit f094168
Showing
8 changed files
with
404 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This folder allows support for the ED64(P) flashcart when using V series hardware. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
#include <stdbool.h> | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#include <fatfs/ff.h> | ||
#include <libdragon.h> | ||
|
||
#include "utils/fs.h" | ||
#include "utils/utils.h" | ||
|
||
#include "../flashcart_utils.h" | ||
#include "ed64_ll.h" | ||
#include "ed64.h" | ||
|
||
#define EEPROM_ADDRESS (0x1FFE2000) | ||
|
||
extern int ed_exit(void); | ||
|
||
static flashcart_error_t ed64_init (void) { | ||
|
||
// TODO: partly already done, see https://github.com/DragonMinded/libdragon/blob/4ec469d26b6dc4e308caf3d5b86c2b340b708bbd/src/libcart/cart.c#L1064 | ||
|
||
// FIXME: Update firmware if needed. | ||
// FIXME: Enable RTC if available. | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
static flashcart_error_t ed64_deinit (void) { | ||
|
||
// For the moment, just use libCart exit. | ||
ed_exit(); | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
static flashcart_error_t ed64_load_rom (char *rom_path, flashcart_progress_callback_t *progress) { | ||
FIL fil; | ||
UINT br; | ||
|
||
if (f_open(&fil, strip_sd_prefix(rom_path), FA_READ) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
fix_file_size(&fil); | ||
|
||
size_t rom_size = f_size(&fil); | ||
|
||
// FIXME: if the cart is not V3 or X5 or X7, we need to - 128KiB | ||
if (rom_size > MiB(64) - KiB(128)) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
|
||
size_t sdram_size = rom_size; | ||
|
||
size_t chunk_size = MiB(1); | ||
for (int offset = 0; offset < sdram_size; offset += chunk_size) { | ||
size_t block_size = MIN(sdram_size - offset, chunk_size); | ||
if (f_read(&fil, (void *) (ROM_ADDRESS + offset), block_size, &br) != FR_OK) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
if (progress) { | ||
progress(f_tell(&fil) / (float) (f_size(&fil))); | ||
} | ||
} | ||
if (f_tell(&fil) != sdram_size) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
|
||
if (f_close(&fil) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
static flashcart_error_t ed64_load_file (char *file_path, uint32_t rom_offset, uint32_t file_offset) { | ||
FIL fil; | ||
UINT br; | ||
|
||
if (f_open(&fil, strip_sd_prefix(file_path), FA_READ) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
fix_file_size(&fil); | ||
|
||
size_t file_size = f_size(&fil) - file_offset; | ||
|
||
// FIXME: if the cart is not V3 or X5 or X7, we need to - 128KiB | ||
if (file_size > (MiB(64) - KiB(128) - rom_offset)) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_ARGS; | ||
} | ||
|
||
if (f_lseek(&fil, file_offset) != FR_OK) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
if (f_read(&fil, (void *) (ROM_ADDRESS + rom_offset), file_size, &br) != FR_OK) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
if (br != file_size) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
if (f_close(&fil) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
static flashcart_error_t ed64_load_save (char *save_path) { | ||
void *address = NULL; | ||
ed64_save_type_t type = ed64_ll_get_save_type(); | ||
|
||
switch (type) { | ||
case SAVE_TYPE_EEPROM_4K: | ||
case SAVE_TYPE_EEPROM_16K: | ||
address = (void *) (EEPROM_ADDRESS); | ||
break; | ||
case SAVE_TYPE_SRAM: | ||
case SAVE_TYPE_SRAM_128K: | ||
case SAVE_TYPE_FLASHRAM: | ||
address = (void *) (SRAM_ADDRESS); | ||
break; | ||
case SAVE_TYPE_NONE: | ||
default: | ||
return FLASHCART_ERROR_ARGS; | ||
} | ||
|
||
FIL fil; | ||
UINT br; | ||
|
||
if (f_open(&fil, strip_sd_prefix(save_path), FA_READ) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
size_t save_size = f_size(&fil); | ||
|
||
if (f_read(&fil, address, save_size, &br) != FR_OK) { | ||
f_close(&fil); | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
if (f_close(&fil) != FR_OK) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
if (br != save_size) { | ||
return FLASHCART_ERROR_LOAD; | ||
} | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
static flashcart_error_t ed64_set_save_type (flashcart_save_type_t save_type) { | ||
ed64_save_type_t type; | ||
|
||
switch (save_type) { | ||
case FLASHCART_SAVE_TYPE_NONE: | ||
type = SAVE_TYPE_NONE; | ||
break; | ||
case FLASHCART_SAVE_TYPE_EEPROM_4K: | ||
type = SAVE_TYPE_EEPROM_4K; | ||
break; | ||
case FLASHCART_SAVE_TYPE_EEPROM_16K: | ||
type = SAVE_TYPE_EEPROM_16K; | ||
break; | ||
case FLASHCART_SAVE_TYPE_SRAM: | ||
type = SAVE_TYPE_SRAM; | ||
break; | ||
case FLASHCART_SAVE_TYPE_SRAM_BANKED: | ||
case FLASHCART_SAVE_TYPE_SRAM_128K: | ||
type = SAVE_TYPE_SRAM_128K; | ||
break; | ||
case FLASHCART_SAVE_TYPE_FLASHRAM: | ||
type = SAVE_TYPE_FLASHRAM; | ||
break; | ||
default: | ||
return FLASHCART_ERROR_ARGS; | ||
} | ||
|
||
ed64_ll_set_save_type(type); | ||
|
||
return FLASHCART_OK; | ||
} | ||
|
||
|
||
static flashcart_t flashcart_ed64 = { | ||
.init = ed64_init, | ||
.deinit = ed64_deinit, | ||
.load_rom = ed64_load_rom, | ||
.load_file = ed64_load_file, | ||
.load_save = ed64_load_save, | ||
.set_save_type = ed64_set_save_type, | ||
.set_save_writeback = NULL, | ||
}; | ||
|
||
|
||
flashcart_t *ed64_get_flashcart (void) { | ||
return &flashcart_ed64; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* @file flashcart.h | ||
* @brief ED64 Flashcart Utilities | ||
* @ingroup flashcart | ||
*/ | ||
|
||
#ifndef FLASHCART_ED64_H__ | ||
#define FLASHCART_ED64_H__ | ||
|
||
|
||
#include "../flashcart.h" | ||
|
||
|
||
/** | ||
* @addtogroup ed64 | ||
* @{ | ||
*/ | ||
|
||
flashcart_t *ed64_get_flashcart (void); | ||
|
||
/** @} */ /* ed64 */ | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include <libdragon.h> | ||
|
||
#include "ed64_ll.h" | ||
|
||
|
||
/* ED64 configuration registers base address */ | ||
#define ED64_CONFIG_REGS_BASE (0xA8040000) | ||
|
||
typedef enum { | ||
// REG_CFG = 0, | ||
// REG_STATUS = 1, | ||
// REG_DMA_LENGTH = 2, | ||
// REG_DMA_RAM_ADDR = 3, | ||
// REG_MSG = 4, | ||
// REG_DMA_CFG = 5, | ||
// REG_SPI = 6, | ||
// REG_SPI_CFG = 7, | ||
// REG_KEY = 8, | ||
REG_SAV_CFG = 9, | ||
// REG_SEC = 10, /* Sectors?? */ | ||
// REG_FPGA_VERSION = 11, /* Altera (Intel) MAX */ | ||
// REG_GPIO = 12, | ||
|
||
} ed64_registers_t; | ||
|
||
|
||
#define SAV_EEP_ON 1 | ||
#define SAV_SRM_ON 2 | ||
#define SAV_EEP_SIZE 4 | ||
#define SAV_SRM_SIZE 8 | ||
|
||
#define SAV_RAM_BANK 128 | ||
#define SAV_RAM_BANK_APPLY 32768 | ||
|
||
uint32_t ed64_ll_reg_read(uint32_t reg); | ||
void ed64_ll_reg_write(uint32_t reg, uint32_t data); | ||
|
||
uint8_t ed64_ll_sram_bank; | ||
ed64_save_type_t ed64_ll_save_type; | ||
|
||
|
||
uint32_t ed64_ll_reg_read(uint32_t reg) { | ||
|
||
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE); | ||
return *(volatile uint32_t *) (ED64_CONFIG_REGS_BASE + reg * 4); | ||
} | ||
|
||
void ed64_ll_reg_write(uint32_t reg, uint32_t data) { | ||
|
||
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE); | ||
*(volatile uint32_t *) (ED64_CONFIG_REGS_BASE + reg * 4) = data; | ||
*(volatile uint32_t *) (ROM_ADDRESS); | ||
|
||
} | ||
|
||
|
||
ed64_save_type_t ed64_ll_get_save_type() { | ||
|
||
return ed64_ll_save_type; | ||
} | ||
|
||
void ed64_ll_set_save_type(ed64_save_type_t type) { | ||
|
||
uint16_t save_cfg; | ||
uint8_t eeprom_on, sram_on, eeprom_size, sram_size, ram_bank; | ||
ed64_ll_save_type = type; | ||
eeprom_on = 0; | ||
sram_on = 0; | ||
eeprom_size = 0; | ||
sram_size = 0; | ||
ram_bank = ed64_ll_sram_bank; | ||
|
||
|
||
switch (type) { | ||
case SAVE_TYPE_EEPROM_16K: | ||
eeprom_on = 1; | ||
eeprom_size = 1; | ||
break; | ||
case SAVE_TYPE_EEPROM_4K: | ||
eeprom_on = 1; | ||
break; | ||
case SAVE_TYPE_SRAM: | ||
sram_on = 1; | ||
break; | ||
case SAVE_TYPE_SRAM_128K: | ||
sram_on = 1; | ||
sram_size = 1; | ||
break; | ||
case SAVE_TYPE_FLASHRAM: | ||
sram_on = 0; | ||
sram_size = 1; | ||
break; | ||
default: | ||
sram_on = 0; | ||
sram_size = 0; | ||
ram_bank = 1; | ||
break; | ||
} | ||
|
||
save_cfg = 0; | ||
if (eeprom_on)save_cfg |= SAV_EEP_ON; | ||
if (sram_on)save_cfg |= SAV_SRM_ON; | ||
if (eeprom_size)save_cfg |= SAV_EEP_SIZE; | ||
if (sram_size)save_cfg |= SAV_SRM_SIZE; | ||
if (ram_bank)save_cfg |= SAV_RAM_BANK; | ||
save_cfg |= SAV_RAM_BANK_APPLY; | ||
|
||
ed64_ll_reg_write(REG_SAV_CFG, save_cfg); | ||
|
||
} | ||
|
||
void ed64_ll_set_sram_bank(uint8_t bank) { | ||
|
||
ed64_ll_sram_bank = bank == 0 ? 0 : 1; | ||
|
||
} |
Oops, something went wrong.