Skip to content

Commit

Permalink
add nestest
Browse files Browse the repository at this point in the history
  • Loading branch information
itsvic-dev committed May 3, 2024
1 parent 2620cfd commit 3a6eebe
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 7 deletions.
57 changes: 57 additions & 0 deletions example/nestest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// (improperly) loads an NES ROM file to $C000 and begins execution there

#include "v6502/cpu.h"
#include "v6502/memory.h"
#include "v6502/print.h"
#include <fstream>

class SimpleRAMBus : public MemoryBus {
public:
SimpleRAMBus() { ram = new uint8_t[0x10000]; }
~SimpleRAMBus() { delete[] ram; }

uint8_t read(uint16_t addr) override { return ram[addr]; }
void write(uint16_t addr, uint8_t data) override { ram[addr] = data; }

private:
uint8_t *ram;
};

int main(int argc, char **argv) {
if (argc < 2) {
print("usage: {} <binary file>\nprogram will be loaded to $6000 and "
"executed until it reaches the end\n",
argv[0]);
return -1;
}

SimpleRAMBus bus;
CPU cpu(&bus);

uint16_t addr = 0xC000;
{
std::ifstream bin(argv[1]);
char byte;
while (bin.get(byte)) {
// offset by the NES file header lol
bus.write((addr++) - 16, byte);
}
}

bus.write(0xFFFC, 0x00);
bus.write(0xFFFD, 0xC0);

print("resetting CPU\n");
cpu.reset();

try {
while (true) {
cpu.executeStep();
}
} catch (...) {
print("[warn] execution ended prematurely due to a v6502 error!!!\n");
}

print("\n---\nresults: {:02x} {:02x}\n", bus.read(2), bus.read(3));
return 0;
}
4 changes: 2 additions & 2 deletions inc/v6502/print.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
#include <format>
#include <iostream>

#define print(...) std::cout << std::format(__VA_ARGS__)
#define print_err(...) std::cerr << std::format(__VA_ARGS__)
#define print(...) std::cout << std::format(__VA_ARGS__) << std::flush
#define print_err(...) std::cerr << std::format(__VA_ARGS__) << std::flush
6 changes: 6 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,9 @@ executable(
'example/loadram.cpp',
dependencies: v6502_dep,
)

executable(
'v6502_nestest',
'example/nestest.cpp',
dependencies: v6502_dep,
)
13 changes: 8 additions & 5 deletions src/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,14 @@ static uint16_t getDisasmOperand(CPU *cpu, AddressingMode mode) {
case Y_ZERO_PAGE:
case X_ZP_INDIRECT:
case ZP_INDIRECT_Y:
return cpu->bus->read(cpu->pc - 1);
return cpu->bus->read(cpu->pc);
case ABSOLUTE:
case X_ABSOLUTE:
case Y_ABSOLUTE:
return cpu->readWord(cpu->pc - 2);
case ABSOLUTE_INDIRECT:
return cpu->readWord(cpu->pc);
case RELATIVE:
return cpu->pc + (int8_t)(cpu->readWord(cpu->pc - 2));
return cpu->pc + 2 + (int8_t)(cpu->readWord(cpu->pc));
default:
return 0;
}
Expand All @@ -126,14 +127,16 @@ void CPU::executeStep() {
uint8_t opcode = fetchByte();
if (!cpuOpcodes.contains(opcode)) {
print_err("[v6502] unknown CPU opcode encountered: {:02x}\n", opcode);
std::terminate();
throw 1;
}
auto instruction = cpuOpcodes[opcode];
instruction.function(this, instruction.mode);
#ifdef V6502_DEBUG
char disasmInstruction[256] = {0};
snprintf(disasmInstruction, 256, instruction.basicInfo.c_str(),
getDisasmOperand(this, instruction.mode));
#endif
instruction.function(this, instruction.mode);
#ifdef V6502_DEBUG
print_err(
"{: <16} A:{:02x} X:{:02x} Y:{:02x} P:{:02x} SP:{:02x} PC:{:04x}\n",
disasmInstruction, a, x, y, status, sp, pc);
Expand Down

0 comments on commit 3a6eebe

Please sign in to comment.