-
Notifications
You must be signed in to change notification settings - Fork 18
/
tiny-model-readme.txt
100 lines (72 loc) · 3.47 KB
/
tiny-model-readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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.