misc. fixes

This commit is contained in:
Amish K. Naidu 2022-08-21 20:33:02 +05:30
parent 80d17ba00d
commit 1b384a6184
4 changed files with 40 additions and 57 deletions

View file

@ -1,7 +1,7 @@
#ifndef MEMORY_H
#define MEMORY_H
#include <vector>
#include <map>
#include <unordered_map>
#include <functional>
#include <memory>
#include "Cartridge.h"
@ -39,8 +39,8 @@ namespace sn
std::vector<Byte> m_extRAM;
Mapper* m_mapper;
std::map<IORegisters, std::function<void(Byte)>> m_writeCallbacks;
std::map<IORegisters, std::function<Byte(void)>> m_readCallbacks;;
std::unordered_map<IORegisters, std::function<void(Byte)>> m_writeCallbacks;
std::unordered_map<IORegisters, std::function<Byte(void)>> m_readCallbacks;;
};
};

View file

@ -33,6 +33,7 @@ namespace sn
};
Mapper(Cartridge& cart, Type t) : m_cartridge(cart), m_type(t) {};
virtual ~Mapper() = default;
virtual void writePRG (Address addr, Byte value) = 0;
virtual Byte readPRG (Address addr) = 0;
@ -48,7 +49,7 @@ namespace sn
virtual void scanlineIRQ(){}
static std::unique_ptr<Mapper> createMapper (Type mapper_t, Cartridge& cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb);
static std::unique_ptr<Mapper> createMapper (Type mapper_t, Cartridge& cart, std::function<void()> interrupt_cb, std::function<void(void)> mirroring_cb);
protected:
Cartridge& m_cartridge;

View file

@ -8,7 +8,7 @@ namespace sn
class MapperMMC3 : public Mapper
{
public:
MapperMMC3(Cartridge &cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb);
MapperMMC3(Cartridge &cart, std::function<void()> interrupt_cb, std::function<void(void)> mirroring_cb);
Byte readPRG(Address addr);
void writePRG(Address addr, Byte value);
@ -17,9 +17,6 @@ namespace sn
Byte readCHR(Address addr);
void writeCHR(Address addr, Byte value);
bool irqState();
void irqClear();
void scanline();
void scanlineIRQ();
private:
@ -30,11 +27,9 @@ namespace sn
uint32_t m_bankRegister[8];
Byte lastread;
bool bIRQActive;
bool bIRQEnable;
Address nIRQCounter;
Address nIRQReload;
bool m_irqEnabled;
Byte m_irqCounter;
Byte m_irqLatch;
bool m_irqReloadPending;
std::vector<Byte> m_prgRam;
@ -48,7 +43,7 @@ namespace sn
NameTableMirroring m_mirroring;
std::function<void(void)> m_mirroringCallback;
std::function<void(InterruptType)> m_interruptCallback;
std::function<void()> m_interruptCallback;
};
} // namespace sn

View file

@ -1,17 +1,18 @@
#include "MapperMMC3.h"
#include "Log.h"
namespace sn
{
MapperMMC3::MapperMMC3(Cartridge &cart, std::function<void(InterruptType)> interrupt_cb, std::function<void(void)> mirroring_cb) :
MapperMMC3::MapperMMC3(Cartridge &cart, std::function<void()> interrupt_cb, std::function<void(void)> mirroring_cb) :
Mapper(cart, Mapper::MMC3),
m_targetRegister(0),
m_prgBankMode(false),
m_chrInversion(false),
lastread(0),
bIRQActive(false),
bIRQEnable(false),
nIRQCounter(0),
nIRQReload(0),
m_bankRegister{},
m_irqEnabled(false),
m_irqCounter(0),
m_irqLatch(0),
m_irqReloadPending(false),
m_prgRam(32 * 1024),
m_mirroringRam(4 * 1024),
m_mirroring(Horizontal),
@ -154,9 +155,11 @@ namespace sn
if (!(addr & 0x01))
{
// Mirroring
if (m_cartridge.getNameTableMirroring() & 0x8){
if (m_cartridge.getNameTableMirroring() & 0x8)
{
m_mirroring = NameTableMirroring::FourScreen;
}else if (value & 0x01)
}
else if (value & 0x01)
{
m_mirroring = NameTableMirroring::Horizontal;
}
@ -176,30 +179,26 @@ namespace sn
{
if (!(addr & 0x01))
{
nIRQReload = value;
m_irqLatch = value;
}
else
{
nIRQCounter = 0;
m_irqCounter = 0;
m_irqReloadPending = true;
}
}
else if (addr >= 0xE000)
{
if (!(addr & 0x01))
{
bIRQEnable = false;
bIRQActive = false;
}
else
{
bIRQEnable = true;
}
// enabled if odd address
m_irqEnabled = (addr & 0x01) == 0x01;
// TODO acknowledge any pending interrupts?
}
}
void MapperMMC3::writeCHR(Address addr, Byte value) {
void MapperMMC3::writeCHR(Address addr, Byte value)
{
if (addr >= 0x2000 && addr <= 0x2fff)
{
m_mirroringRam[addr-0x2000]=value;
@ -207,37 +206,25 @@ namespace sn
}
bool MapperMMC3::irqState()
void MapperMMC3::scanlineIRQ()
{
return bIRQActive;
}
bool zeroTransition = false;
void MapperMMC3::irqClear()
{
bIRQActive = false;
}
void MapperMMC3::scanline()
{
if (nIRQCounter == 0)
if (m_irqCounter == 0 || m_irqReloadPending)
{
nIRQCounter = nIRQReload;
m_irqCounter = m_irqLatch;
// zeroTransition = m_irqReloadPending;
m_irqReloadPending = false;
}
else
nIRQCounter--;
if (nIRQCounter == 0 && bIRQEnable)
{
bIRQActive = true;
m_irqCounter--;
zeroTransition = m_irqCounter == 0;
}
}
void MapperMMC3::scanlineIRQ(){
scanline();
if(irqState()){
m_interruptCallback(InterruptType::IRQ);
irqClear();
if(zeroTransition && m_irqEnabled)
{
m_interruptCallback();
}
}