Download v36 from HERE.
Information down below is partially obsolete, refer to README-NintendulatorDX.txt in the release package instead.
---
Because of new features in CC65 I've been able to add a new feature to Nintendulator's debugger. Now it's possible to view the original source code when debugging if the ROM has been assembled with CC65. I'm not sure how much I'm going to be working on this in the future so I'll just release it now. Here's a screenshot:
This was a quick hack so there probably are some bugs in there. Even in its current state I think it's quite useful though.
How to use
Pass the "--dbgfile foo.nes.dbg" switch to linker to generate the debug file. You'll also need to include the debug information in object files using the "-g" switch when assembling/compiling. The debug file has to have the same name as the iNES rom with ".dbg" extension added, for example "foo.nes.dbg".
NOTE! You need to use the latest snapshot version of CC65 because these features do not exist in the stable version.
For now it only works with iNES roms! Also it will not work if the linker config outputs to more than one file.
How to use the cycle counting timers
Write to $402x to start the timer and $403x to stop it (where x is the timer ID 0-15). $401E/$401F are aliases for $4020/$4030 (for VirtuaNES compatibility). Timer title can be specified with a symbol named "__timerX_title" which points to the zero padded timer title.
Now, one important thing about the timers. If you do STA $4020 followed by STA $4030 it'll report 0 cycles, so the STA cycles don't count. But it also subtracts 4 cycles from all running counters when nested timers are used. For example:
Code:
; this code will report 0 cycles for both timers!
sta $4020
sta $4021
sta $4030
sta $4031
Here are couple of macros for CA65:
Code:
.macro start_timer timer
sta $4020+timer
.endmacro
.macro stop_timer timer
sta $4030+timer
.endmacro
.macro timer_title timer, title
.ident(.sprintf("__timer%d_title", timer)):
.byte title, 0
.endmacro
How to use debug output feature
This feature allows you to do "printf" style debugging from your applications. It works like this: when the emulator detects a write to $4040, it reads a string from PC+3 and outputs it in the debug window. This feature can thus be used from any assembler. Some simple number formatting is also supported.
Some helper macros for CA65:
Code:
.macro debugOut str
.local over
sta $4040
jmp over
.byte str, 0
over:
.endmacro
.define fHex8( addr ) 1, 0, <(addr), >(addr)
.define fDec8( addr ) 1, 1, <(addr), >(addr)
.define fHex16( addr ) 1, 2, <(addr), >(addr)
.define fDec16( addr ) 1, 3, <(addr), >(addr)
Some usage examples:
Code:
.zeropage
some_var: .res 2
other_var: .res 1
.code
entry:
lda #$34
sta some_var
lda #$12
sta some_var+1
debugOut {"entry point reached, some_var = ", fHex16{some_var}, ", isn't that exciting?"}
lda #123
sta other_var
debugOut {"other var is ", fDec8{other_var}, " in decimal"}
Here's a helper macro for C language:
Code:
#define DEBUG_OUT( str ) \
do { \
( ( void __fastcall__ ( * )( void ) )"\x8D\x40\x40\x60\xEA\xEA" str )(); \
} while ( 0 )
Using it is simple: (NOTE! The parameter has to be a string literal.)
Code:
DEBUG_OUT( "Testing NintendulatorDX debug output from CC65!" );
Unfortunately it's not possible to output the values of variables from C code at this time.
How to use the .proc/.scope profiling feature
This feature allows you to find out how many cycles each .proc/.scope is taking in your program. It works by keeping count of number of cycles taken by each value of the PC register, and writes out the results in a file named "<romname>.nes.profiling.txt" when the ROM is unloaded.
Write to $4041 to start collecting profiling data, and $4042 to stop. You don't have to write to $4042 if you want the data collecting to end when the ROM is unloaded. If you simply want to collect data for the entire run of the program, write to $4041 somewhere in your reset routine.
Currently the feature does NOT support banking, so if you use banked ROMs with it you will get erroneous results.
The results are something like this:
Code:
[module general.o]: 4328012 (91.6 %)
init: 89352 (2.06 %)
detectSystem: 60556 (1.4 %)
initVariables: 44 (0.00102 %)
reset: 2771377 (64 %)
setPalette: 24 (0.000555 %)
updateControllerState: 4903 (0.113 %)
nmi: 1401756 (32.4 %)
irq: 0 (0 %)
This tells us that 91.6% of processing time was spent in the module general.o, and out of those 4328012 cycles 1.4% was spent in the routine detectSystem, and so on. In other words, the percentages on the higher levels are always relative to the parent.
Downloads
Emulator + mappers (Unicode, Win2K/XP/Vista/7): http://kkfos.aspekt.fi/downloads/ninten ... x-0.33.zip
I have included a compatible version of the CC65 snapshot in the above package.
That should be all for now.
EDIT: Now supports bankswitching, updated download links.
EDIT: Added the screenshot as an image instead of link
EDIT 2011-01-05: Added some features, updated link to v0.20.
EDIT 2011-02-04: Added a note below CC65 snapshot link
EDIT 2011-02-26: Pulled latest version of Nintendulator from SourceForge SVN and applied the updates, the new version includes timer support, download link updated
EDIT 2011-03-27: Updated to version 0.26, shows init and play cycles for NSF, some bugs fixed
EDIT 2011-07-06: Version 0.27
EDIT 2011-08-03: Version 0.28. Preliminary support for debug messages. Sources added to the package.
EDIT 2011-09-12: Version 0.33. Includes proc/scope profiling support.
EDIT 2012-03-23: Added an example of using the debug output feature from C code.
Awesome. That really looks like a useful feature. I may try it soon, but not for while since I'm involved in several assembly projects with ASM6. I am interested though.
Bankswitching code is now supported. Once again you'll need to update CC65 to the latest snapshot version. Next up is probably some kind of watch window for variables.
I've updated the download links in the first post.
thefox wrote:
Bankswitching code is now supported. Once again you'll need to update CC65 to the latest snapshot version. Next up is probably some kind of watch window for variables.
I've updated the download links in the first post.
Heh, I see what you did there....
neilbaldwin wrote:
thefox wrote:
Bankswitching code is now supported. Once again you'll need to update CC65 to the latest snapshot version. Next up is probably some kind of watch window for variables.
I've updated the download links in the first post.
Heh, I see what you did there....
I'm not sure I do though.
...
Anyways I've added a variable watch feature to this thingaling now. Screenshot:
Still needs some work:
1) reading from memory
2) modifiers for the input string, something like "velocity,word" would instruct it that "velocity" is a pointer to a 16-bit value, or even more complex expression parsing
Downloads will come later. Probably.
I worked a little bit on this again. Now the watch list can retrieve and display values from memory. Data size can also be specified (byte/word), e.g. "foo,w" adds a watch on symbol "foo" which points to a 16-bit word. "foo,b" and "foo" are equivalent. Should probably add support for 32-bit and fixed point variables in the future.
Expression parser would be nice.. so you could do stuff like "sprites+20" or "$123+55,w".
EDIT: Forgot to mention, it's also possible to double click on the source listing to set a breakpoint.
Known bugs:
- watch list is not cleared when a new ROM is loaded (need to restart Nintendulator)
Download link for v0.20 is in the first post.
Does this only work with CC65? I mean as opposed to working with CA65?
Probably a dumb question
It's good to see that it's moving forward. Hope I can find the time to program on the nes again someday and use it.
If I had time, what I would like to do is instead of adding all the new information inside nintendulator, I would like instead to "attach to the nintendulator process" from a custom IDE. The concept is similar to Visual studio remote debugging. This way, that would remove the clutter of the "one screen debugger" that I don't like. Soon it will become a mess and won't be manageable. Maybe I will have time someday to build that idea. I think that would be the best solution.
And ideally, an emu supporting remote debugging would support the same protocol as
existing remote debug tools, which would let programmers use IDEs that they may already know to debug NES code.
neilbaldwin wrote:
Does this only work with CC65? I mean as opposed to working with CA65?
Probably a dumb question
Works with CA65 (as you can see assembly code listing is displayed in the screenshots). When I'm talking about CC65 I mean the complete package (assembler, linker, archiver etc), not just the C compiler.
Banshaku wrote:
It's good to see that it's moving forward. Hope I can find the time to program on the nes again someday and use it.
If I had time, what I would like to do is instead of adding all the new information inside nintendulator, I would like instead to "attach to the nintendulator process" from a custom IDE. The concept is similar to Visual studio remote debugging. This way, that would remove the clutter of the "one screen debugger" that I don't like. Soon it will become a mess and won't be manageable. Maybe I will have time someday to build that idea. I think that would be the best solution.
I agree, that kind of feature would be very nice. Actually it's not the first time that the topic has been brought up in here. But it's a lot of work for (relatively) little gain in functionality.
Like I said, probably a dumb question.
OK, next question that isn't a dumb question: can you make Nintendulator support NES2.0 so that you can have ROM/mapper configurations that use >8KB of NVRAM (like SXROM)?
(Though if you're not involved in making Nintendulator then it probably is a dumb question.
)
Oh and, my build file creates several .o files that are linked together into one ROM. Does that mean this will work with your tool?
Sorry for all the questions: I really like the prospect of this but I really don't have the time to be distracted by it if it's not going to work with my project. That's not your fault, I know
neilbaldwin wrote:
:) Like I said, probably a dumb question.
OK, next question that isn't a dumb question: can you make Nintendulator support NES2.0 so that you can have ROM/mapper configurations that use >8KB of NVRAM (like SXROM)?
I could and might at some point, but it's probably better to e-mail Quietust about it. He's still the sole official developer, I just grabbed the source and hacked away.
neilbaldwin wrote:
Oh and, my build file creates several .o files that are linked together into one ROM. Does that mean this will work with your tool?
Yeah it will work. What I meant in the first post was that you can't have separate output files like "header.bin" and "code.bin" which are concatenated later. Output must be directly to iNES ROM (code assumes that segment output offsets include the 16 byte header.. this is needed for bankswitching calculations).
Quote:
Sorry for all the questions: I really like the prospect of this but I really don't have the time to be distracted by it if it's not going to work with my project. That's not your fault, I know
Questions are fine.
thefox wrote:
I could and might at some point, but it's probably better to e-mail Quietust about it. He's still the sole official developer, I just grabbed the source and hacked away.
Do you know him? If so, a friendly word would be helpful
neilbaldwin wrote:
thefox wrote:
I could and might at some point, but it's probably better to e-mail Quietust about it. He's still the sole official developer, I just grabbed the source and hacked away.
Do you know him? If so, a friendly word would be helpful
Nope, not really.
neilbaldwin wrote:
thefox wrote:
I could and might at some point, but it's probably better to e-mail Quietust about it. He's still the sole official developer, I just grabbed the source and hacked away.
Do you know him? If so, a friendly word would be helpful
Sadly, Q disappeared from the forums abruptly after a rather strange interaction. Hopefully he's still lurking here, but I wouldn't expect him to respond to any messages here on Nesdev.
That's a shame.
Well, if he is lurking or anyone is in contact with him I'd love to discuss the possibility of making the changes I mentioned.
PM me through here or email me;
neil@ntrq.net
The biggest PITA is that I can't get it to work under any virtual machine I have. Really don't feel like installing windows for real just so I can run this.
And nevermind. Found a bug where the window is invisible. The workaround is to right click on the taskbar and select maximize.
Also wanna add thank you so much for this. Feel like I'm coding with sanity again since I can debug at my source code.
I worked on timer support yesterday. Timers allow you to count and display CPU cycles between two blocks. Currently it's implemented using special registers: $401E/$401F control timer 0 (VirtuaNES compatible) and $402x/$403x control 16 additional timers.
I might change it to use specially named symbols instead. So you'd define a symbol named timer1_start/timer1_end or something. Currently it can't be made to work properly with bank switching though. Also a symbol could be exported to define a name for a timer. Or the names could be read from text file... or entered in the debugger. I'm not sure what would be the best way.
Now if Uz only would implement those damn line infos for .repeat blocks and macros in CC65... I would be one happy camper.
Also note to self: need to fork Nintendulator from SourceForge SVN instead of working on a static copy.
ManicGenius wrote:
And nevermind. Found a bug where the window is invisible. The workaround is to right click on the taskbar and select maximize.
Bug in Nintendulator? Can you elaborate? What window?
Quote:
Also wanna add thank you so much for this. Feel like I'm coding with sanity again since I can debug at my source code.
I know what you mean, when you're used to proper debugging tools there's no going back. Surprisingly many developers (all around, not just NesDev) are very ignorant about this and resort to "printf debugging" instead.
Sometimes when starting Nintendulator the main window will not show up (either it's hidden or the initial position is offscreen somehow). It then takes maximizing it from the task bar to get it visible at all. Selecting a size from the PPU menu will unmaximize it without making it invisible again.
I don't think I've had the problem, however, since I started using the most recent Unicode binary. I'm running 64bit Windows 7. Using the ASCII binary, Windows will switch my desktop theme saying the program doesn't support it.
(For some reason, whenever I download Nintendulator, I tend to download the wrong one. I always get rather confused by the layout of the website, even though it was obviously designed to be simple.)
Two other random things! It stores the palette settings (NTSC slider values) in the registry, which makes it really hard to reset if you don't remember the initial value. I deleted all the registry entries for Nintendulator, but then the palette still didn't look quite right.
Also, kind of a nitpick, but the menu item that shows the "Debug Information" window should probably toggle it rather than do nothing when the window is already displayed.
Non-Unicode binaries are for Windows 95, Windows 98, and Windows ME. If you're running an NT-based operating system (Windows 2000, Windows XP, Windows Vista, or Windows 7), get the Unicode one.
tepples wrote:
Non-Unicode binaries are for Windows 95, Windows 98, and Windows ME. If you're running an NT-based operating system (Windows 2000, Windows XP, Windows Vista, or Windows 7), get the Unicode one.
Issue happens regardless of binary type.
thefox wrote:
I know what you mean, when you're used to proper debugging tools there's no going back. Surprisingly many developers (all around, not just NesDev) are very ignorant about this and resort to "printf debugging" instead.
Printf debugging has it's place, but usually only for hard bugs where throw/catch clauses will work. For soft bugs, printf debugging is a nightmare.
Hangin10 wrote:
Sometimes when starting Nintendulator the main window will not show up (either it's hidden or the initial position is offscreen somehow). It then takes maximizing it from the task bar to get it visible at all. Selecting a size from the PPU menu will unmaximize it without making it invisible again.
Thanks for elaborating, however I want to stress this is not an official Nintendulator support thread or anything and I'm probably not going to fix any of these general type bugs (unless I really feel like it
).
It sounds like it starts offscreen, have you tried right clicking on it in taskbar and selecting "Move"? (On Win 7 you have to Shift+Right Click). Then you can move the Window with arrow keys and after first key press you can also move with mouse.
ManicGenius wrote:
Printf debugging has it's place, but usually only for hard bugs where throw/catch clauses will work. For soft bugs, printf debugging is a nightmare.
Yes, there are times when it's OK, or the only option even.
thefox wrote:
I might change it to use specially named symbols instead. So you'd define a symbol named timer1_start/timer1_end or something. Currently it can't be made to work properly with bank switching though. Also a symbol could be exported to define a name for a timer. Or the names could be read from text file... or entered in the debugger. I'm not sure what would be the best way.
I worked around the bank switching problem by prefixing the timer title with a signature (like __timer1_title__), ANDing the symbol address with $FFF and checking all 4K banks for the signature. Works well enough, so now I have nice titles for all my timers. Quite useful.
thefox wrote:
Yes, there are times when it's OK, or the only option even.
Yeah, tell me about it
thefox wrote:
thefox wrote:
I might change it to use specially named symbols instead. So you'd define a symbol named timer1_start/timer1_end or something. Currently it can't be made to work properly with bank switching though. Also a symbol could be exported to define a name for a timer. Or the names could be read from text file... or entered in the debugger. I'm not sure what would be the best way.
I worked around the bank switching problem by prefixing the timer title with a signature (like __timer1_title__), ANDing the symbol address with $FFF and checking all 4K banks for the signature. Works well enough, so now I have nice titles for all my timers. Quite useful.
Awesome... this debug tool just gets better and better
What I'd love to see is a way to open listing files (.LST) in a debugger, and get source level debugging from those. Just suggesting listing files because they don't need any reassembly, just identification of addresses to line numbers, and those are already in the file.
Although, embedding ASM6 into an emulator seems like it would be easy as well.
Woohoo! Just found out that the latest development build of Nintendulator now supports NES2.0 and 32KB .sav files.
Many thanks to Quietust, if he's reading
Now, all I need is the fox to add these debugging features to the latest unstable build of Nintendulator and maybe I can finally fix these bugs and get PR8 released.
Just sayin' ...
neilbaldwin wrote:
(...) Nintendulator now supports NES2.0 and 32KB .sav files.
- How is that possible? 32k at $6000-$7FFF is certainly bank switched. Could someone explain me, plz?
Zepper wrote:
32k at $6000-$7FFF is certainly bank switched. Could someone explain me, plz?
Have a
wiki page or
two.
Dwedit wrote:
Although, embedding ASM6 into an emulator seems like it would be easy as well.
NESICIDE has source-level debug capability. The assembler within NESICIDE is an ASM6 remake, and NESICIDE has a built-in emulator.
I'm going to try to put together a video of it's source-level debugging capabilities, but I'm more into working on the tool (adding symbol watching, etc.) and am a total n00b at making videos...
Did notice a peculiarity with this, it doesn't descend into macros. Issue for me mostly cause I use a lot of macros.
ManicGenius wrote:
Did notice a peculiarity with this, it doesn't descend into macros. Issue for me mostly cause I use a lot of macros.
ManicGenius wrote:
Did notice a peculiarity with this, it doesn't descend into macros. Issue for me mostly cause I use a lot of macros.
I have mentioned this in previous posts. It's a CA65/LD65 problem. Nothing I can do about it, unfortunately, short of adding that functionality to CC65 myself, which is not an easy task at all.
.repeat/.endrepeat blocks have the same problem.
thefox wrote:
ManicGenius wrote:
Did notice a peculiarity with this, it doesn't descend into macros. Issue for me mostly cause I use a lot of macros.
I have mentioned this in previous posts. It's a CA65/LD65 problem. Nothing I can do about it, unfortunately, short of adding that functionality to CC65 myself, which is not an easy task at all.
.repeat/.endrepeat blocks have the same problem.
I'm happy to let you know that Uz has fixed this now, download the latest snapshot of CC65 to get the fixed version. It needs some additional work to be perfect (would be helpful to be able to display the macro invocation line also), but I think it makes a better default than the old "only use the invocation line" behaviour.
Does this latest snapshot work with your debugging extensions?
neilbaldwin wrote:
Does this latest snapshot work with your debugging extensions?
Yup.
EDIT:
neilbaldwin wrote:
Woohoo! Just found out that the latest development build of Nintendulator now supports NES2.0 and 32KB .sav files.
Many thanks to Quietust, if he's reading
Now, all I need is the fox to add these debugging features to the latest unstable build of Nintendulator and maybe I can finally fix these bugs and get PR8 released.
Yeah, I'll do this once I get around to forking it from the SVN.
thefox wrote:
neilbaldwin wrote:
Does this latest snapshot work with your debugging extensions?
Yup.
EDIT:
neilbaldwin wrote:
Woohoo! Just found out that the latest development build of Nintendulator now supports NES2.0 and 32KB .sav files.
Many thanks to Quietust, if he's reading
Now, all I need is the fox to add these debugging features to the latest unstable build of Nintendulator and maybe I can finally fix these bugs and get PR8 released.
Yeah, I'll do this once I get around to forking it from the SVN.
Please, please, please do
Just to let any new users (and those who keep updating their CC65) know:
As of 2011-02-04 the latest snapshot doesn't work with current release (v0.20) because the debug file version was bumped up to 1.1 with new features and the old parser doesn't know how to parse it (and only checks the major part of the version number, so it'll TRY to parse it, and fail). I'll release a new version soon.
The update allows me to display both the macro invocation line and the macro body, so I guess I'll try to add that functionality next. I'm not yet sure what would be the best way to display nested macros. Kinda would like to get rid of the Win32 dialogs and use something more flexible.
Download link updated in the first post to
v0.25. I applied all changes from Nintendulator SourceForge SVN repo, so that should include all that NES2.0 stuff and so on. I set up my stuff so that it should be more straightforward to keep this thing updated with SF SVN from now on. I really didn't test this at all and can't remember if I left some bad bugs in there so report any crashes/strange stuff.
This release also supports the cycle counting timers I was talking about before. Here's how it works: Write to $402x to start the timer and $403x to stop it. $401E/$401F are aliases for $4020/$4030 (for VirtuaNES compatibility). Timer title can be specified with a symbol named "__timerX_title" which points to byte sequence "__timerX__" followed by zero padded timer title.
Now, one important thing about the timers. If you do STA $4020 followed by STA $4030 it'll report 0 cycles, so the STA cycles don't count. But it also subtracts 4 cycles from all running counters when nested timers are used. For example:
Code:
; this code will report 0 cycles for both timers!
sta $4020
sta $4021
sta $4030
sta $4031
Oh another important thing, the timers are never reseted to 0 so you must restart Nintendulator for that. Of course I'll make them reset on power off/reset later but not interested in working on this now.
Here are couple of macros for CA65:
Code:
.macro start_timer timer
sta $4020+timer
.endmacro
.macro stop_timer timer
sta $4030+timer
.endmacro
.macro timer_title timer, title
.ident(.sprintf("__timer%d_title", timer)):
.byte title, 0
.endmacro
EDIT: Removed identifier string from timer_title macro.
Dwedit wrote:
What I'd love to see is a way to open listing files (.LST) in a debugger, and get source level debugging from those. Just suggesting listing files because they don't need any reassembly, just identification of addresses to line numbers, and those are already in the file.
Forgot to reply to this. What benefit would this offer over displaying the actual source code?
Do .lst files expand .repeat and macros differently from source files?
tepples wrote:
Do .lst files expand .repeat and macros differently from source files?
As far as I can tell they don't expand at all in listing files. Also it only displays the first 12 bytes of the expanded data.
When I set all of this up, run the ROM and step the debugger the application throws a std::length_error exception. Is this because I am using a CC65 snapshot from 02/27/2011? I saw on page 3 of this thread that as of 02/04/2011 the CC65 snapshot did not work with this patch, but there was no mention if version 0.25 fixed this or not.
Does the FTP link for the CC65 snapshot in the first post point to the proper (older) version? If not where can I get the right version?
qbradq wrote:
When I set all of this up, run the ROM and step the debugger the application throws a std::length_error exception. Is this because I am using a CC65 snapshot from 02/27/2011? I saw on page 3 of this thread that as of 02/04/2011 the CC65 snapshot did not work with this patch, but there was no mention if version 0.25 fixed this or not.
Does the FTP link for the CC65 snapshot in the first post point to the proper (older) version? If not where can I get the right version?
Yes 0.25 fixed the compatibility problems, this must be some other bug. The FTP link in the first post is to the CC65 snapshot folder which always has the latest nightly build, so it's fine. Does it show any additional info with the exception?
If you want to share the .dbg file and the .nes ROM that produce that exception you can send them to e-mail address thefox (at) aspekt.fi
There are no other details as there are no debugging symbols in the executable. The stack trace is just a bunch of hex offsets
One suspicion I had was that I had unused segments defined in the object file. I corrected that but it made no difference.
You may download a zip file with the .nes, .nes.dbg and .o files
here. The linker config outputs a single object file per your instructions.
The source tree is not needed for this to occur.
Steps to reproduce:
1. Extract ZIP file contents to a directory.
2. Load the .nes file with your patched Nintendulator binary (dated 02/26/2011)
3. Open the debugger window
4. Click the "Run" button
5. Click the "Step" button
6. Badness ensues
qbradq wrote:
Steps to reproduce:
1. Extract ZIP file contents to a directory.
2. Load the .nes file with your patched Nintendulator binary (dated 02/26/2011)
3. Open the debugger window
4. Click the "Run" button
5. Click the "Step" button
6. Badness ensues
I can't reproduce this for some reason, it doesn't crash here. Did you try it without the source files?
EDIT: BTW, the stack trace + any additional info would be helpful even if it only displays hex addresses
Ok, so here's a head scratcher. When I start the program, then use the Open menu to open the ROM it works fine. However, if I start the program with the ROM file as the first command line argument the issue does appear.
I can work around this but it kinda throws my dev cycle off. I have a build script that loads the ROM in the emulator on a successful build. Would you mind to see if you can reproduce it this way?
qbradq wrote:
Ok, so here's a head scratcher. When I start the program, then use the Open menu to open the ROM it works fine. However, if I start the program with the ROM file as the first command line argument the issue does appear.
I can work around this but it kinda throws my dev cycle off. I have a build script that loads the ROM in the emulator on a successful build. Would you mind to see if you can reproduce it this way?
Yes I was able to reproduce it, it was a stupid bug. The code which stripped the ROM path was assuming there was at least one / or \ in the path. Download
http://thefox.aspekt.fi/nintendulator-bugfix.zip and extract to v0.25 folder to get the (hopefully) fixed version (this zip doesn't contain the mapper files).
Cool man, thanks for the quick turn-around. I really appreciate it! Thank you again for all of your hard work on this. I am sure it will save me a bunch of time in development.
I'd also like to let you know this was the only thing that convinced me to learn ca65 and ld65. Now that I have I wouldn't dream of going back
qbradq wrote:
Cool man, thanks for the quick turn-around. I really appreciate it! Thank you again for all of your hard work on this. I am sure it will save me a bunch of time in development.
No problem, thanks for reporting the bug!
Quote:
I'd also like to let you know this was the only thing that convinced me to learn ca65 and ld65. Now that I have I wouldn't dream of going back
I know, right?
Btw one "bug" with this version is that the way it behaves with macro line infos is kind of random. Since CC65 now supports multiple line infos for one macro address (line info for the macro invocation line, the actual macro body line and additional line infos for nested macros), it'll always pick the first one that the dbginfo API returns. This is sometimes the invocation line, sometimes one in the macro body, and sometimes might be something else. I didn't bother fixing this yet since I don't know what would be the best way to handle it.
EDIT: there's something seriously wrong with clicking on the source code listing to set a breakpoint in the latest release, I guess the new SVN updates broke it... EDIT2: fixed
I'll release the fix later with a new version.
Version 0.26 released with the above bug fixes applied. Also displays init and play cycle counts for NSFs.
Thank you for your continued work on this thefox! I have been using this daily and it's a huge help.
every time i load a state, the mode changes from ntsc, pal, or hybrid. anyone else getting this bug?
yesyesyall wrote:
every time i load a state, the mode changes from ntsc, pal, or hybrid. anyone else getting this bug?
I don't think this is a bug. The bug was that it DIDN'T change the mode in previous versions of Nintendulator. So what you're experiencing is the proper behaviour. Also this fix was made by Q, not by me.
ah, okay! thanks! is there a simple way i can stop that, or would it require surgery? i can revert to older versions, but i LOVE everything about my current version except for that little thing.
yesyesyall wrote:
ah, okay! thanks! is there a simple way i can stop that, or would it require surgery? i can revert to older versions, but i LOVE everything about my current version except for that little thing.
I don't see why that feature would bother you... IF it always switches PPU mode to the next mode when loading, then you're using an older version which had a bug. This is not the proper behaviour I was talking about.
oh, okay. yeah, it does. every time i press F8, it loads the state, but also automatically switches PPU mode one down. (for example, if i am in PAL and load a state, the state is loaded and the mode is switched to Hybrid. if i am in hybrid, the state is loaded and 'wraps around' to NTSC mode.)
yesyesyall wrote:
oh, okay. yeah, it does. every time i press F8, it loads the state, but also automatically switches PPU mode one down. (for example, if i am in PAL and load a state, the state is loaded and the mode is switched to Hybrid. if i am in hybrid, the state is loaded and 'wraps around' to NTSC mode.)
Yeah then you're using an old version. Get the latest dev build from the official Nintendulator site or my debug extension version from the first post in this thread.
Also, just to remind everybody, this still isn't a generic Nintendulator support thread.
thefox wrote:
I worked on timer support yesterday. Timers allow you to count and display CPU cycles between two blocks. Currently it's implemented using special registers: $401E/$401F control timer 0 (VirtuaNES compatible) and $402x/$403x control 16 additional timers.
Would you mind to put that in the top post or the read me or something? I have to go digging through this post every time I wan to use them
This is a really great feature that has really helped me a lot.
qbradq wrote:
thefox wrote:
I worked on timer support yesterday. Timers allow you to count and display CPU cycles between two blocks. Currently it's implemented using special registers: $401E/$401F control timer 0 (VirtuaNES compatible) and $402x/$403x control 16 additional timers.
Would you mind to put that in the top post or the read me or something? I have to go digging through this post every time I wan to use them
This is a really great feature that has really helped me a lot.
Sure, done.
Thanks man! Helpful macros too!
Just an FYI to anybody who has been trying this out in the last couple of weeks or wants to do so in the future:
Because of recent changes in CC65, if you use the latest snapshot of CC65, NintendulatorDX won't work correctly (you'll get errors in the Debug Information window). A temporary fix is to use an older snapshot (which unfortunately isn't available for download anywhere).
This is all good in the long run though, as CC65 debug file now supports segment (= banking) and size info for symbols. This means you'll no longer need to type ",w" after symbol names to display 16-bit data as long as the size info is available. It also opens some options for profiling since the size of .proc blocks is known... I hope to put out a new version this month.
Big thanks to Uz (the author of CC65) for adding all the new features in CC65!
Good to see that this project is moving forward. I didn't touch a line of code in a while so didn't try it yet. Hope I will be able someday.
I guess I must be repeating myself. getting older
Banshaku wrote:
Good to see that this project is moving forward. I didn't touch a line of code in a while so didn't try it yet. Hope I will be able someday.
I guess I must be repeating myself. getting older
Thanks!
Here's the latest version:
http://kkfos.aspekt.fi/downloads/ninten ... x-0.27.zip
The fixes/changes are:
- works with the latest CC65 snapshot
- timer titles no longer need to be prefixed with the ASCII identifier
- watch window will try to automatically set the symbol size (byte/word)
- diagnostics will be shown in two cases: 1) if absolute addressing is used when zero page could have been used (can happen by accident) 2) if an unitialized memory location is accessed, i.e. one that is read before a value has been written to it after reset/power on
Yes yes... I know there are some legitimate applications to using absolute addressing for zero page addresses (timing stuff) and reading seemingly uninitialized memory (detecting power on/reset). Maybe I'll add an option to turn the feature off later if people find it too annoying.
Looks like the debug format change on the latest snapshot of CC65. When I try to load my ROM I get messages like the one below.
Error:
Code:
Debug info error on line 8227: Unexpected input token 27
Line:
Code:
sym name="_graphics_chr",value=0x0,addrsize=absolute,type=label,segment=6
If I remove the ",segment=6" bit from the end it works.
I also get this error:
Code:
Debug info error on line 8292: Unexpected input token 28
For this line:
Code:
sym name="L0280",value=0x814C,addrsize=absolute,type=label,size=3,segment=0
And it works if I remove the ",size=3,segment=0" part.
qbradq wrote:
Looks like the debug format change on the latest snapshot of CC65. When I try to load my ROM I get messages like the one below.
Works fine here. Are you sure you're using the latest version of NintendulatorDX (v0.27)? v0.26 had this problem.
Ack! My bad TheFox. I thought that was the problem yeseterday, so I downloaded your latest version. Too bad I forgot to unpack the new version
Works like a charm.
Version 0.28 released. Download link is in the first post.
Changes:
- Preliminary support for debug messages
- Sources added to the package because somebody ratted my violation of GPL to Quietust... just kidding, no hard feelings. :=) I was going to release the source at some point anyways.
How to use debug output feature
This feature allows you to do "printf" style debugging from your applications. It works like this: when the emulator detects a write to $4040, it reads a string from PC+3 and outputs it in the debug window. This feature can thus be used from any assembler. Some simple number formatting is also supported.
Some helper macros for CA65:
Code:
.macro debugOut str
.local over
sta $4040
jmp over
.byte str, 0
over:
.endmacro
.define fHex8( addr ) 1, 0, <(addr), >(addr)
.define fDec8( addr ) 1, 1, <(addr), >(addr)
.define fHex16( addr ) 1, 2, <(addr), >(addr)
.define fDec16( addr ) 1, 3, <(addr), >(addr)
Some usage examples:
Code:
.zeropage
some_var: .res 2
other_var: .res 1
.code
entry:
lda #$34
sta some_var
lda #$12
sta some_var+1
debugOut {"entry point reached, some_var = ", fHex16{some_var}, ", isn't that exciting?"}
lda #123
sta other_var
debugOut {"other var is ", fDec8{other_var}, " in decimal"}
Nice, with an alternate macro that could work on NES too (printing through the controller port to a terminal) - with a significant speed penalty though, if execution time matters.
Memblers wrote:
Nice, with an alternate macro that could work on NES too (printing through the controller port to a terminal) - with a significant speed penalty though, if execution time matters.
Yeah, I initially intended to supply just a single register to handle character output to the terminal, and let the 6502 side handle all formatting, but opted for this because it takes constant time. Still need to add some more formatting options.
Version 0.33 released. Download link in the first post as usual.
Changes are:
- Modified to work with the latest version of CC65 snapshot (I also included this snapshot in the package).
- .proc/.scope profiling information can be collected (see first post).
- Better support for multiple line infos from the same line.
The profiling feature is very useful/cool IMO. As long as your functions are wrapped in .proc/.endproc, you simply have to write to $4041 (to enable profiling) to get an idea where the hotspots are in your program.
Is there a way to disable the Debug Information Window from popping up at start up?
JeffAMX wrote:
Is there a way to disable the Debug Information Window from popping up at start up?
Simply close it and it shouldn't pop up the next time you open the app.
I'm having problems getting it to work
I'm using both the emu and CC65 builds attached to the first post.
The debug information log says the debug info is loaded, however when I start stepping through the disassembly the boxes on the bottom (combobox and list) are blank.
I tried changing the paths on the generated .dbg file from relative to absolute, but it was irrelevant.
Any ideas?
Thanks in advance.
zlash wrote:
I'm having problems getting it to work
I'm using both the emu and CC65 builds attached to the first post.
The debug information log says the debug info is loaded, however when I start stepping through the disassembly the boxes on the bottom (combobox and list) are blank.
I tried changing the paths on the generated .dbg file from relative to absolute, but it was irrelevant.
Any ideas?
I can take a look at it if you send me the ROM and the .dbg file. My email is thefox (at) aspekt (dot) fi.
Thanks for your help! However, looking again at the files before sending them, I found that there were no problems other than my own stupidity.
I overlooked a part of my build script and forgot to add -g when creating the objects. Fixed it, and now everything works as expected.
Now debugging is 38.5%(Not scientifically corroborated) more convenient!
Great work!
Ok, I know it's a little nit-picky, but was it really necessary to put the timer regs in the same place as the FDS regs when there's a hundred other places they could have been?
Also, it doesn't work in Wine at all. Not that you probably care.
Karatorian wrote:
Also, it doesn't work in Wine at all.
"FCEUX. Because Nintendulator is
Java-trapped."*
* The name's origin is historic. Technically, programs written in Java are no longer Java-trapped, but the problem of free programs that work only on a non-free platform continues.
Karatorian wrote:
Also, it doesn't work in Wine at all. Not that you probably care.
You could try the
Linux build of NESICIDE which is capable of source level debugging, also. Get/install the three .deb packages from the link.
I'll have to look into NESTICIDE, I've been wishing for an emulator with debugging support for some time now.
FCEUX is actually pretty useless on un*x, because the debugger UI is Windows only.
Karatorian wrote:
FCEUX is actually pretty useless on un*x, because the debugger UI is Windows only.
As long as un*x runs on an x86 CPU, FCEUX for Windows works fine in Wine without sound, except closing the Hex Editor will crash FCEUX. I have no problem with FCEUX in Wine on Xubuntu 11.10; what problem did you run into?
Actually, I never tried it in Wine. I used native builds.
Karatorian wrote:
Ok, I know it's a little nit-picky, but was it really necessary to put the timer regs in the same place as the FDS regs when there's a hundred other places they could have been?
Didn't know the FDS regs were there.
Feel free to modify the source to change them.
I've added an example of using the debug output feature from C code in the first post. It doesn't support outputting variable values just yet though.
I added banking support to the proc/scope profiling feature yesterday, it's pretty cool. Release will come later...
I've started working on bolting Lua support to NintendulatorDX. My vision about it is a little bit different than the way FCEUX handles it. I want to embed Lua code in to the ROM, so that it can be used for 1) runtime asserts 2) prototype code 3) debug output, among other things.
At the moment I have two macros that work like this:
Code:
luaExecStr "NDX.print( 'foo' .. 12345 )"
luaExecFile "src/lua-test.lua"
Now the hardest part is coming up with a nice way for the Lua code to interface the emulator. I first thought about copying the interface from FCEUX (which I believe copied at least parts of it from Snes9x), but I think I'll come up with my own one instead. Or maybe both, so I can get compatibility with Lua scripts made for FCEUX.
The main motivation for coming up with a new interface is that I believe the FCEUX way is too verbose for "inline" runtime asserts (FCEUX uses stuff like
memory.readbyte(0x123)==0x69 when it could be
RAM[0x123]==0x69).
If anybody has ideas about how the Lua-emulator interface should work, let me know!
Also, note to self, I need to add a way of retrieving the debug symbols.
I'm trying to update my assembler to output version 2.0 debug info files. Can you point me to the documentation on this file format? I've looked at the dbginfo.c file but I can't make heads or tails of what it's doing.
qbradq wrote:
I'm trying to update my assembler to output version 2.0 debug info files. Can you point me to the documentation on this file format? I've looked at the dbginfo.c file but I can't make heads or tails of what it's doing.
There's no documentation as far as I know. Easiest way to figure it out is probably just to play around with CA65 and see what kind of output it produces for different source inputs.
thefox wrote:
I've started working on bolting Lua support to NintendulatorDX. My vision about it is a little bit different than the way FCEUX handles it. I want to embed Lua code in to the ROM, so that it can be used for 1) runtime asserts 2) prototype code 3) debug output, among other things.
I've made good progress and I'm pretty happy with how it works now. Couple of examples:
Debug output:
Code:
.zeropage
some_var: .byte 0
.proc something
lda #$69
; RAM table (for reading/writing bytes) is automatically defined.
luaExecStr "print( 'value from memory is ' .. RAM[ 0x234 ] )"
; RAM table can also be indexed with symbols. Only works for global symbols right now (no scopes, but of course it's always possible to define aliases for scoped variables in CA65).
luaExecStr "print( 'value from memory is ' .. RAM.some_var )"
luaExecStr "print( string.format( 'A = %X, X = %X, Y = %X', REG.A, REG.X, REG.Y ) )"
rts
.endproc
luaExecStr doesn't embed any code/data in the ROM (but it will embed one NOP if requested, as is required in some cases), it works by defining debug symbols for the information it needs and outputting the data in a separate segment, which is then output to a separate file. All of Lua code is executed in 0 cycles, so it's nice for prototyping.
Runtime asserts:
Code:
luaExecStr "if RAM.some_var > 50 and REG.A = 0x49 then iup.Message( 'Assert failed', 'Something went wrong' ); NDX.stop() end"
It's of course possible to define a simpler macro for runtime asserts, which will hide the iup.Message call etc.
Prototyping:
Code:
; foo.s (6502 code)
.bss
ARRAY_SIZE = 100
array: .res ARRAY_SIZE
.code
.proc gahh
luaExecFile "gahh-proto.lua"
rts
.endproc
-- gahh-proto.lua (Lua code)
-- Fill "array" with something.
array_addr = SYM.array[ 1 ]
for i = 0, SYM.ARRAY_SIZE[ 1 ] - 1 do
RAM[ array_addr + i ] = i + 123
end
IUP GUI toolkit is also included by default. It can be used to implement custom debug dialogs:
Code:
-- Lua code
ctl = iup.label { title="something", expand="YES" }
dlg = iup.dialog { ctl, title="Debug Helper", size="200x200" }
dlg:show()
; 6502 code
luaExecStr "ctl.title = string.format( 'some_var is %X', RAM.some_var )"
Functions currently exported from the emulator:
Code:
NDX.getPPUCycles
NDX.setRegister
NDX.print -- For printing to the Nintendulator Debug Information window, normal print() prints to the Lua console
NDX.getRegister
NDX.writeRAM
NDX.getCPUCycles
NDX.stop
NDX.readRAM
NDX.getSymbols
Eventually I hope to add support for "stand alone" Lua scripts (like in FCEUX), which don't need to be executed from within the code.
Now I just need a new project which I can use all of these features on.
BTW, release will come some time later, my repo got corrupted so I need to set up the source control again to make it easy to merge stuff from the official Nintendulator SVN repo.
thefox wrote:
Eventually I hope to add support for "stand alone" Lua scripts (like in FCEUX), which don't need to be executed from within the code.
Did that too. Also added support for CD (Canvas Draw) graphics library, as well as an ability to overlay graphics generated with it on top of the emulated view. Then I wrote a little FCEUX compatiblity module (incomplete) and ported over some of the Lua scripts from FCEUX, like SMB Snow and miau's Megaman 2 Laser Eyes. Cool, cool, should be done soon.
You never cease to astound
What's inspiring all of the Lua work fox? Is there a project you're working on that's using it?
This is awesome and I'm excited to use these new debugging features.
I assume you could define a breakpoint with something like: luaExecStr "print( 'Breakpoint encountered.'); NDX.stop() end"
With no code being output to your nes code/rom?
qbradq wrote:
You never cease to astound
What's inspiring all of the Lua work fox? Is there a project you're working on that's using it?
Thanks! As to why, I was bored and decided it was a good time to learn some Lua.
But all of this will certainly come in handy in future projects. I wish I had had something like this when working on STREEMERZ.
Movax12 wrote:
I assume you could define a breakpoint with something like: luaExecStr "print( 'Breakpoint encountered.'); NDX.stop() end"
With no code being output to your nes code/rom?
Yes. The macro outputs the string to a special segment, which is redirected to another file (I use extension .ndx for these). There's one case when it's necessary to output one NOP though:
Code:
; Display a message when some condition happens:
lda foo
beq not_foo
; The emulator uses addresses (and banking information) to identify these, so
; if luaExecStr/luaExecFile is the very last thing before the condition label, it
; needs to output one NOP, so that its address is not the same as "not_foo".
luaExecStr "print( 'foo happened' )", 1
not_foo:
Of course, at least in some cases it's possible to implement the above check like this too, avoiding the NOP:
Code:
; NOTE: In Lua, all numbers evaluate as true, so have to explicitly check for non-zero.
luaExecStr "if RAM.foo > 0 then print( 'foo happened' ) end"
All of this stuff only works in CA65 of course, and only with debug file enabled. (I could make it work universally by using a special register write, like the debug output feature currently does, but that's low priority.)
I've made a test ROM for TNROM boards configured with 32KB of VRAM (
link). I've found that I needed to build the mappers from SVN to get it to work. Have you considered updating your mappers to the latest SVN?
qbradq wrote:
I've made a test ROM for TNROM boards configured with 32KB of VRAM (
link). I've found that I needed to build the mappers from SVN to get it to work. Have you considered updating your mappers to the latest SVN?
Ah I didn't know about, in fact I remember requesting >8KB CHR-RAM support for MMC3 from Quietust
but didn't get a reply (but looks like he implemented it after all) (
correction: I misremembered, he did reply, and implemented the support not long after the reply, unknown to me). But yeah, I'll add the updated mappers to the upcoming release.
The MMC3 code appears to support 256 1K RAM banks now, although I only tested 32KB. Glad to hear it'll be in the next release
Well, I decided to release v34. It's not perfect, but I'm done with tinkering.
Download from
HERE.
New stuff:
- Lua scripting
- Banking support for profiling
- Debug breakpoints (write to a magic register or call ndxDebugBreak macro to stop the emulator)
- Better documentation
- Feature demo for CA65
- Mappers updated to the latest version from SVN
- Source moved to gitorious (
https://gitorious.org/nintendulatordx)
As usual, if you find anything wrong in the docs (wrote them in a hurry) or anywhere else, let me know. The Lua-emulator thread synchronization is still a bit iffy (should work, but the user has to know what he/she is doing).
Decided to put together v35. It has a bunch of old changes that I couldn't bother to merge to the public repository. From now on I'll probably be updating only the public repository.
The changes:
Code:
* "Expand macros" option.
* CA65 debug header no longer tramples over custom character mappings.
* Absolute file paths can be used in debug files.
* Bug fixed from dbginfo.c that caused some (rare) debug files not to
be loaded.
* readMemory() function added to the Lua interface.
* Latest updates from the main Nintendulator repo integrated.
* Warnings are given for uninitialized PRG-RAM accesses.
* Memory can be randomized on power-on.
* Lua, CD and IUP updated to the latest versions.
* Updated project to Visual Studio 2013.
* Added limited PowerPak hardware emulation (requires recompilation).
* Diagnostic message is shown if PPU_DATA is written to during rendering.
* NTSC NES borders are displayed.
Download from the usual place:
http://kkfos.aspekt.fi/projects/nes/too ... dulatordx/The git repository was moved to GitHub:
https://github.com/fo-fo/nintendulatordx
By expand macros, does this mean in the code view in the debugger you will see the macro expanded in place, so you can see the context of the surrounding code? I recall in previous versions it would "jump" to the macro in the code. If this is what you've improved, then awesome, thanks!
GradualGames wrote:
By expand macros, does this mean in the code view in the debugger you will see the macro expanded in place, so you can see the context of the surrounding code? I recall in previous versions it would "jump" to the macro in the code. If this is what you've improved, then awesome, thanks!
Not quite like that, but maybe sort of similar if I understood you right. When the option is turned on, the behavior is same as in previous versions. When the option is off, NDX will stay at the highest possible level and not display macro contents (previously it'd go as deep into macros as possible).
It probably should have an option to set the desired depth. At the moment it will reset the depth on every step. (Fortunately I think most people would be usually interested only in the highest
or the lowest depth).
Here's version 36:
http://kkfos.aspekt.fi/projects/nes/too ... dulatordx/This release contains some fixes to search paths of assembly and Lua source files. There's a menu option for using an NTSC/PAL aspect ratio and support for blargg's NTSC filter. The NTSC filter doesn't support field merging yet, so it can be a bit flickery, but should give a general picture about how the game is going to look on an NTSC TV. There's an option to darken the overscan area of the screen (with 90% safe area), but note that this doesn't work if the NTSC filter is turned on. Performance overall might be a little bit worse than earlier release because some upscaling is done in software.
NOTE: The results you get from the aspect ratio options may depend on your display drivers. I noticed that on my GeForce 8800 GTS the driver used nearest neighbor filtering when scaling the image, and on my current Intel HD 4600 it uses bilinear filtering. Bilinear filtering works better for the aspect ratio settings (because of the 2x upscaling done in software before the aspect ratio stretch). Unfortunately I haven't found a way to force the filtering algorithm in DirectDraw, so looks like the only way to get consistent behavior is to switch to Direct3D (might happen in the future).
All in all there are many gotchas in this version which I couldn't bother to fix just yet, but also didn't want to sit on it for an eternity. Hopefully somebody out there will find some use out of it.
If you try it out and encounter any problems, LMK.
Changes:
Code:
* NDX searches for source files in the current working directory
(previously only relative to the ROM directory)
* NDX searches for Lua scripts relative to current working directory.
* Menu option added for NTSC/PAL aspect ratio.
* NTSC filter support added (blargg's nes_ntsc).
* Frame skip option removed.
* Color depths other than 32-bit removed.
* Diagnostic is shown if invalid black (0xD) is used in rendering.
* Improved the implementation of Lua require().
* Fixed a bug that caused the A register to be cleared when
ndxDebugBreak was used without the debugger window being open.
* Fixed some problems with POV axes (patch from Nintendulator main
repository)
* Lua code can call back into 6502 code (NDX.jsr())
* Menu option for darkening borders outside the 90% safe area of
the (NTSC) screen.