/* V9t9TrackDiskImage.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.FileInputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.Arrays; import v9t9.common.client.ISettingsHandler; public class V9t9TrackDiskImage extends BaseTrackDiskImage { /* Header for track (*.trk) files; also used internally for sector files, but not present in image: we guess the disk geometry from the size and sector 0 information. */ static final String TRACK_MAGIC = "trak"; static final int TRACK_MAGIC_SIZE = 4; static final int TRACK_VERSION = 1; public static final short TRACK_HEADER_SIZE = 12; public V9t9TrackDiskImage(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-v9t9"; } @Override public void writeImageHeader() throws IOException { if (getHandle() == null || readonly) { return; } /* byteswap header for export */ getHandle().seek(0); getHandle().write(TRACK_MAGIC.getBytes()); getHandle().write(TRACK_VERSION); getHandle().write(hdr.getTracks()); getHandle().write(hdr.getSides()); getHandle().write(hdr.getSecsPerTrack()); getHandle().write(hdr.getTrackSize() >> 8); getHandle().write(hdr.getTrackSize() & 0xff); getHandle().write(hdr.getTrack0Offset() >> 8); getHandle().write(hdr.getTrack0Offset() & 0xff); /* maintain invariants */ growImageForContent(); } /* (non-Javadoc) * @see v9t9.emulator.hardware.dsrs.realdisk.BaseDiskImage#getHeaderSize() */ @Override public int getHeaderSize() { return TRACK_HEADER_SIZE; } @Override public void readImageHeader() throws IOException { if (getHandle() == null) return; readonly |= !spec.canWrite(); getHandle().seek(0); /* byteswap imported header */ byte[] magic = new byte[TRACK_MAGIC.length()]; getHandle().read(magic); byte version = getHandle().readByte(); hdr.setTracks(getHandle().readByte() & 0xff); hdr.setSides(getHandle().readByte() & 0xff); byte spt = getHandle().readByte(); hdr.setTrackSize((((getHandle().read() & 0xff) << 8) | (getHandle().read() & 0xff))); if (spt == 0) { spt = (byte) (hdr.getTrackSize() / 256); if (spt < 18) spt = 9; else spt = 18; } hdr.setSecsPerTrack(spt & 0xff); hdr.setTrack0Offset((((getHandle().read() & 0xff) << 8) | (getHandle().read() & 0xff))); hdr.setSide2DirectionKnown(false); /* verify */ if (!Arrays.equals(TRACK_MAGIC.getBytes(), magic)) { throw new IOException(MessageFormat.format("Disk image ''{0}'' has unknown type (got {1}, expected {2})", spec, new String(magic), TRACK_MAGIC)); } if (version < 1 || version > TRACK_VERSION) { throw new IOException(MessageFormat.format("Disk image ''{0}'' has too new version ({1} > {2})\n", spec, version, TRACK_VERSION)); } if (hdr.getTrackSize() < 0) { throw new IOException(MessageFormat.format("Disk image ''{0}'' has invalid track size {1}\n", spec, hdr.getTrackSize())); } if (hdr.getTrackSize() > RealDiskConsts.DSKbuffersize) { throw new IOException(MessageFormat.format("Disk image has too large track size ({0} > {1})", hdr.getTrackSize(), RealDiskConsts.DSKbuffersize)); } } /* (non-Javadoc) * @see v9t9.emulator.hardware.dsrs.realdisk.BaseDiskImage#getDefaultTrackSize() */ @Override public short getDefaultTrackSize() { return (short) 3210; } public static boolean isTrackImage(File file) { byte[] header = new byte[TRACK_MAGIC.length()]; FileInputStream fis = null; try { fis = new FileInputStream(file); fis.read(header); return Arrays.equals(TRACK_MAGIC.getBytes(), header); } catch (IOException e) { // ignore } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { } } } return false; } }