diff options
Diffstat (limited to 'src/nes')
| -rw-r--r-- | src/nes/cpu.cc | 35 | ||||
| -rw-r--r-- | src/nes/cpu.hh | 9 | ||||
| -rw-r--r-- | src/nes/mapper.cc | 12 | ||||
| -rw-r--r-- | src/nes/nes.cc | 16 | ||||
| -rw-r--r-- | src/nes/nes.hh | 4 | ||||
| -rw-r--r-- | src/nes/ppu.cc | 10 | ||||
| -rw-r--r-- | src/nes/ppu.hh | 12 | ||||
| -rw-r--r-- | src/nes/util/address.hh | 2 |
8 files changed, 84 insertions, 16 deletions
diff --git a/src/nes/cpu.cc b/src/nes/cpu.cc index 277c05d..2a079cc 100644 --- a/src/nes/cpu.cc +++ b/src/nes/cpu.cc @@ -14,6 +14,25 @@ namespace nes registers_.pc = read16(address{ 0xFFFC }); } + auto cpu::snapshot(test::status& snapshot) -> void + { + snapshot.cpu_cycle = current_cycles_; + snapshot.ram = std::vector(std::begin(ram_), std::end(ram_)); + snapshot.registers.pc = registers_.pc; + snapshot.registers.sp = registers_.sp; + snapshot.registers.a = registers_.a; + snapshot.registers.x = registers_.x; + snapshot.registers.y = registers_.y; + snapshot.registers.p = registers_.p; + snapshot.registers.c = registers_.c; + snapshot.registers.z = registers_.z; + snapshot.registers.i = registers_.i; + snapshot.registers.d = registers_.d; + snapshot.registers.b = registers_.b; + snapshot.registers.v = registers_.v; + snapshot.registers.n = registers_.n; + } + auto cpu::step_to(cycle_count const target) -> void { while (current_cycles_ < target) @@ -71,7 +90,7 @@ namespace nes case 0x27: run_rla<addressing_mode::zero_page>(); break; case 0x28: run_plp(); break; case 0x29: run_and<addressing_mode::immediate>(); break; - case 0x2A: run_rol<addressing_mode::absolute>(); break; + case 0x2A: run_rol<addressing_mode::accumulator>(); break; case 0x2B: run_anc<addressing_mode::immediate>(); break; case 0x2C: run_bit<addressing_mode::absolute>(); break; case 0x2D: run_and<addressing_mode::absolute>(); break; @@ -352,7 +371,7 @@ namespace nes { // ASL: Arithmetic Shift Left auto operand = fetch_operand<Mode>(); - eval_asl(operand.read()); + operand.write(eval_asl(operand.read())); current_cycles_ += shift_cycle_count<Mode>(); } @@ -613,7 +632,7 @@ namespace nes template<cpu::addressing_mode Mode> auto cpu::run_ahx() -> void { - // AHX: AND A X H + // AHX: ??? // TODO std::abort(); } @@ -694,7 +713,7 @@ namespace nes template<cpu::addressing_mode Mode> auto cpu::run_tas() -> void { - // TAS: S = A & X + AND S H + // TAS: ??? // TODO std::abort(); } @@ -702,7 +721,7 @@ namespace nes template<cpu::addressing_mode Mode> auto cpu::run_shy() -> void { - // SHY: AND Y H + // SHY: ??? // TODO std::abort(); } @@ -710,7 +729,7 @@ namespace nes template<cpu::addressing_mode Mode> auto cpu::run_shx() -> void { - // SHY: AND X H + // SHY: ??? // TODO std::abort(); } @@ -796,7 +815,7 @@ namespace nes template<cpu::addressing_mode Mode> auto cpu::run_las() -> void { - // LAS: AND S, store into A, X, S + // LAS: ??? // TODO std::abort(); } @@ -1055,7 +1074,7 @@ namespace nes registers_.a = new_val; registers_.c = tmp > 0xFF; - registers_.v = ((old_val ^ arg) & 0x80) == 0 && ((old_val ^ new_val) & 0x80) == 0; + registers_.v = ((old_val ^ arg) & 0x80) == 0 && ((old_val ^ new_val) & 0x80) != 0; update_alu_flags(registers_.a); } diff --git a/src/nes/cpu.hh b/src/nes/cpu.hh index 59f2db4..3587fd6 100644 --- a/src/nes/cpu.hh +++ b/src/nes/cpu.hh @@ -2,6 +2,7 @@ #include "nes/util/cycle_count.hh" #include "nes/util/address.hh" +#include "status.hh" namespace nes { @@ -114,7 +115,7 @@ namespace nes bool i : 1; // interrupt inhibit bool d : 1; // decimal bool b : 1; // break - bool _ : 1; // (unused, always true) + bool : 1; // (unused, always true) bool v : 1; // overflow bool n : 1; // negative }; @@ -130,6 +131,8 @@ namespace nes auto operator=(cpu const&) -> cpu& = delete; auto operator=(cpu&&) -> cpu& = delete; + auto snapshot(test::status&) -> void; + auto step_to(cycle_count) -> void; private: @@ -251,8 +254,8 @@ namespace nes template<> auto name##_cycle_count<addressing_mode::mode>() -> cycle_count { return cycle_count::from_cpu(value); } DEFINE_CYCLE_COUNT(jump) - DEFINE_CYCLE_COUNT_INSTANCE(jump, absolute, 2) - DEFINE_CYCLE_COUNT_INSTANCE(jump, indirect, 2) + DEFINE_CYCLE_COUNT_INSTANCE(jump, absolute, 3) + DEFINE_CYCLE_COUNT_INSTANCE(jump, indirect, 5) DEFINE_CYCLE_COUNT(shift) DEFINE_CYCLE_COUNT_INSTANCE(shift, accumulator, 2) diff --git a/src/nes/mapper.cc b/src/nes/mapper.cc index a540dbf..a451e3a 100644 --- a/src/nes/mapper.cc +++ b/src/nes/mapper.cc @@ -27,9 +27,13 @@ namespace nes auto mapper::nrom_read(address const addr) -> std::uint8_t { + if (addr <= address{ 0x5FFF }) + { + return 0x0; + } if (addr <= address{ 0x7FFF }) { - return cartridge_.get_ram()[addr.get_absolute() % 0x2000]; + return cartridge_.get_ram()[addr.get_absolute() - 0x6000]; } if (addr <= address{ 0xBFFF }) { @@ -52,9 +56,13 @@ namespace nes auto mapper::nrom_write(address const addr, std::uint8_t const value) -> void { + if (addr <= address{ 0x5FFF }) + { + return; + } if (addr <= address{ 0x7FFF }) { - cartridge_.get_ram_mut()[addr.get_absolute() % 0x2000] = value; + cartridge_.get_ram_mut()[addr.get_absolute() - 0x6000] = value; } } diff --git a/src/nes/nes.cc b/src/nes/nes.cc index 0579735..84f3309 100644 --- a/src/nes/nes.cc +++ b/src/nes/nes.cc @@ -10,6 +10,7 @@ namespace nes : cartridge_{ std::move(cartridge) } , display_{ display } , mapper_{ mapper::select(cartridge_) } + , ppu_{ cpu_, mapper_ } , cpu_{ ppu_, mapper_, controller_1_, controller_2_ } { if (!cartridge_.is_valid()) @@ -24,7 +25,12 @@ namespace nes auto nes::step(std::chrono::microseconds const delta) -> void { - current_cycles_ += cycle_count::from_duration(delta); + step(cycle_count::from_duration(delta)); + } + + auto nes::step(cycle_count const delta) -> void + { + current_cycles_ += delta; cpu_.step_to(current_cycles_); ppu_.step_to(current_cycles_); @@ -32,4 +38,12 @@ namespace nes display_.clear(rgb{ animation_progress_, animation_progress_, animation_progress_ }); display_.switch_buffers(); } + + auto nes::snapshot() -> test::status + { + auto res = test::status{}; + res.sram = std::vector(cartridge_.get_ram(), cartridge_.get_ram() + cartridge_.get_ram_length()); + cpu_.snapshot(res); + return res; + } } // namespace nes
\ No newline at end of file diff --git a/src/nes/nes.hh b/src/nes/nes.hh index be50bbb..2701f4b 100644 --- a/src/nes/nes.hh +++ b/src/nes/nes.hh @@ -6,6 +6,7 @@ #include "nes/cpu.hh" #include "nes/ppu.hh" #include "nes/mapper.hh" +#include "status.hh" namespace nes { @@ -38,5 +39,8 @@ namespace nes auto get_controller_2() -> controller& { return controller_2_; } auto step(std::chrono::microseconds delta) -> void; + auto step(cycle_count delta) -> void; + + auto snapshot() -> test::status; }; } // namespace nes
\ No newline at end of file diff --git a/src/nes/ppu.cc b/src/nes/ppu.cc index c2ec439..302b395 100644 --- a/src/nes/ppu.cc +++ b/src/nes/ppu.cc @@ -2,7 +2,17 @@ namespace nes { + ppu::ppu(cpu& cpu, mapper& mapper) + : cpu_{ cpu } + , mapper_{ mapper } + { + } + auto ppu::step_to(cycle_count const cycle) -> void { + while (current_cycles_ < cycle) + { + current_cycles_ += cycle_count::from_ppu(1); + } } } // namespace nes
\ No newline at end of file diff --git a/src/nes/ppu.hh b/src/nes/ppu.hh index edb7aba..8f116c7 100644 --- a/src/nes/ppu.hh +++ b/src/nes/ppu.hh @@ -4,10 +4,20 @@ namespace nes { + class cpu; + class mapper; + class ppu { + static constexpr auto vram_size = std::size_t{ 0x800 }; + + cycle_count current_cycles_; + cpu& cpu_; + mapper& mapper_; + std::uint8_t vram_[vram_size]{}; + public: - explicit ppu() = default; + explicit ppu(cpu& cpu, mapper& mapper); ppu(ppu const&) = delete; ppu(ppu&&) = delete; diff --git a/src/nes/util/address.hh b/src/nes/util/address.hh index 0161998..77ee76a 100644 --- a/src/nes/util/address.hh +++ b/src/nes/util/address.hh @@ -21,7 +21,7 @@ namespace nes /// Create an address from its page and offset combination. constexpr explicit address(std::uint8_t const page, std::uint8_t const offset) - : address{ static_cast<std::uint16_t>((page << 8) | (offset < 0)) } + : address{ static_cast<std::uint16_t>((page << 8) | (offset << 0)) } { } |
