MMC3 A12 tracking

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

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

MMC3 A12 tracking

Post by Anes » Fri Mar 19, 2021 6:05 pm

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: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes » Sat Mar 20, 2021 8:36 am

No help?? Chryst!!
ANes

User avatar
Ben Boldt
Posts: 785
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: MMC3 A12 tracking

Post by Ben Boldt » Sat Mar 20, 2021 6:18 pm

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: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes » Sat Mar 20, 2021 7:43 pm

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: 3237
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper » 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

//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: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: MMC3 A12 tracking

Post by Anes » Mon Mar 22, 2021 1:17 pm

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: 3237
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper » Tue Mar 23, 2021 6:16 pm

ppuflag is the PPU address ANDed with $1000, or formerly loopy_t & 0x1000

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

Re: MMC3 A12 tracking

Post by Anes » 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?
ANes

User avatar
Zepper
Formerly Fx3
Posts: 3237
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: MMC3 A12 tracking

Post by Zepper » Wed Mar 24, 2021 7:08 am

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 » Thu Apr 08, 2021 5:08 am

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

Post Reply