What are the common problems encountered when running homebrew code on actual NES hardware? Is there a faq or document somewhere?
Common problem is that something simple and well documented that works well in every emulator, just does not work on the hardware (and rarely vice versa too). Problems I had were related to the vertical scroll after a split (still is mystery what was wrong) and to working with OAM without using OAM DMA (it just was a bad idea).
In my game, I was still updating the PPU after the end of VBlank, but before any visible scan lines were rendered. None of the emulators caught this (fceux, nintendulator, nestopia, nesicide). Yet on real hardware this caused serious PPU glitches.
In my mind, this is also a bug in the emulators. They were not emulating real hardware accurately. I assume that someone could construct a test for this, like Blargg's test roms. I thought about reducing my problem to a demo rom and releasing it, but a) I needed to use my time on other things and b) Blargg is gone, so idk if he or anyone would updating his test roms. "Clueless's test rom" would most likely be forgotten / ignored, as I lack the serious cred that Blargg has.
clueless wrote:
"Clueless's test rom" would most likely be forgotten / ignored, as I lack the serious cred that Blargg has.
That's what the wiki is for. If you make the test ROM, and I can verify that it runs differently on my PowerPak and on one of the big three emulators, I will promote it.
One problem that hit me and tool me a while to fix was related to doing a Sprite DMA late in vblank.
It was invoked during VBlank, but AFAIK the entire operation did not complete during VBlank.
On real hardware (and Nintendulator) my sprites did not show up.
On FCEU, which was my default emulator, things appeared fine.
Another huge gotcha for me was mistakely using palette entry '0x0D'.
On emulators everything looked good. On my old CRT TV everything looked good.
On my newer LCD TV, the graphics scrolled and jumped around like nuts.
Al
Don't turn off the screen early during HBLANK time, otherwise you get screwed up sprites.
The mistake I made when I was making some NES homebrew was using sprites without DMA. On emulator it looked fine. I think I used FCEU. This was a long time ago though. Later when more accurate emulators came about I tried the program again and saw it fail and like only 1 sprite even appeared on the screen.
It just shows the important of testing on real hardware. Even though the PowerPAK isn't spot on for something like mapper IRQ behavior of the MMC3, for other boards without IRQ it's a great tool. I know some mentioned you don't get the raw power-up state but that's a minor issue if you just be sure to initialize everything as you should.
Just to break the combo, I've not run into anything that worked on a good emulator and failed on hardware. My game doesn't do anything complex with the PPU though, it's only clever CPU code.
Sometimes I run into things that break differently on hardware and an emulator, though. But they've always been shown as clearly broken by an emulator. For instance, now my screen updates are running a little too long. On FCEUX this occasionally caused the scrolling to jump, but on an actual NES it was actually crashy.
I've always turned off the PPU when entering vblank, and turned it back on when leaving. This lets you use the prerender scanline as vblank time, so I see no reason not to do it, as long as you also do full 2005/2006 writes to set scrolling. It also makes the scrolling merely jump if your code is too long, instead of crazy corruption.
Dwedit: This is a great idea! I can still optimize my NMI routine to at least not go FAR over in the Vblank time, but if it ever still does by a little this seems like a GREAT catch.
I never has upates getting too close to the end of VBlank. If I'd have them overflow into the frame I'd rather see it happen and see a completely bugged screen than leaving it as it and then having occasional jumping on the screen.
But it's just a personal choice.
When it comes to sprite updates without using DMA, I just ask, why ? Even if it worked, there would be absolutely no point in it since it would just be a huge waste of CPU time. Maybe if you never use all 64 sprites it would save a little RAM but really it's not worth it.
The only application I see for OAM updates without DMA involves trying to play audio through timed writes to $4011 and move sprites at the same time.
Dwedit: That's a great idea! I stopped doing that when I stopped trying to extend vblank, but I didn't think about that nice side effect.
Now keep in mind that I've only executed one program on an NES (last night) but I did run into an issue. I cleared my OAM RAM to all 0xFF's, but I was not executing a sprite DMA after that. This was fine on an emulator (not sure why...) but on the hardware this resulted in random sprites all over the screen.
This would not be noticeable if your NMI handler does a sprite DMA every frame, but my engine uses an "OAM Updated" flag to trigger this, which in my test ROM was never getting set as it does not use sprites.
One thing everyone has to understand is that FCEU(XYZαβγ) is extremely forgiving with badly written code. It's far from accurate, and is probably much closer to Nesticle than to a real NES. Don't ever rely on it as your only emulator.
Quote:
This would not be noticeable if your NMI handler does a sprite DMA every frame, but my engine uses an "OAM Updated" flag to trigger this, which in my test ROM was never getting set as it does not use sprites.
I do exactly that, and I think it's a good idea, because if for some reason your frame didn't finish in time (and a NMI happens), the OAM page is half-updated, and you probably don't want to do any sprite DMA, because sprites would flicker (as if there wasn't enough sprite flicker with the 8-sprites-per-line limitations...)
However it works fine at startup because in my routine that clears OAM with $f0's (I guess I use $f0's although $ff might work just as well) I set the "OAM updated" flag.
tokumaru wrote:
One thing everyone has to understand is that FCEU(XYZαβγ) is extremely forgiving with badly written code. It's far from accurate, and is probably much closer to Nesticle than to a real NES. Don't ever rely on it as your only emulator.
I do. It's not forgiving with PPU stuff at startup, just found some glitches in the beginning or my games program. It's the best emulator for development though with all the tools, sadly. If another emulator came up with a hex editor and name table viewer and maybe a debugger, and didn't start with error messages or multiple boxes of crap I don't want, I'll gladly switch.
I use FCEUX all the time too, because of its great debug capabilities, but it will not catch a large number of PPU problems your code might have. So even if FCEU(X) is your main development emulator, you should still give your programs a spin in Nintendulator and Nestopia at least, because those are much less forgiving.
Would be really cool if someone made a dev emulator that not forgives any known problems. Even if it slow, with just few mappers popular for homebrew, and without nice UI.
I do, but neither meet the criteria of not erroring or having random boxes on startup.
3gengames wrote:
neither meet the criteria of not erroring or having random boxes on startup.
Then there's probably something wrong with your setup, because that doesn't happen to me.
I took "random boxes on startup" to refer to the Nintendulator window whose title is Debug Information.
shawnleblanc wrote:
What are the common problems encountered when running homebrew code on actual NES hardware?
In my case, my intro code used for the Neo Demiforce FF2e (FF2j in English) translation didn't properly reset the necessary PPU addressing bits when I did certain VRAM writes. The result was
corrupted graphics while fading text (palette adjustments). You can see videos of the
incorrect and
correct behaviours. Folks like Bregalad and others provided details (and had actually patched the ROM to fix the problem).
The reason I didn't notice the problem was because 1) at the time there was no PowerPak and no easy way to make a dev cart, and 2) all the emulators available at the time didn't show the bug. What the nesdev community knew of the PPU back then (circa 1997) differs from what's known today.
You can
read about the technical stuff if you want, or the
convo I had with Bregalad discussing the details and the history. Be sure to read the full thread from that point forward, as the details get worked out from that point onward.
Shiru wrote:
Would be really cool if someone made a dev emulator that not forgives any known problems. Even if it slow, with just few mappers popular for homebrew, and without nice UI.
I agree, I started to add diagnostic features like this into my modified version of Nintendulator couple of weeks ago. Messages about 1) using uninitialized memory 2) writing to/reading from 2007 during rendering 3) writing to certain PPU regs when PPU hasn't warmed up etc. I'll gladly take any suggestions if somebody can think of more helpful diagnostics like that.
I've noticed some odd behavior on the console that emulators didn't catch. This thread contains a bug that I actually noticed on the console:
http://nesdev.com/bbs/viewtopi ... sc&start=0
In my game when the screen gets turned off between switching rooms or levels, I would disable rendering mid-frame, and sometimes it would get disabled when the player or an enemy was on that scanline. This would cause sprite glitches the next time sprites are re-enabled, which would often screw up sprite #0, which means my game would get caught in an infinite loop waiting for sprite #0 to change the scroll at the bottom of the status bar.
Yeah, that's a very nasty thing that no emulator appears to emulate. disabling sprites mid-frame is pure evil. I still don't know when it's safe to do this. Enabling rendering late however appears to have no side effects, and I've been doing this in my game with no problems.
tokumaru wrote:
One thing everyone has to understand is that FCEU(XYZαβγ) is extremely forgiving with badly written code. It's far from accurate, and is probably much closer to Nesticle than to a real NES.
Comparing something to Nesticle is not the kind of claim you throw around lightly. Nesticle doesn't even understand that there are 262 scanlines, and that there are 341 PPU cycles per scanline. Open the NES Timing window and see how horrible the numbers look there. Nesticle can't even scroll correctly.
(I know, 6-day late reply...)
Heh, I didn't mean to offend FCEU. It's just that I've personally seen it ignore some pretty serious mistakes. Anyway, I didn't say it was as bad as Nesticle, just that it's probably closer to it than to a real NES, which doesn't necessarily mean it's close in absolute terms.