It is currently Sat Sep 23, 2017 7:32 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
PostPosted: Sat Aug 05, 2017 1:12 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
Yes, there are no single cycle instructions, but you never have to wait a single cycle. The amount of time to wait can be an even or an odd number of cycles though, so in order to wait 3 more pixels you can, for example, replace a NOP (2 cycles) for a BIT $ff (3 cycles), and you'll effectively have waited 1 more cycle. As long as the minimum padding is 2 cycles, you can increase it in single cycle increments.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 1:48 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
Ha. That's funny. I didn't realize NOP was actually an instruction. I just thought it was an abbreviation for a family of potential operations that acted as null. This is where having studied computer science probably would've paid off! haha

And...whoa! After counting cycles (and understanding how that works) and doing the math on the scroll...........

Attachment:
Whoa.png
Whoa.png [ 3.49 KiB | Viewed 301 times ]


Eureka! The brown text is the same palette spot as the pink text above. Obviously, this is just a dummy - and that is a dummy sprite compared to the one I would use...but...ha! YES! And in context, that single black line at the bottom of the menu bar would be a complete non-issue :-)

You guys are awesome. The real question is...do I want to go into the REAL game, start futzing with my object drawing routines (starting them all at 0204), find all my sprite-blanking routines, add the checks for nt and sprite0 being drawn, and add this to an already crowded NMI..........

Hmmmmm......still though, very cool to *get* this. As always, you guys rock. Thank you for your constant feedback and unparalleled patience :-)


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 2:13 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5643
Location: Canada
JoeGtake2 wrote:
I didn't realize NOP was actually an instruction.

Every CPU I've learned machine code for has had an offical NOP instruction (may or may not have that specific name, though). They're very useful in a lot of cases, not just delay, but for example patching an executable either temporarily for debugging or to fix something without having to or being able to recompile from source, etc.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 4:04 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
JoeGtake2 wrote:
And...whoa!

Nice, it's finally working!

Just one more thing: if you do decide to put this in an actual game that will be released, be sure to test on real hardware! Fiddling with the PPU mid-frame is one of the hardest things to time right, and several emulators get it wrong (FCEUX for example, despite being an *awesome* development tool, is notoriously bad at replicating these minute timing aspects of the PPU).

Oh, another thing: as discovered semi-recently, disabling rendering mid-frame can corrupt the OAM *once rendering is enabled again* (so even if you do a sprite DMA while rendering is off, they will still get corrupted), so you should either understand the technical reasons why this happens and avoid the specific situations that cause this (I still haven't fully understood this!) or keep sprites sprites disabled (i.e. masked) after the split to hide any possible sprite glitching for the remaining of the frame. AFAIK, no emulators will replicate this behavior, so again, testing on hardware is highly recommended.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 6:17 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
Yeah, my order of operations for tomorrow is:

1) flash this to cart, test it on my top loader. If it works...
2) Iterate the actual game in its current form and spend likely the whole day moving some memory around, cleaning up my NMI to make it a bit more economical, tracking down places that would write to 0200, making contingency cases for when sprites might not be drawn...etc...hopefully get it working...
3) Get it looking good (right sprite in the right place with background...maybe even prioritized behind...so as not to be just some anomalous sprite dangling there)
4) flash to cart and test again on hardware.

If, after a good 10 hour day tomorrow it's not working right, I just might jettison it, but at least now thanks to you guys here I have an accurate record of how I got it working, and *get* how I got it working (and how to adjust accordingly to get it working again.

I didn't quite get your meaning on the last point. You're saying that this could corrupt any sprite draws that follow this during that frame? Because obviously, using this as a top menu bar...that would mean...*all* other sprites in the gameplay area. Is this what you mean?

Also, would you suggest an emulator that supports mapper 30 that might be a good second-check? I have a lot of other emus, but none that support mapper 30, which is why I've relied on a thing Shiru built for us for SUPER birds eye view quick proto, FCEUX to get closer and debug, and then hardware as a final look. It might be good to have another intermediary.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 6:57 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
JoeGtake2 wrote:
I didn't quite get your meaning on the last point. You're saying that this could corrupt any sprite draws that follow this during that frame?

Yup. There's this nasty thing about the OAM that if you turn rendering off at certain points of the scanline, it starts overwriting OAM data when you turn rendering back on, be it on the same frame or the next, regardless of what you do while rendering is off... tepples discovered this when he was turning rendering off early to increase VRAM bandwidth and observed flickering sprites on the next frame.

Quote:
Because obviously, using this as a top menu bar...that would mean...*all* other sprites in the gameplay area. Is this what you mean?

In this case, you better read up about the glitch and how to avoid it: viewtopic.php?t=4647

From memory, you have to keep the number of sprites in the scanline where rendering is turned off to a minimum (ideally zero, but you obviously need at least one for the hit) and turn rendering off as late as possible but still before hblank (i.e. x <= 255), but don't quote me on that.

Quote:
Also, would you suggest an emulator that supports mapper 30 that might be a good second-check?

I'm not familiar with mapper 30 at all, so I really don't know. Hopefully someone else can help you with this.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:18 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6178
Location: Seattle
JoeGtake2 wrote:
Also, would you suggest an emulator that supports mapper 30 that might be a good second-check? I have a lot of other emus, but none that support mapper 30, which is why I've relied on a thing Shiru built for us for SUPER birds eye view quick proto, FCEUX to get closer and debug, and then hardware as a final look. It might be good to have another intermediary.
Mapper 30 is just UNROM with 2 additional optional things:
1- CHR-RAM bankswitching
2- self-flash capability

Caitsith2 had added support to FCEUX as of april 2014, so modern releases should have it...
Mesen doesn't have self-flashing but does support CHR-RAM bankswitching.
I don't think the previous generation of best-in-breed emulators are supported enough to have it.

But if you're not relying on those two behaviors, you should be able to just run it as mapper 2 for testing.


Last edited by lidnariq on Sat Aug 05, 2017 7:19 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:18 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5643
Location: Canada
tokumaru wrote:
In this case, you better read up about the glitch and how to avoid it: http://forums.nesdev.com/viewtopic.php?t=4647

From memory, you have to keep the number of sprites in the scanline where rendering is turned off to a minimum (ideally zero, but you obviously need at least one for the hit) and turn rendering off as late as possible but still before hblank (i.e. x <= 255), but don't quote me on that.

It's not as bad as that, I think? Just turn rendering off (i.e. write $2001) after pixel 192 240 on a scanline and you should be fine, unless I'm mistaken. This is easy to time if you're already trying to set up an hblank timing.

Reference: https://wiki.nesdev.com/w/index.php/Errata#OAM_and_Sprites

(Edit: corrected 192 to 240, and additional note moved below.)


Last edited by rainwarrior on Sat Aug 05, 2017 7:44 pm, edited 3 times in total.

Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:25 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 254
Annnnnd first step = a failure. You are correct. On hardware, I had the glitch that tells me timing was, indeed, off. Drat. Curses. Foiled.

Attachment:
IMG_2910.JPG
IMG_2910.JPG [ 1.15 MiB | Viewed 267 times ]


I'd imagine this would be a fairly obnoxious series of trial and erroring to get exactly right (changing values, flashing, testing...rinse, repeat)...then the time it would take to modify the code...then the potential for the sprite flickering issue...maaaaaaaybe it's not so big a deal. At least I figured it out on a conceptual level.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:33 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5643
Location: Canada
(Continued from above...)

FWIW, there are only very few games that actually do mid-screen palette changes, and I don't think any of them use sprites below the palette change

Actually, come to think of it, you may have to turn rendering back on later than pixel 192 240 as well to keep from coming online mid-evaluation too (though you might as well do it in hblank for cleanliness?)... since sprite evaluation is buffered for one line also, I am not sure if you'll get 1 line of pre-split sprites in your buffer still when you resume rendering... you could turn on background but hide sprites for one line just to flush it if that's the case... can't recall if this is really an issue though? (It's been a while since I tried it.)

JoeGtake2 wrote:
Annnnnd first step = a failure. You are correct. On hardware, I had the glitch that tells me timing was, indeed, off. Drat. Curses. Foiled.

I'd imagine this would be a fairly obnoxious series of trial and erroring to get exactly right (changing values, flashing, testing...rinse, repeat)...then the time it would take to modify the code...then the potential for the sprite flickering issue...maaaaaaaybe it's not so big a deal. At least I figured it out on a conceptual level.

If you are using FCEUX, use the "new PPU" setting if you're not but... I don't think it's really quite adequate for this kind of timing.

Nintendulator has given very good/close results in my experience with this, not sure if it's 100% but it's as good as I've seen when comparing.

I would strongly suggest that you step through the code in Nintendulator and pay very particular attention to what pixel of the scanline the writes are taking place. Make sure it's within the hblank pixel range, and try to leave a margin for error on both sides. (Measure it many times, there is going to be jitter of several pixels from your BIT loop too, pushing it back and forth, make sure you find both the low and high range of this jitter for the write timing!)


One other thing you may notice on hardware is that the NTSC PPU's "hblank" area isn't entirely blank, the image starts and ends early so often "in hblank" effects like this can still be seen at the edge of the picture (some TVs or capture device will show more of this than others).


Last edited by rainwarrior on Sat Aug 05, 2017 7:43 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:39 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
rainwarrior wrote:
It's not as bad as that, I think? Just turn rendering off (i.e. write $2001) after pixel 192 on a scanline and you should be fine, unless I'm mistaken.

The wiki says "x=192 for lines with no sprites, x=240 for lines with at least one sprite", and while he could trigger the sprite 0 hit using the bottom row of the sprite to avoid evaluating it on the scanline where rendering is turned off, this is for a status bar at the top of the screen, so there may be sprites scrolling from/to the top of the screen and crossing the boundary of status bar, where rendering is turned off.

JoeGtake2 wrote:
Annnnnd first step = a failure.

Yeah, raster effects can be annoying like that to code. I've had a lot of headaches with these kinds of glitches in the past (don't be surprised if you get it to look right on hardware and then it looks wrong on emulators!), enough for me to give up on anything that turns rendering off/on mid-frame. I'll still do tamer raster effects, such as scroll changes or anything that doesn't interfere with the PU's work (color emphasis, grayscale, bankswitching, etc.) because the timing constraints aren't so severe in those cases.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:42 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5643
Location: Canada
tokumaru wrote:
The wiki says "x=192 for lines with no sprites, x=240 for lines with at least one sprite"

Pardon that omission, was working from memory and was only skimming the reference I provded. I thought the margin was wider. :( So yeah, 240 not 192.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 7:47 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
rainwarrior wrote:
Nintendulator has given very good/close results in my experience with this, not sure if it's 100% but it's as good as I've seen when comparing.

A few years back when I was experimenting with sensitive timing like this, Nestopia always gave me the closest results compared to what I saw on real hardware, but unfortunately it didn't have any debugging features at all. Nintendulator was pretty close too. I can't vouch for any of the more current emulators, because I haven't done this kind of testing in a while.


Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 8:18 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5643
Location: Canada
Yeah, what I'm vouching most for is Nintendulator's debugger's pixel timing feature. Like, don't try and do it by just visual output alone, get your writes timed within its hblank (which you can only verify the specific timing of in the debugger). If you get them centred in that range (hopefully with a little bit of padding on both ends), that has the best chance of transferring to hardware correctly.

A visual test alone is not good enough. "This appears to work on FCEUX/Nestopia/Nintendulator/etc." has far less chance of transferring correctly to hardware than something you've intentionally designed to fit in the centre of a range of timing tolerance.


Also, jitter is important to account for too. The BIT/BEQ loop is 7 cycles, so that's 21 pixels your timing is going to move back or forth. Make sure you verify/measure this and account for it. Centre your timings based on the middle of this range, and choose your margins to accommodate this range. (If you do LESS stuff per hblank you can have a bigger margin, too.)

edit: corrected another mistake


Last edited by rainwarrior on Sat Aug 05, 2017 8:53 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Sat Aug 05, 2017 8:47 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10012
Location: Rio de Janeiro - Brazil
rainwarrior wrote:
Yeah, what I'm vouching most for is Nintendulator's debugger's pixel timing feature. Like, don't try and do it by just visual output alone

The problem is that a pixel timing feature doesn't mean much if the visual output doesn't match what the hardware shows. It's not that Nintendulator is way off, so it's debugging features are indeed *very* useful, but in my old tests, Nestopia consistently outperformed Nintendulator for tiny timing issues like this, even if not by much, so I thought I'd mention it.

Quote:
The BIT/BEQ loop is 6 cycles

7 cycles actually, since the branch is continuously taken while waiting for the hit, so 21 pixels. But yes, it's very important that you account for this jitter.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: zzo38 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