Sign in Join
Wiki copytemporary

DOS: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: DOS

OldNewLine
1+> **Note:** This page has outdated information. Somebody is updating the information but you can help.
2+
3+## Overview
4+
5+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.
6+
7+The number 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.
8+
9+### Advantages over FPC for GO32V2
10+
11+- Generated code can run on 16-bit processors. Since these processors are obsolete and out of production, this is mostly useful for [retrocomputing](http://en.wikipedia.org/wiki/Retrocomputing) purposes. Note also that the 80186 is still in use in embedded devices: [1](http://www.cpushack.com/2013/01/12/the-intel-80186-gets-turbocharged-vautomation-turbo186/)
12+- It's possible to write [TSRs](http://en.wikipedia.org/wiki/Terminate_and_Stay_Resident).
13+- It's possible to write DOS .SYS device drivers. (Not ready yet, but should be easy to implement)
14+- It allows writing a bootloader in Pascal.
15+- It allows writing 16-bit BIOS code in Pascal (e.g. you can now do a project like [SeaBIOS](http://www.seabios.org) but in Pascal).
16+- It can compile Turbo Pascal 7 code with less changes needed, compared to GO32V2 (no need to port the inline assembly code, for example).
17+- 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.)
18+- Compiled binaries are smaller and you don't have to ship CWSDPMI.EXE in order for your program to work under real DOS.
19+
20+### Advantages over Turbo Pascal
21+
22+- Compiler is Free/Open Source software and is in active development.
23+- Supports long file names.
24+- Not affected (just like FPC for GO32v2) by the infamous CRT unit bug, that causes runtime error 200 on startup when the program is run on a fast CPU.
25+- Multiple memory models are supported.
26+- Supports huge pointers.
27+- Heap manager supports allocating blocks larger than 64 KB (only in the memory models with far data, such as compact, large or huge).
28+- All the extra Object Pascal features supported by FPC should work. This includes ansistrings, classes, interfaces, exceptions, generics, etc.
29+- 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)
30+
31+### Limitations
32+
33+The DOS platforms brings some limitations, like
34+
35+- data structures cannot be larger than 64KB
36+- no simple way of pre-emptive multitasking.
37+- it is unlikely the Lazarus LCL GUI will be ported to the DOS environment
38+ - However, an [OpenGEM](http://en.wikipedia.org/wiki/OpenGEM) widget set is possible
39+ - Since the large memory model of the i8086 code generator have matured, [[Win16]] support has also been started in FPC trunk
40+
41+## Requirements
42+
43+### FPC 3.0.x
44+
45+The compiler is a cross compiler that runs at least on Windows (both x86 and x64), Linux, and macOS. For compiling programs, it needs:
46+
47+- the Open Watcom linker - WLINK
48+- the Open Watcom library manager - WLIB
49+- the Netwide Assembler - [NASM](http://www.nasm.us/)
50+
51+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 is resolved in FPC trunk, where there's an internal assembler and linker implemented in the compiler itself.
52+
53+### FPC trunk
54+
55+FPC trunk contains an internal assembler and linker for DOS, so the Open Watcom tools are no longer required. NASM is still required for building an i8086-msdos snapshot, because of the msdos startup code in the rtl.
56+
57+## Releases
58+
59+### 3.0.4
60+
61+The crosscompiler packages for Windows, Linux - i386 and Linux - x86_64 are also available at the official Free Pascal website: <http://freepascal.org/download.var>
62+
63+- Crosscompiler package for Windows:
64+ - <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/i386-win32/fpc-3.0.4.i386-win32.cross.i8086-msdos.exe>
65+- Crosscompiler package for Linux - i386
66+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/i386-linux/fpc-3.0.4.i386-linux.cross.i8086-msdos.tar.xz>
67+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/i386-linux/fpc-i8086-msdos-3.0.4-1.i686.rpm>
68+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/i386-linux/fpc-i8086-msdos-3.0.4-1.src.rpm>
69+- Crosscompiler package for Linux - x86_64
70+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/x86_64-linux/fpc-3.0.4.x86_64-linux.cross.i8086-msdos.tar.xz>
71+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/x86_64-linux/fpc-i8086-msdos-3.0.4-1.x86_64.rpm>
72+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.4/x86_64-linux/fpc-i8086-msdos-3.0.4-1.src.rpm>
73+
74+### 3.0.2
75+
76+- Crosscompiler package for Windows:
77+ - <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/i386-win32/fpc-3.0.2.i386-win32.cross.i8086-msdos.exe>
78+- Crosscompiler package for Linux - i386
79+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/i386-linux/fpc-3.0.2.i386-linux.cross.i8086-msdos.tar.xz>
80+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/i386-linux/fpc-i8086-msdos-3.0.2-1.i686.rpm>
81+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/i386-linux/fpc-i8086-msdos-3.0.2-1.src.rpm>
82+- Crosscompiler package for Linux - x86_64
83+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/x86_64-linux/fpc-3.0.2.x86_64-linux.cross.i8086-msdos.tar.xz>
84+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/x86_64-linux/fpc-i8086-msdos-3.0.2-1.x86_64.rpm>
85+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.2/x86_64-linux/fpc-i8086-msdos-3.0.2-1.src.rpm>
86+
87+### 3.0.0
88+
89+- Crosscompiler package for Windows:
90+ - <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/i8086-msdos/fpc-3.0.0.i386-win32.cross.i8086-msdos.exe>
91+- Crosscompiler package for Linux - i386
92+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/i386-linux/fpc-3.0.0.i386-linux.cross.i8086-msdos.tar.xz>
93+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/i386-linux/rpm/fpc-i8086-msdos-3.0.0-1.i686.rpm>
94+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/i386-linux/rpm/fpc-i8086-msdos-3.0.0-1.src.rpm>
95+- Crosscompiler package for Linux - x86_64
96+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/x86_64-linux/fpc-3.0.0.x86_64-linux.cross.i8086-msdos.tar.xz>
97+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/x86_64-linux/rpm/fpc-i8086-msdos-3.0.0-1.x86_64.rpm>
98+ - SRPM: <ftp://ftp.freepascal.org/pub/fpc/dist/3.0.0/x86_64-linux/rpm/fpc-i8086-msdos-3.0.0-1.src.rpm>
99+
100+### 3.0.0rc2
101+
102+- Crosscompiler package for Windows:
103+ - <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/i386-win32/fpc-3.0.0rc2.i386-win32.cross.i8086-msdos.exe>
104+- Crosscompiler package for Linux - i386
105+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/i386-linux/fpc-3.0.0rc2.i386-linux.cross.i8086-msdos.tar.xz>
106+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/i386-linux/rpm/fpc-i8086-msdos-3.0.0-0.rc2.i686.rpm>
107+- Crosscompiler package for Linux - x86_64
108+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/x86_64-linux/fpc-3.0.0rc2.x86_64-linux.cross.i8086-msdos.tar.xz>
109+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc2/x86_64-linux/rpm/fpc-i8086-msdos-3.0.0-0.rc2.x86_64.rpm>
110+
111+### 3.0.0rc1
112+
113+- Crosscompiler package for Windows:
114+ - <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc1/i386-win32/fpc-3.0.0rc1.i8086-msdos.exe>
115+- Crosscompiler package for Linux - i386
116+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc1/i386-linux/i8086-msdos-fpc-3.0.0rc1.i386-linux.tar.xz>
117+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc1/i386-linux/rpm/fpc-i8086-msdos-3.0.0-0.rc1.i686.rpm>
118+- Crosscompiler package for Linux - x86_64
119+ - .tar.xz: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc1/x86_64-linux/i8086-msdos-fpc-3.0.0rc1.x86_64-linux.tar.xz>
120+ - RPM: <ftp://ftp.freepascal.org/pub/fpc/beta/3.0.0-rc1/x86_64-linux/rpm/fpc-i8086-msdos-3.0.0-0.rc1.x86_64.rpm>
121+
122+## Snapshots
123+
124+There are daily snapshots available here:
125+
126+<ftp://ftp.freepascal.org/pub/fpc/snapshot/trunk/i8086-msdos/>
127+
128+There's also a snapshot available here, but it's quite outdated, so it's better to simply use the above snapshot or to build your own:
129+
130+<http://www.bttr-software.de/forum/forum_entry.php?id=12985>
131+
132+### Building a snapshot manually
133+
134+- make sure **nasm** is in your path (the fixes-3.0 branch also requires **wlink** and **wlib**)
135+- checkout fpc trunk:
136+
137+`svn checkout `[`http://svn.freepascal.org/svn/fpc/trunk`](http://svn.freepascal.org/svn/fpc/trunk)` fpc`
138+
139+- enter the fpc directory and build the compiler with the following command (replace **/usr/bin/ppc386** with the full path to the stable (3.0.4) FPC compiler binary; replace **-WmSmall** with **-WmTiny**, **-WmMedium**, **-WmCompact**, **-WmLarge** or **-WmHuge** if you want to use another memory model):
140+
141+`make clean all OS_TARGET=msdos CPU_TARGET=i8086 OPT="-CX -XXs" CROSSOPT=`**`-WmSmall`**` BINUTILSPREFIX= PP=`**`/usr/bin/ppc386`**
142+
143+- install the snapshot (replace **linux** and **i386** with the OS and CPU you're using; replace **INSTALL_PREFIX** with the directory you want the snapshot installed):
144+
145+`make crossinstall OS_SOURCE=`**`linux`**` CPU_SOURCE=`**`i386`**` OS_TARGET=msdos CPU_TARGET=i8086 PP=compiler/ppcross8086 CROSSOPT=`**`-WmSmall`**` \`\
146+`    BINUTILSPREFIX= INSTALL_PREFIX=`**`/home/blablabla/fpc-i8086/snapshot/small`**` OPT="-CX -XXs"`
147+
148+### Updating your fpc.cfg
149+
150+Add the following to your fpc.cfg to enable smartlinking and disable the default binutils prefix (so that you don't have to rename nasm, wlink and wlib to msdos-nasm, msdos-wlink and msdos-wlib):
151+
152+`#ifdef cpui8086`\
153+`-CX`\
154+`-XX`\
155+`-XP`\
156+`#endif`
157+
158+To enable building for all the memory models, build snapshots for the tiny, small, medium, compact, large and huge memory model, and then find the lines in your fpc.cfg that specify the path to the RTL:
159+
160+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget`\
161+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*`\
162+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl`
163+
164+And update them to something similar to:
165+
166+`#IFDEF CPUI8086`\
167+`-Fu/home/blablabla/fpc-i8086/snapshot/$fpcmemorymodel/lib/fpc/$fpcversion/units/$fpctarget`\
168+`-Fu/home/blablabla/fpc-i8086/snapshot/$fpcmemorymodel/lib/fpc/$fpcversion/units/$fpctarget/*`\
169+`-Fu/home/blablabla/fpc-i8086/snapshot/$fpcmemorymodel/lib/fpc/$fpcversion/units/$fpctarget/rtl`\
170+`#ELSE`\
171+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget`\
172+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*`\
173+`-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl`\
174+`#ENDIF`
175+
176+This should enable you to build programs in any of the supported memory models with just a compiler switch:
177+
178+`ppcross8086 -WmTiny -Wtcom hello.pas`\
179+`ppcross8086 -WmTiny -Wtexe hello.pas`\
180+`ppcross8086 -WmSmall hello.pas`\
181+`ppcross8086 -WmMedium hello.pas`\
182+`ppcross8086 -WmCompact hello.pas`\
183+`ppcross8086 -WmLarge hello.pas`\
184+`ppcross8086 -WmHuge hello.pas`
185+
186+And in case you're wondering - it doesn't matter which ppcross8086 compiler binary you use (i.e. from the tiny, small, medium, compact, large or huge model snapshot). They are identical. Only the compiled units differ.
187+
188+## Status
189+
190+The compiler has been enabled as a CPU/OS target in FPC.exe since revision 25792 (CPU: i8086, OS: msdos).
191+
192+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.
193+
194+### Internal linker
195+
196+The internal linker does not support all records and features of the OMF object file format. It was designed to support only the records produced by the NASM assembler and FPC's own internal object writer. You may encounter problems if you try to link object modules produced by other compilers and assemblers.
197+
198+### Floating point support
199+
200+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.
201+
202+### Nil pointer assignment checking
203+
204+The **small** and **medium** memory models offer rudimentary nil pointer assignment checking. The system RTL puts a pattern of 32 bytes equal to \$01 at the beginning of the data segment (DS:0000). At the end of program execution, this pattern is checked and if turns out it has changed, the message:
205+
206+`Nil pointer assignment`
207+
208+is printed on the screen. This indicates that a nil pointer assignment has happened at some time during the program execution. Unfortunately, we can't tell when exactly, only that it has happened.
209+
210+### New pointer types
211+
212+To reflect the i8086 segmented memory model, FPC supports several pointer types:
213+
214+#### Near pointers
215+
216+This is the default pointer type in the tiny, small and medium memory models.
217+
218+Near pointers can be declared in any memory model, using the *near* keyword. For example:
219+
220+``` pascal
221+type
222+ PNearInteger = ^Integer; near;
223+```
224+
225+There's also an untyped near pointer, predefined in the system unit, called *NearPointer*.
226+
227+#### Special versions of near pointers
228+
229+Near pointers are declared using the *near* keyword, followed by a segment register, enclosed in single quotes. For example:
230+
231+``` pascal
232+type
233+ PNearCSInteger = ^Integer; near 'CS';
234+ PNearDSInteger = ^Integer; near 'DS';
235+ PNearESInteger = ^Integer; near 'ES';
236+ PNearSSInteger = ^Integer; near 'SS';
237+ PNearFSInteger = ^Integer; near 'FS';
238+ PNearGSInteger = ^Integer; near 'GS';
239+```
240+
241+There are also untyped versions, predefined in the system unit:
242+
243+` NearCSPointer`\
244+` NearDSPointer`\
245+` NearESPointer`\
246+` NearSSPointer`\
247+` NearFSPointer`\
248+` NearGSPointer`
249+
250+#### Far pointers
251+
252+This is the default pointer type in the compact, large and huge memory models.
253+
254+Far pointers can be declared in any memory model, using the *far* keyword. For example:
255+
256+``` pascal
257+type
258+ PFarInteger = ^Integer; far;
259+```
260+
261+There's also an untyped far pointer, predefined in the system unit, called *FarPointer*.
262+
263+#### Huge pointers
264+
265+Huge pointers are like far pointers that support pointer arithmetic without the 64kb segment wraparound. That means they will automatically switch to a different segment if the offset exceeds 64k or becomes less than 0. Thus, they are very useful for accessing blocks of memory that exceed 64kb. Additionally, they support normalization, which is explained in the next section. Their main disadvantage is that they are quite a bit slower compared to far pointers.
266+
267+Huge pointers are declared using the *huge* keyword. For example:
268+
269+``` pascal
270+type
271+ PHugeInteger = ^Integer; huge;
272+```
273+
274+There's also an untyped huge pointer, predefined in the system unit, called *HugePointer*.
275+
276+##### Huge pointer normalization
277+
278+In real mode it is possible for several different pointers to point to the same memory address. For example, the following different pointers point to the same memory location:
279+
280+``` pascal
281+Ptr($1000, $2345)
282+Ptr($1200, $0345)
283+Ptr($1234, $0005)
284+```
285+
286+This is because they resolve to the same linear address via the formula (segment * 16 + offset):
287+
288+``` pascal
289+Ptr($1000, $2345) // -> $1000 * 16 + $2345 = $12345
290+Ptr($1200, $0345) // -> $1200 * 16 + $0345 = $12345
291+Ptr($1234, $0005) // -> $1234 * 16 + $0005 = $12345
292+```
293+
294+A Pointer whose offset is between \$0 and \$F is called a *normalized* pointer. That's the pointer with the lowest possible offset among all the pointers that point to the same linear address.
295+
296+Huge pointers can be automatically normalized by the compiler when doing pointer arithmetic on them or when comparing them. This is controlled by the *\$HugePointerNormalization*, *\$HugePointerArithmeticNormalization* and *\$HugePointerComparisonNormalization* directives. All three of them are local switches, so you can change the modes in the middle of the program.
297+
298+###### \$HugePointerArithmeticNormalization
299+
300+This directive controls whether huge pointers are automatically normalized by the compiler after doing pointer arithmetic on them.
301+
302+###### \$HugePointerComparisonNormalization
303+
304+This directive controls whether huge pointers are normalized before comparing them.
305+
306+###### \$HugePointerNormalization
307+
308+This sets both \$HugePointerArithmeticNormalization and \$HugePointerComparisonNormalization:
309+
310+| mode | arithmetic normalization | comparison normalization | description |
311+|----|----|----|----|
312+| {\$HugePointerNormalization BorlandC} | On | On | Like Borland C |
313+| {\$HugePointerNormalization MicrosoftC} | Off | Off | Like Microsoft C |
314+| {\$HugePointerNormalization WatcomC} | Off | On | Like Watcom C |
315+
316+### Tested machines
317+
318+Compiled programs have been tested and known to work on the following machines:
319+
320+- [IBM PC 5150](http://oldcomputers.net/ibm5150.html) (the first PC model ever), with a 4.77 MHz 8088 CPU, 512 KB RAM and a CGA card, running IBM DOS 3.30
321+- [HP 200LX](http://en.wikipedia.org/wiki/HP_200LX), with a 7.91 MHz 80186 CPU, running MS-DOS 5.0
322+- IBM PS/2 Model 30-286, with a 10 MHz 80286 CPU and an AMD 287 FPU, running MS-DOS 6.22
323+- various boring 32-bit and 64-bit machines :)
324+- [DOSBox](http://en.wikipedia.org/wiki/DOSBox)
325+
326+### Supported memory models
327+
328+#### Tiny
329+
330+- Activated by the `-WmTiny` compiler option
331+- Code + Data + Heap + Stack \<= 64KB
332+- CS = DS = SS
333+- Pointer = NearPointer
334+- CodePointer = NearPointer
335+- Code starts at offset \$100
336+- 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
337+- The compiler defines: FPC_MM_TINY
338+
339+#### Small
340+
341+- Activated by the `-WmSmall` compiler option. This is the default memory model, so it is chosen if you don't specify a memory model.
342+- Code \<= 64KB, Data + Heap + Stack \<= 64KB (Code and data are in separate segments, so programs can use up to 128KB in total)
343+- DS = SS
344+- Pointer = NearPointer
345+- CodePointer = NearPointer
346+- Can produce only .exe files
347+- The compiler defines: FPC_MM_SMALL
348+
349+#### Medium
350+
351+- Activated by the `-WmMedium` compiler option
352+- Code \<= 1MB, Data + Heap + Stack \<= 64KB
353+- DS = SS
354+- Pointer = NearPointer
355+- CodePointer = FarPointer
356+- Can produce only .exe files
357+- The compiler defines: FPC_MM_MEDIUM
358+
359+#### Compact
360+
361+- Activated by the `-WmCompact` compiler option
362+- Code \<= 64KB, Data \<= 64KB, Stack \<= 64KB, Heap \<= 1MB
363+- Data structures cannot exceed 64KB
364+- Pointer = FarPointer
365+- CodePointer = NearPointer
366+- Can produce only .exe files
367+- The compiler defines: FPC_MM_COMPACT
368+
369+#### Large
370+
371+- Activated by the `-WmLarge` compiler option. This is the memory model used by Turbo Pascal version 4 and above
372+- Code \<= 1MB, Data \<= 64KB, Stack \<= 64KB, Heap \<= 1MB
373+- Data structures cannot exceed 64KB
374+- Pointer = FarPointer
375+- CodePointer = FarPointer
376+- Can produce only .exe files
377+- The compiler defines: FPC_MM_LARGE
378+
379+#### Huge
380+
381+- Activated by the `-WmHuge` compiler option
382+- Code \<= 1MB, Data \<= 1MB, Stack \<= 64KB, Heap \<= 1MB
383+- Static data of a single pascal module (i.e. unit or program) cannot exceed 64KB
384+- Data structures cannot exceed 64KB
385+- Pointer = FarPointer
386+- CodePointer = FarPointer
387+- Can produce only .exe files
388+- The compiler defines: FPC_MM_HUGE
389+
390+### Units and programs exceeding 64KB of code
391+
392+Although the medium, large and huge memory models support up to 1MB of code for the whole program+units, there's still a limit of 64kb code per pascal module (i.e. unit or program). If this limit is exceeded, you can overcome this by splitting the unit or program that exceeded 64KB into smaller units, so that each of them stays within the 64KB limit. But there's also an easier solution. You can put the following directive in the module that exceeds 64KB:
393+
394+`{$HUGECODE on}`
395+
396+This forces each procedure and function to be in a separate segment. Note that since the code of the unit is no longer in a single segment, this also disallows mixing near and far procedures in the same unit, so in this mode, 'near' and {\$F-} are ignored.
397+
398+Using {\$HUGECODE on} does not count as using a different memory model, because you can freely mix units with {\$HUGECODE on} and {\$HUGECODE off} in the same program.
399+
400+### Supported calling conventions
401+
402+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.
403+
404+#### Pascal
405+
406+This is the default calling convention. It strives for compatibility with Turbo Pascal 7.
407+
408+- Parameters are pushed on the stack left to right.
409+- The callee cleans the parameters from the stack.
410+- Procedures and functions must preserve DS, SS and BP and may destroy AX, BX, CX, DX, SI, DI and ES.
411+- 16-bit results are returned in AX, 32-bit results in DX:AX
412+- 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.
413+
414+## Troubleshooting
415+
416+### Compile error: missing .o files
417+
418+Problem: If you see errors/warnings like this during compiling & linking:
419+
420+```text
421+test.pas(12,24) Warning: Object system.o not found, Linking may fail !
422+Error! E2008: cannot open system.o : No such file or directory
423+```
424+
425+(and indeed there don't appear to be any .o files in your msdos units directory)
426+
427+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.
428+
429+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.
430+
431+Hint: You can add these options to your fpc.cfg file, as described in the "Updating your fpc.cfg" section.
432+
433+## Running the testsuite
434+
435+### Using DOSBox
436+
437+- build a snapshot for the memory model you want to test
438+- it is recomended to use a 32-bit x86 build of DOSBox, because the 64-bit one has inaccurate FPU emulation
439+- compile fpc/tests/utils/dosbox/dosbox_wrapper.pas for your native platform
440+- prepare and run a script like this:
441+
442+``` bash
443+#!/bin/sh
444+
445+FPCDIR=/home/blablabla/fpc-i8086/fpc
446+MEMMODEL=Small
447+
448+export FPCMAKE=$FPCDIR/utils/fpcm/fpcmake
449+export DOSBOX=/usr/bin/dosbox
450+export SDL_VIDEODRIVER=dummy
451+export SDL_AUDIODRIVER=dummy
452+
453+cd $FPCDIR/tests/
454+
455+ulimit -m 256000
456+#ulimit -v 256000
457+ulimit -d 256000
458+
459+echo running testsuite
460+make full FPCFPMAKE=$FPCDIR/compiler/ppcx64 TEST_FPC=$FPCDIR/compiler/ppcross8086 TEST_OPT=-Wm$MEMMODEL EMULATOR=$FPCDIR/tests/utils/dosbox/dosbox_wrapper
461+```
462+
463+## See also
464+
465+- [[GO32V2]] - DOS Extender
466+- [[go32v2 development]]
467+
468+---
469+*From the Free Pascal wiki, page "DOS", as it stood on 2021-04-14 after a change by Ñuño Martínez, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
470+Category: Cross compilation
471+Category: DOS
472+Category: FPC
473+Category: FPC internals
474+Category: Historical
475+Category: Operating Systems and Platforms

Back to history