Today was "rewrite the Win16 local heap manager" day. Probably could have gotten away with a less aggressive approach, but figured in the long run it would pay off.

Fortunately, there's a lot of good information out there. Mostly worked from Schulman's 1992 "Undocumented Windows" book, which describes most of the Win16 heap data structures. Also some good information in Raymond Chen's Old New Thing blogs to provide some perspective.

Previously I was using my own generic heap library, which I like because it keeps metadata outside of the heap memory block, so there's no risk of corruption. However, I was definitely seeing suspicious activity from some early programs making assumptions about the structure of the heap data, so figured that replicating the original behavior with more fidelity would be a good thing.

Unfortunately, it's moderately complex. They maintain a doubly-linked list of blocks, and a separate doubly-linked list of free blocks. On top of that it supports optionally-moveable memory blocks with MacOS-like handles (which was actually what tripped me up in the first place).

Now at least it's working enough for the 4 officially supported Win16 games (Pipe Dream, Indy Desktop, Star Wars Chess, Star Wars Screen Entertainment), so time to make it official.

Protip: when writing a heap manager, always write an extensive heap validation function and in your debug builds call it before and after any heap manipulation to ensure that you haven't messed things up. I've written probably a dozen or so heap implementations in my time and this has always saved my bacon.