133 lines
4.3 KiB
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$
|
|
}
|
|
}
|