package com.bytezone.diskbrowser.nib; // -----------------------------------------------------------------------------------// class DiskReader16Sector extends DiskReader // -----------------------------------------------------------------------------------// { private static final int RAW_BUFFER_SIZE = 342; private static final int BUFFER_WITH_CHECKSUM_SIZE = RAW_BUFFER_SIZE + 1; private final byte[] decodeA = new byte[BUFFER_WITH_CHECKSUM_SIZE]; private final byte[] decodeB = new byte[RAW_BUFFER_SIZE]; private final byte[] encodeA = new byte[RAW_BUFFER_SIZE]; private final byte[] encodeB = new byte[BUFFER_WITH_CHECKSUM_SIZE]; private final ByteTranslator byteTranslator = new ByteTranslator6and2 (); // ---------------------------------------------------------------------------------// DiskReader16Sector () // ---------------------------------------------------------------------------------// { super (16); } // ---------------------------------------------------------------------------------// @Override byte[] decodeSector (byte[] buffer, int offset) throws DiskNibbleException // ---------------------------------------------------------------------------------// { // rearrange 342 bytes into 256 byte[] decodedBuffer = new byte[SECTOR_SIZE]; // 256 bytes // 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); // 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"); // move 6 bits into place for (int i = 0; i < SECTOR_SIZE; i++) 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++) { byte val = decodeB[i]; decodedBuffer[i] |= reverse ((val & 0x0C) >> 2); decodedBuffer[j] |= reverse ((val & 0x30) >> 4); if (k < SECTOR_SIZE) decodedBuffer[k] |= reverse ((val & 0xC0) >> 6); } return decodedBuffer; } // convert 256 data bytes into 342 translated bytes plus a checksum // ---------------------------------------------------------------------------------// @Override byte[] encodeSector (byte[] buffer) // ---------------------------------------------------------------------------------// { byte[] encodedBuffer = new byte[BUFFER_WITH_CHECKSUM_SIZE]; // move data buffer down to make room for the 86 extra bytes for (int i = 0; i < SECTOR_SIZE; i++) encodeA[i + 86] = buffer[i]; // 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; encodeA[i] = (byte) (b1 | b2 | b3); } else encodeA[i] = (byte) (b1 | b2); } // convert into checksum bytes byte checksum = 0; for (int i = 0; i < RAW_BUFFER_SIZE; i++) { encodeB[i] = (byte) (checksum ^ encodeA[i]); checksum = encodeA[i]; } encodeB[RAW_BUFFER_SIZE] = checksum; // add checksum to the end // remove two bits and convert to translated bytes for (int i = 0; i < BUFFER_WITH_CHECKSUM_SIZE; i++) encodedBuffer[i] = byteTranslator.encode (encodeB[i]); return encodedBuffer; } }