From 455151abf746c6fabb9ef1e337592229119f82c0 Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Wed, 10 Jul 2024 13:34:09 -0500 Subject: [PATCH] #44: Tighter sector order detection, at least for prodos volumes. --- src/main/java/jace/hardware/FloppyDisk.java | 31 ++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/jace/hardware/FloppyDisk.java b/src/main/java/jace/hardware/FloppyDisk.java index be3c8c3..ca0acf5 100644 --- a/src/main/java/jace/hardware/FloppyDisk.java +++ b/src/main/java/jace/hardware/FloppyDisk.java @@ -118,13 +118,13 @@ public class FloppyDisk { */ public FloppyDisk(File diskFile) throws IOException { FileInputStream input = new FileInputStream(diskFile); - readDisk(input); + readDisk(input, diskFile.getName().toUpperCase().endsWith(".PO") ? SectorOrder.PRODOS : SectorOrder.DOS); writeProtected = !diskFile.canWrite(); diskPath = diskFile; } // brendanr: refactored to use input stream - public void readDisk(InputStream diskFile) throws IOException { + public void readDisk(InputStream diskFile, SectorOrder assumedOrder) throws IOException { isNibblizedImage = true; volumeNumber = CardDiskII.DEFAULT_VOLUME_NUMBER; headerLength = 0; @@ -154,7 +154,17 @@ public class FloppyDisk { } 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()); currentSectorOrder = sectorOrder.sectors; @@ -174,27 +184,22 @@ public class FloppyDisk { StateManager.markDirtyValue(currentSectorOrder); } - private SectorOrder detectSectorOrder(byte[] nibbles, SectorOrder defaultOrder) { - // Easiest way to tell sector order is see if we can parse a prodos volume at block 2 - int offset = 0x0400; - SectorOrder result = defaultOrder; + private boolean isProdosVolumeBlock(byte[] nibbles, int offset) { // First two bytes are zero (no previous block) 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 int nextBlock = (nibbles[offset+2] & 0x0ff) | (nibbles[offset+3] << 8); if (nextBlock == 1 || nextBlock == 2 || nextBlock > 280) { - return result; + return false; } // Now check total blocks at offset 0x29 int totalBlocks = (nibbles[offset+0x29] & 0x0ff) | (nibbles[offset+0x2a] << 8); if (totalBlocks != 280) { - System.out.println("Prodos detection failed: total blocks is not 280: " + totalBlocks); - return result; + return false; } - System.out.println("This disk appears to be Prodos-ordered."); - return SectorOrder.PRODOS; + return true; } /* * Convert a block-format disk to a 6-by-2 nibblized encoding scheme (raw NIB disk format)