mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-01 02:31:00 +00:00
Factor out bit spreading.
(And do a better job of it)
This commit is contained in:
parent
fc4ca4f8e3
commit
955cb6411c
37
Numeric/BitSpread.hpp
Normal file
37
Numeric/BitSpread.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// BitSpread.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 12/10/2021.
|
||||
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef BitSpread_hpp
|
||||
#define BitSpread_hpp
|
||||
|
||||
namespace Numeric {
|
||||
|
||||
/// @returns The bits of @c input with a 0 bit inserted between each and
|
||||
/// keeping the least-significant bit in its original position.
|
||||
///
|
||||
/// i.e. if @c input is abcdefgh then the result is 0a0b0c0d0e0f0g0h
|
||||
constexpr uint16_t spread_bits(uint8_t input) {
|
||||
uint16_t result = uint16_t(input); // 0000 0000 abcd efgh
|
||||
result = (result | (result << 4)) & 0x0f0f; // 0000 abcd 0000 efgh
|
||||
result = (result | (result << 2)) & 0x3333; // 00ab 00cd 00ef 00gh
|
||||
return (result | (result << 1)) & 0x5555; // 0a0b 0c0d 0e0f 0g0h
|
||||
}
|
||||
|
||||
/// Performs the opposite action to @c spread_bits; given the 16-bit input
|
||||
/// @c abcd @c efgh @c ijkl @c mnop, returns the byte value @c bdfhjlnp
|
||||
/// i.e. every other bit is retained, keeping the least-significant bit in place.
|
||||
constexpr uint8_t unspread_bits(uint16_t input) {
|
||||
input &= 0x5555; // 0a0b 0c0d 0e0f 0g0h
|
||||
input = (input | (input >> 1)) & 0x3333; // 00ab 00cd 00ef 00gh
|
||||
input = (input | (input >> 2)) & 0x0f0f; // 0000 abcd 0000 efgh
|
||||
return uint8_t(input | (input >> 4)); // 0000 0000 abcd efgh
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* BitSpread_hpp */
|
@ -2009,6 +2009,7 @@
|
||||
4BD0FBC2233706A200148981 /* CSApplication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CSApplication.m; sourceTree = "<group>"; };
|
||||
4BD1552E270B14AC00410C6E /* MemoryMap.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemoryMap.hpp; sourceTree = "<group>"; };
|
||||
4BD1552F2711E5FD00410C6E /* kickstart13 boot logo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "kickstart13 boot logo.json"; path = "Kickstart 1.3 boot logo/kickstart13 boot logo.json"; sourceTree = "<group>"; };
|
||||
4BD155312716362A00410C6E /* BitSpread.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = BitSpread.hpp; sourceTree = "<group>"; };
|
||||
4BD191D9219113B80042E144 /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
|
||||
4BD191F22191180E0042E144 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = "<group>"; };
|
||||
4BD191F32191180E0042E144 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
|
||||
@ -3154,6 +3155,7 @@
|
||||
4B7BA03C23D55E7900B98D9E /* Numeric */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BD155312716362A00410C6E /* BitSpread.hpp */,
|
||||
4B7BA03E23D55E7900B98D9E /* CRC.hpp */,
|
||||
4B7BA03F23D55E7900B98D9E /* LFSR.hpp */,
|
||||
4BFEA2F12682A90200EBF94C /* Sizes.hpp */,
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "../../Encodings/MFM/Constants.hpp"
|
||||
#include "../../Encodings/MFM/Encoder.hpp"
|
||||
#include "../../../../Numeric/BitSpread.hpp"
|
||||
#include "../../Track/PCMTrack.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
@ -78,16 +79,7 @@ template <typename IteratorT> auto checksum(IteratorT begin, IteratorT end) {
|
||||
++begin;
|
||||
|
||||
// Do a clockless MFM encode.
|
||||
const auto spread = uint16_t(
|
||||
((value&0x80) << 7) |
|
||||
((value&0x40) << 6) |
|
||||
((value&0x20) << 5) |
|
||||
((value&0x10) << 4) |
|
||||
((value&0x08) << 3) |
|
||||
((value&0x04) << 2) |
|
||||
((value&0x02) << 1) |
|
||||
((value&0x01) << 0)
|
||||
);
|
||||
const auto spread = Numeric::spread_bits(value);
|
||||
checksum[offset] ^= spread;
|
||||
offset ^= 1;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "Constants.hpp"
|
||||
#include "../../Track/PCMTrack.hpp"
|
||||
#include "../../../../Numeric/CRC.hpp"
|
||||
#include "../../../../Numeric/BitSpread.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
@ -29,32 +30,11 @@ class MFMEncoder: public Encoder {
|
||||
|
||||
void add_byte(uint8_t input, uint8_t fuzzy_mask = 0) final {
|
||||
crc_generator_.add(input);
|
||||
const uint16_t spread_value =
|
||||
uint16_t(
|
||||
((input & 0x01) << 0) |
|
||||
((input & 0x02) << 1) |
|
||||
((input & 0x04) << 2) |
|
||||
((input & 0x08) << 3) |
|
||||
((input & 0x10) << 4) |
|
||||
((input & 0x20) << 5) |
|
||||
((input & 0x40) << 6) |
|
||||
((input & 0x80) << 7)
|
||||
);
|
||||
const uint16_t spread_value = Numeric::spread_bits(input);
|
||||
const uint16_t spread_mask = Numeric::spread_bits(fuzzy_mask);
|
||||
const uint16_t or_bits = uint16_t((spread_value << 1) | (spread_value >> 1) | (last_output_ << 15));
|
||||
const uint16_t output = spread_value | ((~or_bits) & 0xaaaa);
|
||||
|
||||
const uint16_t spread_mask =
|
||||
uint16_t(
|
||||
((fuzzy_mask & 0x01) << 0) |
|
||||
((fuzzy_mask & 0x02) << 1) |
|
||||
((fuzzy_mask & 0x04) << 2) |
|
||||
((fuzzy_mask & 0x08) << 3) |
|
||||
((fuzzy_mask & 0x10) << 4) |
|
||||
((fuzzy_mask & 0x20) << 5) |
|
||||
((fuzzy_mask & 0x40) << 6) |
|
||||
((fuzzy_mask & 0x80) << 7)
|
||||
);
|
||||
|
||||
output_short(output, spread_mask);
|
||||
}
|
||||
|
||||
@ -108,27 +88,8 @@ class FMEncoder: public Encoder {
|
||||
void add_byte(uint8_t input, uint8_t fuzzy_mask = 0) final {
|
||||
crc_generator_.add(input);
|
||||
output_short(
|
||||
uint16_t(
|
||||
((input & 0x01) << 0) |
|
||||
((input & 0x02) << 1) |
|
||||
((input & 0x04) << 2) |
|
||||
((input & 0x08) << 3) |
|
||||
((input & 0x10) << 4) |
|
||||
((input & 0x20) << 5) |
|
||||
((input & 0x40) << 6) |
|
||||
((input & 0x80) << 7) |
|
||||
0xaaaa
|
||||
),
|
||||
uint16_t(
|
||||
((fuzzy_mask & 0x01) << 0) |
|
||||
((fuzzy_mask & 0x02) << 1) |
|
||||
((fuzzy_mask & 0x04) << 2) |
|
||||
((fuzzy_mask & 0x08) << 3) |
|
||||
((fuzzy_mask & 0x10) << 4) |
|
||||
((fuzzy_mask & 0x20) << 5) |
|
||||
((fuzzy_mask & 0x40) << 6) |
|
||||
((fuzzy_mask & 0x80) << 7)
|
||||
)
|
||||
Numeric::spread_bits(input) | 0xaaaa,
|
||||
Numeric::spread_bits(fuzzy_mask)
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user