From d1823be9026ed17f438372eecf975f7c1d404bca Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Sat, 22 Jan 2022 13:03:05 +0100 Subject: [PATCH] double buffered reads --- sw/n64/src/exception.S | 2 +- sw/n64/src/exception.c | 2 +- sw/n64/src/io.h | 4 ++-- sw/n64/src/sc64.c | 49 +++++++++++++++++++++--------------------- sw/pc/sc64.py | 10 +++++---- sw/riscv/SC64.ld | 4 ++-- sw/riscv/src/cfg.c | 6 ++++-- sw/riscv/src/sys.h | 2 +- 8 files changed, 42 insertions(+), 37 deletions(-) diff --git a/sw/n64/src/exception.S b/sw/n64/src/exception.S index ab3d16e..c7caa23 100644 --- a/sw/n64/src/exception.S +++ b/sw/n64/src/exception.S @@ -1,7 +1,7 @@ #include "vr4300.h" -#define WATCHDOG_TIMEOUT (5 * (93750000UL / 2)) +#define WATCHDOG_TIMEOUT (3 * (93750000UL / 2)) #define VECTOR_LOCATION (0xA0000000UL) #define VECTOR_SIZE (0x80) diff --git a/sw/n64/src/exception.c b/sw/n64/src/exception.c index 927f722..c965c05 100644 --- a/sw/n64/src/exception.c +++ b/sw/n64/src/exception.c @@ -276,7 +276,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask, if (exception_code == EXCEPTION_INTERRUPT) { if (interrupt_mask & INTERRUPT_MASK_TIMER) { exception_disable_watchdog(); - exception_print("Still loading after 5 second limit...\n\n"); + exception_print("Still loading after 3 second limit...\n\n"); return; } } else if (exception_code == EXCEPTION_SYSCALL) { diff --git a/sw/n64/src/io.h b/sw/n64/src/io.h index 8e8eb4e..e6897cf 100644 --- a/sw/n64/src/io.h +++ b/sw/n64/src/io.h @@ -230,8 +230,8 @@ typedef struct { io32_t DATA[2]; io32_t VERSION; io32_t __padding[4092]; - io32_t CPU_RAM[3968]; - io32_t BUFFER[128]; + io32_t CPU_RAM[3840]; + io32_t BUFFER[256]; } sc64_regs_t; #define SC64_BASE (0x1FFF0000UL) diff --git a/sw/n64/src/sc64.c b/sw/n64/src/sc64.c index cef551c..34761cb 100644 --- a/sw/n64/src/sc64.c +++ b/sw/n64/src/sc64.c @@ -63,7 +63,7 @@ void sc64_init (void) { } 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]; do { 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) { - uint32_t args[2] = { drive, 0 }; + uint32_t args[2] = { (drive & 0xFF), 0 }; if (sc64_perform_cmd(SC64_CMD_DRIVE_INIT, args, NULL)) { return true; } - if (sc64_wait_drive_ready(drive) != 0) { + if (sc64_wait_drive_ready(drive)) { return true; } return false; } -static bool sc64_drive_start_read_and_wait (drive_id_t drive, uint32_t sector) { - uint32_t args[2] = { drive, sector }; - if (sc64_perform_cmd(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) { +static bool sc64_drive_start_rw (drive_id_t drive, bool write, uint32_t sector, uint32_t offset) { + uint32_t args[2] = { (((offset & 0xFFFFFF) << 8) | (drive & 0xFF)), sector }; + if (sc64_perform_cmd(write ? SC64_CMD_DRIVE_WRITE : SC64_CMD_DRIVE_READ, args, NULL)) { return true; } return false; } 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); + 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) { - if (sc64_drive_start_read_and_wait(drive, sector)) { + 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++) { uint32_t data = pi_io_read(src + i); *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 >> 0) & 0xFF); } - sector += 1; + current_offset = current_offset ? 0 : SECTOR_SIZE; count -= 1; } @@ -139,7 +137,10 @@ bool sc64_storage_write (drive_id_t drive, const void *buffer, uint32_t sector, data |= ((*src++) << 0); 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; } sector += 1; diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index d06ecbf..7567550 100644 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -542,22 +542,24 @@ class SC64: def __debug_process_fsd_read(self, data: bytes) -> None: sector = int.from_bytes(data[0:4], byteorder='little') + offset = int.from_bytes(data[4:8], byteorder='little') if (self.__fsd_file): 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)) else: - self.__write_cmd("T", 0, 0) + self.__write_cmd("T", offset, 0) def __debug_process_fsd_write(self, data: bytes) -> None: sector = int.from_bytes(data[0:4], byteorder='little') + offset = int.from_bytes(data[4:8], byteorder='little') if (self.__fsd_file): 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)) else: - self.__write_cmd("F", 0, 0) + self.__write_cmd("F", offset, 0) def __debug_process_dd_block(self, data: bytes) -> None: diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld index 1573836..69d4601 100644 --- a/sw/riscv/SC64.ld +++ b/sw/riscv/SC64.ld @@ -1,6 +1,6 @@ MEMORY { - ram (rwx) : org = 0x00000000, len = 16k - 512 - buffer (rw) : org = 0x00003E00, len = 512 + ram (rwx) : org = 0x00000000, len = 15k + buffer (rw) : org = 0x00003C00, len = 1k rom (rx) : org = 0x10010000, len = 26k } diff --git a/sw/riscv/src/cfg.c b/sw/riscv/src/cfg.c index cfa0d44..afb635c 100644 --- a/sw/riscv/src/cfg.c +++ b/sw/riscv/src/cfg.c @@ -310,7 +310,8 @@ void process_cfg (void) { event.id = EVENT_ID_FSD_READ; event.trigger = CALLBACK_BUFFER_WRITE; 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; } else { return; @@ -328,7 +329,8 @@ void process_cfg (void) { event.id = EVENT_ID_FSD_WRITE; event.trigger = CALLBACK_BUFFER_READ; 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; } else { return; diff --git a/sw/riscv/src/sys.h b/sw/riscv/src/sys.h index 4d84f9d..380aafa 100644 --- a/sw/riscv/src/sys.h +++ b/sw/riscv/src/sys.h @@ -22,7 +22,7 @@ typedef volatile uint32_t io32_t; #define RAM_BASE (0x00000000UL) -#define RAMBUFFER_SIZE (512) +#define RAMBUFFER_SIZE (1024) #define RAM_SIZE ((16 * 1024) - RAMBUFFER_SIZE) #define RAMBUFFER_BASE (RAM_BASE + RAM_SIZE) #define RAM (*((io32_t *) RAM_BASE))