diff --git a/file_io.cpp b/file_io.cpp index aeb7df4..eb1d813 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -65,7 +65,7 @@ int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute) char *p = strrchr(full_path, '/'); strcpy(file->name, (mode == -1) ? full_path : p+1); - file->fd = (mode == -1) ? shm_open("/vtrd", O_CREAT | O_RDWR | O_TRUNC, 0777) : open(full_path, mode); + file->fd = (mode == -1) ? shm_open("/vtrd", O_CREAT | O_RDWR | O_TRUNC, 0777) : open(full_path, mode, 0777); if (file->fd <= 0) { if(!mute) printf("FileOpenEx(open) File:%s, error: %d.\n", full_path, file->fd); @@ -100,6 +100,15 @@ int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute) return 1; } +__off64_t FileGetSize(fileTYPE *file) +{ + if (file->fd <= 0) return 0; + + struct stat64 st; + int ret = fstat64(file->fd, &st); + return (ret < 0) ? 0 : st.st_size; +} + int FileOpen(fileTYPE *file, const char *name, char mute) { return FileOpenEx(file, name, O_RDONLY, mute); diff --git a/file_io.h b/file_io.h index 886062b..f1bf899 100644 --- a/file_io.h +++ b/file_io.h @@ -13,6 +13,7 @@ typedef struct int type; __off64_t size; __off64_t offset; + char path[1024]; char name[261]; } fileTYPE; @@ -45,6 +46,8 @@ int FileOpenEx(fileTYPE *file, const char *name, int mode, char mute = 0); int FileOpen(fileTYPE *file, const char *name, char mute = 0); void FileClose(fileTYPE *file); +__off64_t FileGetSize(fileTYPE *file); + int FileSeek(fileTYPE *file, __off64_t offset, int origin); int FileSeekLBA(fileTYPE *file, uint32_t offset); diff --git a/user_io.cpp b/user_io.cpp index 748461f..11c2eea 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -858,7 +858,7 @@ void user_io_set_index(unsigned char index) DisableFpga(); } -int user_io_file_mount(char *name, unsigned char index) +int user_io_file_mount(char *name, unsigned char index, char pre) { int writable = 0; int ret = 0; @@ -876,10 +876,18 @@ int user_io_file_mount(char *name, unsigned char index) if (!ret) { - writable = 0; sd_image[index].size = 0; printf("Failed to open file %s\n", name); - printf("Eject image from %d slot\n", index); + if (pre) + { + writable = 1; + printf("Will be created upon write\n"); + } + else + { + writable = 0; + printf("Eject image from %d slot\n", index); + } } else { @@ -891,17 +899,26 @@ int user_io_file_mount(char *name, unsigned char index) // send mounted image size first then notify about mounting EnableIO(); spi8(UIO_SET_SDINFO); + + __off64_t size = sd_image[index].size; + if (!ret && pre) + { + size = -1; + sd_image[index].type = 2; + strcpy(sd_image[index].path, name); + } + if (io_ver) { - spi_w((uint16_t)(sd_image[index].size)); - spi_w((uint16_t)(sd_image[index].size>>16)); - spi_w((uint16_t)(sd_image[index].size>>32)); - spi_w((uint16_t)(sd_image[index].size>>48)); + spi_w((uint16_t)(size)); + spi_w((uint16_t)(size>>16)); + spi_w((uint16_t)(size>>32)); + spi_w((uint16_t)(size>>48)); } else { - spi32le(sd_image[index].size); - spi32le(sd_image[index].size>>32); + spi32le(size); + spi32le(size>>32); } DisableIO(); @@ -1268,7 +1285,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m char *p = strrchr((char*)buf, '.'); if (!p) p = (char*)buf + strlen(name); strcpy(p, ".sav"); - user_io_file_mount((char*)buf); + user_io_file_mount((char*)buf, 0, 1); } // signal end of transmission @@ -1630,6 +1647,7 @@ void user_io_poll() { //printf("SD WR %d on %d\n", lba, disk); + int done = 0; buffer_lba[disk] = lba; // Fetch sector data from FPGA ... @@ -1637,15 +1655,43 @@ void user_io_poll() spi_block_read(buffer[disk], fio_size); DisableIO(); - // ... and write it to disk - int done = 0; - if ((sd_image[disk].size>>9)>lba) + if (sd_image[disk].type == 2 && !lba) { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba)) + //Create the file + if (FileOpenEx(&sd_image[disk], sd_image[disk].path, O_CREAT | O_RDWR | O_SYNC)) { - if (FileWriteSec(&sd_image[disk], buffer[disk])) done = 1; + diskled_on(); + if (FileWriteSec(&sd_image[disk], buffer[disk])) + { + sd_image[disk].size = 512; + done = 1; + } + } + else + { + printf("Error in creating file: %s\n", sd_image[disk].path); + } + } + else + { + // ... and write it to disk + __off64_t size = sd_image[disk].size>>9; + if (size && size>=lba) + { + diskled_on(); + if (FileSeekLBA(&sd_image[disk], lba)) + { + if (FileWriteSec(&sd_image[disk], buffer[disk])) + { + done = 1; + if (size == lba) + { + size++; + sd_image[disk].size = size << 9; + } + } + } } } @@ -1681,7 +1727,6 @@ void user_io_poll() //Even after error we have to provide the block to the core //Give an empty block. if (!done) memset(buffer[disk], 0, sizeof(buffer[disk])); - buffer_lba[disk] = lba; } @@ -1710,6 +1755,11 @@ void user_io_poll() } } if(done) buffer_lba[disk] = lba + 1; + + if (sd_image[disk].type == 2) + { + buffer_lba[disk] = -1; + } } } diff --git a/user_io.h b/user_io.h index 71e44b5..e1a6d1a 100644 --- a/user_io.h +++ b/user_io.h @@ -189,7 +189,7 @@ void user_io_serial_tx(char *, uint16_t); char *user_io_8bit_get_string(char); unsigned long user_io_8bit_set_status(unsigned long, unsigned long); int user_io_file_tx(const char* name, unsigned char index = 0, char opensave = 0, char mute = 0, char composite = 0); -int user_io_file_mount(char *name, unsigned char index = 0); +int user_io_file_mount(char *name, unsigned char index = 0, char pre = 0); char user_io_dip_switch1(void); char user_io_serial_status(serial_status_t *, uint8_t); char *user_io_get_core_name();