/* RawTrackDiskImage.java (c) 2010-2013 Edward Swartz All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html */ package v9t9.engine.files.image; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.text.MessageFormat; import v9t9.common.client.ISettingsHandler; /** * Raw track image which has no header * @author ejs * */ public class RawTrackDiskImage extends BaseTrackDiskImage { public RawTrackDiskImage(ISettingsHandler settings, String name, File file) { super(name, file, settings); } /* (non-Javadoc) * @see v9t9.emulator.hardware.dsrs.realdisk.BaseDiskImage#getDiskType() */ @Override public String getDiskType() { return "track-image-raw"; } @Override public void writeImageHeader() throws IOException { if (getHandle() == null || readonly) { return; } /* maintain invariants */ growImageForContent(); } /* (non-Javadoc) * @see v9t9.emulator.hardware.dsrs.realdisk.BaseDiskImage#getHeaderSize() */ @Override public int getHeaderSize() { return 0; } @Override public void readImageHeader() throws IOException { if (getHandle() == null) return; readonly = !spec.canWrite(); // try to get sector 0 byte[] sector = readSector0(getHandle()); if (sector == null) throw new IOException(MessageFormat.format("RawTrackDiskImage: disk image ''{0}'' does not appear to be a raw track image", spec)); hdr.setSides(sector[0x12] & 0xff); hdr.setTracks(sector[0x11] & 0xff); hdr.setSecsPerTrack(sector[0x0C] & 0xff); if (hdr.getTracks() == 0 || hdr.getSides() == 0 || 'D' != sector[0x0D] || 'S' != sector[0x0E] || 'K' != sector[0x0F]) throw new IOException(MessageFormat.format("RawTrackDiskImage: disk image ''{0}'' does not appear to be formatted", spec)); hdr.setTrackSize((int) (getHandle().length() / hdr.getTracks() / hdr.getSides())); if (hdr.getSides() == 1 && hdr.getTrackSize() > 5000) { hdr.setTrackSize(hdr.getTrackSize() / 2); hdr.setSides(hdr.getSides() + 1); } hdr.setTrack0Offset(0); hdr.setSide2DirectionKnown(false); if (hdr.getTrackSize() <= 0) { throw new IOException(MessageFormat.format("RawTrackDiskImage: disk image ''{0}'' has invalid track size {1}\n", spec, hdr.getTrackSize())); } if (hdr.getTrackSize() > RealDiskConsts.DSKbuffersize) { throw new IOException(MessageFormat.format("RawTrackDiskImage: disk image ''{0}'' has too large track size ({1} > {2})", spec, hdr.getTrackSize(), RealDiskConsts.DSKbuffersize)); } } /** * @param handle * @return * @throws IOException */ private static byte[] readSector0(RandomAccessFile handle) throws IOException { int ch; int beforeMarkerSeen = 0; int count = 0; handle.seek(0); while ((ch = handle.read()) >= 0 && count < 18 && ++beforeMarkerSeen < 65536) { if (ch == 0xfe // ID && handle.read() == 0 // track && handle.read() == 0 // ... && handle.read() == 0) // sector { while ((ch = handle.read()) != 0xfb && ch >= 0) /* */ ; if (ch < 0) continue; byte[] sector = new byte[256]; handle.read(sector); if (new String(sector).contains("DSK")) return sector; count++; beforeMarkerSeen = 0; } } return null; } /* (non-Javadoc) * @see v9t9.emulator.hardware.dsrs.realdisk.BaseDiskImage#getDefaultTrackSize() */ @Override public short getDefaultTrackSize() { return (short) 3253; } public static boolean isTrackImage(File file) { RandomAccessFile fh = null; try { fh = new RandomAccessFile(file, "r"); byte[] sector = readSector0(fh); return sector != null; } catch (IOException e) { // ignore } finally { if (fh != null) { try { fh.close(); } catch (IOException e) { } } } return false; } }