Mesen - NES Emulator

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

Fiskbit wrote:The search seems pretty clunky, though; it plays the current audio repeatedly and then speeds up afterward to compensate for the lost time. If it finds another matching ROM, does it automatically load that to work with the state, or what? This strikes me as surprising behavior
Yes - this behavior exists because you can open a save state file directly and have Mesen load the corresponding game. If it's freezing for a few seconds, you likely have several hundreds/thousands ROMs, which is not really a typical scenario.

I've done some changes (halfway done or so):
-Current byte in hex editor is always highlighted
-Right-click on nametable can put a breakpoint (on a "nametable ram" location, which is new, too)
-DMC reads will now trigger breakpoints (but this will trigger in the middle of the instruction, even if sub-instruction breakpoints are disabled (because otherwise this would require predicting the next DMC read ahead of time, which implies predicting the APU's behavior, which is a lot of trouble/CPU time)
-Copy action on text boxes should be fixed
-The "read" cycle for the DMC will now show up as "DMC" in the instruction progress. Stall cycles aren't marked, yet, though.
-Break on decayed oam read option should no longer trigger when cpu cycle counter reaches 2^31
-Added an option to the hex editor to highlight the current column/row
Fiskbit wrote:- When creating a breakpoint by clicking in the code view in a 24 KB mapper 0 ROM on an address $C000-FFFF, the breakpoint claims to be on an address $8000-BFFF.
If you mean the breakpoint list is displaying the "wrong" address, this is normal in this case. The breakpoint is added to the real offset in PRG ROM, and then the matching (current) CPU address for that breakpoint is calculated as needed - several addresses can match, when mirrors exist, and only the first one will be shown. e.g, on a 8kb PRG ROM game, putting a breakpoint on $E500 might show "$8500 [$0500]" as the address, the first one being the current (calculated) CPU address (for the first mirror) and the 2nd one is the offset in PRG ROM (which is where the breakpoint is actually set). It doesn't know that you put the breakpoint on $E500 specifically, it'll break when any of the mirrors is executed/read/written.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Mesen - NES Emulator

Post by Fiskbit »

Thanks for the details, and I look forward to trying out those improvements!


I encountered another issue tonight. I made a version of one of my tests that uses mapper 218, and it needs to be 8 KB. Trying to load this 8 KB ROM with an NES 2.0 header specifying 8 KB through mapper byte 9 being $0F and byte 4 being $34 (001101 00, or 2^13 * 1 = 8 KB) results in Mesen seriously misbehaving (doesn't load the ROM, has high CPU use, won't load other ROMs, hangs on close). I get the same behavior if I lie and just mark the ROM as being 16 KB with a normal iNES header (with it still only being 8 KB). Using a 16 KB version with that iNES header works fine.

Even if Mesen doesn't support this ROM size right now (and assuming I did the NES 2.0 sizing correctly...), it should still probably fail more gracefully. Testing was done on Mesen 0.9.7.48, and I've attached a ROM that reproduces the issue.
Attachments
oam_corruption_stress_test_mapper218_8kb_mesen.nes
(8.02 KiB) Downloaded 147 times
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Mesen - NES Emulator

Post by unregistered »

Sour wrote:You mean it did something like this? (this code makes no sense, but just for illustrative purposes)

Code: Select all

mylabel:
  LDA #$00
  LDX #$00
  BNE mylabel+2
  LDY #$00
  BNE mylabel+2
Where "mylabel+2" would normally be a branch to the 2nd line (the "LDX #$00" instruction)

In that case, it's probably ok, I think. This isn't likely to happen (and it's not actually giving false information, either). Multi-byte labels in PRG ROM are useful for hardcoded byte arrays, etc., so I can't really disable them altogether.

Internally, the debugger is creating multiple labels (e.g: mylabel+0, mylabel+1, mylabel+2, mylabel+3), but I made it so only the first label is shown, and without displaying the "+0", which is why it still says "mylabel:" rather than "mylabel+0:" on the first line. Otherwise the display for non-disassembled data arrays was a mess, e.g:

Code: Select all

mydata+0:
  .db $00
mydata+1:
  .db $00
mydata+2:
  .db $00
mydata+3:
  .db $00
Instead of just:

Code: Select all

mydata:
  .db $00 $00 $00 $00
Yes Sour, that is exactly what I meant! :) Your wisdom and change have made it so much better, for me at least. Now that function name, after assigning a length of 2, doesn't have a "+0" at the end while my p43 still has a "+0" for RAM location $0043! Thank you so much! :D
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Mesen - NES Emulator

Post by Fiskbit »

Looks like my problem with the 8 KB ROM was that I had failed to set the NES 2.0 identifier bit, so it was interpreting the PRG size as being very large. Setting the identifier correctly allows it to load properly. I'd guess Mesen is misbehaving if the PRG is smaller than advertised.
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

Yes, the code that loads the ROM will end up in an endless loop if the file is smaller than 16kb (because that's the smallest PRG size that can be defined in iNES 1.0), will get it fixed soon.

In other news, I've been trying to rewrite my DMC/OAM DMA logic based on this thread (since conceptually it seems to make a lot of sense), but I haven't managed to find a solution that makes blargg's test pass (the one that measures the time taken by a sprite DMA when a DMC DMA happens in the middle). I do have a "fix" for your test rom, but I'm not convinced that the DMA behavior in Mesen is 100% accurate in the first place (it's a decent approximation at best), so if possible I'd like to fix it properly rather than tackle an extra patch on top of it.

I'll have to see if I can get that ROM to pass on Visual NES first, which could at least help confirm or invalidate what's written in that thread (but the test will take over an hour to run, so it'll have to wait until tomorrow)
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

And after 1+ hour of running that simulation at a whopping 2 frames per minute, the result isn't excessively useful:
oamdma.png
oamdma.png (5.99 KiB) Viewed 4476 times
I was hoping the delays might match, and they are kind of close, but not perfect (and I don't know what to make of the last 2 values). So, I'm not sure how reliable the Visual 2A03 is for this (although it could also be specific to Visual NES, but I have no simple way of running this test on the original JS simulators to check, not to mention it would take 10+ hours to run)

I was going to take a look at Bizhawk's implementation of this, but it looks like Bizhawk also doesn't pass your sync test, so that doesn't help, either. Might have to put this particular issue on the "try to figure this out someday" pile, unfortunately.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Mesen - NES Emulator

Post by unregistered »

@Fiskbit, found that you can get Mesen to run 1 CPU cycle by pressing ctrl+b to bring up the "Break In..." window and then pressing enter to select "OK". :) It's really easy. :)

tl;dr: Run 1 CPU cycle via: ctrl+b, enter
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Mesen - NES Emulator

Post by unregistered »

Sour, for some reason, maybe I changed something, when holding left or right before reset... and then resetting... the input becomes like nothing is pressed. After releasing the direction held our character moves in the opposite direction. I bet this is my fault, but I can't find out how to rectify this weirdness. Do you have an idea of what I could have changed to cause this? :?:

This is something I must have done to try to combat a bug that used to be in our game. That bug must have vanished and now Mesen input can be weird. Just found that our game doesn't have this problem when running in FCEUX 2.2.3. :)
Sour
Posts: 891
Joined: Sun Feb 07, 2016 6:16 pm

Re: Mesen - NES Emulator

Post by Sour »

What do you see when you display the input on the screen? (Options->Input->Advanced) As far as I can tell, everything seems to be working properly on my end (the held button stays pressed and works as expected after a reset, without ever letting it go)
unregistered wrote:found that you can get Mesen to run 1 CPU cycle by pressing ctrl+b to bring up the "Break In...
While this works, it's not ideal from a usability perspective, but most of all, it's a bit misleading. Currently the "break in X CPU cycles" option works by breaking X*3 PPU cycles later (which isn't the quite the same). Internally, the debugger can currently only break at the start of X CPU instructions or X PPU cycles - would need to change this to also support X CPU cycles.
Skadiet
Posts: 10
Joined: Sun Jan 14, 2018 7:50 pm

Re: Mesen - NES Emulator

Post by Skadiet »

I may have found a very small inconsistency in the way that Mesen (and apparently other emulators) defaults attribute data relative to the original NES. I was able to test out a game, which I'm currently developing, on original hardware a few nights ago and noticed that my intro screen did not look right. The intro screen was apparently using the attributes from my main game-screen rather than defaulting to all zeros as it had been in Mesen. I was expecting all attribute data to be zero since I was planning on using palette 0 for the entire intro screen. This is largely "programmer-user-error" since I probably should have initialized the attributes for my intro screen (even if they were all zeros), but I just wanted to let you know in case it was something that you were interested in modifying.

Here are the details. I have an NROM game with essentially two screens and vertical mirroring. In my initialization code, I first initialized the palettes. Then, I initialized the attribute data starting at $23C0. I did NOT initialize any attribute data starting at $27C0. Next, I set the PPUCTRL flag to #%10000001 so that the PPU is pointing at the nametable in $2400. Finally, I loaded the intro screen nametable data into $2400 and then the game-screen nametable data into $2000. I know it's kind of backwards (you'd expect the intro screen in $2000) but that's just how it was.

In conclusion, in my example, Mesen appeared to have defaulted the attributes in $27C0 to all zeros because I did not supply it with any data. However, the NES appears to have used the attributes from $23C0 when it displayed the nametable data in $2400. Alternatively the NES could have copied the $23C0 data into $27C0 somehow. Not sure.

I hope you find this helpful.
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: Mesen - NES Emulator

Post by gauauu »

Do you have Mesen set to randomize things on power-on state? Under options -> emulation settings-> advanced there's some options that are helpful to test if you're doing development:

- Enable OAM RAM decay
- Randomize power-on state for mappers
- Default power on state for Ram: Random Values


These will help you test some of those issues with things not be initialized correctly. (which may or may not answer your question, I'm not sure)
Skadiet
Posts: 10
Joined: Sun Jan 14, 2018 7:50 pm

Re: Mesen - NES Emulator

Post by Skadiet »

gauauu wrote:Do you have Mesen set to randomize things on power-on state? Under options -> emulation settings-> advanced
Ah, that may solve it. Will check tonight. Thanks, @gauauu!

Edit: I guess the weird thing on the NES was that it didn’t appear random but rather equal to the other attribute data. Either way, randomizing would have helped me catch this in advance.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Mesen - NES Emulator

Post by unregistered »

Sour wrote:What do you see when you display the input on the screen? (Options->Input->Advanced)
The displayed input on screen helped me to know that the opposite direction is pressed. I have spent around two days on this... stepping through reads from $4016 and can guarantee that that register returns 00 if left or right is pressed and held before reset during input. And then, I think it inverts the lowest two bits after that direction is released and it must clear that bit if that initial direction is pressed again, after every direction pressed, beyond the initial direction press released. But, maybe not exactly like that bc pressing the same direction again halts her.
Sour wrote:As far as I can tell, everything seems to be working properly on my end (the held button stays pressed and works as expected after a reset, without ever letting it go)
Yes, that's exactly what happens in FCEUX 2.2.3. I must have changed something in Mesen's settings.xml file or another file... hmm...

revision.
final revision.

p.s. Sour, is controller 1's input displayed on screen directly affected by values read from $4016? I doubt it is, but if it is that would make sense and provide less $4016 checking for me in the future. :)
Last edited by unregistered on Fri Jan 18, 2019 1:34 pm, edited 3 times in total.
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: Mesen - NES Emulator

Post by gauauu »

Skadiet wrote: Edit: I guess the weird thing on the NES was that it didn’t appear random but rather equal to the other attribute data. Either way, randomizing would have helped me catch this in advance.
Yeah, that's why I'm a little unsure about whether this will help you or not. It's possible something else is happening.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Mesen - NES Emulator

Post by unregistered »

Umm... so I copied the Mesen exe file to a new Mesen folder on a different drive and the Mesen initialization part ran and folders were created... and our game file that I pasted into the new Mesen folder experiences the same problems. However, when running in FCEUX 2.2.3 it always starts without problems. So it must have something to do with Mesen's code... I can't post the .nes file so it's ok, with me at least, if you don't fix this. :)

edit: hmm... maybe my setting the "new" Mesen up in a similar fashion to my original Mesen has something to do with this? Just enabled the Preferences>Advanced>"Disable built-in game database", set up the standard controller's input to work with my nes controller attatched to my CPU via usb, and added the Pause key to also pause the game with Esc.
Last edited by unregistered on Fri Jan 18, 2019 3:34 pm, edited 1 time in total.
Post Reply