Bit toggling detection (blargg mmc3 tests)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Bit toggling detection (blargg mmc3 tests)
by on (#95283)
I know, i know it's not an Emulator question, but i just wanted to know how to detect when a bit toggles in a variable in C.
I think i'm doing it well, but i wanted to know how YOU do it.
I have googled it you know, but i haven't found good info.

I ask since blarrg's mmc3 test rely in bit toggling at $2006.

Thxs

by on (#95286)
Code:
bit_changed = (old ^ new) & bitmask;
new_bit_value = new & bitmask;

by on (#95288)
Code:
bit_changed = (old ^ new) & bitmask;
new_bit_value = new & bitmask;


Sorry for being to noob. I really don't get it :oops:
Shouldn't "old" be updated?
why "new_bit_value".
I think i need a programming class here.
Could you be more verbose?

by on (#95289)
"old" is the previous value of the variable.
"new" is what you'll be setting the value to.
"bit_changed" is zero if the bit is the same, or nonzero if the bit has changed. You get this from XORing old and new, then masking with the bit mask.
"bitmask" is a variable that contains a single bit set somewhere. So if you want to look at bit 8, that's a value of 256, or (1 << 8).

So when you want to see if a variable has changed or not, you put in checking code every time you write to the variable.


But anyway, checking for PPU A12 changes is different, since PPU A12 changes all the time during rendering. The example code is a generic version of checking when a bit changes in a variable. In order for that kind of example code to work, you need to write your PPU code to work like Nintendulator's, where it actually sets a variable for the physical PPU address bus (different from the "PPU address value" from 2006) every time it does a fetch.

by on (#95290)
Your function could look something like this:
Code:
void update_vram_address(unsigned int new_value)
{
  unsigned int old_value = vram_address;
  vram_address = new_value;
  if ((old_value ^ new_value) & 0x1000)
  {
    // A12 changed!
    bool new_a12_state = new & bitmask;
    a12_changed_to(new_a12_state);
  }
}

but as Dwedit says, you will have to call that function every time the VRAM address changes, i.e. before every memory fetch during rendering and whenever the $2006/$2007 registers are used.

by on (#95301)
I simply gave up about predicting the A12 state for MMC3. I'm rewriting my gfx engine.

by on (#95343)
Thanks much clear now, but i think i will not be predicting A12 line.
It's simply very hard (so Zepper don't feel bad :) ).

Wich is the simplest way to implement mmc3 clocking without predicting A12 state??

What im currently doing is clocking the counter at cc 256 including scanline -1, it doesn't work the best but it's a solution for me.