diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/DiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/DiskFactory.java
index e1b1f5a4..5f4e183d 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/DiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/DiskFactory.java
@@ -33,6 +33,33 @@ import org.applecommander.util.DataBuffer;
import java.util.ArrayList;
import java.util.List;
+/**
+ * The DiskFactory inspects a given Source inspect it to see if it matches filesystem structure(s).
+ * Invoke via {@link Disks#inspect(Source)} which will return a Context. The Context _can be empty_.
+ * If this is the case, devices can be created via the {@link Context#blockDevice()} and
+ * {@link Context#trackSectorDevice()} builders.
+ *
+ * The builders follow the observation about what each filesystem currently uses:
+ *
+ * OS 13-sector 16-sector 800K HDV
+ * ========= ========= ========== ====== ========
+ * CP/M - CP/M - -
+ * DOS Physical DOS Pascal -
+ * Gutenberg - DOS - -
+ * NakeDOS - Physical - -
+ * Pascal - Pascal Pascal -
+ * ProDOS - Pascal Pascal Pascal
+ * RDOS Physical DOS - -
+ *
+ *
+ * - 13-sector disks are only track/sector devices. (And RDOS has a unique mapping to 256 byte blocks).
+ * - 16-sector disks have a variety of sector mappings. It can also double as a "standard" 512 byte block,
+ * as well as a unique CP/M 1024 block device.
+ * - 800K disks are only standard 512 byte block (Prodos or Pascal). OzDOS and UniDOS do have unique
+ * mappings to track and sector, but logically, they are block devices.
+ * - Anything else (larger than 800K) are "hard-disk" images and only blocks.
+ *
+ */
public interface DiskFactory {
void inspect(Context ctx);
@@ -40,9 +67,6 @@ public interface DiskFactory {
public final Source source;
public final NibbleTrackReaderWriter nibbleTrackReaderWriter;
public final List disks = new ArrayList<>();
- // Note: These are only set if we *KNOW* what they are. Except DSK images, where both will be set.
- public final BlockDevice blockDevice;
- public final TrackSectorDevice sectorDevice;
public Context(Source source) {
this.source = source;
@@ -50,26 +74,11 @@ public interface DiskFactory {
/* Does it have the WOZ1 or WOZ2 header? */
int signature = source.readBytes(0, 4).readInt();
if (WozImage.WOZ1_MAGIC == signature || WozImage.WOZ2_MAGIC == signature) {
- blockDevice = null;
nibbleTrackReaderWriter = new WozImage(source);
- sectorDevice = identifySectorsPerTrack(nibbleTrackReaderWriter);
} else if (source.is(Hint.NIBBLE_SECTOR_ORDER) || source.isApproxEQ(DiskConstants.APPLE_140KB_NIBBLE_DISK)) {
- blockDevice = null;
nibbleTrackReaderWriter = new NibbleImage(source);
- sectorDevice = identifySectorsPerTrack(nibbleTrackReaderWriter);
- } else if (source.is(Hint.PRODOS_BLOCK_ORDER) || source.getSize() > DiskConstants.APPLE_400KB_DISK || source.extensionLike("po")) {
- nibbleTrackReaderWriter = null;
- blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
- sectorDevice = null;
- } else if (source.is(Hint.DOS_SECTOR_ORDER) || source.extensionLike("do")) {
- nibbleTrackReaderWriter = null;
- blockDevice = null;
- sectorDevice = new DosOrderedTrackSectorDevice(source, Hint.DOS_SECTOR_ORDER);
} else {
nibbleTrackReaderWriter = null;
- // Could be either - most likely the nebulous "dsk" extension
- blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
- sectorDevice = new DosOrderedTrackSectorDevice(source);
}
}
@@ -111,5 +120,141 @@ public interface DiskFactory {
// Failure
return null;
}
+
+ public BlockDeviceBuilder blockDevice() {
+ return new BlockDeviceBuilder(this);
+ }
+ public static class BlockDeviceBuilder {
+ private Context ctx;
+ private List devices = new ArrayList<>();
+ private BlockDeviceBuilder(Context ctx) {
+ this.ctx = ctx;
+ }
+ public BlockDeviceBuilder include16Sector(Hint hint) {
+ if (ctx.nibbleTrackReaderWriter != null) {
+ TrackSectorDevice nibble = ctx.identifySectorsPerTrack(ctx.nibbleTrackReaderWriter);
+ if (nibble != null) {
+ TrackSectorDevice converted = switch (hint) {
+ case DOS_SECTOR_ORDER -> SkewedTrackSectorDevice.physicalToDosSkew(nibble);
+ case PRODOS_BLOCK_ORDER -> SkewedTrackSectorDevice.physicalToPascalSkew(nibble);
+ case NIBBLE_SECTOR_ORDER -> nibble;
+ default -> throw new RuntimeException("wrong hint type: " + hint);
+ };
+ devices.add(new TrackSectorToBlockAdapter(converted, TrackSectorToBlockAdapter.BlockStyle.PRODOS));
+ }
+ }
+ else if (ctx.source.isApproxEQ(DiskConstants.APPLE_140KB_DISK)) {
+ if (ctx.source.is(Hint.DOS_SECTOR_ORDER) || ctx.source.extensionLike("do")) {
+ TrackSectorDevice doDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.DOS_SECTOR_ORDER);
+ TrackSectorDevice poDevice = SkewedTrackSectorDevice.dosToPascalSkew(doDevice);
+ devices.add(new TrackSectorToBlockAdapter(poDevice, TrackSectorToBlockAdapter.BlockStyle.PRODOS));
+ }
+ else if (ctx.source.is(Hint.PRODOS_BLOCK_ORDER) || ctx.source.extensionLike("po")) {
+ devices.add(new ProdosOrderedBlockDevice(ctx.source, BlockDevice.STANDARD_BLOCK_SIZE));
+ }
+ else {
+ devices.add(new ProdosOrderedBlockDevice(ctx.source, BlockDevice.STANDARD_BLOCK_SIZE));
+ TrackSectorDevice doDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.DOS_SECTOR_ORDER);
+ TrackSectorDevice poDevice = SkewedTrackSectorDevice.dosToPascalSkew(doDevice);
+ devices.add(new TrackSectorToBlockAdapter(poDevice, TrackSectorToBlockAdapter.BlockStyle.PRODOS));
+ }
+ }
+ return this;
+ }
+ public BlockDeviceBuilder include800K() {
+ if (ctx.source.isApproxEQ(DiskConstants.APPLE_800KB_DISK)) {
+ devices.add(new ProdosOrderedBlockDevice(ctx.source, BlockDevice.STANDARD_BLOCK_SIZE));
+ }
+ return this;
+ }
+ public BlockDeviceBuilder includeHDV() {
+ if (ctx.source.getSize() > DiskConstants.APPLE_800KB_DISK) {
+ devices.add(new ProdosOrderedBlockDevice(ctx.source, BlockDevice.STANDARD_BLOCK_SIZE));
+ }
+ return this;
+ }
+ public List get() {
+ return devices;
+ }
+ }
+
+ public TrackSectorDeviceBuilder trackSectorDevice() {
+ return new TrackSectorDeviceBuilder(this);
+ }
+ public static class TrackSectorDeviceBuilder {
+ private Context ctx;
+ private List devices = new ArrayList<>();
+ private TrackSectorDeviceBuilder(Context ctx) {
+ this.ctx = ctx;
+ }
+ public TrackSectorDeviceBuilder include13Sector() {
+ if (ctx.nibbleTrackReaderWriter != null) {
+ TrackSectorDevice nibble = ctx.identifySectorsPerTrack(ctx.nibbleTrackReaderWriter);
+ if (nibble != null && nibble.getGeometry().sectorsPerTrack() == 13) {
+ devices.add(nibble);
+ }
+ }
+ return this;
+ }
+ public TrackSectorDeviceBuilder include16Sector(Hint hint) {
+ if (ctx.nibbleTrackReaderWriter != null) {
+ TrackSectorDevice nibble = ctx.identifySectorsPerTrack(ctx.nibbleTrackReaderWriter);
+ if (nibble != null && nibble.getGeometry().sectorsPerTrack() == 16) {
+ TrackSectorDevice converted = switch (hint) {
+ case DOS_SECTOR_ORDER -> SkewedTrackSectorDevice.physicalToDosSkew(nibble);
+ case PRODOS_BLOCK_ORDER -> SkewedTrackSectorDevice.physicalToPascalSkew(nibble);
+ case NIBBLE_SECTOR_ORDER -> nibble;
+ default -> throw new RuntimeException("wrong hint type: " + hint);
+ };
+ devices.add(converted);
+ }
+ } else if (ctx.source.isApproxEQ(DiskConstants.APPLE_140KB_DISK)) {
+ TrackSectorDevice doDevice = null;
+ TrackSectorDevice poDevice = null;
+ if (ctx.source.is(Hint.DOS_SECTOR_ORDER) || ctx.source.extensionLike("do")) {
+ doDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.DOS_SECTOR_ORDER);
+ }
+ else if (ctx.source.is(Hint.PRODOS_BLOCK_ORDER) || ctx.source.extensionLike("po")) {
+ poDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.PRODOS_BLOCK_ORDER);
+ }
+ else {
+ doDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.DOS_SECTOR_ORDER);
+ poDevice = new DosOrderedTrackSectorDevice(ctx.source, Hint.PRODOS_BLOCK_ORDER);
+ }
+ switch (hint) {
+ case DOS_SECTOR_ORDER -> {
+ if (doDevice != null) {
+ devices.add(doDevice);
+ }
+ if (poDevice != null) {
+ TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(poDevice);
+ devices.add(SkewedTrackSectorDevice.physicalToDosSkew(tmp));
+ }
+ }
+ case PRODOS_BLOCK_ORDER -> {
+ if (doDevice != null) {
+ TrackSectorDevice tmp = SkewedTrackSectorDevice.dosToPhysicalSkew(doDevice);
+ devices.add(SkewedTrackSectorDevice.physicalToPascalSkew(tmp));
+ }
+ if (poDevice != null) {
+ devices.add(poDevice);
+ }
+ }
+ case NIBBLE_SECTOR_ORDER -> {
+ if (doDevice != null) {
+ devices.add(SkewedTrackSectorDevice.dosToPhysicalSkew(doDevice));
+ }
+ if (poDevice != null) {
+ devices.add(SkewedTrackSectorDevice.pascalToPhysicalSkew(poDevice));
+ }
+ }
+ }
+ }
+ return this;
+ }
+ public List get() {
+ return devices;
+ }
+ }
}
}
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/cpm/CpmDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/cpm/CpmDiskFactory.java
index 129f0787..bb241d04 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/cpm/CpmDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/cpm/CpmDiskFactory.java
@@ -19,15 +19,11 @@
*/
package com.webcodepro.applecommander.storage.os.cpm;
-import com.webcodepro.applecommander.storage.DiskConstants;
import com.webcodepro.applecommander.storage.DiskFactory;
import org.applecommander.device.*;
import org.applecommander.hint.Hint;
import org.applecommander.util.DataBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Test this disk for a likely CP/M filesystem.
* @see CP/M 2.2
@@ -36,42 +32,18 @@ import java.util.List;
public class CpmDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- List devices = new ArrayList<>();
- if (ctx.sectorDevice != null) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- // cheating so I don't need to figure out physical to CP/M skew!
- TrackSectorDevice dosSkew = SkewedTrackSectorDevice.physicalToDosSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.dosToCpmSkew(dosSkew));
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- devices.add(SkewedTrackSectorDevice.dosToCpmSkew(ctx.sectorDevice));
- }
- else if (ctx.sectorDevice.is(Hint.PRODOS_BLOCK_ORDER)) {
- devices.add(SkewedTrackSectorDevice.pascalToCpmSkew(ctx.sectorDevice));
- }
- else {
- // Presumably a DSK image, so DO and PO are possibilities
- devices.add(SkewedTrackSectorDevice.dosToCpmSkew(ctx.sectorDevice));
- devices.add(SkewedTrackSectorDevice.pascalToCpmSkew(ctx.sectorDevice));
- }
- }
- else if (ctx.blockDevice != null) {
- if (ctx.blockDevice.getGeometry().blocksOnDevice() == 280) {
- TrackSectorDevice device = new BlockToTrackSectorAdapter(ctx.blockDevice,
- new ProdosBlockToTrackSectorAdapterStrategy());
- devices.add(SkewedTrackSectorDevice.pascalToCpmSkew(device));
- }
- }
- // Any devices in the list are expected to be in CP/M block order
- devices.forEach(device -> {
- if (device.getGeometry().sectorsPerDisk() == 560) {
- BlockDevice blockDevice = new TrackSectorToBlockAdapter(device, TrackSectorToBlockAdapter.BlockStyle.CPM);
- CpmFormatDisk disk = new CpmFormatDisk(ctx.source.getName(), blockDevice);
- if (check(disk)) {
- ctx.disks.add(disk);
- }
- }
- });
+ ctx.trackSectorDevice()
+ .include16Sector(Hint.DOS_SECTOR_ORDER)
+ .get()
+ .forEach(device -> {
+ BlockDevice blockDevice = new TrackSectorToBlockAdapter(
+ SkewedTrackSectorDevice.dosToCpmSkew(device),
+ TrackSectorToBlockAdapter.BlockStyle.CPM);
+ CpmFormatDisk disk = new CpmFormatDisk(ctx.source.getName(), blockDevice);
+ if (check(disk)) {
+ ctx.disks.add(disk);
+ }
+ });
}
public boolean check(CpmFormatDisk disk) {
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosDiskFactory.java
index 1a6bc6ab..f14dc990 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosDiskFactory.java
@@ -21,14 +21,11 @@ package com.webcodepro.applecommander.storage.os.dos33;
import com.webcodepro.applecommander.storage.DiskFactory;
import org.applecommander.device.BlockToTrackSectorAdapter;
-import org.applecommander.device.ProdosBlockToTrackSectorAdapterStrategy;
-import org.applecommander.device.SkewedTrackSectorDevice;
import org.applecommander.device.TrackSectorDevice;
import org.applecommander.hint.Hint;
import org.applecommander.os.dos.OzdosAdapterStrategy;
import org.applecommander.os.dos.UnidosAdapterStrategy;
import org.applecommander.util.DataBuffer;
-import static com.webcodepro.applecommander.storage.DiskConstants.*;
import static com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk.*;
import java.util.*;
@@ -37,53 +34,45 @@ public class DosDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
// It seems easiest to gather all possibilities first...
- List devices = new ArrayList<>();
- // We need DOS ordered...
- if (ctx.sectorDevice != null) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- if (ctx.sectorDevice.getGeometry().sectorsPerTrack() == 13) {
- // 13-sector = DOS 3.2 = physical sector order
- devices.add(ctx.sectorDevice);
- }
- else {
- // 16-sector = DOS 3.3 = DOS sector order
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(ctx.sectorDevice));
- }
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- devices.add(ctx.sectorDevice);
- }
- else if (ctx.sectorDevice.is(Hint.PRODOS_BLOCK_ORDER)) {
- // Cheating a bit...
- TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(tmp));
- }
- else {
- // Likely a DSK image, need to pick between DO and PO...
- TrackSectorDevice device1 = ctx.sectorDevice;
- // Cheating a bit...
- TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- TrackSectorDevice device2 = SkewedTrackSectorDevice.physicalToDosSkew(tmp);
+ final List devices = new ArrayList<>();
- int count1 = count(device1);
- int count2 = count(device2);
- // Note this assumes DO was the first device in the list to give it an edge
- if (count1 >= count2) devices.add(device1);
- else devices.add(device2);
- }
- }
- else if (ctx.blockDevice != null) {
- if (ctx.blockDevice.getGeometry().blocksOnDevice() == PRODOS_BLOCKS_ON_140KB_DISK) {
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, new ProdosBlockToTrackSectorAdapterStrategy()));
- }
- else if (ctx.blockDevice.getGeometry().blocksOnDevice() == PRODOS_BLOCKS_ON_800KB_DISK) {
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, UnidosAdapterStrategy.UNIDOS_DISK_1));
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, UnidosAdapterStrategy.UNIDOS_DISK_2));
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, OzdosAdapterStrategy.OZDOS_DISK_1));
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, OzdosAdapterStrategy.OZDOS_DISK_2));
+ // Look for DOS on 13-sector and 16-sector devices:
+ devices.addAll(ctx.trackSectorDevice()
+ .include13Sector()
+ .include16Sector(Hint.DOS_SECTOR_ORDER)
+ .get());
+ if (devices.size() == 2) {
+ // Likely a DSK image, need to pick between DO and PO...
+ TrackSectorDevice doDevice = null;
+ TrackSectorDevice poDevice = null;
+ for (TrackSectorDevice device : devices) {
+ if (device.is(Hint.DOS_SECTOR_ORDER) && doDevice == null) {
+ doDevice = device;
+ }
+ else if (device.is(Hint.PRODOS_BLOCK_ORDER) && poDevice == null) {
+ poDevice = device;
+ }
}
+ if (doDevice == null || poDevice == null) {
+ throw new RuntimeException("unexpected situation: device is neither PO or DO -or- we have more than 1");
+ }
+ int doCount = count(doDevice);
+ int poCount = count(poDevice);
+ // Keep the one with the most catalog sectors (slight edge to DO)
+ devices.remove(doCount >= poCount ? poDevice : doDevice);
}
+ // Look for 800K block devices to find UniDOS or OzDOS:
+ ctx.blockDevice()
+ .include800K()
+ .get()
+ .forEach(blockDevice -> {
+ devices.add(new BlockToTrackSectorAdapter(blockDevice, UnidosAdapterStrategy.UNIDOS_DISK_1));
+ devices.add(new BlockToTrackSectorAdapter(blockDevice, UnidosAdapterStrategy.UNIDOS_DISK_2));
+ devices.add(new BlockToTrackSectorAdapter(blockDevice, OzdosAdapterStrategy.OZDOS_DISK_1));
+ devices.add(new BlockToTrackSectorAdapter(blockDevice, OzdosAdapterStrategy.OZDOS_DISK_2));
+ });
+
// ... and then test for DOS VTOC etc. Passing track number along to hopefully handle it later!
for (TrackSectorDevice device : devices) {
if (check(device)) {
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergDiskFactory.java
index 0044dc1e..d3204dd2 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergDiskFactory.java
@@ -21,53 +21,23 @@ package com.webcodepro.applecommander.storage.os.gutenberg;
import com.webcodepro.applecommander.storage.DiskConstants;
import com.webcodepro.applecommander.storage.DiskFactory;
-import org.applecommander.device.BlockToTrackSectorAdapter;
-import org.applecommander.device.ProdosBlockToTrackSectorAdapterStrategy;
-import org.applecommander.device.SkewedTrackSectorDevice;
import org.applecommander.device.TrackSectorDevice;
import org.applecommander.hint.Hint;
import org.applecommander.util.DataBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
import static com.webcodepro.applecommander.storage.os.gutenberg.GutenbergFormatDisk.*;
public class GutenbergDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- List devices = new ArrayList<>();
- // We need DOS ordered...
- if (ctx.sectorDevice != null) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(ctx.sectorDevice));
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- devices.add(ctx.sectorDevice);
- }
- else if (ctx.sectorDevice.is(Hint.PRODOS_BLOCK_ORDER)) {
- // Cheating a bit...
- TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(tmp));
- }
- else {
- // Likely a DSK image
- devices.add(ctx.sectorDevice);
- // Cheating a bit...
- TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(tmp));
- }
- }
- else if (ctx.blockDevice != null) {
- TrackSectorDevice po = new BlockToTrackSectorAdapter(ctx.blockDevice, new ProdosBlockToTrackSectorAdapterStrategy());
- TrackSectorDevice tmp = SkewedTrackSectorDevice.pascalToPhysicalSkew(po);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(tmp));
- }
- devices.forEach(device -> {
- if (check(device)) {
- ctx.disks.add(new GutenbergFormatDisk(ctx.source.getName(), device));
- }
- });
+ ctx.trackSectorDevice()
+ .include16Sector(Hint.DOS_SECTOR_ORDER)
+ .get()
+ .forEach(device -> {
+ if (check(device)) {
+ ctx.disks.add(new GutenbergFormatDisk(ctx.source.getName(), device));
+ }
+ });
}
public boolean check(TrackSectorDevice order) {
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/nakedos/NakedosDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/nakedos/NakedosDiskFactory.java
index b0783235..1a36b7b9 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/nakedos/NakedosDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/nakedos/NakedosDiskFactory.java
@@ -20,46 +20,21 @@
package com.webcodepro.applecommander.storage.os.nakedos;
import com.webcodepro.applecommander.storage.DiskFactory;
-import org.applecommander.device.BlockToTrackSectorAdapter;
-import org.applecommander.device.ProdosBlockToTrackSectorAdapterStrategy;
-import org.applecommander.device.SkewedTrackSectorDevice;
import org.applecommander.device.TrackSectorDevice;
import org.applecommander.hint.Hint;
import org.applecommander.util.DataBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
public class NakedosDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- List devices = new ArrayList<>();
- // NakeDOS expects "physical" sector ordering
- if (ctx.sectorDevice != null) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- devices.add(ctx.sectorDevice);
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- devices.add(SkewedTrackSectorDevice.dosToPhysicalSkew(ctx.sectorDevice));
- }
- else if (ctx.sectorDevice.is(Hint.PRODOS_BLOCK_ORDER)) {
- devices.add(SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice));
- }
- else {
- devices.add(SkewedTrackSectorDevice.dosToPhysicalSkew(ctx.sectorDevice));
- devices.add(SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice));
- }
- }
- else if (ctx.blockDevice != null) {
- devices.add(SkewedTrackSectorDevice.pascalToPhysicalSkew(new BlockToTrackSectorAdapter(
- ctx.blockDevice, new ProdosBlockToTrackSectorAdapterStrategy())));
- }
-
- devices.forEach(device -> {
- if (check(device)) {
- ctx.disks.add(new NakedosFormatDisk(ctx.source.getName(), device));
- }
- });
+ ctx.trackSectorDevice()
+ .include16Sector(Hint.NIBBLE_SECTOR_ORDER)
+ .get()
+ .forEach(device -> {
+ if (check(device)) {
+ ctx.disks.add(new NakedosFormatDisk(ctx.source.getName(), device));
+ }
+ });
}
public boolean check(TrackSectorDevice device) {
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalDiskFactory.java
index a59e8e84..4d3846e6 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalDiskFactory.java
@@ -22,50 +22,24 @@ package com.webcodepro.applecommander.storage.os.pascal;
import com.webcodepro.applecommander.storage.DiskConstants;
import com.webcodepro.applecommander.storage.DiskFactory;
import org.applecommander.device.BlockDevice;
-import org.applecommander.device.SkewedTrackSectorDevice;
-import org.applecommander.device.TrackSectorDevice;
-import org.applecommander.device.TrackSectorToBlockAdapter;
import org.applecommander.hint.Hint;
import org.applecommander.util.DataBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Automatic discovery of Pascal volumes.
*/
public class PascalDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- List devices = new ArrayList<>();
- if (ctx.blockDevice != null) {
- devices.add(ctx.blockDevice);
- }
- if (ctx.sectorDevice != null && ctx.sectorDevice.getGeometry().sectorsPerDisk() <= 1600) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- TrackSectorDevice skewed = SkewedTrackSectorDevice.physicalToPascalSkew(ctx.sectorDevice);
- devices.add(new TrackSectorToBlockAdapter(skewed, TrackSectorToBlockAdapter.BlockStyle.PASCAL));
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- TrackSectorDevice skewed = SkewedTrackSectorDevice.dosToPascalSkew(ctx.sectorDevice);
- devices.add(new TrackSectorToBlockAdapter(skewed, TrackSectorToBlockAdapter.BlockStyle.PASCAL));
- }
- else {
- // Likely a DSK image, need to pick between DO and PO...
- // Try DO
- TrackSectorDevice device1 = SkewedTrackSectorDevice.dosToPascalSkew(ctx.sectorDevice);
- devices.add(new TrackSectorToBlockAdapter(device1, TrackSectorToBlockAdapter.BlockStyle.PRODOS));
- // Try PO
- TrackSectorDevice device2 = ctx.sectorDevice;
- devices.add(new TrackSectorToBlockAdapter(device2, TrackSectorToBlockAdapter.BlockStyle.PRODOS));
- }
- }
-
- devices.forEach(device -> {
- if (check(device)) {
- ctx.disks.add(new PascalFormatDisk(ctx.source.getName(), device));
- }
- });
+ ctx.blockDevice()
+ .include16Sector(Hint.PRODOS_BLOCK_ORDER)
+ .include800K()
+ .get()
+ .forEach(device -> {
+ if (check(device)) {
+ ctx.disks.add(new PascalFormatDisk(ctx.source.getName(), device));
+ }
+ });
}
/** Check for a likely directory structure. Note that we scan all sizes, even though that is overkill. */
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskFactory.java
index b00019ef..4f68c200 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskFactory.java
@@ -21,59 +21,28 @@ package com.webcodepro.applecommander.storage.os.prodos;
import com.webcodepro.applecommander.storage.DiskFactory;
import org.applecommander.device.BlockDevice;
-import org.applecommander.device.SkewedTrackSectorDevice;
-import org.applecommander.device.TrackSectorDevice;
-import org.applecommander.device.TrackSectorToBlockAdapter;
import org.applecommander.hint.Hint;
import org.applecommander.util.DataBuffer;
import static com.webcodepro.applecommander.storage.DiskConstants.*;
-import java.util.ArrayList;
-import java.util.List;
-
public class ProdosDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- // It seems easiest to gather all possibilities first...
- List tests = new ArrayList<>();
- if (ctx.blockDevice != null) {
- tests.add(new ProdosFormatDisk(ctx.source.getName(), ctx.blockDevice));
- }
- if (ctx.sectorDevice != null && ctx.sectorDevice.getGeometry().sectorsPerDisk() <= 1600) {
- TrackSectorDevice skewed = null;
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- skewed = SkewedTrackSectorDevice.physicalToPascalSkew(ctx.sectorDevice);
- BlockDevice device = new TrackSectorToBlockAdapter(skewed, TrackSectorToBlockAdapter.BlockStyle.PRODOS);
- tests.add(new ProdosFormatDisk(ctx.source.getName(), device));
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- skewed = SkewedTrackSectorDevice.dosToPascalSkew(ctx.sectorDevice);
- BlockDevice device = new TrackSectorToBlockAdapter(skewed, TrackSectorToBlockAdapter.BlockStyle.PRODOS);
- tests.add(new ProdosFormatDisk(ctx.source.getName(), device));
- }
- else {
- // Likely a DSK image, need to pick between DO and PO...
- // Try DO
- TrackSectorDevice device1 = SkewedTrackSectorDevice.dosToPascalSkew(ctx.sectorDevice);
- tests.add(new ProdosFormatDisk(ctx.source.getName(), new TrackSectorToBlockAdapter(device1,
- TrackSectorToBlockAdapter.BlockStyle.PRODOS)));
- // Try PO
- TrackSectorDevice device2 = ctx.sectorDevice;
- tests.add(new ProdosFormatDisk(ctx.source.getName(), new TrackSectorToBlockAdapter(device2,
- TrackSectorToBlockAdapter.BlockStyle.PRODOS)));
- }
- }
- // ... and then test for ProDOS details:
- for (ProdosFormatDisk fdisk : tests) {
- if (check(fdisk)) {
- ctx.disks.add(fdisk);
- }
- }
+ ctx.blockDevice()
+ .include16Sector(Hint.PRODOS_BLOCK_ORDER)
+ .include800K()
+ .includeHDV()
+ .get()
+ .forEach(device -> {
+ if (check(device)) {
+ ctx.disks.add(new ProdosFormatDisk(ctx.source.getName(), device));
+ }
+ });
}
- public boolean check(ProdosFormatDisk fdisk) {
+ public boolean check(BlockDevice device) {
int nextBlock = 2;
- DataBuffer volumeDirectory = DataBuffer.wrap(fdisk.readBlock(nextBlock));
+ DataBuffer volumeDirectory = device.readBlock(nextBlock);
int priorBlock = volumeDirectory.getUnsignedShort(0x00);
int storageType = volumeDirectory.getUnsignedByte(0x04) >> 4;
int entryLength = volumeDirectory.getUnsignedByte(0x23);
@@ -109,7 +78,7 @@ public class ProdosDiskFactory implements DiskFactory {
nextBlock = volumeDirectory.getUnsignedShort(0x02);
if (nextBlock == 0) break;
if (nextBlock >= totalBlocks) return false;
- volumeDirectory = DataBuffer.wrap(fdisk.readBlock(nextBlock));
+ volumeDirectory = device.readBlock(nextBlock);
}
return good;
}
diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosDiskFactory.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosDiskFactory.java
index 7c15afb7..4c1744a1 100644
--- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosDiskFactory.java
+++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosDiskFactory.java
@@ -29,8 +29,6 @@ import org.applecommander.util.DataBuffer;
import static com.webcodepro.applecommander.storage.DiskConstants.DOS32_SECTORS_ON_115KB_DISK;
import static com.webcodepro.applecommander.storage.os.rdos.RdosFormatDisk.*;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
public class RdosDiskFactory implements DiskFactory {
@@ -38,50 +36,24 @@ public class RdosDiskFactory implements DiskFactory {
@Override
public void inspect(Context ctx) {
- List devices = new ArrayList<>();
- if (ctx.sectorDevice != null) {
- if (ctx.sectorDevice.is(Hint.NIBBLE_SECTOR_ORDER)) {
- if (ctx.sectorDevice.getGeometry().sectorsPerTrack() == 13) {
- devices.add(ctx.sectorDevice);
- }
- else {
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(ctx.sectorDevice));
- }
- }
- else if (ctx.sectorDevice.is(Hint.DOS_SECTOR_ORDER)) {
- devices.add(ctx.sectorDevice);
- }
- else if (ctx.sectorDevice.is(Hint.PRODOS_BLOCK_ORDER)) {
- // cheating a bit here
- TrackSectorDevice physicalSkew = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(physicalSkew));
- }
- else {
- // DSK image. Could be DO or PO.
- devices.add(ctx.sectorDevice);
- // cheating a bit here for PO
- TrackSectorDevice physicalSkew = SkewedTrackSectorDevice.pascalToPhysicalSkew(ctx.sectorDevice);
- devices.add(SkewedTrackSectorDevice.physicalToDosSkew(physicalSkew));
- }
- }
- if (ctx.blockDevice != null) {
- devices.add(new BlockToTrackSectorAdapter(ctx.blockDevice, new ProdosBlockToTrackSectorAdapterStrategy()));
- }
-
- devices.forEach(device -> {
- int sectorsPerTrack = check(device);
- if (sectorsPerTrack > 0) {
- // Detect if we're a 16 sector disk but RDOS expects only 13 sectors:
- if (sectorsPerTrack != device.getGeometry().sectorsPerTrack()) {
- // 13-sector disks are in physical order, so fix it:
- device = SkewedTrackSectorDevice.dosToPhysicalSkew(device);
- // And make the 16-sector disk a fake 13-sector disk:
- device = SkewedTrackSectorDevice.truncate16sectorTo13(device);
- }
- BlockDevice blockDevice = new TrackSectorToBlockAdapter(device, TrackSectorToBlockAdapter.BlockStyle.RDOS);
- ctx.disks.add(new RdosFormatDisk(ctx.source.getName(), blockDevice));
- }
- });
+ ctx.trackSectorDevice()
+ .include13Sector()
+ .include16Sector(Hint.DOS_SECTOR_ORDER)
+ .get()
+ .forEach(device -> {
+ int sectorsPerTrack = check(device);
+ if (sectorsPerTrack > 0) {
+ // Detect if we're a 16 sector disk but RDOS expects only 13 sectors:
+ if (sectorsPerTrack != device.getGeometry().sectorsPerTrack()) {
+ // 13-sector disks are in physical order, so fix it:
+ device = SkewedTrackSectorDevice.dosToPhysicalSkew(device);
+ // And make the 16-sector disk a fake 13-sector disk:
+ device = SkewedTrackSectorDevice.truncate16sectorTo13(device);
+ }
+ BlockDevice blockDevice = new TrackSectorToBlockAdapter(device, TrackSectorToBlockAdapter.BlockStyle.RDOS);
+ ctx.disks.add(new RdosFormatDisk(ctx.source.getName(), blockDevice));
+ }
+ });
}
/**