This commit is contained in:
Denis Molony 2018-08-11 14:12:21 +10:00
parent 82600b8d0b
commit dc319ebb97
9 changed files with 132 additions and 105 deletions

View File

@ -44,6 +44,7 @@ public class ByteTranslator5and3 extends ByteTranslator
@Override
byte encode (byte b)
{
System.out.println ("encode() not written");
return 0;
}
@ -55,14 +56,12 @@ public class ByteTranslator5and3 extends ByteTranslator
byte decode (byte b) throws DiskNibbleException
{
int val = (b & 0xFF) - 0xAB; // 0 - 84
// assert val >= 0 && val <= 84 : "Val: " + val;
if (val < 0 || val > 84)
throw new DiskNibbleException ("Val: " + val);
byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits)
// assert trans >= 0 && trans <= 31 : "Trans: " + trans;
if (trans < 0 || trans > 31)
throw new DiskNibbleException ("Trans: " + trans);
return (byte) (trans << 3); // left justify 5 bits
return trans;
}
}

View File

@ -28,23 +28,29 @@ public class ByteTranslator6and2 extends ByteTranslator
}
}
// ---------------------------------------------------------------------------------//
// encode
// ---------------------------------------------------------------------------------//
@Override
byte encode (byte b)
{
return writeTranslateTable6and2[(b & 0xFC) / 4];
return writeTranslateTable6and2[(b & 0xFC)];
}
// ---------------------------------------------------------------------------------//
// decode
// ---------------------------------------------------------------------------------//
@Override
byte decode (byte b) throws DiskNibbleException
{
int val = (b & 0xFF) - 0x96; // 0 - 105
// assert val >= 0 && val <= 105 : "Val: " + val;
if (val < 0 || val > 105)
throw new DiskNibbleException ("Val: " + val);
byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits)
// assert trans >= 0 && trans <= 63 : "Trans: " + trans;
if (trans < 0 || trans > 63)
throw new DiskNibbleException ("Trans: " + trans);
return (byte) (trans << 2); // left justify 6 bits
return trans;
}
}

View File

@ -238,12 +238,15 @@ public class DiskFactory
disk = checkDos (appleDisk);
return disk == null ? new DataDisk (appleDisk) : disk;
}
AppleDisk appleDisk256 = new AppleDisk (wozDisk, 35, 16);
disk = checkDos (appleDisk256);
if (disk == null)
disk = checkProdos (new AppleDisk (wozDisk, 35, 8));
if (disk == null)
disk = new DataDisk (appleDisk256);
if (wozDisk.getSectorsPerTrack () == 16)
{
AppleDisk appleDisk256 = new AppleDisk (wozDisk, 35, 16);
disk = checkDos (appleDisk256);
if (disk == null)
disk = checkProdos (new AppleDisk (wozDisk, 35, 8));
if (disk == null)
disk = new DataDisk (appleDisk256);
}
return disk;
}
catch (Exception e)

View File

@ -7,7 +7,7 @@ public abstract class DiskReader
static final int BLOCK_SIZE = 256;
static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
int sectorsPerTrack;
final int sectorsPerTrack;
boolean debug = false;
// ---------------------------------------------------------------------------------//

View File

@ -4,11 +4,11 @@ import com.bytezone.diskbrowser.disk.MC3470.DiskSector;
public class DiskReader13Sector extends DiskReader
{
private static final int RAW_BUFFER_SIZE_DOS_32 = 410;
private static final int BUFFER_WITH_CHECKSUM_SIZE_DOS_32 = RAW_BUFFER_SIZE_DOS_32 + 1;
private static final int RAW_BUFFER_SIZE = 410;
private static final int BUFFER_WITH_CHECKSUM_SIZE = RAW_BUFFER_SIZE + 1;
private final byte[] decodeDos32a = new byte[BUFFER_WITH_CHECKSUM_SIZE_DOS_32];
private final byte[] decodeDos32b = new byte[RAW_BUFFER_SIZE_DOS_32];
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 ();
@ -33,17 +33,17 @@ public class DiskReader13Sector extends DiskReader
try
{
// convert legal disk values to actual 5 bit values
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_32; i++) // 411 bytes
decodeDos32a[i] = byteTranslator53.decode (buffer[offset++]);
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 411 bytes
decodeA[i] = (byte) (byteTranslator53.decode (buffer[offset++]) << 3);
// reconstruct 410 bytes each with 5 bits
byte chk = 0;
int ptr = 0;
for (int i = 409; i >= 256; i--) // 154 bytes
chk = decodeDos32b[i] = (byte) (decodeDos32a[ptr++] ^ chk);
chk = decodeB[i] = (byte) (decodeA[ptr++] ^ chk);
for (int i = 0; i < 256; i++) // 256 bytes
chk = decodeDos32b[i] = (byte) (decodeDos32a[ptr++] ^ chk);
if ((chk ^ decodeDos32a[ptr]) != 0)
chk = decodeB[i] = (byte) (decodeA[ptr++] ^ chk);
if ((chk ^ decodeA[ptr]) != 0)
throw new DiskNibbleException ("Checksum failed");
// rearrange 410 bytes into 256
@ -56,7 +56,7 @@ public class DiskReader13Sector extends DiskReader
for (int i = 50; i >= 0; i--)
{
for (int j = 0; j < 8; j++)
k[j] = decodeDos32b[i + lines[j]];
k[j] = decodeB[i + lines[j]];
k[0] |= (k[5] & 0xE0) >>> 5;
k[1] |= (k[6] & 0xE0) >>> 5;
@ -76,7 +76,7 @@ public class DiskReader13Sector extends DiskReader
// add last byte
decodedBuffer[ptr] =
(byte) (decodeDos32b[255] | ((decodeDos32b[409] & 0x3F) >>> 3));
(byte) (decodeB[255] | ((decodeB[409] & 0x3F) >>> 3));
}
catch (Exception e)
{
@ -117,6 +117,6 @@ public class DiskReader13Sector extends DiskReader
@Override
int expectedDataSize ()
{
return 411;
return BUFFER_WITH_CHECKSUM_SIZE;
}
}

View File

@ -4,14 +4,14 @@ import com.bytezone.diskbrowser.disk.MC3470.DiskSector;
public class DiskReader16Sector extends DiskReader
{
private static final int RAW_BUFFER_SIZE_DOS_33 = 342;
private static final int BUFFER_WITH_CHECKSUM_SIZE_DOS_33 = RAW_BUFFER_SIZE_DOS_33 + 1;
private static final int RAW_BUFFER_SIZE = 342;
private static final int BUFFER_WITH_CHECKSUM_SIZE = RAW_BUFFER_SIZE + 1;
private final byte[] decodeDos33a = new byte[BUFFER_WITH_CHECKSUM_SIZE_DOS_33];
private final byte[] decodeDos33b = new byte[RAW_BUFFER_SIZE_DOS_33];
private final byte[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final byte[] decodeB = new byte[RAW_BUFFER_SIZE];
private final byte[] encodeDos33a = new byte[RAW_BUFFER_SIZE_DOS_33];
private final byte[] encodeDos33b = new byte[BUFFER_WITH_CHECKSUM_SIZE_DOS_33];
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 ();
@ -39,34 +39,34 @@ public class DiskReader16Sector extends DiskReader
try
{
if (offset + BUFFER_WITH_CHECKSUM_SIZE_DOS_33 >= buffer.length)
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_DOS_33, buffer.length - offset));
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_DOS_33; i++) // 343 bytes
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 343 bytes
{
if (offset == buffer.length)
offset = 0;
decodeDos33a[i] = byteTranslator62.decode (buffer[offset++]);
decodeA[i] = (byte) (byteTranslator62.decode (buffer[offset++]) << 2);
}
// reconstruct 342 bytes each with 6 bits
byte chk = 0;
for (int i = decodeDos33b.length - 1; i >= 0; i--) // 342 bytes
chk = decodeDos33b[i] = (byte) (decodeDos33a[i + 1] ^ chk);
if ((chk ^ decodeDos33a[0]) != 0)
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");
// move 6 bits into place
for (int i = 0; i < BLOCK_SIZE; i++)
decodedBuffer[i] = decodeDos33b[i + 86];
decodedBuffer[i] = decodeB[i + 86];
// reattach each byte's last 2 bits
for (int i = 0, j = 86, k = 172; i < 86; i++, j++, k++)
{
byte val = decodeDos33b[i];
byte val = decodeB[i];
decodedBuffer[i] |= reverse ((val & 0x0C) >> 2);
decodedBuffer[j] |= reverse ((val & 0x30) >> 4);
@ -91,11 +91,11 @@ public class DiskReader16Sector extends DiskReader
@Override
byte[] encodeSector (byte[] buffer)
{
byte[] encodedBuffer = new byte[BUFFER_WITH_CHECKSUM_SIZE_DOS_33];
byte[] encodedBuffer = new byte[BUFFER_WITH_CHECKSUM_SIZE];
// move data buffer down to make room for the 86 extra bytes
for (int i = 0; i < BLOCK_SIZE; i++)
encodeDos33a[i + 86] = buffer[i];
encodeA[i + 86] = buffer[i];
// build extra 86 bytes from the bits stripped from the data bytes
for (int i = 0; i < 86; i++)
@ -106,24 +106,25 @@ public class DiskReader16Sector extends DiskReader
if (i < 84)
{
int b3 = reverse (buffer[i + 172] & 0x03) << 6;
encodeDos33a[i] = (byte) (b1 | b2 | b3);
encodeA[i] = (byte) (b1 | b2 | b3);
}
else
encodeDos33a[i] = (byte) (b1 | b2);
encodeA[i] = (byte) (b1 | b2);
}
// convert into checksum bytes
byte checksum = 0;
for (int i = 0; i < RAW_BUFFER_SIZE_DOS_33; i++)
for (int i = 0; i < RAW_BUFFER_SIZE; i++)
{
encodeDos33b[i] = (byte) (checksum ^ encodeDos33a[i]);
checksum = encodeDos33a[i];
encodeB[i] = (byte) (checksum ^ encodeA[i]);
checksum = encodeA[i];
}
encodeDos33b[RAW_BUFFER_SIZE_DOS_33] = checksum; // add checksum to the end
encodeB[RAW_BUFFER_SIZE] = checksum; // add checksum to the end
// remove two bits and convert to translated bytes
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_33; i++)
encodedBuffer[i] = byteTranslator62.encode (encodeDos33b[i]);
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++)
encodedBuffer[i] = byteTranslator62.encode (encodeB[i]);
return encodedBuffer;
}
@ -158,6 +159,6 @@ public class DiskReader16Sector extends DiskReader
@Override
int expectedDataSize ()
{
return 343;
return BUFFER_WITH_CHECKSUM_SIZE;
}
}

View File

@ -7,20 +7,20 @@ class MC3470
{
private final boolean debug = false;
private final byte[] dataBuffer = new byte[411];
int dataPtr = 0;
private final List<DiskSector> diskSectors = new ArrayList<> ();
DiskReader diskReader;
State currentState;
DiskSector currentDiskSector;
int expectedDataSize;
private State currentState;
private DiskSector currentDiskSector;
private int expectedDataSize;
DiskReader diskReader16 = new DiskReader16Sector ();
DiskReader diskReader13 = new DiskReader13Sector ();
private DiskReader diskReader;
private final DiskReader diskReader16 = new DiskReader16Sector ();
private final DiskReader diskReader13 = new DiskReader13Sector ();
enum State
private final byte[] dataBuffer = new byte[500];
private int dataPtr = 0;
private enum State
{
ADDRESS, DATA, OTHER
}
@ -30,15 +30,16 @@ class MC3470
// ---------------------------------------------------------------------------------//
void readTrack (byte[] buffer, int offset, int bytesUsed, int bitCount)
throws DiskNibbleException
{
int value = 0;
final int max = offset + bytesUsed;
int totalBits = 0;
diskSectors.clear ();
currentDiskSector = null;
currentState = State.OTHER;
expectedDataSize = 200;
int value = 0;
if (debug)
{
@ -91,32 +92,65 @@ class MC3470
diskReader.storeBuffer (diskSector, diskBuffer);
}
// ---------------------------------------------------------------------------------//
// is13Sector
// ---------------------------------------------------------------------------------//
boolean is13Sector ()
{
return diskSectors.size () == 13 && diskReader.sectorsPerTrack == 13;
}
// ---------------------------------------------------------------------------------//
// is16Sector
// ---------------------------------------------------------------------------------//
boolean is16Sector ()
{
return diskSectors.size () == 16 && diskReader.sectorsPerTrack == 16;
}
// ---------------------------------------------------------------------------------//
// checkState
// ---------------------------------------------------------------------------------//
private void checkState (int value)
private void checkState (int value) throws DiskNibbleException
{
if (value == 0xB5 && isPrologue ())
switch (value)
{
diskReader = diskReader13;
setState (State.ADDRESS);
case 0xB5:
if (isPrologue ())
{
diskReader = diskReader13;
setState (State.ADDRESS);
}
break;
case 0x96:
if (isPrologue ())
{
diskReader = diskReader16;
setState (State.ADDRESS);
}
break;
case 0xAD:
if (isPrologue ())
setState (State.DATA);
break;
case 0xEB:
if (isEpilogue ())
setState (State.OTHER);
break;
}
if (value == 0x96 && isPrologue ())
{
diskReader = diskReader16;
setState (State.ADDRESS);
}
if (value == 0xAD && isPrologue ())
setState (State.DATA);
if (value == 0xEB && isEpilogue ())
setState (State.OTHER);
if (dataPtr == expectedDataSize)
{
if (currentState == State.OTHER)
throw new DiskNibbleException ("No address or data prologues found");
setState (State.OTHER);
}
}
// ---------------------------------------------------------------------------------//
@ -158,29 +192,11 @@ class MC3470
break;
case OTHER:
expectedDataSize = -1; // unspecified length
expectedDataSize = 200; // what is the maximum filler?
break;
}
}
// ---------------------------------------------------------------------------------//
// is13Sector
// ---------------------------------------------------------------------------------//
boolean is13Sector ()
{
return diskSectors.size () == 13 && diskReader.sectorsPerTrack == 13;
}
// ---------------------------------------------------------------------------------//
// is16Sector
// ---------------------------------------------------------------------------------//
boolean is16Sector ()
{
return diskSectors.size () == 16 && diskReader.sectorsPerTrack == 16;
}
// ---------------------------------------------------------------------------------//
// isPrologue
// ---------------------------------------------------------------------------------//
@ -207,7 +223,7 @@ class MC3470
class DiskSector
{
DiskAddressField addressField;
final DiskAddressField addressField;
byte[] buffer;
DiskSector (DiskAddressField addressField)

View File

@ -152,7 +152,7 @@ class Nibblizer
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_32; i++) // 411 bytes
{
// System.out.printf ("%,5d %02X%n", i, buffer[offset]);
decodeDos32a[i] = byteTranslator53.decode (buffer[offset++]);
decodeDos32a[i] = (byte) (byteTranslator53.decode (buffer[offset++]) << 3);
}
// reconstruct 410 bytes each with 5 bits
@ -215,7 +215,7 @@ class Nibblizer
{
// convert legal disk values to actual 6 bit values
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_33; i++) // 343 bytes
decodeDos33a[i] = byteTranslator62.decode (buffer[offset++]);
decodeDos33a[i] = (byte) (byteTranslator62.decode (buffer[offset++]) << 2);
// reconstruct 342 bytes each with 6 bits
byte chk = 0;

View File

@ -105,7 +105,7 @@ class WozDisk
{
mc3470.readTrack (buffer, ptr, bytesUsed, bitCount);
if (trackNo == 0)
if (trackNo == 0) // create disk buffer
{
if (mc3470.is13Sector ())
diskBuffer = new byte[35 * 13 * 256];
@ -122,7 +122,9 @@ class WozDisk
}
catch (Exception e)
{
e.printStackTrace ();
// e.printStackTrace ();
System.out.println (e);
break read;
}
ptr += TRK_SIZE;
@ -148,7 +150,7 @@ class WozDisk
int getSectorsPerTrack ()
{
return mc3470.is13Sector () ? 13 : 16;
return mc3470.is13Sector () ? 13 : mc3470.is16Sector () ? 16 : 0;
}
// ---------------------------------------------------------------------------------//