The wall under Rosetta
2026-10-23, written up the next morning from the session's notes.
After POD first showed its demo race in a window (POD in a window), the next goal was simple: press a key and drive. That took the rest of the evening on the Mac, and ended with us leaving the Mac behind. This is the story of that detour, because the user wanted it told: running a 1997 Windows game today is a puzzle in its own right.

POD's main menu under Wine 11.18 on the Mac. It looks fine, but nothing moves: no cursor, no keys, and one CPU core at 100%.
First, pressing a key at all
The first wall was ours, not the game's. The shell this work runs in may not send keyboard or mouse events to other apps: macOS asks for Accessibility permission, and the shell does not have it (AXIsProcessTrusted() is false). The computer-use tools could not see the game's windows either: a Wine program is not an app with a bundle, so it was filtered out.
So we built an input tool that runs inside Wine. podinput.exe is a few hundred lines of C, compiled for 32-bit Windows with zig. It sends keys as scancodes (which DirectInput reads) and clicks with SendInput. Events that start inside Wine never need macOS's permission. Its first click answered the game's "sound driver busy" question and showed it worked. GameFrame now has the same tool, as winput.
Then the menu froze
With input working, the menu ignored every key and click. Wine's log had one line: nested exception on signal stack. Something had faulted inside Wine's own exception handler.
We worked through the likely causes one at a time, and each run took two minutes to reach the menu:
| Tried | Why it seemed likely | Result |
|---|---|---|
| No sound device | The sound thread had crashed once before | Still froze |
No CD audio (mcicda off) | The menu starts the CD music | Still froze |
| A 1 MB stack (the EXE asks for 64 KB) | A small stack leaves no room for Wine's signal frame | Still froze |
No SuspendThread | The game pauses its own thread with it; Wine on macOS suspends with a signal | Still froze |
| No FS and GS reloads in the Watcom runtime | Under Rosetta a reloaded FS could point a thread at another thread's data | Still froze |
| Wine 11.18 (staging) instead of 11.0 | Nine months of fixes | Froze differently |
| A CrossOver-based engine (Sikarugir CX 23) | CrossOver once ran 32-bit games another way | Same 32-bit design; asked for the CD |

The CrossOver-based engine never got as far: it did not see our folder as the POD disc.
Two of those patches stayed, because they are right whatever the cause: the game no longer suspends its own thread, and its stack is larger. The FS and GS change came out again. It changed nothing, and an unexplained patch is worse than none.
What the register dump said
Wine 11.18 traced the fault more clearly than 11.0 had. With +seh on, it printed the faulting thread's registers: the instruction pointer was inside wow64cpu.dll, Wine's own code for running 32-bit programs, and the code segment was 0x0107, the 32-bit one.
Disassembling wow64cpu both ways told the rest. That spot is the entry into 64-bit code for a system call. Read as 64-bit code, it swaps the stack pointer and saves registers. Read as 32-bit code, the same bytes do something else: xchg r14, rsp becomes dec ecx; xchg esi, esp, and the stack pointer gets the game's window handle (0x20066). So now and then, a game thread's jump from 32-bit into 64-bit code happened without the processor switching mode. Under 11.0 Wine then faulted while building an exception frame on that bad stack; under 11.18 it resumed the thread, which faulted again at once, forever. That was the frozen menu at 100% CPU.
Nothing in POD causes this. Wine on an Apple-silicon Mac runs 32-bit Windows code through Rosetta, and the switch between the two modes is where it fails. The user's rule for a bug report is strict, and right: only report it once a small test program with no POD in it shows the same fault. That test program is still to be written.
Leaving the Mac
At that point the useful question changed from "how do we fix Wine here?" to "where does Wine just work?" The answer was a real x86 PC, emulated: Debian under QEMU, where 32-bit code runs as 32-bit code with no translation underneath.


The first two screens in the emulated PC: first the CD question again (a folder is not a CD to Wine on Linux), then, with the disc attached as a real CD drive, the sound question over the Indeo warning. Past those, the menu, in its real rust-orange colours, answered every key.
The rest of the night is in To the finish line.
How it is known
Every row of the table above is measured: a run with the change, a minute at the menu, the log checked for the fault. The wow64cpu analysis is observed (the register dump and the disassembly) and the cause is inferred. Each wall now has an entry in GameFrame's know-how layer, so ./gameframe advise "nested exception on signal stack" returns this whole list of attempts before anyone starts again.