It is currently Thu Oct 19, 2017 11:49 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: Mon Feb 06, 2017 4:12 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
I injected some logging into my PPU implementation. It records $2005 and $2006 writes along with the scanline, scanline cycle and w, t, v and x registers before and after the write. Also, by monitoring the pixel colors, it can differentiate between a good and bad frame.

Here's a good frame (scrollY = 203 at the split):

Code:
[$2005] = 00, scanline = 192, cycle = 287 w_before = false, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = true, t_after = 0000, v_after = 1300, x_after = 00, scrollY_after = 193
[$2005] = 00, scanline = 192, cycle = 305 w_before = true, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = false, t_after = 0000, v_after = 1300, x_after = 00, scrollY_after = 193
[$2006] = 3F, scanline = 192, cycle = 323 w_before = false, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = true, t_after = 3F00, v_after = 1300, x_after = 00, scrollY_after = 193
[$2006] = 01, scanline = 193, cycle = 0 w_before = true, t_before = 3F00, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = false, t_after = 3F01, v_after = 3F01, x_after = 00, scrollY_after = 435
[$2006] = 27, scanline = 193, cycle = 186 w_before = false, t_before = 3F01, v_before = 3F08, x_before = 00, scrollY_before = 435 w_after = true, t_after = 2701, v_after = 3F08, x_after = 00, scrollY_after = 435
[$2006] = 00, scanline = 193, cycle = 204 w_before = true, t_before = 2701, v_before = 3F08, x_before = 00, scrollY_before = 435 w_after = false, t_after = 2700, v_after = 2700, x_after = 00, scrollY_after = 194


Here's a bad frame (scrollY = 202 at the split):

Code:
[$2005] = 00, scanline = 192, cycle = 300 w_before = false, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = true, t_after = 0000, v_after = 1300, x_after = 00, scrollY_after = 193
[$2005] = 00, scanline = 192, cycle = 318 w_before = true, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = false, t_after = 0000, v_after = 1300, x_after = 00, scrollY_after = 193
[$2006] = 3F, scanline = 192, cycle = 336 w_before = false, t_before = 0000, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = true, t_after = 3F00, v_after = 1300, x_after = 00, scrollY_after = 193
[$2006] = 01, scanline = 193, cycle = 13 w_before = true, t_before = 3F00, v_before = 1300, x_before = 00, scrollY_before = 193 w_after = false, t_after = 3F01, v_after = 3F01, x_after = 00, scrollY_after = 435
[$2006] = 27, scanline = 193, cycle = 199 w_before = false, t_before = 3F01, v_before = 3F08, x_before = 00, scrollY_before = 435 w_after = true, t_after = 2701, v_after = 3F08, x_after = 00, scrollY_after = 435
[$2006] = 00, scanline = 193, cycle = 217 w_before = true, t_before = 2701, v_before = 3F08, x_before = 00, scrollY_before = 435 w_after = false, t_after = 2700, v_after = 2700, x_after = 00, scrollY_after = 194


I cannot detect any race conditions based on those values. Perhaps someone else will notice something. Thanks for looking.

Edit: Further logging revealed the core issue. The game disables rendering, it does the writes above and then it enables rendering. There is a timing issue where rendering is enabled just prior or just after the Y-increment, which causes the shaking. The Y-increment doesn't get called when rendering is disabled. I'll study this further.


Top
 Profile  
 
PostPosted: Mon Feb 06, 2017 5:54 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Well, you see the $2006 write and the Y-increment... but not the race condition. You're very good by digging something else... :shock: :roll: :roll: :lol: :lol:


Top
 Profile  
 
PostPosted: Mon Feb 06, 2017 6:15 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Zepper wrote:
Well, you see the $2006 write and the Y-increment... but not the race condition. You're very good by digging something else... :shock: :roll: :roll: :lol: :lol:


The cause is actually a $2001 write that takes place slightly after the dot where the Y-increment should take place. Meaning, it's a missed Y-increment.


Top
 Profile  
 
PostPosted: Mon Feb 06, 2017 6:26 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
zeroone wrote:
Zepper wrote:
Well, you see the $2006 write and the Y-increment... but not the race condition. You're very good by digging something else... :shock: :roll: :roll: :lol: :lol:


The cause is actually a $2001 write that takes place slightly after the dot where the Y-increment should take place. Meaning, it's a missed Y-increment.

I would justify me again, but do whatever you want to believe.


Top
 Profile  
 
PostPosted: Mon Feb 06, 2017 8:35 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Do registers $2005 and $2006 update the v, t and w registers immediately? Or, are they updated after a brief delay (i.e. a PPU cycle or 2)?


Top
 Profile  
 
PostPosted: Wed Feb 08, 2017 9:12 am 
Offline

Joined: Wed Jun 15, 2016 11:49 am
Posts: 44
fred wrote:
I very briefly tested writes to 0x2006 a while back in visual nes. It did seem like setting vramaddr_v to vramaddr_t in the second write was delayed a few ticks (~3?). I don't know the inner workings of the ppu enough to tell for certain.

The status bar in bart vs the space mutants that relies on a 6-5-5-6 series of writes stops shaking in my emulator if i delay the v = t effect for 3 ppu ticks. My cpu-ppu sync is not good enough to prove anything though, as evident by battletoads stage 2 crashing even faster with this change.


This is very interesting. Thanks for pointing this out. I wonder what other writes take a tick or 2 to take effect?


Top
 Profile  
 
PostPosted: Thu Feb 09, 2017 5:06 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Works like a charm. Wow. Even the "race condition" of $2006 vs Y-increment isn't necessary in this case.

Well, Battletoads still hangs during stage 2 - you know... it's a missing sprite zero hit.


Top
 Profile  
 
PostPosted: Thu Feb 09, 2017 7:01 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Zepper wrote:
Works like a charm. Wow. Even the "race condition" of $2006 vs Y-increment isn't necessary in this case.

Well, Battletoads still hangs during stage 2 - you know... it's a missing sprite zero hit.


Earlier, you suggested to skip a Y-increment if it occurred shortly after a $2006 write. However, by delaying the V-register update, it will overwrite the effect of the Y-increment that occurred slightly before the write.

I suspect any such skip or delay is a actually just a hack that does not reflect how the actual hardware performs. And, it's dangerous to introduce fixes through hacks since it's difficult to detect the affects on all other games with timing issues.

Ultimately, it comes down to how the emulator divides up time. The CPU runs at a third of the rate of the PPU. Consequentially, it's not clear exactly on what dot or perhaps even sub-dot information transfer actually occurs. And, it may even vary depending on the current state of the system. By running the PPU for 3 cycles after every CPU cycle, it's like trying to fit a small sheet on a large bed. You can pull it around, but you'll never fully cover the bed.


Top
 Profile  
 
PostPosted: Thu Feb 09, 2017 7:53 pm 
Offline

Joined: Fri Dec 30, 2011 7:15 am
Posts: 41
Location: Sweden
Here's what i was looking at in visual nes: http://pastebin.com/ket4LxgS
Pastebin because it's a lot of lines. This is two cpu cycles - the write to 0x2006, and fetching the next opcode. As can be seen, vramaddr_t gets set immediately on phi2 of the write cycle (ppu dot 198). vramaddr_v changes in the middle of dot 201.

That's what it looks like to me anyway. I don't want to talk in certainties here, because I only say what visual nes shows. I don't have any real understanding of the nes, if you know what i mean.


Top
 Profile  
 
PostPosted: Fri Feb 10, 2017 4:49 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
So... that's it. Even Nintendulator does not apply the changes immediately, see $2007 for example.


Top
 Profile  
 
PostPosted: Fri Feb 10, 2017 8:44 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Zepper wrote:
So... that's it. Even Nintendulator does not apply the changes immediately, see $2007 for example.


In Nintendulator 0.975, the status bar in "The Simpsons: Bart Vs. the Space Mutants" shakes and Battletoads Stage 2 tends to freeze. Those issues do not appear in Nintendulator 0.970; however, that earlier version contains a hack where the X and Y increments take place 4 dots earlier than they actually should. In addition, many of the timing test ROMs fail in both Nintendulator versions.

Nintendulator is an excellent emulator. But, it never fully overcame these problems either.


Top
 Profile  
 
PostPosted: Sat Feb 11, 2017 4:34 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Do you still have questions about the $2006 "delay" find?


Top
 Profile  
 
PostPosted: Sat Feb 11, 2017 1:08 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Zepper wrote:
So... that's it. Even Nintendulator does not apply the changes immediately, see $2007 for example.


In Nintendulator, PPU register writes update the v, t and w registers immediately. The delayed writes are for VRAM only.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 4:31 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Let me rephrase myself...

1. True, Nintendulator has such "delay" on $2007 only.
2. Do you expect a Nintendulator update to formalize the recent $2006 loopy_v=loopy_t delay find? Yes?


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 6:57 am 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
I'm seriously out of it from illness and other stuff, but I spent a bit of time playing around in Visual 2C02, and I think I can confirm what fred found.

write_2006_low goes high during the second write to $2006 - no delay.

delayed_write_2006_low goes high after a variable delay: (First number is rising edge, second number is falling edge, times are in the same units as Visual 2C02 so 1 pixel = 4 cycles.)
Code:
  normal    delayed
16.0 23.5  24.0 28.0
16.5 24.0  24.0 28.0
17.0 24.5  28.0 32.0
17.5 25.0  28.0 32.0
18.0 25.5  28.0 32.0
18.5 26.0  28.0 32.0
19.0 26.5  28.0 32.0
19.5 27.0  28.0 32.0
20.0 27.5  28.0 32.0
20.5 28.0  28.0 32.0
21.0 28.5  32.0 36.0

As you can see (by all the numbers being a multiple of 4), delayed_write_2006_low always goes high at the start of a pixel. It in turn drives both copy_vramaddr_vscroll and copy_vramaddr_hscroll half a pixel later, reloading vramaddr_v in time for the start of the next pixel.

So to get from the time of the $2006 write to the time of the v register load, the rule is "add 13 cycles (3.25 pixels) and round down to the nearest multiple of 4 (pixel)". If you don't emulate steps less than a pixel (and why would you) that works out to a three pixel delay from the second $2006 write to the v = t register load.

EDIT: I'm pretty sure that should be 15 cycles = 3.75 pixels. Forgot to account for the time to actually reload v.


Last edited by Rahsennor on Sun Feb 12, 2017 5:29 pm, edited 1 time in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 79 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 4 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