mirror of
https://github.com/amhndu/SimpleNES.git
synced 2024-06-12 01:16:57 -04:00
add mappercontrolled mirroring, fix irq callback
This commit is contained in:
parent
3334273032
commit
9a73b46afe
|
@ -1,5 +1,6 @@
|
|||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
#include "CPUOpcodes.h"
|
||||
#include "MainBus.h"
|
||||
|
||||
namespace sn
|
||||
|
@ -8,12 +9,6 @@ namespace sn
|
|||
class CPU
|
||||
{
|
||||
public:
|
||||
enum InterruptType
|
||||
{
|
||||
IRQ,
|
||||
NMI,
|
||||
BRK_
|
||||
};
|
||||
|
||||
CPU(MainBus &mem);
|
||||
|
||||
|
|
|
@ -120,8 +120,15 @@ namespace sn
|
|||
TSX = 0xba,
|
||||
};
|
||||
|
||||
enum InterruptType
|
||||
{
|
||||
IRQ,
|
||||
NMI,
|
||||
BRK_
|
||||
};
|
||||
|
||||
//0 implies unused opcode
|
||||
int OperationCycles[0x100] = {
|
||||
static const int OperationCycles[0x100] = {
|
||||
7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
|
||||
2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
|
||||
6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef MAPPER_H
|
||||
#define MAPPER_H
|
||||
#include "CPUOpcodes.h"
|
||||
#include "Cartridge.h"
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
@ -13,6 +14,7 @@ namespace sn
|
|||
FourScreen = 8,
|
||||
OneScreenLower,
|
||||
OneScreenHigher,
|
||||
MapperControlled,
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,7 +56,7 @@ namespace sn
|
|||
|
||||
virtual void scanlineIRQ(){}
|
||||
|
||||
static std::unique_ptr<Mapper> createMapper (Type mapper_t, Cartridge& cart, std::function<void(int)> interrupt_cb, std::function<void(void)> mirroring_cb);
|
||||
static std::unique_ptr<Mapper> createMapper (Type mapper_t, Cartridge& cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb);
|
||||
|
||||
protected:
|
||||
Cartridge& m_cartridge;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace sn
|
|||
class MapperMMC3 : public Mapper
|
||||
{
|
||||
public:
|
||||
MapperMMC3(Cartridge &cart, std::function<void(int)> interrupt_cb, std::function<void(void)> mirroring_cb);
|
||||
MapperMMC3(Cartridge &cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb);
|
||||
|
||||
Byte readPRG(Address addr);
|
||||
void writePRG(Address addr, Byte value);
|
||||
|
@ -57,7 +57,7 @@ namespace sn
|
|||
std::vector<Byte> m_mirroringRAM;
|
||||
std::vector<Byte> ramstatic;
|
||||
std::function<void(void)> m_mirroringCallback;
|
||||
std::function<void(int)> m_interruptCallback;
|
||||
std::function<void(InterruptType)> m_interruptCallback;
|
||||
Byte A12_count;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Emulator.h"
|
||||
#include "CPUOpcodes.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <thread>
|
||||
|
@ -36,7 +37,7 @@ namespace sn
|
|||
LOG(Error) << "Critical error: Failed to set I/O callbacks" << std::endl;
|
||||
}
|
||||
|
||||
m_ppu.setInterruptCallback([&](){ m_cpu.interrupt(CPU::NMI); });
|
||||
m_ppu.setInterruptCallback([&](){ m_cpu.interrupt(InterruptType::NMI); });
|
||||
}
|
||||
|
||||
void Emulator::run(std::string rom_path)
|
||||
|
@ -46,7 +47,7 @@ namespace sn
|
|||
|
||||
m_mapper = Mapper::createMapper(static_cast<Mapper::Type>(m_cartridge.getMapper()),
|
||||
m_cartridge,
|
||||
[&](int type){ m_cpu.interrupt(static_cast<CPU::InterruptType>(type)); },
|
||||
[&](InterruptType type){ m_cpu.interrupt(type); },
|
||||
[&](){ m_pictureBus.updateMirroring(); });
|
||||
if (!m_mapper)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Mapper.h"
|
||||
#include "CPUOpcodes.h"
|
||||
#include "MapperNROM.h"
|
||||
#include "MapperSxROM.h"
|
||||
#include "MapperMMC3.h"
|
||||
|
@ -15,7 +16,7 @@ namespace sn
|
|||
return static_cast<NameTableMirroring>(m_cartridge.getNameTableMirroring());
|
||||
}
|
||||
|
||||
std::unique_ptr<Mapper> Mapper::createMapper(Mapper::Type mapper_t, sn::Cartridge& cart, std::function<void(int)> interrupt_cb, std::function<void(void)> mirroring_cb)
|
||||
std::unique_ptr<Mapper> Mapper::createMapper(Mapper::Type mapper_t, sn::Cartridge& cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb)
|
||||
{
|
||||
std::unique_ptr<Mapper> ret(nullptr);
|
||||
switch (mapper_t)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#include "MapperMMC3.h"
|
||||
#include "CPU.h"
|
||||
|
||||
namespace sn
|
||||
{
|
||||
|
||||
MapperMMC3::MapperMMC3(Cartridge &cart, std::function<void(int)> interrupt_cb, std::function<void(void)> mirroring_cb) :
|
||||
MapperMMC3::MapperMMC3(Cartridge &cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb) :
|
||||
Mapper(cart, Mapper::MMC3),
|
||||
m_interruptCallback(interrupt_cb),
|
||||
m_mirroringCallback(mirroring_cb),
|
||||
|
@ -21,7 +20,7 @@ namespace sn
|
|||
{
|
||||
|
||||
ramstatic.resize(32 * 1024);
|
||||
m_mirroringRAM.resize(0x800);
|
||||
m_mirroringRAM.resize(0x1000);
|
||||
|
||||
prgbank0 = &cart.getROM()[cart.getROM().size() - 0x4000];
|
||||
prgbank1 = &cart.getROM()[cart.getROM().size() - 0x2000];
|
||||
|
@ -40,7 +39,7 @@ chrbank6 = &cart.getVROM()[cart.getVROM().size() * 0x400];
|
|||
chrbank7 = &cart.getVROM()[cart.getVROM().size() * 0x400];
|
||||
|
||||
if (cart.getNameTableMirroring() & 0x8){
|
||||
mirrormode = NameTableMirroring::FourScreen;
|
||||
mirrormode = NameTableMirroring::MapperControlled;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,11 +252,11 @@ void MapperMMC3::writeCHR(Address addr, Byte value)
|
|||
{}
|
||||
|
||||
void MapperMMC3::writeNameTable(Address addr, Byte value){
|
||||
m_mirroringRAM[addr-0x2800] = value;
|
||||
m_mirroringRAM[addr-0x2000] = value;
|
||||
}
|
||||
|
||||
Byte MapperMMC3::readNameTable(Address addr){
|
||||
return m_mirroringRAM[addr-0x2800];
|
||||
return m_mirroringRAM[addr-0x2000];
|
||||
}
|
||||
|
||||
bool MapperMMC3::irqState()
|
||||
|
@ -274,7 +273,7 @@ void MapperMMC3::irqClear()
|
|||
void MapperMMC3::scanline()
|
||||
{
|
||||
if (nIRQCounter == 0)
|
||||
{
|
||||
{
|
||||
nIRQCounter = nIRQReload;
|
||||
}
|
||||
else
|
||||
|
@ -289,7 +288,7 @@ void MapperMMC3::scanline()
|
|||
void MapperMMC3::scanlineIRQ(){
|
||||
scanline();
|
||||
if(irqState()){
|
||||
m_interruptCallback(int(CPU::InterruptType::IRQ));
|
||||
m_interruptCallback(InterruptType::IRQ);
|
||||
irqClear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,19 +19,15 @@ namespace sn
|
|||
else if (addr < 0x3eff) //Name tables upto 0x3000, then mirrored upto 3eff
|
||||
{
|
||||
auto index = addr & 0x3ff;
|
||||
if (addr < 0x2400) //NT0
|
||||
if (NameTable0 >= m_RAM.size())
|
||||
return m_mapper->readNameTable(addr);
|
||||
else if (addr < 0x2400) //NT0
|
||||
return m_RAM[NameTable0 + index];
|
||||
else if (addr < 0x2800) //NT1
|
||||
return m_RAM[NameTable1 + index];
|
||||
else if (addr < 0x2c00) //NT2
|
||||
if (NameTable2 == ~0ul)
|
||||
return m_mapper->readNameTable(addr);
|
||||
else
|
||||
return m_RAM[NameTable2 + index];
|
||||
return m_RAM[NameTable2 + index];
|
||||
else //NT3
|
||||
if (NameTable3 == ~0ul)
|
||||
return m_mapper->readNameTable(addr);
|
||||
else
|
||||
return m_RAM[NameTable3 + index];
|
||||
}
|
||||
else if (addr < 0x3fff)
|
||||
|
@ -55,20 +51,16 @@ namespace sn
|
|||
else if (addr < 0x3eff) //Name tables upto 0x3000, then mirrored upto 3eff
|
||||
{
|
||||
auto index = addr & 0x3ff;
|
||||
if (addr < 0x2400) //NT0
|
||||
if (NameTable0 >= m_RAM.size())
|
||||
m_mapper->writeNameTable(addr, value);
|
||||
else if (addr < 0x2400) //NT0
|
||||
m_RAM[NameTable0 + index] = value;
|
||||
else if (addr < 0x2800) //NT1
|
||||
m_RAM[NameTable1 + index] = value;
|
||||
else if (addr < 0x2c00) //NT2
|
||||
if (NameTable2 == ~0ul)
|
||||
m_mapper->writeNameTable(addr, value);
|
||||
else
|
||||
m_RAM[NameTable2 + index] = value;
|
||||
m_RAM[NameTable2 + index] = value;
|
||||
else //NT3
|
||||
if (NameTable3 == ~0ul)
|
||||
m_mapper->writeNameTable(addr, value);
|
||||
else
|
||||
m_RAM[NameTable3 + index] = value;
|
||||
m_RAM[NameTable3 + index] = value;
|
||||
}
|
||||
else if (addr < 0x3fff)
|
||||
{
|
||||
|
@ -102,10 +94,9 @@ namespace sn
|
|||
LOG(InfoVerbose) << "Single Screen mirroring set with higher bank." << std::endl;
|
||||
break;
|
||||
case FourScreen:
|
||||
NameTable0 = 0x0;
|
||||
NameTable1 = 0x400;
|
||||
NameTable2 = NameTable3 = ~0ul;
|
||||
LOG(InfoVerbose) << "4 screen mirroring set." << std::endl;
|
||||
case MapperControlled:
|
||||
NameTable0 = m_RAM.size();
|
||||
LOG(InfoVerbose) << "Mapper controlled mirroring." << std::endl;
|
||||
break;
|
||||
default:
|
||||
NameTable0 = NameTable1 = NameTable2 = NameTable3 = 0;
|
||||
|
|
Loading…
Reference in a new issue