Also not sure your intentions or your potential readers' intentions for testing environments, but if a lot of illegal opcodes are used in your main loop in Nintendulator -- even if the message menu is closed -- your emulation will significantly degrade in speed.
If that's true, it could be used as copy protection in a rhythm game. Every beat of the music, it'd randomly choose between waiting for vblank with official instructions and waiting for vblank with unofficial instructions and keep waiting that way until the next beat. Watch animation become all jerky.
Any games using the MUSE sound engine -- since it uses illegal ops -- experience this issue in Nintendulator and not other emulators.
Don't want to spam the thread but...
B00daW wrote:
Any games using the MUSE sound engine -- since it uses illegal ops -- experience this issue in Nintendulator and not other emulators.
There's an option in the "unstable" build (I never had
any problems with it) of Nintendulator to disable messages about unofficial opcodes (CPU -> Log Invalid Opcodes).
[Off topic]
Copy protection for emulators so far:
FCEUX:None to my knowledge.
Nestopia:Force a reset, write to screen, read back. If wrong, it's nestopia.
Nintendulator:Bankswitch using [ZP],Y, possibly more ways like that.
[/Off topic]
[On Topic]
I like using NESICIDE as the tutorial, I'm just waiting for an x64 Ubuntu version for now, heh.
3gengames wrote:
FCEUX:None to my knowledge.
Are you kidding? FCEUX is the easiest to detect, because it's the most inaccurate one of the bunch. It fucks up a lot with sprites (I think that the sprite evaluation and pattern fetching aren't emulated at a low level, so the timing is all wrong for those), so something with a sprite 0 hit could definitely identify the emulator. It also initializes RAM to a very specific state, with alternating blocks of $00 and $FF.
But I have to ask: what does this have to do with anything?
Split by request of Dwedit.
Another technique to degrade performance on emulators is to bunch up big CPU computation jobs (such as decompression or LUT generation or AI pathfinding) and set them up to run during the most timing-sensitive parts of a game. But this is more applicable to emulators of Game Boy, Super NES, and other platforms other than the NES, which have an instruction to freeze the CPU entirely until the next interrupt.
But ultimately, any emulator allowing such performance degradation is either A. defective, B. misconfigured out of the box (e.g. Nintendulator), or C. running on sufficiently underpowered hardware (e.g. PocketNES).
Most emulators, especially those with an eye on performance, will optimize to make the common case a lot faster in exchange for a rare case being a lot slower.
Snes9X has a fun one: if you change the CPU FastROM setting, it rebuilds a big lookup table to determine the speed of various memory accesses.
Write an unrolled loop that turns it on and off rapidly, and you'll go well below 60fps on any PC.
I don't like caches, so I subtract FastROM<<1 from appropriate memory areas. A bit slower on ROM reads, but you can't murder the performance.
I think everybody optimizes mosaic effects to only apply when mosaic is enabled and >1x1.
But anyway, slowing an emulator down versus detecting it is quite different. The only way anyone's managed to identify my emulator so far was by analyzing the randomization pattern of memory, since mine is more chaotic than the real thing. It's that way intentionally to help catch bugs in games that rely on uninitialized memory.
I personally know more ways to detect it, but I'll never tell ;)
I don't know about degraded performance but you could break it completely in an emulator if you added something to make the mapper unique on the cartridge. You could do a fair amount of copy protection if you were motivated to do so.
infiniteneslives wrote:
I don't know about degraded performance but you could break it completely in an emulator if you added something to make the mapper unique on the cartridge.
I believe the VRC variants were intended for just this, and the NES 2.0 mapper variant field was added for this as well.