I believe I solved the time issue by revamping the routines that figure out which fireball to track. The routines use a^2 + b^2 = x^2 to determine how far each fireball is. I used tables with precalced ^2 values and 16 bit math to sum the results because the values went up to 25600(160^2). To save time I didn't worry about calculating the square root of the sum as it doesn't matter.
There's up to 9 additions(3 AI players * 3 fireballs) and 6 compares (3 AI players and 2 compares - M0 vs M1, then either M0 vs BL or M1 vs BL) and that takes up a lot of extra time when using 16 bit values.
I revised the routines to use a^2/100 + b^2/100 = x^2/100 which allowed the math to be done using 8 bits. If the sum overflowed I just set the result to 254 (a distance of 255 denotes an inactive fireball which results in the fireball being ignored during the compare for closest).
Also implemented a random routine and used it to drive the AI catch routines instead of using the FRAME counter to do so. I also revised how the shields move when they've caught a solitary fireball.
I removed the overshoot compensation routines for the AI players when I was trying to save processing time. You'll notice purple moves jerky compared to before when it's tracking a slow moving fireball as it overshoots in one direction then the other. I'll add the routines back in a future build.