From f5cdeb61cbe1605f3332a6927848535b494f3585 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sun, 3 Nov 2019 15:49:01 +1000 Subject: [PATCH] tidying --- .../diskbrowser/applefile/CharacterRom.java | 3 +- .../diskbrowser/applefile/Charset.java | 5 +- .../bytezone/diskbrowser/gui/DiskBrowser.java | 37 ++++++++-- .../gui/FileNodeSelectedEvent.java | 10 +++ .../diskbrowser/gui/FileSystemTab.java | 26 ++++++- .../bytezone/diskbrowser/gui/MenuHandler.java | 10 --- .../bytezone/diskbrowser/gui/TreeBuilder.java | 36 ++++++++++ .../diskbrowser/prodos/FileEntry.java | 59 ++++++++++++--- .../prodos/ProdosBitMapSector.java | 3 +- .../diskbrowser/prodos/ProdosDirectory.java | 22 ++++-- .../diskbrowser/prodos/ProdosDisk.java | 28 ++++---- .../diskbrowser/utilities/HexFormatter.java | 72 +++++++++++++++++++ .../diskbrowser/utilities/Utility.java | 22 ++++++ 13 files changed, 285 insertions(+), 48 deletions(-) diff --git a/src/com/bytezone/diskbrowser/applefile/CharacterRom.java b/src/com/bytezone/diskbrowser/applefile/CharacterRom.java index e47bd27..49deae3 100644 --- a/src/com/bytezone/diskbrowser/applefile/CharacterRom.java +++ b/src/com/bytezone/diskbrowser/applefile/CharacterRom.java @@ -11,6 +11,7 @@ public class CharacterRom extends CharacterList { private static final int charsX = 16; private static final int charsY = 6; + private static final int HEADER_LENGTH = 0x100; String description; List characters = new ArrayList<> (); @@ -19,7 +20,7 @@ public class CharacterRom extends CharacterList public CharacterRom (String name, byte[] buffer) // ---------------------------------------------------------------------------------// { - super (name, buffer, charsX, charsY, 256); + super (name, buffer, charsX, charsY, HEADER_LENGTH); description = new String (buffer, 16, 16); diff --git a/src/com/bytezone/diskbrowser/applefile/Charset.java b/src/com/bytezone/diskbrowser/applefile/Charset.java index 3e914bd..79727db 100755 --- a/src/com/bytezone/diskbrowser/applefile/Charset.java +++ b/src/com/bytezone/diskbrowser/applefile/Charset.java @@ -39,10 +39,11 @@ public class Charset extends CharacterList { DataBuffer dataBuffer = image.getRaster ().getDataBuffer (); int element = 0; + ptr += sizeY; // start at the end and move backwards - for (int i = sizeY - 1; i >= 0; i--) + for (int i = 0; i < sizeY; i++) { - int value = buffer[ptr + i] & 0xFF; + int value = buffer[--ptr] & 0xFF; for (int j = 0; j < sizeX; j++) { dataBuffer.setElem (element++, (value & 0x01) == 0 ? 0 : 0xFF); diff --git a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java index 2b1072a..dc2dcc8 100755 --- a/src/com/bytezone/diskbrowser/gui/DiskBrowser.java +++ b/src/com/bytezone/diskbrowser/gui/DiskBrowser.java @@ -14,8 +14,15 @@ import javax.swing.*; import com.bytezone.diskbrowser.duplicates.RootFolderData; +// -----------------------------------------------------------------------------------// public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitListener +// -----------------------------------------------------------------------------------// { + static long start; + static + { + start = System.currentTimeMillis (); + } private static String[] args; private static final String windowTitle = "Apple ][ Disk Browser"; private final Preferences prefs = Preferences.userNodeForPackage (this.getClass ()); @@ -26,9 +33,12 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi private final RootFolderData rootFolderData = new RootFolderData (); + // ---------------------------------------------------------------------------------// public DiskBrowser () + // ---------------------------------------------------------------------------------// { super (windowTitle); + System.out.printf ("Start Init: %,5d%n", System.currentTimeMillis () - start); if (args.length > 0 && "-reset".equals (args[0])) new WindowState (prefs).clear (); @@ -175,9 +185,12 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi // activate the highest panel now that the listeners are ready catalogPanel.activate (); + System.out.printf ("End Init : %,5d%n", System.currentTimeMillis () - start); } + // ---------------------------------------------------------------------------------// private JPanel addPanel (JComponent pane, String title, String location) + // ---------------------------------------------------------------------------------// { JPanel panel = new JPanel (new BorderLayout ()); panel.setBackground (Color.WHITE); @@ -187,27 +200,35 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi return panel; } + // ---------------------------------------------------------------------------------// @Override public void diskSelected (DiskSelectedEvent e) + // ---------------------------------------------------------------------------------// { setTitle (windowTitle + e.getFormattedDisk () == null ? "" : e.getFormattedDisk ().getName ()); } + // ---------------------------------------------------------------------------------// @Override public void quit (Preferences preferences) + // ---------------------------------------------------------------------------------// { windowSaver.saveWindow (); } + // ---------------------------------------------------------------------------------// @Override public void restore (Preferences preferences) + // ---------------------------------------------------------------------------------// { windowSaver = new WindowSaver (prefs, this, "DiskBrowser"); windowSaver.restoreWindow (); } + // ---------------------------------------------------------------------------------// public static void main (String[] args) + // ---------------------------------------------------------------------------------// { DiskBrowser.args = args; EventQueue.invokeLater (new Runnable () @@ -221,17 +242,15 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi }); } + // ---------------------------------------------------------------------------------// private static void setLookAndFeel () + // ---------------------------------------------------------------------------------// { try { + UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ()); if (MAC) - { - UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ()); System.setProperty ("apple.laf.useScreenMenuBar", "true"); - } - else - UIManager.setLookAndFeel ("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception e) { @@ -241,17 +260,23 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi List quitListeners = new ArrayList<> (); + // ---------------------------------------------------------------------------------// public void addQuitListener (QuitListener listener) + // ---------------------------------------------------------------------------------// { quitListeners.add (listener); } + // ---------------------------------------------------------------------------------// public void removeQuitListener (QuitListener listener) + // ---------------------------------------------------------------------------------// { quitListeners.remove (listener); } + // ---------------------------------------------------------------------------------// private void fireQuitEvent () + // ---------------------------------------------------------------------------------// { for (QuitListener listener : quitListeners) listener.quit (prefs); @@ -259,7 +284,9 @@ public class DiskBrowser extends JFrame implements DiskSelectionListener, QuitLi System.exit (0); } + // ---------------------------------------------------------------------------------// private void fireRestoreEvent () + // ---------------------------------------------------------------------------------// { for (QuitListener listener : quitListeners) listener.restore (prefs); diff --git a/src/com/bytezone/diskbrowser/gui/FileNodeSelectedEvent.java b/src/com/bytezone/diskbrowser/gui/FileNodeSelectedEvent.java index d8e3c4a..5d3307c 100644 --- a/src/com/bytezone/diskbrowser/gui/FileNodeSelectedEvent.java +++ b/src/com/bytezone/diskbrowser/gui/FileNodeSelectedEvent.java @@ -4,29 +4,39 @@ import java.util.EventObject; import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode; +// -----------------------------------------------------------------------------------// public class FileNodeSelectedEvent extends EventObject +// -----------------------------------------------------------------------------------// { private final FileNode node; boolean redo; + // ---------------------------------------------------------------------------------// public FileNodeSelectedEvent (Object source, FileNode node) + // ---------------------------------------------------------------------------------// { super (source); this.node = node; } + // ---------------------------------------------------------------------------------// public FileNode getFileNode () + // ---------------------------------------------------------------------------------// { return node; } + // ---------------------------------------------------------------------------------// @Override public String toString () + // ---------------------------------------------------------------------------------// { return node.file.getAbsolutePath (); } + // ---------------------------------------------------------------------------------// public String toText () + // ---------------------------------------------------------------------------------// { return node.file.getAbsolutePath (); } diff --git a/src/com/bytezone/diskbrowser/gui/FileSystemTab.java b/src/com/bytezone/diskbrowser/gui/FileSystemTab.java index 46c22ad..b28151e 100755 --- a/src/com/bytezone/diskbrowser/gui/FileSystemTab.java +++ b/src/com/bytezone/diskbrowser/gui/FileSystemTab.java @@ -19,19 +19,22 @@ import javax.swing.event.TreeWillExpandListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; import com.bytezone.diskbrowser.disk.DiskFactory; import com.bytezone.diskbrowser.disk.FormattedDisk; import com.bytezone.diskbrowser.gui.RedoHandler.RedoEvent; import com.bytezone.diskbrowser.gui.TreeBuilder.FileNode; +// -----------------------------------------------------------------------------------// class FileSystemTab extends AbstractTab +// -----------------------------------------------------------------------------------// { File rootFolder; + // ---------------------------------------------------------------------------------// public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler redoHandler, Font font, DiskSelectedEvent diskEvent) + // ---------------------------------------------------------------------------------// { super (redoHandler, selector, font); this.rootFolder = folder; @@ -57,22 +60,28 @@ class FileSystemTab extends AbstractTab System.out.println ("No disk event"); } + // ---------------------------------------------------------------------------------// public FileSystemTab (File folder, DiskAndFileSelector selector, RedoHandler navMan, Font font) + // ---------------------------------------------------------------------------------// { this (folder, selector, navMan, font, null); // default to first available disk } + // ---------------------------------------------------------------------------------// @Override public void activate () + // ---------------------------------------------------------------------------------// { tree.setSelectionPath (null); // turn off any current selection to force an event redoHandler.setCurrentData (redoData); } // connected to RefreshTreeAction + // ---------------------------------------------------------------------------------// @Override public void refresh () + // ---------------------------------------------------------------------------------// { String currentDiskName = ((FileNode) getSelectedObject ()).file.getAbsolutePath (); TreeBuilder tb = new TreeBuilder (rootFolder); @@ -82,7 +91,9 @@ class FileSystemTab extends AbstractTab setSelectionListener (tree); } + // ---------------------------------------------------------------------------------// void redoEvent (RedoEvent event) + // ---------------------------------------------------------------------------------// { DefaultMutableTreeNode node = null; if (event.type.equals ("FileNodeEvent")) @@ -103,7 +114,9 @@ class FileSystemTab extends AbstractTab System.out.println ("Disk node not found"); } + // ---------------------------------------------------------------------------------// void selectDisk (String path) + // ---------------------------------------------------------------------------------// { DefaultMutableTreeNode node = findNode (rootFolder.getAbsolutePath () + path); if (node != null) @@ -114,12 +127,16 @@ class FileSystemTab extends AbstractTab } } + // ---------------------------------------------------------------------------------// private DefaultMutableTreeNode findNode (String absolutePath) + // ---------------------------------------------------------------------------------// { return search (getRootNode (), absolutePath); } + // ---------------------------------------------------------------------------------// private DefaultMutableTreeNode search (DefaultMutableTreeNode node, String absolutePath) + // ---------------------------------------------------------------------------------// { FileNode fn = (FileNode) node.getUserObject (); @@ -153,7 +170,9 @@ class FileSystemTab extends AbstractTab return null; } + // ---------------------------------------------------------------------------------// public void replaceDisk (FormattedDisk disk) + // ---------------------------------------------------------------------------------// { // first check currently selected disk FileNode fn = (FileNode) getSelectedObject (); @@ -172,7 +191,9 @@ class FileSystemTab extends AbstractTab } } + // ---------------------------------------------------------------------------------// private void setSelectionListener (JTree tree) + // ---------------------------------------------------------------------------------// { tree.addTreeSelectionListener (new TreeSelectionListener () { @@ -195,9 +216,8 @@ class FileSystemTab extends AbstractTab @Override public void treeWillExpand (TreeExpansionEvent e) throws ExpandVetoException { - TreePath path = e.getPath (); DefaultMutableTreeNode node = - (DefaultMutableTreeNode) path.getLastPathComponent (); + (DefaultMutableTreeNode) e.getPath ().getLastPathComponent (); FileNode fn = (FileNode) node.getUserObject (); if (node.getChildCount () == 0) fn.readFiles (); diff --git a/src/com/bytezone/diskbrowser/gui/MenuHandler.java b/src/com/bytezone/diskbrowser/gui/MenuHandler.java index 6abb20b..0334ca5 100755 --- a/src/com/bytezone/diskbrowser/gui/MenuHandler.java +++ b/src/com/bytezone/diskbrowser/gui/MenuHandler.java @@ -252,16 +252,6 @@ public class MenuHandler interleaveGroup.add (interleave3Item); saveDiskItem.setAction (saveTempFileAction); - - // this is done early because the CatalogPanel creates the previous disk used - // before restore() is called - // what about all the other preferences??? - // prodosSortDirectoriesItem - // .setSelected (prefs.getBoolean (PREFS_PRODOS_SORT_DIRECTORIES, true)); - - // setBasicPreferences (); - // setAssemblerPreferences (); - // setProdosPreferences (); } private void setBasicPreferences () diff --git a/src/com/bytezone/diskbrowser/gui/TreeBuilder.java b/src/com/bytezone/diskbrowser/gui/TreeBuilder.java index 55d2bce..b8af6ab 100755 --- a/src/com/bytezone/diskbrowser/gui/TreeBuilder.java +++ b/src/com/bytezone/diskbrowser/gui/TreeBuilder.java @@ -19,14 +19,18 @@ import com.bytezone.diskbrowser.disk.FormattedDisk; import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.Utility; +// -----------------------------------------------------------------------------------// public class TreeBuilder +// -----------------------------------------------------------------------------------// { private static SimpleDateFormat sdf = new SimpleDateFormat ("dd MMM yyyy"); private final FileComparator fileComparator = new FileComparator (); private final JTree tree; + // ---------------------------------------------------------------------------------// public TreeBuilder (File rootFolder) + // ---------------------------------------------------------------------------------// { assert (rootFolder.exists ()); assert (rootFolder.isDirectory ()); @@ -43,12 +47,16 @@ public class TreeBuilder setDiskIcon ("/com/bytezone/diskbrowser/icons/disk.png"); } + // ---------------------------------------------------------------------------------// public JTree getTree () + // ---------------------------------------------------------------------------------// { return tree; } + // ---------------------------------------------------------------------------------// private void addFiles (DefaultMutableTreeNode parentNode, File directory) + // ---------------------------------------------------------------------------------// { File[] files = directory.listFiles (); if (files == null || files.length == 0) @@ -70,7 +78,9 @@ public class TreeBuilder } } + // ---------------------------------------------------------------------------------// private DefaultMutableTreeNode createNode (File file, boolean allowsChildren) + // ---------------------------------------------------------------------------------// { FileNode fileNode = new FileNode (file); DefaultMutableTreeNode newNode = new DefaultMutableTreeNode (fileNode); @@ -79,7 +89,9 @@ public class TreeBuilder return newNode; } + // ---------------------------------------------------------------------------------// private void setDiskIcon (String iconName) + // ---------------------------------------------------------------------------------// { URL url = this.getClass ().getResource (iconName); if (url != null) @@ -98,7 +110,9 @@ public class TreeBuilder /* * Class used to control the text displayed by the JTree. */ + // ---------------------------------------------------------------------------------// public class FileNode implements DataSource // why does it implement DataSource? + // ---------------------------------------------------------------------------------// { DefaultMutableTreeNode parentNode; public final File file; @@ -109,22 +123,30 @@ public class TreeBuilder int disks; boolean showDisks; + // -------------------------------------------------------------------------------// public FileNode (File file) + // -------------------------------------------------------------------------------// { this.file = file; } + // -------------------------------------------------------------------------------// public void setTreeNode (DefaultMutableTreeNode node) + // -------------------------------------------------------------------------------// { this.parentNode = node; } + // -------------------------------------------------------------------------------// public void readFiles () + // -------------------------------------------------------------------------------// { addFiles (parentNode, file); } + // -------------------------------------------------------------------------------// public FormattedDisk getFormattedDisk () + // -------------------------------------------------------------------------------// { if (formattedDisk == null) try @@ -140,7 +162,9 @@ public class TreeBuilder return formattedDisk; } + // -------------------------------------------------------------------------------// public boolean replaceDisk (FormattedDisk disk) + // -------------------------------------------------------------------------------// { String path = disk.getDisk ().getFile ().getAbsolutePath (); if (formattedDisk != null && path.equals (file.getAbsolutePath ())) @@ -151,8 +175,10 @@ public class TreeBuilder return false; } + // -------------------------------------------------------------------------------// @Override public String toString () + // -------------------------------------------------------------------------------// { String name = file.getName (); if (name.length () > MAX_NAME_LENGTH) @@ -163,8 +189,10 @@ public class TreeBuilder return name; } + // -------------------------------------------------------------------------------// @Override public String getText () + // -------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); @@ -200,26 +228,34 @@ public class TreeBuilder return text.toString (); } + // -------------------------------------------------------------------------------// @Override public String getAssembler () + // -------------------------------------------------------------------------------// { return null; } + // -------------------------------------------------------------------------------// @Override public String getHexDump () + // -------------------------------------------------------------------------------// { return null; } + // -------------------------------------------------------------------------------// @Override public BufferedImage getImage () + // -------------------------------------------------------------------------------// { return null; } + // -------------------------------------------------------------------------------// @Override public JComponent getComponent () + // -------------------------------------------------------------------------------// { return null; } diff --git a/src/com/bytezone/diskbrowser/prodos/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/FileEntry.java index 8d5c66e..9873239 100755 --- a/src/com/bytezone/diskbrowser/prodos/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/FileEntry.java @@ -16,7 +16,9 @@ import com.bytezone.diskbrowser.utilities.HexFormatter; // - Populate dataBlocks, indexBlocks, catalogBlock and masterIndexBlock // - Provide getDataSource () +// -----------------------------------------------------------------------------------// class FileEntry extends CatalogEntry implements ProdosConstants +// -----------------------------------------------------------------------------------// { private final int fileType; final int keyPtr; @@ -34,8 +36,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants private boolean invalid; private FileEntry link; + // ---------------------------------------------------------------------------------// public FileEntry (ProdosDisk fDisk, byte[] entryBuffer, DirectoryHeader parent, int parentBlock) + // ---------------------------------------------------------------------------------// { super (fDisk, entryBuffer); @@ -88,14 +92,16 @@ class FileEntry extends CatalogEntry implements ProdosConstants } } + // ---------------------------------------------------------------------------------// private void readForks () + // ---------------------------------------------------------------------------------// { parentDisk.setSectorType (keyPtr, parentDisk.extendedKeySector); indexBlocks.add (disk.getDiskAddress (keyPtr)); byte[] buffer2 = disk.readSector (keyPtr); // data fork and resource fork - // read 2 mini entries (data fork / resource fork) + // read 2 mini entries (data fork & resource fork) for (int i = 0; i < 512; i += 256) { int storageType = buffer2[i] & 0x0F; @@ -105,10 +111,12 @@ class FileEntry extends CatalogEntry implements ProdosConstants } } + // ---------------------------------------------------------------------------------// private void addDataBlocks (int storageType, int keyPtr) + // ---------------------------------------------------------------------------------// { DiskAddress emptyDiskAddress = disk.getDiskAddress (0); - List blocks = new ArrayList (); + List blocks = new ArrayList<> (); switch (storageType) { @@ -146,9 +154,11 @@ class FileEntry extends CatalogEntry implements ProdosConstants } } + // ---------------------------------------------------------------------------------// private List readIndex (int blockPtr) + // ---------------------------------------------------------------------------------// { - List blocks = new ArrayList (256); + List blocks = new ArrayList<> (256); if (blockPtr == 0) // master index contains a zero for (int i = 0; i < 256; i++) @@ -169,7 +179,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return blocks; } + // ---------------------------------------------------------------------------------// private List readMasterIndex (int keyPtr) + // ---------------------------------------------------------------------------------// { masterIndexBlock = disk.getDiskAddress (keyPtr); parentDisk.setSectorType (keyPtr, parentDisk.masterIndexSector); @@ -182,7 +194,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants if (buffer[highest] != 0 || buffer[highest + 0x100] != 0) break; - List blocks = new ArrayList (highest + 1); + List blocks = new ArrayList<> (highest + 1); for (int i = 0; i <= highest; i++) { int blockNo = (buffer[i] & 0xFF) | ((buffer[i + 256] & 0xFF) << 8); @@ -192,7 +204,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return blocks; } + // ---------------------------------------------------------------------------------// private boolean isValid (int blockNo) + // ---------------------------------------------------------------------------------// { if (false) { @@ -204,8 +218,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants return disk.isValidAddress (blockNo) && !parentDisk.isSectorFree (blockNo); } + // ---------------------------------------------------------------------------------// @Override public DataSource getDataSource () + // ---------------------------------------------------------------------------------// { if (file != null) return file; @@ -271,8 +287,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants file = new OriginalHiResImage (name, exactBuffer, auxType); else if (endOfFile == 38400 && name.startsWith ("LVL.")) file = new LodeRunner (name, exactBuffer); - else if (auxType == 0x1000 && endOfFile == 0x400 - && CharacterRom.isRom (exactBuffer)) + else if (auxType == 0x1000 && CharacterRom.isRom (exactBuffer)) file = new CharacterRom (name, exactBuffer); else if (auxType == 0 && endOfFile == 0x8000) { @@ -313,7 +328,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants break; case FILE_TYPE_DIRECTORY: - VolumeDirectoryHeader vdh = parentDisk.vdh; + VolumeDirectoryHeader vdh = parentDisk.getVolumeDirectoryHeader (); file = new ProdosDirectory (parentDisk, name, buffer, vdh.totalBlocks, vdh.freeBlocks, vdh.usedBlocks); break; @@ -432,7 +447,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return file; } + // ---------------------------------------------------------------------------------// private boolean oneOf (int val, int... values) + // ---------------------------------------------------------------------------------// { for (int value : values) if (val == value) @@ -440,7 +457,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return false; } + // ---------------------------------------------------------------------------------// private byte[] getExactBuffer (byte[] buffer) + // ---------------------------------------------------------------------------------// { byte[] exactBuffer; if (buffer.length < endOfFile) @@ -458,7 +477,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return exactBuffer; } + // ---------------------------------------------------------------------------------// private DataSource getRandomAccessTextFile () + // ---------------------------------------------------------------------------------// { // Text files with aux (reclen) > 0 are random access, possibly with // non-contiguous records, so they need to be handled differently @@ -477,7 +498,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants } } + // ---------------------------------------------------------------------------------// private DataSource getTreeTextFile () + // ---------------------------------------------------------------------------------// { List buffers = new ArrayList<> (); List addresses = new ArrayList<> (); @@ -508,7 +531,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return new TextFile (name, buffers, auxType, endOfFile); } + // ---------------------------------------------------------------------------------// private DataSource getSaplingTextFile () + // ---------------------------------------------------------------------------------// { List buffers = new ArrayList<> (); List addresses = new ArrayList<> (); @@ -520,7 +545,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return new TextFile (name, buffers, auxType, endOfFile); } + // ---------------------------------------------------------------------------------// private DataSource getSeedlingTextFile () + // ---------------------------------------------------------------------------------// { byte[] buffer = getBuffer (); if (endOfFile < buffer.length) @@ -536,7 +563,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants return new TextFile (name, buffer, auxType, endOfFile); } + // ---------------------------------------------------------------------------------// private byte[] getBuffer () + // ---------------------------------------------------------------------------------// { switch (storageType) { @@ -568,8 +597,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants } } + // ---------------------------------------------------------------------------------// private int readIndexBlock (int indexBlock, List addresses, List buffers, int logicalBlock) + // ---------------------------------------------------------------------------------// { byte[] indexBuffer = disk.readSector (indexBlock); for (int j = 0; j < 256; j++) @@ -586,11 +617,14 @@ class FileEntry extends CatalogEntry implements ProdosConstants } logicalBlock++; } + return logicalBlock; } + // ---------------------------------------------------------------------------------// @Override public List getSectors () + // ---------------------------------------------------------------------------------// { List sectors = new ArrayList<> (); sectors.add (catalogBlock); @@ -598,11 +632,14 @@ class FileEntry extends CatalogEntry implements ProdosConstants sectors.add (masterIndexBlock); sectors.addAll (indexBlocks); sectors.addAll (dataBlocks); + return sectors; } + // ---------------------------------------------------------------------------------// @Override public boolean contains (DiskAddress da) + // ---------------------------------------------------------------------------------// { if (da == null) return false; @@ -614,20 +651,26 @@ class FileEntry extends CatalogEntry implements ProdosConstants for (DiskAddress block : dataBlocks) if (da.matches (block)) return true; + return false; } - // called from ProdosDisk.processDirectoryBlock + // called from ProdosDisk.processDirectoryBlock, used to link DoubleHires image files + // ---------------------------------------------------------------------------------// void link (FileEntry fileEntry) + // ---------------------------------------------------------------------------------// { this.link = fileEntry; } + // ---------------------------------------------------------------------------------// @Override public String toString () + // ---------------------------------------------------------------------------------// { if (ProdosConstants.fileTypes[fileType].equals ("DIR")) return name; + String locked = (access == 0x00) ? "*" : " "; if (true) diff --git a/src/com/bytezone/diskbrowser/prodos/ProdosBitMapSector.java b/src/com/bytezone/diskbrowser/prodos/ProdosBitMapSector.java index 30ad274..a7a33a6 100755 --- a/src/com/bytezone/diskbrowser/prodos/ProdosBitMapSector.java +++ b/src/com/bytezone/diskbrowser/prodos/ProdosBitMapSector.java @@ -23,7 +23,8 @@ class ProdosBitMapSector extends AbstractSector // check range of bits for current block - so far I don't have a disk that needs // more than a single block - int relativeBlock = diskAddress.getBlock () - parent.vdh.bitMapBlock; + int relativeBlock = + diskAddress.getBlock () - parent.getVolumeDirectoryHeader ().bitMapBlock; int startBit = relativeBlock * 4096; // int endBit = startBit + 4096; if (startBit >= grid.width * grid.height) diff --git a/src/com/bytezone/diskbrowser/prodos/ProdosDirectory.java b/src/com/bytezone/diskbrowser/prodos/ProdosDirectory.java index 21ebab0..78d8c16 100755 --- a/src/com/bytezone/diskbrowser/prodos/ProdosDirectory.java +++ b/src/com/bytezone/diskbrowser/prodos/ProdosDirectory.java @@ -1,24 +1,31 @@ package com.bytezone.diskbrowser.prodos; +import java.text.SimpleDateFormat; import java.util.GregorianCalendar; import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.disk.FormattedDisk; import com.bytezone.diskbrowser.utilities.HexFormatter; +// -----------------------------------------------------------------------------------// class ProdosDirectory extends AbstractFile implements ProdosConstants +// -----------------------------------------------------------------------------------// { private static final String NO_DATE = ""; private static final String newLine = String.format ("%n"); private static final String newLine2 = newLine + newLine; + private static final SimpleDateFormat sdf = new SimpleDateFormat ("d-MMM-yy"); + private static final SimpleDateFormat stf = new SimpleDateFormat ("H:mm"); private final ProdosDisk parentFD; private final int totalBlocks; private final int freeBlocks; private final int usedBlocks; + // ---------------------------------------------------------------------------------// public ProdosDirectory (FormattedDisk parent, String name, byte[] buffer, int totalBlocks, int freeBlocks, int usedBlocks) + // ---------------------------------------------------------------------------------// { super (name, buffer); @@ -28,8 +35,10 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants this.usedBlocks = usedBlocks; } + // ---------------------------------------------------------------------------------// @Override public String getText () + // ---------------------------------------------------------------------------------// { StringBuffer text = new StringBuffer (); text.append ("Disk : " + parentFD.getDisplayPath () + newLine2); @@ -65,13 +74,12 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants GregorianCalendar created = HexFormatter.getAppleDate (buffer, i + 24); String dateC = created == null ? NO_DATE - : parentFD.sdf.format (created.getTime ()).toUpperCase ().replace (".", ""); - String timeC = created == null ? "" : parentFD.stf.format (created.getTime ()); + : sdf.format (created.getTime ()).toUpperCase ().replace (".", ""); + String timeC = created == null ? "" : stf.format (created.getTime ()); GregorianCalendar modified = HexFormatter.getAppleDate (buffer, i + 33); - String dateM = modified == null ? NO_DATE : parentFD.sdf - .format (modified.getTime ()).toUpperCase ().replace (".", ""); - String timeM = - modified == null ? "" : parentFD.stf.format (modified.getTime ()); + String dateM = modified == null ? NO_DATE + : sdf.format (modified.getTime ()).toUpperCase ().replace (".", ""); + String timeM = modified == null ? "" : stf.format (modified.getTime ()); int eof = HexFormatter.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]); int fileType = buffer[i + 16] & 0xFF; @@ -117,7 +125,9 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants return text.toString (); } + // ---------------------------------------------------------------------------------// private String convert (String name, int flags) + // ---------------------------------------------------------------------------------// { char[] newName = name.toCharArray (); for (int i = 0, weight = 0x8000; i < newName.length; i++, weight >>>= 1) diff --git a/src/com/bytezone/diskbrowser/prodos/ProdosDisk.java b/src/com/bytezone/diskbrowser/prodos/ProdosDisk.java index 40c417c..294dfe3 100755 --- a/src/com/bytezone/diskbrowser/prodos/ProdosDisk.java +++ b/src/com/bytezone/diskbrowser/prodos/ProdosDisk.java @@ -2,7 +2,6 @@ package com.bytezone.diskbrowser.prodos; import java.awt.Color; import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -25,8 +24,6 @@ public class ProdosDisk extends AbstractFormattedDisk static ProdosPreferences prodosPreferences; // set by MenuHandler final DateFormat df = DateFormat.getInstance (); - final SimpleDateFormat sdf = new SimpleDateFormat ("d-MMM-yy"); - final SimpleDateFormat stf = new SimpleDateFormat ("H:mm"); final SectorType dosSector = new SectorType ("Bootstrap Loader", Color.lightGray); final SectorType catalogSector = new SectorType ("Catalog", new Color (0, 200, 0)); @@ -38,9 +35,9 @@ public class ProdosDisk extends AbstractFormattedDisk final SectorType extendedKeySector = new SectorType ("Extended key", Color.gray); private final List headerEntries = new ArrayList<> (); - VolumeDirectoryHeader vdh; private final DefaultMutableTreeNode volumeNode; private final NodeComparator nodeComparator = new NodeComparator (); + private VolumeDirectoryHeader vdh; private static final boolean debug = false; @@ -129,15 +126,15 @@ public class ProdosDisk extends AbstractFormattedDisk case ProdosConstants.VOLUME_HEADER: assert headerEntries.size () == 0; vdh = new VolumeDirectoryHeader (this, entry); - localHeader = vdh; - assert localHeader.entryLength == ProdosConstants.ENTRY_SIZE; - headerEntries.add (localHeader); + assert vdh.entryLength == ProdosConstants.ENTRY_SIZE; + headerEntries.add (vdh); currentSectorType = catalogSector; if (!disk.isSectorEmpty (block)) sectorTypes[block] = currentSectorType; for (int i = 0; i < vdh.totalBitMapBlocks; i++) sectorTypes[vdh.bitMapBlock + i] = volumeMapSector; parentNode.setUserObject (vdh); // populate the empty volume node + localHeader = vdh; break; case ProdosConstants.SUBDIRECTORY_HEADER: @@ -197,11 +194,11 @@ public class ProdosDisk extends AbstractFormattedDisk } // ---------------------------------------------------------------------------------// - public boolean isReservedAddress (int blockNo) - // ---------------------------------------------------------------------------------// - { - return false; - } + // public boolean isReservedAddress (int blockNo) + // // ---------------------------------------------------------------------------------// + // { + // return false; + // } // ---------------------------------------------------------------------------------// public static boolean isCorrectFormat (AppleDisk disk) @@ -238,6 +235,13 @@ public class ProdosDisk extends AbstractFormattedDisk return true; } + // ---------------------------------------------------------------------------------// + VolumeDirectoryHeader getVolumeDirectoryHeader () + // ---------------------------------------------------------------------------------// + { + return vdh; + } + // ---------------------------------------------------------------------------------// public DataSource getFile (int fileNo) // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java index 55cd864..f39103f 100755 --- a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java +++ b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java @@ -4,45 +4,61 @@ import java.math.BigDecimal; import java.math.MathContext; import java.util.GregorianCalendar; +// -----------------------------------------------------------------------------------// public class HexFormatter +// -----------------------------------------------------------------------------------// { private static String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; private static MathContext mathContext = new MathContext (9); + // ---------------------------------------------------------------------------------// public static String format (byte[] buffer) + // ---------------------------------------------------------------------------------// { return format (buffer, 0, buffer.length); } + // ---------------------------------------------------------------------------------// public static String formatNoHeader (byte[] buffer) + // ---------------------------------------------------------------------------------// { return formatNoHeader (buffer, 0, buffer.length); } + // ---------------------------------------------------------------------------------// public static String format (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { return format (buffer, offset, length, true, 0); } + // ---------------------------------------------------------------------------------// public static String format (byte[] buffer, int offset, int length, int startingAddress) + // ---------------------------------------------------------------------------------// { return format (buffer, offset, length, true, startingAddress); } + // ---------------------------------------------------------------------------------// public static String formatNoHeader (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { return format (buffer, offset, length, false, 0); } + // ---------------------------------------------------------------------------------// public static String formatNoHeader (byte[] buffer, int offset, int length, int startingAddress) + // ---------------------------------------------------------------------------------// { return format (buffer, offset, length, false, startingAddress); } + // ---------------------------------------------------------------------------------// public static String format (byte[] buffer, int offset, int length, boolean header, int startingAddress) + // ---------------------------------------------------------------------------------// { StringBuilder line = new StringBuilder (); int[] freq = new int[256]; @@ -113,7 +129,9 @@ public class HexFormatter return line.toString (); } + // ---------------------------------------------------------------------------------// public static String sanitiseString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { StringBuilder trans = new StringBuilder (); for (int j = offset; j < offset + length; j++) @@ -136,12 +154,16 @@ public class HexFormatter return trans.toString (); } + // ---------------------------------------------------------------------------------// public static String getString (byte[] buffer) + // ---------------------------------------------------------------------------------// { return getString (buffer, 0, buffer.length); } + // ---------------------------------------------------------------------------------// public static String getString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); @@ -165,7 +187,9 @@ public class HexFormatter return text.toString (); } + // ---------------------------------------------------------------------------------// public static String getString2 (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { StringBuilder text = new StringBuilder (); @@ -193,17 +217,23 @@ public class HexFormatter return text.toString (); } + // ---------------------------------------------------------------------------------// public static String getHexString (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { return getHexString (buffer, offset, length, true); } + // ---------------------------------------------------------------------------------// public static String getHexString (byte[] buffer) + // ---------------------------------------------------------------------------------// { return getHexString (buffer, 0, buffer.length); } + // ---------------------------------------------------------------------------------// public static String getHexString (byte[] buffer, int offset, int length, boolean space) + // ---------------------------------------------------------------------------------// { StringBuilder hex = new StringBuilder (); int max = Math.min (offset + length, buffer.length); @@ -218,8 +248,10 @@ public class HexFormatter return hex.toString (); } + // ---------------------------------------------------------------------------------// public static String getHexStringReversed (byte[] buffer, int offset, int length, boolean space) + // ---------------------------------------------------------------------------------// { StringBuilder hex = new StringBuilder (); for (int i = length - 1; i >= 0; i--) @@ -233,14 +265,18 @@ public class HexFormatter return hex.toString (); } + // ---------------------------------------------------------------------------------// public static String getBitString (byte b) + // ---------------------------------------------------------------------------------// { String s = "0000000" + Integer.toBinaryString (b & 0xFF); s = s.replaceAll ("0", "."); return s.substring (s.length () - 8); } + // ---------------------------------------------------------------------------------// public static char byteValue (byte b) + // ---------------------------------------------------------------------------------// { int c = b & 0xFF; if (c > 127) @@ -253,7 +289,9 @@ public class HexFormatter } + // ---------------------------------------------------------------------------------// public static String format4 (int value) + // ---------------------------------------------------------------------------------// { if (value < 0) return "***err**"; @@ -270,12 +308,16 @@ public class HexFormatter return text.toString (); } + // ---------------------------------------------------------------------------------// public static String format3 (int value) + // ---------------------------------------------------------------------------------// { return format4 (value).substring (1); } + // ---------------------------------------------------------------------------------// public static String format2 (int value) + // ---------------------------------------------------------------------------------// { if (value < 0) value += 256; @@ -283,23 +325,31 @@ public class HexFormatter return text; } + // ---------------------------------------------------------------------------------// public static String format1 (int value) + // ---------------------------------------------------------------------------------// { String text = hex[value]; return text; } + // ---------------------------------------------------------------------------------// public static int intValue (byte b1, byte b2) + // ---------------------------------------------------------------------------------// { return (b1 & 0xFF) + (b2 & 0xFF) * 256; } + // ---------------------------------------------------------------------------------// public static int intValue (byte b1, byte b2, byte b3) + // ---------------------------------------------------------------------------------// { return (b1 & 0xFF) + (b2 & 0xFF) * 256 + (b3 & 0xFF) * 65536; } + // ---------------------------------------------------------------------------------// public static int unsignedLong (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { int val = 0; for (int i = 3; i >= 0; i--) @@ -310,13 +360,17 @@ public class HexFormatter return val; } + // ---------------------------------------------------------------------------------// public static int signedLong (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { return (((buffer[ptr] & 0xFF) << 24) | ((buffer[ptr] & 0xFF) << 16) | ((buffer[ptr] & 0xFF) << 8) | (buffer[ptr + 1] & 0xFF)); } + // ---------------------------------------------------------------------------------// public static int getLongBigEndian (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { int val = 0; for (int i = 0; i < 4; i++) @@ -327,7 +381,9 @@ public class HexFormatter return val; } + // ---------------------------------------------------------------------------------// public static int unsignedShort (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { if (ptr >= buffer.length) { @@ -337,7 +393,9 @@ public class HexFormatter return (buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8); } + // ---------------------------------------------------------------------------------// public static int signedShort (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { if (ptr >= buffer.length) { @@ -347,7 +405,9 @@ public class HexFormatter return (short) ((buffer[ptr] & 0xFF) | ((buffer[ptr + 1] & 0xFF) << 8)); } + // ---------------------------------------------------------------------------------// public static int getShortBigEndian (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { int val = 0; for (int i = 0; i < 2; i++) @@ -358,7 +418,9 @@ public class HexFormatter return val; } + // ---------------------------------------------------------------------------------// public static double getSANEDouble (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// { long bits = 0; for (int i = 7; i >= 0; i--) @@ -370,7 +432,9 @@ public class HexFormatter return Double.longBitsToDouble (bits); } + // ---------------------------------------------------------------------------------// public static double floatValueOld (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// { double val = 0; @@ -396,7 +460,9 @@ public class HexFormatter return val; } + // ---------------------------------------------------------------------------------// public static double floatValue (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { int exponent = buffer[ptr] & 0x7F; // biased 128 if (exponent == 0) @@ -415,7 +481,9 @@ public class HexFormatter return negative ? rounded * -1 : rounded; } + // ---------------------------------------------------------------------------------// public static GregorianCalendar getAppleDate (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// { int date = HexFormatter.intValue (buffer[offset], buffer[offset + 1]); if (date > 0) @@ -434,7 +502,9 @@ public class HexFormatter return null; } + // ---------------------------------------------------------------------------------// public static GregorianCalendar getPascalDate (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// { int year = (buffer[offset + 1] & 0xFF); int day = (buffer[offset] & 0xF0) >> 4; @@ -451,7 +521,9 @@ public class HexFormatter return new GregorianCalendar (year, month - 1, day); } + // ---------------------------------------------------------------------------------// public static String getPascalString (byte[] buffer, int offset) + // ---------------------------------------------------------------------------------// { int length = buffer[offset] & 0xFF; return HexFormatter.getString (buffer, offset + 1, length); diff --git a/src/com/bytezone/diskbrowser/utilities/Utility.java b/src/com/bytezone/diskbrowser/utilities/Utility.java index 47d42cc..f6f8b38 100644 --- a/src/com/bytezone/diskbrowser/utilities/Utility.java +++ b/src/com/bytezone/diskbrowser/utilities/Utility.java @@ -7,7 +7,9 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; +// -----------------------------------------------------------------------------------// public class Utility +// -----------------------------------------------------------------------------------// { public static final List suffixes = Arrays.asList ("po", "dsk", "do", "hdv", "2mg", "v2d", "d13", "sdk", "woz"); @@ -26,25 +28,33 @@ public class Utility // return false; // } + // ---------------------------------------------------------------------------------// public static boolean test (Graphics2D g) + // ---------------------------------------------------------------------------------// { return g.getFontRenderContext ().getTransform () .equals (AffineTransform.getScaleInstance (2.0, 2.0)); } + // ---------------------------------------------------------------------------------// static int getLong (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { return getWord (buffer, ptr) + getWord (buffer, ptr + 2) * 0x10000; } + // ---------------------------------------------------------------------------------// static int getWord (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { int a = (buffer[ptr + 1] & 0xFF) << 8; int b = buffer[ptr] & 0xFF; return a + b; } + // ---------------------------------------------------------------------------------// public static boolean find (byte[] buffer, byte[] key) + // ---------------------------------------------------------------------------------// { for (int i = 0; i < buffer.length; i++) { @@ -60,7 +70,9 @@ public class Utility return false; } + // ---------------------------------------------------------------------------------// public static LocalDateTime getDateTime (byte[] buffer, int ptr) + // ---------------------------------------------------------------------------------// { try { @@ -78,7 +90,9 @@ public class Utility } } + // ---------------------------------------------------------------------------------// public static boolean matches (byte[] buffer, int offset, byte[] key) + // ---------------------------------------------------------------------------------// { int ptr = 0; while (offset < buffer.length && ptr < key.length) @@ -88,12 +102,16 @@ public class Utility return true; } + // ---------------------------------------------------------------------------------// public static int getSuffixNo (String filename) + // ---------------------------------------------------------------------------------// { return suffixes.indexOf (getSuffix (filename)); } + // ---------------------------------------------------------------------------------// public static String getSuffix (String filename) + // ---------------------------------------------------------------------------------// { String lcFilename = filename.toLowerCase (); @@ -109,14 +127,18 @@ public class Utility return lcFilename.substring (dotPos + 1); } + // ---------------------------------------------------------------------------------// public static boolean validFileType (String filename) + // ---------------------------------------------------------------------------------// { if (filename.startsWith (".")) // ignore invisible files return false; return suffixes.contains (getSuffix (filename)); } + // ---------------------------------------------------------------------------------// public static int crc32 (byte[] buffer, int offset, int length) + // ---------------------------------------------------------------------------------// { int crc = 0xFFFFFFFF; // one's complement of zero int eof = offset + length;