double buffered reads

This commit is contained in:
Polprzewodnikowy 2022-01-22 13:03:05 +01:00
parent ee43b5f7c0
commit d1823be902
8 changed files with 42 additions and 37 deletions

View File

@ -1,7 +1,7 @@
#include "vr4300.h" #include "vr4300.h"
#define WATCHDOG_TIMEOUT (5 * (93750000UL / 2)) #define WATCHDOG_TIMEOUT (3 * (93750000UL / 2))
#define VECTOR_LOCATION (0xA0000000UL) #define VECTOR_LOCATION (0xA0000000UL)
#define VECTOR_SIZE (0x80) #define VECTOR_SIZE (0x80)

View File

@ -276,7 +276,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask,
if (exception_code == EXCEPTION_INTERRUPT) { if (exception_code == EXCEPTION_INTERRUPT) {
if (interrupt_mask & INTERRUPT_MASK_TIMER) { if (interrupt_mask & INTERRUPT_MASK_TIMER) {
exception_disable_watchdog(); exception_disable_watchdog();
exception_print("Still loading after 5 second limit...\n\n"); exception_print("Still loading after 3 second limit...\n\n");
return; return;
} }
} else if (exception_code == EXCEPTION_SYSCALL) { } else if (exception_code == EXCEPTION_SYSCALL) {

View File

@ -230,8 +230,8 @@ typedef struct {
io32_t DATA[2]; io32_t DATA[2];
io32_t VERSION; io32_t VERSION;
io32_t __padding[4092]; io32_t __padding[4092];
io32_t CPU_RAM[3968]; io32_t CPU_RAM[3840];
io32_t BUFFER[128]; io32_t BUFFER[256];
} sc64_regs_t; } sc64_regs_t;
#define SC64_BASE (0x1FFF0000UL) #define SC64_BASE (0x1FFF0000UL)

View File

@ -63,7 +63,7 @@ void sc64_init (void) {
} }
static uint32_t sc64_wait_drive_ready (drive_id_t drive) { static uint32_t sc64_wait_drive_ready (drive_id_t drive) {
uint32_t args[2] = { drive, 0 }; uint32_t args[2] = { (drive & 0xFF), 0 };
uint32_t result[2]; uint32_t result[2];
do { do {
sc64_perform_cmd(SC64_CMD_DRIVE_BUSY, args, result); sc64_perform_cmd(SC64_CMD_DRIVE_BUSY, args, result);
@ -72,46 +72,44 @@ static uint32_t sc64_wait_drive_ready (drive_id_t drive) {
} }
bool sc64_storage_init (drive_id_t drive) { bool sc64_storage_init (drive_id_t drive) {
uint32_t args[2] = { drive, 0 }; uint32_t args[2] = { (drive & 0xFF), 0 };
if (sc64_perform_cmd(SC64_CMD_DRIVE_INIT, args, NULL)) { if (sc64_perform_cmd(SC64_CMD_DRIVE_INIT, args, NULL)) {
return true; return true;
} }
if (sc64_wait_drive_ready(drive) != 0) { if (sc64_wait_drive_ready(drive)) {
return true; return true;
} }
return false; return false;
} }
static bool sc64_drive_start_read_and_wait (drive_id_t drive, uint32_t sector) { static bool sc64_drive_start_rw (drive_id_t drive, bool write, uint32_t sector, uint32_t offset) {
uint32_t args[2] = { drive, sector }; uint32_t args[2] = { (((offset & 0xFFFFFF) << 8) | (drive & 0xFF)), sector };
if (sc64_perform_cmd(SC64_CMD_DRIVE_READ, args, NULL)) { if (sc64_perform_cmd(write ? SC64_CMD_DRIVE_WRITE : SC64_CMD_DRIVE_READ, args, NULL)) {
return true;
}
if (sc64_wait_drive_ready(drive) != 0) {
return true;
}
return false;
}
static bool sc64_drive_start_write_and_wait (drive_id_t drive, uint32_t sector) {
uint32_t args[2] = { drive, sector };
if (sc64_perform_cmd(SC64_CMD_DRIVE_WRITE, args, NULL)) {
return true;
}
if (sc64_wait_drive_ready(drive) != 0) {
return true; return true;
} }
return false; return false;
} }
bool sc64_storage_read (drive_id_t drive, void *buffer, uint32_t sector, uint32_t count) { bool sc64_storage_read (drive_id_t drive, void *buffer, uint32_t sector, uint32_t count) {
io32_t *src = SC64->BUFFER; io32_t *src;
uint8_t *dst = (uint8_t *) (buffer); uint8_t *dst = (uint8_t *) (buffer);
uint32_t current_offset = 0;
uint32_t next_offset = SECTOR_SIZE;
if (sc64_drive_start_rw(drive, false, sector++, 0)) {
return true;
}
while (count > 0) { while (count > 0) {
if (sc64_drive_start_read_and_wait(drive, sector)) { if (sc64_wait_drive_ready(drive)) {
return true; return true;
} }
if (count > 1) {
if (sc64_drive_start_rw(drive, false, sector++, next_offset)) {
return true;
}
next_offset = next_offset ? 0 : SECTOR_SIZE;
}
src = &SC64->BUFFER[current_offset / sizeof(io32_t)];
for (int i = 0; i < (SECTOR_SIZE / sizeof(uint32_t)); i++) { for (int i = 0; i < (SECTOR_SIZE / sizeof(uint32_t)); i++) {
uint32_t data = pi_io_read(src + i); uint32_t data = pi_io_read(src + i);
*dst++ = ((data >> 24) & 0xFF); *dst++ = ((data >> 24) & 0xFF);
@ -119,7 +117,7 @@ bool sc64_storage_read (drive_id_t drive, void *buffer, uint32_t sector, uint32_
*dst++ = ((data >> 8) & 0xFF); *dst++ = ((data >> 8) & 0xFF);
*dst++ = ((data >> 0) & 0xFF); *dst++ = ((data >> 0) & 0xFF);
} }
sector += 1; current_offset = current_offset ? 0 : SECTOR_SIZE;
count -= 1; count -= 1;
} }
@ -139,7 +137,10 @@ bool sc64_storage_write (drive_id_t drive, const void *buffer, uint32_t sector,
data |= ((*src++) << 0); data |= ((*src++) << 0);
pi_io_write((dst + i), data); pi_io_write((dst + i), data);
} }
if (sc64_drive_start_write_and_wait(drive, sector)) { if (sc64_drive_start_rw(drive, true, sector, 0)) {
return true;
}
if (sc64_wait_drive_ready(drive)) {
return true; return true;
} }
sector += 1; sector += 1;

View File

@ -542,22 +542,24 @@ class SC64:
def __debug_process_fsd_read(self, data: bytes) -> None: def __debug_process_fsd_read(self, data: bytes) -> None:
sector = int.from_bytes(data[0:4], byteorder='little') sector = int.from_bytes(data[0:4], byteorder='little')
offset = int.from_bytes(data[4:8], byteorder='little')
if (self.__fsd_file): if (self.__fsd_file):
self.__fsd_file.seek(sector * 512) self.__fsd_file.seek(sector * 512)
self.__write_cmd("T", 0, 512) self.__write_cmd("T", offset, 512)
self.__write(self.__fsd_file.read(512)) self.__write(self.__fsd_file.read(512))
else: else:
self.__write_cmd("T", 0, 0) self.__write_cmd("T", offset, 0)
def __debug_process_fsd_write(self, data: bytes) -> None: def __debug_process_fsd_write(self, data: bytes) -> None:
sector = int.from_bytes(data[0:4], byteorder='little') sector = int.from_bytes(data[0:4], byteorder='little')
offset = int.from_bytes(data[4:8], byteorder='little')
if (self.__fsd_file): if (self.__fsd_file):
self.__fsd_file.seek(sector * 512) self.__fsd_file.seek(sector * 512)
self.__write_cmd("F", 0, 512) self.__write_cmd("F", offset, 512)
self.__fsd_file.write(self.__read(512)) self.__fsd_file.write(self.__read(512))
else: else:
self.__write_cmd("F", 0, 0) self.__write_cmd("F", offset, 0)
def __debug_process_dd_block(self, data: bytes) -> None: def __debug_process_dd_block(self, data: bytes) -> None:

View File

@ -1,6 +1,6 @@
MEMORY { MEMORY {
ram (rwx) : org = 0x00000000, len = 16k - 512 ram (rwx) : org = 0x00000000, len = 15k
buffer (rw) : org = 0x00003E00, len = 512 buffer (rw) : org = 0x00003C00, len = 1k
rom (rx) : org = 0x10010000, len = 26k rom (rx) : org = 0x10010000, len = 26k
} }

View File

@ -310,7 +310,8 @@ void process_cfg (void) {
event.id = EVENT_ID_FSD_READ; event.id = EVENT_ID_FSD_READ;
event.trigger = CALLBACK_BUFFER_WRITE; event.trigger = CALLBACK_BUFFER_WRITE;
event.callback = set_usb_drive_not_busy; event.callback = set_usb_drive_not_busy;
if (usb_put_event(&event, &args[1], sizeof(args[1]))) { uint32_t data[2] = { args[1], (args[0] >> 8) };
if (usb_put_event(&event, data, sizeof(data))) {
p.usb_drive_busy = true; p.usb_drive_busy = true;
} else { } else {
return; return;
@ -328,7 +329,8 @@ void process_cfg (void) {
event.id = EVENT_ID_FSD_WRITE; event.id = EVENT_ID_FSD_WRITE;
event.trigger = CALLBACK_BUFFER_READ; event.trigger = CALLBACK_BUFFER_READ;
event.callback = set_usb_drive_not_busy; event.callback = set_usb_drive_not_busy;
if (usb_put_event(&event, &args[1], sizeof(args[1]))) { uint32_t data[2] = { args[1], (args[0] >> 8) };
if (usb_put_event(&event, data, sizeof(data))) {
p.usb_drive_busy = true; p.usb_drive_busy = true;
} else { } else {
return; return;

View File

@ -22,7 +22,7 @@ typedef volatile uint32_t io32_t;
#define RAM_BASE (0x00000000UL) #define RAM_BASE (0x00000000UL)
#define RAMBUFFER_SIZE (512) #define RAMBUFFER_SIZE (1024)
#define RAM_SIZE ((16 * 1024) - RAMBUFFER_SIZE) #define RAM_SIZE ((16 * 1024) - RAMBUFFER_SIZE)
#define RAMBUFFER_BASE (RAM_BASE + RAM_SIZE) #define RAMBUFFER_BASE (RAM_BASE + RAM_SIZE)
#define RAM (*((io32_t *) RAM_BASE)) #define RAM (*((io32_t *) RAM_BASE))