Then I remembered my old Atari 8-bit programming days and the vertical blank interrupt (which there was on the PSX, but we couldn't run all the physics in the VBI time allotment). What we could do though, was to use setjmp/longjmp to switch contexts between threads and then hack the vertical blank interrupt to save off the registers from the main thread, longjmp back to the physics thread, which would then restore the registers of the main thread and longjmp back to it. Bingo, 29.94Hz pre-emptive two-threading (which was all we needed).
(I don't recall if we actually used setjmp/longjmp or if we just stored away the PC register to return from the interrupt and monkeyed with it to return from the interrupt to the physics thread [as if it was interrupted at the start of a cycle of the engine] and then return from there to code that would restore the registers and make it appear to the main thread that it was returning from a VBI.)