// // Created by Selim Mustafaev on 09.08.2023. // #ifndef NES_CARTRIDGE_H #define NES_CARTRIDGE_H #include "Mapper/Mapper.h" #include #include #include namespace nes { namespace fs = std::filesystem; constexpr uint8_t ROM_MAGIC[4] = { 'N', 'E', 'S', 0x1a }; constexpr size_t PRG_CHUNK_SIZE = 16*1024; constexpr size_t CHR_CHUNK_SIZE = 8*1024; class Cartridge { public: enum Mirroring: uint8_t { Horizontal = 0, Vertical = 1 }; struct Flags { Mirroring mirroring: 1; uint8_t batteryBacked: 1; uint8_t trainer: 1; uint8_t nametableAltLayout: 1; uint8_t mapper: 4; }; struct Flags2 { uint8_t reserved: 2; uint8_t version: 2; uint8_t upperMapper: 4; }; struct RomHeader { uint8_t magic[4]; uint8_t prgChunks; uint8_t chrChunks; Flags flags; Flags2 flags2; uint8_t prgRamSize; uint8_t reserved[7]; }; public: explicit Cartridge(const fs::path& path); public: uint8_t readPrg(uint16_t address); void writePrg(uint16_t address, uint8_t value); uint8_t readChr(uint16_t address); void writeChr(uint16_t address, uint8_t value); uint8_t readRam(uint16_t address); void writeRam(uint16_t address, uint8_t value); Mirroring mirroring() const; private: std::unique_ptr _romData; std::unique_ptr _mapper; RomHeader* _header; std::span _prgRom; std::span _chrRom; std::unique_ptr _ram; std::unique_ptr _chrRam; }; } #endif //NES_CARTRIDGE_H