Skip to content

Commit

Permalink
Add memory card support for Dreamcast:
Browse files Browse the repository at this point in the history
Fixed maple_tx size wraparound bug
Implemented several commands for the maple memory card function
Open different memory card files for DC and N64
Saved about 1K of IRAM by decreasing the size of wait_100ns()
  • Loading branch information
breademan authored and darthcloud committed Jul 29, 2023
1 parent cb2bf99 commit df9e3a8
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 114 deletions.
104 changes: 76 additions & 28 deletions main/adapter/memory_card.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "sdkconfig.h"
#include "system/fs.h"
#include "memory_card.h"
#include "system/delay.h"

#define MC_BUFFER_SIZE (128 * 1024)
#define MC_BUFFER_BLOCK_SIZE (4 * 1024)
Expand All @@ -22,14 +23,76 @@
/* Workaround: Remove region from heap pool until I figure it out */
SOC_RESERVE_MEMORY_REGION(0x3FFE7D98, 0x3FFE7E28, bad_region);


static const uint8_t vmu_init_system_area[] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x27, 0x11, 0x98, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0x00, 0xFE, 0x00, 0xFF, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D,
0x00, 0x1F, 0x00, 0xC8, 0x00, 0x80, 0x00, 0x00,
};


static const uint8_t fat_data[32] = {
0xff, 0xfa, 0xff, 0xfc, 0x00, 0xf2, 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf3, 0x00, 0xf6, 0x00, 0xf5,
0x00, 0xf8, 0x00, 0xf7, 0x00, 0xfa, 0x00, 0xf9, 0x00, 0xfc, 0x00, 0xfb, 0xff, 0xfa, 0xff, 0xfa
};


static uint8_t *mc_buffer[MC_BUFFER_BLOCK_CNT] = {0};
static esp_timer_handle_t mc_timer_hdl = NULL;
static int32_t mc_block_state = 0;
static char * mc_filename;

static int32_t mc_restore(void);
static int32_t mc_store(void);
static inline void mc_store_cb(void *arg);

static int32_t create_vmu_file(void) {
int32_t ret = -1;
FILE *file = fopen(mc_filename, "wb");

if (file == NULL) {
printf("# %s: failed to open file for writing\n", __FUNCTION__);
}
else {
uint32_t zero_count = 0;
uint32_t data_count = 0;
// Write blocks 00-FD -- initialize with zeros.
// the first block of mc_buffer will be our zero source.
memset((void *)mc_buffer[0], 0, MC_BUFFER_BLOCK_SIZE);
for (uint32_t i = 0; i < MC_BUFFER_BLOCK_CNT; i++) {
zero_count += fwrite((void *)mc_buffer[0], MC_BUFFER_BLOCK_SIZE, 1, file);
}
//Seek to block FE
fseek(file, (512*0xFE), SEEK_SET);
//Write block FE
const uint8_t fat_unallocated[4] = {0xff, 0xfc, 0xff, 0xfc};
for (uint32_t i = 0; i < 120; i++) {
data_count = fwrite(fat_unallocated, 4, 1, file); // I'm not 100% confident the endianness on this will work like I expect. TODO: Check this.
}
data_count += fwrite(fat_data, 4, 8, file);

// Write block FF
data_count += fwrite(vmu_init_system_area, 4, sizeof(vmu_init_system_area), file);
// Pad the rest with zeros
for (uint32_t i = 0; i < (128 - sizeof(vmu_init_system_area)); i++) {
data_count += fwrite((void *)mc_buffer[0], 4, 1, file);
}

if (zero_count == MC_BUFFER_BLOCK_CNT) {
ret = 0;
mc_block_state = 0;
}
fclose(file);


printf("# %s: file created. zero_cnt(should be one): %ld. Words of data written: %ld\n", __FUNCTION__, zero_count, data_count);
}
return ret;
}

static void mc_start_update_timer(uint64_t timeout_us) {
if (mc_timer_hdl) {
if (esp_timer_is_active(mc_timer_hdl)) {
Expand All @@ -42,13 +105,12 @@ static void mc_start_update_timer(uint64_t timeout_us) {
static int32_t mc_restore(void) {
struct stat st;
int32_t ret = -1;

if (stat(MEMORY_CARD_FILE, &st) != 0) {
if (stat(mc_filename, &st) != 0) {
printf("# %s: No Memory Card on FS. Creating...\n", __FUNCTION__);
ret = mc_store();
ret = create_vmu_file();
}
else {
FILE *file = fopen(MEMORY_CARD_FILE, "rb");
FILE *file = fopen(mc_filename, "rb");
if (file == NULL) {
printf("# %s: failed to open file for reading\n", __FUNCTION__);
}
Expand All @@ -71,33 +133,10 @@ static int32_t mc_restore(void) {
return ret;
}

static int32_t mc_store(void) {
int32_t ret = -1;

FILE *file = fopen(MEMORY_CARD_FILE, "wb");
if (file == NULL) {
printf("# %s: failed to open file for writing\n", __FUNCTION__);
}
else {
uint32_t count = 0;
for (uint32_t i = 0; i < MC_BUFFER_BLOCK_CNT; i++) {
count += fwrite((void *)mc_buffer[i], MC_BUFFER_BLOCK_SIZE, 1, file);
}
fclose(file);

if (count == MC_BUFFER_BLOCK_CNT) {
ret = 0;
mc_block_state = 0;
}
printf("# %s: file updated cnt: %ld\n", __FUNCTION__, count);
}
return ret;
}

static int32_t mc_store_spread(void) {
int32_t ret = -1;

FILE *file = fopen(MEMORY_CARD_FILE, "r+b");
FILE *file = fopen(mc_filename, "r+b");
if (file == NULL) {
printf("# %s: failed to open file for writing\n", __FUNCTION__);
}
Expand Down Expand Up @@ -141,6 +180,7 @@ int32_t mc_init(void) {

for (uint32_t i = 0; i < MC_BUFFER_BLOCK_CNT; i++) {
mc_buffer[i] = malloc(MC_BUFFER_BLOCK_SIZE);
memset((void *)mc_buffer[i],0,MC_BUFFER_BLOCK_SIZE);

if (mc_buffer[i] == NULL) {
printf("# %s mc_buffer[%ld] alloc fail\n", __FUNCTION__, i);
Expand All @@ -150,6 +190,14 @@ int32_t mc_init(void) {
}

esp_timer_create(&mc_timer_args, &mc_timer_hdl);

while(wired_adapter.system_id==WIRED_AUTO){
printf("Waiting for wired_adapter.system_id to be decided\n");
delay_us(200);
}

if (wired_adapter.system_id==DC) mc_filename = DC_MEMORY_CARD_FILE;
else mc_filename = N64_MEMORY_CARD_FILE;

ret = mc_restore();

Expand Down
3 changes: 2 additions & 1 deletion main/system/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#define LE_LINK_KEYS_FILE "/fs/le_linkkeys.bin"
#define BDADDR_FILE "/fs/bdaddr.bin"
#define CONFIG_FILE "/fs/config.bin"
#define MEMORY_CARD_FILE "/fs/mc.bin"
#define N64_MEMORY_CARD_FILE "/fs/mc.bin"
#define DC_MEMORY_CARD_FILE "/fs/vmu0.bin"
#define BITSTREAM_FILE "/fs/bitstream.bit"

int32_t fs_init(void);
Expand Down
Loading

0 comments on commit df9e3a8

Please sign in to comment.