An Easy Explanation of MS-DOS Compilation for the Liberated Linux Developer

Create 16-bit DOS games in the current computing era! In this one-part series, you'll learn how to:

  1. Seamlessly run the Turbo C compiler on your own code

  2. ???

  3. Profit!

tl;dr: You can fork my repo and replace the C code: firedude

Requirements

Setup

  1. Install DOSBox and add to your $PATH

  2. Download Turbo C and extract to an accessible location (e.g. ~/turboc)

  3. Create your project folder (e.g. ~/project)

Project Structure

You'll want to create the following files:

~/project ├── build.dosbox.conf ├── build.sh ├── run.sh ├── build | ├── .gitkeep └── src ├── main.c

build.sh

#!/usr/bin/env bash SDL_VIDEODRIVER=dummy dosbox -conf ./build.dosbox-firedude.conf -noconsole cat ./build/TCC.LOG

The SDL_VIDEODRIVER=dummy and -noconsole options hide the DOSBox window on Linux and Windows. I'm not sure if DOSBox can run headless on macOS.

You can also add error handling by grepping ./build/TCC.LOG:

#!/usr/bin/env bash set -e executable="./build/GAME.EXE" buildlog="./build/TCC.LOG" SDL_VIDEODRIVER=dummy dosbox -conf ./build.dosbox-firedude.conf -noconsole if [ ! -f "$buildlog" ] then echo 'Error: No build log found.' exit 4 fi cat "$buildlog" if grep --quiet 'error\|Error\|Undefined symbol' $buildlog then echo 'Error(s) during compilation.' exit 5 elif [ ! -f "$executable" ] then echo 'Error: No executable found.' exit 6 fi

(Some errors might slip through this grep command, so it might need some tweaks.)

run.sh

#!/usr/bin/env bash dosbox ./build/GAME.EXE

If your game requires specific DOSBox settings, then you can of course go ahead and use the dosbox -conf option and make another config file:

#!/usr/bin/env bash dosbox -conf run.dosbox.conf ./build/GAME.EXE

build.dosbox.conf

We probably won't need to change any settings besides specifying the [autoexec] section. If necessary, check DOSBoxWiki for details.

[autoexec] MOUNT S: ./src MOUNT T: ~/turboc MOUNT O: ./build DEL O:\TCC.LOG T: TCC -1 -ml -IT:\INCLUDE -IS:\ -LT:\LIB -eGAME.EXE -nO:\ S:\*.c > O:\TCC.LOG EXIT

A breakdown of these Turbo C arguments:

  • -1 - Target 80186/286 (Optional - targets 80386 when omitted)

  • -ml - Uses the Large memory model, which we need to access VGA video memory

  • -IT:\INCLUDE - Includes the Turbo C header files (such as DOS.H)

  • -IS:\ - Includes your own header files in ./src

  • -LT:\LIB - Includes Turbo C's own libraries

  • -eGAME.EXE - Sets the compiled executable name

    • If you change this name, keep in mind the usual MS-DOS 8.3 file lengths.

  • -nO:\ - Outputs the compiled file(s) to O: (a.k.a. ./build)

  • S:\*.c - Compile your C source files in ./src

  • > O:\TCC.LOG - Redirects the output to ./build/TCC.LOG

main.c

  1. Download this VGA color palette tester: main.c

  2. Run the build/run scripts to see if everything's in working order:

./build.sh && ./run.sh

A screenshot of DOSBox running a demo program

If you see a few VGA rainbows for 5 seconds, then everything's set up!

More Caveats

Since Turbo C is an ancient C compiler and is an MS-DOS program, ensure that:

  • All comments are block comments (/* ... */)

  • All source files (inside src) use Windows line endings (CRLF)

  • All variables are declared at the beginning of scope blocks

Further Reading

I have a list of useful MS-DOS/Turbo C resources here: firedude#resources

Appendix

It's worth noting that while Turbo C is a free download, it's only licensed for distribution from the official website. As a result, it may be tough to encapsulate this guide in a standalone software package. If you do figure it out, I'd love to hear about it!

Comments