Does SimCity 2000 actually use your FPU?

A question that's nagged me for years: if you dropped a 387 maths coprocessor into a 386DX-40, would SimCity 2000 run any faster? Plenty of DOS games never touched the FPU, so the coprocessor was often dead weight. So I pulled apart the shipped binary to check.

There's no source, so this is static analysis — disassembling SC2000.EXE from the 1994 CD-ROM Collection. Claude did most of the legwork counting opcodes, same as the recent site redesign.

What it is

SC2000.EXE is a 32-bit protected-mode program behind a DOS/4GW extender, compiled with Watcom C/C++ as a Linear Executable. It was built with Watcom's -fpi floating-point model, which matters below.

Does it use floating point?

Yes — around 543 x87 instructions spread across the 644 KB code segment. A typical routine:

fild word ptr [ebp-4] ; int -> float
fmul dword ptr [ebp-0xc]
fadd dword ptr [ebp-8]
fdiv dword ptr [0x543b] ; divide by a float constant
fld1 ; load 1.0
fcomp dword ptr [ebp-8]
fnstsw ax / sahf / jbe ; FP compare -> branch

The fnstsw ax; sahf; jbe sequence is the 387-era way of branching on a float compare; a Pentium Pro would use fcomi, which never appears, so this was written for the 386. There's also a lot of fild/fistp — int to float and back — which is what you'd expect from a sim that keeps its state as integers.

Hardware or emulator?

The -fpi model emits real x87 instructions and links a software emulator as a fallback. With a coprocessor they run on it; without, they fault and the emulator handles them. There's the usual detection routine (fninit, read the control word, cmp ah, 3) and support for the NO87 environment variable to force the emulator. So an FPU is used when present but not required.

How much faster?

Per operation, a 387 op is about 25–90 cycles; emulated in software it's roughly 1,000–5,000, so the coprocessor is about 20–80× faster, worst for divides and transcendentals. But only about 2.5% of the game's functions touch the FPU. The constant work — the 128×128 tile sim (power, water, traffic, pollution, land value, crime) and the isometric blitter — is all integer.

Workload | Effect of a 387
Normal play — scrolling, drawing, the sim tick, UI | A few percent at most.
Periodic recalcs — budget, graphs, terrain generation, loading a city | Noticeable; a 1–2 s pause can become near-instant.

Bottom line

A 386DX-40 with no coprocessor runs SimCity 2000 fine — that's what the -fpi/NO87 design is for. A 387 won't help the scrolling, but it takes the edge off the periodic pauses (when processing e.g the budget).