Clean up Storage.hpp and starship operators.
This commit is contained in:
1 parent
8ff5129704
commit
f459ffe619
4 files changed
+143
-55
No files matched your search
@@ -347,7 +347,11 @@ void IWM::select_shift_mode() {
|
||||
// If writing mode just began, set the drive into write mode and cue up the first output byte.
|
||||
if(old_shift_mode != ShiftMode::Writing && shift_mode_ == ShiftMode::Writing) {
|
||||
if(drives_[active_drive_]) {
|
||||
drives_[active_drive_]->begin_writing(Storage::Time(1, clock_rate_ / bit_length_.get()), false, false);
|
||||
drives_[active_drive_]->begin_writing(
|
||||
Storage::Time(1, clock_rate_ / bit_length_.as<int>()),
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
shift_register_ = next_output_;
|
||||
write_handshake_ |= 0x80 | 0x40;
|
||||
|
||||
@@ -222,7 +222,10 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator ==(const Flags &rhs) const {
|
||||
auto operator <=> (const Flags &rhs) const {
|
||||
return get() <=> rhs.get();
|
||||
}
|
||||
auto operator == (const Flags &rhs) const {
|
||||
return get() == rhs.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -28,29 +29,61 @@ template <typename ValueT> struct Halves<ValueT, std::endian::big> {
|
||||
|
||||
/// Provides access to all intermediate parts of a larger int.
|
||||
template <typename Full, typename Half> union alignas(Full) alignas(Half) RegisterPair {
|
||||
RegisterPair(Full v) : full(v) {}
|
||||
constexpr RegisterPair(const Full v) noexcept : full(v) {}
|
||||
RegisterPair() = default;
|
||||
|
||||
Full full;
|
||||
auto operator <=>(const RegisterPair &rhs) const {
|
||||
Halves<Half> halves;
|
||||
|
||||
auto operator <=>(const RegisterPair rhs) const {
|
||||
return full <=> rhs.full;
|
||||
}
|
||||
auto operator ==(const RegisterPair &rhs) const {
|
||||
auto operator ==(const RegisterPair rhs) const {
|
||||
return full == rhs.full;
|
||||
}
|
||||
|
||||
Halves<Half> halves;
|
||||
};
|
||||
|
||||
using RegisterPair16 = RegisterPair<uint16_t, uint8_t>;
|
||||
using RegisterPair32 = RegisterPair<uint32_t, RegisterPair16>;
|
||||
|
||||
static_assert(sizeof(RegisterPair32) == 4);
|
||||
static_assert(
|
||||
(
|
||||
std::endian::native == std::endian::little &&
|
||||
offsetof(RegisterPair32, halves.low) == 0 &&
|
||||
offsetof(RegisterPair32, halves.high) == 2
|
||||
) ||
|
||||
(
|
||||
std::endian::native == std::endian::big &&
|
||||
offsetof(RegisterPair32, halves.low) == 2 &&
|
||||
offsetof(RegisterPair32, halves.high) == 0
|
||||
)
|
||||
);
|
||||
|
||||
static_assert(sizeof(RegisterPair16) == 2);
|
||||
static_assert(
|
||||
(
|
||||
std::endian::native == std::endian::little &&
|
||||
offsetof(RegisterPair16, halves.low) == 0 &&
|
||||
offsetof(RegisterPair16, halves.high) == 1
|
||||
) ||
|
||||
(
|
||||
std::endian::native == std::endian::big &&
|
||||
offsetof(RegisterPair16, halves.low) == 1 &&
|
||||
offsetof(RegisterPair16, halves.high) == 0
|
||||
)
|
||||
);
|
||||
|
||||
/// Provides access to lower portions of a larger int.
|
||||
template <typename IntT, std::endian = std::endian::native> union SlicedInt {};
|
||||
|
||||
template <> union SlicedInt<uint16_t, std::endian::little> {
|
||||
uint16_t w;
|
||||
uint8_t b;
|
||||
|
||||
auto operator <=>(const SlicedInt rhs) const {
|
||||
return w <=> rhs.w;
|
||||
}
|
||||
};
|
||||
|
||||
template <> union SlicedInt<uint16_t, std::endian::big> {
|
||||
@@ -59,6 +92,10 @@ template <> union SlicedInt<uint16_t, std::endian::big> {
|
||||
uint8_t __padding[1];
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
auto operator <=>(const SlicedInt rhs) const {
|
||||
return w <=> rhs.w;
|
||||
}
|
||||
};
|
||||
|
||||
template <> union SlicedInt<uint32_t, std::endian::little> {
|
||||
@@ -69,6 +106,10 @@ template <> union SlicedInt<uint32_t, std::endian::little> {
|
||||
struct {
|
||||
SlicedInt<uint16_t> low, high;
|
||||
};
|
||||
|
||||
auto operator <=>(const SlicedInt &rhs) const {
|
||||
return l <=> rhs.l;
|
||||
}
|
||||
};
|
||||
|
||||
template <> union SlicedInt<uint32_t, std::endian::big> {
|
||||
@@ -84,11 +125,41 @@ template <> union SlicedInt<uint32_t, std::endian::big> {
|
||||
struct {
|
||||
SlicedInt<uint16_t> high, low;
|
||||
};
|
||||
|
||||
auto operator <=>(const SlicedInt rhs) const {
|
||||
return l <=> rhs.l;
|
||||
}
|
||||
};
|
||||
|
||||
using SlicedInt16 = SlicedInt<uint16_t>;
|
||||
using SlicedInt32 = SlicedInt<uint32_t>;
|
||||
|
||||
static_assert(sizeof(SlicedInt16) == 2);
|
||||
static_assert(
|
||||
(
|
||||
std::endian::native == std::endian::little &&
|
||||
offsetof(SlicedInt16, b) == 0
|
||||
) ||
|
||||
(
|
||||
std::endian::native == std::endian::big &&
|
||||
offsetof(SlicedInt16, b) == 1
|
||||
)
|
||||
);
|
||||
|
||||
static_assert(sizeof(SlicedInt32) == 4);
|
||||
static_assert(
|
||||
(
|
||||
std::endian::native == std::endian::little &&
|
||||
offsetof(SlicedInt16, b) == 0 &&
|
||||
offsetof(SlicedInt16, w) == 0
|
||||
) ||
|
||||
(
|
||||
std::endian::native == std::endian::big &&
|
||||
offsetof(SlicedInt16, b) == 3 &&
|
||||
offsetof(SlicedInt16, w) == 2
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#pragma pack(pop)
|
||||
+58
-48
@@ -21,18 +21,24 @@ namespace Storage {
|
||||
*/
|
||||
struct Time {
|
||||
unsigned int length, clock_rate;
|
||||
constexpr Time() : length(0), clock_rate(1) {}
|
||||
constexpr Time(unsigned int unsigned_int_value) : length(unsigned_int_value), clock_rate(1) {}
|
||||
constexpr Time(int int_value) : Time(unsigned(int_value)) {}
|
||||
constexpr Time(unsigned int length, unsigned int clock_rate) : length(length), clock_rate(clock_rate) {}
|
||||
constexpr Time(int length, int clock_rate) : Time(unsigned(length), unsigned(clock_rate)) {}
|
||||
Time(uint64_t length, uint64_t clock_rate) {
|
||||
constexpr Time() noexcept : length(0), clock_rate(1) {}
|
||||
|
||||
template <std::integral IntT>
|
||||
requires (sizeof(IntT) <= sizeof(int))
|
||||
constexpr Time(const IntT value) noexcept : length(unsigned(value)), clock_rate(1) {}
|
||||
|
||||
template <std::integral IntT>
|
||||
requires (sizeof(IntT) <= sizeof(int))
|
||||
constexpr Time(const IntT length, const IntT clock_rate) noexcept :
|
||||
length(unsigned(length)), clock_rate(unsigned(clock_rate)) {}
|
||||
|
||||
Time(const uint64_t length, const uint64_t clock_rate) noexcept {
|
||||
install_result(length, clock_rate);
|
||||
}
|
||||
Time(float value) {
|
||||
Time(const float value) noexcept {
|
||||
install_float(value);
|
||||
}
|
||||
static constexpr Time simplified(unsigned int _length, unsigned int _clock_rate) {
|
||||
static constexpr Time simplified(const unsigned int _length, const unsigned int _clock_rate) {
|
||||
const auto gcd = std::gcd(_length, _clock_rate);
|
||||
return Time(_length / gcd, _clock_rate / gcd);
|
||||
}
|
||||
@@ -54,27 +60,15 @@ struct Time {
|
||||
return T(length) / T(clock_rate);
|
||||
}
|
||||
|
||||
inline bool operator < (const Time &other) const {
|
||||
return uint64_t(other.clock_rate) * uint64_t(length) < uint64_t(clock_rate) * uint64_t(other.length);
|
||||
auto operator <=> (const Time &rhs) const {
|
||||
return uint64_t(rhs.clock_rate) * uint64_t(length) <=> uint64_t(clock_rate) * uint64_t(rhs.length);
|
||||
}
|
||||
|
||||
inline bool operator <= (const Time &other) const {
|
||||
return uint64_t(other.clock_rate) * uint64_t(length) <= uint64_t(clock_rate) * uint64_t(other.length);
|
||||
auto operator == (const Time &rhs) const {
|
||||
return *this <=> rhs == std::strong_ordering::equal;
|
||||
}
|
||||
|
||||
inline bool operator > (const Time &other) const {
|
||||
return uint64_t(other.clock_rate) * uint64_t(length) > uint64_t(clock_rate) * uint64_t(other.length);
|
||||
}
|
||||
|
||||
inline bool operator >= (const Time &other) const {
|
||||
return uint64_t(other.clock_rate) * uint64_t(length) >= uint64_t(clock_rate) * uint64_t(other.length);
|
||||
}
|
||||
|
||||
inline bool operator == (const Time &other) const {
|
||||
return uint64_t(other.clock_rate) * uint64_t(length) == uint64_t(clock_rate) * uint64_t(other.length);
|
||||
}
|
||||
|
||||
inline Time operator + (const Time &other) const {
|
||||
Time operator + (const Time &other) const {
|
||||
if(!other.length) return *this;
|
||||
|
||||
uint64_t result_length;
|
||||
@@ -83,13 +77,14 @@ struct Time {
|
||||
result_length = uint64_t(length) + uint64_t(other.length);
|
||||
result_clock_rate = clock_rate;
|
||||
} else {
|
||||
result_length = uint64_t(length) * uint64_t(other.clock_rate) + uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_length =
|
||||
uint64_t(length) * uint64_t(other.clock_rate) + uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
}
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time &operator += (const Time &other) {
|
||||
Time &operator += (const Time &other) {
|
||||
if(!other.length) return *this;
|
||||
if(!length) {
|
||||
*this = other;
|
||||
@@ -102,14 +97,15 @@ struct Time {
|
||||
result_length = uint64_t(length) + uint64_t(other.length);
|
||||
result_clock_rate = uint64_t(clock_rate);
|
||||
} else {
|
||||
result_length = uint64_t(length) * uint64_t(other.clock_rate) + uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_length =
|
||||
uint64_t(length) * uint64_t(other.clock_rate) + uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
}
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Time operator - (const Time &other) const {
|
||||
Time operator - (const Time &other) const {
|
||||
if(!other.length) return *this;
|
||||
|
||||
uint64_t result_length;
|
||||
@@ -118,13 +114,14 @@ struct Time {
|
||||
result_length = uint64_t(length) - uint64_t(other.length);
|
||||
result_clock_rate = clock_rate;
|
||||
} else {
|
||||
result_length = uint64_t(length) * uint64_t(other.clock_rate) - uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_length =
|
||||
uint64_t(length) * uint64_t(other.clock_rate) - uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
}
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time operator -= (const Time &other) {
|
||||
Time operator -= (const Time &other) {
|
||||
if(!other.length) return *this;
|
||||
|
||||
uint64_t result_length;
|
||||
@@ -133,71 +130,72 @@ struct Time {
|
||||
result_length = uint64_t(length) - uint64_t(other.length);
|
||||
result_clock_rate = uint64_t(clock_rate);
|
||||
} else {
|
||||
result_length = uint64_t(length) * uint64_t(other.clock_rate) - uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_length =
|
||||
uint64_t(length) * uint64_t(other.clock_rate) - uint64_t(other.length) * uint64_t(clock_rate);
|
||||
result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
}
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Time operator * (const Time &other) const {
|
||||
Time operator * (const Time &other) const {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(other.length);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time &operator *= (const Time &other) {
|
||||
Time &operator *= (const Time &other) {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(other.length);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(other.clock_rate);
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Time operator * (unsigned int multiplier) const {
|
||||
Time operator * (unsigned int multiplier) const {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(multiplier);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate);
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time &operator *= (unsigned int multiplier) {
|
||||
Time &operator *= (unsigned int multiplier) {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(multiplier);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate);
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Time operator / (const Time &other) const {
|
||||
Time operator / (const Time &other) const {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(other.clock_rate);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(other.length);
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time &operator /= (const Time &other) {
|
||||
Time &operator /= (const Time &other) {
|
||||
uint64_t result_length = uint64_t(length) * uint64_t(other.clock_rate);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(other.length);
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Time operator / (unsigned int divisor) const {
|
||||
Time operator / (unsigned int divisor) const {
|
||||
uint64_t result_length = uint64_t(length);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(divisor);
|
||||
return Time(result_length, result_clock_rate);
|
||||
}
|
||||
|
||||
inline Time &operator /= (unsigned int divisor) {
|
||||
Time &operator /= (unsigned int divisor) {
|
||||
uint64_t result_length = uint64_t(length);
|
||||
uint64_t result_clock_rate = uint64_t(clock_rate) * uint64_t(divisor);
|
||||
install_result(result_length, result_clock_rate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void set_zero() {
|
||||
void set_zero() {
|
||||
length = 0;
|
||||
clock_rate = 1;
|
||||
}
|
||||
|
||||
inline void set_one() {
|
||||
void set_one() {
|
||||
length = 1;
|
||||
clock_rate = 1;
|
||||
}
|
||||
@@ -207,8 +205,11 @@ struct Time {
|
||||
}
|
||||
|
||||
private:
|
||||
inline void install_result(uint64_t long_length, uint64_t long_clock_rate) {
|
||||
if(long_length <= std::numeric_limits<unsigned int>::max() && long_clock_rate <= std::numeric_limits<unsigned int>::max()) {
|
||||
void install_result(uint64_t long_length, uint64_t long_clock_rate) {
|
||||
if(
|
||||
long_length <= std::numeric_limits<unsigned int>::max() &&
|
||||
long_clock_rate <= std::numeric_limits<unsigned int>::max()
|
||||
) {
|
||||
length = unsigned(long_length);
|
||||
clock_rate = unsigned(long_clock_rate);
|
||||
return;
|
||||
@@ -231,21 +232,30 @@ private:
|
||||
long_clock_rate >>= 1;
|
||||
}
|
||||
|
||||
if(long_length > std::numeric_limits<unsigned int>::max() || long_clock_rate > std::numeric_limits<unsigned int>::max()) {
|
||||
if(
|
||||
long_length > std::numeric_limits<unsigned int>::max() ||
|
||||
long_clock_rate > std::numeric_limits<unsigned int>::max()
|
||||
) {
|
||||
uint64_t common_divisor = std::gcd(long_length, long_clock_rate);
|
||||
long_length /= common_divisor;
|
||||
long_clock_rate /= common_divisor;
|
||||
|
||||
// Okay, in desperation accept a loss of accuracy.
|
||||
while(
|
||||
(long_length > std::numeric_limits<unsigned int>::max() || long_clock_rate > std::numeric_limits<unsigned int>::max()) &&
|
||||
(
|
||||
long_length > std::numeric_limits<unsigned int>::max() ||
|
||||
long_clock_rate > std::numeric_limits<unsigned int>::max()
|
||||
) &&
|
||||
(long_clock_rate > 1)) {
|
||||
long_length >>= 1;
|
||||
long_clock_rate >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(long_length <= std::numeric_limits<unsigned int>::max() && long_clock_rate <= std::numeric_limits<unsigned int>::max()) {
|
||||
if(
|
||||
long_length <= std::numeric_limits<unsigned int>::max() &&
|
||||
long_clock_rate <= std::numeric_limits<unsigned int>::max()
|
||||
) {
|
||||
length = unsigned(long_length);
|
||||
clock_rate = unsigned(long_clock_rate);
|
||||
} else {
|
||||
@@ -254,7 +264,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
inline void install_float(float value) {
|
||||
void install_float(const float value) {
|
||||
// Grab the float's native mantissa and exponent.
|
||||
int exponent;
|
||||
const float mantissa = frexpf(value, &exponent);
|
||||
|
||||
Reference in new issue
Block a user