#44: Tighter sector order detection, at least for prodos volumes.

This commit is contained in:
Brendan Robert 2024-07-10 13:34:09 -05:00
parent 9769f3282a
commit 455151abf7

View File

@ -118,13 +118,13 @@ public class FloppyDisk {
*/ */
public FloppyDisk(File diskFile) throws IOException { public FloppyDisk(File diskFile) throws IOException {
FileInputStream input = new FileInputStream(diskFile); FileInputStream input = new FileInputStream(diskFile);
readDisk(input); readDisk(input, diskFile.getName().toUpperCase().endsWith(".PO") ? SectorOrder.PRODOS : SectorOrder.DOS);
writeProtected = !diskFile.canWrite(); writeProtected = !diskFile.canWrite();
diskPath = diskFile; diskPath = diskFile;
} }
// brendanr: refactored to use input stream // brendanr: refactored to use input stream
public void readDisk(InputStream diskFile) throws IOException { public void readDisk(InputStream diskFile, SectorOrder assumedOrder) throws IOException {
isNibblizedImage = true; isNibblizedImage = true;
volumeNumber = CardDiskII.DEFAULT_VOLUME_NUMBER; volumeNumber = CardDiskII.DEFAULT_VOLUME_NUMBER;
headerLength = 0; headerLength = 0;
@ -154,7 +154,17 @@ public class FloppyDisk {
} }
if (sectorOrder == SectorOrder.UNKNOWN) { if (sectorOrder == SectorOrder.UNKNOWN) {
sectorOrder = detectSectorOrder(nibbles, SectorOrder.DOS); if (isProdosVolumeBlock(nibbles, 0x0400)) {
System.out.println("Prodos volume block found at 0x0400");
sectorOrder = SectorOrder.PRODOS;
} else if (isProdosVolumeBlock(nibbles, 0x0B00)) {
System.out.println("Prodos volume block found at 0x0A00");
sectorOrder = SectorOrder.DOS;
}
}
if (sectorOrder == SectorOrder.UNKNOWN) {
System.out.println("Assuming sector order based on file extension");
sectorOrder = assumedOrder;
} }
System.out.println(null == sectorOrder ? "Sector order is null" : "Sector order is " + sectorOrder.name()); System.out.println(null == sectorOrder ? "Sector order is null" : "Sector order is " + sectorOrder.name());
currentSectorOrder = sectorOrder.sectors; currentSectorOrder = sectorOrder.sectors;
@ -174,27 +184,22 @@ public class FloppyDisk {
StateManager.markDirtyValue(currentSectorOrder); StateManager.markDirtyValue(currentSectorOrder);
} }
private SectorOrder detectSectorOrder(byte[] nibbles, SectorOrder defaultOrder) { private boolean isProdosVolumeBlock(byte[] nibbles, int offset) {
// Easiest way to tell sector order is see if we can parse a prodos volume at block 2
int offset = 0x0400;
SectorOrder result = defaultOrder;
// First two bytes are zero (no previous block) // First two bytes are zero (no previous block)
if (nibbles[offset] != 0 || nibbles[offset+1] != 0) { if (nibbles[offset] != 0 || nibbles[offset+1] != 0) {
return result; return false;
} }
// Next two bytes are either both zero or at least in the range of 3...280 // Next two bytes are either both zero or at least in the range of 3...280
int nextBlock = (nibbles[offset+2] & 0x0ff) | (nibbles[offset+3] << 8); int nextBlock = (nibbles[offset+2] & 0x0ff) | (nibbles[offset+3] << 8);
if (nextBlock == 1 || nextBlock == 2 || nextBlock > 280) { if (nextBlock == 1 || nextBlock == 2 || nextBlock > 280) {
return result; return false;
} }
// Now check total blocks at offset 0x29 // Now check total blocks at offset 0x29
int totalBlocks = (nibbles[offset+0x29] & 0x0ff) | (nibbles[offset+0x2a] << 8); int totalBlocks = (nibbles[offset+0x29] & 0x0ff) | (nibbles[offset+0x2a] << 8);
if (totalBlocks != 280) { if (totalBlocks != 280) {
System.out.println("Prodos detection failed: total blocks is not 280: " + totalBlocks); return false;
return result;
} }
System.out.println("This disk appears to be Prodos-ordered."); return true;
return SectorOrder.PRODOS;
} }
/* /*
* Convert a block-format disk to a 6-by-2 nibblized encoding scheme (raw NIB disk format) * Convert a block-format disk to a 6-by-2 nibblized encoding scheme (raw NIB disk format)