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

158 lines
4.9 KiB
Java
Raw Normal View History

2018-08-11 00:07:50 +00:00
package com.bytezone.diskbrowser.disk;
import com.bytezone.diskbrowser.disk.MC3470.DiskSector;
public class DiskReader16Sector extends DiskReader
{
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
private static int[] interleave =
{ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 };
// ---------------------------------------------------------------------------------//
// constructor
// ---------------------------------------------------------------------------------//
DiskReader16Sector ()
{
super (16);
}
// ---------------------------------------------------------------------------------//
// decodeSector
// ---------------------------------------------------------------------------------//
@Override
2018-08-12 07:16:03 +00:00
byte[] decodeSector (byte[] buffer)
2018-08-11 00:07:50 +00:00
{
// rearrange 342 bytes into 256
2018-08-12 07:16:03 +00:00
byte[] decodedBuffer = new byte[BLOCK_SIZE]; // 256 bytes
int offset = 0;
2018-08-11 00:07:50 +00:00
try
{
// convert legal disk values to actual 6 bit values
2018-08-11 04:12:21 +00:00
for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) // 343 bytes
2018-08-12 07:16:03 +00:00
decodeA[i] = (byte) (byteTranslator.decode (buffer[offset++]) << 2);
2018-08-11 00:07:50 +00:00
// reconstruct 342 bytes each with 6 bits
byte chk = 0;
2018-08-12 07:16:03 +00:00
for (int i = decodeB.length - 1; i >= 0; i--) // 342 bytes
2018-08-11 04:12:21 +00:00
chk = decodeB[i] = (byte) (decodeA[i + 1] ^ chk);
if ((chk ^ decodeA[0]) != 0)
2018-08-11 00:07:50 +00:00
throw new DiskNibbleException ("Checksum failed");
// move 6 bits into place
for (int i = 0; i < BLOCK_SIZE; i++)
2018-08-11 04:12:21 +00:00
decodedBuffer[i] = decodeB[i + 86];
2018-08-11 00:07:50 +00:00
// reattach each byte's last 2 bits
for (int i = 0, j = 86, k = 172; i < 86; i++, j++, k++)
{
2018-08-11 04:12:21 +00:00
byte val = decodeB[i];
2018-08-11 00:07:50 +00:00
decodedBuffer[i] |= reverse ((val & 0x0C) >> 2);
decodedBuffer[j] |= reverse ((val & 0x30) >> 4);
if (k < BLOCK_SIZE)
decodedBuffer[k] |= reverse ((val & 0xC0) >> 6);
}
}
catch (Exception e)
{
System.out.println (e);
2018-08-12 07:16:03 +00:00
// e.printStackTrace ();
2018-08-11 00:07:50 +00:00
}
return decodedBuffer;
}
// ---------------------------------------------------------------------------------//
// encodeSector
// ---------------------------------------------------------------------------------//
// convert 256 data bytes into 342 translated bytes plus a checksum
@Override
byte[] encodeSector (byte[] buffer)
{
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
for (int i = 0; i < BLOCK_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
// ---------------------------------------------------------------------------------//
// reverse 2 bits - 0 <= bits <= 3
private static int reverse (int bits)
{
return bits == 1 ? 2 : bits == 2 ? 1 : bits;
}
// ---------------------------------------------------------------------------------//
// storeBuffer
// ---------------------------------------------------------------------------------//
@Override
void storeBuffer (DiskSector diskSector, byte[] diskBuffer)
{
DiskAddressField addressField = diskSector.addressField;
byte[] sectorBuffer = diskSector.buffer;
int offset = addressField.track * 0x1000 + interleave[addressField.sector] * 256;
System.arraycopy (sectorBuffer, 0, diskBuffer, offset, 256);
}
// ---------------------------------------------------------------------------------//
// expectedDataSize
// ---------------------------------------------------------------------------------//
@Override
int expectedDataSize ()
{
2018-08-11 04:12:21 +00:00
return BUFFER_WITH_CHECKSUM_SIZE;
2018-08-11 00:07:50 +00:00
}
}