The Amiga writer now generates valid flux files --- but it looks like the

writer's broken (both the Amiga and the Brother have failed).
This commit is contained in:
David Given
2019-12-14 20:44:48 +01:00
parent 5a0fb2761a
commit 792cc88192
9 changed files with 226 additions and 68 deletions

View File

@@ -21,47 +21,6 @@
static const FluxPattern SECTOR_PATTERN(48, AMIGA_SECTOR_RECORD);
static Bytes deinterleave(const uint8_t*& input, size_t len)
{
assert(!(len & 1));
const uint8_t* odds = &input[0];
const uint8_t* evens = &input[len/2];
Bytes output;
ByteWriter bw(output);
for (size_t i=0; i<len/2; i++)
{
uint8_t o = *odds++;
uint8_t e = *evens++;
/* This is the 'Interleave bits with 64-bit multiply' technique from
* http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
*/
uint16_t result =
(((e * 0x0101010101010101ULL & 0x8040201008040201ULL)
* 0x0102040810204081ULL >> 49) & 0x5555) |
(((o * 0x0101010101010101ULL & 0x8040201008040201ULL)
* 0x0102040810204081ULL >> 48) & 0xAAAA);
bw.write_be16(result);
}
input += len;
return output;
}
static uint32_t checksum(const Bytes& bytes)
{
ByteReader br(bytes);
uint32_t checksum = 0;
assert((bytes.size() & 3) == 0);
while (!br.eof())
checksum ^= br.read_be32();
return checksum & 0x55555555;
}
AbstractDecoder::RecordType AmigaDecoder::advanceToNextRecord()
{
_sector->clock = _fmr->seekToPattern(SECTOR_PATTERN);
@@ -78,22 +37,22 @@ void AmigaDecoder::decodeSectorRecord()
const uint8_t* ptr = bytes.begin() + 3;
Bytes header = deinterleave(ptr, 4);
Bytes recoveryinfo = deinterleave(ptr, 16);
Bytes header = amigaDeinterleave(ptr, 4);
Bytes recoveryinfo = amigaDeinterleave(ptr, 16);
_sector->logicalTrack = header[1] >> 1;
_sector->logicalSide = header[1] & 1;
_sector->logicalSector = header[2];
uint32_t wantedheaderchecksum = deinterleave(ptr, 4).reader().read_be32();
uint32_t gotheaderchecksum = checksum(rawbytes.slice(6, 40));
uint32_t wantedheaderchecksum = amigaDeinterleave(ptr, 4).reader().read_be32();
uint32_t gotheaderchecksum = amigaChecksum(rawbytes.slice(6, 40));
if (gotheaderchecksum != wantedheaderchecksum)
return;
uint32_t wanteddatachecksum = deinterleave(ptr, 4).reader().read_be32();
uint32_t gotdatachecksum = checksum(rawbytes.slice(62, 1024));
uint32_t wanteddatachecksum = amigaDeinterleave(ptr, 4).reader().read_be32();
uint32_t gotdatachecksum = amigaChecksum(rawbytes.slice(62, 1024));
_sector->data.clear();
_sector->data.writer().append(deinterleave(ptr, 512)).append(recoveryinfo);
_sector->data.writer().append(amigaDeinterleave(ptr, 512)).append(recoveryinfo);
_sector->status = (gotdatachecksum == wanteddatachecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
}