a possible loophole is if the Morph timer gets reduced to something like FFFFh (and then 00FFh) when a Revert-prohibiting status is in effect, and you have a VERY small Morph decrementor (e.g. 16d). once the status is gone, Revert won't necessarily be queued right after, as the next few calls to C2/1211 won't zero Morph's timer. should the battle end quickly, you're now hoping that the end-of-battle code calls C2/0B36. i don't like relying on it for this, especially given there are multiple ways for a battle to end, and thus multiple holes to plug for patchmakers.
I'm not 100% sure I understand what you're trying to explain, so bear with me... when you say "something like FFFFh", you mean if the subtraction is performed when $3F32 > $3F30, correct? As in, the last tick of the timer?
So if I understand you correctly, this is caused by not zeroing $3F30 in C2/1211? The smallest natural decrementor is 8 (Max supply, after Phunbaba, with Slow), so if $3F30 was exactly FFh, there can be a delay of up to 32 frames to run down the timer again and re-queue Revert, during which the battle could end, thus preventing Revert for about half a second. Correct?
With the Stop/Quick/Freeze check in effect, those statuses will prevent C2/1211 from running the few remaining ticks of the timer down and re-queueing Revert until they end, while Sleep will let it keep running down over and over again and try to re-queue Revert every 32 (at most) frames, until the battle ends. If I'm not mistaken.
As you say, this could also happen if the battle ends while Terra is Sleeping, or if Stopped/Frozen (and her timer ran out during their animation), or if her timer ran out while someone cast Quick, and then finished the battle while Quicked.
In the case of Stop/Freeze/Quick being in effect through battle end, since we pause C2/1211 for those statuses, we're always relying on battle ending code to correctly update the supply. In any case, since we're stopping the timer for battle end, we should make sure all battle endings update the supply as well.
a well-timed Haste or Slow casting might mitigate the problem of the "a possible loophole ..." scenario laid out in my May 5th post. the now-recalculated, post-timer-expiration Morph decrementor will be rather large, so that will minimize the wait for a follow-up Revert to be queued. (a wait that should really be infinitesimal or nonexistent, so this is an improvement, however weird).
---
oops, think i got that wrong, by assuming that a very low Morph supply would simply give a very large decrementor. but the supply in that example is 0, and there are problems calling C2/0B01 with that:
- you edited out the decrementor capping at 2048.
- even with capping, the earlier "JSR $4792" will perform a divide by 0, and return nonsense.
so it's better called "an ill-timed Haste or Slow casting". :/
thus, i recommend adding back the capping check, and adding a "BEQ $0B2C" before the "JSR $4792", so a minimum supply gives a maximum decrementor.
while it might be tempting to drop the "JSR $0B36" to avoid this particular issue, my May 05, 2016, 10:18:44 PM CDT (May 06, 2016, 03:18:44 AM GMT) post -- and numerous others -- explains why doing that is nonsense and risky.
Sorry to open the debate on this again, but this just has me MORE convinced that updating the supply the very instant the timer runs out is the risky option. I seems safer to update the supply only once we've cleared $3EE2, thus stopping the calls to C2/1211 AND C2/0B01.
I just think it makes sense to only update supply after Morph definitely has ended, as marked by Revert executing, or the battle ending. In other words, dropping the "JSR $0B36" in C2/1211 in favour of a "STZ $3F30".
i think an empty gauge would show up in end battle even if the latter is no longer called, but should really test it.
I'm not exactly sure if by "empty gauge" you mean "no decreasing green gauge" or a literally empty gauge (no increasing white ATB gauge either). If it's the former, clearing $3EE2 at battle end (thus stopping the calls to C2/1211) does indeed clear the green bar and restores the white ATB bar.
but it's gotta be more than 3 bytes to fit both the $3EE2 test and the call, no? that said, i'm not sure why you have "PHA / PLA" surrounding the call to init_morph.
You're right, preserving A isn't needed, my mistake.
When I said three bytes, I was thinking that we could let C2/0B01 handle the check, but that only checks "if someone is morphed", not "is current target morphed" and we don't want casting Haste/Slow on someone ELSE to change the speed on Terra's Morph bar.
This is a somewhat risky suggestion what with all the hack authors out there, but couldn't we change the LDA $3EE2/BPL in C2/0B01 to CPX $3EE2/BEQ? In vanilla, there should only exist one Morpher (Terra) at a time (not considering craziness like the Rippler bug, but setting Morph via Rippler doesn't initialize their timer, so it doesn't set $3EE2 either).
I would hope any potential hack authors interested in allowing multiple Morphers and using this patch would read the documentation I intend to write (where this caveat would naturally feature) and find out how to remedy the problem (commenting/uncommenting some lines in the included .asm file).

Anyone wanting a hack with multiple Morphers has other problems anyway, since there is only one timer and one supply (and only Terra can add to it, I think). They would have to rewrite the Morph code anyway to account for multiple Morphers. Changing the LDA/BPL to CPX/BEQ would actually
FIX the problem of multiple Morphers resetting each other's timers make it worse by only timing the
first last morpher, (even if they are running down the supply while doing so),
even if it would in addition to introducing some weirdness with Haste/Slow affecting everyone's gauges. I suppose it actually makes sense that they would each be updating the decrementor, too, with the Morph supply being shared.

No, wait, that wouldn't fix it, that would make it
worse, since only the first Morpher would get a timer and the others would get free unlimited Morph.
