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 @Override
byte encode (byte b) byte encode (byte b)
{ {
System.out.println ("encode() not written");
return 0; return 0;
} }
@ -55,14 +56,12 @@ public class ByteTranslator5and3 extends ByteTranslator
byte decode (byte b) throws DiskNibbleException byte decode (byte b) throws DiskNibbleException
{ {
int val = (b & 0xFF) - 0xAB; // 0 - 84 int val = (b & 0xFF) - 0xAB; // 0 - 84
// assert val >= 0 && val <= 84 : "Val: " + val;
if (val < 0 || val > 84) if (val < 0 || val > 84)
throw new DiskNibbleException ("Val: " + val); throw new DiskNibbleException ("Val: " + val);
byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits) byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits)
// assert trans >= 0 && trans <= 31 : "Trans: " + trans;
if (trans < 0 || trans > 31) if (trans < 0 || trans > 31)
throw new DiskNibbleException ("Trans: " + trans); 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 @Override
byte encode (byte b) byte encode (byte b)
{ {
return writeTranslateTable6and2[(b & 0xFC) / 4]; return writeTranslateTable6and2[(b & 0xFC)];
} }
// ---------------------------------------------------------------------------------//
// decode
// ---------------------------------------------------------------------------------//
@Override @Override
byte decode (byte b) throws DiskNibbleException byte decode (byte b) throws DiskNibbleException
{ {
int val = (b & 0xFF) - 0x96; // 0 - 105 int val = (b & 0xFF) - 0x96; // 0 - 105
// assert val >= 0 && val <= 105 : "Val: " + val;
if (val < 0 || val > 105) if (val < 0 || val > 105)
throw new DiskNibbleException ("Val: " + val); throw new DiskNibbleException ("Val: " + val);
byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits) byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits)
// assert trans >= 0 && trans <= 63 : "Trans: " + trans;
if (trans < 0 || trans > 63) if (trans < 0 || trans > 63)
throw new DiskNibbleException ("Trans: " + trans); 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); disk = checkDos (appleDisk);
return disk == null ? new DataDisk (appleDisk) : disk; return disk == null ? new DataDisk (appleDisk) : disk;
} }
if (wozDisk.getSectorsPerTrack () == 16)
{
AppleDisk appleDisk256 = new AppleDisk (wozDisk, 35, 16); AppleDisk appleDisk256 = new AppleDisk (wozDisk, 35, 16);
disk = checkDos (appleDisk256); disk = checkDos (appleDisk256);
if (disk == null) if (disk == null)
disk = checkProdos (new AppleDisk (wozDisk, 35, 8)); disk = checkProdos (new AppleDisk (wozDisk, 35, 8));
if (disk == null) if (disk == null)
disk = new DataDisk (appleDisk256); disk = new DataDisk (appleDisk256);
}
return disk; return disk;
} }
catch (Exception e) catch (Exception e)

View File

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

View File

@ -4,11 +4,11 @@ import com.bytezone.diskbrowser.disk.MC3470.DiskSector;
public class DiskReader13Sector extends DiskReader public class DiskReader13Sector extends DiskReader
{ {
private static final int RAW_BUFFER_SIZE_DOS_32 = 410; private static final int RAW_BUFFER_SIZE = 410;
private static final int BUFFER_WITH_CHECKSUM_SIZE_DOS_32 = RAW_BUFFER_SIZE_DOS_32 + 1; 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[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final byte[] decodeDos32b = new byte[RAW_BUFFER_SIZE_DOS_32]; private final byte[] decodeB = new byte[RAW_BUFFER_SIZE];
private final ByteTranslator byteTranslator53 = new ByteTranslator5and3 (); private final ByteTranslator byteTranslator53 = new ByteTranslator5and3 ();
@ -33,17 +33,17 @@ public class DiskReader13Sector extends DiskReader
try try
{ {
// convert legal disk values to actual 5 bit values // convert legal disk values to actual 5 bit values
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_32; i++) // 411 bytes for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 411 bytes
decodeDos32a[i] = byteTranslator53.decode (buffer[offset++]); decodeA[i] = (byte) (byteTranslator53.decode (buffer[offset++]) << 3);
// reconstruct 410 bytes each with 5 bits // reconstruct 410 bytes each with 5 bits
byte chk = 0; byte chk = 0;
int ptr = 0; int ptr = 0;
for (int i = 409; i >= 256; i--) // 154 bytes 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 for (int i = 0; i < 256; i++) // 256 bytes
chk = decodeDos32b[i] = (byte) (decodeDos32a[ptr++] ^ chk); chk = decodeB[i] = (byte) (decodeA[ptr++] ^ chk);
if ((chk ^ decodeDos32a[ptr]) != 0) if ((chk ^ decodeA[ptr]) != 0)
throw new DiskNibbleException ("Checksum failed"); throw new DiskNibbleException ("Checksum failed");
// rearrange 410 bytes into 256 // rearrange 410 bytes into 256
@ -56,7 +56,7 @@ public class DiskReader13Sector extends DiskReader
for (int i = 50; i >= 0; i--) for (int i = 50; i >= 0; i--)
{ {
for (int j = 0; j < 8; j++) 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[0] |= (k[5] & 0xE0) >>> 5;
k[1] |= (k[6] & 0xE0) >>> 5; k[1] |= (k[6] & 0xE0) >>> 5;
@ -76,7 +76,7 @@ public class DiskReader13Sector extends DiskReader
// add last byte // add last byte
decodedBuffer[ptr] = decodedBuffer[ptr] =
(byte) (decodeDos32b[255] | ((decodeDos32b[409] & 0x3F) >>> 3)); (byte) (decodeB[255] | ((decodeB[409] & 0x3F) >>> 3));
} }
catch (Exception e) catch (Exception e)
{ {
@ -117,6 +117,6 @@ public class DiskReader13Sector extends DiskReader
@Override @Override
int expectedDataSize () 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 public class DiskReader16Sector extends DiskReader
{ {
private static final int RAW_BUFFER_SIZE_DOS_33 = 342; private static final int RAW_BUFFER_SIZE = 342;
private static final int BUFFER_WITH_CHECKSUM_SIZE_DOS_33 = RAW_BUFFER_SIZE_DOS_33 + 1; 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[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final byte[] decodeDos33b = new byte[RAW_BUFFER_SIZE_DOS_33]; private final byte[] decodeB = new byte[RAW_BUFFER_SIZE];
private final byte[] encodeDos33a = new byte[RAW_BUFFER_SIZE_DOS_33]; private final byte[] encodeA = new byte[RAW_BUFFER_SIZE];
private final byte[] encodeDos33b = new byte[BUFFER_WITH_CHECKSUM_SIZE_DOS_33]; private final byte[] encodeB = new byte[BUFFER_WITH_CHECKSUM_SIZE];
private final ByteTranslator byteTranslator62 = new ByteTranslator6and2 (); private final ByteTranslator byteTranslator62 = new ByteTranslator6and2 ();
@ -39,34 +39,34 @@ public class DiskReader16Sector extends DiskReader
try try
{ {
if (offset + BUFFER_WITH_CHECKSUM_SIZE_DOS_33 >= buffer.length) if (offset + BUFFER_WITH_CHECKSUM_SIZE >= buffer.length)
throw new DiskNibbleException ( throw new DiskNibbleException (
String.format ("Buffer not long enough (need %d, found %d)", 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 // 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) if (offset == buffer.length)
offset = 0; offset = 0;
decodeDos33a[i] = byteTranslator62.decode (buffer[offset++]); decodeA[i] = (byte) (byteTranslator62.decode (buffer[offset++]) << 2);
} }
// reconstruct 342 bytes each with 6 bits // reconstruct 342 bytes each with 6 bits
byte chk = 0; byte chk = 0;
for (int i = decodeDos33b.length - 1; i >= 0; i--) // 342 bytes for (int i = decodeB.length - 1; i >= 0; i--) // 342 bytes
chk = decodeDos33b[i] = (byte) (decodeDos33a[i + 1] ^ chk); chk = decodeB[i] = (byte) (decodeA[i + 1] ^ chk);
if ((chk ^ decodeDos33a[0]) != 0) if ((chk ^ decodeA[0]) != 0)
throw new DiskNibbleException ("Checksum failed"); throw new DiskNibbleException ("Checksum failed");
// move 6 bits into place // move 6 bits into place
for (int i = 0; i < BLOCK_SIZE; i++) 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 // reattach each byte's last 2 bits
for (int i = 0, j = 86, k = 172; i < 86; i++, j++, k++) 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[i] |= reverse ((val & 0x0C) >> 2);
decodedBuffer[j] |= reverse ((val & 0x30) >> 4); decodedBuffer[j] |= reverse ((val & 0x30) >> 4);
@ -91,11 +91,11 @@ public class DiskReader16Sector extends DiskReader
@Override @Override
byte[] encodeSector (byte[] buffer) 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 // move data buffer down to make room for the 86 extra bytes
for (int i = 0; i < BLOCK_SIZE; i++) 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 // build extra 86 bytes from the bits stripped from the data bytes
for (int i = 0; i < 86; i++) for (int i = 0; i < 86; i++)
@ -106,24 +106,25 @@ public class DiskReader16Sector extends DiskReader
if (i < 84) if (i < 84)
{ {
int b3 = reverse (buffer[i + 172] & 0x03) << 6; int b3 = reverse (buffer[i + 172] & 0x03) << 6;
encodeDos33a[i] = (byte) (b1 | b2 | b3); encodeA[i] = (byte) (b1 | b2 | b3);
} }
else else
encodeDos33a[i] = (byte) (b1 | b2); encodeA[i] = (byte) (b1 | b2);
} }
// convert into checksum bytes // convert into checksum bytes
byte checksum = 0; 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]); encodeB[i] = (byte) (checksum ^ encodeA[i]);
checksum = encodeDos33a[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 // remove two bits and convert to translated bytes
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_33; i++) for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++)
encodedBuffer[i] = byteTranslator62.encode (encodeDos33b[i]); encodedBuffer[i] = byteTranslator62.encode (encodeB[i]);
return encodedBuffer; return encodedBuffer;
} }
@ -158,6 +159,6 @@ public class DiskReader16Sector extends DiskReader
@Override @Override
int expectedDataSize () int expectedDataSize ()
{ {
return 343; return BUFFER_WITH_CHECKSUM_SIZE;
} }
} }

View File

@ -7,20 +7,20 @@ class MC3470
{ {
private final boolean debug = false; private final boolean debug = false;
private final byte[] dataBuffer = new byte[411];
int dataPtr = 0;
private final List<DiskSector> diskSectors = new ArrayList<> (); private final List<DiskSector> diskSectors = new ArrayList<> ();
DiskReader diskReader;
State currentState; private State currentState;
DiskSector currentDiskSector; private DiskSector currentDiskSector;
int expectedDataSize; private int expectedDataSize;
DiskReader diskReader16 = new DiskReader16Sector (); private DiskReader diskReader;
DiskReader diskReader13 = new DiskReader13Sector (); 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 ADDRESS, DATA, OTHER
} }
@ -30,15 +30,16 @@ class MC3470
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
void readTrack (byte[] buffer, int offset, int bytesUsed, int bitCount) void readTrack (byte[] buffer, int offset, int bytesUsed, int bitCount)
throws DiskNibbleException
{ {
int value = 0;
final int max = offset + bytesUsed; final int max = offset + bytesUsed;
int totalBits = 0; int totalBits = 0;
diskSectors.clear (); diskSectors.clear ();
currentDiskSector = null; currentDiskSector = null;
currentState = State.OTHER; currentState = State.OTHER;
expectedDataSize = 200;
int value = 0;
if (debug) if (debug)
{ {
@ -91,33 +92,66 @@ class MC3470
diskReader.storeBuffer (diskSector, diskBuffer); 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 // checkState
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
private void checkState (int value) private void checkState (int value) throws DiskNibbleException
{ {
if (value == 0xB5 && isPrologue ()) switch (value)
{
case 0xB5:
if (isPrologue ())
{ {
diskReader = diskReader13; diskReader = diskReader13;
setState (State.ADDRESS); setState (State.ADDRESS);
} }
break;
if (value == 0x96 && isPrologue ()) case 0x96:
if (isPrologue ())
{ {
diskReader = diskReader16; diskReader = diskReader16;
setState (State.ADDRESS); setState (State.ADDRESS);
} }
break;
if (value == 0xAD && isPrologue ()) case 0xAD:
if (isPrologue ())
setState (State.DATA); setState (State.DATA);
break;
if (value == 0xEB && isEpilogue ()) case 0xEB:
if (isEpilogue ())
setState (State.OTHER); setState (State.OTHER);
break;
}
if (dataPtr == expectedDataSize) if (dataPtr == expectedDataSize)
{
if (currentState == State.OTHER)
throw new DiskNibbleException ("No address or data prologues found");
setState (State.OTHER); setState (State.OTHER);
} }
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
// setState // setState
@ -158,29 +192,11 @@ class MC3470
break; break;
case OTHER: case OTHER:
expectedDataSize = -1; // unspecified length expectedDataSize = 200; // what is the maximum filler?
break; break;
} }
} }
// ---------------------------------------------------------------------------------//
// is13Sector
// ---------------------------------------------------------------------------------//
boolean is13Sector ()
{
return diskSectors.size () == 13 && diskReader.sectorsPerTrack == 13;
}
// ---------------------------------------------------------------------------------//
// is16Sector
// ---------------------------------------------------------------------------------//
boolean is16Sector ()
{
return diskSectors.size () == 16 && diskReader.sectorsPerTrack == 16;
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
// isPrologue // isPrologue
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
@ -207,7 +223,7 @@ class MC3470
class DiskSector class DiskSector
{ {
DiskAddressField addressField; final DiskAddressField addressField;
byte[] buffer; byte[] buffer;
DiskSector (DiskAddressField addressField) 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 for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE_DOS_32; i++) // 411 bytes
{ {
// System.out.printf ("%,5d %02X%n", i, buffer[offset]); // 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 // reconstruct 410 bytes each with 5 bits
@ -215,7 +215,7 @@ class Nibblizer
{ {
// convert legal disk values to actual 6 bit values // 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_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 // reconstruct 342 bytes each with 6 bits
byte chk = 0; byte chk = 0;

View File

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