mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-02-08 02:30:30 +00:00
Sort Prodos folders
This commit is contained in:
parent
b7f9b73643
commit
1c53b291dd
@ -159,7 +159,7 @@ public class SHRPictureFile2 extends HiResImage
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println ("PIC unknown aux " + auxType);
|
||||
System.out.printf ("PIC unknown aux: %04X%n ", auxType);
|
||||
failureReason = "unknown PIC aux";
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,8 @@ public class AppleDisk implements Disk
|
||||
private ActionListener actionListenerList;
|
||||
private List<DiskAddress> blockList;
|
||||
|
||||
private WozFile wozFile;
|
||||
|
||||
private final boolean debug = false;
|
||||
|
||||
public AppleDisk (File file, int tracks, int sectors) throws FileFormatException
|
||||
@ -243,6 +245,7 @@ public class AppleDisk implements Disk
|
||||
|
||||
public AppleDisk (WozFile wozFile, int tracks, int sectors)
|
||||
{
|
||||
this.wozFile = wozFile;
|
||||
this.tracks = tracks;
|
||||
this.sectors = sectors;
|
||||
file = wozFile.file;
|
||||
@ -654,15 +657,21 @@ public class AppleDisk implements Disk
|
||||
if (path.startsWith (home))
|
||||
path = "~" + path.substring (home.length ());
|
||||
|
||||
text.append (String.format ("Path............ %s%n", path));
|
||||
text.append (String.format ("File name....... %s%n", file.getName ()));
|
||||
text.append (String.format ("File size....... %,d%n", file.length ()));
|
||||
text.append (String.format ("Tracks.......... %d%n", tracks));
|
||||
text.append (String.format ("Sectors......... %d%n", sectors));
|
||||
text.append (String.format ("Blocks.......... %,d%n", blocks));
|
||||
text.append (String.format ("Track size...... %,d%n", trackSize));
|
||||
text.append (String.format ("Sector size..... %d%n", sectorSize));
|
||||
text.append (String.format ("Interleave...... %d", interleave));
|
||||
text.append (String.format ("Path................. %s%n", path));
|
||||
text.append (String.format ("File name............ %s%n", file.getName ()));
|
||||
text.append (String.format ("File size............ %,d%n", file.length ()));
|
||||
text.append (String.format ("Tracks............... %d%n", tracks));
|
||||
text.append (String.format ("Sectors.............. %d%n", sectors));
|
||||
text.append (String.format ("Blocks............... %,d%n", blocks));
|
||||
text.append (String.format ("Track size........... %,d%n", trackSize));
|
||||
text.append (String.format ("Sector size.......... %d%n", sectorSize));
|
||||
text.append (String.format ("Interleave........... %d", interleave));
|
||||
|
||||
if (wozFile != null)
|
||||
{
|
||||
text.append ("\n\n");
|
||||
text.append (wozFile);
|
||||
}
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package com.bytezone.diskbrowser.gui;
|
||||
|
||||
/***********************************************************************************************
|
||||
* Contains a single instance of FileSystemTab, and any number of AppleDiskTab instances.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
***********************************************************************************************/
|
||||
|
||||
import java.awt.Dimension;
|
||||
@ -50,7 +50,6 @@ class CatalogPanel extends JTabbedPane
|
||||
private Font font;
|
||||
private FileSystemTab fileTab;
|
||||
private final List<AppleDiskTab> diskTabs = new ArrayList<AppleDiskTab> ();
|
||||
// private final DocumentCreatorFactory lister;
|
||||
private final DiskAndFileSelector selector = new DiskAndFileSelector ();
|
||||
private final RedoHandler redoHandler;
|
||||
private CloseTabAction closeTabAction;
|
||||
@ -390,7 +389,7 @@ class CatalogPanel extends JTabbedPane
|
||||
// if (evt.getKey ().equals (PreferencesDialog.prefsCatalogFont))
|
||||
// font = new Font (evt.getNewValue (), Font.PLAIN, font.getSize ());
|
||||
// if (evt.getKey ().equals (PreferencesDialog.prefsCatalogFontSize))
|
||||
// font = new Font (font.getFontName (),
|
||||
// font = new Font (font.getFontName (),
|
||||
// Font.PLAIN, Integer.parseInt (evt.getNewValue ()));
|
||||
// if (fileTab != null)
|
||||
// fileTab.setTreeFont (font);
|
||||
|
@ -24,6 +24,7 @@ class DataPanel extends JTabbedPane
|
||||
AssemblerPreferencesListener
|
||||
{
|
||||
private static final int TEXT_WIDTH = 65;
|
||||
private static final int BACKGROUND = 245;
|
||||
|
||||
JTextArea hexText;
|
||||
JTextArea disassemblyText;
|
||||
@ -70,6 +71,9 @@ class DataPanel extends JTabbedPane
|
||||
imagePane =
|
||||
new JScrollPane (imagePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
|
||||
imagePane.setBorder (null);
|
||||
|
||||
imagePane.getVerticalScrollBar ().setUnitIncrement (50);
|
||||
imagePane.getHorizontalScrollBar ().setUnitIncrement (25);
|
||||
|
||||
@ -321,7 +325,7 @@ class DataPanel extends JTabbedPane
|
||||
|
||||
public ImagePanel ()
|
||||
{
|
||||
this.setBackground (Color.gray);
|
||||
this.setBackground (new Color (BACKGROUND, BACKGROUND, BACKGROUND));
|
||||
}
|
||||
|
||||
private void setImage (BufferedImage image)
|
||||
|
@ -30,10 +30,10 @@ class FileSystemTab extends AbstractTab
|
||||
{
|
||||
File rootFolder;
|
||||
|
||||
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan,
|
||||
public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler redoHandler,
|
||||
Font font, DiskSelectedEvent diskEvent)
|
||||
{
|
||||
super (navMan, selector, font);
|
||||
super (redoHandler, selector, font);
|
||||
this.rootFolder = folder;
|
||||
|
||||
TreeBuilder tb = new TreeBuilder (folder);
|
||||
@ -52,7 +52,7 @@ class FileSystemTab extends AbstractTab
|
||||
}
|
||||
|
||||
if (diskEvent != null)
|
||||
navMan.diskSelected (diskEvent);
|
||||
redoHandler.diskSelected (diskEvent);
|
||||
else
|
||||
System.out.println ("No disk event");
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
// -----------------------------------------------------------------------------------//
|
||||
public class DiskReaderGCR extends DiskReader
|
||||
class DiskReaderGCR extends DiskReader
|
||||
// -----------------------------------------------------------------------------------//
|
||||
{
|
||||
static final int TAG_SIZE = 12;
|
||||
@ -26,7 +26,7 @@ public class DiskReaderGCR extends DiskReader
|
||||
// decode four disk bytes into three data bytes (174 * 3 + 2 = 524)
|
||||
while (true)
|
||||
{
|
||||
// ROL checksum
|
||||
// ROL checksum (also keep left-shifted hi bit)
|
||||
checksums[2] = (checksums[2] & 0xFF) << 1; // shift left
|
||||
if ((checksums[2] > 0xFF)) // check for overflow
|
||||
++checksums[2]; // set bit 0
|
||||
@ -64,29 +64,29 @@ public class DiskReaderGCR extends DiskReader
|
||||
byte b2 = (byte) (d2 | (d3 << 6));
|
||||
|
||||
// compare disk checksums with calculated checksums
|
||||
if ((checksums[0] & 0xFF) != (b0 & 0xFF) //
|
||||
|| (checksums[1] & 0xFF) != (b1 & 0xFF) //
|
||||
|| (checksums[2] & 0xFF) != (b2 & 0xFF))
|
||||
if ((byte) (checksums[0] & 0xFF) != b0 //
|
||||
|| (byte) (checksums[1] & 0xFF) != b1 //
|
||||
|| (byte) (checksums[2] & 0xFF) != b2)
|
||||
throw new DiskNibbleException ("Checksum failed");
|
||||
|
||||
return outBuffer;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private byte checksum (byte diskByte, int[] checksums, int a)
|
||||
private byte checksum (byte diskByte, int[] checksums, int current)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
int b = (a + 2) % 3;
|
||||
int val = (diskByte ^ checksums[b]) & 0xFF;
|
||||
checksums[a] += val; // prepare next checksum
|
||||
int prev = (current + 2) % 3;
|
||||
int val = (diskByte ^ checksums[prev]) & 0xFF;
|
||||
checksums[current] += val; // add to this checksum
|
||||
|
||||
if (checksums[b] > 0xFF) // is there a carry?
|
||||
if (checksums[prev] > 0xFF) // was there a carry last time?
|
||||
{
|
||||
++checksums[a]; // pass it on
|
||||
checksums[b] &= 0xFF; // back to 8 bits
|
||||
++checksums[current]; // add it to this checksum
|
||||
checksums[prev] &= 0xFF; // reset previous carry
|
||||
}
|
||||
|
||||
return (byte) val; // converted data byte
|
||||
return (byte) val; // converted data byte
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
@ -36,6 +36,7 @@ public class WozFile
|
||||
public final File file;
|
||||
|
||||
private Info info;
|
||||
private Meta meta;
|
||||
private int diskSectors;
|
||||
|
||||
private byte[] addressPrologue;
|
||||
@ -70,6 +71,8 @@ public class WozFile
|
||||
int ptr = 12;
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
validateChunk (buffer, ptr);
|
||||
|
||||
String chunkId = new String (buffer, ptr, 4);
|
||||
int size = val32 (buffer, ptr + 4);
|
||||
if (debug1)
|
||||
@ -80,7 +83,7 @@ public class WozFile
|
||||
case "INFO": // 60 bytes
|
||||
info = new Info (buffer, ptr);
|
||||
if (info.wozVersion >= 2)
|
||||
setSectors (info.bootSectorFormat == 2 ? 13 : 16);
|
||||
setPrologue (info.bootSectorFormat == 2 ? 13 : 16);
|
||||
break;
|
||||
case "TMAP": // 160 bytes
|
||||
tmap (buffer, ptr);
|
||||
@ -89,7 +92,7 @@ public class WozFile
|
||||
tracks = trks (buffer, ptr);
|
||||
break;
|
||||
case "META":
|
||||
meta (buffer, ptr, size);
|
||||
meta = new Meta (buffer, ptr, size);
|
||||
break;
|
||||
case "WRIT":
|
||||
break;
|
||||
@ -124,6 +127,33 @@ public class WozFile
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private boolean validateChunk (byte[] buffer, int ptr) throws DiskNibbleException
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
int size = val32 (buffer, ptr + 4);
|
||||
if (size <= 0 || size + ptr + 8 > buffer.length)
|
||||
{
|
||||
if (info != null)
|
||||
System.out.println (info);
|
||||
throw new DiskNibbleException (String.format ("Invalid chunk size: %08X%n", size));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int val = buffer[ptr + i] & 0xFF;
|
||||
if (val < 'A' || val > 'Z') // not uppercase ascii
|
||||
{
|
||||
if (info != null)
|
||||
System.out.println (info);
|
||||
throw new DiskNibbleException (
|
||||
String.format ("Invalid chunk name character: %02X%n", val));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public byte[] getDiskBuffer ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -160,7 +190,7 @@ public class WozFile
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private void setSectors (int diskSectors)
|
||||
private void setPrologue (int diskSectors)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
this.diskSectors = diskSectors;
|
||||
@ -174,27 +204,6 @@ public class WozFile
|
||||
ptr += 8;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private void meta (byte[] buffer, int ptr, int length)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
ptr += 8;
|
||||
|
||||
if (debug1)
|
||||
{
|
||||
String metaData = new String (buffer, ptr, length);
|
||||
String[] chunks = metaData.split ("\n");
|
||||
for (String chunk : chunks)
|
||||
{
|
||||
String[] parts = chunk.split ("\t");
|
||||
if (parts.length >= 2)
|
||||
System.out.printf ("%-20s %s%n", parts[0], parts[1]);
|
||||
else
|
||||
System.out.printf ("%-20s%n", parts[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private List<Track> trks (byte[] rawBuffer, int ptr)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -274,6 +283,16 @@ public class WozFile
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@Override
|
||||
public String toString ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
if (meta != null)
|
||||
return info.toString () + "\n\n" + meta.toString ();
|
||||
return info.toString ();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public static void main (String[] args)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -314,7 +333,9 @@ public class WozFile
|
||||
int requiredRam;
|
||||
int largestTrack;
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
Info (byte[] buffer, int ptr)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
wozVersion = val8 (buffer, ptr + 8);
|
||||
|
||||
@ -343,7 +364,7 @@ public class WozFile
|
||||
public String toString ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
StringBuilder text = new StringBuilder ("WOZ info:\n\n");
|
||||
|
||||
String diskTypeText = diskType == 1 ? "5.25" : "3.5";
|
||||
|
||||
@ -374,6 +395,46 @@ public class WozFile
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------//
|
||||
class Meta
|
||||
// -----------------------------------------------------------------------------------//
|
||||
{
|
||||
List<String> lines = new ArrayList<> ();
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
Meta (byte[] buffer, int ptr, int length)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
String dots = " ......................";
|
||||
String metaData = new String (buffer, ptr + 8, length);
|
||||
String[] chunks = metaData.split ("\n");
|
||||
for (String chunk : chunks)
|
||||
{
|
||||
String[] parts = chunk.split ("\t");
|
||||
if (parts.length >= 2)
|
||||
lines.add (String.format ("%-21.21s %s", parts[0] + dots, parts[1]));
|
||||
else
|
||||
lines.add (String.format ("%-21.21s", parts[0] + dots));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@Override
|
||||
public String toString ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
StringBuilder text = new StringBuilder ("WOZ meta:\n\n");
|
||||
|
||||
for (String line : lines)
|
||||
text.append (String.format ("%s%n", line));
|
||||
|
||||
if (text.length () > 0)
|
||||
text.deleteCharAt (text.length () - 1);
|
||||
|
||||
return text.toString ();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------//
|
||||
class Track implements Iterable<Sector>
|
||||
// -----------------------------------------------------------------------------------//
|
||||
@ -428,9 +489,9 @@ public class WozFile
|
||||
|
||||
if (addressPrologue == null) // WOZ1
|
||||
if (findNext (address16prologue, ptr) > 0)
|
||||
setSectors (16);
|
||||
setPrologue (16);
|
||||
else if (findNext (address13prologue, ptr) > 0)
|
||||
setSectors (13);
|
||||
setPrologue (13);
|
||||
else
|
||||
throw new DiskNibbleException ("No address prologue found");
|
||||
|
||||
|
@ -100,7 +100,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
{
|
||||
int storageType = buffer2[i] & 0x0F;
|
||||
int keyBlock = HexFormatter.unsignedShort (buffer2, i + 1);
|
||||
// int eof = HexFormatter.intValue (buffer2[i + 3], buffer2[i + 4], buffer2[i + 5]);
|
||||
int eof = HexFormatter.intValue (buffer2[i + 3], buffer2[i + 4], buffer2[i + 5]);
|
||||
addDataBlocks (storageType, keyBlock);
|
||||
}
|
||||
}
|
||||
@ -265,7 +265,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
else if (endOfFile == 0x4000 && auxType == 0x4000)
|
||||
file = new DoubleHiResImage (name, exactBuffer);
|
||||
else if (oneOf (endOfFile, 0x1FF8, 0x1FFF, 0x2000, 0x4000)
|
||||
&& oneOf (auxType, 0x1FFF, 0x2000, 0x4000))
|
||||
&& oneOf (auxType, 0x1FFF, 0x2000, 0x4000, 0x6000))
|
||||
file = new OriginalHiResImage (name, exactBuffer, auxType);
|
||||
else if (endOfFile == 38400 && name.startsWith ("LVL."))
|
||||
file = new LodeRunner (name, exactBuffer);
|
||||
|
@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
|
||||
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||
import com.bytezone.diskbrowser.applefile.BootSector;
|
||||
@ -31,6 +32,7 @@ public class ProdosDisk extends AbstractFormattedDisk
|
||||
|
||||
private final List<DirectoryHeader> headerEntries = new ArrayList<DirectoryHeader> ();
|
||||
protected VolumeDirectoryHeader vdh;
|
||||
private final DefaultMutableTreeNode volumeNode;
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
@ -56,7 +58,7 @@ public class ProdosDisk extends AbstractFormattedDisk
|
||||
bootSector = new BootSector (disk, buffer, "Prodos", da);
|
||||
|
||||
DefaultMutableTreeNode root = getCatalogTreeRoot ();
|
||||
DefaultMutableTreeNode volumeNode = new DefaultMutableTreeNode ("empty volume node");
|
||||
volumeNode = new DefaultMutableTreeNode ("empty volume node");
|
||||
root.add (volumeNode);
|
||||
|
||||
processDirectoryBlock (2, null, volumeNode);
|
||||
@ -73,6 +75,48 @@ public class ProdosDisk extends AbstractFormattedDisk
|
||||
else if (stillAvailable (da2))
|
||||
falseNegatives++;
|
||||
}
|
||||
|
||||
sort (volumeNode);
|
||||
((DefaultTreeModel) catalogTree.getModel ()).reload ();
|
||||
}
|
||||
|
||||
public void sort (DefaultMutableTreeNode node)
|
||||
{
|
||||
for (int base = 0; base < node.getChildCount (); base++)
|
||||
{
|
||||
DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) node.getChildAt (base);
|
||||
if (!baseNode.isLeaf ())
|
||||
{
|
||||
sort (baseNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
String childName = ((FileEntry) baseNode.getUserObject ()).name;
|
||||
DefaultMutableTreeNode smallestNode = null;
|
||||
String smallestName = childName;
|
||||
int smallestPos = -1;
|
||||
|
||||
for (int j = base + 1; j < node.getChildCount (); j++)
|
||||
{
|
||||
DefaultMutableTreeNode compareNode = (DefaultMutableTreeNode) node.getChildAt (j);
|
||||
if (!compareNode.isLeaf ())
|
||||
continue;
|
||||
|
||||
String compareName = ((FileEntry) compareNode.getUserObject ()).name;
|
||||
if (smallestName.compareToIgnoreCase (compareName) > 0)
|
||||
{
|
||||
smallestNode = compareNode;
|
||||
smallestName = compareName;
|
||||
smallestPos = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (smallestNode != null)
|
||||
{
|
||||
node.insert (baseNode, smallestPos);
|
||||
node.insert (smallestNode, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirectoryBlock (int block, FileEntry parent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user