mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 00:30:31 +00:00
Relocates and cleans up what is currently written of Apple GCR handling as the encoder.
A decoder will be forthcoming.
This commit is contained in:
parent
59718e132b
commit
2e20191c01
@ -9,7 +9,7 @@
|
|||||||
#include "AppleDSK.hpp"
|
#include "AppleDSK.hpp"
|
||||||
|
|
||||||
#include "../../Track/PCMTrack.hpp"
|
#include "../../Track/PCMTrack.hpp"
|
||||||
#include "../../Encodings/AppleGCR.hpp"
|
#include "../../Encodings/AppleGCR/Encoder.hpp"
|
||||||
|
|
||||||
using namespace Storage::Disk;
|
using namespace Storage::Disk;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "NIB.hpp"
|
#include "NIB.hpp"
|
||||||
|
|
||||||
#include "../../Track/PCMTrack.hpp"
|
#include "../../Track/PCMTrack.hpp"
|
||||||
#include "../../Encodings/AppleGCR.hpp"
|
#include "../../Encodings/AppleGCR/Encoder.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
//
|
|
||||||
// AppleGCR.hpp
|
|
||||||
// Clock Signal
|
|
||||||
//
|
|
||||||
// Created by Thomas Harte on 21/04/2018.
|
|
||||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef AppleGCR_hpp
|
|
||||||
#define AppleGCR_hpp
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include "../../Disk/Track/PCMSegment.hpp"
|
|
||||||
|
|
||||||
namespace Storage {
|
|
||||||
namespace Encodings {
|
|
||||||
|
|
||||||
namespace AppleGCR {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@returns the eight-bit 13-sector GCR encoding for the low five bits of @c value.
|
|
||||||
*/
|
|
||||||
// unsigned int five_and_three_encoding_for_value(int value);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@returns the eight-bit 16-sector GCR encoding for the low six bits of @c value.
|
|
||||||
*/
|
|
||||||
// unsigned int six_and_two_encoding_for_value(int value);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
A block is defined to be five source bytes, which encodes to eight GCR bytes.
|
|
||||||
*/
|
|
||||||
// void encode_five_and_three_block(uint8_t *destination, uint8_t *source);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
A block is defined to be three source bytes, which encodes to four GCR bytes.
|
|
||||||
*/
|
|
||||||
// void encode_six_and_two_block(uint8_t *destination, uint8_t *source);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@returns the four bit nibble for the five-bit GCR @c quintet if a valid GCR value; INT_MAX otherwise.
|
|
||||||
*/
|
|
||||||
// unsigned int decoding_from_quintet(unsigned int quintet);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@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};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Produces the Apple-standard '4 and 4' per-sector header. This is the same
|
|
||||||
for both the 13- and 16-sector formats, and is 112 bits long.
|
|
||||||
*/
|
|
||||||
Storage::Disk::PCMSegment header(uint8_t volume, uint8_t track, uint8_t sector);
|
|
||||||
|
|
||||||
Storage::Disk::PCMSegment six_and_two_data(const uint8_t *source);
|
|
||||||
Storage::Disk::PCMSegment six_and_two_sync(int length);
|
|
||||||
|
|
||||||
Storage::Disk::PCMSegment five_and_three_data(const uint8_t *source);
|
|
||||||
Storage::Disk::PCMSegment five_and_three_sync(int length);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* AppleGCR_hpp */
|
|
@ -6,11 +6,11 @@
|
|||||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "AppleGCR.hpp"
|
#include "Encoder.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const unsigned int five_and_three_mapping[] = {
|
const uint8_t five_and_three_mapping[] = {
|
||||||
0xab, 0xad, 0xae, 0xaf, 0xb5, 0xb6, 0xb7, 0xba,
|
0xab, 0xad, 0xae, 0xaf, 0xb5, 0xb6, 0xb7, 0xba,
|
||||||
0xbb, 0xbd, 0xbe, 0xbf, 0xd6, 0xd7, 0xda, 0xdb,
|
0xbb, 0xbd, 0xbe, 0xbf, 0xd6, 0xd7, 0xda, 0xdb,
|
||||||
0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xed, 0xee, 0xef,
|
0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xed, 0xee, 0xef,
|
||||||
@ -53,26 +53,6 @@ Storage::Disk::PCMSegment sync(int length, int bit_size) {
|
|||||||
|
|
||||||
using namespace Storage::Encodings;
|
using namespace Storage::Encodings;
|
||||||
|
|
||||||
|
|
||||||
/*void AppleGCR::encode_five_and_three_block(uint8_t *destination, uint8_t *source) {
|
|
||||||
destination[0] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[0] >> 3 ));
|
|
||||||
destination[1] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[0] << 2) | (source[1] >> 6) ));
|
|
||||||
destination[2] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[1] >> 1 ));
|
|
||||||
destination[3] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[1] << 4) | (source[2] >> 4) ));
|
|
||||||
destination[4] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[2] << 1) | (source[3] >> 7) ));
|
|
||||||
destination[5] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[3] >> 2 ));
|
|
||||||
destination[6] = static_cast<uint8_t>(five_and_three_encoding_for_value( (source[3] << 3) | (source[4] >> 5) ));
|
|
||||||
destination[7] = static_cast<uint8_t>(five_and_three_encoding_for_value( source[4] ));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
/*void AppleGCR::encode_six_and_two_block(uint8_t *destination, uint8_t *source) {
|
|
||||||
destination[0] = static_cast<uint8_t>(six_and_two_encoding_for_value( source[0] >> 2 ));
|
|
||||||
destination[1] = static_cast<uint8_t>(six_and_two_encoding_for_value( (source[0] << 4) | (source[1] >> 4) ));
|
|
||||||
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] ));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Storage::Disk::PCMSegment AppleGCR::six_and_two_sync(int length) {
|
Storage::Disk::PCMSegment AppleGCR::six_and_two_sync(int length) {
|
||||||
return sync(length, 10);
|
return sync(length, 10);
|
||||||
}
|
}
|
||||||
@ -132,6 +112,11 @@ Storage::Disk::PCMSegment AppleGCR::five_and_three_data(const uint8_t *source) {
|
|||||||
// destination_pointer += 8;
|
// destination_pointer += 8;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// Map five-bit values up to full bytes.
|
||||||
|
for(std::size_t c = 0; c < 410; ++c) {
|
||||||
|
segment.data[3 + c] = five_and_three_mapping[segment.data[3 + c]];
|
||||||
|
}
|
||||||
|
|
||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
|
|
60
Storage/Disk/Encodings/AppleGCR/Encoder.hpp
Normal file
60
Storage/Disk/Encodings/AppleGCR/Encoder.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// AppleGCR.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 21/04/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AppleGCR_hpp
|
||||||
|
#define AppleGCR_hpp
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "../../../Disk/Track/PCMSegment.hpp"
|
||||||
|
|
||||||
|
namespace Storage {
|
||||||
|
namespace Encodings {
|
||||||
|
namespace AppleGCR {
|
||||||
|
|
||||||
|
/// 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};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Produces the Apple-standard four-and-four per-sector header. This is the same
|
||||||
|
for both the 13- and 16-sector formats, and is 112 bits long.
|
||||||
|
*/
|
||||||
|
Storage::Disk::PCMSegment header(uint8_t volume, uint8_t track, uint8_t sector);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Produces the data section of a six-and-two format sector; the segment returned
|
||||||
|
will be 2,792 bits long, encoding the first 256 bytes from @c source.
|
||||||
|
*/
|
||||||
|
Storage::Disk::PCMSegment six_and_two_data(const uint8_t *source);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Produces @c length sync six-and-two format sync bytes. The segment returned
|
||||||
|
is @c 10*length bits long.
|
||||||
|
*/
|
||||||
|
Storage::Disk::PCMSegment six_and_two_sync(int length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Produces the data section of a five-and-three format sector; the segment returned
|
||||||
|
will be 3,336 bits long, encoding the first 256 bytes from @c source.
|
||||||
|
*/
|
||||||
|
Storage::Disk::PCMSegment five_and_three_data(const uint8_t *source);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Produces @c length sync five-and-three format sync bytes. The segment returned
|
||||||
|
is @c 9*length bits long.
|
||||||
|
*/
|
||||||
|
Storage::Disk::PCMSegment five_and_three_sync(int length);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AppleGCR_hpp */
|
Loading…
x
Reference in New Issue
Block a user