From Free Pascal wiki
Jump to navigationJump to search


A DOS (8086) cross compiler is currently being developed in FPC trunk (the development version). It started as a hobby project meant to explore how to port FPC to a new platform.

The amount of (FPC on) DOS users is probably quite low, especially since there is an FPC compiler for the more capable GO32v2 DOS extender available which runs on 80386+ processors.

Advantages over FPC for GO32V2

  • Generated code can run on 16-bit processors. Since these processors are obsolete and out of production, this is mostly useful for retrocomputing purposes. Note also that the 80186 is still in use in embedded devices: [1]
  • It's possible to write TSRs.
  • It's possible to write DOS .SYS device drivers. (Not ready yet, but should be easy to implement)
  • It allows writing a bootloader in Pascal.
  • It allows writing 16-bit BIOS code in Pascal (e.g. you can now do a project like SeaBIOS but in Pascal).
  • Real mode DOS programs are less sensitive to bugs in virtual DOS environments, since they're immune to DPMI bugs and in fact require no DPMI at all. (Provided that your program fits within the memory constraints, of course.)

Advantages over Turbo Pascal

  • Compiler is Free/Open Source software and is in active development.
  • Supports long file names.
  • Multiple memory models are supported.
  • All the extra Object Pascal features supported by FPC should work. This includes ansistrings, classes, interfaces, exceptions, generics, etc.
  • Crosscompilation is doable without running the development system in a dosbox/VM (compile/build on Windows 64-bit, only need 16-bit capable OS for running)


The DOS platforms brings some limitations, like

  • data structures cannot be larger than 64KB
  • no simple way of pre-emptive multitasking.
  • it is unlikely the Lazarus LCL GUI will be ported to the DOS environment
    • However, an OpenGEM widget set is possible
    • When the large memory model of the i8086 code generator matures, Win16 support can also be implemented


There's a snapshot available here:

It is not the latest version, but contains all the necessary tools and instructions to build the cross compiler under Windows.


The compiler has been enabled as a CPU/OS target in FPC.exe since revision 25792 (CPU: i8086, OS: msdos).

The RTL compiles. Most units from Go32v2 have been ported. Just like Go32v2, the RTL supports long file names when run under a Windows 95+/2000+ DOS box or under plain DOS with a long file names driver such as doslfn.exe. FPC demo programs such as fpctris and samegame work in all supported memory models.

Floating point support

Floating point operations require an FPU. Software FPU emulation is not yet implemented and using floating point operations on a real machine without an FPU will lead to a hang.

Tested machines

Compiled programs have been tested and known to work on the following machines:

  • IBM PC 5150 (the first PC model ever), with a 4.77 MHz 8088 CPU, 512 KB RAM and a CGA card, running IBM DOS 3.30
  • HP 200LX, with a 7.91 MHz 80186 CPU, running MS-DOS 5.0
  • various boring 32-bit and 64-bit machines :)
  • DOSBox

Supported memory models


  • Activated by the -WmTiny compiler option
  • Code + Data + Heap + Stack <= 64KB
  • CS = DS = SS
  • Pointer = NearPointer
  • CodePointer = NearPointer
  • Code starts at offset $100
  • Can produce both .com and .exe files. The binary format can be chosen with the -Wtcom and -Wtexe compiler options. The default format is .exe
  • The compiler defines: FPC_MM_TINY


  • Activated by the -WmSmall compiler option. This is the default memory model, so it is chosen if you don't specify a memory model.
  • Code <= 64KB, Data + Heap + Stack <= 64KB (Code and data are in separate segments, so programs can use up to 128KB in total)
  • DS = SS
  • Pointer = NearPointer
  • CodePointer = NearPointer
  • Can produce only .exe files
  • The compiler defines: FPC_MM_SMALL


  • Activated by the -WmMedium compiler option
  • Code <= 1MB, Data + Heap + Stack <= 64KB
  • DS = SS
  • Pointer = NearPointer
  • CodePointer = FarPointer
  • Can produce only .exe files
  • The compiler defines: FPC_MM_MEDIUM

Memory models planned for the future, but not yet started




Supported calling conventions

Currently, only the Pascal calling convention is supported. All the other calling conventions are entirely untested and should not be used, because they may or may not work and may change at any time.


This is the default calling convention. It strives for compatibility with Turbo Pascal 7.

  • Parameters are pushed on the stack left to right.
  • The callee cleans the parameters from the stack.
  • Procedures and functions must preserve DS and BP and may destroy AX, BX, CX, DX, SI, DI and ES.
  • 16-bit results are returned in AX, 32-bit results in DX:AX
  • 64-bit ints are returned in AX:BX:CX:DX. Note that Turbo Pascal doesn't support int64, so this behavior is borrowed from Open Watcom's 'pascal' calling convention.


The compiler is a cross compiler that runs at least on Windows (both x86 and x64) and Linux. For compiling, it needs:

  • the Netwide Assembler - NASM
  • the Open Watcom linker - WLINK
  • the Open Watcom library manager - WLIB

In theory it should be able to run on any platform, supported by FPC, where NASM and the Open Watcom tools are available. This includes DOS via the GO32V2 extender. However, because the Watcom tools for DOS are compiled with a different extender, there are some issues related to long file names and the passing of long command line arguments. This might be resolved by recompiling the Watcom tools with DJGPP or by implementing a 16-bit DOS backend asm object writer and linker inside FPC.


Compile error: missing .o files

Problem: If you see errors/warnings like this during compiling & linking: test.pas(12,24) Warning: Object system.o not found, Linking may fail ! Error! E2008: cannot open system.o : No such file or directory (and indeed there don't appear to be any .o files in your msdos units directory)

Solution: You haven't used smartlinking. You should always compile i8086-msdos programs with smartlinking, i.e. use the -XX and -CX options. Smartlinking uses .a files, nonsmartlinking uses .o files.

The reason the .o files aren't generated is because the system unit exceeds the 64kb code limit for the small and tiny memory models and is therefore impossible to compile even 'hello world' without smartlinking, so creating the .o files is a waste of time. It might work for the medium model, but then you have to build the snapshot without -CX. However, with the tight memory constraints of real mode DOS, there is little reason not to use smartlinking in every memory model. Also, the medium model still has a limit of 64k code per unit, so even there it might not work without smartlinking. It certainly hasn't been tested.

Hint: You can add these options to your fpc.cfg file:

#ifdef cpui8086