debug output for prodos catalogs

This commit is contained in:
Denis Molony 2021-04-27 21:26:09 +10:00
parent 0032b0c2bb
commit bb1a7af6c8
21 changed files with 380 additions and 125 deletions

View File

@ -106,7 +106,6 @@ public abstract class AbstractFile implements DataSource
public JComponent getComponent ()
// ---------------------------------------------------------------------------------//
{
JPanel panel = new JPanel ();
return panel;
return new JPanel ();
}
}

View File

@ -1,19 +1,25 @@
package com.bytezone.diskbrowser.prodos;
package com.bytezone.diskbrowser.applefile;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.prodos.DirectoryHeader;
import com.bytezone.diskbrowser.prodos.ProdosConstants;
import com.bytezone.diskbrowser.prodos.ProdosDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
class ProdosDirectory extends AbstractFile implements ProdosConstants
public class ProdosDirectory extends AbstractFile implements ProdosConstants
// -----------------------------------------------------------------------------------//
{
static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy");
static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm");
static final String UNDERLINE = "--------------------------------------------------\n";
private static final String NO_DATE = "<NO DATE>";
private static final String newLine = String.format ("%n");
private static final String newLine2 = newLine + newLine;
private final ProdosDisk parentFD;
private final int totalBlocks;
@ -21,8 +27,8 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
private final int usedBlocks;
// ---------------------------------------------------------------------------------//
ProdosDirectory (FormattedDisk parent, String name, byte[] buffer, int totalBlocks,
int freeBlocks, int usedBlocks)
public ProdosDirectory (FormattedDisk parent, String name, byte[] buffer,
int totalBlocks, int freeBlocks, int usedBlocks)
// ---------------------------------------------------------------------------------//
{
super (name, buffer);
@ -38,8 +44,38 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
public String getText ()
// ---------------------------------------------------------------------------------//
{
StringBuffer text = new StringBuffer ();
text.append ("File : " + parentFD.getDisplayPath () + newLine2);
if (showDebugText)
return getDebugText ();
else
return getDirectoryText ();
}
// ---------------------------------------------------------------------------------//
private String getDebugText ()
// ---------------------------------------------------------------------------------//
{
List<DirectoryHeader> directoryHeaders = parentFD.getDirectoryHeaders ();
StringBuilder text = new StringBuilder ();
for (DirectoryHeader directoryHeader : directoryHeaders)
{
text.append (UNDERLINE);
text.append (directoryHeader.getText ());
text.append ("\n");
text.append (UNDERLINE);
directoryHeader.listFileEntries (text);
}
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private String getDirectoryText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
text.append ("File : " + parentFD.getDisplayPath () + "\n\n");
for (int i = 0; i < buffer.length; i += ENTRY_SIZE)
{
int storageType = (buffer[i] & 0xF0) >> 4;
@ -56,9 +92,9 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
case VOLUME_HEADER:
case SUBDIRECTORY_HEADER:
String root = storageType == VOLUME_HEADER ? "/" : "";
text.append (root + filename + newLine2);
text.append (root + filename + "\n\n");
text.append (" NAME TYPE BLOCKS "
+ "MODIFIED CREATED ENDFILE SUBTYPE" + newLine2);
+ "MODIFIED CREATED ENDFILE SUBTYPE" + "\n\n");
break;
case FREE:
@ -74,13 +110,13 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
LocalDateTime createdDate = Utility.getAppleDate (buffer, i + 24);
LocalDateTime modifiedDate = Utility.getAppleDate (buffer, i + 33);
String dateC = createdDate == null ? NO_DATE
: createdDate.format (ProdosDisk.df).toUpperCase ();
String dateM = modifiedDate == null ? NO_DATE
: modifiedDate.format (ProdosDisk.df).toUpperCase ();
String dateC =
createdDate == null ? NO_DATE : createdDate.format (df).toUpperCase ();
String dateM =
modifiedDate == null ? NO_DATE : modifiedDate.format (df).toUpperCase ();
String timeC = createdDate == null ? "" : createdDate.format (ProdosDisk.tf);
String timeM = modifiedDate == null ? "" : modifiedDate.format (ProdosDisk.tf);
String timeC = createdDate == null ? "" : createdDate.format (tf);
String timeM = modifiedDate == null ? "" : modifiedDate.format (tf);
int eof = Utility.intValue (buffer[i + 21], buffer[i + 22], buffer[i + 23]);
int fileType = buffer[i + 16] & 0xFF;
@ -102,7 +138,7 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
break;
case FILE_TYPE_AWP:
aux = Utility.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
aux = Utility.intValue (buffer[i + 32], buffer[i + 31]); // backwards!
if (aux != 0)
filename = convert (filename, aux);
break;
@ -117,12 +153,14 @@ class ProdosDirectory extends AbstractFile implements ProdosConstants
break;
default:
text.append (" <Unknown strage type : " + storageType + newLine);
text.append (" <Unknown strage type : " + storageType + "\n");
}
}
text.append (
String.format ("%nBLOCKS FREE:%5d BLOCKS USED:%5d TOTAL BLOCKS:%5d%n",
freeBlocks, usedBlocks, totalBlocks));
return text.toString ();
}

View File

@ -37,6 +37,8 @@ public class SegmentHeader
String loadname;
String segname;
boolean debug = false;
// ---------------------------------------------------------------------------------//
public SegmentHeader (byte[] buffer, int offset)
// ---------------------------------------------------------------------------------//
@ -79,7 +81,8 @@ public class SegmentHeader
else
segname = "not finished";
System.out.println (this);
if (debug)
System.out.println (this);
int ptr = offset + dispdata;
while (true)
@ -89,25 +92,33 @@ public class SegmentHeader
if (recType > 0 && recType <= 0xDF)
{
System.out.printf ("Const: %02X%n", recType);
System.out.println (HexFormatter.format (buffer, ptr, recType + 1, ptr));
if (debug)
{
System.out.printf ("Const: %02X%n", recType);
System.out.println (HexFormatter.format (buffer, ptr, recType + 1, ptr));
}
ptr += recType + 1;
continue;
}
System.out.printf ("%02X ", recType);
if (debug)
System.out.printf ("%02X ", recType);
switch (recType)
{
case 0x00: // END
System.out.println ("END");
if (debug)
System.out.println ("END");
break;
case 0xE0: // ALIGN
System.out.printf ("ALIGN:%n");
if (debug)
System.out.printf ("ALIGN:%n");
break;
case 0xE1: // ORG
System.out.printf ("ORG:%n");
if (debug)
System.out.printf ("ORG:%n");
break;
case 0xE2: // RELOC
@ -115,8 +126,9 @@ public class SegmentHeader
int bitShift = buffer[ptr + 2] & 0xFF;
int segmentOffset = Utility.getLong (buffer, ptr + 3);
int value = Utility.getLong (buffer, ptr + 7);
System.out.printf ("RELOC: %02X %02X %08X %08X%n", bytesRelocated, bitShift,
segmentOffset, value);
if (debug)
System.out.printf ("RELOC: %02X %02X %08X %08X%n", bytesRelocated, bitShift,
segmentOffset, value);
ptr += 11;
continue;
@ -127,72 +139,88 @@ public class SegmentHeader
int fileNo = Utility.getWord (buffer, ptr + 7);
int segNo = Utility.getWord (buffer, ptr + 9);
int subroutineOffset = Utility.getLong (buffer, ptr + 11);
System.out.printf ("INTERSEG: %02X %02X %08X %04X %04X %08X%n", count1, count2,
operandOffset, fileNo, segNo, subroutineOffset);
if (debug)
System.out.printf ("INTERSEG: %02X %02X %08X %04X %04X %08X%n", count1,
count2, operandOffset, fileNo, segNo, subroutineOffset);
ptr += 15;
break;
case 0xE4: // USING
System.out.printf ("USING:%n");
if (debug)
System.out.printf ("USING:%n");
break;
case 0xE5: // STRONG
System.out.printf ("STRONG:%n");
if (debug)
System.out.printf ("STRONG:%n");
break;
case 0xE6: // GLOBAL
System.out.printf ("GLOBAL:%n");
if (debug)
System.out.printf ("GLOBAL:%n");
break;
case 0xE7: // GEQU
System.out.printf ("GEQU:%n");
if (debug)
System.out.printf ("GEQU:%n");
break;
case 0xE8: // MEM
System.out.printf ("MEM:%n");
if (debug)
System.out.printf ("MEM:%n");
break;
case 0xEB: // EXPR
System.out.printf ("EXPR:%n");
if (debug)
System.out.printf ("EXPR:%n");
break;
case 0xEC: // ZEXPR
System.out.printf ("ZEXPR:%n");
if (debug)
System.out.printf ("ZEXPR:%n");
break;
case 0xED: // BEXPR
System.out.printf ("BEXPR:%n");
if (debug)
System.out.printf ("BEXPR:%n");
break;
case 0xEE: // RELEXPR
System.out.printf ("RELEXPR:%n");
if (debug)
System.out.printf ("RELEXPR:%n");
break;
case 0xEF: // LOCAL
System.out.printf ("LOCAL:%n");
if (debug)
System.out.printf ("LOCAL:%n");
break;
case 0xF0: // EQU
String label = HexFormatter.getPascalString (buffer, ptr + 1);
System.out.printf ("EQU: %s%n", label);
if (debug)
System.out.printf ("EQU: %s%n", label);
break;
case 0xF1: // DS
System.out.printf ("DS:%n");
if (debug)
System.out.printf ("DS:%n");
break;
case 0xF2: // LCONST
int constLength = Utility.getLong (buffer, ptr + 1);
System.out.printf ("Const: %04X%n", constLength);
if (debug)
System.out.printf ("Const: %04X%n", constLength);
ptr += constLength + 5;
continue;
case 0xF3: // LEXPR
System.out.printf ("LEXPR:%n");
if (debug)
System.out.printf ("LEXPR:%n");
break;
case 0xF4: // ENTRY
System.out.printf ("ENTRY:%n");
if (debug)
System.out.printf ("ENTRY:%n");
break;
case 0xF5: // cRELOC
@ -200,8 +228,9 @@ public class SegmentHeader
int cBitShift = buffer[ptr + 2] & 0xFF;
int cSegmentOffset = Utility.getWord (buffer, ptr + 3);
int cValue = Utility.getWord (buffer, ptr + 5);
System.out.printf ("cRELOC: %02X %02X %08X %08X%n", cBytesRelocated, cBitShift,
cSegmentOffset, cValue);
if (debug)
System.out.printf ("cRELOC: %02X %02X %08X %08X%n", cBytesRelocated,
cBitShift, cSegmentOffset, cValue);
ptr += 7;
continue;
@ -211,15 +240,17 @@ public class SegmentHeader
int cOperandOffset = Utility.getWord (buffer, ptr + 3);
int cSegNo = buffer[ptr + 5] & 0xFF;
int cSubroutineOffset = Utility.getWord (buffer, ptr + 6);
System.out.printf ("cINTERSEG: %02X %02X %04X %02X %04X%n", cCount1, cCount2,
cOperandOffset, cSegNo, cSubroutineOffset);
if (debug)
System.out.printf ("cINTERSEG: %02X %02X %04X %02X %04X%n", cCount1, cCount2,
cOperandOffset, cSegNo, cSubroutineOffset);
ptr += 8;
continue;
case 0xF7: // SUPER
int superLength = Utility.getLong (buffer, ptr + 1);
int recordType = buffer[ptr + 5] & 0xFF;
System.out.printf ("Super type %02X%n", recordType);
if (debug)
System.out.printf ("Super type %02X%n", recordType);
ptr += superLength + 5;
continue;
@ -228,7 +259,8 @@ public class SegmentHeader
break;
}
System.out.println ();
if (debug)
System.out.println ();
break;
}
}
@ -258,33 +290,18 @@ public class SegmentHeader
kindPrivate = (segAttr & 0x40) != 0;
kindStatic = (segAttr & 0x80) == 0;
switch (segType)
kindWhereText = switch (segType)
{
case 0:
kindWhereText = "Code Segment";
break;
case 1:
kindWhereText = "Data Segment";
break;
case 2:
kindWhereText = "Jump Table Segment";
break;
case 4:
kindWhereText = "Pathname Segment";
break;
case 8:
kindWhereText = "Library Dictionary Segment";
break;
case 0x10:
kindWhereText = "Initialization Segment";
break;
case 0x11:
kindWhereText = "Absolute Bank Segment";
break;
case 0x12:
kindWhereText = "Direct Page / Stack Segment";
break;
}
case 0x00 -> "Code Segment";
case 0x01 -> "Data Segment";
case 0x02 -> "Jump Table Segment";
case 0x04 -> "Pathname Segment";
case 0x08 -> "Library Dictionary Segment";
case 0x10 -> "Initialization Segment";
case 0x11 -> "Absolute Bank Segment";
case 0x12 -> "Direct Page / Stack Segment";
default -> "Unknown";
};
}
// ---------------------------------------------------------------------------------//

View File

@ -169,15 +169,11 @@ public class DiskFactory
suffix = "dsk";
compressed = true;
}
catch (IOException e)
catch (Exception e)
{
e.printStackTrace ();
return null;
}
catch (FileFormatException e)
{
return null;
}
}
FormattedDisk disk = null;

View File

@ -6,6 +6,7 @@ public class TextPreferences
{
public boolean showTextOffsets;
public boolean showHeader = true;
public boolean merlinFormat = true;
// ---------------------------------------------------------------------------------//
@Override
@ -15,7 +16,8 @@ public class TextPreferences
StringBuilder text = new StringBuilder ();
text.append (String.format ("Show offsets .......... %s%n", showTextOffsets));
text.append (String.format ("Show header ........... %s", showHeader));
text.append (String.format ("Show header ........... %s%n", showHeader));
text.append (String.format ("Show .S as Merlin ..... %s", merlinFormat));
return text.toString ();
}

View File

@ -18,6 +18,9 @@ abstract class CatalogEntry implements AppleFileSource
Disk disk;
ProdosDisk parentDisk;
int blockNo;
int entryNo;
String name;
int storageType;
@ -30,11 +33,13 @@ abstract class CatalogEntry implements AppleFileSource
DirectoryHeader parentDirectory;
// ---------------------------------------------------------------------------------//
CatalogEntry (ProdosDisk parentDisk, byte[] entryBuffer)
CatalogEntry (ProdosDisk parentDisk, byte[] entryBuffer, int blockNo, int entryNo)
// ---------------------------------------------------------------------------------//
{
this.parentDisk = parentDisk;
this.disk = parentDisk.getDisk ();
this.blockNo = blockNo;
this.entryNo = entryNo;
name = HexFormatter.getString (entryBuffer, 1, entryBuffer[0] & 0x0F);
storageType = (entryBuffer[0] & 0xF0) >> 4;
@ -45,6 +50,20 @@ abstract class CatalogEntry implements AppleFileSource
access = entryBuffer[30] & 0xFF;
}
// ---------------------------------------------------------------------------------//
public String getName ()
// ---------------------------------------------------------------------------------//
{
return name;
}
// ---------------------------------------------------------------------------------//
public String getText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%04X:%02X %-15s %02X", blockNo, entryNo, name, storageType);
}
// ---------------------------------------------------------------------------------//
@Override
public String getUniqueName ()

View File

@ -3,7 +3,7 @@ package com.bytezone.diskbrowser.prodos;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
abstract class DirectoryHeader extends CatalogEntry
public abstract class DirectoryHeader extends CatalogEntry
// -----------------------------------------------------------------------------------//
{
final int entryLength;
@ -11,13 +11,55 @@ abstract class DirectoryHeader extends CatalogEntry
final int fileCount;
// ---------------------------------------------------------------------------------//
DirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer)
DirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer, int blockNo, int entryNo)
// ---------------------------------------------------------------------------------//
{
super (parentDisk, entryBuffer);
super (parentDisk, entryBuffer, blockNo, entryNo);
entryLength = entryBuffer[31] & 0xFF;
entriesPerBlock = entryBuffer[32] & 0xFF;
fileCount = Utility.intValue (entryBuffer[33], entryBuffer[34]);
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%s %04X", super.getText (), fileCount);
}
// ---------------------------------------------------------------------------------//
public void listFileEntries (StringBuilder text)
// ---------------------------------------------------------------------------------//
{
int blockNo = this.blockNo;
do
{
byte[] buffer = disk.readBlock (blockNo);
int ptr = 4;
int entryNo = 1;
for (int i = 0; i < 13; i++)
{
int nameLength = buffer[ptr] & 0x0F;
int storageType = (buffer[ptr] & 0xF0) >>> 4;
if (nameLength > 0 && storageType < 0x0E)
{
String name = new String (buffer, ptr + 1, nameLength);
int blocksUsed = Utility.intValue (buffer[ptr + 0x13], buffer[ptr + 0x14]);
int fileType = buffer[ptr + 0x10] & 0xFF;
int keyPointer = Utility.intValue (buffer[ptr + 0x11], buffer[ptr + 0x12]);
int headerPointer = Utility.intValue (buffer[ptr + 0x25], buffer[ptr + 0x26]);
text.append (String.format ("%04X:%02X %-15s %02X %04X %02X %04X %04X%n",
blockNo, entryNo, name, storageType, blocksUsed, fileType, keyPointer,
headerPointer));
}
ptr += 0x27;
++entryNo;
}
blockNo = Utility.intValue (buffer[2], buffer[3]);
} while (blockNo != 0);
}
}

View File

@ -28,6 +28,7 @@ import com.bytezone.diskbrowser.applefile.MerlinSource;
import com.bytezone.diskbrowser.applefile.ObjectModule;
import com.bytezone.diskbrowser.applefile.OriginalHiResImage;
import com.bytezone.diskbrowser.applefile.PascalArea;
import com.bytezone.diskbrowser.applefile.ProdosDirectory;
import com.bytezone.diskbrowser.applefile.QuickDrawFont;
import com.bytezone.diskbrowser.applefile.SHRPictureFile1;
import com.bytezone.diskbrowser.applefile.SHRPictureFile2;
@ -69,10 +70,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants
// ---------------------------------------------------------------------------------//
FileEntry (ProdosDisk fDisk, byte[] entryBuffer, DirectoryHeader parent,
int parentBlock)
int parentBlock, int entryNo)
// ---------------------------------------------------------------------------------//
{
super (fDisk, entryBuffer);
super (fDisk, entryBuffer, parentBlock, entryNo);
assert parent != null;
this.parentDirectory = parent;
@ -547,6 +548,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
file = new ErrorMessageFile (name, buffer, e);
e.printStackTrace ();
}
return file;
}

View File

@ -1,5 +1,7 @@
package com.bytezone.diskbrowser.prodos;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.ENTRY_SIZE;
import java.awt.Color;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
@ -29,7 +31,6 @@ public class ProdosDisk extends AbstractFormattedDisk
{
static ProdosPreferences prodosPreferences; // set by MenuHandler
// final DateFormat df = DateFormat.getInstance ();
static final DateTimeFormatter df = DateTimeFormatter.ofPattern ("d-LLL-yy");
static final DateTimeFormatter tf = DateTimeFormatter.ofPattern ("H:mm");
@ -119,7 +120,7 @@ public class ProdosDisk extends AbstractFormattedDisk
sectorTypes[block] = currentSectorType;
int max = disk.getBlockSize () - ProdosConstants.ENTRY_SIZE;
for (int ptr = 4; ptr < max; ptr += ProdosConstants.ENTRY_SIZE)
for (int ptr = 4, entryNo = 0; ptr < max; ptr += ENTRY_SIZE, entryNo++)
{
int storageType = (sectorBuffer[ptr] & 0xF0) >> 4;
if (storageType == 0) // deleted or unused
@ -145,7 +146,7 @@ public class ProdosDisk extends AbstractFormattedDisk
break;
case ProdosConstants.SUBDIRECTORY_HEADER:
localHeader = new SubDirectoryHeader (this, entry, parent);
localHeader = new SubDirectoryHeader (this, entry, parent, block);
headerEntries.add (localHeader);
currentSectorType = subcatalogSector;
if (!disk.isBlockEmpty (block))
@ -153,7 +154,8 @@ public class ProdosDisk extends AbstractFormattedDisk
break;
case ProdosConstants.SUBDIRECTORY:
FileEntry fileEntry = new FileEntry (this, entry, localHeader, block);
FileEntry fileEntry =
new FileEntry (this, entry, localHeader, block, entryNo);
fileEntries.add (fileEntry);
DefaultMutableTreeNode directoryNode = new DefaultMutableTreeNode (fileEntry);
directoryNode.setAllowsChildren (true);
@ -166,7 +168,7 @@ public class ProdosDisk extends AbstractFormattedDisk
case ProdosConstants.TREE:
case ProdosConstants.PASCAL_ON_PROFILE:
case ProdosConstants.GSOS_EXTENDED_FILE:
fileEntry = new FileEntry (this, entry, localHeader, block);
fileEntry = new FileEntry (this, entry, localHeader, block, entryNo);
fileEntries.add (fileEntry);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (fileEntry);
node.setAllowsChildren (false);
@ -200,13 +202,6 @@ public class ProdosDisk extends AbstractFormattedDisk
}
}
// ---------------------------------------------------------------------------------//
// public boolean isReservedAddress (int blockNo)
// // ---------------------------------------------------------------------------------//
// {
// return false;
// }
// ---------------------------------------------------------------------------------//
public static boolean isCorrectFormat (AppleDisk disk)
// ---------------------------------------------------------------------------------//
@ -242,6 +237,13 @@ public class ProdosDisk extends AbstractFormattedDisk
return true;
}
// ---------------------------------------------------------------------------------//
public List<DirectoryHeader> getDirectoryHeaders ()
// ---------------------------------------------------------------------------------//
{
return headerEntries;
}
// ---------------------------------------------------------------------------------//
VolumeDirectoryHeader getVolumeDirectoryHeader ()
// ---------------------------------------------------------------------------------//
@ -255,6 +257,7 @@ public class ProdosDisk extends AbstractFormattedDisk
{
if (fileNo == 0)
return volumeDirectoryHeader.getDataSource ();
return fileEntries.get (fileNo - 1).getDataSource ();
}

View File

@ -4,22 +4,27 @@ import java.util.List;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.Utility;
import com.bytezone.diskbrowser.utilities.Utility;;
// -----------------------------------------------------------------------------------//
class SubDirectoryHeader extends DirectoryHeader
public class SubDirectoryHeader extends DirectoryHeader
// -----------------------------------------------------------------------------------//
{
private final int parentPointer;
private final int parentSequence;
private final int parentSize;
private final int blockNo;
// ---------------------------------------------------------------------------------//
SubDirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer, FileEntry parent)
SubDirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer, FileEntry parent,
int blockNo)
// ---------------------------------------------------------------------------------//
{
super (parentDisk, entryBuffer);
super (parentDisk, entryBuffer, blockNo, 1);
this.parentDirectory = parent.parentDirectory;
this.blockNo = blockNo;
parentPointer = Utility.intValue (entryBuffer[35], entryBuffer[36]);
parentSequence = entryBuffer[37] & 0xFF;
@ -46,6 +51,22 @@ class SubDirectoryHeader extends DirectoryHeader
return null;
}
// ---------------------------------------------------------------------------------//
public int getBlockNo ()
// ---------------------------------------------------------------------------------//
{
return blockNo;
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%s %04X:%02X", super.getText (), parentPointer,
parentSequence);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -1,14 +1,17 @@
package com.bytezone.diskbrowser.prodos;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.BLOCK_SIZE;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.applefile.ProdosDirectory;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
class VolumeDirectoryHeader extends DirectoryHeader
public class VolumeDirectoryHeader extends DirectoryHeader
// -----------------------------------------------------------------------------------//
{
protected final int bitMapBlock;
@ -21,15 +24,12 @@ class VolumeDirectoryHeader extends DirectoryHeader
VolumeDirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer)
// ---------------------------------------------------------------------------------//
{
super (parentDisk, entryBuffer);
super (parentDisk, entryBuffer, 2, 1);
bitMapBlock = Utility.unsignedShort (entryBuffer, 35);
totalBlocks = Utility.unsignedShort (entryBuffer, 37);
// if (totalBlocks == 0xFFFF || totalBlocks == 0x7FFF)
// totalBlocks = (int) disk.getFile ().length () / 4096 * 8;// ignore extra bytes
totalBitMapBlocks = (totalBlocks - 1) / 512 + 1;
totalBitMapBlocks = (totalBlocks - 1) / BLOCK_SIZE + 1;
int block = 2;
do
@ -90,7 +90,7 @@ class VolumeDirectoryHeader extends DirectoryHeader
{
byte[] buf = disk.readBlock (block);
blockList.add (buf);
block = Utility.intValue (buf[2], buf[3]); // next block
block = Utility.intValue (buf[2], buf[3]); // next block
} while (block > 0);
byte[] fullBuffer = new byte[blockList.size () * 507];
@ -100,6 +100,7 @@ class VolumeDirectoryHeader extends DirectoryHeader
System.arraycopy (bfr, 4, fullBuffer, offset, 507);
offset += 507;
}
return new ProdosDirectory (parentDisk, name, fullBuffer, totalBlocks, freeBlocks,
usedBlocks);
}
@ -114,6 +115,14 @@ class VolumeDirectoryHeader extends DirectoryHeader
return sectors;
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%s %04X %02X", super.getText (), totalBlocks, bitMapBlock);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -14,6 +14,7 @@ import java.time.LocalDateTime;
public class DirectoryHeader
// -----------------------------------------------------------------------------------//
{
static final String UNDERLINE = "--------------------------------------------";
ProdosDisk disk;
byte[] buffer;
int ptr;
@ -70,6 +71,49 @@ public class DirectoryHeader
writeShort (buffer, ptr + 0x21, fileCount);
}
// ---------------------------------------------------------------------------------//
void list ()
// ---------------------------------------------------------------------------------//
{
System.out.println (UNDERLINE);
System.out.println (toText ());
System.out.println (UNDERLINE);
int blockNo = ptr / BLOCK_SIZE;
do
{
int offset = blockNo * BLOCK_SIZE;
int ptr = offset + 4;
for (int i = 0; i < ENTRIES_PER_BLOCK; i++)
{
int storageType = (buffer[ptr] & 0xF0) >>> 4;
int nameLength = buffer[ptr] & 0x0F;
if (nameLength != 0 && storageType < 0x0E)
{
FileEntry fileEntry = new FileEntry (disk, buffer, ptr);
fileEntry.read ();
System.out.println (fileEntry.toText ());
}
ptr += ENTRY_SIZE;
}
blockNo = readShort (buffer, offset + 2);
} while (blockNo > 0);
System.out.println ();
}
// ---------------------------------------------------------------------------------//
String toText ()
// ---------------------------------------------------------------------------------//
{
int block = ptr / BLOCK_SIZE;
int entry = ((ptr % BLOCK_SIZE) - 4) / 39 + 1;
return String.format ("%04X:%02X %-15s %02X %04X", block, entry, fileName,
storageType, fileCount);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -309,6 +309,17 @@ public class FileEntry
return indexBlock;
}
// ---------------------------------------------------------------------------------//
String toText ()
// ---------------------------------------------------------------------------------//
{
int block = ptr / BLOCK_SIZE;
int entry = ((ptr % BLOCK_SIZE) - 4) / 39 + 1;
return String.format ("%04X:%02X %-15s %02X %04X %02X %04X %04X", block, entry,
fileName, storageType, blocksUsed, fileType, keyPointer, headerPointer);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -14,10 +14,10 @@ import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
// -----------------------------------------------------------------------------------//
public class ProdosDisk
@ -38,7 +38,7 @@ public class ProdosDisk
private final byte[] bootSector = new byte[BLOCK_SIZE];
private VolumeDirectoryHeader volumeDirectoryHeader;
private Map<Integer, SubdirectoryHeader> subdirectoryHeaders = new HashMap<> ();
private Map<Integer, SubdirectoryHeader> subdirectoryHeaders = new TreeMap<> ();
private List<String> paths = new ArrayList<> ();
// ---------------------------------------------------------------------------------//
@ -126,9 +126,11 @@ public class ProdosDisk
throws DiskFullException, VolumeCatalogFullException
// ---------------------------------------------------------------------------------//
{
if (path.isBlank ())
throw new IllegalArgumentException ("Path is empty");
// save path for verification
paths.add (path);
System.out.printf ("Path: %s%n", path);
// split the full path into an array of subdirectories and a file name
String[] subdirectories;
@ -249,13 +251,23 @@ public class ProdosDisk
{
for (SubdirectoryHeader subdirectoryHeader : subdirectoryHeaders.values ())
{
System.out.printf ("%-35s%n", subdirectoryHeader.fileName);
// System.out.printf ("%-35s%n", subdirectoryHeader.fileName);
FileEntry fileEntry = subdirectoryHeader.getParentFileEntry ();
if (!fileEntry.fileName.equals (subdirectoryHeader.fileName))
System.out.println ("fail");
System.out.printf ("fail: %s%n", subdirectoryHeader.fileName);
}
}
// ---------------------------------------------------------------------------------//
void display ()
// ---------------------------------------------------------------------------------//
{
volumeDirectoryHeader.list ();
for (SubdirectoryHeader subdirectoryHeader : subdirectoryHeaders.values ())
subdirectoryHeader.list ();
}
// ---------------------------------------------------------------------------------//
public void close ()
// ---------------------------------------------------------------------------------//
@ -278,7 +290,8 @@ public class ProdosDisk
}
System.out.println ();
}
verify ();
// verify ();
// display ();
}
// ---------------------------------------------------------------------------------//

View File

@ -2,7 +2,6 @@ package com.bytezone.diskbrowser.prodos.write;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.BLOCK_SIZE;
import static com.bytezone.diskbrowser.prodos.ProdosConstants.ENTRY_SIZE;
import static com.bytezone.diskbrowser.prodos.write.ProdosDisk.UNDERLINE;
import static com.bytezone.diskbrowser.utilities.Utility.readShort;
import static com.bytezone.diskbrowser.utilities.Utility.writeShort;
@ -92,6 +91,14 @@ public class SubdirectoryHeader extends DirectoryHeader
buffer[ptr + 0x26] = parentEntryLength;
}
// ---------------------------------------------------------------------------------//
@Override
String toText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%s %04X:%02X", super.toText (), parentPointer, parentEntry);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -1,6 +1,5 @@
package com.bytezone.diskbrowser.prodos.write;
import static com.bytezone.diskbrowser.prodos.write.ProdosDisk.UNDERLINE;
import static com.bytezone.diskbrowser.utilities.Utility.readShort;
import static com.bytezone.diskbrowser.utilities.Utility.writeShort;
@ -42,6 +41,14 @@ public class VolumeDirectoryHeader extends DirectoryHeader
writeShort (buffer, ptr + 0x25, totalBlocks);
}
// ---------------------------------------------------------------------------------//
@Override
String toText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%-29s %04X %04X", super.toText (), totalBlocks, bitMapPointer);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()

View File

@ -44,7 +44,8 @@ class LZW2 extends LZW
setBuffer (buffer, ptr); // prepare to read n-bit integers
byte[] lzwBuffer = undoLZW (rleLength);
assert (chunkLength - 4) == bytesRead ();
if ((chunkLength - 4) != bytesRead ())
System.out.printf ("Invalid chunk length%n");
if (rleLength == TRACK_LENGTH) // no run length encoding
chunks.add (lzwBuffer);

View File

@ -47,7 +47,9 @@ class MasterHeader
reserved = Utility.getWord (buffer, ptr + 30);
eof = Utility.getLong (buffer, ptr + 38);
assert reserved == 0;
// assert reserved == 0;
// if (reserved != 0)
// System.out.printf ("Reserved for zero, actual: %02X%n", reserved);
byte[] crcBuffer = new byte[40];
System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length);
@ -87,6 +89,7 @@ class MasterHeader
text.append (String.format ("Created ........ %s%n", created.format ()));
text.append (String.format ("Modified ....... %s%n", modified.format ()));
text.append (String.format ("Version ........ %,d%n", version));
text.append (String.format ("Reserved ....... %016X%n", reserved));
text.append (String.format ("Master EOF ..... %,d", eof));
return text.toString ();

View File

@ -118,6 +118,12 @@ public class NuFX
if (record.hasFile ())
{
String fileName = volumeName.convert (record.getFileName ());
if (!record.isValidFileSystem ())
{
System.out.printf ("File %s is file system %s%n", fileName,
record.getFileSystemName ());
continue;
}
// int fileSize = record.getFileSize ();
byte fileType = (byte) record.getFileType ();
int eof = record.getUncompressedSize ();

View File

@ -86,6 +86,13 @@ class Record
fileName = "";
}
// ---------------------------------------------------------------------------------//
boolean isValidFileSystem ()
// ---------------------------------------------------------------------------------//
{
return fileSystemID <= 4 || fileSystemID == 8;
}
// ---------------------------------------------------------------------------------//
int getAttributes ()
// ---------------------------------------------------------------------------------//
@ -198,6 +205,13 @@ class Record
return fileSystemID;
}
// ---------------------------------------------------------------------------------//
String getFileSystemName ()
// ---------------------------------------------------------------------------------//
{
return fileSystems[fileSystemID];
}
// ---------------------------------------------------------------------------------//
int getFileSize ()
// ---------------------------------------------------------------------------------//

View File

@ -52,7 +52,8 @@ class Thread
{
case 0: // uncompressed
break;
case 1: // Huffman Squeeze
case 1: // Huffman Squeeze - see archivers folder
System.out.printf ("Huffman squeeze");
break;
case 2: // Dynamic LZW/1
lzw = new LZW1 (data);