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.
This commit is contained in:
parent
9c75e0bb97
commit
14452da320
8 changed files with 543 additions and 82 deletions
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "lz.h"
|
||||
#include "Petscii.h"
|
||||
#include <malloc.h>
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "DiskImage.h"
|
||||
#include "Petscii.h"
|
||||
#include "FileBrowser.h"
|
||||
#include "DiskImage.h"
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdio.h>
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -172,6 +172,8 @@ protected:
|
|||
|
||||
u8 GetFilenameCharacter(u8 value);
|
||||
|
||||
int WriteNewDiskInRAM(char* filenameNew, bool automount, unsigned length);
|
||||
|
||||
UpdateAction updateAction;
|
||||
u8 commandCode;
|
||||
bool receivedCommand : 1;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue