mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
101 lines
3.2 KiB
C++
101 lines
3.2 KiB
C++
#ifndef INCLUDED_UTIL_BITREGISTER_H
|
|
#define INCLUDED_UTIL_BITREGISTER_H
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <ostream>
|
|
|
|
namespace Util
|
|
{
|
|
class BitRegister
|
|
{
|
|
public:
|
|
inline bool Empty() const
|
|
{
|
|
return m_bits.empty();
|
|
}
|
|
|
|
inline size_t Size() const
|
|
{
|
|
return m_bits.size();
|
|
}
|
|
|
|
// Functions that return all or part of the bit register as an integer
|
|
uint8_t GetBit(size_t pos) const;
|
|
uint64_t GetBits() const;
|
|
uint64_t GetBits(size_t from, size_t count) const;
|
|
|
|
// Functions that grow/shrink the bit register
|
|
void AddToRight(uint8_t bit);
|
|
void AddToLeft(uint8_t bit);
|
|
uint8_t RemoveFromLeft();
|
|
void RemoveFromLeft(size_t count);
|
|
uint8_t RemoveFromRight();
|
|
void RemoveFromRight(size_t count);
|
|
|
|
// Functions that preserve the current register size, shifting in the "no
|
|
// data" value as needed
|
|
void ShiftRight(size_t count);
|
|
void ShiftLeft(size_t count);
|
|
|
|
// Functions that preserve the register size, shifting a bit in one side
|
|
// and ejecting one out the other
|
|
uint8_t ShiftOutRight(uint8_t bit);
|
|
uint8_t ShiftOutLeft(uint8_t bit);
|
|
|
|
// Functions that insert bits, clipped against current register size
|
|
void SetBit(size_t bitPos, uint8_t value);
|
|
void Insert(size_t bitPos, const std::string &value);
|
|
|
|
// Functions that reset the contents but not the size of the register
|
|
void SetZeros();
|
|
void SetOnes();
|
|
|
|
// Functions that reset the contents (and size) of the register
|
|
void Set(const std::string &value);
|
|
void SetZeros(size_t count);
|
|
void SetOnes(size_t count);
|
|
void Reset();
|
|
|
|
// Configuration state
|
|
void SetNoBitValue(uint8_t bit);
|
|
|
|
// String serialization
|
|
std::string ToBinaryString() const;
|
|
std::string ToHexString() const;
|
|
friend std::ostream &operator<<(std::ostream &os, const BitRegister ®);
|
|
|
|
// Constructors
|
|
BitRegister();
|
|
BitRegister(size_t count);
|
|
BitRegister(size_t count, uint8_t bit);
|
|
|
|
private:
|
|
/*
|
|
* Vector layout:
|
|
*
|
|
* Index: 0 1 2 3 ... N
|
|
* +---+---+---+---+-...-+---+
|
|
* <-- left -- | 1 | 0 | 1 | 1 | ... | 1 | -- right -->
|
|
* +---+---+---+---+-...-+---+
|
|
*
|
|
* "Left" means lower indices in the array and bits are numbered left to
|
|
* right (leftmost bit is bit 0). Insertions of values into the bit vector
|
|
* place the MSB in a lower bit number than successive bits. For example,
|
|
* insertion of the 8-bit value 0xe2 at bit position 2 places the MSB (1)
|
|
* in bit 2, 0 in bit 3, 1 in bit 4, 0 in bit 5, etc.
|
|
*/
|
|
std::vector<uint8_t> m_bits;
|
|
uint8_t m_no_data = 0; // by default, assume non-existent bits are 0
|
|
|
|
uint8_t GetLeftmost() const;
|
|
uint8_t GetRightmost() const;
|
|
static size_t HexStart(const std::string &value);
|
|
static size_t BinStart(const std::string &value);
|
|
static size_t CountBitsHex(const std::string &value, size_t startPos);
|
|
static size_t CountBitsBin(const std::string &value, size_t startPos);
|
|
};
|
|
} // Util
|
|
|
|
#endif // INCLUDED_UTIL_BITREGISTER_H
|