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
Omar and Lorraine
  • 38,883
  • 14
  • 134
  • 274
  • 4
    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 '19 at 12:38

1 Answers1

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.

Martin Rosenau
  • 3,399
  • 3
  • 11
  • 23
  • I see. I edited my post. – Martin Rosenau Jan 28 '19 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 '19 at 09:21
  • @Wilson yes that the configurable part I was mentioning (did not see the Tommys comment when I wrote the comment) – Spektre Jan 29 '19 at 10:26