It is currently Fri Oct 20, 2017 2:46 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 38 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Fri Jun 20, 2014 1:47 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
A couple of months ago I tried implementing MMC1 and I got suck on it for a while, got demotivated, and had a break from the NES. Now I'm trying to get things rolling again and I thought I'd ask about it here.

My MMC1 mapper messes up pretty much every game. My other mappers (0, 2, 3, 7) work perfectly fine as far as I know, so I doubt it's a PPU issue. Most of the games have graphics issues, some games crash due to wrong register reads/writes. I checked the CHR switching a thousand times and compared it to other emulators' MMC1, but it always checks out so I have no clue why this happens. Here are some screenshots:

Abadox

Image

(Crashes on startup due to a read from "register 6" which doesn't exist apparently)


Addams Family

Image

Image

Image

(Scrambled graphics)


Adventures in the Magic Kingdom

Image

(Scrambled graphics)


Dungeon Magic

Image

Image

(Start screen is fine then flickering scrambled graphics)


Mega Man II

Image

Image

(Actually starts fine but then graphics get scrambled)

Some of these games have a fine start screen, others don't. All of them mess up beyond that.

If you want to see more games, please ask. If you want to see the MMC1 source, that's fine too.


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 2:07 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
Since you can get games to start, PRG switching has to be more or less OK. Quite obviously your CHR bankswitching is wrong, so just keep looking. You may find it helpful to render the currently mapped in CHR tiles in another window, then you can very easily compare to other emulators like FCEUX and Nintendulator.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 3:10 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
thefox wrote:
Quite obviously your CHR bankswitching is wrong, so just keep looking.


Code:
    private void setBanks() {
        //4K CHR banks
        if (isSet(control, 4)) {
            switchCHR(4, (chrReg0 & 0x1F) % chrCount, 0);
            switchCHR(4, (chrReg1 & 0x1F) % chrCount, 1);
        } else {
            switchCHR(8, ((chrReg0 & 0x1F) >>> 1) % chrCount, 0);
        }

        if (!isSet(control, 3)) {
            switchPRG(32, ((prgReg & 0xF) >>> 1) % prgCount, 0);
        } else if (!isSet(control, 2)) {
            switchPRG(16, 0, 0);
            switchPRG(16, (prgReg & 0xF) % prgCount, 1);
        } else {
            switchPRG(16, (prgReg & 0xF) % prgCount, 0);
            switchPRG(16, (prgCount - 1) % prgCount, 1);
        }
    }


This is the piece of code I use for switching. Do you know what might be wrong with the CHR parts? The method switchCHR takes the following parameters respectively: the size of the bank in KB, the number of the bank in the cartridge, the position in which it has to be put (char bank 0 or 1).


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 4:28 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
Hard to say. Note that many games like Mega Man 2 use CHR-RAM, so usually they'll use the 8 KB banking mode. Since Mega Man 2 crashes after a while, there could be a bug unrelated to CHR banking as well.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 5:33 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
thefox wrote:
Hard to say. Note that many games like Mega Man 2 use CHR-RAM, so usually they'll use the 8 KB banking mode. Since Mega Man 2 crashes after a while, there could be a bug unrelated to CHR banking as well.


Mega Man 2 never crashes, the graphics are just f'd up. Here's what happens further into the game:

Image

(After pressing start the start/password screen is screwed up)

Image

(After pressing start again the stage pick screen is screwed up)

Image

Image

Image

(Stages are graphically completely messed up but still playable as if the game was running completely normally)

Any ideas? The 4 other mappers work perfectly but this one doesn't at all.


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 6:39 am 
Offline
NESICIDE developer
User avatar

Joined: Mon Oct 13, 2008 7:55 pm
Posts: 1026
Location: Minneapolis, MN
ArsonIzer wrote:
thefox wrote:
Quite obviously your CHR bankswitching is wrong, so just keep looking.


Code:
    private void setBanks() {
...
    }

I'm not sure you need the >>>1 on the 8KB CHR-switching case. My MMC1 implementation uses the register bits identically for 8KB or 4KB switching, and I don't see graphics messed up like that.


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 6:48 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19110
Location: NE Indiana, USA (NTSC)
What does it do with the MMC1 version of Holy Diver Batman?


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 7:11 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
cpow wrote:
I'm not sure you need the >>>1 on the 8KB CHR-switching case. My MMC1 implementation uses the register bits identically for 8KB or 4KB switching, and I don't see graphics messed up like that.


From the wiki:

Quote:
Select 4 KB or 8 KB CHR bank at PPU $0000 (low bit ignored in 8 KB mode)


If I don't do that the bank at the location (sans the >>> 1) is outside of the number of available banks.

tepples wrote:
What does it do with the MMC1 version of Holy Diver Batman?


Are you talking about the zip file with a bunch of strangely named .nes files? If so, all files starting with M1_ result in a black screen. The ones with M0_ and M2_ show a blue screen with yellow text (looks okay).


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 7:33 am 
Offline
NESICIDE developer
User avatar

Joined: Mon Oct 13, 2008 7:55 pm
Posts: 1026
Location: Minneapolis, MN
ArsonIzer wrote:
cpow wrote:
From the wiki:

Quote:
Select 4 KB or 8 KB CHR bank at PPU $0000 (low bit ignored in 8 KB mode)


If I don't do that the bank at the location (sans the >>> 1) is outside of the number of available banks.

The distinction is, I think: it is ignored by the hardware, which doesn't mean you should shift it away.

Looking at my implementation, perhaps I am just getting lucky...my mapper implementation almost ignores the low bit.

The 4KB case:
Code:
                     m_pCHRmemory [ 0 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+0 ];
                     m_pCHRmemory [ 1 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+1 ];
                     m_pCHRmemory [ 2 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+2 ];
                     m_pCHRmemory [ 3 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+3 ];


The 8KB case:
Code:
                     m_pCHRmemory [ 0 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+0 ];
                     m_pCHRmemory [ 1 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+1 ];
                     m_pCHRmemory [ 2 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+2 ];
                     m_pCHRmemory [ 3 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+3 ];
                     m_pCHRmemory [ 4 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+4 ];
                     m_pCHRmemory [ 5 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+5 ];
                     m_pCHRmemory [ 6 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+6 ];
                     m_pCHRmemory [ 7 ] = m_CHRmemory [ ((m_reg[1]&0x1F)<<2)+7 ];


Note how the register value is shifted 2-left to account for the 4KB-to-1KB bank [I switch CHR at 1KB granularity always]. That is done in both cases. In the 4KB case, there are 4 1KB banks to switch, so +0, +1, +2, and +3 toggle the 2 low bits that were added by the 4KB-to-1KB conversion.

In the 8KB case, there's the same 2 low bits that are added by the 4KB-to-1KB conversion, but I'm switching 8 banks, so +0, +1, +2, +3 and also +4, +5, +6, and +7. The first set should change the thirdmost low-bit, which wasn't added by my 4KB-to-1KB conversion [it was part of the original register value] to 0. The second set should change the thirdmost low-bit to 1. It is the "should" that indicates I must just be getting lucky. Note that the masking should be 0x1E in the 8KB switching case. Masking equals ignoring.


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 8:38 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10064
Location: Rio de Janeiro - Brazil
It appears there's something wrong with the name table mirroring as well.


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 9:41 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
@cpow
Thanks for the explanation. I'm now masking it with 0x1E.

The issue remains though, but I don't think the graphics problems have anything to do with that. Mega Man 2 for instance, uses only 1 CHR bank and since it's combined with modulo chrCount, whatever number comes out, it's always going to switch to bank 0 (0 % 1 == 0, 345243 % 1 == 0, etc), so the correct CHR bank (0 in this situation) is always active. Something else is going on. Maybe looking at a screenshot next to FCEUX can help:

Image
Image
Image
Image
Image

I'm aware that it might be nametable-related, but why does every other mapper work fine except for this one where everything fails? Is this related to how/when my mapper switches nametable mirroring?


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 10:32 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19110
Location: NE Indiana, USA (NTSC)
ArsonIzer wrote:
[The Holy Diver Batman test ROMs for MMC1] result in a black screen. The ones [for NROM and UNROM] show a blue screen with yellow text (looks okay).

The very first thing Holy Diver Batman tests is nametable mirroring. It will fail early and quickly if your emulator handles the mapper's mirroring wrong. Did you get a black screen with beeped Morse code, or a black screen with silence?


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 10:54 am 
Offline

Joined: Fri Jul 19, 2013 11:38 am
Posts: 115
tepples wrote:
Did you get a black screen with beeped Morse code, or a black screen with silence?


I have no APU. Do I have to implement sound for this? That could take a while since I don't even have a basic understanding of audio. Is there something else I could do, for instance make a CPU log and check it against another?


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 11:27 am 
Offline
NESICIDE developer
User avatar

Joined: Mon Oct 13, 2008 7:55 pm
Posts: 1026
Location: Minneapolis, MN
You're masking but did you remove the >>>1?


Top
 Profile  
 
PostPosted: Fri Jun 20, 2014 12:08 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10064
Location: Rio de Janeiro - Brazil
ArsonIzer wrote:
I'm aware that it might be nametable-related, but why does every other mapper work fine except for this one where everything fails?

Name table mirroring is controlled by the mapper, so it's not unusual that a single mapper has screwed up mirroring. A lot of your screenshots appear to be displaying the name table that should be hidden. Have you double checked your MMC1 mirroring logic?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 38 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 7 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