-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d1f9ac8
commit 0e59b9a
Showing
1 changed file
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
Notes regarding DOSLIB's 16-bit tiny model builds. | ||
|
||
Watcom C does not natively have a "tiny" model, though | ||
the linker does when generating a .COM file. | ||
|
||
The problem, is that anything involving FAR pointers | ||
or references generates segment base relocations, which | ||
the .COM linker ignores. If not rectified, the resulting | ||
binary will crash. | ||
|
||
Things that trigger Watcom C to generate far segment | ||
relocations: | ||
|
||
- declaring variables as "far" | ||
|
||
example: unsigned char far somearray[1024]; | ||
|
||
- typecasting a function or variable from near to far | ||
|
||
example: void far *ptr = (void far*)(&var); | ||
|
||
- calling a function with a parameter that takes a | ||
far pointer, and passing a near pointer (near to | ||
far conversion as part of the function call). | ||
|
||
example: | ||
|
||
void interrupt vecthandler() { /* function is "near", in DGROUP */ | ||
... | ||
} | ||
|
||
... | ||
_dos_setvect(0xAA,vecthandler); | ||
|
||
The Open Watcom V2's stance on generating segment | ||
relocations is understandable: the small memory model | ||
acts the way it does and a lot of code relies on it. | ||
Making the compiler assume CS = DGROUP and load segment | ||
registers would break that. However, that means no | ||
official support for what I'm trying to do for the | ||
tiny model. | ||
|
||
DOSLIB's tiny model is explicitly defined as like the | ||
small memory model, but with the strict limitation that | ||
CS = DS = DGROUP, therefore, no segment relocations | ||
are needed at runtime to do near to far conversions, | ||
because the code can always pull it out of CS. | ||
|
||
To accomplish that, a patching tool is included in this | ||
project. The tool reads the symbol information, and then | ||
uses the FIXUP table to patch opcodes in the code segment | ||
so that the code loads from CS instead of a 16-bit immediate | ||
word that the EXE relocation table would *normally* overwrite | ||
with the segment value. The patched OBJ is then written back | ||
over the original, and then linked into the final binary | ||
to produce a working .COM executable. The tool is named | ||
"OMFSEGDG", or "OMF segment DGROUP patching utility". | ||
|
||
To avoid corrupting the code, or making patches that are | ||
unreasonable, the tool enforces the rule that it will only | ||
patch a segment relocation if: | ||
|
||
* The FIXUP refers to the TEXT segment, or a segment | ||
that is of the CODE class. | ||
|
||
* It's an EXTERN reference (it can't know until final | ||
linking where the EXTERN goes, so as part of the tiny | ||
model, it must assume it's in the same DGROUP) | ||
|
||
* The FIXUP refers to the DGROUP segment group. | ||
|
||
For any other case, it will refuse to patch that segment | ||
relocation, and will print a warning. | ||
|
||
In this project, OBJ files generated by both Open Watcom | ||
C and NASM are patched in the tiny memory model target | ||
to make them usable in a .COM executable model. | ||
|
||
===== KNOWN ISSUES WITH TINY MODEL ===== | ||
|
||
* Watcom C's floating point library (8087 emulation) | ||
|
||
You may see a warning in the .map file and on the console | ||
about the floating point emulator. There is nothing I | ||
can do about that at this time, however, I have yet to | ||
see any issues appear. | ||
|
||
For the time being, to be safe, try not to use floating | ||
point in your tiny model targets. | ||
|
||
* far-declared variables cannot be fixed up in this manner | ||
|
||
If you declare a variable of type "far", Watcom C will | ||
usually create a new SEGDEF for that variable which will | ||
not be part of DGROUP, and therefore will not be patchable | ||
for the tiny memory model. | ||
|
||
At this time, OMFSEGDG does not yet recognize this case, | ||
and the resulting binary will fail and possibly crash. | ||
|