This commit is contained in:
Denis Molony 2018-08-12 17:16:03 +10:00
parent dc319ebb97
commit 6eb4acc85d
8 changed files with 127 additions and 78 deletions

View File

@ -57,11 +57,10 @@ public class ByteTranslator5and3 extends ByteTranslator
{
int val = (b & 0xFF) - 0xAB; // 0 - 84
if (val < 0 || val > 84)
throw new DiskNibbleException ("Val: " + val);
throw new DiskNibbleException ("5&3 val: " + val);
byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits)
if (trans < 0 || trans > 31)
throw new DiskNibbleException ("Trans: " + trans);
throw new DiskNibbleException ("5&3 trans: " + trans);
return trans;
}
}

View File

@ -47,10 +47,10 @@ public class ByteTranslator6and2 extends ByteTranslator
{
int val = (b & 0xFF) - 0x96; // 0 - 105
if (val < 0 || val > 105)
throw new DiskNibbleException ("Val: " + val);
throw new DiskNibbleException ("6&2 val: " + val);
byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits)
if (trans < 0 || trans > 63)
throw new DiskNibbleException ("Trans: " + trans);
throw new DiskNibbleException ("6&2 trans: " + trans);
return trans;
}
}

View File

@ -8,21 +8,21 @@ class DiskAddressField
// constructor
// ---------------------------------------------------------------------------------//
DiskAddressField (byte[] buffer, int offset)
DiskAddressField (byte[] buffer)
{
volume = decode4and4 (buffer, offset);
track = decode4and4 (buffer, offset + 2);
sector = decode4and4 (buffer, offset + 4);
checksum = decode4and4 (buffer, offset + 6);
volume = decode4and4 (buffer, 0);
track = decode4and4 (buffer, 2);
sector = decode4and4 (buffer, 4);
checksum = decode4and4 (buffer, 6);
}
// ---------------------------------------------------------------------------------//
// decode4and4
// ---------------------------------------------------------------------------------//
int decode4and4 (byte[] buffer, int offset)
private int decode4and4 (byte[] buffer, int offset)
{
int odds = ((buffer[offset] & 0xFF) << 1) + 1;
int odds = ((buffer[offset] & 0xFF) << 1) | 0x01;
int evens = buffer[offset + 1] & 0xFF;
return odds & evens;
}

View File

@ -23,7 +23,7 @@ public abstract class DiskReader
// abstract functions
// ---------------------------------------------------------------------------------//
abstract byte[] decodeSector (byte[] buffer, int ptr);
abstract byte[] decodeSector (byte[] buffer);
abstract byte[] encodeSector (byte[] buffer);

View File

@ -10,7 +10,7 @@ public class DiskReader13Sector extends DiskReader
private final byte[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final byte[] decodeB = new byte[RAW_BUFFER_SIZE];
private final ByteTranslator byteTranslator53 = new ByteTranslator5and3 ();
private final ByteTranslator byteTranslator = new ByteTranslator5and3 ();
// ---------------------------------------------------------------------------------//
// constructor
@ -26,15 +26,16 @@ public class DiskReader13Sector extends DiskReader
// ---------------------------------------------------------------------------------//
@Override
byte[] decodeSector (byte[] buffer, int offset)
byte[] decodeSector (byte[] buffer)
{
byte[] decodedBuffer = new byte[BLOCK_SIZE];
int offset = 0;
try
{
// convert legal disk values to actual 5 bit values
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 411 bytes
decodeA[i] = (byte) (byteTranslator53.decode (buffer[offset++]) << 3);
decodeA[i] = (byte) (byteTranslator.decode (buffer[offset++]) << 3);
// reconstruct 410 bytes each with 5 bits
byte chk = 0;
@ -75,11 +76,11 @@ public class DiskReader13Sector extends DiskReader
}
// add last byte
decodedBuffer[ptr] =
(byte) (decodeB[255] | ((decodeB[409] & 0x3F) >>> 3));
decodedBuffer[ptr] = (byte) (decodeB[255] | ((decodeB[409] & 0x3F) >>> 3));
}
catch (Exception e)
{
// e.printStackTrace ();
System.out.println (e);
}

View File

@ -13,7 +13,7 @@ public class DiskReader16Sector extends DiskReader
private final byte[] encodeA = new byte[RAW_BUFFER_SIZE];
private final byte[] encodeB = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final ByteTranslator byteTranslator62 = new ByteTranslator6and2 ();
private final ByteTranslator byteTranslator = new ByteTranslator6and2 ();
private static int[] interleave =
{ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
@ -32,29 +32,21 @@ public class DiskReader16Sector extends DiskReader
// ---------------------------------------------------------------------------------//
@Override
byte[] decodeSector (byte[] buffer, int offset)
byte[] decodeSector (byte[] buffer)
{
// rearrange 342 bytes into 256
byte[] decodedBuffer = new byte[BLOCK_SIZE]; // 256 bytes
byte[] decodedBuffer = new byte[BLOCK_SIZE]; // 256 bytes
int offset = 0;
try
{
if (offset + BUFFER_WITH_CHECKSUM_SIZE >= buffer.length)
throw new DiskNibbleException (
String.format ("Buffer not long enough (need %d, found %d)",
BUFFER_WITH_CHECKSUM_SIZE, buffer.length - offset));
// convert legal disk values to actual 6 bit values
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 343 bytes
{
if (offset == buffer.length)
offset = 0;
decodeA[i] = (byte) (byteTranslator62.decode (buffer[offset++]) << 2);
}
decodeA[i] = (byte) (byteTranslator.decode (buffer[offset++]) << 2);
// reconstruct 342 bytes each with 6 bits
byte chk = 0;
for (int i = decodeB.length - 1; i >= 0; i--) // 342 bytes
for (int i = decodeB.length - 1; i >= 0; i--) // 342 bytes
chk = decodeB[i] = (byte) (decodeA[i + 1] ^ chk);
if ((chk ^ decodeA[0]) != 0)
throw new DiskNibbleException ("Checksum failed");
@ -78,6 +70,7 @@ public class DiskReader16Sector extends DiskReader
catch (Exception e)
{
System.out.println (e);
// e.printStackTrace ();
}
return decodedBuffer;
@ -124,7 +117,7 @@ public class DiskReader16Sector extends DiskReader
// remove two bits and convert to translated bytes
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++)
encodedBuffer[i] = byteTranslator62.encode (encodeB[i]);
encodedBuffer[i] = byteTranslator.encode (encodeB[i]);
return encodedBuffer;
}

View File

@ -3,21 +3,27 @@ package com.bytezone.diskbrowser.disk;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.utilities.HexFormatter;
class MC3470
{
private static final int EMPTY = 999;
private final boolean debug = false;
private final boolean dump = false;
private final List<DiskSector> diskSectors = new ArrayList<> ();
private State currentState;
private DiskSector currentDiskSector;
private int expectedDataSize;
private boolean finished;
private boolean restarted;
private DiskReader diskReader;
private final DiskReader diskReader16 = new DiskReader16Sector ();
private final DiskReader diskReader13 = new DiskReader13Sector ();
private final byte[] dataBuffer = new byte[500];
private final byte[] dataBuffer = new byte[EMPTY];
private int dataPtr = 0;
private enum State
@ -38,17 +44,22 @@ class MC3470
diskSectors.clear ();
currentDiskSector = null;
currentState = State.OTHER;
expectedDataSize = 200;
expectedDataSize = EMPTY;
finished = false;
restarted = false;
int value = 0;
dataPtr = 0;
if (debug)
{
System.out.printf ("%nOffset : %06X%n", offset);
System.out.printf ("Bytes used: %06X%n", bytesUsed);
System.out.printf ("Bit count : %06X%n", bitCount);
System.out.printf ("remaining : %06X%n", bitCount % 8);
}
int inPtr = offset;
while (inPtr < max)
int inPtr = offset; // keep offset in case we have to loop around
while (!finished && inPtr < max)
{
int b = buffer[inPtr++] & 0xFF;
for (int mask = 0x80; mask != 0; mask >>>= 1)
@ -57,29 +68,36 @@ class MC3470
if ((b & mask) != 0)
value |= 1;
++totalBits;
if ((value & 0x80) != 0) // is hi-bit set?
{
if (dump)
{
if (dataPtr % 16 == 0)
System.out.printf ("%n%04X: ", dataPtr);
System.out.printf ("%02X ", value);
}
dataBuffer[dataPtr++] = (byte) value;
checkState (value);
value = 0;
}
if (++totalBits == bitCount)
break;
}
if (inPtr == max && currentState == State.DATA)
if (inPtr == max && currentState == State.DATA && !restarted)
{
System.out.println ("Unfinished business");
inPtr = offset;
restarted = true;
}
}
// if (bytesUsed > outputBuffer.length)
// {
// System.out.printf ("Bytes used %,5d%n", bytesUsed);
// System.out.printf ("Buffer size %,5d%n", outPtr);
// }
if (value != 0)
System.out.printf ("********** Value not used: %01X%n", value);
if (debug)
{
System.out.printf ("total bits : %d%n", bitCount);
System.out.printf ("bits used : %d%n", totalBits);
}
}
// ---------------------------------------------------------------------------------//
@ -148,7 +166,7 @@ class MC3470
if (dataPtr == expectedDataSize)
{
if (currentState == State.OTHER)
throw new DiskNibbleException ("No address or data prologues found");
throw new DiskNibbleException ("No address or data blocks found");
setState (State.OTHER);
}
}
@ -161,40 +179,67 @@ class MC3470
{
if (currentState == newState && currentState == State.OTHER)
return;
assert currentState != newState;
assert currentState != newState : currentState + " -> " + newState;
switch (currentState) // this state is now finished
{
case ADDRESS:
currentDiskSector = new DiskSector (new DiskAddressField (dataBuffer, 0));
currentDiskSector = new DiskSector (new DiskAddressField (dataBuffer));
if (dump)
System.out.println (currentDiskSector);
break;
case DATA:
currentDiskSector.setBuffer (diskReader.decodeSector (dataBuffer, 0));
diskSectors.add (currentDiskSector);
if (currentDiskSector != null)
{
currentDiskSector.setBuffer (diskReader.decodeSector (dataBuffer));
diskSectors.add (currentDiskSector);
currentDiskSector = null;
if (diskSectors.size () == diskReader.sectorsPerTrack)
finished = true;
}
else
{
if (debug)
{
System.out.printf ("cannot store %d DATA no ADDRESS", dataPtr);
System.out.println (HexFormatter.format (dataBuffer, 0, dataPtr));
}
}
break;
case OTHER:
break;
}
switch (newState) // this state is now starting
{
case ADDRESS:
if (dump)
System.out.print ("ADDRESS ");
expectedDataSize = 8;
break;
case DATA:
if (dump)
System.out.println ("DATA");
if (debug && currentDiskSector == null)
{
System.out.println ("starting DATA with no ADDRESS");
System.out.println (HexFormatter.format (dataBuffer, 0, dataPtr));
}
expectedDataSize = diskReader.expectedDataSize ();
break;
case OTHER:
if (dump)
System.out.println ("OTHER");
expectedDataSize = EMPTY; // what is the maximum filler?
break;
}
currentState = newState;
dataPtr = 0; // start collecting new buffer
switch (currentState) // this state is now starting
{
case ADDRESS:
expectedDataSize = 8;
break;
case DATA:
expectedDataSize = diskReader.expectedDataSize ();
break;
case OTHER:
expectedDataSize = 200; // what is the maximum filler?
break;
}
}
// ---------------------------------------------------------------------------------//
@ -203,7 +248,9 @@ class MC3470
private boolean isPrologue ()
{
return dataPtr >= 3 && dataBuffer[dataPtr - 3] == (byte) 0xD5
return dataPtr >= 3
&& (dataBuffer[dataPtr - 3] == (byte) 0xD5
|| dataBuffer[dataPtr - 3] == (byte) 0xD4) // non-standard
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
}
@ -213,7 +260,9 @@ class MC3470
private boolean isEpilogue ()
{
return dataPtr >= 3 && dataBuffer[dataPtr - 3] == (byte) 0xDE
return dataPtr >= 3
&& (dataBuffer[dataPtr - 3] == (byte) 0xDE
|| dataBuffer[dataPtr - 3] == (byte) 0xDA) // non-standard
&& dataBuffer[dataPtr - 2] == (byte) 0xAA;
}

View File

@ -5,7 +5,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
class WozDisk
@ -87,7 +86,11 @@ class WozDisk
else if ("TRKS".equals (chunkId))
{
if (debug)
System.out.println ("Reading TRKS");
{
System.out.println ("***************************************");
System.out.printf ("* Disk ......... %s%n", file.getName ());
System.out.println ("***************************************");
}
int tracks = chunkSize / TRK_SIZE;
for (int trackNo = 0; trackNo < tracks; trackNo++)
@ -97,8 +100,11 @@ class WozDisk
if (debug)
{
System.out.printf ("Bytes used .... %,6d%n", bytesUsed);
System.out.printf ("Bit count .... %,6d%n", bitCount);
System.out.println ("******************************");
System.out.printf ("* Track ......... %,6d *%n", trackNo);
System.out.printf ("* Bytes used .... %,6d *%n", bytesUsed);
System.out.printf ("* Bit count .... %,6d *%n", bitCount);
System.out.println ("******************************");
}
try
@ -115,6 +121,7 @@ class WozDisk
{
System.out.println ("unknown disk format");
break read;
// continue;
}
}
@ -124,7 +131,7 @@ class WozDisk
{
// e.printStackTrace ();
System.out.println (e);
break read;
// break read;
}
ptr += TRK_SIZE;
@ -132,8 +139,8 @@ class WozDisk
}
else if ("META".equals (chunkId))
{
System.out.printf ("[%s] %08X%n", chunkId, chunkSize);
System.out.println (HexFormatter.format (buffer, ptr, chunkSize));
// System.out.printf ("[%s] %08X%n", chunkId, chunkSize);
// System.out.println (HexFormatter.format (buffer, ptr, chunkSize));
ptr += chunkSize;
}
else