MMC3 A12 tracking

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

MMC3 A12 tracking

Post by Anes »

Please be patient with me. It's the first time i try to do this. I know it's a difficult thing to accomplish, so i'm asking for help.
I'm trying to catch A12 0->1 and clocking the MMC3 IRQ counter.

I pass all MMC3 blargg's test execpt the timing for scanline 0, which throughs me "too soon".

My IRQ counter routine is this:

Code: Select all

void ClockIRQCounter(Cpu * cpu)
{
	if (irq_counter == 0 || irq_reload)
	{
		irq_counter = irq_latch;
		irq_reload = 0;
	}
	else
		irq_counter--;
	if (irq_counter == 0 && !irq_disable)
		cpu->SetIRQ(true);
}
I suppoouse it's right.

Then, to track A12 0->1 i do this:

Code: Select all

void update_vram_address(u16 new_value, Cpu * cpu)
{
	if ((old_value ^ new_value) & 0x1000)
	{
		if (new_value & 0x1000))			//if A12 0->1
			ClockIRQCounter(cpu);		//Clocks the acual irq counter routine
		old_value = new_value;
	}
}
This is the important one, i don't know what i'm doing wrong.
I have deuggged the code, some games work fine like SMB3, TMNT2, Double Dragon 2 and 3,
but some games don't. For example Flinstons, Rescue.. etc, and Jetsons. The lower "satus bar" shakes,not too much, but it does it.

Of course i know, Flinstons and Jetson use 16 height sprites, so the PT are supposed to change, but it doesn't.

We know that the when PPU fetches background does this like this:

-------------------------------------------------------------------------------------------
Cycle 0: Request NT addr
Cycle 1: Fetch NT -> Call update_vram_address
Cycle 2: Request AT addr
Cycle 4: Fetch AT Call update_vram_address
Cycle 5: Request PT addr
Cycle 6: Fetch PT 1 byte Call update_vram_address
Cycle 7: PT addr |= 0x08
Cycle 8: Fetch PT 2 byte Call update_vram_address and fill latches
-------------------------------------------------------------------------------------------

Ok, i have debugged and tested, but it still has errors.

I ask please if someone looks somthing wrong, tell me.
ANes
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes »

No help?? Chryst!!
ANes
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC3 A12 tracking

Post by Ben Boldt »

I think it is actually a difficult question to answer -- scanline counters are notoriously complicated and confusing. I wish I could help. Have you looked at the wiki?

https://wiki.nesdev.com/w/index.php/MMC3#IRQ_Specifics

Inevitably you will figure this out and it would be much appreciated if you added notes/clarifications about your stumbling blocks back into the wiki.
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes »

Oh!! The Pink Floyd's Dark Side of the Moon With Zelda!! That's ok :D Two epic things.

Yeah i have checked the wiki so many times. I tought that changing my CPU emulation cycle by cycle would help.
As you said is very confusing. I would like to do something like Messen did, but i cant.

Then if i take "Fixed values" of MMC3 irq counter clocking according to PT BG, Sprites BG and Size it works (said cc 260 and 324) the lower bottom bars stop shaking.
But predecting A12 it's some thing i would want to do.
If not i will forget about predicting A12 changes and use the fixed values altought it doesnt quite right
ANes
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper »

ANES, do you use ICQ? let's chat! 12292568

1. Well, most games rely on sprite fetching at PPU cycle 260. In other words, when sprite tiles are fetched from PPU $1000, so MMC3 IRQ should be clocked.
2. You must put a check on $2006 writes, watching PPU address.
3. When you get a raise 0->1, there's a small delay before it goes 0->1 again, around 5~8 PPU cycles.
Here's my code. It covers both MMC3A and B variants, so perhaps you can modify the code & ignore the MMC.irq_alt stuff.

Code: Select all

//ppuflag is the PPU address ANDed with $1000, or formerly loopy_v & 0x1000
static void irq_mmc3_clock(unsigned int scanline,unsigned int ppuflag)
{
   if(irq_latency > 0)
      irq_latency--;

   if(!irq_latency && ppuflag) {
      int old_counter = MMC.irq_counter;
      //valid clock, do stuff
      if((0 == MMC.irq_counter) || MMC.irq_reset)
         MMC.irq_counter = MMC.irq_latch;
      else MMC.irq_counter--;
      //check IRQ triggering.
      if((!MMC.irq_alt || (old_counter > 0) || MMC.irq_reset) && (0 == MMC.irq_counter) && MMC.irq_flag)
         cpu_irqtrigger(TIRQ_MPR);
      MMC.irq_reset = 0;
   }
   if(ppuflag)
      irq_latency = 8;
}
Last edited by Zepper on Wed Mar 24, 2021 7:07 am, edited 2 times in total.
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes »

Zepper wrote: Mon Mar 22, 2021 5:53 am ANES, do you use ICQ? let's chat! 12292568

1. Well, most games rely on sprite fetching at PPU cycle 260. In other words, when sprite tiles are fetched from PPU $1000, so MMC3 IRQ should be clocked.
2. You must put a check on $2006 writes, watching PPU address.
3. When you get a raise 0->1, there's a small delay before it goes 0->1 again, around 5~8 PPU cycles.
Here's my code. It covers both MMC3A and B variants, so perhaps you can modify the code & ignore the MMC.irq_alt stuff.

Code: Select all

static void irq_mmc3_clock(unsigned int scanline,unsigned int ppuflag)
{
   if(irq_latency > 0)
      irq_latency--;

   if(!irq_latency && ppuflag) {
      int old_counter = MMC.irq_counter;
      //valid clock, do stuff
      if((0 == MMC.irq_counter) || MMC.irq_reset)
         MMC.irq_counter = MMC.irq_latch;
      else MMC.irq_counter--;
      //check IRQ triggering.
      if((!MMC.irq_alt || (old_counter > 0) || MMC.irq_reset) && (0 == MMC.irq_counter) && MMC.irq_flag)
         cpu_irqtrigger(TIRQ_MPR);
      MMC.irq_reset = 0;
   }
   if(ppuflag)
      irq_latency = 8;
}
Mmm... i don't get it very well zepper "ppuflag" which flag is it? Do you call the code when sprites and bg are fetched and $2006 writes?
ANes
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper »

ppuflag is the PPU address ANDed with $1000, or formerly loopy_t & 0x1000
User avatar
Anes
Posts: 702
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes »

Ok Zepper, i understand a little more now.
I tested your IRQ clocking and works as idendtical as mine. (Flinstones game bar keeps shaking, for example)
I have a question, i tought that the "check" for A12 should be done in PPU ADDRESS. You are telling me to do it in loopy_t which is the "TEMP" address?
Do you do it to your "TEMP" address?
ANes
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper »

Anes wrote: Tue Mar 23, 2021 8:20 pm Ok Zepper, i understand a little more now.
I tested your IRQ clocking and works as idendtical as mine. (Flinstones game bar keeps shaking, for example)
I have a question, i tought that the "check" for A12 should be done in PPU ADDRESS. You are telling me to do it in loopy_t which is the "TEMP" address?
Do you do it to your "TEMP" address?
My bad. :oops:
It should be loopy_v
Mattiac
Posts: 22
Joined: Sun Jun 16, 2019 7:00 am

Re: MMC3 A12 tracking

Post by Mattiac »

Furrtek-san reverse engineered MMC3C and maybe that can help you, Anes-san? http://github.com/furrtek/VGChips/tree/ ... endo/MMC3C
Post Reply