NES Update $2003 behaviour
Fixes Huge Insect Some debate reamins about what exactly is happening here though
This commit is contained in:
parent
b453745404
commit
df7a93e83a
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue