Add a working M6502 ARR implementation

This commit is contained in:
Adrian Conlon 2024-01-06 12:19:02 +00:00
parent bc37fd4e30
commit bd289ed8fb
2 changed files with 34 additions and 4 deletions

View File

@ -56,6 +56,8 @@ namespace EightBit {
void busWrite() noexcept final;
[[nodiscard]] uint8_t busRead() noexcept final;
// Instructions with BCD effects
[[nodiscard]] virtual uint8_t sub(uint8_t operand, uint8_t data, int borrow = 0) noexcept;
[[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t data) noexcept;
[[nodiscard]] uint8_t sub_b(uint8_t operand, uint8_t data, int borrow = 0) noexcept;
@ -66,6 +68,12 @@ namespace EightBit {
[[nodiscard]] uint8_t add_b(uint8_t operand, uint8_t data, int carry) noexcept;
[[nodiscard]] uint8_t add_d(uint8_t operand, uint8_t data, int carry) noexcept;
// Undocumented compound instructions (with BCD effects)
virtual void arr(uint8_t value) noexcept;
virtual void arr_b(uint8_t value) noexcept;
virtual void arr_d(uint8_t value) noexcept;
private:
const uint8_t IRQvector = 0xfe; // IRQ vector
const uint8_t RSTvector = 0xfc; // RST vector
@ -174,7 +182,6 @@ namespace EightBit {
// Undocumented compound instructions
void anc(uint8_t value) noexcept;
void arr(uint8_t value) noexcept;
void asr(uint8_t value) noexcept;
void axs(uint8_t value) noexcept;
void dcp(uint8_t value) noexcept;

View File

@ -698,10 +698,33 @@ void EightBit::MOS6502::anc(const uint8_t value) noexcept {
}
void EightBit::MOS6502::arr(const uint8_t value) noexcept {
A() = andr(A(), value);
A() = ror(A());
decimal() ? arr_d(value) : arr_b(value);
}
void EightBit::MOS6502::arr_d(const uint8_t value) noexcept {
// With thanks to https://github.com/TomHarte/CLK
// What a very strange instruction ARR is...
A() &= value;
auto unshiftedA = A();
A() = through((A() >> 1) | (carry() << 7));
P() = setBit(P(), VF, (A() ^ (A() << 1)) & VF);
if (lowerNibble(unshiftedA) + (unshiftedA & 0x1) > 5)
A() = lowerNibble(A() + 6) | higherNibble(A());
P() = setBit(P(), CF, higherNibble(unshiftedA) + (unshiftedA & 0x10) > 0x50);
if (carry())
A() += 0x60;
}
void EightBit::MOS6502::arr_b(const uint8_t value) noexcept {
A() &= value;
A() = through((A() >> 1) | (carry() << 7));
P() = setBit(P(), CF, A() & Bit6);
P() = setBit(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
P() = setBit(P(), VF, (A() ^ (A() << 1)) & VF);
}
void EightBit::MOS6502::asr(const uint8_t value) noexcept {