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

101 lines
3.9 KiB
Java
Raw Normal View History

2019-09-04 20:44:43 +00:00
package com.bytezone.diskbrowser.nib;
// -----------------------------------------------------------------------------------//
2019-09-13 05:32:35 +00:00
class DiskReaderGCR extends DiskReader
2019-09-04 20:44:43 +00:00
// -----------------------------------------------------------------------------------//
{
2019-09-05 12:34:34 +00:00
static final int TAG_SIZE = 12;
2019-09-04 20:44:43 +00:00
private final ByteTranslator byteTranslator = new ByteTranslator6and2 ();
// ---------------------------------------------------------------------------------//
2019-09-04 22:15:53 +00:00
DiskReaderGCR ()
2019-09-04 20:44:43 +00:00
// ---------------------------------------------------------------------------------//
{
super (0);
}
// ---------------------------------------------------------------------------------//
@Override
2019-09-05 02:02:34 +00:00
byte[] decodeSector (byte[] inBuffer, int inPtr) throws DiskNibbleException
2019-09-04 20:44:43 +00:00
// ---------------------------------------------------------------------------------//
{
2019-09-05 12:34:34 +00:00
byte[] outBuffer = new byte[BLOCK_SIZE + TAG_SIZE]; // 524 bytes
2019-09-04 20:44:43 +00:00
int outPtr = 0;
int[] checksums = new int[3];
2019-09-05 03:11:29 +00:00
// decode four disk bytes into three data bytes (174 * 3 + 2 = 524)
while (true)
2019-09-04 20:44:43 +00:00
{
2019-09-13 05:32:35 +00:00
// ROL checksum (also keep left-shifted hi bit)
2019-09-05 20:23:44 +00:00
checksums[2] = (checksums[2] & 0xFF) << 1; // shift left
if ((checksums[2] > 0xFF)) // check for overflow
++checksums[2]; // set bit 0
2019-09-04 20:44:43 +00:00
2019-09-04 21:14:35 +00:00
// 6&2 translation
2019-09-05 02:02:34 +00:00
byte d3 = byteTranslator.decode (inBuffer[inPtr++]); // composite byte
byte d0 = byteTranslator.decode (inBuffer[inPtr++]);
byte d1 = byteTranslator.decode (inBuffer[inPtr++]);
2019-09-04 20:44:43 +00:00
2019-09-05 21:54:51 +00:00
// reassemble data bytes
2019-09-05 22:01:13 +00:00
byte b0 = (byte) (d0 | ((d3 << 2) & 0xC0));
byte b1 = (byte) (d1 | ((d3 << 4) & 0xC0));
2019-09-04 20:44:43 +00:00
2019-09-04 21:14:35 +00:00
// calculate running checksums
2019-09-05 22:36:15 +00:00
outBuffer[outPtr++] = checksum (b0, checksums, 0);
outBuffer[outPtr++] = checksum (b1, checksums, 1);
2019-09-04 20:44:43 +00:00
2019-09-05 03:11:29 +00:00
if (outPtr == outBuffer.length)
break;
byte d2 = byteTranslator.decode (inBuffer[inPtr++]); // translate
2019-09-05 03:20:05 +00:00
byte b2 = (byte) (d2 | (d3 << 6)); // reassemble
2019-09-05 22:36:15 +00:00
outBuffer[outPtr++] = checksum (b2, checksums, 2); // checksum
2019-09-04 20:44:43 +00:00
}
2019-09-05 12:34:34 +00:00
// decode four disk bytes into three checksum bytes
2019-09-05 02:02:34 +00:00
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++]);
2019-09-04 20:44:43 +00:00
2019-09-05 21:54:51 +00:00
// reassemble checksums
2019-09-05 22:01:13 +00:00
byte b0 = (byte) (d0 | ((d3 << 2) & 0xC0));
byte b1 = (byte) (d1 | ((d3 << 4) & 0xC0));
2019-09-05 21:54:51 +00:00
byte b2 = (byte) (d2 | (d3 << 6));
2019-09-04 20:44:43 +00:00
2019-09-04 21:14:35 +00:00
// compare disk checksums with calculated checksums
2019-09-13 05:32:35 +00:00
if ((byte) (checksums[0] & 0xFF) != b0 //
|| (byte) (checksums[1] & 0xFF) != b1 //
|| (byte) (checksums[2] & 0xFF) != b2)
2019-09-04 20:44:43 +00:00
throw new DiskNibbleException ("Checksum failed");
return outBuffer;
}
// ---------------------------------------------------------------------------------//
2019-09-13 05:32:35 +00:00
private byte checksum (byte diskByte, int[] checksums, int current)
2019-09-04 20:44:43 +00:00
// ---------------------------------------------------------------------------------//
{
2019-09-13 05:32:35 +00:00
int prev = (current + 2) % 3;
int val = (diskByte ^ checksums[prev]) & 0xFF;
checksums[current] += val; // add to this checksum
2019-09-04 20:44:43 +00:00
2019-09-13 05:32:35 +00:00
if (checksums[prev] > 0xFF) // was there a carry last time?
2019-09-04 20:44:43 +00:00
{
2019-09-13 05:32:35 +00:00
++checksums[current]; // add it to this checksum
checksums[prev] &= 0xFF; // reset previous carry
2019-09-04 20:44:43 +00:00
}
2019-09-13 05:32:35 +00:00
return (byte) val; // converted data byte
2019-09-04 20:44:43 +00:00
}
// ---------------------------------------------------------------------------------//
@Override
byte[] encodeSector (byte[] buffer)
// ---------------------------------------------------------------------------------//
{
2019-09-05 12:34:34 +00:00
System.out.println ("encodeSector() not written");
2019-09-04 20:44:43 +00:00
return null;
}
}