[nes] timing and accuracy work.
This commit is contained in:
parent
89ff0c8927
commit
e6afb2359b
|
@ -224,6 +224,7 @@
|
|||
<Compile Include="Sound\Utilities\Waves.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Consoles\Nintendo\Docs\test_status.txt" />
|
||||
<Content Include="Consoles\PC Engine\Compat.txt" />
|
||||
<Content Include="Consoles\Sega\SMS\Compat.txt" />
|
||||
<Content Include="Notes.txt" />
|
||||
|
|
|
@ -17,16 +17,27 @@ namespace BizHawk.Emulation.CPUs.M6502
|
|||
PendingCycles += cycles;
|
||||
while (PendingCycles > 0)
|
||||
{
|
||||
if (NMI)
|
||||
{
|
||||
TriggerException(ExceptionType.NMI);
|
||||
NMI = false;
|
||||
}
|
||||
if (IRQ && !FlagI)
|
||||
{
|
||||
TriggerException(ExceptionType.IRQ);
|
||||
}
|
||||
|
||||
if (NMI)
|
||||
{
|
||||
TriggerException(ExceptionType.NMI);
|
||||
NMI = false;
|
||||
}
|
||||
if (IRQ && !FlagI)
|
||||
{
|
||||
if (SEI_Pending)
|
||||
FlagI = true;
|
||||
TriggerException(ExceptionType.IRQ);
|
||||
}
|
||||
if (CLI_Pending)
|
||||
{
|
||||
FlagI = false;
|
||||
CLI_Pending = false;
|
||||
}
|
||||
if (SEI_Pending)
|
||||
{
|
||||
FlagI = true;
|
||||
SEI_Pending = false;
|
||||
}
|
||||
if(debug) Console.WriteLine(State());
|
||||
|
||||
ushort this_pc = PC;
|
||||
|
@ -209,7 +220,15 @@ TriggerException(ExceptionType.BRK);
|
|||
PendingCycles -= 5; TotalExecutedCycles += 5;
|
||||
break;
|
||||
case 0x28: // PLP
|
||||
P = ReadMemory((ushort)(++S + 0x100));
|
||||
//handle I flag differently. sort of a sloppy way to do the job, but it does finish it off.
|
||||
value8 = ReadMemory((ushort)(++S + 0x100));
|
||||
if ((value8 & 0x04) != 0 && !FlagI)
|
||||
SEI_Pending = true;
|
||||
if ((value8 & 0x04) == 0 && FlagI)
|
||||
CLI_Pending = true;
|
||||
value8 &= unchecked((byte)~0x04);
|
||||
P &= 0x04;
|
||||
P |= value8;
|
||||
FlagT = true;//this seems wrong
|
||||
PendingCycles -= 4; TotalExecutedCycles += 4;
|
||||
break;
|
||||
|
@ -431,7 +450,8 @@ FlagT = true;// this seems wrong
|
|||
PendingCycles -= 6; TotalExecutedCycles += 6;
|
||||
break;
|
||||
case 0x58: // CLI
|
||||
FlagI = false;
|
||||
//FlagI = false;
|
||||
CLI_Pending = true;
|
||||
PendingCycles -= 2; TotalExecutedCycles += 2;
|
||||
break;
|
||||
case 0x59: // EOR addr,Y
|
||||
|
@ -594,7 +614,8 @@ FlagT = true;// this seems wrong
|
|||
PendingCycles -= 6; TotalExecutedCycles += 6;
|
||||
break;
|
||||
case 0x78: // SEI
|
||||
FlagI = true;
|
||||
//FlagI = true;
|
||||
SEI_Pending = true;
|
||||
PendingCycles -= 2; TotalExecutedCycles += 2;
|
||||
break;
|
||||
case 0x79: // ADC addr,Y
|
||||
|
|
|
@ -103,6 +103,9 @@ namespace BizHawk.Emulation.CPUs.M6502
|
|||
|
||||
public bool IRQ;
|
||||
public bool NMI;
|
||||
public bool CLI_Pending;
|
||||
public bool SEI_Pending;
|
||||
public bool EscapeRequest;
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
look for tests here: http://wiki.nesdev.com/w/index.php/Emulator_tests
|
||||
|
||||
blargg's MMC3:
|
||||
FAIL for 4 and 6. i think 4 might not fail until some invisible PPU operations are correct. neither nintendulator or fceux pass these.
|
||||
|
||||
blargg's ppu tests:
|
||||
PASS for all but power_up_palette.nes which is lame
|
||||
|
||||
blargg's ppu_vbl_nmi:
|
||||
FAIL for 9. But hardly anyone passes this.....
|
||||
|
||||
blargg's sprite hit tests:
|
||||
FAIL for 9 and 10. fceux passes 10 (oldppu) and nintendulator passes both.
|
||||
boath are not going to work any time soon due to sprite pattern decoding being separate from BG pattern fetching instead of interleaved.
|
||||
|
||||
all_instrs.nes
|
||||
FAIL (freezes emu??). I think this requires undocumented instructions.
|
||||
|
||||
cpu_interrupts.nes
|
||||
PASS
|
||||
|
||||
instr_misc.nes
|
||||
PASS
|
||||
|
||||
instr_timing.nes
|
||||
PASS
|
||||
|
||||
nestest.nes
|
||||
PASS
|
||||
|
||||
official_only.nes
|
||||
PASS
|
|
@ -15,6 +15,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
bool Configure(NES.EDetectionOrigin origin);
|
||||
byte ReadPRG(int addr);
|
||||
byte ReadPPU(int addr); byte PeekPPU(int addr);
|
||||
void AddressPPU(int addr);
|
||||
byte ReadWRAM(int addr);
|
||||
byte ReadEXP(int addr);
|
||||
void WritePRG(int addr, byte value);
|
||||
|
@ -140,6 +141,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void AddressPPU(int addr) { }
|
||||
public virtual byte PeekPPU(int addr) { return ReadPPU(addr); }
|
||||
|
||||
public virtual byte ReadPPU(int addr)
|
||||
|
|
|
@ -63,7 +63,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
if (ROM != null && bus_conflict) value = HandleNormalPRGConflict(addr,value);
|
||||
prg = (value*2) & prg_mask;
|
||||
int prg_bank = value & 7;
|
||||
prg = (prg_bank * 2) & prg_mask;
|
||||
if ((value & 0x10) == 0)
|
||||
SetMirrorType(NES.NESBoardBase.EMirrorType.OneScreenA);
|
||||
else
|
||||
|
|
|
@ -22,6 +22,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
{
|
||||
bank_regs[8] = (byte)(num_prg_banks - 1);
|
||||
bank_regs[9] = (byte)(num_prg_banks - 2);
|
||||
bank_regs[0] = 0;
|
||||
bank_regs[1] = 1;
|
||||
bank_regs[2] = 2;
|
||||
bank_regs[3] = 3;
|
||||
bank_regs[4] = 4;
|
||||
bank_regs[5] = 5;
|
||||
sync_2k_chr();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -34,10 +41,28 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public int chr_mode, prg_mode, reg_addr;
|
||||
|
||||
//this contains the 8 programmable regs and 2 more at the end to represent PRG banks -2 and -1; and 4 more at the end to break down chr regs 0 and 1
|
||||
//in other words:
|
||||
//0: chr reg 0 (not used directly)
|
||||
//1: chr reg 1 (not used directly)
|
||||
//2,3,4,5: chr reg 2,3,4,5
|
||||
//6,7: prg reg 6,7
|
||||
//8,9: prg reg -2,-1
|
||||
//10: chr reg 0A
|
||||
//11: chr reg 0B
|
||||
//12: chr reg 1A
|
||||
//13: chr reg 1B
|
||||
ByteBuffer bank_regs = new ByteBuffer(14);
|
||||
ByteBuffer prg_lookup = new ByteBuffer(new byte[] { 6, 7, 9, 8, 9, 7, 6, 8 });
|
||||
ByteBuffer chr_lookup = new ByteBuffer(new byte[] { 10, 11, 12, 13, 2, 3, 4, 5 });
|
||||
|
||||
void sync_2k_chr()
|
||||
{
|
||||
bank_regs[10] = (byte)((bank_regs[0] & ~1) + 0);
|
||||
bank_regs[11] = (byte)((bank_regs[0] & ~1) + 1);
|
||||
bank_regs[12] = (byte)((bank_regs[1] & ~1) + 0);
|
||||
bank_regs[13] = (byte)((bank_regs[1] & ~1) + 1);
|
||||
}
|
||||
|
||||
public virtual void WritePRG(int addr, byte value)
|
||||
{
|
||||
switch (addr & 0x6001)
|
||||
|
@ -49,11 +74,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
break;
|
||||
case 0x0001: //$8001
|
||||
bank_regs[reg_addr] = value;
|
||||
//setup the 2K chr regs
|
||||
bank_regs[10] = (byte)((bank_regs[0] & ~1) + 0);
|
||||
bank_regs[11] = (byte)((bank_regs[0] & ~1) + 1);
|
||||
bank_regs[12] = (byte)((bank_regs[1] & ~1) + 0);
|
||||
bank_regs[13] = (byte)((bank_regs[1] & ~1) + 1);
|
||||
sync_2k_chr();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -114,37 +135,49 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
case 0x2001: //$A001
|
||||
//wram enable/protect
|
||||
break;
|
||||
case 0x4000: //$C000
|
||||
case 0x4000: //$C000 - IRQ Reload value
|
||||
irq_reload = value;
|
||||
break;
|
||||
case 0x4001: //$C001
|
||||
case 0x4001: //$C001 - IRQ Clear
|
||||
irq_counter = 0;
|
||||
break;
|
||||
case 0x6000: //$E000
|
||||
case 0x6000: //$E000 - IRQ Acknowledge / Disable
|
||||
irq_enable = false;
|
||||
irq_pending = false;
|
||||
SyncIRQ();
|
||||
break;
|
||||
case 0x6001: //$E001
|
||||
case 0x6001: //$E001 - IRQ Enable
|
||||
irq_enable = true;
|
||||
SyncIRQ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IRQ_EQ_Pass()
|
||||
{
|
||||
if (irq_enable)
|
||||
irq_pending = true;
|
||||
SyncIRQ();
|
||||
}
|
||||
|
||||
void ClockIRQ()
|
||||
{
|
||||
if (irq_counter == 0)
|
||||
{
|
||||
irq_counter = irq_reload;
|
||||
|
||||
//TODO - MMC3 variant behaviour??? not sure
|
||||
//was needed to pass 2-details.nes
|
||||
if (irq_counter == 0)
|
||||
IRQ_EQ_Pass();
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_counter--;
|
||||
//Console.WriteLine(irq_counter);
|
||||
if (irq_counter == 0)
|
||||
{
|
||||
if (irq_enable)
|
||||
irq_pending = true;
|
||||
SyncIRQ();
|
||||
IRQ_EQ_Pass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,24 +273,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
|
||||
//state
|
||||
protected MMC3 mmc3;
|
||||
|
||||
public override void AddressPPU(int addr)
|
||||
{
|
||||
mmc3.Tick_PPU(addr);
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
mmc3.Tick_PPU(addr);
|
||||
return base.ReadPPU(addr);
|
||||
}
|
||||
|
||||
public override void WritePPU(int addr, byte value)
|
||||
{
|
||||
mmc3.Tick_PPU(addr);
|
||||
base.WritePPU(addr, value);
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
base.WritePRG(addr, value);
|
||||
}
|
||||
|
||||
protected override void BaseSetup()
|
||||
{
|
||||
wram_mask = (Cart.wram_size * 1024) - 1;
|
||||
|
|
|
@ -50,6 +50,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//analyze board type
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "TXROM-HOMEBREW":
|
||||
break;
|
||||
case "NES-TBROM": //tecmo world cup soccer (DE) [untested]
|
||||
AssertPrg(64); AssertChr(64); AssertVram(0); AssertWram(0);
|
||||
AssertBattery(false);
|
||||
|
|
|
@ -96,13 +96,22 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
else
|
||||
cycles <<= 4;
|
||||
|
||||
|
||||
//tricky logic to try to run one instruction at a time
|
||||
cpu_accumulate += cycles;
|
||||
if (cpu_accumulate >= 48)
|
||||
int cpu_cycles = cpu_accumulate / 48;
|
||||
for (; ; )
|
||||
{
|
||||
int todo = cpu_accumulate / 48;
|
||||
cpu_accumulate -= todo * 48;
|
||||
if (cpu_cycles == 0) break;
|
||||
int need_cpu = -cpu.PendingCycles + 1;
|
||||
if (cpu_cycles < need_cpu) break;
|
||||
if (need_cpu == 0) need_cpu = 1;
|
||||
int todo = need_cpu;
|
||||
cpu_cycles -= todo;
|
||||
cpu_accumulate -= 48*todo;
|
||||
cpu.Execute(todo);
|
||||
apu.Run(todo);
|
||||
ppu.TickCpu();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//when the ppu issues a write it goes through here and into the game board
|
||||
public void ppubus_write(int addr, byte value)
|
||||
{
|
||||
nes.board.AddressPPU(addr);
|
||||
nes.board.WritePPU(addr, value);
|
||||
}
|
||||
|
||||
//when the ppu issues a read it goes through here and into the game board
|
||||
public byte ppubus_read(int addr)
|
||||
{
|
||||
nes.board.AddressPPU(addr);
|
||||
//apply freeze
|
||||
if (ppubus_freeze[addr].IsFrozen)
|
||||
return ppubus_freeze[addr].value;
|
||||
|
@ -89,17 +91,48 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
nes.cpu.NMI = true;
|
||||
}
|
||||
|
||||
public void TickCpu()
|
||||
{
|
||||
if (NMI_PendingCycles > 0)
|
||||
{
|
||||
NMI_PendingCycles--;
|
||||
if (NMI_PendingCycles == 0)
|
||||
{
|
||||
TriggerNMI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void runppu(int x)
|
||||
{
|
||||
//pputime+=x;
|
||||
|
||||
//DON'T LIKE THIS....
|
||||
ppur.status.cycle += x;
|
||||
if (ppur.status.cycle > ppur.status.end_cycle)
|
||||
while(ppur.status.cycle >= ppur.status.end_cycle)
|
||||
ppur.status.cycle -= ppur.status.end_cycle;
|
||||
|
||||
if(x == 0) return;
|
||||
|
||||
nes.RunCpu(1);
|
||||
x--;
|
||||
|
||||
if (Reg2002_vblank_active_pending)
|
||||
{
|
||||
if (Reg2002_vblank_active_pending)
|
||||
Reg2002_vblank_active = 1;
|
||||
Reg2002_vblank_active_pending = false;
|
||||
}
|
||||
|
||||
if (Reg2002_vblank_clear_pending)
|
||||
{
|
||||
Reg2002_vblank_active = 0;
|
||||
Reg2002_vblank_clear_pending = false;
|
||||
}
|
||||
|
||||
|
||||
if (x == 0) return;
|
||||
nes.RunCpu(x);
|
||||
//pputime -= cputodo<<2;
|
||||
}
|
||||
|
||||
//hack
|
||||
|
|
|
@ -294,6 +294,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
Bit Reg2002_objoverflow; //Sprite overflow. The PPU can handle only eight sprites on one scanline and sets this bit if it starts drawing sprites.
|
||||
Bit Reg2002_objhit; //Sprite 0 overlap. Set when a nonzero pixel of sprite 0 is drawn overlapping a nonzero background pixel. Used for raster timing.
|
||||
Bit Reg2002_vblank_active; //Vertical blank start (0: has not started; 1: has started)
|
||||
bool Reg2002_vblank_active_pending; //set of Reg2002_vblank_active is pending
|
||||
bool Reg2002_vblank_clear_pending; //ppu's clear of vblank flag is pending
|
||||
int NMI_PendingCycles;
|
||||
byte PPUGenLatch;
|
||||
public PPUREGS ppur;
|
||||
Reg_2000 reg_2000;
|
||||
|
@ -324,11 +327,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//PPU CONTROL (write)
|
||||
void write_2000(byte value)
|
||||
{
|
||||
if (!reg_2000.vblank_nmi_gen & ((value & 0x80) != 0) && (Reg2002_vblank_active))
|
||||
if (!reg_2000.vblank_nmi_gen & ((value & 0x80) != 0) && (Reg2002_vblank_active) && !Reg2002_vblank_clear_pending)
|
||||
{
|
||||
//if we just unleashed the vblank interrupt then activate it now
|
||||
//FCEUX would use a "trigger NMI2" here in order to result in some delay effect
|
||||
TriggerNMI();
|
||||
NMI_PendingCycles = 2;
|
||||
}
|
||||
reg_2000.Value = value;
|
||||
}
|
||||
|
@ -354,12 +356,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
int ret = (Reg2002_vblank_active << 7) | (Reg2002_objhit << 6) | (Reg2002_objoverflow << 5) | (PPUGenLatch & 0x1F);
|
||||
|
||||
Reg2002_vblank_active = 0;
|
||||
Reg2002_vblank_active_pending = false;
|
||||
|
||||
return (byte)ret;
|
||||
}
|
||||
void clear_2002()
|
||||
{
|
||||
Reg2002_vblank_active = Reg2002_objhit = Reg2002_objoverflow = 0;
|
||||
Reg2002_objhit = Reg2002_objoverflow = 0;
|
||||
Reg2002_vblank_clear_pending = true;
|
||||
}
|
||||
|
||||
//OAM ADDRESS (write)
|
||||
|
@ -378,7 +382,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
OAM[reg_2003] = value;
|
||||
reg_2003++;
|
||||
}
|
||||
byte read_2004() { return 0xFF; /* TODO !!!!!! THIS IS UGLY. WE SHOULD PASTE IT IN OR REWRITE IT BUT WE NEED TO ASK QEED FOR TEST CASES*/ }
|
||||
byte read_2004() {
|
||||
return OAM[reg_2003];
|
||||
}
|
||||
|
||||
//SCROLL (write)
|
||||
void write_2005(byte value)
|
||||
|
@ -414,6 +420,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
ppur._vt |= (value >> 5);
|
||||
ppur._ht = value & 31;
|
||||
ppur.install_latches();
|
||||
|
||||
nes.board.AddressPPU(ppur.get_2007access());
|
||||
}
|
||||
vtoggle ^= true;
|
||||
}
|
||||
|
@ -443,6 +451,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
}
|
||||
|
||||
ppur.increment2007(reg_2000.vram_incr32 != 0);
|
||||
int newaddr = ppur.get_2007access() & 0x3FFF;
|
||||
nes.board.AddressPPU(newaddr);
|
||||
}
|
||||
byte read_2007()
|
||||
{
|
||||
|
@ -462,6 +472,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
}
|
||||
|
||||
ppur.increment2007(reg_2000.vram_incr32 != 0);
|
||||
|
||||
int newaddr = ppur.get_2007access() & 0x3FFF;
|
||||
nes.board.AddressPPU(newaddr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//http://nesdev.parodius.com/bbs/viewtopic.php?p=4571&sid=db4c7e35316cc5d734606dd02f11dccb
|
||||
|
||||
//todo - read http://wiki.nesdev.com/w/index.php/PPU_sprite_priority
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
@ -85,17 +87,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
return;
|
||||
}
|
||||
|
||||
Reg2002_vblank_active = 1;
|
||||
Reg2002_vblank_active_pending = true;
|
||||
ppuphase = PPUPHASE.VBL;
|
||||
|
||||
//Not sure if this is correct. According to Matt Conte and my own tests, it is.
|
||||
//Timing is probably off, though.
|
||||
//Not sure if this is correct. According to Matt Conte and my own tests, it is. Timing is probably off, though.
|
||||
//NOTE: Not having this here breaks a Super Donkey Kong game.
|
||||
reg_2003 = 0;
|
||||
const int delay = 20; //fceu used 12 here but I couldnt get it to work in marble madness and pirates.
|
||||
|
||||
runppu(delay); //X6502_Run(12);
|
||||
if (reg_2000.vblank_nmi_gen) TriggerNMI();
|
||||
//fceu/fceux had 12 here, but 15 was required to pass blargg's 05-nmi_timing.nes
|
||||
const int delay = 15;
|
||||
runppu(3);
|
||||
bool nmi_destiny = reg_2000.vblank_nmi_gen && Reg2002_vblank_active;
|
||||
runppu(delay - 3);
|
||||
if (nmi_destiny) TriggerNMI();
|
||||
if (PAL)
|
||||
runppu(70 * (kLineTime) - delay);
|
||||
else
|
||||
|
@ -103,17 +107,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
|
||||
//this seems to run just before the dummy scanline begins
|
||||
clear_2002();
|
||||
//this early out caused metroid to fail to boot. I am leaving it here as a reminder of what not to do
|
||||
//if(!PPUON) { runppu(kLineTime*242); goto finish; }
|
||||
|
||||
//There are 2 conditions that update all 5 PPU scroll counters with the
|
||||
//contents of the latches adjacent to them. The first is after a write to
|
||||
//2006/2. The second, is at the beginning of scanline 20, when the PPU starts
|
||||
//rendering data for the first time in a frame (this update won't happen if
|
||||
//all rendering is disabled via 2001.3 and 2001.4).
|
||||
|
||||
//if(PPUON)
|
||||
// ppur.install_latches();
|
||||
|
||||
TempOAM* oams = stackalloc TempOAM[128];
|
||||
int* oamcounts = stackalloc int[2];
|
||||
|
@ -142,6 +135,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//two of those tiles were read in the last scanline.
|
||||
for (int xt = 0; xt < 32; xt++)
|
||||
{
|
||||
if (sl == 31 && xt == 31)
|
||||
{
|
||||
int zzz = 9;
|
||||
}
|
||||
Read_bgdata(ref bgdata[xt + 2]);
|
||||
|
||||
//ok, we're also going to draw here.
|
||||
|
@ -205,11 +202,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
//transparent pixel bailout
|
||||
if (spixel == 0) continue;
|
||||
|
||||
//TODO - make sure we dont trigger spritehit if the edges are masked for either BG or OBJ
|
||||
//spritehit:
|
||||
//1. is it sprite#0?
|
||||
//2. is the bg pixel nonzero?
|
||||
//then, it is spritehit.
|
||||
if (oam->index == 0 && (pixel & 3) != 0 && rasterpos < 255)
|
||||
if (oam->index == 0)
|
||||
{
|
||||
int zzz = 9;
|
||||
}
|
||||
if (oam->index == 0 && pixel != 0 && rasterpos < 255)
|
||||
{
|
||||
Reg2002_objhit = true;
|
||||
}
|
||||
|
@ -397,20 +399,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
|
||||
ppuphase = PPUPHASE.BG;
|
||||
|
||||
//fetch BG: two tiles for next line
|
||||
for (int xt = 0; xt < 2; xt++)
|
||||
Read_bgdata(ref bgdata[xt]);
|
||||
|
||||
//I'm unclear of the reason why this particular access to memory is made.
|
||||
//The nametable address that is accessed 2 times in a row here, is also the
|
||||
//same nametable address that points to the 3rd tile to be rendered on the
|
||||
//screen (or basically, the first nametable address that will be accessed when
|
||||
//the PPU is fetching background data on the next scanline).
|
||||
//(not implemented yet)
|
||||
runppu(kFetchTime*2);
|
||||
runppu(kFetchTime * 2);
|
||||
if (sl == 0)
|
||||
{
|
||||
if (idleSynch && reg_2001.PPUON && !PAL)
|
||||
if (idleSynch && reg_2001.show_bg && !PAL)
|
||||
ppur.status.end_cycle = 340;
|
||||
else
|
||||
ppur.status.end_cycle = 341;
|
||||
|
@ -418,7 +416,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
}
|
||||
else
|
||||
ppur.status.end_cycle = 341;
|
||||
//runppu(kFetchTime);
|
||||
|
||||
//fetch BG: two tiles for next line
|
||||
for (int xt = 0; xt < 2; xt++)
|
||||
Read_bgdata(ref bgdata[xt]);
|
||||
|
||||
//After memory access 170, the PPU simply rests for 4 cycles (or the
|
||||
//equivelant of half a memory access cycle) before repeating the whole
|
||||
|
|
|
@ -55,12 +55,16 @@ static string ClassifyTable = @"
|
|||
1 32 32 8 0 NES-SEROM; lolo
|
||||
1 128 0 8 0 NES-SNROM; zelda
|
||||
1 128 128 8 0 NES-SKROM; zelda 2
|
||||
1 128 0 8 8 NES-SNROM; some of blargg's tests (apu)
|
||||
1 256 0 8 8 NES-SNROM; some of blargg's test (cpu tests)
|
||||
1 32 0 8 8 NROM-HOMEBREW; instr_timing.nes
|
||||
1 64 0 8 8 NROM-HOMEBREW; instr_misc.nes
|
||||
1 80 0 8 8 NROM-HOMEBREW; blargg's cpu_interrupts.nes
|
||||
1 128 0 8 8 NES-SNROM; some of blargg's tests (apu) [TODO recheck as NROM-HOMEBREW]
|
||||
1 256 0 8 8 NES-SNROM; some of blargg's test (cpu tests) [TODO recheck as NROM-HOMEBREW]
|
||||
2 128 0 8 0 NES-UNROM; mega man
|
||||
2 256 0 8 0 NES-UOROM; paperboy 2
|
||||
3 32 32 8 0 NES-CNROM; adventure island
|
||||
4 128 128 8 0 NES-TSROM; double dragon 2 (should be TL1ROM but maybe this will work)
|
||||
4 32 8 8 0 TXROM-HOMEBREW; blargg's mmc3 tests
|
||||
7 128 0 8 0 NES-ANROM; marble madness
|
||||
7 256 0 8 8 NES-AOROM; battletoads
|
||||
11 32 16 8 0 Discrete_74x377
|
||||
|
|
|
@ -362,17 +362,27 @@ namespace M6502
|
|||
w.WriteLine(" PendingCycles += cycles;");
|
||||
w.WriteLine(" while (PendingCycles > 0)");
|
||||
w.WriteLine(" {");
|
||||
|
||||
w.WriteLine(" if (NMI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TriggerException(ExceptionType.NMI);");
|
||||
w.WriteLine(" NMI = false;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (IRQ && !FlagI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TriggerException(ExceptionType.IRQ);");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine("");
|
||||
w.WriteLine(" if (NMI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" TriggerException(ExceptionType.NMI);");
|
||||
w.WriteLine(" NMI = false;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (IRQ && !FlagI)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" if (SEI_Pending)");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" TriggerException(ExceptionType.IRQ);");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (CLI_Pending)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" FlagI = false;");
|
||||
w.WriteLine(" CLI_Pending = false;");
|
||||
w.WriteLine(" }");
|
||||
w.WriteLine(" if (SEI_Pending)");
|
||||
w.WriteLine(" {");
|
||||
w.WriteLine(" FlagI = true;");
|
||||
w.WriteLine(" SEI_Pending = false;");
|
||||
w.WriteLine(" }");
|
||||
|
||||
w.WriteLine(" if(debug) Console.WriteLine(State());");
|
||||
w.WriteLine("");
|
||||
|
|
|
@ -82,7 +82,8 @@ namespace M6502
|
|||
|
||||
private void CLI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagI = false;");
|
||||
w.WriteLine(Spaces + "//FlagI = false;");
|
||||
w.WriteLine(Spaces + "CLI_Pending = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
|
@ -244,7 +245,15 @@ namespace M6502
|
|||
|
||||
private void PLP(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "P = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + "//handle I flag differently. sort of a sloppy way to do the job, but it does finish it off.");
|
||||
w.WriteLine(Spaces + "value8 = ReadMemory((ushort)(++S + 0x100));");
|
||||
w.WriteLine(Spaces + "if ((value8 & 0x04) != 0 && !FlagI)");
|
||||
w.WriteLine(Spaces + "\tSEI_Pending = true;");
|
||||
w.WriteLine(Spaces + "if ((value8 & 0x04) == 0 && FlagI)");
|
||||
w.WriteLine(Spaces + "\tCLI_Pending = true;");
|
||||
w.WriteLine(Spaces + "value8 &= unchecked((byte)~0x04);");
|
||||
w.WriteLine(Spaces + "P &= 0x04;");
|
||||
w.WriteLine(Spaces + "P |= value8;");
|
||||
w.WriteLine("FlagT = true;//this seems wrong");//this seems wrong
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
@ -333,7 +342,8 @@ w.WriteLine("FlagT = true;// this seems wrong");//this seems wrong
|
|||
|
||||
private void SEI(OpcodeInfo op, TextWriter w)
|
||||
{
|
||||
w.WriteLine(Spaces + "FlagI = true;");
|
||||
w.WriteLine(Spaces + "//FlagI = true;");
|
||||
w.WriteLine(Spaces + "SEI_Pending = true;");
|
||||
w.WriteLine(Spaces + "PendingCycles -= {0}; TotalExecutedCycles += {0};", op.Cycles);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue