mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
64dd speedup and button handling
This commit is contained in:
parent
f701df4fbb
commit
093aabe940
@ -6,8 +6,8 @@
|
|||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
|
|
||||||
|
|
||||||
#define SD_BLOCK_SIZE (512)
|
#define SD_SECTOR_SIZE (512)
|
||||||
#define BUFFER_BLOCKS_MAX (sizeof(SC64_BUFFERS->BUFFER) / SD_BLOCK_SIZE)
|
#define BUFFER_BLOCKS_MAX (sizeof(SC64_BUFFERS->BUFFER) / SD_SECTOR_SIZE)
|
||||||
#define FROM_BCD(x) ((((x >> 4) & 0x0F) * 10) + (x & 0x0F))
|
#define FROM_BCD(x) ((((x >> 4) & 0x0F) * 10) + (x & 0x0F))
|
||||||
|
|
||||||
|
|
||||||
@ -37,10 +37,10 @@ DRESULT disk_read (BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
|
|||||||
}
|
}
|
||||||
uint32_t *physical_address = (uint32_t *) (PHYSICAL(buff));
|
uint32_t *physical_address = (uint32_t *) (PHYSICAL(buff));
|
||||||
if (physical_address < (uint32_t *) (N64_RAM_SIZE)) {
|
if (physical_address < (uint32_t *) (N64_RAM_SIZE)) {
|
||||||
uint8_t aligned_buffer[BUFFER_BLOCKS_MAX * SD_BLOCK_SIZE] __attribute__((aligned(8)));
|
uint8_t aligned_buffer[BUFFER_BLOCKS_MAX * SD_SECTOR_SIZE] __attribute__((aligned(8)));
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
uint32_t blocks = ((count > BUFFER_BLOCKS_MAX) ? BUFFER_BLOCKS_MAX : count);
|
uint32_t blocks = ((count > BUFFER_BLOCKS_MAX) ? BUFFER_BLOCKS_MAX : count);
|
||||||
size_t length = (blocks * SD_BLOCK_SIZE);
|
size_t length = (blocks * SD_SECTOR_SIZE);
|
||||||
if (sc64_sd_read_sectors((uint32_t *) (SC64_BUFFERS->BUFFER), sector, blocks)) {
|
if (sc64_sd_read_sectors((uint32_t *) (SC64_BUFFERS->BUFFER), sector, blocks)) {
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
@ -69,10 +69,10 @@ DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) {
|
|||||||
}
|
}
|
||||||
uint32_t *physical_address = (uint32_t *) (PHYSICAL(buff));
|
uint32_t *physical_address = (uint32_t *) (PHYSICAL(buff));
|
||||||
if (physical_address < (uint32_t *) (N64_RAM_SIZE)) {
|
if (physical_address < (uint32_t *) (N64_RAM_SIZE)) {
|
||||||
uint8_t aligned_buffer[BUFFER_BLOCKS_MAX * SD_BLOCK_SIZE] __attribute__((aligned(8)));
|
uint8_t aligned_buffer[BUFFER_BLOCKS_MAX * SD_SECTOR_SIZE] __attribute__((aligned(8)));
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
uint32_t blocks = ((count > BUFFER_BLOCKS_MAX) ? BUFFER_BLOCKS_MAX : count);
|
uint32_t blocks = ((count > BUFFER_BLOCKS_MAX) ? BUFFER_BLOCKS_MAX : count);
|
||||||
size_t length = (blocks * SD_BLOCK_SIZE);
|
size_t length = (blocks * SD_SECTOR_SIZE);
|
||||||
if (((uint32_t) (buff) % 8) == 0) {
|
if (((uint32_t) (buff) % 8) == 0) {
|
||||||
pi_dma_write((io32_t *) (SC64_BUFFERS->BUFFER), (void *) (buff), length);
|
pi_dma_write((io32_t *) (SC64_BUFFERS->BUFFER), (void *) (buff), length);
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,10 +60,6 @@ void menu_load_and_run (void) {
|
|||||||
}
|
}
|
||||||
FF_CHECK(f_read(&fil, menu, size, &br), "Couldn't read menu file");
|
FF_CHECK(f_read(&fil, menu, size, &br), "Couldn't read menu file");
|
||||||
FF_CHECK(br != size, "Read size is different than expected");
|
FF_CHECK(br != size, "Read size is different than expected");
|
||||||
// TODO: delete this, do not touch SDRAM when loading menu
|
|
||||||
FF_CHECK(f_lseek(&fil, 0), "Couldn't seek to the beginning of file");
|
|
||||||
FF_CHECK(f_read(&fil, (void *) (0xB0000000UL), f_size(&fil), &br), "Couldn't read file contents to SDRAM");
|
|
||||||
// TODO: ^
|
|
||||||
FF_CHECK(f_close(&fil), "Couldn't close menu file");
|
FF_CHECK(f_close(&fil), "Couldn't close menu file");
|
||||||
FF_CHECK(f_unmount(""), "Couldn't unmount drive");
|
FF_CHECK(f_unmount(""), "Couldn't unmount drive");
|
||||||
|
|
||||||
|
@ -94,13 +94,31 @@ static bool cfg_translate_address (uint32_t *address, uint32_t length, bool with
|
|||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
uint32_t rom_end = (with_flash ? 0x15000000 : 0x14000000);
|
*address &= 0x1FFFFFFF;
|
||||||
if (*address >= 0x10000000 && *address < rom_end) {
|
if (*address >= 0x06000000 && *address < 0x06400000) {
|
||||||
if ((*address + length) <= rom_end) {
|
if ((*address + length) <= 0x06400000) {
|
||||||
|
*address = *address - 0x06000000 + 0x03BC0000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*address >= 0x08000000 && *address < 0x08020000) {
|
||||||
|
if ((*address + length) <= 0x08020000) {
|
||||||
|
*address = *address - 0x08000000 + 0x03FE0000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*address >= 0x10000000 && *address < 0x14000000) {
|
||||||
|
if ((*address + length) <= 0x14000000) {
|
||||||
*address = *address - 0x10000000 + 0x00000000;
|
*address = *address - 0x10000000 + 0x00000000;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (with_flash && *address >= 0x14000000 && *address < 0x15000000) {
|
||||||
|
if ((*address + length) <= 0x15000000) {
|
||||||
|
*address = *address - 0x14000000 + 0x04000000;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (*address >= 0x1FFE0000 && *address < 0x1FFE2000) {
|
if (*address >= 0x1FFE0000 && *address < 0x1FFE2000) {
|
||||||
if ((*address + length) <= 0x1FFE2000) {
|
if ((*address + length) <= 0x1FFE2000) {
|
||||||
*address = *address - 0x1FFE0000 + 0x05000000;
|
*address = *address - 0x1FFE0000 + 0x05000000;
|
||||||
@ -446,7 +464,7 @@ void cfg_process (void) {
|
|||||||
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cfg_translate_address(&args[0], args[1] * 512, true)) {
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, true)) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -461,7 +479,7 @@ void cfg_process (void) {
|
|||||||
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
cfg_set_error(CFG_ERROR_BAD_ARGUMENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cfg_translate_address(&args[0], args[1] * 512, true)) {
|
if (cfg_translate_address(&args[0], args[1] * SD_SECTOR_SIZE, true)) {
|
||||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
|
#include "led.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
@ -86,7 +87,6 @@ struct process {
|
|||||||
bool sd_mode;
|
bool sd_mode;
|
||||||
uint8_t sd_current_disk;
|
uint8_t sd_current_disk;
|
||||||
sd_disk_info_t sd_disk_info[DD_SD_MAX_DISKS];
|
sd_disk_info_t sd_disk_info[DD_SD_MAX_DISKS];
|
||||||
uint32_t sd_sector_table[DD_SD_SECTOR_TABLE_SIZE];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -100,9 +100,12 @@ static uint16_t dd_track_head_block (void) {
|
|||||||
return (track | head | block);
|
return (track | head | block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t dd_fill_sd_sector_table (uint32_t index) {
|
static uint32_t dd_fill_sd_sector_table (uint32_t index, uint32_t *sector_table) {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
sd_disk_info_t info = p.sd_disk_info[p.sd_current_disk];
|
sd_disk_info_t info = p.sd_disk_info[p.sd_current_disk];
|
||||||
|
if (info.thb_table_address == 0xFFFFFFFF) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t thb_entry_address = (info.thb_table_address + (index * sizeof(uint32_t)));
|
uint32_t thb_entry_address = (info.thb_table_address + (index * sizeof(uint32_t)));
|
||||||
fpga_mem_read(thb_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
fpga_mem_read(thb_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
||||||
uint32_t start_offset = SWAP32(tmp);
|
uint32_t start_offset = SWAP32(tmp);
|
||||||
@ -111,34 +114,52 @@ static uint32_t dd_fill_sd_sector_table (uint32_t index) {
|
|||||||
}
|
}
|
||||||
p.block_offset = (start_offset % SD_SECTOR_SIZE);
|
p.block_offset = (start_offset % SD_SECTOR_SIZE);
|
||||||
uint32_t block_length = ((p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM);
|
uint32_t block_length = ((p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM);
|
||||||
uint32_t end_offset = ((start_offset + block_length) - 1); // CHECK THIS
|
uint32_t end_offset = ((start_offset + block_length) - 1);
|
||||||
uint32_t starting_sector = (start_offset / SD_SECTOR_SIZE);
|
uint32_t starting_sector = (start_offset / SD_SECTOR_SIZE);
|
||||||
uint32_t sectors = (1 + ((end_offset / SD_SECTOR_SIZE) - starting_sector));
|
uint32_t sectors = (1 + ((end_offset / SD_SECTOR_SIZE) - starting_sector));
|
||||||
for (int i = 0; i < sectors; i++) {
|
for (int i = 0; i < sectors; i++) {
|
||||||
uint32_t sector_entry_address = info.sector_table_address + ((starting_sector + i) * sizeof(uint32_t));
|
uint32_t sector_entry_address = info.sector_table_address + ((starting_sector + i) * sizeof(uint32_t));
|
||||||
fpga_mem_read(sector_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
fpga_mem_read(sector_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
||||||
p.sd_sector_table[i] = SWAP32(tmp);
|
sector_table[i] = SWAP32(tmp);
|
||||||
}
|
}
|
||||||
return sectors;
|
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) {
|
static bool dd_block_read_request (void) {
|
||||||
uint16_t index = dd_track_head_block();
|
uint16_t index = dd_track_head_block();
|
||||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||||
|
|
||||||
if (p.sd_mode) {
|
if (p.sd_mode) {
|
||||||
dd_set_block_ready(false);
|
dd_process_sd_request(index, buffer_address, false);
|
||||||
uint32_t sectors = dd_fill_sd_sector_table(index);
|
|
||||||
if (sectors > 0) {
|
|
||||||
for (int i = 0; i < sectors; i++) {
|
|
||||||
if (sd_read_sectors(buffer_address, p.sd_sector_table[i], 1)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
buffer_address += SD_SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
dd_set_block_ready(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
usb_tx_info_t packet_info;
|
usb_tx_info_t packet_info;
|
||||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||||
@ -150,25 +171,14 @@ static bool dd_block_read_request (void) {
|
|||||||
p.block_offset = 0;
|
p.block_offset = 0;
|
||||||
return usb_enqueue_packet(&packet_info);
|
return usb_enqueue_packet(&packet_info);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dd_block_write_request (void) {
|
static bool dd_block_write_request (void) {
|
||||||
uint32_t index = dd_track_head_block();
|
uint32_t index = dd_track_head_block();
|
||||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||||
|
|
||||||
if (p.sd_mode) {
|
if (p.sd_mode) {
|
||||||
dd_set_block_ready(false);
|
dd_process_sd_request(index, buffer_address, true);
|
||||||
uint32_t sectors = dd_fill_sd_sector_table(index);
|
|
||||||
if (sectors > 0) {
|
|
||||||
for (int i = 0; i < sectors; i++) {
|
|
||||||
if (sd_write_sectors(buffer_address, p.sd_sector_table[i], 1)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
buffer_address += SD_SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
dd_set_block_ready(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
usb_tx_info_t packet_info;
|
usb_tx_info_t packet_info;
|
||||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||||
@ -182,6 +192,7 @@ static bool dd_block_write_request (void) {
|
|||||||
p.block_offset = 0;
|
p.block_offset = 0;
|
||||||
return usb_enqueue_packet(&packet_info);
|
return usb_enqueue_packet(&packet_info);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dd_set_cmd_response_ready (void) {
|
static void dd_set_cmd_response_ready (void) {
|
||||||
@ -250,18 +261,36 @@ void dd_set_sd_mode (bool value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dd_set_sd_disk_info (uint32_t address, uint32_t length) {
|
void dd_set_sd_disk_info (uint32_t address, uint32_t length) {
|
||||||
uint32_t tmp[2];
|
sd_disk_info_t info;
|
||||||
|
length /= sizeof(info);
|
||||||
p.sd_current_disk = 0;
|
p.sd_current_disk = 0;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < DD_SD_MAX_DISKS; i++) {
|
||||||
fpga_mem_read(address, sizeof(tmp), (uint8_t *) (tmp));
|
if (i < length) {
|
||||||
p.sd_disk_info[i].thb_table_address = SWAP32(tmp[0]);
|
fpga_mem_read(address, sizeof(info), (uint8_t *) (&info));
|
||||||
p.sd_disk_info[i].sector_table_address = SWAP32(tmp[1]);
|
p.sd_disk_info[i].thb_table_address = (SWAP32(info.thb_table_address) & 0x1FFFFFFF);
|
||||||
address += sizeof(tmp);
|
p.sd_disk_info[i].sector_table_address = (SWAP32(info.sector_table_address) & 0x1FFFFFFF);
|
||||||
|
address += sizeof(info);
|
||||||
|
} else {
|
||||||
|
p.sd_disk_info[i].thb_table_address = 0xFFFFFFFF;
|
||||||
|
p.sd_disk_info[i].sector_table_address = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dd_handle_button (void) {
|
void dd_handle_button (void) {
|
||||||
// TODO: disk swap
|
led_blink_act();
|
||||||
|
if (dd_get_disk_state() == DD_DISK_STATE_EJECTED) {
|
||||||
|
dd_set_disk_state(DD_DISK_STATE_INSERTED);
|
||||||
|
} else {
|
||||||
|
dd_set_disk_state(DD_DISK_STATE_EJECTED);
|
||||||
|
for (uint8_t i = 0; i < DD_SD_MAX_DISKS; i++) {
|
||||||
|
uint8_t sd_next_disk = ((p.sd_current_disk + i + 1) % DD_SD_MAX_DISKS);
|
||||||
|
if (p.sd_disk_info[sd_next_disk].thb_table_address != 0xFFFFFFFF) {
|
||||||
|
p.sd_current_disk = sd_next_disk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dd_init (void) {
|
void dd_init (void) {
|
||||||
@ -276,6 +305,7 @@ void dd_init (void) {
|
|||||||
p.drive_type = DD_DRIVE_TYPE_RETAIL;
|
p.drive_type = DD_DRIVE_TYPE_RETAIL;
|
||||||
p.sd_mode = false;
|
p.sd_mode = false;
|
||||||
p.sd_current_disk = 0;
|
p.sd_current_disk = 0;
|
||||||
|
dd_set_sd_disk_info(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dd_process (void) {
|
void dd_process (void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user