mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Calling it 'number theory' probably isn't accurate but extracted the CRC stuff and started using it for [M]FM encoding.
This commit is contained in:
parent
55a7418cbf
commit
180c3df2d4
11
NumberTheory/CRC.cpp
Normal file
11
NumberTheory/CRC.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// CRC.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 18/09/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "CRC.hpp"
|
||||
|
||||
using namespace NumberTheory;
|
40
NumberTheory/CRC.hpp
Normal file
40
NumberTheory/CRC.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// CRC.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 18/09/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef CRC_hpp
|
||||
#define CRC_hpp
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace NumberTheory {
|
||||
|
||||
class CRC16 {
|
||||
public:
|
||||
CRC16(uint16_t polynomial, uint16_t reset_value) :
|
||||
reset_value_(reset_value), value_(reset_value), polynomial_(polynomial) {}
|
||||
|
||||
inline void reset() { value_ = reset_value_; }
|
||||
inline void add(uint8_t value) {
|
||||
// TODO: go table based
|
||||
value_ ^= (uint16_t)value << 8;
|
||||
for(int c = 0; c < 8; c++)
|
||||
{
|
||||
uint16_t exclusive_or = (value_&0x8000) ? polynomial_ : 0x0000;
|
||||
value_ = (uint16_t)(value_ << 1) ^ exclusive_or;
|
||||
}
|
||||
}
|
||||
inline uint16_t get_value() { return value_; }
|
||||
|
||||
private:
|
||||
uint16_t reset_value_, polynomial_;
|
||||
uint16_t value_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* CRC_hpp */
|
@ -356,6 +356,7 @@
|
||||
4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */; };
|
||||
4BF1354C1D6D2C300054B2EA /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1354A1D6D2C300054B2EA /* StaticAnalyser.cpp */; };
|
||||
4BF8295D1D8F048B001BAE39 /* MFM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8295B1D8F048B001BAE39 /* MFM.cpp */; };
|
||||
4BF829601D8F3C87001BAE39 /* CRC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8295E1D8F3C87001BAE39 /* CRC.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -808,6 +809,8 @@
|
||||
4BF1354B1D6D2C300054B2EA /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = StaticAnalyser.hpp; path = ../../StaticAnalyser/StaticAnalyser.hpp; sourceTree = "<group>"; };
|
||||
4BF8295B1D8F048B001BAE39 /* MFM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MFM.cpp; path = Encodings/MFM.cpp; sourceTree = "<group>"; };
|
||||
4BF8295C1D8F048B001BAE39 /* MFM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = MFM.hpp; path = Encodings/MFM.hpp; sourceTree = "<group>"; };
|
||||
4BF8295E1D8F3C87001BAE39 /* CRC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CRC.cpp; path = ../../NumberTheory/CRC.cpp; sourceTree = "<group>"; };
|
||||
4BF8295F1D8F3C87001BAE39 /* CRC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRC.hpp; path = ../../NumberTheory/CRC.hpp; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -1394,6 +1397,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BB697C61D4B558F00248BDF /* Factors.hpp */,
|
||||
4BF8295E1D8F3C87001BAE39 /* CRC.cpp */,
|
||||
4BF8295F1D8F3C87001BAE39 /* CRC.hpp */,
|
||||
);
|
||||
name = NumberTheory;
|
||||
sourceTree = "<group>";
|
||||
@ -2079,6 +2084,7 @@
|
||||
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
|
||||
4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */,
|
||||
4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */,
|
||||
4BF829601D8F3C87001BAE39 /* CRC.cpp in Sources */,
|
||||
4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */,
|
||||
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
|
||||
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "MFM.hpp"
|
||||
|
||||
#import "../PCMTrack.hpp"
|
||||
#import "../../../NumberTheory/CRC.hpp"
|
||||
|
||||
using namespace Storage::Encodings::MFM;
|
||||
|
||||
@ -106,6 +107,19 @@ template <class T> class FMShifter: public Shifter<T> {
|
||||
}
|
||||
};
|
||||
|
||||
static uint8_t logarithmic_size_for_size(size_t size)
|
||||
{
|
||||
switch(size)
|
||||
{
|
||||
default: return 0;
|
||||
case 256: return 1;
|
||||
case 512: return 2;
|
||||
case 1024: return 3;
|
||||
case 2048: return 4;
|
||||
case 4196: return 5;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
GetTrackWithSectors(
|
||||
const std::vector<Sector> §ors,
|
||||
@ -115,6 +129,7 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
size_t inter_sector_gap)
|
||||
{
|
||||
T shifter;
|
||||
NumberTheory::CRC16 crc_generator(0x1021, 0xffff);
|
||||
|
||||
// output the index mark
|
||||
shifter.add_index_address_mark();
|
||||
@ -125,30 +140,46 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
// add sectors
|
||||
for(const Sector §or : sectors)
|
||||
{
|
||||
// gap
|
||||
for(int c = 0; c < pre_address_mark_bytes; c++) shifter.add_byte(0x00);
|
||||
|
||||
// sector header
|
||||
shifter.add_ID_address_mark();
|
||||
shifter.add_byte(sector.track);
|
||||
shifter.add_byte(sector.side);
|
||||
shifter.add_byte(sector.sector);
|
||||
switch(sector.data.size())
|
||||
{
|
||||
default: shifter.add_byte(0); break;
|
||||
case 256: shifter.add_byte(1); break;
|
||||
case 512: shifter.add_byte(2); break;
|
||||
case 1024: shifter.add_byte(3); break;
|
||||
case 2048: shifter.add_byte(4); break;
|
||||
case 4196: shifter.add_byte(5); break;
|
||||
}
|
||||
// TODO: CRC of bytes since the track number
|
||||
uint8_t size = logarithmic_size_for_size(sector.data.size());
|
||||
shifter.add_byte(size);
|
||||
|
||||
// header CRC
|
||||
crc_generator.reset();
|
||||
crc_generator.add(sector.track);
|
||||
crc_generator.add(sector.side);
|
||||
crc_generator.add(sector.sector);
|
||||
crc_generator.add(size);
|
||||
uint16_t crc_value = crc_generator.get_value();
|
||||
shifter.add_byte(crc_value & 0xff);
|
||||
shifter.add_byte(crc_value >> 8);
|
||||
|
||||
// gap
|
||||
for(int c = 0; c < post_address_mark_bytes; c++) shifter.add_byte(0x4e);
|
||||
for(int c = 0; c < pre_data_mark_bytes; c++) shifter.add_byte(0x00);
|
||||
|
||||
// data
|
||||
shifter.add_data_address_mark();
|
||||
for(size_t c = 0; c < sector.data.size(); c++) shifter.add_byte(sector.data[c]);
|
||||
// TODO: CRC of data
|
||||
crc_generator.reset();
|
||||
for(size_t c = 0; c < sector.data.size(); c++)
|
||||
{
|
||||
shifter.add_byte(sector.data[c]);
|
||||
crc_generator.add(sector.data[c]);
|
||||
}
|
||||
|
||||
// data CRC
|
||||
crc_value = crc_generator.get_value();
|
||||
shifter.add_byte(crc_value & 0xff);
|
||||
shifter.add_byte(crc_value >> 8);
|
||||
|
||||
// gap
|
||||
for(int c = 0; c < post_data_bytes; c++) shifter.add_byte(0x00);
|
||||
for(int c = 0; c < inter_sector_gap; c++) shifter.add_byte(0x4e);
|
||||
}
|
||||
@ -159,17 +190,19 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
|
||||
return std::shared_ptr<Storage::Disk::Track>(new Storage::Disk::PCMTrack(std::move(segment)));
|
||||
}
|
||||
|
||||
struct VectorReceiver {
|
||||
void output_short(uint16_t value) {
|
||||
data.push_back(value & 0xff);
|
||||
data.push_back(value >> 8);
|
||||
}
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSectors(const std::vector<Sector> §ors)
|
||||
{
|
||||
struct VectorShifter: public FMShifter<VectorShifter> {
|
||||
void output_short(uint16_t value) {
|
||||
data.push_back(value & 0xff);
|
||||
data.push_back(value >> 8);
|
||||
}
|
||||
std::vector<uint8_t> data;
|
||||
struct VectorShifter: public FMShifter<VectorShifter>, VectorReceiver {
|
||||
using VectorReceiver::output_short;
|
||||
};
|
||||
|
||||
return GetTrackWithSectors<VectorShifter>(
|
||||
sectors,
|
||||
16, 0x00,
|
||||
@ -180,14 +213,9 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetFMTrackWithSec
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSectors(const std::vector<Sector> §ors)
|
||||
{
|
||||
struct VectorShifter: public MFMShifter<VectorShifter> {
|
||||
void output_short(uint16_t value) {
|
||||
data.push_back(value & 0xff);
|
||||
data.push_back(value >> 8);
|
||||
}
|
||||
std::vector<uint8_t> data;
|
||||
struct VectorShifter: public MFMShifter<VectorShifter>, VectorReceiver {
|
||||
using VectorReceiver::output_short;
|
||||
};
|
||||
|
||||
return GetTrackWithSectors<VectorShifter>(
|
||||
sectors,
|
||||
50, 0x4e,
|
||||
|
Loading…
Reference in New Issue
Block a user