Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

Ads

#1 2018-11-11 20:48:08

PinoBatch
Member
Registered: 2018-03-22
Posts: 31

Telling LYs? (test ROM)

This program tests a Game Boy emulator's input entropy.

The Game Boy has an interrupt that can fire when a button changes from not pressed to pressed.  This interrupt can fire 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 inspecting a hardware register called LY, which presumably stands for LCD Y Position.  For instance, it could wait for a press at the title screen and then seed a random number generator from LY.

But simple emulators always fire the joypad interrupt at the same time each frame, such as the start or end of vertical blanking. The lack of variance in LY 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), one after another in any order. The arrow at the right side tells exactly when, relative to the LCD frame, your button changed from not pressed to pressed.

https://forums.nesdev.com/download/file.php?id=13968

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

Test results

- Game Boy (DMG), Game Boy Color (CGB): Pass
- Game Boy Player (DOL-017): Pass
- BGB 1.5.7: Pass
- mGBA 0.8-5388-f92059be: Fail (though replies to issue #1232 dispute whether it's a bug at all)

Download Telling LYs? ROM and source code

Offline

 

#2 2018-11-13 04:01:54

nitro2k01
Administrator
Registered: 2008-02-22
Posts: 181

Re: Telling LYs? (test ROM)

Why use the interrupt, as opposed to polling P1? It's not the interrupt per se, but changes to the joypad state which has this behavior. Polling would give you the added benefit of being able to detect all changes to the joypad state, as opposed to the subset that the interrupt can detect. Although it should be said that on hardware, the interrupt is likely to fire on on->off transitions as well, due to switch bounce in the contact. And likewise, does it add anything to require pressing each button once, as opposed to pressing the same button multiple times?

In discussions with beware, I've said that I'm not sure of the merits of fixing this issue in emulators. For what benefits it may have, it adds another layer of complexity to code that should have normally have a very simple logic. It also effectively introduces 1 frame of lag if implemented naïvely, since a button transition is likely to be delayed into later into a certain frame, and not be seen by the game until the next frame. beware solved this by detecting the game's behavior and only enabling the fix if needed. This solves the lag issue (for typical games) but introduces even more complexity under the hood.

As far as I remember from discussions with beware at the time he implemented this fix, the issue with Super Ninja (mentioned in the mGBA issue linked in the OP) was that it was polling the P1 constantly and somehow was relying on switch bounce for receiving double (or maybe an even number) of off->on transitions. The time in the frame where the transition would occur would not have affected this, per se. Caveat emptor: this may have been a different game than the aforementioned Super Ninja.

As an aside, it is likely possible to detect SGB using similar timing methods. Since the SGB is running asynchronously to the SNES, button transitions would not happen on GB VBlank intervals, though. Instead, they will happens at the SNES's frame rate. So by accumulating the time between transitions you should be able to detect that the timestamps for the transitions are congruent to that rate. And because of this, I would predict that Super Ninja works as poorly on SGB as it does on certain emulators.

Edit: Clarification about the last sentence. The reason I predict Super Ninja would work poorly on SGB is the lack of switch bounce, not the periodic rate at which the button state is updated.

Last edited by nitro2k01 (2018-11-14 03:53:07)


Blog: Gameboy Genius
"A journey of a thousand miles begins with one small step"
Old Chinese Proverb

Offline

 

#3 2018-11-20 21:03:20

PinoBatch
Member
Registered: 2018-03-22
Posts: 31

Re: Telling LYs? (test ROM)

nitro2k01 wrote:

Why use the interrupt, as opposed to polling P1?

Power. Waking up only for vblank (to update the scroll position and run the OAM DMA) and for keypresses keeps the CPU in battery-sipping halt state longer.

nitro2k01 wrote:

Although it should be said that on hardware, the interrupt is likely to fire on on->off transitions as well, due to switch bounce in the contact.

The joypad interrupt handler disables the joypad interrupt if exactly one button was pressed. On bounce, the handler instead runs again. It also reads the controller during vblank, and once no buttons are pressed, it reenables the interrupt.

nitro2k01 wrote:

And likewise, does it add anything to require pressing each button once, as opposed to pressing the same button multiple times?

It lets the program double as a generic input test, and if there is bounce that it misses, it doesn't see the button as two steps toward completion.

nitro2k01 wrote:

beware solved this by detecting the game's behavior and only enabling the fix if needed. This solves the lag issue (for typical games) but introduces even more complexity under the hood.

His solution the randomization on and off based on polling pattern. If the joypad interrupt is on, or more than two consecutive scanlines, and demo recording/playback is off, the complex stuff turns on. Otherwise, it uses the simple method. Thus a game's menu might use LY reads in joypad interrupt handler to collect entropy to seed an RNG, and then the gameplay itself reads only after vblank.

nitro2k01 wrote:

As an aside, it is likely possible to detect SGB using similar timing methods.

It is. Running Telling LYs and repeatedly pressing the B Button causes the arrow indicator at the right to move down the screen slightly faster than once a second, based on SGB's GB vblank running faster than Super NES 60.10 Hz vblank. It'd probably run the other way on SGB2. Game Boy Player cannot be detected this way, as Startup Disc either polls the controller more than once per frame or randomizes input.

As for bounce and timing being distinct: I'm told Game Boy Advance SP uses buttons that are far less prone to bounce than Game Boy, Game Boy Pocket, Game Boy Color, or the original Game Boy Advance.

Offline

 

#4 2018-11-24 20:48:51

Tag365
Member
Registered: 2016-06-01
Posts: 41

Re: Telling LYs? (test ROM)

PinoBatch wrote:

nitro2k01 wrote:

Why use the interrupt, as opposed to polling P1?

Power. Waking up only for vblank (to update the scroll position and run the OAM DMA) and for keypresses keeps the CPU in battery-sipping halt state longer.

So you mean that "Waking up only for vblank and for keypresses" means the battery drains faster?

Offline

 

#5 2018-11-25 11:43:02

PinoBatch
Member
Registered: 2018-03-22
Posts: 31

Re: Telling LYs? (test ROM)

"Battery-sipping" means low current. It is contrasted with "battery-guzzling" meaning high current.

Reading the controller in a busy wait loop uses more power than reading the controller only once per vblank and once per keypress in an interrupt handler.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson