mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 22:19:14 +01:00
double buffered reads
This commit is contained in:
parent
ee43b5f7c0
commit
d1823be902
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
|
||||||
while (count > 0) {
|
if (sc64_drive_start_rw(drive, false, sector++, 0)) {
|
||||||
if (sc64_drive_start_read_and_wait(drive, sector)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
while (count > 0) {
|
||||||
|
if (sc64_wait_drive_ready(drive)) {
|
||||||
|
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;
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user