It is currently Mon Dec 18, 2017 12:16 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Wed Aug 02, 2017 1:28 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
When writing data to PPUADDR, we need to reset the high/low latch by writing LDA PPUSTATUS first.

Now, I've also seen the version BIT PPUSTATUS.

So, I have three questions:

1. Is there any advantage of using BIT over using LDA?

2. And can both versions be used for both, PPUADDR and PPUSCROLL?

3. Are there other PPU addresses where I have to reset the high/low latch by using PPUSTATUS? Or are PPUADDR and PPUSCROLL the only ones?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 1:44 pm 
Offline

Joined: Mon Nov 10, 2008 3:09 pm
Posts: 431
DRW wrote:
When writing data to PPUADDR, we need to reset the high/low latch by writing LDA PPUSTATUS first.

Now, I've also seen the version BIT PPUSTATUS.

So, I have three questions:

1. Is there any advantage of using BIT over using LDA?


Using BIT preserves the previous contents of A.

Quote:
2. And can both versions be used for both, PPUADDR and PPUSCROLL?


Yes, the effect on the PPU is identical with either instruction. Both instructions do a read from memory, the difference is whether they put the data into A or not.

Quote:
3. Are there other PPU addresses where I have to reset the high/low latch by using PPUSTATUS? Or are PPUADDR and PPUSCROLL the only ones?


PPUADDR and PPUSCROLL are the only write-twice registers that have a high/low latch.


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 1:49 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
Thanks for the information.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 3:09 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
The other thing BIT does that LDA doesn't is it reads bit 6 (sprite 0 hit) into the V (overflow) flag, so for sprite 0 hit testing it's usually the best choice.

For bit 7 (vblank) both LDA and BIT put it in the N (sign) flag, so both are equally good unless you want to preserve A.

For bit 5 (sprite overflow) there's no convenient flag load. The best choice here is BIT, but after loading A with %00100000. (Because BIT does an AND operation without destroying A you can keep testing it in a loop.)


BIT's non-destructive AND is also useful for combination tests, e.g. if you want to test for sprite 0 and vblank together (for backup in case the hit fails unexpectedly?), you can load A with %11000000 and do a BIT test loop. (Take note: BIT's AND only updates the Z flag, the N/V flags are loaded directly from $2002 and not part of the AND operation.)


I just have a habit of using BIT with that register even if I don't need to preserve A. There's just such a strong correlation in practice between BIT and $2002 on the NES, it feels like the "natural" way to read it. (BIT does have some other uses, but they're relatively rare compared to seeing it as a $2002 read.)


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 4:41 pm 
Offline

Joined: Mon Jul 03, 2017 4:37 pm
Posts: 101
Yes, BIT was literally designed for situations, like this.

-Thom


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 5:34 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 934
Location: Sweden
I see why BIT can be used to get bit 6 and 7, but I don't get why LDA misses bit 5 and 6?


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 5:47 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
Pokun wrote:
I see why BIT can be used to get bit 6 and 7, but I don't get why LDA misses bit 5 and 6?

tschak909 sort of answered that:
tschak909 wrote:
BIT was literally designed for situations, like this.

The purpose of BIT is to use A as an AND mask to test an arbitrary bit (or any 8-bit mask) from a memory location. As an added bonus, it also has a direct fetch of bits 6 and 7 so that they could be used even more easily without having to prepare A. (I wonder if they were greedy enough whether they could have used the carry flag as well?)

LDA on the other hand is a general purpose load instruction. It only sets a minimum number of flags (zero flag and sign flag) becauase it needs to be unobtrusive. LDA gets interleaved with other instructions; think about how a 16-bit addition needs to have LDA in between two ADC instructions, etc. They weren't going to cram in extra "free bit test" stuff into assorted flags, that's very specific to BIT.


Top
 Profile  
 
PostPosted: Wed Aug 02, 2017 6:00 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10172
Location: Rio de Janeiro - Brazil
Just wanted to point out that, from my own experience, that you don't *have* to reset the $2005/6 latch all the time, as long as your code is well behaved and never does any stray $2005/6 accesses. Clearing the latch can be seen as a safety measure, so if you feel more comfortable doing it, that's fine, but you don't *need* to do it. I never do it and never had any problems, and a lot of commercial games I debugged don't do it either.


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 12:26 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
tokumaru wrote:
Just wanted to point out that, from my own experience, that you don't *have* to reset the $2005/6 latch all the time, as long as your code is well behaved and never does any stray $2005/6 accesses.

That's exactly the reason why "City Trouble" still works despite me not using it for scrolling.

But here's a question: What if you don't use the latch and someone presses the reset button exactly between two STA PPUADDR? Wouldn't the following game be misaligned until you power it off?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 12:52 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
DRW wrote:
But here's a question: What if you don't use the latch and someone presses the reset button exactly between two STA PPUADDR? Wouldn't the following game be misaligned until you power it off?

Yes, you must clear it once on startup, at the very least.

Though standard startup also polls $2002 for two frames to wait for the PPU to warm up anyway, so you've probably already cleared the latch doing that.


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 12:56 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10172
Location: Rio de Janeiro - Brazil
DRW wrote:
What if you don't use the latch and someone presses the reset button exactly between two STA PPUADDR? Wouldn't the following game be misaligned until you power it off?

The correct reset procedure requires you to wait a few frames for the PPU to initialize, and during this time we usually count frames by reading $2002 repeatedly and checking the vblank flag, so the latch is guaranteed to be cleared after resets.

EDIT: Like rainwarrior said.


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 1:06 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
Oh, right: BIT PPUSTATUS in the wait for vblank function. I forgot about that.

Does anybody know of any other possible conceivable situation where the stuff can somehow misalign, even if I always read or write PPUADDR and PPUSCROLL in pairs?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 1:14 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
I think it's perfectly good practice to clear the latch at the start of an NMI handler's upload session, or when you're about to load a nametable, etc.

You don't strictly have to, but a few bytes/cycles of redundant latch clears in your game could make the difference between a latent bug that causes a hard fail vs. one that the program can recover from. I actually think they're worth putting in, personally.

There are a lot of ways bugs can arise that end up being completely benign with just a little bit of redundant code. Looking back at some code you shipped later on and thinking "that shouldn't have worked?", and then you realize that extra little bit of protection you'd written that you didn't expect to matter was actually doing its job. I've seen that enough times to think it's worth doing.


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 1:22 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
O.k., I'll keep it then.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Thu Aug 03, 2017 1:58 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10172
Location: Rio de Janeiro - Brazil
BTW, about a year ago I found out I could slightly abuse the way the high/low latch and $2005/6 writes work in order to speed up the updating of columns in the attribute tables in one of my engines: Change only low byte of VRAM address (good for attributes)

rainwarrior wrote:
I think it's perfectly good practice to clear the latch at the start of an NMI handler's upload session, or when you're about to load a nametable, etc.

I'm not strongly against clearing the latch as a safety measure, just like I'm not against clearing all RAM during reset as a safety measure, but when done during development, these procedures could end up hiding bugs that'd be easy to catch otherwise. You should NOT have stray writes to $2005/6 in your game, ever, but how will you detect these bugs if you're clearing the latch left and right?

Quote:
You don't strictly have to, but a few bytes/cycles of redundant latch clears in your game could make the difference between a latent bug that causes a hard fail vs. one that the program can recover from. I actually think they're worth putting in, personally.

My advice is, by all means, cover your ass by clearing whatever you can as much and as often as it takes for you to feel comfortable, but save such safety measures for the end of development, because while having bugs manifest themselves in the final product is a BAD thing, having them manifesting themselves during development is a GOOD thing.

Anyway, the reason I don't personally clear the latch is because I always find myself in situations where every cycle matters. I try to code my systems to be as dynamic as possible, and after the overhead of switching banks and deciding it does indeed have to process VRAM updates, my vblank handlers only have so much time left for the actual updates. The updates are scheduled dynamically according to the available time, and there are a few of them that I absolutely need to happen in the same frame, such as a row and a column of metatiles when the screen scrolls diagonally. I kid you not, the 4 cycles taken by a BIT $2002 were preventing me from fitting those 2 updates together. Between refactoring the more complex systems in hopes of shaving those cycles off from somewhere else or just removing the BIT $2002, the choice was easy. Ever since that happened, it has always made more sense to me to claim those 4 cycles as useful vram update time than using them for a safety measure I probably won't ever need. I guess I could clear the latch *after* the vram updates, but... meh.


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

All times are UTC - 7 hours


Who is online

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