Building Byte-identical MS-DOS 4.00

MS-DOS 4.00 was open sourced by Microsoft a few years ago. But the sources are corrupted and the git repo is not configured correctly. I saw people having instructions like manually converting line endings, even though git can do that more easily and also won’t show the file changed. And nobody seemed interested in a byte-identical build to the production release.

For starters, let’s configure git. Assuming you’ve already cloned https://github.com/microsoft/MS-DOS.git to local disk, in .git/info/attributes (which is like .gitattributes, but not checked in):

*.ASM	text eol=crlf
*.BAT	text eol=crlf
*.H	text eol=crlf
*.INC	text eol=crlf
*.INI	text eol=crlf
*.MSG	text eol=crlf
*.PRT	text eol=crlf
*.SKL	text eol=crlf
GRAPHICS.PRO	text eol=crlf
LOCSCR	text eol=crlf
MAKEFILE	text eol=crlf
USA.INF	text eol=crlf
ZERO.DAT	text eol=crlf

When the line endings change, the working directory is not immediately changed yet won’t show up with git status or be changed by git checkout. I deleted the files with rm -r * and then checked them all out again with git checkout ..

The build is old-style where all the artifacts sit next to the source files. To make git status less ugly, I added to .git/info/exclude (which is like .gitignore):

*.OBJ
*.LIB
*.LST
*.IDX
*.CL[0-9A-F]
*.MAP
*.COM
*.EXE
*.DAT
*.HLP
*.BAK
*.CTL
*.SYS

For building, I used vanilla DOSBox on Linux. For build speed, I disabled cycle limiting by making msdos4.dosbox (as a sibling of MS-DOS checkout):

[cpu]
cycles=max

The original instructions for how to build are at v4.0/src/RUNME.BAT, which does nothing but echo so would have been nicer as a text file. I expanded those steps to one that would setup DOSBox and copy files to a floppy: msdos4.bat (as a sibling of MS-DOS checkout):

mount d .
d:
cd src

call setenv
@rem Workaround broken config from setenv.bat
set LIB=%BAKROOT%\src\tools\bld\lib
set INCLUDE=%BAKROOT%\src\tools\bld\inc
nmake
mkdir out
call cpy out

z:imgmount a boot.img -size 512,9,2,40
cd out
@rem Copy system files, as would be done with 'format a: /s'
copy IO.SYS MSDOS.SYS COMMAND.COM FORMAT.COM a:
cd ..
exit

Then I had shell script to trigger it all, msdos4.sh (as a sibling of MS-DOS checkout):

#!/bin/bash
set -e
cd MS-DOS/v4.0/src
mkdir -p OUT
# dosbox doesn't support format.com, so format the disk outside of dos
fallocate -l 368640 BOOT.IMG
mkfs.fat -F 12 BOOT.IMG

(cd .. && dosbox -conf ../../msdos4.dosbox ../../msdos4.bat)

# dosbox doesn't support format.com, so extract the boot sector as binary
# (not assembly like INC/BOOT.INC) and manually write it to the disk, as would
# be done with 'format a: /s'
dd if=BOOT/MSBOOT.BIN of=BOOT/BOOTSECT.BIN bs=512 skip=62 count=1
dd if=BOOT/BOOTSECT.BIN of=BOOT.IMG bs=1 count=3 conv=notrunc
dd if=BOOT/BOOTSECT.BIN of=BOOT.IMG bs=1 skip=62 seek=62 count=450 conv=notrunc

# To now make a 100% legit disk, fallocate a disk, run qemu,
# and "format b: /s /4"
# fallocate -l 368640 BOOTLEGIT.IMG
# qemu-system-i386 -drive file=MS-DOS/v4.0/src/BOOT.IMG,format=raw,index=0,if=floppy -drive file=BOOTLEGIT.IMG,format=raw,index=1,if=floppy

You can see my comments about working around various bugs/limitations. But you’ll also find it failing to compile due to lines that are too long. That is the corruption I mentioned earlier.

Originally, these files were written using the IBM PC code page cp437, but before being added to git they were re-interpreted as UTF-8. This caused things like box-drawing characters to be expanded into multi-byte sequences which exceed the line length. But it also means we would no longer see pretty boxes!

The fixes for cp437 are more extensive, but msdos4-cp437.patch has the necessary changes. Some information from the originial files was lost when re-saving as UTF-8, so the changes for code comments are are estimations. But anything in the final binary we can be confident is identical to the original.

The build should now succeed. A clean build (after git clean -fx) takes two minutes on my laptop. MS-DOS/v4.0/src/OUT has the various output binaries, all of which are byte-identical to official MS-DOS 4.00 binaries. There’s also MS-DOS/v4.0/src/BOOT.IMG which is a bootable floppy disk that can be booted with DOSBox or QEMU.