Previous | Table of Contents | Next |
This section describes many of the more advanced programming options available in Turbo Pascal. Those options are creating overlay files, using object (OBJ) files, using assembler and inline statements, and calling software interrupt procedures.
5.2.12.1. Overlay Files
The overlay unit exists to enable copying of code in large applications to memory or disk. The complete construction of an overlaid application creates an EXE file as well as an overlay file. Both are required for the executable to run. The first set of statements to note is the {$O+} in the unit. This compiler directive gives permission in the unit for it to be overlaid. Note that the default is $O-. The CRT, Overlay, and System units cannot be overlaid. Also, it would be good to test self-written units for their ability to be overlaid.
The next thing to observe is the use of the {$O <TPU name>} in the main program. It is a requirement that all units to be overlaid are listed. After that, note the use of the procedures Ovrinit, OvrInitEMS, and the variable OvrResult. OvrResult is the variable that returns status codes of the other two procedures, giving indication of specific problems. OvrInit initializes the automatic overlay system, with the overlay name created (note that it is always <sourcename>.OVR when compiled, although it can be renamed to work as long as the correct filename is in the procedure parameter).
If the call to OvrInit is successful, then, optionally, a call to OvrInitEMS can be made. This procedure, if successful, allows paging of the overlay to Expanded Memory Specification (EMS) memory.
Listing 5.46 and Listing 5.47 show an example of assembling an overlaid application. Generally, because the size of an application that should be overlaid is large, this example is a ludicrous one, yet good to show such a situation. Also, complete error-checking statements have been left out but may be found in the manuals or online help.
Listing 5.46. A sample unit for an overlaid application.
{$O+} unit fig46; { note, the identifier must match the name of the file } interface function power(x:real; y: integer):real; implementation function power(x:real; y: integer):real; { exactly as above } var i: integer; result: real; begin result := 1; for i := 1 to y do result := result * x; power := result; end; end.
Listing 5.47. A sample base program for an overlaid application.
program fig47; uses fig46, overlay; {if more than 1 unit put commas between each id} var i: byte; {$O FIG46.TPU } { list units to be overlaid } begin OvrInit(FIG47.OVR); if OvrResult <> 0 then begin { note specific reasons can be stated } writeln(Error loading overlay!); halt(100); end else begin OvrInitEMS; { if overlay loadable, then try to load in EMS } if OvrResult <> 0 then writeln(#254, Not loaded in EMS for some reason.) else writeln(#254, Overlay loaded in EMS); end; writeln; for i := 1 to 10 do writeln(i, squared is , power(i,2):0:2); end.
Additionally, an overlay can be appended to the executable by use of the copy /B dos command. Then the executable name must be specified in the OvrInit procedure.
5.2.12.2. Using OBJ Files
OBJ files, which contain procedures or functions, may be used in Turbo Pascal. They should be compiled in the standard Pascal style (far, pascal). The $L variable is used to link in the OBJ file, and then the procedure or function must be restated as an external function, with types matching that in the object. Nothing may be used that is not compiled in the far pascal mode (see Listing 5.48).
Listing 5.48. Linking in an object file.
{source for OBJ file must appear this way, no things linked in not compiled far, pascal } int far pascal writeaverage(int a, int b, int c) { int temp; temp = a + b + c; return(temp / 3); } Linked in program: program fig48; {$F+} {$L FIG48.OBJ} function writeaverage(a,b,c: integer):integer;external; begin write(The average of 1,3, and 2 (rounded to nearest whole 1umber) ); writeln(is , writeaverage(1,3,2)); end.
5.2.12.3. Assembler and Inline Statements
Assembler and inline machine code are easy to implement in Turbo Pascal. You can include standard Intel assembler syntax code by enclosing it in an asm..end block. Inline statements can be included by using the inline() statement in a manner such as this: inline($9C/$42);. Do not try this example, as I made up the statement.
5.2.12.4. Software Interrupt Procedures
This section describes calling a software interrupt procedure using standard Pascal structures. The process is much like assembler, though slightly different. The predefined type registers is used in DOS. This is a record type that can be used as a set to call the interrupt procedure, with each assembler variable accessible (for example, regs.ax). After the registers type is set, then the procedure Intr() or MsDos() may be called. The intr procedure takes an interrupt value and then a registers set. MsDos takes only a register set because it is a procedure that calls Intr using interrupt $21, the common MS-DOS interrupt.
The example shown in Listing 5.49 is a little program that returns the cluster size of the current drive.
Listing 5.49. An example of an interrupt call.
program fig49; uses dos; function getclustersize(drive: byte): Word; var register: registers; begin register.ax := $3600; register.cx := 0; register.dx := drive; Intr($21, register); getclustersize := register.ax * register.cx; end; begin writeln(Cluster size of current drive is: , getclustersize(0)); end.
Previous | Table of Contents | Next |