Microsoft C to Borland C++
Conversion Guide
BORLAND INTERNATIONAL, INC.  1800 GREEN HILLS ROAD
P.O. BOX 660001, SCOTTS VALLEY, CA  95067-0001


Copyright 1992 by Borland International. All rights
reserved. All Borland products are trademarks or registered trademarks
of Borland International, Inc. Other brand and product names are
trademarks or registered trademarks of their respective holders.



If you're an experienced C or C++ programmer, but the Borland C++
programming environment and tools are new to you, then you should read
this section before you do anything else. We appreciate that you want
to be up and running fast with a new piece of software, and we know
that you want to spend as little time as possible reading manuals.
However, the time that you spend reading this section will probably
save you a lot of time later. Please read on.

Why Should You Use Borland C++, Anyway?
You may have become accustomed to using Microsoft C over the years. If
you were developing for the Windows environment in the past, Microsoft
C and the SDK were the only game in town. And maybe you are a little
skeptical that a newer product is superior to an old standby.

Compared to the Microsoft development environment, Borland C++ is a
real time saver from the moment you install it until you have debugged
your program. For most typical applications, a program compiled with
Borland C++ executes faster than when compiled with Microsoft C. The
Borland C++ environment provides you with more and better supporting
tools than Microsoft's, tools that are easier to use and that save you
many hours of time during your software development cycle. The time
that you save enables you to develop richer and better software
faster, and helps your company to remain competitive no matter what
its line of business may be.

Let's cover these areas in greater depth.

Installation.
There is one and only one installation program for Borland C++, and it
sets up all of the Borland C++ tools and resources in a single highly
integrated directory structure.

By contrast, you need to install several sets of software to be
productive with Microsoft software development products. If some of
your software is written in assembly language, you need to buy the
Microsoft Assembler separately, and install it on your system. If you
are writing software for Windows, first you must install Microsoft
C6.0a, then pick and choose the tools, libraries, and header files
from the Microsoft Windows SDK and decide where to install them. The
installation of the Microsoft Windows SDK is a manual process with
nothing to guide you or protect you from making a clerical error.

Once you have installed Borland C++, you will realize its built-in
productivity benefits. Rather than setting up INCLUDE and LIB
environment variables, you tell the Borland C++ Integrated Development
Environment (IDE) where your include files and libraries are, and the
IDE does all the rest.

PreCompiled Headers.
By making good use of extended memory, using precompiled headers, and
embodying other advanced compiler technology, Borland C++ compiles
programs lightning fast even when all of the code optimization options
and warning messages are enabled.

In a typical comparison of compilation speeds MAKEing a widely
distributed Windows application of moderate size, Borland C++ produced
an .EXE file in 46 seconds while the Microsoft tools did it in 146
seconds, over three times as long. The program consisted of 12 C
modules that contained 11000 source lines and 3 assembly language
modules totaling 1000 lines plus all of the required header and
include files. All possible compiler optimizations were enabled for
this comparison. The test PC was a 33MHz 80486 with 16MB of memory and
a SCSI hard disk with a 12 millisecond seek time.


Integrated Environments.
The Borland C++ IDE is quicker than PWB, which swaps to disk rather
than using expanded or extended memory. It is much quicker and easier
to edit several source files at once with the IDE.

Turbo C++ for Windows is a complete Windows-based system that allows
you to edit, compile, test and debug Windows applications while
remaining entirely within the Microsoft Windows environment. The Turbo
C++ for Windows program editor has a contemporary SpeedBar for
point-and-click action on common editing functions. Borland C++
project files are interchangeable between Turbo C++ for Windows and
the IDE, allowing you transparent use of the environment that suits
your needs at a given moment.


Debugging.
The Turbo Debugger (TD) user interface is more intuitive to use than
CodeView's, which retains many of the artifacts of its SYMDEB command-
oriented predecessor. TD has commands to search memory for
instructions or data elements, useful for debugging programs without
source code or sometimes even with the source code. TD can be loaded
resident to debug Terminate-and-Stay-Resident (TSR) programs. You can
debug a program running in one PC remotely from another PC in cases
where the run-time environment of a target program requires the
maximum amount of available memory. Remote debugging with TD is
possible via either a serial port or across a local area network
(LAN). TD has companion driver modules which enable hardware-level
debugging using the 386 debug registers.

Turbo Debugger for Windows runs inside Windows and allows you to debug
Windows programs using a system with only a single monitor. When
invoked, it saves the Windows screen context, displays debugging info,
then switches back to Windows. CodeView requires two monitors for
debugging, typically a color monitor for Windows and a monochrome
monitor to display debugging info. CodeView has none of the other
features above, though in some cases an expensive add-on product
provides them.

Optimizations.
Borland C++ gives you greater control over how the compiler optimizes
your program with 13 independent classes of code optimizations. You
can select the best combination of optimizations for your application,
trading off execution speed and program size. Microsoft has just as
many optimizations, but it is often not clear whether or not they
overlap one another until you have experimented with the various
choices.

Borland C++ provides in-line code generation for 19 frequently used C
functions, Microsoft C for an indeterminate number. An in-line
function often generates more code than a function call does, but it
executes much faster than library function calls, especially on 386
and 486 PCs with CPU cache memory.

Ansi Standard.
Borland C++ is fully compliant with the ANSI C specification and
incorporates the latest C++ 3.0 draft specification. Compiling with
Borland C++ gives you extensive warning diagnostics, many of which
tell you things about your program that even a commercial LINT program
will not. Using these diagnostics, you can spot a problem area and
change your program before debugging it, often avoiding long debugging
sessions.


Development Tools.
Borland C++ is a complete development environment that includes many
productivity tools which are not part of Microsoft C. If you ever want
to search a group of source files to find occurrences of the same or
similar strings of text such as variable or function names, the
Borland C++ UNIX-style GREP program will do the job.



Resource Workshop
For Windows development, the Resource Workshop is a single one-stop
utility that integrates into a coherent hierarchy all of the Windows
resources for a program, and allows you to conveniently edit, add, or
delete any Windows resource from your program. It even allows you to
edit the resources in an .EXE version of a program, a feature that is
extremely useful for creating national language versions and for doing
special customizations.



Turbo Profiler
The Turbo Profiler allows you to profile Windows and non-Windows
programs alike, and to isolate time-consuming hot spots in the code. 
It measures the exact amount of time spent by your application on a
function-by-function basis, or for each single statement executed by
your program.



Other tools
The H2ASH utility generates assembly language structures from C or C++
header files, allowing you to easily keep C and assembly modules in
sync. The TOUCH utility updates the file system date for a file or a
set of files, so you can easily trigger an operation across a group of
files such as a file backup or a program make. The OBJXREF program
generates a cross-reference of global functions and variables used
within object files and libraries, so you can see at a glance the
relationship between function definitions and calls or among usages of
global variables.


Class Libraries.
The Object Windows Library (OWL) is a C++ class library containing the
classes used to program user interfaces for Windows applications.
Turbo Vision is a similar library for DOS-based applications. Finally,
the Borland C++ class libraries consist of reusable software to manage
many objects used every day by programmers: sorted arrays, btree
structures, linked lists, queues, hash tables, stacks, strings, and
the PC hardware timer. Borland C++ includes the source code for most
of these libraries, so that if you need to better understand how a
function works, or if you want to derive a similar function, you can
readily do so.

These are the many reasons why you should use Borland C++. As you use
it more, you will surely find some more reasons yourself.


Here is a summary to give you a quick start in getting your Microsoft
C program running with Borland C++.

1) Make sure your programs compile and run correctly with Microsoft C.
There is no need to confuse things by converting programs that do not
already work. If you do so, and something goes wrong, you won't know
whether there was a bug in the original program, or the problem arose
during the conversion process.

2) Start up the Borland C++ IDE (Integrated Development Environment) and
open a new project, giving it the same name as your compiled program.

3) Select Borland C++ Keywords in the Options|Compiler|Source menu item
of the IDE.  This option tells the compiler to recognize the Borland
C++ extension keywords, including near, far, huge, asm, cdecl, pascal,
interrupt, _es, _export, _ds, _cs, _ss, and the register
pseudovariables.

4) Now, add to the project the names of all of the C source (.C) files
and .ASM modules for any assembly language functions you may have. If
you are writing a program for the Windows environment, add .RC and
.DEF files to the project as well. The Borland C++ IDE automatically
keeps track of the other dependencies involving .H header files, .BMP
bitmap files, .ICO icon files, .CUR cursor files, and assembly
language include files.

5) Turn on all warnings with the Options|Compiler|Messages menu item or
with the -w command line option.

6) Compile each module without any optimizations enabled.

7) Any compiler warnings generated by Borland C++ will alert you to
potential pitfalls. These catch many subtle programming errors
otherwise not found until you debug your program. Try to figure out
why the warning was generated. You might try to add ANSI function
prototypes and explicit typecasts whenever you are in doubt about the
correctness of the executable program.

8) If you have any C-callable functions written in assembly language,
refer to the brief discussion later on about C functions written in
assembly language.

9) Test your program, referring to the information and the sample
programs in the following sections. They explain and illustrate the
differences between Microsoft C and Borland C++ in detail.

10) Finally, when your program is fully operational, recompile it with the
required code optimizations enabled, and test again.

11) If you want to compile your program from the command line rather than
with the Borland C++ IDE, generate a Borland make file with the
PRJ2MAK utility.


This set of steps is not exhaustive and it does not cover every
possibility that might arise when converting Microsoft C programs, but
it is a reasonably complete set of guidelines for you to follow.

Compatibility

Borland C++ supports the same set of keywords as Microsoft C 5.1 with
the exception of fortran. Borland C++ also supports the same set of
keywords as Microsoft C 6.0 with the exception of:

   -_based, _self, and _segname, because Borland C++ does not support
     based pointers

    - Borland C++'s keyword _seg is the equivalent of the Microsoft keyword
     _segment

_emit; Borland C++ uses the pseudofunction _ _emit_ _, because this
style allows addresses of variables to be given as arguments, and
allows multiple bytes to be output; _emit, by contrast, works like an
assembly DB, allowing one immediate byte to be output. If your program
uses the Microsoft _emit, add the following statement to your program
after the including dos.h:

#define _emit(b) _ _emit_ _ (b)

_fortran; use the _pascal calling convention instead

Borland C++ provides _cs, _ds, _es, and _ss pointer types. See the
section "Mixed model programming: Addressing modifiers" in the Borland
C++ Programmers Guide for more information.

If your program uses the fortran calling convention for functions, you
can use the pascal calling convention instead. If you have many
fortran functions in a source module, you might find it convenient to
add the following statement just before all of the header declarations
in your source code module:

#define fortran _pascal

However, pay attention to the differences between Microsoft C and
Borland C++ in the scheme for passing floating point arguments,
especially if your fortran function is written in assembly language.

The __MSC macro
If your Microsoft C program uses the DOSERROR structure, then, and
only then, you need to add the definition of the _ _MSC macro to your
program to preserve compatibility with the Microsoft variable names
used within DOSERROR.  In previous versions of Borland C++, you needed
to incorporate the _ _MSC macro to use many Microsoft C DOS and BIOS
functions. The statement

#define _ _MSC
needs to appear before the statement

#include <dos.h>

to use the Microsoft DOSERROR variable names.

The Header Files
You can use either the old Microsoft header file name or the
equivalent Borland C++ header file name according to the following
table:

    Original        Alias
	alloc.h	        malloc.h
	dir.h  	        direct.h
	mem.h  	        memory.h

A Memory Model Overview
Although the same names are used for the six standard memory models,
there are some fairly significant differences in memory allocation for
the large data models in the standard memory configurations.

In Microsoft C, all large data models (compact, large, and huge) have a
default NEAR data segment to which DS is maintained. Data is allocated
in this data segment if the data size falls below a certain threshold,
or in a far data segment otherwise. You can set the threshold value with
the /Gtn option, where n is a byte value. The default threshold is
32,767. If /Gt is given but n is not specified, the default is 256.

In the other three memory models (tiny, small, and medium) under
Microsoft C, both a near and a far heap are maintained.

In Borland C++, the large and compact models but not the huge model have
a default NEAR data segment to which DS is maintained. All static data
is allocated to this segment by default, limiting the total static data
in the program to 64K, but making all external data references near.

In Microsoft's version of the huge memory model, a default data segment
for the entire program is maintained which limits total near data to
64K. No limit is imposed on array sizes since all extern arrays are
treated as huge (_huge).

In Borland C++'s huge memory model, each module has its own data
segment. The data segment is loaded on function entry. All data defined
in a module is referenced as near data and all extern data references
are far. The huge model is limited to 64K of near data in each module.

A command line compiler option, -Fs, and integrated environment dialog,
Options|Compiler, are available to allow the Borland C++ compiler to
assume that DS is equal to SS in all memory models. You can use it when
porting code originally written for Microsoft C that makes the stack
part of the data segment.  When you specify this option, the compiler
will link in an alternate startup module (C0Fx.OBJ) that will place the
stack in the data segment.  Usually the compiler assumes that SS is
equal to DS in the small, tiny and medium memory models (except for
DLLs).

The details of memory management functions, and the differences between
Microsoft C and Borland C++ in this area, are covered in the discussion
of MALLOC.H below and in the following section entitled "Converting
Microsoft DOS Memory Management Functions".

Constants and COMDEFs
Defining data in the header files in your program can cause duplicate
symbol errors at link time if the same header file is compiled into
multiple modules.  Microsoft C generates communal variable (COMDEF)
records in the .OBJ files for global data allowing the linker to map
duplicate global data to the same storage location.

Borland C++ also supports COMDEF generation with the -Fc command-line
option. -Fc tells the compiler to generates COMDEFs for global "C"
variables that are not initialized and not declared as static or extern.
So long as a given variable doesn't need to be initialized to a nonzero
value, you don't need to include a definition for it in any of the
source files.


                      Some Conversion Hints

Use Portable Functions

Portable functions are those compatible with many different compilers
and machines. Generally they are ANSI standard functions. Whenever
possible, use only functions from the ANSI standard library (for
/example, use time instead of gettime). The portability boxes in the
Borland C++ Library Reference Manual will tell you if a function is ANSI
standard.

If you must use a function that's not in the ANSI standard library, use
a Unix-compatible function, if possible (for example, use chmod instead
of _chmod). Again, the portability boxes in the Borland C++ Library
Reference Manual will tell you if a function is available on Unix
machines.

Use Function Prototypes

Write function prototypes for all functions that do not yet have them.
Function prototyping was added to the ANSI C standard to help you find
subtle logic errors quickly. But you have to use function prototypes for
them to help you.


Avoid Machine Dependencies

Avoid the use of bit fields and code that depends on word size,
structure alignment or memory model. For example, Borland C++ defines
ints to be 16 bits wide, but a 32-bit C++ compiler would define 32-bit
wide ints.

Use ANSI standard manifest constants to refer to the various values and
arguments used by standard C functions. More generally, use manifest
constants to define constant values rather than sprinkling your program
with hard-coded "magic numbers".

DOSERROR
If you use the DOSERROR structure in a source module, insert the
preprocessor statement
 #define _ _MSC
 before dos.h is included.

/STACK Linker Option
If you were using the link option /STACK:n in your Microsoft C
application, initialize the global variable _stklen with the appropriate
stack size.


            Source Program Conversion - Header by Header

Borland C++ provides far-reaching source language compatibility for DOS
and Windows programs written with Microsoft C Version 6.0a. The
exceptions consist of nonstandard functions and manifest constants that
are not often used. As a result, you should be able to compile almost
any Microsoft C6.0a source program with few source code changes, if any,
and have it working quickly with Borland C++.

The number of exceptions where you need to make source code changes are
listed below in alphabetical order arranged by Microsoft C header file
name, along with suggestions and examples for how to treat them.  If a
Microsoft C header file is not listed here, this means that there are no
known issues with its compatibility between Microsoft C6.0a and Borland
C++. Eighteen of the 33 header files shipped with Microsoft C6.0a and
the Microsoft Windows Software Development Kit (SDK) are fully
compatible with Borland C++.

The functional areas of C that require the greatest number of changes
are memory management and graphics. If your Microsoft C6.0a programs
make extensive use of functions in these areas, refer to the more
lengthy sections that follow. They compare the Borland C++ and Microsoft
C approaches, contain programs that guide you through a successful
conversion, and compare functionally equivalent Microsoft C programs
side by side.

CTYPE.H
The manifest constants defined in the header files and used in the
various ctype functions are different between MSC6.0 and Borland C++. As
long as you use the portable ctype macros, this should present no issue.
If your program uses only the portable ctype macros, rather than
referring to the ctype manifest constants, it will behave the same with
either compiler.

If your program does refer directly to the Microsoft C ctype manifest
constants, add any of the following #defines as appropriate: 

#define	_UPPER	_IS_UPP	/* upper case letter */
#define	_LOWER	_IS_LOW	/* lower case letter */
#define	_DIGIT	_IS_DIG	/* digit[0-9] */
#define	_SPACE	_IS_SP	/* tab, carriage return, newline, */
			/* vertical tab or form feed */
#define	_PUNCT	_IS_PUN	/* punctuation character */
#define	_CONTROL	_IS_CTL	/* control character */
#define	_HEX	_IS_HEX	/* hexadecimal digit */

Borland C++ has no equivalent for the _BLANK manifest constant used
within the Microsoft C version of the isprint macro. The following
program shows how to define and use a portable isblank macro to test for
a blank space. This is much better than using _BLANK.

/* ISBLANK.C illustrates use of the portable character classification
 * function isblank.
 */

#include <ctype.h>
#include <stdio.h>
#define isblank(_c)  isprint(_c) && !isgraph(_c)

void main()
{
    int ch;

    /* Display the blank character. */
    for( ch = 0; ch < 256; ch++ )
    {
    if (isblank(ch))
    printf ( "The value 0x%.2x is a blank space.\n", ch );
    }
}

When compiled and run with either compiler, ISBLANK.C displays one line
of text, "The value 0x20 is a blank space."

The Microsoft C6.0a ctype header also contains two undocumented macros
useful primarily for the language syntax checking done by a C compiler:
iscsym and iscsymf.

DOS.H
If your Microsoft C6.0a program uses the dosexterror function and its
associated DOSERROR structure and variable names, add the following
statement to your program to define the DOSERROR structure according to
Microsoft C conventions:
 #define __MSC


ERRNO.H
The numeric values of the manifest constants for many of the error codes
returned in the global variable errno differ between the Borland C++
errno.h and its Microsoft C6.0a counterpart. Many of these manifest
constants are present to provide compatibility with UNIX. As long as
your program refers to error codes using the manifest constants
themselves, rather than any numeric values, it will behave the same with
either compiler. The following pair of short code fragments illustrates
this point, and underscores the role of standard C manifest constants in
making programs portable: 

/* ERRNO.H Example 1 - This example IS NOT portable */
  int ThisError;
  ThisError = errno;
  if (ThisError == 7)
    /* When reporting that an argument list that is too long,
       the Microsoft C run-time library assigns value of 7
       to the error code, while Borland C++3.0 run-time
       library assigns a value  of 20. */
    printf("Arg list too long");


/* ERRNO.H Example 2 - This example IS portable */
  int ThisError;
  ThisError = errno;
  if (ThisError == E2BIG)
    /* When reporting that an argument list that is too long,
       the manifest constant value E2BIG is returned by both
       Microsoft C6.0a and Borland C++3.0. */
    printf("Arg list too long");

FCNTL.H
The Borland C++ header file does not define the older UNIX manifest
constant O_RAW. If your Microsoft C program uses it, add the following
statement to your program after including fcntl.h:

#define  O_RAW  O_BINARY


FLOAT.H
Between Borland C++ and Microsoft C6.0a, there are very minor
differences in the values of some of the double precision (DBL_...) and
floating point (FLT_...) manifest constants that specify the limits of
computations. If your program explicitly references any of these
constants, make extra sure to verify that it produces the expected
results with Borland C++.

Also, some 8087/80287 status word subconditions (SW_...) and floating
point error signals (FPE_...) are defined as manifest constants in the
Microsoft C header, but not in the Borland C++ header. If your program
uses any of these manifest constants, add them to your program source
code with #defines.


GRAPH.H
The Borland C++ Borland Graphical Interface (GRAPHICS.H) is quite
different from the low-level graphics library supplied with Microsoft C,
although the respective functions show a general one-to-one
correspondence. If your programs currently use Microsoft's GRAPH.H, see
the following section entitled "Converting Microsoft DOS Graphics
Functions" for more details and examples.


LOCALE.H
The manifest constants LC_MIN and LC_MAX are not in the Borland C++
locale.h header file. If you use them in your Microsoft C6.0a program,
add the following prior to compiling with Borland C++:

#define  LC_MIN  LC_ALL
define  LC_MAX  LC_TIME


MALLOC.H
The Borland C++ memory management functions differ somewhat from the
memory management that is part of Microsoft C6.0a. If your programs
currently use Microsoft's MALLOC.H, see the section entitled "Converting
Microsoft DOS Memory Management Functions" for a comparison between the
two memory management facilities and some practical examples of
Microsoft C6.0a programs, before and after conversion to Borland C++.

If your programs rigorously use only the ANSI standard C memory
allocation functions, it is unlikely that you will have any difficulty
recompiling and running your programs with Borland C++. If you use the
DOS-specific memory management functions provided by Microsoft C, then
you will have to take some care in converting your programs.


MATH.H
Older versions of Microsoft C used a 6-byte floating point format that
predated the standard IEEE format. Microsoft C6.0a provides a set of
functions to convert data between Microsoft's old format and the IEEE
format. These functions are typically used for converting data files
from one format to the other. Borland C++ does not support the
proprietary Microsoft floating point format. Use the standard IEEE
format instead, and convert all of your data files to IEEE format.

Borland C++ does not provide the Bessel functions of the first and
second kinds which are available in the Microsoft C6.0a run-time
library: j0, j1, jn, y0, y1, yn, _j0l, _j1l, _jnl, _y0l, _y1l, and _ynl.

PGCHART.H
Borland C++ does not include functions to display presentation graphics,
a library added to Microsoft C with Version 6.0a.

PROCESS.H
The Microsoft 6.0a functions wait is not in the Borland C++ header file.
wait is a function available under UNIX.

SIGNAL.H
The Borland C++ header file does not define SIGUSR1, SIGUSR2, and
SIGUSR3, manifest constants for user signals contained in Microsoft
C6.0a. If your program uses them, you need to define them yourself prior
to compiling with Borland C++.

STDDEF.H
The Borland C++ header file does not define the errno variable, as does
Microsoft C6.0a. Instead the function prototype for errno is in
Borland's errno.h, so add the following to your program:

#include <errno.h>

The function prototype for errno is also compiled conditionally by the
dos.h and stdlib.h headers.


STDIO.H
If your program uses the high-level functions defined in this header
file, your Microsoft C6.0a programs will compile and run with no
changes. You need to be aware of a few things, however, if your program
accesses any of the low-level elements defined in the Microsoft stdio.h
header:

The Microsoft manifest constant, _NFILE, defines the maximum number of
files that your program can have open at one time. Replace all
references to _NFILE with references to the Borland C++ equivalent,
FOPEN_MAX. Better still, add the following statement to your program
after #include'ing stdio.h:
 #define  _NFILE  FOPEN_MAX

If your program does the low-level stream I/O table manipulations
typically found in older K&R-style C programs, then all references to
the Microsoft C6.0a array, _iob[], need to refer instead to the Borland
C++ array, stream[]. The simplest solution is to add the following
statement to your program:
#define  _iob  stream

The Microsoft C high-level macros getc and putc use the undocumented
low-level _filbuf and _flsbuf functions, respectively.  As long as your
programs use only high-level portable stream I/O functions, this is not
a problem.

STDLIB.H
If your program uses the function perror defined in the Microsoft C6.0a
version of stdlib.h, add the following statement which adds the function
prototype definition for the Borland C++ perror:
#include <stdio.h>
Note that the ANSI standard defines the perror function in STDIO.H and
not STDLIB.H.

If your program uses the proprietary Microsoft function, onexit, replace
all occurrences with the ANSI standard function, atexit. The easiest way
to do this is with a single statement that makes the substitution with
the C macro preprocessor:
#define  onexit  atexit

TIME.H
The manifest constants CLOCKS_PER_SEC and CLK_TCK have different values
for Microsoft C6.0a and Borland C++. If you use the defined macros then
no source code change is required. If your program depends on the
specific value, either redefine them with the Microsoft C values, or
change your program to use the Borland C++ values.




         Assembly Language Functions Called by C Programs


The conventions for passing arguments to functions on the stack are
compatible between Borland C++ and Microsoft C6.0a for equivalent memory
models (tiny, small, medium, large, compact, huge), and equivalent
function types (near, far, cdecl, pascal, or _farcall). But there are
some differences in the handling of return values by the compilers and
these may require changes to your assembly language functions. These
details are important for assembly language functions, but somewhat
transparent for functions written in C. When your C function and your
calling program are written, the Microsoft C and Borland C++ compilers
adjust automatically for these differences in handling return values.

Structures Returned By Value

In a Microsoft C function declared with _cdecl, the function returns a
pointer to a static location. This static location is created on a
per-function basis. For a function declared with _pascal, the calling
program allocates space on the stack for the return value. The calling
program passes the address of the return value in a hidden argument to
the function.

Borland C++ returns 1-byte structures in AL, 2-byte structures in AX and
4-byte structures in AX and DX. For 3-byte structures and structures
larger than 4-bytes, the compiler passes a hidden argument (a far
pointer) to the function that tells the function where to return the
structure.

Integer Return Values.
Microsoft C and Borland C++ are compatible in their conventions for
returning simple integer variables. They return 1-byte variables (char)
in AL, 2-byte variables (int, short, and near) in AX and 4-byte
variables (long and far) in AX and DX.

Floating-Point Return Values.
In Microsoft C, _cdecl causes float and double values to be returned in
the _ _fac (floating point accumulator) global variable. Long doubles
are returned on the NDP stack. _fastcall causes floating point types to
be returned on the NDP stack. _pascal causes the calling program to
allocate space on the stack and pass an address to the function. The
function stores the return value and returns the address.

In Borland C++, floating point values are always returned on the NDP
stack.

Rules for EXTERNs and External Symbols
Borland C++ applies different rules than Microsoft C6.0a for generating
external symbols for the Turbo Linker, depending on whether the function
type is cdecl (default) or pascal. For cdecl functions, the rule is C
function_name --> _function_name, i.e. function name retains its case
and the underbar character is prefixed to it. For pascal functions, the
rule is C function_name --> FUNCTION_NAME, i.e. function name simply
transformed to upper case. In general, you would use pascal functions
only in Windows programs.

The following set of changes to your assembly language source code
should deal with many compatibility issues between Borland C++ and
Microsoft C: (See the Turbo Assembler User's Guide and Programmer's
Guide for more information.)

1. Add the following directives at the beginning of your program to tell
the Turbo Assembler (TASM) how to deal with Microsoft assembler (MASM)
compatibility: 

	ifdef	??Version	; defined only by TASM
	MASM51		; MASM 5.1 compatibility
	QUIRKS		; assemble with MASM quirks
	endif

2. If your functions written in assembly language use the MASM .MODEL 
directive for standard segmentation, then your functions will take the 
form:  (The TASM MODEL directive is the equivalent of .MODEL.)

	public	_asm_func
_asm_func	PROC	FAR USES SI DI DS, ASMARG:WORD

Change this to:
	public	ASM_PROC
ASM_PROC	PROC	FAR USES SI DI DS, ASMARG:WORD

3. Similarly, if your assembly language functions use older style 
segmentation, then your functions will take the form:

	public	_asm_func2
_asm_func2	PROC
	<executable statements>
_asm_func2	ENDP  

Change this to:  
 
	public	ASM_FUNC2
ASM_FUNC2	PROC
	<executable statements>
ASM_FUNC2	ENDP

4. Far more preferable to the approach in item 3 above, modify your
programs to use the TASM MODEL directive and the extended PROC syntax
shown in item 2 above. The benefit of the extended PROC is that the all
details of passing arguments and returning values are managed
automatically by TASM, and you need not concern yourself with them.



        Converting Microsoft DOS Memory Management Functions

C programs written for the conventional MS-DOS environment rely on the
Intel segmented architecture to access data on the heap. The Intel
segmented architecture limits to 64K bytes the amount of data that can
be accessed with one setting of a segment register. It also forces an
arbitrary division between the near heap and the far heap.

The near heap is the heap space available in the default data segment
after static and stack data have been allocated. The far heap consists
of the remaining available conventional DOS memory after a program is
loaded and its code, data, stack, and near heap space are allocated.
Borland C++ and Microsoft C have slightly different but quite compatible
heap manager implementations to deal with the intricacies of segmented
architecture, but you need to convert Microsoft's non- standard heap
function calls to ANS or Borland C++ function calls.

Borland C++ memory management design and implementation are more robust
than Microsoft's. These are the advantages of Borland C++ memory
management:

When a Borland C++ program starts up, the Borland C++ memory management
functions treat all of the available conventional DOS memory as a single
free far heap block. When a Microsoft C6.0a program starts up, its heap
management run-time library normally allocates _amblksiz bytes of memory
as the initial free far heap space. The Microsoft global variable
_amblksiz has a default value of 8192 bytes.  Subsequently, the
Microsoft C6.0a heap manager adds _amblksiz bytes of memory to the far
heap whenever it has allocated all of the free far heap space and needs
to get more from DOS. If your program uses the heap in an extremely
dynamic manner, you will find Borland C++ memory management faster.

Borland C++ does not allocate memory blocks on the heap when a program
requests a block size of zero bytes. This is treated as an error
condition, because a heap allocation of zero bytes is logically
inconsistent with good programming practice. Microsoft C allocates a
heap block of zero bytes without indicating an error.

Borland C++ satisfies any single request for more than 64K bytes of heap
space if your program is compiled with an appropriate memory model,
compact, large, or huge. All of the far heap management functions
support huge heap blocks, those that are greater than 64K bytes in size.
Only the Microsoft C6.0a halloc and hfree functions allocate huge heap
blocks.

When a program releases a memory block from the heap, the Borland C++
heap manager cleans up free heap space. It also links together any free
heap blocks that are consecutive in memory to form a single larger free
heap block. This allows Borland C++ to reuse free heap space when your
program makes a subsequent heap allocation request. With Microsoft C
heap management, the free heap space remains fragmented, and it
sometimes does not get reused. If your program, compiled under Microsoft
C6.0a, allocates and deallocates memory very frequently, there is a
reasonable probability that it will be unable to obtain a memory block
to satisfy a memory allocation request.

Borland C++ allows your program to determine the status of free memory
on a heap. However, it does not allow you to examine the contents of
free heap memory, which is really not owned by your program. Microsoft C
permits you to examine the contents of free heap directly. But neither
memory management scheme can prevent your program from overwriting free
heap memory if a pointer goes astray.

The Microsoft C functions that expand the heap do not move heap blocks
in memory. The Borland C++ realloc functions sometimes relocate heap
blocks in memory to increase the probability that a request to grow a
heap block will be successful. As a rule, you should always make sure
that any pointers aliased to heap blocks are updated after a realloc
function.


Microsoft C Based Heaps
The nonstandard based heap feature was introduced initially by Microsoft
with Version 6.0 of Microsoft C. Borland C++ does not support based
pointers, and it has no function prototypes (function names _b...) for
using the based heap. You would typically use based pointers in a large
or huge memory model Microsoft C program to give you a faster method to
accessing data than using the far heap. If your Microsoft C program uses
based heap functions, you can take one of two possible courses of
action: 

1. Recompile your program with Microsoft C6.0a adding the following
statement at the beginning of your program:
        #define _MSC_VER 510

This directive forces the Microsoft C compiler to generate warning or
fatal error messages for all references to based heap functions and the
related elements _based, _segment, _self, and _segname. Replace the
based heap functions with comparable far heap functions, change all
references to _based pointers, remove all definitions of based variable
types, and check out your program for correct operation.  Finally,
recompile your program with Borland C++.

2. Compile your program with Borland C++, and replace all based heap
functions with borland far heap functions (farheap...), delete all
_segment variables, and change the references to _based pointers.  Now,
check out your program for correct operation.

Two sample programs, BASE_BEF.C and BASE_AFT.C, show you how to deal
with the Microsoft C6.0a based variable functions and constructs. 
BASE_BEF.C exercises the Microsoft based variable and based heap memory
management functions. BASE_AFT.C achieves the same end result by using
the Borland C++ farheap instead of the Microsoft based heap. These
programs are available for download (see the appendix for more details).


General Comparison of Heap Functions
The following sections contain a comparison of Microsoft C and Borland
C++ heap functions. Two sample programs MFARHEAP.C and BFARHEAP.C show
you how to convert from Microsoft C6.0a far heap calls to Borland C++
far heap calls.  MFARHEAP.C exercises the Microsoft far heap memory
management functions prefixed by the _f symbols. BFARHEAP.C achieves the
same end result by using the Borland C++ farheap functions. These
programs are available for download (see the appendix for more details).



heapadd functions.
The Microsoft heapadd functions, _heapadd and _bheapadd, expand the size
of the appropriate heap by requesting additional memory from DOS and
adding it to the threaded list used to manage heap space. Note that all
of these functions are non-portable and non-standard. When a Microsoft
C6.0a program starts up, the heap management run-time library normally
allocates _amblksiz bytes of memory, but less than the total amount of
unused DOS conventional memory. The default value for _amblksiz is 8192.
Subsequently, the Microsoft C6.0a heap manager adds _amblksiz bytes of
memory to the far heap whenever it has run out of free heap space.

Borland C++ has no corresponding heapadd functions because it manages
free heap space differently. When a program compiled with Borland C++
starts up, the heap management run-time library allocates all of the
unused DOS conventional memory as free far heap.

Recommended Action: Remove heapadd function calls, or insert the
following #define which causes the C preprocessor to ignore all
occurrences of the function call:
 
 #define _heapadd(a,b)

expand functions.
The Microsoft C6.0a expand functions, _expand, _bexpand, _fexpand, and
_nexpand, change the size of a previously allocated block of heap
memory. The size of a memory block may become either larger or smaller
as the result of a Microsoft C6.0a expand function. An expand function
does not move a block around in memory to make it larger. If an expand
function cannot increase the size of a heap block because the memory
above it is already allocated, it returns an error.

Borland C++ has no corresponding expand functions because it manages
free heap space dynamically, but the Borland C++ realloc functions,
realloc and farrealloc, perform a task similar to the expand functions.
These functions do relocate a heap block if required, so they are less
likely to fail to expand a heap block than the Microsoft C expand
functions.

Recommended Actions: Substitute realloc function calls for Microsoft
expand function calls, using realloc in place of either _expand or
_nexpand, and farrealloc in place of either _fexpand or _bexpand.  Since
realloc returns a pointer to the memory block, which may have been
relocated, you will also have to make sure that you always use the new
pointer value when referring to data in the reallocated heap block. If
possible, use the ANSI standard realloc function in preference to the
DOS-specific farrealloc.



heapchk functions.
The Microsoft C6.0a heapchk functions, _heapchk, _bheapchk, _fheapchk,
_nheapchk, check the consistency of an entire heap. With Microsoft C6.0a
memory management, there are three possible error conditions: the heap
header control area is invalid, the heap area is uninitialized, or a
heap node contains invalid data.

Borland C++ provides the heapcheck and farheapcheck functions that
accomplish the same objective as the Microsoft heapchk functions.  They
return only two error conditions: the heap area is uninitialized, and
the heap is corrupted.

Recommended Action: Substitute heapcheck function calls for Microsoft
_heapchk function calls, using heapcheck in place of either _heapchk or
_nheapchk, and farheapcheck in place of either _fheapchk or _bheapchk.
The sample programs MFARHEAP.C and BFARHEAP.C in the following section
entitled "Converting from Microsoft Heap Management to Borland C++ Heap
Management" show how this is done with a #define for _fheapchk.



heapmin functions.
The Microsoft C6.0a heapmin functions, _heapmin, _bheapmin, _fheapmin,
and _nheapmin, release unused heap memory to DOS.

Borland C++ has no corresponding heapmin functions because it manages
free heap space differently. See the discussion under heapadd Functions.

Recommended Action: Remove heapmin function calls or insert the
following #define which causes the C preprocessor to ignore all
occurrences of the function call:



#define _heapmin()



heapset functions.
The Microsoft C6.0a heapset functions, _heapset, _bheapset, _fheapset,
and _nheapset, check a heap for consistency and initialize all bytes of
free heap memory to a constant value. Your program can later verify that
the heap has not be overwritten by a stray pointer by checking all free
heap memory for the same constant value using a matching heapchk
function.

Borland C++ provides the heapfillfree and farheapfillfree functions that
accomplish the same objective as the Microsoft heapset functions.  Both
the Microsoft heapset and Borland C++ heapfillfree functions return the
same error conditions as their corresponding heapchk functions.

Recommended Action: Substitute Borland C++ heapset function calls for
Microsoft _heapset function calls, using heapset in place of either
_heapset or _nheapset, and farheapset in place of either _fheapset or
_bheapset. The sample programs MFARHEAP.C and BFARHEAP.C show how this
is done with a #define for _fheapset.



heapwalk functions.
The Microsoft C6.0a heapwalk functions, _heapwalk, _bheapwalk,
_fheapwalk, and _nheapwalk, traverse the heap and return a heap
structure containing information about the next heap entry. Prior to
calling a heapwalk function, you initialize the heap structure with a
pointer value, either to a valid heap block, or NULL, if you want to get
information about the first block in the threaded heap list. The
Microsoft heapwalk functions return heap information about all heap
blocks of a given type, whether allocated or free. They return the size
of the heap block that was allocated, excluding control structures and
padding bytes.

Borland C++ provides the heapwalk and farheapwalk functions that
accomplish an objective similar to the Microsoft heapwalk functions. 
However, the Borland C++ heapwalk functions return heap information only
about heap blocks that are currently allocated to your program. It also
returns the size of the heap block including control structures and
padding bytes.

Recommended Actions: Substitute heapwalk function calls for Microsoft
_heapwalk function calls, using heapwalk in place of either _heapwalk or
_nheapwalk, and farheapwalk in place of either _fheapwalk or _bheapwalk.
You may also have to change the logic of your program slightly to use
these functions which are primarily an adjunct to debugging. The sample
programs MFARHEAP.C and BFARHEAP.C show how this is done with a #define
for _fheapwalk.


msize functions.
The Microsoft C6.0a msize functions, _msize, _bmsize, _fmsize, and
_nmsize, return the size of a memory block allocated on the heap with a
given pointer. Borland C++ has no similar function.

Recommended Actions: Every time you allocate a memory block using one of
the malloc functions or change its size with a realloc function, you
will need to save and tabulate the number of bytes allocated, kept on a
one-to-one basis with the pointer to the allocated memory. Then, change
every reference to an msize function and its associated pointer argument
to use the number of bytes previously allocated for that pointer. DO NOT
use the Borland C++ heapwalk functions to find out the size of a memory
block on the heap, because these functions return a value that includes
the size of heap block control structure and any padding bytes. The
sample programs MFARHEAP.C and BFARHEAP.C show how this might be done.




Other Microsoft Based Heap Functions
Microsoft C6.0a has other functions that allocate, reallocate and
release memory from a based heap. These functions are _bcalloc, _bfree,
_bmalloc, and _brealloc. The _bheapseg and _bfreeseg functions allocate
and deallocate based heap segments, respectively. Borland C++ does not
support the based heap, based pointers, and _segment variables.

Recommended Actions: Remove all _bheapseg and _bfreeseg function calls,
and all definitions of variables of the type _segment. Change all _based
pointers to _far pointers. As a general rule when converting to Borland
C++, substitute either the corresponding ANSI standard memory allocation
function, or the corresponding Borland C++ far heap memory allocation
function. You should use ANSI standard functions whenever possible to
facilitate portability, as long as they permit you to manage memory as
you need to do. Because all of the Microsoft C6.0a based heap functions
take an additional segment variable as an argument, it is not
straightforward to write a set of #define's to make the substitution.
The sample programs BASE_BEF.C and BASE_AFT.C serve together as an
example to show you how to convert programs that used based heap
variables.



freect
The Microsoft _freect function inquires about the maximum number of
items can be allocated on the near heap, where an item is a fixed number
of bytes in size. _freect would typically be used in tiny, small or
medium memory model Microsoft C programs.

Borland C++ does not have a similar function, but it does have the
coreleft function that returns the total number of bytes of unused
memory at the top of the heap.

Recommended Actions: Substitute the coreleft function for _freect. 
Compute the effective item size by adding six to the item size then
round it up to the nearest multiple of 16. Finally, compute the maximum
number of items that can be allocated by dividing the memory left by the
effective item size, and pass this argument to coreleft.  The Borland
C++ heap management functions require a six byte control structure for
each heap block. They always allocate a heap block on a paragraph
boundary, demanding that the effective size allocated is an exact
multiple of 16.




Keeping Out of Heaps of Trouble
Here are some other tips to help you work effectively with the Borland
C++ heap manager.

The Microsoft C _nheap family of functions map directly into the ANSI
heap functions of Borland C++.

The Microsoft C _fheap family of functions map directly to the Borland
C++ farheap set of functions, as shown by the sample MFARHEAP.C and
BFARHEAP.C programs.

To have the greatest degree of portability and to guarantee defect- free
program, whenever you reallocate heap space, always make sure that you
use the current segment:offset value of a heap pointer returned by the
heap manager. And, especially, be sure that any pointers derived from
the pointer returned by the heap manager are all initialized to the
latest value before use.


                      Environments and tools


The Borland C++ IDE is roughly the equivalent of the Programmer's
Workbench, although naturally we think you'll find the IDE much easier
to use. Chapter 3 of the Borland C++ User's Guide manual provides a
complete reference to the IDE.

The IDE loads its settings from two files: TCCONFIG.TC, the default
configuration file, and a project file (.PRJ). TCCONFIG.TC contains
general environmental information. The current project file contains
information more specific to the application you're building.

A project is the IDE's equivalent of a makefile. It includes the list of
files to be built, as well as settings for the IDE options that control
the compilation and linkage of that program. If you don't specify a
project file when you start the IDE, a nameless project is opened and
set with default compiler and linker options, but no file name list.

Unlike Microsoft C, however, Borland C++ does not automatically create
and run a makefile based on settings and file names that you give it in
the project. If you want to use the IDE to set up a project, but use
MAKE to do the actual build, then you can use the PRJ2MAK utility to
convert a project file to a makefile.

The following sections describe the significant differences between
Borland C++'s MAKE, Project Manager, linker (TLINK), and command-line
compiler (BCC) and Microsoft C's NMAKE, LINK, and CL.



Paths for .h and .LIB files
Microsoft C requires two environment variables, LIB and INCLUDE. The
Microsoft C compiler uses INCLUDE to find standard header files.
Similarly, the Microsoft linker uses the LIB variable to discover the
location of the run-time libraries. Borland C++ does not use environment
variables to store the paths for the library and the include files.
Instead, you can easily set these paths in the IDE using the environment
options. If you are working with the command-line compiler or the
linker, you can use either command-line options or configuration files.



Remember that even if you haven't opened a project, Borland C++ will
store the paths in its default project file.


When you install Borland C++, you are asked to set paths for include
files and library files. Those paths become the default paths in the
IDE. The include and library files paths are also written to the default
command-line compiler configuration file TURBOC.CFG. The library path is
written to the default standalone linker configuration file TLINK.CFG. 


In the IDE, you can change the default search paths for libraries and
header files with the Options|Directories command. The settings in the
Directories dialog box become a part of the current project.

For the command-line compiler, you can change the search path for
include and library files with the -I and -L options, respectively.
These options can also be changed in the configuration file for the
command-line compiler, TURBOC.CFG.

The linker can use the /L option to set search paths for libraries and
initialization code (like C0S.OBJ, the startup code for the small memory
model). For instance, this option


/LC:\BORLANDC\LIB;C:\WINAPPS\LIB


tells the linker to look in the two paths named for library and
initialization files.

You can also create a TLINK.CFG file. TLINK.CFG is a regular text file
that contains a list of valid TLINK options.

For the Windows Resource Compiler, the -x option tells it to ignore the
INCLUDE variable. In addition, you can specify an additional search path
with the -i option ( -i all by itself does not imply -x).")

When the Resource Compiler is invoked from the command line, it looks
for windows.h on the path specified by the INCLUDE environment variable,
if there is one. If that INCLUDE variable is set to some path other than
the location of the windows.h supplied by Borland C++, your module might
not be compiled correctly. (This does not occur in the IDE, because the
IDE passes the correct information to the Resource Compiler.)

For instance, if you have been using Microsoft C, then you probably have
an INCLUDE environment variable set to the path of the Microsoft C
header files. If you have also been using the Microsoft Windows SDK,
then the version of windows.h included with the SDK is probably also in
the INCLUDE directory.

When you're building a Borland C++ application, the Resource Compiler
should include the windows.h shipped with Borland C++. If you have a
defined INCLUDE environment variable, then you should tell the Resource
Compiler to ignore it with the -x option. (The same holds true for
Microsoft C LIB environment variable, i.e. it contains both the standard
C library path and the Windows library path, the latter only if you are
writing for Windows and you have installed the Windows library in a path
different than the standard MSC C libraries.)


MAKE
The version of MAKE supplied with Borland C++ 3.0 contains many new
features, some of which are designed to increase compatibility with
Microsoft's NMAKE. The new command-line switch -N turns on full NMAKE
compatibility. See Chapter 2 of the Borland C++ Tools & Utilities Guide
manual for more information on MAKE's options. The following list
summarizes the differences between MAKE and NMAKE.

NMAKE supports response files but MAKE doesn't.

In NMAKE, you must surround strings to be compared with quotes. MAKE
doesn't have this requirement; as long as the string to be compared
doesn't contain spaces, you can compare them without quotes.

NMAKE predefines several implicit rules; MAKE doesn't. However, the
BUILTINS.MAK file contains several implicit rules that you can use
without specifying them in the makefile.

MAKE doesn't pass through environment variables.


Command-line Compiler

The following table lists comparable BCC and CL command-line compiler
options. Some of the CPP (standalone preprocessor) options are listed.
In many multi-pass compilers, a separate pass performs the work of the
preprocessor, and the results of the pass can be examined. Since Borland
C++ uses an integrated single-pass compiler, we provide the standalone
utility CPP to supply the first-pass functionality found in other
compilers.

Note that most CL options that take arguments allow for a space between
the option and the argument. BCC options that take arguments are usually
immediately followed by the argument or list.

CL and BCC options compared
Microsoft C	Borland C++
CL option  BCC option    What it does
    N/A     @name         Gives the command-line
                          compiler a response
                          file name.
    N/A     +name         Tell the command-line
                          compiler to use the
                          alternate configuration
                          file name
    N/A     -A            ANSI keywords
    N/A     -A-, -AT      Borland C++ keywords
                          (default)
    N/A     -AK           Use only Kernighan and
                          Ritchie keywords.
    N/A     -AU           Use only UNIX keywords.
    /Zp2    -a            Align word.
    /Zp1    -a-           Align byte (default).
  /Aw, /Gw  -WD           Creates an .OBJ for Windows
                          to be linked as a .DLL with
                          all functions exportable.
  /Aw, /GW  -WDE          Creates an .OBJ for Windows
                          to be linked as a .DLL with
                          explicit export functions.
    /Ax     -mx           Use memory model x, where x
                          is t, s, m, c, l, or h.. For
                          BCC, following t, s, or m
                          with ! tells compiler to
                          assume DS != SS.
    /Bn      N/A          Use alt preprocessor CnL.
    N/A     -B            Compile and call the
                          assembler to process inline
                          assembly code.
    N/A     -b            Make enums word-sized
                          (default)
    N/A     -b-           Make enums signed
                          or unsigned.
    /C      N/A           Preserve comments in C
                          preprocessor
    N/A     -C            Nested comments on.
    N/A     -C-           Nested comments off.(default)
    /c      -c            Compile to .OBJ but do
                          not link.
    /Did  -Dname          Define 'name' to the string
                          consisting of the null character.
 /Did=value -Dname=string Defines 'name' to 'string'.
    N/A     -d            Merge duplicate strings on.
    N/A     -d-           Merge duplicate strings off
                          (default) (default).
    N/A     -Ename        Use filename as the
                          assembler to use.
    /E     CPP -P         Preprocess source to
                          standard output, include
                          line numbers.
    /EP    CPP -P-        Preprocess source to
                          standard output, without
                          line numbers.
    N/A     -f-           Don't do floating point.
    N/A     -ff           Fast floating point (default).
    N/A     -ff-          Strict ANSI floating point
    N/A     -ff-          Strict ANSI floating point.
    N/A     -f87          Use 8087 h/w instructions.
    N/A     -f287         Use 80287 h/w instructions.
  /F hexnum  N/A          Sets stack size to hexnum
                          bytes (hexnum must be
                          hexadecimal).
(By default) -Fc          Generates COMDEFs.
    N\A      -Fm          Enables the -Fc, -Ff, and
                          -Fs     options.
(By default) -Fs          Make DS==SS for all
                          memory models
/Fa [file]   N/A          Create assembly listing.
                          Name for list file defaults
                          to Source.ASM.
    /Fb      N/A          Creates a bound executable file
/Fc [file]   -S           Produces a combined source
                          and assembly code listing.
                          Name for list file defaults
                          to Source.COD.
/Fe file   -efile         'file' names executable file.
/Fl [file]   N/A          Creates object code list.
                          Name for list file defaults
                          to Source.COD.
/Fm [file]   -M           Creates map file. Name
                          defaults to Source.MAP,
                          where source is the first
                          source file specified.
/Fo file   -ofile         'file' names object file.
    /FPa    N/A           Generate floating-point
                          calls; select alternate math
                          library.
    /FPc    -f            Emulate floating point
                          (default, coprocessor used if
                           present at run time).
    /FPc87  N/A           Selects 80x87 library (80x87
                          coprocessor must be present
                          at run time).
    /FPi    N/A           Inlines 80x87 instructions;
                          selects emulator library
                          (coprocessor used if present
                          at run time).
    /FPi87  -f87, -f287   Inlines 80x87 instructions;
                          chooses coprocessor library
                          (coprocessor must be present
                          at run time).

  /F[file]   N/A          Generates standard PWB
                          Source Browser database.
  /FR[file]  N/A          Generates extended PWB
                          Source Browser database.
  /Fs [file] N/A          Produce source list file.
                          defaults to Source.LST.
  /Fx [file] N/A          'file' specifies a name
                          for the MASM cross-reference
                          file.
    G0      -1-           Generate 8088/8086
                          instructions.
    G1      -1            Generate 80186 instructions.
    G2      -2            Generate 80286
                          protected-mode compatible
                          instructions.
    /Gc     -p            Use Pascal calling
                          convention. For CL, this is
                          Pascal or FORTRAN, but they
                          currently same calling
                          convention.
    /Gd     -p-           Standard C calling
                          conventions (default).
    /Ge     -N            Check for stack overflow.
                          (Default for CL, but not for
                          BCC).
    /Gi     N/A           Compile incrementally (for
                          use with quick compile
                          option /qc).
    /Gm     N/A           Store strings in CONST seg
    N/A    -gn            Stop compilation after n
                          warning messages
    /Gr    -pr            Enables _fastcall to call
                          conventions for functions
                          (if possible, passing value
                          in registers).
    /Gs     -N-           Turn off checking for stack
                          overflow. (Off by default
                          for BCC.)
 /Gt [number] -Ff[=size]  Creates far variables
                          automatically; 'size' or
                          'number' is threshold.
    /Gw      -W           Creates correct
                          prolog/epilog for Windows
                          program. For Borland C++,
                          this creates an application
                          with all functions exportable
    /GW     -WE           Generates prolog/epilog for
                          explicit functions (marked
                          with _export) in Windows
                          program.
    N/A      -H           Causes the compiler to
                          generate and use pre-
                          compiled headers.
    N/A      -H-          Turns off generation and
                          use of precompiled headers
                          (default).
    N/A      -Hu          Tells the compiler to use
                          but not generate precompiled
                          headers.
    N/A   -H=filename     Sets the name of the file
                          for precompiled headers.
(By default) -h           Use fast huge ptr math
 /H number  -inumber      Restricts length of external
                          names to 'number'.
    /HELP   BCC           Calls QuickHelp. For help on
                          BCC, simply invoke without
                          options.
    N/A     -in           Make significant identifier
                          length to be 'n'.
  /I dir  -Ipath          Directories for include files
                          For CL, adds directory to the
                          beginning of include file
                          search directory list.
    N/A   -jn             Stop after 'n' compiler error
                          messages.
    /J    -K              Changes default for char.
                          from signed to unsigned. For
                          Borland C++, -K- returns to
                          signed.
    N/A   -Jg             Definitions for all template
                          instances, and merge
                          duplicates (default)
    N/A  -Jgd             Public definitions for all
                          template instances
    N/A  -Jgx             External references for all
                          template instances
    N/A  -k               Std stack frame on (default).
    N/A -Lpath            Directories for libraries.
 /Lc,/Lr  /Td             Tells linker to create a
                          real mode executable.
/Li [number]  N/A         Use incremental linker,
                          instead of standard linker.
                          Number specifies byte
                          boundary for padding near
                          functions.
 /Lr See /Lc.
 /link opts -lopts        Pass 'opts' to linker when
                          invoked.
   N/A      -l-option     Suppress 'option' for the linker
   N/A      -M            Instruct the linker to
                          create a map file.
 /MA option -Toption      Pass 'option' to assembler
                          when invoked.
   N/A      -npath        Set the output directory
 /NDdataseg -zRname       Sets the data segment name.
                          For BCC, option changes the
                          name of the uninitialized
                          data segment class to name.
                          By default, the uninitialized
                          data segments are assigned
                          to class BSS.
 /NMmodule   N/A          Sets module name to 'module'
 /nologo     N/A          Don't print sign-on banner.
 /NTsegname -zCname       Sets code segment name. This
                          option changes the name of
                          the code segment to 'name'. By
                          default, the code segment is
                          named _TEXT, except for the
                          medium, large and huge
                          models, where the name is
                          filename_TEXT. (filename
                          here is the source file name.)
    N/A     -O            Optimize jumps.
    N/A     -O-           No optimization (default).
   /O [options] (See comment)   Provides optimization. For
                          Borland C++, see specific
                          options; for instance, -Z,
                          -O, or -G.
    /Os     -G-           Optimize for size (default)
    /Os     -O1           Optimize, smallest code
    /Ot     -G            Optimize for speed
    /Ot     -O2           Optimize, fastest code
    /Oa     -Oa           Optimize, no pointer aliasing
    /Ow      N/A          no aliasing in function calls
    N/A     -Ob           Optimize, dead store
                          elimination
    /Og     -Oc           Optimize, local common
                          subexpression elimination
    /Od     -Od           Optimize, disable all
                          optimizations
    /Oe     -Oe           Optimize, global register
                          allocation, variable live range
    /Og     -Og           Optimize, global common
                          subexpression elimination
    /Oi     -Oi           Optimize, intrinsic functions,
                          automatic inlining
    /Ol     -Ol           Optimize, loop optimization
    /Ol     -Om           Optimize, loop invariants,
                          code motion on
    /On     N/A           disable "unsafe" optimizations
    N/A     -Op           Optimize, copy propagation
    /Op     N/A           enable precision optimizations
    /Or     N/A           disable inline return
    /Os     -Os           Optimize, size of code
    /Ot     -Ot           Optimize, speed of .EXE
    /Ol     -Ov           Optimize, loop induction
                          variable, strength reduction
    /Ox     -Ox           Optimize, speed: compatible
                          with Microsoft compilers
    N/A     -P            Perform a C++ compile
                          regardless of source file
                          extension.
    N/A     -Pext         Perform a C++ compile and
                          set the default extension to
                          ext.
    N/A     -P-           Perform a C++ or C compile
                          depending on source file
                          extension (default).
    N/A     -P-ext        Perform a C++ or C compile
                          depending on extension; set
                          default extension to ext.
    N/A     -p-           Use C calling convention
                          (default).
    /P  CPP -P- -oname    Preprocesses source file and
                          sends output to name
                          (CPP), or to Source.I (CL).
    N/A     -Qe           Instructs the compiler to
                          use all available EMS memory
                          (default).
    N/A     -Qe-          Instructs the compiler to
                          not use any EMS memory.
    N/A     -Qx           Instructs the compiler to
                          use all available extended
                          memory.
    N/A     -Qx=nnnn      Instructs the compiler to
                          reserve nnnn Kb of extended
                          memory for other programs,
                          and to use the rest itself.
    N/A     -Qx=nnnn,yyyy Instructs the compiler to
                          reserve 'nnnn' Kb of extended
                          memory for other programs
                          and 'yyyy' for itself.
    N/A     -Qx=,yyyy     Instructs the compiler to
                          reserve 'yyyy' Kb of extended
                          memory for itself.
    N/A     -Qx-          Instructs the compiler to
                          not use any extended memory
    /qc     N/A           Invokes quick compile.
    N/A     -R            Generate ObjectBrowser
                          information.
    N/A     -r            Use register variables on
                          (default).
    N/A     -r-           Suppresses the use of
                          register variables.
    N/A     -rd           Only allow declared
                          register variables to
                          be kept in registers.
    N/A     -S            Produce .ASM file
   /Sx option  N/A        Set options for source
                          listing. Where 'x' is l, p,
                          s, or t.
    N/A     -T-           Remove all previous
                          assembler options.
   /Ta asm_src  N/A       Specifies that 'asm_src' be
                          treated as an assembler
                          source file.
   /Tc srcfile  N/A       Specifies that 'srcfile' be
                          treated as a c source file.
    N/A    -tDe           Compiled and linked program
                          is DOS .EXE file
    N/A    -tDc           Compiled and linked program
                          is DOS .COM file
    N/A    -tW            Compiled and linked program
                          is a Windows module using
                          the -W options
    N/A    -u             Generate underscores (default)
    N/A    -u-            Disable underscores
    /u     N/A            Undefines all predefined
                          identifiers
 /U Ident  -UIdent        Undefine any previous
                          definitions of 'Ident'.
    N/A    -V             Smart C++ virtual tables.
    N/A    -Va            Pass class args by reference
                          to temp variable
    N/A    -Vb            Backwards compatibility,
                          virtual base class pointer
    N/A    -Vc            Backwards compatibility,
                          no hidden members and code
    N/A    -Vf            C++ far virtual tables
    N/A    -Vmv           Member pointers have no
                          restrictions
    N/A    -Vmm           Member pointers support
                          multiple inheritance
    N/A    -Vms           Member pointers support
                          single inheritance
    N/A    -Vmd           Use smallest representation
                          for member pointers
    N/A    -Vmp           Honor declared precision for
                          all member pointer types
    N/A    -Vo            Backwards compatibility,
                          master switch turns on all
    N/A    -Vp            Backwards compatibility,
                          pass 'this' to pascal
                          member functions
    N/A    -Vt            Place virtual table pointer
                          after non-static data members
    N/A    -Vs            Local C++ virtual tables.
    N/A    -Vv            Backwards compatibility,
                          don't change layout of classes
    N/A    -VmX           C++ member pointers
    N/A  -V0, -V1         External and Public C++
                          virtual tables.
    N/A    -Vf            Far C++ virtual tables.
    N/A    -v             Source debugging on
    N/A    -v-            Source debugging off
    N/A   -vi, -vi-       Controls expansion of inline
                          functions.
 /V string N/A            Copies 'string' to object file
                          (for version control).
    N/A    -w             Display warnings on.
    N/A    -wxxx          Enable 'xxx' warning message.
    N/A    -w-xxx         Disable 'xxx' warning message.
    /w     -w-            Display warnings off.
    N/A    -WS            Creates an .OBJ for Windows
                          that uses smart callbacks.
    /W n   (See -w)       Set warning level 0, 1, 2,
                          3, or 4.
    /WX   -g1             Makes all warnings fatal. No
                          object files are generated
                          if warning occurs. (The -g
                          option takes the form -gn,
                          where n is the limit to
                          number of warnings.)
    N/A    -X             Disable compiler
                          autodependency output.
    /X     N/A            Ignore INCLUDE
                          environment variable list
                          of include search paths.
    N/A    -Y             Enable overlay code
                          generation.
    N/A    -Yo            Overlay the compiled files.
    N/A    -y             Include line numbers in
                          .OBJ for debugger
    N/A    -y-            Do not include line numbers
                          in .OBJ for debugger
    N/A    -Z             Enable register usage
                          optimization.
    N/A   -zAname         set Code class to 'name'
    N/A   -zBname         set BSS class to 'name'
    N/A   -zDname         set BSS segment to 'name'
    N/A   -zEname         set Far segment to 'name'
    N/A   -zFname         set Far class to 'name'
    N/A   -zGname         set BSS group to 'name'
    N/A   -zHname         set Far group to 'name'
    N/A   -zPname         set Code group to 'name'
    N/A   -zSname         set Data group to 'name'
    N/A   -zTname         set Data class to 'name'
    N/A   -zX*            Use default segment, class,
                          or group name for X.
    /Za    -A             Enforces ANSI compatibility.
                          Use only ANSI keywords. No
                          vendor-specific extension
                          allowed.
    /Zc    N/A            Ignores case for functions
                          declared as _pascal.
    /Zd    /y             Generates line numbers for
                          symbolic debugger.
    /Ze -A-, -AT          Enable vendor-specific
                          extensions.
    /Zg    N/A            Generates function
                          prototypes; writes to
                          standard output.
    /Zi    /v             For Microsoft, generates
                          debugger information for
                          CodeView. For Borland C++,
                          generates information for
                          IDE debugger and Turbo
                          Debugger.
    /Zl   N/A             Library search records not
                          written to object file.
    /Zpn -a, -a-          Packs structure members
                          on the 'n' byte boundary.
                          'n' can be 1, 2, or 4.
    /Zr   N/A             Generates checks for null
                          pointers and far pointers
                          that are out of range.
 /Zs files  N/A           Syntax check only.


Command-line Options and Libraries

The C0Fx.OBJ modules are provided for compatibility with source
files intended for compilers from other vendors. The C0Fx.OBJ
modules substitute for the C0x.OBJ modules; they are to be linked
with DOS applications only, not Windows applications or DLLs.
These initialization modules are written to alter the memory
model such that the stack segment is inside the data segment. The
appropriate C0Fx.OBJ module will be used automatically if you use
either the -Fs or the -Fm command-line compiler option.

The -Fc (generate COMDEFs), -Ff (create far variables), -Fs
(assume DS == SS in all models), and -Fm (enable all -Fx options)
command-line compiler options are provided for Microsoft
compatibility. These options are documented in full in Chapter 5
of the Borland C++ User's Guide manual.


Linker

The Borland C++ linker, TLINK, is invoked automatically from the
command- line compiler unless the -c compiler option is used.
Options such as memory model and target (Windows or DOS), are
passed from the compiler to TLINK; TLINK links the appropriate
libraries based on the compile options.

TLINK can be used to build both DOS and Windows programs. See
Chapter 4 in the Borland C++ Tools & Utilities Guide manual for
material on module definition file statements.

The following table compares TLINK and LINK options. Note that
Borland C++ TLINK options are case-sensitive, while Microsoft
LINK options are not.

LINK and TLINK options compared
Microsoft C	Borland C++
Link option   TLINK option    What it does

N/A           /3              Enable 32-bit processing.
/A:size       /A=nnnn         Specify segment alignment
                              for Windows images.
/BA           N/A             BATCH. Suppresses prompts
                              for library or object files
                              not found.
N/A           /C              Treat EXPORTS and
                              IMPORTS section of module
                              definition file as case
                              sensitive.
/CO           /v              Include full symbolic debug
                              information.
/CP:bytes     N/A             Sets the program's maximum
                              memory allocation to 'bytes'.
N/A           /d              Warn if duplicate symbols in
                              libraries.
/DOSSEG    (See comment)      For assembly programs,
                              forces a certain ordering of
                              segments in executable. To
                              enable DOSSEG for an
                              assembly program, include
                              DOSSEG in the source code.
/DS          N/A              For assembly programs, tells
                              linker to load data starting
                              at high end of DS instead of
                              low end.
/E           N/A              Packs the executable by
                              removing repeated series of
                              bytes.
/F       By default           For LINK, tells linker to
                              optimize far calls to
                              procedures in same segment
                              as caller. (Used with MS
                              /PACKCODE option.) For
                              TLINK optimizes far calls
                              automatically.
/HE          /?               Provides help on
                              command-line options.
/HI         N/A               For real-mode assembly
                              programs, places executable
                              as high in memory as possible.
N/A         /i                Initialize all segments.
/INC        N/A               Prepares for ILINK.
/INF        N/A               Tells LINK to display link
                              information while in process.
N/A        /Lpaths            Specify library search paths.
/LI        /l                 Include source line numbers
                              and associated addresses in
                              map file.
/M          /m                Create map file with public
                              global symbols.
/NOD [:name] /n               Don't use default libraries.
/NOE         /e               Ignore Extended Dictionary.
/NOF        N/A               Turns off far call
                              translation (see /F option)
/NOI        /c                Treat case as significant
                              in symbols.
/NOL        N/A               Suppress banner
/NON        N/A               Arrange segments in
                              executable in the same
                              order as they are arranged
                              by /DOSSEG.
/NOP       /P-                Turn off code packing.
N/A        /o                 Overlay following modules or
                              libraries. Microsoft LINK
                              uses parentheses around
                              files to be overlaid. (Note
                              that the overlay scheme is
                              different between products.)
/O:number  N/A                Set interrupt 'number' for
                              passing control to overlays
                              (other than the default 63).
/PACKC[:n] /P=n               Pack code segments. 'n'
                              specifies maximum size
                              of groups formed by
/PACKC or /P.
/PACKD[:n]    N/A             Pack data segments. 'n'
                              specifies maximum size of
                              groups formed by /PACKD.
/PADC:size    N/A             Tells LINK to pad code
                              module for ILINK by
                              'size' bytes.
/PADD:size    N/A             Tells LINK to pad data
                              segments by 'size' bytes.
/PAU          N/A             Pauses linking.
/PM:type      N/A             Sets window type for
                              Presentation Manager.
 /Q           N/A             Produces Quick library.
 N/A /s                       Create detailed map of
                              segments.
 /SE:number   N/A             Sets maximum number of
                              segments allowed.
 /ST:number   N/A             Sets stack size.
 /T           /t              Produce .COM files.
 N/A          /Td             Create target DOS
                              executable.
N/A           /Tdc            Create target DOS .COM file.
N/A           /Tde            Create target DOS .EXE file.
N/A           /Tw             Create target Windows
                              executable (.DLL or .EXE).
N/A           /Twe            Create target Windows
                              application (.EXE).
N/A           /Twd            Create target Windows DLL
                              (.DLL).
/W            N/A             Warn fixups.
N/A           /x              Don't create map file.
N/A           /ye             Use expanded memory for
                              swapping.
N/A           /yx             Use extended memory for
                              swapping.



       Converting Microsoft DOS Graphics Functions

The differences between the Microsoft C6.0a DOS graphics system
and the Borland Graphics Interface are summarized for your
reference below.

Two sample programs, MSCGRF.C and BGIGRF.C, provide you with a 
comparison between Microsoft C6.0a and Borland C++ graphics. You
will find them helpful as a reference as you convert Microsoft C
graphics programs to run with the Borland C++ BGI. These programs
are available for download (see the appendix for more details).


Supported Graphics Adapters

Microsoft C6.0a is a closed-ended graphics system that supports a
limited set of graphics cards. There is no public specification
from Microsoft explaining how to add support for other graphics
drivers.  Graphics adapters recognized automatically by Microsoft
C6.0a graphics are Video Graphics Array (VGA), Extended Graphics
Adapter (EGA), Color Graphics Adapter (CGA), Multicolor Graphics
Array (MCGA), and the Olivetti/AT&T variations of the first three
standards.

In addition, if you run the Microsoft-supplied
terminate-and-stay-resident (TSR) program, MSHERC, Microsoft's
graphics recognizes and supports video adapters compatible with
the Hercules monochrome graphics hardware specification. If you
develop software for use by others, you must require your users
to run MSHERC before running your Microsoft C graphics programs
with a Hercules monochrome graphics adapter. MSHERC occupies
nearly 7K bytes of memory, and cannot be removed from memory once
installed.

The Microsoft C _getvideoconfig function returns information
about the current graphics adapter, and the _setvideomode
function sets up the adapter in an appropriate graphics mode.

The Borland Graphics Interface (BGI) is an open-ended graphics
system that supports industry standard graphics adapters.
Available from Borland is a specification that describes the BGI
and how to develop third-party BGI graphics drivers. The BGI
automatically recognizes and supports VGA, EGA, CGA, IBM PC 3270,
Olivetti/AT&T CGA, and Hercules monochrome graphics adapters. If
an IBM 8514 Application Interface (AI) TSR is installed on a PC
with an IBM 8514 or compatible graphics adapter, the BGI
recognizes and supports this device, in conformance with IBM's
recommendations for 8514 programming.

In addition to the BGI graphics drivers supplied with Borland C++
3.0, third-party BGI drivers have been developed to support
various VGA chip sets operating in Super VGA graphics modes that
offer higher resolution and/or more colors than standard VGA. The
Borland CompuServe Forum always contains information about
currently available BGI drivers.

With Borland C++, the initgraph function loads a graphics driver
from disk and puts the graphics system into graphics mode. It is
generally the first BGI function that your program calls. You may
also use the detectgraph function to override the graphics mode
selected by initgraph.

If you or users of your software have a third-party BGI graphics
driver available, your program would first use the
registerbgidriver function to register it for use by BGI, and
then call initgraph.

Make sure that your program can access the BGI drivers that it
needs to use. The third argument to the initgraph function gives
the path where your program finds all of the BGI drivers it can
use. Relying on just the initgraph function is the simplest for
you to program, but it may complicate the installation of your
software.

You may also add BGI drivers to the GRAPHICS.LIB library supplied
with Borland C++, link them into your program, then register them
for use by your program with the registerbgidriver function.
These steps simplify installation of your software, but add to
the amount of memory required by your program. See the on-line
help in the IDE and the documentation file UTIL.DOC for more
information about this treatment of BGI drivers.



Displaying Fonts

Microsoft C6.0a provides two types of graphics fonts, fixed
height bitmapped fonts and scalable vector fonts. It also has
special functions to display the built-in video BIOS bitmapped
font for the current graphics mode. Microsoft graphics manages
the BIOS font differently than the graphics fonts.

The Microsoft bitmapped fonts are in three typeface families:
fixed width Courier, sans serif proportional Helv, and serif
proportional Times Roman. The scalable vector fonts are Modern, a
narrow sans serif proportional font; Script, a handwriting-like
font; and Roman, a Times Roman look-alike.

The Microsoft bitmapped fonts cannot be resized. If you want to
use a specific bitmapped font, it is best if your program builds
a table of available fonts and their characteristics obtained by
calls to the _getfontinfo function. Then it can build a text
string describing the exact attributes of the required font, and
select the font with the _setfont function.

The Microsoft scalable fonts can be displayed at any size. In
addition, you can display a scalable font at any horizontal to
vertical ratio.

The Microsoft C6.0a graphics library does not have any functions
to justify text at the left, center, right, top, middle, or
bottom of a rectangular area. As a consequence, your program must
manage each step of the process: calculation of text width and
height, status of justification attributes, computation of
starting x-y text coordinate including justification, and,
finally, the actual display of the text.

To use Microsoft graphics fonts, your program must read them from
the directory passed to the _registerfonts function.

Borland C++ includes eleven vector fonts of the sans serif,
serif, and ornamental varieties.  The default font is an 8x8
pixel sans serif font that can be resized in integral multiples
of 8 pixels using the settextsize function. You can resize all of
the other fonts to various sizes by using the settextsize
function. You can establish the horizontal-vertical ratio for
displaying text with the setusercharsize function. The default
horizontal-vertical ratio is one-to-one (1:1).

The Borland C++ settextjustify function sets up the rules used to
justify text. Once set up, text justification is done
automatically by the outtextxy function with respect to the
current graphics position.

To use Borland C++ graphics fonts, your program must read them
from the same directory in which the BGI drivers are found.
Alternately, you can link BGI fonts into your program,
registering and using them much like any BGI drivers you may have
linked into your program. You can register a font for use by your
program with the registerbgifont function. See the on-line help
in the IDE and the documentation file UTIL.DOC for more
information about treating BGI fonts in this fashion.

Finally, the Borland C++ 8x8 default font displayed at a 1:1
horizontal- vertical ratio offers the best fit for replacing the
built-in BIOS bitmapped font displayed by the Microsoft C6.0a
functions _outmem and _outtext. Note though that the sizes of the
BIOS fonts vary: CGA is 8x8, EGA is 8x14, Hercules is 9x14, and
VGA is 8x16.



The State of the Graphics System

Microsoft C6.0a does not have a complete set of function calls to
determine the current state of the graphics system. As a result,
you must keep track of the graphics system state yourself in your
programs, saving old and new state of each graphics attribute
when you set it. However, the following graphics state
information is maintained by Microsoft C graphics: x-y
coordinates, foreground color, background color, fill pattern,
line pattern, font characteristics, font orientation, and line
drawing mode.

Borland C++ has a complete set of function calls to return the
current state of each attribute in the graphics system. These
include graphics mode, palette, x-y coordinates, foreground
color, background color, palette, aspect ratio, fill pattern and
color, line pattern and color, font characteristics, font
orientation, and viewport settings.



Graphics Coordinate Systems

Microsoft C graphics have three types of functions for displaying
graphic objects: physical coordinates, viewport coordinates, and
two types of windowed coordinates. Physical coordinates serve
only as absolute physical reference points for graphics
operations; they are not used by any graphics functions that draw
on the screen.

Microsoft viewport coordinates are integer x-y values plotted
with respect to the zero point of the current window, as set with
the _setviewport function. The _outgtext function displays text
using the current viewport coordinates.

Microsoft windowed coordinates are floating point x-y values set
up with the _setwindow function, and may be positive or negative
numbers.  Both _setviewport and _setwindow establish the
rectangular boundaries of a window using the upper left and lower
right corners of the rectangle. If you use windowed coordinates
for drawing graphic objects, you must also transform these
coordinates into viewport coordinates to display text with your
graph. Use either _getviewcoord_wxy or _getviewcoord_w to do
this.

The shape drawing functions draw lines, rectangles, arcs, and
polygons, get images from the screen, and put images onto the
screen.  Each function that uses viewpoint coordinates has one or
two analogous functions in the windowed coordinate system. For
example, _arc draws an arc with viewport coordinates, while
_arc_wxy draw an arc in windowed coordinates. The _ellipse
function draws an ellipse using viewport coordinates, and both
_ellipse_w and _ellipse_wxy use windowed coordinates. The
windowed functions with the suffix _w accept coordinate arguments
with four distinct x-y values, while those with the suffix _wxy
take structures of x-y coordinate pairs as arguments.

Microsoft C graphics provides the _getphyscoord, _getviewcoord,
_getviewcoord_w, _getviewcoord_wxy, and _getwindowcoord functions
to map from one coordinate system to another, which is required
uses windowed graphics functions.

Borland C++ offers a unified view of graphics with a single set
of functions that all use viewport coordinates as a single frame
of reference. After the viewport is set, all functions operate
relative to the zero x-y coordinate of the viewport.


Other Things You Must Do Differently

Microsoft C 6.0a graphics has no predefined bitmap patterns for
filling shapes or drawing lines. You must design and describe
bitmap patterns in your program before using them. Microsoft C
graphics also does not have any parameter to control the width of
lines drawn. In the Microsoft graphics system, if you need to
draw a line more than one pixel wide, you accomplish this by
drawing several lines one pixel apart from each other until the
resulting line is wide enough.

Borland C++ allows you to use its built-in bitmap patterns to
fill shapes and to draw lines, and to define and use your own.
You can also vary the widths of lines drawn by the arc,
rectangle, pie, drawpoly, line, and linerel, or ellipse
functions.

Microsoft C6.0a graphics employs the concept of a bounding
rectangle, a rectangle drawn so that it contains a drawn ellipse,
or the ellipse from which a drawn shape is derived. A bounding
rectangle touches an ellipse or circle at exactly four points,
the vertices of the figure.  For an arc or pie, the endpoints of
the drawn shape are marked by lines that intersect the bounding
rectangle. To draw a curved shape, you need to compute the upper
left and lower right of corners of its bounding rectangle from
its center point and radii.

The Borland C++ graphics system uses a simple and intuitive
system for drawing curved shapes. You need only to describe the
center point of the shape in x-y coordinates, and the radii. To
draw either an arc or pie shape, you also need to specify the
starting and ending angles of the endpoints, stated in degrees.

The Microsoft C graphics function _setwritemode controls the
logical line drawing mode used for _putimage, _lineto, _polygon,
and _rectangle operations. The manifest constants _GAND, _GOR,
_GPRESET, _GPSET, and _GXOR provide different ways to combine the
result of from the current drawing operation with the data
already on screen. The results are less than intuitive, as shown
by the pair of graphic programs BGIGRF.C and MSCGRF.C. Borland
C++ uses logical operators to control only the putimage function.


A Graphics Reference for Microsoft C Users

Here is a reference of graphics functions to help you convert
your Microsoft C graphics programs. BGI contains many other
useful graphics functions. This reference tabulates the BGI
functions that most closely correspond to Microsoft C graphics
functions. They are listed in alphabetic order by category of
graphics function.


Graphics System Control

Microsoft C                 Borland BGI

_getactivepage              N/A, maintain in your program
_getvideoconfig             detectgraph, initgraph,
                            getaspectratio,getpalette,
                            getmaxx, getmaxy
_getvisualpage              N/A, maintain in your program
_setactivepage              setactivepage
_setvideomode               setgraphmode
_setvideomoderows           No equivalent, uses BIOS font
_setvisualpage              setvisualpage


Drawing & Filling
Microsoft C              Borland BGI

_arc                     arc
_ellipse                 ellipse or fillellipse
_floodfill               floodfill
_getarcinfo              getarccoords [arc only]
_getcurrentposition      getx & gety
_getcurrentposition_w    No equivalent, remap to viewport
                         coordinates and use getx and gety
_getfillmask             getfillpattern
_getlinestyle            getlinesettings [line style,
                         pattern, & thickness]
_getwritemode            N/A
_lineto                  lineto
_moveto                  moveto
_pie                     pieslice
_polygon                 drawpoly or fillpoly
_rectangle               rectangle
_setfillmask             setfillpattern
_setlinestyle            setlinestyle [line style,
                         pattern, & thickness]
_setwritemode            raster operations (ROPS) are
                         used as arguments to putimage



Text Output
Microsoft C              Borland BGI

_displaycursor           No equivalent, used in text mode
_getfontinfo             gettextsettings
_getgtextextent          textwidth
_getgtextvector          No equivalent, maintain this
                         information in your program
_gettextcolor            No equivalent, uses BIOS font
_gettextcursor           No equivalent, used in text mode
_gettextposition         No equivalent, uses BIOS font
_gettextwindow           No equivalent, uses BIOS font
_outgtext                outtext
_outmem                  No equivalent, uses BIOS font
_outtext                 No equivalent, uses BIOS font
_registerfonts           registerbgifont
_scrolltextwindow        No equivalent, uses BIOS font
_setfont                 settextstyle & setusercharsize
_setgtextvector          settextstyle
_settextcolor            No equivalent, uses BIOS font
_settextcursor           No equivalent, used in text mode
_settextposition         No equivalent, uses BIOS font
_settextrows             No equivalent, uses BIOS font
_settextwindow           No equivalent, uses BIOS font
_unregisterfonts         No equivalent
_wrapon                  No equivalent, controls word wrap for
                         _outtext]


Screen, Viewport & Window

Microsoft C              Borland BGI

_clearscreen             cleardevice or clearviewport
_getimage                getimage
_getphyscoord            No equivalent,
                         view(x,y) --> physical (x,y)
_getpixel                getpixel
_getviewcoord            No equivalent,
                         physical (x,y) --> view(x,y)
_getviewcoord_w          No equivalent,
                         window (wx,wy) --> view(x,y)
_getviewcoord_wxy        No equivalent,
                         window (wx,wy) --> view(x,y)
_getwindowcoord          No equivalent,
                         view(x,y) --> window(wx,wy)
_imagesize               imagesize
_putimage                putimage
_setcliprgn              setviewport [also viewport]
_setpixel                setpixel
_setvieworg              setviewport [window & clip, too]
_setviewport             setviewport [also clip]
_setwindow               Window coordinates are
                         not available



Color Control
Microsoft C              Borland BGI

_getbkcolor              getbkcolor
_getcolor                getcolor
_remappalette            setpalette
_remapallpalette         setallpalette
_selectpalette           [Not available, CGA only]
_setbkcolor              setbkcolor
_setcolor                setcolor


State Query & Error Handling
Microsoft C              Borland BGI

_grstatus                graphresult & grapherrormsg


