Building an Open Watcom Linux-to-DOS cross-compiler
Nowadays, Open Watcom v2 seems to be the go-to free software compiler for 16-bit DOS. It can run on DOS natively, but you can also cross-compile from modern operating systems, including 64-bit Linux.
Although there is an official Wiki about building the toolchain, to me it reads more like a reference for those already in the know (and it’s a lot of words anyway!)
Below I reproduce just the steps I had to take to get a fully working toolchain.
git clone git@github.com:open-watcom/open-watcom-v2.git
,cd open-watcom-v2
- in setvars.sh, I uncommented
export OWDOSBOX=dosbox
, since I already had DOSBox installed source setvars.sh
./buildrel.sh
This will use your system GCC to build the Open Watcom toolchain (for all possible hosts & targets).
Assuming everything went fine, to use the newly-build compiler, some environment variables need to be configured – unlike GCC, where it usually suffices to have it in PATH
.
export WATCOM=$(pwd)/rel
export PATH=$WATCOM/binl64:$WATCOM/binl:$PATH
export INCLUDE=$WATCOM/h
Let’s see if we can compile a minimal program…
wcl -bt=dos $WATCOM/src/hello.c
…and run it.
dosbox hello.exe
Using DOS system calls
Open Watcom provides an implementation of the Standard C library; however, if you prefer to indulge in the quirkiness of DOS system calls, you can also do that, using Watcom’s funky #pragma aux
syntax. The following program illustrates a call to the INT 21h AH=09h function (display string):
void print(char *string);
#pragma aux print = \
"mov ah, 09h" \
"int 0x21" \
parm [dx] \
modify [ax];
int main(void) {
/* string must be terminated with '$' */
print("hello, world\n$");
return 0;
}
For portability, though, it might be better to include <dos.h>
and use the wrappers found there (such as _dos_write
), which should still be a lighter abstraction than <stdio.h>
.
UPDATE: This post contains many more useful examples and links related to OW2 on Linux.