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

All times are UTC - 7 hours





Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Sun Aug 06, 2017 1:08 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5710
Location: Canada
When discussing trying to do a palette swap in hblank in this thread, I had a thought that a visual test could help calibrate timings for emulators.

I wrote this very quick/simple visual test as a very rough start. This generates a sprite 0 hit, waits a configurable number of cycles, then writes $2001 to set the greyscale flag, giving a visual indication of where that occurs. This is intended to give a rough estimate of where emulators think the horizontal blank is, and maybe try to shed some light on the question "how much can I trust an emulator with hblank timing?

In this initial rough test, I determined where the first and last "off-screen" delay settings appear:
Code:
My NES/Famicom: $13-$29
FCEUX New PPU:  $10-$28
Nintendulator:  $12-$28
nestopia:       $13-$28

Note: on my NES and Famicom the change is clearly visible in the areas to the left and right of the picture, i.e. I can see about 8 pixels to the left and 5 pixels to the right of the rendered picture on my TV, so at delays adjacent to the ones stated I can still see the visual change, but they're off the edge of the picture an emulator would display.

So, I mean this is hopeful looking at least. In general emulators seem to agree where the end of hblank is relative to a sprite 0 hit, at least at the CPU cycle granularity. I think Nestopia and Nintendulator are very close to each other, like maybe 1 pixel different at either end, and both seem to show the change about 2 pixels later than my NES. (The CPU cycle counts above exaggerate the difference slightly, but I'm not sure how accurately I can measure pixels visually on my TV at the moment.)

FCEUX's New PPU has an 8-pixel granularity on its rendering, so I think that mostly accounts for the difference in its low delay value (i.e. the appearance of the write is delayed up to 8 pixels anyway, 2.6 cycles).

My NES and Famicom appear to be consistent with each other.

In the debuggers, however, the FCEUX's "pixel" value seems to be about 25 higher than Nintendulator's "tick" value, and I don't know why. I'm not sure if this is just a different numbering convention or what... will have to investigate.


So that's just one quick test trying to see if there's much variability between emulators. It could easily be adapted to investigate whether the timing consequences of other effects diverge, scroll changes, palette changes, etc. (i.e. things which may have their specific timings emulated differently) the source is included if you want to modify it for different tests.


Attachments:
hblank_test.zip [5.12 KiB]
Downloaded 34 times
Top
 Profile  
 
PostPosted: Sun Aug 06, 2017 5:14 am 
Offline

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 285
Thanks for making this!

Mesen displays no glitch between $14 and $29. $13 & $2A have a pixel or 2 flashing.
This test is affected by the logic Mesen/Bizhawk implement related to the grayscale bit, though.
According to Alyosha and other people's findings, the effect of the grayscale bit is delayed by 2 pixels (link)

So changing that delay to 1 pixel, for example, will make Mesen display the glitch between $13 & $28 (but results in a less accurate result for demo_ntsc, which Nestopia/Nintendulator both fail, iirc).

Other emulators:
puNES: $12-$28
MyNes (the emulator): $12-$28
Nintaco: $13-$28
Bizhawk: $14-$29

So I guess no emulator gets its exactly the same as your NES, but most of them are pretty close.
Assuming the other emus don't implement the 2-cycle delay (and assuming the NES actually has this delay) and adjusting for it:
NES: $13-$29
Bizhawk/Mesen: $14-$29
puNES/MyNes/Nintendulator: $14-$2A
Nintaco/Nestopia: $15-$2A
FCEUX: $12-$2A


Top
 Profile  
 
PostPosted: Sun Aug 06, 2017 6:35 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
*ahem*

RockNES: $12-$28.


Top
 Profile  
 
PostPosted: Sun Aug 06, 2017 8:45 am 
Offline

Joined: Wed Jun 15, 2016 11:49 am
Posts: 44
Oh cool another test using the black / white flag. It would be good to nail down the exact behaviour here. I really don't see any way the nmi_sync test can work without some kind of delay involved with this flag, whether in latching the write or in applying the correction somewhere later in the rendering pipeline.

Hopefully this can shed some light on it.


Top
 Profile  
 
PostPosted: Sun Aug 06, 2017 12:56 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5710
Location: Canada
Well, really the test should be measured in pixels not CPU cycles. The point of my using CPU cycles was to estimate how much range software has for getting this correct. A rig for testing how many cycles you can push your code back or forth until it will break.

If you're trying to tune an emulator, you'll want to measure exactly how many pixels and compare to an NES. This was proving difficult to measure on my TV though for the moment, the signal quality made it hard to tell. Probably there's a better choice of background image to compare against I could make here to help...

Also, maybe I should allow moving the sprite as well. You could get pixel resolution instead of cycle resolution...


Top
 Profile  
 
PostPosted: Mon Aug 07, 2017 3:04 pm 
Offline

Joined: Wed Jun 15, 2016 11:49 am
Posts: 44
rainwarrior wrote:
Well, really the test should be measured in pixels not CPU cycles. The point of my using CPU cycles was to estimate how much range software has for getting this correct. A rig for testing how many cycles you can push your code back or forth until it will break.

If you're trying to tune an emulator, you'll want to measure exactly how many pixels and compare to an NES. This was proving difficult to measure on my TV though for the moment, the signal quality made it hard to tell. Probably there's a better choice of background image to compare against I could make here to help...

Also, maybe I should allow moving the sprite as well. You could get pixel resolution instead of cycle resolution...


Also it would be cool to be able to check the timing relative to other similar PPU signals, like BG enable/disable. For example if on one scanline you enable greyscale and exactly one scanline later you disable BG, then it would be obvious if there was any relative delay between the two. Just an idea.


Top
 Profile  
 
PostPosted: Mon Aug 07, 2017 4:31 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
Alyosha_TAS wrote:
For example if on one scanline you enable greyscale and exactly one scanline later you disable BG

Problem is that there's no way to do something "exactly one scanline later", since a scanline doesn't have a whole number of CPU cycles (NTSC = 341 / 3 = 113.666... PAL = 341 / 3.2 = 106,5625). So I guess that the best you can do in NTSC is "exactly 3 scanlines later", and "exactly 16 scanlines later" in PAL.


Top
 Profile  
 
PostPosted: Mon Aug 07, 2017 4:58 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
tokumaru wrote:
Alyosha_TAS wrote:
For example if on one scanline you enable greyscale and exactly one scanline later you disable BG

Problem is that there's no way to do something "exactly one scanline later", since a scanline doesn't have a whole number of CPU cycles (NTSC = 341 / 3 = 113.666... PAL = 341 / 3.2 = 106,5625). So I guess that the best you can do in NTSC is "exactly 3 scanlines later", and "exactly 16 scanlines later" in PAL.

...and blargg never did that on his tests?


Top
 Profile  
 
PostPosted: Mon Aug 07, 2017 5:14 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
Zepper wrote:
...and blargg never did that on his tests?

Even on blargg's demos the effects shift 1 or 2 pixels horizontally from scanline to scanline. It's mathematically impossible to trigger something on the exact same pixel on consecutive scanlines, because CPU would have to wait a fractional number of cycles, which is just not possible.

Just look at blargg's full palette demo... the boundaries between colors are slightly jittery, and only align vertically every 3 scanlines, because that's how long it takes to realign the CPU and the PPU. Not only that, but the number of CPU cycles in a frame is also not a whole number, so the jittery boundaries change position from frame to frame. Brargg got as close as possible to a straight vertical line, it's mathematically impossible to do any better.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 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