As I promised months ago, here's the relevant assembly code.
This code sets the pause flag during each loop of the battle module in Recommended/Wait mode. If no command is being executed, the pause flag is set to 0x00. If the command being executed is from a priority queue (e.g. counters and limit breaks), then we don't change the pause flag. If the command being executed is from the normal command queue, then we set the pause flag to 0x01 if there are no moves waiting on the queue, otherwise we set it to 0x03.
000a32c0: 3c02800f lui r2,0x800f ; BEGIN ATB PAUSE FLAG SUBROUTINE
000a32c4: 94427daa lhu r2,0x7daa(r2) ; r2 = $0x800F7DAA (0b01 = 0x01 if ATB Recommended, 0b10 = 0x02 if ATB Wait)
000a32c8: 27bdffe8 addiu r29,r29,0xffe8 ; r29 = r29 - 0x0018
000a32cc: 1040001d beq r2,r0,0x000a3344 ; skip ATB animation pause check if neither Recommended nor Wait
000a32d0: afbf0010 sw r31,0x0010(r29)
000a32d4: 10800012 beq r4,r0,0x000a3320 ; branch if r4 == 0... (no active command)
000a32d8: 34020006 ori r2,r0,0x0006 ; with r2 = 0x06
000a32dc: 3c03800f lui r3,0x800f
000a32e0: 94637dba lhu r3,0x7dba(r3) ; r3 = $0x800F7DBA (which queue are we resolving, counters and limits have priority)
000a32e4: 00000000 nop
000a32e8: 14620016 bne r3,r2,0x000a3344 ; branch if r3 != 0x06 (0x02 counterattack queue, 0x05 limit break queue, otherwise 0x06 for normal moves)
000a32ec: 00000000 nop
000a32f0: 3c03800f lui r3,0x800f
000a32f4: 90636b9a lbu r3,0x6b9a(r3) ; r3 = $0x800F6B9A (current queue position)
000a32f8: 3c02800f lui r2,0x800f
000a32fc: 90426ba1 lbu r2,0x6ba1(r2) ; r2 = $0x800F6BA1 (total queue length)
000a3300: 00000000 nop
000a3304: 10620002 beq r3,r2,0x000a3310 ; branch if r3 == r2...
000a3308: 34070001 ori r7,r0,0x0001 ; ...with r7 = 0x01 (if no moves waiting on queue, pause flag is 0x01)
000a330c: 34070003 ori r7,r0,0x0003 ; otherwise r7 = 0x03 (if moves waiting on queue, pause flag is 0x03)
000a3310: 00002021 addu r4,r0,r0 ; r4 = 0
000a3314: 00002821 addu r5,r0,r0 ; r5 = 0
000a3318: 08028ccf j 0x000a333c ; jump to set pause flag...
000a331c: 34060007 ori r6,r0,0x0007 ; ...with r6 = 0x07
000a3320: 0c028dfe jal 0x000a37f8 ; call to check pause flag...
000a3324: 2404ffff addiu r4,r0,0xffff ; ...with r4 = 0xFFFF (null)
000a3328: 10400006 beq r2,r0,0x000a3344 ; branch if r2 == 0 (zeroed pause flag)
000a332c: 00002021 addu r4,r0,r0
000a3330: 00002821 addu r5,r0,r0
000a3334: 34060007 ori r6,r0,0x0007
000a3338: 00003821 addu r7,r0,r0
000a333c: 0c029c95 jal 0x000a7254 ; call to set pause flag
000a3340: 00000000 nop
000a3344: 8fbf0010 lw r31,0x0010(r29)
000a3348: 27bd0018 addiu r29,r29,0x0018
000a334c: 03e00008 jr r31
000a3350: 00000000 nop
Here's the code that updates the pause flag whenever anyone gets full ATB, as part of the ATB increment subroutine.
000a3bac: 96620008 lhu r2,0x0008(r19) ; r2 = $(r19+0x0008)
000a3bb0: 3c03800f lui r3,0x800f
000a3bb4: 8c6339e0 lw r3,0x39e0(r3) ; r3 = $0x800F39E0 (pause flag)
000a3bb8: 3042fffe andi r2,r2,0xfffe ; r2 = r2 AND 0xFFFE i.e. 0b1111111111111110
000a3bbc: 34630002 ori r3,r3,0x0002 ; r3 = r3 OR 0x0002 (this converts 0x01 into 0x03, so animation timer starts incrementing!)
000a3bc0: a6620008 sh r2,0x0008(r19) ; store r2 at $(r19+0x0008)
000a3bc4: 3c01800f lui r1,0x800f
000a3bc8: ac2339e0 sw r3,0x39e0(r1) ; store r3 at $0x800F39E0 (pause flag, increments timer if equal to 0x03)
Here's the code that checks for whether to pause ATB on each frame. First, we check if the pause flag is 0x03, and if so we add Speed_mod to the animation timer. We pause if there's a submenu open in Wait mode, if there's a summon animation playing, the animation timer is greater than 0x4000 = 16385, plus an unknown condition that I haven't figured out (I believe it may be used to pause ATB when dialogue is appearing during battle?)
000a3828: 27bdffe8 addiu r29,r29,0xffe8 ; BEGIN ATB PAUSE CHECK SUBROUTINE
000a382c: afb00010 sw r16,0x0010(r29)
000a3830: 00008021 addu r16,r0,r0
000a3834: 3c03800f lui r3,0x800f
000a3838: 8c6339e0 lw r3,0x39e0(r3) ; r3 = $0x800F39E0 (pause flag)
000a383c: 34020003 ori r2,r0,0x0003 ; r2 = 0x0003
000a3840: 14620009 bne r3,r2,0x000a3868 ; branch if r3 != 0x0003, i.e. skip animation timer increment if pause flag is not equal to 0x0003
000a3844: afbf0014 sw r31,0x0014(r29)
000a3848: 3c03800f lui r3,0x800f
000a384c: 94637da6 lhu r3,0x7da6(r3) ; r3 = $0x800F7DA6 (Speed modifier: 273 on fastest Battle Speed, 91 on default, 54 on slowest)
000a3850: 3c02800f lui r2,0x800f
000a3854: 8c4239e4 lw r2,0x39e4(r2) ; r2 = $0x800F39E4 (animation timer)
000a3858: 00000000 nop
000a385c: 00431021 addu r2,r2,r3 ; r2 = r2 + r3
000a3860: 3c01800f lui r1,0x800f
000a3864: ac2239e4 sw r2,0x39e4(r1) ; store animation timer in $0x800F39E4, (pauses ATB if greater than 0x4001)000a3868: 3c03800f lui r3,0x800f ; BEGIN ATB PAUSE CHECK SUBROUTINE
000a386c: 94637daa lhu r3,0x7daa(r3) ; r3 = (r3+0x7DAA) = $0x800F7DAA (0b01 = 0x01 if ATB Recommended, 0b10 = 0x02 if ATB Wait)
000a3870: 34020002 ori r2,r0,0x0002 ; r2 = 0x02
000a3874: 1462000e bne r3,r2,0x000a38b0 ; skip menu check if r3 != r2, i.e. not ATB Wait
000a3878: 00000000 nop
000a387c: 3c03800f lui r3,0x800f ; r3 = 0x800F0000
000a3880: 84633896 lh r3,0x3896(r3) ; r3 = $(r3+0x3896) = $0x800F3896 (menu halfword)
000a3884: 00000000 nop
000a3888: 2c62001c sltiu r2,r3,0x001c ; r2 = r3 < 0x001C
000a388c: 10400008 beq r2,r0,0x000a38b0 ; branch if r2 == 0 (r2 >= 0x001C)...
000a3890: 00031080 sll r2,r3,0x02 ; ...with r2 = r3 >> 0x02
000a3894: 3c01800a lui r1,0x800a ; r1 = 0x800A0000
000a3898: 00220821 addu r1,r1,r2 ; r1 = r1 + r2
000a389c: 8c2201b0 lw r2,0x01b0(r1) ; r2 = $(r1+0x01B0)
000a38a0: 00000000 nop
000a38a4: 00400008 jr r2 ; jump to $r2 (e.g. 0x800A38AC for magic menu)
000a38a8: 00000000 nop
000a38ac: 34100001 ori r16,r0,0x0001 ; r16 = 0x0001 (set true if we got a pause from ATB Wait)
000a38b0: 0c0292a0 jal 0x000a4a80 ; check for summon byte at $0x800FAFDC
000a38b4: 00000000 nop
000a38b8: 02028025 or r16,r16,r2 ; r16 = r16 OR r2 (set true if we got a pause from ATB Wait OR summon)
000a38bc: 3c038010 lui r3,0x8010
000a38c0: 946383d0 lhu r3,-0x7c30(r3) ; r3 = $0x800F83D0
000a38c4: 3c02800f lui r2,0x800f
000a38c8: 8c4239e4 lw r2,0x39e4(r2) ; r2 = $0x800F39E4
000a38cc: 30630003 andi r3,r3,0x0003 ; r3 = r3 AND 0x0003
000a38d0: 0003182b sltu r3,r0,r3 ; r3 = ($0x800F83D0 AND 0x0003) != 0
000a38d4: 28424001 slti r2,r2,0x4001 ; r2 = $0x800F39E4 < 0x4001
000a38d8: 14400002 bne r2,r0,0x000a38e4 ; branch if r2 != 0, i.e. $800F39E4 < 0x4001...
000a38dc: 02038025 or r16,r16,r3 ; ...with r16 = r16 OR r3 (set true if we got a pause from ATB Wait OR summon OR animation pause)
000a38e0: 34100001 ori r16,r0,0x0001 ; r16 = 0x0001
000a38e4: 02001021 addu r2,r16,r0 ; r2 = r16
000a38e8: 8fbf0014 lw r31,0x0014(r29)
000a38ec: 8fb00010 lw r16,0x0010(r29) ; set true for pause from ATB Wait, summon, $0x800F83D0 AND 0x0003 != 0 (???), or animation timer is greater than 0x4001 = 16385
000a38f0: 27bd0018 addiu r29,r29,0x0018
000a38f4: 03e00008 jr r31 ; r31 = 0x800a3950
000a38f8: 00000000 nop
Here's the calculation for Speed_mod, which is used in ATB calculations as well as the animation timer increment each frame.
001b085c: 00041100 sll r2,r4,0x04 ; r2 = r4 << 0x04 (mult by 16) BEGIN SUBROUTINE: CALC SPEED MULTIPLIER FROM BATTLE SPEED
001b0860: 00441023 subu r2,r2,r4 ; r2 = r2 - r4 (subtract val, so overall mult 15)
001b0864: 00021140 sll r2,r2,0x05 ; r2 = r2 << 0x05 (mult by 32, so overall mult 480)
001b0868: 04410003 bgez r2,0x001b0878 ; branch if r2 >= 0...
001b086c: 00021a03 sra r3,r2,0x08 ; ...with r3 = r2 >> 0x08 (divide by 256)
001b0870: 244200ff addiu r2,r2,0x00ff ; r2 = r2 + 0x00FF (add 255, failsafe for negative number rounding which is irrelevant)
001b0874: 00021a03 sra r3,r2,0x08 ; r3 = r2 >> 0x08 (divide by 256)
001b0878: 24630078 addiu r3,r3,0x0078 ; r3 = r3 + 0x0078 (add 120)
001b087c: 00031840 sll r3,r3,0x01 ; r3 = r3 << 0x0001 (mult by 2)
001b0880: 3c020001 lui r2,0x0001 ; r2 = 0x00010000
001b0884: 0043001a div r2,r3 ; div r2/r3
001b0888: 14600002 bne r3,r0,0x001b0894 ; branch if not divide by 0
001b088c: 00000000 nop
001b0890: 0007000d break 0x00001c00
001b0894: 2401ffff addiu r1,r0,0xffff ; r1 = 0xFFFF
001b0898: 14610004 bne r3,r1,0x001b08ac ; branch if not divide by 0xFFFF
001b089c: 3c018000 lui r1,0x8000
001b08a0: 14410002 bne r2,r1,0x001b08ac ; branch if not divide from 0x80000000 (negative 32-bit int limit, -2147483648)
001b08a4: 00000000 nop
001b08a8: 0006000d break 0x00001800
001b08ac: 00001012 mflo r2 ; r2 = result of divide (65536/(2*(120+(480*val)/256)) = 32768/(120+(15/8)*val)
001b08b0: 3c01800f lui r1,0x800f
001b08b4: a4227da6 sh r2,0x7da6(r1) ; store r2 at 0x800F7DA6
001b08b8: 03e00008 jr r31
001b08bc: 00000000 nop