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

167 lines
6.3 KiB
Java
Executable File

package com.bytezone.diskbrowser.dos;
import com.bytezone.diskbrowser.disk.AbstractSector;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
class DosCatalogSector extends AbstractSector
// -----------------------------------------------------------------------------------//
{
private static final String[] fileTypes =
{ "Text file", "Integer Basic program", "Applesoft Basic program", "Binary file",
"SS file", "Relocatable file", "AA file", "Lisa file" };
private static int CATALOG_ENTRY_SIZE = 35;
private final DosDisk dosDisk;
// ---------------------------------------------------------------------------------//
DosCatalogSector (DosDisk dosDisk, Disk disk, byte[] buffer, DiskAddress diskAddress)
// ---------------------------------------------------------------------------------//
{
super (disk, buffer, diskAddress);
this.dosDisk = dosDisk;
}
// ---------------------------------------------------------------------------------//
@Override
public String createText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text =
getHeader ("DOS " + dosDisk.getVersionText () + " Catalog Sector");
addText (text, buffer, 0, 1, "Not used");
addText (text, buffer, 1, 2, "Next catalog track/sector");
addText (text, buffer, 3, 4, "Not used");
addText (text, buffer, 7, 4, "Not used");
boolean dos4 = dosDisk.getVersion () > 3;
for (int i = 11; i <= 255; i += CATALOG_ENTRY_SIZE)
{
text.append ("\n");
if (dos4)
createDos4Text (text, i);
else
createDos3Text (text, i);
}
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private void createDos4Text (StringBuilder text, int i)
// ---------------------------------------------------------------------------------//
{
int track = buffer[i] & 0x3F;
int sector = buffer[i + 1] & 0x1F;
int fileType = buffer[i + 2] & 0x7F;
boolean deleteFlag = (buffer[i] & 0x80) != 0;
boolean zeroTrackFlag = (buffer[i] & 0x40) != 0;
boolean lockedFlag = (buffer[i + 2] & 0x80) != 0;
if (buffer[i] == 0 && !zeroTrackFlag)
{
addText (text, buffer, i + 0, 2, "");
addText (text, buffer, i + 2, 1, "");
addText (text, buffer, i + 3, 4, "");
addText (text, buffer, i + 33, 2, "");
}
else
{
addText (text, buffer, i, 1,
String.format ("TS list track (%s, %s)", deleteFlag ? "deleted" : "not deleted",
zeroTrackFlag ? "track zero" : "not track zero"));
addText (text, buffer, i + 1, 1, "TS list sector");
addText (text, buffer, i + 2, 1,
String.format ("File type (%s)", lockedFlag ? "locked" : "unlocked"));
addText (text, buffer, i + 3, 4, getName (buffer, i + 3, 24));
for (int j = 0; j < 20; j += 4)
addText (text, buffer, i + 7 + j, 4, "");
addText (text, buffer, i + 27, 3,
"Date/time initialised: " + Utility.getDateTime (buffer, i + 27));
addText (text, buffer, i + 30, 3, "");
addTextAndDecimal (text, buffer, i + 33, 2, "File size");
}
}
// ---------------------------------------------------------------------------------//
private void createDos3Text (StringBuilder text, int i)
// ---------------------------------------------------------------------------------//
{
if (buffer[i] == (byte) 0xFF) // file is deleted
{
addText (text, buffer, i, 2, "DEL: file @ " + HexFormatter.format2 (buffer[i + 32])
+ " " + HexFormatter.format2 (buffer[i + 1]));
addText (text, buffer, i + 2, 1, "DEL: File type " + getType (buffer[i + 2]));
if (buffer[i + 3] == 0)
addText (text, buffer, i + 3, 4, "");
else
addText (text, buffer, i + 3, 4, "DEL: " + getName (buffer, i + 3, 29));
addTextAndDecimal (text, buffer, i + 33, 2, "DEL: Sector count");
}
else if (buffer[i] > 0) // file exists
{
addText (text, buffer, i, 2, "TS list track/sector");
addText (text, buffer, i + 2, 1, "File type " + getType (buffer[i + 2]));
if (buffer[i + 3] == 0)
addText (text, buffer, i + 3, 4, "");
else
{
addText (text, buffer, i + 3, 4, getName (buffer, i + 3, 30));
for (int j = 0; j < 24; j += 4)
addText (text, buffer, i + j + 7, 4, "");
addText (text, buffer, i + 31, 2, "");
}
addTextAndDecimal (text, buffer, i + 33, 2, "Sector count");
}
else // no file
{
addText (text, buffer, i + 0, 2, "");
addText (text, buffer, i + 2, 1, "");
addText (text, buffer, i + 3, 4, "");
addText (text, buffer, i + 33, 2, "");
}
}
// ---------------------------------------------------------------------------------//
static String getName (byte[] buffer, int offset, int length)
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
// int max = buffer[offset] == (byte) 0xFF ? 32 : 33;
for (int i = offset; i < offset + length; i++)
{
int c = buffer[i] & 0xFF;
if (c == 136)
{
if (text.length () > 0)
text.deleteCharAt (text.length () - 1);
continue;
}
if (c > 127)
c -= c < 160 ? 64 : 128;
if (c < 32) // non-printable
text.append ("^" + (char) (c + 64));
else
text.append ((char) c); // standard ascii
}
return text.toString ();
}
// ---------------------------------------------------------------------------------//
private String getType (byte value)
// ---------------------------------------------------------------------------------//
{
int type = value & 0x7F;
boolean locked = (value & 0x80) > 0;
int val = 7;
for (int i = 64; i > type; val--, i /= 2)
;
return "(" + fileTypes[val] + (locked ? ", locked)" : ", unlocked)");
}
}