Added Cartridge class and worked on it and MainMemory a bit

This commit is contained in:
Amish Naidu 2016-07-10 20:35:47 +05:30
parent 21af8b990b
commit 8bfb3cb9b9
6 changed files with 146 additions and 11 deletions

1
.gitignore vendored
View file

@ -2,4 +2,5 @@
*.cbp
*.depend
*.kdev4
.kdev*
build/

27
include/Cartridge.h Normal file
View file

@ -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<Byte>& getROM();
const std::vector<Byte>& getVROM();
Byte getMapper();
private:
std::vector<Byte> m_PRG_ROM;
std::vector<Byte> m_CHR_ROM;
Byte m_nameTableMirroring;
Byte m_mapper;
bool m_extendedRAM;
};
}
#endif // CARTRIDGE_H

View file

@ -1,21 +1,21 @@
#ifndef MEMORY_H
#define MEMORY_H
#include <vector>
#include <cstdint>
#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<Byte> mem;
std::vector<Byte> m_data;
Cartridge* m_cartride;
Byte m_mapper;
};
};

View file

@ -1,6 +1,6 @@
#include <iostream>
#include "CPU.h"
#include <fstream>
#include "Cartridge.h"
int main()
{

89
src/Cartridge.cpp Normal file
View file

@ -0,0 +1,89 @@
#include "Cartridge.h"
#include <fstream>
#include <iostream>
#include <string>
namespace sn
{
Cartridge::Cartridge() :
m_nameTableMirroring(0),
m_mapper(0),
m_extendedRAM(false)
{
}
const std::vector<Byte>& Cartridge::getROM()
{
return m_PRG_ROM;
}
const std::vector<Byte>& 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<Byte> 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;
}
}
}
}

View file

@ -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);
}
}
};