mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-10 19:52:07 +00:00
Improve compatibility with .net emulator code.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
20ebbd4048
commit
d0467421ff
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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.
105
Z80/inc/Z80.h
105
Z80/inc/Z80.h
@ -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 |