Maximum Overkill | OS/2 Museum
Skip to content
OS/2 Museum
OS/2, vintage PC computing, and random musings
Home<br>About
Wanted List
OS/2 History
OS/2 Beginnings
OS/2 1.0
OS/2 1.1
OS/2 1.2 and 1.3
OS/2 16-bit Server
OS/2 2.0
OS/2 2.1 and 2.11
OS/2 Warp
OS/2 Warp, PowerPC Edition
OS/2 Warp 4
OS/2 Timeline
OS/2 Library
OS/2 1.x SDK
OS/2 1.x Programming
OS/2 2.0 Technical Library
OS/2 Videos, 1987
DOS History
DOS Beginnings
DOS 1.0 and 1.1
DOS 2.0 and 2.1
DOS 3.0, 3.1, and 3.2
DOS 3.3
DOS 4.0
DOS Library
NetWare History
NetWare Timeline
NetWare Library
Windows History
Windows Library
PC UNIX History
Solaris 2.1 for x86
← Win16 Memory Management
Maximum Overkill
Posted on July 24, 2026 by Michal Necasek
A reader pointed at the 1992 game Comanche: Maximum Overkill by NovaLogic as a possible unreal mode user—since the original game release was known to be problematic.
Screenshot of original 1992 Comanche game when it is not horribly crashing
I examined the game and found no unreal mode usage, just a rather unusual homebrew DOS extender (which, among other things, uses expand-down segments for data, presumably in order to catch null pointer accesses).
The original 1992 Comanche release is extremely picky about memory managers. The game refuses to work with EMM emulators and crashes when EMM386 is active. The game may also hang or reboot the system when HIMEM.SYS is not loaded (the problem seems to be system configuration dependent).
These issues are clearly noted in the Comanche documentations, but at the same time they’re also all signs of a substandard DOS extender.
On top of that, the game authors accomplished a remarkable feat: By only loosely following Intel’s instructions on how to enter protected mode, NovaLogic managed to write a game which worked on the then-existing 386 and 486 processors, but under some circumstances failed to run on Pentium and later processors.
To NovaLogic’s credit, these problems were fixed, and an updated CD-ROM release from 1994 works significantly better.
Here is the original 1992 Comanche code sequence which switches from real to protected mode:
1318:0b96 fa cli<br>1318:0b97 2e 0f 01 0e 62 00 sidt [cs:00062h]<br>1318:0b9d 2e 0f 01 06 5a 00 sgdt [cs:0005ah]<br>1318:0ba3 66 9c pushfd<br>1318:0ba5 66 2e 8f 06 68 00 pop dword [cs:00068h]<br>1318:0bab e8 cb 08 call 01479h<br>1318:0bae 0f 20 c0 mov eax, cr0<br>1318:0bb1 66 83 c8 01 or eax, byte 000000001h<br>1318:0bb5 0f 22 c0 mov cr0, eax<br>1318:0bb8 b8 18 13 mov ax, 01318h<br>1318:0bbb 8a d4 mov dl, ah<br>1318:0bbd c1 e0 04 sal ax, 004h<br>1318:0bc0 c0 ea 04 shr dl, 004h<br>1318:0bc3 2a f6 sub dh, dh<br>1318:0bc5 05 00 00 add ax, 00000h<br>1318:0bc8 80 d2 00 adc dl, 000h<br>1318:0bcb 2e a3 44 00 mov word [cs:00044h], ax<br>1318:0bcf 2e 89 16 46 00 mov word [cs:00046h], dx<br>1318:0bd4 2e 0f 01 16 42 00 lgdt [cs:00042h]<br>1318:0bda b8 18 13 mov ax, 01318h
At address 1318:0BB5, the game enables protected mode by writing to control register CR0. The following instructions then execute in protected mode.
A key detail is that contrary to Intel’s recommendations, the game does not reload segment registers, and does not perform any jumps prescribed by Intel. As a consequence, the game continues running with real-mode CS after switching to protected mode.
The trouble hits at address 1318:0BCB. The game tries to write to memory using a CS segment override. Ironically, the game could just as easily have used an ES segment override because at that point, ES and CS (but not DS!) point to the same segment.
This code worked just fine on 386 and 486 processors, which is obviously how it made it into a commercial game release (because that’s all that was available when the game was released). But the same code often failed on the Pentium, released just a few months later, in March 1993 (the game files are dated November 1992).
How is that possible? In the Pentium, Intel made a subtle but crucial architectural change.
Why CS Is Weird
As discussed elsewhere, real mode works very much like Ring-0 protected mode, with a few relatively minor differences that relate primarily to segment register loading and interrupt dispatching.
However, Intel needed to solve an important problem for which there was no obvious clean solution. In real mode, the CS segment must be writable, yet in protected mode, a writable code segment simply does not exist. This is not such a problem after CPU reset, because the initial CS value can be more or less anything. But it is a serious problem after returning to real mode from protected mode—because by definition, protected mode only loads code selectors into CS, and those can’t be writable. Yet after returning to real mode, CS somehow must be made writable, otherwise real-mode code cannot function.
According to Robert Collins (usually a very reliable source), Intel’s original solution was to modify the CS access rights on any far control transfer (i.e. every time CS got reloaded) in real mode to 93h, which indicates a...