Improve compatibility with .net emulator code.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-11-09 18:58:23 +00:00
parent 20ebbd4048
commit d0467421ff
18 changed files with 572 additions and 555 deletions

View File

@ -135,11 +135,11 @@ namespace EightBit {
}
static void adjustAuxiliaryCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
setFlag(f, AC, calculateHalfCarryAdd(before, value, calculation));
f = setBit(f, AC, calculateHalfCarryAdd(before, value, calculation));
}
static void adjustAuxiliaryCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
clearFlag(f, AC, calculateHalfCarrySub(before, value, calculation));
f = clearBit(f, AC, calculateHalfCarrySub(before, value, calculation));
}
void subtract(uint8_t& operand, uint8_t value, int carry = 0);

View File

@ -36,7 +36,6 @@ void EightBit::Intel8080::handleINT() {
di();
Processor::execute(BUS().DATA());
}
tick(3);
}
void EightBit::Intel8080::di() {
@ -48,13 +47,13 @@ void EightBit::Intel8080::ei() {
}
void EightBit::Intel8080::increment(uint8_t& operand) {
adjustSZP<Intel8080>(F(), ++operand);
clearFlag(F(), AC, lowNibble(operand));
F() = adjustSZP<Intel8080>(F(), ++operand);
F() = clearBit(F(), AC, lowNibble(operand));
}
void EightBit::Intel8080::decrement(uint8_t& operand) {
adjustSZP<Intel8080>(F(), --operand);
setFlag(F(), AC, lowNibble(operand) != Mask4);
F() = adjustSZP<Intel8080>(F(), --operand);
F() = setBit(F(), AC, lowNibble(operand) != Mask4);
}
bool EightBit::Intel8080::jumpConditionalFlag(const int flag) {
@ -129,7 +128,7 @@ bool EightBit::Intel8080::callConditionalFlag(const int flag) {
void EightBit::Intel8080::add(const register16_t value) {
const auto result = HL().word + value.word;
HL() = result;
setFlag(F(), CF, result & Bit16);
F() = setBit(F(), CF, result & Bit16);
}
void EightBit::Intel8080::add(const uint8_t value, const int carry) {
@ -140,8 +139,8 @@ void EightBit::Intel8080::add(const uint8_t value, const int carry) {
A() = result.low;
setFlag(F(), CF, result.word & Bit8);
adjustSZP<Intel8080>(F(), A());
F() = setBit(F(), CF, result.word & Bit8);
F() = adjustSZP<Intel8080>(F(), A());
}
void EightBit::Intel8080::adc(const uint8_t value) {
@ -156,8 +155,8 @@ void EightBit::Intel8080::subtract(uint8_t& operand, const uint8_t value, const
operand = result.low;
setFlag(F(), CF, result.word & Bit8);
adjustSZP<Intel8080>(F(), operand);
F() = setBit(F(), CF, result.word & Bit8);
F() = adjustSZP<Intel8080>(F(), operand);
}
void EightBit::Intel8080::sbb(const uint8_t value) {
@ -165,19 +164,19 @@ void EightBit::Intel8080::sbb(const uint8_t value) {
}
void EightBit::Intel8080::andr(const uint8_t value) {
setFlag(F(), AC, (A() | value) & Bit3);
clearFlag(F(), CF);
adjustSZP<Intel8080>(F(), A() &= value);
F() = setBit(F(), AC, (A() | value) & Bit3);
F() = clearBit(F(), CF);
F() = adjustSZP<Intel8080>(F(), A() &= value);
}
void EightBit::Intel8080::xorr(const uint8_t value) {
clearFlag(F(), AC | CF);
adjustSZP<Intel8080>(F(), A() ^= value);
F() = clearBit(F(), AC | CF);
F() = adjustSZP<Intel8080>(F(), A() ^= value);
}
void EightBit::Intel8080::orr(const uint8_t value) {
clearFlag(F(), AC | CF);
adjustSZP<Intel8080>(F(), A() |= value);
F() = clearBit(F(), AC | CF);
F() = adjustSZP<Intel8080>(F(), A() |= value);
}
void EightBit::Intel8080::compare(const uint8_t value) {
@ -188,24 +187,24 @@ void EightBit::Intel8080::compare(const uint8_t value) {
void EightBit::Intel8080::rlc() {
const auto carry = A() & Bit7;
A() = (A() << 1) | (carry >> 7);
setFlag(F(), CF, carry);
F() = setBit(F(), CF, carry);
}
void EightBit::Intel8080::rrc() {
const auto carry = A() & Bit0;
A() = (A() >> 1) | (carry << 7);
setFlag(F(), CF, carry);
F() = setBit(F(), CF, carry);
}
void EightBit::Intel8080::rl() {
const auto carry = F() & CF;
setFlag(F(), CF, A() & Bit7);
F() = setBit(F(), CF, A() & Bit7);
A() = (A() << 1) | carry;
}
void EightBit::Intel8080::rr() {
const auto carry = F() & CF;
setFlag(F(), CF, A() & Bit0);
F() = setBit(F(), CF, A() & Bit0);
A() = (A() >> 1) | (carry << 7);
}
@ -221,7 +220,7 @@ void EightBit::Intel8080::daa() {
carry = true;
}
add(addition);
setFlag(F(), CF, carry);
F() = setBit(F(), CF, carry);
}
void EightBit::Intel8080::cma() {
@ -229,11 +228,11 @@ void EightBit::Intel8080::cma() {
}
void EightBit::Intel8080::stc() {
setFlag(F(), CF);
F() = setBit(F(), CF);
}
void EightBit::Intel8080::cmc() {
clearFlag(F(), CF, F() & CF);
F() = clearBit(F(), CF, F() & CF);
}
void EightBit::Intel8080::xhtl(register16_t& exchange) {

View File

@ -150,11 +150,11 @@ namespace EightBit {
}
void adjustHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
setFlag(F(), HC, calculateHalfCarryAdd(before, value, calculation));
F() = setBit(F(), HC, calculateHalfCarryAdd(before, value, calculation));
}
void adjustHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
setFlag(F(), HC, calculateHalfCarrySub(before, value, calculation));
F() = setBit(F(), HC, calculateHalfCarrySub(before, value, calculation));
}
void subtract(uint8_t& operand, uint8_t value, int carry = 0);

View File

@ -19,7 +19,7 @@ std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) {
for (int bit = 0; bit < 8; ++bit) {
const auto mask = 1 << bit;
const auto mask = Chip::bit(bit);
const auto bitLow = planeLow & mask ? 1 : 0;
const auto bitHigh = planeHigh & mask ? 0b10 : 0;

View File

@ -125,7 +125,7 @@ void EightBit::GameBoy::Bus::validateCartridgeType() {
default:
if (romSizeSpecification > 6)
throw std::domain_error("Invalid ROM size specification");
gameRomBanks = 1 << (romSizeSpecification + 1);
gameRomBanks = Chip::bit(romSizeSpecification + 1);
if (gameRomBanks != m_gameRomBanks.size())
throw std::domain_error("ROM size specification mismatch");
}

View File

@ -50,15 +50,15 @@ void EightBit::GameBoy::LR35902::ei() {
}
void EightBit::GameBoy::LR35902::increment(uint8_t& operand) {
clearFlag(F(), NF);
adjustZero<LR35902>(F(), ++operand);
clearFlag(F(), HC, lowNibble(operand));
F() = clearBit(F(), NF);
F() = adjustZero<LR35902>(F(), ++operand);
F() = clearBit(F(), HC, lowNibble(operand));
}
void EightBit::GameBoy::LR35902::decrement(uint8_t& operand) {
setFlag(F(), NF);
clearFlag(F(), HC, lowNibble(operand));
adjustZero<LR35902>(F(), --operand);
F() = setBit(F(), NF);
F() = clearBit(F(), HC, lowNibble(operand));
F() = adjustZero<LR35902>(F(), --operand);
}
bool EightBit::GameBoy::LR35902::jrConditionalFlag(const int flag) {
@ -134,8 +134,8 @@ void EightBit::GameBoy::LR35902::add(register16_t& operand, const register16_t v
operand.word = result;
clearFlag(F(), NF);
setFlag(F(), CF, result & Bit16);
F() = clearBit(F(), NF);
F() = setBit(F(), CF, result & Bit16);
adjustHalfCarryAdd(MEMPTR().high, value.high, operand.high);
}
@ -147,9 +147,9 @@ void EightBit::GameBoy::LR35902::add(uint8_t& operand, const uint8_t value, cons
operand = result.low;
clearFlag(F(), NF);
setFlag(F(), CF, result.word & Bit8);
adjustZero<LR35902>(F(), operand);
F() = clearBit(F(), NF);
F() = setBit(F(), CF, result.word & Bit8);
F() = adjustZero<LR35902>(F(), operand);
}
void EightBit::GameBoy::LR35902::adc(uint8_t& operand, const uint8_t value) {
@ -164,9 +164,9 @@ void EightBit::GameBoy::LR35902::subtract(uint8_t& operand, const uint8_t value,
operand = result.low;
setFlag(F(), NF);
setFlag(F(), CF, result.word & Bit8);
adjustZero<LR35902>(F(), operand);
F() = setBit(F(), NF);
F() = setBit(F(), CF, result.word & Bit8);
F() = adjustZero<LR35902>(F(), operand);
}
void EightBit::GameBoy::LR35902::sbc(const uint8_t value) {
@ -174,19 +174,19 @@ void EightBit::GameBoy::LR35902::sbc(const uint8_t value) {
}
void EightBit::GameBoy::LR35902::andr(uint8_t& operand, const uint8_t value) {
setFlag(F(), HC);
clearFlag(F(), CF | NF);
adjustZero<LR35902>(F(), operand &= value);
F() = setBit(F(), HC);
F() = clearBit(F(), CF | NF);
F() = adjustZero<LR35902>(F(), operand &= value);
}
void EightBit::GameBoy::LR35902::xorr(const uint8_t value) {
clearFlag(F(), HC | CF | NF);
adjustZero<LR35902>(F(), A() ^= value);
F() = clearBit(F(), HC | CF | NF);
F() = adjustZero<LR35902>(F(), A() ^= value);
}
void EightBit::GameBoy::LR35902::orr(const uint8_t value) {
clearFlag(F(), HC | CF | NF);
adjustZero<LR35902>(F(), A() |= value);
F() = clearBit(F(), HC | CF | NF);
F() = adjustZero<LR35902>(F(), A() |= value);
}
void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) {
@ -194,69 +194,69 @@ void EightBit::GameBoy::LR35902::compare(uint8_t check, const uint8_t value) {
}
uint8_t EightBit::GameBoy::LR35902::rlc(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
F() = clearBit(F(), NF | HC | ZF);
const auto carry = operand & Bit7;
setFlag(F(), CF, carry);
F() = setBit(F(), CF, carry);
return (operand << 1) | (carry >> 7);
}
uint8_t EightBit::GameBoy::LR35902::rrc(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
F() = clearBit(F(), NF | HC | ZF);
const auto carry = operand & Bit0;
setFlag(F(), CF, carry);
F() = setBit(F(), CF, carry);
return (operand >> 1) | (carry << 7);
}
uint8_t EightBit::GameBoy::LR35902::rl(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
F() = clearBit(F(), NF | HC | ZF);
const auto carry = F() & CF;
setFlag(F(), CF, operand & Bit7);
F() = setBit(F(), CF, operand & Bit7);
return (operand << 1) | (carry >> 4); // CF at Bit4
}
uint8_t EightBit::GameBoy::LR35902::rr(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
F() = clearBit(F(), NF | HC | ZF);
const auto carry = F() & CF;
setFlag(F(), CF, operand & Bit0);
F() = setBit(F(), CF, operand & Bit0);
return (operand >> 1) | (carry << 3); // CF at Bit4
}
uint8_t EightBit::GameBoy::LR35902::sla(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
setFlag(F(), CF, operand & Bit7);
F() = clearBit(F(), NF | HC | ZF);
F() = setBit(F(), CF, operand & Bit7);
return operand << 1;
}
uint8_t EightBit::GameBoy::LR35902::sra(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
setFlag(F(), CF, operand & Bit0);
F() = clearBit(F(), NF | HC | ZF);
F() = setBit(F(), CF, operand & Bit0);
return (operand >> 1) | (operand & Bit7);
}
uint8_t EightBit::GameBoy::LR35902::swap(const uint8_t operand) {
clearFlag(F(), NF | HC | CF);
F() = clearBit(F(), NF | HC | CF);
return promoteNibble(operand) | demoteNibble(operand);
}
uint8_t EightBit::GameBoy::LR35902::srl(const uint8_t operand) {
clearFlag(F(), NF | HC | ZF);
setFlag(F(), CF, operand & Bit0);
F() = clearBit(F(), NF | HC | ZF);
F() = setBit(F(), CF, operand & Bit0);
return (operand >> 1) & ~Bit7;
}
void EightBit::GameBoy::LR35902::bit(const int n, const uint8_t operand) {
const auto carry = F() & CF;
uint8_t discarded = operand;
andr(discarded, 1 << n);
setFlag(F(), CF, carry);
andr(discarded, Chip::bit(n));
F() = setBit(F(), CF, carry);
}
uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) {
return operand & ~(1 << n);
return operand & ~Chip::bit(n);
}
uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) {
return operand | (1 << n);
return operand | Chip::bit(n);
}
void EightBit::GameBoy::LR35902::daa() {
@ -275,26 +275,26 @@ void EightBit::GameBoy::LR35902::daa() {
updated += 0x60;
}
clearFlag(F(), HC | ZF);
setFlag(F(), CF, (F() & CF) || (updated & Bit8));
F() = clearBit(F(), HC | ZF);
F() = setBit(F(), CF, (F() & CF) || (updated & Bit8));
A() = updated & Mask8;
adjustZero<LR35902>(F(), A());
F() = adjustZero<LR35902>(F(), A());
}
void EightBit::GameBoy::LR35902::cpl() {
setFlag(F(), HC | NF);
F() = setBit(F(), HC | NF);
A() = ~A();
}
void EightBit::GameBoy::LR35902::scf() {
setFlag(F(), CF);
clearFlag(F(), HC | NF);
F() = setBit(F(), CF);
F() = clearBit(F(), HC | NF);
}
void EightBit::GameBoy::LR35902::ccf() {
clearFlag(F(), NF | HC);
clearFlag(F(), CF, F() & CF);
F() = clearBit(F(), NF | HC);
F() = clearBit(F(), CF, F() & CF);
}
int EightBit::GameBoy::LR35902::step() {
@ -393,7 +393,7 @@ void EightBit::GameBoy::LR35902::executeCB(const int x, const int y, const int z
}
tick(2);
R(z, operand);
adjustZero<LR35902>(F(), operand);
F() = adjustZero<LR35902>(F(), operand);
if (UNLIKELY(z == 6))
tick(2);
break;
@ -651,9 +651,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
const auto result = before + value;
SP() = result;
const auto carried = before ^ value ^ (result & Mask16);
clearFlag(F(), ZF | NF);
setFlag(F(), CF, carried & Bit8);
setFlag(F(), HC, carried & Bit4);
F() = clearBit(F(), ZF | NF);
F() = setBit(F(), CF, carried & Bit8);
F() = setBit(F(), HC, carried & Bit4);
}
tick(4);
break;
@ -667,9 +667,9 @@ void EightBit::GameBoy::LR35902::executeOther(const int x, const int y, const in
const auto result = before + value;
HL() = result;
const auto carried = before ^ value ^ (result & Mask16);
clearFlag(F(), ZF | NF);
setFlag(F(), CF, carried & Bit8);
setFlag(F(), HC, carried & Bit4);
F() = clearBit(F(), ZF | NF);
F() = setBit(F(), CF, carried & Bit8);
F() = setBit(F(), HC, carried & Bit4);
}
tick(3);
break;

View File

@ -97,12 +97,12 @@ namespace EightBit {
// Addressing modes, read
enum PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice };
enum class PageCrossingBehavior { AlwaysReadTwice, MaybeReadTwice };
uint8_t AM_Immediate();
uint8_t AM_Absolute();
uint8_t AM_ZeroPage();
uint8_t AM_AbsoluteX(PageCrossingBehavior behaviour = MaybeReadTwice);
uint8_t AM_AbsoluteX(PageCrossingBehavior behaviour = PageCrossingBehavior::MaybeReadTwice);
uint8_t AM_AbsoluteY();
uint8_t AM_ZeroPageX();
uint8_t AM_ZeroPageY();
@ -111,8 +111,8 @@ namespace EightBit {
// Flag adjustment
void adjustZero(const uint8_t datum) { clearFlag(P(), ZF, datum); }
void adjustNegative(const uint8_t datum) { setFlag(P(), NF, datum & NF); }
void adjustZero(const uint8_t datum) { P() = clearBit(P(), ZF, datum); }
void adjustNegative(const uint8_t datum) { P() = setBit(P(), NF, datum & NF); }
void adjustNZ(const uint8_t datum) {
adjustZero(datum);

View File

@ -84,7 +84,7 @@ void EightBit::MOS6502::interrupt() {
pushWord(PC());
push(P() | (software ? BF : 0));
}
setFlag(P(), IF); // Disable IRQ
P() = setBit(P(), IF); // Disable IRQ
const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector);
jump(getWordPaged(0xff, vector));
m_handlingRESET = m_handlingNMI = m_handlingINT = false;
@ -137,13 +137,13 @@ int EightBit::MOS6502::execute() {
case 0x15: A() = orr(A(), AM_ZeroPageX()); break; // ORA (zero page, X)
case 0x16: busReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (zero page, X)
case 0x17: slo(AM_ZeroPageX()); break; // *SLO (zero page, X)
case 0x18: busRead(); clearFlag(P(), CF); break; // CLC (implied)
case 0x18: busRead(); P() = clearBit(P(), CF); break; // CLC (implied)
case 0x19: A() = orr(A(), AM_AbsoluteY()); break; // ORA (absolute, Y)
case 0x1a: busRead(); break; // *NOP (implied)
case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y)
case 0x1c: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0x1d: A() = orr(A(), AM_AbsoluteX()); break; // ORA (absolute, X)
case 0x1e: busReadModifyWrite(asl(AM_AbsoluteX(AlwaysReadTwice))); break; // ASL (absolute, X)
case 0x1e: busReadModifyWrite(asl(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ASL (absolute, X)
case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X)
case 0x20: jsr(); break; // JSR (absolute)
@ -171,13 +171,13 @@ int EightBit::MOS6502::execute() {
case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X)
case 0x36: busReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (zero page, X)
case 0x37: rla(AM_ZeroPageX()); break; // *RLA (zero page, X)
case 0x38: busRead(); setFlag(P(), CF); break; // SEC (implied)
case 0x38: busRead(); P() = setBit(P(), CF); break; // SEC (implied)
case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y)
case 0x3a: busRead(); break; // *NOP (implied)
case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y)
case 0x3c: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X)
case 0x3e: busReadModifyWrite(rol(AM_AbsoluteX(AlwaysReadTwice))); break; // ROL (absolute, X)
case 0x3e: busReadModifyWrite(rol(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROL (absolute, X)
case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X)
case 0x40: busRead(); rti(); break; // RTI (implied)
@ -205,13 +205,13 @@ int EightBit::MOS6502::execute() {
case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X)
case 0x56: busReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (zero page, X)
case 0x57: sre(AM_ZeroPageX()); break; // *SRE (zero page, X)
case 0x58: busRead(); clearFlag(P(), IF); break; // CLI (implied)
case 0x58: busRead(); P() = clearBit(P(), IF); break; // CLI (implied)
case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y)
case 0x5a: busRead(); break; // *NOP (implied)
case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y)
case 0x5c: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X)
case 0x5e: busReadModifyWrite(lsr(AM_AbsoluteX(AlwaysReadTwice))); break; // LSR (absolute, X)
case 0x5e: busReadModifyWrite(lsr(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // LSR (absolute, X)
case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X)
case 0x60: busRead(); rts(); break; // RTS (implied)
@ -239,13 +239,13 @@ int EightBit::MOS6502::execute() {
case 0x75: A() = adc(A(), AM_ZeroPageX()); break; // ADC (zero page, X)
case 0x76: busReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (zero page, X)
case 0x77: rra(AM_ZeroPageX()); break; // *RRA (zero page, X)
case 0x78: busRead(); setFlag(P(), IF); break; // SEI (implied)
case 0x78: busRead(); P() = setBit(P(), IF); break; // SEI (implied)
case 0x79: A() = adc(A(), AM_AbsoluteY()); break; // ADC (absolute, Y)
case 0x7a: busRead(); break; // *NOP (implied)
case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y)
case 0x7c: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0x7d: A() = adc(A(), AM_AbsoluteX()); break; // ADC (absolute, X)
case 0x7e: busReadModifyWrite(ror(AM_AbsoluteX(AlwaysReadTwice))); break; // ROR (absolute, X)
case 0x7e: busReadModifyWrite(ror(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROR (absolute, X)
case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X)
case 0x80: AM_Immediate(); break; // *NOP (immediate)
@ -307,7 +307,7 @@ int EightBit::MOS6502::execute() {
case 0xb5: A() = through(AM_ZeroPageX()); break; // LDA (zero page, X)
case 0xb6: X() = through(AM_ZeroPageY()); break; // LDX (zero page, Y)
case 0xb7: A() = X() = through(AM_ZeroPageY()); break; // *LAX (zero page, Y)
case 0xb8: busRead(); clearFlag(P(), VF); break; // CLV (implied)
case 0xb8: busRead(); P() = clearBit(P(), VF); break; // CLV (implied)
case 0xb9: A() = through(AM_AbsoluteY()); break; // LDA (absolute, Y)
case 0xba: busRead(); X() = through(S()); break; // TSX (implied)
case 0xbb: break;
@ -341,13 +341,13 @@ int EightBit::MOS6502::execute() {
case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (zero page, X)
case 0xd6: busReadModifyWrite(dec(AM_ZeroPageX())); break; // DEC (zero page, X)
case 0xd7: dcp(AM_ZeroPageX()); break; // *DCP (zero page, X)
case 0xd8: busRead(); clearFlag(P(), DF); break; // CLD (implied)
case 0xd8: busRead(); P() = clearBit(P(), DF); break; // CLD (implied)
case 0xd9: cmp(A(), AM_AbsoluteY()); break; // CMP (absolute, Y)
case 0xda: busRead(); break; // *NOP (implied)
case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y)
case 0xdc: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0xdd: cmp(A(), AM_AbsoluteX()); break; // CMP (absolute, X)
case 0xde: busReadModifyWrite(dec(AM_AbsoluteX(AlwaysReadTwice))); break; // DEC (absolute, X)
case 0xde: busReadModifyWrite(dec(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // DEC (absolute, X)
case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X)
case 0xe0: cmp(X(), AM_Immediate()); break; // CPX (immediate)
@ -375,13 +375,13 @@ int EightBit::MOS6502::execute() {
case 0xf5: A() = sbc(A(), AM_ZeroPageX()); break; // SBC (zero page, X)
case 0xf6: busReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (zero page, X)
case 0xf7: isb(AM_ZeroPageX()); break; // *ISB (zero page, X)
case 0xf8: busRead(); setFlag(P(), DF); break; // SED (implied)
case 0xf8: busRead(); P() = setBit(P(), DF); break; // SED (implied)
case 0xf9: A() = sbc(A(), AM_AbsoluteY()); break; // SBC (absolute, Y)
case 0xfa: busRead(); break; // *NOP (implied)
case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y)
case 0xfc: AM_AbsoluteX(); break; // *NOP (absolute, X)
case 0xfd: A() = sbc(A(), AM_AbsoluteX()); break; // SBC (absolute, X)
case 0xfe: busReadModifyWrite(inc(AM_AbsoluteX(AlwaysReadTwice))); break; // INC (absolute, X)
case 0xfe: busReadModifyWrite(inc(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // INC (absolute, X)
case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X)
}
@ -482,7 +482,7 @@ uint8_t EightBit::MOS6502::AM_ZeroPage() {
uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) {
const auto [address, page] = Address_AbsoluteX();
auto possible = getBytePaged(page, address.low);
if ((behaviour == AlwaysReadTwice) || UNLIKELY(page != address.high))
if ((behaviour == PageCrossingBehavior::AlwaysReadTwice) || UNLIKELY(page != address.high))
possible = Processor::busRead(address);
return possible;
}
@ -536,8 +536,8 @@ uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) {
const auto difference = m_intermediate;
adjustNZ(difference.low);
setFlag(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
clearFlag(P(), CF, difference.high);
P() = setBit(P(), VF, (operand ^ data) & (operand ^ difference.low) & NF);
P() = clearBit(P(), CF, difference.high);
return returned;
}
@ -580,8 +580,8 @@ uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carry) {
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) {
m_intermediate.word = operand + data + carry;
setFlag(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
setFlag(P(), CF, m_intermediate.high & CF);
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
P() = setBit(P(), CF, m_intermediate.high & CF);
return m_intermediate.low;
}
@ -595,12 +595,12 @@ uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) {
low += 6;
uint8_t high = highNibble(operand) + highNibble(data) + (low > 0xf ? 1 : 0);
setFlag(P(), VF, ~(operand ^ data) & (operand ^ promoteNibble(high)) & NF);
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ promoteNibble(high)) & NF);
if (high > 9)
high += 6;
setFlag(P(), CF, high > 0xf);
P() = setBit(P(), CF, high > 0xf);
return promoteNibble(high) | lowNibble(low);
}
@ -610,12 +610,12 @@ uint8_t EightBit::MOS6502::andr(const uint8_t operand, const uint8_t data) {
}
uint8_t EightBit::MOS6502::asl(const uint8_t value) {
setFlag(P(), CF, value & Bit7);
P() = setBit(P(), CF, value & Bit7);
return through(value << 1);
}
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
setFlag(P(), VF, data & VF);
P() = setBit(P(), VF, data & VF);
adjustZero(operand & data);
adjustNegative(data);
}
@ -623,7 +623,7 @@ void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
void EightBit::MOS6502::cmp(const uint8_t first, const uint8_t second) {
const register16_t result = first - second;
adjustNZ(result.low);
clearFlag(P(), CF, result.high);
P() = clearBit(P(), CF, result.high);
}
uint8_t EightBit::MOS6502::dec(const uint8_t value) {
@ -647,7 +647,7 @@ void EightBit::MOS6502::jsr() {
}
uint8_t EightBit::MOS6502::lsr(const uint8_t value) {
setFlag(P(), CF, value & Bit0);
P() = setBit(P(), CF, value & Bit0);
return through(value >> 1);
}
@ -665,14 +665,14 @@ void EightBit::MOS6502::plp() {
uint8_t EightBit::MOS6502::rol(const uint8_t operand) {
const auto carryIn = carry();
setFlag(P(), CF, operand & Bit7);
P() = setBit(P(), CF, operand & Bit7);
const uint8_t result = (operand << 1) | carryIn;
return through(result);
}
uint8_t EightBit::MOS6502::ror(const uint8_t operand) {
const auto carryIn = carry();
setFlag(P(), CF, operand & Bit0);
P() = setBit(P(), CF, operand & Bit0);
const uint8_t result = (operand >> 1) | (carryIn << 7);
return through(result);
}
@ -693,14 +693,14 @@ void EightBit::MOS6502::rts() {
void EightBit::MOS6502::anc(const uint8_t value) {
A() = andr(A(), value);
setFlag(P(), CF, A() & Bit7);
P() = setBit(P(), CF, A() & Bit7);
}
void EightBit::MOS6502::arr(const uint8_t value) {
A() = andr(A(), value);
A() = ror(A());
setFlag(P(), CF, A() & Bit6);
setFlag(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
P() = setBit(P(), CF, A() & Bit6);
P() = setBit(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
}
void EightBit::MOS6502::asr(const uint8_t value) {
@ -710,7 +710,7 @@ void EightBit::MOS6502::asr(const uint8_t value) {
void EightBit::MOS6502::axs(const uint8_t value) {
X() = through(sub(A() & X(), value));
clearFlag(P(), CF, m_intermediate.high);
P() = clearBit(P(), CF, m_intermediate.high);
}
void EightBit::MOS6502::dcp(const uint8_t value) {

View File

@ -38,11 +38,11 @@ void EightBit::M6532::step() {
const bool interruptPA7 = m_allowPA7Interrupts && (PA() & Bit7);
if (interruptPA7)
setFlag(IF(), Bit6);
IF() = setBit(IF(), Bit6);
const bool interruptTimer = m_allowTimerInterrupts && (m_timerInterval == 0);
if (interruptTimer)
setFlag(IF(), Bit7);
IF() = setBit(IF(), Bit7);
match(IRQ(), !(interruptPA7 || interruptTimer));
@ -93,7 +93,7 @@ void EightBit::M6532::step() {
if (read && a2 && a0) {
DATA() = IF();
clearFlag(IF(), Bit6);
IF() = clearBit(IF(), Bit6);
}
m_allowTimerInterrupts = !!a3;
@ -115,7 +115,7 @@ void EightBit::M6532::step() {
break;
}
m_currentIncrement = m_timerIncrement;
clearFlag(IF(), Bit7);
IF() = clearBit(IF(), Bit7);
}
}
}

View File

@ -195,10 +195,10 @@ namespace EightBit {
// Flag adjustment
template<class T> void adjustZero(const T datum) { clearFlag(CC(), ZF, datum); }
void adjustZero(const register16_t datum) { clearFlag(CC(), ZF, datum.word); }
void adjustNegative(const uint8_t datum) { setFlag(CC(), NF, datum & Bit7); }
void adjustNegative(const uint16_t datum) { setFlag(CC(), NF, datum & Bit15); }
template<class T> void adjustZero(const T datum) { CC() = clearBit(CC(), ZF, datum); }
void adjustZero(const register16_t datum) { CC() = clearBit(CC(), ZF, datum.word); }
void adjustNegative(const uint8_t datum) { CC() = setBit(CC(), NF, datum & Bit7); }
void adjustNegative(const uint16_t datum) { CC() = setBit(CC(), NF, datum & Bit15); }
void adjustNegative(const register16_t datum) { adjustNegative(datum.word); }
template<class T> void adjustNZ(const T datum) {
@ -206,24 +206,24 @@ namespace EightBit {
adjustNegative(datum);
}
void adjustCarry(const uint16_t datum) { setFlag(CC(), CF, datum & Bit8); } // 8-bit addition
void adjustCarry(const uint32_t datum) { setFlag(CC(), CF, datum & Bit16); } // 16-bit addition
void adjustCarry(const uint16_t datum) { CC() = setBit(CC(), CF, datum & Bit8); } // 8-bit addition
void adjustCarry(const uint32_t datum) { CC() = setBit(CC(), CF, datum & Bit16); } // 16-bit addition
void adjustCarry(const register16_t datum) { adjustCarry(datum.word); }
void adjustBorrow(const uint16_t datum) { clearFlag(CC(), CF, datum & Bit8); } // 8-bit subtraction
void adjustBorrow(const uint32_t datum) { clearFlag(CC(), CF, datum & Bit16); } // 16-bit subtraction
void adjustBorrow(const uint16_t datum) { CC() = clearBit(CC(), CF, datum & Bit8); } // 8-bit subtraction
void adjustBorrow(const uint32_t datum) { CC() = clearBit(CC(), CF, datum & Bit16); } // 16-bit subtraction
void adjustBorrow(const register16_t datum) { adjustBorrow(datum.word); }
void adjustOverflow(const uint8_t before, const uint8_t data, const register16_t after) {
const uint8_t lowAfter = after.low;
const uint8_t highAfter = after.high;
setFlag(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & Bit7);
CC() = setBit(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 7)) & Bit7);
}
void adjustOverflow(const uint16_t before, const uint16_t data, const uint32_t after) {
const uint16_t lowAfter = after & Mask16;
const uint16_t highAfter = after >> 16;
setFlag(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & Bit15);
CC() = setBit(CC(), VF, (before ^ data ^ lowAfter ^ (highAfter << 15)) & Bit15);
}
void adjustOverflow(const register16_t before, const register16_t data, const register16_t after) {
@ -231,7 +231,7 @@ namespace EightBit {
}
void adjustHalfCarry(const uint8_t before, const uint8_t data, const uint8_t after) {
setFlag(CC(), HF, (before ^ data ^ after) & Bit4);
CC() = setBit(CC(), HF, (before ^ data ^ after) & Bit4);
}
void adjustAddition(const uint8_t before, const uint8_t data, const register16_t after) {
@ -314,7 +314,7 @@ namespace EightBit {
void restoreRegisterState();
template <class T> T through(const T data) {
clearFlag(CC(), VF);
CC() = clearBit(CC(), VF);
adjustNZ(data);
return data;
}

View File

@ -55,8 +55,8 @@ void EightBit::mc6809::handleRESET() {
lowerBA();
raiseBS();
DP() = 0;
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
CC() = setBit(CC(), IF); // Disable IRQ
CC() = setBit(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, RESETvector));
tick(10);
}
@ -66,8 +66,8 @@ void EightBit::mc6809::handleNMI() {
lowerBA();
raiseBS();
saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
CC() = setBit(CC(), IF); // Disable IRQ
CC() = setBit(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, NMIvector));
tick(12);
}
@ -77,7 +77,7 @@ void EightBit::mc6809::handleINT() {
lowerBA();
raiseBS();
saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ
CC() = setBit(CC(), IF); // Disable IRQ
jump(getWordPaged(0xff, IRQvector));
tick(12);
}
@ -87,8 +87,8 @@ void EightBit::mc6809::handleFIRQ() {
lowerBA();
raiseBS();
savePartialRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
CC() = setBit(CC(), IF); // Disable IRQ
CC() = setBit(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, FIRQvector));
tick(12);
}
@ -765,12 +765,12 @@ EightBit::register16_t EightBit::mc6809::AM_extended_word() {
//
void EightBit::mc6809::saveEntireRegisterState() {
setFlag(CC(), EF);
CC() = setBit(CC(), EF);
saveRegisterState();
}
void EightBit::mc6809::savePartialRegisterState() {
clearFlag(CC(), EF);
CC() = clearBit(CC(), EF);
saveRegisterState();
}
@ -805,15 +805,15 @@ uint8_t EightBit::mc6809::andr(const uint8_t operand, const uint8_t data) {
}
uint8_t EightBit::mc6809::asl(uint8_t operand) {
setFlag(CC(), CF, operand & Bit7);
CC() = setBit(CC(), CF, operand & Bit7);
adjustNZ(operand <<= 1);
const auto overflow = carry() ^ (negative() >> 3);
setFlag(CC(), VF, overflow);
CC() = setBit(CC(), VF, overflow);
return operand;
}
uint8_t EightBit::mc6809::asr(uint8_t operand) {
setFlag(CC(), CF, operand & Bit0);
CC() = setBit(CC(), CF, operand & Bit0);
const uint8_t result = (operand >> 1) | Bit7;
adjustNZ(result);
return result;
@ -824,7 +824,7 @@ void EightBit::mc6809::bit(const uint8_t operand, const uint8_t data) {
}
uint8_t EightBit::mc6809::clr() {
clearFlag(CC(), CF);
CC() = clearBit(CC(), CF);
return through((uint8_t)0U);
}
@ -837,7 +837,7 @@ void EightBit::mc6809::cmp(const register16_t operand, const register16_t data)
}
uint8_t EightBit::mc6809::com(const uint8_t operand) {
setFlag(CC(), CF);
CC() = setBit(CC(), CF);
return through((uint8_t)~operand);
}
@ -849,7 +849,7 @@ void EightBit::mc6809::cwai(const uint8_t data) {
uint8_t EightBit::mc6809::da(uint8_t operand) {
setFlag(CC(), CF, operand > 0x99);
CC() = setBit(CC(), CF, operand > 0x99);
const auto lowAdjust = halfCarry() || (lowNibble(operand) > 9);
const auto highAdjust = carry() || (operand > 0x99);
@ -936,7 +936,7 @@ void EightBit::mc6809::jsr(const register16_t address) {
}
uint8_t EightBit::mc6809::lsr(uint8_t operand) {
setFlag(CC(), CF, operand & Bit0);
CC() = setBit(CC(), CF, operand & Bit0);
adjustNZ(operand >>= 1);
return operand;
}
@ -944,12 +944,12 @@ uint8_t EightBit::mc6809::lsr(uint8_t operand) {
EightBit::register16_t EightBit::mc6809::mul(const uint8_t first, const uint8_t second) {
const register16_t result = first * second;
adjustZero(result);
setFlag(CC(), CF, result.low & Bit7);
CC() = setBit(CC(), CF, result.low & Bit7);
return result;
}
uint8_t EightBit::mc6809::neg(uint8_t operand) {
setFlag(CC(), VF, operand == Bit7);
CC() = setBit(CC(), VF, operand == Bit7);
const register16_t result = 0 - operand;
operand = result.low;
adjustNZ(operand);
@ -1035,8 +1035,8 @@ void EightBit::mc6809::pul(register16_t& stack, const uint8_t data) {
uint8_t EightBit::mc6809::rol(const uint8_t operand) {
const auto carryIn = carry();
setFlag(CC(), CF, operand & Bit7);
setFlag(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6));
CC() = setBit(CC(), CF, operand & Bit7);
CC() = setBit(CC(), VF, ((operand & Bit7) >> 7) ^ ((operand & Bit6) >> 6));
const uint8_t result = (operand << 1) | carryIn;
adjustNZ(result);
return result;
@ -1044,7 +1044,7 @@ uint8_t EightBit::mc6809::rol(const uint8_t operand) {
uint8_t EightBit::mc6809::ror(const uint8_t operand) {
const auto carryIn = carry();
setFlag(CC(), CF, operand & Bit0);
CC() = setBit(CC(), CF, operand & Bit0);
const uint8_t result = (operand >> 1) | (carryIn << 7);
adjustNZ(result);
return result;
@ -1060,8 +1060,8 @@ void EightBit::mc6809::rts() {
void EightBit::mc6809::swi() {
saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
CC() = setBit(CC(), IF); // Disable IRQ
CC() = setBit(CC(), FF); // Disable FIRQ
jump(getWordPaged(0xff, SWIvector));
}

View File

@ -77,7 +77,7 @@ TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") {
SECTION("Immediate (byte)") {
board.poke(0, 0x89);
board.poke(1, 0x7c);
EightBit::Chip::setFlag(cpu.CC(), EightBit::mc6809::CF);
cpu.CC() = EightBit::Chip::setBit(cpu.CC(), EightBit::mc6809::CF);
cpu.A() = 0x3a;
cpu.step();
REQUIRE(cpu.A() == 0xb7);
@ -648,7 +648,7 @@ TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][S
board.poke(0, 0x82);
board.poke(1, 0x34);
cpu.A() = 0x14;
cpu.setFlag(cpu.CC(), EightBit::mc6809::CF);
cpu.CC() = cpu.setBit(cpu.CC(), EightBit::mc6809::CF);
cpu.step();
REQUIRE(cpu.A() == 0xdf);
REQUIRE((cpu.CC() & EightBit::mc6809::ZF) == 0);

Binary file not shown.

View File

@ -137,6 +137,13 @@ namespace EightBit {
m_displacement = fetchByte();
}
uint8_t fetchInitialOpCode() {
lowerM1();
const auto returned = fetchByte();
raiseM1();
return returned;
}
[[nodiscard]] auto& HL2() {
if (LIKELY(!m_displaced))
return HL();
@ -271,12 +278,12 @@ namespace EightBit {
}
}
static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
[[nodiscard]] static uint8_t adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) {
return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation));
}
static void adjustHalfCarrySub(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
f = setBit(f, HC, calculateHalfCarrySub(before, value, calculation));
}
static void adjustOverflowAdd(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
@ -285,7 +292,7 @@ namespace EightBit {
static void adjustOverflowAdd(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
const auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
setFlag(f, VF, overflow);
f = setBit(f, VF, overflow);
}
static void adjustOverflowSub(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
@ -294,17 +301,17 @@ namespace EightBit {
static void adjustOverflowSub(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
const auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
setFlag(f, VF, overflow);
f = setBit(f, VF, overflow);
}
uint8_t subtract(uint8_t operand, uint8_t value, int carry = 0);
static uint8_t subtract(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
void executeCB(int x, int y, int z);
void executeED(int x, int y, int z, int p, int q);
void executeOther(int x, int y, int z, int p, int q);
[[nodiscard]] uint8_t increment(uint8_t operand);
[[nodiscard]] uint8_t decrement(uint8_t operand);
[[nodiscard]] static uint8_t increment(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t decrement(uint8_t& f, uint8_t operand);
void di();
void ei();
@ -312,60 +319,60 @@ namespace EightBit {
void retn();
void reti();
bool jrConditionalFlag(int flag);
bool returnConditionalFlag(int flag);
bool jumpConditionalFlag(int flag);
bool callConditionalFlag(int flag);
[[nodiscard]] bool jrConditionalFlag(uint8_t f, int flag);
[[nodiscard]] bool returnConditionalFlag(uint8_t f, int flag);
[[nodiscard]] bool callConditionalFlag(uint8_t f, int flag);
void jumpConditionalFlag(uint8_t f, int flag);
register16_t sbc(register16_t operand, register16_t value);
register16_t adc(register16_t operand, register16_t value);
register16_t add(register16_t operand, register16_t value, int carry = 0);
[[nodiscard]] register16_t sbc(uint8_t& f, register16_t operand, register16_t value);
[[nodiscard]] register16_t adc(uint8_t& f, register16_t operand, register16_t value);
[[nodiscard]] register16_t add(uint8_t& f, register16_t operand, register16_t value, int carry = 0);
[[nodiscard]] uint8_t add(uint8_t operand, uint8_t value, int carry = 0);
[[nodiscard]] uint8_t adc(uint8_t operand, uint8_t value);
[[nodiscard]] uint8_t sub(uint8_t operand, uint8_t value, int carry = 0);
[[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t value);
void andr(uint8_t value);
void xorr(uint8_t value);
void orr(uint8_t value);
void compare(uint8_t value);
[[nodiscard]] static uint8_t add(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
[[nodiscard]] static uint8_t adc(uint8_t& f, uint8_t operand, uint8_t value);
[[nodiscard]] static uint8_t sub(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
[[nodiscard]] static uint8_t sbc(uint8_t& f, uint8_t operand, uint8_t value);
[[nodiscard]] static uint8_t andr(uint8_t& f, uint8_t operand, uint8_t value);
[[nodiscard]] static uint8_t xorr(uint8_t& f, uint8_t operand, uint8_t value);
[[nodiscard]] static uint8_t orr(uint8_t& f, uint8_t operand, uint8_t value);
static void compare(uint8_t& f, uint8_t operand, uint8_t value);
[[nodiscard]] uint8_t rlc(uint8_t operand);
[[nodiscard]] uint8_t rrc(uint8_t operand);
[[nodiscard]] uint8_t rl(uint8_t operand);
[[nodiscard]] uint8_t rr(uint8_t operand);
[[nodiscard]] uint8_t sla(uint8_t operand);
[[nodiscard]] uint8_t sra(uint8_t operand);
[[nodiscard]] uint8_t sll(uint8_t operand);
[[nodiscard]] uint8_t srl(uint8_t operand);
[[nodiscard]] static uint8_t rlc(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t rrc(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t rl(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t rr(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t sla(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t sra(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t sll(uint8_t& f, uint8_t operand);
[[nodiscard]] static uint8_t srl(uint8_t& f, uint8_t operand);
void bit(int n, uint8_t operand);
static void bit(uint8_t& f, int n, uint8_t operand);
[[nodiscard]] static uint8_t res(int n, uint8_t operand);
[[nodiscard]] static uint8_t set(int n, uint8_t operand);
void daa();
[[nodiscard]] static uint8_t daa(uint8_t& f, uint8_t operand);
void scf();
void ccf();
void cpl();
static void scf(uint8_t& f, uint8_t operand);
static void ccf(uint8_t& f, uint8_t operand);
static uint8_t cpl(uint8_t& f, uint8_t operand);
void xhtl(register16_t& exchange);
void blockCompare(register16_t source, register16_t& counter);
void blockCompare(uint8_t& f, uint8_t value, register16_t source, register16_t& counter);
void cpi();
bool cpir();
void cpi(uint8_t& f, uint8_t value);
bool cpir(uint8_t& f, uint8_t value);
void cpd();
bool cpdr();
void cpd(uint8_t& f, uint8_t value);
bool cpdr(uint8_t& f, uint8_t value);
void blockLoad(register16_t source, register16_t destination, register16_t& counter);
void blockLoad(uint8_t& f, uint8_t a, register16_t source, register16_t destination, register16_t& counter);
void ldi();
bool ldir();
void ldi(uint8_t& f, uint8_t a);
bool ldir(uint8_t& f, uint8_t a);
void ldd();
bool lddr();
void ldd(uint8_t& f, uint8_t a);
bool lddr(uint8_t& f, uint8_t a);
void blockIn(register16_t& source, register16_t destination);
@ -383,10 +390,10 @@ namespace EightBit {
void outd();
bool otdr();
void neg();
[[nodiscard]] uint8_t neg(uint8_t& f, uint8_t operand);
void rrd();
void rld();
void rrd(uint8_t& f, register16_t address, uint8_t& update);
void rld(uint8_t& f, register16_t address, uint8_t& update);
void writePort(uint8_t port);
void writePort();

File diff suppressed because it is too large Load Diff

View File

@ -45,27 +45,26 @@ namespace EightBit {
Mask16 = Bit16 - 1
};
static constexpr uint8_t bit(const int which) noexcept { return 1 << which; }
[[nodiscard]] static constexpr uint8_t bit(const int which) noexcept { return 1 << which; }
static void clearFlag(uint8_t& f, const int flag) noexcept { f &= ~flag; }
static void setFlag(uint8_t& f, const int flag) noexcept { f |= flag; }
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which) noexcept { return input | which; }
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const int condition) noexcept { return setBit(input, which, !!condition); }
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const uint32_t condition) noexcept { return setBit(input, which, !!condition); }
[[nodiscard]] static constexpr uint8_t setBit(uint8_t input, const int which, const bool condition) noexcept { return condition ? setBit(input, which) : clearBit(input, which); }
static void setFlag(uint8_t& f, const int flag, const int condition) noexcept { setFlag(f, flag, !!condition); }
static void setFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { setFlag(f, flag, !!condition); }
static void setFlag(uint8_t& f, const int flag, const bool condition) noexcept { condition ? setFlag(f, flag) : clearFlag(f, flag); }
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which) noexcept { return input & ~which; }
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const int condition) noexcept { return clearBit(input, which, !!condition); }
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const uint32_t condition) noexcept { return clearBit(input, which, !!condition); }
[[nodiscard]] static constexpr uint8_t clearBit(uint8_t input, const int which, const bool condition) noexcept { return setBit(input, which, !condition); }
static void clearFlag(uint8_t& f, const int flag, const int condition) noexcept { clearFlag(f, flag, !!condition); }
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) noexcept { clearFlag(f, flag, !!condition); }
static void clearFlag(uint8_t& f, const int flag, const bool condition) noexcept { setFlag(f, flag, !condition); }
[[nodiscard]] static constexpr auto highNibble(const int value) { return value >> 4; }
[[nodiscard]] static constexpr auto lowNibble(const int value) { return value & Mask4; }
static constexpr auto highNibble(const int value) { return value >> 4; }
static constexpr auto lowNibble(const int value) { return value & Mask4; }
[[nodiscard]] static constexpr auto higherNibble(const int value) { return value & 0xf0; }
[[nodiscard]] static constexpr auto lowerNibble(const int value) { return lowNibble(value); }
static constexpr auto higherNibble(const int value) { return value & 0xf0; }
static constexpr auto lowerNibble(const int value) { return lowNibble(value); }
static constexpr auto promoteNibble(const int value) { return value << 4; }
static constexpr auto demoteNibble(const int value) { return highNibble(value); }
[[nodiscard]] static constexpr auto promoteNibble(const int value) { return value << 4; }
[[nodiscard]] static constexpr auto demoteNibble(const int value) { return highNibble(value); }
virtual ~Chip();

View File

@ -68,9 +68,9 @@ namespace EightBit {
static constexpr auto lowered(const PinLevel line) { return line == PinLevel::Low; }
static void lower(PinLevel& line) noexcept { line = PinLevel::Low; }
static void match(PinLevel& line, int condition) { match(line, condition != 0); }
static void match(PinLevel& line, bool condition) { condition ? raise(line) : lower(line); }
static void match(PinLevel& out, PinLevel in) { out = in; }
static void match(PinLevel& line, int condition) noexcept { match(line, condition != 0); }
static void match(PinLevel& line, bool condition) noexcept { condition ? raise(line) : lower(line); }
static void match(PinLevel& out, PinLevel in) noexcept { out = in; }
virtual ~Device() {};
@ -79,6 +79,6 @@ namespace EightBit {
DECLARE_PIN_INPUT(POWER)
protected:
Device() {};
Device() noexcept {};
};
}

View File

@ -21,9 +21,9 @@ namespace EightBit {
int p = 0;
int q = 0;
opcode_decoded_t() {}
opcode_decoded_t() noexcept {}
opcode_decoded_t(const uint8_t opcode) {
opcode_decoded_t(const uint8_t opcode) noexcept {
x = (opcode & 0b11000000) >> 6; // 0 - 3
y = (opcode & 0b00111000) >> 3; // 0 - 7
z = (opcode & 0b00000111); // 0 - 7
@ -35,7 +35,7 @@ namespace EightBit {
~IntelProcessor() = default;
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
return m_decodedOpcodes[i];
return m_decodedOpcodes.at(i);
}
[[nodiscard]] auto& MEMPTR() noexcept { return m_memptr; }
@ -63,59 +63,59 @@ namespace EightBit {
protected:
IntelProcessor(Bus& bus);
template<class T> static void adjustSign(uint8_t& f, const uint8_t value) {
setFlag(f, T::SF, value & T::SF);
template<class T> [[nodiscard]] static uint8_t adjustSign(uint8_t f, const uint8_t value) {
return setBit(f, T::SF, value & T::SF);
}
template<class T> static void adjustZero(uint8_t& f, const uint8_t value) {
clearFlag(f, T::ZF, value);
template<class T> [[nodiscard]] static uint8_t adjustZero(uint8_t f, const uint8_t value) {
return clearBit(f, T::ZF, value);
}
template<class T> static void adjustParity(uint8_t& f, const uint8_t value) {
clearFlag(f, T::PF, PARITY(value));
template<class T> [[nodiscard]] static uint8_t adjustParity(uint8_t f, const uint8_t value) {
return clearBit(f, T::PF, PARITY(value));
}
template<class T> static void adjustSZ(uint8_t& f, const uint8_t value) {
adjustSign<T>(f, value);
adjustZero<T>(f, value);
template<class T> [[nodiscard]] static uint8_t adjustSZ(uint8_t f, const uint8_t value) {
const auto intermediate = adjustSign<T>(f, value);
return adjustZero<T>(intermediate, value);
}
template<class T> static void adjustSZP(uint8_t& f, const uint8_t value) {
adjustSZ<T>(f, value);
adjustParity<T>(f, value);
template<class T> [[nodiscard]] static uint8_t adjustSZP(uint8_t f, const uint8_t value) {
const auto intermediate = adjustSZ<T>(f, value);
return adjustParity<T>(intermediate, value);
}
template<class T> static void adjustXY(uint8_t& f, const uint8_t value) {
setFlag(f, T::XF, value & T::XF);
setFlag(f, T::YF, value & T::YF);
template<class T> [[nodiscard]] static uint8_t adjustXY(uint8_t f, const uint8_t value) {
const auto intermediate = setBit(f, T::XF, value & T::XF);
return setBit(intermediate, T::YF, value & T::YF);
}
template<class T> static void adjustSZPXY(uint8_t& f, const uint8_t value) {
adjustSZP<T>(f, value);
adjustXY<T>(f, value);
template<class T> [[nodiscard]] static uint8_t adjustSZPXY(uint8_t f, const uint8_t value) {
const auto intermediate = adjustSZP<T>(f, value);
return adjustXY<T>(intermediate, value);
}
template<class T> static void adjustSZXY(uint8_t& f, const uint8_t value) {
adjustSZ<T>(f, value);
adjustXY<T>(f, value);
template<class T> [[nodiscard]] static uint8_t adjustSZXY(uint8_t f, const uint8_t value) {
const auto intermediate = adjustSZ<T>(f, value);
return adjustXY<T>(intermediate, value);
}
//
static constexpr auto buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
[[nodiscard]] static constexpr auto buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
}
[[nodiscard]] static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept {
static std::array<int, 8> halfCarryTableAdd = { { 0, 0, 1, 0, 1, 0, 1, 1} };
const auto index = buildHalfCarryIndex(before, value, calculation);
return halfCarryTableAdd[index & Mask3];
return halfCarryTableAdd.at(index & Mask3);
}
[[nodiscard]] static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) noexcept {
std::array<int, 8> halfCarryTableSub = { { 0, 1, 1, 1, 0, 0, 0, 1 } };
const auto index = buildHalfCarryIndex(before, value, calculation);
return halfCarryTableSub[index & Mask3];
return halfCarryTableSub.at(index & Mask3);
}
void handleRESET() override;
@ -154,7 +154,7 @@ namespace EightBit {
return !!condition;
}
void jr(const int8_t offset) {
void jr(const int8_t offset) noexcept {
jump(MEMPTR() = PC() + offset);
}