Well, if I understand correctly, the crash doesn't really happen because of bugs but because the score calculation happens to eat too many CPU cycles later on.
In other words, even with all the bugs still present, if one replaces the current code that handles the score with something that performs in a (safe) fixed amount of time - which is totally possible - then the resulting ROM will be still bugged but won't crash.
Am I wrong? :|
Right, that was part of the issue! That delay would cause the interrupt to happen before the code loop is done. If that happens after a jump destination is stored in RAM, but before it's used, the address in RAM gets spoiled, and the program jumps to an unintended address.