То, что хочет ОП (или что-то подобное), может быть достигнуто с помощью вложенных struct
с.
Ради интереса я попытался смоделировать то, что предполагал ОП:
#include <bitset>
struct Registers
{
int8_t A;
int8_t X;
int8_t Y;
uint8_t SP;
static constexpr uint8_t PSSize = 8;
struct PS: std::bitset<PSSize> {
enum Flags {
Carry = 0,
Zero = 1,
InterruptDisable = 2,
Decimal = 3,
Break = 4,
Unknown = 5,
Overflow = 6,
Negative = 7
};
static constexpr unsigned Size = PSSize;
constexpr PS(std::uint8_t value):
std::bitset<PSSize>((unsigned long long)value)
{ }
std::uint8_t value() const { return (std::uint8_t)to_ulong(); }
} PS;
uint16_t PC;
constexpr Registers() noexcept :
A(0),
X(0),
Y(0),
SP(0xFF),
PS(0x24),//PS(0b00100100),
PC(0)
{
}
} r;
Aнебольшой тест, чтобы показать это в действии:
#include <iomanip>
#include <iostream>
#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__
int main()
{
std::cout << std::hex << std::setfill('0');
DEBUG(std::cout << Registers::PS::Flags::Carry << '\n');
DEBUG(std::cout << r.PS[Registers::PS::Flags::Carry] << '\n');
DEBUG(std::cout << Registers::PS::Flags::InterruptDisable << '\n');
DEBUG(std::cout << r.PS[Registers::PS::Flags::InterruptDisable] << '\n');
DEBUG(std::cout << Registers::PS::Flags::Break << '\n');
DEBUG(std::cout << r.PS[Registers::PS::Flags::Break] << '\n');
DEBUG(std::cout << Registers::PS::Size << '\n');
DEBUG(std::cout << "0x" << std::setw(2) << (unsigned)r.PS.value() << '\n');
// done
return 0;
}
Вывод:
std::cout << Registers::PS::Flags::Carry << '\n';
0
std::cout << r.PS[Registers::PS::Flags::Carry] << '\n';
0
std::cout << Registers::PS::Flags::InterruptDisable << '\n';
2
std::cout << r.PS[Registers::PS::Flags::InterruptDisable] << '\n';
1
std::cout << Registers::PS::Flags::Break << '\n';
4
std::cout << r.PS[Registers::PS::Flags::Break] << '\n';
0
std::cout << Registers::PS::Size << '\n';
8
std::cout << "0x" << std::setw(2) << (unsigned)r.PS.value() << '\n';
0x24
Примечание:
Об именовании вложенной структуры Registers::PS
и член Registers::PS
с тем же именем я ожидал работать.Хотя обычно я использую начальный символ в верхнем регистре для идентификаторов типов и начальные символы в нижнем регистре для переменных.Следовательно, у меня обычно нет этой проблемы.
Поскольку у меня возникли сомнения по этому поводу, я протестировал struct Registers
на разных компиляторах (хотя я бы не посчитал это доказательством по отношению к стандарту): Compiler Explorer
Извлечение из std::
контейнеров должно выполняться с осторожностью (то есть лучше не делать).Вероятно, из соображений производительности ни один из контейнеров std::
не предоставляет деструктора virtual
с соответствующими последствиями.В приведенном выше коде это не должно быть проблемой.
6502 напомнил мне о Commodore 64 , где я сделал свои первые попытки (хотяC64 имел еще более современный процессор 6510 .Однако, это очень давно ...; -)