From 2aa50d35322a35ca231f2078c2ed08148b97a135 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Wed, 24 Aug 2022 23:47:36 +0200 Subject: [PATCH] Emulator: Put startup into a Loader class --- src/loader.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/loader.h | 23 +++++++++++++++++++ src/main.cpp | 61 +++++++++----------------------------------------- 3 files changed, 92 insertions(+), 51 deletions(-) create mode 100644 src/loader.cpp create mode 100644 src/loader.h diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100644 index 0000000..69a5a3d --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 Riyyi + * + * SPDX-License-Identifier: MIT + */ + +#include "loader.h" +#include "cpu.h" +#include "emu.h" +#include "ppu.h" +#include "ruc/file.h" + +void Loader::init() +{ + destroy(); + + Emu::the().init(8000000); + + CPU cpu(8000000); + PPU ppu(4000000); + + Emu::the().addProcessingUnit("cpu", &cpu); + Emu::the().addProcessingUnit("ppu", &ppu); + + // https://gbdev.io/pandocs/Memory_Map.html + // https://gbdev.io/pandocs/Power_Up_Sequence.html + Emu::the().addMemorySpace("BOOTROM1", 0x0000, 0x00ff); // 256B + Emu::the().addMemorySpace("BOOTROM2", 0x0200, 0x08ff); // 1792B + Emu::the().addMemorySpace("VRAM", 0x8000, 0x9fff, 2); // 8KiB * 2 banks + Emu::the().addMemorySpace("CARDRAM", 0xa000, 0xbfff, 1); // 8KiB * ? banks, if any + Emu::the().addMemorySpace("WRAM1", 0xc000, 0xcfff); // 4 KiB, Work RAM + Emu::the().addMemorySpace("WRAM2", 0xd000, 0xdfff, 7); // 4 KiB * 7 banks, Work RAM + Emu::the().addMemorySpace("ECHORAM", 0xe000, 0xfdff); // 7680B, Mirror of 0xc000~0xddff + Emu::the().addMemorySpace("OAM", 0xfe00, 0xfe9f); // 160B, Object Attribute Memory (VRAM Sprite Attribute Table) + Emu::the().addMemorySpace("Not Usable", 0xfea0, 0xfeff); // 96B, Nintendo probibits this area + Emu::the().addMemorySpace("IO", 0xff00, 0xff7f); // 128B, I/O Registers + Emu::the().addMemorySpace("HRAM", 0xff80, 0xfffe); // 127B, High RAM (CPU cache) + Emu::the().addMemorySpace("IE", 0xffff, 0xffff); // 1B, Interrupt Enable register + + // Load bootrom + auto bootrom = ruc::File("gbc_bios.bin").data(); + for (size_t i = 0; i < bootrom.length(); ++i) { + // Skip cartridge header memory range + if (i >= 0x0100 && i <= 0x01ff) { + continue; + } + + Emu::the().writeMemory(i, bootrom[i]); + } + + while (true) { + Emu::the().update(); + } +} + +void Loader::destroy() +{ + Emu::destroy(); +} diff --git a/src/loader.h b/src/loader.h new file mode 100644 index 0000000..633388b --- /dev/null +++ b/src/loader.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 Riyyi + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include "ruc/singleton.h" +#include + +class Loader final : public ruc::Singleton { +public: + Loader(s) {} + + void init(); + void destroy(); + + void setRomPath(std::string_view rom_path) { m_rom_path = rom_path; } + +private: + std::string_view m_rom_path; +}; diff --git a/src/main.cpp b/src/main.cpp index 67cfc2f..b409f12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,63 +5,22 @@ * SPDX-License-Identifier: MIT */ -#include "cpu.h" -#include "emu.h" -#include "ppu.h" -#include "ruc/file.h" +#include "loader.h" +#include "ruc/argparser.h" #include "ruc/format/print.h" #include "ruc/timer.h" +#include -int main(int argc, char* argv[]) +int main(int argc, const char* argv[]) { - (void)argc; - (void)argv; + std::string_view rom_path; - ruc::Timer t; + ruc::ArgParser argParser; + argParser.addOption(rom_path, 'r', "rom", nullptr, nullptr, "", ruc::ArgParser::Required::Yes); + argParser.parse(argc, argv); - print("{}ms\n", t.elapsedNanoseconds() / 1000000.0); - - Emu::the().init(8000000); - - CPU cpu(8000000); - PPU ppu(4000000); - - Emu::the().addProcessingUnit("cpu", &cpu); - Emu::the().addProcessingUnit("ppu", &ppu); - - // https://gbdev.io/pandocs/Memory_Map.html - // https://gbdev.io/pandocs/Power_Up_Sequence.html - Emu::the().addMemorySpace("BOOTROM1", 0x0000, 0x00ff); // 256B - Emu::the().addMemorySpace("BOOTROM2", 0x0200, 0x08ff); // 1792B - Emu::the().addMemorySpace("VRAM", 0x8000, 0x9fff, 2); // 8KiB * 2 banks - Emu::the().addMemorySpace("CARDRAM", 0xa000, 0xbfff, 1); // 8KiB * ? banks, if any - Emu::the().addMemorySpace("WRAM1", 0xc000, 0xcfff); // 4 KiB, Work RAM - Emu::the().addMemorySpace("WRAM2", 0xd000, 0xdfff, 7); // 4 KiB * 7 banks, Work RAM - Emu::the().addMemorySpace("ECHORAM", 0xe000, 0xfdff); // 7680B, Mirror of 0xc000~0xddff - Emu::the().addMemorySpace("OAM", 0xfe00, 0xfe9f); // 160B, Object Attribute Memory (VRAM Sprite Attribute Table) - Emu::the().addMemorySpace("Not Usable", 0xfea0, 0xfeff); // 96B, Nintendo probibits this area - Emu::the().addMemorySpace("IO", 0xff00, 0xff7f); // 128B, I/O Registers - Emu::the().addMemorySpace("HRAM", 0xff80, 0xfffe); // 127B, High RAM (CPU cache) - Emu::the().addMemorySpace("IE", 0xffff, 0xffff); // 1B, Interrupt Enable register - - // Load bootrom - auto bootrom = ruc::File("gbc_bios.bin").data(); - for (size_t i = 0; i < bootrom.length(); ++i) { - // Skip cartridge header memory range - if (i >= 0x0100 && i <= 0x01ff) { - continue; - } - - Emu::the().writeMemory(i, bootrom[i]); - } - - // Get shared register - print("{}\n", *Emu::the().processingUnit("cpu")->sharedRegister("a")); - print("{}\n", *Emu::the().processingUnit("cpu")->sharedRegister("b")); - - while (true) { - Emu::the().update(); - } + Loader::the().setRomPath(rom_path); + Loader::the().init(); return 0; }