How do you find bugs in your emulator?
Moderator: Moderators
How do you find bugs in your emulator?
I've got a few problematic ROMs that doesn't work in my emulator. The symtoms are just lockups or the game tries to run an illegal opcode which causes my emulator to halt.
The problem is that I am not sure how to find the bugs. I've done a log-feature that logs the previously executed code and where it came from, but it easily gets huge which makes it unusable.
The current one I'm trying to get to work is "Jackal" (mapper 2), which for some reason only gives me a blank screen.
So emulator-authors, do you have any genius-tips or how do you track down problems like this? How do you proceed when a game just refuses to run?
Thanks in advance
The problem is that I am not sure how to find the bugs. I've done a log-feature that logs the previously executed code and where it came from, but it easily gets huge which makes it unusable.
The current one I'm trying to get to work is "Jackal" (mapper 2), which for some reason only gives me a blank screen.
So emulator-authors, do you have any genius-tips or how do you track down problems like this? How do you proceed when a game just refuses to run?
Thanks in advance
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
Re: How do you find bugs in your emulator?
I just kept adding stuff to my debugger output windows to help me figure things out. For example, to figure out the sprite hit and overflow test ROMs I added a bunch of breakpoint events like:oRBIT2002 wrote: So emulator-authors, do you have any genius-tips or how do you track down problems like this? How do you proceed when a game just refuses to run?
Thanks in advance
Break when sprite N enters the multiplexer
Break when sprite N is selected by the multiplexer
Break when sprite N is drawn
Break when sprite 0 is hit
I did the same for debugging my APU, adding breakpoint events like:
Break on length counter clock
Break on DMC DMA
Most of the time a game refuses to run its because there's some condition about sprite 0 hit or sprite overflow that isn't quite right in your emulation. At least, that has been my experience...you'll stop the game and it'll be spinning on a BIT $2002 loop or something and you'll facepalm and exclaim "not ANOTHER one!"
Other cases of game-not-so-runnyness:
Mapper imperfections causing incorrect bank loading causing eventual KIL opcode execution...easy enough to trap and even put up a "DOH" dialog for. Mapper imperfections includes incorrect initialization of mapper state such that the game doesn't even start out with the correct PRG banks loaded where they need to be loaded. [I had a problem where I could get SMB3 *or* SMB2 to run but not both because of some error in the way I was initializing the PRG bank swapping modes].
The way I solved those issues was to add mapper inspectors that let me peer into the internal state of the mapper and trap on writes to the mapper and set breakpoints if the mapper state changes. It's pretty easy to see a bad mapper write when you step over it and all of a sudden you're in the middle of a bunch of .DB $00 crap.
I'm in a bit different situation though I'm not just writing an emulator I'm writing a tool that I think should by definition have the capability to scrutinize the minutia of the machine otherwise it's not very useful as a debug/integration platform.
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
I would disagree with that statement.oRBIT2002 wrote:I pass all CPU-tests using the NESstress ROM so I guess it has to be something else..
Do you pass:
blargg_nes_cpu_test5
branch_timing_tests
cpu_dummy_reads
cpu_timing_test6
instr_misc
instr_timing
Passing those, you probably have a nearly flawless CPU. I say nearly because there's some I didn't include in the list and we don't know everything (yet) about the 2A03.
The best thing you do is to create a log of the running ASM code. It should be a text file within all the executed instructions... and where it hangs/fails. Though, there's one problem: the size. It generates a huge file that isn't opened so quickly in wordpad, for example.
Anyway, yes, it's the best thing. Next, the PPU. There are tons of PPU tests that shoudl help you a lot. They're much more difficult to get a pass than CPU tests.
Anyway, yes, it's the best thing. Next, the PPU. There are tons of PPU tests that shoudl help you a lot. They're much more difficult to get a pass than CPU tests.
Zepper
RockNES author
RockNES author
blarrg's test were by far the most helpful thing for me, but there are a few things they do not catch. To snuff out some lingering issues, I would try to find games that did not work right from the get-go, i.e. games whose title screen wouldn't even come up, or would be glitchy, etc. Then I'd turn on super-detailed tracing like Zepper describes, and compare against the output of Nintendulator running that same game. This technique helped me iron out some bugs that manifested themselves in Galaxian, Joy Mecha Fight, and Slalom.
All I ever needed was a trace logger. Though it helps if you have a way of turning it on and off during execution so if you have a problem beyond the initial bootup you can avoid logging parts that work fine.
But it'd be even better to have a full fledged debugger complete with breakpoints and step by step execution options.
But it'd be even better to have a full fledged debugger complete with breakpoints and step by step execution options.
Blargg's tests are pretty insane. Not many emulators pass all of them.Zelex wrote:blargg's tests are indeed awesome btw, but you don't need to pass them all to emulate most games very well.
Some bugs are hard to find. If it's CPU related, the problem doesn't always appear where the bug is.
Another strange bug I've got is that "Balloon Fight (E)", plays a song during titlescreen (the (US) doesn't, neither the (E) version in any other emulator). How do you bughunt such a thing?
- cpow
- NESICIDE developer
- Posts: 1097
- Joined: Mon Oct 13, 2008 7:55 pm
- Location: Minneapolis, MN
- Contact:
I always wondered exactly what a "fledge" is, and how they become "full"?MottZilla wrote:But it'd be even better to have a full fledged debugger complete with breakpoints and step by step execution options.
But yeah, I know what you mean. For me, having access to the code for said somewhere-between-nil-and-full-fledged debugger in my app makes it that much easier to add specific breakpoint events or log events or features that I can think up to help me bughunt.
One story. I was having a heck of a time figuring out why I could pass all of blargg's sprite hit tests but one, specifically "07.screen_bottom". I had thought I had the timing correct since I passed 03.corners fine [aside: I had wrongly assumed that "corners" meant screen corners, but further debugging of this test ROM showed it meant corners of a sprite in the center of the screen! Duh!]. But, it wasn't until I created the "Execution Visualizer" that could show me where in the PPU time domain code was executing, overlaid on a 341x262 graphic representing the PPU time domain and showing the screen and VBLANK/HBLANK time. I was always executing the "check for hit" code about four and a half scanlines too soon [and it hadn't hit yet, so I failed]. Four and a half scanlines is ~513 CPU cycles...and there I was, not properly accounting for sprite DMA cycles missing from the CPU. Sometimes things don't pop out at me from a trace log...I need visuals!
Wikipedia knows. Fledge is the second stage of a bird's life cycle, after it has left the nest and before it can fly.cpow wrote:I always wondered exactly what a "fledge" isMottZilla wrote:But it'd be even better to have a full fledged debugger complete with breakpoints and step by step execution options.
Ability to do everything but fly, including (in some species) fend for oneself without help from parents.and how they become "full"?