EXAMINING ROOM

Kent Porter and Richard A. Relph - Coordinated by Ron Copeland

Ron Copeland, associate editor, is the coordinator for the review section. He welcomes your feedback on products worth reviewing.


Turbo Pascal, Version 4.0

Target: IBM PS/2, PC AT, and true compatibles

Requires: DOS 2.0 or later; 384K for the integrated environment or 256K for the command-line environment

Price: $99.95

Vendor: Borland International, 4585 Scotts Valley Dr., Scotts Valley, CA 95066; 408 438-8400

With Version 4.0, Borland has turned its highly successful Turbo Pascal into a language package well suited to serious software development. Until now, Turbo Pascal has been a structured language suited for small, individually written projects. Previous versions have had certain limitations that barred them from consideration for major software projects. With Version 4.0, Borland has given us a Pascal that is still every bit as useful to its original market and that is also a worthy compiler for commercial and academic programmers.

Turbo Pascal 4.0 offers several new enhancements both to the Pascal language and to its programming environment. One example, the graphics unit, furnishes the most comprehensive set of screen-handling routines that I've seen with any general-purpose programming language. I'll discuss it presently, but first I'll look at some of the particulars.

Turbo Pascal 4.0 corrects the following oft-heard complaints regarding earlier versions:

Three levels of compilation are available. At the lowest level is a simple compile of the current unit. Next higher is Make, which recompiles the current program and any units that have been changed since the last compile. At the highest level is Build, which unconditionally compiles all the parts of an application.

The complete user interface is awakened by the TURBO command, which starts TURBO.EXE running. For hairy-chested traditionalists, a command-line compiler (TPC.EXE) is also available, replete with Unix-like switches. I can't imagine why anyone would prefer TPC; it doesn't furnish nearly as much functionality (although the language is exactly equivalent), and command-line compilers aren't much fun.

Whichever, compile speed is blazingly fast. Borland claims 27,000 lines per minute on an 8-MHz AT, which is the machine I have. Although I'm unwilling to write 27,000 lines of code simply to prove the company right or wrong, I'll say this: a 600-line program compiles fully before my finger leaves the com- mand key. Even on an old 4.77-MHz XT, Turbo Pascal 4.0 compiles equivalent code as or more rapidly than Turbo C on the AT. And Turbo C is no slouch

Linking

Both the integrated and command-line compilers take the somewhat unusual approach of incorporating the linker. This substantially decreases the overall cycle time from .PAS to resulting .EXE. The built-in linker brings in .OBJ files in standard Intel relocatable format; it identifies them via the $L switch, which names the .OBJ file. This allows you to link with modules written in assembly language or in C using the 'Pascal calling conventions.

Oddly, the compiler doesn't convert Pascal source files into .OBJ format. Source files beginning with the UNIT keyword become .TPU-compiled files, and those starting with the PROGRAM keyword become .EXEs. The linker automatically merges any .TPU units into the final product, identifying them from the USES statement.

Although this unconventional approach is valid most of the time, it makes an assumption that might not be universally true: that you want only to link foreign-language modules into Pascal programs and not the other way around. The absence of .OBJ output files and of any option to create them makes it impossible to export compiled Turbo Pascal modules to other languages. In effect, the built-in linker creates a one-way street leading from other languages to Turbo Pascal. You could wish it were a two-way street.

Compatibility with Version 3.0

Speaking of two-way streets, Version 4.0 does better with regard to Turbo Pascal 3.0 compatibility. Both upward and downward options are available.

A utility program called UPGRADE, distributed with Version 4.0, processes Version 3.0 source files in several different ways. One way marks up the original source file, pointing out obsolete Version 3.0 conventions and explaining what needs to be done. For experienced 3.0 programmers, this is a good way to find out where the mosquitoes are hiding, waiting to bite. Another method merges and unifies the source files for overlays and their parent in order to create a monolithic (multiple code segment) application. There are other options as well. UPGRADE is a forward-compatibility tool.

For backward compatibility, Version 4.0 offers two units called Turbo and Graph3. These allow a Version 4.0 program to employ 3.0 features such as turtle graphics, which Version 4.0 doesn't support. The manual has a 20-page chapter devoted to converting from Version 3.0 to 4.0 in addition to a 12- page appendix detailing the differences between the two. That ought to give you some idea of the extent to which Turbo Pascal has been expanded and enhanced in Version 4.0.

Memory Management

While allowing executable code of any size, Version 4.0 is, of course, subject to the 64K segmentation imposed by the Intel processors. It gets around this by limiting the code in any compile unit to 64K and starting a new code segment for each module during linkage. Thus, intrasegment calls (to local subroutines are near calls employing 16-bit offset pointers and those to external routines and to subprograms named in the interface portion of units are implicitly far (32-bit segment:offset) calls. Programmers have no control over these compiler-generated calling conventions.

You can, however, force a routine or an entire compile unit--into far mode with the $F switch, in which $F + turns on far calls/returns and $F- reverts to default (compiler-controlled) calling conventions according to the rules above. An example of needing a far routine is when furnishing a mouse event handler: the handler is called as a far procedure from the device driver in low memory and thus must return with RETF. If the procedure heading is surrounded by the $F switches, its entire body is forced to far.

The DS register holds constant throughout the code, no matter how many code segments there are. Consequently, global data is limited to 64K, and references to global variables are always 16-bit offsets relative to DS. As in most high-level languages (and identically to Version 3.0), local variables for subprograms are allocated on the stack relative to the BP register and so do not count against the 64K limit for globals. Pointers to dynamic objects allocated on the heap are 32-bit segment:offset variables, allowing them to be passed freely among various code segments.

The default stack for a 4.0 program is 8K, and the heap is all of uncommitted memory above the stack. This eliminates the need to be concerned (as you were in Version 3.0) about heap/stack collisions, but of course it's possible for a highly recursive program to drive the stack down into the data segment. An option lets you set the stack size to something besides 8K and also to claim a finite area for the heap. The latter is important in multitasking and TSRs, neither of which can assume that they own all of memory.

An important addition to the Version 4.0 arsenal is a special interrupt- class procedure, which allows you to embed custom interrupt-service routines into your applications. These can be chaining routines ("hooks") that intervene in standard system interrupts, replacements for such things as the critical error handler, or new software- and hardware- driven routines activated via uncommitted vectors. An interrupt procedure looks much like a normal Pascal procedure, except that the INTEARUPT keyword follows the heading. Also, the heading can name the CPU registers you want preserved on the stack (subject to sequencing rules) and you can then read and write them as local variables.

A particularly nice feature is that the entry processing points the DS register to your program's data segment, furnishing direct access to all the program's globules. Because an interrupt procedure returns via an IAET after reloading the parametric registers from the stack, you cannot call it like a normal subroutine from within your program. That's as it should be. This feature alone makes Turbo Pascal, Version 4.0, a worth-while compiler for serious developers.

Graphics

Another enhancement that scores high on the programmer's Richter scale is a new graphics unit. Encompassing some 60 functions and procedures, it provides a comprehensive set of primitives for controlling the display. These include optional automatic detection of the system's video capabilities and selection of the "best possible" mode among CGA, EGA in its many incarnations, VGA, Hercules, AT&T, and PC3270. You can also inquire about the display options available and force a particular mode election.

Once in a graphics mode, the graph unit provides various line styles and widths as well as drawing and filling routines for common visual objects (bars, circles, polygons, rectangles, and so on). You can partition off view ports, set clipping boundaries, inquire about the screen's aspect ratio, monitor error status, and perform a host of other useful graphics operations. The graph unit supports bitblt operations for high-speed image transfers, including XOR, OR, NOT, and AND. This is a substantial improvement over Version 3.0's PutPic/GetPic operations, providing for much more sophisticated animation effects.

Also furnished with the graph unit are four stroked fonts: triplex, small, sans serif, and Gothic. Unlike conventional bit-mapped character fonts, stroked fonts allow for; justified and variable text sizes up to 10 x that can originate at any pixel (rather than character cell) position and can be oriented either horizontally or vertically.

By default--in both text and graphics modes--Version 4.0 writes directly to screen memory rather than going through conventional DOS/ROM BIOS calls. This makes for extremely fast output. You can over-ride the default, and a Check Snow procedure is thoughtfully provided to prevent the unsightly "snow" occurring on older CGAs during direct screen writes. Nevertheless, the line-drawing routine is not particularly fast.

The 4.0 graph unit is impressive, providing the kind of display control and intrinsic graphics calls that make visual programming fun and easy. Unfortunately, it doesn't conform to any graphics interface standard (GKS, PHIGS, or whatever) and thus lacks high-level routines for axis rotation, scaling, and other coordinate transformations. Still, just about everything you need for graphics power is there.

Data Types

Version 4.0 offers several new data types. There are still six basic types- string, char, Boolean, pointer, integer, and real--but the latter two have more choices.

The integer types and their characteristics are shown in Table 1, this page. The fundamental floating- point type in Version 4.0 is the same 6 found in earlier versions. The old Turbo-87 became a has-been with Version 4.0, which offers four additional real types compatible with IEEE Standard 754 and usable only on an 80x87 math coprocessor; no IEEE emulation package is available. What's more. the compiler won't let you declare variables of these new types unless you specify the $N switch, explicitly stating that your target system has a coprocessor. Table 2, this page, gives the available real types.

Pointers are ordinarily bound to a type, but they can be passed as untyped parameters to a function or procedure. One unfortunate exception to the ANSI standard is that Version 4.0 doesn't support the passing of procedural and functional parameters; that is, procedure B can't accept a pointer to function A, then pass control to function A using the pointer. You couldn't do this in earlier Turbo Pascal versions either, so nothing's changed in that regard, but because the standard mandates it and because it's one of those things that makes C such a powerful systems programming language, Version 4.0 should have supported it.

Here's the Wrap

From the beginning, Turbo Pascal has been controversial on two grounds: its limitations and its disregard of formal standards. With Version 4.0, Borland has removed the limitations. As for standards, you could take the position that with more than 600,000 legal copies available--probably more than all other Pascal compilers combined--Turbo Pascal is the standard by sheer weight of numbers. Frankly, that's what I expected Borland to do inas-much as success breeds arrogance, of which Philippe Kahn has never been found wanting. Instead, though, Version 4.0 has moved much closer to the formal standard, deviating--though differently in particulars--to approximately the same extent as Microsoft, VAX, and other "purer" Pascal dialects. And that's good for everybody.

I wish Turbo Pascal 4.0 had a debugger and that it exported compiled modules for linking with other languages. But what the heck, it's got everything else, and for $99.95, it's all the compiler that even the most demanding Pascal programmer needs.

by Kent Porter

CodeView

Product: Microsoft CodeView, Version 2.1

Target: PC or PS/2 and compatibles

Requires: DOS 2.0 or later

Price: Comes with Microsoft MASM 5.0, C 4.0 or later, and FORTRAN

Vendor: Microsoft, 16011 N.E. 36th Way, P.O. Box 97017, Redmond, WA 98073 (800) 426-9400

I can remember when the hardest thing about debugging code was trying to decide whether to print the whole link map or to just jot down an item or two. Printing the whole thing could take 20 minutes or more. The other tough decision was whether or not to compile the code with listing output so that I could follow my program at the source level.

Thankfully, those days have gone. Symbolic debuggers did away with the need for the link map; source-level debuggers "knew" which source lines went with which machine instructions. But somehow, I still felt there was more a debugger could do for me--such as knowing the type as well as the address of variables, for example; or not intermixing output from the debugger with output from the program under test; or setting it to watch certain variables for me.

To address most of these issues, Microsoft created CodeView 1.0, which came bundled with Microsoft C, Version 4.0. Although memory was still a huge problem, at least the debugger knew as much as I did about the logistics of the program. Version 2.1 relieves the memory problem by making use of expanded (EMS) memory. This is by no means a perfect solution, however.

Microsoft CodeView has two main operating modes. One is purely prompt/command-oriented and is appropriate for use on MS-DOS machines that do not support one of the conventional IBM display adapters. The second is a windowing mode, usable only on MS-DOS machines with compatible display adapters. I'll discuss the windowing mode here, but nearly all Code View's power is likewise available in command mode.

CodeView is easy to use, but not at the expense of power. Most if not all of Symdeb's commands can be used in a dialog window. This scrolling window contains the customary prompt as well as output from issued commands. It even includes some history so you can go back and look at some output again.

There are several other windows that are much more interesting. First, there's the source window; in it, some portion of your source code, usually the portion being executed, is displayed. The source window has three modes--source only, assembly language only, and mixed source and assembly language. The currently executing line is in a color bar.

The remaining two windows are optional. The register window displays the current value of all the processor's registers (all 32 bits if the processor is an 80386 and you have set 386 mode in CodeView). The watch window displays the current value of arbitrary expressions, which allows you to monitor a variable or a more complicated expression .

You can set breakpoints to any given line simply by tapping F9. The desired line is displayed in high-intensity white, indicating a breakpoint. The dialog version of the breakpoint-set command has more power, allowing the setting of pass counts and commands to be executed upon breaking. F7 executes a given statement.

There are the usual two forms ofsingle-step--STEP INTO (F8) and STEP OVER (F10). STEP INTO steps into a function call being stepped, whereas STEP OVER executes until the stepped function returns. Both modes do exactly the same thing if there is no function call at the current location. Both are sensitive to the current source window mode if, in source-only mode, the single steps are source steps. In the other two modes, steps are single instructions.

One of the most useful additions to any debugger is the ability to use data breakpoints. Data breakpoints allow you to stop program execution when a particular variable, expression, or region of memory changes. Microsoft calls these trace points. Of course, you may not be interested in all changes but only in the one change that results in an erroneous value. If you can write an expression that yields zero when all is OK and non zero when the program should stop, you can use watch-points.

The main problem with data breakpoints is speed. Most processors don't implement any special mechanism for them, and as a result, a debugger must do a single step, check data breakpoints, single step, check, and so on. It's easy to see why this can be slow. But Microsoft has started to take advantage of the 80386. Trace points of limited range can be done while the processor is running at full speed on the 386 because of the processor's debug registers. Note that watch points do not take advantage of this feature, and I have no idea why not. To use this feature, you must give /r on the CodeView command line, as documented in the read me file.

I like mice, so Code View's mouse support is a big plus for me. Both F7 (go until) and Fg (set breakpoint) are implemented on the mouse buttons, so these operations are simply point and click. You can scroll both the source and dialog windows and you can move the line between them using the mouse.

One last feature is the ever-desirable CONTINUE UNTIL RETURN. If you have traced into a procedure and then wish to execute until the function returns, simply pull down the Calls menu and point to the function to which you wish to return. The source window then displays that function and the cursor is positioned such that pressing F7 executes the desired result. Note that this feature is available only in window mode, not in dialog mode.

A combination of excellent performance, richness of features, and a large installed base will probably guarantee that CodeView will remain a reference standard in debuggers for some time to come. And despite a few flaws, that's as it should be.

by Richard A. Relph

Table 1: Integer types and their characteristics.

Type               Range                       Size
-----------------------------------------------------------------------
byte               0. .255                     1
shortint           -128. .127                  1
integer            -32768. .32767              2
word               0. .65535                   2
longint            -2147483648. .2147493647    4

Table 2: Real types and their characteristics.

Type            Range                  Digits   Size
------------------------------------------------------
real            10**-38. .10**38       11       6
single          10**-38. .10**38       7        4
double          10**-38. .10**38       15       8
extended        10**-4391. .10**4391   19       10
comp            2**63. .2**63-1        8        ??
                                                18.9 digits of precision