diff --git a/src/com/webcodepro/applecommander/storage/physical/ByteArrayImageLayout.java b/src/com/webcodepro/applecommander/storage/physical/ByteArrayImageLayout.java new file mode 100644 index 0000000..d8dab38 --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/physical/ByteArrayImageLayout.java @@ -0,0 +1,115 @@ +/* + * 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; + +/** + * Manages the layout of the physical disk. This hides implementation details, + * such as if the disk is in 2IMG order. + *

+ * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public class ByteArrayImageLayout { + /** + * This is the physical copy of the disk image which a particular + * implementation of ImageOrder will interpret. + */ + private byte[] diskImage; + /** + * Indicates if the disk image has changed. + */ + private boolean changed; + + /** + * Construct a ByteArrayImageLayout. + */ + public ByteArrayImageLayout(byte[] diskImage) { + setDiskImage(diskImage); + } + + /** + * Construct a ByteArrayImageLayout. + */ + public ByteArrayImageLayout(byte[] diskImage, boolean changed) { + setDiskImage(diskImage); + this.changed = changed; + } + + /** + * Construct a ByteArrayImageLayout. + */ + public ByteArrayImageLayout(int size) { + diskImage = new byte[size]; + changed = true; + } + + /** + * Get the physical disk image. + */ + public byte[] getDiskImage() { + return diskImage; + } + + /** + * Set the physical disk image. + */ + public void setDiskImage(byte[] diskImage) { + this.diskImage = diskImage; + changed = true; + } + + /** + * Answer with the physical size of this disk volume. + */ + public int getPhysicalSize() { + return (diskImage != null) ? diskImage.length : 0; + } + + /** + * Extract a portion of the disk image. + */ + public byte[] readBytes(int start, int length) { + byte[] buffer = new byte[length]; + System.arraycopy(diskImage, start, buffer, 0, length); + return buffer; + } + + /** + * Write data to the disk image. + */ + public void writeBytes(int start, byte[] bytes) { + changed = true; + System.arraycopy(bytes, 0, diskImage, start, bytes.length); + } + + /** + * Indicates if the disk has changed. Triggered when data is + * written and cleared when data is saved. + */ + public boolean hasChanged() { + return changed; + } + + /** + * Set the changed indicator. + */ + public void setChanged(boolean changed) { + this.changed = changed; + } +} diff --git a/src/com/webcodepro/applecommander/storage/physical/DosOrder.java b/src/com/webcodepro/applecommander/storage/physical/DosOrder.java new file mode 100644 index 0000000..baf664c --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/physical/DosOrder.java @@ -0,0 +1,122 @@ +/* + * 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; + +/** + * Supports disk images stored in DOS physical order. + *

+ * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public class DosOrder extends ImageOrder { + /** + * 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("Unrecognized DOS format!"); + } + int offset = (track * getSectorsPerTrack() + sector) * Disk.SECTOR_SIZE; + if (offset > getPhysicalSize()) { + throw new IllegalArgumentException( + "The track (" + track + ") and sector (" + sector + + ") do not match the disk image size."); + } else { + 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); + } +} diff --git a/src/com/webcodepro/applecommander/storage/physical/ImageOrder.java b/src/com/webcodepro/applecommander/storage/physical/ImageOrder.java new file mode 100644 index 0000000..e047a7b --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/physical/ImageOrder.java @@ -0,0 +1,179 @@ +/* + * 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; + +/** + * Manages the interface between the physical disk image order and the + * logical operating system specific order. These management objects + * are intended to be hidden by Disk itself, although the ImageOrder + * may be changed (overridden). + *

+ * To implement this class, over-ride the block-oriented methods + * (readBlock, writeBlock) or the track and sector-oriented + * methods (readSector, writeSector). + * Ensure that isBlockDevice or isTrackAndSectorDevice is set + * appropriately. + *

+ * Note that a block is generally assumed to be an Apple ProDOS + * (or Apple Pascal) formatted volume where a block is 512 bytes. + * The track and sector device is generally a 140K 5.25" disk, + * although it may be an 800K 3.5" disk with two 400K DOS volumes. + * In either case, the sector size will be 256 bytes. + *

+ * At this time, the RDOS block of 256 bytes is managed by the + * RdosFormatDisk, and the 1024 byte CP/M block is managed by the + * CpmFormatDisk (the CP/M sector of 128 bytes is largely ignored). + *

+ * Design note: The physical order could alternatively be implemented + * with a BlockPhysicalOrder structure which includes ProdosOrder + * and a Track and Sector adapter, as well as a TrackAndSectorPhysicalOrder + * which includes a NibblePhysicalOrder and DosOrder as well as + * a Block adapter class. This way, Disk contains two separate classes + * (block as well as a track/sector) to manage the disk. + *

+ * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public abstract class ImageOrder { + /** + * This is the physical copy of the disk image which a particular + * implementation of ImageOrder will interpret. + */ + private ByteArrayImageLayout diskImageManager; + + /** + * Construct a ImageOrder. + */ + public ImageOrder(ByteArrayImageLayout diskImageManager) { + setDiskImageManager(diskImageManager); + } + + /** + * Get the physical disk image. + */ + public ByteArrayImageLayout getDiskImageManager() { + return diskImageManager; + } + + /** + * Answer with the physical size of this disk volume. + */ + public int getPhysicalSize() { + return diskImageManager.getPhysicalSize(); + } + + /** + * Set the physical disk image. + */ + public void setDiskImageManager(ByteArrayImageLayout diskImageManager) { + this.diskImageManager = diskImageManager; + } + + /** + * Extract a portion of the disk image. + */ + public byte[] readBytes(int start, int length) { + return diskImageManager.readBytes(start, length); + } + + /** + * Write data to the disk image. + */ + public void writeBytes(int start, byte[] bytes) { + diskImageManager.writeBytes(start, bytes); + } + + /** + * Answer with the number of blocks on this device. + */ + public int getBlocksOnDevice() { + return getPhysicalSize() / Disk.BLOCK_SIZE; + } + + /** + * Read the block from the disk image. + */ + public abstract byte[] readBlock(int block); + + /** + * Write the block to the disk image. + */ + public abstract void writeBlock(int block, byte[] data); + + /** + * Indicates that this device is block ordered. + */ + public abstract boolean isBlockDevice(); + + /** + * Indicates that this device is track and sector ordered. + */ + public abstract boolean isTrackAndSectorDevice(); + + /** + * Answer with the number of tracks on this device. + */ + public int getTracksPerDisk() { + return getPhysicalSize() / (getSectorsPerTrack() * Disk.SECTOR_SIZE); + } + + /** + * Answer with the number of sectors per track on this device. + */ + public int getSectorsPerTrack() { + if (isSizeApprox(Disk.APPLE_800KB_DISK) + || isSizeApprox(Disk.APPLE_800KB_2IMG_DISK)) { + return 32; + } + return 16; + } + + /** + * Retrieve the specified sector. + */ + public abstract byte[] readSector(int track, int sector) throws IllegalArgumentException; + + /** + * Write the specified sector. + */ + public abstract void writeSector(int track, int sector, byte[] bytes) throws IllegalArgumentException; + + /** + * Indicates if the physical disk is approximately this size. + * Currently hardcoded to allow up to 10 extra bytes at the end of a + * disk image. Must be at least the requested size! + */ + public boolean isSizeApprox(int value) { + return getPhysicalSize() >= value && getPhysicalSize() <= value + 10; + } + + /** + * Format the media. Formatting at the ImageOrder level deals with + * low-level issues. A typical ordering just needs to have the image + * "wiped," and that is the assumed implementation. However, specialized + * orders - such as a nibbilized disk - need to lay down track and + * sector markers. + */ + public void format() { + int size = diskImageManager.getPhysicalSize(); + diskImageManager.setDiskImage(new byte[size]); + } +} diff --git a/src/com/webcodepro/applecommander/storage/physical/NibbleOrder.java b/src/com/webcodepro/applecommander/storage/physical/NibbleOrder.java new file mode 100644 index 0000000..ba97824 --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/physical/NibbleOrder.java @@ -0,0 +1,361 @@ +/* + * 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.util.AppleUtil; + +import java.util.Arrays; + +/** + * Supports disk images stored in nibbilized DOS physical order. + *

+ * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public class NibbleOrder extends DosOrder { + /** + * This is the 6 and 2 write translate table, as given in Beneath + * Apple DOS, pg 3-21. + */ + private static int[] writeTranslateTable = { + //$0 $1 $2 $3 $4 $5 $6 $7 + 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, // +$00 + 0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3, // +$08 + 0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc, // +$10 + 0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3, // +$18 + 0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, // +$20 + 0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec, // +$28 + 0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, // +$30 + 0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff // +$38 + }; + /** + * This maps a DOS 3.3 sector to a physical sector. + * (readSector and writeSector work off of the DOS 3.3 + * sector numbering.) + */ + private static int[] sectorInterleave = { + 0x0, 0xd, 0xb, 0x9, 0x7, 0x5, 0x3, 0x1, + 0xe, 0xc, 0xa, 0x8, 0x6, 0x4, 0x2, 0xf + }; + + /** + * The read translation table. Constructed from the write + * translate table. Used to decode a disk byte into a value + * from 0x00 to 0x3f which is further decoded... + */ + public int[] readTranslateTable; + + /** + * Construct a NibbleOrder. + */ + public NibbleOrder(ByteArrayImageLayout diskImageManager) { + super(diskImageManager); + // Construct the read translation table: + readTranslateTable = new int[256]; + for (int i=0; i> shiftPairs) & 0x03]; + sectorData[i] = (byte) b; + } + return sectorData; + } + + /** + * Locate a field on the track. These are identified by a 3 byte unique + * signature. Because of the way in which disk bytes are captured, we need + * to wrap around the track to ensure all sequences of bytes are accounted for. + *

+ * This methid fills fieldData as well as returning the last position referenced + * in the track buffer. + */ + protected int locateField(int byte1, int byte2, int byte3, byte[] trackData, byte[] fieldData, int startingOffset) { + int i = startingOffset; // logical position in track buffer (can wrap) + int position = 0; // physical position in field buffer + while (i < trackData.length + fieldData.length) { + int offset = i % trackData.length; // physical posistion in track buffer + int b = AppleUtil.getUnsignedByte(trackData[offset]); + if (position == 0 && b == byte1) { + fieldData[position++] = (byte) b; + } else if (position == 1 && b == byte2) { + fieldData[position++] = (byte) b; + } else if (position == 2 && b == byte3) { + fieldData[position++] = (byte) b; + } else if (position >= 3 && position <= fieldData.length) { + if (position < fieldData.length) fieldData[position++] = (byte) b; + if (position == fieldData.length) break; // done! + } else { + position = 0; + } + i++; + } + return i % trackData.length; + } + + /** + * Decode odd-even bytes as stored on disk. The format will be + * in two bytes. They are stored as such:

+	 *     XX = 1d1d1d1d (odd data bits)
+	 *     YY = 1d1d1d1d (even data bits)
+	 * 
+ * XX is then shifted by a bit and ANDed with YY to get the databyte. + * See page 3-12 in Beneath Apple DOS for more information. + */ + protected int decodeOddEven(byte[] buffer, int offset) { + int b1 = AppleUtil.getUnsignedByte(buffer[offset]); + int b2 = AppleUtil.getUnsignedByte(buffer[offset+1]); + return (b1 << 1 | 0x01) & b2; + } + + /** + * Encode odd-even bytes to be stored on disk. See decodeOddEven + * for the format. + * @see #decodeOddEven + */ + protected void encodeOddEven(byte[] buffer, int offset, int value) { + buffer[offset] = (byte) ((value >> 1) | 0xaa); + buffer[offset+1] = (byte) (value | 0xaa); + } + + /** + * Write the specified sector. + */ + public void writeSector(int track, int dosSector, byte[] sectorData) throws IllegalArgumentException { + int sector = sectorInterleave[dosSector]; + // 1. read track + byte[] trackData = readTrackData(track); + // 2. locate address field for this track and sector + int offset = 0; + byte[] addressField = new byte[14]; + boolean found = false; + while (!found && offset < trackData.length) { + int nextOffset = locateField(0xd5, 0xaa, 0x96, trackData, addressField, offset); + if (nextOffset < offset) { // we wrapped! + throw new IllegalArgumentException("Unable to locate physical sector " + + sector + " on track " + track); + } + offset = nextOffset; + int t = decodeOddEven(addressField, 5); + int s = decodeOddEven(addressField, 7); + found = (t == track && s == sector); + } + if (!found) { + throw new IllegalArgumentException("Unable to locate physical sector " + + sector + " on track " + track + "(#2)"); + } + + // 3. PRENIBBLE: This is Java translated from assembly @ $B800 + // The Java routine was not working... :o( + int[] bb00 = new int[0x100]; + int[] bc00 = new int[0x56]; + int x = 0; + int y = 2; + while (true) { + y--; + if (y < 0) { + y+= 256; + } + int a = AppleUtil.getUnsignedByte(sectorData[y]); + bc00[x]<<= 1; + bc00[x]|= a & 1; + a>>= 1; + bc00[x]<<= 1; + bc00[x]|= a & 1; + a>>= 1; + bb00[y] = a; + x++; + if (x >= 0x56) { + x = 0; + if (y == 0) break; // done + } + } + for (x=0; x<0x56; x++) { + bc00[x]&= 0x3f; + } + + // 4. Translated from portions of WRITE at $B82A: + byte[] diskData = new byte[343]; + int pos = 0; + for (y=0x56; y>0; y--) { + if (y == 0x56) { + diskData[pos++] = (byte) writeTranslateTable[bc00[y-1]]; + } else { + diskData[pos++] = (byte) writeTranslateTable[bc00[y] ^ bc00[y-1]]; + } + } + diskData[pos++] = (byte) writeTranslateTable[bc00[0] ^ bb00[y]]; + for (y=1; y<256; y++) { + diskData[pos++] = (byte) writeTranslateTable[bb00[y] ^ bb00[y-1]]; + } + diskData[pos++] = (byte) writeTranslateTable[bb00[255]]; + + // 5. write to disk (data may wrap - hence the manual copy) + byte[] dataFieldPrologue = new byte[3]; + offset= locateField(0xd5, 0xaa, 0xad, trackData, dataFieldPrologue, offset); + for (int i=0; i + * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public class ProdosOrder extends ImageOrder { + /** + * This table contains the block offset for a particular DOS sector. + */ + private static final int[] blockInterleave = { + 0, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 7 + }; + /** + * Defines the location within a block in which the DOS sector resides. + * (0 = 0-255 and 1 = 256-511.) + */ + private static final int[] blockOffsets = { + 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1 + }; + + /** + * Construct a ProdosOrder. + */ + public ProdosOrder(ByteArrayImageLayout diskImageManager) { + super(diskImageManager); + } + + /** + * Indicates that this device is block ordered. + */ + public boolean isBlockDevice() { + return true; + } + + /** + * Indicates that this device is track and sector ordered. + */ + public boolean isTrackAndSectorDevice() { + return false; + } + + /** + * Read the block from the disk image. + * Note: Defined in terms of reading sectors. + */ + public byte[] readBlock(int block) { + return readBytes(block * Disk.BLOCK_SIZE, Disk.BLOCK_SIZE); + } + + /** + * Write the block to the disk image. + * Note: Defined in terms of reading sectors. + */ + public void writeBlock(int block, byte[] data) { + writeBytes(block * Disk.BLOCK_SIZE, data); + } + + /** + * Retrieve the specified sector. + */ + public byte[] readSector(int track, int sector) throws IllegalArgumentException { + int block = track * 8 + blockInterleave[sector]; + byte[] blockData = readBlock(block); + int offset = blockOffsets[sector]; + byte[] sectorData = new byte[Disk.SECTOR_SIZE]; + System.arraycopy(blockData, offset * Disk.SECTOR_SIZE, + sectorData, 0, Disk.SECTOR_SIZE); + return sectorData; + } + + /** + * Write the specified sector. + */ + public void writeSector(int track, int sector, byte[] bytes) throws IllegalArgumentException { + int block = track * 8 + blockInterleave[sector]; + byte[] blockData = readBlock(block); + int offset = blockOffsets[sector]; + System.arraycopy(bytes, 0, blockData, offset * Disk.SECTOR_SIZE, bytes.length); + writeBlock(block, blockData); + } +} diff --git a/src/com/webcodepro/applecommander/storage/physical/UniversalDiskImageLayout.java b/src/com/webcodepro/applecommander/storage/physical/UniversalDiskImageLayout.java new file mode 100644 index 0000000..b810fe6 --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/physical/UniversalDiskImageLayout.java @@ -0,0 +1,67 @@ +/* + * 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; + +/** + * Manages the physical 2IMG disk. + * @author Rob Greene (RobGreene@users.sourceforge.net) + */ +public class UniversalDiskImageLayout extends ByteArrayImageLayout { + /** + * This is the 2IMG offset. + */ + public static final int OFFSET = 0x40; + + /** + * Construct a UniversalDiskImageLayout. + */ + public UniversalDiskImageLayout(byte[] diskImage) { + super(diskImage); + } + + /** + * Construct a UniversalDiskImageLayout. + */ + public UniversalDiskImageLayout(byte[] diskImage, boolean changed) { + super(diskImage, changed); + } + + /** + * Construct a UniversalDiskImageLayout. + */ + public UniversalDiskImageLayout(int size) { + super(size + 0x40); + } + + /** + * Extract a portion of the disk image. + */ + public byte[] readBytes(int start, int length) { + return super.readBytes(start + 0x40, length); + } + + /** + * Write data to the disk image. + */ + public void writeBytes(int start, byte[] bytes) { + super.writeBytes(start + 0x40, bytes); + } + +}