Lonk

We all know what superbunny is. I hope. Lonk is the exact opposite. Two separate addresses help control Link's general state (actually like 300, but we're looking at 2). Address $5D is Link's general state handler. Address $02E0 is a graphics flag.

In the superbunny state, $02E0 has a value of 1, signalling bunny graphics, but $5D has a value of $00, which indicates Link is in his default, human state. Anything that looks at $02E0 for the bunny (such as using items), will believe that Link is a bunny. But anything using $5D (such as the general routine handler that handles A and B inputs) will think he's human.

For Lonk, it's the opposite. $02E0 is 0, signalling human form, but $5D is $17, which means Link is a bunny.

Underworld

To understand how Lonk can trigger when entering the underworld, we need to look at 2 routines that are run when loading the underworld. These routines are executed one after another, so let's show them for fun:

JSR $89F1
Dungeon_ResetTorchBackgroundAndPlayer
JSL $1CFCE2
Link_CheckBunnyStatus

Dungeon_ResetTorchBackgroundAndPlayer does what it says on the tin, but we want to look specifically at the end of it—the part that handles player properties:

LDA $0372
Is Link dashing (or armed spinspeed)
BEQ exit
If not, do nothing
STZ $4D
Clear secondary state handler
STZ $46
Clear recoil timer
LDA #$FF
STA $29
Reset z-axis recoil
STA $C7
I think this one is pointless
STZ $3D
Reset sword stuff
STZ $5E
Reset speed
STZ $032B
Collision related?
STZ $0372
Reset dashing
LDA #$00
Why is this not an STZ?
STA $5D
Reset primary state handler
exit
RTS

The important take away here is that if Link is dashing, then his primary state handler $5D is reset, otherwise, it is left alone.

Link_CheckBunnyStatus is as follows:

LDA $5D
Check primary state handler
CMP #$02
Is Link recoiling?
BNE exit
If not, just leave
LDY #$00
$00 indicates default state
butt
LDA $02E0
Check graphics flag
BEQ set
If human, set $5D to $00
LDY #$17
$17 indicates bunny state
LDA $7EF357
Check for pearl
BEQ set
If no pearl, $5D to $17
LDY #$1C
$1C indicates temporary bunny
set
STY $5D
Set primary state handler
exit
RTL

EXCEPT I LIED!!!!

You see that instruction labelled butt? That's what they intended to do, and that's what's executed in the US version, but in JP1.0, this is what actually happens:

butt
LDA $E0
Check the camera

They assembled it wrong. Instead of reading the 16-bit address for Link's graphics, the addressing mode used was direct page, an 8-bit address. Their source code probably had the correct address, but a stray symbol must have caused it to discard the high byte. It just so happens that the low byte of the intended address is the address for the low byte of the BG1 horizontal scroll.

By the time this check is performed, the entrance's properties has been loaded. Thus, the camera properties being looked at are for the landing point of the entrance. As long as the camera's low byte is not 0, then damage boosting into an entrance will put Link in Lonk state when he doesn't have the moon pearl. In practice, this means that Lonk can only be triggered if the entrance is in the middle of the supertile.

Misbehavior

The state mismatch between the two addresses I originally described ($5D and $02E0) is all you really need to understand the majority of this glitch. Lonk's walk's wonk is due to a shorter animation cycle from $5D being $17 for bunny. Sword and boots are inhibited by that as well. Items, on the other hand, are looking at $02E0. Why? The bunny is allowed to use bottles, so the general state handler can't be used to—well, I guess it could…? That's just not the way they coded it.

Pretty much everything related to both Lonk and Superbunny boil down to which address the developers decided to check for bunny status. Some of these decisions may have been to facilitate the logic when taking temporary bunny into account, but all we can really do is guess.

Other triggers

Other methods of triggering Lonk are fairly straightforward. There is no complexity beyond one of the values was set out of sync.

For whatever reason, the pond code uses the routine Player_ResetState ($07:F18C), which aggressively resets a number of addresses. So aggressive, in fact, that 4 different addresses are reset twice. The only relevant address not reset is $5D, so it will remain as whatever it was. If that value was $17, then we end up as Lonk.

After doing an overworld bunny revival, Link is in a completely normal state, except for address $56. This address is normally kept in sync with $02E0, but not always. In the case of fairy revival above water, it is never checked. Nor is it cleared. To show Link spinning around properly, $02E0 is set to 0 by the revival code. Recovering that value only occurs if $56 is nonzero, but that check is skipped when Link is revived above water. Curiously, $56 is also the address checked when Link is kicked out of the water for not having flippers. Because it is out of sync with $02E0 and doesn't attempt to resync at any point, this routine results in a bunny-revived Link entering the bunny state, with no change to his graphics.

The hookshot disables Lonk because it actually puts Link into a special state, setting $5D to $13. When that's over, the address is reset to 0, because it was assumed that the hookshot could only be used in the default state.

Summary

A disagreement between two addresses—$5D and $02E0—is the cause of all weird Lonk behavior. Taking damage into an overworld–underworld transition causes Link's general state handler ($5D) to either be put into temporary bunny (with the moon pearl), or permabunny (without) when the entrance leads to the center of a supertile. The damage in an entrance version a JP1.0 glitch caused by an erroneously assembled instruction.