commit 5aa8a648718ee86dbe5a9993e169616c84627790 Author: Lauchmelder Date: Wed Oct 20 22:39:29 2021 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a5c2d2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vs/ +out/ +*.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f6dd089 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +# CMakeList.txt: CMake-Projektdatei der obersten Ebene. Führen Sie hier die globale Konfiguration aus, +# und schließen Sie Unterprojekte ein. +# +cmake_minimum_required (VERSION 3.8) + +project ("NES Emulator") + +# Schließen Sie Unterprojekte ein. +add_subdirectory ("NES Emulator") diff --git a/NES Emulator/CMakeLists.txt b/NES Emulator/CMakeLists.txt new file mode 100644 index 0000000..257ec8b --- /dev/null +++ b/NES Emulator/CMakeLists.txt @@ -0,0 +1,3 @@ +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") diff --git a/NES Emulator/bus.c b/NES Emulator/bus.c new file mode 100644 index 0000000..9410ed8 --- /dev/null +++ b/NES Emulator/bus.c @@ -0,0 +1,77 @@ +#include "bus.h" +#include +#include + +#include "cpu.h" +#include "cartridge.h" + +struct Bus* createBus() +{ + struct Bus* bus = (struct Bus*)malloc(sizeof(struct Bus)); + if (bus == NULL) + { + fprintf(stderr, "Failed to create Bus object, aborting."); + exit(1); + } + + // 2KB of memory, equates to 2048 Bytes (0x800) + bus->ram = (Byte*)malloc(0x800); + if (bus->ram == NULL) + { + fprintf(stderr, "Failed to allocate memory for NES RAM, aborting."); + exit(1); + } + + // Create CPU and attach it + bus->cpu = createCPU(bus); + + // Create and insert cartridge + bus->cartridge = createCartridge(bus, "nestest.nes"); + + return bus; +} + +void destroyBus(struct Bus* bus) +{ + destroyCartridge(bus->cartridge); + destroyCPU(bus->cpu); + + free(bus->ram); + free(bus); +} + +Byte Read(struct Bus* bus, Word addr) +{ + // Return from the appropriate device depending on the address + if (addr <= 0x1FFF) // RAM (or one of the mirrored addresses) + { + return bus->ram[addr & 0x7FF]; + } + else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space + { + // rom->read() + } + else + { + fprintf(stderr, "Access violation at $%x", addr); + exit(1); + } +} + +void Write(struct Bus* bus, Word addr, Byte val) +{ + // Write to the appropriate memory or device + if (addr <= 0x1FFF) // RAM (or one of the mirrored addresses) + { + bus->ram[addr & 0x7FF] = val; + } + else if (0x4020 <= addr && addr <= 0xFFFF) // Cartridge space + { + // rom->write() + } + else + { + fprintf(stderr, "Access violation at $%x", addr); + exit(1); + } +} diff --git a/NES Emulator/bus.h b/NES Emulator/bus.h new file mode 100644 index 0000000..92b29d4 --- /dev/null +++ b/NES Emulator/bus.h @@ -0,0 +1,28 @@ +#ifndef _BUS_H_ +#define _BUS_H_ + +#include "types.h" + +struct CPU; +struct Cartridge; + +// Main communication path for devices and memory in the NES +struct Bus +{ + Byte* ram; + + struct CPU* cpu; + struct Cartridge* cartridge; +}; + +// Sets up the Bus, allocates memory and creates devices +struct Bus* createBus(); + +// Destroys the bus, cleans up memory and destroys devices on the Bus +void destroyBus(struct Bus* bus); + +// Read/Write to and from the bus +Byte Read(struct Bus* bus, Word addr); +void Write(struct Bus* bus, Word addr, Byte val); + +#endif // _BUS_H_ \ No newline at end of file diff --git a/NES Emulator/cartridge.c b/NES Emulator/cartridge.c new file mode 100644 index 0000000..df37464 --- /dev/null +++ b/NES Emulator/cartridge.c @@ -0,0 +1,25 @@ +#include "cartridge.h" +#include +#include + +#include "bus.h" + +struct Cartridge* createCartridge(struct Bus* parent, const char* filepath) +{ + struct Cartridge* cartridge = (struct Cartridge*)malloc(sizeof(struct Cartridge)); + if (cartridge == NULL) + { + fprintf(stderr, "Failed to create cartridge.\n"); + exit(1); + } + + cartridge->memory = NULL; + cartridge->bus = parent; + return cartridge; +} + +void destroyCartridge(struct Cartridge* cartridge) +{ + // free(cartridge->memory); + free(cartridge); +} diff --git a/NES Emulator/cartridge.h b/NES Emulator/cartridge.h new file mode 100644 index 0000000..fb9dc64 --- /dev/null +++ b/NES Emulator/cartridge.h @@ -0,0 +1,18 @@ +#ifndef _CARTRIDGE_H_ +#define _CARTRIDGE_H_ + +#include "types.h" + +struct Bus; + +struct Cartridge +{ + Byte* memory; + + struct Bus* bus; +}; + +struct Cartridge* createCartridge(struct Bus* parent, const char* filepath); +void destroyCartridge(struct Cartridge* cartridge); + +#endif //_CARTRIDGE_H_ \ No newline at end of file diff --git a/NES Emulator/cpu.c b/NES Emulator/cpu.c new file mode 100644 index 0000000..2d57c40 --- /dev/null +++ b/NES Emulator/cpu.c @@ -0,0 +1,23 @@ +#include "cpu.h" +#include +#include + +#include "bus.h" + +struct CPU* createCPU(struct Bus* parent) +{ + struct CPU* cpu = (struct CPU*)malloc(sizeof(struct CPU)); + if (cpu == NULL) + { + fprintf(stderr, "Failed to create CPU, aborting.\n"); + exit(1); + } + + cpu->bus = parent; + return cpu; +} + +void destroyCPU(struct CPU* cpu) +{ + free(cpu); +} diff --git a/NES Emulator/cpu.h b/NES Emulator/cpu.h new file mode 100644 index 0000000..3a7e88e --- /dev/null +++ b/NES Emulator/cpu.h @@ -0,0 +1,38 @@ +#ifndef _CPU_H_ +#define _CPU_H_ + +#include "types.h" + +struct Bus; + +struct CPU +{ + Byte acc; + Byte x, y; + Byte sp; + + union + { + struct + { + Byte carry : 1; + Byte zero : 1; + Byte id : 1; + Byte decimal : 1; + Byte unused : 2; + Byte overflow : 1; + Byte negative : 1; + }; + + Byte raw; + } status; + + Word pc; + + struct Bus* bus; +}; + +struct CPU* createCPU(struct Bus* parent); +void destroyCPU(struct CPU* cpu); + +#endif // _CPU_H_ \ No newline at end of file diff --git a/NES Emulator/main.c b/NES Emulator/main.c new file mode 100644 index 0000000..2087b1f --- /dev/null +++ b/NES Emulator/main.c @@ -0,0 +1,9 @@ +#include "bus.h" + +int main() +{ + struct Bus* bus = createBus(); + destroyBus(bus); + + return 0; +} diff --git a/NES Emulator/types.h b/NES Emulator/types.h new file mode 100644 index 0000000..8770d55 --- /dev/null +++ b/NES Emulator/types.h @@ -0,0 +1,10 @@ +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#include + +typedef uint8_t Byte; +typedef uint16_t Word; +typedef uint32_t DWord; + +#endif // _TYPES_H_ \ No newline at end of file