This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Protip for TNROM on hardware using INL-ROM!

Protip for TNROM on hardware using INL-ROM!
by on (#121753)
Been playing with INL's TNROM board and it rules but I thought I would share an interesting caveat when working with it!

I had recently shared a ROM for people to test on their Powerpaks, etc, when I was having problems with FCEUX emulation (that ended up being a bad version of FCEUX, but that's for another thread). It seemed to work fine on consoles everywhere and when using a good emulator all is well.

I tried the same ROM on an INL TNROM board? Nothing! Before I decided to fret, I loaded up a familiar title to see if it was my ROM. Final Fantasy 3 worked like a dream!

So, I tried making the most basic program I could think of: a simple image appearing on the screen. Still didn't work. This was when I suspected it had something to do with my init code, which is of course the universal start up code, I'm certain most people use, found on the wiki.

I stepped through FF3 using Nintendulator's debugger and soon discovered that even though TNROM's use CHR RAM and not ROM, they had some bank switching code for the RAM as part of the init! Sure enough, once I put this code into my own init, everything was fine. It seems that actual TNROM hardware requires at least a basic set up of the CHR RAM where emulators and even the Powerpak don't! I'm not sure if the Powerpak is doing some kind of emulation inside but don't let it fool you into thinking a TNROM game is working the way it would on a TNROM board!

Now here's the code (for ASM6). This would go wherever you choose to do your mapper setup but BEFORE any PPU code (I prefer to play it safe and let the two frame warmup happen before doing anything):
Code:
   ; Set up banks
   lda #$00
   sta BANK_SELECT         ; $8000 swappable, $c000 fixed
                     ; Two 2k banks at $1000
                     ; Four 1k banks at $0000   
   sta BANK_SWITCH         
   
   tax                  ; Init CHR RAM
ChrBankLoop:               
   stx BANK_SELECT         ; $00, $01, $02, $03, $04, $05
   
   lda CHRinitTable,x      ; Sets up CHR banks
   sta BANK_SWITCH         ; $00, $02, $04, $05, $06, $07
   inx
   cpx #$06
   bcc ChrBankLoop

Then wherever your data goes but still in your hardwired bank:
Code:
CHRinitTable:
   .db $00, $02, $04, $05, $06, $07

The table likely has to be different for a different CHR config, but I haven't tested that. So, $00, $01, $02, $03, $05, $07 instead if using the opposide config, etc. After that, everything loads up just as you would want!

I hope this helps anyone doing TNROM development or testing, and if anyone with more technical prowess can elaborate on why this is required on an actual TNROM board but not a Powerpak, I'd love to know!

edit: the first bank write might be redundant, but I am a stickler for making 100% sure things are going to work the way I want :?
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121756)
Happy to see you're digging right in with things!

Yes, the CHR banks and mode certainly do need initialized before use. The powerpak, emus, and such often tend to initialize things for you even if they don't mean to. With actual cartridge hardware running on the NES, you should ALWAYS initialize any registers that are relied upon. I would assume that using the original MMC3 you'd run into the same issue. So this is a good tip in general, not just on my boards specifically. I found similar issues with setting up the PPU, people often don't wait long enough before writing to the PPU with their init code. Even the init code from the nerdy nights tutorial doesn't wait long enough (where I first noticed the issue myself) When using the powerpak the PPU has been running for an eternity by the time your code gets ahold of it, and emus generally don't require warmup.
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121758)
Either way it'd be 0,2,4,5,6,7.

The first two writes are redundant, and counting down from 5 to 0 instead of up from 0 to 5 allows skipping the CPX. Alternate code
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121761)
Thanks for clarifying, tepples! I literally used the exact code I was stepping through from FF3 and it seemed legit (ie. worked for Square). Though I should have been more clear when I said the "first write." I meant the first PAIR of writes. Just a habit in my thinking since a lot of NES register writes happen in pairs, haha

Would you mind explaining that particular number sequence? It seemed to me like the "starting points" to 1k chunks of CHR data, which is why I assumed it would be different depending on the CHR config one chose to use.

And yeah, infiniteneslives, it's always a good habit to init everything before getting started. It was foolhardy to think I could get away with leaving something out because it didn't seem "relevant"!
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121762)
And tepples, thanks for the DEX pointer. Since I'm starting to get the hang of things, I'm now trying to make my brain automatically optimize code and in your alternate example you mention the A and X registers being ready for setting up mirroring. Simple, but very slick. :D
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121763)
Um, if you don't understand what those numbers are, it's no small wounder you did not understand the advise of the forum regulars when we told you to initialize the mapper correctly.

Please familiarize yourself with the documentation for mapper 4 (MMC3). You'll be glad you did.
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121766)
qbradq wrote:
Um, if you don't understand what those numbers are, it's no small wounder you did not understand the advise of the forum regulars when we told you to initialize the mapper correctly.

qbradq, this is the first time I have mentioned such a thing, so nobody has told "me" anything about it. I have already admitted that it was a foolish oversight and remedied it, and I can assure you I will be much more meticulous in the future.

Anyway, I KNEW what the numbers meant (associations of the chunks of CHR RAM on the board to the appropriate PPU registers), but what confused me was how the sequence could be the same either way the CHR was set up. That made me question the sequence and therefore it's purpose. However, upon REREADING the doc (yes, I read it before, believe it or not) I realized that I was looking at the CHR diagram wrong, thinking that the banks were somehow numbered differently based on the config. So now, the sequence makes total sense again. :oops:

edit: I know that noob questions are probably frustrating, and it's easy to assume that the person is not bothering to do their research, but please don't let the noobs ruin what is possibly just a simple misunderstanding from a person who IS actually trying. As evidence, here is a quick little demo of my first person dungeon crawl engine, a la Bard's Tale/Wizardry, that will be a fully functional (and awesome!) game in the relatively near future. This doesn't represent anything near a final product, and I have even already reprogrammed the perspective in prep for some more accurate and detailed art, but it can at least show you that when I ask a question it's because I am legitimately confused about something and not just rolling around like a helpless baby. Up = Forward, Left/Right = turn 90 degrees. https://dl.dropboxusercontent.com/u/108 ... wlTest.nes
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121767)
mrmmaclean wrote:
but what confused me was how the sequence could be the same either way the CHR was set up. That made me question the sequence and therefore it's purpose.
Is there any way we could rewrite or rephrase things to make it more immediately clear what's going on?

P.S. your proof of concept looks like a really good start!
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121768)
lidnariq wrote:
Is there any way we could rewrite or rephrase things to make it more immediately clear what's going on?

To be honest, I think it's just a matter of the page being all monotype like code or code comments. The diagram is clear enough in principal, but that kind of font tends to just look like a wall of text that's easy to skim and miss the finer details. The error is on me, for certain.

If anything, perhaps a note above or below the diagram stating that the registers remain the same despite the configuration could help. But, once again, it would not been needed if I was simply more careful.

ps: thanks! :D
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121773)
Do you find the MMC3 article more or less clear than the Mapper 4 article?

We should really finish cleaning everything up; certain parts of the wiki are in a pretty terrible state of Don't Repeat Yourself.
Re: Protip for TNROM on hardware using INL-ROM!
by on (#121776)
lidnariq wrote:
Do you find the MMC3 article more or less clear than the Mapper 4 article?

I definitely do find the MMC3 one much more clear and, in fact, reference it a lot more. Mind you, a lot of that comes down to the readability of it. I'm quite terrible at memorizing bits and being able to quickly scroll to the appropriate register detail is very important to my feeble mind (this applies to the PPU article, etc, as well). However, in Disch's notes in the iNES 004 article, there's more specifics on how to actually use the registers, such as what order to write to the IRQ regs and, of course, the CHR diagram, for example. The former is more technical and the latter is more practical, but both are required for a full understanding of the mapper and how to code for it.

I appreciate the work you guys do on the wiki, it's really great stuff! But yeah, why have two somewhat incomplete articles when one super article will do!