From 6e27efef8d78a8dff5b88a9ef9c115fe1f15aab7 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Mon, 20 Jan 2020 23:46:21 +0800 Subject: [PATCH] C64: rework T64 support to use memory file. --- DiskImage.cpp | 14 +++---- MiSTer.vcxproj | 2 + MiSTer.vcxproj.filters | 6 +++ file_io.cpp | 4 +- support/c64/c64.cpp | 86 +++++++++++++++++++++++++----------------- support/c64/c64.h | 2 +- user_io.cpp | 26 +++---------- 7 files changed, 76 insertions(+), 64 deletions(-) diff --git a/DiskImage.cpp b/DiskImage.cpp index 76776d3..f181d01 100644 --- a/DiskImage.cpp +++ b/DiskImage.cpp @@ -3337,10 +3337,10 @@ int dsk2nib(const char *name, fileTYPE *f) return 0; } - if (!FileOpenEx(f, "vtrd", -1)) + if (!FileOpenEx(f, "vdsk", -1)) { FileClose(&disk_file); - printf("ERROR: fail to create /vtrd\n"); + printf("ERROR: fail to create vdsk\n"); return 0; } @@ -3372,7 +3372,7 @@ int dsk2nib(const char *name, fileTYPE *f) if (FileWriteAdv(f, raw_track, RAW_TRACK_uint8_tS) != RAW_TRACK_uint8_tS) { - printf("Error writing to /vtrd file\n"); + printf("Error writing to vdsk file\n"); FileClose(&disk_file); FileClose(f); return 0; @@ -3383,7 +3383,7 @@ int dsk2nib(const char *name, fileTYPE *f) f->size = FileGetSize(f); FileSeekLBA(f, 0); - printf("dsk2nib: vtrd size=%llu.\n", f->size); + printf("dsk2nib: vdsk size=%llu.\n", f->size); return 1; } @@ -3394,10 +3394,10 @@ int x2trd(const char *name, fileTYPE *f) TDiskImage *img = new TDiskImage; img->Open(getFullPath(name), true); - if (!FileOpenEx(f, "vtrd", -1)) + if (!FileOpenEx(f, "vdsk", -1)) { delete img; - printf("ERROR: fail to create /vtrd\n"); + printf("ERROR: fail to create vdsk\n"); return 0; } @@ -3406,7 +3406,7 @@ int x2trd(const char *name, fileTYPE *f) f->size = FileGetSize(f); FileSeekLBA(f, 0); - printf("x2trd: vtrd size=%llu.\n", f->size); + printf("x2trd: vdsk size=%llu.\n", f->size); return 1; } diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index 5426435..7445014 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -79,6 +79,7 @@ + @@ -136,6 +137,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index ab1476c..053d5d9 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -187,6 +187,9 @@ Source Files + + Source Files\support + @@ -354,5 +357,8 @@ Header Files + + Header Files\support + \ No newline at end of file diff --git a/file_io.cpp b/file_io.cpp index dd95a8b..86c78c8 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -85,7 +85,7 @@ static int FileIsZipped(char* path, char** zip_path, char** file_path) static char* make_fullpath(const char *path, int mode = 0) { const char *root = getRootDir(); - if (path[0] != '/') + if (strncasecmp(getRootDir(), path, strlen(root))) { sprintf(full_path, "%s/%s", (mode == -1) ? "" : root, path); } @@ -381,7 +381,7 @@ int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute) } else { - int fd = (mode == -1) ? shm_open("/vtrd", O_CREAT | O_RDWR | O_TRUNC, 0777) : open(full_path, mode, 0777); + int fd = (mode == -1) ? shm_open("/vdsk", O_CREAT | O_RDWR | O_TRUNC, 0777) : open(full_path, mode, 0777); if (fd <= 0) { if(!mute) printf("FileOpenEx(open) File:%s, error: %s.\n", full_path, strerror(errno)); diff --git a/support/c64/c64.cpp b/support/c64/c64.cpp index 6feb78f..e63b620 100644 --- a/support/c64/c64.cpp +++ b/support/c64/c64.cpp @@ -38,9 +38,6 @@ #define D64_FILL_VALUE 0xA0 #define D64_INIT_VALUE 0x00 // DIR relies on 0x00 initial value -// leave file for debug -#define CHECK_SUCCESS(op) do { if (!(op)) { FileClose(&fd); /*unlink(path);*/ return 0; } } while(0) - struct FileRecord { char name[D64_BYTE_PER_STRING]; unsigned char cbm; @@ -53,7 +50,7 @@ struct FileRecord { static bool cmp_offset(const FileRecord& a, const FileRecord& b) { return a.offset < b.offset; } static bool cmp_index(const FileRecord& a, const FileRecord& b) { return a.index < b.index; } -static unsigned char d64_sector_per_track(unsigned char trackNum) { +static unsigned char d64_sector_per_track(unsigned char trackNum) { return (trackNum <= 17) ? 21U : (trackNum <= 24) ? 19U : (trackNum <= 30) ? 18U @@ -99,22 +96,18 @@ static void d64_advance_dir_pointer(unsigned char& trackNum, unsigned char& sect // caller needs to handle BAM sector } -int c64_convert_t64_to_d64(fileTYPE* f, const char *path) +static int c64_convert_t64_to_d64(fileTYPE* f_in, fileTYPE* f_out) { - fileTYPE fd; std::vector files; char header[T64_BYTE_PER_HEADER]; char name[D64_BYTE_PER_STRING]; - // remove old file to make sure we don't use it - unlink(path); - - CHECK_SUCCESS(FileSeek(f, 0, SEEK_SET)); + if (!FileSeek(f_in, 0, SEEK_SET)) return 0; // ignore signature - CHECK_SUCCESS(FileReadAdv(f, header, sizeof(header))); - CHECK_SUCCESS(!memcmp(header, "C64", strlen("C64"))); + if(!FileReadAdv(f_in, header, sizeof(header))) return 0; + if (memcmp(header, "C64", strlen("C64"))) return 0; // header - CHECK_SUCCESS(FileReadAdv(f, header, sizeof(header))); + if (!FileReadAdv(f_in, header, sizeof(header))) return 0; unsigned short numRecords = (header[0x03] << 8) | header[0x02]; memcpy(name, header + 0x08, sizeof(name)); @@ -122,7 +115,7 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) for (unsigned i = 0; i < numRecords; i++) { // record - CHECK_SUCCESS(FileReadAdv(f, header, sizeof(header))); + if (!FileReadAdv(f_in, header, sizeof(header))) return 0; if (!header[0x00] || !header[0x01]) continue; FileRecord r; @@ -140,7 +133,7 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) std::sort(files.begin(), files.end(), cmp_offset); for (unsigned i = 0; i < files.size(); i++) { - unsigned short size = (i < files.size() - 1 ? files[i + 1].offset : f->size) - files[i].offset; + unsigned short size = (i < files.size() - 1 ? files[i + 1].offset : f_in->size) - files[i].offset; if (size < files[i].size) files[i].size = size; } std::sort(files.begin(), files.end(), cmp_index); @@ -162,14 +155,12 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) //printf("T64: %d records\n", files.size()); for (auto r : files) printf("start: %x, size: %x, offset %x, index: %d\n", r.start, r.size, r.offset, r.index); - CHECK_SUCCESS(files.size()); - - CHECK_SUCCESS(FileOpenEx(&fd, path, O_CREAT | O_TRUNC | O_RDWR | O_SYNC, 0)); + if (!files.size()) return 0; unsigned char sector[D64_BYTE_PER_SECTOR]; memset(sector, D64_INIT_VALUE, sizeof(sector)); - for (unsigned i = 0; i < D64_SECTOR_PER_DISK; i++) CHECK_SUCCESS(FileWriteAdv(&fd, sector, sizeof(sector))); - CHECK_SUCCESS(FileSeek(&fd, 0, SEEK_SET)); + for (unsigned i = 0; i < D64_SECTOR_PER_DISK; i++) if (!FileWriteAdv(f_out, sector, sizeof(sector))) return 0; + if (!FileSeek(f_out, 0, SEEK_SET)) return 0; unsigned char bam[D64_BYTE_PER_SECTOR]; memset(bam, D64_INIT_VALUE, sizeof(bam)); @@ -184,19 +175,19 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) if (dirEntry == 0 && i != 0) { // set next track/sector pointer of prev node - CHECK_SUCCESS(FileSeek(&fd, d64_offset(dirTrackNum, dirSectorNum), SEEK_SET)); + if (!FileSeek(f_out, d64_offset(dirTrackNum, dirSectorNum), SEEK_SET)) return 0; do d64_advance_dir_pointer(dirTrackNum, dirSectorNum); while (dirTrackNum == D64_BAM_TRACK && dirSectorNum == D64_BAM_SECTOR); dir[0x00] = dirTrackNum; dir[0x01] = dirSectorNum; - CHECK_SUCCESS(FileWriteAdv(&fd, dir, 2)); + if (!FileWriteAdv(f_out, dir, 2)) return 0; // check for overflow bool success = dirSectorNum != D64_DIR_SECTOR; if (!success) printf("T64: dir overflow on file: %d\n", i); - CHECK_SUCCESS(success); + if (!success) return 0; } - CHECK_SUCCESS(FileSeek(&fd, d64_offset(dirTrackNum, dirSectorNum) + dirEntry * D64_BYTE_PER_DIR, SEEK_SET)); + if (!FileSeek(f_out, d64_offset(dirTrackNum, dirSectorNum) + dirEntry * D64_BYTE_PER_DIR, SEEK_SET)) return 0; dir[0x00] = 0x00; dir[0x01] = dirEntry == 0 ? 0xFF : 0x00; dir[0x02] = r.cbm; @@ -209,16 +200,16 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) unsigned sectorSize= d64_file_sector(files[i].size); dir[0x1E] = (sectorSize >> 0) & 0xFF; dir[0x1F] = (sectorSize >> 8) & 0xFF; - CHECK_SUCCESS(FileWriteAdv(&fd, dir, sizeof(dir))); + if (!FileWriteAdv(f_out, dir, sizeof(dir))) return 0; dirEntry = (dirEntry + 1) % D64_DIR_PER_SECTOR; // file sectors - CHECK_SUCCESS(FileSeek(f, r.offset, SEEK_SET)); + if (!FileSeek(f_in, r.offset, SEEK_SET)) return 0; bool writeAddress = true; for (unsigned s = 0; s < r.size; s+= D64_BYTE_PER_FILE_SECTOR) { - CHECK_SUCCESS(FileSeek(&fd, d64_offset(fileTrackNum, fileSectorNum), SEEK_SET)); + if (!FileSeek(f_out, d64_offset(fileTrackNum, fileSectorNum), SEEK_SET)) return 0; d64_advance_pointer(fileTrackNum, fileSectorNum); if (fileTrackNum == D64_DIR_TRACK) fileTrackNum += 1; memset(sector, D64_FILL_VALUE, sizeof(sector)); @@ -231,9 +222,9 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) sector[0x02] = (r.start >> 0) & 0xFF; sector[0x03] = (r.start >> 8) & 0xFF; } - CHECK_SUCCESS(FileReadAdv(f, sector + (writeAddress ? 4 : 2), cnt - (writeAddress ? 2 : 0))); - CHECK_SUCCESS(FileWriteAdv(&fd, sector, sizeof(sector))); + if (!FileReadAdv(f_in, sector + (writeAddress ? 4 : 2), cnt - (writeAddress ? 2 : 0))) return 0; + if (!FileWriteAdv(f_out, sector, sizeof(sector))) return 0; writeAddress = false; } } @@ -272,10 +263,37 @@ int c64_convert_t64_to_d64(fileTYPE* f, const char *path) memset(bam + 0xA7, D64_FILL_VALUE, 0xAA - 0xA7 + 1); memset(bam + 0xAB, 0x00, 0xFF - 0xAB + 1); - CHECK_SUCCESS(FileSeek(&fd, d64_offset(D64_BAM_TRACK, D64_BAM_SECTOR), SEEK_SET)); - CHECK_SUCCESS(FileWriteAdv(&fd, bam, sizeof(bam))); - - FileClose(&fd); + if (!FileSeek(f_out, d64_offset(D64_BAM_TRACK, D64_BAM_SECTOR), SEEK_SET)) return 0; + if (!FileWriteAdv(f_out, bam, sizeof(bam))) return 0; + f_out->size = FileGetSize(f_out); + printf("Virtual D64 size = %llu\n", f_out->size); return 1; -} \ No newline at end of file +} + +int c64_openT64(const char *path, fileTYPE* f) +{ + if (!FileOpenEx(f, "vdsk", -1)) + { + printf("ERROR: fail to create vdsk\n"); + return 0; + } + + fileTYPE f_in; + if (!FileOpen(&f_in, path)) + { + FileClose(f); + return 0; + } + + int ret = c64_convert_t64_to_d64(&f_in, f); + FileClose(&f_in); + + if (!ret) + { + printf("Failed to convert T64 (%s).\n", path); + FileClose(f); + } + + return ret; +} diff --git a/support/c64/c64.h b/support/c64/c64.h index 70d3bca..24e67fc 100644 --- a/support/c64/c64.h +++ b/support/c64/c64.h @@ -1,6 +1,6 @@ #ifndef C64_H #define C64_H -int c64_convert_t64_to_d64(fileTYPE* f, const char *path); +int c64_openT64(const char *path, fileTYPE* f); #endif diff --git a/user_io.cpp b/user_io.cpp index d73ae23..ee4fd65 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -1191,6 +1191,7 @@ int user_io_file_mount(char *name, unsigned char index, char pre) { int writable = 0; int ret = 0; + int len = strlen(name); if (!strcasecmp(user_io_get_core_name_ex(), "apple-ii")) { @@ -1203,6 +1204,11 @@ int user_io_file_mount(char *name, unsigned char index, char pre) { ret = x2trd(name, sd_image + index); } + else if (is_c64_core() && len > 4 && !strcasecmp(name + len - 4, ".t64")) + { + writable = 0; + ret = c64_openT64(name, sd_image + index); + } else { writable = FileCanWrite(name); @@ -1245,26 +1251,6 @@ int user_io_file_mount(char *name, unsigned char index, char pre) strcpy(sd_image[index].path, name); } - if (is_c64_core()) - { - int len = strlen(name); - if(len>4 && !strcasecmp(name+len-4, ".t64")) - { - // mount T64 - size = 0; - writable = false; - const char* path = "/tmp/c64_t64_tmp.d64"; - ret = c64_convert_t64_to_d64(&sd_image[index], path); - FileClose(&sd_image[index]); - - if (ret) - { - ret = FileOpenEx(&sd_image[index], path, O_RDONLY, 0); - size = sd_image[index].size; - } - } - } - if (io_ver) { spi_w((uint16_t)(size));