2015-06-01 09:35:51 +00:00
|
|
|
package com.bytezone.diskbrowser.dos;
|
|
|
|
|
2021-03-28 06:44:36 +00:00
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.AA;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.ApplesoftBasic;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.BB;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Binary;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.IntegerBasic;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Relocatable;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.SS;
|
|
|
|
import static com.bytezone.diskbrowser.dos.DosDisk.FileType.Text;
|
|
|
|
|
2019-01-25 04:57:15 +00:00
|
|
|
import java.time.LocalDateTime;
|
2015-06-01 09:35:51 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2020-02-02 10:17:49 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
|
|
|
import com.bytezone.diskbrowser.applefile.ApplesoftBasicProgram;
|
|
|
|
import com.bytezone.diskbrowser.applefile.AssemblerProgram;
|
2020-11-21 11:15:08 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.BasicTextFile;
|
2020-02-02 10:17:49 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
|
|
|
|
import com.bytezone.diskbrowser.applefile.DoubleHiResImage;
|
|
|
|
import com.bytezone.diskbrowser.applefile.ErrorMessageFile;
|
|
|
|
import com.bytezone.diskbrowser.applefile.FontFile;
|
|
|
|
import com.bytezone.diskbrowser.applefile.HiResImage;
|
|
|
|
import com.bytezone.diskbrowser.applefile.IntegerBasicProgram;
|
2021-03-26 01:11:34 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.MagicWindowText;
|
2020-02-02 10:17:49 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.MerlinSource;
|
|
|
|
import com.bytezone.diskbrowser.applefile.OriginalHiResImage;
|
|
|
|
import com.bytezone.diskbrowser.applefile.PrintShopGraphic;
|
|
|
|
import com.bytezone.diskbrowser.applefile.ShapeTable;
|
|
|
|
import com.bytezone.diskbrowser.applefile.VisicalcFile;
|
2015-06-01 09:35:51 +00:00
|
|
|
import com.bytezone.diskbrowser.disk.Disk;
|
|
|
|
import com.bytezone.diskbrowser.disk.DiskAddress;
|
|
|
|
import com.bytezone.diskbrowser.disk.FormattedDisk;
|
|
|
|
import com.bytezone.diskbrowser.dos.DosDisk.FileType;
|
|
|
|
import com.bytezone.diskbrowser.gui.DataSource;
|
2019-01-25 04:57:15 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.Utility;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
abstract class AbstractCatalogEntry implements AppleFileSource
|
2020-02-08 08:28:22 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2016-02-25 07:45:24 +00:00
|
|
|
protected Disk disk;
|
|
|
|
protected DosDisk dosDisk;
|
|
|
|
protected String name;
|
|
|
|
protected String catalogName;
|
2020-11-21 11:15:08 +00:00
|
|
|
protected String displayName;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-25 07:45:24 +00:00
|
|
|
protected FileType fileType;
|
|
|
|
protected int reportedSize;
|
|
|
|
protected boolean locked;
|
2015-06-01 09:35:51 +00:00
|
|
|
protected DataSource appleFile;
|
2019-01-25 04:57:15 +00:00
|
|
|
protected LocalDateTime lastModified;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
protected DiskAddress catalogSectorDA;
|
2020-02-02 10:17:49 +00:00
|
|
|
protected final List<DiskAddress> dataSectors = new ArrayList<> ();
|
|
|
|
protected final List<DiskAddress> tsSectors = new ArrayList<> ();
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-12-31 09:34:15 +00:00
|
|
|
private CatalogEntry link;
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
AbstractCatalogEntry (DosDisk dosDisk, DiskAddress catalogSector, byte[] entryBuffer)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
this.dosDisk = dosDisk;
|
|
|
|
this.disk = dosDisk.getDisk ();
|
|
|
|
this.catalogSectorDA = catalogSector;
|
2017-05-08 01:46:28 +00:00
|
|
|
|
2020-04-10 23:47:52 +00:00
|
|
|
name = getName ("", entryBuffer);
|
2021-05-19 08:13:17 +00:00
|
|
|
reportedSize = Utility.getShort (entryBuffer, 33);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2019-01-25 04:57:15 +00:00
|
|
|
int type = entryBuffer[2] & 0x7F;
|
|
|
|
locked = (entryBuffer[2] & 0x80) != 0;
|
|
|
|
|
2021-03-28 06:44:36 +00:00
|
|
|
fileType = switch (type)
|
|
|
|
{
|
|
|
|
case 0x00 -> Text;
|
|
|
|
case 0x01 -> IntegerBasic;
|
|
|
|
case 0x02 -> ApplesoftBasic;
|
|
|
|
case 0x04 -> Binary;
|
|
|
|
case 0x08 -> SS;
|
|
|
|
case 0x10 -> Relocatable;
|
|
|
|
case 0x20 -> AA;
|
|
|
|
case 0x40 -> BB;
|
|
|
|
default -> Binary; // should never happen
|
|
|
|
};
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2019-01-25 06:06:31 +00:00
|
|
|
if (dosDisk.getVersion () >= 0x41)
|
|
|
|
lastModified = Utility.getDateTime (entryBuffer, 0x1B);
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
// CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6
|
2021-03-28 06:44:36 +00:00
|
|
|
String base = String.format ("%s%s %03d ", locked ? "*" : " ", getFileType (),
|
|
|
|
reportedSize & 0xFF);
|
2020-12-12 10:41:57 +00:00
|
|
|
catalogName = getName (base, entryBuffer);
|
2020-11-21 11:15:08 +00:00
|
|
|
displayName = getDisplayName (entryBuffer);
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
private String getName (String base, byte[] buffer)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
StringBuilder text = new StringBuilder (base);
|
2020-04-10 23:47:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
int max = buffer[0] == (byte) 0xFF ? 32 : 33;
|
2019-01-25 04:57:15 +00:00
|
|
|
if (dosDisk.getVersion () >= 0x41)
|
|
|
|
max = 27;
|
2020-04-10 23:47:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
for (int i = 3; i < max; i++)
|
|
|
|
{
|
|
|
|
int c = buffer[i] & 0xFF;
|
2020-12-12 10:41:57 +00:00
|
|
|
if ((c == 0x88 || c == 0x8A) && !base.isEmpty ()) // allow backspaces
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (text.length () > 0)
|
|
|
|
text.deleteCharAt (text.length () - 1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (c > 127)
|
|
|
|
c -= c < 160 ? 64 : 128;
|
2020-12-12 10:41:57 +00:00
|
|
|
// c &= 0x7F;
|
2015-06-01 09:35:51 +00:00
|
|
|
if (c < 32)
|
2020-12-12 10:41:57 +00:00
|
|
|
text.append ((char) (c + 64)); // non-printable ascii
|
2015-06-01 09:35:51 +00:00
|
|
|
else
|
2016-12-17 08:34:47 +00:00
|
|
|
text.append ((char) c); // standard ascii
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
2020-04-10 23:47:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
while (text.length () > 0 && text.charAt (text.length () - 1) == ' ')
|
2016-12-17 08:34:47 +00:00
|
|
|
text.deleteCharAt (text.length () - 1); // rtrim()
|
2020-12-12 10:41:57 +00:00
|
|
|
// System.out.println (text.toString ());
|
2020-04-10 23:47:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return text.toString ();
|
|
|
|
}
|
|
|
|
|
2020-11-21 11:15:08 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
private String getDisplayName (byte[] buffer)
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
{
|
|
|
|
StringBuilder text = new StringBuilder ();
|
|
|
|
|
|
|
|
int max = buffer[0] == (byte) 0xFF ? 32 : 33;
|
|
|
|
if (dosDisk.getVersion () >= 0x41)
|
|
|
|
max = 27;
|
|
|
|
|
|
|
|
for (int i = 3; i < max; i++)
|
|
|
|
{
|
|
|
|
int c = buffer[i] & 0xFF;
|
2020-12-12 10:41:57 +00:00
|
|
|
if ((c == 0x88 || c == 0x8A)) // don't allow backspaces
|
2020-11-21 11:15:08 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (c > 127)
|
|
|
|
c -= c < 160 ? 64 : 128;
|
2020-12-12 10:41:57 +00:00
|
|
|
// c &= 0x7F;
|
2020-11-21 11:15:08 +00:00
|
|
|
if (c < 32)
|
|
|
|
text.append ((char) (c + 64)); // non-printable ascii
|
|
|
|
else
|
|
|
|
text.append ((char) c); // standard ascii
|
|
|
|
}
|
|
|
|
|
|
|
|
while (text.length () > 0 && text.charAt (text.length () - 1) == ' ')
|
|
|
|
text.deleteCharAt (text.length () - 1); // rtrim()
|
|
|
|
|
|
|
|
return text.toString ();
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
protected String getFileType ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2020-07-13 04:32:08 +00:00
|
|
|
if (fileType == null)
|
|
|
|
{
|
|
|
|
return "?";
|
|
|
|
}
|
2019-08-11 21:49:23 +00:00
|
|
|
switch (fileType)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
case Text:
|
|
|
|
return "T";
|
|
|
|
case IntegerBasic:
|
|
|
|
return "I";
|
|
|
|
case ApplesoftBasic:
|
|
|
|
return "A";
|
|
|
|
case Binary:
|
|
|
|
return "B";
|
2017-04-02 05:02:29 +00:00
|
|
|
case SS: // what is this?
|
2015-06-01 09:35:51 +00:00
|
|
|
return "S";
|
|
|
|
case Relocatable:
|
|
|
|
return "R";
|
2017-04-02 05:02:29 +00:00
|
|
|
case AA: // what is this?
|
2015-06-01 09:35:51 +00:00
|
|
|
return "A";
|
2019-01-25 21:57:35 +00:00
|
|
|
case BB: // Lisa file
|
|
|
|
return "L";
|
2015-06-01 09:35:51 +00:00
|
|
|
default:
|
|
|
|
System.out.println ("Unknown file type : " + fileType);
|
|
|
|
return "?";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// maybe this should be in the FormattedDisk
|
|
|
|
// maybe DiskAddress should have a 'valid' flag
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
protected DiskAddress getValidAddress (byte[] buffer, int offset)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (disk.isValidAddress (buffer[offset], buffer[offset + 1]))
|
|
|
|
return disk.getDiskAddress (buffer[offset], buffer[offset + 1]);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public DataSource getDataSource ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (appleFile != null)
|
|
|
|
return appleFile;
|
|
|
|
|
2020-04-10 23:47:52 +00:00
|
|
|
byte[] buffer = disk.readBlocks (dataSectors);
|
2015-06-01 09:35:51 +00:00
|
|
|
int reportedLength;
|
|
|
|
if (buffer.length == 0)
|
|
|
|
{
|
|
|
|
appleFile = new DefaultAppleFile (name, buffer);
|
|
|
|
return appleFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2016-02-05 00:23:53 +00:00
|
|
|
byte[] exactBuffer;
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
switch (this.fileType)
|
|
|
|
{
|
|
|
|
case Text:
|
|
|
|
if (VisicalcFile.isVisicalcFile (buffer))
|
|
|
|
appleFile = new VisicalcFile (name, buffer);
|
|
|
|
else
|
2020-09-14 09:51:14 +00:00
|
|
|
appleFile = new BasicTextFile (name, buffer);
|
2015-06-01 09:35:51 +00:00
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
case IntegerBasic:
|
2021-05-19 08:13:17 +00:00
|
|
|
reportedLength = Utility.getShort (buffer, 0);
|
2016-02-05 00:23:53 +00:00
|
|
|
exactBuffer = new byte[reportedLength];
|
2015-06-01 09:35:51 +00:00
|
|
|
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
|
|
|
appleFile = new IntegerBasicProgram (name, exactBuffer);
|
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
case ApplesoftBasic:
|
2021-05-19 08:13:17 +00:00
|
|
|
reportedLength = Utility.getShort (buffer, 0);
|
2015-06-01 09:35:51 +00:00
|
|
|
exactBuffer = new byte[reportedLength];
|
|
|
|
if (reportedLength > buffer.length)
|
|
|
|
reportedLength = buffer.length - 2;
|
|
|
|
System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength);
|
2019-08-09 23:45:49 +00:00
|
|
|
appleFile = new ApplesoftBasicProgram (name, exactBuffer);
|
2015-06-01 09:35:51 +00:00
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
|
|
|
case Binary: // binary file
|
|
|
|
case Relocatable: // relocatable binary file
|
2020-11-22 01:04:27 +00:00
|
|
|
case BB:
|
2021-05-19 08:13:17 +00:00
|
|
|
int loadAddress = Utility.getShort (buffer, 0);
|
|
|
|
reportedLength = Utility.getShort (buffer, 2);
|
2016-03-23 23:37:59 +00:00
|
|
|
if (reportedLength == 0)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2016-03-23 23:37:59 +00:00
|
|
|
System.out.println (name.trim () + " reported length : 0 - reverting to "
|
|
|
|
+ (buffer.length - 4));
|
|
|
|
reportedLength = buffer.length - 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
// buffer is a multiple of the block size, so it usually needs to be reduced
|
|
|
|
if ((reportedLength + 4) <= buffer.length)
|
|
|
|
exactBuffer = new byte[reportedLength];
|
|
|
|
else
|
|
|
|
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
|
|
|
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
2018-08-15 02:32:11 +00:00
|
|
|
|
2017-03-19 09:52:36 +00:00
|
|
|
if ((name.endsWith (".FONT") || name.endsWith (" FONT")
|
|
|
|
|| name.endsWith (".SET") || name.startsWith ("ASCII."))
|
|
|
|
&& FontFile.isFont (exactBuffer))
|
2019-11-01 06:39:23 +00:00
|
|
|
appleFile = new FontFile (name, exactBuffer, loadAddress);
|
2021-03-26 01:11:34 +00:00
|
|
|
else if (name.endsWith (".MW"))
|
|
|
|
appleFile = new MagicWindowText (name, exactBuffer);
|
2016-12-17 08:34:47 +00:00
|
|
|
else if (ShapeTable.isShapeTable (exactBuffer))
|
2016-03-23 23:37:59 +00:00
|
|
|
appleFile = new ShapeTable (name, exactBuffer);
|
2016-12-12 07:43:19 +00:00
|
|
|
else if (name.endsWith (".S"))
|
2017-11-26 06:16:56 +00:00
|
|
|
appleFile = new MerlinSource (name, exactBuffer, loadAddress);
|
2017-02-01 21:15:30 +00:00
|
|
|
else if (HiResImage.isGif (exactBuffer)) // buffer?
|
2016-12-31 09:34:15 +00:00
|
|
|
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress);
|
2017-02-01 21:15:30 +00:00
|
|
|
else if (HiResImage.isPng (exactBuffer)) // buffer?
|
|
|
|
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress);
|
|
|
|
else if (name.endsWith (".BMP") && HiResImage.isBmp (buffer))
|
|
|
|
appleFile = new OriginalHiResImage (name, buffer, loadAddress);
|
2017-01-08 23:36:10 +00:00
|
|
|
else if (name.endsWith (".PAC"))
|
|
|
|
appleFile = new DoubleHiResImage (name, exactBuffer);
|
2016-12-31 09:34:15 +00:00
|
|
|
else if (link != null)
|
|
|
|
{
|
2020-04-10 23:47:52 +00:00
|
|
|
byte[] auxBuffer = link.disk.readBlocks (link.dataSectors);
|
2016-12-31 09:34:15 +00:00
|
|
|
byte[] exactAuxBuffer = getExactBuffer (auxBuffer);
|
|
|
|
if (name.endsWith (".AUX"))
|
|
|
|
appleFile = new DoubleHiResImage (name, exactAuxBuffer, exactBuffer);
|
|
|
|
else
|
|
|
|
appleFile = new DoubleHiResImage (name, exactBuffer, exactAuxBuffer);
|
|
|
|
}
|
2016-03-23 23:37:59 +00:00
|
|
|
else if (loadAddress == 0x2000 || loadAddress == 0x4000)
|
|
|
|
{
|
2016-12-17 08:34:47 +00:00
|
|
|
if (reportedLength > 0x1F00 && reportedLength <= 0x4000)
|
2016-12-31 09:34:15 +00:00
|
|
|
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress);
|
2016-12-17 08:34:47 +00:00
|
|
|
else if (isScrunched (reportedLength))
|
2016-12-31 09:34:15 +00:00
|
|
|
appleFile = new OriginalHiResImage (name, exactBuffer, loadAddress, true);
|
2015-06-01 09:35:51 +00:00
|
|
|
else
|
|
|
|
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
|
|
|
}
|
2018-08-17 01:20:00 +00:00
|
|
|
else if (reportedLength == 0x240 //
|
|
|
|
&& (loadAddress == 0x5800 || loadAddress == 0x6000
|
|
|
|
|| loadAddress == 0x7800))
|
2018-04-25 22:21:26 +00:00
|
|
|
appleFile = new PrintShopGraphic (name, exactBuffer);
|
2018-08-17 01:20:00 +00:00
|
|
|
else if (isRunCommand (exactBuffer))
|
|
|
|
{
|
|
|
|
byte[] buf = new byte[exactBuffer.length - 4];
|
|
|
|
System.arraycopy (exactBuffer, 4, buf, 0, buf.length);
|
2019-08-09 23:45:49 +00:00
|
|
|
appleFile = new ApplesoftBasicProgram (name, buf);
|
2018-08-17 11:46:47 +00:00
|
|
|
System.out.printf ("Possible basic binary: %s%n", name);
|
2018-08-17 01:20:00 +00:00
|
|
|
}
|
2016-03-23 23:37:59 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
appleFile = new AssemblerProgram (name, exactBuffer, loadAddress);
|
|
|
|
if ((exactBuffer.length + 4) < buffer.length)
|
2016-12-12 07:43:19 +00:00
|
|
|
((AssemblerProgram) appleFile).setExtraBuffer (buffer,
|
|
|
|
exactBuffer.length + 4, buffer.length - (exactBuffer.length + 4));
|
2016-03-23 23:37:59 +00:00
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
|
|
|
case SS: // what is this?
|
2015-06-01 09:35:51 +00:00
|
|
|
System.out.println ("SS file");
|
|
|
|
appleFile = new DefaultAppleFile (name, buffer);
|
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
|
|
|
case AA: // what is this?
|
2015-06-01 09:35:51 +00:00
|
|
|
System.out.println ("AA file");
|
|
|
|
appleFile = new DefaultAppleFile (name, buffer);
|
|
|
|
break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
2020-11-22 01:04:27 +00:00
|
|
|
// case BB: // Lisa
|
|
|
|
// loadAddress = Utility.intValue (buffer[0], buffer[1]);
|
|
|
|
// appleFile = new SimpleText2 (name, getExactBuffer (buffer), loadAddress);
|
|
|
|
// break;
|
2016-02-05 00:23:53 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
default:
|
|
|
|
System.out.println ("Unknown file type : " + fileType);
|
|
|
|
appleFile = new DefaultAppleFile (name, buffer);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
appleFile = new ErrorMessageFile (name, buffer, e);
|
|
|
|
e.printStackTrace ();
|
|
|
|
}
|
|
|
|
return appleFile;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-31 09:34:15 +00:00
|
|
|
private byte[] getExactBuffer (byte[] buffer)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-31 09:34:15 +00:00
|
|
|
{
|
|
|
|
byte[] exactBuffer;
|
|
|
|
|
2021-05-19 08:13:17 +00:00
|
|
|
int reportedLength = Utility.getShort (buffer, 2);
|
2016-12-31 09:34:15 +00:00
|
|
|
if (reportedLength == 0)
|
|
|
|
{
|
|
|
|
System.out.println (
|
|
|
|
name.trim () + " reported length : 0 - reverting to " + (buffer.length - 4));
|
|
|
|
reportedLength = buffer.length - 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
// buffer is a multiple of the block size, so it usually needs to be reduced
|
|
|
|
if ((reportedLength + 4) <= buffer.length)
|
|
|
|
exactBuffer = new byte[reportedLength];
|
|
|
|
else
|
|
|
|
exactBuffer = new byte[buffer.length - 4]; // reported length is too long
|
|
|
|
System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length);
|
2018-08-15 02:32:11 +00:00
|
|
|
|
2016-12-31 09:34:15 +00:00
|
|
|
return exactBuffer;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-17 01:20:00 +00:00
|
|
|
private boolean isRunCommand (byte[] buffer)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-17 01:20:00 +00:00
|
|
|
{
|
|
|
|
// see Stargate - Disk 1, Side A.woz
|
|
|
|
return buffer[0] == 0x4C && buffer[1] == (byte) 0xFC && buffer[2] == (byte) 0xA4
|
|
|
|
&& buffer[3] == 0x00;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-17 08:34:47 +00:00
|
|
|
private boolean isScrunched (int reportedLength)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-17 08:34:47 +00:00
|
|
|
{
|
|
|
|
if ((name.equals ("FLY LOGO") || name.equals ("FLY LOGO SCRUNCHED"))
|
|
|
|
&& reportedLength == 0x14FA)
|
|
|
|
return true;
|
2016-12-22 22:41:28 +00:00
|
|
|
|
2016-12-17 08:34:47 +00:00
|
|
|
if (name.equals ("BBROS LOGO SCRUNCHED") && reportedLength == 0x0FED)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-02-25 21:49:22 +00:00
|
|
|
@Override
|
|
|
|
public boolean contains (DiskAddress da)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
for (DiskAddress sector : tsSectors)
|
2016-07-19 01:24:36 +00:00
|
|
|
if (sector.matches (da))
|
2015-06-01 09:35:51 +00:00
|
|
|
return true;
|
2018-08-15 02:32:11 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
for (DiskAddress sector : dataSectors)
|
|
|
|
// random access files may have gaps, and thus null sectors
|
2018-08-15 02:32:11 +00:00
|
|
|
// is this still true? I thought I was using sector zero objects??
|
2016-07-19 01:24:36 +00:00
|
|
|
if (sector != null && sector.matches (da))
|
2015-06-01 09:35:51 +00:00
|
|
|
return true;
|
2018-08-15 02:32:11 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public String getUniqueName ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
// this might not be unique if the file has been deleted
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public FormattedDisk getFormattedDisk ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
return dosDisk;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public List<DiskAddress> getSectors ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskAddress> sectors = new ArrayList<> ();
|
2015-06-01 09:35:51 +00:00
|
|
|
sectors.add (catalogSectorDA);
|
|
|
|
sectors.addAll (tsSectors);
|
|
|
|
sectors.addAll (dataSectors);
|
|
|
|
return sectors;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-31 09:34:15 +00:00
|
|
|
void link (CatalogEntry catalogEntry)
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-12-31 09:34:15 +00:00
|
|
|
{
|
|
|
|
this.link = catalogEntry;
|
|
|
|
}
|
|
|
|
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public String toString ()
|
2020-02-08 08:28:22 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
return catalogName;
|
|
|
|
}
|
|
|
|
}
|