more listeners, recognise deleted CPM files

This commit is contained in:
Denis Molony 2021-06-14 15:55:35 +10:00
parent 83d5be3f9f
commit 7d162a4baf
11 changed files with 45 additions and 38 deletions

View File

@ -26,7 +26,7 @@ class CPMCatalogSector extends AbstractSector
for (int i = 0; i <= 255; i += CATALOG_ENTRY_SIZE) for (int i = 0; i <= 255; i += CATALOG_ENTRY_SIZE)
{ {
if (buffer[i] == (byte) 0xE5) if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5)
break; break;
boolean readOnly = (buffer[i + 9] & 0x80) != 0; boolean readOnly = (buffer[i + 9] & 0x80) != 0;

View File

@ -18,6 +18,8 @@ import com.bytezone.diskbrowser.gui.DataSource;
public class CPMDisk extends AbstractFormattedDisk public class CPMDisk extends AbstractFormattedDisk
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
private static final int EMPTY_BYTE_VALUE = 0xE5;
private final Color green = new Color (0, 200, 0); private final Color green = new Color (0, 200, 0);
public final SectorType catalogSector = new SectorType ("Catalog", green); public final SectorType catalogSector = new SectorType ("Catalog", green);
@ -50,7 +52,7 @@ public class CPMDisk extends AbstractFormattedDisk
sectorTypesList.add (macSector); sectorTypesList.add (macSector);
sectorTypesList.add (otherSector); sectorTypesList.add (otherSector);
setEmptyByte ((byte) 0xE5); setEmptyByte ((byte) EMPTY_BYTE_VALUE);
// search for the version string // search for the version string
for (int i = 8; i >= 4; i -= 2) for (int i = 8; i >= 4; i -= 2)
@ -74,22 +76,28 @@ public class CPMDisk extends AbstractFormattedDisk
sectorTypes[da.getBlockNo ()] = catalogSector; sectorTypes[da.getBlockNo ()] = catalogSector;
byte[] buffer = disk.readBlock (da); byte[] buffer = disk.readBlock (da);
int b1 = buffer[0] & 0xFF; int b1 = buffer[0] & 0xFF;
int b2 = buffer[1] & 0xFF; int b2 = buffer[1] & 0xFF;
if (b1 == 0xE5)
if (b1 == EMPTY_BYTE_VALUE && b2 == EMPTY_BYTE_VALUE)
continue; continue;
if (b1 > 31)
if (b1 > 31 && b1 != EMPTY_BYTE_VALUE)
break; break;
if (b2 < 32 || (b2 > 126 && b2 != 0xE5))
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
break; break;
for (int i = 0; i < buffer.length; i += 32) for (int i = 0; i < buffer.length; i += 32)
{ {
b1 = buffer[i] & 0xFF; b1 = buffer[i] & 0xFF;
b2 = buffer[i + 1] & 0xFF; b2 = buffer[i + 1] & 0xFF;
if (b1 == 0xE5)
break; if (b1 == EMPTY_BYTE_VALUE) // deleted file??
if (b2 < 32 || (b2 > 126 && b2 != 0xE5)) continue;
if (b2 < 32 || (b2 > 126 && b2 != EMPTY_BYTE_VALUE))
break; break;
DirectoryEntry entry = new DirectoryEntry (this, buffer, i); DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
@ -111,9 +119,6 @@ public class CPMDisk extends AbstractFormattedDisk
} }
} }
// root.setUserObject (getCatalog ()); // override the disk's default display
// makeNodeVisible (rootNode.getFirstLeaf ());
volumeNode.setUserObject (getCatalog ()); volumeNode.setUserObject (getCatalog ());
makeNodeVisible (volumeNode.getFirstLeaf ()); makeNodeVisible (volumeNode.getFirstLeaf ());
} }
@ -147,6 +152,7 @@ public class CPMDisk extends AbstractFormattedDisk
{ {
if (fileEntries.size () > 0 && fileEntries.size () > fileNo) if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
return fileEntries.get (fileNo).getSectors (); return fileEntries.get (fileNo).getSectors ();
return null; return null;
} }
@ -224,13 +230,13 @@ public class CPMDisk extends AbstractFormattedDisk
byte[] buffer = disk.readBlock (3, sector); byte[] buffer = disk.readBlock (3, sector);
// check if entire sector is empty (everything == 0xE5) // check if entire sector is empty (everything == 0xE5)
if (bufferContainsAll (buffer, (byte) 0xE5)) if (bufferContainsAll (buffer, (byte) EMPTY_BYTE_VALUE))
break; break;
for (int i = 0; i < buffer.length; i += 32) for (int i = 0; i < buffer.length; i += 32)
{ {
int val = buffer[i] & 0xFF; int val = buffer[i] & 0xFF;
if (val == 0xE5) if (val == EMPTY_BYTE_VALUE)
break; break;
if (val > 31) if (val > 31)
@ -239,7 +245,7 @@ public class CPMDisk extends AbstractFormattedDisk
for (int j = 1; j <= 8; j++) for (int j = 1; j <= 8; j++)
{ {
val = buffer[i + j] & 0xFF; val = buffer[i + j] & 0xFF;
if (val < 32 || (val > 126 && val != 0xE5)) if (val < 32 || (val > 126 && val != EMPTY_BYTE_VALUE))
return false; return false;
} }
} }

View File

@ -77,9 +77,6 @@ class DirectoryEntry implements AppleFileSource
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
blocks.add (new AppleDiskAddress (disk, blockNumber + i)); blocks.add (new AppleDiskAddress (disk, blockNumber + i));
} }
// if (name.equals ("cp/m"))
// for (DiskAddress da : blocks)
// System.out.println (da);
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -32,6 +32,7 @@ public class DiskFactory
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
private static boolean debug = false; private static boolean debug = false;
private static final int DISK_800K = 819200; private static final int DISK_800K = 819200;
private static final int DISK_143K = 143360; private static final int DISK_143K = 143360;
private static final int DISK_116K = 116480; private static final int DISK_116K = 116480;

View File

@ -89,6 +89,9 @@ class CatalogPanel extends JTabbedPane implements RedoListener, SectorSelectionL
{ {
if (evt.getPropertyName ().equals ("RootDirectory")) if (evt.getPropertyName ().equals ("RootDirectory"))
rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ()); rootDirectoryChanged ((File) evt.getOldValue (), (File) evt.getNewValue ());
// else
// closeCurrentTab ();
// System.out.println (evt.getPropertyName ());
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -159,7 +162,6 @@ class CatalogPanel extends JTabbedPane implements RedoListener, SectorSelectionL
fileTab.replaceDisk (((AppleDiskTab) tab).disk); fileTab.replaceDisk (((AppleDiskTab) tab).disk);
} }
// called from CloseTabAction
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public void closeCurrentTab () public void closeCurrentTab ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -19,6 +19,7 @@ public class CloseTabAction extends AbstractAction
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
super ("Close Tab"); super ("Close Tab");
putValue (Action.SHORT_DESCRIPTION, "Close the current disk tab"); putValue (Action.SHORT_DESCRIPTION, "Close the current disk tab");
// putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("ctrl W")); // putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke ("ctrl W"));
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx (); int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();

View File

@ -90,7 +90,9 @@ public class DiskBrowser extends JFrame
// AboutAction aboutAction = new AboutAction (); // AboutAction aboutAction = new AboutAction ();
// HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel); // HideLayoutAction hideLayoutAction = new HideLayoutAction (this, layoutBorderPanel);
ShowFreeSectorsAction showFreeAction = new ShowFreeSectorsAction (); ShowFreeSectorsAction showFreeAction = new ShowFreeSectorsAction ();
CloseTabAction closeTabAction = new CloseTabAction (catalogPanel); CloseTabAction closeTabAction = new CloseTabAction (catalogPanel);
// closeTabAction.addPropertyChangeListener (catalogPanel);
hideCatalogAction.addPropertyChangeListener (this); hideCatalogAction.addPropertyChangeListener (this);
hideLayoutAction.addPropertyChangeListener (this); hideLayoutAction.addPropertyChangeListener (this);

View File

@ -9,7 +9,7 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
class DiskSelectedEvent extends EventObject class DiskSelectedEvent extends EventObject
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
private final FormattedDisk owner; private final FormattedDisk formattedDisk;
boolean redo; boolean redo;
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -17,14 +17,14 @@ class DiskSelectedEvent extends EventObject
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
super (source); super (source);
this.owner = disk; this.formattedDisk = disk;
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public FormattedDisk getFormattedDisk () public FormattedDisk getFormattedDisk ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
return owner; return formattedDisk;
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -32,14 +32,14 @@ class DiskSelectedEvent extends EventObject
public String toString () public String toString ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
return owner.getDisk ().getFile ().getAbsolutePath (); return formattedDisk.getDisk ().getFile ().getAbsolutePath ();
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public String toText () public String toText ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
return owner.getAbsolutePath (); return formattedDisk.getAbsolutePath ();
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -1,10 +0,0 @@
package com.bytezone.diskbrowser.gui;
import java.io.File;
// -----------------------------------------------------------------------------------//
public interface RootDirectoryChangeListener
// -----------------------------------------------------------------------------------//
{
public void rootDirectoryChanged (File oldRootFolder, File newRootFolder);
}

View File

@ -48,10 +48,10 @@ abstract class CatalogEntry implements AppleFileSource
name = HexFormatter.getString (entryBuffer, 1, entryBuffer[0] & 0x0F); name = HexFormatter.getString (entryBuffer, 1, entryBuffer[0] & 0x0F);
storageType = (entryBuffer[0] & 0xF0) >> 4; storageType = (entryBuffer[0] & 0xF0) >> 4;
created = Utility.getAppleDate (entryBuffer, 24); created = Utility.getAppleDate (entryBuffer, 0x18);
version = entryBuffer[28] & 0xFF; version = entryBuffer[0x1C] & 0xFF;
minVersion = entryBuffer[29] & 0xFF; minVersion = entryBuffer[0x1D] & 0xFF;
access = entryBuffer[30] & 0xFF; access = entryBuffer[0x1E] & 0xFF;
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -118,4 +118,12 @@ abstract class CatalogEntry implements AppleFileSource
return text.toString (); return text.toString ();
} }
// https://comp.sys.apple2.narkive.com/lOfvHRLD/prodos-storage-type-and-user-types
// Two previously unused bytes in each file's directory entry are now used to
// indicate the case of a filename. The bytes are at relative locations
// +$1C and +$1D in each directory entry, and were previously labeled version
// and min_version. Since ProDOS 8 never actually used these bytes for version
// checking (except in one case, discussed below), they are now used to store
// lowercase information. (In the Volume header, bytes +$1A and +$1B are used instead.)
} }

View File

@ -153,7 +153,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
resourceFork = new ResourceFork (disk.readBlocks (resourceBlocks)); resourceFork = new ResourceFork (disk.readBlocks (resourceBlocks));
if (!resourceFork.isValid ()) if (!resourceFork.isValid ())
System.out.printf ("Invalid Resource Fork: %s%n", name); System.out.printf ("Invalid Resource Fork: %s%n", getUniqueName ());
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//