source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,188 @@
|
||||
AUTOMATING COLLECTIONS
|
||||
|
||||
Frequently an application organizes data and objects in
|
||||
collections of various types, such as arrays, containers,
|
||||
or linked lists, or it utilizes such capabilites inherent in
|
||||
the operating platform. Collections generally expose an
|
||||
iterator, a counter, a random-access function, and
|
||||
optionally methods for managing the collection. Exposing
|
||||
collections for automation generally involves three steps:
|
||||
|
||||
1. The collection is exposed as a property which returns
|
||||
an object.
|
||||
|
||||
2. A C++ class is created, or enhanced, to support the
|
||||
collection methods.
|
||||
|
||||
3. An iterator is defined to provide code to iterate
|
||||
through the collection.
|
||||
|
||||
|
||||
The iterator is internally exposed to the script controller
|
||||
as a property having the reserved name "_NewEnum" which
|
||||
returns an object supporting the IENUMVariant interface.
|
||||
This interface contains methods to perform iteration. With
|
||||
VisualBasic for Applications, the following syntax is used
|
||||
for iteration:
|
||||
|
||||
For Each Thing In Owner.Bunch ("Thing" is an arbitrary
|
||||
iterator name)
|
||||
Thing.Member...... (can access methods and
|
||||
properties)
|
||||
Next Thing (loops through all items
|
||||
in collection)
|
||||
|
||||
Note that the server can return any data type for items,
|
||||
values or objects.
|
||||
|
||||
|
||||
CREATING C++ CLASSES SPECIFICALLY FOR AUTOMATION
|
||||
|
||||
Frequently C++ classes do not already exist to encapsulate
|
||||
items to be exposed for automation, such as collections,
|
||||
simple structures, and system objects represented by
|
||||
handles. The only C++ methods required are a constructor
|
||||
and support methods for the exposed automation. Instances
|
||||
of these classes are exposed as properties of their parent
|
||||
classes and are constructed as the properties are retrieved
|
||||
(as opposed to returning references to existing C++
|
||||
instances). The constructor must accept a single argument
|
||||
from the parent class: member data, result of an accessor
|
||||
function, or the object's this pointer. The parent class
|
||||
must supply an AUTOxxx macro that supplies this constructor
|
||||
argument as a data member or function, and declares its
|
||||
type with the templatized pointer class
|
||||
TAutoObjectByVal<T>, where T is the new automated C++
|
||||
class. TAutoObjectByVal<T> causes an instance of T to be
|
||||
constructed that persists until all external references to
|
||||
that instance are released (when the exposed object goes
|
||||
out of scope in the automation controller). Examples of
|
||||
the macros used within the DECLARE_AUTOCLASS and
|
||||
DEFINE_AUTOCLASS sections are given below:
|
||||
|
||||
AUTODATARO(Documents, DocList, TAutoObjectByVal<TDocumentList>,)
|
||||
// DocList is a TDocument*, head of a linked list of.
|
||||
// type TDocument. TDocumentList is a new class, constructor:
|
||||
// TDocumentList(TDocument*)
|
||||
EXPOSE_PROPRO(Documents, TDocumentList, "Documents", "Doc Collection", 270)
|
||||
|
||||
AUTOTHIS(Views, TAutoObjectByVal<TViewList>,)
|
||||
// TViewList is a new class, constructor: TView(TDocument* owner)
|
||||
// In this case the parent's this pointer is passed to the constuctor
|
||||
EXPOSE_PROPRO(Views, TViewList, "Views", "View Collection", 240)
|
||||
|
||||
AUTOFUNC0(Buttons, GetWindow(), TAutoObjectByVal<TCalcButtons>, )
|
||||
// GetWindow() gets the window handle of the parent window of
|
||||
// the buttons. TCalcButtons is a new class, constructor:
|
||||
// TCalcButtons(HWND parent)
|
||||
EXPOSE_PROPRO(Buttons, TCalcButtons, "Buttons", Button Collection", 170)
|
||||
|
||||
AUTODATARO(MyArray, Elem, TAutoObjectByVal<TMyArray>,)
|
||||
// Elem is an array of shorts, defined as short Elem[COUNT]
|
||||
// TMyArray is a new class, constructor: TMyArray(short* array)
|
||||
EXPOSE_PROPRO(MyArray, TMyArray, "Array", "Array as collection", 110)
|
||||
|
||||
|
||||
COLLECTION CLASSES
|
||||
|
||||
A C++ class must be defined to host the automation
|
||||
declarations along with the supporting C++ methods. For
|
||||
some collections, a C++ class might already exist. Otherwise
|
||||
one must be defined to represent a collection object.
|
||||
|
||||
|
||||
EXPOSING COLLECTION OBJECTS
|
||||
|
||||
EXPOSING ITERATORS
|
||||
|
||||
Iterators are defined for automation using the AUTOITERATOR
|
||||
macro, which defines the iteration algorithm for the
|
||||
enclosing collection class. No internal name is supplied,
|
||||
as only one iterator may exist within a class. The macro
|
||||
has five arguments, each representing a code fragment,
|
||||
ordered as in a "for" loop.
|
||||
|
||||
1. Declaration of state variables, e.g. int Index
|
||||
2. Loop initializer assigments, e.g. Index = 0
|
||||
3. Loop entry test boolean expression, e.g. Index < This->Total
|
||||
4. Loop iteration statements, e.g. Index++
|
||||
5. Current element access expression, e.g. (This->Array)[Index]
|
||||
|
||||
Commas cannot be used unless inside parentheses. Semicolons
|
||||
can be used to separate multiple statements, but cannot
|
||||
be used to end a macro argument. In common with automated
|
||||
methods, "This" is defined to be the "this" pointer of the
|
||||
enclosing C++ class, in this case the collection itself.
|
||||
|
||||
The AUTOITERATOR macro generates a nested class definition.
|
||||
For complex iterators, this class can be specified directly
|
||||
in C++ as shown below:
|
||||
|
||||
class TIterator : public TAutoIterator {
|
||||
public:
|
||||
ThisClass* This;
|
||||
/* declare state variables here as members */
|
||||
void Init() {/* loop initialization function body */}
|
||||
bool Test() {/* loop entry test function body */}
|
||||
void Step() {/* loop iteration function body;}
|
||||
void Return(TAutoVal& v) {/* current element return: v = expr */}
|
||||
TIterator* Copy() {return new TIterator(*this);}
|
||||
TIterator(ThisClass* obj, TServedObject& owner)
|
||||
: This(obj), TAutoIterator(owner) {}
|
||||
static TAutoIterator* Build(ObjectPtr obj, TServedObject& owner)
|
||||
{ return new TIterator((ThisClass*)obj, owner); }
|
||||
}; friend class TIterator;
|
||||
|
||||
Iterators are exposed as properties using the
|
||||
EXPOSE_ITERATOR macro. Note that no internal or external
|
||||
names are supplied (the external name is internally
|
||||
hard-wired as "_NewEnum"). The automation type describes the
|
||||
type of the items returned from the iterator, in the same
|
||||
manner as a function return.
|
||||
|
||||
AUTOITERATOR(int Index, Index=0, Index<COUNT, Index++,
|
||||
(This->Array)[Index])
|
||||
// Array is a member array of shorts for which an iterator
|
||||
// is defined. It will exposed as a "_NewEnum" property which
|
||||
// returns an OLE enumerator.
|
||||
EXPOSE_ITERATOR(TAutoShort, "Array Iterator", HC_ARRAY_ITERATOR)
|
||||
|
||||
In addition to exposing an iterator, a collection class by
|
||||
convention exposes a "Count" method to return the number of
|
||||
items in the collections, an "Index" method to randomly
|
||||
access an element of the collection, and optionally,
|
||||
methods to externally manage the collection, such as add and
|
||||
delete.
|
||||
|
||||
____________________________________________________________
|
||||
|
||||
|
||||
----example code from AutoCalc------
|
||||
|
||||
class TCalcButtons {
|
||||
public:
|
||||
TCalcButtons(HWND window) : HWnd(window) {}
|
||||
short GetCount() { return IDC_LASTID - IDC_FIRSTID; }
|
||||
HWND HWnd;
|
||||
|
||||
DECLARE_AUTOCLASS(TCalcButtons)
|
||||
AUTOFUNC0 (Count, GetCount, short,)
|
||||
AUTOITERATOR(int Id, Id = IDC_FIRSTID+1,
|
||||
Id <= IDC_LASTID, Id++,
|
||||
TAutoObjectByVal<TCalcButton>(::GetDlgItem(This->HWnd,Id)))
|
||||
};
|
||||
|
||||
DEFINE_AUTOCLASS(TCalcButtons)
|
||||
|
||||
EXPOSE_PROPRO(Count, TAutoLong, "!Count","Button Count",
|
||||
HC_TCALCBUTTONS_COUNT)
|
||||
EXPOSE_ITERATOR(TCalcButton, "Button Iterator",
|
||||
HC_TCALCBUTTONS_ITERATOR)
|
||||
EXPOSE_METHOD_ID(0, Item, TCalcButton,"!Item",
|
||||
"Button Collection Item", 0)
|
||||
REQUIRED_ARG(TAutoShort, "!Index")
|
||||
|
||||
END_AUTOCLASS(TCalcButtons, "ButtonCollection",
|
||||
"Button Collection", HC_TCALCBUTTONS)
|
||||
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
COMPAT.TXT - Compatibility Information
|
||||
(C) Copyright 1995 by Borland International
|
||||
|
||||
|
||||
Contents:
|
||||
========
|
||||
Using ObjectWindows 1.0 with Borland C++ 4.5
|
||||
Downloading OWL1.PAK
|
||||
Using Turbo Assembler 4.0 with Borland C++ 4.5
|
||||
Using the Object Based Class Library with Borland C++ 4.5
|
||||
Using Turbo Vision 1.0x with Borland C++ 4.5
|
||||
Using the Paradox Engine and Database Frameworks with BC 4.5
|
||||
|
||||
|
||||
Using ObjectWindows 1.0 with Borland C++ 4.5
|
||||
============================================
|
||||
|
||||
The ObjectWindows 1.0 library can be built with Borland C++ 4.5 for
|
||||
developing OWL 1.0 native applications. With the increased capacity of the
|
||||
Borland tools as compared to Borland C++ 3.1, you can now use OWL libraries
|
||||
with full symbolic debug information and debug your application in either
|
||||
the Integrated Development Environment or in Tubro Debugger for Windows.
|
||||
|
||||
The overall process requires modifying ObjectWindows source files and
|
||||
rebuilding the object-based container library as well as ObjectWindows. All
|
||||
necessary files are contained in OWL1.PAK which is on the Borland C++
|
||||
compact disk in the \bc45\install directory. If you obtained Borland C++ on
|
||||
5-1/4" disks instead of compact disk, you will need to download OWL1.PAK
|
||||
from Borland's ftp site, local bulletin board, or CompuServe. (See
|
||||
"Downloading OWL1.PAK".)
|
||||
|
||||
To begin the process, copy OWL1.PAK to the \bc45 directory and use
|
||||
unpaq.exe (in the \bc45 directory) to extract the files. When using unpaq,
|
||||
be sure to set:
|
||||
|
||||
Restore directories: checked
|
||||
Archive name: \bc45\owl1.pak
|
||||
Destination dir: \bc45
|
||||
|
||||
Next, select Open archive. By default, all files are selected and if you
|
||||
de-select any, they will not be installed. Now select Decompress.
|
||||
|
||||
Building and using ObjectWindows and the object-based container library are
|
||||
described in 1OWL45.TXT which you will now find in the directory
|
||||
\bc45\source\owl1.
|
||||
|
||||
|
||||
|
||||
Downloading OWL1.PAK
|
||||
====================
|
||||
|
||||
OWL1.PAK can be obtained from the following sources:
|
||||
|
||||
Borland's anonymous ftp site: ftp.borland.com
|
||||
|
||||
CompuServe: !go BCPPWin and look in library 2.
|
||||
|
||||
Borland's Download Bulletin:
|
||||
The DLBBS can be dialed at 408-431-5096. Simply join the C++
|
||||
Conference (number 12). And from the File menu, select download
|
||||
and enter OWL1.PAK (you do not need to be in the specific file
|
||||
area).
|
||||
|
||||
|
||||
Using Turbo Assembler 4.0 with Borland C++ 4.5
|
||||
==============================================
|
||||
Turbo Assembler 4.0 is fully compatible with Borland C++ 4.5. There is
|
||||
an error in the WHEREIS example program which will cause two undefined
|
||||
symbol errors when built. The following corrections will resolve the
|
||||
problem:
|
||||
|
||||
In file \examples\tasm\whereis\iexedos.asm
|
||||
line 118, change:
|
||||
mov es,[es:psp.EnvironmentBlock]
|
||||
to:
|
||||
mov es,[es:Psp.EnvironmentBlock]
|
||||
|
||||
line 196, change:
|
||||
mov ax, [ComSpecSeg]
|
||||
to:
|
||||
mov ax, [ComspecSeg]
|
||||
|
||||
In file \examples\tasm\whereis\whereis.asm
|
||||
line 448, change:
|
||||
endp main
|
||||
to:
|
||||
endp Main
|
||||
|
||||
line 565, change:
|
||||
call WriteAsciizString,ds,offset Syntax
|
||||
to:
|
||||
call WriteASCIIZString,ds,offset Syntax
|
||||
|
||||
|
||||
Using the Object Based Class Library with Borland C++ 4.5
|
||||
=========================================================
|
||||
|
||||
The object based class library, while still included with Borland C++
|
||||
4.5, must be compiled before it can be used. Here are instructions for
|
||||
doing so:
|
||||
|
||||
There is a makefile in the source directory, \BC45\SOURCE\CLASSLIB which
|
||||
can be used to build all versions of the class library. For example, to
|
||||
build a large model static version for use with Object Windows, run the
|
||||
following command:
|
||||
|
||||
MAKE -DDOS -DOBJECTS "-DBCC=bcc -x-" -DMODEL=l -DNAME=tclassl
|
||||
|
||||
To build a debugging dynamic version of the class library DLL, run the
|
||||
following command:
|
||||
|
||||
MAKE -DDOS -DDBG -DOBJECTS "-DBCC=bcc -x-" -DDLL -DNAME=tclass
|
||||
|
||||
Note that to successfully use the DLL version of the class library you will
|
||||
have to copy TCLASS40.DLL from the \BC45\LIB directory into the \BC45\BIN
|
||||
directory.
|
||||
|
||||
|
||||
|
||||
Using Turbo Vision 1.0x with Borland C++ 4.5
|
||||
============================================
|
||||
|
||||
REBUILDING THE TURBO VISION LIBRARY:
|
||||
|
||||
Due to changes in the debug information format, symbol length, and
|
||||
runtime library, the Turbo Vision 1.0 library must be recompiled with
|
||||
Borland C++ 4.5. Note that Turbo Vision 2.0 is fully compatible with
|
||||
Borland C++ 4.5 and does not require the modifications in this section.
|
||||
|
||||
There are a few minor changes that need to be made to the source code
|
||||
before recompiling it with the new compiler. These are due to slightly
|
||||
tightened syntax restrictions. The makefile will require some
|
||||
modification as well, which are shown below.
|
||||
|
||||
There are 3 steps to this process:
|
||||
|
||||
1. Copy the old 3.1 Turbo Vision source into the new BC45 directory
|
||||
structure.
|
||||
2. Make the appropriate changes according to the instructions below.
|
||||
3. Run MAKE to build the new Turbo Vision library you need to
|
||||
continue your work. If you are using Turbo Vision in an overlaid
|
||||
application, make sure you follow the instructions specific to
|
||||
overlays.
|
||||
|
||||
These steps are now presented in more detail: Note that the Borland C++
|
||||
root directory is assumed to be \BC45. Change this as necessary for your
|
||||
particular installation. Also, if you are upgrading from Borland C++
|
||||
2.0 and have the original version of Turbo Vision, some of the line
|
||||
numbers mentioned may not accurately reflect your version.
|
||||
|
||||
You need to copy your old Turbo Vision source and include files from
|
||||
Borland C++ 3.1 into your Borland C++ 4.5 directory hierarchy. To do
|
||||
this, just run the following command:
|
||||
|
||||
XCOPY \BC31\TVISION \BC45\TVISION /S
|
||||
|
||||
and when it asks you about creating a directory called TVISION, say yes.
|
||||
Modify the above paths according to your system configuration if
|
||||
necessary. You are now ready to make the necessary modifications before
|
||||
rebuilding the library.
|
||||
|
||||
The changes are as follows:
|
||||
|
||||
1. Due to tighter syntax checking, case blocks that declare initialized
|
||||
local variables need their own scoping block. Make the changes below
|
||||
in the order shown so that confusion over the correct line numbers
|
||||
can be avoided. In general, the '{' follows a case statement, and
|
||||
the '}' follows a break statement.
|
||||
|
||||
COLORSEL.CPP
|
||||
|
||||
Add after line 219: }
|
||||
Add after line 179: {
|
||||
Add after line 177: }
|
||||
Add after line 164: {
|
||||
|
||||
TBUTTON.CPP
|
||||
|
||||
Add after line 226: }
|
||||
Add after line 211: {
|
||||
Add after line 209: }
|
||||
Add after line 192: {
|
||||
|
||||
2. TINPUTLIN.CPP
|
||||
Replace line 44: if( (p = strchr( s, '~' )) != 0 )
|
||||
With if( (p = (char*) strchr( s, '~' )) != 0)
|
||||
|
||||
3. TMNUVIEW.CPP
|
||||
Replace line 348: char *loc = strchr( p->name, '~' );
|
||||
With char *loc = (char*)strchr( p->name, '~' );
|
||||
|
||||
4. TVWRITE.ASM
|
||||
Replace line 25: PUBLIC @TView@writeChar$qsszcucs
|
||||
With PUBLIC @TView@writeChar$qsscucs
|
||||
|
||||
Replace line 27: PUBLIC @TView@writeStr$qssnxzcuc
|
||||
With PUBLIC @TView@writeStr$qssnxcuc
|
||||
|
||||
Replace line 366: PROC @TView@writeChar$qsszcucs
|
||||
With PROC @TView@writeChar$qsscucs
|
||||
|
||||
Replace line 436: PROC @TView@writeStr$qssnxzcuc
|
||||
With PROC @TView@writeStr$qssnxcuc
|
||||
|
||||
Note that all of the above changes simply entail removing
|
||||
the letter 'z' from the last part of the mangled symbol
|
||||
name.
|
||||
|
||||
5. MAKEFILE
|
||||
Replace line 100:
|
||||
CFLAGS = -c $(CCOVYFLAGS) -P -O1 -m$(MODEL) -I$(INCLUDE) -n$(OBJDIR)
|
||||
With
|
||||
CFLAGS = -c -x- $(CCOVYFLAGS) -P -O1 -m$(MODEL) -I$(INCLUDE) -n$(OBJDIR)
|
||||
|
||||
Replace line 73:
|
||||
TLIB = $(BCROOT)\bin\tlib /0
|
||||
With this group of 5 lines:
|
||||
!ifdef DEBUG
|
||||
TLIB = $(BCROOT)\bin\tlib
|
||||
!else
|
||||
TLIB = $(BCROOT)\bin\tlib /0
|
||||
!endif
|
||||
|
||||
*** If you did NOT purchase the Turbo Assembler add-on package for
|
||||
Borland C++ 4.5, you must make some additional changes.
|
||||
|
||||
Replace the group at lines 259-263:
|
||||
!if $d(BC)
|
||||
$(TASM) $&.asm, $(OBJDIR)\$&.obj
|
||||
!else
|
||||
copy $(TVLIBDIR)\$&.obj $(OBJDIR)
|
||||
!endif
|
||||
With this group:
|
||||
!if !$d(NOTASM)
|
||||
$(TASM) $&.asm, $(OBJDIR)\$&.obj
|
||||
!else
|
||||
copy $(LIBDIR)\COMPAT\$&.obj $(OBJDIR)
|
||||
!endif
|
||||
|
||||
Add after line 49:
|
||||
NOTASM = 1
|
||||
|
||||
|
||||
USE OF EXCEPTION HANDLING WITH TURBO VISION:
|
||||
|
||||
Turbo Vision was designed with its own global new operator. Due to this
|
||||
internal design you will not be able to use exception handling with the
|
||||
new operator. However, any other type of exception handling is
|
||||
supported. In order to enable exception handling do not make the change
|
||||
to line 88 of the makefile.
|
||||
|
||||
|
||||
USE OF OVERLAYS WITH TURBO VISION:
|
||||
|
||||
** Note: All instructions in this section are in addition to the changes
|
||||
recommended above.
|
||||
|
||||
As with Borland C++ 3.1, Turbo Vision can be used in an overlayed program
|
||||
if the library is rebuild with certain options, shown below:
|
||||
|
||||
All overlayed modules must be compiled with local virtual tables (-Vs).
|
||||
|
||||
Overlayed modules no longer need to be compiled via assembler (-B).
|
||||
|
||||
Overlayed modules must be compiled with exceptions disabled (-x-).
|
||||
|
||||
Here are the steps required to build an overlayable version of TV.LIB:
|
||||
|
||||
1. First make an additional change to file TVISION\SOURCE\MAKEFILE:
|
||||
|
||||
Change line 96 from : CCOVYFLAGS = -Y -Vs -B
|
||||
to : CCOVYFLAGS = -Y -Vs
|
||||
|
||||
2. Change to the \BC45\TVISION\LIB directory and make a backup copy of
|
||||
TV.LIB by typing:
|
||||
|
||||
COPY TV.LIB OLDTV.LIB
|
||||
|
||||
3. Switch to the \BC45\TVISION\SOURCE directory and type:
|
||||
|
||||
MAKE -B -DOVERLAY
|
||||
|
||||
4. This will create a new TV.LIB in the \BC45\TVISION\LIB directory.
|
||||
There are seven modules in TV.LIB which cannot be overlayed. The
|
||||
easiest solution to this problem is to create three seperate
|
||||
libraries. Two libraries will be used when creating overlayed TV
|
||||
apps, and the original TV.LIB will remain for use in non-overlayed TV
|
||||
apps:
|
||||
|
||||
TV.LIB - full TV lib for use in non-overlayed TV apps
|
||||
TVO.LIB - overlayable modules of TV.LIB
|
||||
TVNO.LIB - non-overlayable modules of TV.LIB
|
||||
|
||||
To create these libraries, switch into the TVISION\LIB directory and
|
||||
type the following commands:
|
||||
|
||||
TLIB TV.LIB -*SYSERR -*TSCREEN -*DRIVERS -*DRIVERS2 -*SWAPST -*TEVENT -*SYSINT
|
||||
TLIB TVNO.LIB +SYSERR +TSCREEN +DRIVERS +DRIVERS2 +SWAPST +TEVENT +SYSINT
|
||||
RENAME TV.LIB TVO.LIB
|
||||
RENAME TVOLD.LIB TV.LIB
|
||||
DEL *.OBJ *.BAK
|
||||
|
||||
5. You will now have the three libraries. To create an overlayed Turbo
|
||||
Vision application, include both TVO.LIB and TVNO.LIB in the project
|
||||
file or link line of the makefile. Using the local options for each
|
||||
item, mark TVO.LIB as overlayed and TVNO.LIB as non-overlayed. Also,
|
||||
go to the TargetExpert dialog box for this target and uncheck the
|
||||
Turbo Vision Library.
|
||||
|
||||
|
||||
|
||||
Using the Paradox Engine And Database Frameworks with BC 4.5
|
||||
============================================================
|
||||
|
||||
THE PARADOX ENGINE
|
||||
|
||||
There is only one significant detail regarding the use of the Paradox
|
||||
Engine 3.0x with Borland C++ 4.5. The BC 3.1 versions of setjump and
|
||||
longjump will have to be linked into your application in order to create
|
||||
DOS Paradox Engine and Database Framework applications. The object
|
||||
module, setjmp.obj, is provided in the BC45\LIB\COMPAT directory. Linking
|
||||
this module into your application will replace the BC 4.5 version of
|
||||
these functions. To do this, simply add the file
|
||||
\BC45\LIB\COMPAT\SETJMP.OBJ to your project file or to the link command
|
||||
in your makefile.
|
||||
|
||||
|
||||
REBUILDING THE DATABASE FRAMEWORKS
|
||||
|
||||
Due to changes in the debug information format, symbol length, and
|
||||
runtime library, the Database Framework library must be recompiled with
|
||||
Borland C++ 4.5.
|
||||
|
||||
A number of changes will have to be made to the Paradox Engine DBF v3.01
|
||||
makefile in order for it to work with BC 4.5 (this makefile is available
|
||||
from our local BBS at (408) 431-5096 as the file TI1169.ZIP and from
|
||||
TechFax at (800) 822-4269, document number 1169):
|
||||
|
||||
1. Copy makefile.bc to make40.mak
|
||||
|
||||
2. Make certain that a turboc.cfg file exists in the BC45\BIN directory
|
||||
containing:
|
||||
|
||||
-Ic:\bc45\include
|
||||
-Lc:\bc45\lib
|
||||
|
||||
Make certain that a tlink.cfg file exist in the BC45\BIN directory
|
||||
containing:
|
||||
|
||||
-Lc:\bc45\lib
|
||||
|
||||
Adjust the above paths to reflect your systems' configuration.
|
||||
|
||||
3. Make the following changes:
|
||||
|
||||
Line 83: Change the 'CCINCLUDE=' line to contain the path to the BC
|
||||
4.5 include directory.
|
||||
Line 168: Delete the blank space at the end of the 'DEBUGFLAG=v ' line
|
||||
Line 172: Delete the blank space at the end of the 'DYNAMICFLAG=d ' line
|
||||
Line 202: Add '-DWindows' after '-DWINDOWS'
|
||||
Line 204: Add '-DWindows' after '-DWINDOWS'
|
||||
Line 206: Add '-DWindows' after '-DWINDOWS'
|
||||
Line 239: Replace '$D' with 'BuildDir'
|
||||
Line 249: Replace '$D' with 'BuildDir'
|
||||
Line 261: Replace '$D' with 'BuildDir'
|
||||
|
||||
Then use the following command to create a Database Framework Library.
|
||||
Add one or both of the options -DDBG and -DWINDOWS to add debug info or
|
||||
build for use in WINDOWS code. (Refer to the makefile for even more
|
||||
options.)
|
||||
|
||||
make -fmake40.mak
|
||||
|
||||
For example, the following command will create a large model, static
|
||||
windows DBF library with debug info:
|
||||
|
||||
make -DWINDOWS -DDBG -fmake40.mak
|
||||
|
||||
The libraries will be created in the PXENG30\C\LIB directory. These
|
||||
libraries are now ready for use in your Database Frameworks Program.
|
||||
|
||||
|
||||
CHANGES TO USER CODE WITH RESPECT TO DBF
|
||||
|
||||
The only change to your source code involves the use of the 'new'
|
||||
operator. In BC++ 4.5, the new operator no longer returns NULL in case
|
||||
of failure, rather the xalloc exception is thrown. To change this back
|
||||
so operator new returns NULL, call set_new_handler(0).
|
||||
|
||||
The only remaining issue is with using the new operator in the
|
||||
constructor of global objects. How do you call set_new_handler(0)
|
||||
before a global object's constructor is called? This is accomplished by
|
||||
using a #pragma startup function with a priority higher than that of the
|
||||
startup function used to call the particular global object's
|
||||
constructor. The following code shows an example of changing the
|
||||
behavior of new:
|
||||
|
||||
#include <new.h>
|
||||
|
||||
void old_new(void)
|
||||
{
|
||||
set_new_handler(0);
|
||||
}
|
||||
|
||||
#pragma startup old_new 31
|
||||
|
||||
BEngine eng(pxWin);
|
||||
|
||||
int main (void)
|
||||
{
|
||||
.
|
||||
.
|
||||
.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Note that creating global instances of Database Framework objects is not
|
||||
recommended because it can make error checking difficult.
|
||||
|
||||
The other option is to change the source of the Database Frameworks: Add
|
||||
the try {} catch(xalloc) clause everywhere that new is called.
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
New Features of EasyWin
|
||||
=======================
|
||||
Turbo C++ for Windows provides EasyWin, a feature that lets you
|
||||
compile standard DOS applications which use traditional TTY style
|
||||
input and output so they can run as true Windows programs. With
|
||||
EasyWin, you do not need to change a DOS program to run it under
|
||||
Windows.
|
||||
|
||||
EasyWin now has support for several new features:
|
||||
|
||||
- Printing support lets you print the contents of the EasyWin window.
|
||||
|
||||
- Viewable scrolling buffer stores either 100 or 400 lines of text
|
||||
(depending on the memory model). This buffer automatically scrolls
|
||||
as you move the vertical or horizontal scroll bar thumb tabs.
|
||||
|
||||
- Redirects output to a file of your choice when the buffer runs out
|
||||
of space.
|
||||
|
||||
- Full Windows Clipboard support, lets you paste to standard input and
|
||||
copying from the buffer onto the Clipboard, using either the
|
||||
keyboard or the mouse.
|
||||
|
||||
For additional information about EasyWin, see:
|
||||
|
||||
- Appendix A, "Using EasyWin" in the User's Guide
|
||||
|
||||
- In the online help, Search for "EasyWin" or "DOS applications".
|
||||
|
||||
Printing
|
||||
--------
|
||||
Use the Print command on the system menu to print the contents of an
|
||||
EasyWin window. It activates the standard Print dialog from which you
|
||||
can specify printing options.
|
||||
|
||||
By default, EasyWin prints 80 columns and approximately 54 lines on
|
||||
U.S. Letter size (8.5" x 11") paper.
|
||||
|
||||
Note: The Print command is grayed if you do not have a default
|
||||
printer installed under Windows. If you have a printer
|
||||
installed but it is not the default, make it the default
|
||||
printer before attempting to print from an EasyWin
|
||||
application.
|
||||
|
||||
Scrolling Buffer
|
||||
----------------
|
||||
EasyWin caches your screen output into a buffer of either:
|
||||
|
||||
- 400 lines (for compact and large memory models)
|
||||
|
||||
- 100 lines (for small and medium memory models)
|
||||
|
||||
You can view the buffer any time by using the scroll bar or any of the
|
||||
standard window movement keys.
|
||||
|
||||
You can change the buffer size of your EasyWin application by
|
||||
declaring the following global variable in your main source file with
|
||||
the appropriate initializer:
|
||||
|
||||
POINT _BufferSize = { X, Y };
|
||||
|
||||
where:
|
||||
|
||||
X is the number of columns you want. Setting X to a value
|
||||
other than 80 is not recommended as the results are
|
||||
unpredictable.
|
||||
|
||||
Y is the number of lines you want. If you need to specify a
|
||||
value for Y greater than 100, use the compact or large
|
||||
memory model. The small and medium memory models have
|
||||
limited local heap space for the buffer.
|
||||
|
||||
Autoscrolling
|
||||
-------------
|
||||
If you click and drag either the vertical or horizontal scroll bar
|
||||
thumb tab, the text in the buffer automatically scrolls up and down or
|
||||
left and right. This is a useful feature when you want to quickly scan
|
||||
large amounts of data in the EasyWin window.
|
||||
|
||||
Saving Text in an Output File
|
||||
-----------------------------
|
||||
If you want to redirect the output of your program to a file, add the
|
||||
following global variable to your main source file:
|
||||
|
||||
char *_OutputFileName = "C:\\myoutput.txt";
|
||||
|
||||
Make _OutputFileName the name of the file in which to store the
|
||||
redirected output.
|
||||
|
||||
Note: If the output file you specified already exists, it is deleted
|
||||
without warning.
|
||||
|
||||
Clipboard Support
|
||||
-----------------
|
||||
EasyWin lets you to cut, copy, and paste text from an EasyWin
|
||||
application window.
|
||||
|
||||
To select text, use the Edit command from the system menu and choose
|
||||
Mark. This puts you in Mark mode. You can use the mouse or the
|
||||
keyboard to select text. You can move the cursor and select text using
|
||||
the standard rules and keystrokes for this feature.
|
||||
|
||||
Action Explanation
|
||||
------ -----------
|
||||
Enter Exits Mark mode. Any marked text is copied to the
|
||||
Clipboard.
|
||||
|
||||
Escape Exits Mark mode. No text is selected.
|
||||
|
||||
Right mouse button same as Enter.
|
||||
|
||||
Edit|Copy same as Enter.
|
||||
|
||||
Edit|Paste pastes text into stdin, receiving the contents of
|
||||
the Clipboard as input to your program, merging it
|
||||
with any keyboard input.
|
||||
|
||||
Example
|
||||
-------
|
||||
If you are writing a program that requests its data from the keyboard
|
||||
via scanf, cin, or other similar stdio/conio functions:
|
||||
|
||||
1. Write a data file that contains your entire input.
|
||||
|
||||
2. Load that file into NotePad, select it, and copy it to the
|
||||
Clipboard.
|
||||
|
||||
3. Run your program, go to the system edit menu, and choose Paste.
|
||||
|
||||
Your program accepts the contents of Clipboard as input.
|
||||
|
||||
Notes:
|
||||
|
||||
- The Paste command is grayed if the Clipboard contains no objects of
|
||||
type CF_TEXT or if your program has terminated.
|
||||
|
||||
- The Copy command is grayed if you have not selected a block of text.
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,108 @@
|
||||
===========================================================================
|
||||
International API
|
||||
===========================================================================
|
||||
|
||||
|
||||
Borland C++ provides support for international program
|
||||
development. Currently, support is provided for the
|
||||
Great Britain and United States English, French, and
|
||||
German locales. Future releases of Borland C++ will
|
||||
increase the number of locales supported.
|
||||
|
||||
The LOCALE.BLL Support for these locales is contained in the
|
||||
file is installed LOCALE.BLL library. By default, the "C" locale is in
|
||||
in BC45\BIN effect. However, a call to setlocale dynamically links
|
||||
directory. the LOCALE.BLL library to your program. A locale-
|
||||
specific module is enabled by a call to setlocale. The
|
||||
call will also specify which character set to use with
|
||||
the locale. (Character set is sometimes referred to as
|
||||
"code page" or "code set.") You can query the locale
|
||||
settings by using localeconv and setlocale functions.
|
||||
See the Library Reference, Chapter 3, for a description
|
||||
of these functions.
|
||||
|
||||
If the call to setlocale can be resolved, several
|
||||
character-handling functions change their behavior.
|
||||
Because Borland C++ 4.5 international API currently
|
||||
supports only 8-bit characters (thereby enabling
|
||||
recognition of as many as 256 characters), only
|
||||
single-byte character-handling functions are affected.
|
||||
The list of affected functions is in the Library
|
||||
Reference, Chapter 1.
|
||||
|
||||
In your code, you must #define _ _USELOCALES_ _to have
|
||||
the locale-sensitive functions available. Otherwise,
|
||||
only the "C" locale macros will be used.
|
||||
|
||||
|
||||
The international =======================================================
|
||||
API sample program
|
||||
To illustrate the effects of selecting different
|
||||
locales, Borland C++ provides a sample program. The
|
||||
sample program (named INTLDEMO.EXE) is an ObjectWindows
|
||||
application. All source code and a project file for the
|
||||
sample are provided. The sample program INTLDEMO (in
|
||||
BC45\EXAMPLES\WINDOWS\INTLDEMO) demonstrates how the
|
||||
setlocale function can produce an "internationally
|
||||
aware" Windows application. You can switch the inter-
|
||||
face language at run time between English, French, and
|
||||
German.
|
||||
|
||||
|
||||
1
|
||||
|
||||
|
||||
INTLDEMO displays all of the Windows ANSI character set
|
||||
(also referred to as the WIN 1252 character set) in a
|
||||
16-by-16 character grid. A number of characters are
|
||||
highlighted according to the selections under the
|
||||
"Locale" and the "Classification" menus. When you
|
||||
execute INTLDEMO, the screen shows the default "C"
|
||||
locale, and the default classification is isalpha. The
|
||||
highlighted characters are therefore the characters A
|
||||
to Z and a to z. By selecting another locale (for
|
||||
example, French) the accented versions of the
|
||||
characters (for example ‚) are also highlighted.
|
||||
Various combinations of locale and classification can
|
||||
be illustrated by selecting the appropriate menu items.
|
||||
|
||||
The results of calling the localeconv function for the
|
||||
current locale are illustrated by selecting
|
||||
"Conventions|Show". For example, with the French locale
|
||||
selected, the international currency symbol becomes FRF
|
||||
and the currency symbol becomes F. Note that this
|
||||
window can remain open while either the language or
|
||||
locale is changed and the values are updated
|
||||
accordingly.
|
||||
|
||||
The "File|List" menu produces a dialog box that
|
||||
demonstrates the effects of the locale on collation
|
||||
sequences and on date and time functions. The files in
|
||||
the current directory are shown sorted according to the
|
||||
current locale, and with date and times displayed
|
||||
according to the conventions and in the language of the
|
||||
selected locale. File names can be switched between
|
||||
upper/lower case to demonstrate the effects of the
|
||||
toupper and tolower functions in the current locale.
|
||||
The dialog also illustrates the effects of the
|
||||
BWCCIntlInit function on the Ok, Cancel and Help
|
||||
buttons of the dialog. Any file can be selected to be
|
||||
viewed and its contents similarly sorted according to
|
||||
the current locale collation sequence.
|
||||
|
||||
The "Language" menu allows the language of the UI to be
|
||||
changed "on the fly." This feature uses ObjectWindow's
|
||||
ability to associate windows interface elements to a
|
||||
module, in this case a .DLL that contains the resources
|
||||
in a particular language. When the language is changed,
|
||||
a new language .DLL is loaded and the interface
|
||||
elements are reloaded from that .DLL. Note that the
|
||||
date and times in the File List dialog are not affected
|
||||
by the change in language, but by the choice of locale.
|
||||
|
||||
The 'Classification' menu shows a list of the locale-
|
||||
sensitive isxxx() functions. Selecting one of these
|
||||
items will cause the characters that return true for
|
||||
this function in the current locale to be highlighted
|
||||
in the main window.
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
// These error codes have been taken from the OLE header files and sorted
|
||||
// into numerical order. The comments too come from the OLE header files.
|
||||
//
|
||||
// This list is provided as a convenience for interpreting OLE error
|
||||
// codes when functions fail.
|
||||
|
||||
#define S_OK 0x00000000
|
||||
#define S_FALSE 0x00000001
|
||||
#define STG_S_CONVERTED 0x00030200
|
||||
#define OLE_S_FIRST 0x00040000 // all interfaces
|
||||
#define OLE_S_USEREG 0x00040000 // use the reg database to provide the requested info
|
||||
#define OLE_S_STATIC 0x00040001 // success, but static
|
||||
#define OLE_S_MAC_CLIPFORMAT 0x00040002 // macintosh clipboard format
|
||||
#define OLE_S_LAST 0x000400FF
|
||||
#define DRAGDROP_S_DROP 0x00040100
|
||||
#define DRAGDROP_S_CANCEL 0x00040101
|
||||
#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102
|
||||
#define CLASSFACTORY_S_FIRST 0x00040110 // IClassFactory
|
||||
#define CLASSFACTORY_S_LAST 0x0004011F
|
||||
#define MARSHAL_S_FIRST 0x00040120 // IMarshal, IStdMarshalInfo, marshal APIs
|
||||
#define MARSHAL_S_LAST 0x0004012F
|
||||
#define DATA_S_SAMEFORMATETC 0x00040130
|
||||
#define DATA_S_FIRST 0x00040130 // IDataObject
|
||||
#define DATA_S_LAST 0x0004013F
|
||||
#define VIEW_S_FIRST 0x00040140 // IViewObject
|
||||
#define VIEW_S_LAST 0x0004014F
|
||||
#define REGDB_S_FIRST 0x00040150 // reg.dat manipulation API
|
||||
#define REGDB_S_LAST 0x0004015F
|
||||
#define CACHE_S_FORMATETC_NOTSUPPORTED 0x00040170
|
||||
#define CACHE_S_FIRST 0x00040170 // IOleCache
|
||||
#define CACHE_S_SAMECACHE 0x00040171
|
||||
#define CACHE_S_SOMECACHES_NOTUPDATED 0x00040172
|
||||
#define CACHE_S_LAST 0x0004017F
|
||||
#define OLEOBJ_S_FIRST 0x00040180 // IOleObject
|
||||
#define OLEOBJ_S_CANNOT_DOVERB_NOW 0x00040181
|
||||
#define OLEOBJ_S_INVALIDHWND 0x00040182
|
||||
#define OLEOBJ_S_LAST 0x0004018F
|
||||
#define CLIENTSITE_S_FIRST 0x00040190 // IOleClientSite
|
||||
#define CLIENTSITE_S_LAST 0x0004019F
|
||||
#define INPLACE_S_FIRST 0x000401A0 // IOleWindow,IOleInPlaceObject,IOleInPlaceActiveObject
|
||||
#define INPLACE_S_TRUNCATED 0x000401A0 // Message is too long, some of it had to be truncated before displaying
|
||||
#define INPLACE_S_LAST 0x000401AF // IOleInPlaceUIWindow,IOleInPlaceFrame,IOleInPlaceSite
|
||||
#define ENUM_S_FIRST 0x000401B0 // IEnum*
|
||||
#define ENUM_S_LAST 0x000401BF
|
||||
#define CONVERT10_S_FIRST 0x000401C0 // OleConvertOLESTREAMToIStorage, OleConvertIStorageToOLESTREAM
|
||||
#define CONVERT10_S_NO_PRESENTATION 0x000401C0 // Returned by either API, the original object had no presentation
|
||||
#define CONVERT10_S_LAST 0x000401CF
|
||||
#define CLIPBRD_S_FIRST 0x000401D0 // OleSetClipboard, OleGetClipboard, OleFlushClipboard
|
||||
#define CLIPBRD_S_LAST 0x000401DF
|
||||
#define MK_S_FIRST 0x000401E0 // IMoniker, IBindCtx, IRunningObjectTable, IParseDisplayName
|
||||
#define MK_S_REDUCED_TO_SELF 0x000401E2
|
||||
#define MK_S_ME 0x000401E4
|
||||
#define MK_S_HIM 0x000401E5
|
||||
#define MK_S_US 0x000401E6
|
||||
#define MK_S_MONIKERALREADYREGISTERED 0x000401E7
|
||||
#define MK_S_LAST 0x000401EF // IOleContainer, IOleItemContainer, IOleLink
|
||||
#define CO_S_FIRST 0x000401F0 // all Co* API
|
||||
#define CO_S_LAST 0x000401FF
|
||||
#define E_NOTIMPL 0x80000001 // not implemented
|
||||
#define E_OUTOFMEMORY 0x80000002 // ran out of memory
|
||||
#define E_INVALIDARG 0x80000003 // one or more arguments are invalid
|
||||
#define E_NOINTERFACE 0x80000004 // no such interface supported
|
||||
#define E_POINTER 0x80000005 // invalid pointer
|
||||
#define E_HANDLE 0x80000006 // invalid handle
|
||||
#define E_ABORT 0x80000007 // operation aborted
|
||||
#define E_FAIL 0x80000008 // unspecified error
|
||||
#define E_ACCESSDENIED 0x80000009 // general access denied error
|
||||
#define E_UNEXPECTED 0x8000FFFF // relatively catastrophic failure
|
||||
#define RPC_E_CALL_REJECTED 0x80010001 // call was rejected by callee
|
||||
#define RPC_E_CALL_CANCELED 0x80010002 // call was canceld by call - returned by MessagePending
|
||||
#define RPC_E_CANTPOST_INSENDCALL 0x80010003 // the caller is dispatching an intertask SendMessage call and can NOT call out via PostMessage
|
||||
#define RPC_E_CANTCALLOUT_INASYNCCALL 0x80010004 // the caller is dispatching an asynchronus call can NOT make an outgoing call on behalf of this call
|
||||
#define RPC_E_CANTCALLOUT_INEXTERNALCALL 0x80010005 // the caller is not in a state where an outgoing call can be made
|
||||
#define RPC_E_CONNECTION_TERMINATED 0x80010006 // the connection terminated or is in a bogus state
|
||||
#define RPC_E_SERVER_DIED 0x80010007 // the callee (server [not server application]) is not available
|
||||
#define RPC_E_CLIENT_DIED 0x80010008 // the caller (client) disappeared while the callee (server) was processing a call
|
||||
#define RPC_E_INVALID_DATAPACKET 0x80010009 // the date paket with the marshalled parameter data is incorrect
|
||||
#define RPC_E_CANTTRANSMIT_CALL 0x8001000A // the call was not transmitted properly; the message queue was full and was not emptied after yielding
|
||||
#define RPC_E_CLIENT_CANTMARSHAL_DATA 0x8001000B // the client (caller) can not marshall the parameter data
|
||||
#define RPC_E_CLIENT_CANTUNMARSHAL_DATA 0x8001000C // the client (caller) can not unmarshall the return data
|
||||
#define RPC_E_SERVER_CANTMARSHAL_DATA 0x8001000D // the server (caller) can not unmarshall the parameter data
|
||||
#define RPC_E_SERVER_CANTUNMARSHAL_DATA 0x8001000E // the server (caller) can not marshall the return data - low memory
|
||||
#define RPC_E_INVALID_DATA 0x8001000F // received data are invalid; can be server or client data
|
||||
#define RPC_E_INVALID_PARAMETER 0x80010010 // a particular parameter is invalid and can not be un/marshalled
|
||||
#define RPC_E_CANTCALLOUT_AGAIN 0x80010011 // DDE conversation - no second outgoing call on same channel
|
||||
#define RPC_E_UNEXPECTED 0x8001FFFF // a internal error occured
|
||||
#define DISP_E_UNKNOWNINTERFACE 0x80020001
|
||||
#define DISP_E_MEMBERNOTFOUND 0x80020003
|
||||
#define DISP_E_PARAMNOTFOUND 0x80020004
|
||||
#define DISP_E_TYPEMISMATCH 0x80020005
|
||||
#define DISP_E_UNKNOWNNAME 0x80020006
|
||||
#define DISP_E_NONAMEDARGS 0x80020007
|
||||
#define DISP_E_BADVARTYPE 0x80020008
|
||||
#define DISP_E_EXCEPTION 0x80020009
|
||||
#define DISP_E_OVERFLOW 0x8002000A
|
||||
#define DISP_E_BADINDEX 0x8002000B
|
||||
#define DISP_E_UNKNOWNLCID 0x8002000C
|
||||
#define DISP_E_ARRAYISLOCKED 0x8002000D
|
||||
#define DISP_E_BADPARAMCOUNT 0x8002000E
|
||||
#define DISP_E_PARAMNOTOPTIONAL 0x8002000F
|
||||
#define DISP_E_BADCALLEE 0x80020010
|
||||
#define DISP_E_NOTACOLLECTION 0x80020011
|
||||
#define TYPE_E_BUFFERTOOSMALL 0x80028016
|
||||
#define TYPE_E_INVDATAREAD 0x80028018
|
||||
#define TYPE_E_UNSUPFORMAT 0x80028019
|
||||
#define TYPE_E_REGISTRYACCESS 0x8002801C
|
||||
#define TYPE_E_LIBNOTREGISTERED 0x8002801D
|
||||
#define TYPE_E_UNDEFINEDTYPE 0x80028027
|
||||
#define TYPE_E_QUALIFIEDNAMEDISALLOWED 0x80028028
|
||||
#define TYPE_E_INVALIDSTATE 0x80028029
|
||||
#define TYPE_E_WRONGTYPEKIND 0x8002802A
|
||||
#define TYPE_E_ELEMENTNOTFOUND 0x8002802B
|
||||
#define TYPE_E_AMBIGUOUSNAME 0x8002802C
|
||||
#define TYPE_E_NAMECONFLICT 0x8002802D
|
||||
#define TYPE_E_UNKNOWNLCID 0x8002802E
|
||||
#define TYPE_E_DLLFUNCTIONNOTFOUND 0x8002802F
|
||||
#define TYPE_E_BADMODULEKIND 0x800288BD
|
||||
#define TYPE_E_SIZETOOBIG 0x800288C5
|
||||
#define TYPE_E_DUPLICATEID 0x800288C6
|
||||
#define TYPE_E_TYPEMISMATCH 0x80028CA0
|
||||
#define TYPE_E_OUTOFBOUNDS 0x80028CA1
|
||||
#define TYPE_E_IOERROR 0x80028CA2
|
||||
#define TYPE_E_CANTCREATETMPFILE 0x80028CA3
|
||||
#define TYPE_E_CANTLOADLIBRARY 0x80029C4A
|
||||
#define TYPE_E_INCONSISTENTPROPFUNCS 0x80029C83
|
||||
#define TYPE_E_CIRCULARTYPE 0x80029C84
|
||||
#define STG_E_INVALIDFUNCTION 0x80030001
|
||||
#define STG_E_FILENOTFOUND 0x80030002
|
||||
#define STG_E_PATHNOTFOUND 0x80030003
|
||||
#define STG_E_TOOMANYOPENFILES 0x80030004
|
||||
#define STG_E_ACCESSDENIED 0x80030005
|
||||
#define STG_E_INVALIDHANDLE 0x80030006
|
||||
#define STG_E_INSUFFICIENTMEMORY 0x80030008
|
||||
#define STG_E_INVALIDPOINTER 0x80030009
|
||||
#define STG_E_NOMOREFILES 0x80030012
|
||||
#define STG_E_DISKISWRITEPROTECTED 0x80030013
|
||||
#define STG_E_SEEKERROR 0x80030019
|
||||
#define STG_E_WRITEFAULT 0x8003001D
|
||||
#define STG_E_READFAULT 0x8003001E
|
||||
#define STG_E_SHAREVIOLATION 0x80030020
|
||||
#define STG_E_LOCKVIOLATION 0x80030021
|
||||
#define STG_E_FILEALREADYEXISTS 0x80030050
|
||||
#define STG_E_INVALIDPARAMETER 0x80030057
|
||||
#define STG_E_MEDIUMFULL 0x80030070
|
||||
#define STG_E_ABNORMALAPIEXIT 0x800300FA
|
||||
#define STG_E_INVALIDHEADER 0x800300FB
|
||||
#define STG_E_INVALIDNAME 0x800300FC
|
||||
#define STG_E_UNKNOWN 0x800300FD
|
||||
#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FE
|
||||
#define STG_E_INVALIDFLAG 0x800300FF
|
||||
#define STG_E_INUSE 0x80030100
|
||||
#define STG_E_NOTCURRENT 0x80030101
|
||||
#define STG_E_REVERTED 0x80030102
|
||||
#define STG_E_CANTSAVE 0x80030103
|
||||
#define STG_E_OLDFORMAT 0x80030104
|
||||
#define STG_E_OLDDLL 0x80030105
|
||||
#define STG_E_SHAREREQUIRED 0x80030106
|
||||
#define STG_E_NOTFILEBASEDSTORAGE 0x80030107
|
||||
#define STG_E_EXTANTMARSHALLINGS 0x80030108
|
||||
#define OLE_E_FIRST 0x80040000 // all interfaces
|
||||
#define OLE_E_OLEVERB 0x80040000 // invalid OLEVERB structure
|
||||
#define OLE_E_ADVF 0x80040001 // invalid advise flags
|
||||
#define OLE_E_ENUM_NOMORE 0x80040002 // you can't enuemrate any more, because the associated data is missing
|
||||
#define OLE_E_ADVISENOTSUPPORTED 0x80040003 // this implementation doesn't take advises
|
||||
#define OLE_E_NOCONNECTION 0x80040004 // there is no connection for this connection id
|
||||
#define OLE_E_NOTRUNNING 0x80040005 // need run the object to perform this operation
|
||||
#define OLE_E_NOCACHE 0x80040006 // there is no cache to operate on
|
||||
#define OLE_E_BLANK 0x80040007 // Uninitialized object
|
||||
#define OLE_E_CLASSDIFF 0x80040008 // linked object's source class has changed
|
||||
#define OLE_E_CANT_GETMONIKER 0x80040009 // not able to get the moniker of the object
|
||||
#define OLE_E_CANT_BINDTOSOURCE 0x8004000A // not able to bind to the source
|
||||
#define OLE_E_STATIC 0x8004000B // object is static, operation not allowed
|
||||
#define OLE_E_PROMPTSAVECANCELLED 0x8004000C // user cancelled out of save dialog
|
||||
#define OLE_E_INVALIDRECT 0x8004000D // invalid rectangle
|
||||
#define OLE_E_WRONGCOMPOBJ 0x8004000E // compobj.dll is too old for the ole2.dll initialized
|
||||
#define OLE_E_INVALIDHWND 0x8004000F // invalid window handle
|
||||
#define OLE_E_NOT_INPLACEACTIVE 0x80040010 // object is not in any of the inplace active states
|
||||
#define OLE_E_CANTCONVERT 0x80040011 // not able to convert the object
|
||||
#define OLE_E_NOSTORAGE 0x80040012 // not able to perform the operation because object is not given storage yet.
|
||||
#define DVGEN_E_FIRST 0x80040064 // (OLE_E_FIRST+100) Might move to FACILITY_NULL
|
||||
#define DV_E_FORMATETC 0x80040064 // invalid FORMATETC structure
|
||||
#define DV_E_DVTARGETDEVICE 0x80040065 // invalid DVTARGETDEVICE structure
|
||||
#define DV_E_STGMEDIUM 0x80040066 // invalid STDGMEDIUM structure
|
||||
#define DV_E_STATDATA 0x80040067 // invalid STATDATA structure
|
||||
#define DV_E_LINDEX 0x80040068 // invalid lindex
|
||||
#define DV_E_TYMED 0x80040069 // invalid tymed
|
||||
#define DV_E_CLIPFORMAT 0x8004006A // invalid clipboard format
|
||||
#define DV_E_DVASPECT 0x8004006B // invalid aspect(s)
|
||||
#define DV_E_DVTARGETDEVICE_SIZE 0x8004006C // tdSize paramter of the DVTARGETDEVICE structure is invalid
|
||||
#define DV_E_NOIVIEWOBJECT 0x8004006D // object doesn't support IViewObject interface
|
||||
#define OLE_E_LAST 0x800400FF
|
||||
#define DRAGDROP_E_FIRST 0x80040100 // IDropSource, IDropTarget
|
||||
#define DRAGDROP_S_FIRST 0x80040100 // IDropSource, IDropTarget
|
||||
#define DRAGDROP_E_INVALIDHWND 0x80040100 // invalid HWND
|
||||
#define DRAGDROP_E_ALREADYREGISTERED 0x80040100 // this window has already been registered as a drop target
|
||||
#define DRAGDROP_E_NOTREGISTERED 0x80040100 // trying to revoke a drop target that has not been registered
|
||||
#define DRAGDROP_E_LAST 0x8004010F
|
||||
#define DRAGDROP_S_LAST 0x8004010F
|
||||
#define CLASS_E_NOAGGREGATION 0x80040110 // class does not support aggregation (or class object is remote)
|
||||
#define CLASSFACTORY_E_FIRST 0x80040110 // IClassFactory
|
||||
#define CLASS_E_CLASSNOTAVAILABLE 0x80040111 // dll doesn't support that class (returned from DllGetClassObject)
|
||||
#define CLASSFACTORY_E_LAST 0x8004011F
|
||||
#define MARSHAL_E_FIRST 0x80040120 // IMarshal, IStdMarshalInfo, marshal APIs
|
||||
#define MARSHAL_E_LAST 0x8004012F
|
||||
#define DATA_E_FIRST 0x80040130 // IDataObject
|
||||
#define DATA_E_LAST 0x8004013F
|
||||
#define VIEW_E_DRAW 0x80040140
|
||||
#define VIEW_E_FIRST 0x80040140 // IViewObject
|
||||
#define VIEW_E_LAST 0x8004014F
|
||||
#define REGDB_E_FIRST 0x80040150 // reg.dat manipulation API
|
||||
#define REGDB_E_READREGDB 0x80040150 // some error reading the registration database
|
||||
#define REGDB_E_WRITEREGDB 0x80040151 // some error reading the registration database
|
||||
#define REGDB_E_KEYMISSING 0x80040152 // some error reading the registration database
|
||||
#define REGDB_E_INVALIDVALUE 0x80040153 // some error reading the registration database
|
||||
#define REGDB_E_CLASSNOTREG 0x80040154 // some error reading the registration database
|
||||
#define REGDB_E_IIDNOTREG 0x80040155 // some error reading the registration database
|
||||
#define REGDB_E_LAST 0x8004015F
|
||||
#define CACHE_E_NOCACHE_UPDATED 0x80040170
|
||||
#define CACHE_E_FIRST 0x80040170 // IOleCache
|
||||
#define CACHE_E_LAST 0x8004017F
|
||||
#define OLEOBJ_E_NOVERBS 0x80040180
|
||||
#define OLEOBJ_S_INVALIDVERB 0x80040180
|
||||
#define OLEOBJ_E_FIRST 0x80040180 // IOleObject
|
||||
#define OLEOBJ_E_INVALIDVERB 0x80040181
|
||||
#define OLEOBJ_E_LAST 0x8004018F
|
||||
#define CLIENTSITE_E_FIRST 0x80040190 // IOleClientSite
|
||||
#define CLIENTSITE_E_LAST 0x8004019F
|
||||
#define INPLACE_E_FIRST 0x800401A0 // IOleWindow,IOleInPlaceObject,IOleInPlaceActiveObject
|
||||
#define INPLACE_E_NOTUNDOABLE 0x800401A0 // undo is not avaiable
|
||||
#define INPLACE_E_NOTOOLSPACE 0x800401A1 // Space for tools is not available
|
||||
#define INPLACE_E_LAST 0x800401AF // IOleInPlaceUIWindow,IOleInPlaceFrame,IOleInPlaceSite
|
||||
#define ENUM_E_FIRST 0x800401B0 // IEnum*
|
||||
#define ENUM_E_LAST 0x800401BF
|
||||
#define CONVERT10_E_FIRST 0x800401C0 // OleConvertOLESTREAMToIStorage, OleConvertIStorageToOLESTREAM
|
||||
#define CONVERT10_E_OLESTREAM_GET 0x800401C0 // OLESTREAM Get method failed
|
||||
#define CONVERT10_E_OLESTREAM_PUT 0x800401C1 // OLESTREAM Put method failed
|
||||
#define CONVERT10_E_OLESTREAM_FMT 0x800401C2 // Contents of the OLESTREAM not in correct format
|
||||
#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3 // There was in an error in a Windows GDI call while converting the bitmap to a DIB
|
||||
#define CONVERT10_E_STG_FMT 0x800401C4 // Contents of the IStorage not in correct format
|
||||
#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5 // Contents of IStorage is missing one of the standard streams ("\1CompObj", "\1Ole", "\2OlePres000")
|
||||
#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6 // There was in an error in a Windows GDI call while converting the DIB to a bitmap
|
||||
#define CONVERT10_E_LAST 0x800401CF
|
||||
#define CLIPBRD_E_FIRST 0x800401D0 // OleSetClipboard, OleGetClipboard, OleFlushClipboard
|
||||
#define CLIPBRD_E_CANT_OPEN 0x800401D0 // OpenClipboard Failed
|
||||
#define CLIPBRD_E_CANT_EMPTY 0x800401D1 // EmptyClipboard Failed
|
||||
#define CLIPBRD_E_CANT_SET 0x800401D2 // SetClipboard Failed
|
||||
#define CLIPBRD_E_BAD_DATA 0x800401D3 // Data on clipboard is invalid
|
||||
#define CLIPBRD_E_CANT_CLOSE 0x800401D4 // OpenClipboard Failed
|
||||
#define CLIPBRD_E_LAST 0x800401DF
|
||||
#define MK_E_CONNECTMANUALLY 0x800401E0
|
||||
#define MK_E_FIRST 0x800401E0 // IMoniker, IBindCtx, IRunningObjectTable, IParseDisplayName
|
||||
#define MK_E_EXCEEDEDDEADLINE 0x800401E1
|
||||
#define MK_E_NEEDGENERIC 0x800401E2
|
||||
#define MK_E_UNAVAILABLE 0x800401E3
|
||||
#define MK_E_SYNTAX 0x800401E4
|
||||
#define MK_E_NOOBJECT 0x800401E5
|
||||
#define MK_E_INVALIDEXTENSION 0x800401E6
|
||||
#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7
|
||||
#define MK_E_NOTBINDABLE 0x800401E8
|
||||
#define MK_E_NOTBOUND 0x800401E9 // called IBindCtx->RevokeObjectBound for an object which was not bound
|
||||
#define MK_E_CANTOPENFILE 0x800401EA
|
||||
#define MK_E_MUSTBOTHERUSER 0x800401EB
|
||||
#define MK_E_NOINVERSE 0x800401EC
|
||||
#define MK_E_NOSTORAGE 0x800401ED
|
||||
#define MK_E_NOPREFIX 0x800401EE
|
||||
#define MK_E_LAST 0x800401EF // IOleContainer, IOleItemContainer, IOleLink
|
||||
#define CO_E_FIRST 0x800401F0 // all Co* API
|
||||
#define CO_E_NOTINITIALIZED 0x800401F0 // CoInitialize has not been called and must be
|
||||
#define CO_E_ALREADYINITIALIZED 0x800401F1 // CoInitialize has already been called and cannot be called again (temporary)
|
||||
#define CO_E_CANTDETERMINECLASS 0x800401F2 // can't determine clsid (e.g., extension not in reg.dat)
|
||||
#define CO_E_CLASSSTRING 0x800401F3 // the string form of the clsid is invalid (including ole1 classes)
|
||||
#define CO_E_IIDSTRING 0x800401F4 // the string form of the iid is invalid
|
||||
#define CO_E_APPNOTFOUND 0x800401F5 // application not found
|
||||
#define CO_E_APPSINGLEUSE 0x800401F6 // application cannot be run more than once
|
||||
#define CO_E_ERRORINAPP 0x800401F7 // some error in the app program file
|
||||
#define CO_E_DLLNOTFOUND 0x800401F8 // dll not found
|
||||
#define CO_E_ERRORINDLL 0x800401F9 // some error in the dll file
|
||||
#define CO_E_WRONGOSFORAPP 0x800401FA // app written for other version of OS or other OS altogether
|
||||
#define CO_E_OBJNOTREG 0x800401FB // object is not registered
|
||||
#define CO_E_OBJISREG 0x800401FC // object is already registered
|
||||
#define CO_E_OBJNOTCONNECTED 0x800401FD // handler is not connected to server
|
||||
#define CO_E_APPDIDNTREG 0x800401FE // app was launched, but didn't registered a class factory
|
||||
#define CO_E_LAST 0x800401FF
|
||||
#define FACILITY_NULL 0 // generally useful errors ([SE]_*)
|
||||
#define FACILITY_RPC 1 // remote procedure call errors (RPC_E_*)
|
||||
#define FACILITY_DISPATCH 2 // late binding dispatch errors
|
||||
#define FACILITY_STORAGE 3 // storage errors (STG_E_*)
|
||||
#define FACILITY_ITF 4 // interface-specific errors
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,64 @@
|
||||
RWINI.TXT
|
||||
===========
|
||||
|
||||
This file explains switches used in the WORKSHOP.INI
|
||||
file that control driver behavior (WORKSHOP.INI is
|
||||
in your Windows directory).
|
||||
|
||||
A number of display drivers don't implement some
|
||||
off-screen operations correctly. This file documents
|
||||
specific workarounds for some of these driver problems.
|
||||
Most of the workarounds were tested on a variety of drivers
|
||||
and don't cause additional problems. However, some of these
|
||||
workarounds have side effects on other drivers, or they
|
||||
significantly affect the performance of the operation. These
|
||||
workarounds are controlled by switches in WORKSHOP.INI.
|
||||
Place all of the switches under the section [Resource Workshop].
|
||||
|
||||
|
||||
RWS_OwnFloodFill=1
|
||||
------------------
|
||||
Some drivers don't perform flood fill correctly. Either the
|
||||
operation fails, or vertical bars are placed on byte
|
||||
boundaries in the image. If when using the paint can tool
|
||||
you see either of these symptoms, use this switch to correct
|
||||
it. Note that this switch is slower than the driver code.
|
||||
|
||||
RWS_Own16Color=1
|
||||
----------------
|
||||
If you are creating 16-color bitmaps with custom colors
|
||||
(for example, a gray-scale image), you must turn off the
|
||||
"Save with default device colors" option in the
|
||||
Options|Editor options dialog box. If, after doing that, the
|
||||
color table returns to the default colors after saving, use
|
||||
this switch to correct the problem.
|
||||
|
||||
RWS_Own256Color=1
|
||||
-----------------
|
||||
If you're creating 256-color images with custom colors and
|
||||
the colors return to the default, use this switch to correct
|
||||
the problem.
|
||||
|
||||
RWS_ColorCopy=1
|
||||
---------------
|
||||
Some drivers don't perform GetDIBits properly when the
|
||||
source device dependent bitmap is monochrome and either
|
||||
less than 8 pixels wide or an odd number of pixels wide.
|
||||
You can determine if this problem exists by creating a
|
||||
new 6X6X2-Color image. If the initial image is black,
|
||||
your driver has this problem. This switch copies the
|
||||
monochrome image to a color image before calling GetDIBits.
|
||||
|
||||
NoDriverHacks=1
|
||||
---------------
|
||||
When using 256-color drivers, Resource Workshop displays
|
||||
a grid on all zoomed images. Use this switch to turn off the
|
||||
grid. If Workshop crashes when an image is zoomed, turn the
|
||||
switch off and report the problem to your driver manufacturer.
|
||||
|
||||
bAutoH=0
|
||||
--------
|
||||
Use this switch to suppress the Add File To Project dialog
|
||||
box when creating new .RC projects.
|
||||
|
||||
========= END OF FILE RWINI.TXT =========
|
||||
@@ -0,0 +1,815 @@
|
||||
/*************************************************************************/
|
||||
TURBO DEBUGGER
|
||||
Assembler-level debugging
|
||||
|
||||
This file contains information about Assembler-level debugging. The
|
||||
contents of the file are as follows:
|
||||
|
||||
1. When source debugging isn't enough
|
||||
2. The assembler
|
||||
3. Assembler-specific bugs
|
||||
4. Inline assembler tips
|
||||
5. Inline assembler keywords
|
||||
6. The Numeric Processor window
|
||||
|
||||
The material in this file is for programmers who are familiar with
|
||||
programming the 80x86 processor family in assembler. You don't need
|
||||
to use the information in this chapter to debug your programs, but
|
||||
there are certain problems that might be easier to find using
|
||||
the techniques discussed here.
|
||||
|
||||
|
||||
===================================================================
|
||||
1. When source debugging isn't enough
|
||||
===================================================================
|
||||
|
||||
Sometimes, however, you can gain insight into a problem by looking
|
||||
at the exact instructions that the compiler generated, the contents
|
||||
of the CPU registers, and the contents of the stack. To do this,
|
||||
you need to be familiar with both the 80x86 family of processors
|
||||
and with how the compiler turns your source code into machine
|
||||
instructions. Because many excellent books are available about the
|
||||
internal workings of the CPU, we won't go into that in detail here.
|
||||
You can quickly learn how the compiler turns your source code into
|
||||
machine instructions by looking at the instructions generated for
|
||||
each line of source code within the CPU window.
|
||||
|
||||
Turbo Debugger can detect an 8087, 80287, 80387, or 80486 numeric
|
||||
coprocessor and disassemble those instructions if a floating-point
|
||||
chip or emulator is present.
|
||||
|
||||
The instruction mnemonic RETF indicates that this is a far return
|
||||
instruction. The normal RET mnemonic indicates a near return.
|
||||
|
||||
Where possible, the target of JMP and CALL instructions is
|
||||
displayed symbolically. If CS:IP is a JMP or conditional jump
|
||||
instruction, an up-arrow or down-arrow that shows jump direction
|
||||
will be displayed only if the executing instruction will cause the
|
||||
jump to occur. Also, memory addresses used by MOV, ADD, and other
|
||||
instructions display symbolic addresses.
|
||||
|
||||
|
||||
===================================================================
|
||||
2. The assembler
|
||||
===================================================================
|
||||
|
||||
If you use the Assemble command in the Code pane local menu, Turbo
|
||||
Debugger lets you assemble instructions for the 8086, 80186, 80286,
|
||||
80386, and 80486 processors, and also for the 8087, 80287, and 80387
|
||||
numeric coprocessors.
|
||||
|
||||
When you use Turbo Debugger's built-in assembler to modify your program,
|
||||
the changes you make are not permanent. If you reload your program Run|
|
||||
Program Reset, or if you load another program using File|Open,
|
||||
you'll lose any changes you've made.
|
||||
|
||||
Normally you use the assembler to test an idea for fixing your program.
|
||||
Once you've verified that the change works, you must change your source
|
||||
code and recompile and link your program.
|
||||
|
||||
The following sections describe the differences between the built-
|
||||
in assembler and the syntax accepted by Borland C++'s inline
|
||||
assembler.
|
||||
|
||||
|
||||
Operand address size overrides
|
||||
==============================
|
||||
|
||||
For the call (CALL), jump (JMP), and conditional jump (JNE, JL, and
|
||||
so forth) instructions, the assembler automatically generates the
|
||||
smallest instruction that can reach the destination address. You
|
||||
can use the NEAR and FAR overrides before the destination address
|
||||
to assemble the instruction with a specific size. For example,
|
||||
|
||||
CALL FAR XYZ
|
||||
JMP NEAR A1
|
||||
|
||||
|
||||
Memory and immediate operands
|
||||
-----------------------------
|
||||
|
||||
When you use a symbol from your program as an instruction operand,
|
||||
you must tell the built-in assembler whether you mean the contents
|
||||
of the symbol or the address of the symbol. If you use just the
|
||||
symbol name, the assembler treats it as an address, exactly as if
|
||||
you had used the assembler OFFSET operator before it. If you put
|
||||
the symbol inside brackets ([ ]), it becomes a memory reference.
|
||||
For example, if your program contains the data definition
|
||||
|
||||
A DW 4
|
||||
|
||||
then "A" references the area of memory where A is stored.
|
||||
|
||||
When you assemble an instruction or evaluate an assembler
|
||||
expression to refer to the contents of a variable, use the name of
|
||||
the variable alone or between brackets:
|
||||
|
||||
mov dx,a
|
||||
mov ax,[a]
|
||||
|
||||
To refer to the address of the variable, use the OFFSET operator:
|
||||
|
||||
mov ax,offset a
|
||||
|
||||
|
||||
Operand data size overrides
|
||||
===========================
|
||||
|
||||
For some instructions, you must specify the operand size using one
|
||||
of the following expressions before the operand:
|
||||
|
||||
BYTE PTR
|
||||
WORD PTR
|
||||
|
||||
Here are examples of instructions using these overrides:
|
||||
|
||||
add BYTE PTR[si],10
|
||||
mov WORD PTR[bp+10],99
|
||||
|
||||
In addition to these size overrides, you can use the following
|
||||
overrides to assemble 8087/80287/80387/80486 numeric processor
|
||||
instructions:
|
||||
|
||||
DWORD PTR
|
||||
QWORD PTR
|
||||
TBYTE PTR
|
||||
|
||||
Here are some examples using these overrides:
|
||||
|
||||
fild QWORD PTR[bx]
|
||||
stp TBYTE PTR[bp+4]
|
||||
|
||||
|
||||
String instructions
|
||||
===================
|
||||
|
||||
When you assemble a string instruction, you must include the size
|
||||
(byte or word) as part of the instruction mnemonic. The assembler
|
||||
does not accept the form of the string instructions that uses a
|
||||
sizeless mnemonic with an operand that specifies the size. For
|
||||
example, use STOSW rather than STOS WORD PTR[di].
|
||||
|
||||
|
||||
=========================================
|
||||
3. Assembler-specific bugs
|
||||
=========================================
|
||||
|
||||
This section, which covers some of the common pitfalls of assembly
|
||||
language programming, is intended for people who have Turbo Assembler
|
||||
or use inline assembler in C++ programs. You should refer to the
|
||||
Turbo Assembler User's Guide for a fuller explanation on these
|
||||
often encountered errors--and tips on how to avoid them.
|
||||
|
||||
Forgetting to return to DOS
|
||||
===========================
|
||||
|
||||
In C++, a program ends automatically when there is no more code to
|
||||
execute, even if no explicit termination command was written into the
|
||||
program. Not so in assembly language, where only those actions that
|
||||
you explicitly request are performed. When you run a program that has
|
||||
no command to return to DOS, execution simply continues right past the
|
||||
end of the program's code and into whatever code happens to be in the
|
||||
adjacent memory.
|
||||
|
||||
|
||||
Forgetting a RET instruction
|
||||
============================
|
||||
|
||||
The proper invocation of a subroutine consists of a call to the subroutine
|
||||
from another section of code, execution of the subroutine, and a return
|
||||
from the subroutine to the calling code. Remember to insert a RET
|
||||
instruction in each subroutine, so that the RETurn to the calling code
|
||||
occurs. When you're typing a program, it's easy to skip a RET and end
|
||||
up with an error.
|
||||
|
||||
|
||||
Generating the wrong type of return
|
||||
===================================
|
||||
|
||||
The PROC directive has two effects. First, it defines a name by which a
|
||||
procedure can be called. Second, it controls whether the procedure is a near
|
||||
or far procedure.
|
||||
|
||||
The RET instructions in a procedure should match the type of the procedure,
|
||||
shouldn't they?
|
||||
|
||||
Yes and no. The problem is that it's possible and often desirable to group
|
||||
several subroutines in the same procedure. Since these subroutines lack an
|
||||
associated PROC directive, their RET instructions take on the type of the
|
||||
overall procedure, which is not necessarily the correct type for the
|
||||
individual subroutines.
|
||||
|
||||
|
||||
Reversing operands
|
||||
==================
|
||||
|
||||
To many people, the order of instruction operands in 8086 assembly language
|
||||
seems backward (and there is certainly some justification for this
|
||||
viewpoint). If the line
|
||||
|
||||
mov ax,bx
|
||||
|
||||
meant "move AX to BX," the line would scan smoothly from left to right, and
|
||||
this is exactly the way in which many microprocessor manufacturers have
|
||||
designed their assembly languages.
|
||||
|
||||
However, Intel took a different approach with 8086 assembly language; for
|
||||
us, the line means "move BX to AX," and that can sometimes cause confusion.
|
||||
|
||||
|
||||
Forgetting the stack or reserving a too-small stack
|
||||
===================================================
|
||||
|
||||
In most cases, you're treading on thin ice if you don't explicitly allocate
|
||||
space for a stack. Programs without an allocated stack sometimes run, but
|
||||
there is no assurance that these programs will run under all circumstances.
|
||||
DOS programs can have a .STACK directive to reserve space for the stack.
|
||||
For each program, you should reserve more than enough space for the
|
||||
deepest stack the program can use.
|
||||
|
||||
|
||||
Calling a subroutine that wipes out registers
|
||||
=============================================
|
||||
|
||||
When you're writing assembler code, it's easy to think of the registers
|
||||
as local variables, dedicated to the use of the procedure you're working
|
||||
on at the moment. In particular, there's a tendency to assume that
|
||||
registers are unchanged by calls to other procedures. It just isn't
|
||||
so--the registers are global variables, and each procedure can preserve or
|
||||
destroy any or all registers.
|
||||
|
||||
|
||||
Using the wrong sense for a conditional jump
|
||||
============================================
|
||||
|
||||
The profusion of conditional jumps in assembly language (JE, JNE, JC,
|
||||
JNC, JA, JB, JG, and so on) allows tremendous flexibility in writing
|
||||
code--and also makes it easy to select the wrong jump for a given purpose.
|
||||
Moreover, since condition-handling in assembly language requires at least
|
||||
two separate lines, one for the comparison and one for the conditional
|
||||
jump (it requires many more lines for complex conditions), assembly
|
||||
language condition-handling is less intuitive and more prone to errors than
|
||||
condition-handling in C++.
|
||||
|
||||
|
||||
Forgetting about REP string overrun
|
||||
===================================
|
||||
|
||||
String instructions have a curious property: After they're executed, the
|
||||
pointers they use wind up pointing to an address 1 byte away (or 2 bytes
|
||||
for a word instruction) from the last address processed. This can cause
|
||||
some confusion with repeated string instructions, especially REP SCAS and
|
||||
REP CMPS.
|
||||
|
||||
|
||||
Relying on a zero CX to cover a whole segment
|
||||
=============================================
|
||||
|
||||
Any repeated string instruction executed with CX equal to zero does nothing.
|
||||
This can be convenient in that there's no need to check for the zero
|
||||
case before executing a repeated string instruction; on the other hand,
|
||||
there's no way to access every byte in a segment with a byte-sized string
|
||||
instruction.
|
||||
|
||||
|
||||
Using incorrect direction flag settings
|
||||
=======================================
|
||||
|
||||
When a string instruction is executed, its associated pointer or pointers--
|
||||
SI or DI or both--increment or decrement. It all depends on the state of the
|
||||
direction flag.
|
||||
|
||||
The direction flag can be cleared with CLD to cause string instructions to
|
||||
increment (count up) and can be set with STD to cause string instructions to
|
||||
decrement (count down). Once cleared or set, the direction flag stays in the
|
||||
same state until either another CLD or STD is executed, or until the flags
|
||||
are popped from the stack with POPF or IRET. While it's handy to be able to
|
||||
program the direction flag once and then execute a series of string
|
||||
instructions that all operate in the same direction, the direction flag can
|
||||
also be responsible for intermittent and hard-to-find bugs by causing the
|
||||
behavior of string instructions to depend on code that executed much earlier.
|
||||
|
||||
|
||||
Using the wrong sense for a repeated string comparison
|
||||
======================================================
|
||||
|
||||
The CMPS instruction compares two areas of memory; the SCAS instruction
|
||||
compares the accumulator to an area of memory. Prefixed by REPE, either
|
||||
of these instructions can perform a comparison until either CX becomes
|
||||
zero or a not-equal comparison occurs. Unfortunately, it's easy to become
|
||||
confused about which of the REP prefixes does what.
|
||||
|
||||
|
||||
Forgetting about string segment defaults
|
||||
========================================
|
||||
|
||||
Each of the string instructions defaults to using a source segment (if any)
|
||||
of DS, and a destination segment (if any) of ES. It's easy to forget this
|
||||
and try to perform, say, a STOSB to the data segment, since that's where
|
||||
all the data you're processing with non-string instructions normally resides.
|
||||
|
||||
|
||||
Converting incorrectly from byte to word operations
|
||||
===================================================
|
||||
|
||||
In general, it's desirable to use the largest possible data size (usually
|
||||
word, but dword on an 80386) for a string instruction, since string
|
||||
instructions with larger data sizes often run faster.
|
||||
|
||||
There are a couple of potential pitfalls here. First, the conversion from a
|
||||
byte count to a word count by a simple
|
||||
|
||||
shr cx,1
|
||||
|
||||
loses a byte if CX is odd, since the least-significant bit is shifted out.
|
||||
|
||||
Second, make sure you remember SHR divides the byte count by two. Using,
|
||||
say, STOSW with a byte rather than a word count can wipe out other data
|
||||
and cause problems of all sorts.
|
||||
|
||||
|
||||
Using multiple prefixes
|
||||
=======================
|
||||
|
||||
String instructions with multiple prefixes are error-prone and should
|
||||
generally be avoided.
|
||||
|
||||
|
||||
Relying on the operand(s) to a string instruction
|
||||
=================================================
|
||||
|
||||
The optional operand or operands to a string instruction are used for data
|
||||
sizing and segment overrides only, and do not guarantee that the memory
|
||||
location referenced is accessed.
|
||||
|
||||
|
||||
Wiping out a register with multiplication
|
||||
=========================================
|
||||
|
||||
Multiplication--whether 8 bit by 8 bit, 16 bit by 16 bit, or 32 bit by 32
|
||||
bit--always destroys the contents of at least one register other than the
|
||||
portion of the accumulator used as a source operand.
|
||||
|
||||
|
||||
Forgetting that string instructions alter several registers
|
||||
===========================================================
|
||||
|
||||
The string instructions, MOVS, STOS, LODS, CMPS, and SCAS, can affect several
|
||||
of the flags and as many as three registers during execution of a single
|
||||
instruction. When you use string instructions, remember that SI, DI, or
|
||||
both either increment or decrement (depending on the state of the direction
|
||||
flag) on each execution of a string instruction. CX is also decremented at
|
||||
least once, and possibly as far as zero, each time a string instruction with
|
||||
a REP prefix is used.
|
||||
|
||||
|
||||
Expecting certain instructions to alter the carry flag
|
||||
======================================================
|
||||
|
||||
While some instructions affect registers or flags unexpectedly, other
|
||||
instructions don't even affect all the flags you might expect them to.
|
||||
|
||||
|
||||
Waiting too long to use flags
|
||||
=============================
|
||||
|
||||
Flags last only until the next instruction that alters them, which is
|
||||
usually not very long. It's a good practice to act on flags as soon as
|
||||
possible after they're set, thereby avoiding all sorts of potential bugs.
|
||||
|
||||
|
||||
Confusing memory and immediate operands
|
||||
=======================================
|
||||
|
||||
An assembler program may refer either to the offset of a memory variable or
|
||||
to the value stored in that memory variable. Unfortunately, assembly language
|
||||
is neither strict nor intuitive about the ways in which these two types of
|
||||
references can be made, and as a result, offset and value references to a
|
||||
memory variable are often confused.
|
||||
|
||||
|
||||
Failing to preserve everything in an interrupt handler
|
||||
======================================================
|
||||
|
||||
Every interrupt handler should explicitly preserve the contents of all
|
||||
registers. While it is valid to preserve explicitly only those registers
|
||||
that the handler modifies, it's good insurance just to push all registers
|
||||
on entry to an interrupt handler and pop all registers on exit.
|
||||
|
||||
|
||||
Forgetting group overrides in operands and data tables
|
||||
======================================================
|
||||
|
||||
Segment groups let you partition data logically into a number of areas
|
||||
without having to load a segment register every time you want to switch
|
||||
from one of those logical data areas to another.
|
||||
|
||||
|
||||
|
||||
=========================================
|
||||
4. Inline assembler tips
|
||||
=========================================
|
||||
|
||||
|
||||
Looking at raw hex data
|
||||
=======================
|
||||
|
||||
You can use the Data|Add Watch and Data| Evaluate/Modify commands with
|
||||
a format modifier to look at raw data dumps. For example, if your
|
||||
language is Assembler,
|
||||
|
||||
[ES:DI],20m
|
||||
|
||||
specifies that you want to look at a raw hex memory dump of the 20 bytes
|
||||
pointed to by the ES:DI register pair.
|
||||
|
||||
|
||||
Source-level debugging
|
||||
======================
|
||||
|
||||
You can step through your assembler code using a Module window just as
|
||||
with any of the high-level languages. If you want to see the register
|
||||
values, you can put a Registers window to the right of the Module window.
|
||||
|
||||
Sometimes, you may want to use a CPU window and see your source code as
|
||||
well. To do this, open a CPU window and choose the Code pane's Mixed
|
||||
command until it reads Both. That way you can see both your source code
|
||||
and machine code bytes. Remember to zoom the CPU window (by pressing F5)
|
||||
if you want to see the machine code bytes.
|
||||
|
||||
|
||||
Examining and changing registers
|
||||
================================
|
||||
|
||||
The obvious way to change registers is to highlight a register in either
|
||||
a CPU window or Registers window. A quick way to change a register is to
|
||||
choose Data|Evaluate/Modify. You can enter an assignment expression that
|
||||
directly modifies a register's contents. For example,
|
||||
|
||||
SI = 99
|
||||
|
||||
loads the SI register with 99.
|
||||
|
||||
Likewise, you can examine registers using the same technique. For example,
|
||||
|
||||
Alt-D E AX
|
||||
|
||||
shows you the value of the AX register.
|
||||
|
||||
|
||||
=========================================
|
||||
5. Inline assembler keywords
|
||||
=========================================
|
||||
|
||||
This section lists the instruction mnemonics and other special symbols that
|
||||
you use when entering instructions with the inline assembler. The keywords
|
||||
presented here are the same as those used by Turbo Assembler.
|
||||
|
||||
|
||||
8086/80186/80286 instructional mnemonics
|
||||
_________________________________________
|
||||
AAA INC LIDT** REPNZ
|
||||
AAD INSB* LLDT** REPZ
|
||||
AAM INSW* LMSW** RET
|
||||
AAS INT LOCK REFT
|
||||
ADC INTO LODSB ROL
|
||||
ADD IRET LODSW ROR
|
||||
AND JB LOOP SAHF
|
||||
ARPL** JBE LOOPNZ SAR
|
||||
BOUND* JCXZ LOOPZ SBB
|
||||
CALL JE LSL** SCASB
|
||||
CLC JL LTR** SCASW
|
||||
CLD JLE MOV SGDT**
|
||||
CLI JMP MOVSB SHL
|
||||
CLTS** JNB MOVSW SHR
|
||||
CMC JNBE MUL SLDT**
|
||||
CMP JNE NEG SMSW**
|
||||
CMPSB JNLE NOP STC
|
||||
CMPSW JNO NOT STD
|
||||
CWD JNP OR STI
|
||||
DAA JO OUT STOSB
|
||||
DAS JP OUTSB STOSW
|
||||
DEC JS OUTSW STR**
|
||||
DIV LAHF POP SUB
|
||||
ENTER* LAR** POPA* TEST
|
||||
ESC LDS POPF WAIT
|
||||
HLT LEA PUSH VERR**
|
||||
IDIV LEAVE PUSHA* VERW**
|
||||
IMUL LES PUSHF XCHG
|
||||
IN LGDT** RCL XLAT
|
||||
XOR
|
||||
___________________________________________
|
||||
|
||||
* Available only when running on the 186 and 286 processor
|
||||
** Available only when running on the 286 processor
|
||||
|
||||
|
||||
Turbo Debugger supports all 80386 and 80387 instruction
|
||||
mnemonics and registers:
|
||||
|
||||
80386 instruction mnemonics
|
||||
_________________________________________
|
||||
|
||||
BSF LSS SETG SETS
|
||||
BSR MOVSX SETL SHLD
|
||||
BT MOVZX SETLE SHRD
|
||||
BTC POPAD SETNB CMPSD
|
||||
BTR POPFD SETNE STOSD
|
||||
BTS PUSHAD SETNL LODSD
|
||||
CDQ PUSHFD SETNO MOVSD
|
||||
CWDE SETA SETNP SCASD
|
||||
IRETD SETB SETNS INSD
|
||||
LFS SETBE SETO OUTSD
|
||||
LGS SETE SETP JECXZ
|
||||
__________________________________________
|
||||
|
||||
80486 instruction mnemonics
|
||||
_________________________________________
|
||||
|
||||
BSWAP INVLPG
|
||||
CMPXCHG WBINVD
|
||||
INVD XADD
|
||||
_________________________________________
|
||||
|
||||
80386 registers
|
||||
_________________________________________
|
||||
|
||||
EAX EDI
|
||||
EBX EBP
|
||||
ECX ESP
|
||||
EDX FS
|
||||
ESI GS
|
||||
_________________________________________
|
||||
|
||||
CPU registers
|
||||
__________________________________________________________________
|
||||
|
||||
Byte registers AH, AL, BH, BL, CH, CL, DH, DL
|
||||
|
||||
Word registers AX, BX, CX, DX, SI, DI, SP, BP, FLAGS
|
||||
|
||||
Segment registers CS, DS, ES, SS
|
||||
|
||||
Floating registers ST, ST(0), ST(1), ST(2), ST(3), ST(4),
|
||||
ST(5), ST(6), ST(7)
|
||||
___________________________________________________________________
|
||||
|
||||
Special keywords
|
||||
_________________________________________
|
||||
|
||||
WORD PTR TBYTE PTR
|
||||
BYTE PTR NEAR
|
||||
DWORD PTR FAR
|
||||
QWORD PTR SHORT
|
||||
_________________________________________
|
||||
|
||||
8087/80287 numeric coprocessor instruction mnemonics
|
||||
____________________________________________________
|
||||
FABS FIADD FLDL2E FST
|
||||
FADD FIACOM FLDL2T FSTCW
|
||||
FADDP FIACOMP FLDPI FSTENV
|
||||
FBLD FIDIV FLDZ FSTP
|
||||
FBSTP FIDIVR FLD1 FSTSW**
|
||||
FCHS FILD FMUL FSUB
|
||||
FCLEX FIMUL FMULP FSUBP
|
||||
FCOM FINCSTP FNOP FSUBR
|
||||
FCOMP FINIT FNSTS** FSUBRP
|
||||
FCOMPP FIST FPATAN FTST
|
||||
FDECSTP FISTP FPREM FWAIT
|
||||
FDISI FISUB FPTAN FXAM
|
||||
FDIV FISUBR FRNDINT FXCH
|
||||
FDIVP FLD FRSTOR FXTRACT
|
||||
FDIVR FLDCWR FSAVENT FYL2X
|
||||
FDIVRP FLDENV FSCALE FYL2XPI
|
||||
FENI FLDLG2 FSETPM* F2XM1
|
||||
FFREE FLDLN2 FSQRT
|
||||
_____________________________________________________
|
||||
|
||||
* Available only when running on the 287 numeric coprocessor.
|
||||
** On the 80287, the fstsw instruction can use the AX register as an
|
||||
operand, as well as the normal memory operand.
|
||||
|
||||
|
||||
80387 instruction mnemonics
|
||||
_________________________________________
|
||||
|
||||
FCOS FUCOM
|
||||
FSIN FUCOMP
|
||||
FPREM1 FUCOMPP
|
||||
FSINCOS
|
||||
_________________________________________
|
||||
|
||||
|
||||
The 80x87 coprocessor chip and emulator
|
||||
=======================================
|
||||
|
||||
This section is for programmers who are familiar with the operation
|
||||
if the 80x87 math coprocessor. If your program uses floating-point
|
||||
numbers, Turbo Debugger lets you examine and change the state of the numeric
|
||||
coprocessor or, if the coprocessor is emulated, examine the state of the
|
||||
software emulator. (Windows permits you only to examine the state of the
|
||||
emulator, not to change it.) You don't need to use the capabilities
|
||||
described in this chapter to debug programs that use floating-point numbers,
|
||||
although some very subtle bugs may be easier to find.
|
||||
|
||||
In this section, we discuss the differences between the 80x87 chip and
|
||||
the software emulator. We also describe the Numeric Processor window and
|
||||
show you how to examine and modify the floating-point registers, the status
|
||||
bits, and the control bits.
|
||||
|
||||
|
||||
The 80x87 chip vs. the emulator
|
||||
===============================
|
||||
|
||||
TDW automatically detects whether your program is using the math chip or the
|
||||
emulator and adjusts its behavior accordingly.
|
||||
|
||||
Note that most programs use either the emulator or the math chip, not both
|
||||
within the same program. If you have written special assembler code that
|
||||
uses both, TDW won't be able to show you the status of the math chip; it
|
||||
reports on the emulator only.
|
||||
|
||||
|
||||
=========================================
|
||||
6. The Numeric Processor window
|
||||
=========================================
|
||||
|
||||
You create a Numeric Processor window by choosing the View|Numeric Processor
|
||||
command from the menu bar. The line at the top of the window shows the
|
||||
current instruction pointer, opcode, and data pointer. The instruction
|
||||
pointer is both shown as a 20-bit physical address. The data pointer is
|
||||
either a 16-bit or a 20-bit address, depending on the memory model. You
|
||||
can convert 20-bit addresses to segment and offset form by using the first
|
||||
four digits as the segment value and the last digit as the offset value.
|
||||
|
||||
For example, if the top line shows IPTR=5A669, you can treat this as the
|
||||
address 5a66:9 if you want to examine the current data and instruction in
|
||||
a CPU window. This window has three panes: The left pane (Register pane)
|
||||
shows the contents of the floating-point registers, the middle pane
|
||||
(Control pane) shows the control flags, and the right pane (Status pane)
|
||||
shows the status flags.
|
||||
|
||||
The top line shows you the following information about the last floating-
|
||||
point operation that was executed:
|
||||
|
||||
o Emulator indicates that the numeric processor is being emulated. If there
|
||||
were a numeric processor, 8087, 80287, 80387, or 80486 would appear instead.
|
||||
|
||||
o The IPTR shows the 20-bit physical address from which the last floating-
|
||||
point instruction was fetched.
|
||||
|
||||
o The OPCODE shows the instruction type that was fetched.
|
||||
|
||||
o The OPTR shows the 16-bit or 20-bit physical address of the memory address
|
||||
that the instruction referenced, if any.
|
||||
|
||||
|
||||
The Register pane
|
||||
-----------------
|
||||
|
||||
The 80-bit floating-point registers
|
||||
-----------------------------------
|
||||
|
||||
The Register pane shows each of the floating-point registers, ST(0) to
|
||||
ST(7), along with its status (valid/zero/special/empty). The contents
|
||||
are shown as an 80-bit floating-point number.
|
||||
|
||||
If you've zoomed the Numeric Processor window (by pressing F5) or made
|
||||
it wider by using Window|Size/Move, you'll also see the floating-point
|
||||
registers displayed as raw hex bytes.
|
||||
|
||||
|
||||
The Register pane's local menu
|
||||
------------------------------
|
||||
___________
|
||||
| Zero |
|
||||
| Empty |
|
||||
| Change... |
|
||||
|___________|
|
||||
|
||||
To bring up the Register pane local menu, press Alt-F10, or use the Ctrl
|
||||
key with the first letter of the desired command to directly access the
|
||||
command.
|
||||
|
||||
Zero
|
||||
----
|
||||
|
||||
Sets the value of the currently highlighted register to zero.
|
||||
|
||||
Empty
|
||||
-----
|
||||
|
||||
Sets the value of the currently highlighted register to empty. This is a
|
||||
special status that indicates that the register no longer contains valid
|
||||
data.
|
||||
|
||||
Change
|
||||
------
|
||||
|
||||
Loads a new value into the currently highlighted register. You are
|
||||
prompted for the value to load. You can enter an integer or floating-
|
||||
point value, using the current language's expression parser. The value
|
||||
you enter is automatically converted to the 80-bit temporary real format
|
||||
used by the numeric coprocessor.
|
||||
|
||||
You can also invoke this command by simply starting to type the new value
|
||||
for the floating-point register. A dialog box appears, exactly as if you
|
||||
had specified the Change command.
|
||||
|
||||
|
||||
The Control pane
|
||||
----------------
|
||||
|
||||
The control bits
|
||||
----------------
|
||||
|
||||
The following table lists the different control flags and how they
|
||||
appear in the Control pane:
|
||||
_________________________________________
|
||||
|
||||
Name in pane Flag description__
|
||||
|
||||
im Invalid operation mask
|
||||
dm Denormalized operand mask
|
||||
zm Zero divide mask
|
||||
om Overflow mask
|
||||
um Underflow mask
|
||||
pm Precision mask
|
||||
iem Interrupt enable mask (8087 only)
|
||||
pc Precision control
|
||||
rc Rounding control
|
||||
ic Infinity control__
|
||||
|
||||
|
||||
The Control pane's local menu
|
||||
-----------------------------
|
||||
________
|
||||
| Toggle |
|
||||
|________|
|
||||
|
||||
Press Tab to go to the Control pane, then press Alt-F10 to pop up the
|
||||
local menu. (Alternatively, you can use the Ctrl key with the first letter
|
||||
of the desired command to access it.)
|
||||
|
||||
Toggle
|
||||
------
|
||||
|
||||
Cycles through the values that the currently highlighted control flag
|
||||
can be set to. Most flags can only be set or cleared (0 or 1), so this
|
||||
command just toggles the flag to the other value. Some other flags have
|
||||
more than two values; for those flags, this command increments the flag
|
||||
value until the maximum value is reached, and then sets it back to zero.
|
||||
|
||||
You can also toggle the control flag values by highlighting them and
|
||||
pressing Enter.
|
||||
|
||||
|
||||
The Status pane
|
||||
---------------
|
||||
|
||||
The status bits
|
||||
---------------
|
||||
|
||||
The following table lists the different status flags and how they appear
|
||||
in the Status pane:
|
||||
____________________________________
|
||||
|
||||
Name in pane Flag description__
|
||||
|
||||
ie Invalid operation
|
||||
de Denormalized operand
|
||||
ze Zero divide
|
||||
oe Overflow
|
||||
ue Underflow
|
||||
pe Precision
|
||||
ir Interrupt request
|
||||
cc Condition code
|
||||
st Stack top pointer_
|
||||
|
||||
|
||||
The Status pane's local menu
|
||||
----------------------------
|
||||
________
|
||||
| Toggle |
|
||||
|________|
|
||||
|
||||
Press Tab to move to the Statuspane, then press Alt-F10 to pop up the
|
||||
local menu. (You can also use the Ctrl key with the first letter of the
|
||||
desired command to access the command directly.)
|
||||
|
||||
|
||||
Toggle
|
||||
------
|
||||
|
||||
Cycles through the values that the currently highlighted status flag
|
||||
can be set to. Most flags can only be set or cleared (0 or 1), so this
|
||||
command just toggles the flag to the other value. Some other flags have
|
||||
more than two values; for those flags, this command increments the
|
||||
flag value until the maximum value is reached, and then sets it back to
|
||||
zero.
|
||||
|
||||
You can also toggle the status flag values by highlighting them and
|
||||
pressing Enter.
|
||||
|
||||
/***************************** END OF FILE *******************************/
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*************************************************************************/
|
||||
TURBO DEBUGGER
|
||||
USING THE HARDWARE DEBUGGING FEATURES
|
||||
|
||||
|
||||
CONFIGURING YOUR SYSTEM
|
||||
=======================
|
||||
|
||||
Before you can set hardware breakpoints, you must install TDDEBUG.386.
|
||||
|
||||
Turbo Debugger uses the debug registers of 80386 (and higher) processors to
|
||||
set hardware breakpoints. However, for Turbo Debugger to take advantage of
|
||||
the special debug registers, TDDEBUG.386 must be properly installed.
|
||||
(TDDEBUG.386 provides the same functionality as the Windows SDK file
|
||||
WINDEBUG.386, with added support for the debug registers.)
|
||||
|
||||
INSTALL.EXE copies TDDEBUG.386 to your hard disk and alters your Windows
|
||||
SYSTEM.INI file so that Windows loads TDDEBUG.386 instead of WINDEBUG.386.
|
||||
If you are having problems setting hardware breakpoints, make sure that
|
||||
TDDEBUG.386 is correctly installed:
|
||||
|
||||
1) The installation program copies TDDEBUG.386 from the installation disks
|
||||
to your your language BIN directory. If you move the file to another
|
||||
directory, substitute that directory in the following instructions.
|
||||
|
||||
2) With an editor, open the Windows SYSTEM.INI file, search for "[386enh]".
|
||||
Add the following line to that section:
|
||||
|
||||
device = c:\lang_dir\bin\TDDEBUG.386
|
||||
|
||||
3) If there's a line in the [386enh] section that loads WINDEBUG.386, you
|
||||
must either comment that line out with a semicolon or delete it
|
||||
altogether. (You can't load both TDDEBUG.386 and WINDEBUG.386.)
|
||||
|
||||
For example, if you load WINDEBUG.386 from the C:\WINDOWS directory,
|
||||
the commented-out line would read:
|
||||
|
||||
;device=c:\windows\windebug.386
|
||||
|
||||
|
||||
SETTING HARDWARE BREAKPOINTS
|
||||
============================
|
||||
|
||||
There are several ways to set a hardware-assisted breakpoint:
|
||||
|
||||
o Choose Breakpoints|Changed memory global.
|
||||
|
||||
In the input box of the dialog box that opens, enter a memory
|
||||
address followed by the number of bytes TDW is to watch to determine
|
||||
if your program has changed anything in that part of memory. If you
|
||||
enter a variable name or expression as the address, the count refers
|
||||
to how many objects of that size to watch.
|
||||
|
||||
For example, if your program contains a word-sized variable x,
|
||||
typing "x,2" causes two objects of size sizeof(x) (4 bytes total)
|
||||
to be watched.
|
||||
|
||||
When you set a breakpoint using the Changed Memory Global command, Turbo
|
||||
Debugger automatically determines whether that breakpoint can make use of
|
||||
the available hardware. If it can, Turbo Debugger sets a hardware
|
||||
breakpoint for you and indicates that the breakpoint is set in hardware
|
||||
by putting an asterisk (*) after the global breakpoint number in the left
|
||||
pane of the Breakpoints window.
|
||||
|
||||
o Choose Breakpoints|Hardware Breakpoint.
|
||||
|
||||
Use this command to set a general-purpose hardware breakpoint. This
|
||||
command displays the Hardware Breakpoint Options dialog box (described
|
||||
later).
|
||||
|
||||
o Use the Breakpoint Options dialog box (see the paragraphs after the next
|
||||
one for an explanation of how to display this dialog box) to get to the
|
||||
Hardware Breakpoint Options dialog box (described later).
|
||||
|
||||
In the Breakpoint Options dialog box, check the Global checkbox, then
|
||||
press the Change button to display the Conditions and Actions dialog
|
||||
box. In this dialog box, select the Hardware radio button in the
|
||||
Condition group, then press the Hardware button at the bottom of the
|
||||
box to display the Hardware Breakpoint Options dialog box.
|
||||
|
||||
You can get to the Breakpoint Options dialog box from two locations:
|
||||
the Breakpoints menu or the Breakpoints view window.
|
||||
|
||||
- Choose Breakpoints|At (Alt-B A) to display the Breakpoint Options
|
||||
dialog box.
|
||||
|
||||
- Choose View|Breakpoints to display the Breakpoints window. In the left
|
||||
pane, highlight the breakpoint you want to work with, then display the
|
||||
local menu (Alt-F10 or right-hand mouse click) and choose the Set
|
||||
Options or the Add command to display the Breakpoint Options dialog box.
|
||||
|
||||
|
||||
USING THE HARDWARE BREAKPOINT OPTIONS DIALOG BOX
|
||||
================================================
|
||||
|
||||
This section starts with a description of the hardware and software
|
||||
limitations on the hardware conditions you can set with Turbo Debugger,
|
||||
and then explains all the options you can set from the Hardware Breakpoints
|
||||
dialog box.
|
||||
|
||||
|
||||
Hardware conditions permitted with TDDEBUG.386
|
||||
----------------------------------------------
|
||||
|
||||
When you're using TDDEBUG.386 with Turbo Debugger, you can set the following
|
||||
types of hardware breakpoints from the Hardware Breakpoint dialog box:
|
||||
|
||||
o Instruction fetch
|
||||
|
||||
o Read from memory
|
||||
|
||||
o Read/write memory
|
||||
|
||||
Because you can't set any type of data matching when you use TDDEBUG.386,
|
||||
you must always set the Data Match radio buttons to Match All. You can
|
||||
also match only a single memory address or range of memory addresses.
|
||||
A range can encompass from 1 to 16 bytes, depending on how many other
|
||||
hardware breakpoints you have set and the address of the beginning of
|
||||
the range.
|
||||
|
||||
The other options in the Hardware Breakpoint dialog are for other hardware
|
||||
debuggers and device drivers that might support more matching modes.
|
||||
|
||||
|
||||
The Hardware Breakpoint Options dialog box
|
||||
------------------------------------------
|
||||
|
||||
This section describes the options on the Hardware Breakpoint Option
|
||||
dialog box. Remember that your hardware isn't likely to support
|
||||
all combinations of matching that you can specify from this menu. The
|
||||
previous section describes the combinations that are allowed for the
|
||||
TDDEBUG.386 device driver supplied with Turbo Debugger.
|
||||
|
||||
The Hardware Breakpoint Options dialog box lets you set the three matching
|
||||
criteria that make up a hardware breakpoint:
|
||||
|
||||
o The bus cycle type to be matched
|
||||
|
||||
o The range of addresses to be matched
|
||||
|
||||
o The range of data values to be matched
|
||||
|
||||
For example, a hardware breakpoint might say "Watch for an I/O write
|
||||
anywhere from address 3F8 to 3FF as long as the data value is equal to
|
||||
1." This breakpoint will then be triggered any time a byte of 1 is
|
||||
written to any of the I/O locations that control the COM1 serial port.
|
||||
|
||||
Usually, you set far simpler hardware breakpoints than this, such
|
||||
as "Watch for I/O to address 200."
|
||||
|
||||
Cycle Type radio buttons
|
||||
------------------------
|
||||
|
||||
With these radio buttons, you can make one of the following settings:
|
||||
|
||||
Read Memory Match memory reads
|
||||
Write Memory Match memory writes
|
||||
Access Memory Match memory read or write
|
||||
Input I/O Match I/O input
|
||||
Output I/O Match I/O Output
|
||||
Both I/O Match I/O input or output
|
||||
Fetch Instruction Match instruction fetch
|
||||
|
||||
The Access Memory option is a combination of the Read Memory and Write
|
||||
Memory options--it matches either memory reads or writes. Likewise,
|
||||
the Both I/O option matches I/O reads or writes.
|
||||
|
||||
Some hardware debuggers are capable of distinguishing between simple
|
||||
data reads from memory and instruction fetches. In this case, if you
|
||||
set a breakpoint to match on read memory, an instruction fetch from
|
||||
that location will not trigger the hardware breakpoint. Instruction
|
||||
cycles include all the bytes that the processor reads in order to
|
||||
determine the instruction operation to perform, including prefix
|
||||
bytes, operand addresses, and immediate values. The actual data read
|
||||
or written to memory referenced by an operand's address is not
|
||||
considered to be part of the instruction fetch. For example,
|
||||
|
||||
MOV AX,[1234]
|
||||
|
||||
fetches 3 instruction bytes from memory and reads 2 data bytes. If you
|
||||
use instruction fetch matching, remember that the 80x86 processor
|
||||
family prefetches instructions to be executed, so you may get false
|
||||
matches, depending on whether your hardware debugger can sort out
|
||||
prefetched instructions from ones that are really executed.
|
||||
|
||||
Address radio buttons
|
||||
---------------------
|
||||
|
||||
With these radio buttons, you can make one of the following settings:
|
||||
|
||||
Above Match above an address
|
||||
Below Match below an address
|
||||
Range Match within address range
|
||||
Not Range Match outside address range
|
||||
Less or Equal Match below or equal to address
|
||||
Greater or Equal Match above or equal to address
|
||||
Equal Match a single address
|
||||
Unequal Match all but a single address
|
||||
Match All Match any address
|
||||
|
||||
|
||||
Data Match radio buttons
|
||||
------------------------
|
||||
|
||||
The Data Match radio buttons let you make the following settings:
|
||||
|
||||
Above Match above a value
|
||||
Below Match below a value
|
||||
Range Match within value range
|
||||
Not Range Match outside value range
|
||||
Less or Equal Match below or equal to value
|
||||
Greater or Equal Match above or equal to value
|
||||
Equal Match a single value
|
||||
Unequal Match all but a single value
|
||||
Match All Match any value
|
||||
|
||||
If you turn on a Data or Address option that involves any less-than or
|
||||
greater-than condition, a single address match range either starts at
|
||||
zero and extends to the value you specified, or starts at the value
|
||||
you specified and extends to the highest allowed value for addresses
|
||||
or data.
|
||||
|
||||
/***************************** END OF FILE *******************************/
|
||||
@@ -0,0 +1,421 @@
|
||||
/***********************************************************************/
|
||||
TURBO DEBUGGER
|
||||
TIPS AND HINTS
|
||||
|
||||
This file contains tips and hints concerning problems you might
|
||||
encounter while using TD.EXE, TDW.EXE, and TD32.EXE. The following
|
||||
topics are covered:
|
||||
|
||||
1. TDW.INI
|
||||
2. TDW Hardware Debugging
|
||||
3. Running TDW under Windows For Workgroups
|
||||
4. Restart Information/Session State Saving
|
||||
5. Program Reset
|
||||
6. Program Interrupt Key
|
||||
7. Resetting and restarting programs
|
||||
8. Video Support
|
||||
9. Windows debugging hints
|
||||
10. Answers to common questions
|
||||
|
||||
|
||||
------------
|
||||
1. TDW.INI
|
||||
------------
|
||||
You must have a single copy of TDW.INI located on your system, and
|
||||
it must be located in your main Windows directory (usually "\WINDOWS").
|
||||
Be sure to delete any extra copies of TDW.INI that you might have on
|
||||
your system.
|
||||
|
||||
By default, TDW.INI contains the following text:
|
||||
|
||||
[TurboDebugger]
|
||||
VideoDll = <Your_BorlandC_Bin_Directory>\SVGA.DLL
|
||||
debuggerDll = <Your_BorlandC_Bin_Directory>\TDWINTH.DLL
|
||||
|
||||
[VideoOptions]
|
||||
|
||||
You can use TD32 to debug under Win32s. However, to do so, you must
|
||||
ensure you use SVGA.DLL or equivalent support in the VideoDLL entry
|
||||
in the [TurboDebugger] section of TDW.INI. Use the Turbo Debugger Video
|
||||
Configuration utility (TDWINI.EXE) to set the required option.
|
||||
|
||||
|
||||
---------------------------
|
||||
2. TDW Hardware Debugging
|
||||
---------------------------
|
||||
In order to support hardware debugging in TDW, you need to load
|
||||
the device driver TDDEBUG.386. Edit your SYSTEM.INI file in the \WINDOWS
|
||||
directory and add the following statement to the [386enh] section:
|
||||
|
||||
device=<Your_BorlandC_Bin_Directory>\TDDEBUG.386
|
||||
|
||||
Make sure that you comment out the line that loads the Windows driver
|
||||
WINDEBUG.386 with a semicolon. For example:
|
||||
|
||||
;c:\windows\windebug.386
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
3. Running TDW under Windows For Workgroups
|
||||
---------------------------------------------
|
||||
If you use Windows for Workgroups 3.11, you must use TDWINTH.DLL when
|
||||
you debug with TDW. Be sure the DebuggerDll setting in your
|
||||
TDW.INI file explicitly points to TDWINTH.DLL. For example:
|
||||
|
||||
debuggerDll=<Your_BorlandC_Bin_Directory>\TDWINTH.DLL
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
4. Restart Information/Session State Saving
|
||||
---------------------------------------------
|
||||
Turbo Debugger saves Breakpoint, Inspector, and other session information
|
||||
when you exit a debugging session. Then, when you restart a debugging
|
||||
session, Turbo Debugger restores this information. To ignore the restart
|
||||
information, use Turbo Debugger's -ji command line switch when you load
|
||||
Turbo Debugger.
|
||||
|
||||
If your system crashes during a debugging session, your configuration
|
||||
file is likely to become corrupt. This can cause Turbo Debugger to hang
|
||||
on startup. Because of this, it is advisable to delete any .TR, .TRW, or
|
||||
.TR2 files from your hard disk if you crash during a debugging session.
|
||||
|
||||
|
||||
------------------
|
||||
5. Program Reset
|
||||
------------------
|
||||
Dialog applications that do not have a parent window will cause your
|
||||
system to hang if you reload the application.
|
||||
|
||||
|
||||
--------------------------
|
||||
6. Program Interrupt Key
|
||||
--------------------------
|
||||
Under TD: Ctrl-Break
|
||||
Under TDW: Ctrl-Alt-SysReq
|
||||
Under Win32s: Ctrl-Alt-F11
|
||||
Under NT: F12
|
||||
|
||||
|
||||
--------------------------------------
|
||||
7. Resetting and restarting programs
|
||||
--------------------------------------
|
||||
When you reload or reset a program a number of times under Windows 32s,
|
||||
it is likely that you will run out of memory. This problem has been
|
||||
reported to Microsoft.
|
||||
|
||||
If Turbo Debugger fails to start correctly, especially after a system
|
||||
crash, the debugger session state and configuration files may be
|
||||
corrupted. Try removing the following files:
|
||||
|
||||
For TD: TDCONFIG.TD
|
||||
***.TR
|
||||
|
||||
For TDW: TDCONFIG.TDW
|
||||
***.TRW
|
||||
|
||||
For TD32: TDCONFIG.TD2
|
||||
***.TR2
|
||||
|
||||
Where *** equals your application's name.
|
||||
|
||||
These files will be found in either the working directory,
|
||||
the \BorlandC\Bin directory, or the \Windows directory.
|
||||
|
||||
|
||||
------------------
|
||||
8. Video Support
|
||||
------------------
|
||||
Turbo Debugger requires that you use the correct Windows video driver
|
||||
for your video card. For example, if you have a TSENG card, make sure
|
||||
that you are using the TSENG Windows video driver (the generic VGA
|
||||
video driver does not work correctly with this video card).
|
||||
|
||||
To find out what type of video card you have installed in your
|
||||
machine, type MSD <Enter> at the DOS prompt. Use the TDWINI.EXE
|
||||
utility to set up your video driver.
|
||||
|
||||
SVGA.DLL supports most video card configurations, provided that you
|
||||
are using the correct Windows video drivers. Use the Turbo Debugger Video
|
||||
Configuration utility (TDWINI.EXE) to determine the correct Video Support
|
||||
for your adapter.
|
||||
|
||||
|
||||
Screen not being repainted
|
||||
--------------------------
|
||||
Ensure that the "ForceRepaint" flag is set to "Yes" in the
|
||||
VideoOptions section of TDW.INI:
|
||||
|
||||
[VideoOptions]
|
||||
ForceRepaint=Yes
|
||||
|
||||
This can be done through the Turbo Debugger Video Configuration
|
||||
utility (TDWINI.EXE).
|
||||
|
||||
|
||||
Dual Monitor Support under Windows 32s
|
||||
--------------------------------------
|
||||
TD32 can support dual monitor debugging under Windows 32s.
|
||||
Ensure that a monochrome adapter is installed in your machine
|
||||
and set the Mono flag in the [VideoOptions] section of TDW.INI
|
||||
to "Yes."
|
||||
|
||||
[VideoOptions]
|
||||
MONO=yes
|
||||
|
||||
This can be done through the Turbo Debugger Video Configuration
|
||||
utility, TDWINI.EXE.
|
||||
|
||||
|
||||
---------------------------
|
||||
9. Windows debugging hints
|
||||
---------------------------
|
||||
View|Windows Messages
|
||||
|
||||
1) If you set up View|Windows Messages to display messages for
|
||||
more than one procedure or handle or both, do not log all
|
||||
messages. Instead, log specific messages for each procedure or
|
||||
handle. If you log all messages, the system might hang, in
|
||||
which case you will have to reboot to continue. This behavior
|
||||
is due to the large number of messages being transferred
|
||||
between Windows and Turbo Debugger.
|
||||
|
||||
2) When setting a break on the Mouse class of messages, note that
|
||||
a "mouse down" message must be followed by a "mouse up" message
|
||||
before the keyboard will become active again. When you return
|
||||
to the application, you might have to press the mouse button
|
||||
several times (or press the <ALT> key) to get Windows to receive a
|
||||
"mouse up" message. You'll know Windows has received the message
|
||||
when you see it in the bottom pane of the Windows Message window
|
||||
after the program breaks.
|
||||
|
||||
|
||||
--------------------------------
|
||||
10. Answers to common questions
|
||||
--------------------------------
|
||||
Following is a list of the most commonly asked questions about TDW:
|
||||
|
||||
1) Are there any syntactic or parsing differences between Turbo
|
||||
Debugger's C expression evaluation and Turbo C++ for Windows'?
|
||||
|
||||
You can't pass constant-string arguments when evaluating
|
||||
functions.
|
||||
|
||||
OK: myfunc(123) myfunc(string_variable)
|
||||
|
||||
BAD: myfunc("constant")
|
||||
|
||||
2) What should I be aware of when I am debugging multilanguage
|
||||
programs with Turbo Debugger?
|
||||
|
||||
Turbo Debugger's default source language is "Source," which
|
||||
means it chooses the expression language based on the current
|
||||
source module. This can cause some confusion if your program
|
||||
has source modules written in different languages (like C
|
||||
and assembler). Since you are actually entering a language
|
||||
expression any time Turbo Debugger prompts you for a value
|
||||
or an address, this can cause some unexpected results:
|
||||
|
||||
a. Even if you are in a CPU window or a Dump window, you
|
||||
must still enter addresses in the source language,
|
||||
despite the fact that the window is displaying in hex.
|
||||
For example, to display the contents of memory address
|
||||
1234:5678, you must type one of the following
|
||||
expressions, depending on your current source language:
|
||||
|
||||
C 0x1234:0x5678
|
||||
Pascal $1234:$5678
|
||||
Assembler 1234H:5678H
|
||||
|
||||
b. When your current language is assembler, you must be
|
||||
careful when entering hex numbers, since they are
|
||||
interpreted EXACTLY as they would be in an assembler
|
||||
source file. This means that if you want to enter a
|
||||
number that starts with one of the hex digits A - F, you
|
||||
must first precede the letter with a 0 so Turbo Debugger
|
||||
knows you are entering a number. Likewise, if your number
|
||||
ends in B or D (indicating a binary or decimal number), you
|
||||
must add an H to indicate that you really want a hex number:
|
||||
|
||||
OK: 0aaaa 123dh 89abh
|
||||
|
||||
BAD: aaaa 123d 89ab
|
||||
|
||||
3) Why does the text "Cannot be changed" come up when I do an
|
||||
assignment in the Data/Evaluate/Modify "New value" pane?
|
||||
|
||||
If you use the Data/Evaluate/Modify command (Ctrl-F4) to
|
||||
change a variable by direct assignment, the "New value" pane
|
||||
will say "Cannot be changed." This doesn't mean the
|
||||
assignment didn't take effect. What it does mean is that the
|
||||
assignment expression as a whole is not a memory-referencing
|
||||
expression whose value you can change by moving to the
|
||||
bottom pane. Here are some examples of direct assignment
|
||||
expressions:
|
||||
|
||||
C x = 4
|
||||
Pascal ratio := 1.234
|
||||
Assembler wval = 4 shl 2
|
||||
|
||||
If you had typed just "x," "ratio," or "wval" into the top
|
||||
pane, then you would be able to move to the bottom pane and
|
||||
enter a new value. The direct assignment method using the
|
||||
"=" or ":=" assignment operator is quicker and more
|
||||
convenient if you don't care about examining the value of
|
||||
the variable before modifying it.
|
||||
|
||||
|
||||
4) What could happen when global breakpoints are set on local
|
||||
variables?
|
||||
|
||||
When you set global breakpoints using local variables, make
|
||||
sure the breakpoints are cleared before you exit the
|
||||
procedure or function that the variables are defined in. The
|
||||
best way to do this is to put a breakpoint on the last line
|
||||
of the procedure or function. If you do not clear the
|
||||
breakpoints, your program will break unexpectedly and may
|
||||
even hang on some machines because the breakpoints are being
|
||||
set in memory that is not currently being used by the
|
||||
procedure or function.
|
||||
|
||||
5) Why is execution slower when tracing (F7) than when stepping
|
||||
(F8) through my programs?
|
||||
|
||||
TDW can do reverse execution, which means that when you are
|
||||
tracing through your program, TDW could be saving all the
|
||||
information about each source line you trace over. TDW only
|
||||
saves this information in the Module window if you have chosen
|
||||
View|Execution History and toggled the Full History local menu
|
||||
command to 'Yes'.
|
||||
|
||||
If you want faster execution you can step over (F8) the instruction
|
||||
or toggle the Full History option to 'No' in the Execution History
|
||||
window. (Although reverse execution is always available in the
|
||||
CPU view, you must toggle this option to 'Yes' for it to work
|
||||
in the Module view. The default setting in the Module view is 'No'.)
|
||||
|
||||
6) What are some of the syntactic and parsing differences
|
||||
between Turbo Debugger's built-in assembler and the
|
||||
standalone Turbo Assembler?
|
||||
|
||||
A discussion follows this short example program:
|
||||
|
||||
.model small
|
||||
.data
|
||||
|
||||
abc struc
|
||||
mem1 dd ?
|
||||
mem2 db ?
|
||||
mem3 db " "
|
||||
abc ends
|
||||
|
||||
align 16
|
||||
a abc <1,2,"xyz">
|
||||
|
||||
msg1 db "testing 1 2 3", 0
|
||||
msg2 db "hello world", 0
|
||||
nmptr dw msg1
|
||||
fmptr dd msg1,msg2
|
||||
nfmptr dw fmptr
|
||||
xx dw seg a
|
||||
|
||||
.code
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
mov bx,offset a
|
||||
mov bx,nmptr
|
||||
les si,fmptr
|
||||
mov ah,4ch
|
||||
int 21h
|
||||
end
|
||||
|
||||
Because the assembler expression parser does not accept all legal
|
||||
TASM instruction operands, Turbo Debugger assembler expressions
|
||||
can be more general than those of TASM and can use multiple levels
|
||||
of memory-referencing, much like C and Pascal. However, there are a
|
||||
few constructs that you may be used to that you'll have to specify
|
||||
differently for the Turbo Debugger assembler expression parser to
|
||||
accept them:
|
||||
|
||||
a. Size overrides should always appear inside the
|
||||
brackets; PTR is optional after the size. Also, when
|
||||
referring to a structure, you must use the name of the
|
||||
structure, not the name of the variable:
|
||||
|
||||
OK: [byte ptr bx] [dword si] [abc bx]
|
||||
|
||||
BAD: byte ptr[bx] [struc abc bx] [a bx]
|
||||
|
||||
b. You must specify a structure name when accessing the
|
||||
members of a structure with a register pointer.
|
||||
|
||||
OK: [abc ptr bx].mem1 [abc bx].mem3 + 1
|
||||
|
||||
BAD: [bx].mem1
|
||||
|
||||
c. You can't use multiple instances of brackets ([]) unless they are
|
||||
adjacent, and you can only follow a bracketed expression with
|
||||
a dot and a structure member name or another bracketed
|
||||
expression:
|
||||
|
||||
OK: 4[bx][si] [abc bx].mem2
|
||||
|
||||
BAD: [bx]4[si] [bx]+4
|
||||
|
||||
d. If you use a register as part of a memory expression
|
||||
and you don't specify a size, WORD is assumed:
|
||||
|
||||
[bx] is the same as [word bx]
|
||||
|
||||
e. You can use any register you want between brackets ([]),
|
||||
not just the combinations of BX, BP, SI, and DI allowed in
|
||||
instruction operands. For example,
|
||||
|
||||
[ax+bx]
|
||||
[bx+sp]
|
||||
|
||||
f. You can use multiple levels of brackets to follow chains of
|
||||
pointers. For example,
|
||||
|
||||
[byte [[nfmptr]+4]]
|
||||
|
||||
g. Be careful with using registers to access memory locations.
|
||||
You might get unexpected results if your segment
|
||||
registers are not set up properly. If you don't
|
||||
explicitly specify a segment register, Turbo Debugger
|
||||
uses the DS register to reference memory.
|
||||
|
||||
h. When you do specify a segment register, make sure you
|
||||
follow the same rule for size overrides: put it
|
||||
INSIDE the brackets, as follows:
|
||||
|
||||
OK: [byte es:di] [es:fmptr]
|
||||
|
||||
BAD: es:[byte di]
|
||||
|
||||
i. Use the OFFSET operator to get the address of a
|
||||
variable or structure. Turbo Debugger automatically
|
||||
supplies the brackets around a variable name if you just type
|
||||
the variable name alone.
|
||||
|
||||
a contents of structure a
|
||||
[a] contents of structure a
|
||||
offset a address of structure a
|
||||
|
||||
j. You can use the type overrides and the format control
|
||||
count to examine any area of memory displayed as you wish.
|
||||
|
||||
[byte es:bx],10 10 bytes pointed to by es:bx
|
||||
[dword ds:si],4 4 dwords pointed to by ds:si
|
||||
|
||||
This is very useful when specifying watch expressions.
|
||||
|
||||
k. Sometimes you use a word memory location or register to
|
||||
point to a paragraph in memory that contains a data
|
||||
structure. Access the structure with expressions like
|
||||
|
||||
[abc [xx]:0].mem1
|
||||
[abc es:0].mem3
|
||||
|
||||
/************************* END OF FILE *****************************/
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
/*************************************************************************/
|
||||
TURBO DEBUGGER
|
||||
Turbo Debugger Readme file
|
||||
|
||||
This file discusses the following Turbo Debugger related topics:
|
||||
|
||||
1. Just-In-Time debugging with TD32
|
||||
2. New tools
|
||||
3. Debugging throw calls
|
||||
4. Debugging under Win32s
|
||||
5. Corrupt session state files
|
||||
6. Using TD.EXE in a Windows DOS box
|
||||
7. Debugging multiple applications using TDW
|
||||
8. TDW and <Ctrl><Alt><SysReq>
|
||||
9. TDW and TD32s' Icons
|
||||
10. Resetting an application that's running under TDW
|
||||
11. Resetting a process that's attached to TD32
|
||||
12. Network messages and TDW and TD32
|
||||
13. Debugging DLL's via LoadLibrary under Windows
|
||||
14. PENDING activity indicator
|
||||
15. TDW Video Support with Resource intensive applications
|
||||
16. TDW & The Integrated Debugger with PC Tools for Windows version 1.0.
|
||||
17. Using TDW with Borland C++ and Borland Pascal
|
||||
18. C++ exception handling
|
||||
|
||||
|
||||
1. Just-In-Time debugging with TD32
|
||||
-----------------------------------
|
||||
Windows NT gives TD32 the ability to trap application exceptions,
|
||||
even when TD32 is not running. If your application encounters an exception,
|
||||
the Windows NT Program Registry can automatically launch TD32. TD32 then
|
||||
displays the source line where the exception occurred.
|
||||
|
||||
To set up Just-In-Time debugging, you must specify a debugger in the
|
||||
Windows NT program registry. Once set up, Windows NT starts the registered
|
||||
debugger in the event of an application error. This mechanism lets you
|
||||
connect TD32 to any process that fails.
|
||||
|
||||
Windows NT displays an Application Error dialog box when an unhandled
|
||||
exception occurs. The dialog box provides an OK button, which you can
|
||||
choose to terminate the application. However, if you register a debugger
|
||||
in the Windows NT program registry, the dialog box will also contain a
|
||||
CANCEL button. Choosing CANCEL invokes the registered debugger.
|
||||
|
||||
To add TD32 to the program registry:
|
||||
1) Run the program JITIME.EXE (located in your Borland C++ BIN directory)
|
||||
from Windows NT.
|
||||
|
||||
2) Check one of the following:
|
||||
TD32 -- Registers TD32.EXE as the default debugger
|
||||
Dr. Watson -- Registers WinSpector as the default debugger
|
||||
None -- Does not register any debugger
|
||||
Other -- Registers the debugger of your choice
|
||||
|
||||
3) Select Confirm Invocation if you want the Application Error dialog
|
||||
box to display a CANCEL button. If Confirm Invocation is not checked,
|
||||
Windows NT automatically starts the selected debugger when any
|
||||
application error occurs.
|
||||
|
||||
|
||||
2. New tools
|
||||
------------
|
||||
The 16-bit linker now handles symbol tables larger than 64K in the
|
||||
debug information for an .EXE file. This change required a modification
|
||||
to the format of the debug information generated by the linker. As a
|
||||
result, the following tools have been updated to correspond to this
|
||||
TLINK modification:
|
||||
|
||||
TDW, TDUMP, the IDE Debugger, the IDE Browser
|
||||
|
||||
If you attempt to use any of the new tools with old executable files,
|
||||
they will output an error message and refuse to run. To work around this
|
||||
condition, relink your application using the new TLINK.EXE. However, if you
|
||||
use an old version of TDUMP it checks for version 4.0 and later.
|
||||
If TDUMP generates garbage when dumping an executable file, check the symbolic
|
||||
debug version number contained in the header. If it is version 4.01, make sure
|
||||
that you are using the correct version of TDUMP (TDUMP prints out "Version 4.1"
|
||||
in the banner when you run it).
|
||||
|
||||
|
||||
3. Debugging throw calls
|
||||
------------------------
|
||||
If you step over or into a throw() call, the application will run until it
|
||||
reaches a breakpoint or program termination instead of stopping at the
|
||||
appropriate catch() function. To debug catch() functions, set breakpoints
|
||||
within the functions.
|
||||
|
||||
|
||||
4. Debugging under Win32s
|
||||
-------------------------
|
||||
a) To use TD32 under Windows 3.1, you must have Win32s installed. Win32s
|
||||
is usually installed at the same time you install BC45. If Win32s is not
|
||||
properly installed, TD32 will not run under Windows 3.1. To verify that
|
||||
Win32s is properly installed, run the Freecell application supplied with
|
||||
Win32s.
|
||||
|
||||
b) Because Win32s does not run under Windows 3.0, TD32 is not compatible
|
||||
with Windows 3.0.
|
||||
|
||||
c) TD32 can support dual monitor debugging under Win32s. Ensure that
|
||||
a monochrome adapter is installed in your machine and set the
|
||||
[VideoOptions] section of TDW.INI to the following setting:
|
||||
|
||||
[VideoOptions]
|
||||
MONO=yes
|
||||
|
||||
This operation can be performed automatically by using the TDWINI.EXE Video
|
||||
Configuration Utility and selecting the Mono option in the SVGA.DLL Settings
|
||||
Dialog.
|
||||
|
||||
d) You cannot trace into Windows kernel code when you debug with TD32 under
|
||||
Win32s. TD32 steps over any call that steps into the kernel code. If you
|
||||
attempt to step into a statement that does not have debug information, and
|
||||
that statement calls the kernel code, TD32 will not perform a Screen Swap
|
||||
unless Display Options are set to Always or unless you are using the
|
||||
TDWGUI.DLL video driver.
|
||||
|
||||
e) See the online text file TD_HELP.TXT for more information on
|
||||
using TD32 and TDW.
|
||||
|
||||
|
||||
5. Corrupt session state files
|
||||
------------------------------
|
||||
If your machine locks up while you are debugging a Windows application,
|
||||
it is best to delete any session state files before restarting the debugger.
|
||||
This can be done by either deleting the session state files or by starting
|
||||
the debugger with the -jn command-line option.
|
||||
|
||||
|
||||
6. Using TD.EXE in a Windows DOS box
|
||||
------------------------------------
|
||||
The TD.PIF file included with the BC45 installation insures the proper
|
||||
settings for running the DOS based Turbo Debugger (TD.EXE) in a Windows
|
||||
DOS box. If need be, you can create this .PIF file using Window's Pif
|
||||
editor, and setting the following values:
|
||||
|
||||
Program Filename: TD.EXE
|
||||
Window Title: Turbo Debugger for DOS
|
||||
Video Memory: Text
|
||||
Memory Requirements: 128 -1
|
||||
EMS: 0 -1
|
||||
XMS Memory 0 3096
|
||||
Execution: Background & Exclusive enabled
|
||||
( required for Dual Monitor debugging )
|
||||
|
||||
Close Window on Exit.
|
||||
|
||||
Advanced Options:
|
||||
Memory Options: Lock Application Memory.
|
||||
Display Options: Retain Video Memory.
|
||||
|
||||
TD.EXE running in a DOS Box results in heavy use of the GDI resources.
|
||||
Running a high resolution video driver on some video adapters while
|
||||
running multiple applications can result in an inability to display
|
||||
High Resolution Graphics. If this is the case, close one or more of the
|
||||
Windows applications that are currently running.
|
||||
|
||||
|
||||
7. Debugging multiple applications using TDW
|
||||
--------------------------------------------
|
||||
You can debug multiple applications under TDW as follows:
|
||||
|
||||
1. Load the first program to be debugged into TDW.
|
||||
|
||||
2. Once the application is loaded, press the F3 key to
|
||||
display the Load Module Source or DLL Symbols dialog box.
|
||||
|
||||
3. In the DLL Name text entry box, enter the name of the
|
||||
.EXE or DLL to add. If the .EXE or DLL resides in
|
||||
another directory, you need to provide the full path.
|
||||
|
||||
4. Press <Enter>. TDW adds the program name to the
|
||||
DLLs & Programs list box and puts the !! symbol after it.
|
||||
|
||||
5. Close the Load Module Source or DLL dialog box, return to
|
||||
the Module window, and set any necessary breakpoints in
|
||||
the first program.
|
||||
|
||||
6. Press F9 to run the first program.
|
||||
|
||||
7. Switch to the Windows Program Manager while the first
|
||||
program is running and run the second program in the
|
||||
usual way.
|
||||
|
||||
8. You see the display switch back to TDW with the CPU
|
||||
window showing the start-up information of the second
|
||||
application. Close the CPU window.
|
||||
|
||||
9. In the Module window, set any necessary breakpoints in
|
||||
the second application, then press the F9 key to run it.
|
||||
|
||||
This method is useful for debugging DDE conversations or any
|
||||
other inter-program communication in the Windows environment
|
||||
(such as OLE 2 applications).
|
||||
|
||||
|
||||
8. TDW and <Ctrl><Alt><SysReq>
|
||||
------------------------------
|
||||
When you're debugging with TDW, you can press <Ctrl><Alt><SysReq> to
|
||||
interrupt the application being debugged and to return control to TDW.
|
||||
However, the behavior in TDW 4.0 has changed slightly to accommodate the
|
||||
use of Microsoft's TOOLHELP.DLL. If your application is idle when you
|
||||
interrupt its execution, TDW posts a WM_NULL message to the application
|
||||
to "wake it up" so it can respond to the interrupt. Because of this, you
|
||||
may need to press <Ctrl><Alt><SysReq> a number of times before you get a
|
||||
response from the application being debugged.
|
||||
|
||||
|
||||
9. TDW and TD32s' Icons
|
||||
-----------------------
|
||||
The Working Directory settings in the Turbo Debugger icons have been slightly
|
||||
changed. To accommodate for DLLs in the working directory of the application
|
||||
being debugged, TDW & TD32 set the working directory to the directory used
|
||||
in the Command Line input box. Because of this, TDW and TD32 ignores any
|
||||
directories input into the Working Directory input box. You can work around
|
||||
this by using the -t command line option without supplying a path. For example
|
||||
|
||||
TDW -t MYAPP.EXE
|
||||
|
||||
In this case, the debugger uses the icon property's working directory, but it
|
||||
will not be able to find the applications .DLL files.
|
||||
|
||||
|
||||
10. Resetting an application that's running under TDW
|
||||
-----------------------------------------------------
|
||||
If you reset TDW before running the application you're debugged runs to
|
||||
completion, Windows will not free the applications resources. To prevent
|
||||
this from occurring, run the application being debugged to completion
|
||||
before restating it. Resources are freed by Windows only when an application
|
||||
has been terminated via a WM_QUIT message.
|
||||
|
||||
|
||||
11. Resetting a process that's attached to TD32
|
||||
-----------------------------------------------
|
||||
TD32 cannot reset a process which you have attached to using the File|Attach
|
||||
command. If you reset or terminate a process that you attached to, you must
|
||||
start a new debugging session.
|
||||
|
||||
|
||||
12. Network messages and TDW and TD32
|
||||
-------------------------------------
|
||||
Network message broadcasts must be disabled when you run either TDW or TD32.
|
||||
It is recommended that you disable message broadcasts from your Windows
|
||||
Network dialog in the Control Panel.
|
||||
|
||||
|
||||
13. Debugging DLL's via LoadLibrary under Windows
|
||||
-------------------------------------------------
|
||||
If you are debugging a .DLL inside TDW, and the source for the .DLL resides
|
||||
in a different directory, make sure that TDW's <Option><Path to Source>
|
||||
command includes the directory where the .DLL source is located.
|
||||
|
||||
|
||||
14. PENDING activity indicator
|
||||
------------------------------
|
||||
The PENDING activity indicator was omitted from page 52 of the Turbo Debugger
|
||||
User's Guide. It is documented in the section "Controlling Program Execution"
|
||||
on page 28.
|
||||
|
||||
|
||||
15. TDW Video Support with Resource intensive applications
|
||||
----------------------------------------------------------
|
||||
SVGA.DLL performs a mode switch using the Death & Resurrection DDK API calls.
|
||||
In applications that use resources intensely ( e.g. BCW 4.5 ) the Death &
|
||||
Resurrection calls fail inside certain Windows Display Drivers. This is a
|
||||
problem with the Windows display driver. If you encounter such behavior,
|
||||
change the TDW.INI settings using TDWINI.EXE for SVGA.DLL to:
|
||||
Use Documented Mode Switch
|
||||
then restart the GDI when Turbo Debugger exits.
|
||||
|
||||
As an alternative, change your Video .DLL to TDWGUI.DLL.
|
||||
|
||||
|
||||
16. TDW & The Integrated Debugger with PC Tools for Windows version 1.0.
|
||||
------------------------------------------------------------------------
|
||||
TDW & the Integrated Debugger are not 100% compatible with PC Tools for
|
||||
Windows 1.0. The known problems inside TDW are resetting & reloading
|
||||
applications causing random General Protection Faults.
|
||||
|
||||
When debugging an application with the Integrated Debugger, random General
|
||||
Protection Faults occur which do not occur when you debug without PC Tools
|
||||
for Windows loaded. Central Point has acknowledged this incompatibility.
|
||||
|
||||
|
||||
17. Using TDW with Borland C++ and Borland Pascal
|
||||
-------------------------------------------------
|
||||
If you have both Borland C++ and Borland Pascal installed on your system:
|
||||
|
||||
You cannot run both versions of TDW simultaneously. TDW 3.1 must be
|
||||
run to debug your Borland Pascal programs, and TDW 4.0 must be run
|
||||
to debug Borland C++ programs.
|
||||
|
||||
Make sure that old copies of TDW.INI are removed from your system
|
||||
(run the TDWINI.EXE utility to clean up old TDW.INI files).
|
||||
|
||||
If you wish to use TDWGUI.DLL with TDW version 3.1 you need to
|
||||
manually add UseTimer=Yes to the VideoOptions section of TDW.INI.
|
||||
Note that this option should not be set when using TDW version 4.0.
|
||||
This means that you would need to hand change your TDW.INI file each
|
||||
time you switched between versions of TDW. For this reason, we
|
||||
recommend the non-windowed video DLLs (such as SVGA.DLL) for
|
||||
customers who debug both BP and BC applications.
|
||||
|
||||
Check the [386Enh] section in your Windows SYSTEM.INI file for
|
||||
multiple entries for the device TDDEBUG.386. Remove duplicate
|
||||
entries of TDDEBUG.386 so that only the version from Borland C++
|
||||
is loaded. On disk, you may also want to rename or remove the BP7
|
||||
versions of TDDEBUG.386 and TDWIN.DLL to avoid their accidental loading.
|
||||
You must restart Windows after making changes to system.ini.
|
||||
|
||||
|
||||
18. C++ exception handling
|
||||
---------------------------
|
||||
Turbo Debugger has the ability to step into the catch function after a
|
||||
C++ exception is generated. If an exception is generated:
|
||||
|
||||
1) Turbo Debugger notices the exception and pauses the program with the
|
||||
*cursor* (not the IP) placed on the throw that is responsible for
|
||||
the exception. In this way, Turbo Debugger notifies the user of the
|
||||
location where the exception was generated.
|
||||
|
||||
2) Press <F8> to have the debugger step into the catch function, or
|
||||
press <F9> to continue running the program if you are not interested
|
||||
in this particular C++ exception.
|
||||
|
||||
/***************************** END OF FILE *******************************/
|
||||
|
||||
@@ -0,0 +1,711 @@
|
||||
/*************************************************************************/
|
||||
TURBO DEBUGGER
|
||||
UTILITIES REFERENCE
|
||||
|
||||
This file contains information about the following Turbo Debugger utilities:
|
||||
|
||||
1. TDSTRIP and TDSTRP32
|
||||
2. TDUMP
|
||||
3. TDMEM
|
||||
4. TDWINI
|
||||
5. TDRF
|
||||
6. TDINST, TDWINST, and TD32INST
|
||||
|
||||
For convenience, when searching for information about a particular utility,
|
||||
you can search for the name of the utility followed by a colon (i.e. TDUMP:).
|
||||
Doing so will take you directly to the header for the utility specified.
|
||||
|
||||
For a list of all the command-line options available for TDSTRIP.EXE,
|
||||
and TDUMP.EXE, just type the program name and press Enter. For example,
|
||||
to see the command-line options for TDSTRIP.EXE, you enter
|
||||
|
||||
TDSTRIP
|
||||
|
||||
For a list of all the command-line options available for TDMEM.EXE,
|
||||
enter the program name followed by -?.
|
||||
|
||||
TDMEM -?
|
||||
|
||||
|
||||
1. TDSTRIP: The symbol table stripping utility
|
||||
==============================================
|
||||
TDSTRIP.EXE (and TDSTRP32, the 32-bit version of TDSTRIP) lets you
|
||||
remove the symbol table from an executable program. This is a faster
|
||||
way of removing the symbol table than recompiling and relinking your
|
||||
program without symbolic debug information. TDSTRIP can also remove
|
||||
debugging information from an .OBJ file:
|
||||
|
||||
TDSTRIP PROGRAM.OBJ
|
||||
|
||||
You can also use TDSTRIP to remove the symbol table and put it in
|
||||
a separate file. This is useful when you want to convert the .EXE
|
||||
format program to a .COM file and still retain the debugging symbol
|
||||
table. TDSTRIP puts the symbol table in a file with the extension
|
||||
.TDS. Turbo Debugger looks for this file when it loads a program to
|
||||
debug that doesn't have a symbol table.
|
||||
|
||||
|
||||
TDSTRIP command-line options
|
||||
----------------------------
|
||||
The general form of the DOS command line used to start TDSTRIP is:
|
||||
|
||||
TDSTRIP [-s] [-c] <exename> [<outputname>]
|
||||
|
||||
If you don't specify the -s option, the symbol table is removed from
|
||||
the .EXE file <exename>. If you specify an <outputname>, the original
|
||||
.EXE file is left unchanged and a version with no symbol table is created
|
||||
as <outputname>.
|
||||
|
||||
If you do specify the -s option, the symbol table will be put in a
|
||||
file with the same name as <exename> but with the extension .TDS. If you
|
||||
specify an output file, the symbol table will be put in <outputname>.
|
||||
|
||||
If you specify the -c option, the input .EXE file is converted into a
|
||||
.COM file. If you use -c in conjunction with -s, you can convert an
|
||||
.EXE file with symbols into a .COM file with a separate .TDS symbol
|
||||
file. This lets you debug .COM files with Turbo Debugger while
|
||||
retaining full debugging information.
|
||||
|
||||
You can only convert certain .EXE files into .COM files. The same
|
||||
restrictions apply to the -c option of TDSTRIP as to the /t option of
|
||||
TLINK: Your program must start at location 100 hex, and it can't
|
||||
contain any segment fixups.
|
||||
|
||||
The default extension for <exename> is .EXE. If you add an extension,
|
||||
it overrides the default.
|
||||
|
||||
There are two default extensions for <outputname>,
|
||||
|
||||
o .TDS when you use the -s command-line switch
|
||||
o .EXE when you don't use the -s command-line switch
|
||||
|
||||
If you add an extension, it overrides the defaults.
|
||||
|
||||
Here are some sample TDSTRIP command lines. The following command
|
||||
removes the symbol table from MYPROG.EXE:
|
||||
|
||||
TDSTRIP MYPROG
|
||||
|
||||
The following command removes the symbol table from MYPROG.OLD
|
||||
and places it in MYPROG.TDS:
|
||||
|
||||
TDSTRIP -s MYPROG.OLD
|
||||
|
||||
The following command leaves MYPROG.EXE unchanged but creates another
|
||||
copy of it named MYPROG.NEW without a symbol table:
|
||||
|
||||
TDSTRIP MYPROG MYPROG.NEW
|
||||
|
||||
The following command removes the symbol table from MYPROG.EXE and
|
||||
places it in MYSYMS.TDS:
|
||||
|
||||
TDSTRIP -s MYPROG MYSYMS
|
||||
|
||||
|
||||
TDSTRIP error messages
|
||||
----------------------
|
||||
Following is a list of TDSTRIP error messages:
|
||||
|
||||
Can't create file: ___
|
||||
TDSTRIP couldn't create the output symbol or .EXE file. Either there
|
||||
is no more room on your disk, or you specified an invalid output file
|
||||
name.
|
||||
|
||||
Can't open file: ___
|
||||
TDSTRIP could not locate the .EXE file from which you want to remove the
|
||||
symbol table.
|
||||
|
||||
Error reading from input exe file
|
||||
An error occurred during reading from the input executable program
|
||||
file. Your disk may be unreadable. Try the operation again.
|
||||
|
||||
Error writing to output file: ___; disk may be full
|
||||
TDSTRIP couldn't write to the output symbol or executable file. This
|
||||
usually happens when there is no more room on your disk. You will have
|
||||
to delete some files to make room for the file created by TDSTRIP.
|
||||
|
||||
Input file is not an .exe file
|
||||
You've specified an input file name that isn't a valid executable
|
||||
program. You can strip symbols only from .EXE programs because these
|
||||
are the only ones that TLINK can put a symbol table in. Programs in
|
||||
.COM file format don't have symbol tables and can't be processed by
|
||||
TDSTRIP.
|
||||
|
||||
Invalid command-line option: ___
|
||||
You've given an invalid command-line option when starting TDSTRIP
|
||||
from the DOS command line.
|
||||
|
||||
Invalid exe file format
|
||||
The input file appears to be an .EXE format program file, but
|
||||
something is wrong with it. You should relink the program with TLINK.
|
||||
|
||||
Not enough memory
|
||||
Your system doesn't have enough free memory for TDSTRIP to load and
|
||||
process the .EXE file. This only happens in extreme circumstances
|
||||
(TDSTRIP has very modest memory requirements). Try rebooting your
|
||||
system and running TDSTRIP again. You might have previously run a
|
||||
program that allocated some memory that won't be freed until you reboot.
|
||||
|
||||
Program does not have a symbol table
|
||||
You've specified an input file that's a valid .EXE file, but it
|
||||
doesn't have a symbol table.
|
||||
|
||||
Program does not have a valid symbol table
|
||||
The symbol table at the end of the .EXE file isn't a valid TLINK
|
||||
symbol table. This can happen if you try to use TDSTRIP on a program
|
||||
created by a linker other than TLINK. Relink the program with TLINK.
|
||||
|
||||
Too many arguments
|
||||
You can supply a maximum of two arguments to TDSTRIP, the first being
|
||||
the name of the executable program, and the second being the name of
|
||||
the output file for symbols or the executable program.
|
||||
|
||||
You must supply an exe file name
|
||||
You've started TDSTRIP without giving it the name of an .EXE program
|
||||
file whose symbol table you want to strip.
|
||||
|
||||
|
||||
2. TDUMP: The file dumping utility
|
||||
==================================
|
||||
The TDUMP utility program produces a file dump that shows the
|
||||
structure of a file.
|
||||
|
||||
TDUMP breaks apart a file structurally and uses the file's extension to
|
||||
determine the output display format. TDUMP recognizes many file formats,
|
||||
including .EXE, .OBJ, and .LIB files. If TDUMP doesn't recognize an
|
||||
extension, it produces a hexadecimal dump of the file. You can control
|
||||
the output format by using command-line options when you start the
|
||||
program. (These options are described later).
|
||||
|
||||
TDUMP's ability to peek at a file's inner structure displays not only
|
||||
a file's contents, but also how a file is constructed. Moreover,
|
||||
because TDUMP verifies that a file's structure matches its extension,
|
||||
you can also use TDUMP to test file integrity.
|
||||
|
||||
|
||||
TDUMP syntax
|
||||
------------
|
||||
The DOS command-line syntax for TDUMP is:
|
||||
|
||||
TDUMP [<options>] <Inputfile> [<Listfile>] [<options>]
|
||||
|
||||
<Inputfile> is the file whose structure you want to display (or "dump").
|
||||
<Listfile> is an optional output file name (you can also use the standard
|
||||
DOS redirection command ">"). <options> stands for any of the TDUMP
|
||||
options discussed in the next section.
|
||||
|
||||
|
||||
TDUMP command-line options
|
||||
--------------------------
|
||||
You can use several optional switches with TDUMP, all of which start with
|
||||
a hyphen or a forward slash. The following two examples are equivalent:
|
||||
|
||||
TDUMP -el -v demo.exe
|
||||
|
||||
TDUMP /el /v demo.exe
|
||||
|
||||
|
||||
The -a and -a7 options
|
||||
----------------------
|
||||
TDUMP automatically adjusts its output display according to the file type.
|
||||
You can force a file to be displayed as ASCII by including the -a or -a7
|
||||
option.
|
||||
|
||||
-a produces an ASCII file display, which shows the offset and the contents
|
||||
in displayable ASCII characters. A character that is not displayable
|
||||
(like a control character) appears as a period.
|
||||
|
||||
-a7 converts high-ASCII characters to their low-ASCII equivalents. This
|
||||
is useful if the file you are dumping sets high-ASCII characters as
|
||||
flags (WordStar files do this).
|
||||
|
||||
|
||||
The -b# option
|
||||
--------------
|
||||
The -b# option allows you to display information beginning at a specified
|
||||
offset. For example, if you wanted a dump of MYFILE starting from offset
|
||||
100, you would use:
|
||||
|
||||
TDUMP -b100 MYFILE
|
||||
|
||||
|
||||
The -e, -el, -er and -ex options
|
||||
--------------------------------
|
||||
All four options force TDUMP to display the file as an executable
|
||||
(.EXE) file.
|
||||
|
||||
An .EXE file display consists of information contained within a file
|
||||
that is used by the operating system when loading a file. If symbolic
|
||||
debugging information is present (Turbo Debugger or Microsoft CodeView),
|
||||
TDUMP displays it.
|
||||
|
||||
TDUMP displays information for DOS executable files, NEW style executable
|
||||
files ( Microsoft Windows and OS/2 .EXEs and DLLs ), and Linear Executable
|
||||
files.
|
||||
|
||||
-el suppresses line numbers in the display.
|
||||
|
||||
-er prevents the relocation table from displaying.
|
||||
|
||||
-ex prevents the display of New style executable information.
|
||||
This means TDUMP will only display information for the DOS
|
||||
"stub" program.
|
||||
|
||||
|
||||
The -h option
|
||||
-------------
|
||||
The -h option displays the dump file in hexadecimal (hex) format. Hex
|
||||
format consists of a column of offset numbers, 16 columns of hex numbers,
|
||||
and their ASCII equivalents (a period appears where no displayable ASCII
|
||||
character occurs).
|
||||
|
||||
If TDUMP doesn't recognize the input file's extension, it displays the
|
||||
file in hex format (unless an option is used to indicate another format).
|
||||
|
||||
|
||||
The -l option
|
||||
-------------
|
||||
The -l option displays the output file in library (.LIB) file format.
|
||||
A library file is a collection of object files (see the -o option for
|
||||
more on object files). The library file dump displays library-specific
|
||||
information, object files, and records in the object file.
|
||||
|
||||
|
||||
The -m option
|
||||
-------------
|
||||
The -m option leaves C++ names occurring in object files, executable
|
||||
files, and Turbo Debugger symbolic information files in "mangled" format.
|
||||
This option is helpful in determining how the C++ compiler "mangles"
|
||||
a given function name and its arguments.
|
||||
|
||||
|
||||
The -o, -oc, -ox, and -oi options
|
||||
---------------------------------
|
||||
-o displays the file as an object (.OBJ) file. An object file
|
||||
display contains descriptions of the command records that pass
|
||||
commands and data to the linker, telling it how to create an .EXE
|
||||
file.
|
||||
|
||||
The display format shows each record and its associated data on a
|
||||
record-by-record basis.
|
||||
|
||||
-oc causes TDUMP to perform a cyclic redundancy test (CRC) on each
|
||||
encountered record. The display differs from the -o display only
|
||||
if an erroneous CRC check is encountered (the TDUMP CRC value differs
|
||||
from the record's CRC byte).
|
||||
|
||||
-ox<id> excludes designated record types from the object module dump.
|
||||
Replace <id> with the record name not to be displayed. For
|
||||
instance,
|
||||
|
||||
TDUMP -oxPUBDEF MYMODULE.OBJ
|
||||
|
||||
produces an object module display for MYMODULE.OBJ that excludes the
|
||||
PUBDEF records.
|
||||
|
||||
-oi<id> includes only specified record types in the object module dump.
|
||||
Replace <id> with the name of the record to be displayed.
|
||||
For instance,
|
||||
|
||||
TDUMP -oiPUBDEF MYMODULE.OBJ
|
||||
|
||||
produces an object module display for MYMODULE.OBJ that displays
|
||||
only the PUBDEF records.
|
||||
|
||||
The -ox and -oi options are helpful in finding errors that occur during
|
||||
linking. By examining the spelling and case of the EXTDEF symbol and
|
||||
the PUBDEF symbol, you can resolve many linking problems. For instance,
|
||||
if you receive an "unresolved external" message from the linker, use
|
||||
"TDUMP -oiEXTDEF" to display the external definitions occurring in the
|
||||
module causing the error. Then, use "TDUMP -oiPUBDEF" on the module
|
||||
containing the public symbol the linker could not match.
|
||||
|
||||
Another use for the -oi switch is to check the names and sizes
|
||||
of the segments generated in a particular module. For instance,
|
||||
|
||||
TDUMP -oiSEGDEF MYMODULE.OBJ
|
||||
|
||||
displays the names, attributes, and sizes of all of the segments
|
||||
in MYMODULE.
|
||||
|
||||
|
||||
The -v option
|
||||
-------------
|
||||
The -v option is used for verbose display. If used with an .OBJ or .LIB
|
||||
file, TDUMP produces a hexadecimal dump of the record's contents without
|
||||
any comments about the records.
|
||||
|
||||
|
||||
If you use TDUMP on a Turbo Debugger symbol table, it displays the
|
||||
information tables in the order in which it encounters them. TDUMP
|
||||
doesn't combine information from several tables to give a more meaningful
|
||||
display on a per-module basis.
|
||||
|
||||
|
||||
3. TDMEM: The memory display utility
|
||||
====================================
|
||||
TDMEM displays the current availability of your computer's memory.
|
||||
This includes Expanded or Extended memory, if it exists, and conventional
|
||||
memory. This is useful when debugging TSR and device driver programs.
|
||||
You can use the File|Table relocate option in Turbo Debugger to specify
|
||||
a base segment address for the current symbol table that is shown when
|
||||
running TDMEM.
|
||||
|
||||
|
||||
4. TDWINI: The video DLL setup utility
|
||||
======================================
|
||||
TDWINI helps you select and configure the video DLL that you use with TDW.
|
||||
For complete instructions on this utility, see the online help (F1)
|
||||
provided with the utility.
|
||||
|
||||
|
||||
5. TDRF: Utility for remote file commands and file transfer
|
||||
===========================================================
|
||||
The remote file transfer utility (TDRF) works in conjunction with TDREMOTE
|
||||
or WREMOTE running on another system. (For more information on TDREMOTE and
|
||||
WREMOTE, see the "Remote Debugging" appendix in the "Turbo Debugger User's
|
||||
Guide"). With TDRF you can perform most DOS file maintenance operations on
|
||||
the remote system. You can
|
||||
|
||||
o copy files to the remote system
|
||||
o copy files from the remote system
|
||||
o make directories
|
||||
o remove directories
|
||||
o display directories
|
||||
o change directories
|
||||
o rename files
|
||||
o delete files
|
||||
|
||||
Once you have started TDREMOTE or WREMOTE on the remote system, you can
|
||||
use TDRF at any time. You can start it directly from the DOS prompt, or
|
||||
you can access DOS from inside Turbo Debugger by using the File|DOS
|
||||
Shell command, then start TDRF (even while debugging a program on the
|
||||
remote system). This second method is useful if you've forgotten to put
|
||||
some files on the remote system that are required by the program you're
|
||||
debugging.
|
||||
|
||||
When describing TDRF in the following sections, we refer to the system
|
||||
you're typing at as the "local system" and any files there as "local
|
||||
files," and the other system connected by a serial cable or network as
|
||||
the "remote system" and any files there as "remote files."
|
||||
|
||||
|
||||
Starting TDRF from the DOS command line
|
||||
---------------------------------------
|
||||
The general form of the command line for TDRF is
|
||||
|
||||
TDRF [<options>] <command> [<arguments>]
|
||||
|
||||
The <options> control whether the link is network or serial, and if it's
|
||||
serial, the speed of the remote link and which port it runs on. The
|
||||
options are described in more detail in the next section.
|
||||
|
||||
<command> indicates the operation you want to perform. You can type the
|
||||
command either as a DOS command--like COPY, DEL, MD, and so on--or as
|
||||
a single-letter abbreviation.
|
||||
|
||||
<arguments> are any arguments to the command.
|
||||
|
||||
For example, to get a directory display of all files starting with ABC
|
||||
in the current directory on the remote system, you could type:
|
||||
|
||||
TDRF DIR ABC*
|
||||
|
||||
All the commands are described fully after the next section.
|
||||
|
||||
|
||||
TDRF command-line options
|
||||
-------------------------
|
||||
You must start an option with either a hyphen (-) or a slash (/).
|
||||
The following list shows the command-line options for TDRF:
|
||||
|
||||
-rn<L>;<R> Sets the link to network, the local name to <L>, and the remote
|
||||
name to <R>.
|
||||
|
||||
If you link over the network, the name of the local machine defaults to
|
||||
"LOCAL" and the remote machine to "REMOTE". You can set your own name for
|
||||
the machines by entering a name up to 16 characters long for either the
|
||||
local machine, the remote machine, or both.
|
||||
|
||||
You must be running TDREMOTE or WREMOTE with the -rn option on the remote
|
||||
machine with the local machine name set to the same name as you've indicated
|
||||
in the TDRF command.
|
||||
|
||||
-rsN Sets the type of remote link to serial and the speed of the link.
|
||||
|
||||
The -rs option sets the speed at which the remote serial link operates.
|
||||
You must make sure you use the same speed with TDRF that you specified
|
||||
when you started TDREMOTE or WREMOTE on the remote system. N can be 1, 2,
|
||||
3, or 4, where 1 signifies a speed of 9600 baud, 2 signifies 19,200 baud,
|
||||
3 signifies 38,400 baud, and 4 signifies 115,000 baud.
|
||||
|
||||
In other words, the higher the number, the faster the data transfer
|
||||
rate across the serial link. Normally, TDRF defaults to -rs4 (the highest
|
||||
speed).
|
||||
|
||||
-rpN Sets the remote serial link port.
|
||||
|
||||
The -rp option specifies which port to use for the remote serial link.
|
||||
N can be either 1 or 2, where 1 stands for COM1 and 2 stands for COM2.
|
||||
|
||||
-w Writes options to the TDRF executable program file.
|
||||
|
||||
You can make the TDRF command-line options permanent by writing them
|
||||
back into the TDRF executable program image on disk. Do this by
|
||||
specifying the -w command-line option along with the other options you
|
||||
wish to make permanent. You will then be prompted for the name of the
|
||||
executable program.
|
||||
|
||||
If you're running on DOS 3.0 or later, the prompt will indicate the
|
||||
path and file name that you executed TDRF from. You can accept this
|
||||
name by pressing Enter, or you can enter a new executable file name.
|
||||
The new name must already exist and must be a copy of the TDRF program
|
||||
that you've already made.
|
||||
|
||||
If you're running on DOS 2.x, you'll have to supply the full path
|
||||
and file name of the executable program.
|
||||
|
||||
If you enter the name of an executable file that doesn't exist (a new
|
||||
filename), TDRF will create a new executable file.
|
||||
|
||||
|
||||
TDRF commands
|
||||
-------------
|
||||
Following are the command names you can use with the TDRF utility. You
|
||||
can use the wildcards * and ? with the COPY, COPYFROM, DEL, and DIR
|
||||
commands.
|
||||
|
||||
|
||||
COPY
|
||||
|
||||
Copies files from the local system to the remote system. You can also
|
||||
type COPYTO instead of COPY. The single letter abbreviation for this
|
||||
command is T.
|
||||
|
||||
If you supply a single file name after the COPY command, that file
|
||||
name will be copied to the current directory on the remote system. If
|
||||
you supply a second file name after the name of the file on the local
|
||||
system, the local file will be copied to that destination on the
|
||||
remote system. You can specify either a new file name, a directory
|
||||
name, or a drive name on the remote system. For example,
|
||||
|
||||
TDRF COPY TEST1 \MYDIR
|
||||
|
||||
copies file TEST1 from the local system to file MYDIR\TEST1 on the
|
||||
remote system.
|
||||
|
||||
|
||||
COPYFROM
|
||||
|
||||
Copies files from the remote system to the local system. The single
|
||||
letter abbreviation for this command is F.
|
||||
|
||||
If you supply a single file name after the COPYFROM command, that file
|
||||
name will be copied from the current directory on the remote system to
|
||||
the current directory on the local system. If you supply a second file
|
||||
name after the name of the file on the remote system, the remote file
|
||||
will be copied to that destination on the local system. You can
|
||||
specify either a new file name, a directory name, or a drive name on
|
||||
the local system. For example,
|
||||
|
||||
TDRF COPYFROM MYFILE ..
|
||||
|
||||
copies file MYFILE from the remote system to the parent directory of
|
||||
the current directory on the local system.
|
||||
|
||||
TDRF F TC*.* A:\TCDEMO
|
||||
|
||||
copies all files beginning with TC on the current directory of the
|
||||
remote system to the TCDEMO directory on the local system's drive A.
|
||||
|
||||
|
||||
DEL
|
||||
|
||||
Erases a single file from the remote system. The single letter
|
||||
abbreviation for this command is E.
|
||||
|
||||
If you just give a file name with no directory or drive, the file is
|
||||
deleted from the current directory on the remote system. For example,
|
||||
|
||||
TDRF DEL XYZ
|
||||
|
||||
removes file XYZ from the current directory of the remote system.
|
||||
|
||||
|
||||
DIR
|
||||
|
||||
Displays a listing of the files in a directory on the remote system.
|
||||
The single letter abbreviation for this command is D.
|
||||
|
||||
This command behaves similarly to the equivalent DOS command. If
|
||||
you don't specify a wildcard mask, it shows all the files in the
|
||||
directory; if you do specify a mask, only those files will be listed.
|
||||
You can interrupt the directory display at any time by pressing
|
||||
Ctrl-Break.
|
||||
|
||||
The directory listing is displayed in a format similar to that
|
||||
used by the DOS DIR command. For example,
|
||||
|
||||
TDRF DIR \SYS\*.SYS
|
||||
|
||||
results in a display like the following:
|
||||
|
||||
Directory of C:\SYS
|
||||
|
||||
ANSI SYS 4833 8-23-91 6:00a
|
||||
VDISK SYS 5190 8-23-91 6:00a
|
||||
|
||||
|
||||
REN
|
||||
|
||||
Renames a single file on the remote system. The single letter
|
||||
abbreviation for this command is R.
|
||||
|
||||
You must supply two file names with this command: the original file
|
||||
name and the new file name. The new name can specify a different
|
||||
directory as part of the name, but not a different drive. For example,
|
||||
|
||||
TDRF REN TEST1 \TEST2
|
||||
|
||||
renames file TEST1 in the current directory in the remote to TEST2 in
|
||||
the root directory. This effectively "moves" the file from one
|
||||
directory to another. You can also use this command to simply rename a
|
||||
file within a directory, without moving it to another directory.
|
||||
|
||||
|
||||
MD
|
||||
|
||||
Makes a new directory on the remote system. The single letter
|
||||
abbreviation for this command is M.
|
||||
|
||||
You must supply the name of the directory to be created. If you don't
|
||||
supply a directory path as part of the new directory name, the new
|
||||
directory will be created in the current directory on the remote
|
||||
system. For example,
|
||||
|
||||
TDRF MD TEST
|
||||
|
||||
creates a directory named TEST in the current directory on the remote
|
||||
system.
|
||||
|
||||
|
||||
RD
|
||||
|
||||
Removes an existing directory on the remote system. The single letter
|
||||
abbreviation for this command is K.
|
||||
|
||||
You must supply the name of the directory to be removed. If you don't
|
||||
supply a directory path as part of the new directory name, the
|
||||
directory will be removed from the current directory on the remote
|
||||
system. For example,
|
||||
|
||||
TDRF RD MYDIR
|
||||
|
||||
removes a directory named MYDIR from the current directory on the
|
||||
remote system.
|
||||
|
||||
|
||||
CD
|
||||
|
||||
Changes to a new directory on the remote system. The single letter
|
||||
abbreviation for this command is C.
|
||||
|
||||
You must supply the name of the directory to change to. You can also
|
||||
supply a new drive to switch to, or even supply a new drive and
|
||||
directory all at once. For example,
|
||||
|
||||
TDRF CD A:ABC
|
||||
|
||||
makes drive A the current drive on the remote system, and switches to
|
||||
directory ABC as well.
|
||||
|
||||
|
||||
TDRF messages
|
||||
-------------
|
||||
Following is a list of the messages you might encounter when working with
|
||||
TDRF:
|
||||
|
||||
"Can't create file on local system: ___"
|
||||
You were copying a file from the remote system using the COPYFROM
|
||||
command, but the file could not be created on the local system.
|
||||
Either the disk is full on the local system, or the file name on the
|
||||
remote system is the same as a directory name on the local system.
|
||||
|
||||
"Can't modify exe file"
|
||||
The file name you specified to modify is not a valid copy of the TDRF
|
||||
utility. You can only modify a copy of the TDRF utility with the -w
|
||||
option.
|
||||
|
||||
"Can't open exe file to modify"
|
||||
The file name you specified to be modified can't be opened. You've
|
||||
probably entered an invalid or nonexistent file name.
|
||||
|
||||
"Error opening file: ___"
|
||||
The file you wanted to transfer to the remote system could not be
|
||||
opened. You probably specified a nonexistent or invalid file name.
|
||||
|
||||
"Error writing file: ___"
|
||||
An error occurred while writing to a file on the local system,
|
||||
probably because the local disk is full. Try deleting enough
|
||||
files to make room for the file you want to copy from the
|
||||
remote system.
|
||||
|
||||
"Error writing file ___ on remote system"
|
||||
An error occurred while writing a file to the disk on the remote
|
||||
system, probably because the remote disk is full. Try deleting
|
||||
enough files to make room for the file you want to transfer.
|
||||
|
||||
"File name is a directory on remote"
|
||||
You've tried to copy a file from the local to the remote system, but
|
||||
the local file name exists as a directory on the remote system. You'll
|
||||
have to rename the file by giving a second argument to the COPY
|
||||
command.
|
||||
|
||||
"Interrupted"
|
||||
You've pressed Ctrl-Break while waiting for communications to be
|
||||
established with the remote system.
|
||||
|
||||
"Invalid command: ___"
|
||||
You've entered a command that TDRF doesn't recognize. For each
|
||||
command, you can use the DOS-style command word or the single-letter
|
||||
abbreviation.
|
||||
|
||||
"Invalid command line option: ___"
|
||||
You've given an invalid command-line option when starting TDRF from
|
||||
the DOS command line.
|
||||
|
||||
"Invalid destination disk drive"
|
||||
You've specified a nonexistent disk drive letter in your command.
|
||||
Remember that the remote system might have a different number of disk
|
||||
drives than the local system.
|
||||
|
||||
"No matching files on remote"
|
||||
You've done a DIR command, but either there are no files in the
|
||||
directory on the remote system, or no files match the wildcard
|
||||
specification that you gave as an argument to the DIR command.
|
||||
|
||||
"No remote command specified"
|
||||
You haven't specified any command on the DOS command line; TDRF has
|
||||
nothing to do.
|
||||
|
||||
"Too few arguments"
|
||||
You haven't supplied enough arguments for the command you
|
||||
requested. Some commands require an argument, like DEL, MD,
|
||||
CD, RD, and so on.
|
||||
|
||||
"Too many arguments"
|
||||
You've specified too many arguments for the command you requested.
|
||||
No command requires more than two arguments, and some require only one.
|
||||
|
||||
"Wrong version of remote driver"
|
||||
You're using incompatible versions of TDRF and TDREMOTE. Make sure
|
||||
you're using the latest version of each utility.
|
||||
|
||||
|
||||
6. TDINST, TDWINST, and TD32INST
|
||||
================================
|
||||
Press <F1> while running TDINST, TDWINST, or TD32INST to obtain online help
|
||||
regarding the Turbo Debugger installation programs.
|
||||
|
||||
|
||||
\**************************** END OF FILE ********************************\
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,633 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CONTENTS
|
||||
___________________________________________________________________________
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Introduction . . . . . . . . . . . 1 WM_HEDITCTL and HE_CHAROFFSET . 6
|
||||
Hardware requirements and basic WM_SKB message . . . . . . . . 7
|
||||
limitations . . . . . . . . . . . 1 SKN_TERMINATED . . . . . . . . 7
|
||||
Installation notes and REC_DEBUG . . . . . . . . . . . 7
|
||||
procedures . . . . . . . . . . . . 2 clErrorLevel . . . . . . . . . 8
|
||||
Installing the pen components-- Dictionary searches . . . . . . 8
|
||||
minimum . . . . . . . . . . . . 2 rc.RectBound . . . . . . . . . 8
|
||||
SYSTEM.INI changes . . . . . . 2 DRV_SetSamplingDist . . . . . . 9
|
||||
Installing the pen COMPONENTS-- RecognizeData and ink . . . . . 9
|
||||
complete . . . . . . . . . . . . 2 List of characters effected by
|
||||
SYSTEM.INI changes . . . . . . 3 ALC_PUNC . . . . . . . . . . . 9
|
||||
PENWIN.INI changes . . . . . . 4 DLLs that use hedit and bedit
|
||||
Shipping PENWIN.DLL with your controls . . . . . . . . . . . 9
|
||||
application . . . . . . . . . . . 4 Dictionary and recognizer ISVs:
|
||||
Release notes . . . . . . . . . . 5 When Windows ends . . . . . . . 9
|
||||
Hedits--delayed recogntion SetAlcBitGesture,
|
||||
mode . . . . . . . . . . . . . . 5 ResetAlcBitGesture, and
|
||||
PostVirtualMouseEvent . . . . . 6 IsAlcBitGesture removed . . . . 10
|
||||
ALC_USEBITMAP . . . . . . . . . 6 REC_ error values from Recognize
|
||||
ProcessWriting . . . . . . . . . 6 . . . . . . . . . . . . . . . 10
|
||||
Microsoft user dictionary DLL . 6 DIRQ_SUGGEST not implemented . 10
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
i
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
===========================================================================
|
||||
Introduction
|
||||
===========================================================================
|
||||
|
||||
Borland C++ contains sufficient components from Windows
|
||||
for Pen Computing to let you to build and test pen
|
||||
applications. A mouse can be used to get a rough idea
|
||||
of how recognition and a pen will work.
|
||||
|
||||
However, we strongly recommended that you use Windows
|
||||
for Pen Computing hardware (a pen, for example) during
|
||||
the design and development process. This is critical
|
||||
because a pen gives you an accurate feel for how an
|
||||
application will work in real situations and because
|
||||
the Microsoft Alphanumeric Recognition System (MARS)
|
||||
shipped with Borland C++ has been optimized for a pen
|
||||
and won't work as well with a mouse.
|
||||
|
||||
|
||||
|
||||
===========================================================================
|
||||
Hardware requirements and basic limitations
|
||||
===========================================================================
|
||||
|
||||
1. A driver for Microsoft-compatible mice has been
|
||||
provided so you can do simple testing of pen
|
||||
functionality. This pen driver is called
|
||||
MSMOUSE.DRV.
|
||||
|
||||
2. At this time, only VGA displays can be used with the
|
||||
pen extensions. The VGAP.DRV display driver is a
|
||||
modified version of the VGA.DRV that supports
|
||||
inking. It's required if you want to test pen
|
||||
functionalities.
|
||||
|
||||
3. Handwriting recognition with a mouse will be much
|
||||
less accurate than with digitizer hardware designed
|
||||
specifically for Pen Computing. The recognizer has
|
||||
been designed to work with pen computers and
|
||||
peripherals with true digitizer input and its
|
||||
associated high data rates and high data resolution.
|
||||
|
||||
4. The spell checking technology included in Windows
|
||||
for Pens must be used exclusively for the purpose of
|
||||
improving handwriting recognition. It is not to be
|
||||
used by applications as a spell checker or spelling
|
||||
corrector.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
===========================================================================
|
||||
Installation notes and procedures
|
||||
===========================================================================
|
||||
|
||||
|
||||
|
||||
Installing the pen =======================================================
|
||||
components--
|
||||
minimum This procedure will result in a system that will let
|
||||
you build applications that contain hedit and bedit
|
||||
controls--and call any Windows for Pen Computing API
|
||||
functions. You will not be able to perform handwriting
|
||||
recognition or see ink on the screen.
|
||||
|
||||
|
||||
------------------ The following items must be added or changed in your
|
||||
SYSTEM.INI changes SYSTEM.INI file so that the pen extensions will work.
|
||||
------------------
|
||||
Note! Back up your old SYSTEM.INI file before proceeding.
|
||||
|
||||
1. In the "[boot]" section:
|
||||
|
||||
a. Add "penwindows" to the list of drivers after the
|
||||
"drivers=" key. For example:
|
||||
|
||||
drivers=mmsystem.dll penwindows
|
||||
|
||||
2. In the "[Drivers]" section:
|
||||
|
||||
a. Add a new item "penwindows" and set it equal to
|
||||
the path to PENWIN.DLL. For example:
|
||||
|
||||
penwindows=C:\BORLANDC\REDIST\PENWIN.DLL
|
||||
|
||||
When Windows is restarted PENWIN.DLL will be loaded as
|
||||
an installed driver and you will be able to run
|
||||
applications containing bedit and hedit controls and
|
||||
call the Windows for Pen Computing APIs.
|
||||
|
||||
|
||||
Installing the pen =======================================================
|
||||
COMPONENTS--
|
||||
complete This procedure will result in a system that will run
|
||||
pen applications and allow you to experiment with
|
||||
handwriting recognition and inking functionalities in
|
||||
your applications. Once again, interaction with the
|
||||
mouse will prove inferior in every respect to
|
||||
interaction with a true pen device--but this system of
|
||||
|
||||
|
||||
|
||||
- 2 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using the special mouse driver will allow you to
|
||||
experiment and perform rudimentary testing of your pen
|
||||
functionalities.
|
||||
|
||||
|
||||
------------------ The following items must be added or changed in your
|
||||
SYSTEM.INI changes SYSTEM.INI
|
||||
------------------ file so that the pen extensions will work.
|
||||
|
||||
Note! Back up your old SYSTEM.INI file before proceeding.
|
||||
|
||||
1. In the "[boot]" section:
|
||||
|
||||
a. Change the "display.drv=" line so that the
|
||||
display driver is the pen capable VGAP.DRV
|
||||
shipped with Borland C++. For example:
|
||||
|
||||
display.drv=C:\BORLANDC\REDIST\VGAP.DRV
|
||||
|
||||
Only the VGA display device is supported by the
|
||||
pen components in Borland C++.
|
||||
|
||||
b. Add "pen penwindows" to the list of drivers after
|
||||
the "drivers=" key. For example:
|
||||
|
||||
drivers=mmsystem.dll pen penwindows
|
||||
|
||||
c. Change the "mouse.drv=" line so that it points to
|
||||
YESMOUSE.DRV. For example:
|
||||
|
||||
mouse.drv=C:\BORLANDC\REDIST\YESMOUSE.DRV
|
||||
|
||||
2. In the "[Drivers]" section:
|
||||
|
||||
a. Add a new item "pen" and set it equal to the path
|
||||
to MSMOUSE.DRV. For example:
|
||||
|
||||
pen=C:\BORLANDC\REDIST\MSMOUSE.DRV
|
||||
|
||||
b. Add a new item "penwindows" and set it equal to
|
||||
the path to PENWIN.DLL. For example:
|
||||
|
||||
penwindows=C:\BORLANDC\REDIST\PENWIN.DLL
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 3 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
------------------ The PENWIN.INI file contains a number of initialization
|
||||
PENWIN.INI changes settings for Windows for Pen Computing.
|
||||
------------------
|
||||
There are also two explicit paths that must correctly
|
||||
identify the locations of MARS.DLL and MARS.MOB.
|
||||
INSTALL will add the correct paths to PENWIN.INI but if
|
||||
you move any files, open PENWIN.INI with any generic
|
||||
text editor (like Windows Notepad) and change the path
|
||||
to MARS.DLL and MARS.MOB so that it correctly
|
||||
identifies points to the correct location.
|
||||
|
||||
Once the paths are correct, the file should be copied
|
||||
to the Windows 3.1 root--that is, the directory
|
||||
containing the Windows 3.1 WIN.COM.
|
||||
|
||||
|
||||
|
||||
===========================================================================
|
||||
Shipping PENWIN.DLL with your application
|
||||
===========================================================================
|
||||
|
||||
PENWIN.DLL is a fully redistributable component of
|
||||
Windows for Pen Computing. Because applications will
|
||||
seek to leverage the Pen API--hedit and bedit controls
|
||||
in particular--PENWIN.DLL can be shipped with your
|
||||
application. There are some considerations to keep in
|
||||
mind in shipping PENWIN.DLL with your application:
|
||||
|
||||
1. PENWIN.DLL functions ONLY under Windows 3.1. It WILL
|
||||
NOT WORK with Windows 3.0 because it functions only
|
||||
as an installable device driver--a feature not
|
||||
present in Windows 3.0.
|
||||
|
||||
2. As with other redistributable components such as
|
||||
BWCC.DLL and the OLE libraries, it is the
|
||||
responsibility of the application vendor to
|
||||
determine whether PENWIN.DLL has already been
|
||||
installed (there is a GetSystemMetrics() call for
|
||||
this) and to ensure that the version of PENWIN.DLL
|
||||
with the latest version stamping is the one that is
|
||||
running.
|
||||
|
||||
3. Unlike some of the other redistributable components,
|
||||
if your application installs PENWIN.DLL for the
|
||||
first time, or replaces the current version with a
|
||||
later one, Windows will have to be restarted. As an
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 4 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
installable driver PENWIN.DLL can be loaded only at
|
||||
Windows boot time. Restarting Windows can be
|
||||
accomplished via an ExitWindows() call or by simply
|
||||
prompting the user to do so.
|
||||
|
||||
To install PENWIN.DLL on a Windows 3.1 system follow
|
||||
the "Minimum" procedure listed above.
|
||||
|
||||
4. PENWIN.DLL may be in either the \WINDOWS or the
|
||||
\WINDOWS\SYSTEM directory. The default will be
|
||||
\WINDOWS but since Windows for Pen Computing is an
|
||||
OEM product, Microsoft cannot completely control
|
||||
where PENWIN.DLL is located on a particular machine.
|
||||
|
||||
|
||||
|
||||
===========================================================================
|
||||
Release notes
|
||||
===========================================================================
|
||||
|
||||
Release Notes for the Microsoft(R) Windows for Pen
|
||||
Computing Programmer's Reference, version 1.00 (C)
|
||||
Copyright 1992 Microsoft Corporation.
|
||||
|
||||
This section contains release notes for version 1.00 of
|
||||
the Microsoft(R) Windows for Pen Computing Programmer's
|
||||
Reference. The information in this section is more
|
||||
current than the information in the manual. Where this
|
||||
file conflicts with printed documentation, you should
|
||||
assume that this file is correct.
|
||||
|
||||
Microsoft revises its documentation at the time of
|
||||
reprinting; the manuals and online help files may
|
||||
already include some of this information.
|
||||
|
||||
|
||||
Hedits--delayed =======================================================
|
||||
recogntion mode
|
||||
Setting focus in hedit causes any text in the control
|
||||
to appear even if the control is in "ink" mode. If this
|
||||
is undesireable the control should never be allowed to
|
||||
get the focus.
|
||||
|
||||
Sending an hedit the WM_HEDITCTL message with the
|
||||
HE_SETINKMODE parameter will clear the hedit's text
|
||||
buffer. The same message to a bedit will preserve the
|
||||
control's text contents.
|
||||
|
||||
|
||||
|
||||
|
||||
- 5 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PostVirtualMouseEvent======================================================
|
||||
|
||||
Values greater than the maximum resolution in X
|
||||
direction (usually 640) and max resoultion Y direction
|
||||
(usually 480) will overflow.
|
||||
|
||||
|
||||
ALC_USEBITMAP =======================================================
|
||||
|
||||
The Microsoft recognizer does not implement
|
||||
ALC_USEBITMAP in the alcPriority field for version 1.0.
|
||||
Note that alcPriority is implemented for the alc field.
|
||||
|
||||
|
||||
ProcessWriting =======================================================
|
||||
|
||||
In the description of ProcessWriting, it says "The
|
||||
window specified by the hwnd parameter receives a
|
||||
WM_PARENTNOTIFY message when ProcessWriting destroys
|
||||
its inking window."
|
||||
|
||||
The window never gets the WM_PARENTNOTIFY message since
|
||||
it is not
|
||||
guaranteed that an inking window is created.
|
||||
|
||||
|
||||
Microsoft user =======================================================
|
||||
dictionary DLL
|
||||
The documentation incorrectly states that up to 16
|
||||
dictionaries can be loaded.
|
||||
|
||||
MSSPELL.DLL actually allows only six wordlists to be
|
||||
loaded. Consequently, version 1.00 of the Microsoft
|
||||
User Dictionary DLL allows only six wordlists to be
|
||||
loaded at a time.
|
||||
|
||||
|
||||
WM_HEDITCTL and =======================================================
|
||||
HE_CHAROFFSET
|
||||
Under the documentation for WM_HEDITCTL messages, under
|
||||
HE_CHAROFFSET, it says "See the related HE_CHAROFFSET."
|
||||
It should say "See the related HE_CHARPOSITION."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 6 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WM_SKB message =======================================================
|
||||
|
||||
When the state of the SKB changes, a WM_SKB message is
|
||||
posted. The documentation says that the LOWORD of the
|
||||
lParam contains information on what changed and that
|
||||
the HIWORD contains the window handle of the SKB.
|
||||
|
||||
Actually, the LOWORD contains the hWnd and the HIWORD
|
||||
contains the information on what changed.
|
||||
|
||||
This should be corrected in two places: The
|
||||
ShowKeyboard function and in the WM_SKB message
|
||||
documentation.
|
||||
|
||||
Also, one more value should be mentioned: The HIWORD of
|
||||
lParam contains SKN_TERMINATED (value 0xffff) if the
|
||||
keyboard has been closed.
|
||||
|
||||
|
||||
SKN_TERMINATED =======================================================
|
||||
|
||||
WM_SKB sends SKN_TERMINATED in HIWORD(lParam) when
|
||||
terminating SKN_TERMINATED (0xffff) is sent in the
|
||||
HIWORD(lParam) when the WM_SKB is sent to notify
|
||||
top-level windows that the On-Screen Keyboard is being
|
||||
terminated. This needs to be added to the documentation
|
||||
for the WM_SKB message and for the ShowKeyboard
|
||||
function.
|
||||
|
||||
|
||||
REC_DEBUG =======================================================
|
||||
|
||||
In the Guide to Pen Programming, Chapter 11 "Pen
|
||||
Messages and
|
||||
Constants," under REC_ Values, under Debugging Values,
|
||||
it says:
|
||||
|
||||
"REC_DEBUG All debugging return values are less than
|
||||
this."
|
||||
|
||||
It should say:
|
||||
|
||||
"REC_DEBUG All debugging return values are less than or
|
||||
equal to this."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 7 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clErrorLevel =======================================================
|
||||
|
||||
The documentation for the RC field clErrorLevel says
|
||||
that this value can range from 0 to 100. In the
|
||||
PENWIN.H file, the minimum CL value is defined as
|
||||
|
||||
#define CL_MINIMUM 1
|
||||
|
||||
The correct minimum for clErrorLevel is 1
|
||||
|
||||
|
||||
Dictionary =======================================================
|
||||
searches
|
||||
The documentation is somewhat confusing on the point of
|
||||
dictionary enumeration procedures in chapter 7, page
|
||||
103. To expound:
|
||||
|
||||
If there are ten dictionaries in the dictionary path,
|
||||
and the ninth finds a match for a particular
|
||||
enumeration in a symbol graph, the remaining symbol
|
||||
graph elements will STILL be enumerated--checking for a
|
||||
match in a higher-order dictionary. In other words, the
|
||||
other eight dictionaries before the ninth dictionary in
|
||||
the list will get a shot at finding a "better" match.
|
||||
Enumeration of dictionaries therefore can be said to
|
||||
stop only when the symbol graph is exausted, or the
|
||||
first dictionary in the list responds affirmatively to
|
||||
a query.
|
||||
|
||||
|
||||
rc.RectBound =======================================================
|
||||
|
||||
Here is additional detail on the rectBound element of
|
||||
the RC structure.
|
||||
|
||||
rc.rectBound will be ignored if PCM_RECTBOUND is not
|
||||
set. The documentation suggests on page 237 that
|
||||
rc.lPcm = PCM_RECTBOUND only determines how the
|
||||
recognition context will end.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 8 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DRV_SetSamplingDist =======================================================
|
||||
|
||||
Page 226 of Chapter 10--PENINFO structure:
|
||||
|
||||
In the notes after nSamplingRate and nSamplingDist, the
|
||||
driver messages that manipulate these fields are
|
||||
misnamed. In the printed documentation, they are named
|
||||
DRV_SetSamplingDist and DRV_SetSamplingRate; they are
|
||||
actually DRV_SetPenSamplingDist and
|
||||
DRV_SetPenSamplingRate.
|
||||
|
||||
|
||||
RecognizeData and =======================================================
|
||||
ink
|
||||
Calls to RecognizeData may return an rcresult that
|
||||
references pendata different than that used as a
|
||||
Parameter to the call. For example, Strokes may be
|
||||
removed and the rgbInk and nInkWidth fields of the
|
||||
PENDATAHEADER may not match the values in the original
|
||||
pendata, as no inking has taken place during this
|
||||
recognition context.
|
||||
|
||||
|
||||
List of characters =======================================================
|
||||
effected by
|
||||
ALC_PUNC On page 253 of the documentation, the list of chars in
|
||||
ALC_PUNC has two semicolons; one of these should be a
|
||||
colon.
|
||||
|
||||
|
||||
DLLs that use =======================================================
|
||||
hedit and bedit
|
||||
controls Any DLL that creates an hedit or bedit control must
|
||||
have a nonzero heap size. This is because those
|
||||
controls allocate buffers out of this heap.
|
||||
|
||||
|
||||
Dictionary and =======================================================
|
||||
recognizer ISVs:
|
||||
When Windows ends When a Windows session is about to end, PENWIN.DLL
|
||||
takes the following actions:
|
||||
|
||||
o Calls all the dictionaries in the global recognition
|
||||
context with a DIRQ_CLEANUP message and then frees
|
||||
the corresponding DLLs.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 9 -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
o Calls the CloseRecognizer function for the current
|
||||
recognizer and frees the corresponding DLL.
|
||||
|
||||
Dictionaries and recognizers can take the appropriate
|
||||
cleanup action at this time. The limitations on things
|
||||
that can be done are the same as those when an
|
||||
application receives a WM_ENDSESSION message.
|
||||
|
||||
|
||||
|
||||
|
||||
SetAlcBitGesture, =======================================================
|
||||
ResetAlcBitGesture,
|
||||
and The Windows for Pen Computing Programmer's Reference
|
||||
IsAlcBitGesture refers to the above macros. They have been removed
|
||||
removed because the ability to set alc bits for gestures was
|
||||
not implemented.
|
||||
|
||||
|
||||
REC_ error values =======================================================
|
||||
from Recognize
|
||||
In the documentation for Recognize API and REC_ values
|
||||
in chapter 11, there is a Debugging values section.
|
||||
There is a sentence that reads: "All of the values
|
||||
listed in the following table are in debug version
|
||||
only." That sentence should be replaced with the
|
||||
following: "All of the values below are providing for
|
||||
debugging information. A well-behaved application
|
||||
should not specify an RC that causes any of these
|
||||
values to be returned."
|
||||
|
||||
|
||||
DIRQ_SUGGEST not =======================================================
|
||||
implemented
|
||||
In version 1.0 of Windows for Pens, the dictionary
|
||||
shipped with the system does not support DIRQ_SUGGEST.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- 10 -
|
||||
|
||||
Reference in New Issue
Block a user