This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Detecting emulators with PPU writes

Detecting emulators with PPU writes
by on (#66488)
The wiki says:
Quote:
Most emulators allow the program to twiddle PPU registers immediately, while the NES PPU ignores most writes for the first frame after a reset.

Quote:
Writes to the following registers are ignored if earlier than ~29658 CPU clocks after reset: $2000, $2001, $2005, $2006. The other registers work immediately: $2002, $2003, $2004, $2007, $4014.


Shouldn't it be possible write to the PPU as the very first thing you do as the program starts up, then wait for the PPU to stabilize and read the supposedly illegal written values?

For instance:
Code:
Start:
   lda #$20
   sta $2006
   lda #$10
   sta $2006
   lda #$A0
   sta $2007

waitVBlank1:
   lda $2002
   bpl waitVBlank1
waitVBlank2:
   lda $2002
   bpl waitVBlank2
   
   lda #$20
   sta $2006
   lda #$10
   sta $2006
   lda $2007
   lda $2007
   cmp #$A0
   beq Detected.Emulator


If the emulator works according to the Wiki, the $A0 value should in fact not be written to $2010 at all, because the PPU ignores the $2006 writes. That would of course mean the above code will detect emulators that allow writing to the PPU immediately, am I correct?
If this is the case, very few emulators seems to disallow writing to the PPU immediately.

Of course you have to take into account that the PPU might already have been stabilized at the beginning of the program (Reset?).

Any thoughts/picking? :)

by on (#66489)
There's no reliable way of detecting an emulator. Also I don't know that the PPU always ignores writes, just a good portion of the time as stated. It's not something to depend on in code.

by on (#66490)
With something like this, Soft Resets on a Famicom or toploader will be considered emulators. (the PPU is NOT reseted on those machines when RESET is held).

by on (#66491)
Of course, that's why I said you have to take into account that the PPU might already have been stabilized. Maybe set a variable for detecting soft resets? But if the PPU doesn't always ignore the writes on startup as Blargg states, this code might mistake a real NES/Famicom for an emulator which kinda defeats the purpose.

by on (#66492)
Why would you want to detect emulators anyway?

by on (#66495)
Some reasons was covered in this thread.
Detecting emulators and display a message that the emulator might be inaccurate might take some the blame off your game by fanboys where your game doesn't work in their favorite emulator. Not for writing compatible code, but basically just warn the user. Warning the user might also force emulator developers make more accurate emulators.

by on (#66496)
Even on authentic NES hardware, a game running on a PowerPak or other multicart will see writes to these "blocked" registers take effect when it first starts because the menu did all the work. Soft resets after that, on the other hand, will have writes be ignored on the first frame.

Better is to detect behavior related to what your game actually uses. For example, if your game (ab)uses APU DMC to make a letterbox or other scroll split effect, test that while your game's copyright screen is being displayed. The one thing this won't detect, however, is people who abuse save states and slowdown to falsify achievements.

by on (#66497)
Maybe to sell cartridges that won't work on an emu when dumped ?
But anyways...
Quote:
But if the PPU doesn't always ignore the writes on startup as Blargg states, this code might mistake a real NES/Famicom for an emulator which kinda defeats the purpose.

Not only that, but also an emulator might as well ignore your first writes like the real hardware would. So false detections are possible in both directions, which basically sucks.

I've heard a good way to test emulators was to test the open bus behavior when reading for example $4016 - emulators will return $4x, but if you use indirect adressing to read $4016, it will return something else. This might as well be emulated by someone - so it's not a solid way either. In fact there is no solid way, because anything that could deflect "most emulators", an emulator can be upgraded to be more accurate and defeat your detection algorithm. That would be a cat-and-mouse game, as seen with PSP and NDS consoles and flash cards available for them.

by on (#66498)
Wkter wrote:
Detecting emulators and display a message that the emulator might be inaccurate might take some the blame off your game by fanboys where your game doesn't work in their favorite emulator.

In the old days the "for use only on original consoles" warnings were enough to take the blame off the games. You could very well just have a similar warning on the label, and not worry about monkeying around with unreliable code that might backfire under certain circumstances.

Quote:
Warning the user might also force emulator developers make more accurate emulators.

If there's a prominent malfunction, I'm sure they'll be tempted to fix it anyway. In fact, it would be better if they used their time to fix the behaviors that cause the actual glitches than the behavior that causes the warning to be displayed.

by on (#66499)
Bregalad wrote:
Maybe to sell cartridges that won't work on an emu when dumped ?

...that can be hacked to work in 2 minutes or less...

by on (#66500)
Which is why the power-on self-test should be focused on creating a glitch that happens if and only if the glitch happens during the game. You've got 120 frames to burn during the copyright screen; put them to good use.

A screen like this will probably prevent problems even if your detection code has a (rare) false positive:
Code:
 |====== Compatibility ======|
 |                           |
 | NOTE: This product is     |
 | designed for use with a   |
 | Nintendo Entertainment    |
 | System (NTSC U/C) or      |
 | Family Computer (NTSC J). |
 | Glitches may occur on     |
 | European or third-party   |
 | consoles.                 |
 | To continue anyway, hold  |
 | the A and B Buttons.      |
 |                           |
 `---------------------------'

by on (#66502)
tokumaru wrote:
If there's a prominent malfunction, I'm sure they'll be tempted to fix it anyway. In fact, it would be better if they used their time to fix the behaviors that cause the actual glitches than the behavior that causes the warning to be displayed.

Sure, but if the glitches causes the warning the glitches will be fixed. This method is of course just to "force" better emulation and the use of accurate emulators.

Bregalad wrote:
Maybe to sell cartridges that won't work on an emu when dumped ?

If you really think you'll sell more hard copies than soft...

I though of the warning message after seeing how much the emulators disagree on a simple program I'm making, so the best thing would of course be to have more accurate emulators.

by on (#66508)
Wkter wrote:
I though of the warning message after seeing how much the emulators disagree on a simple program I'm making

If it really is simple, in the sense that you are trying to do everything "by the book" (i.e. no forced blanking, no mid-screen PPU changes or any other kind of special effects), you should check your program for bugs. If you are indeed just doing the "bread and butter", there is no reason for current emulators to disagree on the output. If this is happening, even if your program happens to work on hardware as expected it's probably not very stable, and might still fail under certain circumstances.

What I mean is, don't blame the emulator(s) if you are not relying on obscure aspects that are not well documented.

by on (#66511)
It's a little more than bread and butter.. I've also added some cheese.
I've used an NSF from Famitracker using the MMC5 expansion chip and I do some bankswitching, but 4/9 emulators doesn't have the extra sound channels or other sound issues. The main point of the program is the music, and when it's not played correctly I'd like to be able to say "This is not what it's supposed to sound like". The point of the PPU writes was just to detect emulators in general, though. But I don't have any way of testing on the real hardware at the moment, so I suppose I'll let it pass.

tokumaru wrote:
What I mean is, don't blame the emulator(s) if you are not relying on obscure aspects that are not well documented.

I suppose you mean IF i rely on obscure stuff, but that's not my point. My point is that many emulators doesn't aim on being accurate and I'd like to be safe and detect them and tell the user "Safety helmet required, enter on your own risk". Not that it's something I'd die for, though, it'd just be nice to do.

by on (#66512)
Only practical use for emulator identification is to check for shaky scrolling, then correct for the timing difference if shaking is detected, so it looks better on the emulator. This is especially for NESten or NNNesterJ. VirtuaNES and LoopyNES aren't too bad.

Or detect Nesticle and outright reject it for games which do ANY kind of raster effects. Games which just scroll with no effects tend to work fine on Nesticle though, with some exceptions (like Cartoon Workshop).

by on (#66519)
Wkter wrote:
I've used an NSF from Famitracker using the MMC5 expansion chip and I do some bankswitching

MMC5 mapper support among emulators and even PowerPak can be incomplete.

Quote:
but 4/9 emulators doesn't have the extra sound channels

Neither does a Nintendo Entertainment System. If you're relying on the extra sound channels, you're not really making an NES game (at least until that plug-in adapter for the expansion port comes out); you're making a Famicom game.

Quote:
I suppose you mean IF i rely on obscure stuff

Mapper sound is "obscure stuff".

by on (#66522)
tepples wrote:
Neither does a Nintendo Entertainment System. If you're relying on the extra sound channels, you're not really making an NES game (at least until that plug-in adapter for the expansion port comes out); you're making a Famicom game.

Oh, snap! I had forgotten about that.
With the expansion port adapter wouldn't it be as simple as connecting EXP0-EXP1 with Audio In/Out on the adapter, and use the EXP0-EXP1 in the cartridge as the Audio In/Out on the Famicom?

by on (#66523)
Even the NES format MMC5 boards were made with slots for resistors that can be soldered to add sound to one of the EXP pins, and then it could just be connected to audio_in and work.

NB : The MMC5 should be the best emulated expansion sound, because it's just two more square wave channels which are identical to the ones inside the NES except the lack the sweep function. (or are you using that weird/undocumented additional DMC channel ?)

I'd fear that other types of expansion sound (FDS, VRC6, N106) would be emulated inaccurately - because it's hard to make a card using them on 100% real hardware. For VRC6 you'll have to import one game from japan, for the FDS not only you have to import one, but you'll have to do crazy modifications to it to be able to rewrite disks, and for the N106 all cads are epoxy blobs so impossible to change the ROMs on them.

I believe the VRC7 and FME7 are variants of well known standard sound chips, so they should be decently emulated.

by on (#66526)
Bregalad wrote:
NB : The MMC5 should be the best emulated expansion sound, because it's just two more square wave channels which are identical to the ones inside the NES except the lack the sweep function. (or are you using that weird/undocumented additional DMC channel ?)

No, I only use the standard square channels, which is why I was surprised so many emulators didn't emulate them. I suppose it had lower priority due to the NES doesn't support the extra sound from the cartridge?

by on (#66540)
You're probably right about priority. In 72-pin locales, MMC5 means Castlevania III and a bunch of turn-based war sims published by Koei. The majority of emulator users' priority on MMC5 is just to see CV3 working, even though CV3 uses very few of the MMC3's advanced features.

by on (#66551)
Bregalad wrote:
and for the N106 all cads are epoxy blobs so impossible to change the ROMs on them.

Bregalad, you do know it's common practice to cut a square around the glop-tops and use their traces to connect to them, right?

Example 1
Example 2
Example 3

So even if changing the ROM on the board is impossible, it should still be possible to remove the mapper and put it in another board. It's not impossible.

by on (#66559)
I've done that blob stuff few times, when reviving some good pirate game controllers.

by on (#66571)
OK it's great to know it's technically possible to test something on the N106 on the hardware. Then you have to :

- Import a Namco game from japan using this mapper
- Open this game and cut the epoxy blob containing the mapper
- Find a host board that has a mapper that could be replaced by the N106 without too much modifications
- Connect all wires to the host board

Or alternatively :

- Cut the epoxy blobs for both PRG-ROM and CHR-ROM on the game you imported, and somehow connect your own EPROMs/FLashROMs to them.

by on (#66577)
Quote:
OK it's great to know it's technically possible to test something on the N106 on the hardware. Then you have to: [...]

Or hotswap the cartridge, without any modifications.

by on (#66580)
Can you make a complete sound code that fits in the NES' 2k of RAM, and use a cartridge only for its mapper ?
Or do you mean this technique would just work to verify tricky test on real HW to know if the channels are emulated properly - without testing an actual song ?

BTW it's fun I already wondered if it would work to have code running entierely in the internal 2k of RAM, of course it would require to completely disable NMIs and IRQs, and hopefully the user don't press reset. Then you can remove the cartridge and have a program that still runs (if you don't use any graphics that is).

by on (#66584)
Bregalad wrote:
Can you make a complete sound code that fits in the NES' 2k of RAM, and use a cartridge only for its mapper ?

That's doable. How big was the music code in SMB1? And how hard would it be to stream the music from a PC through controller port 2?

But doing without NMI might screw you up because you can't reliably wait for vblank without hitting the 1/21 skip probability from spinning on $2002. If you can hook a game's NMI handler, on the other hand... What main loop style did Namco use most in N106 games? SMB1-style (all in NMI), FF1-style (all in main loop), or mixed?

by on (#66587)
Polling 2002 is quite reliable if you're checking for the sprite 0 hit bit to change, instead of the VBL bit.

Maybe not sprite 0 hit, since there may be no CHR data available, so maybe use the sprite overflow bit instead.

by on (#66589)
Bregalad wrote:
Can you make a complete sound code that fits in the NES' 2k of RAM, and use a cartridge only for its mapper ?

Sure, but you merely mentioned testing things on the N106. The simplest way to do full code is to stream sound commands over a link to a PC.

Quote:
BTW it's fun I already wondered if it would work to have code running entierely in the internal 2k of RAM, of course it would require to completely disable NMIs and IRQs, and hopefully the user don't press reset.

I do this all the time. Small loader sits in memory waiting to receive $500-byte program from PC, program is run, then loader is re-run waiting for next program.

You could poll the 2A03's frame IRQ flag, since that can be reliably read. Or you can rely on the data stream from the PC to the NES for timing.

by on (#66590)
For the N106, there is one message thread on this board that explain how to take a dragon ninja cart that doesn't contain any epoxy blob, add the missing hardware for the sound to work and convert it.

The thread is here, by Sdm.

Before saying that it's not possible, it's good to search in the archive of nesdev ;)

by on (#66621)
I'm not sure what mod this guy did. Are you sure he "added" missing sound hardware ?

Quote:
But doing without NMI might screw you up because you can't reliably wait for vblank without hitting the 1/21 skip probability from spinning on $2002. If you can hook a game's NMI handler, on the other hand... What main loop style did Namco use most in N106 games? SMB1-style (all in NMI), FF1-style (all in main loop), or mixed?

err... you can't hotswap the cartridge intantly, so the vectors will be open bus for a while.

Quote:
And how hard would it be to stream the music from a PC through controller port 2?

Mmmh inteseting but I'm afraid it's very hard. You'd need an old PC with a parallel port and a program sending data to it, and you'd need to make wires that reliably connect your parallel port to the controller port. Possible, but no easy task.

Quote:
I do this all the time. Small loader sits in memory waiting to receive $500-byte program from PC, program is run, then loader is re-run waiting for next program.

All the time really ? May I ask why / how ? Have you made tests on obscure mappers that way ?

by on (#66625)
Bregalad wrote:
Mmmh inteseting but I'm afraid it's very hard. You'd need an old PC with a parallel port and a program sending data to it, and you'd need to make wires that reliably connect your parallel port to the controller port. Possible, but no easy task.

Did you see my Nokia display to USB project on instructables? You don't need a parallel port at all and it's infact very easy to make. As far as I know, Atmel has some AVR chips that have high-speed USB. So it should defiantly be feasible with very little effort put into it.

by on (#66627)
Bregalad wrote:
Quote:
And how hard would it be to stream the music from a PC through controller port 2?

Mmmh inteseting but I'm afraid it's very hard. You'd need an old PC with a parallel port and a program sending data to it, and you'd need to make wires that reliably connect your parallel port to the controller port. Possible, but no easy task.

Uhhh, no. You can use a serial port, including one of the cheap USB-serial adaptors available. It's not hard at all, and doesn't require that the PC do any special timing.

Wkter wrote:
Did you see my Nokia display to USB project on instructables? You don't need a parallel port at all and it's infact very easy to make. As far as I know, Atmel has some AVR chips that have high-speed USB. So it should defiantly be feasible with very little effort put into it.

You don't need any MCUs, just a serial port connected to a controller cable. For example, the FTDI USB-to-TTL 5V cable, just splice it with a controller cable, as I and thefox have done recently. Or use a MAX232, as I've been doing for about 15 years now for NES and SNES development via connection to a PC.

Quote:
I do this all the time. Small loader sits in memory waiting to receive $500-byte program from PC, program is run, then loader is re-run waiting for next program.

All the time really ? May I ask why / how ? Have you made tests on obscure mappers that way ?[/quote]
I have a lot of devcarts with only battery RAM, no ROM. These get corrupt due to a crashed program, or one that hangs when the reset vector doesn't point to the bootloader, so I need to rewrite the RAM. I just boot on another cartridge, then hotswap to the one needing reprogramming (with a programming running on the NES that cosntantly does sprite DMA, so that it's less likely to crash). And as you say, this is how I ran tests on various revisions of the MMC3, also some of those MMC5 tests. Combined with the Game Genie, you can have the NMI and IRQ vectors pointing into RAM.

by on (#66629)
Bregalad wrote:
err... you can't hotswap the cartridge intantly, so the vectors will be open bus for a while.

Which is why you turn off all NMI and IRQ for the few seconds it takes to Stop 'n' Swop.

Quote:
You'd need an old PC with a parallel port

Or a USB to serial adapter. We recently had a topic about such cables in the HW section.

by on (#66639)
Bregalad wrote:
I'm not sure what mod this guy did. Are you sure he "added" missing sound hardware ?


Dragon Ninja doesn't use the N106 music hardware, just the mapper. From what I understood, Sdm converted the cart and could use Megami tensei II on it which does require N106 part for the music. There is some schema related to the music mod but I don't understand electronic so I don't know what it does exactly. Maybe if you read the thread and check the schema you will figure it out.

Dragon Ninja is not an expensive cart. I got one cart exactly for that but never found the time to do the mod. It does contain a N106, no blob (I opened it).

by on (#66675)
tepples wrote:
Bregalad wrote:
Can you make a complete sound code that fits in the NES' 2k of RAM, and use a cartridge only for its mapper ?

That's doable. How big was the music code in SMB1? And how hard would it be to stream the music from a PC through controller port 2?


I've done the sound streaming before, it was absurdly simple. Added just a few lines of code to an NSF plugin for winamp, then had the NES sit there and continually grab "address, data" in bit-banged RS232 style. Extend the address you can control the entire NES that way too, I suppose.