mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-06-13 23:29:32 +00:00
Compare commits
2 Commits
72e548ae13
...
c15f7f836e
Author | SHA1 | Date | |
---|---|---|---|
|
c15f7f836e | ||
|
5d24a136a2 |
|
@ -1,9 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "checker_t.h"
|
||||
|
||||
std::set<uint8_t> checker_t::m_undocumented_opcodes;
|
||||
bool checker_t::m_undocumented_opcodes_initialised = false;
|
||||
|
||||
void checker_t::addActualCycle(const uint16_t address, const uint8_t value, const std::string action) {
|
||||
m_actualCycles.push_back({ address, value, action });
|
||||
}
|
||||
|
@ -114,8 +111,6 @@ void checker_t::initialiseState(const test_t test) {
|
|||
|
||||
void checker_t::initialise() {
|
||||
|
||||
seedUndocumentedOpcodes();
|
||||
|
||||
auto& bus = runner();
|
||||
|
||||
bus.ReadByte.connect([this, &bus](EightBit::EventArgs&) {
|
||||
|
@ -180,7 +175,10 @@ bool checker_t::checkState(test_t test) {
|
|||
ram_problem = true;
|
||||
}
|
||||
|
||||
return pc_good && s_good && a_good && x_good && y_good && p_good && !ram_problem;
|
||||
return
|
||||
pc_good && s_good
|
||||
&& a_good && x_good && y_good && p_good
|
||||
&& !ram_problem;
|
||||
}
|
||||
//
|
||||
void checker_t::pushCurrentMessage() {
|
||||
|
@ -210,13 +208,6 @@ void checker_t::check(test_t test) {
|
|||
const auto pc = cpu.PC().word;
|
||||
const auto start_opcode = runner().peek(pc);
|
||||
|
||||
m_undocumented = m_undocumented_opcodes.contains(start_opcode);
|
||||
if (undocumented()) {
|
||||
m_valid = false;
|
||||
m_messages.push_back("Undocumented");
|
||||
return;
|
||||
}
|
||||
|
||||
m_cycles = cpu.step();
|
||||
runner().lowerPOWER();
|
||||
|
||||
|
@ -250,26 +241,3 @@ void checker_t::check(test_t test) {
|
|||
dumpCycles("-- Actual cycles", m_actualCycles);
|
||||
}
|
||||
}
|
||||
|
||||
void checker_t::seedUndocumentedOpcodes() {
|
||||
if (m_undocumented_opcodes_initialised) return;
|
||||
m_undocumented_opcodes = {
|
||||
0x02, 0x03, 0x04, 0x07, 0x0b, 0x0c, 0x0f,
|
||||
0x12, 0x13, 0x14, 0x17, 0x1a, 0x1b, 0x1c, 0x1f,
|
||||
0x22, 0x23, 0x27, 0x2b, 0x2f,
|
||||
0x32, 0x33, 0x34, 0x37, 0x3a, 0x3b, 0x3c, 0x3f,
|
||||
0x42, 0x43, 0x44, 0x47, 0x4b, 0x4f,
|
||||
0x52, 0x53, 0x54, 0x57, 0x5a, 0x5b, 0x5c, 0x5f,
|
||||
0x62, 0x63, 0x64, 0x67, 0x6b, 0x6f,
|
||||
0x72, 0x73, 0x74, 0x77, 0x7a, 0x7b, 0x7c, 0x7f,
|
||||
0x80, 0x82, 0x83, 0x87, 0x89, 0x8b, 0x8f,
|
||||
0x92, 0x93, 0x97, 0x9b, 0x9c, 0x9e, 0x9f,
|
||||
0xa3, 0xa7, 0xab, 0xaf,
|
||||
0xb2, 0xb3, 0xb7, 0xbb, 0xbf,
|
||||
0xc2, 0xc3, 0xc7, 0xcb, 0xcf,
|
||||
0xd2, 0xd3, 0xd4, 0xd7, 0xda, 0xdb, 0xdc, 0xdf,
|
||||
0xe2, 0xe3, 0xe7, 0xeb, 0xef,
|
||||
0xf1, 0xf2, 0xf3, 0xf4, 0xf7, 0xfa, 0xfb, 0xfc, 0xff,
|
||||
};
|
||||
m_undocumented_opcodes_initialised = true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
|
||||
#include <Disassembly.h>
|
||||
#include <Symbols.h>
|
||||
|
@ -14,9 +13,6 @@
|
|||
|
||||
class checker_t {
|
||||
private:
|
||||
static std::set<uint8_t> m_undocumented_opcodes;
|
||||
static bool m_undocumented_opcodes_initialised;
|
||||
|
||||
TestRunner& m_runner;
|
||||
EightBit::Symbols m_symbols;
|
||||
EightBit::Disassembly m_disassembler = { m_runner, m_runner.CPU(), m_symbols };
|
||||
|
@ -31,13 +27,11 @@ private:
|
|||
|
||||
int m_cycles = 0;
|
||||
bool m_valid = true;
|
||||
bool m_undocumented = false;
|
||||
|
||||
[[nodiscard]] constexpr auto& os() noexcept { return m_os; }
|
||||
|
||||
[[nodiscard]] constexpr auto& runner() noexcept { return m_runner; }
|
||||
|
||||
void seedUndocumentedOpcodes();
|
||||
[[nodiscard]] bool checkState(test_t test);
|
||||
|
||||
void pushCurrentMessage();
|
||||
|
@ -92,8 +86,6 @@ public:
|
|||
[[nodiscard]] constexpr auto invalid() const noexcept { return !valid(); }
|
||||
[[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 1); }
|
||||
[[nodiscard]] constexpr auto implemented() const noexcept { return !unimplemented(); }
|
||||
[[nodiscard]] constexpr auto undocumented() const noexcept { return m_undocumented; }
|
||||
[[nodiscard]] constexpr auto documented() const noexcept { return !undocumented(); }
|
||||
|
||||
[[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; }
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ int main() {
|
|||
|
||||
const auto start_time = std::chrono::steady_clock::now();
|
||||
|
||||
int undocumented_opcode_count = 0;
|
||||
int unimplemented_opcode_count = 0;
|
||||
int invalid_opcode_count = 0;
|
||||
|
||||
|
@ -46,8 +45,6 @@ int main() {
|
|||
++invalid_opcode_count;
|
||||
if (checker.unimplemented())
|
||||
++unimplemented_opcode_count;
|
||||
if (checker.undocumented())
|
||||
++undocumented_opcode_count;
|
||||
std::cout << "** Failed: " << test.name() << "\n";
|
||||
for (const auto& message : checker.messages())
|
||||
std::cout << "**** " << message << "\n";
|
||||
|
@ -61,7 +58,6 @@ int main() {
|
|||
const auto seconds = std::chrono::duration_cast<std::chrono::duration<double>>(elapsed_time).count();
|
||||
std::cout
|
||||
<< "Elapsed time: " << seconds << " seconds"
|
||||
<< ", undocumented opcode count: " << undocumented_opcode_count
|
||||
<< ", unimplemented opcode count: " << unimplemented_opcode_count
|
||||
<< ", invalid opcode count: " << (invalid_opcode_count - unimplemented_opcode_count)
|
||||
<< std::endl;
|
||||
|
|
|
@ -58,8 +58,8 @@ namespace EightBit {
|
|||
|
||||
[[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) noexcept;
|
||||
[[nodiscard]] uint8_t sub_d(uint8_t operand, uint8_t data, int borrow) noexcept;
|
||||
[[nodiscard]] uint8_t sub_b(uint8_t operand, uint8_t data, int borrow = 0) noexcept;
|
||||
[[nodiscard]] uint8_t sub_d(uint8_t operand, uint8_t data, int borrow = 0) noexcept;
|
||||
|
||||
[[nodiscard]] virtual uint8_t add(uint8_t operand, uint8_t data, int carry = 0) noexcept;
|
||||
[[nodiscard]] uint8_t adc(uint8_t operand, uint8_t data) noexcept;
|
||||
|
@ -184,17 +184,82 @@ namespace EightBit {
|
|||
void slo(uint8_t value) noexcept;
|
||||
void sre(uint8_t value) noexcept;
|
||||
|
||||
// Unconditional page fixup cycle required
|
||||
void fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
getBytePaged(unfixed_page, address.low); // Possible fixup for page boundary crossing
|
||||
BUS().ADDRESS() = address;
|
||||
}
|
||||
|
||||
// Complicated addressing mode implementations
|
||||
|
||||
void sta_AbsoluteX() noexcept;
|
||||
void sta_AbsoluteY() noexcept;
|
||||
void sta_IndirectIndexedY() noexcept;
|
||||
|
||||
void write_A_with_fixup(const register16_t& address, uint8_t unfixed_page) noexcept {
|
||||
getBytePaged(unfixed_page, address.low); // Possible fixup for page boundary crossing
|
||||
memoryWrite(address, A());
|
||||
void sta_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
memoryWrite(A());
|
||||
}
|
||||
|
||||
// Undocumented complicated mode implementations
|
||||
|
||||
// SLO
|
||||
void slo_AbsoluteX() noexcept;
|
||||
void slo_AbsoluteY() noexcept;
|
||||
void slo_IndirectIndexedY() noexcept;
|
||||
void slo_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
slo(memoryRead());
|
||||
}
|
||||
|
||||
// ISB
|
||||
void isb_AbsoluteX() noexcept;
|
||||
void isb_AbsoluteY() noexcept;
|
||||
void isb_IndirectIndexedY() noexcept;
|
||||
void isb_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
isb(memoryRead());
|
||||
}
|
||||
|
||||
// RLA
|
||||
void rla_AbsoluteX() noexcept;
|
||||
void rla_AbsoluteY() noexcept;
|
||||
void rla_IndirectIndexedY() noexcept;
|
||||
void rla_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
rla(memoryRead());
|
||||
}
|
||||
|
||||
// RRA
|
||||
void rra_AbsoluteX() noexcept;
|
||||
void rra_AbsoluteY() noexcept;
|
||||
void rra_IndirectIndexedY() noexcept;
|
||||
void rra_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
rra(memoryRead());
|
||||
}
|
||||
|
||||
// DCP
|
||||
void dcp_AbsoluteX() noexcept;
|
||||
void dcp_AbsoluteY() noexcept;
|
||||
void dcp_IndirectIndexedY() noexcept;
|
||||
void dcp_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
dcp(memoryRead());
|
||||
}
|
||||
|
||||
// SRE
|
||||
void sre_AbsoluteX() noexcept;
|
||||
void sre_AbsoluteY() noexcept;
|
||||
void sre_IndirectIndexedY() noexcept;
|
||||
void sre_with_fixup(const register16_t address, const uint8_t unfixed_page) noexcept {
|
||||
fixup(address, unfixed_page);
|
||||
sre(memoryRead());
|
||||
}
|
||||
|
||||
// NOP
|
||||
void nop_AbsoluteX() noexcept;
|
||||
|
||||
uint8_t x = 0; // index register X
|
||||
uint8_t y = 0; // index register Y
|
||||
uint8_t a = 0; // accumulator
|
||||
|
|
|
@ -14,11 +14,11 @@ EightBit::MOS6502::MOS6502(Bus& bus) noexcept
|
|||
});
|
||||
}
|
||||
|
||||
DEFINE_PIN_LEVEL_CHANGERS(NMI, MOS6502);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(SO, MOS6502);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(SYNC, MOS6502);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RDY, MOS6502);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RW, MOS6502);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(NMI, MOS6502)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(SO, MOS6502)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(SYNC, MOS6502)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RDY, MOS6502)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RW, MOS6502)
|
||||
|
||||
int EightBit::MOS6502::step() noexcept {
|
||||
resetCycles();
|
||||
|
@ -124,15 +124,15 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x09: A() = orr(A(), AM_Immediate()); break; // ORA (immediate)
|
||||
case 0x0a: memoryRead(PC()); A() = asl(A()); break; // ASL A (implied)
|
||||
case 0x0b: anc(AM_Immediate()); break; // *ANC (immediate)
|
||||
case 0x0c: AM_Absolute(); break; // *NOP (absolute)
|
||||
case 0x0c: { auto ignored = Address_Absolute(); } break; // *NOP (absolute)
|
||||
case 0x0d: A() = orr(A(), AM_Absolute()); break; // ORA (absolute)
|
||||
case 0x0e: memoryReadModifyWrite(asl(AM_Absolute())); break; // ASL (absolute)
|
||||
case 0x0f: slo(AM_Absolute()); break; // *SLO (absolute)
|
||||
|
||||
case 0x10: branch(!negative()); break; // BPL (relative)
|
||||
case 0x10: branch(negative() == 0); break; // BPL (relative)
|
||||
case 0x11: A() = orr(A(), AM_IndirectIndexedY()); break; // ORA (indirect indexed Y)
|
||||
case 0x12: break;
|
||||
case 0x13: slo(AM_IndirectIndexedY()); break; // *SLO (indirect indexed Y)
|
||||
case 0x13: slo_IndirectIndexedY(); break; // *SLO (indirect indexed Y)
|
||||
case 0x14: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0x15: A() = orr(A(), AM_ZeroPageX()); break; // ORA (zero page, X)
|
||||
case 0x16: memoryReadModifyWrite(asl(AM_ZeroPageX())); break; // ASL (zero page, X)
|
||||
|
@ -140,11 +140,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x18: memoryRead(PC()); P() = clearBit(P(), CF); break; // CLC (implied)
|
||||
case 0x19: A() = orr(A(), AM_AbsoluteY()); break; // ORA (absolute, Y)
|
||||
case 0x1a: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0x1b: slo(AM_AbsoluteY()); break; // *SLO (absolute, Y)
|
||||
case 0x1c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x1b: slo_AbsoluteY(); break; // *SLO (absolute, Y)
|
||||
case 0x1c: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x1d: A() = orr(A(), AM_AbsoluteX()); break; // ORA (absolute, X)
|
||||
case 0x1e: memoryReadModifyWrite(asl(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ASL (absolute, X)
|
||||
case 0x1f: slo(AM_AbsoluteX()); break; // *SLO (absolute, X)
|
||||
case 0x1f: slo_AbsoluteX(); break; // *SLO (absolute, X)
|
||||
|
||||
case 0x20: jsr(); break; // JSR (absolute)
|
||||
case 0x21: A() = andr(A(), AM_IndexedIndirectX()); break; // AND (indexed indirect X)
|
||||
|
@ -166,7 +166,7 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x30: branch(negative()); break; // BMI (relative)
|
||||
case 0x31: A() = andr(A(), AM_IndirectIndexedY()); break; // AND (indirect indexed Y)
|
||||
case 0x32: break;
|
||||
case 0x33: rla(AM_IndirectIndexedY()); break; // *RLA (indirect indexed Y)
|
||||
case 0x33: rla_IndirectIndexedY(); break; // *RLA (indirect indexed Y)
|
||||
case 0x34: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0x35: A() = andr(A(), AM_ZeroPageX()); break; // AND (zero page, X)
|
||||
case 0x36: memoryReadModifyWrite(rol(AM_ZeroPageX())); break; // ROL (zero page, X)
|
||||
|
@ -174,11 +174,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x38: memoryRead(PC()); P() = setBit(P(), CF); break; // SEC (implied)
|
||||
case 0x39: A() = andr(A(), AM_AbsoluteY()); break; // AND (absolute, Y)
|
||||
case 0x3a: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0x3b: rla(AM_AbsoluteY()); break; // *RLA (absolute, Y)
|
||||
case 0x3c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x3b: rla_AbsoluteY(); break; // *RLA (absolute, Y)
|
||||
case 0x3c: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x3d: A() = andr(A(), AM_AbsoluteX()); break; // AND (absolute, X)
|
||||
case 0x3e: memoryReadModifyWrite(rol(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROL (absolute, X)
|
||||
case 0x3f: rla(AM_AbsoluteX()); break; // *RLA (absolute, X)
|
||||
case 0x3f: rla_AbsoluteX(); break; // *RLA (absolute, X)
|
||||
|
||||
case 0x40: memoryRead(PC()); rti(); break; // RTI (implied)
|
||||
case 0x41: A() = eorr(A(), AM_IndexedIndirectX()); break; // EOR (indexed indirect X)
|
||||
|
@ -197,10 +197,10 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x4e: memoryReadModifyWrite(lsr(AM_Absolute())); break; // LSR (absolute)
|
||||
case 0x4f: sre(AM_Absolute()); break; // *SRE (absolute)
|
||||
|
||||
case 0x50: branch(!overflow()); break; // BVC (relative)
|
||||
case 0x50: branch(overflow() == 0); break; // BVC (relative)
|
||||
case 0x51: A() = eorr(A(), AM_IndirectIndexedY()); break; // EOR (indirect indexed Y)
|
||||
case 0x52: break;
|
||||
case 0x53: sre(AM_IndirectIndexedY()); break; // *SRE (indirect indexed Y)
|
||||
case 0x53: sre_IndirectIndexedY(); break; // *SRE (indirect indexed Y)
|
||||
case 0x54: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0x55: A() = eorr(A(), AM_ZeroPageX()); break; // EOR (zero page, X)
|
||||
case 0x56: memoryReadModifyWrite(lsr(AM_ZeroPageX())); break; // LSR (zero page, X)
|
||||
|
@ -208,11 +208,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x58: memoryRead(PC()); P() = clearBit(P(), IF); break; // CLI (implied)
|
||||
case 0x59: A() = eorr(A(), AM_AbsoluteY()); break; // EOR (absolute, Y)
|
||||
case 0x5a: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0x5b: sre(AM_AbsoluteY()); break; // *SRE (absolute, Y)
|
||||
case 0x5c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x5b: sre_AbsoluteY(); break; // *SRE (absolute, Y)
|
||||
case 0x5c: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x5d: A() = eorr(A(), AM_AbsoluteX()); break; // EOR (absolute, X)
|
||||
case 0x5e: memoryReadModifyWrite(lsr(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // LSR (absolute, X)
|
||||
case 0x5f: sre(AM_AbsoluteX()); break; // *SRE (absolute, X)
|
||||
case 0x5f: sre_AbsoluteX(); break; // *SRE (absolute, X)
|
||||
|
||||
case 0x60: memoryRead(PC()); rts(); break; // RTS (implied)
|
||||
case 0x61: A() = adc(A(), AM_IndexedIndirectX()); break; // ADC (indexed indirect X)
|
||||
|
@ -234,7 +234,7 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x70: branch(overflow()); break; // BVS (relative)
|
||||
case 0x71: A() = adc(A(), AM_IndirectIndexedY()); break; // ADC (indirect indexed Y)
|
||||
case 0x72: break;
|
||||
case 0x73: rra(AM_IndirectIndexedY()); break; // *RRA (indirect indexed Y)
|
||||
case 0x73: rra_IndirectIndexedY(); break; // *RRA (indirect indexed Y)
|
||||
case 0x74: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0x75: A() = adc(A(), AM_ZeroPageX()); break; // ADC (zero page, X)
|
||||
case 0x76: memoryReadModifyWrite(ror(AM_ZeroPageX())); break; // ROR (zero page, X)
|
||||
|
@ -242,11 +242,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x78: memoryRead(PC()); P() = setBit(P(), IF); break; // SEI (implied)
|
||||
case 0x79: A() = adc(A(), AM_AbsoluteY()); break; // ADC (absolute, Y)
|
||||
case 0x7a: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0x7b: rra(AM_AbsoluteY()); break; // *RRA (absolute, Y)
|
||||
case 0x7c: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x7b: rra_AbsoluteY(); break; // *RRA (absolute, Y)
|
||||
case 0x7c: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0x7d: A() = adc(A(), AM_AbsoluteX()); break; // ADC (absolute, X)
|
||||
case 0x7e: memoryReadModifyWrite(ror(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // ROR (absolute, X)
|
||||
case 0x7f: rra(AM_AbsoluteX()); break; // *RRA (absolute, X)
|
||||
case 0x7f: rra_AbsoluteX(); break; // *RRA (absolute, X)
|
||||
|
||||
case 0x80: AM_Immediate(); break; // *NOP (immediate)
|
||||
case 0x81: memoryWrite(Address_IndexedIndirectX(), A()); break; // STA (indexed indirect X)
|
||||
|
@ -265,7 +265,7 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0x8e: memoryWrite(Address_Absolute(), X()); break; // STX (absolute)
|
||||
case 0x8f: memoryWrite(Address_Absolute(), A() & X()); break; // *SAX (absolute)
|
||||
|
||||
case 0x90: branch(!carry()); break; // BCC (relative)
|
||||
case 0x90: branch(carry() == 0); break; // BCC (relative)
|
||||
case 0x91: sta_IndirectIndexedY(); break; // STA (indirect indexed Y)
|
||||
case 0x92: break;
|
||||
case 0x93: break;
|
||||
|
@ -333,10 +333,10 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0xce: memoryReadModifyWrite(dec(AM_Absolute())); break; // DEC (absolute)
|
||||
case 0xcf: dcp(AM_Absolute()); break; // *DCP (absolute)
|
||||
|
||||
case 0xd0: branch(!zero()); break; // BNE (relative)
|
||||
case 0xd0: branch(zero() == 0); break; // BNE (relative)
|
||||
case 0xd1: cmp(A(), AM_IndirectIndexedY()); break; // CMP (indirect indexed Y)
|
||||
case 0xd2: break;
|
||||
case 0xd3: dcp(AM_IndirectIndexedY()); break; // *DCP (indirect indexed Y)
|
||||
case 0xd3: dcp_IndirectIndexedY(); break; // *DCP (indirect indexed Y)
|
||||
case 0xd4: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0xd5: cmp(A(), AM_ZeroPageX()); break; // CMP (zero page, X)
|
||||
case 0xd6: memoryReadModifyWrite(dec(AM_ZeroPageX())); break; // DEC (zero page, X)
|
||||
|
@ -344,11 +344,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0xd8: memoryRead(PC()); P() = clearBit(P(), DF); break; // CLD (implied)
|
||||
case 0xd9: cmp(A(), AM_AbsoluteY()); break; // CMP (absolute, Y)
|
||||
case 0xda: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0xdb: dcp(AM_AbsoluteY()); break; // *DCP (absolute, Y)
|
||||
case 0xdc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0xdb: dcp_AbsoluteY(); break; // *DCP (absolute, Y)
|
||||
case 0xdc: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0xdd: cmp(A(), AM_AbsoluteX()); break; // CMP (absolute, X)
|
||||
case 0xde: memoryReadModifyWrite(dec(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // DEC (absolute, X)
|
||||
case 0xdf: dcp(AM_AbsoluteX()); break; // *DCP (absolute, X)
|
||||
case 0xdf: dcp_AbsoluteX(); break; // *DCP (absolute, X)
|
||||
|
||||
case 0xe0: cmp(X(), AM_Immediate()); break; // CPX (immediate)
|
||||
case 0xe1: A() = sbc(A(), AM_IndexedIndirectX()); break; // SBC (indexed indirect X)
|
||||
|
@ -370,7 +370,7 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0xf0: branch(zero()); break; // BEQ (relative)
|
||||
case 0xf1: A() = sbc(A(), AM_IndirectIndexedY()); break; // SBC (indirect indexed Y)
|
||||
case 0xf2: break;
|
||||
case 0xf3: isb(AM_IndirectIndexedY()); break; // *ISB (indirect indexed Y)
|
||||
case 0xf3: isb_IndirectIndexedY(); break; // *ISB (indirect indexed Y)
|
||||
case 0xf4: AM_ZeroPageX(); break; // *NOP (zero page, X)
|
||||
case 0xf5: A() = sbc(A(), AM_ZeroPageX()); break; // SBC (zero page, X)
|
||||
case 0xf6: memoryReadModifyWrite(inc(AM_ZeroPageX())); break; // INC (zero page, X)
|
||||
|
@ -378,11 +378,11 @@ int EightBit::MOS6502::execute() noexcept {
|
|||
case 0xf8: memoryRead(PC()); P() = setBit(P(), DF); break; // SED (implied)
|
||||
case 0xf9: A() = sbc(A(), AM_AbsoluteY()); break; // SBC (absolute, Y)
|
||||
case 0xfa: memoryRead(PC()); break; // *NOP (implied)
|
||||
case 0xfb: isb(AM_AbsoluteY()); break; // *ISB (absolute, Y)
|
||||
case 0xfc: AM_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0xfb: isb_AbsoluteY(); break; // *ISB (absolute, Y)
|
||||
case 0xfc: nop_AbsoluteX(); break; // *NOP (absolute, X)
|
||||
case 0xfd: A() = sbc(A(), AM_AbsoluteX()); break; // SBC (absolute, X)
|
||||
case 0xfe: memoryReadModifyWrite(inc(AM_AbsoluteX(PageCrossingBehavior::AlwaysReadTwice))); break; // INC (absolute, X)
|
||||
case 0xff: isb(AM_AbsoluteX()); break; // *ISB (absolute, X)
|
||||
case 0xff: isb_AbsoluteX(); break; // *ISB (absolute, X)
|
||||
}
|
||||
|
||||
ASSUME(cycles() > 0);
|
||||
|
@ -710,7 +710,7 @@ void EightBit::MOS6502::asr(const uint8_t value) noexcept {
|
|||
}
|
||||
|
||||
void EightBit::MOS6502::axs(const uint8_t value) noexcept {
|
||||
X() = through(sub(A() & X(), value));
|
||||
X() = through(sub_b(A() & X(), value));
|
||||
P() = clearBit(P(), CF, m_intermediate.high);
|
||||
}
|
||||
|
||||
|
@ -748,15 +748,112 @@ void EightBit::MOS6502::sre(const uint8_t value) noexcept {
|
|||
|
||||
void EightBit::MOS6502::sta_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
write_A_with_fixup(address, page);
|
||||
sta_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::sta_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
write_A_with_fixup(address, page);
|
||||
sta_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::sta_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
write_A_with_fixup(address, page);
|
||||
sta_with_fixup(address, page);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void EightBit::MOS6502::slo_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
slo_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::slo_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
slo_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::slo_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
slo_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::isb_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
isb_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::isb_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
isb_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::isb_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
isb_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rla_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
rla_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rla_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
rla_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rla_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
rla_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rra_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
rra_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rra_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
rra_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::rra_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
rra_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::dcp_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
dcp_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::dcp_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
dcp_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::dcp_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
dcp_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::sre_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
sre_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::sre_AbsoluteY() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
sre_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::sre_IndirectIndexedY() noexcept {
|
||||
const auto [address, page] = Address_IndirectIndexedY();
|
||||
sre_with_fixup(address, page);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::nop_AbsoluteX() noexcept {
|
||||
const auto [address, page] = Address_AbsoluteX();
|
||||
fixup(address, page);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user