dmolony-DiskBrowser/src/com/bytezone/diskbrowser/nib/DiskReaderGCR.java

100 lines
3.8 KiB
Java

package com.bytezone.diskbrowser.nib;
// -----------------------------------------------------------------------------------//
public class DiskReaderGCR extends DiskReader
// -----------------------------------------------------------------------------------//
{
static final int TAG_SIZE = 12;
private final ByteTranslator byteTranslator = new ByteTranslator6and2 ();
// ---------------------------------------------------------------------------------//
DiskReaderGCR ()
// ---------------------------------------------------------------------------------//
{
super (0);
}
// ---------------------------------------------------------------------------------//
@Override
byte[] decodeSector (byte[] inBuffer, int inPtr) throws DiskNibbleException
// ---------------------------------------------------------------------------------//
{
byte[] outBuffer = new byte[BLOCK_SIZE + TAG_SIZE]; // 524 bytes
int outPtr = 0;
int[] checksums = new int[3];
// decode four disk bytes into three data bytes (174 * 3 + 2 = 524)
while (true)
{
// ROL first checksum
checksums[0] = (checksums[0] & 0xFF) << 1; // shift left
if ((checksums[0] > 0xFF)) // check for overflow
++checksums[0]; // set bit 0
// 6&2 translation
byte d3 = byteTranslator.decode (inBuffer[inPtr++]); // composite byte
byte d0 = byteTranslator.decode (inBuffer[inPtr++]);
byte d1 = byteTranslator.decode (inBuffer[inPtr++]);
// reassemble bytes
byte b0 = (byte) (d0 | ((d3 & 0x30) << 2));
byte b1 = (byte) (d1 | ((d3 & 0x0C) << 4));
// calculate running checksums
outBuffer[outPtr++] = checksum (b0, checksums, 0, 2);
outBuffer[outPtr++] = checksum (b1, checksums, 2, 1);
if (outPtr == outBuffer.length)
break;
byte d2 = byteTranslator.decode (inBuffer[inPtr++]); // translate
byte b2 = (byte) (d2 | (d3 << 6)); // reassemble
outBuffer[outPtr++] = checksum (b2, checksums, 1, 0); // checksum
}
// decode four disk bytes into three checksum bytes
byte d3 = byteTranslator.decode (inBuffer[inPtr++]); // composite byte
byte d0 = byteTranslator.decode (inBuffer[inPtr++]);
byte d1 = byteTranslator.decode (inBuffer[inPtr++]);
byte d2 = byteTranslator.decode (inBuffer[inPtr++]);
// reassemble bytes
byte b0 = (byte) ((d0 & 0x3F) | ((d3 & 0x30) << 2));
byte b1 = (byte) ((d1 & 0x3F) | ((d3 & 0x0C) << 4));
byte b2 = (byte) ((d2 & 0x3F) | ((d3 & 0x03) << 6));
// compare disk checksums with calculated checksums
if ((checksums[0] & 0xFF) != (b2 & 0xFF) //
|| (checksums[1] & 0xFF) != (b1 & 0xFF) //
|| (checksums[2] & 0xFF) != (b0 & 0xFF))
throw new DiskNibbleException ("Checksum failed");
return outBuffer;
}
// ---------------------------------------------------------------------------------//
private byte checksum (byte diskByte, int[] checksums, int current, int next)
// ---------------------------------------------------------------------------------//
{
int val = (diskByte ^ checksums[current]) & 0xFF;
checksums[next] += val; // prepare next checksum
if (checksums[current] > 0xFF) // is there a carry?
{
++checksums[next]; // pass it on
checksums[current] &= 0xFF; // back to 8 bits
}
return (byte) val; // converted data byte
}
// ---------------------------------------------------------------------------------//
@Override
byte[] encodeSector (byte[] buffer)
// ---------------------------------------------------------------------------------//
{
System.out.println ("encodeSector() not written");
return null;
}
}