mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2026-04-25 20:18:05 +00:00
Making PascalFormatDisk use BlockDevice.
This commit is contained in:
+16
-9
@@ -21,7 +21,8 @@ package com.webcodepro.applecommander.storage.os.pascal;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DiskConstants;
|
||||
import com.webcodepro.applecommander.storage.DiskFactory;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import org.applecommander.device.BlockDevice;
|
||||
import org.applecommander.device.TrackSectorToBlockAdapter;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
|
||||
/**
|
||||
@@ -30,22 +31,28 @@ import org.applecommander.util.DataBuffer;
|
||||
public class PascalDiskFactory implements DiskFactory {
|
||||
@Override
|
||||
public void inspect(Context ctx) {
|
||||
ctx.orders.forEach(order -> {
|
||||
if (check(order)) {
|
||||
ctx.disks.add(new PascalFormatDisk(ctx.source.getName(), order));
|
||||
if (ctx.blockDevice != null) {
|
||||
if (check(ctx.blockDevice)) {
|
||||
ctx.disks.add(new PascalFormatDisk(ctx.source.getName(), ctx.blockDevice));
|
||||
}
|
||||
});
|
||||
}
|
||||
if (ctx.sectorDevice != null && ctx.sectorDevice.getGeometry().sectorsPerDisk() <= 1600) {
|
||||
BlockDevice device = new TrackSectorToBlockAdapter(ctx.sectorDevice);
|
||||
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. */
|
||||
public boolean check(ImageOrder order) {
|
||||
public boolean check(BlockDevice device) {
|
||||
boolean good = false;
|
||||
if (order.getPhysicalSize() >= DiskConstants.APPLE_140KB_DISK) {
|
||||
if (device.getGeometry().blockSize() >= DiskConstants.PRODOS_BLOCKS_ON_140KB_DISK) {
|
||||
// Read entire directory for analysis
|
||||
DataBuffer dir = DataBuffer.create(2048);
|
||||
for (int block=2; block<6; block++) {
|
||||
byte[] data = order.readBlock(block);
|
||||
dir.put((block-2)* DiskConstants.BLOCK_SIZE, DataBuffer.wrap(data));
|
||||
DataBuffer data = device.readBlock(block);
|
||||
dir.put((block-2)*DiskConstants.BLOCK_SIZE, data);
|
||||
}
|
||||
// Check volume entry
|
||||
int dFirstBlock = dir.getUnsignedShort(0);
|
||||
|
||||
+30
-19
@@ -22,9 +22,13 @@
|
||||
package com.webcodepro.applecommander.storage.os.pascal;
|
||||
|
||||
import com.webcodepro.applecommander.storage.*;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.util.AppleUtil;
|
||||
import com.webcodepro.applecommander.util.TextBundle;
|
||||
import org.applecommander.device.BlockDevice;
|
||||
import org.applecommander.source.Source;
|
||||
import org.applecommander.util.Container;
|
||||
import org.applecommander.util.DataBuffer;
|
||||
|
||||
import static com.webcodepro.applecommander.storage.DiskConstants.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -36,7 +40,7 @@ import java.util.*;
|
||||
* @author Rob Greene
|
||||
* @author John B. Matthews [getFiles(), get/putDirectory(), createFile()]
|
||||
*/
|
||||
public class PascalFormatDisk extends FormattedDiskX {
|
||||
public class PascalFormatDisk extends FormattedDisk implements Container {
|
||||
private TextBundle textBundle = StorageBundle.getInstance();
|
||||
/**
|
||||
* The size of the Pascal file entry.
|
||||
@@ -113,24 +117,39 @@ public class PascalFormatDisk extends FormattedDiskX {
|
||||
return !bitmap.get(location); // false = used
|
||||
}
|
||||
}
|
||||
|
||||
private BlockDevice device;
|
||||
|
||||
/**
|
||||
* Constructor for PascalFormatDisk.
|
||||
*/
|
||||
public PascalFormatDisk(String filename, ImageOrder imageOrder) {
|
||||
super(filename, imageOrder);
|
||||
public PascalFormatDisk(String filename, BlockDevice device) {
|
||||
super(filename, device.get(Source.class).orElseThrow());
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PascalFormatDisk.
|
||||
*/
|
||||
public static PascalFormatDisk[] create(String filename, String volumeName, ImageOrder imageOrder) {
|
||||
PascalFormatDisk disk = new PascalFormatDisk(filename, imageOrder);
|
||||
public static PascalFormatDisk[] create(String filename, String volumeName, BlockDevice device) {
|
||||
PascalFormatDisk disk = new PascalFormatDisk(filename, device);
|
||||
disk.format();
|
||||
disk.setDiskName(volumeName);
|
||||
return new PascalFormatDisk[] { disk };
|
||||
}
|
||||
|
||||
protected byte[] readBlock(int block) {
|
||||
return device.readBlock(block).asBytes();
|
||||
}
|
||||
protected void writeBlock(int block, byte[] data) {
|
||||
device.writeBlock(block, DataBuffer.wrap(data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> get(Class<T> iface) {
|
||||
return Container.get(iface, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify the operating system format of this disk.
|
||||
* @see com.webcodepro.applecommander.storage.FormattedDisk#getFormat()
|
||||
@@ -554,15 +573,17 @@ public class PascalFormatDisk extends FormattedDiskX {
|
||||
* @see com.webcodepro.applecommander.storage.FormattedDisk#format()
|
||||
*/
|
||||
public void format() {
|
||||
getImageOrder().format();
|
||||
writeBootCode();
|
||||
device.format();
|
||||
DataBuffer bootBlock = DataBuffer.create(BLOCK_SIZE);
|
||||
bootBlock.put(0, DataBuffer.wrap(getBootCode()));
|
||||
device.writeBlock(0, bootBlock);
|
||||
// Create volume name
|
||||
byte[] directory = readDirectory();
|
||||
AppleUtil.setWordValue(directory, 0, 0); // always 0
|
||||
AppleUtil.setWordValue(directory, 2, 6); // last directory block
|
||||
AppleUtil.setWordValue(directory, 4, 0); // entry type (0=vol header)
|
||||
// volume name should have been set in constructor!
|
||||
int blocks = getImageOrder().getBlocksOnDevice();
|
||||
int blocks = device.getGeometry().blocksOnDevice();
|
||||
AppleUtil.setWordValue(directory, 14, blocks);
|
||||
AppleUtil.setWordValue(directory, 16, 0); // no files
|
||||
AppleUtil.setWordValue(directory, 18, 0); // first block
|
||||
@@ -645,16 +666,6 @@ public class PascalFormatDisk extends FormattedDiskX {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change to a different ImageOrder. Remains in Pascal format but
|
||||
* the underlying order can change.
|
||||
* @see ImageOrder
|
||||
*/
|
||||
public void changeImageOrder(ImageOrder imageOrder) {
|
||||
AppleUtil.changeImageOrderByBlock(getImageOrder(), imageOrder);
|
||||
setImageOrder(imageOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the raw bytes into the file. This bypasses any special formatting
|
||||
* of the data (such as prepending the data with a length and/or an address).
|
||||
|
||||
+10
-10
@@ -84,9 +84,9 @@ public class DiskWriterTest {
|
||||
@Test
|
||||
public void testWriteToPascal140kDisk() throws IOException, DiskException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_140KB_DISK, "new-disk").get();
|
||||
ImageOrder imageOrder = new ProdosOrder(source);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
FormattedDisk[] disks = PascalFormatDisk.create(
|
||||
"write-test-pascal-140k.po", "TEST", imageOrder); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
"write-test-pascal-140k.po", "TEST", blockDevice); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
writeFiles(disks, "code", "text", false); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
saveDisks(disks);
|
||||
}
|
||||
@@ -97,9 +97,9 @@ public class DiskWriterTest {
|
||||
@Test
|
||||
public void testWriteToPascal800kDisk() throws DiskFullException, IOException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_800KB_DISK, "new-disk").get();
|
||||
ImageOrder imageOrder = new ProdosOrder(source);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
FormattedDisk[] disks = PascalFormatDisk.create(
|
||||
"write-test-pascal-800k.po", "TEST", imageOrder); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
"write-test-pascal-800k.po", "TEST", blockDevice); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
//writeFiles(disks, "code", "text", false); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
saveDisks(disks);
|
||||
}
|
||||
@@ -189,10 +189,10 @@ public class DiskWriterTest {
|
||||
@Test
|
||||
public void testCreateAndDeletePascal140kDisk() throws IOException, DiskException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_140KB_DISK, "new-disk").get();
|
||||
ImageOrder imageOrder = new ProdosOrder(source);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
FormattedDisk[] disks = PascalFormatDisk.create(
|
||||
"createanddelete-test-pascal-140k.po", "TEST", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
imageOrder);
|
||||
blockDevice);
|
||||
createAndDeleteFiles(disks, "CODE"); //$NON-NLS-1$
|
||||
saveDisks(disks);
|
||||
}
|
||||
@@ -203,10 +203,10 @@ public class DiskWriterTest {
|
||||
@Test
|
||||
public void testCreateAndDeletePascal800kDisk() throws IOException, DiskException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_800KB_DISK, "new-disk").get();
|
||||
ImageOrder imageOrder = new ProdosOrder(source);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
FormattedDisk[] disks = PascalFormatDisk.create(
|
||||
"createanddelete-test-pascal-800k.po", "TEST", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
imageOrder);
|
||||
blockDevice);
|
||||
createAndDeleteFiles(disks, "CODE"); //$NON-NLS-1$
|
||||
saveDisks(disks);
|
||||
}
|
||||
@@ -289,10 +289,10 @@ public class DiskWriterTest {
|
||||
@Test
|
||||
public void testCreateDeleteCreatePascalDisk() throws IOException, DiskException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_140KB_DISK, "new-disk").get();
|
||||
ImageOrder imageOrder = new ProdosOrder(source);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
FormattedDisk[] disks = PascalFormatDisk.create(
|
||||
"createdeletecreate-test-pascal-140k.po", "TEST", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
imageOrder);
|
||||
blockDevice);
|
||||
createDeleteCreate(disks, "CODE"); //$NON-NLS-1$
|
||||
saveDisks(disks);
|
||||
}
|
||||
|
||||
+4
-4
@@ -21,21 +21,21 @@ package com.webcodepro.applecommander.storage.os.pascal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.applecommander.device.BlockDevice;
|
||||
import org.applecommander.device.ProdosOrderedBlockDevice;
|
||||
import org.applecommander.source.DataBufferSource;
|
||||
import org.applecommander.source.Source;
|
||||
|
||||
import com.webcodepro.applecommander.storage.DiskConstants;
|
||||
import com.webcodepro.applecommander.storage.DiskFullException;
|
||||
import com.webcodepro.applecommander.storage.physical.ImageOrder;
|
||||
import com.webcodepro.applecommander.storage.physical.ProdosOrder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PascalFormatDiskTest {
|
||||
@Test
|
||||
public void testSanitizeFilename() throws DiskFullException {
|
||||
Source source = DataBufferSource.create(DiskConstants.APPLE_140KB_DISK, "new-disk").get();
|
||||
ImageOrder order = new ProdosOrder(source);
|
||||
PascalFormatDisk[] disks = PascalFormatDisk.create("deleteme.po", "TEST", order);
|
||||
BlockDevice blockDevice = new ProdosOrderedBlockDevice(source, BlockDevice.STANDARD_BLOCK_SIZE);
|
||||
PascalFormatDisk[] disks = PascalFormatDisk.create("deleteme.po", "TEST", blockDevice);
|
||||
PascalFormatDisk disk = disks[0];
|
||||
|
||||
assertEquals("FILENAME", disk.getSuggestedFilename("FileName"));
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ public class DiskImageWizard extends Wizard {
|
||||
case FORMAT_OZDOS:
|
||||
return OzDosFormatDisk.create(name.toString(), imageOrder);
|
||||
case FORMAT_PASCAL:
|
||||
return PascalFormatDisk.create(name.toString(), volumeName, imageOrder);
|
||||
return PascalFormatDisk.create(name.toString(), volumeName, blockDevice);
|
||||
case FORMAT_PRODOS:
|
||||
return ProdosFormatDisk.create(name.toString(), volumeName, blockDevice);
|
||||
case FORMAT_RDOS:
|
||||
|
||||
Reference in New Issue
Block a user