Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Thu Apr 16, 2020 3:40 am

Pardon me if this is necro-bumping an old thread. But a feature I am really missing whilst debugging NES code is the ability to do asserts to check registers / memory values.

Adding them using macros to generate code is certainly an option, but it'll increase code size and potentially make branch labels out-of-range as well. It would be far more preferable to have a macro that only changes how the debugger reacts, rather than changing any code.

Seeing how Mesen's debugger already has the ability to:
1. Read CA65 source assembly / .dbg files and associate disassembly with source code
2. Set conditions for breakpoints

...I am thinking the ability to trigger conditional breakpoints based on comments should be relatively easy to add? :)

Something like this:

Code: Select all

ldx MyIndex   ; MESEN_DEBUG_ASSERT(X < 10) - check that index is in range
                     ; MESEN_DEBUG_ASSERT([MyPointer] >= $8000) - check that pointer references ROM

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Fri Apr 17, 2020 3:52 pm

Bananmos wrote:
Thu Apr 16, 2020 3:40 am
...I am thinking the ability to trigger conditional breakpoints based on comments should be relatively easy to add? :)
And you would be correct!

It's not really all fleshed out, but it only took about 15 lines of code to get something decent working:
mesenassert.png
Basically, it looks for a "assert(...)" comment in the code, and adds a (hidden) breakpoint with the opposite condition (so anything that's a valid mesen expression/condition can be added as an assert)
As is, this only works with CA65 integration, though. I should probably make it work with all comments (not just those imported by CA65), to allow this to work with asm6f, etc., too.

Fiskbit
Posts: 120
Joined: Sat Nov 18, 2017 9:15 pm

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Fiskbit » Fri Apr 17, 2020 4:38 pm

Very cool feature. When the assert is on the same line as an instruction, does it check state before or after the instruction? When it's on its own line, does it check after the previous instruction and before the next one?

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Fri Apr 17, 2020 5:13 pm

At the moment it just adds a regular execution breakpoint on the first byte of the instruction - this is identical to clicking on the margin to add a breakpoint and then adding a condition to it. So, it checks the state before running the instruction.

This means you could also use this to add "regular" breakpoints in the source code: "assert(false)" or "assert(0)" will always cause a break. This might be more handy than using stuff like BRK since it doesn't affect execution. So code like:

Code: Select all

;assert(0)
STA $2000
or

Code: Select all

STA $2000 ;assert(0)
would always break before the STA instruction runs.

The logic is the same whether the comment is displayed on the side or above, the only difference here is that mesen displays multi-line comments above a line instead of next to it. In terms of CA65 integration, the source files are parsed and comments above a line (or on the right) are both associated to the same line of code.

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Sat Apr 18, 2020 6:18 am

Wow, what a quick response... and a feature implementation as well!

That already sounds like a great help in debugging... but to be complete for the use-case I'm thinking about, I think what's missing is the ability to use defined expressions from CA65 as conditions.

So that for example you can error-check your bounds by doing:

Code: Select all

MYARRAY:
.db $65, $02
MYARRAY_LENGTH = 2   ; (or possibly even: MYARRAY_LENGTH = * - MYARRAY)
[...]
LDY myIndex,x
LDA MYARRAY,y   ; assert(Y < MYARRAY_LENGTH)
I tried using a constant expression defined in CA65 as input to the breakpoint condition in the debugger, but it looks like it won't accept it.

TBH I could easily make my build system replace any _LENGTH variables found in the .dbg file with their assigned constants to get this feature working... but it sure would be neater to avoid that extra step, as it's already got too many layers of scripting :)

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Sat Apr 18, 2020 11:30 am

Bananmos wrote:
Sat Apr 18, 2020 6:18 am
I think what's missing is the ability to use defined expressions from CA65 as conditions.
With a bit of work, it can work for asserts for CA65:
assertconstant.png
It parses the comment, finds matching constants in the .dbg file and generates a breakpoint with the changed value (e.g Speed = 5 in this case)

Though since I want to generalize this to work for comments in general rather than just CA65, in the end the disassembly would show the comment as "assert(x == 5)" (e.g it would change the comment itself), but I think that's an acceptable compromise. This also wouldn't let you use CA65 constants in expressions (e.g breakpoints or the watch) - the C++ core has no knowledge that CA65 integration is even a thing, so adding something like this would require a lot of work.

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Sat Apr 18, 2020 12:46 pm

Sour wrote:
Sat Apr 18, 2020 11:30 am
Bananmos wrote:
Sat Apr 18, 2020 6:18 am
I think what's missing is the ability to use defined expressions from CA65 as conditions.
With a bit of work, it can work for asserts for CA65:
assertconstant.png
It parses the comment, finds matching constants in the .dbg file and generates a breakpoint with the changed value (e.g Speed = 5 in this case)

Though since I want to generalize this to work for comments in general rather than just CA65, in the end the disassembly would show the comment as "assert(x == 5)" (e.g it would change the comment itself), but I think that's an acceptable compromise. This also wouldn't let you use CA65 constants in expressions (e.g breakpoints or the watch) - the C++ core has no knowledge that CA65 integration is even a thing, so adding something like this would require a lot of work.
That does sound like a fair compromise. :)

And much thanks for pursuing this - it'll save me a ton of time debugging!

Will a build supporting it eventually pop up here?

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Sat Apr 18, 2020 3:29 pm

Bananmos wrote:
Sat Apr 18, 2020 12:46 pm
Will a build supporting it eventually pop up here?
The latest build (0.9.9.25) has support for the asserts (for all comments, not just CA65 integration)
Let me know if you find issues - I haven't tested this a whole ton. :p

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Thu Apr 30, 2020 5:39 pm

Sour wrote:
Sat Apr 18, 2020 3:29 pm
Bananmos wrote:
Sat Apr 18, 2020 12:46 pm
Will a build supporting it eventually pop up here?
The latest build (0.9.9.25) has support for the asserts (for all comments, not just CA65 integration)
Let me know if you find issues - I haven't tested this a whole ton. :p
Finally got around to trying it out... and it works fantastically with both registers and symbols I've tried! This is such a game changer for debugging :D

But I do have another unrelated but likewise hopefully-simple-feature-request though... ;)

The code I end up debugging a lot is sprite drawing code - and I would guess I'm not alone here... all the edge-cases for clipping with the requirements for it to be fast can lead to subtle bugs.

Mesen's sprite viewer has been of great help, as it shows the OAM is a more visual format. But the annoying thing is that I can't actually see that visual presentation of the result until I perform a $4014 DMA to get OAM into the PPU memory. And ideally I'd like to be able to have the sprite viewer show the intermediate result as I'm single-stepping my code.

So I gotta ask... would it be easy enough to add a feature to the OAM viewer that can switch it to sourcing its data from a specific page of CPU memory instead of PPU OAM?

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Thu Apr 30, 2020 7:30 pm

Was already planning on eventually doing something like this for the CHR viewer (to allow it to display PRG ROM as tiles), makes sense to have something similar for the sprite viewer, too.

So, here you go! (next appveyor build will have it)
SpriteViewer.png

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Sun May 03, 2020 7:19 am

Was already planning on eventually doing something like this for the CHR viewer (to allow it to display PRG ROM as tiles), makes sense to have something similar for the sprite viewer, too.

So, here you go! (next appveyor build will have it)
Thanks a lot! Just used this new feature to easily track down an annoying bug triggering when trying to use a metasprites with all 64 sprites. :)

I did run into a few minor issues however:
* The feature that makes the sprite viewer automatically show the pattern table for sprites as set by $2000 is generally convenient. But as my sprite table is at $1000 and I often find myself setting breakpoints in code where $2000 has been temporarily set to zero to disable NMIs, and with no way to override this setting I am left with the wrong tiles showing until I make the debugger stop somewhere else in my code.

* The 2x setting in the PPU viewer looks pretty useful as a means to zoom. But for all the views that stack two pixel images, it ends up being too tall for a 1080p display. OTOH, the widget that end up on the sides are unaffected by the scaling. Have you considered re-arranging the UI to stack the pixel images horizontally and have the widgets on the bottom? It would solve this problem with 1080p screens for everything but the 4x nametable viewer (but with vertical mirroring as I'm using, the lower one is redundant to me anyway and would best be removed completely in 2x mode)

* Sometimes, I accidentally open a new PPU Viewer window despite already having one open, and this appears to cause Mesen to hang and requiring a force kill with the Windows task manager.

None of these features are deal-breaker by any means - just figured I would mention them :)

And this is unrelated to the PPU Viewer, but despite having set the .dbg files to auto-import, Mesen doesn't seem to actually do this. I have to re-load the .dbg file manually every time I do a new build and fire up Mesen.
Do you know what's going wrong here?

The ability to show CHR from PRG-ROM sounds neat feature! Ideally, the format would be semi-configurable, as CHR data in PRG-ROM data often tends to be stored differently to the native format to make unrolled loops more efficient. For example, a common pattern is to have each row / plane in a separate array, to avoid having to increment / decrement the index registers for every byte copied:
WriteScrambledTile:
lda tileDataP0R0,x
sta $2007
[...]
lda tileDataP0R7,x
sta $2007
lda tileDataP1R0,x
sta $2007
[...]
lda tileDataP0R7,x
sta $2007
rts
But I realise this configurability might be difficult to achieve in practice... and could probably only work if the separated arrays are 256-byte-aligned.

Finally, I noticed you just added support for OAM corruption in Mesen. I know it's still a beta feature, but that's really useful! I spent quite a bit of time tweaking my NMI code to stay within the safe hblank region, and have been careful not to touch it since. The event viewer already helps a lot with this, but having the OAM corruption emulated is great to see the effect of it. As expected, the latest forced blanking code I'm prototyping right now causes a flickerfest when turning the feature on... which is a good reminder to myself why it's still prototype code... :P

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Sun May 03, 2020 12:25 pm

I'll add a dropdown/toggle to pick between auto/8px/16px sprites when I have a chance.
Bananmos wrote:
Sun May 03, 2020 7:19 am
* The 2x setting in the PPU viewer looks pretty useful as a means to zoom. But for all the views that stack two pixel images, it ends up being too tall for a 1080p display.
The PPU viewer in general is a bit annoying to deal with, layout-wise. And the 2x zoom option is essentially a patch to allow at least some level of zooming, but as you can tell, it's not ideal.
Ideally I think I would probably split the ppu viewer into separate windows (to not be forced to keep all of them the same size, which limits what I can do quite a bit in terms of layout..), remove the 2x zoom options and instead implement zoom like I did in Mesen-S' viewers (which I ported back to mesen's event viewer a while ago) - basically you can zoom freely with ctrl-+/- or the ctrl+mouse wheel, and then scroll around the picture with click+drag, which in my opinion works a lot better, is less restrictive and is much more flexible in terms of layout. Changing all this isn't what I would call trivial, though..
* Sometimes, I accidentally open a new PPU Viewer window despite already having one open, and this appears to cause Mesen to hang and requiring a force kill with the Windows task manager.
Having too many windows opened (and having them set to refresh at a high FPS) can sometimes cause the windows message queue to get filled with draw requests faster than the application can process them.
I've added some logic over on Mesen-S to try to limit the odds of this ever causing a lockup, though (by reducing the refresh speed based on roughly how long the refreshes are taking.) I'll try to copy that fix over to Mesen soon and let you know.
And this is unrelated to the PPU Viewer, but despite having set the .dbg files to auto-import, Mesen doesn't seem to actually do this. I have to re-load the .dbg file manually every time I do a new build and fire up Mesen.
Is the .dbg file called "myrom.dbg" (not the lack of .nes in the name here) for a rom called "myrom.nes"? Is it in the same folder as the "myrom.nes" file?
Finally, I noticed you just added support for OAM corruption in Mesen. I know it's still a beta feature, but that's really useful!
Glad it's already useful to someone! Like you said, this is very much a work in progress and still doesn't quite react exactly like the hardware does for all scenarios. Are you testing on NTSC? Or PAL? I don't think we've tested/confirmed that this behavior occurs for PAL consoles, yet.

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Mon May 04, 2020 5:52 am

Sour wrote:
Sun May 03, 2020 12:25 pm

Is the .dbg file called "myrom.dbg" (not the lack of .nes in the name here) for a rom called "myrom.nes"? Is it in the same folder as the "myrom.nes" file?
Doh! It was named myrom.nes.dbg... I've updated my built batch script and it seems to work fine now :)
Glad it's already useful to someone! Like you said, this is very much a work in progress and still doesn't quite react exactly like the hardware does for all scenarios. Are you testing on NTSC? Or PAL? I don't think we've tested/confirmed that this behavior occurs for PAL consoles, yet.
It was quite a few years since I did this tweaking to avoid OAM corruption, but it was on an NTSC console. Even longer ago, I primarily used a PAL console, and I'm pretty sure the issue doesn't exist on PAL, as I have no recollection of it ever being a problem.

I think the main gap in PAL emulation is still that the DMC cycle steal emulation is not correctly emulated. If ever there's a suitable test ROM for it I'd be happy to run it on my PAL console.

The test ROM would likely need to be a bit more elaborate than my old demo I posted before, where I was just relying on tweaking delay loops with visual feedback, and all this was way before Blargg's work on sync:ing the NMI to rendering.

Bananmos
Posts: 524
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Bananmos » Sat May 09, 2020 10:04 am

So I'm trying to use the new super-useful assert feature with modulo to check my sprite page index is always divisible by 4, but can't get it to work.

* Doing "assert(Y % 4 == 0)" just plain doesn't do anything. And when I try to type "%" in the debugger, it wont even accept the condition - so guess the modulo operator is not supported yet?

* Doing the common work-around of a bitwise-and with "assert(Y & 3 == 0)" does seem to trigger the assert in the debugger... but even for values that are clearly multiples of 4. So not sure what's going on here?

Would be great to have some way of doing modulo on my asserted values... :)

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

Re: Mesen Debugger - Feedback/Feature Requests? (2018 edition)

Post by Sour » Sat May 09, 2020 10:25 am

Ah, I probably broke the modulo operator back when I added support binary values (e.g "x == %00010001"). Might have to change the operator for one of them, but I'll try and see if it's simple to keep them both in with the '%' operator.

I think the assert(Y & 3 == 0) part is an order of operation problem? It's doing 3 == 0 -> false/0, and then Y & 0, which is always 0, so the assert always triggers. "(Y & 3) == 0" should work, though.

Post Reply