From 2b71e3e0d2aa0ce9e350ad93c08ec60c58b2c7e5 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sat, 23 Oct 2021 20:36:38 +0200 Subject: [PATCH] added SDL --- CMakeLists.txt | 7 ++---- NES Emulator/CMakeLists.txt | 3 +++ NES Emulator/bus.c | 26 +++++++++++++++++---- NES Emulator/bus.h | 6 ++++- NES Emulator/cpu.c | 4 ++-- NES Emulator/main.c | 46 ++++++++++++++++++++++++++++++++++--- NES Emulator/ppu.c | 10 +++++--- NES Emulator/ppu.h | 5 ++-- 8 files changed, 85 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6dd089..61e7eb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,6 @@ -# 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) +cmake_minimum_required (VERSION 3.8) project ("NES Emulator") -# Schließen Sie Unterprojekte ein. +add_subdirectory ("vendor/SDL") add_subdirectory ("NES Emulator") diff --git a/NES Emulator/CMakeLists.txt b/NES Emulator/CMakeLists.txt index f37c02f..aa29dc1 100644 --- a/NES Emulator/CMakeLists.txt +++ b/NES Emulator/CMakeLists.txt @@ -2,6 +2,9 @@ add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.h" "ppu.c") +target_include_directories(nesemu PUBLIC SDL2-static) +target_link_libraries(nesemu PUBLIC SDL2-static SDL2main) + if(MSVC) target_compile_definitions(nesemu PUBLIC _CRT_SECURE_NO_WARNINGS) endif() diff --git a/NES Emulator/bus.c b/NES Emulator/bus.c index 31429b7..c4259b5 100644 --- a/NES Emulator/bus.c +++ b/NES Emulator/bus.c @@ -42,7 +42,7 @@ struct Bus* createBus() // Create PPU and attack it bus->ppu = createPPU(bus); - printf("Reset vector: $%x\n", ((Word)readCartridge(bus->cartridge, 0xFFFD) << 8) | (readCartridge(bus->cartridge, 0xFFFC))); + bus->masterClockTimer = 0; return bus; } @@ -115,10 +115,26 @@ void writeBus(struct Bus* bus, Word addr, Byte val) } -void tick(struct Bus* bus) +int tick(struct Bus* bus) { - for (int i = 0; i < 3; i++) - tickPPU(bus->ppu); + bus->masterClockTimer++; - tickCPU(bus->cpu); + tickPPU(bus->ppu); + if (bus->masterClockTimer == 3) + { + tickCPU(bus->cpu); + bus->masterClockTimer = 0; + } +} + +int doInstruction(struct Bus* bus) +{ + while(bus->cpu->remainingCycles > 0) + tick(bus); + tick(bus); +} + +int doFrame(struct Bus* bus) +{ + do tick(bus); while (bus->ppu->x != 0 || bus->ppu->y != 0); } \ No newline at end of file diff --git a/NES Emulator/bus.h b/NES Emulator/bus.h index e9b2d39..2c2e3d0 100644 --- a/NES Emulator/bus.h +++ b/NES Emulator/bus.h @@ -16,6 +16,8 @@ struct Bus struct CPU* cpu; struct PPU* ppu; struct Cartridge* cartridge; + + Byte masterClockTimer; }; // Sets up the Bus, allocates memory and creates devices @@ -30,6 +32,8 @@ void writeBus(struct Bus* bus, Word addr, Byte val); // Ticks the master clock 12 times (i.e. 1 CPU tick & 3 PPU dots) -void tick(struct Bus* bus); +int tick(struct Bus* bus); +int doInstruction(struct Bus* bus); +int doFrame(struct Bus* bus); #endif // _BUS_H_ \ No newline at end of file diff --git a/NES Emulator/cpu.c b/NES Emulator/cpu.c index 4e35d7a..9042d3e 100644 --- a/NES Emulator/cpu.c +++ b/NES Emulator/cpu.c @@ -25,7 +25,7 @@ struct CPU* createCPU(struct Bus* parent) } // TODO: THIS IS JUST FOR THE TEST ROM - // cpu->pc.word = 0xC000; + cpu->pc.word = 0xC000; cpu->pc.word = ((Word)readBus(parent, 0xFFFD) << 8) | readBus(parent, 0xFFFC); cpu->status.raw = 0x34; @@ -189,7 +189,7 @@ void fetch(struct CPU* cpu) void execute(struct CPU* cpu) { - LOG_BUS(cpu->bus); + // LOG_BUS(cpu->bus); switch (cpu->currentOpcode->op) { diff --git a/NES Emulator/main.c b/NES Emulator/main.c index 75be372..c3d7ff5 100644 --- a/NES Emulator/main.c +++ b/NES Emulator/main.c @@ -1,15 +1,55 @@ #include "bus.h" -int main() +#include +#include + +int main(int argc, char** argv) { + SDL_Init(SDL_INIT_VIDEO); + + SDL_Window* window = SDL_CreateWindow("NES Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_SHOWN); + if (window == NULL) + { + fprintf(stderr, "Failed to create SDL_Window.\n"); + exit(1); + } + + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (renderer == NULL) + { + fprintf(stderr, "Failed to create SDL_Renderer\n"); + exit(1); + } + struct Bus* bus = createBus(); - for (;;) + SDL_Event event; + int running = 1; + while(running) { - tick(bus); + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_WINDOWEVENT: + { + switch (event.window.event) + { + case SDL_WINDOWEVENT_CLOSE: + running = 0; + break; + } + } break; + } + } + + + doFrame(bus); } destroyBus(bus); + SDL_Quit(); + return 0; } diff --git a/NES Emulator/ppu.c b/NES Emulator/ppu.c index f723d27..c9d7f8d 100644 --- a/NES Emulator/ppu.c +++ b/NES Emulator/ppu.c @@ -76,8 +76,10 @@ void destroyPPU(struct PPU* ppu) { free(ppu->oam); free(ppu->paletteIndexes); - free(ppu->nametables); - free(ppu->patternTables); + for(int i = 0; i < 4; i++) + free(ppu->nametables[i]); + for (int i = 0; i < 2; i++) + free(ppu->patternTables[i]); free(ppu); } @@ -152,7 +154,7 @@ void ppuWrite(struct PPU* ppu, Word addr, Byte val) } } -void tickPPU(struct PPU* ppu) +int tickPPU(struct PPU* ppu) { ppu->x++; @@ -164,4 +166,6 @@ void tickPPU(struct PPU* ppu) if (ppu->y == 261) ppu->y = 0; } + + return (ppu->x == 0 && ppu->y == 0); } diff --git a/NES Emulator/ppu.h b/NES Emulator/ppu.h index f5b8d71..eb4a06d 100644 --- a/NES Emulator/ppu.h +++ b/NES Emulator/ppu.h @@ -2,6 +2,7 @@ #define _PPU_H_ #include "types.h" +#include "SDL.h" struct Bus; @@ -94,8 +95,6 @@ struct PPU Word x, y; - - struct Bus* bus; }; @@ -105,6 +104,6 @@ void destroyPPU(struct PPU* ppu); Byte ppuRead(struct PPU* ppu, Word addr); void ppuWrite(struct PPU* ppu, Word addr, Byte val); -void tickPPU(struct PPU* ppu); +int tickPPU(struct PPU* ppu); #endif // _PPU_H_ \ No newline at end of file