Telling LYs? (Input timing test ROM)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Telling LYs? (Input timing test ROM)
by on (#239871)
This program, a port of a test ROM for Game Boy, tests an NES emulator's input entropy.

The NES CPU can read the system's controller ports more often than once per video frame, which is 50 or 60.1 Hz. The state of the controller ports can change at any time in the frame: top, middle, bottom, or in the vertical blanking between frames. A program can see exactly when the interrupt fired by polling the controller repeatedly during a frame and counting how many times it was polled since the start of the frame. For instance, it could wait for a press at the title screen and then seed a random number generator from the time it took.

But simple emulators always change inputs at the same time each frame, such as the start or end of vertical blanking. The lack of variance in timing is telling about whether an emulator was used; hence the name.

How to use

Starting at the title screen, press all four directions on the Control Pad and all four buttons (A, B, Select, and Start) of controller 1, one after another in any order. The arrow at the right side tells exactly when, relative to the PPU frame, the last button changed from not pressed to pressed.
Attachment:
File comment: After having pressed five buttons
telling-lys_000_8.png
telling-lys_000_8.png [ 18.59 KiB | Viewed 2878 times ]

Once you have pressed all eight keys, a screen for passing or failing appears.

Test results
A front-loading NTSC NES with a PowerPak passes. FCEUX as of June 2019 and Mesen 0.97 (September 2018) reach the "Incorrect behavior" screen, with the arrow remaining in roughly the same position throughout the test.
Re: Telling LYs? (Input timing test ROM)
by on (#239874)
I still think that the program could benefit from a "polite answer" or "devasting answer" option before showing the test result.

For actually emulating "real" scanline timings: It depends on how often the emulator is reading controls (or when it receives controller IRQs or windows keyboard messages etc).
For most responsive controls the emulator should then forward the input to the emulated hardware without artifically delaying the input timings.

What might work is starting/stopping the CPU emulation at 15kHz intervals (instead of 60Hz intervals) (ie. delay the CPU emulation, instead of delaying the controller inputs).

I don't think that it's too important to emulate super accurate controller timings though.
Re: Telling LYs? (Input timing test ROM)
by on (#239876)
It's just that 60 Hz polling is something that a program can easily Spot and exploit for copy protection, or it may cause problems where a program works on an emulator but occasionally fails to notice input on hardware. I've read of two ways to work around it:

A. Pass on the timing you do get
If the OS provides input event timestamps with 1 ms timing to the application at 1 kHz, the emulator can pass on the events to the ROM with 1 ms timing. This is what, for example, the Game Boy Interface (GBI) homebrew driver app for Game Boy Player on GameCube does, as it polls the GameCube controller at 1000 Hz.

B. Add realistic randomness if it can be detected
bgb, a Game Boy emulator by beware, normally changes input state at vblank to improve input latency. But if the ROM does anything where it can detect this behavior, namely if the ROM enables joypad interrupt or has recently polled the controller several times during a single frame, bgb switches to changing it at a pseudorandom time. Though the joypad interrupt doesn't apply to NES implementation of this heuristic, it might be trickier to accommodate DPCM-safe controller rereading routines.