mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][SW] Save writeback SD card optimizations
This commit is contained in:
parent
908fc04ebb
commit
170bf28553
@ -42,15 +42,6 @@ typedef enum {
|
||||
BOOT_MODE_DIRECT = 3
|
||||
} boot_mode_t;
|
||||
|
||||
typedef enum {
|
||||
SAVE_TYPE_NONE = 0,
|
||||
SAVE_TYPE_EEPROM_4K = 1,
|
||||
SAVE_TYPE_EEPROM_16K = 2,
|
||||
SAVE_TYPE_SRAM = 3,
|
||||
SAVE_TYPE_FLASHRAM = 4,
|
||||
SAVE_TYPE_SRAM_BANKED = 5
|
||||
} save_type_t;
|
||||
|
||||
typedef enum {
|
||||
CIC_SEED_UNKNOWN = 0xFFFF
|
||||
} cic_seed_t;
|
||||
@ -359,6 +350,10 @@ bool cfg_update (uint32_t *args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
save_type_t cfg_get_save_type (void) {
|
||||
return p.save_type;
|
||||
}
|
||||
|
||||
void cfg_get_time (uint32_t *args) {
|
||||
rtc_time_t t;
|
||||
rtc_get_time(&t);
|
||||
|
@ -6,9 +6,20 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
SAVE_TYPE_NONE = 0,
|
||||
SAVE_TYPE_EEPROM_4K = 1,
|
||||
SAVE_TYPE_EEPROM_16K = 2,
|
||||
SAVE_TYPE_SRAM = 3,
|
||||
SAVE_TYPE_FLASHRAM = 4,
|
||||
SAVE_TYPE_SRAM_BANKED = 5
|
||||
} save_type_t;
|
||||
|
||||
|
||||
uint32_t cfg_get_version (void);
|
||||
bool cfg_query (uint32_t *args);
|
||||
bool cfg_update (uint32_t *args);
|
||||
save_type_t cfg_get_save_type (void);
|
||||
void cfg_get_time (uint32_t *args);
|
||||
void cfg_set_time (uint32_t *args);
|
||||
void cfg_reset_state (void);
|
||||
|
@ -125,41 +125,14 @@ static uint32_t dd_fill_sd_sector_table (uint32_t index, uint32_t *sector_table)
|
||||
return sectors;
|
||||
}
|
||||
|
||||
static void dd_process_sd_request (uint16_t index, uint32_t buffer_address, bool write) {
|
||||
uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE];
|
||||
uint32_t sectors = dd_fill_sd_sector_table(index, sector_table);
|
||||
dd_set_block_ready(false);
|
||||
if (sectors == 0) {
|
||||
return;
|
||||
}
|
||||
uint32_t starting_sector = 0;
|
||||
uint32_t sectors_to_process = 0;
|
||||
for (uint32_t i = 0; i < sectors; i++) {
|
||||
sectors_to_process += 1;
|
||||
if ((i < (sectors - 1)) && ((sector_table[i] + 1) == sector_table[i + 1])) {
|
||||
continue;
|
||||
}
|
||||
if (write) {
|
||||
if (sd_write_sectors(buffer_address, sector_table[starting_sector], sectors_to_process)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (sd_read_sectors(buffer_address, sector_table[starting_sector], sectors_to_process)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
buffer_address += (sectors_to_process * SD_SECTOR_SIZE);
|
||||
starting_sector += sectors_to_process;
|
||||
sectors_to_process = 0;
|
||||
}
|
||||
dd_set_block_ready(true);
|
||||
}
|
||||
|
||||
static bool dd_block_read_request (void) {
|
||||
uint16_t index = dd_track_head_block();
|
||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||
if (p.sd_mode) {
|
||||
dd_process_sd_request(index, buffer_address, false);
|
||||
uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE];
|
||||
uint32_t sectors = dd_fill_sd_sector_table(index, sector_table);
|
||||
bool error = sd_optimize_sectors(buffer_address, sector_table, sectors, sd_read_sectors);
|
||||
dd_set_block_ready(!error);
|
||||
} else {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
@ -178,7 +151,10 @@ static bool dd_block_write_request (void) {
|
||||
uint32_t index = dd_track_head_block();
|
||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||
if (p.sd_mode) {
|
||||
dd_process_sd_request(index, buffer_address, true);
|
||||
uint32_t sector_table[DD_SD_SECTOR_TABLE_SIZE];
|
||||
uint32_t sectors = dd_fill_sd_sector_table(index, sector_table);
|
||||
bool error = sd_optimize_sectors(buffer_address, sector_table, sectors, sd_write_sectors);
|
||||
dd_set_block_ready(!error);
|
||||
} else {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
|
@ -197,6 +197,7 @@ static bool sd_dat_wait (uint16_t timeout) {
|
||||
do {
|
||||
uint32_t sd_dat = fpga_reg_get(REG_SD_DAT);
|
||||
uint32_t sd_dma_scr = fpga_reg_get(REG_SD_DMA_SCR);
|
||||
led_blink_act();
|
||||
if ((!(sd_dat & SD_DAT_BUSY)) && (!(sd_dma_scr & DMA_SCR_BUSY))) {
|
||||
sd_clear_timeout();
|
||||
return (sd_dat & SD_DAT_ERROR);
|
||||
@ -430,6 +431,34 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors) {
|
||||
uint32_t starting_sector = 0;
|
||||
uint32_t sectors_to_process = 0;
|
||||
|
||||
if (count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (sector_table[i] == 0) {
|
||||
return true;
|
||||
}
|
||||
sectors_to_process += 1;
|
||||
if ((i < (count - 1)) && ((sector_table[i] + 1) == sector_table[i + 1])) {
|
||||
continue;
|
||||
}
|
||||
bool error = sd_process_sectors(address, sector_table[starting_sector], sectors_to_process);
|
||||
if (error) {
|
||||
return true;
|
||||
}
|
||||
address += (sectors_to_process * SD_SECTOR_SIZE);
|
||||
starting_sector += sectors_to_process;
|
||||
sectors_to_process = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sd_init (void) {
|
||||
p.card_initialized = false;
|
||||
sd_set_clock(CLOCK_STOP);
|
||||
|
@ -8,12 +8,16 @@
|
||||
#define SD_SECTOR_SIZE (512)
|
||||
|
||||
|
||||
typedef bool sd_process_sectors_t (uint32_t address, uint32_t sector, uint32_t count);
|
||||
|
||||
|
||||
bool sd_card_init (void);
|
||||
void sd_card_deinit (void);
|
||||
uint32_t sd_card_get_status (void);
|
||||
bool sd_card_get_info (uint32_t address);
|
||||
bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count);
|
||||
bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count);
|
||||
bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors);
|
||||
void sd_init (void);
|
||||
void sd_process (void);
|
||||
|
||||
|
@ -1,13 +1,19 @@
|
||||
#include "cfg.h"
|
||||
#include "fpga.h"
|
||||
#include "sd.h"
|
||||
#include "timer.h"
|
||||
#include "writeback.h"
|
||||
|
||||
|
||||
#define SAVE_MAX_SECTOR_COUNT (256)
|
||||
#define SRAM_FLASHRAM_ADDRESS (0x03FE0000)
|
||||
#define EEPROM_ADDRESS (0x05002000)
|
||||
#define WRITEBACK_DELAY_TICKS (100)
|
||||
#define SAVE_MAX_SECTOR_COUNT (256)
|
||||
#define SRAM_FLASHRAM_ADDRESS (0x03FE0000)
|
||||
#define EEPROM_ADDRESS (0x05002000)
|
||||
#define EEPROM_4K_SECTOR_COUNT (1)
|
||||
#define EEPROM_16K_SECTOR_COUNT (4)
|
||||
#define SRAM_SECTOR_COUNT (64)
|
||||
#define FLASHRAM_SECTOR_COUNT (256)
|
||||
#define SRAM_BANKED_SECTOR_COUNT (192)
|
||||
#define WRITEBACK_DELAY_TICKS (100)
|
||||
|
||||
|
||||
struct process {
|
||||
@ -22,20 +28,37 @@ static struct process p;
|
||||
|
||||
|
||||
static void writeback_save_to_sd (void) {
|
||||
uint32_t save_address = SRAM_FLASHRAM_ADDRESS;
|
||||
if (fpga_reg_get(REG_CFG_SCR) & CFG_SCR_EEPROM_ENABLED) {
|
||||
save_address = EEPROM_ADDRESS;
|
||||
}
|
||||
for (int i = 0; i < SAVE_MAX_SECTOR_COUNT; i++) {
|
||||
uint32_t sector = p.sectors[i];
|
||||
if (sector == 0) {
|
||||
uint32_t address;
|
||||
uint32_t count;
|
||||
|
||||
switch (cfg_get_save_type()) {
|
||||
case SAVE_TYPE_EEPROM_4K:
|
||||
address = EEPROM_ADDRESS;
|
||||
count = EEPROM_4K_SECTOR_COUNT;
|
||||
break;
|
||||
}
|
||||
if (sd_write_sectors(save_address, sector, 1)) {
|
||||
case SAVE_TYPE_EEPROM_16K:
|
||||
address = EEPROM_ADDRESS;
|
||||
count = EEPROM_16K_SECTOR_COUNT;
|
||||
break;
|
||||
case SAVE_TYPE_SRAM:
|
||||
address = SRAM_FLASHRAM_ADDRESS;
|
||||
count = SRAM_SECTOR_COUNT;
|
||||
break;
|
||||
case SAVE_TYPE_FLASHRAM:
|
||||
address = SRAM_FLASHRAM_ADDRESS;
|
||||
count = FLASHRAM_SECTOR_COUNT;
|
||||
break;
|
||||
case SAVE_TYPE_SRAM_BANKED:
|
||||
address = SRAM_FLASHRAM_ADDRESS;
|
||||
count = SRAM_BANKED_SECTOR_COUNT;
|
||||
break;
|
||||
default:
|
||||
p.enabled = false;
|
||||
break;
|
||||
}
|
||||
save_address += SD_SECTOR_SIZE;
|
||||
return;
|
||||
}
|
||||
|
||||
if(sd_optimize_sectors(address, p.sectors, count, sd_write_sectors)) {
|
||||
p.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user