1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-31 18:04:37 +00:00

Makes some faulty steps further towards providing Apple GCR assistance.

This commit is contained in:
Thomas Harte 2018-04-23 19:59:03 -07:00
parent d447e81abd
commit bce0702745
2 changed files with 106 additions and 0 deletions

View File

@ -51,3 +51,93 @@ void AppleGCR::encode_six_and_two_block(uint8_t *destination, uint8_t *source) {
destination[2] = static_cast<uint8_t>(six_and_two_encoding_for_value( (source[1] << 2) | (source[2] >> 6) ));
destination[3] = static_cast<uint8_t>(six_and_two_encoding_for_value( source[2] ));
}
/*!
Produces a PCM segment containing @c length sync bytes, each aligned to the beginning of
a @c bit_size -sized window.
*/
static Storage::Disk::PCMSegment sync(int length, int bit_size) {
Storage::Disk::PCMSegment segment;
// Allocate sufficient storage.
segment.data.resize(static_cast<size_t>(((length * bit_size) + 7) >> 3), 0);
while(length--) {
segment.data[segment.number_of_bits >> 3] |= 0xff >> (segment.number_of_bits & 7);
if(segment.number_of_bits & 7) {
segment.data[1 + (segment.number_of_bits >> 3)] |= 0xff << (8 - (segment.number_of_bits & 7));
}
segment.number_of_bits += static_cast<unsigned int>(bit_size);
}
return segment;
}
Storage::Disk::PCMSegment AppleGCR::six_and_two_sync(int length) {
return sync(length, 9);
}
Storage::Disk::PCMSegment AppleGCR::five_and_three_sync(int length) {
return sync(length, 10);
}
Storage::Disk::PCMSegment AppleGCR::header(uint8_t volume, uint8_t track, uint8_t sector) {
const uint8_t checksum = volume ^ track ^ sector;
// Apple headers are encoded using an FM-esque scheme rather than 6 and 2, or 5 and 3.
Storage::Disk::PCMSegment segment;
segment.data.resize(14);
segment.number_of_bits = 14*8;
segment.data[0] = header_prologue[0];
segment.data[1] = header_prologue[1];
segment.data[2] = header_prologue[2];
#define WriteFM(index, value) \
segment.data[index+0] = static_cast<uint8_t>((value >> 1) | 0xaa); \
segment.data[index+1] = static_cast<uint8_t>(value | 0xaa); \
WriteFM(3, volume);
WriteFM(5, track);
WriteFM(7, sector);
WriteFM(9, checksum);
#undef WriteFM
segment.data[11] = epilogue[0];
segment.data[12] = epilogue[1];
segment.data[13] = epilogue[2];
return segment;
}
Storage::Disk::PCMSegment AppleGCR::five_and_three_data(uint8_t *source) {
Storage::Disk::PCMSegment segment;
segment.data.resize(410 + 7);
segment.data[0] = header_prologue[0];
segment.data[1] = header_prologue[1];
segment.data[2] = header_prologue[2];
std::size_t source_pointer = 0;
std::size_t destination_pointer = 3;
while(source_pointer < 255) {
encode_five_and_three_block(&segment.data[destination_pointer], &source[source_pointer]);
source_pointer += 5;
destination_pointer += 8;
}
return segment;
}
Storage::Disk::PCMSegment AppleGCR::six_and_two_data(uint8_t *source) {
Storage::Disk::PCMSegment segment;
segment.data.resize(342 + 7);
segment.data[0] = header_prologue[0];
segment.data[1] = header_prologue[1];
segment.data[2] = header_prologue[2];
return segment;
}

View File

@ -10,6 +10,7 @@
#define AppleGCR_hpp
#include <cstdint>
#include "../../Disk/Track/PCMSegment.hpp"
namespace Storage {
namespace Encodings {
@ -45,6 +46,21 @@ namespace AppleGCR {
@returns the byte composed by splitting the dectet into two qintets, decoding each and composing the resulting nibbles.
*/
// unsigned int decoding_from_dectet(unsigned int dectet);
/// Describes the standard three-byte prologue that begins a header.
const uint8_t header_prologue[3] = {0xd5, 0xaa, 0x96};
/// Describes the standard three-byte prologue that begins a data section.
const uint8_t data_prologue[3] = {0xd5, 0xaa, 0xad};
/// Describes the epilogue that ends both data sections and headers.
const uint8_t epilogue[3] = {0xde, 0xaa, 0xeb};
Storage::Disk::PCMSegment header(uint8_t volume, uint8_t track, uint8_t sector);
Storage::Disk::PCMSegment six_and_two_data(uint8_t *source);
Storage::Disk::PCMSegment six_and_two_sync(int length);
Storage::Disk::PCMSegment five_and_three_data(uint8_t *source);
Storage::Disk::PCMSegment five_and_three_sync(int length);
}
}