AppleCommander/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/physical/DosOrder.java

133 lines
4.3 KiB
Java

/*
* AppleCommander - An Apple ][ image utility.
* Copyright (C) 2003 by Robert Greene
* robgreene at users.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.webcodepro.applecommander.storage.physical;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.util.TextBundle;
/**
* Supports disk images stored in DOS physical order.
* <p>
* @author Rob Greene (RobGreene@users.sourceforge.net)
*/
public class DosOrder extends ImageOrder {
private TextBundle textBundle = StorageBundle.getInstance();
/**
* Construct a DosOrder.
*/
public DosOrder(ByteArrayImageLayout diskImageManager) {
super(diskImageManager);
}
/**
* Indicates that this device is block ordered.
*/
public boolean isBlockDevice() {
return false;
}
/**
* Indicates that this device is track and sector ordered.
*/
public boolean isTrackAndSectorDevice() {
return true;
}
/**
* Retrieve the specified sector.
*/
public byte[] readSector(int track, int sector) throws IllegalArgumentException {
return readBytes(getOffset(track, sector), Disk.SECTOR_SIZE);
}
/**
* Write the specified sector.
*/
public void writeSector(int track, int sector, byte[] bytes)
throws IllegalArgumentException {
writeBytes(getOffset(track, sector), bytes);
}
/**
* Compute the track and sector offset into the disk image.
* This takes into account what type of format is being dealt
* with.
*/
protected int getOffset(int track, int sector) throws IllegalArgumentException {
if (!isSizeApprox(Disk.APPLE_140KB_DISK)
&& !isSizeApprox(Disk.APPLE_800KB_DISK)
&& !isSizeApprox(Disk.APPLE_800KB_2IMG_DISK)
&& track != 0 && sector != 0) { // HACK: Allows boot sector writing
throw new IllegalArgumentException(
textBundle.get("DosOrder.UnrecognizedFormatError")); //$NON-NLS-1$
}
int offset = (track * getSectorsPerTrack() + sector) * Disk.SECTOR_SIZE;
if (offset > getPhysicalSize()) {
throw new IllegalArgumentException(
textBundle.format("DosOrder.InvalidSizeError", //$NON-NLS-1$
track, sector));
}
return offset;
}
/**
* Read the block from the disk image.
* Note: Defined in terms of reading sectors.
*/
public byte[] readBlock(int block) {
int track = block / 8;
int sectorIndex = block % 8;
int[] sectorMapping1 = { 0, 13, 11, 9, 7, 5, 3, 1 };
int[] sectorMapping2 = { 14, 12, 10, 8, 6, 4, 2, 15 };
int sector1 = sectorMapping1[sectorIndex];
int sector2 = sectorMapping2[sectorIndex];
byte[] blockData = new byte[Disk.BLOCK_SIZE];
System.arraycopy(readSector(track, sector1), 0, blockData, 0, Disk.SECTOR_SIZE);
System.arraycopy(readSector(track, sector2), 0, blockData, Disk.SECTOR_SIZE, Disk.SECTOR_SIZE);
return blockData;
}
/**
* Write the block to the disk image.
* Note: Defined in terms of reading sectors.
*/
public void writeBlock(int block, byte[] data) {
int track = block / 8;
int sectorIndex = block % 8;
int[] sectorMapping1 = { 0, 13, 11, 9, 7, 5, 3, 1 };
int[] sectorMapping2 = { 14, 12, 10, 8, 6, 4, 2, 15 };
int sector1 = sectorMapping1[sectorIndex];
int sector2 = sectorMapping2[sectorIndex];
byte[] sectorData = new byte[Disk.SECTOR_SIZE];
System.arraycopy(data, 0, sectorData, 0, Disk.SECTOR_SIZE);
writeSector(track, sector1, sectorData);
System.arraycopy(data, Disk.SECTOR_SIZE, sectorData, 0, Disk.SECTOR_SIZE);
writeSector(track, sector2, sectorData);
}
/**
* Return the name of this image order.
*/
public String getName() {
return textBundle.get("DosOrder.OrderName"); //$NON-NLS-1$
}
}