mirror of
https://github.com/libretro/nestopia.git
synced 2024-11-23 00:19:44 +00:00
Update core to 1.51.0
This commit is contained in:
parent
0232076014
commit
8c2b99b537
@ -26916,4 +26916,99 @@
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<cartridge system="NES-NTSC" dump="ok" crc="FDC7C50B" sha1="5E8F67BEFB2B1BCBD0384E3144ACB2766FC3E443">
|
||||
<board type="NES-ETROM" mapper="5">
|
||||
<prg size="128k" />
|
||||
<chr size="128k" />
|
||||
<wram size="8k" />
|
||||
<wram size="8k" battery="1" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<cartridge system="Famicom" dump="unknown" crc="084F61CD" sha1="44BC6C4E8B3F6C635281B4C05382E8F316D8269E">
|
||||
<board type="NAMCOT-3301" mapper="0">
|
||||
<prg size="8k" />
|
||||
<chr size="8k" />
|
||||
<pad h="0" v="1" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<cartridge system="Famicom" dump="unknown" crc="76A6A813" sha1="0FE9120FD5ADC2790B0B9E8FADD136F9C66A709F">
|
||||
<board type="NAMCOT-3301" mapper="0">
|
||||
<prg size="8k" />
|
||||
<chr size="8k" />
|
||||
<pad h="0" v="1" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<peripherals>
|
||||
<device type="fourplayer" />
|
||||
</peripherals>
|
||||
<cartridge system="NES-NTSC" dump="ok" crc="1394DED0" sha1="B1C6A700A9F3B73666018E46515D376F06B8E9C2">
|
||||
<board type="NES-UNROM" mapper="2">
|
||||
<prg size="64k" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<peripherals>
|
||||
<device type="fourplayer" />
|
||||
</peripherals>
|
||||
<cartridge system="NES-NTSC" dump="ok" crc="90D2E9F0" sha1="2801AADD9D0308CF2C9069A2BB76242ECA5B1501">
|
||||
<board type="NES-NROM-256" mapper="0">
|
||||
<prg size="32k" />
|
||||
<chr size="8k" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<peripherals>
|
||||
<device type="fourplayer" />
|
||||
</peripherals>
|
||||
<cartridge system="NES-NTSC" dump="ok" crc="2DA5ECE0" sha1="F3554E45D3261157653643C23A378C0295A5F893">
|
||||
<board type="NES-NROM-256" mapper="0">
|
||||
<prg size="32k" />
|
||||
<chr size="8k" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<peripherals>
|
||||
<device type="fourplayer" />
|
||||
</peripherals>
|
||||
<cartridge system="Famicom" dump="unknown" crc="69977C9E" sha1="C43D5F049F4F7862E6DECCA7500C0C23E349AF9F">
|
||||
<board mapper="0">
|
||||
<prg size="32k" />
|
||||
<chr size="8k" />
|
||||
<pad h="0" v="1" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<game>
|
||||
<peripherals>
|
||||
<device type="fourplayer" />
|
||||
</peripherals>
|
||||
<cartridge system="Famicom" dump="ok" crc="4FF17864" sha1="5119F1D6B67C5E44D63BA1E7080A6FE17623415C">
|
||||
<board type="NES-SLROM" mapper="1">
|
||||
<prg size="128k" />
|
||||
<chr size="128k" />
|
||||
<chip type="MMC1B2" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>
|
||||
<!--game>
|
||||
<peripherals>
|
||||
<device type="zapper" />
|
||||
</peripherals>
|
||||
<cartridge system="Famicom" dump="ok" crc="A0FBF02E" sha1="38236FBD5B70F651674D52EE519AB4DBB11F7955">
|
||||
<board type="UNL-TF1201" mapper="298">
|
||||
<prg size="128k" />
|
||||
<chr size="128k" />
|
||||
</board>
|
||||
</cartridge>
|
||||
</game>-->
|
||||
</database>
|
||||
|
@ -204,6 +204,7 @@ SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardMmc5.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardMmc6.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot163.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot175.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot340.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot34xx.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNanjing.cpp
|
||||
SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNihon.cpp
|
||||
|
@ -863,7 +863,7 @@ static void check_variables(void)
|
||||
video.EnableUnlimSprites(true);
|
||||
}
|
||||
|
||||
var.key = "nestopia_overclock";
|
||||
/* var.key = "nestopia_overclock";
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
@ -872,7 +872,7 @@ static void check_variables(void)
|
||||
else if (strcmp(var.value, "2x") == 0)
|
||||
video.EnableOverclocking(true);
|
||||
}
|
||||
|
||||
*/
|
||||
var.key = "nestopia_fds_auto_insert";
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
|
@ -361,6 +361,11 @@ namespace Nes
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint Apu::GetCtrl()
|
||||
{
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
Result Apu::SetSpeed(const uint speed)
|
||||
{
|
||||
if (settings.speed == speed)
|
||||
@ -1670,7 +1675,7 @@ namespace Nes
|
||||
step = 0x7;
|
||||
status = STATUS_COUNTING;
|
||||
waveLength = 0;
|
||||
linearCtrl = 0;
|
||||
//linearCtrl = 0;
|
||||
linearCounter = 0;
|
||||
|
||||
lengthCounter.Reset();
|
||||
@ -1870,7 +1875,6 @@ namespace Nes
|
||||
amp = (sum * outputVolume + rate/2) / rate * 3;
|
||||
}
|
||||
}
|
||||
// Disabling these blocks fixes scratchy audio in many games
|
||||
/*else if (amp < Channel::OUTPUT_DECAY)
|
||||
{
|
||||
return 0;
|
||||
@ -2121,7 +2125,6 @@ namespace Nes
|
||||
dma.buffered = false;
|
||||
dma.address = 0xC000;
|
||||
dma.buffer = 0x00;
|
||||
overclockingIsSafe = true;
|
||||
}
|
||||
|
||||
Cycle Apu::Dmc::GetResetFrequency(CpuModel model)
|
||||
@ -2362,31 +2365,16 @@ namespace Nes
|
||||
{
|
||||
out.dac = data & 0x7F;
|
||||
curSample = out.dac * outputVolume;
|
||||
|
||||
if (out.dac != 0)
|
||||
{
|
||||
overclockingIsSafe = false;
|
||||
}
|
||||
}
|
||||
|
||||
NST_SINGLE_CALL void Apu::Dmc::WriteReg2(const uint data)
|
||||
{
|
||||
regs.address = 0xC000 | (data << 6);
|
||||
|
||||
if (regs.address != 0)
|
||||
{
|
||||
overclockingIsSafe = true;
|
||||
}
|
||||
}
|
||||
|
||||
NST_SINGLE_CALL void Apu::Dmc::WriteReg3(const uint data)
|
||||
{
|
||||
regs.lengthCounter = (data << 4) + 1;
|
||||
|
||||
if (regs.lengthCounter != 0)
|
||||
{
|
||||
overclockingIsSafe = true;
|
||||
}
|
||||
}
|
||||
|
||||
NST_SINGLE_CALL bool Apu::Dmc::ClockDAC()
|
||||
|
@ -50,7 +50,6 @@ namespace Nes
|
||||
public:
|
||||
|
||||
explicit Apu(Cpu&);
|
||||
|
||||
void Reset(bool);
|
||||
void PowerOff();
|
||||
void ClearBuffers();
|
||||
@ -65,6 +64,7 @@ namespace Nes
|
||||
Result SetSpeed(uint);
|
||||
Result SetVolume(uint,uint);
|
||||
uint GetVolume(uint) const;
|
||||
uint GetCtrl();
|
||||
void Mute(bool);
|
||||
void SetAutoTranspose(bool);
|
||||
void SetGenie(bool);
|
||||
@ -461,7 +461,7 @@ namespace Nes
|
||||
enum
|
||||
{
|
||||
MIN_FRQ = 2 + 1,
|
||||
STEP_CHECK = 0x00, // >= 0x1F is technically correct but will produce clicks/pops
|
||||
STEP_CHECK = 0x1F,
|
||||
REG0_LINEAR_COUNTER_LOAD = 0x7F,
|
||||
REG0_LINEAR_COUNTER_START = 0x80,
|
||||
REG2_WAVE_LENGTH_LOW = 0x00FF,
|
||||
@ -529,8 +529,6 @@ namespace Nes
|
||||
|
||||
Dmc();
|
||||
|
||||
bool overclockingIsSafe;
|
||||
|
||||
void Reset(CpuModel);
|
||||
void UpdateSettings(uint);
|
||||
void LoadState(State::Loader&,const Cpu&,CpuModel,Cycle&);
|
||||
@ -628,16 +626,6 @@ namespace Nes
|
||||
|
||||
public:
|
||||
|
||||
void SetOverclockSafety(bool safe)
|
||||
{
|
||||
dmc.overclockingIsSafe = safe;
|
||||
}
|
||||
|
||||
bool GetOverclockSafety()
|
||||
{
|
||||
return dmc.overclockingIsSafe;
|
||||
}
|
||||
|
||||
dword GetSampleRate() const
|
||||
{
|
||||
return settings.rate;
|
||||
|
@ -674,7 +674,7 @@ namespace Nes
|
||||
|
||||
if (setup.version)
|
||||
{
|
||||
setup.mapper |= uint(header[8]) << 8 & 0x100;
|
||||
setup.mapper |= uint(header[8]) << 8 & 0x300;
|
||||
setup.subMapper = header[8] >> 4;
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,6 @@ namespace Nes
|
||||
ticks = 0;
|
||||
logged = 0;
|
||||
|
||||
cpuOverclocking = false;
|
||||
|
||||
pc = RESET_VECTOR;
|
||||
|
||||
cycles.count = 0;
|
||||
@ -247,7 +245,12 @@ namespace Nes
|
||||
if (hard)
|
||||
{
|
||||
Poke(0x4017, 0x00);
|
||||
cycles.count = cycles.clock[RESET_CYCLES-1];
|
||||
cycles.count = cycles.clock[RESET_CYCLES] + cycles.clock[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Poke(0x4017, apu.GetCtrl());
|
||||
cycles.count = cycles.clock[RESET_CYCLES] + cycles.clock[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1723,18 +1726,42 @@ namespace Nes
|
||||
return address;
|
||||
}
|
||||
|
||||
NST_SINGLE_CALL uint Cpu::Shx(uint address)
|
||||
NST_SINGLE_CALL void Cpu::Shx(uint address)
|
||||
{
|
||||
address = x & ((address >> 8) + 1);
|
||||
uint newaddress = (address + y);
|
||||
uint data = x & ((address >> 8) + 1);
|
||||
Peek((address & 0xFF00) | (newaddress & 0x00FF)); // Dummy read
|
||||
|
||||
if ((address ^ newaddress) & 0x100)
|
||||
{
|
||||
address = (newaddress & (x << 8)) | (newaddress & 0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
address = newaddress;
|
||||
}
|
||||
|
||||
NotifyOp("SHX",1UL << 15);
|
||||
return address;
|
||||
StoreMem(address, data);
|
||||
}
|
||||
|
||||
NST_SINGLE_CALL uint Cpu::Shy(uint address)
|
||||
NST_SINGLE_CALL void Cpu::Shy(uint address)
|
||||
{
|
||||
address = y & ((address >> 8) + 1);
|
||||
uint newaddress = (address + x);
|
||||
uint data = y & ((address >> 8) + 1);
|
||||
Peek((address & 0xFF00) | (newaddress & 0x00FF)); // Dummy read
|
||||
|
||||
if ((address ^ newaddress) & 0x100)
|
||||
{
|
||||
address = (newaddress & (y << 8)) | (newaddress & 0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
address = newaddress;
|
||||
}
|
||||
|
||||
NotifyOp("SHY",1UL << 16);
|
||||
return address;
|
||||
StoreMem(address, data);
|
||||
}
|
||||
|
||||
NST_NO_INLINE uint Cpu::Slo(uint data)
|
||||
@ -1901,18 +1928,6 @@ namespace Nes
|
||||
|
||||
if (interrupt.irqClock != CYCLE_MAX)
|
||||
interrupt.irqClock = (interrupt.irqClock > cycles.frame ? interrupt.irqClock - cycles.frame : 0);
|
||||
|
||||
if (cpuOverclocking)
|
||||
{
|
||||
uint startCycle = cycles.count;
|
||||
uint lastCycle = cycles.count + extraCycles;
|
||||
do
|
||||
{
|
||||
ExecuteOp();
|
||||
}
|
||||
while (cycles.count < extraCycles);
|
||||
cycles.count = startCycle;
|
||||
}
|
||||
}
|
||||
|
||||
void Cpu::Clock()
|
||||
@ -2095,6 +2110,15 @@ namespace Nes
|
||||
Store##addr_( dst, instr_(dst) ); \
|
||||
}
|
||||
|
||||
// Unofficial Opcodes SHX/SHY are edge cases
|
||||
#define NES_I_W_U(instr_,addr_,hex_) \
|
||||
\
|
||||
void Cpu::op##hex_() \
|
||||
{ \
|
||||
const uint dst = addr_##_W(); \
|
||||
instr_(dst); \
|
||||
}
|
||||
|
||||
#define NES_IP_C_(instr_,ops_,ticks_,hex_) \
|
||||
\
|
||||
void Cpu::op##hex_() \
|
||||
@ -2352,8 +2376,8 @@ namespace Nes
|
||||
NES_I_W_A( Sha, AbsY, 0x9F )
|
||||
NES_I_W_A( Sha, IndY, 0x93 )
|
||||
NES_I_W_A( Shs, AbsY, 0x9B )
|
||||
NES_I_W_A( Shx, AbsY, 0x9E )
|
||||
NES_I_W_A( Shy, AbsX, 0x9C )
|
||||
NES_I_W_U( Shx, Abs, 0x9E ) // Edge case: AbsY done internally
|
||||
NES_I_W_U( Shy, Abs, 0x9C ) // Edge case: AbsX done internally
|
||||
NES_IRW__( Slo, Zpg, 0x07 )
|
||||
NES_IRW__( Slo, ZpgX, 0x17 )
|
||||
NES_IRW__( Slo, Abs, 0x0F )
|
||||
|
@ -260,8 +260,8 @@ namespace Nes
|
||||
NST_SINGLE_CALL void Lxa (uint);
|
||||
NST_SINGLE_CALL void Sbx (uint);
|
||||
NST_SINGLE_CALL uint Shs (uint);
|
||||
NST_SINGLE_CALL uint Shx (uint);
|
||||
NST_SINGLE_CALL uint Shy (uint);
|
||||
NST_SINGLE_CALL void Shx (uint);
|
||||
NST_SINGLE_CALL void Shy (uint);
|
||||
|
||||
NST_NO_INLINE void Anc (uint);
|
||||
NST_NO_INLINE uint Dcp (uint);
|
||||
@ -487,8 +487,6 @@ namespace Nes
|
||||
Ram ram;
|
||||
Apu apu;
|
||||
IoMap map;
|
||||
bool cpuOverclocking;
|
||||
uint extraCycles;
|
||||
|
||||
static dword logged;
|
||||
static void (Cpu::*const opcodes[0x100])();
|
||||
@ -501,12 +499,6 @@ namespace Nes
|
||||
return apu;
|
||||
}
|
||||
|
||||
void SetOverclocking(bool overclocking,uint newCycles)
|
||||
{
|
||||
cpuOverclocking = overclocking;
|
||||
extraCycles = newCycles;
|
||||
}
|
||||
|
||||
Cycle Update(uint readAddress=0)
|
||||
{
|
||||
apu.ClockDMA( readAddress );
|
||||
|
@ -373,7 +373,7 @@ namespace Nes
|
||||
{
|
||||
State::Loader::Data<4> data( state );
|
||||
|
||||
io.ctrl = data[0];
|
||||
io.ctrl = adapter.ctrl = data[0];
|
||||
io.port = data[1];
|
||||
break;
|
||||
}
|
||||
@ -550,7 +550,13 @@ namespace Nes
|
||||
|
||||
NES_POKE_D(Fds,4023)
|
||||
{
|
||||
io.ctrl = data;
|
||||
io.ctrl = adapter.ctrl = data;
|
||||
|
||||
if (!(io.ctrl & Io::CTRL0_DISK_ENABLED))
|
||||
{
|
||||
cpu.ClearIRQ();
|
||||
adapter.DisableIRQ();
|
||||
}
|
||||
}
|
||||
|
||||
NES_POKE_D(Fds,4026)
|
||||
@ -783,21 +789,25 @@ namespace Nes
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
void Fds::Unit::Timer::Advance(uint& timer)
|
||||
bool Fds::Unit::Timer::Clock()
|
||||
{
|
||||
timer |= STATUS_PENDING_IRQ;
|
||||
bool retval = false;
|
||||
|
||||
if (ctrl & CTRL_REPEAT)
|
||||
count = latch;
|
||||
else
|
||||
ctrl &= ~uint(CTRL_ENABLED);
|
||||
|
||||
latch = 0; // Fixes Kaettekita Mario Bros - FHorse/dragon2snow
|
||||
}
|
||||
if (ctrl & CTRL_ENABLED)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
retval = true;
|
||||
count = latch;
|
||||
|
||||
NST_SINGLE_CALL bool Fds::Unit::Timer::Clock()
|
||||
{
|
||||
return !(ctrl & CTRL_ENABLED) || !count || --count;
|
||||
if (!(ctrl & CTRL_REPEAT))
|
||||
ctrl &= ~uint(CTRL_ENABLED);
|
||||
}
|
||||
else
|
||||
count--;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
@ -1202,11 +1212,15 @@ namespace Nes
|
||||
|
||||
ibool Fds::Unit::Clock()
|
||||
{
|
||||
return
|
||||
(
|
||||
(timer.Clock() ? 0 : (timer.Advance(status), 1)) |
|
||||
(drive.Clock() ? 0 : drive.Advance(status))
|
||||
);
|
||||
bool retval = false;
|
||||
|
||||
if (timer.Clock())
|
||||
{
|
||||
status |= STATUS_PENDING_IRQ;
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return (retval | (drive.Clock() ? 0 : drive.Advance(status)));
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
@ -1216,6 +1230,12 @@ namespace Nes
|
||||
Fds::Adapter::Adapter(Cpu& c,const Disks::Sides& s)
|
||||
: Timer::M2<Unit>(c,s) {}
|
||||
|
||||
void Fds::Adapter::DisableIRQ()
|
||||
{
|
||||
unit.status &= ~uint(Unit::STATUS_PENDING_IRQ);
|
||||
unit.timer.ctrl &= ~uint(Unit::Timer::CTRL_ENABLED);
|
||||
}
|
||||
|
||||
void Fds::Adapter::Reset(Cpu& cpu,byte* const io,bool protect)
|
||||
{
|
||||
Timer::M2<Unit>::Reset( true, true );
|
||||
@ -1379,12 +1399,17 @@ namespace Nes
|
||||
{
|
||||
Update();
|
||||
|
||||
if (!(ctrl & Io::CTRL0_DISK_ENABLED))
|
||||
return;
|
||||
|
||||
unit.timer.ctrl = data;
|
||||
unit.timer.count = unit.timer.latch;
|
||||
unit.status &= Unit::STATUS_TRANSFERED;
|
||||
|
||||
if (!unit.status)
|
||||
ClearIRQ();
|
||||
if (data & Unit::Timer::CTRL_ENABLED)
|
||||
return;
|
||||
|
||||
ClearIRQ();
|
||||
}
|
||||
|
||||
NES_POKE_D(Fds::Adapter,4024)
|
||||
|
@ -340,7 +340,6 @@ namespace Nes
|
||||
Timer();
|
||||
|
||||
void Reset();
|
||||
void Advance(uint&);
|
||||
|
||||
NST_SINGLE_CALL bool Clock();
|
||||
|
||||
@ -435,6 +434,7 @@ namespace Nes
|
||||
|
||||
Adapter(Cpu&,const Disks::Sides&);
|
||||
|
||||
void DisableIRQ();
|
||||
void Reset(Cpu&,byte*,bool=false);
|
||||
void LoadState(State::Loader&,dword,Ppu&);
|
||||
void SaveState(State::Saver&) const;
|
||||
@ -447,6 +447,8 @@ namespace Nes
|
||||
NST_SINGLE_CALL uint Activity() const;
|
||||
|
||||
using Timer::M2<Unit>::VSync;
|
||||
|
||||
byte ctrl;
|
||||
};
|
||||
|
||||
struct Io
|
||||
|
@ -108,7 +108,6 @@ namespace Nes
|
||||
yuvMap (NULL)
|
||||
{
|
||||
cycles.one = PPU_RP2C02_CC;
|
||||
overclocked = false;
|
||||
PowerOff();
|
||||
}
|
||||
|
||||
@ -169,7 +168,7 @@ namespace Nes
|
||||
{
|
||||
static const byte powerUpPalette[] =
|
||||
{
|
||||
0x3F,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,
|
||||
0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,
|
||||
0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C,
|
||||
0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14,
|
||||
0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08
|
||||
@ -240,8 +239,7 @@ namespace Nes
|
||||
cycles.count = Cpu::CYCLE_MAX;
|
||||
|
||||
scanline = SCANLINE_VBLANK;
|
||||
scanline_sleep = -1;
|
||||
ssleep = -1;
|
||||
scanline_sleep = 0;
|
||||
|
||||
io.address = 0;
|
||||
io.pattern = 0;
|
||||
@ -493,8 +491,6 @@ namespace Nes
|
||||
|
||||
Cycle frame;
|
||||
|
||||
scanline_sleep = -1;
|
||||
|
||||
switch (model)
|
||||
{
|
||||
case PPU_RP2C02:
|
||||
@ -503,8 +499,6 @@ namespace Nes
|
||||
|
||||
default:
|
||||
|
||||
ssleep = PPU_RP2C02_VSLEEP - 2;
|
||||
|
||||
if (cycles.hClock == HCLOCK_DUMMY)
|
||||
{
|
||||
cycles.vClock = PPU_RP2C02_HVINT / PPU_RP2C02_CC - HCLOCK_DUMMY;
|
||||
@ -521,8 +515,6 @@ namespace Nes
|
||||
|
||||
case PPU_RP2C07:
|
||||
|
||||
ssleep = PPU_RP2C07_VSLEEP - 2;
|
||||
|
||||
if (cycles.hClock == HCLOCK_DUMMY)
|
||||
{
|
||||
cycles.vClock = PPU_RP2C07_HVINT / PPU_RP2C07_CC - HCLOCK_DUMMY;
|
||||
@ -539,8 +531,6 @@ namespace Nes
|
||||
|
||||
case PPU_DENDY:
|
||||
|
||||
ssleep = PPU_DENDY_VSLEEP - 2;
|
||||
|
||||
if (cycles.hClock == HCLOCK_DUMMY)
|
||||
{
|
||||
cycles.vClock = PPU_DENDY_HVINT / PPU_DENDY_CC - HCLOCK_DUMMY;
|
||||
@ -556,44 +546,6 @@ namespace Nes
|
||||
break;
|
||||
}
|
||||
|
||||
if (overclocked)
|
||||
{
|
||||
Apu& audioSafeOverclock = cpu.GetApu();
|
||||
if (audioSafeOverclock.GetOverclockSafety())
|
||||
{
|
||||
switch (model)
|
||||
{
|
||||
case PPU_RP2C02:
|
||||
default:
|
||||
|
||||
cpu.SetOverclocking(true,PPU_RP2C02_HSYNC * PPU_RP2C02_VACTIVE);
|
||||
break;
|
||||
|
||||
case PPU_RP2C07:
|
||||
|
||||
cpu.SetOverclocking(true,PPU_RP2C07_HSYNC * PPU_RP2C07_VACTIVE);
|
||||
break;
|
||||
|
||||
case PPU_DENDY:
|
||||
|
||||
cpu.SetOverclocking(true,PPU_DENDY_HSYNC * PPU_DENDY_VACTIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.SetOverclocking(false,0);
|
||||
}
|
||||
|
||||
audioSafeOverclock.SetOverclockSafety(true);//overclocking is only safe if direct pcm audio has not been written for one frame
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.SetOverclocking(false,0);
|
||||
Apu& audioSafeOverclock = cpu.GetApu();
|
||||
audioSafeOverclock.SetOverclockSafety(false);
|
||||
}
|
||||
|
||||
cpu.SetFrameCycles( frame );
|
||||
}
|
||||
|
||||
@ -698,6 +650,12 @@ namespace Nes
|
||||
io.line.Toggle( io.address, GetCycles() );
|
||||
}
|
||||
|
||||
NST_FORCE_INLINE void Ppu::UpdateScrollAddressLine()
|
||||
{
|
||||
if (io.line)
|
||||
io.line.Toggle( scroll.address & 0x3FFF, cpu.GetCycles() );
|
||||
}
|
||||
|
||||
NST_FORCE_INLINE void Ppu::UpdateVramAddress()
|
||||
{
|
||||
if ((scanline != SCANLINE_VBLANK ) && (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED))
|
||||
@ -824,7 +782,7 @@ namespace Nes
|
||||
oam.mask = oam.show[pos];
|
||||
|
||||
if ((regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) && !(data & Regs::CTRL1_BG_SP_ENABLED))
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
UpdateScrollAddressLine();
|
||||
}
|
||||
|
||||
io.latch = data;
|
||||
@ -968,10 +926,7 @@ namespace Nes
|
||||
{
|
||||
scroll.latch = (scroll.latch & 0x7F00) | data;
|
||||
scroll.address = scroll.latch;
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) ||
|
||||
(scanline == SCANLINE_VBLANK)) {
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
}
|
||||
UpdateScrollAddressLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -983,13 +938,11 @@ namespace Nes
|
||||
uint address = scroll.address;
|
||||
|
||||
UpdateVramAddress();
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) ||
|
||||
(scanline == SCANLINE_VBLANK)) {
|
||||
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || (scanline == SCANLINE_VBLANK))
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
}
|
||||
else {
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
io.latch = data;
|
||||
|
||||
@ -1027,10 +980,9 @@ namespace Nes
|
||||
|
||||
address = scroll.address & 0x3FFF;
|
||||
UpdateVramAddress();
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) ||
|
||||
(scanline == SCANLINE_VBLANK)) {
|
||||
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || (scanline == SCANLINE_VBLANK))
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
}
|
||||
|
||||
io.latch = (address & 0x3F00) != 0x3F00 ? io.buffer : palette.ram[address & 0x1F] & Coloring();
|
||||
io.buffer = (address >= 0x2000 ? nmt.FetchName( address ) : chr.FetchPattern( address ));
|
||||
@ -1458,7 +1410,7 @@ namespace Nes
|
||||
{
|
||||
NST_VERIFY( cycles.count != cycles.hClock );
|
||||
|
||||
if (scanline_sleep >= 0)
|
||||
if (scanline_sleep) // Extra lines between VBLANK and NMI in Dendy mode
|
||||
{
|
||||
switch (cycles.hClock)
|
||||
{
|
||||
@ -1807,15 +1759,15 @@ namespace Nes
|
||||
|
||||
case 338:
|
||||
|
||||
if (scanline_sleep++ != ssleep)
|
||||
if (++scanline_sleep < PPU_DENDY_VSLEEP)
|
||||
{
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += 341;
|
||||
cycles.vClock += HCLOCK_DUMMY;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
if (cycles.count <= HCLOCK_DUMMY)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
cycles.count -= HCLOCK_DUMMY;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
@ -1828,37 +1780,13 @@ namespace Nes
|
||||
}
|
||||
|
||||
case HCLOCK_VBLANK_0:
|
||||
VBlank0:
|
||||
|
||||
regs.status |= Regs::STATUS_VBLANKING;
|
||||
cycles.hClock = HCLOCK_VBLANK_1;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_1)
|
||||
break;
|
||||
goto VBlank0;
|
||||
|
||||
case HCLOCK_VBLANK_1:
|
||||
VBlank1:
|
||||
|
||||
regs.status = (regs.status & 0xFF) | (regs.status >> 1 & Regs::STATUS_VBLANK);
|
||||
oam.visible = oam.output;
|
||||
cycles.hClock = HCLOCK_VBLANK_2;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_2)
|
||||
break;
|
||||
goto VBlank1;
|
||||
|
||||
case HCLOCK_VBLANK_2:
|
||||
VBlank2:
|
||||
|
||||
scanline_sleep = -1;
|
||||
|
||||
cycles.hClock = HCLOCK_DUMMY;
|
||||
cycles.count = Cpu::CYCLE_MAX;
|
||||
cycles.reset = 0;
|
||||
|
||||
if (regs.ctrl[0] & regs.status & Regs::CTRL0_NMI)
|
||||
cpu.DoNMI( cpu.GetFrameCycles() );
|
||||
|
||||
return;
|
||||
goto VBlank2;
|
||||
}
|
||||
}
|
||||
else if (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED)
|
||||
@ -2519,7 +2447,7 @@ namespace Nes
|
||||
|
||||
if (scanline++ != 239)
|
||||
{
|
||||
const uint line = (scanline != 0 || model != PPU_RP2C02 || !regs.frame ? 341 : 340);
|
||||
const uint line = (scanline != 0 || model != PPU_RP2C02 || !regs.frame ? HCLOCK_DUMMY : (HCLOCK_DUMMY - 1));
|
||||
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += line;
|
||||
@ -2533,16 +2461,17 @@ namespace Nes
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ssleep >= 0)
|
||||
if (model == PPU_DENDY)
|
||||
{
|
||||
scanline_sleep = 0;
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += 341;
|
||||
scanline_sleep = 1;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += HCLOCK_DUMMY;
|
||||
|
||||
if (cycles.count <= HCLOCK_DUMMY)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
cycles.count -= HCLOCK_DUMMY;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
@ -2556,13 +2485,37 @@ namespace Nes
|
||||
}
|
||||
|
||||
case HCLOCK_VBLANK_0:
|
||||
goto VBlank0;
|
||||
VBlank0:
|
||||
|
||||
regs.status |= Regs::STATUS_VBLANKING;
|
||||
cycles.hClock = HCLOCK_VBLANK_1;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_1)
|
||||
break;
|
||||
|
||||
case HCLOCK_VBLANK_1:
|
||||
goto VBlank1;
|
||||
VBlank1:
|
||||
|
||||
regs.status = (regs.status & 0xFF) | (regs.status >> 1 & Regs::STATUS_VBLANK);
|
||||
oam.visible = oam.output;
|
||||
cycles.hClock = HCLOCK_VBLANK_2;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_2)
|
||||
break;
|
||||
|
||||
case HCLOCK_VBLANK_2:
|
||||
goto VBlank2;
|
||||
VBlank2:
|
||||
|
||||
scanline_sleep = 0;
|
||||
|
||||
cycles.hClock = HCLOCK_DUMMY;
|
||||
cycles.count = Cpu::CYCLE_MAX;
|
||||
cycles.reset = 0;
|
||||
|
||||
if (regs.ctrl[0] & regs.status & Regs::CTRL0_NMI)
|
||||
cpu.DoNMI( cpu.GetFrameCycles() );
|
||||
|
||||
return;
|
||||
|
||||
case HCLOCK_BOOT:
|
||||
goto Boot;
|
||||
@ -3227,29 +3180,29 @@ namespace Nes
|
||||
if (scanline == 0 && model == PPU_RP2C02)
|
||||
output.burstPhase = (output.burstPhase + 1) % 3;
|
||||
|
||||
cycles.vClock += 341;
|
||||
cycles.vClock += HCLOCK_DUMMY;
|
||||
cycles.hClock = 0;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
if (cycles.count <= HCLOCK_DUMMY)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
cycles.count -= HCLOCK_DUMMY;
|
||||
|
||||
goto HActiveOff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ssleep >= 0)
|
||||
else
|
||||
{
|
||||
if (model == PPU_DENDY)
|
||||
{
|
||||
scanline_sleep = 0;
|
||||
scanline_sleep = 1;
|
||||
|
||||
cycles.vClock += 341;
|
||||
cycles.vClock += HCLOCK_DUMMY;
|
||||
cycles.hClock = 0;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
if (cycles.count <= HCLOCK_DUMMY)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
cycles.count -= HCLOCK_DUMMY;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
|
@ -139,7 +139,6 @@ namespace Nes
|
||||
|
||||
enum
|
||||
{
|
||||
HCLOCK_POSTRENDER = 340,
|
||||
HCLOCK_DUMMY = 341,
|
||||
HCLOCK_VBLANK_0 = 681,
|
||||
HCLOCK_VBLANK_1 = 682,
|
||||
@ -176,6 +175,7 @@ namespace Nes
|
||||
NST_FORCE_INLINE uint Emphasis() const;
|
||||
|
||||
NST_FORCE_INLINE void UpdateAddressLine(uint);
|
||||
NST_FORCE_INLINE void UpdateScrollAddressLine();
|
||||
NST_FORCE_INLINE void UpdateVramAddress();
|
||||
|
||||
NST_FORCE_INLINE void OpenName();
|
||||
@ -345,9 +345,6 @@ namespace Nes
|
||||
|
||||
typedef void (Ppu::*Phase)();
|
||||
|
||||
byte ram[0x100];
|
||||
byte buffer[MAX_LINE_SPRITES * 4];
|
||||
|
||||
const byte* limit;
|
||||
Output* visible;
|
||||
Phase phase;
|
||||
@ -361,6 +358,9 @@ namespace Nes
|
||||
bool spriteZeroInLine;
|
||||
bool spriteLimit;
|
||||
|
||||
byte ram[0x100];
|
||||
byte buffer[MAX_LINE_SPRITES*4];
|
||||
|
||||
Output output[MAX_LINE_SPRITES];
|
||||
};
|
||||
|
||||
@ -415,9 +415,9 @@ namespace Nes
|
||||
Nmt nmt;
|
||||
int scanline;
|
||||
int scanline_sleep;
|
||||
int ssleep;
|
||||
bool overclocked;
|
||||
|
||||
public:
|
||||
Output output;
|
||||
private:
|
||||
PpuModel model;
|
||||
Hook hActiveHook;
|
||||
Hook hBlankHook;
|
||||
@ -432,7 +432,6 @@ namespace Nes
|
||||
static const byte yuvMaps[4][0x40];
|
||||
|
||||
public:
|
||||
Output output;
|
||||
|
||||
void Update()
|
||||
{
|
||||
@ -543,16 +542,6 @@ namespace Nes
|
||||
{
|
||||
return oam.spriteLimit;
|
||||
}
|
||||
|
||||
bool GetOverclockState() const
|
||||
{
|
||||
return overclocked;
|
||||
}
|
||||
|
||||
void SetOverclockState(bool overclock2x)
|
||||
{
|
||||
overclocked = overclock2x;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,10 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
#define NST_NO_SCALEX 1
|
||||
#define NST_NO_HQ2X 1
|
||||
#define NST_NO_2XSAI 1
|
||||
#define NST_NO_XBR 1
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
@ -58,20 +58,6 @@ namespace Nes
|
||||
return RESULT_NOP;
|
||||
}
|
||||
|
||||
Result Video::EnableOverclocking(bool state) throw()
|
||||
{
|
||||
if (emulator.tracker.IsLocked( true ))
|
||||
return RESULT_ERR_NOT_READY;
|
||||
|
||||
if (emulator.ppu.GetOverclockState() != state)
|
||||
{
|
||||
emulator.ppu.SetOverclockState( state );
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
return RESULT_NOP;
|
||||
}
|
||||
|
||||
bool Video::AreUnlimSpritesEnabled() const throw()
|
||||
{
|
||||
return !emulator.ppu.HasSpriteLimit();
|
||||
|
@ -223,11 +223,6 @@ namespace Nes
|
||||
* @return result code
|
||||
*/
|
||||
Result EnableUnlimSprites(bool state) throw();
|
||||
|
||||
/**
|
||||
* Adds extra scanlines to fix lag
|
||||
*/
|
||||
Result EnableOverclocking(bool state) throw();
|
||||
|
||||
/**
|
||||
* Checks if the PPU sprite software extension is enabled.
|
||||
|
@ -97,13 +97,13 @@
|
||||
#include "NstBoardWaixing.hpp"
|
||||
#include "NstBoardWhirlwind.hpp"
|
||||
#include "NstBoardBenshengBs5.hpp"
|
||||
#include "NstBoardUnlN625092.hpp"
|
||||
#include "NstBoardUnlA9746.hpp"
|
||||
#include "NstBoardUnlCc21.hpp"
|
||||
#include "NstBoardUnlEdu2000.hpp"
|
||||
#include "NstBoardUnlKingOfFighters96.hpp"
|
||||
#include "NstBoardUnlKingOfFighters97.hpp"
|
||||
#include "NstBoardUnlMortalKombat2.hpp"
|
||||
#include "NstBoardUnlN625092.hpp"
|
||||
#include "NstBoardUnlSuperFighter3.hpp"
|
||||
#include "NstBoardUnlTf1201.hpp"
|
||||
#include "NstBoardUnlWorldHero.hpp"
|
||||
@ -397,7 +397,16 @@ namespace Nes
|
||||
{
|
||||
wrk.Source().SetSecurity( true, board.GetWram() > 0 );
|
||||
|
||||
for (uint i=board.GetSavableWram(), n=board.GetWram(); i < n; ++i)
|
||||
uint i = board.GetSavableWram();
|
||||
uint n = board.GetWram();
|
||||
|
||||
if (board.GetMapper() == 1 && board.GetWram() == SIZE_16K)
|
||||
{
|
||||
i = 0;
|
||||
n = SIZE_8K;
|
||||
}
|
||||
|
||||
for (; i < n; ++i)
|
||||
*wrk.Source().Mem(i) = (board.IsAutoWram() && i < SIZE_8K) ? (0x6000 + i) >> 8 : 0x00;
|
||||
|
||||
vram.Fill( 0x00 );
|
||||
@ -815,7 +824,7 @@ namespace Nes
|
||||
{ "CAMERICA-BF9097", Type::CAMERICA_BF9097 },
|
||||
{ "CAMERICA-GAMEGENIE", Type::STD_NROM },
|
||||
{ "COLORDREAMS-74*377", Type::DISCRETE_74_377 },
|
||||
{ "DREAMTECH01", Type::DREAMTECH_01 },
|
||||
{ "DREAMTECH01", Type::DREAMTECH01 },
|
||||
{ "HVC-AMROM", Type::STD_AMROM },
|
||||
{ "HVC-AN1ROM", Type::STD_AN1ROM },
|
||||
{ "HVC-ANROM", Type::STD_ANROM },
|
||||
@ -1096,8 +1105,11 @@ namespace Nes
|
||||
{ "UNL-EDU2000", Type::UNL_EDU2000 },
|
||||
{ "UNL-H2288", Type::KAY_H2288 },
|
||||
{ "UNL-KOF97", Type::UNL_KINGOFFIGHTERS97 },
|
||||
{ "UNL-KS7013B", Type::KAISER_KS7013B },
|
||||
{ "UNL-KS7016", Type::KAISER_KS7016 },
|
||||
{ "UNL-KS7031", Type::KAISER_KS7031 },
|
||||
{ "UNL-KS7032", Type::KAISER_KS7032 },
|
||||
{ "UNL-KS7037", Type::KAISER_KS7037 },
|
||||
{ "UNL-N625092", Type::UNL_N625092 },
|
||||
{ "UNL-SA-0036", Type::SACHEN_SA0036 },
|
||||
{ "UNL-SA-0037", Type::SACHEN_SA0037 },
|
||||
@ -1110,7 +1122,7 @@ namespace Nes
|
||||
{ "UNL-SACHEN-8259B", Type::SACHEN_8259B },
|
||||
{ "UNL-SACHEN-8259C", Type::SACHEN_8259C },
|
||||
{ "UNL-SACHEN-8259D", Type::SACHEN_8259D },
|
||||
{ "UNL-SHERO", Type::SACHEN_STREETHEROES },
|
||||
{ "UNL-SHERO", Type::UNL_SHERO },
|
||||
{ "UNL-SL1632", Type::REXSOFT_SL1632 },
|
||||
{ "UNL-SMB2J", Type::BTL_SMB2_C },
|
||||
{ "UNL-T-230", Type::BTL_T230 },
|
||||
@ -1218,7 +1230,7 @@ namespace Nes
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Board::Context::DetectBoard(const byte mapper,const byte submapper,const dword chrRam,const dword wram,bool wramAuto)
|
||||
bool Board::Context::DetectBoard(const word mapper,const byte submapper,const dword chrRam,const dword wram,bool wramAuto)
|
||||
{
|
||||
Type::Id id;
|
||||
|
||||
@ -1241,7 +1253,12 @@ namespace Nes
|
||||
{
|
||||
case 0:
|
||||
|
||||
if ((prg < SIZE_32K && prg != SIZE_16K) || !chr || wram >= SIZE_8K || (nmt != Type::NMT_HORIZONTAL && nmt != Type::NMT_VERTICAL))
|
||||
if (prg == SIZE_8K && chr == SIZE_8K)
|
||||
{
|
||||
name = "NAMCOT-3301";
|
||||
id = Type::STD_NROM;
|
||||
}
|
||||
else if ((prg < SIZE_32K && prg != SIZE_16K) || !chr || wram >= SIZE_8K || (nmt != Type::NMT_HORIZONTAL && nmt != Type::NMT_VERTICAL))
|
||||
{
|
||||
name = "NROM (non-standard)";
|
||||
id = Type::UNL_NROM;
|
||||
@ -1921,8 +1938,16 @@ namespace Nes
|
||||
|
||||
case 27:
|
||||
|
||||
name = "UNL WORLDHERO";
|
||||
id = Type::UNL_WORLDHERO;
|
||||
if (prg >= SIZE_128K)
|
||||
{
|
||||
name = "UNL WORLDHERO";
|
||||
id = Type::UNL_WORLDHERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "UNL-CC-21";
|
||||
id = Type::UNL_CC21;
|
||||
}
|
||||
break;
|
||||
|
||||
case 28:
|
||||
@ -2833,8 +2858,21 @@ namespace Nes
|
||||
|
||||
case 176:
|
||||
|
||||
name = "XIAO ZHUAN YUAN";
|
||||
id = Type::UNL_XZY;
|
||||
if (prg >= SIZE_2048K)
|
||||
{
|
||||
name = "BMC-SUPER24IN1SC03";
|
||||
id = Type::BMC_SUPER_24IN1;
|
||||
}
|
||||
else if (prg > SIZE_128K)
|
||||
{
|
||||
name = "BMC-FK23C";
|
||||
id = Type::BMC_FKC23C;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "XIAO ZHUAN YUAN";
|
||||
id = Type::UNL_XZY;
|
||||
}
|
||||
break;
|
||||
|
||||
case 177:
|
||||
@ -3170,11 +3208,16 @@ namespace Nes
|
||||
name = "BMC SUPER 42-IN-1";
|
||||
id = Type::BMC_SUPER_42IN1;
|
||||
}
|
||||
else
|
||||
else if (prg == SIZE_2048K)
|
||||
{
|
||||
name = "BMC 76-IN-1";
|
||||
id = Type::BMC_76IN1;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "BMC-GHOSTBUSTERS63IN1";
|
||||
id = Type::BMC_CTC65;
|
||||
}
|
||||
break;
|
||||
|
||||
case 227:
|
||||
@ -3334,6 +3377,127 @@ namespace Nes
|
||||
id = Type::BMC_110IN1;
|
||||
break;
|
||||
|
||||
case 262:
|
||||
|
||||
name = "UNL-SHERO";
|
||||
id = Type::UNL_SHERO;
|
||||
break;
|
||||
|
||||
case 263:
|
||||
|
||||
name = "UNL-KOF97";
|
||||
id = Type::UNL_KINGOFFIGHTERS97;
|
||||
break;
|
||||
|
||||
case 265:
|
||||
|
||||
name = "BMC-T-262";
|
||||
id = Type::BMC_T262;
|
||||
break;
|
||||
|
||||
case 283:
|
||||
if (prg > SIZE_256K)
|
||||
{
|
||||
name = "BMC-GS-2013";
|
||||
id = Type::RCM_GS2013;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "BMC-GS-2004";
|
||||
id = Type::RCM_GS2004;
|
||||
}
|
||||
break;
|
||||
|
||||
case 285:
|
||||
|
||||
name = "BMC-A65AS";
|
||||
id = Type::BMC_A65AS;
|
||||
break;
|
||||
|
||||
case 286:
|
||||
|
||||
name = "BMC-BS-5";
|
||||
id = Type::BENSHENG_BS5;
|
||||
break;
|
||||
|
||||
case 298:
|
||||
|
||||
name = "UNL-TF1201";
|
||||
id = Type::UNL_TF1201;
|
||||
break;
|
||||
|
||||
case 300:
|
||||
|
||||
name = "BMC-190IN1";
|
||||
id = Type::BMC_GOLDEN_190IN1;
|
||||
break;
|
||||
|
||||
case 301:
|
||||
|
||||
name = "BMC-8157";
|
||||
id = Type::BMC_8157;
|
||||
break;
|
||||
|
||||
case 305:
|
||||
|
||||
name = "UNL-KS7031";
|
||||
id = Type::KAISER_KS7031;
|
||||
break;
|
||||
|
||||
case 306:
|
||||
|
||||
name = "UNL-KS7016";
|
||||
id = Type::KAISER_KS7016;
|
||||
break;
|
||||
|
||||
case 307:
|
||||
|
||||
name = "UNL-KS7037";
|
||||
id = Type::KAISER_KS7037;
|
||||
break;
|
||||
|
||||
case 312:
|
||||
|
||||
name = "UNL-KS7013B";
|
||||
id = Type::KAISER_KS7013B;
|
||||
break;
|
||||
|
||||
case 314:
|
||||
|
||||
name = "BMC-64IN1NOREPEAT";
|
||||
id = Type::BMC_Y2K_64IN1;
|
||||
break;
|
||||
|
||||
case 329:
|
||||
|
||||
name = "UNL-EDU2000";
|
||||
id = Type::UNL_EDU2000;
|
||||
break;
|
||||
|
||||
case 332:
|
||||
|
||||
name = "BMC-WS";
|
||||
id = Type::BMC_SUPER_40IN1;
|
||||
break;
|
||||
|
||||
case 521:
|
||||
|
||||
name = "DREAMTECH01";
|
||||
id = Type::DREAMTECH01;
|
||||
break;
|
||||
|
||||
case 529:
|
||||
|
||||
name = "UNL-T-230";
|
||||
id = Type::BTL_T230;
|
||||
break;
|
||||
|
||||
case 530:
|
||||
|
||||
name = "UNL-AX5705";
|
||||
id = Type::BTL_AX5705;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return false;
|
||||
@ -3537,7 +3701,7 @@ namespace Nes
|
||||
case Type::CNE_DECATHLON : return new Cne::Decathlon(c);
|
||||
case Type::CNE_PSB : return new Cne::Psb(c);
|
||||
case Type::CONY_STD : return new Cony::Standard(c);
|
||||
case Type::DREAMTECH_01 : return new DreamTech::D01(c);
|
||||
case Type::DREAMTECH01 : return new DreamTech::D01(c);
|
||||
case Type::FUTUREMEDIA_STD : return new FutureMedia::Standard(c);
|
||||
case Type::FUJIYA_STD : return new Fujiya::Standard(c);
|
||||
case Type::FUKUTAKE_SBX : return new Fukutake::Sbx(c);
|
||||
@ -3602,9 +3766,12 @@ namespace Nes
|
||||
case Type::JYCOMPANY_TYPE_B :
|
||||
case Type::JYCOMPANY_TYPE_C : return new JyCompany::Standard(c);
|
||||
case Type::KAISER_KS202 : return new Kaiser::Ks202(c);
|
||||
case Type::KAISER_KS7013B : return new Kaiser::Ks7013b(c);
|
||||
case Type::KAISER_KS7016 : return new Kaiser::Ks7016(c);
|
||||
case Type::KAISER_KS7022 : return new Kaiser::Ks7022(c);
|
||||
case Type::KAISER_KS7031 : return new Kaiser::Ks7031(c);
|
||||
case Type::KAISER_KS7032 : return new Kaiser::Ks7032(c);
|
||||
case Type::KAISER_KS7037 : return new Kaiser::Ks7037(c);
|
||||
case Type::KAISER_KS7058 : return new Kaiser::Ks7058(c);
|
||||
case Type::KASING_STD : return new Kasing::Standard(c);
|
||||
case Type::KAY_H2288 : return new Kay::H2288(c);
|
||||
@ -3631,8 +3798,8 @@ namespace Nes
|
||||
case Type::NAMCOT_163_1 :
|
||||
case Type::NAMCOT_163_S_0 :
|
||||
case Type::NAMCOT_163_S_1 : return new Namcot::N163(c);
|
||||
case Type::NAMCOT_340 :
|
||||
case Type::NAMCOT_175 : return new Namcot::N175(c);
|
||||
case Type::NAMCOT_340 : return new Namcot::N340(c);
|
||||
case Type::NANJING_STD : return new Nanjing::Standard(c);
|
||||
case Type::UNL_UXROM_M5 :
|
||||
case Type::NIHON_UNROM_M5 : return new Nihon::UnRomM5(c);
|
||||
@ -3662,7 +3829,6 @@ namespace Nes
|
||||
case Type::SACHEN_SA72008 : return new Sachen::Sa72008(c);
|
||||
case Type::SACHEN_74_374A : return new Sachen::S74x374a(c);
|
||||
case Type::SACHEN_74_374B : return new Sachen::S74x374b(c);
|
||||
case Type::SACHEN_STREETHEROES : return new Sachen::StreetHeroes(c);
|
||||
case Type::SOMERITEAM_SL12 : return new SomeriTeam::Sl12(c);
|
||||
case Type::SUBOR_TYPE0 : return new Subor::Type0(c);
|
||||
case Type::SUBOR_TYPE1 : return new Subor::Type1(c);
|
||||
@ -3707,6 +3873,7 @@ namespace Nes
|
||||
case Type::UNL_MORTALKOMBAT2 : return new Unlicensed::MortalKombat2(c);
|
||||
case Type::UNL_N625092 : return new Unlicensed::N625092(c);
|
||||
case Type::UNL_SUPERFIGHTER3 : return new Unlicensed::SuperFighter3(c);
|
||||
case Type::UNL_SHERO : return new Sachen::StreetHeroes(c);
|
||||
case Type::UNL_TF1201 : return new Unlicensed::Tf1201(c);
|
||||
case Type::UNL_WORLDHERO : return new Unlicensed::WorldHero(c);
|
||||
case Type::UNL_XZY : return new Unlicensed::Xzy(c);
|
||||
|
@ -94,7 +94,7 @@ namespace Nes
|
||||
CRM_32
|
||||
};
|
||||
|
||||
template<byte MPR,word PROM,word CROM,byte NVWRAM,byte WRAM,Cram CRAM,NmtInit NMT,byte UNIQUE>
|
||||
template<word MPR,word PROM,word CROM,byte NVWRAM,byte WRAM,Cram CRAM,NmtInit NMT,byte UNIQUE>
|
||||
struct MakeId
|
||||
{
|
||||
NST_COMPILE_ASSERT
|
||||
@ -258,7 +258,7 @@ namespace Nes
|
||||
BANDAI_AEROBICSSTUDIO = MakeId< 3, 32, 32, 0, 0, CRM_0, NMT_X, 2 >::ID,
|
||||
BANDAI_OEKAKIDS = MakeId< 96, 128, 0, 0, 0, CRM_32, NMT_1, 0 >::ID,
|
||||
// Bensheng
|
||||
BENSHENG_BS5 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 2 >::ID,
|
||||
BENSHENG_BS5 = MakeId< 286, 128, 64, 0, 0, CRM_0, NMT_V, 2 >::ID,
|
||||
// Bootleg multicarts
|
||||
BMC_110IN1 = MakeId< 255, 2048, 1024, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_150IN1 = MakeId< 202, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
@ -273,16 +273,16 @@ namespace Nes
|
||||
BMC_64IN1 = MakeId< 204, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_72IN1 = MakeId< 225, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_76IN1 = MakeId< 226, 2048, 0, 0, 0, CRM_8, NMT_H, 0 >::ID,
|
||||
BMC_8157 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_8157 = MakeId< 301, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_9999999IN1 = MakeId< 213, 128, 64, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_A65AS = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_V, 1 >::ID,
|
||||
BMC_A65AS = MakeId< 285, 512, 0, 0, 0, CRM_8, NMT_V, 1 >::ID,
|
||||
BMC_BALLGAMES_11IN1 = MakeId< 51, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_CTC65 = MakeId< NMPR, 2048, 0, 0, 0, CRM_8, NMT_H, 0 >::ID,
|
||||
BMC_CTC65 = MakeId< 226, 2048, 0, 0, 0, CRM_8, NMT_H, 1 >::ID,
|
||||
BMC_DRAGONBOLLPARTY = MakeId< 83, 1024, 1024, 8, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_FAMILY_4646B = MakeId< 134, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_FKC23C = MakeId< NMPR, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_FKC23C = MakeId< 176, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_GAME_800IN1 = MakeId< 236, 512, 64, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_GOLDEN_190IN1 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_GOLDEN_190IN1 = MakeId< 300, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_GOLDENGAME_150IN1 = MakeId< 235, 2048, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_GOLDENGAME_260IN1 = MakeId< 235, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_GKA = MakeId< 57, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
@ -294,9 +294,9 @@ namespace Nes
|
||||
BMC_CH001 = MakeId< 63, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_POWERJOY_84IN1 = MakeId< 126, 2048, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_RESETBASED_4IN1 = MakeId< 60, 64, 32, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_SUPER_24IN1 = MakeId< NMPR, 4096, 2048, 8, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
BMC_SUPER_24IN1 = MakeId< 176, 4096, 2048, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
BMC_SUPER_22GAMES = MakeId< 233, 1024, 0, 0, 0, CRM_8, NMT_Z, 0 >::ID,
|
||||
BMC_SUPER_40IN1 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 1 >::ID,
|
||||
BMC_SUPER_40IN1 = MakeId< 332, 128, 64, 0, 0, CRM_0, NMT_V, 1 >::ID,
|
||||
BMC_SUPER_42IN1 = MakeId< 226, 1024, 0, 0, 0, CRM_8, NMT_H, 0 >::ID,
|
||||
BMC_SUPER_700IN1 = MakeId< 62, 2048, 1024, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_SUPERBIG_7IN1 = MakeId< 44, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
@ -304,15 +304,15 @@ namespace Nes
|
||||
BMC_SUPERHIK_4IN1 = MakeId< 49, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BMC_SUPERHIK_300IN1 = MakeId< 212, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_SUPERVISION_16IN1 = MakeId< 53, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_T262 = MakeId< NMPR, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_T262 = MakeId< 265, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_VRC4 = MakeId< 23, 512, 0, 8, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BMC_VT5201 = MakeId< 60, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_Y2K_64IN1 = MakeId< NMPR, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BMC_Y2K_64IN1 = MakeId< 314, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
// Bootlegs
|
||||
BTL_2708 = MakeId< 103, 128, 0, 0, 16, CRM_8, NMT_V, 0 >::ID,
|
||||
BTL_6035052 = MakeId< 238, 512, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_AISENSHINICOL = MakeId< 42, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
BTL_AX5705 = MakeId< NMPR, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_AX5705 = MakeId< 530, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_DRAGONNINJA = MakeId< 222, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_GENIUSMERIOBROS = MakeId< 55, 64, 8, 2, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_MARIOBABY = MakeId< 42, 128, 128, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
@ -323,7 +323,7 @@ namespace Nes
|
||||
BTL_SMB2_C = MakeId< 43, 128, 8, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
BTL_SMB3 = MakeId< 106, 256, 128, 8, 0, CRM_0, NMT_H, 0 >::ID,
|
||||
BTL_SUPERBROS11 = MakeId< 196, 512, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
BTL_T230 = MakeId< NMPR, 256, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BTL_T230 = MakeId< 529, 256, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
BTL_TOBIDASEDAISAKUSEN = MakeId< 120, 128, 8, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Camerica
|
||||
CAMERICA_BF9093 = MakeId< 71, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
@ -342,7 +342,7 @@ namespace Nes
|
||||
// Cony
|
||||
CONY_STD = MakeId< 83, 256, 512, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
// Dreamtech
|
||||
DREAMTECH_01 = MakeId< NMPR, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
DREAMTECH01 = MakeId< 521, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
// Fujiya
|
||||
FUJIYA_STD = MakeId< 170, 32, 8, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Fukutake
|
||||
@ -418,9 +418,12 @@ namespace Nes
|
||||
JYCOMPANY_TYPE_C = MakeId< 211, 2048, 2048, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Kaiser
|
||||
KAISER_KS202 = MakeId< 56, 256, 128, 8, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
KAISER_KS7013B = MakeId< 312, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
KAISER_KS7016 = MakeId< 306, 128, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
KAISER_KS7022 = MakeId< 175, 256, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
KAISER_KS7031 = MakeId< NMPR, 128, 0, 0, 16, CRM_8, NMT_V, 0 >::ID,
|
||||
KAISER_KS7031 = MakeId< 305, 128, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
KAISER_KS7032 = MakeId< 142, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
KAISER_KS7037 = MakeId< 307, 128, 0, 0, 8, CRM_8, NMT_X, 0 >::ID,
|
||||
KAISER_KS7058 = MakeId< 171, 32, 32, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Kasing
|
||||
KASING_STD = MakeId< 115, 512, 512, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
@ -454,8 +457,7 @@ namespace Nes
|
||||
NAMCOT_163_S_0 = MakeId< 19, 512, 256, 0, 0, CRM_0, NMT_X, 1 >::ID,
|
||||
NAMCOT_163_S_1 = MakeId< 19, 512, 256, 8, 0, CRM_0, NMT_X, 1 >::ID,
|
||||
NAMCOT_175 = MakeId< 210, 512, 128, 8, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
// FIXME: Setting NMT_4 is incorrect but makes things work
|
||||
NAMCOT_340 = MakeId< 210, 256, 256, 0, 0, CRM_0, NMT_4, 0 >::ID,
|
||||
NAMCOT_340 = MakeId< 210, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Nitra
|
||||
NITRA_TDA = MakeId< 250, 512, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
// NTDEC
|
||||
@ -468,10 +470,10 @@ namespace Nes
|
||||
// Nihon Bussan
|
||||
NIHON_UNROM_M5 = MakeId< 180, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
// Open Corp
|
||||
OPENCORP_DAOU306 = MakeId< 156, 256, 256, 8, 0, CRM_0, NMT_1, 0 >::ID,
|
||||
OPENCORP_DAOU306 = MakeId< 156, 256, 512, 8, 0, CRM_0, NMT_1, 0 >::ID,
|
||||
// RCM
|
||||
RCM_GS2004 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
RCM_GS2013 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_X, 1 >::ID,
|
||||
RCM_GS2004 = MakeId< 283, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
RCM_GS2013 = MakeId< 283, 512, 0, 0, 0, CRM_8, NMT_X, 1 >::ID,
|
||||
RCM_GS2015 = MakeId< 216, 64, 64, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
RCM_TETRISFAMILY = MakeId< 61, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID,
|
||||
// Rex Soft
|
||||
@ -492,7 +494,6 @@ namespace Nes
|
||||
SACHEN_SA72008 = MakeId< 133, 64, 32, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
SACHEN_74_374A = MakeId< 243, 64, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
SACHEN_74_374B = MakeId< 150, 64, 128, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
SACHEN_STREETHEROES = MakeId< NMPR, 512, 512, 0, 0, CRM_8, NMT_2, 0 >::ID,
|
||||
// Someri Team
|
||||
SOMERITEAM_SL12 = MakeId< 116, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Subor
|
||||
@ -526,7 +527,6 @@ namespace Nes
|
||||
TENGEN_800004 = MakeId< 206, 128, 64, 0, 0, CRM_0, NMT_2, 1 >::ID,
|
||||
TENGEN_800008 = MakeId< 3, 64, 64, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
TENGEN_800030 = MakeId< 206, 128, 64, 0, 0, CRM_0, NMT_X, 1 >::ID,
|
||||
//TENGEN_800032 = MakeId< 64, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
TENGEN_800032 = MakeId< 64, 128, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
TENGEN_800037 = MakeId< 158, 128, 128, 0, 0, CRM_0, NMT_Z, 0 >::ID,
|
||||
TENGEN_800042 = MakeId< 68, 128, 256, 0, 0, CRM_0, NMT_V, 1 >::ID,
|
||||
@ -539,14 +539,15 @@ namespace Nes
|
||||
TXC_TW = MakeId< 189, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
// Unlicensed
|
||||
UNL_A9746 = MakeId< 219, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_CC21 = MakeId< NMPR, 32, 16, 0, 0, CRM_0, NMT_Z, 0 >::ID,
|
||||
UNL_EDU2000 = MakeId< NMPR, 1024, 0, 32, 0, CRM_8, NMT_Z, 0 >::ID,
|
||||
UNL_CC21 = MakeId< 27, 32, 8, 0, 0, CRM_0, NMT_Z, 0 >::ID,
|
||||
UNL_EDU2000 = MakeId< 329, 1024, 0, 0, 32, CRM_8, NMT_Z, 0 >::ID,
|
||||
UNL_KINGOFFIGHTERS96 = MakeId< 187, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_KINGOFFIGHTERS97 = MakeId< NMPR, 512, 256, 0, 0, CRM_0, NMT_X, 1 >::ID,
|
||||
UNL_KINGOFFIGHTERS97 = MakeId< 263, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_MORTALKOMBAT2 = MakeId< 91, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_N625092 = MakeId< 221, 1024, 8, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
UNL_SUPERFIGHTER3 = MakeId< 197, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_TF1201 = MakeId< NMPR, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
UNL_SHERO = MakeId< 262, 512, 512, 0, 0, CRM_8, NMT_4, 0 >::ID,
|
||||
UNL_TF1201 = MakeId< 298, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID,
|
||||
UNL_WORLDHERO = MakeId< 27, 128, 512, 0, 0, CRM_0, NMT_X, 0 >::ID,
|
||||
UNL_AXROM = MakeId< 7, 512, 8, 8, 0, CRM_0, NMT_Z, 0 >::ID,
|
||||
UNL_BXROM = MakeId< 34, 4096, 8, 8, 0, CRM_8, NMT_X, 0 >::ID,
|
||||
@ -653,7 +654,7 @@ namespace Nes
|
||||
Context(Cpu*,Apu*,Ppu*,Ram&,Ram&,const Ram&,Type::Nmt,bool,bool,Chips&);
|
||||
|
||||
bool DetectBoard(wcstring,dword);
|
||||
bool DetectBoard(byte,byte,dword,dword,bool);
|
||||
bool DetectBoard(word,byte,dword,dword,bool);
|
||||
|
||||
cstring name;
|
||||
Type type;
|
||||
|
@ -40,6 +40,7 @@ namespace Nes
|
||||
void Bf9093::SubReset(bool)
|
||||
{
|
||||
Map( 0xC000U, 0xFFFFU, PRG_SWAP_16K_0 );
|
||||
Map( 0x8000U, 0xBFFFU, &Bf9093::Poke_C000 );
|
||||
}
|
||||
|
||||
void Bf9096::SubReset(bool)
|
||||
@ -68,6 +69,11 @@ namespace Nes
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
NES_POKE_D(Bf9093,C000)
|
||||
{
|
||||
prg.SwapBank<SIZE_16K,0x0000>( data );
|
||||
}
|
||||
|
||||
void Bf9096::SwapBasePrg(uint base)
|
||||
{
|
||||
prg.SwapBanks<SIZE_16K,0x0000>( base | (prg.GetBank<SIZE_16K,0x0000>() & 0x3), base | 0x3 );
|
||||
|
@ -47,6 +47,10 @@ namespace Nes
|
||||
protected:
|
||||
|
||||
void SubReset(bool);
|
||||
|
||||
private:
|
||||
|
||||
NES_DECL_POKE( C000 );
|
||||
};
|
||||
|
||||
class Bf9096 : public Board
|
||||
|
@ -3,6 +3,7 @@
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
@ -38,27 +39,6 @@ namespace Nes
|
||||
#pragma optimize("s", on)
|
||||
#endif
|
||||
|
||||
void Ks7058::SubReset(bool)
|
||||
{
|
||||
for (uint i=0x000; i < 0x1000; i += 0x100)
|
||||
{
|
||||
Map( 0xF000+i, 0xF07F+i, CHR_SWAP_4K_0 );
|
||||
Map( 0xF080+i, 0xF0FF+i, CHR_SWAP_4K_1 );
|
||||
}
|
||||
}
|
||||
|
||||
void Ks7022::SubReset(const bool hard)
|
||||
{
|
||||
reg = 0;
|
||||
|
||||
if (hard)
|
||||
prg.SwapBanks<SIZE_16K,0x0000>( 0, 0 );
|
||||
|
||||
Map( 0x8000, &Ks7022::Poke_8000 );
|
||||
Map( 0xA000, &Ks7022::Poke_A000 );
|
||||
Map( 0xFFFC, &Ks7022::Peek_FFFC );
|
||||
}
|
||||
|
||||
Ks202::Ks202(const Context& c)
|
||||
: Board(c), irq(*c.cpu) {}
|
||||
|
||||
@ -89,6 +69,36 @@ namespace Nes
|
||||
irq.Reset( hard, hard ? false : irq.Connected() );
|
||||
}
|
||||
|
||||
void Ks7013b::SubReset(const bool hard)
|
||||
{
|
||||
prg.SwapBank<SIZE_16K>( 0x4000, 0x7 );
|
||||
|
||||
Map( 0x6000U, 0x7FFFU, &Ks7013b::Poke_6000 );
|
||||
Map( 0x8000U, 0xFFFFU, &Ks7013b::Poke_8000 );
|
||||
}
|
||||
|
||||
void Ks7016::SubReset(const bool hard)
|
||||
{
|
||||
reg = 8;
|
||||
|
||||
prg.SwapBank<SIZE_32K>( 0x0000, 0x3 );
|
||||
|
||||
Map( 0x6000U, 0x7FFFU, &Ks7016::Peek_6000 );
|
||||
Map( 0x8000U, 0xFFFFU, &Ks7016::Poke_8000 );
|
||||
}
|
||||
|
||||
void Ks7022::SubReset(const bool hard)
|
||||
{
|
||||
reg = 0;
|
||||
|
||||
if (hard)
|
||||
prg.SwapBanks<SIZE_16K,0x0000>( 0, 0 );
|
||||
|
||||
Map( 0x8000, &Ks7022::Poke_8000 );
|
||||
Map( 0xA000, &Ks7022::Poke_A000 );
|
||||
Map( 0xFFFC, &Ks7022::Peek_FFFC );
|
||||
}
|
||||
|
||||
void Ks7031::SubReset(const bool hard)
|
||||
{
|
||||
Map( 0x6000U, 0xFFFEU, &Ks7031::Peek_6000 );
|
||||
@ -106,6 +116,62 @@ namespace Nes
|
||||
Map( 0x6000U, 0x7FFFU, &Ks7032::Peek_6000 );
|
||||
}
|
||||
|
||||
void Ks7037::SubReset(const bool hard)
|
||||
{
|
||||
if (hard)
|
||||
{
|
||||
regNum = 0;
|
||||
|
||||
for (uint i = 0; i < 8; ++i)
|
||||
regs[i] = 0;
|
||||
}
|
||||
|
||||
Map( 0x6000U, 0x6FFFU, &Ks7037::Peek_6000 );
|
||||
Map( 0x6000U, 0x6FFFU, &Ks7037::Poke_6000 );
|
||||
|
||||
Map( 0x7000U, 0x7FFFU, &Ks7037::Peek_7000 );
|
||||
Map( 0x8000U, 0x9FFFU, &Ks7037::Peek_8000 );
|
||||
|
||||
for (uint i = 0x0000; i < 0x2000; i += 0x2)
|
||||
{
|
||||
Map( 0x8000 + i, &Ks7037::Poke_8000 );
|
||||
Map( 0x8001 + i, &Ks7037::Poke_8001 );
|
||||
}
|
||||
|
||||
Map( 0xA000U, 0xAFFFU, &Ks7037::Peek_A000 );
|
||||
|
||||
Map( 0xB000U, 0xBFFFU, &Ks7037::Peek_B000 );
|
||||
Map( 0xB000U, 0xBFFFU, &Ks7037::Poke_B000 );
|
||||
|
||||
Map( 0xC000U, 0xDFFFU, &Ks7037::Peek_C000 );
|
||||
Map( 0xE000U, 0xEFFFU, &Ks7037::Peek_E000 );
|
||||
}
|
||||
|
||||
void Ks7058::SubReset(bool)
|
||||
{
|
||||
for (uint i=0x000; i < 0x1000; i += 0x100)
|
||||
{
|
||||
Map( 0xF000+i, 0xF07F+i, CHR_SWAP_4K_0 );
|
||||
Map( 0xF080+i, 0xF0FF+i, CHR_SWAP_4K_1 );
|
||||
}
|
||||
}
|
||||
|
||||
void Ks7016::SubLoad(State::Loader& state,const dword baseChunk)
|
||||
{
|
||||
NST_VERIFY( (baseChunk == AsciiId<'K','7','6'>::V) );
|
||||
|
||||
if (baseChunk == AsciiId<'K','7','6'>::V)
|
||||
{
|
||||
while (const dword chunk = state.Begin())
|
||||
{
|
||||
if (chunk == AsciiId<'R','E','G'>::V)
|
||||
reg = state.Read8();
|
||||
|
||||
state.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ks7022::SubLoad(State::Loader& state,const dword baseChunk)
|
||||
{
|
||||
NST_VERIFY( (baseChunk == AsciiId<'K','7','2'>::V) );
|
||||
@ -178,9 +244,32 @@ namespace Nes
|
||||
}
|
||||
}
|
||||
|
||||
void Ks7022::SubSave(State::Saver& state) const
|
||||
void Ks7037::SubLoad(State::Loader& state,const dword baseChunk)
|
||||
{
|
||||
state.Begin( AsciiId<'K','7','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End();
|
||||
NST_VERIFY( (baseChunk == AsciiId<'K','7','7'>::V) );
|
||||
|
||||
if (baseChunk == AsciiId<'K','7','7'>::V)
|
||||
{
|
||||
while (const dword chunk = state.Begin())
|
||||
{
|
||||
if (chunk == AsciiId<'R','E','G'>::V)
|
||||
{
|
||||
State::Loader::Data<9> data( state );
|
||||
|
||||
regs[0] = data[0];
|
||||
regs[1] = data[1];
|
||||
regs[2] = data[2];
|
||||
regs[3] = data[3];
|
||||
regs[4] = data[4];
|
||||
regs[5] = data[5];
|
||||
regs[6] = data[6];
|
||||
regs[7] = data[7];
|
||||
regNum = data[8];
|
||||
}
|
||||
|
||||
state.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ks202::SubSave(State::Saver& state) const
|
||||
@ -201,6 +290,16 @@ namespace Nes
|
||||
state.End();
|
||||
}
|
||||
|
||||
void Ks7016::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'K','7','6'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End();
|
||||
}
|
||||
|
||||
void Ks7022::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'K','7','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End();
|
||||
}
|
||||
|
||||
void Ks7031::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'K','7','1'>::V );
|
||||
@ -209,34 +308,25 @@ namespace Nes
|
||||
state.End();
|
||||
}
|
||||
|
||||
void Ks7037::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'K','7','7'>::V );
|
||||
|
||||
const byte data[9] =
|
||||
{
|
||||
regs[0], regs[1], regs[2], regs[3],
|
||||
regs[4], regs[5], regs[6], regs[7],
|
||||
regNum
|
||||
};
|
||||
|
||||
state.Begin( AsciiId<'R','E','G'>::V ).Write( data ).End();
|
||||
state.End();
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
NES_PEEK_A(Ks7032,6000)
|
||||
{
|
||||
return wrk[0][address - 0x6000];
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7022,8000)
|
||||
{
|
||||
ppu.SetMirroring( (data & 0x4) ? Ppu::NMT_H : Ppu::NMT_V );
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7022,A000)
|
||||
{
|
||||
reg = data & 0xF;
|
||||
}
|
||||
|
||||
NES_PEEK(Ks7022,FFFC)
|
||||
{
|
||||
ppu.Update();
|
||||
chr.SwapBank<SIZE_8K,0x0000>( reg );
|
||||
prg.SwapBanks<SIZE_16K,0x0000>( reg, reg );
|
||||
|
||||
return prg.Peek(0x7FFC);
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks202,8000)
|
||||
{
|
||||
irq.Update();
|
||||
@ -326,6 +416,68 @@ namespace Nes
|
||||
}
|
||||
}
|
||||
|
||||
bool Ks202::Irq::Clock()
|
||||
{
|
||||
return (count++ == 0xFFFF) ? (count=latch, true) : false;
|
||||
}
|
||||
|
||||
void Ks202::Sync(Event event,Input::Controllers* controllers)
|
||||
{
|
||||
if (event == EVENT_END_FRAME)
|
||||
irq.VSync();
|
||||
|
||||
Board::Sync( event, controllers );
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7013b,6000)
|
||||
{
|
||||
prg.SwapBank<SIZE_16K>( 0x0000, data & 0x7 );
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7013b,8000)
|
||||
{
|
||||
ppu.SetMirroring( (data & 0x1) ? Ppu::NMT_H : Ppu::NMT_V );
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7016,6000)
|
||||
{
|
||||
return *(prg.Source().Mem(reg * SIZE_8K) + (address & 0x1FFF));
|
||||
}
|
||||
|
||||
NES_POKE_A(Ks7016,8000)
|
||||
{
|
||||
bool mode = (address & 0x30) == 0x30;
|
||||
|
||||
switch(address & 0xD943) {
|
||||
case 0xD943:
|
||||
reg = mode ? 0xB : (address >> 2) & 0xF;
|
||||
break;
|
||||
|
||||
case 0xD903:
|
||||
reg = mode ? 0x8 | ((address >> 2) & 0x3) : reg = 0xB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7022,8000)
|
||||
{
|
||||
ppu.SetMirroring( (data & 0x4) ? Ppu::NMT_H : Ppu::NMT_V );
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7022,A000)
|
||||
{
|
||||
reg = data & 0xF;
|
||||
}
|
||||
|
||||
NES_PEEK(Ks7022,FFFC)
|
||||
{
|
||||
ppu.Update();
|
||||
chr.SwapBank<SIZE_8K,0x0000>( reg );
|
||||
prg.SwapBanks<SIZE_16K,0x0000>( reg, reg );
|
||||
|
||||
return prg.Peek(0x7FFC);
|
||||
}
|
||||
|
||||
NES_POKE_AD(Ks7031,8000)
|
||||
{
|
||||
regs[(address >> 11) & 0x03] = data;
|
||||
@ -345,17 +497,74 @@ namespace Nes
|
||||
return prg[0][new_addr];
|
||||
}
|
||||
|
||||
bool Ks202::Irq::Clock()
|
||||
NES_PEEK_A(Ks7032,6000)
|
||||
{
|
||||
return (count++ == 0xFFFF) ? (count=latch, true) : false;
|
||||
return wrk[0][address - 0x6000];
|
||||
}
|
||||
|
||||
void Ks202::Sync(Event event,Input::Controllers* controllers)
|
||||
NES_PEEK_A(Ks7037,6000)
|
||||
{
|
||||
if (event == EVENT_END_FRAME)
|
||||
irq.VSync();
|
||||
NST_VERIFY( wrk.Readable(0) );
|
||||
return wrk.Readable(0) ? wrk[0][address - 0x6000] : (address >> 8);
|
||||
}
|
||||
|
||||
Board::Sync( event, controllers );
|
||||
NES_POKE_AD(Ks7037,6000)
|
||||
{
|
||||
NST_VERIFY( wrk.Writable(0) );
|
||||
|
||||
if (wrk.Writable(0))
|
||||
wrk[0][address- 0x6000] = data;
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,7000)
|
||||
{
|
||||
return *(prg.Source().Mem(SIZE_4K * 15) + (address & 0xFFF));
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,8000)
|
||||
{
|
||||
return *(prg.Source().Mem(regs[6] * SIZE_8K) + (address & 0x1FFF));
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7037,8000)
|
||||
{
|
||||
regNum = data & 0x7U;
|
||||
byte mirror[4] = { regs[2], regs[4], regs[3], regs[5] };
|
||||
ppu.SetMirroring(mirror);
|
||||
}
|
||||
|
||||
NES_POKE_D(Ks7037,8001)
|
||||
{
|
||||
regs[regNum] = data;
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,A000)
|
||||
{
|
||||
return *(prg.Source().Mem(SIZE_4K * 28) + (address & 0xFFF));
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,B000)
|
||||
{
|
||||
NST_VERIFY( wrk.Readable(0) );
|
||||
return wrk.Readable(0) ? wrk[0][address - 0xA000] : (address >> 8);
|
||||
}
|
||||
|
||||
NES_POKE_AD(Ks7037,B000)
|
||||
{
|
||||
NST_VERIFY( wrk.Writable(0) );
|
||||
|
||||
if (wrk.Writable(0))
|
||||
wrk[0][address- 0xA000] = data;
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,C000)
|
||||
{
|
||||
return *(prg.Source().Mem(regs[7] * SIZE_8K) + (address & 0x1FFF));
|
||||
}
|
||||
|
||||
NES_PEEK_A(Ks7037,E000)
|
||||
{
|
||||
return *(prg.Source().Mem(SIZE_8K * 15) + (address & 0x1FFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
@ -37,18 +38,6 @@ namespace Nes
|
||||
{
|
||||
namespace Kaiser
|
||||
{
|
||||
class Ks7058 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7058(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
};
|
||||
|
||||
class Ks202 : public Board
|
||||
{
|
||||
public:
|
||||
@ -88,6 +77,59 @@ namespace Nes
|
||||
Timer::M2<Irq> irq;
|
||||
};
|
||||
|
||||
class Ks7013b : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7013b(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
|
||||
NES_DECL_POKE( 6000 );
|
||||
NES_DECL_POKE( 8000 );
|
||||
};
|
||||
|
||||
class Ks7016 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7016(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
void SubLoad(State::Loader&,dword);
|
||||
void SubSave(State::Saver&) const;
|
||||
|
||||
NES_DECL_PEEK( 6000 );
|
||||
NES_DECL_POKE( 8000 );
|
||||
|
||||
uint reg;
|
||||
};
|
||||
|
||||
class Ks7022 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7022(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
void SubLoad(State::Loader&,dword);
|
||||
void SubSave(State::Saver&) const;
|
||||
|
||||
NES_DECL_POKE( 8000 );
|
||||
NES_DECL_POKE( A000 );
|
||||
NES_DECL_PEEK( FFFC );
|
||||
|
||||
uint reg;
|
||||
};
|
||||
|
||||
class Ks7031 : public Board
|
||||
{
|
||||
@ -121,11 +163,10 @@ namespace Nes
|
||||
NES_DECL_PEEK( 6000 );
|
||||
};
|
||||
|
||||
class Ks7022 : public Board
|
||||
class Ks7037 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7022(const Context& c)
|
||||
explicit Ks7037(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
@ -134,11 +175,32 @@ namespace Nes
|
||||
void SubLoad(State::Loader&,dword);
|
||||
void SubSave(State::Saver&) const;
|
||||
|
||||
NES_DECL_POKE( 8000 );
|
||||
NES_DECL_POKE( A000 );
|
||||
NES_DECL_PEEK( FFFC );
|
||||
byte regNum;
|
||||
byte regs[8];
|
||||
|
||||
uint reg;
|
||||
NES_DECL_PEEK( 6000 );
|
||||
NES_DECL_POKE( 6000 );
|
||||
NES_DECL_PEEK( 7000 );
|
||||
NES_DECL_PEEK( 8000 );
|
||||
NES_DECL_POKE( 8000 );
|
||||
NES_DECL_POKE( 8001 );
|
||||
NES_DECL_PEEK( A000 );
|
||||
NES_DECL_PEEK( B000 );
|
||||
NES_DECL_POKE( B000 );
|
||||
NES_DECL_PEEK( C000 );
|
||||
NES_DECL_PEEK( E000 );
|
||||
};
|
||||
|
||||
class Ks7058 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit Ks7058(const Context& c)
|
||||
: Board(c) {}
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,12 @@ namespace Nes
|
||||
void Vrc2::SwapChr(uint address,uint subBank) const
|
||||
{
|
||||
ppu.Update();
|
||||
chr.SwapBank<SIZE_1K>( address, (chr.GetBank<SIZE_1K>(address) & 0xF0U >> OFFSET) | ((subBank >> chrShift & 0xF) << OFFSET) );
|
||||
|
||||
chr.SwapBank<SIZE_1K>( address, chrShift ? OFFSET ?
|
||||
(chr.GetBank<SIZE_1K>(address) & 0x07U) | ((subBank & 0xFU) << 3) :
|
||||
(chr.GetBank<SIZE_1K>(address) & 0xF8U) | ((subBank >> 1) & 0x7U) :
|
||||
(chr.GetBank<SIZE_1K>(address) & 0xF0U >> OFFSET) | ((subBank & 0xFU) << OFFSET)
|
||||
);
|
||||
}
|
||||
|
||||
NES_POKE_D(Vrc2,B000) { SwapChr<0>( 0x0000, data ); }
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../NstLog.hpp"
|
||||
#include "NstBoard.hpp"
|
||||
#include "NstBoardMmc1.hpp"
|
||||
#include "../NstFile.hpp"
|
||||
|
||||
namespace Nes
|
||||
{
|
||||
@ -119,6 +120,20 @@ namespace Nes
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
void Mmc1::Save(File& file) const
|
||||
{
|
||||
uint offset = (board.GetWram() == SIZE_16K) ? SIZE_8K : 0; // SOROM
|
||||
if (board.HasBattery() && board.GetSavableWram())
|
||||
file.Save( File::BATTERY, wrk.Source().Mem(offset), board.GetSavableWram() );
|
||||
}
|
||||
|
||||
void Mmc1::Load(File& file)
|
||||
{
|
||||
uint offset = (board.GetWram() == SIZE_16K) ? SIZE_8K : 0; // SOROM
|
||||
if (board.HasBattery() && board.GetSavableWram())
|
||||
file.Load( File::BATTERY, wrk.Source().Mem(offset), board.GetSavableWram() );
|
||||
}
|
||||
|
||||
void Mmc1::UpdatePrg()
|
||||
{
|
||||
prg.SwapBanks<SIZE_16K,0x0000>
|
||||
|
@ -82,6 +82,9 @@ namespace Nes
|
||||
|
||||
private:
|
||||
|
||||
void Save(File&) const;
|
||||
void Load(File&);
|
||||
|
||||
void ResetRegisters();
|
||||
virtual void NST_FASTCALL UpdateRegisters(uint);
|
||||
|
||||
|
@ -655,10 +655,9 @@ namespace Nes
|
||||
|
||||
NES_HOOK(Mmc5,HActive)
|
||||
{
|
||||
banks.fetchMode = Banks::FETCH_MODE_BG;
|
||||
|
||||
if (ppu.IsEnabled())
|
||||
{
|
||||
banks.fetchMode = Banks::FETCH_MODE_BG;
|
||||
spliter.x = 0x1F;
|
||||
|
||||
if (ppu.GetPixelCycles() != ~0U)
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "NstBoardNamcot163.hpp"
|
||||
#include "NstBoardNamcot175.hpp"
|
||||
#include "NstBoardNamcot340.hpp"
|
||||
#include "NstBoardNamcot34xx.hpp"
|
||||
|
||||
namespace Nes
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2014 R. Danbrook
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
@ -23,10 +23,7 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cstring>
|
||||
#include "NstBoard.hpp"
|
||||
#include "../NstTimer.hpp"
|
||||
#include "../NstFile.hpp"
|
||||
#include "NstBoardNamcot175.hpp"
|
||||
|
||||
namespace Nes
|
||||
@ -43,16 +40,14 @@ namespace Nes
|
||||
|
||||
N175::N175(const Context& c)
|
||||
:
|
||||
Board (c),
|
||||
irq (*c.cpu)
|
||||
Board (c)
|
||||
{
|
||||
}
|
||||
|
||||
void N175::SubReset(const bool hard)
|
||||
{
|
||||
|
||||
irq.Reset( hard, hard || irq.Connected() );
|
||||
|
||||
Map( 0x6000U, 0x7FFFU, &N175::Peek_6000 );
|
||||
Map( 0x6000U, 0x7FFFU, &N175::Poke_6000 );
|
||||
Map( 0x8000U, 0x87FFU, CHR_SWAP_1K_0 );
|
||||
Map( 0x8800U, 0x8FFFU, CHR_SWAP_1K_1 );
|
||||
Map( 0x9000U, 0x97FFU, CHR_SWAP_1K_2 );
|
||||
@ -61,157 +56,35 @@ namespace Nes
|
||||
Map( 0xA800U, 0xAFFFU, CHR_SWAP_1K_5 );
|
||||
Map( 0xB000U, 0xB7FFU, CHR_SWAP_1K_6 );
|
||||
Map( 0xB800U, 0xBFFFU, CHR_SWAP_1K_7 );
|
||||
Map( 0xC000U, 0xC7FFU, &N175::Poke_C000 );
|
||||
Map( 0xE000U, 0xE7FFU, PRG_SWAP_8K_0 );
|
||||
Map( 0xE800U, 0xEFFFU, PRG_SWAP_8K_1 );
|
||||
Map( 0xF000U, 0xF7FFU, PRG_SWAP_8K_2 );
|
||||
}
|
||||
|
||||
void N175::Irq::Reset(const bool hard)
|
||||
{
|
||||
if (hard)
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void N175::Load(File& file)
|
||||
{
|
||||
if (board.HasBattery())
|
||||
{
|
||||
const File::LoadBlock block[] =
|
||||
{
|
||||
{ wrk.Source().Mem(), board.GetWram() }
|
||||
};
|
||||
|
||||
file.Load( File::BATTERY, block );
|
||||
}
|
||||
else
|
||||
{
|
||||
Board::Load( file );
|
||||
}
|
||||
}
|
||||
|
||||
void N175::Save(File& file) const
|
||||
{
|
||||
if (board.HasBattery())
|
||||
{
|
||||
const File::SaveBlock block[] =
|
||||
{
|
||||
{ wrk.Source().Mem(), board.GetWram() }
|
||||
};
|
||||
|
||||
file.Save( File::BATTERY, block );
|
||||
}
|
||||
else
|
||||
{
|
||||
Board::Save( file );
|
||||
}
|
||||
}
|
||||
|
||||
void N175::SubLoad(State::Loader& state,const dword baseChunk)
|
||||
{
|
||||
NST_VERIFY( baseChunk == (AsciiId<'N','6','3'>::V) );
|
||||
|
||||
if (baseChunk == AsciiId<'N','6','3'>::V)
|
||||
{
|
||||
while (const dword chunk = state.Begin())
|
||||
{
|
||||
switch (chunk)
|
||||
{
|
||||
case AsciiId<'I','R','Q'>::V:
|
||||
{
|
||||
State::Loader::Data<3> data( state );
|
||||
irq.unit.count = data[1] | (data[2] << 8 & 0x7F00) | (data[0] << 15 & 0x8000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void N175::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'N','6','3'>::V );
|
||||
|
||||
const byte data[3] =
|
||||
{
|
||||
irq.unit.count >> 15,
|
||||
irq.unit.count >> 0 & 0xFF,
|
||||
irq.unit.count >> 8 & 0x7F
|
||||
};
|
||||
|
||||
state.Begin( AsciiId<'I','R','Q'>::V ).Write( data ).End();
|
||||
|
||||
state.End();
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
bool N175::Irq::Clock()
|
||||
NES_PEEK_A(N175,6000)
|
||||
{
|
||||
return (count - 0x8000 < 0x7FFF) && (++count == 0xFFFF);
|
||||
NST_VERIFY( wrk.Readable(0) );
|
||||
return wrk.Readable(0) ? wrk[0][address & 0x7FFU] : (address >> 8);
|
||||
}
|
||||
|
||||
NES_PEEK(N175,5000)
|
||||
NES_POKE_AD(N175,6000)
|
||||
{
|
||||
irq.Update();
|
||||
return irq.unit.count & 0xFF;
|
||||
}
|
||||
NST_VERIFY( wrk.Writable(0) );
|
||||
|
||||
NES_POKE_D(N175,5000)
|
||||
{
|
||||
irq.Update();
|
||||
irq.unit.count = (irq.unit.count & 0xFF00) | data;
|
||||
irq.ClearIRQ();
|
||||
}
|
||||
|
||||
NES_PEEK(N175,5800)
|
||||
{
|
||||
irq.Update();
|
||||
return irq.unit.count >> 8;
|
||||
}
|
||||
|
||||
NES_POKE_D(N175,5800)
|
||||
{
|
||||
irq.Update();
|
||||
irq.unit.count = (irq.unit.count & 0x00FF) | (data << 8);
|
||||
irq.ClearIRQ();
|
||||
}
|
||||
|
||||
void N175::SwapNmt(const uint address,const uint data) const
|
||||
{
|
||||
ppu.Update();
|
||||
nmt.Source( data < 0xE0 ).SwapBank<SIZE_1K>( address, data );
|
||||
if (wrk.Writable(0))
|
||||
wrk[0][address & 0x7FFU] = data;
|
||||
}
|
||||
|
||||
NES_POKE_D(N175,C000)
|
||||
{
|
||||
SwapNmt( 0x0000, data );
|
||||
}
|
||||
|
||||
NES_POKE_D(N175,C800)
|
||||
{
|
||||
SwapNmt( 0x0400, data );
|
||||
}
|
||||
|
||||
NES_POKE_D(N175,D000)
|
||||
{
|
||||
SwapNmt( 0x0800, data );
|
||||
}
|
||||
|
||||
NES_POKE_D(N175,D800)
|
||||
{
|
||||
SwapNmt( 0x0C00, data );
|
||||
}
|
||||
|
||||
void N175::Sync(Event event,Input::Controllers* controllers)
|
||||
{
|
||||
if (event == EVENT_END_FRAME)
|
||||
irq.VSync();
|
||||
|
||||
Board::Sync( event, controllers );
|
||||
bool enable = data & 0x1;
|
||||
wrk.Source().SetSecurity(enable, enable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2014 R. Danbrook
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
@ -47,35 +47,10 @@ namespace Nes
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
void SubSave(State::Saver&) const;
|
||||
void SubLoad(State::Loader&,dword);
|
||||
void Load(File&);
|
||||
void Save(File&) const;
|
||||
void Sync(Event,Input::Controllers*);
|
||||
void SwapChr(uint,uint,uint) const;
|
||||
void SwapNmt(uint,uint) const;
|
||||
|
||||
struct Irq
|
||||
{
|
||||
void Reset(bool);
|
||||
bool Clock();
|
||||
|
||||
uint count;
|
||||
};
|
||||
|
||||
NES_DECL_PEEK( 4800 );
|
||||
NES_DECL_POKE( 4800 );
|
||||
NES_DECL_PEEK( 5000 );
|
||||
NES_DECL_POKE( 5000 );
|
||||
NES_DECL_PEEK( 5800 );
|
||||
NES_DECL_POKE( 5800 );
|
||||
NES_DECL_PEEK( 6000 );
|
||||
NES_DECL_POKE( 6000 );
|
||||
NES_DECL_POKE( C000 );
|
||||
NES_DECL_POKE( C800 );
|
||||
NES_DECL_POKE( D000 );
|
||||
NES_DECL_POKE( D800 );
|
||||
NES_DECL_POKE( F800 );
|
||||
|
||||
Timer::M2<Irq> irq;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
89
source/core/board/NstBoardNamcot340.cpp
Normal file
89
source/core/board/NstBoardNamcot340.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
// Nestopia is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Nestopia is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Nestopia; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "NstBoard.hpp"
|
||||
#include "NstBoardNamcot340.hpp"
|
||||
|
||||
namespace Nes
|
||||
{
|
||||
namespace Core
|
||||
{
|
||||
namespace Boards
|
||||
{
|
||||
namespace Namcot
|
||||
{
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
#pragma optimize("s", on)
|
||||
#endif
|
||||
|
||||
N340::N340(const Context& c)
|
||||
:
|
||||
Board (c)
|
||||
{
|
||||
}
|
||||
|
||||
void N340::SubReset(const bool hard)
|
||||
{
|
||||
Map( 0x8000U, 0x87FFU, CHR_SWAP_1K_0 );
|
||||
Map( 0x8800U, 0x8FFFU, CHR_SWAP_1K_1 );
|
||||
Map( 0x9000U, 0x97FFU, CHR_SWAP_1K_2 );
|
||||
Map( 0x9800U, 0x9FFFU, CHR_SWAP_1K_3 );
|
||||
Map( 0xA000U, 0xA7FFU, CHR_SWAP_1K_4 );
|
||||
Map( 0xA800U, 0xAFFFU, CHR_SWAP_1K_5 );
|
||||
Map( 0xB000U, 0xB7FFU, CHR_SWAP_1K_6 );
|
||||
Map( 0xB800U, 0xBFFFU, CHR_SWAP_1K_7 );
|
||||
Map( 0xE000U, 0xE7FFU, &N340::Poke_E000 );
|
||||
Map( 0xE800U, 0xEFFFU, PRG_SWAP_8K_1 );
|
||||
Map( 0xF000U, 0xF7FFU, PRG_SWAP_8K_2 );
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
#pragma optimize("", on)
|
||||
#endif
|
||||
|
||||
NES_POKE_D(N340,E000)
|
||||
{
|
||||
prg.SwapBank<SIZE_8K>( 0, data & 0x3FU );
|
||||
|
||||
switch ((data >> 6) & 0x3U)
|
||||
{
|
||||
case 0x0U: // One-screen A
|
||||
ppu.SetMirroring( Ppu::NMT_0 );
|
||||
break;
|
||||
case 0x1U: // Vertical
|
||||
ppu.SetMirroring( Ppu::NMT_V );
|
||||
break;
|
||||
case 0x2U: // One-screen B
|
||||
ppu.SetMirroring( Ppu::NMT_1 );
|
||||
break;
|
||||
case 0x3U: // Horizontal
|
||||
ppu.SetMirroring( Ppu::NMT_H );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
source/core/board/NstBoardNamcot340.hpp
Normal file
58
source/core/board/NstBoardNamcot340.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Nestopia - NES/Famicom emulator written in C++
|
||||
//
|
||||
// Copyright (C) 2003-2008 Martin Freij
|
||||
// Copyright (C) 2021 Rupert Carmichael
|
||||
//
|
||||
// This file is part of Nestopia.
|
||||
//
|
||||
// Nestopia is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Nestopia is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Nestopia; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NST_BOARD_NAMCOT_340_H
|
||||
#define NST_BOARD_NAMCOT_340_H
|
||||
|
||||
#ifdef NST_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace Nes
|
||||
{
|
||||
namespace Core
|
||||
{
|
||||
namespace Boards
|
||||
{
|
||||
namespace Namcot
|
||||
{
|
||||
class N340 : public Board
|
||||
{
|
||||
public:
|
||||
|
||||
explicit N340(const Context&);
|
||||
|
||||
private:
|
||||
|
||||
void SubReset(bool);
|
||||
|
||||
NES_DECL_POKE( E000 );
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -22,6 +22,8 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Reference: https://github.com/TASVideos/fceux/blob/master/src/boards/156.cpp
|
||||
|
||||
#include "NstBoard.hpp"
|
||||
#include "NstBoardOpenCorp.hpp"
|
||||
|
||||
@ -37,17 +39,139 @@ namespace Nes
|
||||
#pragma optimize("s", on)
|
||||
#endif
|
||||
|
||||
void Daou306::RemapChr()
|
||||
{
|
||||
chr.SwapBank<SIZE_1K>( 0x0000, (chrHigh[0] << 8) | chrLow[0] );
|
||||
chr.SwapBank<SIZE_1K>( 0x0400, (chrHigh[1] << 8) | chrLow[1] );
|
||||
chr.SwapBank<SIZE_1K>( 0x0800, (chrHigh[2] << 8) | chrLow[2] );
|
||||
chr.SwapBank<SIZE_1K>( 0x0C00, (chrHigh[3] << 8) | chrLow[3] );
|
||||
chr.SwapBank<SIZE_1K>( 0x1000, (chrHigh[4] << 8) | chrLow[4] );
|
||||
chr.SwapBank<SIZE_1K>( 0x1400, (chrHigh[5] << 8) | chrLow[5] );
|
||||
chr.SwapBank<SIZE_1K>( 0x1800, (chrHigh[6] << 8) | chrLow[6] );
|
||||
chr.SwapBank<SIZE_1K>( 0x1C00, (chrHigh[7] << 8) | chrLow[7] );
|
||||
|
||||
if (mirrorUsed) {
|
||||
ppu.SetMirroring( mirror ^ 0x1 ? Ppu::NMT_V : Ppu::NMT_H );
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu.SetMirroring( Ppu::NMT_0 );
|
||||
}
|
||||
}
|
||||
|
||||
void Daou306::SubReset(bool)
|
||||
{
|
||||
Map( 0xC000U, CHR_SWAP_1K_0 );
|
||||
Map( 0xC001U, CHR_SWAP_1K_1 );
|
||||
Map( 0xC002U, CHR_SWAP_1K_2 );
|
||||
Map( 0xC003U, CHR_SWAP_1K_3 );
|
||||
Map( 0xC008U, CHR_SWAP_1K_4 );
|
||||
Map( 0xC009U, CHR_SWAP_1K_5 );
|
||||
Map( 0xC00AU, CHR_SWAP_1K_6 );
|
||||
Map( 0xC00BU, CHR_SWAP_1K_7 );
|
||||
for (uint i = 0; i < 8; i++)
|
||||
{
|
||||
chrLow[i] = chrHigh[i] = 0;
|
||||
}
|
||||
|
||||
Map( 0xC000U, 0xC00FU, &Daou306::Poke_C000 );
|
||||
Map( 0xC010U, PRG_SWAP_16K_0 );
|
||||
Map( 0xC014U, &Daou306::Poke_C014 );
|
||||
}
|
||||
|
||||
NES_POKE_AD(Daou306,C000)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0xC000:
|
||||
case 0xC001:
|
||||
case 0xC002:
|
||||
case 0xC003:
|
||||
chrLow[address & 0x03] = data;
|
||||
break;
|
||||
case 0xC004:
|
||||
case 0xC005:
|
||||
case 0xC006:
|
||||
case 0xC007:
|
||||
chrHigh[address & 0x03] = data;
|
||||
break;
|
||||
case 0xC008:
|
||||
case 0xC009:
|
||||
case 0xC00A:
|
||||
case 0xC00B:
|
||||
chrLow[4 + (address & 0x03)] = data;
|
||||
break;
|
||||
case 0xC00C:
|
||||
case 0xC00D:
|
||||
case 0xC00E:
|
||||
case 0xC00F:
|
||||
chrHigh[4 + (address & 0x03)] = data;
|
||||
break;
|
||||
}
|
||||
RemapChr();
|
||||
}
|
||||
|
||||
NES_POKE_D(Daou306,C014)
|
||||
{
|
||||
mirror = data;
|
||||
mirrorUsed = 1;
|
||||
}
|
||||
|
||||
void Daou306::SubLoad(State::Loader& state,const dword baseChunk)
|
||||
{
|
||||
NST_VERIFY( baseChunk == (AsciiId<'O','P','C'>::V) );
|
||||
|
||||
if (baseChunk == AsciiId<'O','P','C'>::V)
|
||||
{
|
||||
state.Begin();
|
||||
|
||||
State::Loader::Data<18> data( state );
|
||||
chrLow[0] = data[0];
|
||||
chrLow[1] = data[1];
|
||||
chrLow[2] = data[2];
|
||||
chrLow[3] = data[3];
|
||||
chrLow[4] = data[4];
|
||||
chrLow[5] = data[5];
|
||||
chrLow[6] = data[6];
|
||||
chrLow[7] = data[7];
|
||||
chrHigh[0] = data[8];
|
||||
chrHigh[1] = data[9];
|
||||
chrHigh[2] = data[10];
|
||||
chrHigh[3] = data[11];
|
||||
chrHigh[4] = data[12];
|
||||
chrHigh[5] = data[13];
|
||||
chrHigh[6] = data[14];
|
||||
chrHigh[7] = data[15];
|
||||
mirror = data[16];
|
||||
mirrorUsed = data[17];
|
||||
|
||||
state.End();
|
||||
|
||||
RemapChr();
|
||||
}
|
||||
}
|
||||
|
||||
void Daou306::SubSave(State::Saver& state) const
|
||||
{
|
||||
state.Begin( AsciiId<'O','P','C'>::V );
|
||||
|
||||
const byte data[18] =
|
||||
{
|
||||
chrLow[0],
|
||||
chrLow[1],
|
||||
chrLow[2],
|
||||
chrLow[3],
|
||||
chrLow[4],
|
||||
chrLow[5],
|
||||
chrLow[6],
|
||||
chrLow[7],
|
||||
chrHigh[0],
|
||||
chrHigh[1],
|
||||
chrHigh[2],
|
||||
chrHigh[3],
|
||||
chrHigh[4],
|
||||
chrHigh[5],
|
||||
chrHigh[6],
|
||||
chrHigh[7],
|
||||
mirror,
|
||||
mirrorUsed,
|
||||
};
|
||||
|
||||
state.Begin( AsciiId<'C','H','R'>::V ).Write( data ).End();
|
||||
|
||||
state.End();
|
||||
}
|
||||
|
||||
#ifdef NST_MSVC_OPTIMIZE
|
||||
|
@ -46,7 +46,18 @@ namespace Nes
|
||||
|
||||
private:
|
||||
|
||||
byte chrLow[8];
|
||||
byte chrHigh[8];
|
||||
byte mirror;
|
||||
byte mirrorUsed;
|
||||
|
||||
void RemapChr();
|
||||
void SubReset(bool);
|
||||
void SubSave(State::Saver&) const;
|
||||
void SubLoad(State::Loader&,dword);
|
||||
|
||||
NES_DECL_POKE( C000 );
|
||||
NES_DECL_POKE( C014 );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ namespace Nes
|
||||
ctrl = data[0] >> 1 & 0x1F;
|
||||
length = data[1] | (data[2] << 8 & 0xF00);
|
||||
volume = levels[(ctrl & 0xF) ? (ctrl & 0xF) * 2 + 1 : 0];
|
||||
dc = (status & 0x1) ? ~0UL : 0UL;
|
||||
dc = (status & 0x1) ? ~dword(0) : dword(0);
|
||||
|
||||
UpdateSettings( fixed );
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ namespace Nes
|
||||
if (hard)
|
||||
{
|
||||
count = 0;
|
||||
cycles = 0;
|
||||
reload = false;
|
||||
latch = 0;
|
||||
enabled = false;
|
||||
@ -121,14 +122,16 @@ namespace Nes
|
||||
|
||||
case AsciiId<'I','R','Q'>::V:
|
||||
{
|
||||
State::Loader::Data<3> data( state );
|
||||
State::Loader::Data<4> data( state );
|
||||
|
||||
irq.unit.enabled = data[0] & 0x1;
|
||||
irq.unit.mode = data[0] & 0x2 ? 1 : 0;
|
||||
irq.a12.Connect( data[0] & 0x2 );
|
||||
irq.m2.Connect( data[0] & 0x2 );
|
||||
irq.unit.reload = data[0] & 0x4;
|
||||
irq.unit.latch = data[1];
|
||||
irq.unit.count = data[2];
|
||||
irq.unit.cycles = data[3];
|
||||
|
||||
break;
|
||||
}
|
||||
@ -164,13 +167,14 @@ namespace Nes
|
||||
}
|
||||
|
||||
{
|
||||
const byte data[3] =
|
||||
const byte data[4] =
|
||||
{
|
||||
(irq.unit.enabled ? 0x1U : 0x0U) |
|
||||
(irq.m2.Connected() ? 0x2U : 0x0U) |
|
||||
(irq.unit.reload ? 0x4U : 0x0U),
|
||||
irq.unit.latch,
|
||||
irq.unit.count & 0xFF
|
||||
irq.unit.count & 0xFF,
|
||||
irq.unit.cycles,
|
||||
};
|
||||
|
||||
state.Begin( AsciiId<'I','R','Q'>::V ).Write( data ).End();
|
||||
@ -185,47 +189,39 @@ namespace Nes
|
||||
|
||||
bool Rambo1::Irq::Unit::Clock()
|
||||
{
|
||||
/*if (!reload)
|
||||
cycles++;
|
||||
|
||||
if (latch == 1)
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
return !--count && enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = latch;
|
||||
return false;
|
||||
}
|
||||
count = 0;
|
||||
}
|
||||
else if (reload)
|
||||
{
|
||||
reload = false;
|
||||
count = latch | (latch ? 1 : 0);
|
||||
|
||||
if (mode)
|
||||
count |= 2;
|
||||
|
||||
if (!latch && cycles > A12_FILTER)
|
||||
count = 1;
|
||||
else if (latch && (cycles > (A12_FILTER * 3)))
|
||||
count++;
|
||||
|
||||
cycles = 0;
|
||||
}
|
||||
else if (!count)
|
||||
{
|
||||
count = latch;
|
||||
if (cycles > A12_FILTER)
|
||||
cycles = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
reload = false;
|
||||
count = latch + 1;
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// From dragon2snow
|
||||
if (reload) {
|
||||
if (latch < 1) {
|
||||
count = latch + 1;
|
||||
}
|
||||
else {
|
||||
count = latch + 2;
|
||||
}
|
||||
reload = false;
|
||||
count--;
|
||||
}
|
||||
else if (!count) {
|
||||
count = latch + 1;
|
||||
}
|
||||
|
||||
count--;
|
||||
|
||||
if (!count && enabled) {
|
||||
/* wait one M2 cycle, then trigger IRQ */
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
return (!count && enabled);
|
||||
}
|
||||
|
||||
void Rambo1::Irq::Update()
|
||||
@ -320,6 +316,7 @@ namespace Nes
|
||||
{
|
||||
irq.Update();
|
||||
irq.unit.latch = data;
|
||||
irq.unit.mode = irq.m2.Connected();
|
||||
}
|
||||
|
||||
NES_POKE_D(Rambo1,C001)
|
||||
|
@ -95,9 +95,11 @@ namespace Nes
|
||||
bool Clock();
|
||||
|
||||
uint count;
|
||||
uint cycles;
|
||||
uint latch;
|
||||
ibool reload;
|
||||
ibool enabled;
|
||||
ibool mode;
|
||||
};
|
||||
|
||||
typedef Timer::A12<Unit&,A12_FILTER,IRQ_DELAY> A12;
|
||||
|
@ -49,7 +49,8 @@ namespace Nes
|
||||
NES_POKE_A(Cc21,8000)
|
||||
{
|
||||
ppu.SetMirroring( (address & 0x2) ? Ppu::NMT_1 : Ppu::NMT_0 );
|
||||
chr.SwapBank<SIZE_8K,0x0000>( address );
|
||||
chr.SwapBank<SIZE_4K,0x0000>( address );
|
||||
chr.SwapBank<SIZE_4K,0x1000>( address );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ namespace Nes
|
||||
}
|
||||
|
||||
Map( 0x9000U, &KingOfFighters97::Poke_8001 );
|
||||
Map( 0xA000U, &KingOfFighters97::Poke_8000 );
|
||||
Map( 0xA000U, &KingOfFighters97::Poke_A000 );
|
||||
Map( 0xB000U, &KingOfFighters97::Poke_A001 );
|
||||
Map( 0xD000U, &KingOfFighters97::Poke_C001 );
|
||||
|
||||
for (uint i=0x0000; i < 0x1000; i += 0x2)
|
||||
@ -89,6 +90,16 @@ namespace Nes
|
||||
Mmc3::NES_DO_POKE(8001,0x8001,Unscramble(data));
|
||||
}
|
||||
|
||||
NES_POKE_D(KingOfFighters97,A000)
|
||||
{
|
||||
ppu.SetMirroring( (data & 0x02) ? Ppu::NMT_H : Ppu::NMT_V );
|
||||
}
|
||||
|
||||
NES_POKE_D(KingOfFighters97,A001)
|
||||
{
|
||||
Mmc3::NES_DO_POKE(A001,0xA001,Unscramble(data));
|
||||
}
|
||||
|
||||
NES_POKE_D(KingOfFighters97,C000)
|
||||
{
|
||||
Mmc3::NES_DO_POKE(C000,0xC000,Unscramble(data));
|
||||
|
@ -52,6 +52,8 @@ namespace Nes
|
||||
|
||||
NES_DECL_POKE( 8000 );
|
||||
NES_DECL_POKE( 8001 );
|
||||
NES_DECL_POKE( A000 );
|
||||
NES_DECL_POKE( A001 );
|
||||
NES_DECL_POKE( C000 );
|
||||
NES_DECL_POKE( C001 );
|
||||
NES_DECL_POKE( E000 );
|
||||
|
Loading…
Reference in New Issue
Block a user