From e8a40813991456461d6ab3bcdc4a119cc35ecbb3 Mon Sep 17 00:00:00 2001 From: Date: Mon, 9 Aug 2010 06:40:08 +0000 Subject: [PATCH] Add basic NakedOS support --- .../applecommander/storage/Disk.java | 29 + .../storage/StorageBundle.properties | 1 + .../storage/os/nakedos/NakedosFileEntry.java | 259 +++++++++ .../storage/os/nakedos/NakedosFormatDisk.java | 535 ++++++++++++++++++ .../applecommander/ui/UiBundle.properties | 1 + 5 files changed, 825 insertions(+) create mode 100644 src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFileEntry.java create mode 100644 src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFormatDisk.java diff --git a/src/com/webcodepro/applecommander/storage/Disk.java b/src/com/webcodepro/applecommander/storage/Disk.java index 6b943db..ff18f72 100644 --- a/src/com/webcodepro/applecommander/storage/Disk.java +++ b/src/com/webcodepro/applecommander/storage/Disk.java @@ -34,6 +34,7 @@ import com.webcodepro.applecommander.storage.os.cpm.CpmFormatDisk; import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk; import com.webcodepro.applecommander.storage.os.dos33.OzDosFormatDisk; import com.webcodepro.applecommander.storage.os.dos33.UniDosFormatDisk; +import com.webcodepro.applecommander.storage.os.nakedos.NakedosFormatDisk; import com.webcodepro.applecommander.storage.os.gutenberg.GutenbergFormatDisk; import com.webcodepro.applecommander.storage.os.pascal.PascalFormatDisk; import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk; @@ -248,6 +249,9 @@ public class Disk { } else if (isDosFormat()) { return new FormattedDisk[] { new DosFormatDisk(filename, imageOrder) }; + } else if (isNakedosFormat()) { + return new FormattedDisk[] + { new NakedosFormatDisk(filename, imageOrder) }; } else if (isPascalFormat()) { return new FormattedDisk[] { new PascalFormatDisk(filename, imageOrder) }; @@ -482,6 +486,31 @@ public class Disk { && vtoc[0x137] == 1; // bytes per sector (high byte) } + /** + * Test the disk format to see if this is a NakedOS formatted + * disk. + */ + public boolean isNakedosFormat() { + if (!is140KbDisk()) return false; + byte[] vtoc = readSector(0, 3); // VTOC starts on sector 9 (mapped to 3) + return (imageOrder.isSizeApprox(APPLE_140KB_DISK) + || imageOrder.isSizeApprox(APPLE_140KB_NIBBLE_DISK)) + && vtoc[0xd0] == -2 // expect DOS as reserved + && vtoc[0xd1] == -2 // expect DOS as reserved + && vtoc[0xd2] == -2 // expect DOS as reserved + && vtoc[0xd3] == -2 // expect DOS as reserved + && vtoc[0xd4] == -2 // expect DOS as reserved + && vtoc[0xd5] == -2 // expect DOS as reserved + && vtoc[0xd6] == -2 // expect DOS as reserved + && vtoc[0xd7] == -2 // expect DOS as reserved + && vtoc[0xd8] == -2 // expect DOS as reserved + && vtoc[0xd9] == -2 // expect DOS as reserved + && vtoc[0xda] == -2 // expect DOS as reserved + && vtoc[0xdb] == -2 // expect DOS as reserved + && vtoc[0xdc] != -2 // expect something besides DOS next + ; + } + /** * Test the disk format to see if this is a Pascal formatted * disk. Pascal disks may be either 140K or 800K. diff --git a/src/com/webcodepro/applecommander/storage/StorageBundle.properties b/src/com/webcodepro/applecommander/storage/StorageBundle.properties index 1544aeb..5eb850c 100644 --- a/src/com/webcodepro/applecommander/storage/StorageBundle.properties +++ b/src/com/webcodepro/applecommander/storage/StorageBundle.properties @@ -21,6 +21,7 @@ Modified=Modified SizeInBytes=Size (bytes) DiskNameN={0} (Disk {1}) Dos33=DOS 3.3 +NakedOS=NakedOS LockedQ=Locked? DirectoryCreationNotSupported=Unable to create directories. Gutenberg=Gutenberg diff --git a/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFileEntry.java b/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFileEntry.java new file mode 100644 index 0000000..a03b817 --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFileEntry.java @@ -0,0 +1,259 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 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.os.nakedos; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; + +import com.webcodepro.applecommander.storage.DiskFullException; +import com.webcodepro.applecommander.storage.FileEntry; +import com.webcodepro.applecommander.storage.FileFilter; +import com.webcodepro.applecommander.storage.FormattedDisk; +import com.webcodepro.applecommander.storage.StorageBundle; +import com.webcodepro.applecommander.storage.filters.BinaryFileFilter; +import com.webcodepro.applecommander.util.AppleUtil; +import com.webcodepro.applecommander.util.TextBundle; + +/** + * Represents a Nakedos file entry on disk. + *

+ * Date created: August 5, 2010 10:23:23 AM + * @author David Schmidt + */ +public class NakedosFileEntry implements FileEntry { + + private TextBundle textBundle = StorageBundle.getInstance(); + /** + * Holds the disk the FileEntry is attached to. + */ + private NakedosFormatDisk disk; + /** + * The file number/name of this file + */ + private int fileNumber; + /** + * The number of sectors used by this file + */ + private int size; + + /** + * Constructor for NakedosFileEntry. + */ + public NakedosFileEntry(NakedosFormatDisk disk, int fileNumber, int size) { + super(); + this.disk = disk; + this.fileNumber = fileNumber; + this.size = size; + } + + /** + * Return the name of this file. + * @see com.webcodepro.applecommander.storage.FileEntry#getFilename() + */ + public String getFilename() { + return AppleUtil.getFormattedByte(fileNumber); + } + + /** + * Return the name of this file. + * @see com.webcodepro.applecommander.storage.FileEntry#getFilename() + */ + public int getFileNumber() { + return fileNumber; + } + + /** + * Set the name of this file. + */ + public void setFilename(String filename) { + /* Not sure that there's a useful analogy for NakedOS... */ + } + + /** + * Return the filetype of this file. + * @see com.webcodepro.applecommander.storage.FileEntry#getFiletype() + */ + public String getFiletype() { + return "B"; // Only one file type... binary //$NON-NLS-1$ + } + + /** + * Set the filetype (typeless - unused) + */ + public void setFiletype(String filetype) { + /* Not sure that there's a useful analogy for NakedOS... */ + } + + /** + * Identify if this file is locked. + * @see com.webcodepro.applecommander.storage.FileEntry#isLocked() + */ + public boolean isLocked() { + /* No file locking in NakedOS */ + return false; + } + + /** + * Set the lock indicator (unused) + */ + public void setLocked(boolean lock) { + /* No file locking in NakedOS */ + } + + /** + * Compute the size of this file (in bytes). + * @see com.webcodepro.applecommander.storage.FileEntry#getSize() + */ + public int getSize() { + return size*256; + } + + /** + * Identify if this is a directory file. + * @see com.webcodepro.applecommander.storage.FileEntry#isDirectory() + */ + public boolean isDirectory() { + return false; + } + + /** + * Identify if this file has been deleted. + * @see com.webcodepro.applecommander.storage.FileEntry#isDeleted() + */ + public boolean isDeleted() { + return false; + } + + /** + * Delete this file (unimplemented). + */ + public void delete() { + // TODO Auto-generated method stub + } + + /** + * Get the standard file column header information. + * This default implementation is intended only for standard mode. + * displayMode is specified in FormattedDisk. + */ + public List getFileColumnData(int displayMode) { + NumberFormat numberFormat = NumberFormat.getNumberInstance(); + List list = new ArrayList(); + switch (displayMode) { + case FormattedDisk.FILE_DISPLAY_NATIVE: + list.add(isLocked() ? "*" : " "); //$NON-NLS-1$ //$NON-NLS-2$ + list.add(getFiletype()); + numberFormat.setMinimumIntegerDigits(3); + list.add(numberFormat.format(getSize()/256)); + list.add(getFilename()); + break; + case FormattedDisk.FILE_DISPLAY_DETAIL: + list.add(isLocked() ? "*" : " "); //$NON-NLS-1$ //$NON-NLS-2$ + list.add(getFiletype()); + list.add(getFilename()); + list.add(numberFormat.format(getSize())); + numberFormat.setMinimumIntegerDigits(3); + list.add(numberFormat.format(getSize()/256)); + list.add(isDeleted() ? textBundle.get("Deleted") : ""); //$NON-NLS-1$//$NON-NLS-2$ + break; + default: // FILE_DISPLAY_STANDARD + list.add(getFilename()); + list.add(getFiletype()); + list.add(numberFormat.format(getSize())); + list.add(isLocked() ? textBundle.get("Locked") : ""); //$NON-NLS-1$//$NON-NLS-2$ + break; + } + return list; + } + + /** + * Get file data. This handles any operating-system specific issues. + */ + public byte[] getFileData() { + return disk.getFileData(this); + } + + /** + * Set the file data. + * + * Note: The address can be set before the data is saved or + * after the data is saved. This is an attempt to make the + * API more easily usable. + * + * Empirically, the data must be set before the address is set. + */ + public void setFileData(byte[] data) throws DiskFullException { + disk.setFileData(this, data); + } + + /** + * Get the suggested FileFilter. This appears to be operating system + * specific, so each operating system needs to implement some manner + * of guessing the appropriate filter. + * FIXME - this code should be a helper class for DOS and RDOS! + */ + public FileFilter getSuggestedFilter() { + return new BinaryFileFilter(); + } + + /** + * Get the FormattedDisk associated with this FileEntry. + * This is useful to interfaces that need to retrieve the associated + * disk. + */ + public FormattedDisk getFormattedDisk() { + return disk; + } + + /** + * Return the maximum filename length. + */ + public int getMaximumFilenameLength() { + return 2; + } + + /** + * Indicates if this filetype requires an address component. + * Note that the FormattedDisk also has this method - normally, + * this will defer to the method on FormattedDisk, as it will be + * more generic. + */ + public boolean needsAddress() { + return false; + } + + /** + * Set the address that this file loads at. + */ + public void setAddress(int address) { + } + + /** + * Indicates that this filetype can be compiled. + */ + public boolean canCompile() { + return false; + } + + public boolean equals (Object o) { + return this.getFilename().equals(((NakedosFileEntry)o).getFilename()); + } +} diff --git a/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFormatDisk.java b/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFormatDisk.java new file mode 100644 index 0000000..63049bb --- /dev/null +++ b/src/com/webcodepro/applecommander/storage/os/nakedos/NakedosFormatDisk.java @@ -0,0 +1,535 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002, 2008 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.os.nakedos; + +import java.util.ArrayList; +import java.util.List; + +import com.webcodepro.applecommander.storage.DirectoryEntry; +import com.webcodepro.applecommander.storage.DiskFullException; +import com.webcodepro.applecommander.storage.FileEntry; +import com.webcodepro.applecommander.storage.FormattedDisk; +import com.webcodepro.applecommander.storage.StorageBundle; +import com.webcodepro.applecommander.storage.physical.ImageOrder; +import com.webcodepro.applecommander.util.AppleUtil; +import com.webcodepro.applecommander.util.TextBundle; + +/** + * Manages a disk that is in NakedOS format. + *

+ * Date created: August 5, 2010 10:23:23 AM + * @author David Schmidt + */ +public class NakedosFormatDisk extends FormattedDisk { + private TextBundle textBundle = StorageBundle.getInstance(); + /** + * Indicates the index of the track in the location array. + */ + public static final int TRACK_LOCATION_INDEX = 0; + /** + * Indicates the index of the sector in the location array. + */ + public static final int SECTOR_LOCATION_INDEX = 1; + /** + * The catalog track. + */ + public static final int CATALOG_TRACK = 0; + /** + * The VTOC sector. + */ + public static final int VTOC_SECTOR = 3; // Logically 9, 10, 11; physically, 3, 10, 2 + /** + * The standard track/sector pairs in a track/sector list. + */ + public static final int TRACK_SECTOR_PAIRS = 122; + /** + * The list of filetypes available. + */ + private static final String[] filetypes = { + "B" //$NON-NLS-1$ + }; + /** + * The number of sectors used on the disk + */ + private int usedSectors = 0; + + private static final int[] sectorTranslate = {0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15}; + /** + * Use this inner interface for managing the disk usage data. + * This offloads format-specific implementation to the implementing class. + */ + private class WPDiskUsage implements DiskUsage { + private int[] location = null; + public boolean hasNext() { + return location == null + || (location[TRACK_LOCATION_INDEX] < getTracks() + && location[SECTOR_LOCATION_INDEX] < getSectors()); + } + public void next() { + if (location == null) { + location = new int[2]; + } else { + location[SECTOR_LOCATION_INDEX]++; + if (location[SECTOR_LOCATION_INDEX] >= getSectors()) { + location[SECTOR_LOCATION_INDEX] = 0; + location[TRACK_LOCATION_INDEX]++; + } + } + } + /** + * Get the free setting for the bitmap at the current location. + * I don't think there is a map stored on disk, however. + */ + public boolean isFree() { + if (location == null || location.length != 2) { + throw new IllegalArgumentException(StorageBundle.getInstance() + .get("DosFormatDisk.InvalidDimensionError")); //$NON-NLS-1$ + } + return false; + } + public boolean isUsed() { + return !isFree(); + } + } + + /**) + * Constructor for NakedosFormatDisk. + */ + public NakedosFormatDisk(String filename, ImageOrder imageOrder) { + super(filename, imageOrder); + } + + /** + * Create a NakedosFormatDisk. All DOS disk images are expected to + * be 140K in size. + */ + public static NakedosFormatDisk[] create(String filename, ImageOrder imageOrder) { + NakedosFormatDisk disk = new NakedosFormatDisk(filename, imageOrder); + disk.format(); + return new NakedosFormatDisk[] { disk }; + } + + /** + * Identify the operating system format of this disk as Nakedos. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getFormat() + */ + public String getFormat() { + return textBundle.get("NakedOS"); //$NON-NLS-1$ + } + + /** + * Retrieve a list of files. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles() + */ + public List getFiles() { + ArrayList list = new ArrayList(); + int totalUsed = 0; + int i; + int[] fileSizes = new int[256]; + byte[] catalogSector1 = readSector(CATALOG_TRACK, 3); + byte[] catalogSector2 = readSector(CATALOG_TRACK, 10); + byte[] catalogSector3 = readSector(CATALOG_TRACK, 2); + for (i = 0;i<48;i++) { + if ((catalogSector1[i+0xd0] != -2) && (catalogSector1[i+0xd0] != -1)) + fileSizes[AppleUtil.getUnsignedByte(catalogSector1[i+0xd0])]+=1; + if (catalogSector1[i+0xd0] != -1) + totalUsed++; + } + for (i = 0;i<256;i++) { + if ((catalogSector2[i] != -2) && (catalogSector2[i] != -1)) + fileSizes[AppleUtil.getUnsignedByte(catalogSector2[i])]+=1; + if ((catalogSector3[i] != -2) && (catalogSector3[i] != -1)) + fileSizes[AppleUtil.getUnsignedByte(catalogSector3[i])]+=1; + if (catalogSector2[i] != -1) + totalUsed++; + if (catalogSector3[i] != -1) + totalUsed++; + } + for (i = 0;i<256;i++) { + if (fileSizes[i] != 0) { + list.add(new NakedosFileEntry(this, i,fileSizes[i])); + } + } + usedSectors = totalUsed; + return list; + } + + /** + * Create a FileEntry. + */ + public FileEntry createFile() throws DiskFullException { + return new NakedosFileEntry(this, -2, 0); + } + + /** + * Identify if additional directories can be created. This + * may indicate that directories are not available to this + * operating system or simply that the disk image is "locked" + * to writing. + */ + public boolean canCreateDirectories() { + return false; + } + + /** + * Indicates if this disk image can create a file. + * If not, the reason may be as simple as it has not been implemented + * to something specific about the disk. + */ + public boolean canCreateFile() { + return false; + } + + /** + * Compute the amount of freespace available on the disk. + * This algorithm completely ignores tracks and sectors by + * running through the entire bitmap stored on the VTOC. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getFreeSpace() + */ + public int getFreeSpace() { + return getFreeSectors() * SECTOR_SIZE; + } + + /** + * Compute the number of free sectors available on the disk. + */ + public int getFreeSectors() { + return getTotalSectors() - getUsedSectors(); + } + + /** + * Return the amount of used space in bytes. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getUsedSpace() + */ + public int getUsedSpace() { + return usedSectors * 256; + } + + /** + * Compute the number of used sectors on the disk. + */ + public int getUsedSectors() { + return usedSectors; + } + + /** + * Compute the total number of sectors available on the disk. + */ + public int getTotalSectors() { + int tracks = getTracks(); + int sectors = getSectors(); + return tracks * sectors; + } + + /** + * Return the disk name. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getDiskName() + */ + public String getDiskName() { + // Pull the disk name out... + return ""; + } + + /** + * Return the VTOC (Volume Table Of Contents). + */ + protected byte[] readVtoc() { + return readSector(CATALOG_TRACK, VTOC_SECTOR); + } + + /** + * Save the VTOC (Volume Table Of Contents) to disk. + */ + protected void writeVtoc(byte[] vtoc) { + writeSector(CATALOG_TRACK, VTOC_SECTOR, vtoc); + } + + /** + * Get the disk usage iterator. + */ + public DiskUsage getDiskUsage() { + return new WPDiskUsage(); + } + + /** + * Get the number of tracks on this disk. + */ + public int getTracks() { + return 35; + } + + /** + * Get the number of sectors on this disk. + */ + public int getSectors() { + return 16; + } + + /** + * Get suggested dimensions for display of bitmap. For DOS 3.3, that information + * is stored in the VTOC, and that information is fairly important. + * @see com.webcodepro.applecommander.storage.FormattedDisk#getBitmapDimensions() + */ + public int[] getBitmapDimensions() { + int tracks = getTracks(); + int sectors = getSectors(); + return new int[] { tracks, sectors }; + } + + /** + * Get the length of the bitmap. + */ + public int getBitmapLength() { + return getTotalSectors(); + } + + /** + * Get the labels to use in the bitmap. + */ + public String[] getBitmapLabels() { + return new String[] { textBundle.get("DosFormatDisk.Track"), textBundle.get("DosFormatDisk.Sector") }; //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Get WP-specific disk information. + */ + public List getDiskInformation() { + getFiles(); + List list = super.getDiskInformation(); + return list; + } + + /** + * Get the standard file column header information. + * This default implementation is intended only for standard mode. + */ + public List getFileColumnHeaders(int displayMode) { + List list = new ArrayList(); + switch (displayMode) { + case FILE_DISPLAY_NATIVE: + list.add(new FileColumnHeader(" ", 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.Type"), 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.SizeInSectors"), 3, FileColumnHeader.ALIGN_RIGHT)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("Name"), 30, //$NON-NLS-1$ + FileColumnHeader.ALIGN_LEFT)); + break; + case FILE_DISPLAY_DETAIL: + list.add(new FileColumnHeader(" ", 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.Type"), 1, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("Name"), 30, //$NON-NLS-1$ + FileColumnHeader.ALIGN_LEFT)); + list.add(new FileColumnHeader(textBundle.get("SizeInBytes"), 6, //$NON-NLS-1$ + FileColumnHeader.ALIGN_RIGHT)); + list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.SizeInSectors"), 3, FileColumnHeader.ALIGN_RIGHT)); //$NON-NLS-1$ + list.add(new FileColumnHeader(textBundle.get("DeletedQ"), 7, //$NON-NLS-1$ + FileColumnHeader.ALIGN_CENTER)); + list.add(new FileColumnHeader(textBundle.get("DosFormatDisk.TrackAndSectorList"), 7, FileColumnHeader.ALIGN_CENTER)); //$NON-NLS-1$ + break; + default: // FILE_DISPLAY_STANDARD + list.addAll(super.getFileColumnHeaders(displayMode)); + break; + } + return list; + } + + /** + * Indicates if this disk format supports "deleted" files. + */ + public boolean supportsDeletedFiles() { + return true; + } + + /** + * Indicates if this disk image can read data from a file. + */ + public boolean canReadFileData() { + return true; + } + + /** + * Indicates if this disk image can write data to a file. + */ + public boolean canWriteFileData() { + return false; + } + + /** + * Identify if this disk format as not capable of having directories. + * @see com.webcodepro.applecommander.storage.FormattedDisk#canHaveDirectories() + */ + public boolean canHaveDirectories() { + return false; + } + + /** + * Indicates if this disk image can delete a file. + */ + public boolean canDeleteFile() { + return false; + } + + /** + * Get the data associated with the specified FileEntry. + */ + public byte[] getFileData(FileEntry fileEntry) { + if ( !(fileEntry instanceof NakedosFileEntry)) { + throw new IllegalArgumentException(textBundle.get("DosFormatDisk.InvalidFileEntryError")); //$NON-NLS-1$ + } + int offset = 0; + byte[] catalogSector1 = readSector(CATALOG_TRACK, 3); + byte[] catalogSector2 = readSector(CATALOG_TRACK, 10); + byte[] catalogSector3 = readSector(CATALOG_TRACK, 2); + NakedosFileEntry entry = (NakedosFileEntry) fileEntry; + byte[] fileData = new byte[entry.getSize()]; + for (int i = 0;i<48;i++) { + if (AppleUtil.getUnsignedByte(catalogSector1[i+0xd0]) == entry.getFileNumber()) { + byte[] fileData1 = readSector(i/16,sectorTranslate[i%16]); + System.arraycopy(fileData1, 0, fileData, offset, fileData1.length); + offset+=fileData1.length; + } + } + for (int i = 0;i<256;i++) { + if (AppleUtil.getUnsignedByte(catalogSector2[i]) == entry.getFileNumber()) { + byte[] fileData1 = readSector((i+48)/16,sectorTranslate[(i+48)%16]); + System.arraycopy(fileData1, 0, fileData, offset, fileData1.length); + offset+=fileData1.length; + } + } + for (int i = 0;i<256;i++) { + if (AppleUtil.getUnsignedByte(catalogSector3[i]) == entry.getFileNumber()) { + byte[] fileData1 = readSector((i+48+256)/16,sectorTranslate[(i+48+256)%16]); + System.arraycopy(fileData1, 0, fileData, offset, fileData1.length); + offset+=fileData1.length; + } + } + return fileData; + } + + /** + * 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). + * Typically, the FileEntry.setFileData method should be used. + */ + public void setFileData(FileEntry fileEntry, byte[] fileData) throws DiskFullException { + setFileData((NakedosFileEntry)fileEntry, fileData); + } + + /** + * Set the data associated with the specified NakedosFileEntry into sectors + * on the disk. + */ + protected void setFileData(NakedosFileEntry fileEntry, byte[] data) throws DiskFullException { + // compute free space and see if the data will fit! + } + + /** + * Format the disk as DOS 3.3. + * @see com.webcodepro.applecommander.storage.FormattedDisk#format() + */ + public void format() { + getImageOrder().format(); + format(); + } + + /** + * Format the disk as NakedOS. + */ + protected void format(int tracksPerDisk, int sectorsPerTrack) { + // TODO: get an image of a "blank" NakedOS disk and capture the boot code + } + + /** + * Validate track/sector range. This just validates the + * maximum values allowable for track and sector. + */ + protected void checkRange(int track, int sector) { + if (track > 50 || sector > 32) { + throw new IllegalArgumentException( + textBundle.format("DosFormatDisk.InvalidTrackAndSectorCombinationError", //$NON-NLS-1$ + track, sector)); + } + } + + /** + * Returns the logical disk number. Returns a 0 to indicate no numbering. + */ + public int getLogicalDiskNumber() { + return 0; + } + + /** + * Returns a valid filename for the given filename. + */ + public String getSuggestedFilename(String filename) { + int len = Math.min(filename.length(), 2); + return filename.toUpperCase().substring(0, len).trim(); + } + + /** + * Returns a valid filetype for the given filename. The most simple + * format will just assume a filetype of binary. This method is + * available for the interface to make an intelligent first guess + * as to the filetype. + */ + public String getSuggestedFiletype(String filename) { + return "B"; //$NON-NLS-1$ + } + + /** + * Returns a list of possible file types. Since the filetype is + * specific to each operating system, a simple String is used. + */ + public String[] getFiletypes() { + return filetypes; + } + + /** + * Indicates if this filetype requires an address component. + * For DOS, only the Binary type needs an address. + */ + public boolean needsAddress(String filetype) { + return "B".equals(filetype); //$NON-NLS-1$ + } + + /** + * Indicates if this FormattedDisk supports a disk map. + */ + public boolean supportsDiskMap() { + return true; + } + + /** + * Change to a different ImageOrder. Remains in DOS 3.3 format but + * the underlying order can change. + * @see ImageOrder + */ + public void changeImageOrder(ImageOrder imageOrder) { + AppleUtil.changeImageOrderByTrackAndSector(getImageOrder(), imageOrder); + setImageOrder(imageOrder); + } + + /** + * Create a new DirectoryEntry. + * @see com.webcodepro.applecommander.storage.DirectoryEntry#createDirectory() + */ + public DirectoryEntry createDirectory() throws DiskFullException { + throw new UnsupportedOperationException(textBundle.get("DirectoryCreationNotSupported")); //$NON-NLS-1$ + } +} diff --git a/src/com/webcodepro/applecommander/ui/UiBundle.properties b/src/com/webcodepro/applecommander/ui/UiBundle.properties index 9d53bce..02e5f8e 100644 --- a/src/com/webcodepro/applecommander/ui/UiBundle.properties +++ b/src/com/webcodepro/applecommander/ui/UiBundle.properties @@ -206,6 +206,7 @@ Unidos=UniDOS Ozdos=OzDOS Rdos=RDOS 2.1 Cpm=CP/M +NakedOS=NakedOS BrowseButton=Browse... CancelButton=Cancel OkButton=OK