From 8bfb3cb9b907fd6deb768918c400a073fcebb471 Mon Sep 17 00:00:00 2001 From: Amish Naidu Date: Sun, 10 Jul 2016 20:35:47 +0530 Subject: [PATCH] Added Cartridge class and worked on it and MainMemory a bit --- .gitignore | 1 + include/Cartridge.h | 27 ++++++++++++++ include/MainMemory.h | 10 ++--- main.cpp | 2 +- src/Cartridge.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++ src/MainMemory.cpp | 28 +++++++++++--- 6 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 include/Cartridge.h create mode 100644 src/Cartridge.cpp diff --git a/.gitignore b/.gitignore index 94f4f7b..56e1542 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.cbp *.depend *.kdev4 +.kdev* build/ diff --git a/include/Cartridge.h b/include/Cartridge.h new file mode 100644 index 0000000..22f72e6 --- /dev/null +++ b/include/Cartridge.h @@ -0,0 +1,27 @@ +#ifndef CARTRIDGE_H +#define CARTRIDGE_H + +namespace +{ + using Byte = uint8_t; + using Address = uint16_t; + + class Cartridge + { + public: + Cartridge(); + bool loadFromFile(std::string path); + const std::vector& getROM(); + const std::vector& getVROM(); + Byte getMapper(); + private: + std::vector m_PRG_ROM; + std::vector m_CHR_ROM; + Byte m_nameTableMirroring; + Byte m_mapper; + bool m_extendedRAM; + }; + +} + +#endif // CARTRIDGE_H diff --git a/include/MainMemory.h b/include/MainMemory.h index 3bf9fae..e1d64fd 100644 --- a/include/MainMemory.h +++ b/include/MainMemory.h @@ -1,21 +1,21 @@ #ifndef MEMORY_H #define MEMORY_H #include -#include +#include "Cartridge.h" namespace sn { - using Byte = uint8_t; - using Address = uint16_t; class MainMemory { public: MainMemory(); Byte& operator[](Address addr); - void set(std::size_t start, std::size_t length, Byte* pointer); + bool loadCartridge(Cartridge *cart); private: - std::vector mem; + std::vector m_data; + Cartridge* m_cartride; + Byte m_mapper; }; }; diff --git a/main.cpp b/main.cpp index d4c7ca2..7c906e8 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,6 @@ #include #include "CPU.h" -#include +#include "Cartridge.h" int main() { diff --git a/src/Cartridge.cpp b/src/Cartridge.cpp new file mode 100644 index 0000000..2a4c6d5 --- /dev/null +++ b/src/Cartridge.cpp @@ -0,0 +1,89 @@ +#include "Cartridge.h" +#include +#include +#include + +namespace sn +{ + Cartridge::Cartridge() : + m_nameTableMirroring(0), + m_mapper(0), + m_extendedRAM(false) + { + + } + const std::vector& Cartridge::getROM() + { + return m_PRG_ROM; + } + + const std::vector& Cartridge::getVROM() + { + return m_CHR_ROM; + } + + Byte Cartridge::getMapper() + { + return m_mapper; + } + + bool Cartridge::loadFromFile(std::string path) + { + std::ifstream romFile (path); + if (!romFile) + { + std::cerr << "Could not open ROM file" << std::endl; + return false; + } + + std::vector header; + + //Header + header.resize(0x10); + if (!romFile.read(&header[0], 0x10)) + { + std::cerr << "Reading iNES header failed." << std::endl; + return false; + } + if (std::string{&header[0], &header[3]} != "NES\x1A") + { + std::cerr << "Not a valid iNES image.\n" << std::endl; + return false; + } + Byte banks = header[4]; + if (!banks) + { + std::cerr << "ROM has no PRG-ROM banks. Loading ROM failed." << std::endl; + return false; + } + Byte vbanks = header[5]; + m_nameTableMirroring = header[6] & 0x9; + m_mapper = ((header[6] >> 4) & 0xf) | (header[7] & 0xf0); + m_extendedRAM = header[6] & 0x2; //we don't care + if (header[6] & 0x4) + { + std::cerr << "Trainer is not supported." << std::endl; + return false; + } + + //PRG-ROM + m_PRG_ROM.resize(0x4000 * banks); + if (!romFile.read(&m_PRG_ROM[0], 0x4000 * banks)) + { + std::cerr << "Reading PRG-ROM from image file failed." << std::endl; + return false; + } + + //CHR-ROM + if (vbanks) + { + m_CHR_ROM.reserve(0x2000 * vbanks); + if (!romFile.read(&m_CHR_ROM[0], 0x2000 * vbanks)) + { + std::cerr << "Reading CHR-ROM from image file failed." << std::endl; + return false; + } + } + } + +} diff --git a/src/MainMemory.cpp b/src/MainMemory.cpp index d457830..9dee556 100644 --- a/src/MainMemory.cpp +++ b/src/MainMemory.cpp @@ -4,20 +4,38 @@ namespace sn { MainMemory::MainMemory() : - mem(0x10000, 0) + mem(0x10000, 0), + m_cartride(nullptr) { } Byte& MainMemory::operator[](Address addr) { if (addr < 0x2000) - return mem[addr & 0x1fff]; - return mem[addr]; + return m_data[addr & 0x1fff]; + return m_data[addr]; } - void MainMemory::set(std::size_t start, std::size_t length, Byte* pointer) + bool MainMemory::loadCartridge(Cartridge* cart) { - std::memcpy(&mem[start], pointer, length); + m_mapper = cart->getMapper(); + auto rom = cart->getROM(); + if (m_mapper != 0) + { + std::cerr << "Mapper not supported" << endl; + return false; + } + + if (rom.size() == 0x4000) //1 bank + { + std::memcpy(&m_data[0x8000], &rom[0], 0x4000); + std::memcpy(&m_data[0xc000], &rom[0], 0x4000); + } + else //2 banks + { + std::memcpy(&m_data[0x8000], &rom[0], 0x4000); + std::memcpy(&m_data[0xc000], &rom[0x4000], 0x4000); + } } };