Open Architecture Handbook - The Borland Developer's Technical Guide
Open Architecture Handbook - The Borland Developer's Technical Guide
_________________________________________________
2 Open Architecture
Handbook
INTRODUCTION
________________________________________________________________________________
internal functions
implementation details
Today we hear more and more about open systems, open standards, open
tools . . .
and open architectures. Along with object-oriented design, the open
architecture
movement heralds a new era of modular software that is designed to
be shareable,
extensible and compatible.
Introduction Page 1
This book, as befits its subject, is not for the novice user or the
technically
unsophisticated. Written largely by the Borland developers who
actually created
the tools described, its style is terse and technical. Every effort
has been
made to present the topics clearly and in an easy-to-read manner,
but the
presentation is not a "tutorial," nor are basic concepts of the
tools discussed
at great length. It is best viewed as a collection of technical
papers by
developers for developers, presenting hard to find information in a
convenient
and readily-accessible form.
Tools discussed
Introduction Page 2
Borland Help System: defines the Borland Help System, including the
source text
file format, binary Help file format, and the run-time Help engine.
Accompanying software
The accompanying Examples and Supplementary Software disk contains a
number of
brief example programs utilizing the information contained in this
book. The
examples are referenced in the chapter(s) to which each example
applies.
A brief disclaimer
The information presented in this guide is for the benefit of advanced
developers who wish to take advantage of various internal features
and formats
of the Borland tools.
Introduction Page 3
Chapter 1 Page 4
CHAPTER
________________________________________________________________________________
C++
object mapping
This chapter describes how Turbo C++ and Borland C++ handles memory
for C++
objects.
The following applies both to the 16-bit (segmented address space) and
the
32-bit versions of BCC. Whenever the text has a near or far pointer,
this
applies to the 16-bit version, and a 32-bit (flat) pointer is to be
substituted for the 32-bit version. When the text describes two near
and
far flavors of the same data structure, a single version using 32-bit
flat
pointers is to be used for the 32-bit product.
class B
{
int b1, b2;
};
class D:B
{
int d;
};
Chapter 1 Page 5
┌─────────────────┐
│ B::b1 │
├─────────────────┤
│ B::b2 │
├─────────────────┤
│ D::d │
└─────────────────┘
The compiler will insert a hidden 'unsigned int' (i.e. 16-bit for the
16-bit
compiler, 32-bit for the 32-bit compiler) displacement member
immediately
preceding the virtual base class sub-object when the following
conditions exist:
The compiler ensures that the derived class of a virtual base with
another
virtual base has the 'indirect' virtual base as its virtual base for
the
following reasons:
Chapter 1 Page 6
The compiler adds such virtual base classes following any user-
specified base
classes, in the order of construction, but the addition occurs only
when the
particular virtual base can't already be reached from the derived
class through
only one level of virtual inheritance. The presence of compiler-
added virtual
base classes doesn't have side-effects such as changing visibility
rules. A
compiler-added virtual base class is used for casts of pointers and
for pointers
of members of the virtual base. The representation of member
pointers is
discussed later.
class VB
{
int vb;
};
class D:virtual VB
{
int d;
};
┌─────────────────┐
│ VB sub-obj ptr ╞════╗
├─────────────────┤ ║
│ D::d │ ║
├─────────────────┤<═══╝
│ VB::vb │
└─────────────────┘
class VB1
{
int vb1;
};
class VB2
{
int vb2;
};
Chapter 1 Page 7
{
int b;
};
D ────> ┌─────────────────┐
│ A sub-obj ptr │═════════════════>═══════════╗
├─────────────────┤ ║
│ B sub-obj ptr │══════════════>══════════╗ ║
D::C ────> ├─────────────────┤ ║ ║
│ VB2 sub-obj ptr │═══════════>═══════╗ ║ ║
├─────────────────┤ ║ ║ ║
│ C::c │ ║ ║ v
├─────────────────┤ ║ v ║
***** ────> │ VB1 sub-obj ptr │═══════>═════╗ v ║ ║
├─────────────────┤ ║ ║ ║ ║
│ D::d │ ║ ║ ║ ║
D::VB1 ────> ├─────────────────┤ <═══════════║ ║ ║ ║
│ VB1::vb1 │ ║ ║ ║ ║
D::A ────> ├─────────────────┤ <══════<════║══<══║══<══║═<═╝
│ VB1 sub-obj ptr │══════>══════╝ ║ ║
├─────────────────┤ v v
│ A::a │ ║ ║
D::VB2 ────> ├─────────────────┤ <════════<════════╝ ║
│ VB2::vb2 │ ^ ║
D::B ────> ├─────────────────┤ <═══════════<═════║══<══╝
│ VB2 sub-obj ptr │ ═════════>════════╝
├─────────────────┤
│ B::b │
└─────────────────┘
The virtual base VB2 is reachable from D through only one level of
virtual
inheritance due to the base class C; therefore, VB2 isn't added by
the compiler
as a virtual base of D. The diagram shows the VB1 base pointer (see
*****),
which is added by the compiler.
class B
{
Chapter 1 Page 8
B();
virtual void f();
int b;
};
class X:virtual B
{
int x;
};
class Y:X
{
Y();
int y;
};
class Z:Y
{
int z;
};
Chapter 1 Page 9
┌──Y──> ┌─────────────────┐
^ │ B sub-obj ptr ├────>───┐
│ ├─────────────────┤ │
│ │ X::x │ │
│ ├─────────────────┤ │
│ │ X/Y vtable ptr │ │
│ ├─────────────────┤ v
│ │ Y::y │ │
│ ├─────────────────┤ │
│ │ Z::z │ │
│ ├─────────────────┤ │
v │ <displacement> │ │
└──B──> ├─────────────────┤ <──────┘
│ B::b │
├─────────────────┤
│ B vtable ptr │
└─────────────────┘
As shown by the diagrams, the displacement between the B sub-object
and the base
of Y differs by 2 bytes, depending on whether the object is of type
Y or Z. The
displacement member will be set to -2 in the constructor Z::Z before
X::X is
called. The displacement member is reset to zero after the call to
X::X has been
completed. The virtual table thunk for the Y::f entry in the B part
of X/Y's
vtable will adjust the value of this by the current value of the
displacement
member, which is zero unless the current object is being constructed
or
destructed.
Empty classes
The size of the this pointer defaults to the default pointer size
for the memory
model in effect. Declaring the class itself as near or far overrides
this
default. A derived class inherits the size of this from the first
base, and all
of the following bases (if any) must use the same this size.
Chapter 1 Page 10
members of the class, allowing many C++ structures with virtual
function members
to be easily shared with other languages, such as C.
In the huge memory model, the vtable pointer is always far, while in
all other
memory models, the vtable pointer defaults to near. Declaring a
class as huge or
_export has the following consequences:
Virtual tables
Chapter 1 Page 11
size_t member_offset;
________
The SI/MI data member pointer is an offset within the class instance
of the
member being pointed to with one added to it, allowing zero to be
used as a NULL
pointer.
______________________
size_t member_offset;
size_t vbcptr_offset;
________
Chapter 1 Page 12
Pointers to function members
Pointers to member functions resemble pointers to data members, except
they
always contain a function pointer. If the function is nonvirtual,
the function
pointer either points to the member function or to a virtual call
thunk that
uses the virtual mechanism to transfer control to an appropriate
virtual
function. The compiler creates such thunks automatically. When
calling through a
pointer to a member function, the appropriate value must be passed
to the
function for the this parameter. When calling using the ->*
operator, the value
equals the object pointer, while when calling using the .* operator,
the value
equals the address of the object. The address must be adjusted based
on
additional fields in the member pointer:
______________________
void (*func_addr)();
void (*func_addr)();
size_t member_offset;
________
The MI function member pointer adjusts the this value passed to the
member
function by member_offset - 1.
______________________
void (*func_addr)();
size_t member_offset;
size_t vbcptr_offset;
________
The VB function member pointer adjusts the this value passed to the
member
function with an algorithm similar to the one that adjusts offsets
for VB data
member pointers.
Chapter 1 Page 13
Static data members default to near in all memory models except the
huge model;
however, static data members of classes declared _export always
default to far
in all memory models.
__export/__import classes
Constructors
The compiler passes a constructor the address of object memory to be
constructed, or it passes a zero for this, in which case the
constructor
allocates the memory for the object through the operator new. If the
allocation
fails, the constructor immediately returns zero; in all other cases,
the
constructor returns the address of the object constructed.
The compiler gives constructors for classes with any virtual bases
(direct or
indirect) an extra int parameter to indicate the following action:
Chapter 1 Page 14
A nonzero means virtual bases have already been constructed by a
derived class
constructor.
Destructors
A destructor tests this for NULL before taking other action on an
object. If
this is NULL, the destructor immediately returns.
All destructors are passed an extra int parameter that contains two
bit flags:
0x01 When this bit is on, the destructor calls operator delete to
deallocate the
memory taken up by the object, then the destructor returns.
0x02 When this bit is on, all virtual bases are destroyed. This bit
is only used
for classes with virtual bases.
extern "C"
void _vector_apply_
(
void far * dest, // address of destination array
void far * src, // address of source array
size_t size, // size of each object
unsigned count, // number of objects
unsigned mode, // type of function to call
... // operator=/copy-constructor address
here
)
extern "C"
void _vector_applyv_
(
void far * dest,
void far * src,
size_t size,
unsigned count,
unsigned mode,
...
)
_vector_apply_ and _vector_vapply_ assign or copy-construct class
elements of
the type array of class type. Since the operator= or the copy-
constructor might
be a near or far function, and take a near or far this value, mode
is passed to
determine how to cast this. A near pointer must be passed for near
functions and
a far pointer for far functions, and it's impossible to determine
the argument
type until runtime; consequently, varargs is used to resolve the
problem. The
compiler guarantees that source and destination are both near or
both far.
Chapter 1 Page 15
The version with the v suffix passes a second argument of zero for
copy-
constructors of classes with virtual bases.
Chapter 1 Page 16
void _vector_delete_
(
void near * ptr, // address of array
size_t size, // size of each object
unsigned count, // how many objects
unsigned mode, // how to call
... // destructor address passed here
)
void _vector_delete_
(
void far * ptr,
size_t size,
unsigned long count,
unsigned mode,
...
)
Chapter 1 Page 17
far function 0x01
pascal call 0x02
far pointer 0x04
deallocate 0x08
stored element count 0x10
huge array (array > 64K) 0x40
Name mangling
1. @className@functionName$args
@className@...
The class name may be followed by a single digit; the digit value
contains the following bits (these can be combined):
See the next section on the encoding of function names and argument
types.
2. @functionName$args
3. @className@dataMember
@myClass@myMember
4. @className@
Chapter 1 Page 18
@outer@inner@...
t type argument
%vector$tl$ii$100%
Ordinary functions
Ordinary function names are encoded directly, as shown in the following
examples:
The string $qi denotes the integer argument of function foo; '$qv'
denotes no
arguments in sna::foo.
Chapter 1 Page 19
Constructors,
destructors, and
overloaded
operators_____________________________________________________________
Character Meaning
Sequence
_____________________________________________________________________
ctr constructor
dtr destructor
add +
adr &
and &
arow ->
arwm ->*
asg =
call ()
cmp ~
coma ,
dec --
dele delete
div /
eql ==
geq >=
gtr >
inc ++
ind *
land &&
lor ||
leq <=
lsh <<
lss <
mod %
mul *
neq !=
new new
not !
or |
rand &=
rdiv /=
rlsh <<=
rmin -=
rmod %=
rmul *=
ror |=
rplu +=
rrsh >>=
rsh >>
rxor ^=
sub -
Chapter 1 Page 20
subs []
xor ^
nwa new []
dla delete []
___________________________________________________________
The following examples show how arguments are encoded with character
sequences,
add, ctr, and dtr from the previous table:
Type conversions
Example:
The i following $o in the first example denotes int; the pzc in the
second
example denotes a near pointer to an unsigned char.
Encoding of arguments
The number and conbinations of function arguments make argument
encoding the
most complex aspect of name mangling.
Argument lists for functions begin with the characters $q. Type
qualifiers are
then encoded as shown in the following table:
________________________________________________________________________________
Character Meaning
Sequence
______________________________________________________________________
up huge
ur _seg
u unsigned
z signed
x const
w volatile
__________________________________________________________
________________________________________________________________________________
Character Meaning
Sequence
______________________________________________________________________
Chapter 1 Page 21
v void
c char
s short
i int
l long
f float
d double
g long double
e ...
_______________________________________________________________
________________________________________________________________________________
Character Meaning
Sequence
______________________________________________________________________
Chapter 1 Page 22
character, ranging from ASCII 31H - 39H and 61H - 7FH (1 to 9 and a
onward),
denotes which argument type to duplicate, as shown in the following
example:
@plot@func1$qdddiiilllpzctata is unmangled to
plot::func1(double, double, double, int, int, int, long,
long, long,
char near*, char near*, char near*)
The DDVT table always precedes the 'regular' virtual table for the
given class.
The DDVT is located at negative offsets from the virtual table
pointer. The
following layout shows the format of the DDVT:
The fpt and idt tables contain the addresses and IDs, respectively,
of all DDVT
functions introduced or overridden in the class. The count holds the
number of
entries in the tables. basep holds the address of the virtual table
for the base
class or zero if the class has no base; the size of the base class
pointer is
the same as the virtual table pointer for the class. The pointer is
a far
pointer for huge classes.
For example, consider the following two classes:
struct base
{
virtual f() = [11];
virtual g() = [22];
virtual h();
};
struct der:base
{
f();
virtual i() = [33];
h();
};
Chapter 1 Page 23
dw 11 ; ID for f()
dw 22 ; ID for g()
dw 2 ; 2 entries in DDVT
dw 0 ; no base class
base_vtable:
dd @base@h$qv ; addr of base::h()
dw 11 ; ID for f()
dw 33 ; ID for i()
dw 2 ; 2 entries in DDVT
CHAPTER
_________________________________________________
Value or
Length Description
____________________________
Chapter 2 Page 25
string
A descriptive name reflecting the name of the
translator used to generate this object file.
For instance "Turbo Assembler Version 2.0".
index
The index of the source file that caused the
record to be emitted.
Chapter 2 Page 26
word
The line number of the instruction in the source
code line that caused the record to be emitted.
The word is present only if the previous index
is nonzero.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
byte
If the symbol is a function with a valid BP, the
byte contains the third bit set to one (hex
0x8), and the upper four bits set to the number
of words between the BP value and the return
address.
index
Index of source file that caused this record to
be emitted.
word
The line number of the instruction in the source
code line that caused the record to be
emitted.The word is present only if the previous
index equals nonzero.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Chapter 2 Page 27
definition records must appear after the type for
the structure, and after all the types that the
member definition records reference.
1st byte:
* 0x60 Static member
* 0x50 Conversion
* 0x01
destructor
* 0x02
constructor
* 0x03
static member function
* 0x04
virtual member function
seventh bit
This bit is set to zero if next bit is a normal
member or to one if the next bit is a New
Offset record.
high bit
This bit is set to zero if there are more
members in the current structure or to one if
this is the last member in the structure.
string
The member name. A zero byte is used for
unnamed members. Since no explicit offset for
each member is given, offsets are computed by
counting the length of each member. When holes
exist from bit fields not filling a byte or
Chapter 2 Page 28
when word alignment is used, an unnamed member
is emitted. Such a member is always a bit field
member with the appropriate number of pad bits.
Although the compiler currently behaves
according to this description, it accepts
nonbit field unnamed members.
index
The member type. For conversions, this index
specifies the target type of the conversion,
for example int for "operator int();".
double word
The new byte offset of the records that follow
it. The double word allows variant records,
since each variant portion can be started with
a New Offset member. As a double word, this
field is suitable for large structures.
Index Type
___________________________________
1 void
2 signed char
4 signed short int
6 signed long int
8 unsigned char
10 unsigned short int
12 unsigned long int
14 float
15 double
16 long double
17 Pascal 6-byte real
Chapter 2 Page 29
18 Pascal boolean
19 Pascal character type
21 8-byte signed range
22 8-byte unsigned range
23 10-byte value (tbyte)
__________________
index
The index of the type being defined. All types
must have a valid index of twenty-four
(decimal) or greater, and the indices must be
unique within the object file. There's no
requirement to write types in any particular
order. All of the type indices for a given file
form a contiguous block beginning at twenty-
four and proceeding to the highest numbered
index. Since some types occupy eight bytes and
others sixteen bytes in the .EXE file, the TID
values requiring sixteen bytes reserve their
own type index as well as the next higher type
index.
string
The type name, if any exists. For C, the type
name is used only for structure, union, and
enum tags. For Pascal, any type might be named.
word
The size in bytes of the type.
TID byte
This is the TID of the type being defined.
These following list shows the :
_________________________________________________
Chapter 2 Page 30
Chapter 2 Page 31
Simple types
Labels
TID_LABEL
* double word
The lower bound of the range
Chapter 2 Page 32
* double word
The upper bound of the range
Cobol-style BCD
TID_BCDCOB
Chapter 2 Page 33
TID_SEG
0x0 ignored
TID_NREF
0x0 ignored
TID_FREF
0x0 ignored
Array types
TID_CARRAY
TID_VLARRAY
TID_PARRAY
Chapter 2 Page 34
Enumerated types
Function types
TID_FUNCTION
Chapter 2 Page 35
byte This byte is set to one if the function
accepts a variable number of arguments;
otherwise, it is zero.
Sets
TID_SET
Binary files
TID_BFILE
Member/duplicate functions
TID_SPECIALFUNC
C++ Class
TID_CLASS
Pointed-to members
TID_MEMBERPTR
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Chapter 2 Page 38
SC_STATIC (0)
index The group index of the symbol.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
SC_ABSOLUTE (1)
index The segment index of the segment
containing the symbol. For an absolute
symbol the index must be an absolute
segment.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
SC_REGISTER (4)
byte A register id. Register ids map to
registers as follows:
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Chapter 2 Page 39
SC_CONST (5)
dword The 32-bit constant value.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
SC_OPT (8)
index The number of entries for this local.
Each entry represents a different
location for the local for a different
set of code offsets; hence, a single
SC_OPT sub-record represents a complete
list of optimized symbol records for
the debugger. The following section
describes the format of the entries:
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
SC_REGISTER
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Chapter 2 Page 41
2nd byte
Chapter 2 Page 42
0xeb External symbol matched type index
The following fields are repeated as many times
as necessary to fit in the record.
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Chapter 2 Page 43
If the debug information version record 3.1 appears in the object file,
the following fields are present:
First is a 16-bit file index.
If this is zero, there is no reference info.
If this is non-zero, there follow a set of line
numbers with special encodings.
Each line number is stored as a delta from the previous line number,
with the starting line number after a file index being 0. By
default, the delta is stored in a byte, with the low 6 bits being
the line number, and the 7th bit being a toggle to specify whether
this is a reference or an assignment. If the 7th bit is set, it is
an assignment. If the byte is greater then or equal to 0xf0, then
it is a special encoding with the following meaning:
0xff Next byte/word is a file index, with an absolute
word line number following.
0xfe The absolute line number is stored in the next word,
and this is a reference.
0xfd The absolute line number is stored in the next word,
and this is an assignment.
Class descriptions
Class descriptions have the following format:
Note
Chapter 2 Page 45
SC_STATIC (0)
index The group index of
the segment
containing the
symbol.
Chapter 2 Page 46
Chapter 2 Page 47
Chapter 2 Page 48
VIRDEF Records
Chapter 2 Page 49
different segments unless it results in
overflows.
Chapter 2 Page 50
CHAPTER
_________________________________________________
struct debug_header
{
unsigned short magic_number; /* To be sure
who we are */
unsigned short version_id; /* In case we
change things */
unsigned long names; /* Names pool
size in bytes */
unsigned long names_count; /* Number of
names in pool */
unsigned long types_count; /* Number of
type entries */
unsigned long members_count; /* Structure
members table */
unsigned long symbols_count; /* Number of
symbols */
unsigned long globals_count; /* Number of
global symbols */
unsigned long modules_count; /* Number of
modules (units)*/
unsigned long locals_count; /* optional;
can be filler*/
unsigned long scopes_count; /* Number of
scopes in table*/
Chapter 3 Page 51
struct header_extension
{
Chapter 3 Page 52
EXE header
fixups
EXE image
Chapter 3 Page 53
debug header
Symbol Table
Module Table
Source File Table
Scopes Table
Line Number Table
Segments Table
Correlation Table
Type Table
Members Table
Class Table
Parent Table
Scope Class Table
Module Class Table
Coverage Map Table
Coverage Offsets Table
Browser Definitions Table
Optimized Symbols Table
Module Optimization Flags Table
Reference Information Table
Names Table
Symbols
struct symbol_record
{
unsigned long symbol_name;
unsigned long symbol_type;
unsigned short symbol_offset;
Chapter 3 Page 54
Chapter 3 Page 55
Chapter 3 Page 56
Modules
struct module_header
{
unsigned long module_name;
unsigned char language;
unsigned short memory_model : 3;
unsigned short underbars_on : 1;
unsigned long symbols_index;
unsigned short symbols_count;
unsigned short source_files_index;
unsigned short source_files_count;
unsigned short correlation_index;
unsigned short correlation_count;
};
Chapter 3 Page 57
source_files_index is the index of the first
source file record for the module.
Value Language
_________________________________
0 Unknown
1 C
2 Pascal
3 Basic (not used)
4 assembly language
5 C++
______________________________________
Source files
struct source_file
{
unsigned long source_file_name;
unsigned long time_stamp;
};
Chapter 3 Page 58
The line numbers for a segment within a source
file will appear as a block in the line number
table.
Line numbers
struct line_number
{
unsigned short line_number_value;
unsigned short line_number_offset;
};
Chapter 3 Page 59
Scopes
struct scope
{
unsigned long autos_index;
unsigned short autos_count;
unsigned short parent_scope;
unsigned long function_symbol;
unsigned short scope_offset;
unsigned short scope_length;
};
Segments
Chapter 3 Page 60
{
unsigned short mod_index;
unsigned short code_segment;
unsigned short code_offset;
unsigned short code_length;
unsigned short scopes_index;
unsigned short scopes_count;
unsigned short correlation_index;
unsigned short correlation_count;
} segrec;
Chapter 3 Page 61
typedef struct
{
unsigned short segment_index;
unsigned short file_index;
unsigned long lines_index;
unsigned short lines_count;
} correlation;
Types
type_id 1 0
type_name 4 1
type_size 2 5
________________
Chapter 3 Page 62
_________________________________________________
Pascal strings
(12 bytes)
Field Size Offset
______________
max_size 1 7
________________
parent type 2 8
lower bound 4 12
upper bound 4 16
________________
Chapter 3 Page 63
_________________________________________________
BCD COBOL
(12 bytes)
Field Size Offset
___________
decimal point 1 5
_____________
_________________________________________________
extra info 1 7
pointed-to type 4 8
_____________
_________________________________________________
element type 4 8
_____________
_________________________________________________
Very large arrays
(12 bytes)
Field Size Offset
___________
object size 2 7
element type 4 9
_____________
Pascal arrays______________________________
(24 bytes)
Field Size Offset
___________
element type 4 8
dimension type 4 12
_____________
Chapter 3 Page 65
_________________________________________________
Enums (24 bytes)
Field Size Offset
___________
lower bound 2 12
upper bound 2 14
members index 4 16
____________
Functions______________________________
(12 bytes)
Field Size Offset
___________
language 0:7 7:0
*
accepts var. args. 0:1 7:7
return type 4 8
*
These should be read as byte:bit
________________
Binary files______________________________
(12 bytes)
Field Size Offset
___________
element type 4 8
_____________
Chapter 3 Page 66
Function prototypes______________________________
(24 bytes)
Field Size Offset
___________
language 0:7 7:0
*
accepts var. args. 0:1 7:7
return type 4 8
parameter start 2 12
*
These should be read as byte:bit
________________
Value Description
__________________________
Special functions______________________________
(24 bytes)
Field Size Offset
__________
language 1 7
return type 4 8
class type 4 12
virtual offset 2 16
Chapter 3 Page 67
symbol index 4 18
info bits 1 22
____________
Value Description
______________________________
0x01 member function
TID_MEMBERPTR____________________________________
Field Size Offset
__________
Chapter 3 Page 68
type index 4 8
base class index 2 12
____________
TID_NEWMEMBERPTR
_________________________________
TID_HANDLEPTR
____________________________________
Chapter 3 Page 69
struct type_rec
{
unsigned char type_id; /* The TID
byte. */
unsigned long type_name; /* Any
associated type name. */
unsigned short type_size; /* The size of
any object */
/* of this
type. */
union
{
/* For TID_VOID, TID_LSTR, TID_DSTR,
TID_SQUAD,
TID_UQUAD, TID_FLOAT, TID_PREAL,
TID_DOUBLE,
TID_LDOUBLE, TID_BCD4, TID_BCD8,
TID_BCD10,
TID_ADESC, TID_LABEL, TID_TFILE,
TID_BOOL,
Chapter 3 Page 70
struct
{ /* only for TID_PSTR */
unsigned char max_size; /* Max
string size */
} pstr;
/*^L*/
struct
{
/* for TID_PCHAR, TID_SCHAR,
TID_SINT, TID_SLONG,
TID_UCHAR, TID_UINT and TID_ULONG
types */
struct
{ /* for TID_BCDCOB only */
unsigned char decimal; /* Number
of digits to */
/* right
of decimal point. */
} bcd;
struct
{ /* TID_LABEL only */
unsigned char nearfar; /* 0
for near, 1 for far */
} label;
struct
{ /* for TID_NEAR, TID_FAR,
TID_NEAR386, TID_FAR386 */
Chapter 3 Page 71
0x1 ES relative
0x2 CS relative
0x3 SS relative
0x4 DS relative
0x5 FS relative
0x6 GS relative
struct
{ /* For TID_SEG, TID_NREF, TID_FREF
*/
struct
{ /* For TID_CARRAY only */
struct
{ /* For TID_VLARRAY only */
struct
{ /* For TID_PARRAY only */
struct
{ /* For TID_STRUCT and TID_UNION */
Chapter 3 Page 72
struct
{ /* For TID_ENUM and TID_PENUM */
struct
{ /* For TID_FUNCTION only */
unsigned language : 7;
unsigned is_varargs : 1; /*
Accepts Var args */
unsigned long return_type;
} function;
/*
The language field is as follows:
Chapter 3 Page 73
struct
{ /* For TID_FUNCPROTOTYPE only */
unsigned language : 7; /*
see TID_FUNCTION */
unsigned is_varargs : 1; /*
Accepts Var args */
unsigned long return_type;
unsigned short param_start; /*
starting index */
/*
in members table */
} funcprototype;
struct
{ /* For TID_SET only */
struct
{ /* For TID_BFILE only */
struct
{ /* For TID_SPECIALFUNC only */
struct
{ /* For TID_CLASS only */
struct
{ /* For TID_MEMBERPTR */
Chapter 3 Page 74
unsigned char filler;
unsigned long type_index;
unsigned short class_index;
} memberptr;
} v;
};
Members
struct member_type
{
unsigned bit_field_size : 6;
unsigned offset_rec : 1;
unsigned end_of_structure: 1;
unsigned long member_name;
unsigned long member_type;
};
/****************************************
The member_name is the index of the name.
The member_type is the index of the type.
****************************************/
struct enum_list_type
{
unsigned filler : 7;
unsigned end_of_list : 1;
unsigned long enum_name;
signed short enum_value;
};
end_of_list is 1 for the last enum value in the
list.
Chapter 3 Page 75
typedef union
{
struct struct_offset_rec o;
struct member_type m;
struct enum_list_type e;
} member_rec;
typedef struct {
unsigned short parent_index; /* index into
parent table */
unsigned short parent_count;
unsigned long member_index;
unsigned long name_index; /* tag */
unsigned short virtual_ptr; /* Offset from
top of class data of
Chapter 3 Page 76
virtual ptr*/
unsigned char info;
/* Info bits:
bit 0: Class is a
virtual base class
bit 1: Class is public
bit 2-7: Offset of method
in virtual table */
} class;
Chapter 3 Page 77
Special cases
If member_record == 0x40, record is a reset
offset record.
typedef struct
{
unsigned short class_index; /* index
into class table */
} parent;
typedef struct
{
unsigned short class_index; /* index
into class table */
unsigned short class_count; /* number
of classes */
} scope_class;
Chapter 3 Page 78
typedef struct
{
unsigned short offset; /* index into
Coverage Offset Table */
} TCoverageOffsetMapTableEntry;
Chapter 3 Page 79
typedef struct
{
unsigned short offset; /* offset
into segment */
} TCoverageOffsetTableEntry;
struct TDefinitionRecord
{
unsigned long symbol_index; /* The index of
the symbol in */
/* the Symbols
table */
unsigned short file_index; /* Which file
the symbol is in */
unsigned short line_number; /* line number
in the file */
};
struct opt_symbol_record {
unsigned short opt_symbol_next;
/* index to next record for
this symbol */
unsigned short opt_symbol_offset;
/* offset is treated as a
register enum */
/* See the Symbols section
for details */
unsigned char opt_symbol_class;
/* Interpreted as for
symbol_record */
unsigned short
opt_symbol_code_offset_start;
/* start of optimization
range */
Chapter 3 Page 80
Chapter 3 Page 81
#define MO_codeMotion 0x0008
#define MO_regAlloc 0x0010
#define MO_loadOptim 0x0020
#define MO_loopOpt 0x0040
#define MO_intrinsics 0x0080
#define MO_deadStorElim 0x0100
#define MO_copyProp 0x0200
#define MO_jumpOpt 0x0400
#define MO_speed_size 0x0800
#define MO_noAliasing 0x1000
Names
typedef struct
{
unsigned short overlay_list; /* start of
linked list of overlay */
/* header segs
*/
unsigned short overlay_size; /* smallest
overlay buffer that */
/* can be used
*/
void far * debugger_hook; /* ptr to
routine in debugger */
} overlay;
Chapter 3 Page 82
CHAPTER
_________________________________________________
Chapter 4 Page 85
TSection
┬───────
├─TOptionSection Compiler, linker, and other
information shown in the
Options menu
├─THeaderSection Date and time of the project
├─TTransferSection Information shown in
Options|Transfer
├─TNoteSection Contents of Window|Project
note
├─TModuleSection Contents of Project Window
├─TDependencySection Contents of Project|View
includes
└─TExtensionSection Miscellaneous string
contents of Project|Local
Options, referenced by
TModuleSection
OptionSection X
HeaderSection X
TransferSection X
NoteSection X
ModuleSection X X
DependencySection X X
ExtensionSection X
_____________________
Chapter 4 Page 86
TRANCOPY syntax
TRANCOPY [-r] <source project> <destination
project>
Chapter 4 Page 87
destination section. With the -r option, the
previous transfer items are replaced. The
TRANCOPY executable ships with both Turbo C++ for
Windows and Borland C++.
STRIPPRJ syntax
STRIPPRJ <source project> <destination
project>
┌────────────────────┐
│ Header │
├────────────────────┤
│ Option section │
├────────────────────┤
│ Header section │
├────────────────────┤
│ Transfer section │
├────────────────────┤
│ Note section │
├────────────────────┤
│ Module section │
├────────────────────┤
│ Dependency section │
├────────────────────┤
│ Extension section │
├────────────────────┤
│ -1 (0xFFFF) │
└────────────────────┘
If you use the Project file utilities you
probably won't have to learn the Project file
format. The class hierarchy does most of the work
for you. The rest of this chapter documents the
format for direct access.
Chapter 4 Page 88
validity. The following seven sections differ in
structure and kinds of information they contain.
However, they each have a section header to
identify Block Type and size of the data area.
Header information
variable length: VisibleIDString = "Turbo C
Project File ^Z"
String designed to display if the project file
is listed to the screen (null terminated).
2 bytes: Version
Unsigned version number that is written into
the project file when it is created. For
internal use. The version number changes
whenever any change occurs in either the
project file format or data. This version must
match that held in the IDE, or the project
manager will not accept the file. The current
version is 0x0701. In the file, the number
reads 01 07 due to byte swapping.
┌───────────────────┐
2 │ Block Type = 50 │
├───────────────────┤
2 │ Data size = n │
╞═══════════════════╡
2 │ ID 1 │ │
├───────────────────┤ │
2 │ Option 1 size = x │ │
├───────────────────┤ │
x │ Data for Option 1 │ │
╞═══════════════════╡ │
2 │ ID 2 │ │
├───────────────────┤ │
2 │ Option 2 size = y │ │
├───────────────────┤ n
y │ Data for Option 2 │ │
╞═══════════════════╡ │
. . . │
├───────────────────┤ │
2 │ ID = 0XFFFF │ │
├───────────────────┤ │
2 │ Size = 0 │ │
└───────────────────┘
variable length data: array of structures. For
each Options menu item:
2 bytes: Option ID
┌───────────────────┐
2 │ Block Type = 51 │
├───────────────────┤
2 │ Size = 6 │
╞═══════════════════╡
2 │ Reserved │
├───────────────────┤
4 │ Project age │
└───────────────────┘
2 bytes: Reserved
seconds: 5 bits
minutes: 6 bits
hour: 5 bits
day: 5 bits
month: 4 bits
year: 7 bits
┌───────────────────┐
2 │ Block Type = 10 │
├───────────────────┤
2 │ Size = n │
╞═══════════════════╡
323 │ Transfer 1 │ │
├───────────────────┤ │
323 │ Transfer 2 │ │
├───────────────────┤ │
. . . n
├───────────────────┤ │
323 │ Transfer k (last) │ │
├───────────────────┤
│
323 │ Transfer k + 1 │ │
│ Translator = 0xFF │ │
└───────────────────┘
Chapter 4 Page 92
┌───────────────────┐
2 │ Block Type = 52 │
├───────────────────┤
2 │ Size = n │
╞═══════════════════╡
n │ ASCII text of note│
└───────────────────┘
variable length data after the header. You can
edit the note in Block Type 52 (34 00 in the
file).
┌───────────────────┐
2 │ Block Type = 53 │
├───────────────────┤
2 │ Size = n │
╞═══════════════════╡
108 │ Module 1 │ │
├───────────────────┤ │
108 │ Module 2 │ │
├───────────────────┤ │
. . . n
├───────────────────┤ │
108 │ Module k (last) │ │
├───────────────────┤ │
108 │ Module k + 1 │ │
│ ProjectItemType = │ │
│ NoMoreItems │ │
└───────────────────┘
2 bytes: ProjectItemType =
reserved 0x0001
reserved 0x0002
Translator 0x0004
Chapter 4 Page 93
2 bytes: reserved: (= 0)
2 bytes: Reserved
Chapter 4 Page 94
┌─────────────────────────┐
2 │ Block Type =
54 │
├─────────────────────────┤
2 │ Size =
n │
╞═════════════════════════╡
2 │ number of
offsets = m+2 ││
├─────────────────────────┤P
2 │0 │a
├─────────────────────────┤r
2 │offset 1 (index
2) │t
├─────────────────────────┤
2 │offset 2 (index
3) │1
├───── . . . ─────────────┤│
2 │offset m (index
m+1) ││
├─────────────────────────┤│
2 │0xFFFF ││
╞═════════════════════════╡│
. . .
╞═════════════════════════╡
2 │Type = 00 (from
offset 1)│P
├─────────────────────────┤a
2 │Number of
dependencies │r
├─────────────────────────┤t
x │Array of dependencies │
╞═════════════════════════╡2
. . .
╞═════════════════════════╡
1 │Type = FF (from
offset 2)││
├─────────────────────────┤P
4 │Age of
dependency │a
├─────────────────────────┤r
y │File name of
dependency │t
╞═════════════════════════╡
. . . 3
└─────────────────────────┘
Chapter 4 Page 95
2 bytes: Type = 00 00
1 byte: Type = FF
Chapter 4 Page 96
Prepare as follows:
4. Count 2*index.
Chapter 4 Page 97
6. Go to this offset. See Part 3 on the diagram.
┌─────────────────────────┐
2 │ Block Type =
55 │
├─────────────────────────┤
2 │ Size =
n │
╞═════════════════════════╡
2 │ number of
offsets = m+2 ││
├─────────────────────────┤│
2 │0 │P
├─────────────────────────┤a
2 │offset 1 (index
2) │r
├─────────────────────────┤t
2 │offset 2 (index
3) │
├───── . . . ─────────────│1
2 │offset m (index
m+1) ││
├─────────────────────────┤│
2 │0xFFFF ││
╞═════════════════════════╡
. . .
╞═════════════════════════╡
x │String1 │P
├─────────────────────────┤a
y │String2 │r
├─────────────────────────┤t
z │String3 │
├────── . . . ────────────┤2
zz│Stringm ││
└─────────────────────────┘
Chapter 4 Page 98
Prepare as follows:
Chapter 4 Page 99
Chapter 5 Page 100
CHAPTER
________________________________________________________________________________
The BGI
driver toolkit
________________________________________________________________________________
File Name File Description
__________________________________________________
All code and data references in the driver must be near (i.e., small
model,
offset only), and the entire driver, both code and data, must fit
within 64K. In
When considering the functions listed here, keep in mind that BGI
performs most
drawing operations using an implicit drawing or tracing color
(COLOR), fill
color (FILLCOLOR), and pattern (FILLPATTERN). For example, the
PIESLICE call
accepts no pattern or color information, but instead uses the
previously set
COLOR value to trace the edge of the slice, and the previously set
FILLCOLOR and
FILLPATTERN values for the interior.
Header Section
CODESEG
dw EMULATE
BGI requires that each driver contain a Driver Status Table (DST) to
determine
the basic characteristics of the device that the driver addresses.
As an
example, the DST for a CGA display is shown here:
STATUS STRUC
STAT DB 0 ; Current Device Status (0 = No Errors)
DEVTYP DB 0 ; Device Type Identifier (must be 0)
XRES DW 639 ; Device Full Resolution in X Direction
YRES DW 199 ; Device Full Resolution in Y Direction
XEFRES DW 639 ; Device Effective X Resolution
YEFRES DW 199 ; Device Effective Y Resolution
XINCH DW 9000 ; Device X Size in inches*1000
YINCH DW 7000 ; Device Y Size in inches*1000
ASPEC DW 4500 ; Aspect Ratio = (y_size/x_size) *
10000
DB 8h
DB 8h ; for compatibility, use these values
DB 90h
DB 90h
STATUS ENDS
The BGI interface provides a system for reporting errors to the BGI
Kernel and
to the higher level code developed using Borland's language
packages. This is
done using the STAT field of the Driver Status Table. This field
should be
filled in by the driver code if an error is detected during the
execution of the
device installation (INSTALL). The following error codes are
predefined in
include file GRAPHICS.H for Turbo C and in the Graphics unit for
Turbo Pascal.
grInvalidFont = -13
grInvalidFontNum = -14
grInvalidDeviceNum = -15
The next field in the Device Status Table, DEVTYP, describes the
class of the
device that the driver controls; for screen devices, this value is
always 0.
The next four fields, XRES, YRES, XEFRES, and YEFRES, contain the
number of
pixels available to BGI on this device in the horizontal and
vertical
dimensions, minus one. For screen devices, XRES=XEFRES and
YRES=YEFRES. The
XINCH and YINCH fields are the number of inches horizontally and
vertically into
which the device's pixels are mapped, times 1000. These fields in
conjunction
with XRES and YRES permit device resolution (DPI, or dots per inch)
calculation.
The routines in the device driver are accessed via a vector table.
This table is
at the beginning of the driver and contains 16-bit offsets to
subroutines and
configuration tables within the driver. The format of the vector
table is shown
below.
VECTOR_TABLE:
Vector Descriptions
The Kernel calls the INSTALL vector to prepare the device driver for
use. A
function code is passed in AL. The following function codes are
defined:
Return:
ES:BX --> Device Status Table (see STATUS structure)
Return:
CX The number of modes supported by this device.
The MODE QUERY function inquires about the maximum number of modes
supported by
this device driver.
Return:
ES:BX --> a Pascal string containing the name
The MODE NAMES function inquires about the ASCII form of the mode
number present
in CX. The return value in ES:BX points to a Pascal string
describing the given
mode. (Note: A Pascal, or _length_, string is a string in which the
first byte
of data is the number of characters in the string, followed by the
string data
itself.) To ease access to these strings from C, the strings should
be followed
by a zero byte, although this zero byte should not be included in
the string
length. The following is an example of this format:
==================================================================
Input:
ES:BX --> Device Information Table
Return:
Nothing
struct DIT
DB 0 ; Background color for initializing
screen
DB 0 ; Init flag; 0A5h = don't init; anything
; else = init
DB 64 dup 0 ; Reserved for Borland's future use
; additional user information here
DIT ends
==================================================================
Input:
Nothing
Return:
Nothing
This vector clears the graphics device to a known state. In the case
of a CRT
device, the screen is cleared. In the case of a printer or plotter,
the paper is
advanced, and pens are returned to the station.
Input:
Nothing
Return:
Nothing
Input:
AX the new CP x coordinate
BX the new CP y coordinate
Return:
Nothing
Input:
AX The ending x coordinate for the line
Chapter 5 Page 107
Return:
Nothing
Input:
AX X1; The beginning X coordinate for the line
BX Y1; The beginning Y coordinate for the line
CX X2; The ending X coordinate for the line
DX Y2; The ending Y coordinate for the line
Return:
Nothing
Input:
AX X--right edge of rectangle
BX Y--bottom edge of rectangle
CX 3D = width of 3D bar (ht := .75 * wdt); 0 = no 3D
effect
DX 3D bar top flag; if CX <> 0, and DX = 0, draw a top
Return:
Nothing
Input:
AX X1--the rectangle's left coordinate
BX Y1--the rectangle's top coordinate
CX X2--the rectangle's right coordinate
DX Y2--the rectangle's bottom coordinate
Return:
Nothing
Fills (but doesn't outline) the indicated rectangle with the current
fill
pattern and fill color.
Input:
AX The starting angle of the arc in degrees (0-360)
BX The ending angle of the arc in degrees (0-360)
CX X radius of the elliptical arc
DX Y radius of the elliptical arc
Return:
Nothing
ARC draws an elliptical arc using the (CP) as the center point of
the arc, from
the given start angle to the given end angle. To get circular arcs
the
application (not the driver) must adjust the Y radius as follows:
Input:
AX The starting angle of the slice in degrees (0-360)
BX The ending angle of the slice in degrees (0-360)
CX X radius of the elliptical slice
DX Y radius of the elliptical slice
Return:
Nothing
PIESLICE draws a filled elliptical pie slice (or wedge) using CP as
the center
of the slice, from the given start angle to the given end angle. The
current
FILLPATTERN and FILLCOLOR is used to fill the slice and it is
outlined in the
current COLOR. To get circular pie slices, the application (not the
driver) must
adjust the Y radius as follows:
Input:
AX X Radius of the ellipse
BX Y Radius of the ellipse
Return:
Nothing
This vector draws a filled ellipse. The center point of the ellipse
is assumed
to be at the current pointer (CP). The AX Register contains the X
Radius of the
ellipse, and the BX Register contains the Y Radius of the ellipse.
Input:
AX The index number and function code for load
BX The color value to load into the palette
Return:
Nothing
The PALETTE vector loads single entries into the palette. The
register AX
contains the function code for the load action and the index of the
color table
entry to be loaded. The upper two bits of AX determine the action to
be taken.
The table below tabulates the actions. If the control bits are 00,
the color
table index in (AX AND 03FFFh) is loaded with the value in BX. If
the control
bits are 10, the color table index in (AX AND 03FFFh) is loaded with
the RGB
value in (Red=BX, Green=CX, and Blue=DX). If the control bits are
11, the color
table entry for the background is loaded with the value in BX.
==================================================================
Input:
ES:BX --> array of palette entries
Return:
Nothing
The ALLPALETTE routine loads the entire palette in one driver call.
The register
pair ES:BX points to the table of values to be loaded into the
palette. The
number of entries is determined by the color entries in the Driver
Status Table.
The background color is not explicitly loaded with this command.
Input:
AL The index number of the current drawing color
AH The index number of the fill color
Return:
Nothing
The COLOR vector determines the current drawing color. The value in
AL is the
index into the palette of the new current drawing color. The value
in the AH
The fill color is used for the interior color for the bar, polygons,
pie slice,
and floodfill primitives.
==================================================================
Input:
AL Primary fill pattern number
ES:BX If pattern number is 0FFh, points to user-defined
pattern mask.
Return:
Nothing
Sets the fill pattern for drawing. The fill pattern is used to fill
all bounded
regions (BAR, POLY, and PIESLICE). The numbers for the predefined
fill patterns
are as follows:
Input:
AL Line pattern number
BX User-defined line drawing pattern
CX Line width for drawing
Return:
Nothing
Sets the current line-drawing style and the width of the line. The
line width is
either one pixel or three pixels in width. The following table
defines the
default line styles:
Input:
AL Hardware font number
AH Hardware font orientation
0 = Normal, 1 = 90 Degree, 2 = Down
BX Desired X Character (size in graphics units)
CX Desired Y Character (size in graphics units)
Return:
BX Closest X Character size available (in graphics units)
CX Closest Y Character size available (in graphics units)
The TEXTSTYLE vector defines the attributes of the hardware font for
output. The
parameters affected are the hardware font to be used, the
orientation of the
font for output, the desired height and width of the font output.
All subsequent
text will be drawn using these attributes.
For example, if the desired font is 8x10 pixels and the device
supports 8x8 and
16x16 fonts, the closest match will be the 8x8. The output of the
function will
be BX = 8, and CX = 8.
Input:
ES:BX --> ASCII text of the string
CX The length (in characters) of the string.
This function sends hardware text to the output device. The text is
output to
the device beginning at the (CP). The (CP) is assumed to be at the
upper left of
the string.
Input:
ES:BX --> ASCII text of the string
CX The length (in characters) of the string.
Return:
BX The width of the string in graphics units.
CX The height of the string in graphics units.
Input:
AX The x coordinate for the seed point
BX The y coordinate for the seed point
CL The boundary color for the Flood Fill
Return:
Nothing (Errors are returned in Device Status STAT field).
Input:
AX The x coordinate for the seed point
BX The y coordinate for the seed point
Return:
DL The color index of the pixel read from the screen.
GETPIXEL reads the color index value of a single pixel from the
graphics screen.
The color index value is returned in the DL register.
Input:
AX The x coordinate for the seed point
BX The y coordinate for the seed point
DL The color index of the pixel read from the screen.
Chapter 5 Page 113
Return:
Nothing
PUTPIXEL writes a single pixel with the the color index value
contained in the
DL register.
Input:
Nothing
Return:
ES:BX --> BitMap Utility Table.
The BITMAPUTIL vector loads a pointer into ES:BX, which is the base
of a table
defining special case-entry points used for pixel manipulation.
These functions
are currently only called by the ellipse emulation routines that are
in the BGI
Kernel. If the device driver does not use emulation for ellipses,
this entry
does not need to be implemented. This entry was provided because
some hardware
requires additional commands to enter and exit pixel mode, thus
adding overhead
to the GETPIXEL and SETPIXEL vectors. This overhead affected the
drawing speed
of the ellipse emulation routines. These entry points are provided
so that the
ellipse emulation routines can enter pixel mode, and remain in pixel
mode for
the duration of the ellipse-rendering process.
This function has the same format as the PUTPIXEL entry described
previously.
This function has the same format as the GETPIXEL entry described
previously.
This function returns the number of bits per pixel (color depth) of
the graphics
hardware in the AX register.
This function take the desired page number in the AL register and
selects
alternate graphics pages for output of graphics primitives.
This function take the desired page number in the AL register and
selects
alternate graphics for displaying on the screen.
Input:
ES:BX Points to the buffer in system memory to be written.
ES:[BX]
contains the width of the rectangle -1. ES:[BX+2] contains the
heigth of the
rectangle -1.
Return:
Nothing
Input:
ES:BX Points to the buffer in system memory to be read.
ES:[BX]
contains the width of the rectangle -1. ES:[BX+2] contains the
heigth of the
rectangle -1.
2: OR mode
3: AND mode
4: Complement mode
Return:
Nothing
The RESTOREBITMAP vector loads screen pixels from the system memory.
The routine
reads a stream of bytes from the system memory into the rectangle
defined by
(SI,DI) - (CX,DX). The value in the AL register defines the mode
that is used
for the write. The following table defines the values of the
available write
modes:
==================================================================
Input:
AX Upper Left X coordinate of clipping rectangle
BX Upper Left Y coordinate of clipping rectangle
CX Lower Right X coordinate of clipping rectangle
DX Lower Right Y coordinate of clipping rectangle
Return:
Nothing
Return:
BX The size of the color lookup table.
CX The maximum color number allowed.
Chapter 5 Page 116
The COLOR TABLE SIZE query determines the maximum number of colors
supported by
the hardware. The value returned in the BX register is the number of
color
entries in the color lookup table. The value returned in the CX
register is the
highest number for a color value. This value is usually the value in
BX minus
one; however, there can be exceptions.
Return:
ES:BX --> default color table for the device
The DEFAULT COLOR TABLE function determines the color table values
for the
default (power-up) color table. The format of this table is a byte
containing
the number of valid entries, followed by the given number of bytes
of color
information.
The source code for a sample, albeit unusual, BGI device driver is
included with
this Toolkit to assist developers in creating their own. The
demonstration
driver is provided in two files, DEBVECT.ASM and DEBUG.C. This
"Debug" driver
doesn't actually draw graphics, but instead simply sends descriptive
messages to
the console screen (via DOS function call 9) upon receiving
commands. Instead of
simply playing back commands, your own driver would be structured
similarly, but
would access control ports and screen memory to perform each
function.
Cookbook
The resulting driver is now ready for testing. Examine the file
TEST.C for an
example of installing, loading, and calling a newly created device
driver.
Examples
; To call any BGI function from assembly language, include the
; structure below and use the CALLBGI macro.
CALLBGI MACRO P
MOV SI,$&P ; PUT OPCODE IN (SI)
CALL CS:DWORD PTR BGI_ADD ; BGI_ADD POINTS TO DRIVER
ENDM
MOV AX, 10
MOV BX, 15
MOV CX, 200
MOV DX, 300
CALLBGI VECT
; To index any item in the status table, include the status table
; structures below and use the BGISTAT macro.
BGISTAT ASPEC
MOV AX, ES:[SI] ; (AX)= Y/X *10000
CHAPTER
________________________________________________________________________________
6
Borland
Help system
This chapter defines the Borland Help system, including the source
text file
format, binary Help file format, and the run-time Help engine, all
of which are
necessary to support the following features:
Turbo Examples.
You can use the information provided in this chapter to write Help
for your own
products. The Help Linker (HL.EXE) is provided on the disk that
accompanies this
book. The Help files it produces are compatible with THELP.COM, a
utility
provided with most Borland compilers.
Wordwrap
The right margin for wrapping is based on the window width, and is
independent
of where the text is relative to the window. This means scrolling
text
horizontally through the window will not cause re-wrapping; only
resizing the
window causes re-wrap. The value specified in field leftMargin of
the binary
file File Header Record is also applied to the right edge of the
window when
determining the right margin for wrapping, but not for truncation of
non-
Chapter 6 Page 119
Wrapping causes lines to move into and out of the display window at
the bottom
of the window only. It never affects lines above the wrapping line.
All hyphenated words in wrappable text must be removed from the Help
source
text. Here are the rules for wrapping at run time (breaking a line
into two or
more lines when the Help display window is too narrow to display the
complete
line):
Here are rules for converting hard returns to soft returns (allowing
text to
flow from the next line to fill the current line to the right
margin):
These rules allow the existing Help text to wrap correctly with
little or no
change.
Only one Turbo Example is allowed per Help topic, where a topic is
defined as
the set of all contexts (screens, pages) joined through the
upContext/downContext fields of a keyword record.
Keywords cannot be nested in Turbo Examples and vice versa. The text
of a Turbo
Example can extend over several contexts (screens, pages), and can
include both
wrapping and non-wrapping text.
UpArrow
DownArrow
LeftArrow
RightArrow
CtrlLeftArrow
CtrlRightArrow
Like Ctrl Left, except moves the cursor right to the start of the
next word.
Home
End
PgUp
Shift
If the Shift key is held down, and one or more sequences of the
previous cursor
control keys are pressed, a block of Help text will be selected. The
block
includes the character position at which the cursor was originally
positioned,
up to but not including the final resting position of the cursor.
The block is
Tab
Selects the next keyword in the current topic text. If the last
keyword in the
topic is currently selected, then selects the first keyword in the
topic. If
there are no keywords in the topic, ignores the command. If the next
keyword is
not currently displayed in the window, scrolls the window
horizontally and/or
vertically to place the keyword text just inside the window.
ShiftTab
Enter
clicking
Clicking moves the cursor to the mouse cursor position, and cancels
selected
text, if any. If the mouse cursor is on a keyword, the keyword
becomes the
active keyword.
Shift
clicking
Shift+clicking causes the current block of selected text to be
extended to the
cursor position.
double clicking
Double clicking moves the cursor to the mouse cursor position, and
cancels
selected text, if any.
right button
No action is defined for the right mouse button in the Help window.
dragging
Scroll bars
Scroll bars are supported in the usual manner for scrolling Help
topic text
within the window.
F1
AltF1
CtrlF1
Esc
Menu options
Two Edit menu options apply when Help is active:
Copy copies the current selected text from the topic text to the
Clipboard. If
no text is currently selected, the command is disabled (grayed in
the menu). The
text is "unselected" after the copy. The rules for coercing text
during a Turbo
Example copy (noted earlier), also apply during a generalized copy
to Clipboard.
Copy Example copies the Turbo Example text from the current topic
text, if any,
to the Clipboard. If the current topic has no Turbo Example, the
command is
disabled (grayed in the menu).
Incremental searching
Incremental searching is supported for movement between keywords in
topic text.
Literal characters entered at the keyboard are matched against
successive
characters in the text of keywords, and the selected keyword is
changed based on
the characters entered. Backspace strips successive characters from
the match
string. Explicit cursor movements cancel the incremental search.
Index context
First and foremost rule: Any command that you use in the Help file
must be
immediately preceded by a semicolon (;). Letter case does not matter
unless
you're using the ;CASESENSE command.
Second rule: You must put hard returns at the end of your lines.
There are several (optional) initial setup commands that you can
place at the
beginning of your Help files.
An example
Here is an example of the typical commands you'd use in a single Help
screen
format:
Turbo Dictionary
^BAnnouncer ^B ^BArchitect ^B
;KEYWORD don
;KEYWORD art
;KEYWORD dailydouble
;KEYWORD potpourri
;INDEX Dictionary
;ENDSCREEN
;SCREEN
;SCREEN marks the beginning of each new Help screen. The ;SCREEN name
given in
this command names the screen that Help searches for when the user
selects a
keyword. (See the ;KEYWORD command, below.)
;KEYWORD
;KEYWORD is an optional command that defines which Help screen to bring
up when
the user selects the matching keyword. Basically, the associated
keyword is a
reference. Perhaps a better way to put it is to compare it with a
similar use in
an encyclopedia or thesaurus. In defining or explaining an entry,
these
reference books may highlight or capitalize other related entries,
or tell you
to See other related entry.
When the user calls up Help, all keywords appear highlighted. You
can move
around the keywords using the Up arrow, Down arrow, Right arrow, and
Left arrow
keys. The keyword you're positioned on is highlighted; to select it,
press
Enter.
;SCREEN metaphysics
Metaphysics
See also
^B Kant ^B
^B Fichte ^B
^B Schelling^B
^B Hegel ^B
;KEYWORD kant
;KEYWORD fichte
;KEYWORD schelling
;KEYWORD hegel
;INDEX Metaphysics
;ENDSCREEN
;SCREEN kant
Kant 1724-1804
;KEYWORD metaphysics
;INDEX Kant
;ENDSCREEN
Note that we showed the ^B's as two separate characters, but they
should
actually be the ^B character: 0x02.
Each keyword within the screen text is delimited by ^B's and has a
matching
;KEYWORD command. (So the Help Linker knows which screen a given
keyword is to
bring up when selected.) Read the following section, "More about
^B's" for
further explanation.
Whatever the keyword happens to be, your beginning and ending ^B's
must be on
the same line; the Help Linker gives an error if you try to wrap a
keyword on
two lines.
;ENDSCREEN
;ENDSCREEN ends the screen you began with ;SCREEN; there's no argument
necessary.
;PAGE
;PAGE is a linking command between two or more Help screens of related
information. Pressing PgUp takes you to the next screen; PgDn takes
you to the
previous screen. A good example of ;PAGE can be found on disk.
where
[p] means p is optional.
{p} means zero or more repetitions of p.
p|q means choose p or q.
Note
/eerrorLimit
errorLimit is the number of errors that need to be
detected before the Help Linker will terminate without
completing the
link operation. If the parameter is missing, the Linker
will terminate
on any error.
/x
If this switch is present, the Help Linker will not
automatically
create and insert an index table screen in the resulting
binary Help
file. Since THELP automatically creates an index screen
"on-the-fly,"
not including the /x switch will only result in a larger
Help file.
The records of the file are grouped into four major sections as
follows:
Administrative
File Stamp
File Signature
File Version
Compression Record
Context Table
Index Table
Keyword Record
File Stamp
An ASCIIZ string identifying the file in "human readable" terms. For
example,
the following strings are used in Turbo C++ and Turbo Pascal
respectively:
The text of this string is defined using the ;STAMP command in Help
source text
processed by the Help Linker.
File Signature
An ASCIIZ string helps to further identify a file as a valid Borland
Help file.
The string may be any value mutually agreed between the author of
the Help text,
and the programmer of the run-time code. The value currently used by
Borland
language products is:
$*$* &&&&$*$
File Version
Two bytes that define the version of the Help Format, and of the Help
File Text,
respectively:
typedef struct
{
byte formatVersion;
byte textVersion;
} TPversionRec;
Record Headers
The remaining records of a Help file have a common format which
includes a
header identifying the record's type and its length:
typedef struct
{
byte recType;
word recLength;
} TPrecHdr;
enum {
RT_FileHeader = 0,
RT_Context = 1,
RT_Text = 2,
RT_Keyword = 3,
RT_Index = 4,
RT_Compression = 5
};
typedef struct
{
word options;
options
options is a bitmapped field that let you select various options. Only
one is
currently supported.
OF_CaseSense (0x0004)
If set, index tokens are listed in mixed case in the Index Record,
and index
searches should be case sensitive.
If cleared, index tokens are all uppercase in the Index Record, and
index
searches should ignore case.
mainIndexScreen
The context number of the context designated by the ;MAININDEX command
in the
Help source text processed by the Help Linker. If ;MAININDEX wasn't
used,
mainIndexScreen is set to zero.
maxScreenSize
The number of bytes in the longest Text Record in the file (not
including its
header). This field is not currently used.
height, width
The default size in rows and columns, respectively, of the display area
of a
Help window.
Set using the ;HEIGHT and ;WIDTH commands in Help source text
processed by the
Help Linker.
leftMargin
The number of columns to leave blank on the left edge of all rows of
Help text
displayed.
Set using the ;LMARGIN command in Help source text processed by the
Help Linker.
Compression Record
Defines how the contents of Text Records are encoded. The record has
the
following general form:
typedef struct
{
byte compType;
byte charTable[ 14 ];
} TPcompRec;
enum {
CT_Nibble = 2
};
enum {
NC_RawChar = 0xF,
NC_RepChar = 0xE
};
Nibble code NC_RawChar introduces two additional nibbles which
define a literal
character; the least significant nibble appears first.
Context table
A table of absolute file offsets which relates Help contexts with their
associated text. The first word of the record gives the number of
contexts in
the table.
Index table
A list of index descriptors.
The list of index descriptors in the Index Record allows the text of
an index
token to be mapped into its associated context number.
The first word of the record gives the number of indexes defined in
the record.
byte lengthCode;
byte uniqueChars[ 1 .. n ];
word contextNumber;
The bits of lengthCode are divided into two bit fields. Bits (7..5)
specify the
number of characters to carry over from the start of the previous
index token
string. Bits (4..0) specify the number of unique characters to add
to the end of
the inherited characters. Field uniqueChars gives the n unique
characters to
add.
For example, if the previous index token was addition, and the next
index token
is advanced, we would inherit two characters from the previous token
(ad), and
add six unique characters (vanced); thus, lengthCode would be 0x46.
Text Record
Defines the compressed text of a context.
Text Records and Keyword Records (see 134) appear in pairs; one pair
for each
context in the Help file. The Text Record always precedes its
associated Keyword
Record. Text Records are addressed in the Help file through file
offset values
found in the Context Table.
The recLength field of the Text Record's header defines the number
of bytes of
compressed text in the record. The Compression Record defines how
the text is
compressed. If the text record is nibble encoded, and the last
nibble of the
last byte is not used, it is set to 0 - this translates to a 0 byte
when the
text is decoded, and the 0 byte represents a blank line.
Keyword Record
Defines keywords embedded in the preceding Text Record, and identifies
related
Text Records.
word upContext;
word downContext;
word keywordCnt;
typedef struct
{
word kwContext;
} TPkwDesc;
The keywords in a Text Record are numbered from 1 to keywordCnt in
the order
they appear in the text (reading left to right, top to bottom).
CONTENTS
______________________________________________________________________
iii