mirror of
https://github.com/0ldsk00l/nestopia.git
synced 2025-04-02 10:31:51 -04:00
Merge improvements from 2dcf289446
This commit is contained in:
parent
5d119ef4ae
commit
465fce638b
14 changed files with 233 additions and 630 deletions
|
@ -26916,4 +26916,88 @@
|
|||
</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>
|
||||
</database>
|
||||
|
|
|
@ -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,7 @@ namespace Nes
|
|||
amp = (sum * outputVolume + rate/2) / rate * 3;
|
||||
}
|
||||
}
|
||||
else if (amp < Channel::OUTPUT_DECAY)
|
||||
/*else if (amp < Channel::OUTPUT_DECAY)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1878,7 +1883,7 @@ namespace Nes
|
|||
{
|
||||
amp -= Channel::OUTPUT_DECAY;
|
||||
step &= STEP_CHECK;
|
||||
}
|
||||
}*/
|
||||
|
||||
return amp;
|
||||
}
|
||||
|
@ -2120,7 +2125,6 @@ namespace Nes
|
|||
dma.buffered = false;
|
||||
dma.address = 0xC000;
|
||||
dma.buffer = 0x00;
|
||||
overclockingIsSafe = true;
|
||||
}
|
||||
|
||||
Cycle Apu::Dmc::GetResetFrequency(CpuModel model)
|
||||
|
@ -2361,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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,6 @@ namespace Nes
|
|||
cycles.count = Cpu::CYCLE_MAX;
|
||||
|
||||
scanline = SCANLINE_VBLANK;
|
||||
scanline_sleep = -1;
|
||||
ssleep = -1;
|
||||
|
||||
io.address = 0;
|
||||
io.pattern = 0;
|
||||
|
@ -493,8 +490,6 @@ namespace Nes
|
|||
|
||||
Cycle frame;
|
||||
|
||||
scanline_sleep = -1;
|
||||
|
||||
switch (model)
|
||||
{
|
||||
case PPU_RP2C02:
|
||||
|
@ -503,8 +498,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 +514,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 +530,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 +545,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,12 +649,37 @@ 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))
|
||||
{
|
||||
scroll.ClockX();
|
||||
scroll.ClockY();
|
||||
if ( regs.ctrl[0] & Regs::CTRL0_INC32 )
|
||||
{
|
||||
if((scroll.address & 0x7000) == 0x7000)
|
||||
{
|
||||
scroll.address &= 0x0FFF;
|
||||
switch(scroll.address & 0x03E0)
|
||||
{
|
||||
case 0x03A0: scroll.address ^= 0x0800; break;
|
||||
case 0x03E0: scroll.address &= 0x7C1F; break;
|
||||
default: scroll.address += 0x20;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll.address += 0x1000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scroll.address++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -824,7 +800,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 +944,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 +956,7 @@ namespace Nes
|
|||
uint address = scroll.address;
|
||||
|
||||
UpdateVramAddress();
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) ||
|
||||
(scanline == SCANLINE_VBLANK)) {
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
UpdateScrollAddressLine();
|
||||
|
||||
io.latch = data;
|
||||
|
||||
|
@ -1027,10 +994,7 @@ namespace Nes
|
|||
|
||||
address = scroll.address & 0x3FFF;
|
||||
UpdateVramAddress();
|
||||
if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) ||
|
||||
(scanline == SCANLINE_VBLANK)) {
|
||||
UpdateAddressLine(scroll.address & 0x3fff);
|
||||
}
|
||||
UpdateScrollAddressLine();
|
||||
|
||||
io.latch = (address & 0x3F00) != 0x3F00 ? io.buffer : palette.ram[address & 0x1F] & Coloring();
|
||||
io.buffer = (address >= 0x2000 ? nmt.FetchName( address ) : chr.FetchPattern( address ));
|
||||
|
@ -1458,410 +1422,7 @@ namespace Nes
|
|||
{
|
||||
NST_VERIFY( cycles.count != cycles.hClock );
|
||||
|
||||
if (scanline_sleep >= 0)
|
||||
{
|
||||
switch (cycles.hClock)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
case 36:
|
||||
case 37:
|
||||
case 38:
|
||||
case 39:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 50:
|
||||
case 51:
|
||||
case 52:
|
||||
case 53:
|
||||
case 54:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 59:
|
||||
case 60:
|
||||
case 61:
|
||||
case 62:
|
||||
case 63:
|
||||
case 64:
|
||||
case 65:
|
||||
case 66:
|
||||
case 67:
|
||||
case 68:
|
||||
case 69:
|
||||
case 70:
|
||||
case 71:
|
||||
case 72:
|
||||
case 73:
|
||||
case 74:
|
||||
case 75:
|
||||
case 76:
|
||||
case 77:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 84:
|
||||
case 85:
|
||||
case 86:
|
||||
case 87:
|
||||
case 88:
|
||||
case 89:
|
||||
case 90:
|
||||
case 91:
|
||||
case 92:
|
||||
case 93:
|
||||
case 94:
|
||||
case 95:
|
||||
case 96:
|
||||
case 97:
|
||||
case 98:
|
||||
case 99:
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 104:
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
case 115:
|
||||
case 116:
|
||||
case 117:
|
||||
case 118:
|
||||
case 119:
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
case 123:
|
||||
case 124:
|
||||
case 125:
|
||||
case 126:
|
||||
case 127:
|
||||
case 128:
|
||||
case 129:
|
||||
case 130:
|
||||
case 131:
|
||||
case 132:
|
||||
case 133:
|
||||
case 134:
|
||||
case 135:
|
||||
case 136:
|
||||
case 137:
|
||||
case 138:
|
||||
case 139:
|
||||
case 140:
|
||||
case 141:
|
||||
case 142:
|
||||
case 143:
|
||||
case 144:
|
||||
case 145:
|
||||
case 146:
|
||||
case 147:
|
||||
case 148:
|
||||
case 149:
|
||||
case 150:
|
||||
case 151:
|
||||
case 152:
|
||||
case 153:
|
||||
case 154:
|
||||
case 155:
|
||||
case 156:
|
||||
case 157:
|
||||
case 158:
|
||||
case 159:
|
||||
case 160:
|
||||
case 161:
|
||||
case 162:
|
||||
case 163:
|
||||
case 164:
|
||||
case 165:
|
||||
case 166:
|
||||
case 167:
|
||||
case 168:
|
||||
case 169:
|
||||
case 170:
|
||||
case 171:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 175:
|
||||
case 176:
|
||||
case 177:
|
||||
case 178:
|
||||
case 179:
|
||||
case 180:
|
||||
case 181:
|
||||
case 182:
|
||||
case 183:
|
||||
case 184:
|
||||
case 185:
|
||||
case 186:
|
||||
case 187:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
case 193:
|
||||
case 194:
|
||||
case 195:
|
||||
case 196:
|
||||
case 197:
|
||||
case 198:
|
||||
case 199:
|
||||
case 200:
|
||||
case 201:
|
||||
case 202:
|
||||
case 203:
|
||||
case 204:
|
||||
case 205:
|
||||
case 206:
|
||||
case 207:
|
||||
case 208:
|
||||
case 209:
|
||||
case 210:
|
||||
case 211:
|
||||
case 212:
|
||||
case 213:
|
||||
case 214:
|
||||
case 215:
|
||||
case 216:
|
||||
case 217:
|
||||
case 218:
|
||||
case 219:
|
||||
case 220:
|
||||
case 221:
|
||||
case 222:
|
||||
case 223:
|
||||
case 224:
|
||||
case 225:
|
||||
case 226:
|
||||
case 227:
|
||||
case 228:
|
||||
case 229:
|
||||
case 230:
|
||||
case 231:
|
||||
case 232:
|
||||
case 233:
|
||||
case 234:
|
||||
case 235:
|
||||
case 236:
|
||||
case 237:
|
||||
case 238:
|
||||
case 239:
|
||||
case 240:
|
||||
case 241:
|
||||
case 242:
|
||||
case 243:
|
||||
case 244:
|
||||
case 245:
|
||||
case 246:
|
||||
case 247:
|
||||
case 248:
|
||||
case 249:
|
||||
case 250:
|
||||
case 251:
|
||||
case 252:
|
||||
case 253:
|
||||
case 254:
|
||||
case 255:
|
||||
case 256:
|
||||
case 257:
|
||||
case 258:
|
||||
case 260:
|
||||
case 261:
|
||||
case 262:
|
||||
case 263:
|
||||
case 264:
|
||||
case 266:
|
||||
case 267:
|
||||
case 268:
|
||||
case 269:
|
||||
case 270:
|
||||
case 271:
|
||||
case 272:
|
||||
case 273:
|
||||
case 274:
|
||||
case 275:
|
||||
case 276:
|
||||
case 277:
|
||||
case 278:
|
||||
case 279:
|
||||
case 280:
|
||||
case 281:
|
||||
case 282:
|
||||
case 283:
|
||||
case 284:
|
||||
case 285:
|
||||
case 286:
|
||||
case 287:
|
||||
case 288:
|
||||
case 289:
|
||||
case 290:
|
||||
case 291:
|
||||
case 292:
|
||||
case 293:
|
||||
case 294:
|
||||
case 295:
|
||||
case 296:
|
||||
case 297:
|
||||
case 298:
|
||||
case 299:
|
||||
case 300:
|
||||
case 301:
|
||||
case 302:
|
||||
case 303:
|
||||
case 304:
|
||||
case 305:
|
||||
case 306:
|
||||
case 307:
|
||||
case 308:
|
||||
case 309:
|
||||
case 310:
|
||||
case 311:
|
||||
case 312:
|
||||
case 313:
|
||||
case 314:
|
||||
case 315:
|
||||
case 316:
|
||||
case 317:
|
||||
case 318:
|
||||
case 319:
|
||||
case 320:
|
||||
case 321:
|
||||
case 322:
|
||||
case 323:
|
||||
case 324:
|
||||
case 325:
|
||||
case 326:
|
||||
case 327:
|
||||
case 328:
|
||||
case 329:
|
||||
case 330:
|
||||
case 331:
|
||||
case 332:
|
||||
case 333:
|
||||
case 334:
|
||||
case 335:
|
||||
case 336:
|
||||
case 337:
|
||||
HActiveSleep:
|
||||
|
||||
cycles.hClock = 338;
|
||||
|
||||
if (cycles.count <= 338)
|
||||
break;
|
||||
|
||||
case 338:
|
||||
|
||||
if (scanline_sleep++ != ssleep)
|
||||
{
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += 341;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycles.hClock = HCLOCK_VBLANK_0;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_0)
|
||||
break;
|
||||
}
|
||||
|
||||
case HCLOCK_VBLANK_0:
|
||||
VBlank0:
|
||||
|
||||
regs.status |= Regs::STATUS_VBLANKING;
|
||||
cycles.hClock = HCLOCK_VBLANK_1;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_1)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED)
|
||||
if (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED)
|
||||
{
|
||||
switch (cycles.hClock)
|
||||
{
|
||||
|
@ -2533,36 +2094,42 @@ namespace Nes
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ssleep >= 0)
|
||||
{
|
||||
scanline_sleep = 0;
|
||||
cycles.hClock = 0;
|
||||
cycles.vClock += 341;
|
||||
cycles.hClock = HCLOCK_VBLANK_0;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycles.hClock = HCLOCK_VBLANK_0;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_0)
|
||||
break;
|
||||
}
|
||||
if (cycles.count <= HCLOCK_VBLANK_0)
|
||||
break;
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
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;
|
||||
|
@ -3237,29 +2804,12 @@ namespace Nes
|
|||
|
||||
goto HActiveOff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ssleep >= 0)
|
||||
{
|
||||
scanline_sleep = 0;
|
||||
else
|
||||
{
|
||||
cycles.hClock = HCLOCK_VBLANK_0;
|
||||
|
||||
cycles.vClock += 341;
|
||||
cycles.hClock = 0;
|
||||
|
||||
if (cycles.count <= 341)
|
||||
break;
|
||||
|
||||
cycles.count -= 341;
|
||||
|
||||
goto HActiveSleep;
|
||||
}
|
||||
else
|
||||
{
|
||||
cycles.hClock = HCLOCK_VBLANK_0;
|
||||
|
||||
if (cycles.count <= HCLOCK_VBLANK_0)
|
||||
break;
|
||||
}
|
||||
if (cycles.count <= HCLOCK_VBLANK_0)
|
||||
break;
|
||||
}
|
||||
|
||||
case HCLOCK_VBLANK_0:
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
@ -414,10 +414,9 @@ namespace Nes
|
|||
Chr chr;
|
||||
Nmt nmt;
|
||||
int scanline;
|
||||
int scanline_sleep;
|
||||
int ssleep;
|
||||
bool overclocked;
|
||||
|
||||
public:
|
||||
Output output;
|
||||
private:
|
||||
PpuModel model;
|
||||
Hook hActiveHook;
|
||||
Hook hBlankHook;
|
||||
|
@ -432,7 +431,6 @@ namespace Nes
|
|||
static const byte yuvMaps[4][0x40];
|
||||
|
||||
public:
|
||||
Output output;
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
@ -543,16 +541,6 @@ namespace Nes
|
|||
{
|
||||
return oam.spriteLimit;
|
||||
}
|
||||
|
||||
bool GetOverclockState() const
|
||||
{
|
||||
return overclocked;
|
||||
}
|
||||
|
||||
void SetOverclockState(bool overclock2x)
|
||||
{
|
||||
overclocked = overclock2x;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,6 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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>
|
||||
#include <new>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1241,7 +1241,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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue