From 3bae1f3c873534fdedd8670fb5f5c2d0aec01e3e Mon Sep 17 00:00:00 2001 From: Robert Greene Date: Fri, 26 Dec 2003 21:40:10 +0000 Subject: [PATCH] Converted to support image order and image layout instead of a simple byte array. --- .../applecommander/storage/DosFormatDisk.java | 11 +-- .../applecommander/storage/FormattedDisk.java | 6 +- .../storage/OzDosFormatDisk.java | 33 ++------ .../storage/PascalFormatDisk.java | 14 ++-- .../storage/ProdosFormatDisk.java | 16 ++-- .../storage/RdosFormatDisk.java | 11 +-- .../storage/UniDosFormatDisk.java | 25 ++----- .../storage/cpm/CpmFormatDisk.java | 19 ++++- .../applecommander/test/DiskWriterTest.java | 75 +++++++++++++++---- src/com/webcodepro/applecommander/ui/ac.java | 7 +- .../ui/swt/DiskImageFormatPane.java | 3 + .../ui/swt/DiskImageOrderPane.java | 9 +++ .../ui/swt/DiskImageWizard.java | 35 +++++++-- 13 files changed, 170 insertions(+), 94 deletions(-) diff --git a/src/com/webcodepro/applecommander/storage/DosFormatDisk.java b/src/com/webcodepro/applecommander/storage/DosFormatDisk.java index 89ce35c..831a520 100644 --- a/src/com/webcodepro/applecommander/storage/DosFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/DosFormatDisk.java @@ -19,6 +19,7 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; import com.webcodepro.applecommander.util.AppleUtil; import java.util.ArrayList; @@ -101,17 +102,16 @@ public class DosFormatDisk extends FormattedDisk { * @param diskImage * @param order */ - public DosFormatDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public DosFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); } /** * Create a DosFormatDisk. All DOS disk images are expected to * be 140K in size. */ - public static DosFormatDisk[] create(String filename) { - DosFormatDisk disk = - new DosFormatDisk(filename, new byte[APPLE_140KB_DISK]); + public static DosFormatDisk[] create(String filename, ImageOrder imageOrder) { + DosFormatDisk disk = new DosFormatDisk(filename, imageOrder); disk.format(); return new DosFormatDisk[] { disk }; } @@ -537,6 +537,7 @@ public class DosFormatDisk extends FormattedDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); format(15, 35, 16); } diff --git a/src/com/webcodepro/applecommander/storage/FormattedDisk.java b/src/com/webcodepro/applecommander/storage/FormattedDisk.java index dd2eaf6..e022559 100644 --- a/src/com/webcodepro/applecommander/storage/FormattedDisk.java +++ b/src/com/webcodepro/applecommander/storage/FormattedDisk.java @@ -19,6 +19,8 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; + import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; @@ -122,8 +124,8 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry { * @param filename * @param diskImage */ - public FormattedDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public FormattedDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); } /** diff --git a/src/com/webcodepro/applecommander/storage/OzDosFormatDisk.java b/src/com/webcodepro/applecommander/storage/OzDosFormatDisk.java index c965b8c..97d5d7e 100644 --- a/src/com/webcodepro/applecommander/storage/OzDosFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/OzDosFormatDisk.java @@ -19,6 +19,8 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; + /** * Manages a disk that is in OzDOS format. * This is basically DOS 3.3 except that the disk has two volumes of @@ -50,20 +52,17 @@ public class OzDosFormatDisk extends DosFormatDisk { * @param filename * @param diskImage */ - public OzDosFormatDisk(String filename, byte[] diskImage, int logicalOffset) { - super(filename, diskImage); + public OzDosFormatDisk(String filename, ImageOrder imageOrder, int logicalOffset) { + super(filename, imageOrder); this.logicalOffset = logicalOffset; } /** * Create a OzDosFormatDisk. */ - public static DosFormatDisk[] create(String filename) { - byte[] diskImage = new byte[APPLE_800KB_2IMG_DISK]; - OzDosFormatDisk disk1 = new OzDosFormatDisk(filename, - diskImage, OZDOS_DISK_1); + public static DosFormatDisk[] create(String filename, ImageOrder imageOrder) { + OzDosFormatDisk disk1 = new OzDosFormatDisk(filename, imageOrder, OZDOS_DISK_1); + OzDosFormatDisk disk2 = new OzDosFormatDisk(filename, imageOrder, OZDOS_DISK_2); disk1.format(); - OzDosFormatDisk disk2 = new OzDosFormatDisk(filename, - diskImage, OZDOS_DISK_2); disk2.format(); return new OzDosFormatDisk[] { disk1, disk2 }; } @@ -93,28 +92,12 @@ public class OzDosFormatDisk extends DosFormatDisk { return 0; } } - /** - * Compute the track and sector offset into the disk image. - * This varies with OzDOS. - */ - protected int getOffset(int track, int sector) throws IllegalArgumentException { - if ((track * 32 + sector) * SECTOR_SIZE > getPhysicalSize()) { - throw new IllegalArgumentException( - "The track (" + track + ") and sector (" + sector - + ") do not match the disk image size."); - } else if (isProdosOrder()) { - return ((track * 32) + sector) * BLOCK_SIZE + logicalOffset; - } else { - // Note that DOS format is unexpected. - throw new IllegalArgumentException( - "Unknown disk format."); - } - } /** * Format the disk as OzDOS. * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); format(31, 50, 32); } } diff --git a/src/com/webcodepro/applecommander/storage/PascalFormatDisk.java b/src/com/webcodepro/applecommander/storage/PascalFormatDisk.java index acd4a12..68cf657 100644 --- a/src/com/webcodepro/applecommander/storage/PascalFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/PascalFormatDisk.java @@ -19,6 +19,7 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; import com.webcodepro.applecommander.util.AppleUtil; import java.util.ArrayList; @@ -108,19 +109,17 @@ public class PascalFormatDisk extends FormattedDisk { * @param filename * @param diskImage */ - public PascalFormatDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public PascalFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); } /** * Create a PascalFormatDisk. */ - public static PascalFormatDisk[] create(String filename, String volumeName, - int size) { - - PascalFormatDisk disk = new PascalFormatDisk(filename, new byte[size]); - disk.setDiskName(volumeName); + public static PascalFormatDisk[] create(String filename, String volumeName, ImageOrder imageOrder) { + PascalFormatDisk disk = new PascalFormatDisk(filename, imageOrder); disk.format(); + disk.setDiskName(volumeName); return new PascalFormatDisk[] { disk }; } @@ -445,6 +444,7 @@ public class PascalFormatDisk extends FormattedDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); writeBootCode(); // Create volume name byte[] directory = readDirectory(); diff --git a/src/com/webcodepro/applecommander/storage/ProdosFormatDisk.java b/src/com/webcodepro/applecommander/storage/ProdosFormatDisk.java index 6bedc50..047de99 100644 --- a/src/com/webcodepro/applecommander/storage/ProdosFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/ProdosFormatDisk.java @@ -19,6 +19,7 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; import com.webcodepro.applecommander.util.AppleUtil; import java.io.IOException; @@ -130,8 +131,8 @@ public class ProdosFormatDisk extends FormattedDisk { * @param filename * @param diskImage */ - public ProdosFormatDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public ProdosFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); volumeHeader = new ProdosVolumeDirectoryHeader(this); initialize(); } @@ -167,10 +168,10 @@ public class ProdosFormatDisk extends FormattedDisk { /** * Create a ProdosFormatDisk. */ - public static ProdosFormatDisk[] create(String filename, String diskName, int imageSize) { - ProdosFormatDisk disk = new ProdosFormatDisk(filename, new byte[imageSize]); - disk.setDiskName(diskName); + public static ProdosFormatDisk[] create(String filename, String diskName, ImageOrder imageOrder) { + ProdosFormatDisk disk = new ProdosFormatDisk(filename, imageOrder); disk.format(); + disk.setDiskName(diskName); return new ProdosFormatDisk[] { disk }; } @@ -683,7 +684,7 @@ public class ProdosFormatDisk extends FormattedDisk { int blocksOnDisk = getBitmapLength(); while (block < blocksOnDisk) { if (isBlockFree(volumeBitmap,block)) { - if ((block+1) * BLOCK_SIZE < getDiskImage().length) { + if ((block+1) * BLOCK_SIZE < getPhysicalSize()) { return block; } throw new ProdosDiskSizeDoesNotMatchException( @@ -771,9 +772,10 @@ public class ProdosFormatDisk extends FormattedDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); writeBootCode(); String volumeName = volumeHeader.getVolumeName(); - int totalBlocks = getDiskImage().length / BLOCK_SIZE; + int totalBlocks = getPhysicalSize() / BLOCK_SIZE; int usedBlocks = (totalBlocks / 4096) + 7; // setup volume directory byte[] data = new byte[BLOCK_SIZE]; diff --git a/src/com/webcodepro/applecommander/storage/RdosFormatDisk.java b/src/com/webcodepro/applecommander/storage/RdosFormatDisk.java index c4638bc..89c61b0 100644 --- a/src/com/webcodepro/applecommander/storage/RdosFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/RdosFormatDisk.java @@ -19,6 +19,7 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; import com.webcodepro.applecommander.util.AppleUtil; import java.util.ArrayList; @@ -122,16 +123,15 @@ public class RdosFormatDisk extends FormattedDisk { * @param filename * @param diskImage */ - public RdosFormatDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public RdosFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); } /** * Create a RdosFormatDisk. */ - public static RdosFormatDisk[] create(String filename) { - RdosFormatDisk disk = - new RdosFormatDisk(filename, new byte[APPLE_140KB_DISK]); + public static RdosFormatDisk[] create(String filename, ImageOrder imageOrder) { + RdosFormatDisk disk = new RdosFormatDisk(filename, imageOrder); disk.format(); return new RdosFormatDisk[] { disk }; } @@ -395,6 +395,7 @@ public class RdosFormatDisk extends FormattedDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); writeBootCode(); // minor hack - ensure that AppleCommander itself recognizes the // RDOS disk! diff --git a/src/com/webcodepro/applecommander/storage/UniDosFormatDisk.java b/src/com/webcodepro/applecommander/storage/UniDosFormatDisk.java index d544da6..28fe06c 100644 --- a/src/com/webcodepro/applecommander/storage/UniDosFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/UniDosFormatDisk.java @@ -19,6 +19,8 @@ */ package com.webcodepro.applecommander.storage; +import com.webcodepro.applecommander.storage.physical.ImageOrder; + /** * Manages a disk that is in UniDOS format. * This is basically DOS 3.3 except that the disk has two volumes of @@ -48,20 +50,17 @@ public class UniDosFormatDisk extends DosFormatDisk { * @param filename * @param diskImage */ - public UniDosFormatDisk(String filename, byte[] diskImage, int logicalOffset) { - super(filename, diskImage); + public UniDosFormatDisk(String filename, ImageOrder imageOrder, int logicalOffset) { + super(filename, imageOrder); this.logicalOffset = logicalOffset; } /** * Create a UniDosFormatDisk. */ - public static DosFormatDisk[] create(String filename) { - byte[] diskImage = new byte[APPLE_800KB_2IMG_DISK]; - UniDosFormatDisk disk1 = new UniDosFormatDisk(filename, - diskImage, UNIDOS_DISK_1); + public static DosFormatDisk[] create(String filename, ImageOrder imageOrder) { + UniDosFormatDisk disk1 = new UniDosFormatDisk(filename, imageOrder, UNIDOS_DISK_1); + UniDosFormatDisk disk2 = new UniDosFormatDisk(filename, imageOrder, UNIDOS_DISK_2); disk1.format(); - UniDosFormatDisk disk2 = new UniDosFormatDisk(filename, - diskImage, UNIDOS_DISK_2); disk2.format(); return new UniDosFormatDisk[] { disk1, disk2 }; } @@ -79,15 +78,6 @@ public class UniDosFormatDisk extends DosFormatDisk { } } - /** - * Modify the disk offset by the logical disk offset. This allows - * simple support for two DOS volumes on a UniDOS disk. - * @see com.webcodepro.applecommander.storage.Disk#getOffset(int, int) - */ - protected int getOffset(int track, int sector) throws IllegalArgumentException { - return super.getOffset(track, sector) + logicalOffset; - } - /** * Returns the logical disk number. This can be used to identify * between disks when a format supports multiple logical volumes. @@ -106,6 +96,7 @@ public class UniDosFormatDisk extends DosFormatDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); format(31, 50, 32); } } diff --git a/src/com/webcodepro/applecommander/storage/cpm/CpmFormatDisk.java b/src/com/webcodepro/applecommander/storage/cpm/CpmFormatDisk.java index 87449f3..fd8bbf0 100644 --- a/src/com/webcodepro/applecommander/storage/cpm/CpmFormatDisk.java +++ b/src/com/webcodepro/applecommander/storage/cpm/CpmFormatDisk.java @@ -22,6 +22,7 @@ package com.webcodepro.applecommander.storage.cpm; import com.webcodepro.applecommander.storage.DiskFullException; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FormattedDisk; +import com.webcodepro.applecommander.storage.physical.ImageOrder; import java.util.ArrayList; import java.util.HashMap; @@ -91,12 +92,21 @@ public class CpmFormatDisk extends FormattedDisk { } } - /** - * Create a CP/M formatted disk. + * Construct a CP/M formatted disk. */ - public CpmFormatDisk(String filename, byte[] diskImage) { - super(filename, diskImage); + public CpmFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); + } + + /** + * Create a CpmFormatDisk. All CP/M disk images are expected to + * be 140K in size. + */ + public static CpmFormatDisk[] create(String filename, ImageOrder imageOrder) { + CpmFormatDisk disk = new CpmFormatDisk(filename, imageOrder); + disk.format(); + return new CpmFormatDisk[] { disk }; } /** @@ -267,6 +277,7 @@ public class CpmFormatDisk extends FormattedDisk { * @see com.webcodepro.applecommander.storage.FormattedDisk#format() */ public void format() { + getImageOrder().format(); byte[] sectorData = new byte[SECTOR_SIZE]; for (int i=0; i Disk.APPLE_140KB_DISK) { + if (disk.getPhysicalSize() > Disk.APPLE_140KB_DISK + && disk.getPhysicalSize() != Disk.APPLE_140KB_NIBBLE_DISK) { // create a few big files writeFile(disk, 150000, binaryType, true); writeFile(disk, 300000, binaryType, true); diff --git a/src/com/webcodepro/applecommander/ui/ac.java b/src/com/webcodepro/applecommander/ui/ac.java index cd016d4..71f7769 100644 --- a/src/com/webcodepro/applecommander/ui/ac.java +++ b/src/com/webcodepro/applecommander/ui/ac.java @@ -28,6 +28,9 @@ import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FileFilter; import com.webcodepro.applecommander.storage.FormattedDisk; import com.webcodepro.applecommander.storage.ProdosFormatDisk; +import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout; +import com.webcodepro.applecommander.storage.physical.ImageOrder; +import com.webcodepro.applecommander.storage.physical.ProdosOrder; import java.io.IOException; import java.util.List; @@ -210,8 +213,10 @@ public class ac { */ static void createPDisk(String fileName, String volName, int imageSize) throws IOException { + ByteArrayImageLayout layout = new ByteArrayImageLayout(imageSize); + ImageOrder imageOrder = new ProdosOrder(layout); FormattedDisk[] disks = - ProdosFormatDisk.create(fileName, volName, imageSize); + ProdosFormatDisk.create(fileName, volName, imageOrder); disks[0].save(); } diff --git a/src/com/webcodepro/applecommander/ui/swt/DiskImageFormatPane.java b/src/com/webcodepro/applecommander/ui/swt/DiskImageFormatPane.java index fe246ce..2da8d12 100644 --- a/src/com/webcodepro/applecommander/ui/swt/DiskImageFormatPane.java +++ b/src/com/webcodepro/applecommander/ui/swt/DiskImageFormatPane.java @@ -57,6 +57,7 @@ public class DiskImageFormatPane extends WizardPane { switch (wizard.getFormat()) { case DiskImageWizard.FORMAT_DOS33: case DiskImageWizard.FORMAT_RDOS: + case DiskImageWizard.FORMAT_CPM: wizard.setOrder(DiskImageWizard.ORDER_DOS); wizard.setSize(FormattedDisk.APPLE_140KB_DISK); return new DiskImageNamePane(parent, wizard); @@ -123,6 +124,8 @@ public class DiskImageFormatPane extends WizardPane { + "that I've seen have been mapped onto a 16 sector disk (leaving 3\n" + "sectors of each track unused. The only image size RDOS supports\n" + "is 140K."); + createRadioButton(buttonSubpanel, "CP/M", DiskImageWizard.FORMAT_CPM, + "CP/M for the Apple computer."); control.pack(); } /** diff --git a/src/com/webcodepro/applecommander/ui/swt/DiskImageOrderPane.java b/src/com/webcodepro/applecommander/ui/swt/DiskImageOrderPane.java index e633c9f..a431ef9 100644 --- a/src/com/webcodepro/applecommander/ui/swt/DiskImageOrderPane.java +++ b/src/com/webcodepro/applecommander/ui/swt/DiskImageOrderPane.java @@ -19,6 +19,8 @@ */ package com.webcodepro.applecommander.ui.swt; +import com.webcodepro.applecommander.storage.Disk; + import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; @@ -87,6 +89,13 @@ public class DiskImageOrderPane extends WizardPane { createRadioButton(buttonSubpanel, "ProDOS ordered", DiskImageWizard.ORDER_PRODOS, "Indicates that image data should be stored by block."); + if (wizard.getSize() == Disk.APPLE_140KB_DISK) { + createRadioButton(buttonSubpanel, "Nibble ordered", + DiskImageWizard.ORDER_NIBBLE, + "Indicates that this is a disk stored as a nibble image. This is " + + "an image that consists of disk bytes. It is only available for " + + "140KB 5.25\" disks."); + } label = new Label(control, SWT.WRAP); if (wizard.isHardDisk()) { diff --git a/src/com/webcodepro/applecommander/ui/swt/DiskImageWizard.java b/src/com/webcodepro/applecommander/ui/swt/DiskImageWizard.java index d32a7f1..a1ddaec 100644 --- a/src/com/webcodepro/applecommander/ui/swt/DiskImageWizard.java +++ b/src/com/webcodepro/applecommander/ui/swt/DiskImageWizard.java @@ -27,6 +27,12 @@ import com.webcodepro.applecommander.storage.PascalFormatDisk; import com.webcodepro.applecommander.storage.ProdosFormatDisk; import com.webcodepro.applecommander.storage.RdosFormatDisk; import com.webcodepro.applecommander.storage.UniDosFormatDisk; +import com.webcodepro.applecommander.storage.cpm.CpmFormatDisk; +import com.webcodepro.applecommander.storage.physical.ByteArrayImageLayout; +import com.webcodepro.applecommander.storage.physical.DosOrder; +import com.webcodepro.applecommander.storage.physical.ImageOrder; +import com.webcodepro.applecommander.storage.physical.NibbleOrder; +import com.webcodepro.applecommander.storage.physical.ProdosOrder; import org.eclipse.swt.widgets.Shell; @@ -43,8 +49,10 @@ public class DiskImageWizard extends Wizard { public static final int FORMAT_PASCAL = 4; public static final int FORMAT_RDOS = 5; public static final int FORMAT_OZDOS = 6; + public static final int FORMAT_CPM = 7; public static final int ORDER_DOS = 1; public static final int ORDER_PRODOS = 2; + public static final int ORDER_NIBBLE = 3; private int format = FORMAT_DOS33; private int size = FormattedDisk.APPLE_140KB_DISK; private String fileName = ""; @@ -79,19 +87,34 @@ public class DiskImageWizard extends Wizard { if (isCompressed()) { name.append(".gz"); } + ByteArrayImageLayout imageLayout = new ByteArrayImageLayout(getSize()); + ImageOrder imageOrder = null; + switch (getOrder()) { + case ORDER_DOS: + imageOrder = new DosOrder(imageLayout); + break; + case ORDER_NIBBLE: + imageOrder = new NibbleOrder(imageLayout); + break; + case ORDER_PRODOS: + imageOrder = new ProdosOrder(imageLayout); + break; + } switch (format) { case FORMAT_DOS33: - return DosFormatDisk.create(name.toString()); + return DosFormatDisk.create(name.toString(), imageOrder); case FORMAT_OZDOS: - return OzDosFormatDisk.create(name.toString()); + return OzDosFormatDisk.create(name.toString(), imageOrder); case FORMAT_PASCAL: - return PascalFormatDisk.create(name.toString(), volumeName, size); + return PascalFormatDisk.create(name.toString(), volumeName, imageOrder); case FORMAT_PRODOS: - return ProdosFormatDisk.create(name.toString(), volumeName, size); + return ProdosFormatDisk.create(name.toString(), volumeName, imageOrder); case FORMAT_RDOS: - return RdosFormatDisk.create(name.toString()); + return RdosFormatDisk.create(name.toString(), imageOrder); case FORMAT_UNIDOS: - return UniDosFormatDisk.create(name.toString()); + return UniDosFormatDisk.create(name.toString(), imageOrder); + case FORMAT_CPM: + return CpmFormatDisk.create(name.toString(), imageOrder); } return null; }