It is currently Mon Oct 23, 2017 4:44 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 30 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: MMC2 question
PostPosted: Fri Nov 11, 2011 3:17 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
wiki wrote:
When the PPU reads from specific tiles in the pattern table during rendering, the MMC2 sets a latch that tells it to use a different 4 KB bank number. This has the effect of setting a different bank for all tiles to the right of a given tile.


Well, does "PPU reads" stand for "reading $2007" or "fetching tiles from the pattern table"?

_________________
Zepper
RockNES developer


Last edited by Zepper on Fri Nov 11, 2011 3:32 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2011 3:28 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19116
Location: NE Indiana, USA (NTSC)
"During rendering" means "fetching tiles from the pattern table". But I'd hazard a guess that the MMC2 looks only at the address bits PA12-PA4, so either rendering or a $2007 readback would trigger it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2011 3:45 pm 
Offline
User avatar

Joined: Wed Dec 06, 2006 8:18 pm
Posts: 2801
You can manually trigger it to switch by reading from the pattern tables with $2007 or if the PPU itself reads the memory. Basically it's all about that memory being read from. If the CPU does it through $2007 or the PPU by rendering, both will make the MMC2/MMC4 bankswitch CHR-ROM.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2011 8:23 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Could someone clarify this thing, please?

Disch' docs wrote:
The swap occurs after the tile is fetched, not before. So if the latch is clear, and tile $FE is loaded,
tile $FE from the first reg (??) will be drawn to the screen, but the next tile drawn will be from the second reg.


What "1st reg" and "2nd reg" ??

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2011 9:29 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
"First reg" is before the swap
"second reg" is after the swap.

For example.... assuming:
- $B000=$00
- $C000=$01
- latch is set so that $B000 is used

When you come across tile $FE, it will be rendered from page $00. The next tile will be rendered from page $01


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2011 11:04 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
I didn't get it. :( Did you mean "latch is set so that $C000 is used"?

I'm trying to remove my working MMC2 "hack":
Code:
      bg_tile = bg_name[attrnum+1];
      if(bg_tile != last_tile)
      {
         if(ppu->bg_pat_table) mmc2_sync_chr(0x1000|(last_tile << 4));
         else mmc2_sync_chr(0x0000|(last_tile << 4));
         last_tile = bg_tile;
      }


Currently, the ring is glitched. It's ok for a few frames, but it glitches.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2011 11:32 am 
Offline
User avatar

Joined: Sat Oct 29, 2005 2:09 am
Posts: 500
Location: Indianapolis
Zepper wrote:

Currently, the ring is glitched. It's ok for a few frames, but it glitches.


When I was debugging MMC2, I hacked things a tad so that the output was highlighted when the second bank was switched in. You might want to do this to see what bank is being switched in during rendering.

Famicom Wars (MMC4, the CHR switching is identical) switches banks many times per frame, and even switches banks for a few characters to render text.

You must use A5 to select which bank you're going to use, and A4-A13 to trigger the switch. The chip looks for 0P 1111 11XX xxxx (from A13 down to A0). Where P is the page#, XX is the XOR of these two bits, and xxxx are don't care bits.

This corresponds to:

Code:

// PPUREAD is true when the PPU has read the CHR data byte
// PPUADD is the 14 bit PPU address you're reading from
// bank0 returns 0/1 depending on which bank you need to use
// bank1 works similar to bank0

if (PPUREAD)
{
    switch(PPUADD & 0x3ff0)
    {
        case 0x0fd0 : bank0 = 0; break;
        case 0x0fe0 : bank0 = 1; break;
        case 0x1fd0 : bank1 = 0; break;
        case 0x1fe0 : bank1 = 1; break;
    }
}





bank0 indicates which of the two banks you must use for PPU addresses 0000-0fff (i.e. mapper register B000 or C000). 0 = B000, 1 = C000

bank1 indicates which of the two banks you must use for PPU addresses 1000-1fff (i.e. mapper register D000 or E000). 0 = D000, 1 = E000

NOTE: you cannot just set the bank inside the case statement. If you do this, it's possible that the game code can select one bank and then clear the screen, select another bank and write graphics without having an FD/FE character. This would result in the wrong bank being displayed, because the game updated the bank # without using switch characters (FD/FE).

_________________
/* this is a comment */


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 15, 2011 12:16 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Quote:
If you do this, it's possible that the game code can select one bank and then clear the screen, select another bank and write graphics without having an FD/FE character. This would result in the wrong bank being displayed, because the game updated the bank # without using switch characters (FD/FE).


Can you elaborate on this? I'm not sure I get what you mean.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 2:11 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Still not clear to me. I did a quick chat on irc about it (with him) and...

1. The PPU fetch a tile.
2. If this tile is $FD or $FE, the mapper "should" look at the PPU address ANDed with 3FF0. In short words, the latches are changed on $1FDx/$1FEx addresses.
3. He suggested to NOT swap banks during rendering in an emulator, basically it's possible "to break" the CHR pointers, of doing something you wouldn't like to do. So, he suggested to swap banks on $C000-$FFFF writes.

I'm out of ideas.

_________________
Zepper
RockNES developer


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 3:17 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Quote:
He suggested to NOT swap banks during rendering in an emulator


Err.. don't you have to? The PPU reads during rendering are what triggers the latch change, which triggers the swap.

It's not that complicated. Here's another example. Given the below situation:

regs:
$C000 = $00
$D000 = $01

latch = $FD (use reg $C000)


Now let's say the PPU has to draw these tiles:

AA FE AA

Events occur as follows:

- PPU fetches lo CHR byte from $0AAx (mapper use bank $00 : $C000)
- PPU fetches hi CHR byte from $0AAx (mapper use bank $00 : $C000)
- PPU fetches lo CHR byte from $0FEx (mapper use bank $00 : $C000)
- PPU fetches hi CHR byte from $0FEx (mapper use bank $00 : $C000)
-- mapper changes latch to $FE, now it will use $D000 instead of $C000 --
- PPU fetches lo CHR byte from $0AAx (mapper use bank $01 : $D000)
- PPU fetches hi CHR byte from $0AAx (mapper use bank $01 : $D000)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 4:48 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Sorry, but I'm not understanding the things. :( Here's the relevant part.

Code:
[23:00] <@kevtris> the mapper specifically looks at the address bus of the PPU and nothing else
[23:00] <@kevtris> it knows a particular tile is being read, because its address is directly related to the tile # (or sprite tile # for that matter)
[23:01] <@kevtris> in both cases it's xTTx  where x is don't care and TT is the tile number.  i.e. 0331h, 0332h,  0339h, 033fh  are all reading tile 33h
[23:01] <@kevtris> each tile is 16 bytes exactly
[23:01] <@kevtris> thus, the lower 4 bits do not matter to the mapper and it does not look at them
[23:02] <@kevtris> that's why I chose 0fd0h  and 0fe0h and 1fd0/1fe0h  on the case statement
01[23:02] <Zepper> but you said "you cannot just set the bank inside the case statement".  That's why i asked you about bankswitching during rendering.
[23:02] <@kevtris> aah that
[23:02] <@kevtris> well that is an emulator caveat
[23:03] <@kevtris> the code I posted will only update bank0/bank1 when tile fd or fe is read
[23:03] <@kevtris> if you do something like this, it will not work:
[23:04] <@kevtris> switch (PPUADD & 0x3ff0)
[23:04] <@kevtris> {
[23:04] <@kevtris> case 0x0fe0 : ppubankhandle = rombanknumber[regc000];
[23:04] <@kevtris> i.e. if you bankswitch via adjusting pointers in the switch/case it will not work right
[23:05] <@kevtris> you adjust pointers in a routine that occurs when a switch happens OR the program writes to c000-ffff


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 7:46 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
I don't know how else to explain it. Maybe pseudocode?

Code:
if( tile_FD_was_just_drawn )
{
  latch = false;
  Sync();
}
else if( tile_FE_was_just_drawn )
{
  latch = true;
  Sync();
}

//...

void Sync()
{
  if(latch)
    SwapCHR( reg_D000 );
  else
    SwapCHR( reg_C000 );
}


Tiles FD and FE switch the latch so that the other CHR reg is used. Effectively causing CHR to automatically swap during rendering.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 7:53 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
The ring and the boxer (not Mac) are glitched. Everything else is fine.
Image

The "PPU address" here (to set up latches/swap chr) is 2000_bg_pattern | (bg_fetched_tile << 4).
My gfx engine never touches the real PPU address, like incrementing or decrementing it on rendering.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 16, 2011 9:07 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Can you post some code?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 17, 2011 7:33 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
It's possible that the game switches CHR banks during cycles 256~340. I'm still tracing my logs. From a preliminary analysis, the ring uses the high latch = 0, but the emu sets to 1, breaking the ring gfx banks.

_________________
Zepper
RockNES developer


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot] and 10 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