It is currently Tue Oct 17, 2017 10:54 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: sprite 0 (attn: disch)
PostPosted: Mon Oct 24, 2005 6:12 am 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
Disch i finally could get working what you told me about "catch up the cpu", but im having problems with sprite 0 hit. Do i count the cycles to hit or do i "hit" in my multiplexer emu and then return from the ppu?

Thanks in advance.

_________________
ANes


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 9:23 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
"Catch up the CPU"? Are you doing it backwards? The idea is you run the CPU first then catch up the other areas (PPU/APU) as needed. You shouldn't run the PPU ahead of the CPU, because the CPU can change PPU operation at any time... whereas all the influence the PPU/APU has on the CPU can be predicted, so you can safely run the CPU far ahead first.

My emu checks for sprite 0 hit during pixel rendering (in the multiplexer), and then changes my 2002 status variable. Then I catch up the CPU on every $2002 read. (yeah it's not super efficient since wait-for-sprite-0-hit loops will have the PPU catching up every other instruction, but it works and is simple)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 2:35 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
Disch wrote:
My emu checks for sprite 0 hit during pixel rendering (in the multiplexer), and then changes my 2002 status variable. Then I catch up the CPU on every $2002 read. (yeah it's not super efficient since wait-for-sprite-0-hit loops will have the PPU catching up every other instruction, but it works and is simple)

You only need to catch up the PPU on $2002 reads during those scanlines where $2002 is likely to change, such as those that contain sprite 0 and thosethat contain >= 8 sprites.

EDIT: corrected


Last edited by tepples on Mon Oct 24, 2005 2:46 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 2:43 pm 
Offline

Joined: Thu Sep 15, 2005 9:23 am
Posts: 1194
Location: Behind you with a knife!
tepples wrote:
You only need to catch up the PPU on $2002 writes during those scanlines where $2002 is likely to change, such as those that contain sprite 0 and thosethat contain >= 8 sprites.


$2002 writes? Isn't $2002 read only?

_________________
http://www.jamesturner.de/


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 2:46 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
Typo. Fixed. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 2:51 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Yeah I've been meaning to organize a method for doing that and impliment it... but I keep putting it off.

You'd only need to catch up when any one of the following is true:

1) PPU is before start of vblank + CPU is past start of vblank
2) PPU is before end of vblank + CPU is past end of vblank
3) Sprite 0 flag is clear + CPU is on on/after a spr0 scanline + PPU is on/before a spr0 scanline + BG and spr rendering are both enabled


Then of course there's stuff for the 8-sprite flag... which I think is why I keep putting off this method of prediction. It's such a pain to track every scanline where the 8-sprite flag could raise and do checks like the above.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 3:10 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
Disch wrote:
Then of course there's stuff for the 8-sprite flag... which I think is why I keep putting off this method of prediction. It's such a pain to track every scanline where the 8-sprite flag could raise and do checks like the above.

You could calculate the next scanline to contain at least 8 sprites whenever $2001 is written to with the sprites turned on, and then you could mark those scanlines for catch-up on $2002 reads.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 3:15 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Quote:
Then of course there's stuff for the 8-sprite flag... which I think is why I keep putting off this method of prediction. It's such a pain to track every scanline where the 8-sprite flag could raise and do checks like the above.


Heh, same issue I've had, though my approach is just to not implement it. If a game is polling it, you need to run the PPU every time since that 8th sprite might have just rendered. I don't think you can tally up the "sprites per scanline" at the beginning of the frame since sprite RAM can be modified mid-frame (correct?). Hmmm well I suppose you could do this ahead of time and only run the PPU on scanlines which have more than 8 sprites, and recalculate this if sprite RAM is modified mid-frame. Quite complex.

So far I've only found Bee 52 to need the flag, so I hard-coded its time to scanline 21+164.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 3:41 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Your post suddenly made it seem much simpler tepples!

You only need to track the first scanline where 9+ sprites are found. You can sort through sprites when the PPU is flipped on ($2001) and when sprite data is changed ($4014, $2004). You don't even have to catch up the PPU... you can just keep a timestamp when the 8-sprite flag will raise.

I just might have to impliment this now. No more procrastinating ;D


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 6:59 am 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
mmm... im still having problems, i ran blargg's s0 hit test and it throw me "not working at all".

any help?

_________________
ANes


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 10:06 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Well I can't really be specific since I don't know what your emu is doing.

But the basic idea I've got working is:

- Catch up the PPU on $2002 reads
- Set the Sprite 0 flag in your PPU emulator as you render pixels

If sprite 0 flag isn't raising, then it could be you're not catching up as far as you need to be (or even at all?)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 9:22 pm 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
i could get working sprite hit (althougth blargg's test still throw me errors).
but now im having problems in mmc3 games.
What im doing is the following:

- on cycle 259 (0 - 340) i clock the irq counter if the conditions for clocking it are true.
- i runppu() when a chr swap is done.

maybe im setting/clearing at a bad moment 2002.7 flag.
i do the following:

- i set 2002.7 (and generate a NMI if enabled) at the end of the frame.
- im clearing it at cycle 0 of scanline = - 1 just after vblank pass.

it seems that this of setting 2002.7 is not bad when i runcpu() after (((262 * 341) / 3) * 15) master cycles (a frame).
When runcpu() returns from the frame i catch up again the ppu (runppu(cpu_timestamp)) and dont know what to do with my ppu_timestamp var (i normaly substract it from my cpu_timestamp var), i dont know if its well said in english i mean: ppu_timestamp -= cpu_timestamp.

_________________
ANes


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 10:33 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Anes wrote:
and dont know what to do with my ppu_timestamp var (i normaly substract it from my cpu_timestamp var), i dont know if its well said in english i mean: ppu_timestamp -= cpu_timestamp.


subtract a frame's worth of cycles from all timestamps.

I have something like the following:

Code:
s32 framecycles = 262 * 341 * PPU_CYCBASE;  // master cycles in a frame

RunCPU(framecycles);
RunPPU(framecycles);
RunAPU(framecycles);

cpu_timestamp -= framecycles;
ppu_timestamp -= framecycles;
apu_timestamp -= framecycles;


do not reset any timestamps to zero, since then you lose "spillover" cycles. Cycles that went into the next frame should take away from the next frame's time.


As for your MMC3 problems, I can't really help ya. Double check your MMC3 IRQ emulation (was it working with your old method?)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 25, 2005 10:48 pm 
Offline
User avatar

Joined: Tue Dec 21, 2004 8:35 pm
Posts: 600
Location: Argentina
Quote:
was it working with your old method?


yeah, it was working at a 90%, i use the code you gave me in a post that is:

Code:
void ClockIRQCounter(void)
{

if (g_MMC3.cIRQ == 0)
   g_MMC3.cIRQ = g_MMC3.cReloadValue; //reload IRQ counter with reload value
else
{
   g_MMC3.cIRQ--; // decrement IRQ counter

   if ((g_MMC3.cIRQ == 0) && (g_MMC3.IRQFlag))//IRQ counter just became 0 and if MMC3 IRQs are enabled, raise 'IRQ pending' flag
      //g_lpCpuContext->IRQ_pending = TRUE;
      a6502IRQSignal();
}

}


strange that its not working ah?
The thing i have a question when IRQ counter just become "0", what is better to directly execute the IRQ or to set a flag and then when cpu emu back to the main execute engine check the IRQ flag and raise it?
Well i hope this can help you to help me.
Thanks!

_________________
ANes


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group