2018-08-17 01:20:00 +00:00
|
|
|
package com.bytezone.diskbrowser.nib;
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2019-08-03 07:49:10 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2019-09-04 20:44:43 +00:00
|
|
|
class DiskReader16Sector extends DiskReader
|
2019-08-03 07:49:10 +00:00
|
|
|
// -----------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
2018-08-11 04:12:21 +00:00
|
|
|
private static final int RAW_BUFFER_SIZE = 342;
|
|
|
|
private static final int BUFFER_WITH_CHECKSUM_SIZE = RAW_BUFFER_SIZE + 1;
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-11 04:12:21 +00:00
|
|
|
private final byte[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE];
|
|
|
|
private final byte[] decodeB = new byte[RAW_BUFFER_SIZE];
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-11 04:12:21 +00:00
|
|
|
private final byte[] encodeA = new byte[RAW_BUFFER_SIZE];
|
|
|
|
private final byte[] encodeB = new byte[BUFFER_WITH_CHECKSUM_SIZE];
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-12 07:16:03 +00:00
|
|
|
private final ByteTranslator byteTranslator = new ByteTranslator6and2 ();
|
2018-08-11 00:07:50 +00:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
DiskReader16Sector ()
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
|
|
|
super (16);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
|
|
@Override
|
2019-07-28 06:24:52 +00:00
|
|
|
byte[] decodeSector (byte[] buffer, int offset) throws DiskNibbleException
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
|
|
|
// rearrange 342 bytes into 256
|
2019-09-05 12:34:34 +00:00
|
|
|
byte[] decodedBuffer = new byte[SECTOR_SIZE]; // 256 bytes
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-13 09:17:05 +00:00
|
|
|
// convert legal disk values to actual 6 bit values
|
|
|
|
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 343 bytes
|
|
|
|
decodeA[i] = (byte) (byteTranslator.decode (buffer[offset++]) << 2);
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-13 09:17:05 +00:00
|
|
|
// reconstruct 342 bytes each with 6 bits
|
|
|
|
byte chk = 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");
|
2018-08-11 00:07:50 +00:00
|
|
|
|
2018-08-13 09:17:05 +00:00
|
|
|
// move 6 bits into place
|
2019-09-05 12:34:34 +00:00
|
|
|
for (int i = 0; i < SECTOR_SIZE; i++)
|
2018-08-13 09:17:05 +00:00
|
|
|
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++)
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
2018-08-13 09:17:05 +00:00
|
|
|
byte val = decodeB[i];
|
|
|
|
|
|
|
|
decodedBuffer[i] |= reverse ((val & 0x0C) >> 2);
|
|
|
|
decodedBuffer[j] |= reverse ((val & 0x30) >> 4);
|
|
|
|
|
2019-09-05 12:34:34 +00:00
|
|
|
if (k < SECTOR_SIZE)
|
2018-08-13 09:17:05 +00:00
|
|
|
decodedBuffer[k] |= reverse ((val & 0xC0) >> 6);
|
2018-08-11 00:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return decodedBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// convert 256 data bytes into 342 translated bytes plus a checksum
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
@Override
|
|
|
|
byte[] encodeSector (byte[] buffer)
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
2018-08-11 04:12:21 +00:00
|
|
|
byte[] encodedBuffer = new byte[BUFFER_WITH_CHECKSUM_SIZE];
|
2018-08-11 00:07:50 +00:00
|
|
|
|
|
|
|
// move data buffer down to make room for the 86 extra bytes
|
2019-09-05 12:34:34 +00:00
|
|
|
for (int i = 0; i < SECTOR_SIZE; i++)
|
2018-08-11 04:12:21 +00:00
|
|
|
encodeA[i + 86] = buffer[i];
|
2018-08-11 00:07:50 +00:00
|
|
|
|
|
|
|
// build extra 86 bytes from the bits stripped from the data bytes
|
|
|
|
for (int i = 0; i < 86; i++)
|
|
|
|
{
|
|
|
|
int b1 = reverse (buffer[i] & 0x03) << 2;
|
|
|
|
int b2 = reverse (buffer[i + 86] & 0x03) << 4;
|
|
|
|
|
|
|
|
if (i < 84)
|
|
|
|
{
|
|
|
|
int b3 = reverse (buffer[i + 172] & 0x03) << 6;
|
2018-08-11 04:12:21 +00:00
|
|
|
encodeA[i] = (byte) (b1 | b2 | b3);
|
2018-08-11 00:07:50 +00:00
|
|
|
}
|
|
|
|
else
|
2018-08-11 04:12:21 +00:00
|
|
|
encodeA[i] = (byte) (b1 | b2);
|
2018-08-11 00:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// convert into checksum bytes
|
|
|
|
byte checksum = 0;
|
2018-08-11 04:12:21 +00:00
|
|
|
for (int i = 0; i < RAW_BUFFER_SIZE; i++)
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
2018-08-11 04:12:21 +00:00
|
|
|
encodeB[i] = (byte) (checksum ^ encodeA[i]);
|
|
|
|
checksum = encodeA[i];
|
2018-08-11 00:07:50 +00:00
|
|
|
}
|
2018-08-11 04:12:21 +00:00
|
|
|
|
|
|
|
encodeB[RAW_BUFFER_SIZE] = checksum; // add checksum to the end
|
2018-08-11 00:07:50 +00:00
|
|
|
|
|
|
|
// remove two bits and convert to translated bytes
|
2018-08-11 04:12:21 +00:00
|
|
|
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++)
|
2018-08-12 07:16:03 +00:00
|
|
|
encodedBuffer[i] = byteTranslator.encode (encodeB[i]);
|
2018-08-11 00:07:50 +00:00
|
|
|
|
|
|
|
return encodedBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// reverse 2 bits - 0 <= bits <= 3
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
private static int reverse (int bits)
|
2019-08-03 07:49:10 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2018-08-11 00:07:50 +00:00
|
|
|
{
|
|
|
|
return bits == 1 ? 2 : bits == 2 ? 1 : bits;
|
|
|
|
}
|
|
|
|
}
|