The Watcom compiler suite is a powerful (reputed to produce the best optimized code for 16 and 32 bits programs by demosceners and game coders in end '90s) compiler/assembler/make/linker suite that comes with tools for binary files manipulations.
Creating a flat binary
OpenWatcom's linker WLink can produce flat binaries using command line options or a linker script. The options aren't well documented (see the linker section of the C++ master reference), but one of its maintainers helped in putting together an example linker script:
name kernel.bin # name of resulting binary output raw # type of binary (ELF, PE, MZ, PharLap, ...) offset=0x100000 # skip first meg; base address of binary file startup.obj # objects to link - this one has to be first file fdc.obj file gui.obj file idt.obj # add more obj files here order # in which order should segments be put into binary clname CODE offset=0x100000 # offset for reference fixups clname DATA
This linker script does not include the BSS class in the binary because its uninitialized data anyway and will only add unnecessary size to the resulting binary.
WLink executes a linker script from the command line as:
How can I tell Watcom to produce XXX files?
Natively, all Watcom C/C++ compilers can produce is OMF (.obj) files by default. (See this forum thread).
What are the differences between Watcom 11.0c and Open Watcom 1.3?
Not much; Open Watcom added a few new features.
Why is my final executable not in fact executable?
Watcom has a habit of inserting additional function calls in your code which are not necessarily available in the final binary. To work around this add the '-s' switch to the command line to disable stack overflow checking.
However the 32-bit C (Wcc386) and C++ (Wpp386) compiler insert function calls that the processor will flag as invalid, and if the interrupt controllers are not fixed the CPU will triple fault. This does not seem to be a problem with the 16-bit compilers. I am still trying to figure out how to bypass these calls.
Watcom makes DS follow the DS:DGROUP, and if you do not want that structure your going to have to fiddle with Jloc.