OK, found a bit more stuff.
Battle data is arranged in eight blocks of 0x130 bytes, starting at the address in 0x03000FDC (U,E) / 0x03000FE0 (J). There are also pointers in 0x03003FA4-C0 (C4-E0 in (J)) to each of the actors' battle data. Mario and Luigi are always the last two blocks, and the enemies take up some number of the first six.
Some of the addresses above, relative to the start of a block:
addr size value
--------------------
0x018 word current xpos
0x01c word current ypos
0x020 word current altitude
0x0d8 word starting xpos
0x0dc word starting ypos
0x0e0 word starting altitude
0x0ec half enemy ID
0x0f5 byte level
0x0f6 half current HP
0x0f8 half max HP
0x0fa half HP - old value, when changing
0x0fc half current BP
0x0fe half max BP
0x100 half BP - old value, when changing
0x102 half pow (Bros. only)
0x104 half def
0x106 half speed
0x108 half stache (includes Lucky Mushroom)
0x10a half pow multiplier
0x10c half def multiplier
0x11c half speed multiplier
0x11e half status effect flags
0x12b byte badge effect +1
0x12c byte gear effect +1
0x12d byte pin effect +1
As for turn order stuff, this appears to be the formula:
When choosing an actor to move, all eight actor slots are considered (I believe dead actors are treated the same as live ones). The following are special cases:
- If the actor doesn't exist, nothing happens.
- If the actor has already moved this turn, they are not considered.
If the actor is eligible for a move this turn (i.e., it does not meet those two criteria):
- Their (spd * spd multiplier) >> 8 is compared with the highest thus far.
- If it is higher (or the first eligible actor), they will be the next to move.
- If it is lower, ignore the actor, it cannot be the next to move.
- If it is the same, generate a number N in range [0, # of actors thus far with that value); the N'th of those actors (0-indexed, in actor order) will be the next to move.
As an example, given the start of a battle on (U) with three Paratroopeas, Mario (speed 120), and Luigi (speed 20):
- Paratroopea 1 considered (speed = 80). First actor to be considered, so it is the next to move by default.
- Paratroopea 2 considered (speed = 80). Tie with the current highest speed, so RNG is rolled for range [0, 2). Result is 1, so second Paratroopea becomes the next to move.
- Paratroopea 3 considered (speed = 80). Tie with the current highest speed, so RNG is rolled for range [0, 3). Result is 0, so first Paratroopea again becomes the next to move.
- <skips next three actors>
- Mario considered (speed = 120). His speed is highest, so he becomes the next to move.
- Luigi considered (speed = 20). His speed is lower than the current highest (Mario's), so he is ignored.
- All actors have been considered; Mario gets to move next, and will not be considered again until all actors have taken a turn.
I presume there are special cases for the Mario Follow / Mario Ahead effects that skip Luigi and make him move before / after Mario in the event he is selected.