mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 22:19:14 +01:00
faster sd menu loading
This commit is contained in:
parent
da99bc5619
commit
72fe795e56
@ -1,3 +1,4 @@
|
|||||||
|
#include <string.h>
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
#include "../io.h"
|
#include "../io.h"
|
||||||
@ -5,6 +6,8 @@
|
|||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SD_BLOCK_SIZE (512)
|
||||||
|
#define BUFFER_BLOCKS_MAX (sizeof(SC64_BUFFERS->BUFFER) / SD_BLOCK_SIZE)
|
||||||
#define FROM_BCD(x) ((((x >> 4) & 0x0F) * 10) + (x & 0x0F))
|
#define FROM_BCD(x) ((((x >> 4) & 0x0F) * 10) + (x & 0x0F))
|
||||||
|
|
||||||
|
|
||||||
@ -34,21 +37,24 @@ 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)));
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
uint32_t block = ((count > 16) ? 16 : count);
|
uint32_t blocks = ((count > BUFFER_BLOCKS_MAX) ? BUFFER_BLOCKS_MAX : count);
|
||||||
if (sc64_sd_read_sectors((uint32_t *) (SC64_BUFFERS->BUFFER), sector, block)) {
|
size_t length = (blocks * SD_BLOCK_SIZE);
|
||||||
|
if (sc64_sd_read_sectors((uint32_t *) (SC64_BUFFERS->BUFFER), sector, blocks)) {
|
||||||
return RES_ERROR;
|
return RES_ERROR;
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < (block * 512); i += 4) {
|
if (((uint32_t) (buff) % 8) == 0) {
|
||||||
// TODO: use dma
|
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), buff, length);
|
||||||
uint32_t data = pi_io_read((uint32_t *) (&SC64_BUFFERS->BUFFER[i]));
|
cache_data_hit_invalidate(buff, length);
|
||||||
uint8_t *ptr = (uint8_t *) (&data);
|
} else {
|
||||||
for (int j = 0; j < 4; j++) {
|
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), aligned_buffer, length);
|
||||||
*buff++ = *ptr++;
|
cache_data_hit_invalidate(aligned_buffer, length);
|
||||||
|
memcpy(buff, aligned_buffer, length);
|
||||||
}
|
}
|
||||||
}
|
buff += length;
|
||||||
count -= block;
|
sector += blocks;
|
||||||
sector += block;
|
count -= blocks;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sc64_sd_read_sectors(physical_address, sector, count)) {
|
if (sc64_sd_read_sectors(physical_address, sector, count)) {
|
||||||
|
@ -25,6 +25,20 @@ void pi_io_write (io32_t *address, uint32_t value) {
|
|||||||
while (pi_busy());
|
while (pi_busy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pi_dma_read (io32_t *address, void *buffer, size_t length) {
|
||||||
|
io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
|
||||||
|
io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
|
||||||
|
io_write(&PI->WDMA, length - 1);
|
||||||
|
while (pi_busy());
|
||||||
|
}
|
||||||
|
|
||||||
|
void pi_dma_write (io32_t *address, void *buffer, size_t length) {
|
||||||
|
io_write(&PI->PADDR, (uint32_t) (PHYSICAL(address)));
|
||||||
|
io_write(&PI->MADDR, (uint32_t) (PHYSICAL(buffer)));
|
||||||
|
io_write(&PI->RDMA, length - 1);
|
||||||
|
while (pi_busy());
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t si_busy (void) {
|
uint32_t si_busy (void) {
|
||||||
return (io_read(&SI->SR) & (SI_SR_IO_BUSY | SI_SR_DMA_BUSY));
|
return (io_read(&SI->SR) & (SI_SR_IO_BUSY | SI_SR_DMA_BUSY));
|
||||||
}
|
}
|
||||||
@ -37,3 +51,23 @@ void si_io_write (io32_t *address, uint32_t value) {
|
|||||||
io_write(address, value);
|
io_write(address, value);
|
||||||
while (si_busy());
|
while (si_busy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cache_operation (uint8_t operation, uint8_t line_size, void *address, size_t length) {
|
||||||
|
uint32_t cache_address = (((uint32_t) (address)) & (~(line_size - 1)));
|
||||||
|
while (cache_address < ((uint32_t) (address) + length)) {
|
||||||
|
asm volatile (
|
||||||
|
"cache %[operation], (%[cache_address]) \n" ::
|
||||||
|
[operation] "i" (operation),
|
||||||
|
[cache_address] "r" (cache_address)
|
||||||
|
);
|
||||||
|
cache_address += line_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_data_hit_invalidate (void *address, size_t length) {
|
||||||
|
cache_operation (0x11, 16, address, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_data_hit_writeback (void *address, size_t length) {
|
||||||
|
cache_operation (0x19, 16, address, length);
|
||||||
|
}
|
||||||
|
@ -281,9 +281,13 @@ void io_write (io32_t *address, uint32_t value);
|
|||||||
uint32_t pi_busy (void);
|
uint32_t pi_busy (void);
|
||||||
uint32_t pi_io_read (io32_t *address);
|
uint32_t pi_io_read (io32_t *address);
|
||||||
void pi_io_write (io32_t *address, uint32_t value);
|
void pi_io_write (io32_t *address, uint32_t value);
|
||||||
|
void pi_dma_read (io32_t *address, void *buffer, size_t length);
|
||||||
|
void pi_dma_write (io32_t *address, void *buffer, size_t length);
|
||||||
uint32_t si_busy (void);
|
uint32_t si_busy (void);
|
||||||
uint32_t si_io_read (io32_t *address);
|
uint32_t si_io_read (io32_t *address);
|
||||||
void si_io_write (io32_t *address, uint32_t value);
|
void si_io_write (io32_t *address, uint32_t value);
|
||||||
|
void cache_data_hit_invalidate (void *address, size_t length);
|
||||||
|
void cache_data_hit_writeback (void *address, size_t length);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user