mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-11-12 23:06:59 +00:00
removed old code
This commit is contained in:
parent
a5542f60ec
commit
80fcc09ab4
@ -22,7 +22,8 @@ public abstract class HiResImage extends AbstractFile
|
||||
// $06 BIN $2000 eof $4000 - DoubleHiResImage
|
||||
// $06 BIN $1FFF eof $1FF8/$1FFF/$2000/$4000 - OriginalHiResImage
|
||||
// $06 BIN $2000 eof $1FF8/$1FFF/$2000/$4000 - OriginalHiResImage
|
||||
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 - OriginalHiResImage
|
||||
// $06 BIN $4000 eof $1FF8/$1FFF/$2000/$4000 - OriginalHiResImage (?)
|
||||
// $06 BIN $4000 eof $4000 - DoubleHiResImage (?)
|
||||
// $06 BIN .3200 - SHRPictureFile2
|
||||
// $06 BIN .3201 - SHRPictureFile2
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class ShapeTable extends AbstractFile
|
||||
{
|
||||
Shape shape = new Shape (buffer, i);
|
||||
if (!shape.valid)
|
||||
return;
|
||||
continue; // shape table should be abandoned
|
||||
shapes.add (shape);
|
||||
|
||||
minRow = Math.min (minRow, shape.minRow);
|
||||
@ -125,6 +125,10 @@ public class ShapeTable extends AbstractFile
|
||||
int offset = HexFormatter.unsignedShort (buffer, ptr);
|
||||
if (offset == 0 || offset >= buffer.length)
|
||||
return false;
|
||||
|
||||
// check if previous shape ended with zero
|
||||
// if (i > 0 && buffer[offset - 1] > 0)
|
||||
// return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -247,7 +251,7 @@ public class ShapeTable extends AbstractFile
|
||||
void convertGrid (int offsetRows, int offsetColumns, int rows, int columns)
|
||||
{
|
||||
// System.out.printf ("Converting shape # %d%n", index);
|
||||
// System.out.printf ("offsetRows %d offsetCols %d%n", offsetRows,
|
||||
// System.out.printf ("offsetRows %d offsetCols %d%n", offsetRows,
|
||||
// offsetColumns);
|
||||
// System.out.printf ("rows %d cols %d%n", rows, columns);
|
||||
|
||||
|
@ -18,7 +18,6 @@ import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||
import com.bytezone.diskbrowser.nib.NibFile;
|
||||
import com.bytezone.diskbrowser.nib.V2dFile;
|
||||
import com.bytezone.diskbrowser.nib.WozFile;
|
||||
import com.bytezone.diskbrowser.nib.WozFileOld;
|
||||
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
|
||||
@ -244,31 +243,6 @@ public class AppleDisk implements Disk
|
||||
diskBuffer = disk.getDiskBuffer ();
|
||||
}
|
||||
|
||||
public AppleDisk (WozFileOld wozFile, int tracks, int sectors)
|
||||
{
|
||||
this.tracks = tracks;
|
||||
this.sectors = sectors;
|
||||
file = wozFile.file;
|
||||
diskBuffer = wozFile.getDiskBuffer ();
|
||||
|
||||
if (sectors == 13)
|
||||
{
|
||||
trackSize = 0xD00;
|
||||
sectorSize = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackSize = 0x1000;
|
||||
sectorSize = trackSize / sectors;
|
||||
}
|
||||
|
||||
blocks = tracks * sectors;
|
||||
hasData = new boolean[blocks];
|
||||
// isMissing = new boolean[blocks];
|
||||
|
||||
checkSectorsForData ();
|
||||
}
|
||||
|
||||
public AppleDisk (WozFile wozFile, int tracks, int sectors)
|
||||
{
|
||||
this.tracks = tracks;
|
||||
|
@ -1,40 +0,0 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
class DiskAddressField
|
||||
{
|
||||
int track, sector, volume, checksum;
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// constructor
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
DiskAddressField (byte[] buffer)
|
||||
{
|
||||
volume = decode4and4 (buffer, 0);
|
||||
track = decode4and4 (buffer, 2);
|
||||
sector = decode4and4 (buffer, 4);
|
||||
checksum = decode4and4 (buffer, 6);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// decode4and4
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private int decode4and4 (byte[] buffer, int offset)
|
||||
{
|
||||
int odds = ((buffer[offset] & 0xFF) << 1) | 0x01;
|
||||
int evens = buffer[offset + 1] & 0xFF;
|
||||
return odds & evens;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// toString
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return String.format ("[volume: %02X, track: %02X, sector: %02X, checksum: %02X]",
|
||||
volume, track, sector, checksum);
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ public abstract class DiskReader
|
||||
|
||||
abstract byte[] encodeSector (byte[] buffer);
|
||||
|
||||
abstract void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer);
|
||||
// abstract void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer);
|
||||
|
||||
abstract int expectedDataSize ();
|
||||
}
|
||||
|
@ -92,14 +92,14 @@ public class DiskReader13Sector extends DiskReader
|
||||
// storeBuffer
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
@Override
|
||||
void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer)
|
||||
{
|
||||
DiskAddressField addressField = diskSector.addressField;
|
||||
byte[] sectorBuffer = diskSector.buffer;
|
||||
int offset = addressField.track * 0x0D00 + addressField.sector * 256;
|
||||
System.arraycopy (sectorBuffer, 0, diskBuffer, offset, 256);
|
||||
}
|
||||
// @Override
|
||||
// void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer)
|
||||
// {
|
||||
// DiskAddressField addressField = diskSector.addressField;
|
||||
// byte[] sectorBuffer = diskSector.buffer;
|
||||
// int offset = addressField.track * 0x0D00 + addressField.sector * 256;
|
||||
// System.arraycopy (sectorBuffer, 0, diskBuffer, offset, 256);
|
||||
// }
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// expectedDataSize
|
||||
|
@ -126,14 +126,14 @@ public class DiskReader16Sector extends DiskReader
|
||||
// storeBuffer
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
@Override
|
||||
void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer)
|
||||
{
|
||||
DiskAddressField addressField = diskSector.addressField;
|
||||
byte[] sectorBuffer = diskSector.buffer;
|
||||
int offset = addressField.track * 0x1000 + interleave[addressField.sector] * 256;
|
||||
System.arraycopy (sectorBuffer, 0, diskBuffer, offset, 256);
|
||||
}
|
||||
// @Override
|
||||
// void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer)
|
||||
// {
|
||||
// DiskAddressField addressField = diskSector.addressField;
|
||||
// byte[] sectorBuffer = diskSector.buffer;
|
||||
// int offset = addressField.track * 0x1000 + interleave[addressField.sector] * 256;
|
||||
// System.arraycopy (sectorBuffer, 0, diskBuffer, offset, 256);
|
||||
// }
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// expectedDataSize
|
||||
|
@ -1,392 +0,0 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class MC3470
|
||||
{
|
||||
private static final int MAX_DATA = 999;
|
||||
private final boolean debug = false;
|
||||
private final boolean dump = true;
|
||||
|
||||
private List<RawDiskSector> diskSectors;
|
||||
|
||||
private State currentState;
|
||||
private RawDiskSector currentDiskSector;
|
||||
|
||||
private int expectedDataSize;
|
||||
private boolean finished;
|
||||
private boolean restarted;
|
||||
|
||||
private DiskReader diskReader;
|
||||
private final DiskReader diskReader16Sector = new DiskReader16Sector ();
|
||||
private final DiskReader diskReader13Sector = new DiskReader13Sector ();
|
||||
|
||||
private final byte[] dataBuffer = new byte[MAX_DATA];
|
||||
private int dataPtr;
|
||||
|
||||
private final byte[] rawBytes = new byte[8000];
|
||||
|
||||
// D5 AA 96 16 sector address prologue
|
||||
// D5 AA B5 13 sector address prologue
|
||||
// D5 AA AD data prologue
|
||||
// DE AA EB epilogue
|
||||
|
||||
// non-standard:
|
||||
// D4 AA 96 address prologue - Bouncing Kamungas
|
||||
// D5 BB CF data prologue - Hard Hat Mac
|
||||
// DA AA EB address epilogue - Bouncing Kamungas
|
||||
// DD AA AD ?? prologue - Wings of Fury (4&4 data)
|
||||
|
||||
private static final byte[] address16prologue =
|
||||
{ (byte) 0xD5, (byte) 0xAA, (byte) 0x96 };
|
||||
private static final byte[] address13prologue =
|
||||
{ (byte) 0xD5, (byte) 0xAA, (byte) 0xB5 };
|
||||
private static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
|
||||
private static final byte[] epilogue = { (byte) 0xDE, (byte) 0xAA, (byte) 0xEB };
|
||||
|
||||
private static final byte[] address16prologueX =
|
||||
{ (byte) 0xD4, (byte) 0xAA, (byte) 0x96 };
|
||||
private static final byte[] dataPrologueX = { (byte) 0xD5, (byte) 0xBB, (byte) 0xCF };
|
||||
private static final byte[] epilogueX = { (byte) 0xDA, (byte) 0xAA, (byte) 0xEB };
|
||||
|
||||
private static final byte[][] master =
|
||||
{ address16prologue, address13prologue, dataPrologue, epilogue, address16prologueX,
|
||||
dataPrologueX, epilogueX };
|
||||
private static final String[] masterNames =
|
||||
{ "Address Prologue 16", "Address Prologue 13", "Data Prologue", "Epilogue",
|
||||
"Address Prologue 16 X", "Data Prologue X", "Epilogue X" };
|
||||
|
||||
private enum State
|
||||
{
|
||||
ADDRESS, DATA, OTHER
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// readTrack
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
List<RawDiskSector> readTrack (byte[] buffer, int offset, int bytesUsed, int bitCount)
|
||||
throws DiskNibbleException
|
||||
{
|
||||
assert false : "Not used";
|
||||
int totalBits = 0;
|
||||
int totalBytes = 0;
|
||||
|
||||
diskSectors = new ArrayList<> ();
|
||||
diskReader = null;
|
||||
currentDiskSector = null;
|
||||
currentState = State.OTHER;
|
||||
expectedDataSize = MAX_DATA;
|
||||
restarted = false;
|
||||
|
||||
byte value = 0; // value to be stored
|
||||
dataPtr = 0;
|
||||
|
||||
int inPtr = offset; // keep offset in case we have to loop around
|
||||
final int max = offset + bytesUsed;
|
||||
finished = false;
|
||||
int zeroBits = 0;
|
||||
|
||||
while (inPtr < max && !finished)
|
||||
{
|
||||
byte b = buffer[inPtr++];
|
||||
|
||||
if (!restarted)
|
||||
totalBytes++;
|
||||
|
||||
for (int mask = 0x80; mask != 0; mask >>>= 1)
|
||||
{
|
||||
value <<= 1; // make space for next bit
|
||||
if ((b & mask) != 0) // is next bit == 1?
|
||||
{
|
||||
value |= 0x01; // store 1
|
||||
zeroBits = 0; // reset zero counter
|
||||
}
|
||||
else
|
||||
{
|
||||
++zeroBits; // increment zero counter
|
||||
if (zeroBits > 2) // looks like copy protection
|
||||
{
|
||||
if (debug)
|
||||
System.out.printf ("%d consecutive zeroes @ %d/%d %s - %,d%n", zeroBits,
|
||||
diskSectors.size (), dataPtr, currentState, totalBits);
|
||||
value |= 0x01; // store 1
|
||||
zeroBits = 0; // reset zero counter
|
||||
}
|
||||
}
|
||||
|
||||
if ((value & 0x80) != 0) // value is not valid until the hi-bit is set
|
||||
{
|
||||
if (dump)
|
||||
{
|
||||
if (dataPtr % 16 == 0)
|
||||
System.out.printf ("%n%04X: ", dataPtr);
|
||||
System.out.printf ("%02X ", value);
|
||||
}
|
||||
|
||||
if (dataPtr >= MAX_DATA)
|
||||
throw new DiskNibbleException ("No prologues found");
|
||||
|
||||
dataBuffer[dataPtr++] = value;
|
||||
value = 0;
|
||||
|
||||
if (currentState == State.OTHER)
|
||||
checkState ();
|
||||
else if (dataPtr == expectedDataSize) // DATA or ADDRESS is now complete
|
||||
{
|
||||
if (debug)
|
||||
System.out.printf ("%s full%n", currentState);
|
||||
setState (State.OTHER);
|
||||
}
|
||||
}
|
||||
|
||||
if (++totalBits == bitCount) // only use this many bits
|
||||
{
|
||||
if (debug)
|
||||
System.out.println ("bitcount reached");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check for unfinished data block, we may need to restart from the beginning
|
||||
// if (totalBits == bitCount && currentState == State.DATA && !restarted)
|
||||
if (totalBits == bitCount && !restarted)
|
||||
{
|
||||
inPtr = offset;
|
||||
restarted = true;
|
||||
if (debug)
|
||||
System.out.println ("wrapping around");
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
System.out.println ("***************************");
|
||||
System.out.printf ("* total bits : %,6d *%n", bitCount);
|
||||
System.out.printf ("* bits used : %,6d *%n", totalBits);
|
||||
System.out.printf ("* total bytes : %,6d *%n", bytesUsed);
|
||||
System.out.printf ("* bytes used : %,6d *%n", totalBytes);
|
||||
System.out.println ("***************************");
|
||||
}
|
||||
|
||||
return diskSectors;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// getNibbleTrack
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public NibbleTrack getNibbleTrack (byte[] buffer, int offset, int length, int bitsUsed)
|
||||
{
|
||||
int rawPtr = 0;
|
||||
|
||||
byte value = 0; // value to be stored
|
||||
final int max = offset + length;
|
||||
int totalBits = 0;
|
||||
int zeroBits = 0;
|
||||
|
||||
while (offset < max)
|
||||
{
|
||||
byte b = buffer[offset++];
|
||||
for (int mask = 0x80; mask != 0; mask >>>= 1)
|
||||
{
|
||||
value <<= 1;
|
||||
if ((b & mask) != 0)
|
||||
{
|
||||
value |= 0x01;
|
||||
zeroBits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++zeroBits;
|
||||
if (zeroBits > 2)
|
||||
System.out.println (zeroBits + " consecutive zeroes");
|
||||
}
|
||||
|
||||
if ((value & 0x80) != 0) // value is not valid until the hi-bit is set
|
||||
{
|
||||
rawBytes[rawPtr++] = value;
|
||||
value = 0;
|
||||
}
|
||||
if (++totalBits == bitsUsed) // only use this many bits
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (value != 0)
|
||||
rawBytes[rawPtr++] = value;
|
||||
|
||||
NibbleTrack track = new NibbleTrack (rawBytes, rawPtr, bitsUsed);
|
||||
return track;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// checkState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void checkState () throws DiskNibbleException
|
||||
{
|
||||
assert currentState == State.OTHER;
|
||||
|
||||
if (dataPtr < 3) // not enough bytes to test
|
||||
return;
|
||||
|
||||
// System.out.printf ("checking %02X %02X %02X%n", dataBuffer[dataPtr - 3],
|
||||
// dataBuffer[dataPtr - 2], dataBuffer[dataPtr - 1]);
|
||||
|
||||
if (match (address16prologue) || match (address16prologueX))
|
||||
{
|
||||
diskReader = diskReader16Sector;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
else if (match (address13prologue))
|
||||
{
|
||||
diskReader = diskReader13Sector;
|
||||
setState (State.ADDRESS);
|
||||
}
|
||||
else if (match (dataPrologue) || match (dataPrologueX))
|
||||
setState (State.DATA);
|
||||
else if (match (epilogue) || match (epilogueX))
|
||||
setState (State.OTHER);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// match
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean match (byte[] pattern)
|
||||
{
|
||||
for (int i = 0, j = dataPtr - 3; i < 3; i++, j++)
|
||||
if (pattern[i] != dataBuffer[j])
|
||||
return false;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
for (int i = 0; i < master.length; i++)
|
||||
if (debugMatch (master[i]))
|
||||
System.out.printf ("Matched: %02X %02X %02X %s%n", pattern[0], pattern[1],
|
||||
pattern[2], masterNames[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// debugMatch
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean debugMatch (byte[] pattern)
|
||||
{
|
||||
for (int i = 0, j = dataPtr - 3; i < 3; i++, j++)
|
||||
if (pattern[i] != dataBuffer[j])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// setState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void setState (State newState) throws DiskNibbleException
|
||||
{
|
||||
if (currentState == State.OTHER && newState == State.OTHER)
|
||||
return;
|
||||
|
||||
assert currentState != newState : currentState + " -> " + newState;
|
||||
|
||||
switch (currentState) // this state is now finished
|
||||
{
|
||||
case ADDRESS:
|
||||
if (currentDiskSector != null)
|
||||
throw new DiskNibbleException ("unused ADDRESS: " + currentDiskSector);
|
||||
|
||||
currentDiskSector = new RawDiskSector (new DiskAddressField (dataBuffer));
|
||||
if (dump)
|
||||
System.out.println ("\n" + currentDiskSector);
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
if (currentDiskSector == null)
|
||||
throw new DiskNibbleException ("cannot store DATA without ADDRESS");
|
||||
|
||||
currentDiskSector.setBuffer (diskReader.decodeSector (dataBuffer));
|
||||
diskSectors.add (currentDiskSector);
|
||||
currentDiskSector = null;
|
||||
if (diskSectors.size () == diskReader.sectorsPerTrack)
|
||||
finished = true;
|
||||
|
||||
break;
|
||||
|
||||
case OTHER: // triggered by an epilogue or full address/data buffer
|
||||
break;
|
||||
}
|
||||
|
||||
switch (newState) // this state is now starting
|
||||
{
|
||||
case ADDRESS:
|
||||
if (currentDiskSector != null)
|
||||
{
|
||||
System.out.println ("\nskipped: " + currentDiskSector);
|
||||
currentDiskSector = null;
|
||||
}
|
||||
// throw new DiskNibbleException (
|
||||
// "cannot start ADDRESS: " + currentDiskSector + " has no data");
|
||||
expectedDataSize = 8;
|
||||
if (dump)
|
||||
System.out.print ("\nADDRESS ");
|
||||
break;
|
||||
|
||||
case DATA:
|
||||
if (currentDiskSector == null)
|
||||
// throw new DiskNibbleException ("cannot start DATA without ADDRESS");
|
||||
return;
|
||||
expectedDataSize = diskReader.expectedDataSize ();
|
||||
if (dump)
|
||||
System.out.println ("\nDATA");
|
||||
break;
|
||||
|
||||
case OTHER:
|
||||
expectedDataSize = MAX_DATA; // what is the maximum filler?
|
||||
if (dump)
|
||||
System.out.println ("\nOTHER");
|
||||
break;
|
||||
}
|
||||
|
||||
currentState = newState;
|
||||
dataPtr = 0; // start collecting new buffer
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// storeSectors
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
void storeSectors (List<RawDiskSector> diskSectors, byte[] diskBuffer)
|
||||
throws DiskNibbleException
|
||||
{
|
||||
if (diskReader == null)
|
||||
throw new DiskNibbleException ("No DiskReader");
|
||||
|
||||
for (RawDiskSector diskSector : diskSectors)
|
||||
diskReader.storeBuffer (diskSector, diskBuffer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// is13Sector
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
boolean is13Sector ()
|
||||
{
|
||||
return diskSectors.size () == 13 && diskReader.sectorsPerTrack == 13;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// is16Sector
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
boolean is16Sector ()
|
||||
{
|
||||
return diskSectors.size () == 16 && diskReader.sectorsPerTrack == 16;
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
public class NibbleTrack
|
||||
{
|
||||
byte[] buffer;
|
||||
int bitsUsed;
|
||||
|
||||
public NibbleTrack (byte[] buffer, int length, int bitsUsed)
|
||||
{
|
||||
assert false : "Not used";
|
||||
this.bitsUsed = bitsUsed;
|
||||
this.buffer = new byte[length];
|
||||
System.arraycopy (buffer, 0, this.buffer, 0, length);
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
|
||||
public class RawDiskSector
|
||||
{
|
||||
final DiskAddressField addressField;
|
||||
byte[] buffer;
|
||||
|
||||
RawDiskSector (DiskAddressField addressField)
|
||||
{
|
||||
assert false : "Not used";
|
||||
this.addressField = addressField;
|
||||
}
|
||||
|
||||
void setBuffer (byte[] buffer)
|
||||
{
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
void dump ()
|
||||
{
|
||||
System.out.println (HexFormatter.format (buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return addressField.toString ();
|
||||
}
|
||||
}
|
@ -1,360 +0,0 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
import com.bytezone.diskbrowser.utilities.Utility;
|
||||
|
||||
public class WozFileOld
|
||||
{
|
||||
private static final byte[] WOZ1_FILE_HEADER =
|
||||
{ 0x57, 0x4F, 0x5A, 0x31, (byte) 0xFF, 0x0A, 0x0D, 0x0A };
|
||||
private static final byte[] WOZ2_FILE_HEADER =
|
||||
{ 0x57, 0x4F, 0x5A, 0x32, (byte) 0xFF, 0x0A, 0x0D, 0x0A };
|
||||
|
||||
private static final int TRK_SIZE = 0x1A00;
|
||||
private static final int INFO_SIZE = 0x3C;
|
||||
private static final int TMAP_SIZE = 0xA0;
|
||||
private static final int DATA_SIZE = TRK_SIZE - 10;
|
||||
|
||||
private final boolean debug = true;
|
||||
private final boolean dump = true;
|
||||
private int diskType; // 5.25 or 3.5
|
||||
private int wozVersion;
|
||||
private int bootSectorFormat;
|
||||
|
||||
public final File file;
|
||||
byte[] diskBuffer;
|
||||
|
||||
private final MC3470 mc3470 = new MC3470 ();
|
||||
private final List<NibbleTrack> nibbleTracks = new ArrayList<> (40);
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// constructor
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public WozFileOld (File file) throws DiskNibbleException
|
||||
{
|
||||
this.file = file;
|
||||
byte[] buffer = readFile ();
|
||||
boolean valid = false;
|
||||
|
||||
if (matches (WOZ1_FILE_HEADER, buffer))
|
||||
wozVersion = 1;
|
||||
else if (matches (WOZ2_FILE_HEADER, buffer))
|
||||
wozVersion = 2;
|
||||
else
|
||||
{
|
||||
System.out.println (HexFormatter.format (buffer, 0, 20));
|
||||
throw new DiskNibbleException ("Header error");
|
||||
}
|
||||
|
||||
int checksum1 = readInt (buffer, 8, 4);
|
||||
int checksum2 = Utility.crc32 (buffer, 12, buffer.length - 12);
|
||||
if (checksum1 != checksum2)
|
||||
{
|
||||
System.out.printf ("Stored checksum : %08X%n", checksum1);
|
||||
System.out.printf ("Calculated checksum : %08X%n", checksum2);
|
||||
throw new DiskNibbleException ("Checksum error");
|
||||
}
|
||||
|
||||
int ptr = 12;
|
||||
read: while (ptr < buffer.length)
|
||||
{
|
||||
String chunkId = new String (buffer, ptr, 4);
|
||||
ptr += 4;
|
||||
int chunkSize = readInt (buffer, ptr, 4);
|
||||
ptr += 4;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
System.out.printf ("Offset : %06X%n", ptr - 8);
|
||||
System.out.printf ("Chunk ID : %s%n", chunkId);
|
||||
System.out.printf ("Chunk size: %,d%n", chunkSize);
|
||||
}
|
||||
|
||||
if ("INFO".equals (chunkId))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
int diskType = buffer[ptr + 1] & 0xFF;
|
||||
String diskTypeText = diskType == 1 ? "5.25" : diskType == 2 ? "3.5" : "??";
|
||||
|
||||
System.out.println ();
|
||||
System.out.printf ("Version ........... %02X%n", buffer[ptr]);
|
||||
System.out.printf ("Disk type ......... %02X %s%n", diskType, diskTypeText);
|
||||
System.out.printf ("Write protected ... %02X%n", buffer[ptr + 2]);
|
||||
System.out.printf ("Synchronised ...... %02X%n", buffer[ptr + 3]);
|
||||
System.out.printf ("Cleaned ........... %02X%n", buffer[ptr + 4]);
|
||||
System.out.printf ("Creator ........... %s%n",
|
||||
new String (buffer, ptr + 5, 32).trim ());
|
||||
|
||||
if (wozVersion > 1)
|
||||
{
|
||||
int bootFormat = buffer[ptr + 38] & 0xFF;
|
||||
String bootFormatText = bootFormat == 1 ? "16 sector"
|
||||
: bootFormat == 2 ? "13 sector" : bootFormat == 3 ? "Both" : "??";
|
||||
System.out.printf ("Disk sides ........ %02X%n", buffer[ptr + 37]);
|
||||
System.out.printf ("Boot format ....... %02X %s%n", bootFormat,
|
||||
bootFormatText);
|
||||
System.out.printf ("Optimal timing .... %02X%n", buffer[ptr + 39]);
|
||||
System.out.printf ("Compatible flags .. %04X%n",
|
||||
readInt (buffer, ptr + 40, 2));
|
||||
System.out.printf ("Minimum RAM ....... %04X%n",
|
||||
readInt (buffer, ptr + 42, 2));
|
||||
System.out.printf ("Largest track ..... %04X%n",
|
||||
readInt (buffer, ptr + 44, 2));
|
||||
}
|
||||
System.out.println ();
|
||||
}
|
||||
|
||||
diskType = buffer[ptr + 1] & 0xFF;
|
||||
if (wozVersion > 1)
|
||||
bootSectorFormat = buffer[ptr + 38] & 0xFF;
|
||||
|
||||
ptr += INFO_SIZE;
|
||||
}
|
||||
else if ("TMAP".equals (chunkId))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
for (int track = 0; track < 40; track++)
|
||||
{
|
||||
for (int qtr = 0; qtr < 4; qtr++)
|
||||
System.out.printf ("%02X ", buffer[ptr++]);
|
||||
System.out.println ();
|
||||
}
|
||||
System.out.println ();
|
||||
}
|
||||
else
|
||||
ptr += TMAP_SIZE;
|
||||
}
|
||||
else if ("TRKS".equals (chunkId))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
System.out.println ("***********************************************");
|
||||
System.out.printf ("* Disk ......... %s%n", file.getName ());
|
||||
System.out.println ("***********************************************");
|
||||
}
|
||||
|
||||
if (wozVersion == 1)
|
||||
{
|
||||
int tracks = chunkSize / TRK_SIZE;
|
||||
|
||||
for (int trackNo = 0; trackNo < tracks; trackNo++)
|
||||
{
|
||||
int bytesUsed = readInt (buffer, ptr + DATA_SIZE, 2);
|
||||
int bitCount = readInt (buffer, ptr + DATA_SIZE + 2, 2);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
System.out.println ("***************************************");
|
||||
System.out.printf ("* Track ......... %,6d of %,6d *%n", trackNo,
|
||||
tracks);
|
||||
System.out.printf ("* Bytes used .... %,6d *%n", bytesUsed);
|
||||
System.out.printf ("* Bit count .... %,6d *%n", bitCount);
|
||||
System.out.println ("***************************************");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// nibbleTracks.add (mc3470.getNibbleTrack (buffer, ptr, bytesUsed, bitCount));
|
||||
List<RawDiskSector> diskSectors =
|
||||
mc3470.readTrack (buffer, ptr, bytesUsed, bitCount);
|
||||
|
||||
if (trackNo == 0) // create disk buffer
|
||||
{
|
||||
if (mc3470.is13Sector ())
|
||||
diskBuffer = new byte[35 * 13 * 256];
|
||||
else if (mc3470.is16Sector ())
|
||||
diskBuffer = new byte[35 * 16 * 256];
|
||||
else
|
||||
{
|
||||
System.out.println ("unknown disk format");
|
||||
break read;
|
||||
}
|
||||
}
|
||||
|
||||
mc3470.storeSectors (diskSectors, diskBuffer);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println (e);
|
||||
break read;
|
||||
}
|
||||
|
||||
ptr += TRK_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
diskBuffer = new byte[(bootSectorFormat == 2 ? 13 : 16) * 35 * 256];
|
||||
|
||||
for (int trackNo = 0; trackNo < 160; trackNo++)
|
||||
{
|
||||
int p = 256 + trackNo * 8;
|
||||
int startingBlock = readInt (buffer, p, 2);
|
||||
int blockCount = readInt (buffer, p + 2, 2);
|
||||
int bitCount = readInt (buffer, p + 4, 4);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
System.out.println ("******************************");
|
||||
System.out.printf ("* Track ......... %,6d *%n", trackNo);
|
||||
System.out.printf ("* Start block ... %,6d *%n", startingBlock);
|
||||
System.out.printf ("* Block count ... %,6d *%n", blockCount);
|
||||
System.out.printf ("* Bit count .... %,6d *%n", bitCount);
|
||||
System.out.println ("******************************");
|
||||
}
|
||||
|
||||
if (startingBlock == 0)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
// nibbleTracks.add (mc3470.getNibbleTrack (buffer, ptr, bytesUsed, bitCount));
|
||||
List<RawDiskSector> diskSectors = mc3470.readTrack (buffer,
|
||||
startingBlock * 512, blockCount * 512, bitCount);
|
||||
|
||||
for (RawDiskSector rawDiskSector : diskSectors)
|
||||
{
|
||||
System.out.println (rawDiskSector);
|
||||
rawDiskSector.dump ();
|
||||
}
|
||||
|
||||
mc3470.storeSectors (diskSectors, diskBuffer);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println (e);
|
||||
break read;
|
||||
}
|
||||
}
|
||||
ptr += chunkSize;
|
||||
}
|
||||
}
|
||||
else if ("META".equals (chunkId))
|
||||
{
|
||||
// System.out.printf ("[%s] %08X%n", chunkId, chunkSize);
|
||||
// System.out.println (HexFormatter.format (buffer, ptr, chunkSize));
|
||||
ptr += chunkSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.printf ("Unknown %08X%n", chunkSize);
|
||||
ptr += chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
// if (!valid)
|
||||
// readNibbleTracks (buffer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// readNibbleTracks
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void readNibbleTracks (byte[] buffer)
|
||||
{
|
||||
for (int track = 0; track < 35; track++)
|
||||
{
|
||||
int ptr = track * 6656 + 256;
|
||||
|
||||
int bytesUsed = readInt (buffer, ptr + DATA_SIZE, 2);
|
||||
int bitCount = readInt (buffer, ptr + DATA_SIZE + 2, 2);
|
||||
|
||||
NibbleTrack nibbleTrack = mc3470.getNibbleTrack (buffer, ptr, bytesUsed, bitCount);
|
||||
nibbleTracks.add (nibbleTrack);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// getSectorsPerTrack
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public int getSectorsPerTrack ()
|
||||
{
|
||||
return mc3470.is13Sector () ? 13 : mc3470.is16Sector () ? 16 : 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// readInt
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private int readInt (byte[] buffer, int offset, int length)
|
||||
{
|
||||
int shift = 0;
|
||||
int value = 0;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
value |= (buffer[offset + i] & 0xFF) << shift;
|
||||
shift += 8;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// getDiskBuffer
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public byte[] getDiskBuffer ()
|
||||
{
|
||||
return diskBuffer;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// readFile
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private byte[] readFile ()
|
||||
{
|
||||
try
|
||||
{
|
||||
BufferedInputStream in = new BufferedInputStream (new FileInputStream (file));
|
||||
byte[] buffer = in.readAllBytes ();
|
||||
in.close ();
|
||||
return buffer;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void dump (int trackNo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// matches
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private boolean matches (byte[] b1, byte[] b2)
|
||||
{
|
||||
for (int i = 0; i < b1.length; i++)
|
||||
if (b1[i] != b2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
File file = new File ("/Users/denismolony/code/python/wozardry-2.0/bill.woz");
|
||||
try
|
||||
{
|
||||
new WozFileOld (file);
|
||||
}
|
||||
catch (DiskNibbleException e)
|
||||
{
|
||||
e.printStackTrace ();
|
||||
}
|
||||
}
|
||||
}
|
@ -223,11 +223,17 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
{
|
||||
switch (fileType)
|
||||
{
|
||||
case FILE_TYPE_USER_DEFINED_1: // OVL
|
||||
if (endOfFile == 0x2000 && auxType == 0)
|
||||
{
|
||||
file = new OriginalHiResImage (name, exactBuffer, auxType);
|
||||
break;
|
||||
}
|
||||
// drop through
|
||||
case FILE_TYPE_BINARY:
|
||||
case FILE_TYPE_RELOCATABLE:
|
||||
case FILE_TYPE_SYS:
|
||||
case FILE_TYPE_BAT:
|
||||
case FILE_TYPE_USER_DEFINED_1:
|
||||
if (SimpleText.isHTML (exactBuffer))
|
||||
file = new SimpleText (name, exactBuffer);
|
||||
else if (HiResImage.isGif (exactBuffer) || HiResImage.isPng (exactBuffer))
|
||||
@ -385,6 +391,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
case FILE_TYPE_LDF:
|
||||
case FILE_TYPE_ANI:
|
||||
case FILE_TYPE_PAL:
|
||||
case FILE_TYPE_NON:
|
||||
file = new DefaultAppleFile (name, exactBuffer);
|
||||
break;
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.bytezone.diskbrowser.prodos;
|
||||
|
||||
public interface ProdosConstants
|
||||
{
|
||||
int FILE_TYPE_NON = 0x00;
|
||||
int FILE_TYPE_PCD = 0x02;
|
||||
int FILE_TYPE_TEXT = 0x04;
|
||||
int FILE_TYPE_PDA = 0x05;
|
||||
@ -31,7 +32,7 @@ public interface ProdosConstants
|
||||
int FILE_TYPE_ICN = 0xCA;
|
||||
int FILE_TYPE_APPLETALK = 0xE2;
|
||||
int FILE_TYPE_PASCAL_VOLUME = 0xEF;
|
||||
int FILE_TYPE_USER_DEFINED_1 = 0xF1;
|
||||
int FILE_TYPE_USER_DEFINED_1 = 0xF1; // OVL
|
||||
int FILE_TYPE_BAT = 0xF5;
|
||||
int FILE_TYPE_INTEGER_BASIC = 0xFA;
|
||||
int FILE_TYPE_INTEGER_BASIC_VARS = 0xFB;
|
||||
|
Loading…
Reference in New Issue
Block a user