Many thanks to Bela Lubkin, (CompuServe 76703,3015) for
masterminding this idea, and Kim Kokkonen (CompuServe 72457,2131)
for helping debug it. If you have any questions or comments,
regarding the following changes, please feel free to contact
Randy Forgaard, on the Borland SIG or via EasyPlex on CompuServe.
Due to a limitation of DOS, Turbo Pascal, version 3.0 only allows up to 15 files at a time to be open. The following method allows you to have up to 96 files open simultaneously under DOS 2.0 or 2.1, or 252 files open simultaneously under DOS 3.0 or greater.
This file is for use with the Turbo Access portion of the MS-DOS Turbo Database Toolbox, version 1.01 or greater, together with MS-DOS or PC-DOS Turbo Pascal, 3.01A. If you have 1.00 of Turbo Database Toolbox contact Borland International for a handout that will update the Turbo Database Toolbox to version 1.01.
This technique is totally internal to the Toolbox. After making the indicated Toolbox changes, you will not have to change the source code of programs that use the Toolbox (except to add a compiler directive and an include file as indicated below).
For more discussion of Handle Tables and the implementation of DOS redirection, please see Stan Mitchell, "Command Line Redirection," PC Tech Journal, January 1986, Page 44.
MODIFYING ACCESS.BOX:
Check the comment header at the beginning of the file to ensure you are using the correct ACCESS.BOX. Please BE SURE to make all modifications on a backup copy of the ACCESS.BOX file.
NOTE: If you have modified ACCESS.BOX per FLUSH.ACC, make the
following additional changes:
6. In FlushFile:
----------------
Add the following line immediately BEFORE the "Seek(...);"
statement:
UnExtend(DatF.F);
Add the following line immediately after the FIRST "MsDos(...);"
statement:
ReExtend(DatF.F);
7. In FlushIndex:
-----------------
Add the following line immediately BEFORE the "Seek(...);"
statement:
UnExtend(IdxF.DataF.F);
Add the following line immediately after the "BlockWrite(..);"
statement:
ReExtend(IdxF.DataF.F);
and make sure that it is on your main program disk when you run
your program.
{$F252}
const
LastHandle = 19; {Highest-numbered handle}
UnusedHandle = $FF; {DcbTable entry that denotes an unused handle}
type
HandleTable = array[0..LastHandle] of Byte;
HandleTablePtr = ^HandleTable;
const
TablePtrOk: Boolean = false; {"True" iff TablePtr is initialized}
var
TablePtr: HandleTablePtr; {Points to Handle Table for this process}
SaveDcb: Byte; {Temporary variable for a DCB number during a
function call}
{Internal routine. Returns the address of the Handle Table,
writeln('This program only works with DOS 2.0 and higher');
Halt
end;
2: regs.AH := $51; {Undocumented, but works with}
{DOS 2.0/2.1 (and 3.X)}
else regs.AH := $62 {Works with DOS 3.0 and higher}
end;
MsDos(regs); {Get PSP address}
GetHandleTableAddr := Ptr(regs.BX, $18)
end {GetHandleTableAddr};
{Causes "f" to become an "extended" file; i.e., to remain open without using up any file handles. The parameter "f" must be any Turbo Pascal file; e.g., a File, a File of Byte, a File of Foo, Text, etc. This routine should be called immediately after the Reset or Rewrite initially used to open "f." After "f" has become extended, it cannot be used by Turbo's built-in file routines until it has been unextended using UnExtend.}
procedure OpenExtend (var f);
var
handle: Integer absolute f;
begin
if not TablePtrOk then
begin
TablePtr := GetHandleTableAddr;
TablePtrOk := true
end;
SaveDcb := TablePtr^[handle];
TablePtr^[handle] := UnusedHandle;
handle := SaveDcb
end {OpenExtend};
{Unextends the extended file "f," so that it can be used by any of Turbo Pascal's built-in file routines. Note that "f" must have been converted to an extended file by OpenExtend before invoking UnExtend(f). After calling UnExtend, and then invoking the Turbo Pascal file function on "f," ReExtend(f) should be invoked immediately to re-extend "f" and restore the DOS file state information.}
procedure UnExtend (var f);
var
handle: Integer absolute f;
begin
SaveDcb := TablePtr^[LastHandle];
TablePtr^[LastHandle] := Lo(handle);
handle := LastHandle
end {UnExtend};
{Re-extends "f" into an extended file. Note that "f" must have been converted to an extended file by OpenExtend, and then unextended using UnExtend, before "f" can be re-extended using ReExtend. ReExtend(f) should be invoked immediately after any normal Turbo Pascal file function call using "f."}
procedure ReExtend (var f);
var
handle: Integer absolute f;
begin
handle := TablePtr^[LastHandle];
TablePtr^[LastHandle] := SaveDcb
end {ReExtend};
TO USE THIS TECHNIQUE:
Make the above modifications. Then --
At the top of your program, prior to the "program" statement, put
the compiler directive {$F252}. (You may use a value smaller
than 252, if you wish. Under DOS 2.0/2.1, values above 96 have
no additional benefit. Each larger value for the {$F} directive
uses 2 additional bytes in the program's global data space.) The value you specify for the {$F} directive is the maximum number of files you will be able to have open at the same time in your program.
Edit your CONFIG.SYS file (see the DOS manual for details), so that it includes a line that says "FILES=XXX". XXX should be a number that is 3 greater than the value you specified for the {$F} directive (larger values will provide no additional benefit, with respect to your individual program), and should not exceed 99 (for DOS 2.0/2.1) or 255 (for DOS 3.0 and higher). Under any version of DOS, the minimum allowable value for XXX is 8. Then, reboot your computer so that the FILES=XXX parameter takes hold.