# A table the game builds at start-up comes out wrong under the emulator

## Symptoms

POD's `FUN_004cfde4` builds a square-root table (√j × 65536, truncated). Run under Unicorn,
10,289 of its 24,576 entries came out one above the truncated root, with no pattern by the
fraction (between 0.5 and 1 some rounded up and some did not).

## Cause

Unicorn starts the x87 with the control word 0. Its precision control (bits 8 and 9) is then
00: every result rounds to 24 bits, single precision. A program on Windows starts with 0x037f
(64-bit precision, round to nearest) because the C library's start-up runs `fninit`; in POD
that is Watcom's at 0x4d74e0. A function called directly under the emulator skips the
start-up, so its `fsqrt` and `fmul` rounded to 24 bits (*measured*: the control word read in a
code hook was 0, and the table matched `trunc(sqrt(j) × 65536)` once the word was set).

## What to do

Start every emulated call through a stub that runs `fninit` and loads the control word the
game runs with (`fninit; fldcw [cw]; call target; hlt`). That is not always the start-up's:
POD's start-up leaves 0x037f, but in the race the game runs with 0x027f (53-bit precision),
read from a step log recorded inside the game. Under 0x037f, one target point in about 18,000
game steps came out one unit off. Read the control word in the running game when you can. `measure/race_rules.py`'s
`run` and `measure/controllers.py`'s `run` use such a stub (the latter with 0x027f). Run a start-up routine that fills tables
(here `FUN_004cfde4`) the same way, then keep the filled image for the later calls. When an
emulated float result looks slightly off, read `FPCW` in a hook before blaming the code.

GameFrame's `pe32_emu` now starts the x87 at 0x037f, as Windows starts a program, and
`reset()` puts it back. Pass `fpu_cw=0x027f` (or the word you read) when the game runs with
another one.
