1

The question you are now reading is about a comment on this question, about overflow bugs in some Pokemon game. A comment on that question says:

It was Game Freak's first project. They just were sloppy programmers. This function merely divides by four, in the usual Game Freak style of doing things.

; 92bbe (24:6bbe)

Unreferenced_Function92bbe: ; 92bbe
    push hl
    srl a
    srl a
    add LOW(.Unknown_92bce)
    ld l, a
    ld a, 0
    adc HIGH(.Unknown_92bce)
    ld h, a
    ld a, [hl]
    pop hl
    ret

; 92bce

.Unknown_92bce: ; 92bce
    db 0, 1, 2, 3, 4, 5

It starts off by saving HL, and I can see it restores HL at the end. That's because it uses HL to construct some kind of pointer which is discarded at the end.

So srl a is obviously going to divide a by two, so doing that twice should divide it by four! The next thing should be to restore HL (or not push it in the first place) and the return, right?

But it's hardly worth putting just srl a;srl a in a subroutine. So there's more: from what I can see, it's computing a pointer to the array marked .Unknown_92bce offset by the accumulator. In other words, it's going to use the value in the accumulator to look up ... the value in the accumulator. If the accumulator is 3 for example, then fetch 3 from the array.

And then obviously it restores hl and returns.

Am I missing something? Is this subroutine equivalent to the following?

Unreferenced_Function92bbe:
    srl a
    srl a
    ret
  • 3
    I don't think you're missing anything; I might speculate that maybe the table originally modelled some function other than f(x)=x but was revised very late on to tweak a gameplay mechanic? That's being generous. – Tommy Jan 28 at 12:38
3

Am I missing something? Is this subroutine equivalent to the following?

Did you see the ld a, [hl]?

The lines before that one are calculating hl = .Unknown_92bce + (a/4).

Then the ld a, [hl] will load the byte from that address.

... so the function is equivalent to the following C pseudo code:

extern byte Unknown_92bce[];
...
Unreferenced_Function92bbe()
{
    A = Unknown_92bce[A/4];
}

Not sure about that. Ignoring the possibility of an overflow, the array Unknown_92bce contains the sequence of integers 0, 1, 2, 3, 4, 5.

If A is in the range 0...20, this really makes no sense.

Some cartridges may contain some special logic that detects (read) accesses to a certain address to do bank switching or similar.

In this case ld a, [hl] is not there to read some value from an array, but to do the bank switching.

However, if the module does not contain such a logic and A is guaranteed to be in the range 0..20, this really makes no sense to me.

  • 1
    Not sure about that. Ignoring the possibility of an overflow, the array Unknown_92bce contains the sequence of integers 0, 1, 2, 3, 4, 5. That means Unknown_92bce[A/4] == A/4. – Wilson Jan 28 at 12:17
  • I see. I edited my post. – Martin Rosenau Jan 28 at 12:28
  • @Wilson is the LUT Unknown_92bce constant or not? without more context is hard to say what it really does. It also might be a leftover from something older or a part of a configurable code ... – Spektre Jan 29 at 9:21
  • 1
    @Spektre Unknown_92bce is in read-only memory; it may not be changed. As Tommy said, maybe they needed to be able to change it during development – Wilson Jan 29 at 9:36
  • @Wilson yes that the configurable part I was mentioning (did not see the Tommys comment when I wrote the comment) – Spektre Jan 29 at 10:26

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.