From 14452da3202dfe69a7933c5f19de6d10c68a72f0 Mon Sep 17 00:00:00 2001 From: Stephen White Date: Sat, 16 Nov 2019 17:00:04 +1100 Subject: [PATCH] Added support for loading T64 files. All the PRG files contained inside a T64 image are transfered over to a in memory D64 image. This in turn is converted to the low level G64 like image that the emulator uses. --- src/DiskCaddy.cpp | 16 ++ src/DiskCaddy.h | 1 + src/DiskImage.cpp | 488 +++++++++++++++++++++++++++++++++++++++++++ src/DiskImage.h | 14 ++ src/FileBrowser.cpp | 2 +- src/iec_commands.cpp | 94 ++------- src/iec_commands.h | 2 + src/types.h | 8 + 8 files changed, 543 insertions(+), 82 deletions(-) diff --git a/src/DiskCaddy.cpp b/src/DiskCaddy.cpp index a8ccb0e..bdbf3ce 100644 --- a/src/DiskCaddy.cpp +++ b/src/DiskCaddy.cpp @@ -163,6 +163,9 @@ bool DiskCaddy::Insert(const FILINFO* fileInfo, bool readOnly) case DiskImage::D81: success = InsertD81(fileInfo, (unsigned char*)DiskImage::readBuffer, bytesRead, readOnly); break; + case DiskImage::T64: + success = InsertT64(fileInfo, (unsigned char*)DiskImage::readBuffer, bytesRead, readOnly); + break; default: success = false; break; @@ -251,6 +254,19 @@ bool DiskCaddy::InsertD81(const FILINFO* fileInfo, unsigned char* diskImageData, return false; } +bool DiskCaddy::InsertT64(const FILINFO* fileInfo, unsigned char* diskImageData, unsigned size, bool readOnly) +{ + DiskImage diskImage; + if (diskImage.OpenT64(fileInfo, diskImageData, size)) + { + diskImage.SetReadOnly(readOnly); + disks.push_back(diskImage); + selectedIndex = disks.size() - 1; + return true; + } + return false; +} + void DiskCaddy::Display() { unsigned numberOfImages = GetNumberOfImages(); diff --git a/src/DiskCaddy.h b/src/DiskCaddy.h index b59247b..eea53fe 100644 --- a/src/DiskCaddy.h +++ b/src/DiskCaddy.h @@ -106,6 +106,7 @@ private: bool InsertNIB(const FILINFO* fileInfo, unsigned char* diskImageData, unsigned size, bool readOnly); bool InsertNBZ(const FILINFO* fileInfo, unsigned char* diskImageData, unsigned size, bool readOnly); bool InsertD81(const FILINFO* fileInfo, unsigned char* diskImageData, unsigned size, bool readOnly); + bool InsertT64(const FILINFO* fileInfo, unsigned char* diskImageData, unsigned size, bool readOnly); void ShowSelectedImage(u32 index); diff --git a/src/DiskImage.cpp b/src/DiskImage.cpp index e9ba652..68cc449 100644 --- a/src/DiskImage.cpp +++ b/src/DiskImage.cpp @@ -25,6 +25,8 @@ #include #include #include "lz.h" +#include "Petscii.h" +#include extern "C" { #include "rpi-gpio.h" @@ -32,6 +34,35 @@ extern "C" extern u32 HashBuffer(const void* pBuffer, u32 length); +#define MAX_DIRECTORY_SECTORS 18 +#define DIRECTORY_SIZE 32 +#define DISK_SECTOR_OFFSET_FIRST_DIRECTORY_SECTOR 357 +#define DISKNAME_OFFSET_IN_DIR_BLOCK 144 +#define DISKID_OFFSET_IN_DIR_BLOCK 162 + +#define DIRECTRY_ENTRY_FILE_TYPE_PRG 0x82 + +static u8 blankD64DIRBAM[] = +{ + 0x12, 0x01, 0x41, 0x00, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, + 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, + 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, + 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, + 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x11, 0xfc, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, + 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, + 0x13, 0xff, 0xff, 0x07, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, + 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x11, 0xff, 0xff, 0x01, + 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, + 0x42, 0x4c, 0x41, 0x4e, 0x4b, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, + 0xa0, 0xa0, 0x31, 0x41, 0xa0, 0x32, 0x41, 0xa0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + unsigned char DiskImage::readBuffer[READBUFFER_SIZE]; static unsigned char compressionBuffer[HALF_TRACK_COUNT * MAX_TRACK_LENGTH]; @@ -140,6 +171,10 @@ void DiskImage::Close() CloseD81(); memset(tracksD81, 0, sizeof(tracksD81)); break; + case T64: + CloseT64(); + memset(tracks, 0x55, sizeof(tracks)); + break; default: break; } @@ -1164,6 +1199,102 @@ void DiskImage::CloseNBZ() attachedImageSize = 0; } +bool DiskImage::OpenT64(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size) +{ + bool success = false; + + Close(); + + this->fileInfo = fileInfo; + + attachedImageSize = size; + + if ((memcmp(diskImage, "C64 tape image file", 20) == 0) || (memcmp(diskImage, "C64s tape image file", 21) == 0)) + { + u16 version = diskImage[0x20] | (diskImage[0x21] << 8); + u16 entries = diskImage[0x22] | (diskImage[0x23] << 8); + u16 entriesUsed = diskImage[0x24] | (diskImage[0x25] << 8); + char name[25] = { 0 }; + for (int i = 0; i < 24; ++i) + { + name[i] = tolower(diskImage[i + 0x28]); + } + + unsigned char* newDiskImage = (unsigned char*)malloc(READBUFFER_SIZE); + + if (newDiskImage) + { + unsigned length = DiskImage::CreateNewDiskInRAM(name, "00", newDiskImage); + + if (length) + { + + u16 entryIndex; + + for (entryIndex = 0; entryIndex < entriesUsed; ++entryIndex) + { + char nameEntry[17] = { 0 }; + int offset = 0x40 + entryIndex * 32; + u8 type = diskImage[offset]; + u8 fileType = diskImage[offset + 1]; + if (fileType == DIRECTRY_ENTRY_FILE_TYPE_PRG) + { + u16 startAddress = diskImage[offset + 2] | (diskImage[offset + 3] << 8); + u16 endAddress = diskImage[offset + 4] | (diskImage[offset + 5] << 8); + unsigned length = endAddress - startAddress; + + u32 fileOffset = diskImage[offset + 8] | (diskImage[offset + 9] << 8) | (diskImage[offset + 10] << 16) | (diskImage[offset + 11] << 24); + strncpy(nameEntry, (const char*)(diskImage + offset + 0x10), 16); + + unsigned char* data = (unsigned char*)malloc(length + 2); + + if (data) + { + data[0] = startAddress & 0xff; + data[1] = (startAddress >> 8) & 0xff; + + memcpy(data + 2, diskImage + fileOffset, length); + length += 2; + bool addFileSuccess = AddFileToRAMD64(newDiskImage, nameEntry, data, length); + + free(data); + } + } + + } + + if (OpenD64(fileInfo, newDiskImage, length)) + { + success = true; + diskType = T64; + } + } + + free(newDiskImage); + } + } + + return success; +} + +bool DiskImage::WriteT64(char* name) +{ + if (readOnly) + return true; + + return true; +} + +void DiskImage::CloseT64() +{ + if (dirty) + { + WriteT64(); + dirty = false; + } + attachedImageSize = 0; +} + bool DiskImage::GetDecodedSector(u32 track, u32 sector, u8* buffer) { if (track > 0) @@ -1190,6 +1321,8 @@ DiskImage::DiskType DiskImage::GetDiskImageTypeViaExtention(const char* diskImag return NBZ; else if (toupper((char)ext[1]) == 'D' && ext[2] == '6' && ext[3] == '4') return D64; + else if (toupper((char)ext[1]) == 'T' && ext[2] == '6' && ext[3] == '4') + return T64; else if (IsLSTExtention(diskImageName)) return LST; else if (toupper((char)ext[1]) == 'D' && ext[2] == '8' && ext[3] == '1') @@ -1418,3 +1551,358 @@ unsigned DiskImage::LastTrackUsed() } return lastTrackUsed; } + +unsigned DiskImage::CreateNewDiskInRAM(const char* filenameNew, const char* ID, unsigned char* destBuffer) +{ + unsigned char* dest; + unsigned char* ptr; + int i; + + DEBUG_LOG("CreateNewDiskInRAM %s\r\n", filenameNew); + + unsigned char buffer[256]; + u32 bytes; + u32 blocks; + + if (destBuffer == 0) + destBuffer = DiskImage::readBuffer; + + dest = destBuffer; + + memset(buffer, 0, sizeof(buffer)); + + for (blocks = 0; blocks < DISK_SECTOR_OFFSET_FIRST_DIRECTORY_SECTOR; ++blocks) + { + for (i = 0; i < 256; ++i) + { + *dest++ = buffer[i]; + } + } + ptr = (unsigned char*)&blankD64DIRBAM[DISKNAME_OFFSET_IN_DIR_BLOCK]; + int len = strlen(filenameNew); + for (i = 0; i < len; ++i) + { + *ptr++ = ascii2petscii(filenameNew[i]); + } + for (; i < 18; ++i) + { + *ptr++ = 0xa0; + } + for (i = 0; i < 2; ++i) + { + *ptr++ = ascii2petscii(ID[i]); + } + for (i = 0; i < 256; ++i) + { + *dest++ = blankD64DIRBAM[i]; + } + buffer[1] = 0xff; + for (i = 0; i < 256; ++i) + { + *dest++ = buffer[i]; + } + buffer[1] = 0; + for (blocks = 0; blocks < 324; ++blocks) + { + for (i = 0; i < 256; ++i) + { + *dest++ = buffer[i]; + } + } + + return (unsigned)(dest - destBuffer); +} + +int DiskImage::RAMD64GetSectorOffset(int track, int sector) +{ + int index; + int sectorOffset = 0; + + for (index = 0; index < (track - 1); ++index) + { + sectorOffset += SectorsPerTrack[index]; + } + sectorOffset += sector; + return sectorOffset; +} + +unsigned char* DiskImage::RAMD64AddDirectoryEntry(unsigned char* ramD64, const char* name, const unsigned char* data, unsigned length) +{ + unsigned char* ptrTrackSector = 0; + unsigned char* ptr; + int directorySector; + int track = 18; + int i; + int numberOfBlocks = length / (256 - 2) + ((length % (256 - 2)) ? 1 : 0); + + int sectorOffset = RAMD64GetSectorOffset(18, 0); + ptr = ramD64 + sectorOffset * 256; + + track = ptr[0]; + + for (directorySector = 1; directorySector < 19; ++directorySector) + { + int entryIndex; + bool found = false; + + sectorOffset = RAMD64GetSectorOffset(track, directorySector); + + DEBUG_LOG("directory sector offset = %d\r\n", sectorOffset); + ptr = ramD64 + sectorOffset * 256; + + entryIndex = 0; + while (!found && entryIndex < 8) + { + unsigned char* ptrEntry = ptr + 2 + entryIndex * DIRECTORY_SIZE; + + if (*ptrEntry == 0) + { + *ptrEntry++ = DIRECTRY_ENTRY_FILE_TYPE_PRG; + + ptrTrackSector = ptrEntry; + + ptrEntry++; // track data start + ptrEntry++; // sector data start + + int len = strlen(name); + len = Min(len, 16); + + for (i = 0; i < len; ++i) + { + *ptrEntry++ = ascii2petscii(tolower(name[i])); + } + for (; i < 16; ++i) + { + *ptrEntry++ = 0xa0; + } + + ptrEntry++; // track and sector of the first side sector block + ptrEntry++; + + ptrEntry++; // record length + + ptrEntry++; // not used + ptrEntry++; + ptrEntry++; + ptrEntry++; + + ptrEntry++; // Track and sector of the new file when overwrtiting with the at sign + ptrEntry++; + + *ptrEntry++ = (unsigned char)(numberOfBlocks & 0xff); + *ptrEntry++ = (unsigned char)(numberOfBlocks >> 8); + ptrEntry++; // not used + ptrEntry++; + found = true; + } + else + { + ++entryIndex; + } + } + + if (entryIndex < 8) + { + ptr[0] = 0; + ptr[1] = 0xff; + + if (directorySector > 1) + { + unsigned char* ptrPrevSector = ramD64 + RAMD64GetSectorOffset(track, directorySector - 1) * 256; + + ptrPrevSector[0] = track; + ptrPrevSector[1] = directorySector - 1; + // Allocate directory sector in the BAM + RAMD64AllocateSector(ramD64, track, directorySector); + } + break; + } + } + + return ptrTrackSector; +} + +int DiskImage::RAMD64FreeSectors(unsigned char* ramD64) +{ + int freeSectors = 0; + unsigned char* ptr; + int sectorOffset = RAMD64GetSectorOffset(18, 0); + + DEBUG_LOG("sectorOffset bam = %d\r\n", sectorOffset); + + ptr = ramD64 + sectorOffset * 256; + + ptr += 4; + + int trackIndex; + for (trackIndex = 0; trackIndex < 35; ++trackIndex) + { + freeSectors += *ptr; + ptr += 4; + } + return freeSectors; +} + +bool DiskImage::RAMD64AllocateSector(unsigned char* ramD64, int track, int sector) +{ + int sectorOffset = RAMD64GetSectorOffset(18, 0); + unsigned bits; + unsigned char* ptr = 4 + ramD64 + sectorOffset * 256 + 4 * (track - 1); + unsigned bitMap = 1 << sector; + bits = ptr[1]; + bits |= ptr[2] << 8; + bits |= ptr[3] << 16; + if (bits & bitMap) + { + ptr[0]--; + bits &= ~bitMap; + ptr[1] = (unsigned char)(bits & 0xff); + ptr[2] = (unsigned char)((bits >> 8) & 0xff); + ptr[3] = (unsigned char)((bits >> 16) & 0xff); + return true; + } + return false; +} + +bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64, int lastTrackUsed, int lastSectorUsed, int& track, int& sector) +{ + unsigned char* ptr; + int sectorOffset = RAMD64GetSectorOffset(18, 0); + int trackIndex; + int sectorIndex; + int stripAmount = 10; + + track = 0; + sector = -1; + if (searchForwards) + { + if (lastTrackUsed == -1) + trackIndex = 18; + else + trackIndex = lastTrackUsed - 1; + + for (; trackIndex < 35; ++trackIndex) + { + if (lastTrackUsed != (trackIndex + 1)) + { + lastSectorUsed = 0; + stripAmount = 0; + } + if (lastSectorUsed < 0) + { + lastSectorUsed = 0; + stripAmount = 0; + } + ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex; + if (*ptr != 0) + { + for (sectorIndex = 0; sectorIndex < SectorsPerTrack[trackIndex]; ++sectorIndex) + { + int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % SectorsPerTrack[trackIndex]; + if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped)) + { + track = trackIndex + 1; + sector = sectorStripped; + return true; + } + } + } + } + } + else + { + if (lastTrackUsed == -1) + trackIndex = 16; + else + trackIndex = lastTrackUsed - 1; + for (; trackIndex >= 0; --trackIndex) + { + if (lastTrackUsed != (trackIndex + 1)) + { + lastSectorUsed = 0; + stripAmount = 0; + } + if (lastSectorUsed < 0) + { + lastSectorUsed = 0; + stripAmount = 0; + } + + ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex; + if (*ptr != 0) + { + for (sectorIndex = 0; sectorIndex < SectorsPerTrack[trackIndex]; ++sectorIndex) + { + int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % SectorsPerTrack[trackIndex]; + if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped)) + { + + + track = trackIndex + 1; + sector = sectorStripped; + + return true; + } + } + } + } + } + return false; +} + +bool DiskImage::AddFileToRAMD64(unsigned char* ramD64, const char* name, const unsigned char* data, unsigned length) +{ + int numberOfSectorsRequired = length / (256 - 2) + ((length % (256 - 2)) ? 1 : 0); + int freeSectors = RAMD64FreeSectors(ramD64); + int bytesRemaining = length; + bool success = false; + int lastTrackUsed = -1; + int lastSectorUsed = -1; + + if (freeSectors >= numberOfSectorsRequired) + { + unsigned char* ptrTrackSector = RAMD64AddDirectoryEntry(ramD64, name, data, length); + if (ptrTrackSector) + { + int blocks; + + for (blocks = 0; blocks < numberOfSectorsRequired; ++blocks) + { + int track; + int sector; + + bool found = RAMD64FindFreeSector(true, ramD64, lastTrackUsed, lastSectorUsed, track, sector); + if (!found) + { + if (lastTrackUsed >= 18) + lastTrackUsed = -1; + found = RAMD64FindFreeSector(false, ramD64, lastTrackUsed, lastSectorUsed, track, sector); + } + if (found) + { + lastTrackUsed = track; + lastSectorUsed = sector; + ptrTrackSector[0] = track; + ptrTrackSector[1] = sector; + ptrTrackSector = ramD64 + RAMD64GetSectorOffset(track, sector) * 256; + + int bytesToCopy = (256 - 2); + + if (bytesRemaining < (256 - 2)) + { + bytesToCopy = bytesRemaining + 1; + ptrTrackSector[0] = 0; + ptrTrackSector[1] = bytesToCopy; + } + + bytesRemaining -= bytesToCopy; + + memcpy(ptrTrackSector + 2, data, bytesToCopy); + } + data += (256 - 2); + } + } + } + + return success; +} diff --git a/src/DiskImage.h b/src/DiskImage.h index e114279..bcc810d 100644 --- a/src/DiskImage.h +++ b/src/DiskImage.h @@ -62,17 +62,21 @@ public: LST, D71, D81, + T64, RAW }; DiskImage(); + static unsigned CreateNewDiskInRAM(const char* filenameNew, const char* ID, unsigned char* destBuffer = 0); + bool OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); bool OpenG64(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); bool OpenNIB(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); bool OpenNBZ(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); bool OpenD71(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); bool OpenD81(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); + bool OpenT64(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size); void Close(); @@ -210,11 +214,13 @@ private: void CloseNBZ(); void CloseD71(); void CloseD81(); + void CloseT64(); bool WriteNIB(); bool WriteNBZ(); bool WriteD71(); bool WriteD81(); + bool WriteT64(char* name = 0); inline void TestDirty(u32 track, bool isDirty) { @@ -235,6 +241,14 @@ private: void OutputD81HeaderByte(unsigned char*& dest, unsigned char byte); void OutputD81DataByte(unsigned char*& src, unsigned char*& dest); + static bool AddFileToRAMD64(unsigned char* ramD64, const char* name, const unsigned char* data, unsigned length); + static unsigned char* RAMD64AddDirectoryEntry(unsigned char* ramD64, const char* name, const unsigned char* data, unsigned length); + static int RAMD64GetSectorOffset(int track, int sector); + static int RAMD64FreeSectors(unsigned char* ramD64); + static bool RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64, int lastTrackUsed, int lastSectorUsed, int& track, int& sector); + static bool RAMD64AllocateSector(unsigned char* ramD64, int track, int sector); + static bool WriteRAMD64(unsigned char* diskImage, unsigned size); + bool readOnly; bool dirty; unsigned attachedImageSize; diff --git a/src/FileBrowser.cpp b/src/FileBrowser.cpp index c22b83b..5a60495 100644 --- a/src/FileBrowser.cpp +++ b/src/FileBrowser.cpp @@ -1332,7 +1332,7 @@ bool FileBrowser::SelectLST(const char* filenameLST) { //DEBUG_LOG("LST token = %s\r\n", token); diskType = DiskImage::GetDiskImageTypeViaExtention(token); - if (diskType == DiskImage::D64 || diskType == DiskImage::G64 || diskType == DiskImage::NIB || diskType == DiskImage::NBZ) + if (diskType == DiskImage::D64 || diskType == DiskImage::G64 || diskType == DiskImage::NIB || diskType == DiskImage::NBZ || diskType == DiskImage::T64) { FileBrowser::BrowsableList::Entry* entry = folder.FindEntry(token); if (entry && !(entry->filImage.fattrib & AM_DIR)) diff --git a/src/iec_commands.cpp b/src/iec_commands.cpp index bf35203..a20574d 100644 --- a/src/iec_commands.cpp +++ b/src/iec_commands.cpp @@ -29,6 +29,7 @@ #include "DiskImage.h" #include "Petscii.h" #include "FileBrowser.h" +#include "DiskImage.h" #include #include #include @@ -93,29 +94,6 @@ static const u8 filetypes[] = { 'D', 'I', 'R', // 6 }; -#define DISKNAME_OFFSET_IN_DIR_BLOCK 144 -#define DISKID_OFFSET_IN_DIR_BLOCK 162 -static u8 blankD64DIRBAM[] = -{ - 0x12, 0x01, 0x41, 0x00, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, - 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, - 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, - 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, - 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x11, 0xfc, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, - 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, 0x13, 0xff, 0xff, 0x07, - 0x13, 0xff, 0xff, 0x07, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, - 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x12, 0xff, 0xff, 0x03, 0x11, 0xff, 0xff, 0x01, - 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, 0x11, 0xff, 0xff, 0x01, - 0x42, 0x4c, 0x41, 0x4e, 0x4b, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, - 0xa0, 0xa0, 0x31, 0x41, 0xa0, 0x32, 0x41, 0xa0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - static char ErrorMessage[64]; static u8* InsertNumber(u8* msg, u8 value) @@ -2136,11 +2114,6 @@ void IEC_Commands::CloseFile(u8 secondary) int IEC_Commands::CreateNewDisk(char* filenameNew, char* ID, bool automount) { - FILINFO filInfo; - FRESULT res; - char* ptr; - int i; - DisplayMessage(240, 280, false, "Creating new disk", RGBA(0xff, 0xff, 0xff, 0xff), RGBA(0xff, 0, 0, 0xff)); DisplayMessage(0, 0, true, "Creating new disk", RGBA(0xff, 0xff, 0xff, 0xff), RGBA(0xff, 0, 0, 0xff)); @@ -2159,63 +2132,22 @@ int IEC_Commands::CreateNewDisk(char* filenameNew, char* ID, bool automount) break; } + unsigned length = DiskImage::CreateNewDiskInRAM(filenameNew, ID); + + return WriteNewDiskInRAM(filenameNew, automount, length); +} + + +int IEC_Commands::WriteNewDiskInRAM(char* filenameNew, bool automount, unsigned length) +{ + FILINFO filInfo; + FRESULT res; + res = f_stat(filenameNew, &filInfo); if (res == FR_NO_FILE) { - - unsigned char* dest = DiskImage::readBuffer; - - char buffer[256]; - u32 bytes; - u32 blocks; - - memset(buffer, 0, sizeof(buffer)); - // TODO: Should check for disk full. - for (blocks = 0; blocks < 357; ++blocks) - { - for (i = 0; i < 256; ++i) - { - *dest++ = buffer[i]; - } - } - ptr = (char*)&blankD64DIRBAM[DISKNAME_OFFSET_IN_DIR_BLOCK]; - int len = strlen(filenameNew); - for (i = 0; i < len; ++i) - { - *ptr++ = ascii2petscii(filenameNew[i]); - } - for (; i < 18; ++i) - { - *ptr++ = 0xa0; - } - for (i = 0; i < 2; ++i) - { - *ptr++ = ascii2petscii(ID[i]); - } - //f_write(&fpOut, blankD64DIRBAM, 256, &bytes); - for (i = 0; i < 256; ++i) - { - *dest++ = blankD64DIRBAM[i]; - } - buffer[1] = 0xff; - //f_write(&fpOut, buffer, 256, &bytes); - for (i = 0; i < 256; ++i) - { - *dest++ = buffer[i]; - } - buffer[1] = 0; - for (blocks = 0; blocks < 324; ++blocks) - { - //if (f_write(&fpOut, buffer, 256, &bytes) != FR_OK) - // break; - for (i = 0; i < 256; ++i) - { - *dest++ = buffer[i]; - } - } - DiskImage diskImage; - diskImage.OpenD64((const FILINFO*)0, (unsigned char*)DiskImage::readBuffer, dest - (unsigned char*)DiskImage::readBuffer); + diskImage.OpenD64((const FILINFO*)0, (unsigned char*)DiskImage::readBuffer, length); switch (newDiskType) { diff --git a/src/iec_commands.h b/src/iec_commands.h index 688a31d..1f8e210 100644 --- a/src/iec_commands.h +++ b/src/iec_commands.h @@ -172,6 +172,8 @@ protected: u8 GetFilenameCharacter(u8 value); + int WriteNewDiskInRAM(char* filenameNew, bool automount, unsigned length); + UpdateAction updateAction; u8 commandCode; bool receivedCommand : 1; diff --git a/src/types.h b/src/types.h index ba55c88..3c31b96 100644 --- a/src/types.h +++ b/src/types.h @@ -24,4 +24,12 @@ typedef enum { EXIT_AUTOLOAD } EXIT_TYPE; +#ifndef Max +#define Max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef Min +#define Min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + #endif