cfad47cfa3/tads2/portnote.txt

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
Notes on porting TADS
2
=====================
3
4
Following are notes on changes made to the OS layer in recent
5
versions, starting with the most recent changes.  If you're updating
6
a TADS port, you should refer to the changes made since the last
7
working version on your system.
8
9
At the end of the file, you'll find more general information on how
10
the portability layer is designed and how to get TADS working on a
11
new operating system.  If you're porting TADS to a new system for the
12
first time, you should look at the general notes at the end of this
13
file.
14
15
16
Quick Start Guide
17
-----------------
18
19
To port TADS to a new platform, you should start by looking at
20
osifc.h, which specifies the entire TADS Operating System Interface.
21
You must provide an implementation of this interface for your
22
platform.
23
24
If you're porting TADS to a machine that resembles another platform
25
where TADS already runs, you can probably use the OS Interface
26
implementation for that existing platform as a starting point; if
27
not, you should read the documentation in osifc.h to learn what each
28
function must do.
29
30
You'll also need to construct a makefile or equivalent for your
31
platform, to compile the C files that make up TADS and link the
32
results into executables for the TADS Interpreter, and optionally the
33
TADS Compiler and other tools.  You should refer to an existing
34
makefile (such as the DOS or Unix makefile) as a starting point.
35
36
37
A Note on Newlines
38
------------------
39
40
Different operating systems have a tendency to disagree on the most
41
trivial details.  One of these pointless variations that causes a lot
42
of trouble is "newline" conventions: each OS has its own way of
43
signaling the end of a line of text in files such as C source and
44
header files.  In almost every case, the end of a line of text is
45
indicated by some combination of the special characters with ASCII
46
values 10 and 13, known respectively as "line feed" or "LF", and
47
"carriage return" or "CR".  MS-DOS uses the sequence CR-LF; Unix uses
48
just LF; Macintosh uses just CR; and some system somewhere probably
49
uses LF-CR.
50
51
In many cases, systems are tolerant of "foreign" conventions, but
52
sometimes the wrong conventions will confuse compilers and other
53
tools.  If you run into any mysterious compiler errors, or your text
54
editor or other tools have problems reading or displaying the TADS
55
source files, you might want to try converting the files to your
56
system's newline conventions.  One of the easiest ways to do this is
57
usually to use your UNZIP tool's "auto-convert text files" option
58
when you unpack the TADS source archive - on command-line systems,
59
this is usually the "unzip -a" option.
60
61
62
Version 2.5.8 changes
63
---------------------
64
65
* New OS_ATTR_xxx codes:
66
67
In the past, the single text attribute was "highlighting," specified
68
with OS_ATTR_HILITE.  Several new attributes have been added.  First,
69
there are two new attributes with specific renderings: OS_ATTR_BOLD
70
and OS_ATTR_ITALIC.  The former should use bold-face if available, the
71
latter an italic font.  On most character-mode platforms, bold-face
72
can be approximated with a brighter color, and italics can be ignored.
73
Second, there are two new abstract attributes: OS_ATTR_EM and
74
OS_ATTR_STRONG.  These correspond to the HTML <EM> and <STRONG>
75
attributes, so it's up to the platform to define the actual
76
appearance.
77
78
PORTS CAN IGNORE THE NEW ATTRIBUTES.  These changes have been made in
79
such a way that everything will continue to work as it has all along
80
if a port ignores the changes.  OS_ATTR_BOLD, OS_ATTR_HILITE, and
81
OS_ATTR_EM will all map to the same code, which is the same as the
82
original OS_ATTR_HILITE code.  OS_ATTR_ITALIC will map to a new code,
83
but since existing ports don't know this code, it will do nothing.
84
OS_ATTR_STRONG maps to zero by default (i.e., no change to the codes
85
at all), so it will also do nothing.  Thus, existing ports will work
86
the same as they always have with existing games.  
87
88
Any port that's capable of displaying italics might want to add
89
recognition of italics.  If you do this, it might be desirable to add
90
definitions to your OS-specific header to #define OS_ATTR_EM as
91
OS_ATTR_ITALIC and OS_ATTR_STRONG as OS_ATTR_BOLD, for consistency
92
with most HTML browser renderings.  Your #defines for these symbols
93
will override the defaults, since the defaults will be defined only if
94
your OS header doesn't otherwise define the symbols.
95
96
97
* MORE banner style:
98
99
A new style flag has been added: OS_BANNER_STYLE_MOREMODE.  This style
100
indicates that the banner should pause for a MORE prompt any time its
101
text overflows the vertical display area of the banner, to give the
102
user a chance to read a long passage and acknowledge that it's okay to
103
show more text.  When this flag isn't set, the default is that long
104
passages are allowed to scroll off the screen (assuming the
105
auto-vscroll style is set), even if the user might not have had a
106
chance to read them.  With this new style flag set, though, a banner
107
window should pause when text overflows the window, using the same
108
sort of prompt and user acknowledgment used for the MORE prompt in the
109
main game window.  Note that there's no sysinfo flag to opt out of
110
implementing this style; it's important enough that platforms
111
supporting the banner API at all must support this style.
112
113
Platforms based on osgen3.c won't need to do anything to support this
114
new style, as it's fully handled in osgen3.c.  Other platforms will
115
have to implement this style in their banner code.
116
117
118
* Parent Windows in the os_banner API:
119
120
The new concept of a "parent" window has been introduced into the
121
banner API.  When a banner window is created, the caller can now
122
optionally designate a parent banner, which is an existing banner
123
window from which the new banner's display area will be taken.  In
124
past versions, there was no explicit parent window, and each new
125
banner's display area was taken out of the main game window's
126
rectangle.  When the caller does not specify a parent banner, this
127
traditional behavior applies; however, when the caller specifies a
128
parent, the display area is taken from the parent rather than from the
129
main game window.
130
131
For implementations based on osgen.c or osgen3.c, no changes are
132
needed to any system-specific code.  All of the necessary changes are
133
handled entirely in osgen.c and osgen3.c.
134
135
Implementations that do not implement the banner API must merely to
136
change the definition of their dummy os_banner_create() function to
137
match the new prototype.
138
139
Systems that implement the banner API and which DO NOT use osgen.c or
140
osgen3.c must implement the new parent window mechanism.  This will
141
require several changes.  First, os_banner_create() must be changed to
142
use the new prototype, which includes an argument for the parent
143
banner handle.  Second, os_banner_create() must remember the parent
144
window handle with the internal data structure it uses to represent
145
the new window.  Third, the system-specific code that calculates the
146
banner layout must take the parent structure into account; see
147
os_banner.htm for details of the required new layout algorithm.
148
Fourth, if the implementation supports drawing banner window borders
149
(as specified through the style flags), it will have to take into
150
account the new rule that a border is drawn to the horizontal or
151
vertical extent (as appropriate) of the *union* of the banner and all
152
of its child windows.  Fifth, os_banner_delete() might need to hide or
153
set to zero size any children of the banner being deleted, since once
154
a parent is deleted, its children become invisible, although they
155
remain valid as abstract objects until explicitly deleted.
156
157
* os_nonstop_mode():
158
159
This new function lets the portable code tell the OS layer that it
160
wants to run in "non-stop" mode, which means that MORE prompting (or
161
any local equivalent) should be disabled.  By default, non-stop mode
162
is turned off; this function lets the portable code turn it on and
163
off.  Character-mode platforms based on osgen.c/osgen3.c don't have to
164
worry about this.  Platforms where MORE prompting doesn't exist or is
165
provided by the portable console layer can simply provide a dummy
166
implementation.  Platforms where the OS layer handles MORE prompting
167
should provide a real implementation of this function.
168
169
170
Version 2.5.7 changes
171
---------------------
172
173
IMPORTANT - if you're using a platform based on osgen.c, you can skip
174
#1 through #5, because these changes are handled by the portable osgen.c
175
implementation.  Skip to #6 if you're using osgen.c
176
177
1.  The function os_hilite() has been DELETED.  You should remove any
178
implementation of this function you provide.
179
180
2.  The new function os_set_text_attr() replaces os_hilite().  This
181
new function is used to set text attributes in the main window.  If
182
you had an implementation of os_hilite() that simply returned zero,
183
your os_set_text_attr() need do nothing at all.  If your os_hilite()
184
implementation did anything else, it can be implemented with something
185
like this:
186
187
  void os_set_text_attr(unsigned int attr)
188
  {
189
    os_printf("%c", (attr & OS_ATTR_HILITE) != 0 ? ON : OFF);
190
  }
191
192
where ON is to be replaced by the character code that os_hilite(1)
193
returned in your old implementation, and OFF is to be replaced by the
194
character code that os_hilite(2) returned.  If possible, you should
195
optimize this by doing nothing when the current hilite mode is not
196
being changed.  The purpose of this change is to generally improve the
197
osifc design, and to make it more extensible by providing a structured
198
way to add new attributes to be added in the future.
199
200
The meanings of colors in os_set_text_color() and os_set_screen_color()
201
have changed.  The values are now encoded RGB values; some macros are
202
provided in osifc.h for manipulating these color values.  Platforms
203
based on osgen.c will NOT have to do anything for this change, since
204
osgen.c defines the osifc-level color routines.
205
206
3.  The os_printf() and os_vprintf() routines have been DELETED.  These
207
have been replaced by os_printz() and os_print() (see #4).
208
209
4.  The new routines os_printz() and os_print() have been ADDED.  These
210
routines do essentially what os_printf() and os_vprintf() formerly did,
211
but with a greatly simplified interface.  These functions are notably
212
different from the former os_printf() and os_vprintf() in some important
213
ways:
214
215
   4a.  These routines do NOT take a printf-style format string, but
216
   simply take a string to display directly.  There is no need to perform
217
   any parameter substitutions on the string.
218
219
   4b.  os_printz() takes a NULL-TERMINATED string, while os_print() takes
220
   a COUNTED-LENGTH string (the byte length is given as a separate argument),
221
   and thus CANNOT assume that the string is null-terminated.  os_printz()
222
   for (PRINT-Zero-terminated) can be implemented as a simple call to
223
   os_print, with the string's length computed with strlen().
224
225
   4c.  These routines NO LONGER have to worry about the "highlight" escape
226
   code sequences.  Highlighting is handled with the new text attributes
227
   settings (see #2 above), so strings presented to os_print will no longer
228
   have any embedded escape codes.  The only special characters that these
229
   routines are now expected to recognize are '\n' and '\r'.
230
231
5.  Several new SYSINFO_xxx codes have been added to osifc.h.  Your
232
os_get_sysinfo() implementation should be updated for the new codes.
233
234
235
6. [Begin osgen.c changes]
236
237
All platforms based on the semi-portable osgen.c implementation must
238
make some small adjustments to their ossxxx routines.  THE FOLLOWING
239
NOTES APPLY *ONLY* TO OSGEN.C PLATFORMS - if you're not linking with
240
osgen.c, ignore the following.  Note that these aren't changes you
241
have to make to osgen.c itself - these are changes you have to make
242
to your system-specific code that osgen.c relies upon.
243
244
There are now two different "osgen" implementations.  First, there's
245
the traditional osgen.c - this is the one you'll get by default if
246
you do nothing, since it's the one your makefile (or equivalent)
247
already uses.  This version of osgen.c has been reworked a little,
248
but it's substantially the same as in past versions.  Second, there's
249
a new version called osgen3.c - if you like, you can switch to this
250
one.  osgen3.c is a REPLACEMENT for osgen.c - you use EITHER osgen.c
251
or osgen3.c, but not both.  If you switch, simply substitute osgen3.c
252
for osgen.c wherever it appears in your makefile.
253
254
Okay, so should you switch to osgen3.c, or stick with osgen.c?  In
255
the long run, the answer is that you should switch; but when you do
256
so is up to you.  What you get with osgen3.c is a full implementation
257
of the new TADS 3 "banner API," which lets TADS 3 programs control
258
the screen layout much more precisely than TADS 2 programs could.  If
259
you are building the TADS 3 interpreter, you should definitely switch
260
to osgen3.c, to give TADS 3 programs the full capabilities of the new
261
banner API.  If you're building only a TADS 2 interpreter, there's
262
less immediate benefit in switching, because TADS 2 programs don't
263
have any way to access the banner API.  The main reason not to switch
264
if you don't have to is that osgen3.c is a substantial rewrite that
265
hasn't been around nearly as long as osgen.c and thus hasn't had
266
nearly as much practical testing; sticking with osgen.c is less
267
likely to introduce new bugs.  On the other hand, it should be
268
practically no work to switch to osgen3.c - the only change should be
269
replacing osgen.c with osgen3.c in your makefile.  If you do plan to
270
port the TADS 3 interpreter at some point, switching to osgen3.c now
271
would have the advantage that you'll feel safer using osgen3.c when
272
the time comes for the TADS 3 port, because you will have been using
273
osgen3.c between now and then.
274
275
You'll have change your osxxx code as described in the sub-topics
276
below, regardless of whether you stick with osgen.c or switch to
277
osgen3.c.
278
279
6a. Several global variables have been eliminated.  You can delete
280
these from your osxxx.h headers and remove calcaulations from your
281
osxxx.c source files.  (It's not vital that you do this, but it's
282
encouraged in the interests of general clean-up.  If you're still
283
using any of these variables for your own purposes, of course, you are
284
free to keep them - just be aware that osgen.c no longer needs them.)
285
The following variables are no longer used in osgen.c:
286
287
  ldesc_color
288
  ldesc_column
289
  ldesc_curline
290
  ldesc_line
291
  max_column
292
  max_line
293
  score_column
294
  sdesc_column
295
  sdesc_line
296
  text_column
297
  text_lastcol
298
  text_normal_color
299
  text_bold_color
300
301
Note that you might not want to delete the xxx_color variables, since
302
you might want to use these same values in your ossgetcolor()
303
implementation (see "fifth..." below).  However, osgen.c no longer
304
uses these variables, since it now instead calls your ossgetcolor()
305
routine to determine what color values to use.
306
307
If you switch to osgen3.c, the following globals are also eliminated
308
(or, rather, can be eliminated, as osgen3.c doesn't require them):
309
310
  sdesc_color
311
  text_color
312
313
6b. Your osxxx.c code MUST NOT set or modify G_os_pagelength or
314
G_os_linewidth.  In the past, the osxxx.c code was responsible for
315
setting these, and was aware of the status line location and so forth.
316
Don't set these variables any more.  Instead, set the new global
317
variables G_oss_screen_width and G_oss_screen_height to the height and
318
width of the screen, in characters - DO NOT make any adjustments for
319
status lines or anything else, as osgen.c will take care of that.  Be
320
sure to set these variables in your os_scrini() routine, so that
321
they're available during osgen.c's initialization.
322
323
6c. If the screen size can ever change dynamically after
324
initialization, you MUST call the new function
325
osssb_on_resize_screen() immediately after updating the global
326
variables G_oss_screen_width and G_oss_screen_height.  This will
327
ensure that osgen.c has a chance to refigure its internal layout
328
parameters according to the new screen size.
329
330
6d.  You should #include "osgen.h" in your osxxx.c file(s).
331
332
6e.  You must implement the new routines oss_get_sysinfo() and
333
ossgetcolor().  (These actually were added just before the 2.5.6
334
release, so if you've sync'ed up lately, you probably have implemented
335
these already - they haven't changed in this version.)  Refer to
336
osgen.h for details on how these are supposed to work.  These new
337
routines provide text color support, so that games can explicitly set
338
the colors of the text they display; color support is optional, but if
339
you don't support color, you must must still provide minimal
340
implementations of these routines to return the same color scheme
341
you've used in the past.  
342
343
In the past, several global variables (text_normal_color,
344
sdesc_color, etc) had the "oss color codes" to use for different
345
types of text - these color codes were passed to ossdsp(), ossclr(),
346
and so on for rendering by your osxxx.c code.  osgen.c no longer uses
347
most of these; it only uses sdesc_color and text_color.  If you're
348
switching to osgen3.c, even those hold-outs are gone.  Instead, the
349
osgen layer calls your ossgetcolor() routine to get the color code to
350
use for each case.  If you don't want to support any more color than
351
you did in the past, you can simply implement ossgetcolor() so that
352
it looks for the various abstract color codes (OS_COLOR_TEXT,
353
OS_COLOR_STATUSLINE, etc), and returns the corresponding global
354
variable value.  The advantage of the new scheme is that it allows
355
the game code to set *specific* colors (e.g., red, blue, cyan) for
356
individual bits of text, as long as your osxxx.c code (and your
357
display hardware, of course) can support specific colors.
358
359
6f.  The macro OSGEN_ATTR_BOLD has been renamed to OS_ATTR_HILITE.  If
360
you ported the 2.5.6 release, you might have a reference to this
361
macro; the meaning is the same, so all you have to do is change the
362
name.  For convenience, OSGEN_ATTR_BOLD is now defined as equivalent
363
to OS_ATTR_HILITE, but the new name should be used as soon as
364
possible.
365
366
6g.  The OS_COLOR_xxx symbols have been renamed to OSGEN_COLOR_xxx.
367
The meanings are the same as they were; the name change reflects the
368
change in the osifc-level color scheme.
369
370
6h.  Eight new OSGEN_COLOR_xxx values have been introduced, to allow
371
for somewhat better granularity in setting colors at the system level.
372
With the new colors, the OSGEN_COLOR_xxx values can specify a total of
373
16 colors, which correspond to the eight ANSI colors at "low
374
intensity" and "high intensity"; the low-intensity set is essentially
375
the high-intensity set at half brightness.  On most systems based on
376
osgen.c, if this full range of colors is available, the brighter half
377
of the range will be used to show high-intensity text, so in fact only
378
eight colors will really be available; on such systems, ossgetcolor()
379
should simply collapse the 16 colors down to the 8 ANSI colors, by
380
treating the low-intensity and high-intensity version of a given color
381
the same, and then pick from the low- or high-intensity version
382
according to the boldness attribute.  Even for systems that collapse
383
the colors in the this manner, though, there is still value in having
384
the broader range, in that the full range of 16 colors can be selected
385
for backgrounds, which do not have a boldness attribute and thus are
386
free to offer the full range of 16 colors to clients.
387
388
6i.  You must implement the new routine oss_raw_key_to_cmd().  This
389
routine's purpose is to map "raw" keystroke codes to command-editing
390
CMD_xxx codes, essentially mapping results from the style that
391
os_getc_raw() uses to the style os_getc() uses.  This routine was
392
created to give the OS implementation more specific control over the
393
mapping of raw keystrokes to command-editing functions.  For most
394
systems, you can probably just copy the MS-DOS implementation, in the
395
source file msdos/osdos.c, making any desired changes to the control
396
key or other mappings.
397
398
399
[End osgen.c changes]
400
401
402
Version 2.5.6 changes
403
---------------------
404
405
Several new SYSINFO_xxx codes have been added - osifc.h has the full
406
list.  The system-specific code that provides system information
407
should be updated to handle the new codes.
408
409
A new file-open function, osfoprwt(), has been added.  This function
410
is the text-mode equivalent of osfoprwb(): it opens a text file for
411
both read and write access, keeping intact any existing contents.  I
412
have attempted to provide a suitable implementation in the source
413
code for each ported version of which I have a copy in my source
414
tree, but a platform expert on each target system might want to check
415
my work to make sure it's correct for their system.
416
417
A second new file-open function, osfoprwtt(), has been added.  This
418
function is the text-mode equivalent of osfoprwtb(): it opens a text
419
file for both read and write access, truncating any existing file.
420
I've attempted to provide a suitable definition for each platform for
421
this function as well.
422
423
The new function os_update_display() has been added.  This function's
424
purpose is to process any pending redraw events immediately, if
425
applicable to the system.  This function only needs to be implemented
426
on event-driven operating systems where the display is drawn in
427
response to redraw events generated by window region invalidations.
428
(If that doesn't mean anything to you, you're almost certainly not on
429
such a platform - the Windows and Macintosh GUI's both use this kind
430
of drawing scheme, but text-mode versions would certainly not.)  The
431
purpose of this routine is to update the display prior to a long
432
computation, to avoid the appearance that the program is frozen
433
during the computation delay.
434
435
The new functions os_set_text_color() and os_set_screen_color() can
436
optionally provide the game with control over display colors.  These
437
are described in osifc.h.  These functions are optional; if they're
438
not suitable for a given platform, simply provide empty
439
implementations.
440
441
The new functions os_gets_timeout() and os_gets_cancel() provides an
442
event-oriented interface for reading a command line from the keyboard.
443
This function is similar to the regular os_gets(), but has a timeout
444
feature that allows the keyboard read to be interrupted after a
445
specified interval has elapsed, and then possibly resumed later.
446
Timed keyboard input is optional; if it can't be implemented on a
447
platform, simply provide an implementation for os_gets_timeout() that
448
returns OS_EVT_NOTIMEOUT when a timeout is provided, and an empty
449
implementation for os_gets_cancel()..  Note that even if timed input
450
is not allowed, os_gets_timeout() should minimally call the plain
451
os_gets() when the caller does not specify a timeout, and only return
452
the OS_EVT_NOTIMEOUT error when a timeout is actually requested by the
453
caller.
454
455
A new interface for managing "banner" windows in the process of being
456
added.  This is a work in progress, and you should just ignore it for
457
now, providing only stub implementations.  The new interface consists
458
of a set of functions (about a dozen) whose names are of the form
459
os_banner_xxx(); I'm still in the process of working out the final
460
details, so the set may change in the future.  These new functions,
461
when they're completed, will provide functionality similar to the HTML
462
TADS <BANNER> tag, but without the limitations that arise from using a
463
single output stream to control all aspects of the display.  In the
464
future, this interface will allow for for implementation of
465
banner-like behavior in text-only platforms, allowing more flexibility
466
for games in their use of text-mode displays.  The banner interface
467
will always be entirely optional; if it is not feasible or desirable
468
to implement the interface, a platform will be able to provide
469
do-nothing implementations for these routines.
470
471
472
Version 2.5.2 changes
473
---------------------
474
475
In preparation for TADS 3, I've been tightening up the interfaces
476
between the OS layer and the portable code.  My goal is to ensure
477
that the a common OS layer can be shared by TADS 2 and TADS 3, which
478
will dramatically simplify the porting of TADS 3 by eliminating the
479
need to write a new set of OS routines.  Porting TADS 3 will simply
480
be a matter of compiling and linking the TADS 3 portable code with
481
the existing TADS 2 OS code for your platform; the only coding you
482
should have to do is to create the makefile.
483
484
I've been working on this OS interface improvement for some time.
485
This process started with the creation of osifc.h, which provides us
486
with a comprehensive definition of the entire interface that the
487
portable code uses to call the OS code.  I've also been expanding and
488
improving the OS interfaces slightly over the past few releases, but
489
I've been trying to minimize these changes to minimize the resulting
490
porting work created.
491
492
With this release, I've addressed a new area, which is references
493
from the OS code to the portable code.  In general, the OS code
494
should never call the portable code or use any global variables
495
defined in the portable code; doing so ties the OS code to a
496
particular portable system, which makes it difficult to re-use the OS
497
code in a new system (such as TADS 3).
498
499
The OS code should NOT henceforth refer to ANY function or global
500
variable defined in the portable code.  If your OS code refers to
501
anything in the portable code, your OS code will not work with TADS
502
3, because those portable symbols will probably not be defined at all
503
in TADS 3.
504
505
I've tried to remove all of the references I could find from the OS
506
code into the portable code.  However, until TADS 3 is ported to the
507
existing platforms, where the linker can root out the missing
508
symbols, it is difficult to know for sure that all of the references
509
are gone.
510
511
* OS code should no longer call runstat().  Most os_gets()
512
implementations started by calling runstat() to update the status
513
line prior to reading input.  The OS code is no longer responsible
514
for this.  You should simply remove any runstat() calls from your
515
OS code.  If you have runstat() calls that are needed in places
516
other than at the start of os_gets(), contact me (mjr_@hotmail.com)
517
if you would like advice on how to remove the dependency and I'll
518
try to help figure out what to do.
519
520
* The global variables "pagelength" and "linewidth" have been renamed
521
to G_os_pagelength and G_os_linewidth.  This formally moves these
522
variables into the OS layer rather than leaving them in the portable
523
formatter.
524
525
* The global variable "moremode" has been renamed to G_os_moremode,
526
moving it into the OS layer.
527
528
* OS routines should no longer call tio_is_html_mode() (or any other
529
tio routines).
530
531
* OS routines should no longer call qasclose().  Most of the
532
os_term() implementations in the OS code were calling this routine;
533
this should instead be handled in the portable code, so the OS code
534
should not use this method at all.
535
536
* OS code should no longer call outformat() or getstring().  The
537
text-only implementations of os_askfile() and os_input_dialog()
538
called these routines, because they implemented their dialogs using
539
formatted text.  To address this, I've moved these text
540
implementations to the portable layer; there is no longer a text-only
541
version of os_askfile() or os_input_dialog().  Refer to askf_tx.c,
542
askf_os.c, indlg_tx.c, and indlg_os.c for details on the new
543
portable-layer implementations.
544
545
MAKEFILE CHANGES: You must include one of askf_tx.c or askf_os.c in
546
each executable you build.  You must include one of indlg_tx.c or
547
indlg_os.c in each executable.  Refer to these files to determine
548
which one to choose.  In general, the _tx versions are text-only
549
implementations -- these do not invoke os_xxx routines; the _os
550
versions simply pass through the operation to the corresponding
551
os_xxx routines.  You should choose the _os version if you have a
552
corresponding os_xxx implementation that you want to use; you should
553
choose the _tx version if you want to use the plain text version.
554
If your os_xxx routine was calling outformat() or getstring(), you
555
should simply delete your os_xxx routine entirely and use the _tx
556
version; otherwise, keep your os_xxx routine and use the _os version.
557
558
OTHER CHANGES:
559
560
* added os_is_special_file()
561
562
* added os_uninit()
563
564
* added OS_CHARMAP_FILECONTENTS identifier
565
566
567
568
Version 2.5.1 changes
569
---------------------
570
571
* I added a new command code for os_getc(): CMD_EOF.  This new code
572
indicates that "end of file" has been reached on the console input;
573
this usually means that the player has terminated the application
574
through some means such as closing its main window, or disconnected
575
the terminal, or something like that.  os_getc() should return this
576
new code when it detects this type of condition so that code that
577
calls os_getc() can finish up whatever it's doing and terminate the
578
application gracefully.
579
580
* There's a new function called os_getc_raw().  This is conceptually
581
a lower-level version of os_getc().  The difference is that os_getc()
582
returns "translated" keystroke CMD_xxx codes, whereas os_getc_raw()
583
returns "raw" CMD_xxx codes.  The translated codes are higher-level
584
functional codes; for example, on Unix, when the user types Ctrl-E,
585
os_getc() would return CMD_END, because Ctrl-E is bound to the
586
end-of-line command.  In contrast, os_getc_raw() would simply return
587
ASCII 5.  Similarly, on DOS, if the user presses the Escape key,
588
os_getc() would return CMD_KILL, but os_getc_raw() returns ASCII 27.
589
Note that some keys return different CMD_xxx codes for os_getc() and
590
os_getc_raw(); for example, on DOS, if the user presses F1, os_getc()
591
returns CMD_SCR (to toggle scrollback mode), but os_getc_raw() returns
592
CMD_F1.
593
594
The purpose of os_getc_raw() is to allow lower-level access to keystroke
595
information, particularly for the inputkey() TADS function, while still
596
preserving the port-specific functional mapping that os_getc() affords.
597
598
Refer to osifc.h for documentation of the new function.  Note that the
599
CMD_xxx codes defined in osifc.h are now commented to indicate which
600
command codes are "translated" and which are "raw"; when a particular
601
key maps to one of each type, os_getc() should return the translated
602
CMD_xxx code and os_getc_raw() should return the raw code.
603
604
* The osfoprwb() function has traditionally been implemented
605
incorrectly.  On most platforms, this has been implemented as a call
606
to fopen() with the mode "r+b" (or simply "r+" on platforms with no
607
text/binary mode distinction), following the example of the DOS code.
608
In fact, the intended function, which was not adequately documented
609
in the osifc.h comments, was to open an existing file or create a new
610
file if it didn't already exist.  The C fopen() "r+" mode fails if the
611
file doesn't exist.  The intended behavior has now been correctly
612
documented in osifc.h, and the DOS, Windows, Unix, and Mac versions
613
have been changed to use the correct behavior.
614
615
616
Version 2.4.1 changes
617
---------------------
618
619
* New OS function: os_input_dialog().  A default character-mode
620
implementation in osgen.c should suffice for most ports, but GUI
621
ports should show a dialog box if possible.  The character-mode
622
implementation in osgen.c is selected at compile time with #define
623
symbol USE_STDIO_INPDLG, which osgen.c defines implicitly if
624
USE_STDIO is defined.
625
626
* New OS function: os_get_str_rsc().  Most platforms should be able
627
to use the default implementation in ostadrsc.c (in the generic
628
code directory).  Where possible, though, this function should be
629
implemented using native OS string resources; this will make it
630
easier for translators to localize the TADS executables.
631
632
* TADSVER.TXT has been changed to TADSVER.HTM, and DOSVER.TXT is
633
now DOSVER.HTM.
634
635
* The interface to the os_askfile() function has changed very
636
slightly, in that the result code values are now more precisely
637
specified.  In the past, this function simply returns zero for
638
success and non-zero to indicate failure of some kind.  The result
639
codes can now indicate the type of failure; in particular, the
640
function can distinguish actual errors from the case where the user
641
simply chooses to cancel the dialog.  Refer to osifc.h for details.
642
I've attempted to change all of the OS sources that I have in my
643
source tree; experts on the code for the individual platforms are
644
encouraged to double-check my changes.
645
646
647
Version 2.4.0 changes
648
---------------------
649
650
* os.h has been reorganized to make it cleaner and more consistent.
651
All of the DOS code has been removed from os.h and moved to new
652
DOS-specific headers; this leaves os.h as a very simple "switchboard"
653
file whose only function is to select the appropriate set of headers
654
to #include based on the system macro settings.  All of the non-DOS
655
headers already worked this way, so this change should be transparent
656
to other ports.
657
658
* osifc.h now has (as far as I can tell) complete documentation of
659
the entire TADS Operating System Interface.  In particular, all of
660
the file-related functions (osfoprb, osfrb, etc) are now specified
661
and documented in osifc.h, as are the former "library" functions
662
(osmalloc, osfree).  This change should not affect any existing code;
663
the additions are mostly comments.
664
665
* The os_find_first_file() and os_find_next_file() interfaces have
666
changed.  Two new parameters, outpathbuf and outpathbufsiz, have been
667
added; the new buffer is to receive the full path of the current
668
file, so that the caller doesn't have to attempt to construct the
669
path name from its components using possibly non-portable
670
assumptions.  This should have minimal impact, since the only ports
671
that appear to implement these functions currently are DOS, Windows,
672
OS/2, and Macintosh.  Refer to osifc.h for documentation.
673
674
* The os_progress() interface has changed slightly.  This function no
675
longer takes a (struct linfdef *) argument, which tied the function
676
to the particulars of an internal structure in the TADS 2 compiler;
677
instead, the function now takes a filename string and a line number.
678
This change should have minimal impact, since only the Macintosh port
679
currently provides a non-trivial implementation of this function.
680
681
682
Version 2.3.0 changes
683
---------------------
684
685
* ATTENTION UNIX USERS - If you run into weird display problems in
686
the interpreter, especially with spurious extra spaces at the
687
beginning of each line, try these definitions in your makefile:
688
689
  LIBS= -lncurses
690
  CFLAGS= -DHAVE_TPARM (plus whatever other CFLAGS you were already using)
691
692
* The existing os_term() function is now used more rigorously.  In
693
the past, the generic code called exit() directly in a few places,
694
which prevented the OS layer from doing any clean-up at termination.
695
The generic code should now use os_term() exclusively to terminate
696
execution.  This shouldn't require any new porting work, since
697
nothing about os_term() has changed -- the only change is that the
698
generic code is calling it more predictably now.  However, a few
699
ports may accidentally have omitted an os_term() implementation from
700
some executables, since it wasn't always needed before; if you get a
701
link error for this symbol during building, adjust your makefile to
702
include an os_term() implementation.
703
704
* A new file, oem.c, defines some global strings for use in identifying
705
the version of TADS.  You must fill in that file with a couple of
706
customized settings for your version.  Please refer to oem.h and
707
oem.c for details on how to do this.
708
709
* A few new OS interface functions have been added.  These functions
710
are described in comments in osifc.h.  The new functions are:
711
712
  os_get_sys_clock_ms()
713
  os_sleep_ms()
714
  os_get_event()
715
  os_set_title()
716
  osfdel_temp()
717
718
These functions should be reasonably simple to implement on most
719
systems.  os_get_event() in particular can simply degrade to
720
os_getc() with some additional argument checks and changes in the
721
return value if it's hard to implement fully on your system; the
722
USE_STDIO version in osgen.c can be used as a default implementation.
723
724
Note also that a completely portable implementation of os_sleep_ms()
725
is in msdos/oswin.c.  You can use this implementation if you wish,
726
but the function is included in the OS interface so that you can
727
replace it with something more suitable for your platform.  The
728
implementation in msdos/oswin.c discards keystrokes and other events
729
that occur during the delay, which may be undesirable on your system.
730
This implementation has the desirable effect of processing UI events,
731
such as window sizing, during the delay.
732
733
Most platforms can provide an empty implementation of os_set_title();
734
this function merely notifies the OS layer that the game has set a
735
title string via the HTML <title> tag.  If it's convenient, the OS
736
layer can use the title string as a window caption, or whatever else
737
makes sense.  Most character-mode display code will simply ignore
738
this; osgen.c has a default implementation that does nothing.
739
740
osfdel_temp() is a new function to complement os_create_tempfile().
741
This function deletes a temporary file previously created with
742
os_create_tempfile(), after the temporary file has been closed;
743
callers previously used osfdel(), the generic file deletion function,
744
to delete these temporary files.  The purpose of this new function is
745
to support systems that can be instructed to delete temporary files
746
automatically when closed; on such systems, a call to osfdel() is
747
redundant (and problematic), since the system will already have
748
automatically deleted the temporary file by the time the caller gets
749
around to invoking osfdel().
750
751
osnoui.c provides a simple implementation of osfdel_temp() that simply
752
calls osfdel(); this works with the implementation of os_create_tempfile()
753
in osnoui.c, so you won't need to make any changes if you're already
754
using this file.  If you're using a customized os_create_tempfile(),
755
you may want to provide a correspondingly customized osfdel_temp().
756
In particular, if your os_create_tempfile() opens the file in such a
757
way that the underlying OS will automatically delete the file when
758
closed, your osfdel_temp() should simply do nothing.
759
760
* The os_askfile() interface (defined in osifc.h) has been changed to
761
provide more information about what kind of prompt to use.  The extra
762
parameters indicate whether we're opening an existing file or saving
763
a new file, and what type of file we're interested in.  Many GUI
764
systems use different dialogs for opening and saving files, and
765
filter files displayed in a file selector dialog according to the
766
type of file to be chosen.  Systems that don't need the extra
767
information can ignore the new parameters; they're purely to make it
768
easier for the system code to determine what type of dialog to show.
769
770
I've updated my copies of the MSDOS, Win32, Mac, and Unix sources for
771
the new os_askfile interface, but I don't have a copy of every
772
port-specific version, so you may need to propagate this change into
773
your version.
774
775
* The #define's for the OSFTxxx codes (the file type codes) are now
776
in osifc.h.  In the past, these were scattered among the different
777
system-specific headers for no good reason -- these are used by
778
portable code, so they are necessarily part of the OS interface, and
779
hence belong in osifc.h.  If you encounter any errors with redundant
780
#define's for these symbols, you should simply remove the #define's
781
from your system-specific headers and use the ones in osifc.h.
782
783
* The #define's for the CMD_xxx codes (the os_getc() extended keystroke
784
codes) are now in osifc.h.  In the past, as with the OSFTxxx codes,
785
these were scattered among the system-specific headers.  It's desirable
786
to be able to use these key codes in the portable code, so these are
787
now part of the general OS interface.  As with the OSFTxxx codes, if
788
you run into any compilation errors with redundant #define's for CMD_xxx
789
symbols, you should be able to remove the #define's from your system-
790
specific headers and use the new osifc.h definitions.
791
792
793
Version 2.2.6 changes
794
---------------------
795
796
In past versions, the release notes for generic changes and platform-
797
specific changes were combined into a single file, which had to be
798
maintained separately on each platform.  For example, the DOS release
799
notes were in TADSVER.DOS.  To create a comprehensive set of release
800
notes for another platform, someone porting TADS had to sift through
801
TADSVER.DOS to pick out the generic changes, then add any changes
802
specific to the ported version.
803
804
In order to remove this extra work, I've broken up the release notes
805
into two separate files.  The new file TADSVER.TXT contains only the
806
generic changes.  Since these changes will automatically be included
807
in any port (because such changes are always in the portable portion
808
of the code), the distribution for a port should always be able to
809
include TADSVER.TXT unchanged.  The separate new file TADSVER.DOS
810
contains changes that apply only to the DOS version.  Since such
811
changes are only in the DOS osxxx code, they should not affect any
812
other platforms, so only DOS users should need to look at this file.
813
814
When creating a ported version, you can now simply create your own
815
platform-specific release notes file where you can describe any changes
816
that you made that apply only to your platform.
817
818
Please let me know (mjr_@hotmail.com) the name of your port-specific
819
release notes file, and I'll add it to the table at the top of
820
TADSVER.TXT, which refers users to the appropriate file for each
821
platform.  (You may want to add an entry to the table yourself for
822
your initial version, if you plan to include TADSVER.TXT with your
823
distribution.)
824
825
826
Version 2.2.4 changes
827
---------------------
828
829
I've changed the source distribution zip file's layout slightly to
830
make the TADS source tree more self-contained.  In the previous
831
version, several files were in a separate LIB directory, which was at
832
the same level in the hierarchy as the TADS2 directory.  This was an
833
undesirable layout for some people, since it meant that TADS had two
834
high-level directories.  Since keeping the files in a separate
835
directory doesn't serve any real purpose currently (the separation is
836
historical), I've merged these files into the base TADS directory
837
(except that a few of the files are now in TADS/MSDOS, because
838
they're DOS-specific).  Of course, you can still lay out your source
839
files however you want them, of course, but if you follow the layout
840
in the zip file, you'll need to adjust your makefile for the changed
841
location of these files.
842
843
If you change the default memory sizes in your osXXX.h file, you should
844
also define message strings that correspond to your new defaults for the
845
usage messages.  To do this, look at errmsg.c, and notice the big list
846
of TxD_xxxSIZ_MSG definitions.  For each value that you override in your
847
OS header, you should provide a corresponding TxD_xxxSIZ_MSG definition
848
that looks like the one in errmsg.c but uses your changed default value.
849
850
851
Version 2.2.3 changes
852
---------------------
853
854
The operating system interfaces have changed somewhat between version
855
2.2.2 and 2.2.3 (the HTML TADS release).  The OS interfaces have been
856
stable for a long time, so most systems where TADS has been ported
857
should have OS-dependent implementations that conform to the 2.2.2
858
interfaces.  Unfortunately, all of these ports will have to be reworked
859
slightly to accomodate the changes in 2.2.3.
860
861
The changes in 2.2.3 should be fairly minor, though, so it shouldn't
862
require a huge effort to upgrade port-specific code that worked with
863
the previous version.  The main changes are that the OS interfaces
864
have been rearranged slightly in the header files (note in particular
865
the creation of osifc.h), and some of the functions that were in
866
osgen.c have been moved to the new file osnoui.c.  A few functions
867
have had minor changes to their interfaces as well.  It will probably
868
be necessary to make some small changes to your makefiles because of
869
the rearrangements.
870
871
One of the biggest changes may be the use of ANSI-style function
872
prototypes throughout the code.  Depending on your compiler, you may
873
or may not have to change your OS function implementations to use ANSI
874
prototypes.
875
876
877
==============================================================================
878
879
General notes on porting TADS
880
-----------------------------
881
882
883
Code Organization
884
-----------------
885
886
The TADS code is divided into portable and system-specific sections.
887
In porting TADS to a new platform, only the system-specific portions
888
should need to be changed.  If any changes are needed to the portable
889
code, we consider the portable code in error and will try to correct
890
it so that it is the same on all platforms.  We want the portable
891
portion to have a single set of sources, without port-dependent
892
ifdefs, across all platforms.
893
894
For the most part, the system-specific sections are isolated in
895
files with the prefix "os", and system-specific functions and macros
896
all begin with "os" or "OS".
897
898
Historical note: At one point we started to group some code that High
899
Energy was internally sharing between multiple products into a code
900
library, all of whose files start with "L".  The file los.h formerly
901
many system-specific macros and definitions; these have been moved
902
into the OS files along with everything else.
903
904
oem.h
905
-----
906
907
This file defines information about the person who built a particular
908
version ("OEM" for "Original Equipment Manufacturer").  Refer to oem.h
909
for details about how to set up the definitions there.
910
911
912
osxxx.h, os.h, and osifc.h
913
--------------------------
914
915
The first thing to do when starting a new port is to create a new
916
system-specific header file for your platform.  You should choose a
917
name for the header based on your platform name; for example, on DOS,
918
the file is osdos.h, and on Unix it's osunix.h.
919
920
Next, you must define a C preprocessor macro that will identify your
921
platform.  This macro will be used to select the appropriate code to
922
include in your version of TADS, using #ifdef preprocessor directives
923
in the TADS code.  Many compilers automatically pre-define a symbol
924
for this purpose, in which case you should use this symbol;
925
otherwise, make up a symbol of your own and define it on the C
926
compiler command line or equivalent when you compile the TADS C files.
927
928
Edit the file os.h.  This is a "switchboard" file that selects an
929
appropriate system-specific header to include.  The TADS portable C
930
files #include os.h, and os.h must in turn #include your header file.
931
You should add a few lines to os.h to #include your header; follow
932
the example of DOS, Unix, and the other platforms:
933
934
#ifdef FROBNIX_OS
935
/* Frobnix operating system definitions are in osfrob.h */
936
#include "osfrob.h"
937
#endif
938
939
You shouldn't add anything else to os.h - the rest of your code should
940
go in your own "osfrob.h" file.
941
942
Now you must write the code in your OS-specific header ("osfrob.h" in
943
the example above).  To do this, refer to osifc.h, which defines the
944
TADS Operating System Interface, which is what you must implement for
945
your machine.
946
947
The purpose of your osxxx.h is to isolate certain platform-specific
948
definitions to a well-defined location in the code.  The rest of the
949
TADS C code is written so that it uses the definitions in osxxx.h;
950
this way, the other code doesn't have to be changed when moving TADS
951
to a new platform.
952
953
The file osifc.h contains the specification and documentation of the
954
TADS Operating System Interface, which contains the portable
955
interface definitions for functions, types, and macros that must be
956
tailored to each platform.  osifc.h contains a portable interface to
957
code that varies by platform; because the interface is portable, the
958
rest of the TADS code doesn't have to know anything about different
959
platforms, since it can expect the exact same functions to be
960
available on every machine.  osifc.h contains only portable code, so
961
you shouldn't make any changes in this file.
962
963
You can probably take one of the existing osxxx.h implementations as
964
a starting point, depending on your hardware and operating system.
965
For example, for a 68000 or 68000-like processor, you might want to
966
start with the Macintosh header (osmac.h), since the alignment and
967
byte ordering macros will be appropriate.  For an 8086-like
968
processor, start with the DOS headers (os.h and los.h).  Other
969
platforms may need additional work.
970
971
IMPORTANT NOTE: Do not make changes in osifc.h - this file should never
972
contain any #ifdef's for different platforms, because it defines a
973
portable interface that is the same everywhere, even though the
974
implementation of the interface varies by platform.  In particular,
975
the #define constants (OS_EVT_xxx, SYSINFO_xxx, and so on) MUST be the
976
same on all platforms, because some of these values can be used
977
programmatically by TADS games; a game can be compiled on one platform
978
and run on any other machine, so these constant values must be the same
979
everywhere for games to work properly.
980
981
982
Datatype configuration
983
----------------------
984
985
TADS makes relatively few assumptions about datatype sizes.  TADS
986
expects that shorts are at least 16 bits, ints are at least 16 bits,
987
and longs are at least 32 bits.
988
989
990
System-specific function implementation
991
---------------------------------------
992
993
Depending on your platform, you may be able to re-use some code that
994
was originally written for the DOS platform, but works with some
995
minor changes on other types of machines as well.
996
997
The files osdos.c, osgen.c, and osnoui.c provide an implementation of
998
the system routines for DOS.  osgen.c and osnoui.c should be usable
999
on any system with DOS-like display characteristics.  Note osgen.c
1000
and osdos.c check to see if several USE_xxx preprocessor symbols are
1001
defined; these macros are NOT defined anywhere in the source, but are
1002
to be defined by the makefile.  On DOS, these os files are compiled
1003
multiple times with different combinations of the USE_xxx symbols to
1004
produce different object files for linking the compiler and run-time.
1005
1006
A stdio (C run-time library "standard input/output") implementation
1007
of many of the routines can also be selected by defining the
1008
preprocessor symbol USE_STDIO.
1009
1010
The file osnoui.c is similar in purpose to osgen.c.  The functions
1011
implemented in osnoui.c are semi-portable implementations of functions
1012
that have no user interface component ("no UI").
1013
1014
1015
Building the system
1016
-------------------
1017
1018
TADS consists of three main pieces: the compiler, the run-time, and
1019
the debugger.  Refer to the DOS makefile to see which object files
1020
are included in each.  Note that it may not be possible to let a
1021
librarian/archiver resolve the links for all symbols, because a few
1022
of the object files provide overlapping sets of symbols -- it is
1023
necessary to manually include such object files in the links.  (The
1024
overlapping symbol sets are generally used to provide empty
1025
definitions for certain functions that are referenced but not
1026
actually used by one executable, but must be fully implemented in
1027
another.)
1028
1029
1030
Debugger
1031
--------
1032
1033
The debugger diverges somewhat from the convention of keeping the
1034
os-dependent functions in a file prefixed by "os" or "los".  The
1035
debugger's user interface is implemented in the file dbgu.c on DOS,
1036
and dbgumac.c on Macintosh.  The DOS version also has a file, osdbg.c,
1037
which provides lower-level functions; it should be possible to port
1038
the debugger to a new platform by using the DOS user interface and
1039
replacing only osdbg.c with an appropriate set of functions for the
1040
new system.  However, for any system without DOS-like display and
1041
input device characteristics, the entire user interface will usually
1042
need to be replaced; for example, on the Mac, dbgu.c is not used at all,
1043
but is replaced by dbgumac.c.  This separation of the user interface
1044
provides maximum flexibility for the debugger's user interface while
1045
minimizing the amount of work to port it to a new platform.
1046
1047
1048
Testing
1049
-------
1050
1051
The first test is to build a run-time and see if it can run games
1052
compiled on another system.  The second is to build the compiler, use
1053
it to compile game on your system, and see if that runs.
1054
1055
You can further test using the regression tests.  Compile DEEP.T,
1056
then run tr like this:
1057
1058
      tr -i dsdwalk.in -l dsdwalk.new deep
1059
1060
Then compare dsdwalk.new (the new log generated by your version of
1061
DEEP) with dsdwalk.log (the reference version) -- if they're
1062
identical, your system is probably in pretty good shape.  You can
1063
test similary with DITCH.T and DDDWALK.IN, and BUGS.T and BUGS.IN.
1064
1065
1066
MS-DOS and Windows Compilation
1067
------------------------------
1068
1069
Two makefiles are provided for compilation on MS-DOS and Windows
1070
machines; both makefiles are in the msdos directory.  To avoid
1071
confusion, these makefiles build object files into separate
1072
directories, and name their executables differently from one
1073
another.
1074
1075
makefile.bc is for compilation with the 16-bit Borland C compiler,
1076
version 4.5.  With this makefile, you can build the real-mode and
1077
protected-mode 16-bit DOS executables.  (You'll need the Borland
1078
Power Pack for DOS in order to build the protected-mode versions
1079
of the executables.)
1080
1081
Note that you should run makefile.bc with Borland make.
1082
1083
makefile.bc compiles into objs (for real-mode object files) and xobjs
1084
(for protected-mode object files), and generates the following
1085
executables:
1086
1087
    tc.exe       - real-mode TADS compiler
1088
    tr.exe       - real-mode TADS run-time
1089
    tdb.exe      - real-mode TADS debugger
1090
    tcx.exe      - 16-bit protected-mode TADS compiler
1091
    trx.exe      - 16-bit protected-mode TADS run-time
1092
    tdbx.exe     - 16-bit protected-mode TADS debugger
1093
    maketrx.exe  - single-file executable binder
1094
    tadsrsc.exe  - TADS resource manager
1095
    trcolor.exe  - run-time color picker
1096
1097
makefile.vc5 is for Microsoft Visual C++ version 5.0.  VC++ 5.0
1098
can only perform 32-bit compilations, so this makefile builds only
1099
32-bit versions of the executables.  Note that this makefile builds
1100
the two TADS libraries that are required for building HTML TADS:
1101
tr32h.lib (the TADS run-time 32-bit Windows library for HTML) and
1102
tdb32h.lib (the TADS debugger 32-bit Windows library for HTML).
1103
1104
You should run makefile.vc5 with Microsoft nmake.
1105
1106
makefile.vc5 compiles into winobjs32 (for 32-bit Windows object files),
1107
and generates the following executables:
1108
1109
    tc32.exe       - TADS compiler 32-bit Windows console application
1110
    tr32.exe       - TADS run-time 32-bit Windows console application
1111
    tdb32.exe      - TADS debugger 32-bit Windows console application
1112
    maketrx32.exe  - executable binder 32-bit Windows console application
1113
    tadsrsc32.exe  - TADS resource manager 32-bit Windows console application
1114
    trcolor32.exe  - run-time color picker 32-bit Windows console application
1115
1116