

Classic NES Series Anti-Emulation Measures - jpfau
https://endrift.com/mgba/2014/12/28/classic-nes/

======
frozenport
>>I’m not sure why they put all of this effort into causing trouble for
emulator developers in this one specific case,

I know why!

If went to bazaar in 90s Russia you would see these '40-in-one' video-game
cartridges which were a bunch of normal bootleg games linked together by a
bootscreen. You could imagine the NES emulator falling under the same
category. Sometimes emulators were sold on CDs.

[http://i.imgur.com/dJ142.jpg?1](http://i.imgur.com/dJ142.jpg?1)

~~~
nogridbag
Ah memories. I had one of those gold NES honey bee adapters with a 250 in 1
cartridge we got from a Chinese friend. At least a quarter of the games were
dups with minor differences and we paid $250 for it, haha. At the time it
seemed like a good deal!

~~~
vlunkr
Yes I played one of these as well that a friend got at the mall. Except I
would say about 3/4 of the games were clones, usually with some terrible color
palette swap. He bought it in the US though, I can't believe a product like
that made it to the market. Especially since every game on there was pirated.

------
AshleysBrain
This doesn't seem to me to be evidence of deliberate anti-emulation features -
just imagine a hastily written port by relatively inexperienced developers who
don't know about these quirks, and then it could be said:

#1 - memory mirroring - accidental bug that doesn't matter since hardware
ignores those bits

#2 - code in vram - possible technique to save memory in another memory area?

#3 - STM to DMA - shortcut to DMA that "just worked" without the original
developers knowing the CPU write ordering

#4 - save type faking - just a library bug that breaks the emulator
heuristics?

#5 - prefetch abuse - idk, maybe a legit attempt to prevent reverse
engineering? Don't really know enough to comment if there's a reasonable
purpose for it

#6 - audio FIFO irregularities - just a bug in the emulator?

How many C/C++ devs accidentaly rely on undefined behavior or specific x86
quirks? It's really easy to do, and doubly so if you're targeting a single
exact hardware configuration. I'm sure it's easy to see these as hostile
attempts to make emulator developer's lives harder, but I think they could
just as easily be accidents, especially with a complex project like porting
NES games to GBA hardware.

On the other hand, I dunno, maybe Nintendo pull out all the stops to try to
prevent reverse engineering and deliberately use these kind of tricks, but
really, they'd go the extra mile for old NES game ports?

Having said that, still a great article for covering some fascinating hardware
quirks and the challenges of writing a bug-compatible emulator!

~~~
smosher_
Some of these are definitely deliberate.

#1. The memory mirroring is IIRC a normal part of the hardware involved.
Executing mirrored code? I can't think of a good reason to do it other than to
trip someone up.

#2. You _might_ do this in earnest, but only if you're decompressing the code
or otherwise generating it and just can't stick it in main RAM. GBA ROMs make
up part of the global address space. There's simply no need to copy existing
code around.

#3. I'm not familiar with it enough to comment. Sounds like it could be
innocent.

#4. Seems unlikely you would include an unnecessary code path, and then
intentionally kill the game if it happened to work. This is actually your
typical anti-debugging technique: trick the environment into to doing
something you can detect, then disable.

#5. Prefetch games usually combine the detect and disable steps mentioned in
#4. #1 and #2 are also related. This is a good contender for "oldest trick in
the book."

#6. Probably a bug.

Source for GBA-specific stuff:
[http://problemkaputt.de/gbatek.htm](http://problemkaputt.de/gbatek.htm)

~~~
monocasa
#2 For tight loops on the GBA you wanted 32bit ARM instructions in an area of
RAM with 32bit accesses. There was a performance penalty both for using thumb
and for running non thumb out of ROM (the bus to ROM was only 16bits). If
there was a lack of WRAM for some reason it would totally make sense to put a
tight loop into VRAM. (And for whatever reason Nintendo is really into putting
random stuff into VRAM. On the DS, one of the ARM7 images would put WLAN
packet buffers into an unused VRAM bank to reduce pressure on other RAM
banks).

~~~
smosher_
That's fair. I had been assuming you'd use ITCM for tight loops regardless but
I can't recall whether you can do that on GBA now that I think of it.

As for copying data around, yeah, if your emu can't copy data to/from VRAM in
a sensible manner it's just not going to work out.

------
glinscott
I wouldn't say the GBA was too forgiving about mistakes. You had very limited
resources, and sometimes needed some tricks to get things running acceptably.
I do remember a few things like a divide by zero in a game that ended up
jumping off into the middle of RAM and by luck, the game just happened to
continue. But the examples from the article seem to be on purpose.

2) Code in VRAM was sometimes faster than executing code from the ROM, due to
waitstates. This was used on the Nintendo DS as well. There was a lot of VRAM,
and it was 0-waitstate, while your instruction cache was tiny.

3) STM to DMA registers was an optimization that was used fairly commonly, at
least in homebrew games

5) This is definitely anti-emulator code :)

~~~
ConnorG
Do you happen to know anywhere to read further on the topic of programming
tricks used in GBA (or any platform) games?

I always find these things really interesting.

------
michielvoo
The STM to DMA registers (using a single CPU instruction to trigger DMA) seems
like a valid optimization, unrelated to piracy prevention.

~~~
centizen
It certainly seems valid, but in context of all of the other protections it's
difficult to say for sure if is or not.

But considering it either hasn't been used in other games, or at least
infrequently enough this emulators author has never seen it before, I'm
leaning towards it being another protection.

~~~
ianferrel
Or they upgraded their compiler/enabled more optimization.

Combining sequential writes into an STM is a standard optimization.

------
mschuster91
Using stuff like the pipeline stage is really bad imo, because it may prevent
your game from running successfully if it is decided on a later stage to
either upgrade the internal hardware (like it was done with the shitload of
PS3 variants) or it is decided years later that the successor console should
be able to play legacy platform games.

~~~
JonathonW
The first of these games was released in February 2004, late in the GBA's
product cycle. At that point, the Nintendo DS hardware would've already been
pretty much finalized (it released in Nov 2004), so they already knew what
things looked like for backwards compatibility (the DS includes the GBA's ARM7
processor).

