DOS 4.1 changes

This commit is contained in:
Denis Molony 2019-01-25 15:57:15 +11:00
parent d9b656cfa0
commit 1b5f3f95a9
10 changed files with 306 additions and 99 deletions

View File

@ -18,7 +18,7 @@ public class SimpleText2 extends AbstractFile
// store a pointer to each new line
int ptr = 0;
while (buffer[ptr] != -1)
while (ptr < buffer.length && buffer[ptr] != -1)
{
int length = buffer[ptr] & 0xFF;
lineStarts.add (ptr);
@ -37,6 +37,8 @@ public class SimpleText2 extends AbstractFile
for (Integer i : lineStarts)
text.append (String.format ("%05X %s%n", i, getLine (i)));
if (text.charAt (text.length () - 1) == '\n')
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
@ -46,8 +48,8 @@ public class SimpleText2 extends AbstractFile
StringBuilder text = new StringBuilder ();
for (Integer i : lineStarts)
text.append (HexFormatter.formatNoHeader (buffer, i, (buffer[i] & 0xFF) + 1)
+ "\n");
text.append (
HexFormatter.formatNoHeader (buffer, i, (buffer[i] & 0xFF) + 1) + "\n");
text.append (HexFormatter.formatNoHeader (buffer, buffer.length - 2, 2) + "\n");
return text.toString ();

View File

@ -396,7 +396,8 @@ public class AppleDisk implements Disk
int ptr = 0;
for (DiskAddress da : daList)
{
if (da != null && da.getBlock () > 0) // sparse text/PNT/PIC files may have gaps
// sparse text/PNT/PIC files may have gaps
if (da != null && (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ()))
readBuffer (da, buffer, ptr);
ptr += sectorSize;
}
@ -458,6 +459,9 @@ public class AppleDisk implements Disk
@Override
public DiskAddress getDiskAddress (int track, int sector)
{
// track &= 0x3F;
// sector &= 0x1F;
if (!isValidAddress (track, sector))
{
System.out.println ("Invalid block : " + track + "/" + sector);
@ -502,10 +506,14 @@ public class AppleDisk implements Disk
@Override
public boolean isValidAddress (int track, int sector)
{
track &= 0x3F;
sector &= 0x1F;
if (track < 0 || track >= this.tracks)
return false;
if (sector < 0 || sector >= this.sectors)
return false;
return true;
}

View File

@ -6,6 +6,7 @@ public class AppleDiskAddress implements DiskAddress
private final int track;
private final int sector;
public final Disk owner;
private boolean zeroFlag;
public AppleDiskAddress (Disk owner, int block)
{
@ -19,15 +20,15 @@ public class AppleDiskAddress implements DiskAddress
public AppleDiskAddress (Disk owner, int track, int sector)
{
this.owner = owner;
this.track = track;
this.sector = sector;
this.block = track * owner.getSectorsPerTrack () + sector;
zeroFlag = (track & 0x40) != 0;
this.track = track & 0x3F;
this.sector = sector & 0x1F;
this.block = this.track * owner.getSectorsPerTrack () + this.sector;
}
@Override
public String toString ()
public boolean zeroFlag ()
{
return String.format ("[Block=%3d, Track=%2d, Sector=%2d]", block, track, sector);
return zeroFlag;
}
@Override
@ -65,4 +66,11 @@ public class AppleDiskAddress implements DiskAddress
{
return owner;
}
@Override
public String toString ()
{
return String.format ("[Block=%3d, Track=%2d, Sector=%2d, Zero=%s]", block, track,
sector, zeroFlag);
}
}

View File

@ -1,5 +1,6 @@
package com.bytezone.diskbrowser.dos;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@ -10,6 +11,7 @@ import com.bytezone.diskbrowser.disk.FormattedDisk;
import com.bytezone.diskbrowser.dos.DosDisk.FileType;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
abstract class AbstractCatalogEntry implements AppleFileSource
{
@ -22,6 +24,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource
protected int reportedSize;
protected boolean locked;
protected DataSource appleFile;
protected LocalDateTime lastModified;
protected DiskAddress catalogSectorDA;
protected final List<DiskAddress> dataSectors = new ArrayList<DiskAddress> ();
@ -34,33 +37,34 @@ abstract class AbstractCatalogEntry implements AppleFileSource
{
this.dosDisk = dosDisk;
this.disk = dosDisk.getDisk ();
this.disk = dosDisk.getDisk ();
this.catalogSectorDA = catalogSector;
reportedSize = HexFormatter.unsignedShort (entryBuffer, 33);
int type = entryBuffer[2] & 0xFF;
locked = (type & 0x80) > 0;
if ((type & 0x7F) == 0)
int type = entryBuffer[2] & 0x7F;
locked = (entryBuffer[2] & 0x80) != 0;
if (type == 0)
fileType = FileType.Text;
else if ((type & 0x01) > 0)
else if ((type == 0x01))
fileType = FileType.IntegerBasic;
else if ((type & 0x02) > 0)
else if ((type == 0x02))
fileType = FileType.ApplesoftBasic;
else if ((type & 0x04) > 0)
else if ((type == 0x04))
fileType = FileType.Binary;
else if ((type & 0x08) > 0)
else if ((type == 0x08))
fileType = FileType.SS;
else if ((type & 0x10) > 0)
else if ((type == 0x10))
fileType = FileType.Relocatable;
else if ((type & 0x20) > 0)
else if ((type == 0x20))
fileType = FileType.AA;
else if ((type & 0x40) > 0)
else if ((type == 0x40))
fileType = FileType.BB;
else
System.out.println ("Unknown file type : " + (type & 0x7F));
System.out.println ("Unknown file type : " + type);
name = getName ("", entryBuffer);
lastModified = Utility.getDateTime (entryBuffer, 0x1B);
// CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6
String base = String.format ("%s%s %03d ", (locked) ? "*" : " ", getFileType (),
(entryBuffer[33] & 0xFF));
@ -71,6 +75,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource
{
StringBuilder text = new StringBuilder (base);
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;

View File

@ -1,5 +1,6 @@
package com.bytezone.diskbrowser.dos;
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.dos.DosDisk.FileType;
import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -20,7 +21,7 @@ class CatalogEntry extends AbstractCatalogEntry
DiskAddress da = disk.getDiskAddress (entryBuffer[0], entryBuffer[1]);
// Loop through all TS-list sectors
loop: while (da.getBlock () > 0)
loop: while (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ())
{
if (dosDisk.stillAvailable (da))
dosDisk.sectorTypes[da.getBlock ()] = dosDisk.tsListSector;
@ -55,7 +56,7 @@ class CatalogEntry extends AbstractCatalogEntry
sectorBuffer[i], sectorBuffer[i + 1], name.trim ());
break loop;
}
if (da.getBlock () == 0)
if (da.getBlock () == 0 && !((AppleDiskAddress) da).zeroFlag ())
{
if (fileType != FileType.Text)
break;
@ -132,6 +133,10 @@ class CatalogEntry extends AbstractCatalogEntry
String lengthText = length == 0 ? "" : String.format ("$%4X %,6d", length, length);
String message = "";
String lockedFlag = (locked) ? "*" : " ";
if (dosDisk.dosVTOCSector.dosVersion >= 0x41)
{
message = lastModified.toString ().replace ('T', ' ');
}
if (reportedSize != actualSize)
message += "Bad size (" + reportedSize + ") ";
if (dataSectors.size () == 0)

View File

@ -4,6 +4,7 @@ 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
{
@ -12,73 +13,119 @@ class DosCatalogSector extends AbstractSector
"SS file", "Relocatable file", "AA file", "BB file" };
private static int CATALOG_ENTRY_SIZE = 35;
public DosCatalogSector (Disk disk, byte[] buffer, DiskAddress diskAddress)
private final DosDisk dosDisk;
public DosCatalogSector (DosDisk dosDisk, Disk disk, byte[] buffer,
DiskAddress diskAddress)
{
super (disk, buffer, diskAddress);
this.dosDisk = dosDisk;
}
@Override
public String createText ()
{
StringBuilder text = getHeader ("Catalog Sector");
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 (true)
{
if (buffer[i] == (byte) 0xFF)
{
addText (text, buffer, i + 0, 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));
addTextAndDecimal (text, buffer, i + 33, 2, "DEL: Sector count");
}
else if (buffer[i] > 0)
{
addText (text, buffer, i + 0, 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));
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
{
addText (text, buffer, i + 0, 2, "");
addText (text, buffer, i + 2, 1, "");
addText (text, buffer, i + 3, 4, "");
addText (text, buffer, i + 33, 2, "");
}
}
if (dos4)
createDos4Text (text, i);
else
createDos3Text (text, i);
}
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
private String getName (byte[] buffer, int offset)
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, "");
}
}
private String getName (byte[] buffer, int offset, int length)
{
StringBuilder text = new StringBuilder ();
int max = buffer[offset] == (byte) 0xFF ? 32 : 33;
for (int i = 3; i < max; i++)
// int max = buffer[offset] == (byte) 0xFF ? 32 : 33;
for (int i = offset; i < offset + length; i++)
{
int c = buffer[i + offset] & 0xFF;
int c = buffer[i] & 0xFF;
if (c == 136)
{
if (text.length () > 0)
@ -87,10 +134,10 @@ class DosCatalogSector extends AbstractSector
}
if (c > 127)
c -= c < 160 ? 64 : 128;
if (c < 32) // non-printable
if (c < 32) // non-printable
text.append ("^" + (char) (c + 64));
else
text.append ((char) c); // standard ascii
text.append ((char) c); // standard ascii
}
return text.toString ();
}

View File

@ -18,7 +18,7 @@ public class DosDisk extends AbstractFormattedDisk
private static final int CATALOG_TRACK = 17;
private static final int VTOC_SECTOR = 0;
private final DosVTOCSector dosVTOCSector;
final DosVTOCSector dosVTOCSector;
private final Color green = new Color (0, 200, 0);
private final DefaultMutableTreeNode volumeNode;
@ -152,6 +152,12 @@ public class DosDisk extends AbstractFormattedDisk
int track = sectorBuffer[1] & 0xFF;
int sector = sectorBuffer[2] & 0xFF;
if (dosVTOCSector.dosVersion >= 0x41)
{
track = track & 0x3F;
sector = sector & 0x1F;
}
if (!disk.isValidAddress (track, sector))
break;
@ -254,6 +260,28 @@ public class DosDisk extends AbstractFormattedDisk
return false;
}
public String getVersionText ()
{
switch (getVersion ())
{
case 0x01:
return "3.1";
case 0x02:
return "3.2";
case 0x03:
return "3.3";
case 0x41:
return "4.1";
default:
return "??";
}
}
public int getVersion ()
{
return dosVTOCSector.dosVersion;
}
private static int checkFormat (AppleDisk disk)
{
byte[] buffer = disk.readSector (0x11, 0x00);
@ -272,10 +300,10 @@ public class DosDisk extends AbstractFormattedDisk
// // return 0;
// }
int version = buffer[3];
if (version < -1 || version > 4)
int version = buffer[3] & 0xFF;
if (version > 0x42 && version != 0xFF)
{
System.out.println ("Bad version : " + buffer[3]);
System.out.printf ("Bad version : %02X%n", version);
return 0;
}
@ -347,7 +375,7 @@ public class DosDisk extends AbstractFormattedDisk
if (type == tsListSector)
return new DosTSListSector (getSectorFilename (da), disk, buffer, da);
if (type == catalogSector)
return new DosCatalogSector (disk, buffer, da);
return new DosCatalogSector (this, disk, buffer, da);
if (type == dataSector)
return new DefaultSector (
"Data Sector at " + address + " : " + getSectorFilename (da), disk, buffer, da);
@ -369,7 +397,7 @@ public class DosDisk extends AbstractFormattedDisk
{
String newLine = String.format ("%n");
String line = "- --- --- ------------------------------ ----- -------------"
+ " -- ---- ----------------" + newLine;
+ " -- ---- -------------------" + newLine;
StringBuilder text = new StringBuilder ();
text.append (String.format ("Disk : %s%n%n", getAbsolutePath ()));
text.append ("L Typ Len Name Addr"
@ -405,33 +433,33 @@ public class DosDisk extends AbstractFormattedDisk
}
/* From http://apple2history.org/history/ah15/
*
There were actually three versions of DOS 3.3 that Apple released without
*
There were actually three versions of DOS 3.3 that Apple released without
bumping the version number:
The first version that was released had FPBASIC and INTBASIC files that were 50
sectors in size.
The second version of DOS 3.3, often referred to as DOS 3.3e, appeared at the
time the Apple IIe was released. In this version, the FPBASIC and INTBASIC files
were 42 sectors in size. The changes introduced at that time included code to turn
off the IIe 80-column card at boot time, and an attempt to fix a bug in the APPEND
command. This fix reportedly introduced an even worse bug, but as the command was
not heavily used it did not make much of an impact on most programmers. The APPEND
The second version of DOS 3.3, often referred to as DOS 3.3e, appeared at the
time the Apple IIe was released. In this version, the FPBASIC and INTBASIC files
were 42 sectors in size. The changes introduced at that time included code to turn
off the IIe 80-column card at boot time, and an attempt to fix a bug in the APPEND
command. This fix reportedly introduced an even worse bug, but as the command was
not heavily used it did not make much of an impact on most programmers. The APPEND
fix was applied by utilizing some formerly unused space in the DOS 3.3 code.
The third version of DOS 3.3 appeared just before the first release of ProDOS.
The only mention of this in the press was in the DOSTalk column of Softalk magazine.
This final version of DOS 3.3 included a different fix for the APPEND bug, using
The third version of DOS 3.3 appeared just before the first release of ProDOS.
The only mention of this in the press was in the DOSTalk column of Softalk magazine.
This final version of DOS 3.3 included a different fix for the APPEND bug, using
another bit of unused space in DOS 3.3.
With regard to the FPBASIC and INTBASIC files: There were three differences between
the 50 sector and the 42 sector versions of the INTBASIC file. Firstly, the
$F800-$FFFF section was removed. This area was the code for the Monitor, and with
the changes introduced in the Apple IIe, it could cause some things to break if
the older Monitor code was executed. Secondly, a FOR/NEXT bug in Integer BASIC was
fixed. Finally, there was a three-byte bug in the Programmers Aid ROM #1 chip.
The code for this chip was included in the INTBASIC file, and could therefore be
With regard to the FPBASIC and INTBASIC files: There were three differences between
the 50 sector and the 42 sector versions of the INTBASIC file. Firstly, the
$F800-$FFFF section was removed. This area was the code for the Monitor, and with
the changes introduced in the Apple IIe, it could cause some things to break if
the older Monitor code was executed. Secondly, a FOR/NEXT bug in Integer BASIC was
fixed. Finally, there was a three-byte bug in the Programmers Aid ROM #1 chip.
The code for this chip was included in the INTBASIC file, and could therefore be
patched.
*/
}

View File

@ -4,12 +4,13 @@ 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 DosVTOCSector extends AbstractSector
{
DosDisk parentDisk;
int volume;
int DOSVersion;
int dosVersion; // 1, 2, 3 or 0x41...
int maxTSPairs;
int lastAllocTrack;
int direction;
@ -25,7 +26,7 @@ class DosVTOCSector extends AbstractSector
super (disk, buffer, diskAddress);
this.parentDisk = parentDisk;
DOSVersion = buffer[3];
dosVersion = buffer[3];
volume = buffer[6] & 0xFF;
maxTSPairs = buffer[39];
lastAllocTrack = buffer[48];
@ -38,6 +39,63 @@ class DosVTOCSector extends AbstractSector
@Override
public String createText ()
{
return dosVersion <= 3 ? createDosText () : createOtherText ();
}
private String createOtherText ()
{
StringBuilder text = getHeader ("DOS 4.1 VTOC Sector");
addText (text, buffer, 0, 1, "Not used");
addText (text, buffer, 1, 2, "First directory track/sector");
addText (text, buffer, 3, 1, "DOS release number");
addText (text, buffer, 4, 1, "Build number");
addText (text, buffer, 5, 1, "Ram DOS " + (char) (buffer[5] & 0x7F));
addTextAndDecimal (text, buffer, 6, 1, "Diskette volume");
addText (text, buffer, 7, 1, "Volume type " + (char) (buffer[7] & 0x7F));
int ptr = 8;
addText (text, buffer, ptr, 4, "Volume name: " + getName (buffer, ptr));
for (int j = 4; j < 24; j += 4)
addText (text, buffer, ptr + j, 4, "");
addText (text, buffer, 0x20, 3,
"Date/time initialised: " + Utility.getDateTime (buffer, 0x20));
addText (text, buffer, 0x23, 3, "");
addText (text, buffer, 0x26, 1, "Not used");
addTextAndDecimal (text, buffer, 0x27, 1, "Maximum TS pairs");
addText (text, buffer, 0x28, 2, "Volume library");
addText (text, buffer, 0x2A, 3,
"Date/time modified: " + Utility.getDateTime (buffer, 0x2A));
addText (text, buffer, 0x2D, 3, "");
addTextAndDecimal (text, buffer, 0x30, 1, "Last allocated track");
addText (text, buffer, 0x31, 1, "Direction to look when allocating the next file");
addText (text, buffer, 0x32, 2, "Not used");
addTextAndDecimal (text, buffer, 0x34, 1, "Maximum tracks");
addTextAndDecimal (text, buffer, 0x35, 1, "Maximum sectors");
addTextAndDecimal (text, buffer, 0x36, 2, "Bytes per sector");
boolean bootSectorEmpty = parentDisk.getDisk ().isSectorEmpty (0);
for (int i = 0x38; i <= 0xC3; i += 4)
{
String extra = "";
if (i == 0x38 && bootSectorEmpty)
extra = "(unusable)";
else if (i == 124)
extra = "(VTOC and Catalog)";
addText (text, buffer, i, 4, String.format ("Track %02X %s %s", (i - 56) / 4,
getBitmap (buffer[i], buffer[i + 1]), extra));
}
text.deleteCharAt (text.length () - 1);
return text.toString ();
}
private String createDosText ()
{
StringBuilder text = getHeader ("VTOC Sector");
addText (text, buffer, 0, 1, "Not used");
@ -138,11 +196,35 @@ class DosVTOCSector extends AbstractSector
return block;
}
// duplicate of DosCatalogSector.getName()
private String getName (byte[] buffer, int offset)
{
StringBuilder text = new StringBuilder ();
int max = 24;
for (int i = 0; i < max; i++)
{
int c = buffer[i + offset] & 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 ();
}
@Override
public String toString ()
{
StringBuffer text = new StringBuffer ();
text.append ("DOS version : 3." + DOSVersion);
text.append ("DOS version : 3." + dosVersion);
text.append ("\nVolume : " + volume);
text.append ("\nMax TS pairs : " + maxTSPairs);
text.append ("\nLast allocated T : " + lastAllocTrack);

View File

@ -7,6 +7,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.disk.FormattedDisk;
@ -152,7 +153,7 @@ class DiskLayoutSelection implements Iterable<DiskAddress>
highlights.clear ();
if (list != null)
for (DiskAddress da : list)
if (da != null && da.getBlock () > 0)
if (da != null && (da.getBlock () > 0 || ((AppleDiskAddress) da).zeroFlag ()))
highlights.add (da);
}

View File

@ -2,6 +2,8 @@ package com.bytezone.diskbrowser.utilities;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
@ -58,6 +60,24 @@ public class Utility
return false;
}
public static LocalDateTime getDateTime (byte[] buffer, int ptr)
{
try
{
int[] val = new int[6];
for (int i = 0; i < 6; i++)
val[i] = Integer.parseInt (String.format ("%02X", buffer[ptr + i] & 0xFF));
LocalDateTime date =
LocalDateTime.of (val[3] + 2000, val[5], val[4], val[2], val[1], val[0]);
return date;
}
catch (DateTimeException e)
{
return null;
}
}
public static boolean matches (byte[] buffer, int offset, byte[] key)
{
int ptr = 0;