mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2026-01-22 17:16:11 +00:00
Now identifying non-standard disk formatting (limited to non-standard nibble images and DOS 3.x).
This commit is contained in:
@@ -75,8 +75,21 @@ public class DosDiskFactory implements DiskFactory {
|
||||
|
||||
// ... and then test for DOS VTOC etc. Passing track number along to hopefully handle it later!
|
||||
for (TrackSectorDevice device : devices) {
|
||||
if (check(device)) {
|
||||
ctx.disks.add(new DosFormatDisk(ctx.source.getName(), device));
|
||||
if (device.is(Hint.NONSTANDARD_NIBBLE_IMAGE)) {
|
||||
// The assumption is that we need to scan (and keep scanning) for possible DOS catalogs...
|
||||
for (int catalogTrack = 3; catalogTrack < device.getGeometry().tracksOnDisk(); catalogTrack++) {
|
||||
try {
|
||||
if (check(device, catalogTrack)) {
|
||||
ctx.disks.add(new DosFormatDisk(ctx.source.getName(), device, catalogTrack));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// ignored. Sort of expected.
|
||||
}
|
||||
}
|
||||
}
|
||||
// ... otherwise, just do the assumed track 17 check!
|
||||
else if (check(device, CATALOG_TRACK)) {
|
||||
ctx.disks.add(new DosFormatDisk(ctx.source.getName(), device, CATALOG_TRACK));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,8 +97,8 @@ public class DosDiskFactory implements DiskFactory {
|
||||
/**
|
||||
* Test this image order by looking for a likely DOS VTOC and set of catalog sectors.
|
||||
*/
|
||||
public boolean check(TrackSectorDevice device) {
|
||||
DataBuffer vtoc = device.readSector(CATALOG_TRACK, VTOC_SECTOR);
|
||||
public boolean check(TrackSectorDevice device, final int catalogTrack) {
|
||||
DataBuffer vtoc = device.readSector(catalogTrack, VTOC_SECTOR);
|
||||
int nextTrack = vtoc.getUnsignedByte(0x01);
|
||||
int nextSector = vtoc.getUnsignedByte(0x02);
|
||||
int tracksPerDisk = vtoc.getUnsignedByte(0x34);
|
||||
@@ -96,13 +109,13 @@ public class DosDiskFactory implements DiskFactory {
|
||||
}
|
||||
if (nextSector != 0 && nextTrack == 0) {
|
||||
// Some folks zeroed out the next track field, so try the same as VTOC (T17)
|
||||
nextTrack = DosFormatDisk.CATALOG_TRACK;
|
||||
nextTrack = catalogTrack;
|
||||
}
|
||||
// Start with VTOC test
|
||||
boolean good = nextTrack <= tracksPerDisk // expect catalog to be sensible
|
||||
&& nextSector > 0 // expect catalog to be...
|
||||
&& nextSector < sectorsPerTrack // ... a legitimate sector
|
||||
&& tracksPerDisk >= CATALOG_TRACK // expect sensible...
|
||||
&& tracksPerDisk >= catalogTrack // expect sensible...
|
||||
&& tracksPerDisk <= 50 // ... tracks per disk
|
||||
&& sectorsPerTrack > 10 // expect sensible...
|
||||
&& sectorsPerTrack <= 32; // ... sectors per disk
|
||||
|
||||
@@ -120,14 +120,16 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
}
|
||||
}
|
||||
|
||||
private TrackSectorDevice device;
|
||||
private final TrackSectorDevice device;
|
||||
private final int catalogTrack;
|
||||
|
||||
/**
|
||||
* Constructor for DosFormatDisk.
|
||||
*/
|
||||
public DosFormatDisk(String filename, TrackSectorDevice device) {
|
||||
public DosFormatDisk(String filename, TrackSectorDevice device, int catalogTrack) {
|
||||
super(filename, device.get(Source.class).orElseThrow());
|
||||
this.device = device;
|
||||
this.catalogTrack = catalogTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +142,7 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
* be 140K in size.
|
||||
*/
|
||||
public static DosFormatDisk[] create(String filename, TrackSectorDevice device) {
|
||||
DosFormatDisk disk = new DosFormatDisk(filename, device);
|
||||
DosFormatDisk disk = new DosFormatDisk(filename, device, CATALOG_TRACK);
|
||||
disk.format();
|
||||
return new DosFormatDisk[] { disk };
|
||||
}
|
||||
@@ -152,9 +154,9 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
public static DosFormatDisk[] create(String filename, BlockDevice device, TrackSectorToBlockStrategy... strategies) {
|
||||
assert strategies.length == 2;
|
||||
assert device.getGeometry().blocksOnDevice() == 1600;
|
||||
DosFormatDisk disk1 = new DosFormatDisk(filename, new BlockToTrackSectorAdapter(device, strategies[0]));
|
||||
DosFormatDisk disk1 = new DosFormatDisk(filename, new BlockToTrackSectorAdapter(device, strategies[0]), CATALOG_TRACK);
|
||||
disk1.format();
|
||||
DosFormatDisk disk2 = new DosFormatDisk(filename, new BlockToTrackSectorAdapter(device, strategies[1]));
|
||||
DosFormatDisk disk2 = new DosFormatDisk(filename, new BlockToTrackSectorAdapter(device, strategies[1]), CATALOG_TRACK);
|
||||
disk2.format();
|
||||
return new DosFormatDisk[] { disk1, disk2 };
|
||||
}
|
||||
@@ -186,7 +188,7 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
}
|
||||
if (sector != 0 && track == 0) {
|
||||
// Some folks zeroed out the next track field, so try the same as VTOC (T17)
|
||||
track = CATALOG_TRACK;
|
||||
track = catalogTrack;
|
||||
}
|
||||
final Set<DosSectorAddress> visits = new HashSet<>();
|
||||
while (sector != 0) { // bug fix: iterate through all catalog _sectors_
|
||||
@@ -320,14 +322,14 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
* Return the VTOC (Volume Table Of Contents).
|
||||
*/
|
||||
public byte[] readVtoc() {
|
||||
return readSector(CATALOG_TRACK, VTOC_SECTOR);
|
||||
return readSector(catalogTrack, VTOC_SECTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the VTOC (Volume Table Of Contents) to disk.
|
||||
*/
|
||||
public void writeVtoc(byte[] vtoc) {
|
||||
writeSector(CATALOG_TRACK, VTOC_SECTOR, vtoc);
|
||||
writeSector(catalogTrack, VTOC_SECTOR, vtoc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,6 +394,9 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
list.add(new DiskInformation(textBundle.get("DosFormatDisk.UsedSectors"), getUsedSectors())); //$NON-NLS-1$
|
||||
list.add(new DiskInformation(textBundle.get("DosFormatDisk.TracksOnDisk"), getTracks())); //$NON-NLS-1$
|
||||
list.add(new DiskInformation(textBundle.get("DosFormatDisk.SectorsOnDisk"), getSectors())); //$NON-NLS-1$
|
||||
if (catalogTrack != CATALOG_TRACK) {
|
||||
list.add(new DiskInformation("Catalog Track (non-standard)", catalogTrack));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -645,28 +650,28 @@ public class DosFormatDisk extends FormattedDisk {
|
||||
byte[] data = new byte[SECTOR_SIZE];
|
||||
for (int sector=firstCatalogSector; sector > 0; sector--) {
|
||||
if (sector > 1) {
|
||||
data[0x01] = CATALOG_TRACK;
|
||||
data[0x01] = (byte)catalogTrack;
|
||||
data[0x02] = (byte)(sector-1);
|
||||
} else {
|
||||
data[0x01] = 0;
|
||||
data[0x02] = 0;
|
||||
}
|
||||
writeSector(CATALOG_TRACK, sector, data);
|
||||
writeSector(catalogTrack, sector, data);
|
||||
}
|
||||
// create VTOC
|
||||
data[0x01] = CATALOG_TRACK; // track# of first catalog sector
|
||||
data[0x01] = (byte)catalogTrack; // track# of first catalog sector
|
||||
data[0x02] = (byte)firstCatalogSector; // sector# of first catalog sector
|
||||
data[0x03] = 3; // DOS 3.3 formatted
|
||||
data[0x06] = (byte)254; // DISK VOLUME#
|
||||
data[0x27] = TRACK_SECTOR_PAIRS; // maximum # of T/S pairs in a sector
|
||||
data[0x30] = CATALOG_TRACK+1; // last track where sectors allocated
|
||||
data[0x30] = (byte)(catalogTrack+1); // last track where sectors allocated
|
||||
data[0x31] = 1; // direction of allocation
|
||||
data[0x34] = (byte)tracksPerDisk; // tracks per disk
|
||||
data[0x35] = (byte)sectorsPerTrack; // sectors per track
|
||||
data[0x37] = 1; // 36/37 are # of bytes per sector
|
||||
for (int track=0; track<tracksPerDisk; track++) {
|
||||
for (int sector=0; sector<sectorsPerTrack; sector++) {
|
||||
if (track == 0 || track == CATALOG_TRACK) {
|
||||
if (track == 0 || track == catalogTrack) {
|
||||
setSectorUsed(track, sector, data);
|
||||
} else {
|
||||
setSectorFree(track, sector, data);
|
||||
|
||||
@@ -31,6 +31,7 @@ import static org.applecommander.device.nibble.NibbleUtil.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
/**
|
||||
@@ -121,6 +122,7 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
private final DiskMarker[] diskMarkers;
|
||||
private final NibbleDiskCodec dataCodec;
|
||||
private final Geometry geometry;
|
||||
private final Set<Hint> hints;
|
||||
|
||||
private TrackSectorNibbleDevice(NibbleTrackReaderWriter trackReaderWriter, NibbleDiskCodec dataCodec,
|
||||
int sectorsPerTrack, DiskMarker... diskMarkers) {
|
||||
@@ -128,6 +130,9 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
this.diskMarkers = diskMarkers;
|
||||
this.dataCodec = dataCodec;
|
||||
this.geometry = new Geometry(trackReaderWriter.getTracksOnDevice(), sectorsPerTrack);
|
||||
this.hints = diskMarkers.length == 1
|
||||
? Set.of(Hint.NIBBLE_SECTOR_ORDER)
|
||||
: Set.of(Hint.NIBBLE_SECTOR_ORDER, Hint.NONSTANDARD_NIBBLE_IMAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,7 +142,7 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
|
||||
@Override
|
||||
public boolean is(Hint hint) {
|
||||
return hint == Hint.NIBBLE_SECTOR_ORDER;
|
||||
return hints.contains(hint);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,11 +19,29 @@
|
||||
*/
|
||||
package org.applecommander.hint;
|
||||
|
||||
/**
|
||||
* Helpful hints that indicate something "interesting" (to code at least) about this <em>thing</em>.
|
||||
* @see HintProvider
|
||||
*/
|
||||
public enum Hint {
|
||||
/** "Nibble" sector order is really physical sector order. */
|
||||
NIBBLE_SECTOR_ORDER,
|
||||
/** Sectors are in DOS 3.3 sector order. */
|
||||
DOS_SECTOR_ORDER,
|
||||
/**
|
||||
* Sectors are organized in ProDOS sector order. Typically, this is initially read as a ProDOS block
|
||||
* and (if needed), mapped back to DOS tracks and sectors.
|
||||
*/
|
||||
PRODOS_BLOCK_ORDER,
|
||||
/** Temporary flag to indicate this image was automagically extracted from a SHK or SDK image. */
|
||||
ORIGIN_SHRINKIT,
|
||||
/** Origin for this image was a 2IMG image. */
|
||||
UNIVERSAL_DISK_IMAGE,
|
||||
DISK_COPY_IMAGE
|
||||
/** Origin for this image was a DiskCopy image. */
|
||||
DISK_COPY_IMAGE,
|
||||
/**
|
||||
* This flag is used to indicate a protected disk. Meaning factories may need to search a bit more
|
||||
* for disk markers.
|
||||
*/
|
||||
NONSTANDARD_NIBBLE_IMAGE
|
||||
}
|
||||
|
||||
@@ -1826,7 +1826,7 @@ public class DiskExplorerTab {
|
||||
BlockDevice blockDevice = new TrackSectorToBlockAdapter(targetDevice, TrackSectorToBlockAdapter.BlockStyle.CPM);
|
||||
yield new CpmFormatDisk(filename, blockDevice);
|
||||
}
|
||||
case DosFormatDisk ignored -> new DosFormatDisk(filename, targetDevice);
|
||||
case DosFormatDisk ignored -> new DosFormatDisk(filename, targetDevice, DosFormatDisk.CATALOG_TRACK);
|
||||
case GutenbergFormatDisk ignored -> new GutenbergFormatDisk(filename, targetDevice);
|
||||
case NakedosFormatDisk ignored -> new NakedosFormatDisk(filename, targetDevice);
|
||||
case PascalFormatDisk ignored -> {
|
||||
|
||||
Reference in New Issue
Block a user