Another try ... I found something weird, and it looks like I fixed it, and the cassette on the TI-99/8 works in a stable way now. It is always difficult to be sure, because you'd have to continue testing until it fails again, which does not terminate when the code happens to be correct.
The 9901 has a timer mode that is used for the cassette (only); it is turned on by loading a value into the clock register in clock mode. The 9901 triggers an interrupt every time the counter reaches 0, and then resets the timer. The issue was that there is some improper use of MAME timers in the TMS9901 emulation. As it was done now, the MAME-internal timer structure was set to some non-zero value and then activated. However, as the timer never ran until then, this activation made the timer fast-forward to the current machine time, triggering hundreds of interrupts. Obviously, in MAME, timers should be kept running from the beginning, and a flag could be used to decide whether the timer have an effect or not. I don't know whether this has changed in the MAME core over time.
Now, in combination with the changes of interrupt latching, the following happened: Once the cassette routine reached the activation of the timer, the timer immediately started to fire interrupts, which were now (correctly) latched but got ignored in earlier versions. Accordingly, this interrupt storm had no effect until I added the latching of interrupts.
I am still not fully sure that the current fix is the solution. By these interrupts (only the first being of interest, as it sets the latch), the cassette routine got interrupted before the cassette flag was set, which led to a termination of the cassette routine. In theory, this could happen in unfortunate situations at any time. On the other hand, by setting the counter and now without triggering premature interrupts, the code may have proceeded far enough to have reached the instruction that sets the cassette flag; note that every counter step is 64 cycles, and the counter is set to 15, so this could be sufficient.
Anyway, I pushed the fix to Github. We'll see.