diff --git a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java index ff3c7ed..61e7ecf 100755 --- a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java @@ -134,7 +134,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk case 1600: if (disk.getSectorsPerTrack () == 32) - gridLayout = new Dimension (32, 50); + gridLayout = new Dimension (disk.getSectorsPerTrack (), disk.getTotalTracks ()); else gridLayout = new Dimension (16, 100); break; diff --git a/src/com/bytezone/diskbrowser/disk/AppleDisk.java b/src/com/bytezone/diskbrowser/disk/AppleDisk.java index 8745d5d..a3015fd 100755 --- a/src/com/bytezone/diskbrowser/disk/AppleDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AppleDisk.java @@ -31,7 +31,7 @@ public class AppleDisk implements Disk private final byte[] diskBuffer; // contains the disk contents in memory private final int tracks; // usually 35 for floppy disks - private int sectors; // 8 or 16 + private int sectors; // 8 or 16 (or 32 for unidos) private int blocks; // 280 or 560 for floppy disks, higher for HD private final int trackSize; // 4096 @@ -84,9 +84,15 @@ public class AppleDisk implements Disk private WozFile wozFile; - private final boolean debug = true; + private final boolean debug = false; public AppleDisk (File file, int tracks, int sectors) throws FileFormatException + { + this (file, tracks, sectors, 0); + } + + public AppleDisk (File file, int tracks, int sectors, int skip) + throws FileFormatException { assert (file.exists ()) : "No such path :" + file.getAbsolutePath (); assert (!file.isDirectory ()) : "File is directory :" + file.getAbsolutePath (); @@ -100,7 +106,7 @@ public class AppleDisk implements Disk byte[] buffer = getPrefix (file); // HDV could be a 2mg String prefix = new String (buffer, 0, 4); - int skip = 0; + // int skip = 0; if (suffix.equalsIgnoreCase ("2mg") || "2IMG".equals (prefix)) { @@ -158,7 +164,7 @@ public class AppleDisk implements Disk } else if (suffix.equalsIgnoreCase ("HDV")) { - // this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8 + //this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8 this.blocks = tracks * sectors; this.sectorSize = 512; this.trackSize = sectors * sectorSize; diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index a377e7e..d395545 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -201,14 +201,17 @@ public class DiskFactory return disk; } - if (file.length () == 819200) + if (file.length () == 819200) // 800K 3.5" { if (debug) System.out.println ("UniDos ?"); // 2 x 400k disk images - AppleDisk appleDisk = new AppleDisk (file, 50, 32); - disk = checkUnidos (appleDisk); - return disk == null ? new DataDisk (appleDisk) : disk; + AppleDisk appleDisk1 = new AppleDisk (file, 50, 32); + AppleDisk appleDisk2 = new AppleDisk (file, 50, 32, 409600); + disk = checkUnidos (appleDisk1); + disk2 = checkUnidos (appleDisk2); + if (disk != null && disk2 != null) + return new DualDosDisk (disk, disk2); } if (debug) @@ -399,7 +402,7 @@ public class DiskFactory if (disk2 != null) disk = new DualDosDisk (disk, disk2); } - else if (checksum == 3028642627L // + else if (checksum == 3028642627L // || checksum == 2070151659L) // Enchanter { if (debug) diff --git a/src/com/bytezone/diskbrowser/disk/DualDosDisk.java b/src/com/bytezone/diskbrowser/disk/DualDosDisk.java index 85f2c7d..b0b914e 100755 --- a/src/com/bytezone/diskbrowser/disk/DualDosDisk.java +++ b/src/com/bytezone/diskbrowser/disk/DualDosDisk.java @@ -13,6 +13,7 @@ import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.gui.DataSource; // Apple Assembly Lines disks are dual-dos +// Should be renamed MultiVolumeDisk (and allow >2 volumes) public class DualDosDisk implements FormattedDisk { diff --git a/src/com/bytezone/diskbrowser/dos/DosDisk.java b/src/com/bytezone/diskbrowser/dos/DosDisk.java index 1e27af1..8ff5789 100755 --- a/src/com/bytezone/diskbrowser/dos/DosDisk.java +++ b/src/com/bytezone/diskbrowser/dos/DosDisk.java @@ -235,7 +235,6 @@ public class DosDisk extends AbstractFormattedDisk { disk.setInterleave (0); int catalogBlocks = checkFormat (disk); - System.out.printf ("Catalog blocks: %d%n", catalogBlocks); if (catalogBlocks > 3) return true; @@ -436,10 +435,10 @@ public class DosDisk extends AbstractFormattedDisk * There were actually three versions of DOS 3.3 that Apple released without bumping the version number: - + The first version that was released had FPBASIC and INTBASIC files that were 50 sectors in size. - + The second version of DOS 3.3, often referred to as “DOS 3.3e”, appeared at the time the Apple IIe was released. In this version, the FPBASIC and INTBASIC files were 42 sectors in size. The changes introduced at that time included code to turn @@ -447,12 +446,12 @@ public class DosDisk extends AbstractFormattedDisk command. This fix reportedly introduced an even worse bug, but as the command was not heavily used it did not make much of an impact on most programmers. The APPEND fix was applied by utilizing some formerly unused space in the DOS 3.3 code. - + The third version of DOS 3.3 appeared just before the first release of ProDOS. The only mention of this in the press was in the DOSTalk column of Softalk magazine. This final version of DOS 3.3 included a different fix for the APPEND bug, using another bit of unused space in DOS 3.3. - + With regard to the FPBASIC and INTBASIC files: There were three differences between the 50 sector and the 42 sector versions of the INTBASIC file. Firstly, the $F800-$FFFF section was removed. This area was the code for the Monitor, and with diff --git a/src/com/bytezone/diskbrowser/dos/DosVTOCSector.java b/src/com/bytezone/diskbrowser/dos/DosVTOCSector.java index 4c1f604..5eace16 100755 --- a/src/com/bytezone/diskbrowser/dos/DosVTOCSector.java +++ b/src/com/bytezone/diskbrowser/dos/DosVTOCSector.java @@ -34,7 +34,7 @@ class DosVTOCSector extends AbstractSector maxTracks = buffer[52] & 0xFF; maxSectors = buffer[53] & 0xFF; sectorSize = HexFormatter.intValue (buffer[54], buffer[55]); - flagSectors (); + flagSectors2 (); } @Override @@ -91,7 +91,7 @@ class DosVTOCSector extends AbstractSector else if (i == 124) extra = "(VTOC and Catalog)"; addText (text, buffer, i, 4, String.format ("Track %02X %s %s", - (i - firstSector) / 4, getBitmap (buffer[i], buffer[i + 1]), extra)); + (i - firstSector) / 4, getBitmap (buffer, i), extra)); } text.deleteCharAt (text.length () - 1); @@ -133,12 +133,10 @@ class DosVTOCSector extends AbstractSector String extra = ""; if (i == firstSector && bootSectorEmpty) extra = "(unusable)"; - // else if (i <= 64 && !bootSectorEmpty) - // extra = "(reserved for DOS)"; - // else if (i == 124) - // extra = "(VTOC and Catalog)"; - addText (text, buffer, i, 4, String.format ("Track %02X %s %s", - (i - firstSector) / 4, getBitmap (buffer[i], buffer[i + 1]), extra)); + String bits = getBitmap (buffer, i); + int track = (i - firstSector) / 4; + addText (text, buffer, i, 4, + String.format ("Track %02X %s %s", track, bits, extra)); } text.deleteCharAt (text.length () - 1); @@ -146,63 +144,112 @@ class DosVTOCSector extends AbstractSector return text.toString (); } - private String getBitmap (byte left, byte right) + // private String getBitmap (byte left, byte right) + // { + // StringBuilder text = new StringBuilder (); + // + // int base = maxSectors == 13 ? 3 : 0; + // right >>= base; + // + // for (int i = base; i < 8; i++) + // { + // if ((right & 0x01) == 1) + // text.append ("."); + // else + // text.append ("X"); + // right >>= 1; + // } + // + // for (int i = 0; i < 8; i++) + // { + // if ((left & 0x01) == 1) + // text.append ("."); + // else + // text.append ("X"); + // left >>= 1; + // } + // + // return text.toString (); + // } + + private String getBitmap (byte[] buffer, int offset) { - int base = maxSectors == 13 ? 3 : 0; - right >>= base; StringBuilder text = new StringBuilder (); - for (int i = base; i < 8; i++) - { - if ((right & 0x01) == 1) - text.append ("."); - else - text.append ("X"); - right >>= 1; - } - for (int i = 0; i < 8; i++) - { - if ((left & 0x01) == 1) - text.append ("."); - else - text.append ("X"); - left >>= 1; - } - return text.toString (); + int value = HexFormatter.getLongBigEndian (buffer, offset); + + String bits = "0000000000000000000000000000000" + Integer.toBinaryString (value); + bits = bits.substring (bits.length () - 32); + bits = bits.substring (0, maxSectors); + bits = bits.replace ('0', 'X'); + bits = bits.replace ('1', '.'); + text.append (bits); + + return text.reverse ().toString (); } - public void flagSectors () + private void flagSectors2 () { - int block = 0; - int base = maxSectors == 13 ? 3 : 0; int firstSector = 0x38; int max = maxTracks * 4 + firstSector; for (int i = firstSector; i < max; i += 4) { - block = check (buffer[i + 1], block, base); - block = check (buffer[i], block, 0); + int track = (i - firstSector) / 4; + String bits = getBitmap (buffer, i); + + // System.out.printf ("%08X %s%n", track, bits); + int blockNo = track * maxSectors; + char[] chars = bits.toCharArray (); + for (int sector = 0; sector < maxSectors; sector++) + { + // System.out.printf ("%3d %s%n", blockNo, chars[sector]); + if (chars[sector] == '.') + { + parentDisk.setSectorFree (blockNo, true); + ++freeSectors; + } + else + { + parentDisk.setSectorFree (blockNo, false); + ++usedSectors; + } + ++blockNo; + } } } - private int check (byte b, int block, int base) - { - b >>= base; - for (int i = base; i < 8; i++) - { - if ((b & 0x01) == 1) - { - parentDisk.setSectorFree (block, true); - ++freeSectors; - } - else - { - parentDisk.setSectorFree (block, false); - ++usedSectors; - } - block++; - b >>= 1; - } - return block; - } + // private void flagSectors () + // { + // int block = 0; + // int base = maxSectors == 13 ? 3 : 0; + // int firstSector = 0x38; + // int max = maxTracks * 4 + firstSector; + // for (int i = firstSector; i < max; i += 4) + // { + // block = check (buffer[i + 1], block, base); + // block = check (buffer[i], block, 0); + // } + // } + + // private int check (byte b, int block, int base) + // { + // b >>= base; + // for (int i = base; i < 8; i++) + // { + // if ((b & 0x01) == 1) + // { + // parentDisk.setSectorFree (block, true); + // ++freeSectors; + // } + // else + // { + // parentDisk.setSectorFree (block, false); + // ++usedSectors; + // } + // block++; + // b >>= 1; + // } + // return block; + // } // duplicate of DosCatalogSector.getName() private String getName (byte[] buffer, int offset)