diff --git a/file_io.cpp b/file_io.cpp index 3d92a55..7d4f135 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -602,6 +602,10 @@ int FileWriteAdv(fileTYPE *file, void *pBuffer, int length, int failres) printf("FileWriteAdv error(%d).\n", ret); return failres; } + + file->offset += ret; + if (file->offset > file->size) file->size = FileGetSize(file); + return ret; } else if (file->zip) { @@ -613,9 +617,6 @@ int FileWriteAdv(fileTYPE *file, void *pBuffer, int length, int failres) printf("FileWriteAdv error(unknown file type).\n"); return failres; } - - file->offset += ret; - return ret; } int FileWriteSec(fileTYPE *file, void *pBuffer) diff --git a/spi.cpp b/spi.cpp index 28169e9..73c75f0 100644 --- a/spi.cpp +++ b/spi.cpp @@ -103,13 +103,13 @@ void spi_uio_cmd32_cont(uint8_t cmd, uint32_t parm) } /* User_io related SPI functions */ -uint8_t spi_uio_cmd_cont(uint8_t cmd) +uint16_t spi_uio_cmd_cont(uint8_t cmd) { EnableIO(); - return spi_b(cmd); + return spi_w(cmd); } -uint8_t spi_uio_cmd(uint8_t cmd) +uint16_t spi_uio_cmd(uint8_t cmd) { uint8_t res = spi_uio_cmd_cont(cmd); DisableIO(); @@ -192,14 +192,14 @@ void spi_write(const uint8_t *addr, uint16_t len, int wide) } } -void spi_block_read(uint8_t *addr, int wide) +void spi_block_read(uint8_t *addr, int wide, int sz) { - if (wide) fpga_spi_fast_block_read((uint16_t*)addr, 256); - else fpga_spi_fast_block_read_8(addr, 512); + if (wide) fpga_spi_fast_block_read((uint16_t*)addr, sz/2); + else fpga_spi_fast_block_read_8(addr, sz); } -void spi_block_write(const uint8_t *addr, int wide) +void spi_block_write(const uint8_t *addr, int wide, int sz) { - if (wide) fpga_spi_fast_block_write((const uint16_t*)addr, 256); - else fpga_spi_fast_block_write_8(addr, 512); + if (wide) fpga_spi_fast_block_write((const uint16_t*)addr, sz/2); + else fpga_spi_fast_block_write_8(addr, sz); } diff --git a/spi.h b/spi.h index e80a381..e013941 100644 --- a/spi.h +++ b/spi.h @@ -41,8 +41,8 @@ uint32_t spi32_w(uint32_t parm); /* block transfer functions */ void spi_read(uint8_t *addr, uint16_t len, int wide); void spi_write(const uint8_t *addr, uint16_t len, int wide); -void spi_block_read(uint8_t *addr, int wide); -void spi_block_write(const uint8_t *addr, int wide); +void spi_block_read(uint8_t *addr, int wide, int sz = 512); +void spi_block_write(const uint8_t *addr, int wide, int sz = 512); /* OSD related SPI functions */ void EnableOsd_on(int target); @@ -52,8 +52,8 @@ void spi_osd_cmd8_cont(uint8_t cmd, uint8_t parm); void spi_osd_cmd8(uint8_t cmd, uint8_t parm); /* User_io related SPI functions */ -uint8_t spi_uio_cmd_cont(uint8_t cmd); -uint8_t spi_uio_cmd(uint8_t cmd); +uint16_t spi_uio_cmd_cont(uint8_t cmd); +uint16_t spi_uio_cmd(uint8_t cmd); uint8_t spi_uio_cmd8_cont(uint8_t cmd, uint8_t parm); uint8_t spi_uio_cmd8(uint8_t cmd, uint8_t parm); uint16_t spi_uio_cmd16(uint8_t cmd, uint16_t parm); diff --git a/user_io.cpp b/user_io.cpp index 4a31c11..0327ebf 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -39,9 +39,12 @@ static char core_path[1024] = {}; static char rbf_path[1024] = {}; -static fileTYPE sd_image[4] = {}; -static int sd_image_cangrow[4] = {}; -static uint64_t buffer_lba[4] = { ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX }; +static fileTYPE sd_image[16] = {}; +static int sd_image_cangrow[16] = {}; +static uint64_t buffer_lba[16] = { ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX, + ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX, + ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX, + ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX }; static int use_save = 0; @@ -1343,42 +1346,6 @@ void user_io_sd_set_config(void) */ } -// read 8+32 bit sd card status word from FPGA -uint16_t user_io_sd_get_status(uint32_t *lba, uint16_t *req_type) -{ - uint32_t s; - uint16_t c; - uint16_t req = 0; - - spi_uio_cmd_cont(UIO_GET_SDSTAT); - if (io_ver) - { - c = spi_w(0); - s = spi_w(0); - s = (s & 0xFFFF) | (((uint32_t)spi_w(0))<<16); - req = spi_w(0); - } - else - { - //note: using 32bit big-endian transfer! - c = spi_in(); - s = spi_in(); - s = (s << 8) | spi_in(); - s = (s << 8) | spi_in(); - s = (s << 8) | spi_in(); - req = spi_in(); - } - DisableIO(); - - if (lba) - *lba = s; - - if (req) - *req_type = req; - - return c; -} - // read 8 bit keyboard LEDs status from FPGA uint16_t user_io_kbdled_get_status(void) { @@ -2626,179 +2593,211 @@ void user_io_poll() while (1) { - const int buf_sz = 16; - static uint8_t buffer[4][buf_sz * 512]; - uint32_t lba; - uint16_t req_type = 0; - uint16_t c = user_io_sd_get_status(&lba, &req_type); - //if(c&3) printf("user_io_sd_get_status: cmd=%02x, lba=%08x\n", c, lba); + int disk = -1; + int ack = 0; + int op = 0; + static uint8_t buffer[16][16384]; + uint64_t lba; + uint32_t blkpow = 9; + uint32_t sz = 512; + uint32_t blksz = 1; - // valid sd commands start with "5x" to avoid problems with - // cores that don't implement this command - if ((c & 0xf0) == 0x50) + uint16_t c = spi_uio_cmd_cont(UIO_GET_SDSTAT); + if (c & 0x8000) { - // check if core requests configuration - if ((c & 0xC) == 0xC) + disk = (c >> 2) & 0xF; + op = c & 3; + ack = disk << 8; + spi_w(0); + lba = spi_w(0); + lba = (lba & 0xFFFF) | (((uint32_t)spi_w(0)) << 16); + blkpow = 7 + ((c >> 6) & 7); + blksz = (((c >> 9) & 0x3F) + 1); + sz = blksz << blkpow; + if (sz > sizeof(buffer[0])) { - printf("core requests SD config\n"); - user_io_sd_set_config(); + sz = sizeof(buffer[0]); + blksz = sz >> blkpow; } - - if (c & 0x3802) + //if (op) printf("c=%X, op=%d, blkpow=%d, sz=%d, lba=%llu, disk=%d\n", c, op, blkpow, sz, lba, disk); + } + else + { + c = spi_w(0); + if ((c & 0xf0) == 0x50 && (c & 0x3F03)) { - int disk = 3; - if (c & 0x0002) disk = 0; - else if (c & 0x0800) disk = 1; - else if (c & 0x1000) disk = 2; + lba = spi_w(0); + lba = (lba & 0xFFFF) | (((uint32_t)spi_w(0)) << 16); - //printf("SD WR %d on %d\n", lba, disk); - - if (use_save) menu_process_save(); - - buffer_lba[disk] = -1; - - // Fetch sector data from FPGA ... - EnableIO(); - spi_w(UIO_SECTOR_WR | ((c & 4) ? 0 : ((disk + 1) << 8))); - spi_block_read(buffer[disk], fio_size); - DisableIO(); - - if (sd_image[disk].type == 2 && !lba) + // check if core requests configuration + if ((c & 0xC) == 0xC) { - //Create the file - if (FileOpenEx(&sd_image[disk], sd_image[disk].path, O_CREAT | O_RDWR | O_SYNC)) + printf("core requests SD config\n"); + user_io_sd_set_config(); + } + + if (c & 0x0003) + { + disk = 0; + op = (c & 1) ? 1 : 2; + } + else if (c & 0x0900) + { + disk = 1; + op = (c & 0x100) ? 1 : 2; + } + else if (c & 0x1200) + { + disk = 2; + op = (c & 0x200) ? 1 : 2; + } + else if (c & 0x2400) + { + disk = 3; + op = (c & 0x400) ? 1 : 2; + } + + ack = ((c & 4) ? 0 : ((disk + 1) << 8)); + } + } + DisableIO(); + + if (op == 2) + { + //printf("SD WR %d on %d\n", lba, disk); + + if (use_save) menu_process_save(); + + buffer_lba[disk] = -1; + + // Fetch sector data from FPGA ... + EnableIO(); + spi_w(UIO_SECTOR_WR | ack); + spi_block_read(buffer[disk], fio_size, sz); + DisableIO(); + + if (sd_image[disk].type == 2 && !lba) + { + //Create the file + if (FileOpenEx(&sd_image[disk], sd_image[disk].path, O_CREAT | O_RDWR | O_SYNC)) + { + diskled_on(); + if (FileWriteSec(&sd_image[disk], buffer[disk])) { - diskled_on(); - if (FileWriteSec(&sd_image[disk], buffer[disk])) - { - sd_image[disk].size = 512; - } - } - else - { - printf("Error in creating file: %s\n", sd_image[disk].path); + sd_image[disk].size = sz; } } else { - // ... and write it to disk - __off64_t size = sd_image[disk].size >> 9; - if (size && lba <= size) + printf("Error in creating file: %s\n", sd_image[disk].path); + } + } + else + { + // ... and write it to disk + uint64_t size = sd_image[disk].size >> blkpow; + if (size && lba <= size) + { + diskled_on(); + if (FileSeek(&sd_image[disk], lba << blkpow, SEEK_SET)) { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba)) + if (!sd_image_cangrow[disk]) { - int sz = 512; - if (!sd_image_cangrow[disk]) - { - __off64_t rem = sd_image[disk].size - sd_image[disk].offset; - sz = (rem >= 512) ? 512 : (int)rem; - } - if(sz && FileWriteAdv(&sd_image[disk], buffer[disk], sz)) - { - if (size == lba && sd_image_cangrow[disk]) - { - size++; - sd_image[disk].size = size << 9; - } - } + __off64_t rem = sd_image[disk].size - sd_image[disk].offset; + sz = (rem >= sz) ? sz : (int)rem; } + + if (sz) FileWriteAdv(&sd_image[disk], buffer[disk], sz); } } } - else if (c & 0x0701) + } + else if (op & 1) + { + uint32_t buf_n = sizeof(buffer[0]) >> blkpow; + //printf("SD RD (%llu,%d) on %d, WIDE=%d\n", lba, sz, disk, fio_size); + + int done = 0; + uint32_t offset; + + if ((buffer_lba[disk] == (uint64_t)-1) || lba < buffer_lba[disk] || (lba + blksz - buffer_lba[disk]) > buf_n) { - int disk = 3; - if (c & 0x0001) disk = 0; - else if (c & 0x0100) disk = 1; - else if (c & 0x0200) disk = 2; - - //printf("SD RD %d on %d, WIDE=%d\n", lba, disk, fio_size); - - int done = 0; - uint32_t offset; - - if ((buffer_lba[disk] == (uint64_t)-1) || lba < buffer_lba[disk] || lba >(buffer_lba[disk] + buf_sz - 1)) + buffer_lba[disk] = -1; + if (sd_image[disk].size) { - buffer_lba[disk] = -1; - if (sd_image[disk].size) + diskled_on(); + if (FileSeek(&sd_image[disk], lba << blkpow, SEEK_SET)) { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba)) + if (FileReadAdv(&sd_image[disk], buffer[disk], sizeof(buffer[disk]))) { - if (FileReadAdv(&sd_image[disk], buffer[disk], sizeof(buffer[disk]))) - { - done = 1; - buffer_lba[disk] = lba; - } + done = 1; + buffer_lba[disk] = lba; } } + } - //Even after error we have to provide the block to the core - //Give an empty block. - if (!done) + //Even after error we have to provide the block to the core + //Give an empty block. + if (!done) + { + if (sd_image[disk].type == 2) { - if (sd_image[disk].type == 2) + if (is_megacd()) { - if (is_megacd()) + mcd_fill_blanksave(buffer[disk], lba); + } + else if (is_pce()) + { + memset(buffer[disk], 0, sizeof(buffer[disk])); + if (!lba) { - mcd_fill_blanksave(buffer[disk], lba); - } - else if (is_pce()) - { - memset(buffer[disk], 0, sizeof(buffer[disk])); - if (!lba) - { - memcpy(buffer[disk], "HUBM\x00\x88\x10\x80", 8); - } - } - else - { - memset(buffer[disk], -1, sizeof(buffer[disk])); + memcpy(buffer[disk], "HUBM\x00\x88\x10\x80", 8); } } else { - memset(buffer[disk], 0, sizeof(buffer[disk])); + memset(buffer[disk], -1, sizeof(buffer[disk])); } } - - offset = 0; - } - else - { - offset = (lba - buffer_lba[disk])*512; - done = 1; - } - - //hexdump(buffer, 32, 0); - - // data is now stored in buffer. send it to fpga - EnableIO(); - spi_w(UIO_SECTOR_RD | ((c & 4) ? 0 : ((disk + 1) << 8))); - spi_block_write(buffer[disk] + offset, fio_size); - DisableIO(); - - if (sd_image[disk].type == 2) - { - buffer_lba[disk] = -1; - } - else if(done && (lba == (buffer_lba[disk] + buf_sz - 1))) - { - diskled_on(); - if (FileReadAdv(&sd_image[disk], buffer[disk], sizeof(buffer[disk]))) - { - buffer_lba[disk] += buf_sz; - } else { memset(buffer[disk], 0, sizeof(buffer[disk])); - buffer_lba[disk] = -1; } } + + offset = 0; + } + else + { + offset = (lba - buffer_lba[disk]) << blkpow; + done = 1; + } + + // data is now stored in buffer. send it to fpga + EnableIO(); + spi_w(UIO_SECTOR_RD | ack); + spi_block_write(buffer[disk] + offset, fio_size, sz); + DisableIO(); + + if (sd_image[disk].type == 2) + { + buffer_lba[disk] = -1; + } + else if(done && (lba + blksz - buffer_lba[disk]) == buf_n) + { + diskled_on(); + if (FileReadAdv(&sd_image[disk], buffer[disk], sizeof(buffer[disk]))) + { + buffer_lba[disk] += buf_n; + } + else + { + memset(buffer[disk], 0, sizeof(buffer[disk])); + buffer_lba[disk] = -1; + } } - else break; } + else break; } }