dmolony-DiskBrowser/src/com/bytezone/diskbrowser/disk/WozDisk.java

215 lines
6.2 KiB
Java
Raw Normal View History

2018-06-08 12:14:19 +00:00
package com.bytezone.diskbrowser.disk;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
2018-06-10 03:12:32 +00:00
import com.bytezone.diskbrowser.utilities.Utility;
2018-06-08 12:14:19 +00:00
public class WozDisk
{
private static final int TRK_SIZE = 0x1A00;
2018-06-09 01:11:02 +00:00
private static final int INFO_SIZE = 0x3C;
private static final int TMAP_SIZE = 0xA0;
2018-06-08 12:14:19 +00:00
private static final int DATA_SIZE = TRK_SIZE - 10;
private static byte[] header =
{ 0x57, 0x4F, 0x5A, 0x31, (byte) 0xFF, 0x0a, 0x0D, 0x0A };
private static final String SPACES = " ";
private final boolean debug = false;
final File file;
final byte[] diskBuffer = new byte[4096 * 35];
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// constructor
// ---------------------------------------------------------------------------------//
2018-06-08 12:14:19 +00:00
public WozDisk (File f)
{
this.file = f;
2018-06-09 01:11:02 +00:00
Nibblizer nibbler = new Nibblizer (f);
2018-06-10 03:12:32 +00:00
byte[] buffer = null;
2018-06-08 12:14:19 +00:00
try
{
BufferedInputStream in = new BufferedInputStream (new FileInputStream (file));
2018-06-10 03:12:32 +00:00
buffer = in.readAllBytes ();
in.close ();
}
catch (IOException e)
{
e.printStackTrace ();
return;
}
2018-06-08 12:14:19 +00:00
2018-06-10 03:12:32 +00:00
assert matches (header, buffer);
int cs1 = readInt (buffer, 8, 4);
int cs2 = Utility.crc32 (buffer, 12, 256 - 12 + 35 * 6656);
if (cs1 != cs2)
{
System.out.printf ("Checksum: %08X%n", cs1);
System.out.printf ("Calculat: %08X%n", cs2);
}
2018-06-08 12:14:19 +00:00
2018-06-10 03:12:32 +00:00
int ptr = 12;
read: while (ptr < buffer.length)
{
String chunkId = readString (buffer, ptr, 4);
ptr += 4;
int chunkSize = readInt (buffer, ptr, 4);
ptr += 4;
if ("INFO".equals (chunkId))
{
if (debug)
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
System.out.printf ("Version ........... %02X%n", buffer[ptr]);
System.out.printf ("Disk type ......... %02X%n", buffer[ptr + 1]);
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%n",
new String (buffer, ptr + 5, 32));
2018-06-08 12:14:19 +00:00
}
2018-06-10 03:12:32 +00:00
ptr += INFO_SIZE;
}
else if ("TMAP".equals (chunkId))
{
if (debug)
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
for (int track = 0; track < 40; track++)
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
for (int qtr = 0; qtr < 4; qtr++)
System.out.printf ("%02X ", buffer[ptr++]);
2018-06-08 12:14:19 +00:00
System.out.println ();
}
2018-06-10 03:12:32 +00:00
System.out.println ();
2018-06-08 12:14:19 +00:00
}
2018-06-10 03:12:32 +00:00
else
ptr += TMAP_SIZE;
}
else if ("TRKS".equals (chunkId))
{
int tracks = chunkSize / TRK_SIZE;
for (int track = 0; track < tracks; track++)
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
int bytesUsed = readInt (buffer, ptr + DATA_SIZE, 2);
int bitCount = readInt (buffer, ptr + DATA_SIZE + 2, 2);
byte[] trackData = new byte[bytesUsed];
readTrack (buffer, ptr, trackData, bytesUsed);
if (!nibbler.processTrack (track, trackData, diskBuffer))
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
System.out.println ("Nibblizer failure");
break read;
2018-06-08 12:14:19 +00:00
}
2018-06-10 03:12:32 +00:00
ptr += TRK_SIZE;
2018-06-08 12:14:19 +00:00
}
}
2018-06-10 03:12:32 +00:00
else if ("META".equals (chunkId))
{
System.out.printf ("[%s] %08X%n", chunkId, chunkSize);
ptr += chunkSize;
}
else
{
System.out.printf ("Unknown %08X%n", chunkSize);
ptr += chunkSize;
}
2018-06-08 12:14:19 +00:00
}
}
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// skip
// ---------------------------------------------------------------------------------//
2018-06-08 12:14:19 +00:00
private void skip (BufferedInputStream file, int size) throws IOException
{
while ((size -= file.skip (size)) > 0)
;
}
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// readString
// ---------------------------------------------------------------------------------//
2018-06-10 03:12:32 +00:00
private String readString (byte[] buffer, int offset, int length)
2018-06-08 12:14:19 +00:00
{
2018-06-10 03:12:32 +00:00
// byte[] bytes = new byte[size];
// file.read (bytes);
return new String (buffer, offset, length);
2018-06-08 12:14:19 +00:00
}
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// readInt
// ---------------------------------------------------------------------------------//
2018-06-08 12:14:19 +00:00
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;
}
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// readInt
// ---------------------------------------------------------------------------------//
2018-06-10 03:12:32 +00:00
// private int readInt (BufferedInputStream file, int size) throws IOException
// {
// byte[] buffer = new byte[size];
// file.read (buffer);
// return readInt (buffer, 0, size);
// }
2018-06-08 12:14:19 +00:00
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// matches
// ---------------------------------------------------------------------------------//
2018-06-08 12:14:19 +00:00
private boolean matches (byte[] b1, byte[] b2)
{
for (int i = 0; i < b1.length; i++)
if (b1[i] != b2[i])
return false;
return true;
}
2018-06-09 01:11:02 +00:00
// ---------------------------------------------------------------------------------//
// readTrack
// ---------------------------------------------------------------------------------//
2018-06-10 03:12:32 +00:00
private void readTrack (byte[] buffer, int offset, byte[] trackData, int bytesUsed)
2018-06-08 12:14:19 +00:00
{
// int consecutiveZeros = 0;
int value = 0;
int ptr = 0;
2018-06-10 03:12:32 +00:00
for (int i = offset; i < offset + bytesUsed; i++)
2018-06-08 12:14:19 +00:00
{
int b = buffer[i] & 0xFF;
for (int mask = 0x80; mask > 0; mask >>>= 1)
{
int bit = (b & mask) == 0 ? 0 : 1;
value <<= 1;
value |= bit;
if ((value & 0x80) != 0) // is hi-bit set?
{
trackData[ptr++] = (byte) (value & 0xFF);
value = 0;
}
}
}
assert value == 0;
}
}