Chatterine Snuggles's RE'ing thread

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Chatterine Snuggles's RE'ing thread

Post by chatty »

So like 6 months ago I had made a thread to RHDN (https://www.romhacking.net/forum/index. ... ic=39622.0) where I was basically documenting my reversing attempts. This time around I decided to move this thread to the NesDev forums.

Okay, one game I'd like to poke around in is Fire Emblem Gaiden (I found editing its texts to be easier compared to FF2 (the game I was dabbling with previously)). I want to edit this screen: https://imgur.com/a/G6EEIpl What do I want to do? Well, I want to expand that window horizontally, as to fit more text. How is that achievable? :p

My edge case: As I've already discussed previously in the NESDev Discord, I'm on a really weak laptop. Even with Linux and all, I'm basically forced to use either the No$NES or the FCEUX debuggers. No$NES runs -slightly- better on my machine, so I'm naturally going to gravitate towards that. THis wouldn't be an issue if I were on Mesen, but that emulator runs really poorly on my 2 GiB of RAM Celeron from 2015.

So, anybody here can give me any sort of tips on what I'd need to do? :oops: If I were on Mesen I'd set a breakpoint to the top left corner of the window and try to work my way backwards to see how the window gets drawn, so I can at least figure out a way to draw the screen on a different position.
Last edited by chatty on Fri Jun 13, 2025 7:48 pm, edited 1 time in total.
User avatar
segaloco
Posts: 723
Joined: Fri Aug 25, 2023 11:56 am
Contact:

Re: Chatterine Snuggles's RE'ing thread

Post by segaloco »

So first thing is to figure out where things are being drawn. 99.9% of the time text boxes and their contents are BG, so you're looking for data being loaded into the nametables.

Generally you want a textbox aligned the same so the functional scroll of your environments using text boxes are multiples of eight, that way at any given time a box will be rendered it is aligned on the same grid. The engine needs to calculate which part of the nametable is currently at *screen* coordinate (x,y), so its unlikely you have something like a Nintendo display list with a fixed nametable destination. Instead usually there's a calculation you put in the desired tile coordinate in screen coordinates and it calculates where in the current visible nametable to start drawing.

All that to say, you're looking at a lot of calculations with keeping the text boxes in predictable bounds when scrolling is used. If you're lucky, there's a subroutine that dynamically draws dialogues from the box drawing bits and takes an upper left corner and dimensions. However, it is also possible an engine has a set of predefined boxes, like you have 3x5, 4x5, and 5x5, and they can start at 3x3 tiles, 3x4 tiles, whatever. Dragon Quest has some of this going on where some of the dialogues like direction and attack selection are incredibly prescriptive (some are indeed fixed display lists) whereas others are draw a box this size in this place.

One gotcha too that is in Dragon Quest and could be in other systems: Many Dragon Quest generic box definitions are concerned with drawing the top and bottom bounds of a box. The sides are then explicitly tiles in the drawing command for that row, such that the string content for that box is stored *with* the edges (but without the top and bottom row). Really all this means is keep in mind that there may not necessarily be a "draw a box" subroutine, but possibly just "draw the parts of the box that can't be embedded in a string".

Good luck!
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

So first thing is to figure out where things are being drawn. 99.9% of the time text boxes and their contents are BG, so you're looking for data being
Meh, I'm pretty positive that it's being stored as background data. Proof: https://imgur.com/a/JNa84uh ...not sure why the font is showing up like that though.
User avatar
segaloco
Posts: 723
Joined: Fri Aug 25, 2023 11:56 am
Contact:

Re: Chatterine Snuggles's RE'ing thread

Post by segaloco »

Are there multiple banks involved? Could be that the font is in a separate bank.
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

segaloco wrote: Thu Jun 12, 2025 1:35 pm Are there multiple banks involved? Could be that the font is in a separate bank.
I don't know. How can I check that? :p

---

Also, how do I embed an image to a post so I don't have to hyperlink it?
User avatar
segaloco
Posts: 723
Joined: Fri Aug 25, 2023 11:56 am
Contact:

Re: Chatterine Snuggles's RE'ing thread

Post by segaloco »

Banks are based on your mapper, which is in the iNES header. Even if you don't know your specific mapper, two of the fields capture the number of PRG and CHR banks, which are concatenated in order. You might check if your tool also has a way to specify which bank to use for rendering, I'd be surprised if a NES tile tool didn't have a way to use different CHR banks.

As for embedding, at the bottom of the post editor there's an "Attachments" section you can use to add images either as attachments at the end or inline.
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

segaloco wrote: Thu Jun 12, 2025 2:11 pm I'd be surprised if a NES tile tool didn't have a way to use different CHR banks.
It's not really a tile tool, it's just the VRAM viewer. I don't know how to change the currently selected bank on the No$NES tilemap viewer xp. Anybody here knows this?

No$NES also seems to have no way of checking the game's own mapper and iNES header, so here's FE2's page on the nes cartridge database https://nescartdb.com/profile/view/1266 ... lem-gaiden

Key things are that it has 256 KB of PRG-ROM and 128 KB of CHR ROM, and that it's MMC4. I know very little about this specific mapper other than that it's basically the MMC2 but different, so I searched for more information about those on the wiki: https://www.nesdev.org/wiki/MMC4 and https://www.nesdev.org/wiki/MMC2

I also bothered checking if this is one of those games like the ones you mentioned which only draws the top and bottom parts of dialogue box windows and hardcodes the left and right sides to the text, and it doesn't seem like it. I say this because I've managed to dump this game's text already and I don't see any of that. I could be wrong though hehe.

EDIT: I also opneed up the game's CHR inside something like YY-CHR, and indeed it seems like the font and the OW graphics are split.

EDIT 2: You might want to check the NO$NES official reference document (https://problemkaputt.de/everynes.htm).
User avatar
Quietust
Posts: 2017
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Chatterine Snuggles's RE'ing thread

Post by Quietust »

Fire Emblem [Gaiden] uses the MMC4, and the MMC4 automatically changes CHR banks whenever tiles $FD and $FE are fetched (with different pairs of banks for each pattern table, in practice one for Background and one for Sprites, and the switch being performed after the tile is fetched).

In this case, the left border of every text box is tile $FD (which switches to the Text bank) and the right border is tile $FE (which switches back to the background Graphics bank). Thus, if you do make the text box wider, the CHR bank switching will adjust automatically.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
segaloco
Posts: 723
Joined: Fri Aug 25, 2023 11:56 am
Contact:

Re: Chatterine Snuggles's RE'ing thread

Post by segaloco »

Quietust wrote: Thu Jun 12, 2025 3:58 pm Fire Emblem [Gaiden] uses the MMC4, and the MMC4 automatically changes CHR banks whenever tiles $FD and $FE are fetched (with different pairs of banks for each pattern table, in practice one for Background and one for Sprites).

In this case, the left border of every text box is tile $FD (which switches to the Text bank) and the right border is tile $FE (which switches back to the background Graphics bank). Thus, if you do make the text box wider, the CHR bank switching will adjust automatically.
That's actually really cool, so you start a line of a box and it flips over, draws the box, background, text, etc, then hits that last tile and says done, back to normal. Sounds pretty ideal for box/window drawing honestly.
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

Quietust wrote: Thu Jun 12, 2025 3:58 pm In this case, the left border of every text box is tile $FD (which switches to the Text bank) and the right border is tile $FE (which switches back to the background Graphics bank).
That actually makes quite some sense. I presume that's why the text doesn't show up properly on the VRAM viewer, right? The viewer is unable to account for this obscure functionality of the game's mapper, resulting in those glitchy tiles you just saw.
Pokun
Posts: 3291
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Chatterine Snuggles's RE'ing thread

Post by Pokun »

Yeah but you can change which scanline to use for rendering the VRAM viewer, so by changing that you should be able to make the text readable.


Punchout also uses this feature for drawing the bottom half of the screen from a different CHR bank. It's a pretty unique feature of the MMC2 and MMC4 mappers (which was only used by a few games made by Intelligent Systems).
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

I have good and bad news.The good news is that I managed to get the latest version of FCEUX native (2.7.0) working on my machine, the bad news is that performance-wise it's not as good as No$NES if I'm running the viewer, debugger and game at the same time (somehting Nocash's emu can do seamlessly), so if I'm ever FCEUX'ing I'll certainly keep the emu paused. That said, expect me to keep bouncing from the two emulators from time to time lol.
Pokun wrote: Thu Jun 12, 2025 5:01 pm Yeah but you can change which scanline to use for rendering the VRAM viewer, so by changing that you should be able to make the text readable.
How can I do that on either emulator? I tried changing the scanline being used to 200 on FCEUX, but the text was still blocky. I also don't see any option like that on NocashNES's VRAM viewer, etiher. :?:

Edit: I should probably add, the thing that makes the tiles change isn't the scanline, but rather the horizontal pixel coordinates. And I don't think FCEUX has an option to do that yet.
Pokun
Posts: 3291
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Chatterine Snuggles's RE'ing thread

Post by Pokun »

I see, I guess it might not work with this feature.
User avatar
chatty
Posts: 33
Joined: Wed Dec 11, 2024 9:41 am
Location: Brazil

Re: Chatterine Snuggles's RE'ing thread

Post by chatty »

Hey. A lot of stuff has been happening to me over the past 2 weeks. Long story short, I bought a new PC, one that can run Mesen I should add. Yay! This means I can use Mesen now.

Now, I tried setting a breakpoint to the top left of the dialogue box, and I seem to have hit a routine for displaying text on-screen....

Code: Select all

C3BF  8D 06 20     * STA PpuAddr_2006
C3C2  C8             INY
C3C3  B1 00          LDA ($00),Y
C3C5  8D 06 20     * STA PpuAddr_2006
C3C8  C8             INY
C3C9  B1 00          LDA ($00),Y
C3CB  0A             ASL A
C3CC  20 F3 C3       JSR $C3F3
C3CF  0A             ASL A
C3D0  B1 00          LDA ($00),Y
C3D2  29 3F          AND #$3F
C3D4  AA             TAX
C3D5  90 01          BCC $C3D8
C3D7  C8             INY
C3D8  B0 01          BCS $C3DB
C3DA  C8             INY
C3DB  B1 00          LDA ($00),Y
C3DD  8D 07 20     > STA PpuData_2007
C3E0  CA             DEX
C3E1  D0 F5          BNE $C3D8
C3E3  C8             INY
C3E4  20 78 C3       JSR $C378
Though I'm not really sure where to go from here lol.

Any ideas?

EDIT: I should probably explain more in-depth what are my questions. Just asking "help plz" isn't going to lead me anywhere, hahahahaha. The instruction that stores the tile to VRAM is that STA PPUDATA instruction, so I googled what that means and found this: https://www.nesdev.org/wiki/PPU_registe ... ead/write) Knowing know how it gets to know *which* tile to grab, how can I know how it knows *where* to draw the tile? The solution is PPUADDR, ofc. So I read into that too. https://www.nesdev.org/wiki/PPU_registe ... 006_write) The address I want to change is $2204, since that's where the top left of the tile is being drawn to. That being said, is PPUADDR little or big endian? The answer is that the write interface is big endian (thanks @Fiskbit on Discord!).

EDIT 2: ANyway, going on with debugging. I set a breakpoint to those two writes to PPUADDR which I annotated with an asterisk (" * ") and it appears like PPUADDR only gets updated in this game's code whenever it needs to go back to the start of a stripe in the windows, so altering one point in this routine should alter the entire game. Right.. Is there a way to add annotations to code I'm tinkering around in? :p Nevermind, seems like I can add some by right-clicking and clicking "Edit Label".

Anyway, here's that same routine again but now with labels:

Code: Select all

                   StartLocationOfPrintingGfx:
C3BF  8D 06 20       STA PpuAddr_2006
C3C2  C8             INY
C3C3  B1 00          LDA ($00),Y
C3C5  8D 06 20       STA PpuAddr_2006
C3C8  C8             INY
C3C9  B1 00          LDA ($00),Y
C3CB  0A             ASL A
C3CC  20 F3 C3       JSR UpdatePPUCTRL
                   WriteToPPUData:
C3CF  0A             ASL A
C3D0  B1 00          LDA ($00),Y
C3D2  29 3F          AND #$3F
C3D4  AA             TAX
C3D5  90 01          BCC Loop
C3D7  C8             INY
                   Loop:
C3D8  B0 01          BCS $C3DB
C3DA  C8             INY
C3DB  B1 00          LDA ($00),Y
C3DD  8D 07 20       STA PpuData_2007
C3E0  CA             DEX
C3E1  D0 F5          BNE Loop
C3E3  C8             INY
C3E4  20 78 C3       JSR End


                   --------UpdatePPUCTRL--------
                   UpdatePPUCTRL:
C3F3  48             PHA
C3F4  A5 D3          LDA $D3
C3F6  09 04          ORA #$04
C3F8  B0 02          BCS $C3FC
C3FA  29 FB          AND #$FB
C3FC  8D 00 20       STA PpuControl_2000
C3FF  85 D3          STA $D3
C401  68             PLA
C402  60             RTS
 
EDIT 3: I did a little bit more of digging. Seems like the game is storing the address in VRAM in the zero-page CPU addressees $01 and $00 (reversed due to little endianness).

EDIT 4: Typo fixed for clarity.
Joe
Posts: 745
Joined: Mon Apr 01, 2013 11:17 pm

Re: Chatterine Snuggles's RE'ing thread

Post by Joe »

chatty wrote: Sun Jun 22, 2025 1:13 pmEDIT 3: I did a little bit more of digging. Seems like the game is storing the address in VRAM in the zero-page CPU addressees $01 and $00 (reversed due to little endianness).
Looks to me like it's a pointer to a display list. The first two bytes of the display list are the VRAM address, the next byte is the length and some control flags, and the following bytes are written to PPUDATA.
Post Reply