different behavior between Nestopia(OSX) and VirtuaNES

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
different behavior between Nestopia(OSX) and VirtuaNES
by on (#129634)
hey guys!
I'm trying to study writing games for NES using CA65
And I got this strange problem:
same code on VirtuaNES works fine, but in Nestopia, it won't.

Nestopia:
http://speedy.sh/76KQk/n.png
VirtuaNES:
http://speedy.sh/hmVyt/t.png

see,in VirtuaNES, everything goes well
but in Nestopia, mario's head is missing.
I don't know what i miss.

here is asm :
http://speedy.sh/yzN2Z/main.asm
and chr file
http://speedy.sh/Buke5/mario.chr

thx in advance!
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129635)
I would suggest using OAM DMA ($4014) like the code that you have commented out. If you do it in the beginning of your vblank handler, it's a fool-proof method, whereas manually uploading the sprites has some quirks (depending on what address $2003 ends up at, etc). Also note that your little 16 iteration loop already takes almost 256 cycles, whereas uploading full 256 bytes with OAM DMA only takes about 512 cycles, so there's not much of a performance gain.

In this case, since your sprites are in ROM, you can copy them to RAM outside of vblank, then OAM DMA the RAM during vblank.
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129636)
Also, you should not look at the behaviour of emus, but of real hardware as it's the only thing that matters in the end. However, generally, Nestopia is more accurate than VirtuaNES which is more permissive, so if your work works in Nestopia it's already a very good sig, if it doesn't work then very likely it will fail on real hardware as well.

Also I don't know why you have commented the "correct" code and placed "wrong" code instead. Was there a probblem with it ?
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129637)
Bregalad wrote:
Also, you should not look at the behaviour of emus, but of real hardware as it's the only thing that matters in the end. However, generally, Nestopia is more accurate than VirtuaNES which is more permissive, so if your work works in Nestopia it's already a very good sig, if it doesn't work then very likely it will fail on real hardware as well.

Also I don't know why you have commented the "correct" code and placed "wrong" code instead. Was there a probblem with it ?


well, it's not about wrong or right, it just two method of displaying a sprite:)
first method (using $4014) is RAM->OAM, second method is what i think can save more RAM method.
but since i'm new to NES development, so i don't know witch method is better.

btw, i just bought everdrive , will be shipped in 3 days. yey :D
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129638)
thefox wrote:
I would suggest using OAM DMA ($4014) like the code that you have commented out. If you do it in the beginning of your vblank handler, it's a fool-proof method, whereas manually uploading the sprites has some quirks (depending on what address $2003 ends up at, etc). Also note that your little 16 iteration loop already takes almost 256 cycles, whereas uploading full 256 bytes with OAM DMA only takes about 512 cycles, so there's not much of a performance gain.

In this case, since your sprites are in ROM, you can copy them to RAM outside of vblank, then OAM DMA the RAM during vblank.


okay thanks for the suggestion:)
so in your opinion, RAM->OMA is a better solution (?)
but i'm little worry about RAM, since we really don't have much RAM to use.
or RAM doesn't matter at all if use wisely?
need more suggestion, thanks:)
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129639)
It is almost always a better idea to use the DMA for your sprites. There is not enough time in vblank to update all of OAM through $2004, and if you turn rendering off the sprites begin to get corrupted as the OAM RAM decays. If you only need to update a couple of sprites per frame, you can get away with a few $2004 writes to update them in vblank, but you still need to fully initialize OAM whenever rendering has been off, which either needs to be done with a DMA or through $2004 over several frames of vblank.

Yes, it's a large chunk of RAM, but it's essential.

If you're looking for a bit more RAM, you might not be using part of the stack area. $100-180 can be a good place to squeeze a few more bytes in.

Also, if you have a static screen that doesn't need to change, you can DMA sprites out of ROM. If you do want to avoid having an OAM copy in RAM, you can a DMA from ROM in the first vblank to initialize, and then little updates via $2004 in subsequent vblanks is okay.
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129641)
Bregalad wrote:
Also, you should not look at the behaviour of emus, but of real hardware as it's the only thing that matters in the end.

While it's true that the hardware has the final word, most emulators should handle simple programs (i.e. no forced blanking, no raster effects, etc.) without problems. If your program isn't doing anything fancy but still fails on some emulators, it's worth checking out what the issue is. Even if it works on original hardware, you could be accidentally doing something without a safe margin of error which could eventually fail under some circumstances. Better safe than sorry.

rainwarrior wrote:
If you're looking for a bit more RAM, you might not be using part of the stack area. $100-180 can be a good place to squeeze a few more bytes in.

Definitely. People often look at the OAM page and think memory is being wasted there, but how many program do you know that need 256 bytes of stack? I don't think I'd ever need more than 64, and that's if I use the stack for temporary storage of arrays. If I use it only for subroutines and passing values I doubt I'd ever use more than 32 bytes.

Anyway, you can still use the OAM page for variables if you use 3 bytes and skip 1 (the Y coordinate) every 4 bytes. The Y value is necessary to put the sprites offscreen, and the other bytes can be used for variables. You won't be able to use arrays or values larger than 24 bits, but I'm sure you can find space for those elsewhere and keep the simpler variables in the OAM page.
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129642)
You might end up using a lot of stack if your game uses a recursive algorithm such as flood fill. Examples of flood fill in commercial games:
  • Segmentation of the playfield into separate connected regions that fall independently (Bombliss; Mega Man X)
  • Segmentation of the playfield into indoor and outdoor regions (Rampart)
  • Determining how many like pieces are touching, if it takes a critical mass to clear them (Puyo Pop; SameGame; Tetrisphere)
  • Determining how far to extend an explosion, though this is often done incrementally (Exodus; Magical Drop)

But in the vast majority of cases I can think of, $0100-$01BF should be free. I tend to use it for a "transfer buffer", where code running during draw time builds data to be copied to VRAM during next vertical blank.
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129764)
Thx guys.
I think I'll use RAM->OAM then :)
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129782)
If the sprites are never moving, then you can OAM from ROM (the sprite palettes and CHR bank can still be changed, and different 256-byte pages of ROM for different screens), and don't need that RAM space. If you don't have any sprites at all, then you can avoid using that RAM too (possibly, some screens might use sprites, but other screens might not use sprites so that RAM is available for other purpose during that time). Regardless, you should use the OAM DMA (which is a APU register designed to interface with the PPU, which is a separate chip) if you are using sprites at all.

And you can use the part of RAM for sprites also for variables as long as the Y coordinate of the sprite is off-screen. On a few mappers it is also possible to use sprites to switch the CHR bank between the top and bottom half of the screen (I think).
Re: different behavior between Nestopia(OSX) and VirtuaNES
by on (#129792)
zzo38 wrote:
If the sprites are never moving, then you can OAM from ROM (the sprite palettes and CHR bank can still be changed, and different 256-byte pages of ROM for different screens), and don't need that RAM space. If you don't have any sprites at all, then you can avoid using that RAM too (possibly, some screens might use sprites, but other screens might not use sprites so that RAM is available for other purpose during that time). Regardless, you should use the OAM DMA (which is a APU register designed to interface with the PPU, which is a separate chip) if you are using sprites at all.

And you can use the part of RAM for sprites also for variables as long as the Y coordinate of the sprite is off-screen. On a few mappers it is also possible to use sprites to switch the CHR bank between the top and bottom half of the screen (I think).


Thank you!
Now i'm pretty sure what should I do.