NES Update $2003 behaviour

Fixes Huge Insect
Some debate reamins about what exactly is happening here though
This commit is contained in:
alyosha-tas 2017-03-07 22:30:41 -05:00 committed by GitHub
parent b453745404
commit df7a93e83a
5 changed files with 62 additions and 24 deletions

View File

@ -224,7 +224,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public virtual void WriteReg2xxx(int addr, byte value)
{
NES.ppu.WriteReg(addr & 7, value);
NES.ppu.WriteReg(addr, value);
}
public virtual void WritePPU(int addr, byte value)

View File

@ -796,7 +796,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
else if (addr < 0x4000)
{
ppu.WriteReg((addr & 0x07), value);
ppu.WriteReg(addr, value);
}
else if (addr < 0x4020)
{

View File

@ -223,6 +223,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ser.Sync("ppu_open_bus", ref ppu_open_bus);
ser.Sync("double_2007_read", ref double_2007_read);
ser.Sync("ppu_open_bus_decay_timer", ref ppu_open_bus_decay_timer, false);
ser.Sync("glitchy_reads_2003", ref glitchy_reads_2003, false);
ser.Sync("OAM", ref OAM, false);
ser.Sync("PALRAM", ref PALRAM, false);

View File

@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public byte ppu_open_bus=0;
public int double_2007_read; // emulates a hardware bug of back to back 2007 reads
public int[] ppu_open_bus_decay_timer = new int[8];
public byte[] glitchy_reads_2003 = new byte[8];
public struct PPUSTATUS
{
@ -400,10 +401,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
//OAM ADDRESS (write)
void write_2003(byte value)
void write_2003(int addr, byte value)
{
//just record the oam buffer write target
reg_2003 = value;
if (region == PPU.Region.NTSC)
{
// in NTSC this does several glitchy things to corrupt OAM
// commented out for now until better understood
byte temp = (byte)(reg_2003 & 0xF8);
byte temp_2 = (byte)(addr >> 16 & 0xF8);
/*
for (int i=0;i<8;i++)
{
glitchy_reads_2003[i] = OAM[temp + i];
//OAM[temp_2 + i] = glitchy_reads_2003[i];
}
*/
reg_2003 = value;
}
else
{
// in PAL, just record the oam buffer write target
reg_2003 = value;
}
}
byte read_2003() { return ppu_open_bus; }
byte peek_2003() { return ppu_open_bus; }
@ -424,15 +443,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
{
if (ppur.status.sl < 241)
{
if (ppur.status.cycle <= 64)
if (ppur.status.cycle < 64)
{
ret = 0xFF; // during this time all reads return FF
}
else if (ppur.status.cycle <= 256)
else if (ppur.status.cycle < 256)
{
ret = read_value;
}
else if (ppur.status.cycle <= 320)
else if (ppur.status.cycle < 320)
{
ret = read_value;
}
@ -669,7 +688,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
PPUGenLatch = value;
ppu_open_bus = value;
switch (addr)
switch (addr & 0x07)
{
case 0:
if (nes._isVS2c05>0)
@ -684,7 +703,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
write_2001(value);
break;
case 2: write_2002(value); break;
case 3: write_2003(value); break;
case 3: write_2003(addr, value); break;
case 4: write_2004(value); break;
case 5: write_2005(value); break;
case 6: write_2006(value); break;

View File

@ -130,16 +130,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ppu_addr_temp |= 8;
bgdata.pt_1 = ppubus_read(ppu_addr_temp, true, true);
runppu(1);
if (reg_2001.PPUON)
{
ppu_was_on = true;
}
break;
case 7:
race_2006 = false;
runppu(1);
//horizontal scroll clocked at cycle 3 and then
//vertical scroll at 256
if (ppu_was_on)
@ -148,6 +150,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (ppur.status.cycle == 256 && !race_2006)
ppur.increment_vs();
}
ppu_was_on = false;
break;
} //switch(cycle)
@ -219,6 +222,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
yp = sl - 1;
ppuphase = PPUPHASE.BG;
// "If PPUADDR is not less then 8 when rendering starts, the first 8 fights in OAM and written to from
// the current location off PPUADDR"
if (sl == 0 && reg_2001.PPUON && reg_2003 >= 8)
{
for (int i = 0; i < 8; i++)
{
OAM[i] = OAM[reg_2003 & 0xF8 + i];
}
}
if (NTViewCallback != null && yp == NTViewCallback.Scanline) NTViewCallback.Callback();
if (PPUViewCallback != null && yp == PPUViewCallback.Scanline) PPUViewCallback.Callback();
@ -259,37 +272,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (ppur.status.cycle == 64)
{
soam_index = 0;
oam_index = 0;// reg_2003;
}
// otherwise, scan through OAM and test if sprites are in range
// if they are, they get copied to the secondary OAM
if (ppur.status.cycle >= 64)
{
if (oam_index == 64)
if (oam_index >= 256)
{
oam_index = 0;
sprite_eval_write = false;
}
if (is_even_cycle && oam_index<64)
if (is_even_cycle && oam_index<256)
{
if ((oam_index * 4 + soam_m_index) < 256)
read_value = OAM[oam_index * 4 + soam_m_index];
if ((oam_index + soam_m_index) < 256)
read_value = OAM[oam_index + soam_m_index];
else
read_value = OAM[oam_index * 4 + soam_m_index - 256];
read_value = OAM[oam_index + soam_m_index - 256];
}
else if (!sprite_eval_write)
{
// if we don't write sprites anymore, just scan through the oam
read_value = soam[0];
oam_index++;
oam_index+=4;
}
else if (sprite_eval_write)
{
//look for sprites
if (spr_true_count==0 && soam_index<8)
{
soam[soam_index * 4] = read_value;
soam[soam_index*4] = read_value;
}
if (soam_index < 8)
@ -297,7 +311,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
if (yp >= read_value && yp < read_value + spriteHeight && spr_true_count == 0)
{
//a flag gets set if sprite zero is in range
if (oam_index == 0)
if (oam_index == 0)//reg_2003)
sprite_zero_in_range = true;
spr_true_count++;
@ -312,10 +326,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
spr_true_count++;
if (spr_true_count == 4)
{
oam_index++;
oam_index+=4;
soam_index++;
if (soam_index == 8)
oam_index_aux = oam_index;
{
// oam_index could be pathologically misaligned at this point, so we have to find the next
// nearest actual sprite to work on >8 sprites per scanline option
oam_index_aux = (oam_index%4)*4;
}
soam_m_index = 0;
spr_true_count = 0;
@ -323,7 +341,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
else
{
oam_index++;
oam_index+=4;
}
}
else if (soam_index>=8)
@ -345,7 +363,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
spr_true_count++;
if (spr_true_count == 4)
{
oam_index++;
oam_index+=4;
soam_index++;
soam_m_index = 0;
spr_true_count = 0;
@ -353,7 +371,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
else
{
oam_index++;
oam_index+=4;
if (soam_index==8)
{
soam_m_index++; // glitchy increment