dmolony-DiskBrowser/src/com/bytezone/diskbrowser/dos/CatalogEntry.java

161 lines
5.5 KiB
Java
Raw Normal View History

2015-06-01 09:35:51 +00:00
package com.bytezone.diskbrowser.dos;
2019-01-25 04:57:15 +00:00
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
2015-06-01 09:35:51 +00:00
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.dos.DosDisk.FileType;
2016-02-24 21:11:14 +00:00
import com.bytezone.diskbrowser.utilities.HexFormatter;
2015-06-01 09:35:51 +00:00
2020-02-08 08:28:22 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
class CatalogEntry extends AbstractCatalogEntry
2020-02-08 08:28:22 +00:00
// -----------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
2017-05-08 01:46:28 +00:00
private int textFileGaps;
private int length;
private int address;
2015-06-01 09:35:51 +00:00
2020-02-08 08:28:22 +00:00
// ---------------------------------------------------------------------------------//
CatalogEntry (DosDisk dosDisk, DiskAddress catalogSector, byte[] entryBuffer)
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
super (dosDisk, catalogSector, entryBuffer); // build lists of ts and data sectors
2017-05-08 01:46:28 +00:00
2015-06-01 09:35:51 +00:00
if (reportedSize > 0 && disk.isValidAddress (entryBuffer[0], entryBuffer[1]))
{
// Get address of first TS-list sector
DiskAddress da = disk.getDiskAddress (entryBuffer[0], entryBuffer[1]);
// Loop through all TS-list sectors
2019-01-25 04:57:15 +00:00
loop: while (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ())
2015-06-01 09:35:51 +00:00
{
if (dosDisk.stillAvailable (da))
dosDisk.sectorTypes[da.getBlock ()] = dosDisk.tsListSector;
else
{
2016-12-17 08:34:47 +00:00
System.out.printf (
"Attempt to assign TS sector to occupied sector " + ": %s from %s%n", da,
name);
2016-07-16 21:33:31 +00:00
// break;
2015-06-01 09:35:51 +00:00
}
tsSectors.add (da);
byte[] sectorBuffer = disk.readSector (da);
int startPtr = 12;
// the tsList *should* start at 0xC0, but some disks start in the unused bytes
if (false)
for (int i = 7; i < startPtr; i++)
if (sectorBuffer[i] != 0)
{
startPtr = i;
break;
}
2016-07-16 21:33:31 +00:00
DiskAddress thisDA = da;
2015-06-01 09:35:51 +00:00
for (int i = startPtr, max = disk.getBlockSize (); i < max; i += 2)
{
da = getValidAddress (sectorBuffer, i);
if (da == null)
{
2020-04-08 02:17:08 +00:00
System.out.printf (
"T/S list at offset %02X contains an invalid address : %02X, %02X (file %s)%n",
i, sectorBuffer[i], sectorBuffer[i + 1], name.trim ());
2015-06-01 09:35:51 +00:00
break loop;
}
2019-01-25 04:57:15 +00:00
if (da.getBlock () == 0 && !((AppleDiskAddress) da).zeroFlag ())
2015-06-01 09:35:51 +00:00
{
if (fileType != FileType.Text)
break;
++textFileGaps;
dataSectors.add (null);
}
else
{
dataSectors.add (da);
if (dosDisk.stillAvailable (da))
dosDisk.sectorTypes[da.getBlock ()] = dosDisk.dataSector;
else
{
2016-02-26 11:03:29 +00:00
System.out
.print ("Attempt to assign Data sector to occupied sector : " + da);
2015-06-01 09:35:51 +00:00
System.out.println (" from " + name);
}
}
}
da = getValidAddress (sectorBuffer, 1);
if (da == null)
{
2016-07-16 21:33:31 +00:00
System.out.print ("Next T/S list in sector " + thisDA);
2016-02-26 11:03:29 +00:00
System.out.printf (" is invalid : %02X, %02X%n", sectorBuffer[1],
2016-12-17 08:34:47 +00:00
sectorBuffer[2]);
2015-06-01 09:35:51 +00:00
break;
}
2016-07-16 21:33:31 +00:00
2019-01-25 06:06:31 +00:00
if (thisDA.matches (da) && ((AppleDiskAddress) thisDA)
.zeroFlag () == ((AppleDiskAddress) da).zeroFlag ())
2016-07-16 21:33:31 +00:00
{
System.out.printf ("Next T/S list in sector %s points to itself%n", thisDA);
break;
}
2015-06-01 09:35:51 +00:00
}
}
// remove trailing empty sectors
if (fileType == FileType.Text)
{
while (dataSectors.size () > 0)
{
DiskAddress da = dataSectors.get (dataSectors.size () - 1);
if (da == null)
{
dataSectors.remove (dataSectors.size () - 1);
--textFileGaps;
}
else
break;
}
}
2017-04-17 03:29:29 +00:00
else if (dataSectors.size () > 0) // get the file length
2015-06-01 09:35:51 +00:00
{
byte[] buffer = disk.readSector (dataSectors.get (0));
switch (fileType)
{
case IntegerBasic:
case ApplesoftBasic:
length = HexFormatter.intValue (buffer[0], buffer[1]);
break;
2016-02-26 11:03:29 +00:00
2015-06-01 09:35:51 +00:00
default:
address = HexFormatter.intValue (buffer[0], buffer[1]);
length = HexFormatter.intValue (buffer[2], buffer[3]);
}
}
}
2020-02-08 08:28:22 +00:00
// ---------------------------------------------------------------------------------//
String getDetails ()
// ---------------------------------------------------------------------------------//
2015-06-01 09:35:51 +00:00
{
int actualSize = dataSectors.size () + tsSectors.size () - textFileGaps;
String addressText = address == 0 ? "" : String.format ("$%4X", address);
String lengthText = length == 0 ? "" : String.format ("$%4X %,6d", length, length);
String message = "";
String lockedFlag = (locked) ? "*" : " ";
2019-01-25 06:06:31 +00:00
2019-01-25 04:57:15 +00:00
if (dosDisk.dosVTOCSector.dosVersion >= 0x41)
message = lastModified.toString ().replace ('T', ' ');
2019-01-25 06:06:31 +00:00
2015-06-01 09:35:51 +00:00
if (reportedSize != actualSize)
message += "Bad size (" + reportedSize + ") ";
if (dataSectors.size () == 0)
message += "No data ";
2016-12-17 08:34:47 +00:00
2019-08-06 04:54:04 +00:00
String catName = catalogName.length () >= 8 ? catalogName.substring (7) : catalogName;
2019-01-26 20:06:13 +00:00
String text = String.format ("%1s %1s %03d %-30.30s %-5s %-13s %3d %3d %s",
2019-08-06 04:54:04 +00:00
lockedFlag, getFileType (), actualSize, catName, addressText, lengthText,
2019-01-26 20:06:13 +00:00
tsSectors.size (), (dataSectors.size () - textFileGaps), message.trim ());
2016-12-17 08:34:47 +00:00
if (actualSize == 0)
text = text.substring (0, 50);
2019-01-25 06:06:31 +00:00
2016-12-17 08:34:47 +00:00
return text;
2015-06-01 09:35:51 +00:00
}
}