Imported existing sources
This commit is contained in:
1 parent
b848581174
commit
619ec483e7
69 files changed
+7961
-36
No files matched your search
@@ -0,0 +1,216 @@
|
||||
#include "mapper001.h"
|
||||
|
||||
#include "utils/datastreamutils.h"
|
||||
|
||||
QString Mapper001::name() const
|
||||
{
|
||||
return QStringLiteral("MMC1");
|
||||
}
|
||||
|
||||
quint8 Mapper001::mapper() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Mapper001::hardReset()
|
||||
{
|
||||
Board::hardReset();
|
||||
|
||||
m_cpuCycles = 0;
|
||||
|
||||
// Registers
|
||||
m_addressReg = 0;
|
||||
m_reg = { 0x0C, 0, 0, 0 };
|
||||
m_reg[0] = 0x0C;
|
||||
m_flagC = false;
|
||||
m_flagS = true;
|
||||
m_flagP = true;
|
||||
m_prgHijackedBit = 0;
|
||||
|
||||
// Buffers
|
||||
m_buffer = 0;
|
||||
m_shift = 0;
|
||||
|
||||
//if (Chips.Contains("MMC1B") || Chips.Contains("MMC1B2"))
|
||||
// TogglePRGRAMEnable(false);
|
||||
|
||||
m_enableWramEnable = true; // !Chips.Contains("MMC1A");
|
||||
|
||||
// use hijacked
|
||||
m_useHijacked = (prgRom16KbMask() & 0x10) == 0x10;
|
||||
if (m_useHijacked)
|
||||
m_prgHijackedBit = 0x10;
|
||||
|
||||
// SRAM Switch ?
|
||||
m_useSramSwitch = false;
|
||||
if (prgRam8KbCount() > 0)
|
||||
{
|
||||
m_useSramSwitch = true;
|
||||
m_sramSwitchMask = m_useHijacked ? 0x08 : 0x18;
|
||||
m_sramSwitchMask &= prgRam8KbMask() << 3;
|
||||
|
||||
if (m_sramSwitchMask == 0)
|
||||
m_useSramSwitch = false;
|
||||
}
|
||||
|
||||
switch16kPrg(0xF | m_prgHijackedBit, PRGArea::AreaC000);
|
||||
}
|
||||
|
||||
void Mapper001::writePrg(quint16 address, quint8 value)
|
||||
{
|
||||
// Too close writes ignored !
|
||||
if (m_cpuCycles > 0)
|
||||
return;
|
||||
|
||||
m_cpuCycles = 3;// Make save cycles ...
|
||||
//Temporary reg port ($8000-FFFF):
|
||||
//[r... ...d]
|
||||
//r = reset flag
|
||||
//d = data bit
|
||||
|
||||
//r is set
|
||||
if ((value & 0x80) == 0x80)
|
||||
{
|
||||
m_reg[0] |= 0x0C;//bits 2,3 of reg $8000 are set (16k PRG mode, $8000 swappable)
|
||||
m_flagS = true;
|
||||
m_flagP = true;
|
||||
m_shift = 0;
|
||||
m_buffer = 0;//hidden temporary reg is reset
|
||||
return;
|
||||
}
|
||||
//d is set
|
||||
if ((value & 0x01) == 0x01)
|
||||
m_buffer |= 1 << m_shift; //'d' proceeds as the next bit written in the 5-bit sequence
|
||||
if (++m_shift < 5)
|
||||
return;
|
||||
// If this completes the 5-bit sequence:
|
||||
// - temporary reg is copied to actual internal reg (which reg depends on the last address written to)
|
||||
m_addressReg = (address & 0x7FFF) >> 13;
|
||||
m_reg[m_addressReg] = m_buffer;
|
||||
|
||||
// - temporary reg is reset (so that next write is the "first" write)
|
||||
m_shift = 0;
|
||||
m_buffer = 0;
|
||||
|
||||
// Update internal registers ...
|
||||
switch (m_addressReg)
|
||||
{
|
||||
case 0:// $8000-9FFF [Flags and mirroring]
|
||||
// Flags
|
||||
m_flagC = m_reg[0] & 0x10;
|
||||
m_flagP = m_reg[0] & 0x08;
|
||||
m_flagS = m_reg[0] & 0x04;
|
||||
updatePRG();
|
||||
updateCHR();
|
||||
// Mirroring
|
||||
switch (m_reg[0] & 3)
|
||||
{
|
||||
case 0: switch1kNmt(Mirroring::OneScA); break;
|
||||
case 1: switch1kNmt(Mirroring::OneScB); break;
|
||||
case 2: switch1kNmt(Mirroring::Vertical); break;
|
||||
case 3: switch1kNmt(Mirroring::Horizontal); break;
|
||||
}
|
||||
break;
|
||||
case 1:// $A000-BFFF [CHR REG 0]
|
||||
// CHR
|
||||
if (!m_flagC)
|
||||
switch8kChr(m_reg[1] >> 1);
|
||||
else
|
||||
switch4kChr(m_reg[1], CHRArea::Area0000);
|
||||
// SRAM
|
||||
if (m_useSramSwitch)
|
||||
switch8kPrg((m_reg[1] & m_sramSwitchMask) >> 3, PRGArea::Area6000);
|
||||
// PRG hijack
|
||||
if (m_useHijacked)
|
||||
{
|
||||
m_prgHijackedBit = m_reg[1] & 0x10;
|
||||
updatePRG();
|
||||
}
|
||||
break;
|
||||
case 2:// $C000-DFFF [CHR REG 1]
|
||||
// CHR
|
||||
if (m_flagC)
|
||||
switch4kChr(m_reg[2], CHRArea::Area1000);
|
||||
// SRAM
|
||||
if (m_useSramSwitch)
|
||||
switch8kPrg((m_reg[2] & m_sramSwitchMask) >> 3, PRGArea::Area6000);
|
||||
// PRG hijack
|
||||
if (m_useHijacked)
|
||||
{
|
||||
m_prgHijackedBit = m_reg[2] & 0x10;
|
||||
updatePRG();
|
||||
}
|
||||
break;
|
||||
case 3:// $E000-FFFF [PRG REG]
|
||||
if (m_enableWramEnable)
|
||||
togglePrgRamEnable((m_reg[3] & 0x10) == 0);
|
||||
updatePRG();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Mapper001::onCpuClock()
|
||||
{
|
||||
if (m_cpuCycles > 0)
|
||||
m_cpuCycles--;
|
||||
}
|
||||
|
||||
void Mapper001::readState(QDataStream &dataStream)
|
||||
{
|
||||
Board::readState(dataStream);
|
||||
dataStream >> m_reg >> m_shift >> m_buffer >> m_flagP >> m_flagC >> m_flagS >> m_enableWramEnable
|
||||
>> m_prgHijackedBit >> m_useHijacked >> m_useSramSwitch >> m_cpuCycles;
|
||||
}
|
||||
|
||||
void Mapper001::writeState(QDataStream &dataStream) const
|
||||
{
|
||||
Board::writeState(dataStream);
|
||||
dataStream << m_reg << m_shift << m_buffer << m_flagP << m_flagC << m_flagS << m_enableWramEnable
|
||||
<< m_prgHijackedBit << m_useHijacked << m_useSramSwitch << m_cpuCycles;
|
||||
}
|
||||
|
||||
int Mapper001::prgRam8KbDefaultBlkCount() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
int Mapper001::chrRom1KbDefaultBlkCount() const
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
void Mapper001::updateCHR()
|
||||
{
|
||||
if (!m_flagC)
|
||||
switch8kChr(m_reg[1] >> 1);
|
||||
else
|
||||
{
|
||||
switch4kChr(m_reg[1], CHRArea::Area0000);
|
||||
switch4kChr(m_reg[2], CHRArea::Area1000);
|
||||
}
|
||||
// SRAM
|
||||
if (m_useSramSwitch)
|
||||
switch8kPrg((m_reg[1] & m_sramSwitchMask) >> 3, PRGArea::Area6000);
|
||||
}
|
||||
|
||||
void Mapper001::updatePRG()
|
||||
{
|
||||
if (!m_flagP)
|
||||
{
|
||||
switch32kPrg(((m_reg[3] & 0xF) | m_prgHijackedBit) >> 1, PRGArea::Area8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_flagS)
|
||||
{
|
||||
switch16kPrg((m_reg[3] & 0xF) | m_prgHijackedBit, PRGArea::Area8000);
|
||||
switch16kPrg(0xF | m_prgHijackedBit, PRGArea::AreaC000);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch16kPrg(m_prgHijackedBit, PRGArea::Area8000);
|
||||
switch16kPrg((m_reg[3] & 0xF) | m_prgHijackedBit, PRGArea::AreaC000);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user