diff --git a/NES Emulator/CMakeLists.txt b/NES Emulator/CMakeLists.txt index 257ec8b..3caca6e 100644 --- a/NES Emulator/CMakeLists.txt +++ b/NES Emulator/CMakeLists.txt @@ -1,3 +1,11 @@ cmake_minimum_required (VERSION 3.8) -add_executable (CMakeTarget "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c") +add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c") + +if(MSVC) +target_compile_definitions(nesemu PUBLIC _CRT_SECURE_NO_WARNINGS) +endif() + +add_custom_command(TARGET nesemu POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/roms $<TARGET_FILE_DIR:nesemu>/roms +) \ No newline at end of file diff --git a/NES Emulator/bus.c b/NES Emulator/bus.c index 9410ed8..9530767 100644 --- a/NES Emulator/bus.c +++ b/NES Emulator/bus.c @@ -26,7 +26,7 @@ struct Bus* createBus() bus->cpu = createCPU(bus); // Create and insert cartridge - bus->cartridge = createCartridge(bus, "nestest.nes"); + bus->cartridge = createCartridge(bus, "roms/nestest.nes"); return bus; } @@ -42,10 +42,12 @@ void destroyBus(struct Bus* bus) Byte Read(struct Bus* bus, Word addr) { + Byte val = 0; + // Return from the appropriate device depending on the address if (addr <= 0x1FFF) // RAM (or one of the mirrored addresses) { - return bus->ram[addr & 0x7FF]; + val = bus->ram[addr & 0x7FF]; } else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space { @@ -56,6 +58,8 @@ Byte Read(struct Bus* bus, Word addr) fprintf(stderr, "Access violation at $%x", addr); exit(1); } + + return val; } void Write(struct Bus* bus, Word addr, Byte val) diff --git a/NES Emulator/cartridge.c b/NES Emulator/cartridge.c index df37464..3b8b105 100644 --- a/NES Emulator/cartridge.c +++ b/NES Emulator/cartridge.c @@ -4,6 +4,33 @@ #include "bus.h" +struct INES_Header +{ + Byte nestext[4]; + Byte prg_rom_size; + Byte chr_rom_size; + + struct + { + Byte mirror : 1; + Byte battery : 1; + Byte trainer : 1; + Byte ignore_mirror : 1; + Byte mapper_lower_nibble : 4; + } Flags6; + + struct + { + Byte vs : 1; + Byte playchoice : 1; + Byte nes20 : 2; + Byte mapper_upper_nibble : 4; + } Flags7; + + Byte prg_ram_size; + Byte unused[7]; +}; + struct Cartridge* createCartridge(struct Bus* parent, const char* filepath) { struct Cartridge* cartridge = (struct Cartridge*)malloc(sizeof(struct Cartridge)); @@ -13,13 +40,35 @@ struct Cartridge* createCartridge(struct Bus* parent, const char* filepath) exit(1); } - cartridge->memory = NULL; + // Open ROM + FILE* fp = fopen(filepath, "rb"); + + // Read header + struct INES_Header header; + fread(&header, sizeof(header), 1, fp); + + cartridge->prg_rom = (Byte*)malloc(0x4000 * (size_t)header.prg_rom_size); + if (cartridge->prg_rom == NULL) + { + fprintf(stderr, "Failed to allocate PRG memory for cartridge, aborting.\n"); + exit(1); + } + + cartridge->chr_rom = (Byte*)malloc(0x2000 * (size_t)header.chr_rom_size); + if (cartridge->prg_rom == NULL) + { + fprintf(stderr, "Failed to allocate CHR memory for cartridge, aborting.\n"); + exit(1); + } + cartridge->bus = parent; return cartridge; } void destroyCartridge(struct Cartridge* cartridge) { - // free(cartridge->memory); + free(cartridge->chr_rom); + free(cartridge->prg_rom); + free(cartridge); } diff --git a/NES Emulator/cartridge.h b/NES Emulator/cartridge.h index fb9dc64..6bdcf37 100644 --- a/NES Emulator/cartridge.h +++ b/NES Emulator/cartridge.h @@ -7,7 +7,8 @@ struct Bus; struct Cartridge { - Byte* memory; + Byte* prg_rom; + Byte* chr_rom; struct Bus* bus; }; diff --git a/roms/nestest.nes b/roms/nestest.nes new file mode 100644 index 0000000..fc2a88c Binary files /dev/null and b/roms/nestest.nes differ