Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
b57194a35b
11 changed files with 149 additions and 103 deletions
|
@ -42,7 +42,7 @@ extern u32 HashBuffer(const void* pBuffer, u32 length);
|
||||||
|
|
||||||
#define DIRECTRY_ENTRY_FILE_TYPE_PRG 0x82
|
#define DIRECTRY_ENTRY_FILE_TYPE_PRG 0x82
|
||||||
|
|
||||||
static u8 blankD64DIRBAM[] =
|
static const u8 blankD64DIRBAM[] =
|
||||||
{
|
{
|
||||||
0x12, 0x01, 0x41, 0x00, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f, 0x15, 0xff, 0xff, 0x1f,
|
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,
|
||||||
|
@ -76,6 +76,11 @@ static const unsigned MAX_D64_SIZE = 0x32200 + 768;
|
||||||
static const unsigned MAX_D71_SIZE = 0x55600 + 1366;
|
static const unsigned MAX_D71_SIZE = 0x55600 + 1366;
|
||||||
static const unsigned MAX_D81_SIZE = 822400;
|
static const unsigned MAX_D81_SIZE = 822400;
|
||||||
|
|
||||||
|
static const unsigned short GCR_SYNC_LENGTH = 5;
|
||||||
|
static const unsigned short GCR_HEADER_LENGTH = 10;
|
||||||
|
static const unsigned short GCR_HEADER_GAP_LENGTH = 9;
|
||||||
|
static const unsigned short GCR_SECTOR_DATA_LENGTH = 325;
|
||||||
|
|
||||||
// CRC-16-CCITT
|
// CRC-16-CCITT
|
||||||
// CRC(x) = x^16 + x^12 + x^5 + x^0
|
// CRC(x) = x^16 + x^12 + x^5 + x^0
|
||||||
unsigned short DiskImage::CRC1021[256] =
|
unsigned short DiskImage::CRC1021[256] =
|
||||||
|
@ -98,6 +103,11 @@ unsigned short DiskImage::CRC1021[256] =
|
||||||
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned trackSize[4] = { 6250, 6666, 7142, 7692 };
|
||||||
|
static const unsigned sectorsPerTrack[4] = { 17, 18, 19, 21 };
|
||||||
|
static const unsigned gapSize[4] = { 9, 12, 17, 8 };
|
||||||
|
|
||||||
|
|
||||||
void DiskImage::CRC(unsigned short& runningCRC, unsigned char data)
|
void DiskImage::CRC(unsigned short& runningCRC, unsigned char data)
|
||||||
{
|
{
|
||||||
runningCRC = CRC1021[(runningCRC >> 8) ^ data] ^ (runningCRC << 8);
|
runningCRC = CRC1021[(runningCRC >> 8) ^ data] ^ (runningCRC << 8);
|
||||||
|
@ -119,21 +129,16 @@ void DiskImage::OutputD81DataByte(unsigned char*& src, unsigned char*& dest)
|
||||||
CRC(crc, data);
|
CRC(crc, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned DiskImage::SectorsPerTrackD64(unsigned track)
|
||||||
|
{
|
||||||
|
return sectorsPerTrack[GetSpeedZoneIndexD64(track)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define NIB_HEADER_SIZE 0xFF
|
#define NIB_HEADER_SIZE 0xFF
|
||||||
|
|
||||||
int gap_match_length = 7; // Used by gcr.cpp
|
int gap_match_length = 7; // Used by gcr.cpp
|
||||||
|
|
||||||
const unsigned char DiskImage::SectorsPerTrack[42] =
|
|
||||||
{
|
|
||||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, // 1 - 17
|
|
||||||
19, 19, 19, 19, 19, 19, 19, // 18 - 24
|
|
||||||
18, 18, 18, 18, 18, 18, // 25 - 30
|
|
||||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, // 31 - 40
|
|
||||||
17, 17 // 41 - 42
|
|
||||||
// total 683-768 sectors
|
|
||||||
};
|
|
||||||
|
|
||||||
DiskImage::DiskImage()
|
DiskImage::DiskImage()
|
||||||
: readOnly(false)
|
: readOnly(false)
|
||||||
, dirty(false)
|
, dirty(false)
|
||||||
|
@ -208,6 +213,9 @@ bool DiskImage::OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsig
|
||||||
unsigned char errorinfo[MAXBLOCKSONDISK];
|
unsigned char errorinfo[MAXBLOCKSONDISK];
|
||||||
unsigned last_track;
|
unsigned last_track;
|
||||||
unsigned sector_ref;
|
unsigned sector_ref;
|
||||||
|
unsigned sectors;
|
||||||
|
unsigned speedZoneIndex;
|
||||||
|
unsigned sectorSize;
|
||||||
unsigned char error;
|
unsigned char error;
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
@ -254,7 +262,7 @@ bool DiskImage::OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsig
|
||||||
unsigned char* dest = tracks[halfTrackIndex];
|
unsigned char* dest = tracks[halfTrackIndex];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
trackLengths[halfTrackIndex] = SectorsPerTrack[track] * GCR_SECTOR_LENGTH;
|
trackLengths[halfTrackIndex] = trackSize[GetSpeedZoneIndexD64(track)];
|
||||||
|
|
||||||
if ((halfTrackIndex & 1) == 0)
|
if ((halfTrackIndex & 1) == 0)
|
||||||
{
|
{
|
||||||
|
@ -262,13 +270,15 @@ bool DiskImage::OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsig
|
||||||
{
|
{
|
||||||
trackUsed[halfTrackIndex] = true;
|
trackUsed[halfTrackIndex] = true;
|
||||||
//DEBUG_LOG("Track %d used\r\n", halfTrackIndex);
|
//DEBUG_LOG("Track %d used\r\n", halfTrackIndex);
|
||||||
for (unsigned sectorNo = 0; sectorNo < SectorsPerTrack[track]; ++sectorNo)
|
speedZoneIndex = GetSpeedZoneIndexD64(track);
|
||||||
|
sectors = sectorsPerTrack[speedZoneIndex];
|
||||||
|
sectorSize = GCR_SYNC_LENGTH + GCR_HEADER_LENGTH + GCR_HEADER_GAP_LENGTH + GCR_SYNC_LENGTH + GCR_SECTOR_DATA_LENGTH + gapSize[speedZoneIndex];
|
||||||
|
|
||||||
|
for (unsigned sectorNo = 0; sectorNo < sectors; ++sectorNo)
|
||||||
{
|
{
|
||||||
error = errorinfo[sector_ref++];
|
error = errorinfo[sector_ref++];
|
||||||
|
convert_sector_to_GCR(diskImage + offset, dest, track + 1, sectorNo, diskImage + 0x165A2, error, sectorSize);
|
||||||
convert_sector_to_GCR(diskImage + offset, dest, track + 1, sectorNo, diskImage + 0x165A2, error);
|
dest += sectorSize;
|
||||||
dest += 361;
|
|
||||||
|
|
||||||
offset += SECTOR_LENGTH;
|
offset += SECTOR_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,9 +301,17 @@ bool DiskImage::OpenD64(const FILINFO* fileInfo, unsigned char* diskImage, unsig
|
||||||
|
|
||||||
bool DiskImage::WriteD64(char* name)
|
bool DiskImage::WriteD64(char* name)
|
||||||
{
|
{
|
||||||
|
BYTE id[3];
|
||||||
|
|
||||||
if (readOnly)
|
if (readOnly)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!GetID(34, id))
|
||||||
|
{
|
||||||
|
DEBUG_LOG("Cannot find directory sector.\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
FIL fp;
|
FIL fp;
|
||||||
FRESULT res = f_open(&fp, fileInfo ? fileInfo->fname : name, FA_CREATE_ALWAYS | FA_WRITE);
|
FRESULT res = f_open(&fp, fileInfo ? fileInfo->fname : name, FA_CREATE_ALWAYS | FA_WRITE);
|
||||||
if (res == FR_OK)
|
if (res == FR_OK)
|
||||||
|
@ -301,8 +319,7 @@ bool DiskImage::WriteD64(char* name)
|
||||||
u32 bytesToWrite;
|
u32 bytesToWrite;
|
||||||
u32 bytesWritten;
|
u32 bytesWritten;
|
||||||
|
|
||||||
int track, sector;
|
unsigned track, sector, sectors;
|
||||||
BYTE id[3];
|
|
||||||
BYTE d64data[MAXBLOCKSONDISK * 256], *d64ptr;
|
BYTE d64data[MAXBLOCKSONDISK * 256], *d64ptr;
|
||||||
int blocks_to_save = 0;
|
int blocks_to_save = 0;
|
||||||
|
|
||||||
|
@ -310,11 +327,6 @@ bool DiskImage::WriteD64(char* name)
|
||||||
|
|
||||||
memset(d64data, 0, sizeof(d64data));
|
memset(d64data, 0, sizeof(d64data));
|
||||||
|
|
||||||
if (!GetID(34, id))
|
|
||||||
{
|
|
||||||
DEBUG_LOG("Cannot find directory sector.\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
d64ptr = d64data;
|
d64ptr = d64data;
|
||||||
for (track = 0; track < HALF_TRACK_COUNT; track += 2)
|
for (track = 0; track < HALF_TRACK_COUNT; track += 2)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +334,8 @@ bool DiskImage::WriteD64(char* name)
|
||||||
{
|
{
|
||||||
//printf("Track %d\r\n", track);
|
//printf("Track %d\r\n", track);
|
||||||
|
|
||||||
for (sector = 0; sector < SectorsPerTrack[track / 2]; sector++)
|
sectors = sectorsPerTrack[GetSpeedZoneIndexD64(track >> 1)];
|
||||||
|
for (sector = 0; sector < sectors; sector++)
|
||||||
{
|
{
|
||||||
ConvertSector(track, sector, d64ptr);
|
ConvertSector(track, sector, d64ptr);
|
||||||
d64ptr += 256;
|
d64ptr += 256;
|
||||||
|
@ -369,6 +382,14 @@ void DiskImage::CloseD64()
|
||||||
|
|
||||||
bool DiskImage::OpenD71(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size)
|
bool DiskImage::OpenD71(const FILINFO* fileInfo, unsigned char* diskImage, unsigned size)
|
||||||
{
|
{
|
||||||
|
unsigned char errorinfo[MAXBLOCKSONDISK * 2];
|
||||||
|
unsigned last_track;
|
||||||
|
unsigned sector_ref;
|
||||||
|
unsigned sectors;
|
||||||
|
unsigned speedZoneIndex;
|
||||||
|
unsigned sectorSize;
|
||||||
|
unsigned char error;
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
this->fileInfo = fileInfo;
|
this->fileInfo = fileInfo;
|
||||||
|
@ -380,43 +401,67 @@ bool DiskImage::OpenD71(const FILINFO* fileInfo, unsigned char* diskImage, unsig
|
||||||
|
|
||||||
attachedImageSize = size;
|
attachedImageSize = size;
|
||||||
|
|
||||||
for (unsigned headIndex = 0; headIndex < 2; ++headIndex)
|
memset(errorinfo, SECTOR_OK, sizeof(errorinfo));
|
||||||
|
|
||||||
|
switch (size)
|
||||||
{
|
{
|
||||||
for (unsigned halfTrackIndex = 0; halfTrackIndex < D71_HALF_TRACK_COUNT; ++halfTrackIndex)
|
case (BLOCKSONDISK * 2 * 257): // 70 track image with errorinfo
|
||||||
|
memcpy(errorinfo, diskImage + (BLOCKSONDISK * 2 * 256), BLOCKSONDISK * 2);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case (BLOCKSONDISK * 2 * 256): // 70 track image w/o errorinfo
|
||||||
|
last_track = 70;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//case (MAXBLOCKSONDISK * 2 * 257): // 80 track image with errorinfo
|
||||||
|
// memcpy(errorinfo, diskImage + (MAXBLOCKSONDISK * 2 * 256), MAXBLOCKSONDISK * 2);
|
||||||
|
// /* FALLTHROUGH */
|
||||||
|
//case (MAXBLOCKSONDISK * 2 * 256): // 40 track image w/o errorinfo
|
||||||
|
// last_track = 80;
|
||||||
|
// break;
|
||||||
|
|
||||||
|
default: // non-standard images, attempt to load anyway
|
||||||
|
last_track = MAX_TRACK_D64 * 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sector_ref = 0;
|
||||||
|
for (unsigned halfTrackIndex = 0; halfTrackIndex < last_track * 2; ++halfTrackIndex)
|
||||||
|
{
|
||||||
|
unsigned char track = (halfTrackIndex >> 1);
|
||||||
|
#if defined(EXPERIMENTALZERO)
|
||||||
|
unsigned char* dest = &tracks[halfTrackIndex << 13];
|
||||||
|
#else
|
||||||
|
unsigned char* dest = tracks[halfTrackIndex];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
trackLengths[halfTrackIndex] = trackSize[GetSpeedZoneIndexD64(track)];
|
||||||
|
|
||||||
|
if ((halfTrackIndex & 1) == 0)
|
||||||
{
|
{
|
||||||
unsigned char track = (halfTrackIndex >> 1);
|
if (offset < size)
|
||||||
unsigned char* dest = tracksD81[halfTrackIndex][headIndex];
|
|
||||||
|
|
||||||
trackLengths[halfTrackIndex] = SectorsPerTrack[track] * GCR_SECTOR_LENGTH;
|
|
||||||
|
|
||||||
if ((halfTrackIndex & 1) == 0)
|
|
||||||
{
|
{
|
||||||
if (offset < size) // This will allow for >35 tracks.
|
trackUsed[halfTrackIndex] = true;
|
||||||
|
speedZoneIndex = GetSpeedZoneIndexD64(track);
|
||||||
|
sectors = sectorsPerTrack[speedZoneIndex];
|
||||||
|
sectorSize = GCR_SYNC_LENGTH + GCR_HEADER_LENGTH + GCR_HEADER_GAP_LENGTH + GCR_SYNC_LENGTH + GCR_SECTOR_DATA_LENGTH + gapSize[speedZoneIndex];
|
||||||
|
for (unsigned sectorNo = 0; sectorNo < sectors; ++sectorNo)
|
||||||
{
|
{
|
||||||
trackUsed[halfTrackIndex] = true;
|
error = errorinfo[sector_ref++];
|
||||||
//DEBUG_LOG("Track %d used\r\n", halfTrackIndex);
|
convert_sector_to_GCR(diskImage + offset, dest, track + 1, sectorNo, diskImage + 0x165A2, error, sectorSize);
|
||||||
for (unsigned sectorNo = 0; sectorNo < SectorsPerTrack[track]; ++sectorNo)
|
dest += sectorSize;
|
||||||
{
|
offset += SECTOR_LENGTH;
|
||||||
convert_sector_to_GCR(diskImage + offset, dest, track + 1, sectorNo, diskImage + 0x165A2, 0);
|
|
||||||
dest += 361;
|
|
||||||
|
|
||||||
offset += SECTOR_LENGTH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
trackUsed[halfTrackIndex] = false;
|
|
||||||
//DEBUG_LOG("Track %d not used\r\n", halfTrackIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trackUsed[halfTrackIndex] = false;
|
trackUsed[halfTrackIndex] = false;
|
||||||
//DEBUG_LOG("Track %d not used\r\n", halfTrackIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trackUsed[halfTrackIndex] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diskType = D71;
|
diskType = D71;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1659,7 +1704,7 @@ int DiskImage::RAMD64GetSectorOffset(int track, int sector)
|
||||||
|
|
||||||
for (index = 0; index < (track - 1); ++index)
|
for (index = 0; index < (track - 1); ++index)
|
||||||
{
|
{
|
||||||
sectorOffset += SectorsPerTrack[index];
|
sectorOffset += sectorsPerTrack[GetSpeedZoneIndexD64(index)];
|
||||||
}
|
}
|
||||||
sectorOffset += sector;
|
sectorOffset += sector;
|
||||||
return sectorOffset;
|
return sectorOffset;
|
||||||
|
@ -1807,8 +1852,9 @@ bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64,
|
||||||
{
|
{
|
||||||
unsigned char* ptr;
|
unsigned char* ptr;
|
||||||
int sectorOffset = RAMD64GetSectorOffset(18, 0);
|
int sectorOffset = RAMD64GetSectorOffset(18, 0);
|
||||||
int trackIndex;
|
unsigned trackIndex;
|
||||||
int sectorIndex;
|
unsigned sectorIndex;
|
||||||
|
unsigned sectors;
|
||||||
int stripAmount = 10;
|
int stripAmount = 10;
|
||||||
|
|
||||||
track = 0;
|
track = 0;
|
||||||
|
@ -1822,7 +1868,7 @@ bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64,
|
||||||
|
|
||||||
for (; trackIndex < 35; ++trackIndex)
|
for (; trackIndex < 35; ++trackIndex)
|
||||||
{
|
{
|
||||||
if (lastTrackUsed != (trackIndex + 1))
|
if ((unsigned)lastTrackUsed != (trackIndex + 1))
|
||||||
{
|
{
|
||||||
lastSectorUsed = 0;
|
lastSectorUsed = 0;
|
||||||
stripAmount = 0;
|
stripAmount = 0;
|
||||||
|
@ -1835,9 +1881,10 @@ bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64,
|
||||||
ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex;
|
ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex;
|
||||||
if (*ptr != 0)
|
if (*ptr != 0)
|
||||||
{
|
{
|
||||||
for (sectorIndex = 0; sectorIndex < SectorsPerTrack[trackIndex]; ++sectorIndex)
|
sectors = sectorsPerTrack[GetSpeedZoneIndexD64(trackIndex)];
|
||||||
|
for (sectorIndex = 0; sectorIndex < sectors; ++sectorIndex)
|
||||||
{
|
{
|
||||||
int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % SectorsPerTrack[trackIndex];
|
int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % sectors;
|
||||||
if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped))
|
if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped))
|
||||||
{
|
{
|
||||||
track = trackIndex + 1;
|
track = trackIndex + 1;
|
||||||
|
@ -1856,7 +1903,7 @@ bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64,
|
||||||
trackIndex = lastTrackUsed - 1;
|
trackIndex = lastTrackUsed - 1;
|
||||||
for (; trackIndex >= 0; --trackIndex)
|
for (; trackIndex >= 0; --trackIndex)
|
||||||
{
|
{
|
||||||
if (lastTrackUsed != (trackIndex + 1))
|
if ((unsigned)lastTrackUsed != (trackIndex + 1))
|
||||||
{
|
{
|
||||||
lastSectorUsed = 0;
|
lastSectorUsed = 0;
|
||||||
stripAmount = 0;
|
stripAmount = 0;
|
||||||
|
@ -1870,9 +1917,10 @@ bool DiskImage::RAMD64FindFreeSector(bool searchForwards, unsigned char* ramD64,
|
||||||
ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex;
|
ptr = 4 + ramD64 + sectorOffset * 256 + 4 * trackIndex;
|
||||||
if (*ptr != 0)
|
if (*ptr != 0)
|
||||||
{
|
{
|
||||||
for (sectorIndex = 0; sectorIndex < SectorsPerTrack[trackIndex]; ++sectorIndex)
|
sectors = sectorsPerTrack[GetSpeedZoneIndexD64(trackIndex)];
|
||||||
|
for (sectorIndex = 0; sectorIndex < sectors; ++sectorIndex)
|
||||||
{
|
{
|
||||||
int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % SectorsPerTrack[trackIndex];
|
int sectorStripped = (sectorIndex + lastSectorUsed + stripAmount) % sectors;
|
||||||
if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped))
|
if (RAMD64AllocateSector(ramD64, trackIndex + 1, sectorStripped))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -36,14 +36,7 @@
|
||||||
#define DIR_ENTRY_NAME_LENGTH 18-2
|
#define DIR_ENTRY_NAME_LENGTH 18-2
|
||||||
|
|
||||||
static const unsigned char HALF_TRACK_COUNT = 84;
|
static const unsigned char HALF_TRACK_COUNT = 84;
|
||||||
static const unsigned char D71_HALF_TRACK_COUNT = 70;
|
|
||||||
static const unsigned char D81_TRACK_COUNT = 80;
|
static const unsigned char D81_TRACK_COUNT = 80;
|
||||||
static const unsigned short GCR_SYNC_LENGTH = 5;
|
|
||||||
static const unsigned short GCR_HEADER_LENGTH = 10;
|
|
||||||
static const unsigned short GCR_HEADER_GAP_LENGTH = 8;
|
|
||||||
static const unsigned short GCR_SECTOR_DATA_LENGTH = 325;
|
|
||||||
static const unsigned short GCR_SECTOR_GAP_LENGTH = 8;
|
|
||||||
static const unsigned short GCR_SECTOR_LENGTH = GCR_SYNC_LENGTH + GCR_HEADER_LENGTH + GCR_HEADER_GAP_LENGTH + GCR_SYNC_LENGTH + GCR_SECTOR_DATA_LENGTH + GCR_SECTOR_GAP_LENGTH; //361
|
|
||||||
|
|
||||||
static const unsigned short G64_MAX_TRACK_LENGTH = 7928;
|
static const unsigned short G64_MAX_TRACK_LENGTH = 7928;
|
||||||
|
|
||||||
|
@ -209,6 +202,13 @@ public:
|
||||||
|
|
||||||
unsigned GetHash() const { return hash; }
|
unsigned GetHash() const { return hash; }
|
||||||
|
|
||||||
|
inline static unsigned GetSpeedZoneIndexD64(unsigned track)
|
||||||
|
{
|
||||||
|
return (track < 30) + (track < 24) + (track < 17);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned SectorsPerTrackD64(unsigned track);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CloseD64();
|
void CloseD64();
|
||||||
void CloseG64();
|
void CloseG64();
|
||||||
|
|
16
src/Drive.h
16
src/Drive.h
|
@ -125,7 +125,7 @@ private:
|
||||||
void DumpTrack(unsigned track); // Used for debugging disk images.
|
void DumpTrack(unsigned track); // Used for debugging disk images.
|
||||||
|
|
||||||
#if defined(EXPERIMENTALZERO)
|
#if defined(EXPERIMENTALZERO)
|
||||||
inline u32 AdvanceSectorPositionR(int& byteOffset)
|
inline u32 AdvanceSectorPosition(int& byteOffset)
|
||||||
{
|
{
|
||||||
if (++headBitOffset == bitsInTrack)
|
if (++headBitOffset == bitsInTrack)
|
||||||
headBitOffset = 0;
|
headBitOffset = 0;
|
||||||
|
@ -133,28 +133,20 @@ private:
|
||||||
return (~headBitOffset) & 7;
|
return (~headBitOffset) & 7;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// No reason why I seperate these into individual read and write versions. I was just trying to get the bit stream to line up when rewriting over existing data.
|
inline u32 AdvanceSectorPosition(int& byteOffset)
|
||||||
inline u32 AdvanceSectorPositionR(int& byteOffset)
|
|
||||||
{
|
{
|
||||||
++headBitOffset %= bitsInTrack;
|
++headBitOffset %= bitsInTrack;
|
||||||
byteOffset = headBitOffset >> 3;
|
byteOffset = headBitOffset >> 3;
|
||||||
return (~headBitOffset) & 7;
|
return (~headBitOffset) & 7;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
inline u32 AdvanceSectorPositionW(int& byteOffset)
|
|
||||||
{
|
|
||||||
byteOffset = headBitOffset >> 3;
|
|
||||||
u32 bit = (~headBitOffset) & 7;
|
|
||||||
++headBitOffset %= bitsInTrack;
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
unsigned cachedheadTrackPos = -1;
|
unsigned cachedheadTrackPos = -1;
|
||||||
int cachedbyteOffset = -1;
|
int cachedbyteOffset = -1;
|
||||||
unsigned char cachedByte = 0;
|
unsigned char cachedByte = 0;
|
||||||
inline bool GetNextBit()
|
inline bool GetNextBit()
|
||||||
{
|
{
|
||||||
int byteOffset;
|
int byteOffset;
|
||||||
int bit = AdvanceSectorPositionR(byteOffset);
|
int bit = AdvanceSectorPosition(byteOffset);
|
||||||
|
|
||||||
//Why is it faster to check both conditions here than to update the cache when moving the head?
|
//Why is it faster to check both conditions here than to update the cache when moving the head?
|
||||||
if (byteOffset != cachedbyteOffset || cachedheadTrackPos != headTrackPos)
|
if (byteOffset != cachedbyteOffset || cachedheadTrackPos != headTrackPos)
|
||||||
|
@ -171,7 +163,7 @@ private:
|
||||||
inline void SetNextBit(bool value)
|
inline void SetNextBit(bool value)
|
||||||
{
|
{
|
||||||
int byteOffset;
|
int byteOffset;
|
||||||
int bit = AdvanceSectorPositionW(byteOffset);
|
int bit = AdvanceSectorPosition(byteOffset);
|
||||||
diskImage->SetBit(headTrackPos, byteOffset, bit, value);
|
diskImage->SetBit(headTrackPos, byteOffset, bit, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1615,7 +1615,7 @@ void FileBrowser::DisplayDiskInfo(DiskImage* diskImage, const char* filenameForI
|
||||||
blocksFree += buffer[bamOffset + bamTrack * BAM_ENTRY_SIZE];
|
blocksFree += buffer[bamOffset + bamTrack * BAM_ENTRY_SIZE];
|
||||||
|
|
||||||
y_px = 0;
|
y_px = 0;
|
||||||
for (int bit = 0; bit < DiskImage::SectorsPerTrack[bamTrack]; bit++)
|
for (u32 bit = 0; bit < DiskImage::SectorsPerTrackD64(bamTrack); bit++)
|
||||||
{
|
{
|
||||||
u32 bits = buffer[bamOffset + 1 + (bit >> 3) + bamTrack * BAM_ENTRY_SIZE];
|
u32 bits = buffer[bamOffset + 1 + (bit >> 3) + bamTrack * BAM_ENTRY_SIZE];
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,12 @@ unsigned InputMappings::directDiskSwapRequest = 0;
|
||||||
//volatile unsigned InputMappings::uartFlags = 0;
|
//volatile unsigned InputMappings::uartFlags = 0;
|
||||||
//unsigned InputMappings::escapeSequenceIndex = 0;
|
//unsigned InputMappings::escapeSequenceIndex = 0;
|
||||||
|
|
||||||
|
u8 InputMappings::INPUT_BUTTON_ENTER = 0;
|
||||||
|
u8 InputMappings::INPUT_BUTTON_UP = 1;
|
||||||
|
u8 InputMappings::INPUT_BUTTON_DOWN = 2;
|
||||||
|
u8 InputMappings::INPUT_BUTTON_BACK = 3;
|
||||||
|
u8 InputMappings::INPUT_BUTTON_INSERT = 4;
|
||||||
|
|
||||||
InputMappings::InputMappings()
|
InputMappings::InputMappings()
|
||||||
: keyboardBrowseLCDScreen(false)
|
: keyboardBrowseLCDScreen(false)
|
||||||
, insertButtonPressedPrev(false)
|
, insertButtonPressedPrev(false)
|
||||||
|
|
|
@ -86,11 +86,11 @@ public:
|
||||||
|
|
||||||
void WaitForClearButtons();
|
void WaitForClearButtons();
|
||||||
|
|
||||||
u8 INPUT_BUTTON_ENTER = 0;
|
static u8 INPUT_BUTTON_ENTER;
|
||||||
u8 INPUT_BUTTON_UP = 1;
|
static u8 INPUT_BUTTON_UP;
|
||||||
u8 INPUT_BUTTON_DOWN = 2;
|
static u8 INPUT_BUTTON_DOWN;
|
||||||
u8 INPUT_BUTTON_BACK = 3;
|
static u8 INPUT_BUTTON_BACK;
|
||||||
u8 INPUT_BUTTON_INSERT = 4;
|
static u8 INPUT_BUTTON_INSERT;
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
|
|
|
@ -398,14 +398,14 @@ convert_GCR_sector(BYTE * gcr_start, BYTE * gcr_cycle, BYTE * d64_sector,
|
||||||
|
|
||||||
void
|
void
|
||||||
convert_sector_to_GCR(BYTE * buffer, BYTE * ptr,
|
convert_sector_to_GCR(BYTE * buffer, BYTE * ptr,
|
||||||
int track, int sector, BYTE * diskID, int error)
|
int track, int sector, BYTE * diskID, int error, int sectorSize)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
BYTE buf[4], databuf[0x104], chksum;
|
BYTE buf[4], databuf[0x104], chksum;
|
||||||
BYTE tempID[3];
|
BYTE tempID[3];
|
||||||
|
|
||||||
memcpy(tempID, diskID, 3);
|
memcpy(tempID, diskID, 3);
|
||||||
memset(ptr, 0x55, 361); /* 'unformat' GCR sector */
|
memset(ptr, 0x55, sectorSize); /* 'unformat' GCR sector */
|
||||||
|
|
||||||
if (error == SYNC_NOT_FOUND)
|
if (error == SYNC_NOT_FOUND)
|
||||||
return;
|
return;
|
||||||
|
@ -472,10 +472,6 @@ convert_sector_to_GCR(BYTE * buffer, BYTE * ptr,
|
||||||
convert_4bytes_to_GCR(databuf + (4 * i), ptr);
|
convert_4bytes_to_GCR(databuf + (4 * i), ptr);
|
||||||
ptr += 5;
|
ptr += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 7 0x55 gap bytes in my reference disk */
|
|
||||||
memset(ptr, 0x55, 7); /* Gap before next sector */
|
|
||||||
ptr += 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
|
@ -135,7 +135,7 @@ size_t find_nondos_track_cycle(BYTE ** cycle_start, BYTE ** cycle_stop,
|
||||||
BYTE convert_GCR_sector(BYTE * gcr_start, BYTE * gcr_end,
|
BYTE convert_GCR_sector(BYTE * gcr_start, BYTE * gcr_end,
|
||||||
BYTE * d64_sector, int track, int sector, BYTE * id);
|
BYTE * d64_sector, int track, int sector, BYTE * id);
|
||||||
void convert_sector_to_GCR(BYTE * buffer, BYTE * ptr,
|
void convert_sector_to_GCR(BYTE * buffer, BYTE * ptr,
|
||||||
int track, int sector, BYTE * diskID, int error);
|
int track, int sector, BYTE * diskID, int error, int sectorSize);
|
||||||
BYTE * find_sector_gap(BYTE * work_buffer, int tracklen, size_t * p_sectorlen);
|
BYTE * find_sector_gap(BYTE * work_buffer, int tracklen, size_t * p_sectorlen);
|
||||||
BYTE * find_sector0(BYTE * work_buffer, int tracklen, size_t * p_sectorlen);
|
BYTE * find_sector0(BYTE * work_buffer, int tracklen, size_t * p_sectorlen);
|
||||||
int extract_GCR_track(BYTE * destination, BYTE * source, int * align,
|
int extract_GCR_track(BYTE * destination, BYTE * source, int * align,
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
|
// along with Pi1541. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "iec_bus.h"
|
#include "iec_bus.h"
|
||||||
|
#include "InputMappings.h"
|
||||||
|
|
||||||
//#define REAL_XOR 1
|
//#define REAL_XOR 1
|
||||||
|
|
||||||
|
int IEC_Bus::buttonCount = sizeof(ButtonPinFlags) / sizeof(unsigned);
|
||||||
|
|
||||||
u32 IEC_Bus::oldClears = 0;
|
u32 IEC_Bus::oldClears = 0;
|
||||||
u32 IEC_Bus::oldSets = 0;
|
u32 IEC_Bus::oldSets = 0;
|
||||||
u32 IEC_Bus::PIGPIO_MASK_IN_ATN = 1 << PIGPIO_ATN;
|
u32 IEC_Bus::PIGPIO_MASK_IN_ATN = 1 << PIGPIO_ATN;
|
||||||
|
@ -77,16 +80,16 @@ bool IEC_Bus::rotaryEncoderEnable;
|
||||||
//ROTARY: Added for rotary encoder inversion (Issue#185) - 08/13/2020 by Geo...
|
//ROTARY: Added for rotary encoder inversion (Issue#185) - 08/13/2020 by Geo...
|
||||||
bool IEC_Bus::rotaryEncoderInvert;
|
bool IEC_Bus::rotaryEncoderInvert;
|
||||||
|
|
||||||
void IEC_Bus::ReadGPIOUserInput( int buttonCount)
|
void IEC_Bus::ReadGPIOUserInput()
|
||||||
{
|
{
|
||||||
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
|
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
|
||||||
if (IEC_Bus::rotaryEncoderEnable == true)
|
if (IEC_Bus::rotaryEncoderEnable == true)
|
||||||
{
|
{
|
||||||
int indexEnter = 0;
|
int indexEnter = InputMappings::INPUT_BUTTON_ENTER;
|
||||||
int indexUp = 1;
|
int indexUp = InputMappings::INPUT_BUTTON_UP;
|
||||||
int indexDown = 2;
|
int indexDown = InputMappings::INPUT_BUTTON_DOWN;
|
||||||
int indexBack = 3;
|
int indexBack = InputMappings::INPUT_BUTTON_BACK;
|
||||||
int indexInsert = 4;
|
int indexInsert = InputMappings::INPUT_BUTTON_INSERT;
|
||||||
|
|
||||||
//Poll the rotary encoder
|
//Poll the rotary encoder
|
||||||
//
|
//
|
||||||
|
@ -139,7 +142,7 @@ void IEC_Bus::ReadGPIOUserInput( int buttonCount)
|
||||||
void IEC_Bus::ReadBrowseMode(void)
|
void IEC_Bus::ReadBrowseMode(void)
|
||||||
{
|
{
|
||||||
gplev0 = read32(ARM_GPIO_GPLEV0);
|
gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||||
ReadGPIOUserInput(buttonCount);
|
ReadGPIOUserInput();
|
||||||
|
|
||||||
bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0);
|
bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0);
|
||||||
if (PI_Atn != ATNIn)
|
if (PI_Atn != ATNIn)
|
||||||
|
|
|
@ -199,7 +199,6 @@ enum PIGPIOMasks
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned ButtonPinFlags[5] = { PIGPIO_MASK_IN_BUTTON1, PIGPIO_MASK_IN_BUTTON2, PIGPIO_MASK_IN_BUTTON3, PIGPIO_MASK_IN_BUTTON4, PIGPIO_MASK_IN_BUTTON5 };
|
static const unsigned ButtonPinFlags[5] = { PIGPIO_MASK_IN_BUTTON1, PIGPIO_MASK_IN_BUTTON2, PIGPIO_MASK_IN_BUTTON3, PIGPIO_MASK_IN_BUTTON4, PIGPIO_MASK_IN_BUTTON5 };
|
||||||
static int buttonCount = sizeof(ButtonPinFlags) / sizeof(unsigned);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Original Non-split lines
|
// Original Non-split lines
|
||||||
|
@ -401,7 +400,7 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void UpdateButton(int index, unsigned gplev0)
|
static void UpdateButton(int index, unsigned gplev0)
|
||||||
{
|
{
|
||||||
bool inputcurrent = (gplev0 & ButtonPinFlags[index]) == 0;
|
bool inputcurrent = (gplev0 & ButtonPinFlags[index]) == 0;
|
||||||
|
|
||||||
|
@ -476,7 +475,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
static void ReadBrowseMode(void);
|
static void ReadBrowseMode(void);
|
||||||
static void ReadGPIOUserInput(int buttonCount);
|
static void ReadGPIOUserInput(void);
|
||||||
static void ReadEmulationMode1541(void);
|
static void ReadEmulationMode1541(void);
|
||||||
static void ReadEmulationMode1581(void);
|
static void ReadEmulationMode1581(void);
|
||||||
|
|
||||||
|
@ -739,6 +738,8 @@ private:
|
||||||
static bool SRQSetToOut;
|
static bool SRQSetToOut;
|
||||||
static bool Resetting;
|
static bool Resetting;
|
||||||
|
|
||||||
|
static int buttonCount;
|
||||||
|
|
||||||
static u32 myOutsGPFSEL0;
|
static u32 myOutsGPFSEL0;
|
||||||
static u32 myOutsGPFSEL1;
|
static u32 myOutsGPFSEL1;
|
||||||
static bool InputButton[5];
|
static bool InputButton[5];
|
||||||
|
|
|
@ -916,7 +916,7 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IEC_Bus::ReadGPIOUserInput(3);
|
IEC_Bus::ReadGPIOUserInput();
|
||||||
|
|
||||||
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
|
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
|
||||||
#if not defined(EXPERIMENTALZERO)
|
#if not defined(EXPERIMENTALZERO)
|
||||||
|
@ -1132,7 +1132,7 @@ EXIT_TYPE Emulate1581(FileBrowser* fileBrowser)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IEC_Bus::ReadGPIOUserInput(3);
|
IEC_Bus::ReadGPIOUserInput();
|
||||||
|
|
||||||
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
|
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
|
||||||
#if not defined(EXPERIMENTALZERO)
|
#if not defined(EXPERIMENTALZERO)
|
||||||
|
|
Loading…
Reference in a new issue