It is currently Tue Oct 16, 2018 9:30 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 42 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Learning MMC1
PostPosted: Wed Sep 19, 2018 1:37 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 72
Location: Colorado
So I've been using the Mesen debugger some code I found on github that is using MMC1, so I've been looking through some docs for the mappers.

When switching levels, the code is writing to $E000 with 5 sta calls and lsr calls in between.

I'm trying to understand the significance of the values being passed into $E000.

Here's what I see in the document about MMC1 I've been looking at:

Code:
$E000-FFFF:  [...W PPPP]
    W = WRAM Disable (0=enabled, 1=disabled)
    P = PRG Reg


So, what exactly is PRG Reg (Program Register?). What exactly happens when you make these calls? My understanding is it somehow swaps out the cpu memory in a location that somehow corresponds to the value you pass in, but since there are only 4 bits I'm not sure exactly how this is happening.

I know this is probably a really stupid question, but I've spent a while trying to figure out how this works from the docs I have, and somehow I'm failing to understand the basics of how this mapper works.

Thanks for your help

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 1:46 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
battagline wrote:
Code:
$E000-FFFF:  [...W PPPP]
That's wrong. There's no upper three bits (not even ignored ones). All registers in the MMC1 are only five bits wide, and written in one bit at a time.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 1:50 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 72
Location: Colorado
Quote:
That's wrong. There's no upper three bits (not even ignored ones). All registers in the MMC1 are only five bits wide, and written in one bit at a time.


That's what the doc says. The code I'm looking at doesn't try and shove in any more bits after the first five. My question was much more basic though. I am just trying to figure out what happens in CPU Memory once you write those five bits.

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 1:53 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
MMC1 is comparatively complex, but the number written there changes what section of ROM the CPU can see.

It might be easier if you try to understand CNROM first? I feel like CHR ROM bankswitching is an easier concept, and the concepts carry over easily.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 2:01 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 72
Location: Colorado
lidnariq wrote:
MMC1 is comparatively complex, but the number written there changes what section of ROM the CPU can see.

It might be easier if you try to understand CNROM first? I feel like CHR ROM bankswitching is an easier concept, and the concepts carry over easily.


I'm looking for a mapper that works with NES Classic without adding a new emulator to the NES Classic. I'm not sure CNROM will work. I was thinking either MMC1 or MMC3, which I know are supported. I happen to come across some code on github that uses MMC1, so I was trying to figure that one out.

Anyway, I'm still hoping I can understand what is happening with MMC1.

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 2:25 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20657
Location: NE Indiana, USA (NTSC)
lidnariq wrote:
battagline wrote:
Code:
$E000-FFFF:  [...W PPPP]
That's wrong. There's no upper three bits (not even ignored ones). All registers in the MMC1 are only five bits wide, and written in one bit at a time.

Would the following be correct and concise?
Code:
$E000-FFFF:  [.... ...L]
    L = Serial load register (LSB first)

Internal register after fifth write to $E000-FFFF:
             [W PPPP]
    W = WRAM Disable (0=enabled, 1=disabled)
    P = PRG Reg


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 2:26 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
My point is don't include the three upper dots, they're confusing because nothing about the MMC1 has eight bits.

Anyway: Battagline, you already asked, and tepples already replied, CNROM is supported.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 3:11 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 72
Location: Colorado
lidnariq wrote:
My point is don't include the three upper dots, they're confusing because nothing about the MMC1 has eight bits.

Anyway: Battagline, you already asked, and tepples already replied, CNROM is supported.


My mistake. I had forgotten CNROM was in that list.

It doesn't really change that I would like to know how MMC1 works though, but it is nice to know that CNROM would work also.

THanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 3:28 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
The NES by itself can only see 32 KiB of memory for program and data and 8 KiB of memory for graphical data; almost all of the "mappers" are ways to let it see more. Wikipedia: https://en.wikipedia.org/wiki/Bank_switching

The MMC1 is simultaneously complex but feature-poor¹, and makes a bad thing to learn from. Mapper 87 and CNROM are the simplest (and oldest) mappers that permit more memory to be used on the NES, which is why I recommend starting there.

¹: I mean the serial interface obfuscates what's going on, compared to, say, VRC1; and the flexibility that made it better for Nintendo to manufacture makes it worse for didactic purposes.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 3:40 pm 
Online
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 936
Location: cypress, texas
battagline wrote:
So I've been using the Mesen debugger some code I found on github that is using MMC1, so I've been looking through some docs for the mappers.

When switching levels, the code is writing to $E000 with 5 sta calls and lsr calls in between.

Have you read the nesdev's wiki on MMC1? https://wiki.nesdev.com/w/index.php?title=INES_Mapper_001
It's complex, like lidnariq said, but after spending some days reading and rereading and praying about understanding it... and some trial and error and forum discussion it began to really make sense to me.

Something that tepples showed me that's so helpful: when you are writing the 5 bits to a MMC1 register, you don't need to put lsr calls in between the stores... say the accumulator already holds #00, or any even value, and register X already holds #01, or any odd value... then, if you are wanting to write #09 to $A000, this faster smaller code works just as well:
Code:
;least significant bit written first
stx $8000 ;1
sta $8000 ;0
sta $8000 ;0
stx $8000 ;1
sta $A000 ;0
;now $A000 holds 01001 binary == 09 decimal
The address only matters on the last store. :)


edit: added "written" to code example :)
final edit: added a new line in front of edit summaries


Last edited by unregistered on Wed Sep 19, 2018 4:00 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 3:50 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
Are you getting started on NES development and want to use a mapper supported by the NES Classic? Why not NROM (i.e. no mapper)? Dealing with bankswitching prematurely will make the learning curve much steeper for you.

Anyway, you need to understand the concepts of bankswitching in order to understand what a mapper does. The basic idea is that the NES can only see a limited amount of PRG and CHR memory at a time, and to access more than these basic amounts you can "map" different parts of larger chips into the space that the NES can see.

Different mappers will divide the memory in chunks of different sizes, and break up the areas the NES can see in different ways. Regardless of how mappers break things up, you have to tell it WHAT to put WHERE ("where" is implicit if there's only one slot to map stuff), and each mapper has its own interface for this. The MMC1 is particularly weird because it only takes 1 bit of information at a time (the bit at position 0, the upper bits are ignored), so you have to write one bit (STA), position the next bit (LSR), write that (STA), position the next (LSR), and so on, until all 5 bits have been written, and only then the mapper can carry out the task of mapping the bank you requested.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 3:59 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
unregistered wrote:
when you are writing the 5 bits to a MMC1 register, you don't need to put lsr calls in between the stores...

That's a cool trick, but only useful when selecting a constant bank. If the bank number comes from a variable, I guess you're stuck with LSR. Or a jump table, but setting that up might be slower than the LSRs...


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 4:11 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20657
Location: NE Indiana, USA (NTSC)
It's still good for setting up $8000 and $A000 if you use 8K CHR RAM and only one mirroring type, where the MMC1's big advantage over stock BNROM/UNROM is WRAM decoding.


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 4:14 pm 
Online
User avatar

Joined: Thu Apr 23, 2009 11:21 pm
Posts: 936
Location: cypress, texas
tokumaru wrote:
unregistered wrote:
when you are writing the 5 bits to a MMC1 register, you don't need to put lsr calls in between the stores...

That's a cool trick, but only useful when selecting a constant bank. If the bank number comes from a variable, I guess you're stuck with LSR. Or a jump table, but setting that up might be slower than the LSRs...
Yes; but, it is really cool to use in the beginning when setting up the mapper (like storing to $8000; haha tepples ninjaed me)! :D And, our game, right now, always starts at level one... so that's helpful there too. :)


Top
 Profile  
 
 Post subject: Re: Learning MMC1
PostPosted: Wed Sep 19, 2018 4:18 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 72
Location: Colorado
unregistered wrote:
battagline wrote:
So I've been using the Mesen debugger some code I found on github that is using MMC1, so I've been looking through some docs for the mappers.

When switching levels, the code is writing to $E000 with 5 sta calls and lsr calls in between.

Have you read the nesdev's wiki on MMC1? https://wiki.nesdev.com/w/index.php?title=INES_Mapper_001
It's complex, like lidnariq said, but after spending some days reading and rereading and praying about understanding it... and some trial and error and forum discussion it began to really make sense to me.

Something that tepples showed me that's so helpful: when you are writing the 5 bits to a MMC1 register, you don't need to put lsr calls in between the stores... say the accumulator already holds #00, or any even value, and register X already holds #01, or any odd value... then, if you are wanting to write #09 to $A000, this faster smaller code works just as well:
Code:
;least significant bit written first
stx $8000 ;1
sta $8000 ;0
sta $8000 ;0
stx $8000 ;1
sta $A000 ;0
;now $A000 holds 01001 binary == 09 decimal
The address only matters on the last store. :)

edit: added "written" to code example :)


That's a neat trick. I have read the docs and I'm just not sure I understand exactly how the bank switching works.

So for all of those who are asking me if I can just use a different mapper, here's the situation. I've written a little "game" that I can run on my nes classic which is basically a guy walking around and shooting squares. One of the issues I've had is trying to figure out how to organize my code.

To learn more, I grabbed someone's code off of github
https://github.com/ZaneDubya/MetroidMMC3

and have been stepping through it to try and figure out what it's doing. For some reason the MMC3 version he has is breaking on me, so I've been stepping through the MMC1 version.

Basically I'd like to understand what MMC1 is doing. A few things I don't yet understand is where all the level data is going initially, and where it get's swapped to when a level changes. It looks like when the level changes, he loads a series of values into $E000. Whenever I return to the initial level, it looks like he loads the following numbers into $E000 using the STA + LSR method: 1, 0, 6, 5, 1, 6, 1, 1, 1, 6, 1, 6, 1
at some point while all of that is going on, does an STA into $A000 with $7F in the accumulator. When he does that he doesn't do it with repeated serial calls like he's doing for $E000 so from my understanding that's just sending a single '1' bit. I'm not really sure why that is necessary.

Anyway, I'm just trying to figure this out for my own understanding.

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: unregistered and 5 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