mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-25 03:56:54 +01:00
Minimal ED64 support
Adds the basic needs to run ROMs on V series hardware.
This commit is contained in:
parent
7797f74c0b
commit
f09416861d
2
Makefile
2
Makefile
@ -20,6 +20,8 @@ SRCS = \
|
|||||||
flashcart/flashcart.c \
|
flashcart/flashcart.c \
|
||||||
flashcart/sc64/sc64_ll.c \
|
flashcart/sc64/sc64_ll.c \
|
||||||
flashcart/sc64/sc64.c \
|
flashcart/sc64/sc64.c \
|
||||||
|
flashcart/ed64/ed64_ll.c \
|
||||||
|
flashcart/ed64/ed64.c \
|
||||||
hdmi/hdmi.c \
|
hdmi/hdmi.c \
|
||||||
libs/libspng/spng/spng.c \
|
libs/libspng/spng/spng.c \
|
||||||
libs/mini.c/src/mini.c \
|
libs/mini.c/src/mini.c \
|
||||||
|
@ -28,9 +28,11 @@ Ensure the cart is running the latest [firmware](https://github.com/Polprzewodni
|
|||||||
Download the `sc64menu.n64` ROM from the latest action run assets.
|
Download the `sc64menu.n64` ROM from the latest action run assets.
|
||||||
Add it to the root folder on your SD card.
|
Add it to the root folder on your SD card.
|
||||||
|
|
||||||
### ED64 & ED64P
|
### ED64
|
||||||
Currently not supported, but there is an aim to do so.
|
Download the `ED64.v64` ROM from the latest action run assets and place it in the `/ED64` folder.
|
||||||
The aim is to replace [Altra64](https://github.com/networkfusion/altra64) and [ED64-UnofficialOS](https://github.com/n64-tools/ED64-UnofficialOS-binaries).
|
|
||||||
|
### ED64P
|
||||||
|
Download the `ED64P.v64` ROM from the latest action run assets and place it in the `/ED64P` folder.
|
||||||
|
|
||||||
|
|
||||||
### Common to all
|
### Common to all
|
||||||
|
1
src/flashcart/ed64/README.md
Normal file
1
src/flashcart/ed64/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This folder allows support for the ED64(P) flashcart when using V series hardware.
|
211
src/flashcart/ed64/ed64.c
Normal file
211
src/flashcart/ed64/ed64.c
Normal file
@ -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;
|
||||||
|
}
|
24
src/flashcart/ed64/ed64.h
Normal file
24
src/flashcart/ed64/ed64.h
Normal file
@ -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
|
116
src/flashcart/ed64/ed64_ll.c
Normal file
116
src/flashcart/ed64/ed64_ll.c
Normal file
@ -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;
|
||||||
|
|
||||||
|
}
|
43
src/flashcart/ed64/ed64_ll.h
Normal file
43
src/flashcart/ed64/ed64_ll.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* @file flashcart.h
|
||||||
|
* @brief ED64 V-Series Flashcart Internal Utilities
|
||||||
|
* @ingroup flashcart
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLASHCART_ED64_LL_H__
|
||||||
|
#define FLASHCART_ED64_LL_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup ed64
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SAVE_TYPE_NONE = 0,
|
||||||
|
SAVE_TYPE_SRAM = 1,
|
||||||
|
SAVE_TYPE_SRAM_128K = 2,
|
||||||
|
SAVE_TYPE_EEPROM_4K = 3,
|
||||||
|
SAVE_TYPE_EEPROM_16K = 4,
|
||||||
|
SAVE_TYPE_FLASHRAM = 5,
|
||||||
|
SAVE_TYPE_CPAK = 8,
|
||||||
|
SAVE_TYPE_DD64 = 16,
|
||||||
|
} ed64_save_type_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define SRAM_ADDRESS (0xA8000000)
|
||||||
|
#define ROM_ADDRESS (0xB0000000)
|
||||||
|
|
||||||
|
/* Save functions */
|
||||||
|
void ed64_ll_set_ram_bank(uint8_t bank);
|
||||||
|
ed64_save_type_t ed64_ll_get_save_type();
|
||||||
|
void ed64_ll_set_save_type(ed64_save_type_t type);
|
||||||
|
|
||||||
|
/** @} */ /* ed64 */
|
||||||
|
|
||||||
|
#endif
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "flashcart.h"
|
#include "flashcart.h"
|
||||||
#include "sc64/sc64.h"
|
#include "sc64/sc64.h"
|
||||||
|
#include "ed64/ed64.h"
|
||||||
|
|
||||||
|
|
||||||
#define WRITEBACK_MAX_SECTORS (256)
|
#define WRITEBACK_MAX_SECTORS (256)
|
||||||
@ -58,7 +59,7 @@ flashcart_error_t flashcart_init (void) {
|
|||||||
{ CART_CI, ci_init, NULL }, // 64drive
|
{ CART_CI, ci_init, NULL }, // 64drive
|
||||||
{ CART_SC, sc_init, sc64_get_flashcart }, // SC64
|
{ CART_SC, sc_init, sc64_get_flashcart }, // SC64
|
||||||
{ CART_EDX, edx_init, NULL }, // Series X EverDrive-64
|
{ CART_EDX, edx_init, NULL }, // Series X EverDrive-64
|
||||||
{ CART_ED, ed_init, NULL }, // Original EverDrive-64
|
{ CART_ED, ed_init, ed64_get_flashcart }, // Original EverDrive-64
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < CART_MAX; i++) {
|
for (int i = 0; i < CART_MAX; i++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user