Answers to Common Questions about QuickBASIC Version 4.00 for the IBM PC 

Summary:

The following application note was developed to provide users of
QuickBASIC Version 4.00 with answers to common questions along with
supplementary information. A copy of this application note 
can be obtained from Microsoft Product Support
Services by calling (206) 454-2030. 

This document contains the following sections:
 
  I. Answers to Common Questions about QuickBASIC Version 4.00
 II. Enhancements/Changes from Previous Versions
III. Documentation Errata for the LOF Function
 
More Information:
 
Microsoft QuickBASIC Version 4.00 for the IBM PC and Compatibles
                             12/4/87
 
Answers to Common Questions about QuickBASIC Version 4.00
 
Question
 
Am I still limited to a maximum of 64K per dynamic numeric array?
 
Response
 
No. By using the /ah switch when invoking either QuickBASIC or the
BASIC compiler, you can allocate dynamic arrays larger than 64K.
Additionally, you are no longer restricted to only using dynamic
arrays whose type are real. Huge arrays may be arrays of records,
fixed-length strings, and numeric data, and may occupy all of
available memory. The following example demonstrates how to allocate a
dynamic string-array using a user-defined type: 
 
TYPE AddressType
     Street              AS STRING * 30
     AptNum              AS INTEGER
     City                AS STRING * 20
     STATE               AS STRING * 2
     ZIP                 AS INTEGER
     Pad                 AS STRING * 8       ' record size of 64 bytes
END TYPE
 
DIM AddressBook(71680) AS AddressType        ' must compile using /ah
                                             ' switch
 
Question:
 
Is it possible to reduce the size of the .EXE files?
 
Response
 
The following is a list of methods you can use to reduce the size of
.EXE files: 
 
1. Use the /E[XEPACK] linker switch. This linker option removes
   sequences of repeated bytes and optimizes the "load-time relocation
   table." The result is that executable files linked with this option 
   may be smaller and load faster than files linked without this
   option. When you make an .EXE file from within the QuickBASIC
   Version 4.00 environment, the /E switch on the linker is on;
   therefore, files are automatically EXEPACKed. 
 
   Note: You cannot use the /EXEPACK option with the /Q option.
 
2. If you are creating a stand-alone .EXE file (i.e., using BCOM40),
   and your program does NOT use the OPEN COM statement, your program 
   will be about 4K smaller if you link with the supplied object file
   NOCOM.OBJ (found on Disk 3, or Disk 2 if you are using 3.5-inch
   disks). 

3. NOEM.OBJ is another supplied object file. It allows stand-alone
   executable files compiled with the /O option to be substantially
   smaller when run on machines equipped with a math coprocessor. For
   more information on the use of NOEM.OBJ, refer to the README.DOC
   file found on Disk 1. 
 
Question
 
QuickBASIC Version 4.00 now supports calls to routines written in
FORTRAN, C, QuickC and Pascal, as well as those written in QuickBASIC
and Assembly. Which versions of these compilers can be used to develop
mixed-language programs? 
 
Response
 
Calls can be made from QuickBASIC to routines developed with the
following compiler versions: 
 
Language            Version Supported
 
FORTRAN                  4.00
Pascal                   4.00
C                        5.00
QuickC                   1.00
Assembly                 4.00
 
Question
 
How do I go into 43-line mode in the editor and debugger?
 
Response
 
The new /H option for QuickBASIC displays the highest resolution
possible on your hardware. For example, if you have an EGA, QuickBASIC
displays 43 lines and 80 columns of text. This option is used with the
QB command, e.g. QB DEMO1.BAS /H. 
 
As with previous versions of QuickBASIC, your programs can also put
the screen into 43-line mode on an EGA-equipped machine. See the entry
for the WIDTH statement in the BASIC language reference manual for
more information. 
 
Question
 
Are QuickBASIC and its compiled programs compatible with Microsoft
Windows? 
 
Response
 
The QuickBASIC Version 4.00 compiler and its compiled programs will
only run as "Bad Applications" in Microsoft Windows. "Bad
Applications" require you to create a PIF (Program Information File)
using the Windows PIFEDIT.EXE program. When you make the .PIF file
for QuickBASIC and its compiled programs, you will need to specify
"Directly Modifies: Screen, Keyboard, COM1, COM2, and Memory".
QuickBASIC Version 4.00 programs have been successfully tested under
Microsoft Windows. 
 
The QB.PIF files provided on the Version 4.00 release disk can be
studied in PIFEDIT.EXE as a guideline for making your own PIF files
for your .EXE programs compiled in QuickBASIC. 
 
QuickBASIC Versions 3.00 and earlier have not been tested under
Microsoft Windows, and may or may not run successfully as "Bad
Applications." 
 
Question
 
How is memory allocated for static and dynamic arrays?
 
Response
 
The BASIC run-time system allocates a full 64K data segment,
regardless of array usage. In the environment, all arrays are NOT
taken out of this space, and are rounded up to the nearest paragraph
in size. Note that there is, of course, symbol-table overhead also
associated with these arrays that takes additional space. 
 
In stand-alone EXE files, static arrays are in the 64K data segment,
but have no overhead information. The size allocated is the size
dimensioned. $DYNAMIC numeric arrays and $DYNAMIC arrays of
user-defined types are not taken out of the data segment, but do have
some overhead information that is taken out of the data segment. 
 
When determining size requirements for programs, it is not enough to
consider only your program's size and its associated data. The
run-time system for stand-alone EXEs, and the QuickBASIC environment
itself, have additional memory requirements, based on what you are
attempting to do and the compile options selected. 
 
Question
 
When linking with BCOM (i.e., using /O compiler option), are all
routines from the BCOM.LIB linked in, or only those that are needed to
execute the program? Similarly, when using BRUN, is the entire file
loaded into memory or are only the needed routines loaded in? 
 
Response
 
When linking with /O, QuickBASIC searches the BCOM.LIB library for
modules containing the procedures referenced in the program. If an
object module in the library does not contain procedures referenced in
the program, it is not included in the executable file. 
 
When linking without /O, the entire run-time module (BRUN40.EXE) is
always loaded into memory prior to execution. 
 
Question
 
Now that the FIELD statement is optional, does its use have any effect
on how programs execute? Is it "better" to define records through the
TYPE...END TYPE statement versus the FIELD statement? 
 
Response
 
The FIELD statement has not been degraded in comparison to earlier
versions. However, the use of user-defined types is definitely
recommended over use of the FIELD statement. Using TYPEs is indeed
somewhat faster than the FIELD statement in some respects. It is most
certainly less complex internally, and a more powerful programming
tool. We strongly recommend its use over the FIELD statement. 
 
Question
 
When the following program is compiled, a subscript-out-of-range
message is generated, even when the switch /ah (for huge arrays) is
used. Why? 
 
DEFINT A-Z
TYPE test
  a AS DOUBLE
  b AS STRING * 288
END TYPE
max = 453
 
REM $DYNAMIC
DIM x(1 TO max)  AS test
 
Response
 
When space is allocated for huge arrays, it is done so in 64K blocks.
If a record size cannot evenly be divided into 64K, a "gap" will
appear between the allocated blocks. However, DOS will only permit one
gap to appear within any huge array. Subsequently, more than two 64K
blocks cannot be allocated when gaps occur. 
 
You can compensate for this limitation by padding each array element
to a size that can be evenly divided into 64K (i.e., 128, 512, etc.).
For the above example, this workaround would be as follows: 
 
DEFINT A-Z
TYPE test
   a   AS DOUBLE            ' 8 BYTES
   b   AS STRING * 288      ' 288 BYTES
   PAD AS STRING * 216      ' workaround: pads to a
                            ' record size of 512 bytes
END TYPE
max = 453
REM $DYNAMIC
 
DIM x(1 TO max) AS test
 
Question
 
Whenever I link a QuickBASIC Version 4.00 program with a FORTRAN
routine that contains WRITE statements, an out-of-heap-space message
is displayed at run time. 
 
Response
 
The following sequence demonstrates a workaround to this problem:
 
' QuickBASIC program CALLTEST2.BAS
'
DECLARE SUB test2()
CALL test2
END
 
 
' QuickBASIC routine NEARHEAP.BAS
' that increases heap space by 2k
'
DIM x%(2048)
COMMON SHARED /nmalloc/ x%()
 
 
C
C   FORTRAN routine TEST2.FOR
C
     subroutine test2()
     write(*,*) 'this is FORTRAN'
     pause
     end
 
1. Compile the FORTRAN subroutine as follows:
 
   fl /FPi /c test2.for
 
2. Compile NEARHEAP.BAS as follows:
 
   bc nearheap.bas;
 
3. Create the Quick library TEST2.QLB containing the FORTRAN routine
   TEST2.FOR and NEARHEAP.OBJ:
 
   link test2+nearheap /q /noe,,nul,bqlb40.lib;
 
4. Create the library file TEST2.LIB, which contains the FORTRAN
   routine and NEARHEAP.OBJ:
 
   lib test2+test2+nearheap;
 
5. At this point you can now work inside the QuickBASIC Version 4.00
   editor using the following command:
 
   qb calltest2 /l test2.qlb
 
 
   Or, you can create an EXE file as follows:
 
   qb calltest2;
   link calltest2,,,test2.lib;
 
Question
 
When using the communications port, QuickBASIC will not run with eight
data bits plus parity on the serial port. Why? 
 
Response
 
QuickBASIC defines a 10-bit data frame. The frame is as follows:
 
                        1 2  -  8 9 A
                        S DDDDDDD P S
 
Bit  1     = Start Bit  (Always)
Bits 2 - 8 = Data Bits  (Optional 7 or 8)
Bit  9     = Parity     (Optional Odd, Even, One)
Bit  A     = Stop Bit   (Optional 1 or 2)
 
The combination of the bits should always add up to ten bits. When you
try to set 1 start + 8 data + 1 parity + 1 stop, that adds up to an
11-bit data frame. 
 
Question
 
Can a program that accesses the communications port (COM1: or COM2:)
be affected by a QuickBASIC program that was run previously? 
 
Response
 
The answer is yes for Versions 1.x, 2.x, and 3.00 of QuickBASIC. If a
program leaves any of the communications port lines ON when it exits,
a program can have problems opening that communications port on any
subsequent execution. 
 
In Version 3.00, if a program exits after a "Device Timeout" on the
communications port, DTR and RTS remain ON. 
 
In Version 4.00, the DTR and RTS lines are cleared after a "Device
Timeout" error. 
 
Question
 
Is it possible to use the COM2: port without having COM1: addressed?
When COM2: is opened for I/O, a bad filename error is issued. 
 
Response
 
Yes, the hardware for COM2: can work without COM1:. QuickBASIC looks
in the BIOS data area at RS232_BASE. This area stores the addresses of
up to four serial communications ports. When you start your system,
the BIOS initialization code checks for serial ports, puts in the
addresses of any it finds, and sets the rest of the locations to zero.
When both COM1: and COM2: are present, the address of COM1: (3F8h), is
in the first word of RS232_BASE and the address of COM2: (2F8h) is in
the second word. However, when QuickBASIC is loaded, it looks at
RS232_BASE to see what serial ports are present, but it only
recognizes COM2: when its address is in the second word. 
 
There is a way to work around this. The following program patches the
second word of RS232_BASE with the address of COM2: 
 
DEF SEG = &H40
IF (PEEK(0)) + 256 * PEEK(1)) = &H2F8 THEN
   POKE 2, &HF8
   POKE 3, &H2
   PRINT "COM2 patch made"
ELSE
   PRINT "COM2 patch NOT made"
END IF
 
This program must be run before you run your QuickBASIC application
that uses COM2:. If you put this code at the beginning of your
program, it will be executed too late to do any good because
QuickBASIC checks for serial ports before it starts running your first
BASIC statement. 
 
Question
 
When I put SOUND statements at the end of the program and run the .EXE
file, the SOUND is truncated at the end. Why? 
 
Response
 
When a program ends, the BASIC run-time system is exited, which
immediately stops any SOUND whose duration exceeds the time taken to
execute any remaining statements in the program. This problem will not
occur in the editor environment since the run-time system is still
available. 
 
To allow the program enough time to complete its SOUND statements,
give the program something to do after the SOUND (a dummy loop for
example) so that the SOUND has time to finish before the program
terminates. 
 
Question
 
My assembly subroutine, which worked with my QuickBASIC Version 3.00
program, now hangs the machine without even calling the MASM routine
when linked with a QuickBASIC Version 4.00 program and run. However,
it runs correctly inside the editor when placed inside a Quick
Library. 
 
Response
 
The problem is due to the use of a label with the END directive in the
assembly routine. This syntax indicates to the linker where program
execution will start. When the linker is used to create an executable
program, it examines each .OBJ file in order to determine whether that
file has an entry point specified. The first .OBJ that specifies an
entry point is assumed by the linker to be the main program, i.e.,
where program execution is to begin. 
 
In earlier versions of the compiler, the QuickBASIC object code
contains an entry-point specifier; therefore, by simply listing your
QuickBASIC object files before the assembly files, the linker
recognizes that the QuickBASIC program is the main program. However,
in QuickBASIC Version 4.00, the entry-point information is no longer
in the object file; rather it resides in the run-time module (i.e.,
BCOM40.LIB or BRUN40.LIB). Therefore, because these files are linked
in after the QuickBASIC and Assembly object files, if the Assembly
routine specifies an entry point, the linker will incorrectly assume
that program execution is to begin in the Assembly routine. 
 
The workaround for this problem is simply to omit the entry-point
specification in your Assembly routine. 
 
The following is an example of the problem:
 
code     segment byte    public  'code'
.
.
temp     proc    far
.
.
temp     endp
 
code     ends
 
         end     temp           ; Problem here
 
The following is a workaround for this problem:
 
code     segment byte    public  'code'
.
.
temp     proc    far
.
.
temp     endp
 
code     ends
 
         end
 
Enhancements/Changes from Previous Versions
 
DOS Patching
 
Users of IBM PC-DOS Version 3.20 no longer need to patch their DOS.
This patch, which was supplied with QuickBASIC Version 3.00, was only
necessary with QuickBASIC Version 3.00 when running QB87.EXE on
machines equipped with math coprocessors AND using IBM PC-DOS Version
3.20. 
 
OPEN COM Statement
 
Three new options have been added to the OPEN COM statement (these
options are more fully described in the QuickBASIC language reference
manual): 
 
1. OP[m]  Controls how long the statement waits for the OPEN to be
          successful. 
2. RB[m]  Sets the size of the receive buffer. If omitted, the
          default value is used. The default value can be set by the
          /c option on the QuickBASIC or the BASIC compiler command
          line. 
3. TB[m]  Sets the size of the transmit buffer. If omitted, the
          default size of 128 bytes is used.
 
LOF Function
 
When used with the OPEN COM statement, the LOF function now returns
the number of bytes free in the OUTPUT buffer. In earlier versions of
QuickBASIC, this function returned the number of bytes in the input
buffer, a function that nearly duplicated that of the LOC function. 
 
Previously, the LOF function could also be used to verify the size of
the input buffer (which could be set with the /c option). The buffer
size can still be verified within a program using the following
formula: 
 
beforeopen = SETMEM(640000)     ' -> beforeopen = #bytes in far heap
                                ' setmem will not be able to allocate
                                ' 640000 bytes, rather only as much as
                                ' possible.
 
OPEN "COM1: 1200,e,7,1,RB(512),TB(512)" FOR OUTPUT AS #1
                                ' opening comm port will reduce the # of
                                ' bytes in the far heap by the sum of
                                ' bytes used by the transmitting and
                                ' receiving buffers (i.e., 1024 bytes).
 
spaceused = beforeopen - SETMEM(640000)
                                ' -> spaceused = # bytes allocated for
                                ' the two com buffers plus about 32
                                ' to compensate for the bytes needed
                                ' for paragraph alignment.
 
CALL PTR86 => VARSEG and VARPTR Commands
 
The PTR86 interrupt routine used in previous versions of QuickBASIC to
obtain the address of a large numeric-array variable is no longer
supported in QuickBASIC Version 4.00. The same information is now
available through the commands VARPTR and VARSEG. 
 
The program below demonstrates how PTR86 is used in QuickBASIC Version
3.00 and QuickBASIC Version 2.x. This example is followed by an
equivalent program using the QuickBASIC Version 4.00 statements VARSEG
and VARPTR. 
 
' QB3 and QB2.x version using CALL PTR86
'
REM $DYNAMIC
DIM buffer%(25)
 
FOR i% = 0 TO 25                        ' initialize array
     buffer%(i%) = i%
     PRINT buffer%(i%);
NEXT i%
 
PRINT
CALL PTR86(varseg%, varoff%, VARPTR(buffer%(0)))
 
DEF SEG = varseg%
 
FOR i% = 0 TO 25
     x% = PEEK(varoff% + ( 2 * i%))
     PRINT x%;
NEXT I%
 
END
 
 
=============================================
 
' QB4 version using VARSEG and VARPTR
'
REM $DYNAMIC
DIM buffer%(25)
 
FOR i% = 0 TO 25                        ' initialize array
     buffer%(i%) = i%
     PRINT buffer%(i%);
NEXT i%
 
PRINT
DEF SEG = VARSEG(buffer%(0))
 
FOR i% = 0 TO 25
     x% = PEEK(VARPTR(buffer%(i%)))
     PRINT x%;
NEXT I%
 
END
 
The following is the output from either program:
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 
CALL INT86 =>  CALL INT86OLD or CALL INTERRUPT Statement
 
QuickBASIC programs that use the CALL INT86 and INT86X interrupt
routines will need to be modified to run under QuickBASIC Version
4.00. The CALL INTERRUPT, CALL INTERRUPTX, CALL INT86OLD and CALL
INT86XOLD routines provide compatibility with older programs using
INT86 and INT86X. Like the previous routines, these new statements are
distributed in a Quick library (QB.QLB and QB.LIB) on the distribution
disks. 
 
The following program provides an example of how the CALL INT86
statement is used in QuickBASIC Version 2.x and QuickBASIC Version
3.00. Corresponding versions of the program using CALL INT86OLD and
CALL INTERRUPT follow. 
 
'
'  This QuickBASIC program will send a copy of the screen output
'  to the line printer using the INT86 routine. The DOS
'  interrupt &H05 will direct the screen output to be printed
'  to the line printer.
'
'
dim inary%(7), outary%(7)
'
for i=1 to 10
   print
   for j=1 to 10
     print "*";
   next j
next i
'
'
call int86(&h05,varptr(inary%(0)),varptr(outary%(0)))
'
end
=======================================================
 
' Same program converted to use the QB4 statement CALL INT86OLD
 
DIM inary%(7), outary%(7)
 
FOR i = 1 TO 10
    FOR j = 1 TO 10
        PRINT "*";
    NEXT j
    PRINT
NEXT i
 
CALL int86old(&H05, inary%(), outary%())           'screen dump
'
END
 
 
======================================================
 
' QB4 version using the CALL INTERRUPT statement
 
TYPE RegType
    AX AS INTEGER
    BX AS INTEGER
    CX AS INTEGER
    DX AS INTEGER
    BP AS INTEGER
    SI AS INTEGER
    DI AS INTEGER
    FLAGS AS INTEGER
END TYPE
 
DIM inary AS RegType
DIM outary AS RegType
 
CLS
FOR i = 1 TO 10
    FOR j = 1 TO 10
        PRINT "*";
    NEXT j
    PRINT
NEXT i
 
CALL interrupt(&H05, inary, outary)           'screen dump
'
END
 
Quick Libraries
 
Quick Libraries are analogous to the User Libraries created with
QuickBASIC Versions 2.00, 2.01, and 3.00. Like User Libraries, a Quick
Library is composed of compiled or assembled modules. These modules
can then be CALLed from QuickBASIC programs during an editing session
within the QuickBASIC Version 4.00 editor. 
 
However, unlike User Libraries, a Quick Library can only be used
within an editing session; Quick Libraries are not used in the
creation or running of an .EXE file. To create an executable program,
the LIB.EXE utility program must be used to create a .LIB file that is
composed of the same .OBJ files contained in the Quick Library. This
library file can then be linked to a compiled QuickBASIC program that
CALLs the procedures in the .LIB file. 
 
Another new characteristic of Quick Libraries is their "granularity."
This feature implies that when linked to a CALLing QuickBASIC module,
only those modules in that Quick Library that are actually called will
be linked into the executable program. Therefore, in order to fully
benefit from this feature, each .OBJ file linked into a Quick Library
should contain either only one procedure (i.e., a subprogram or a
function) or those procedures that will always be called together. 
 
This granular concept can be illustrated using the following
QuickBASIC files: 
 
'MAIN.BAS - main module that calls the subprogram "a"
CALL a
END
 
 
'A.BAS - separately compiled module containing the
'        subprogram a that is CALLed from MAIN.BAS
SUB a
     PRINT "in sub a"
END SUB
 
 
'B.BAS - separately compiled module containing the
'        subprogram b that is never CALLed.
SUB b
     PRINT "in sub b"
END SUB
 
 
'AB.BAS - separately compiled module containing both
'         subprograms a and b.
SUB a
     PRINT "in sub a"
END SUB
 
SUB b
     PRINT "in sub b"
END SUB
 
 
First, each of the files is compiled as follows:
 
MAIN.BAS -> MAIN.OBJ
A.BAS    -> A.OBJ
B.BAS    -> B.OBJ
AB.BAS   -> AB.OBJ
 
Next, two Quick Libraries and two corresponding library files are
created. 
 
The first one, A.QLB, combines the object files A.OBJ and B.OBJ as
follows: 
 
A.OBJ \
       ==> A.QLB and A.LIB
B.OBJ /
 
The second Quick Library will be created from the file AB.OBJ as
follows: 
 
AB.OBJ => AB.QLB and AB.LIB
 
Finally, using MAIN.OBJ, two executable programs are created as
follows: 
 
link MAIN.OBJ, MAINA.EXE, A.LIB;
link MAIN.OBJ, MAINAB.EXE, AB.LIB;
 
The resulting .EXE files will execute identically; however, the
version created using AB.LIB (i.e., MAINAB.EXE) will be larger because
even though only one subprogram is called from MAIN.BAS, both SUB a
and SUB b will be linked in because they are both contained in the
same .OBJ file. 
 
Creating Quick Libraries inside the QuickBASIC Version 4.00
Environment 
 
There are now two methods of creating Quick Libraries. The first, and
easiest method, is to create them within the QuickBASIC Version 4.00
editor by selecting the Make Lib option from the Run menu. To create a
Quick Library in this manner, perform the following steps: 
 
1. Using the Load option from the File menu, Load into the editor all
   the BASIC files you want to be included in the Quick Library. 
 
2. Select the Make Lib option from the Run menu. Once this option is
   selected, the following events automatically occur: 
 
   a. BC.EXE is invoked and each currently loaded BASIC module is
      compiled and its object file saved to disk. 

   b. The LINK.EXE utility is invoked with the /Q[UICKLIB] switch to
      combine all the previously compiled object files plus the
      supplied file BQLB40.LIB (which contains the support routines
      need to create a Quick Library) into a Quick Library. The Quick
      Library will by default have as its name the base name given by
      the user plus the extension .QLB. This .QLB file is then written
      to disk. 
 
   c. The LIB.EXE utility is invoked to create a .LIB file from the
      object files previously created with the BASIC compiler. This
      library file must be present if you intend to create an EXE
      (i.e., executable) program that uses these routines. 

         NOTE: This method for creating a Quick Library can only be
      used when placing QuickBASIC routines in your library. When
      non-BASIC routines are included (i.e., those written in
      Assembly, FORTRAN, Pascal, or C), the Quick Library must be 
      created from the DOS command line. The following section
      describes this method. 
 
Creating Quick Libraries from the DOS Command Line
 
Previous versions of QuickBASIC allowed you to create only User
Libraries from the DOS command line. This was accomplished through the
use of the BUILDLIB.EXE utility. With QuickBASIC Version 4.00, the
BUILDLIB.EXE file is no longer provided; instead, Quick Libraries are
created using the command-line /Q[UICKLIB] option with the linker
(LINK.EXE). 
 
For example, the files A.BAS and B.BAS described above can be made
into a Quick Library and parallel .LIB file using the following DOS
commands: 
 
BC A.BAS;                                    => A.OBJ
BC B.BAS;                                    => B.OBJ
LINK /Q A.OBJ B.OBJ,AB.QLB,,BQLB40.LIB;      => AB.QLB
LIB AB.LIB+A.OBJ+B.OBJ;                      => AB.LIB
 
Run-Time Memory Maps
 
This section contains illustrations of three different run-time memory
maps. The following figure shows the run-time memory map as it appears
when the run-time module BRUN40.EXE is used with the separate
compilation method: 
 
0000:0000----------> ______________
                    |    MS-DOS    |  MS-DOS Operating System
                    |              |
Low Memory--------->|   User Code  |  User program separately linked
                    |              |     with BRUN40.LIB
User data---------->|              |
Start DS:0          |    _DATA     |  QuickBASIC run-time data
                    |    CONST     |     areas, used during user code
                    |    _BSS      |     execution
                    |              |
                    |              |
                    |Quick Library |  Quick library data loaded during
                    |    data      |     startup (optional)
                    |              |
                    | Blank COMMON |  Quick library and user
                    |              |     definitions
Up to               |   BC_CONST   |
64k bytes           |              |  User program constants
                    |   BC_DATA    |
                    |              |  User program variables
                    |    Named     |
                    |    COMMON    |  Named COMMON areas
                    |              |
                    |  User Stack  |  Preset to 512 bytes
                    | String heap  |
User data---------->|Run-time heap |
End DS:xxxx         |              |  This area contains less
                    |              |     frequently used items, such
                    |   FAR heap   |     as large numeric arrays, the
                    |              |     user environment table, and
                    |              |     error-information tables for
                    |              |     debugging mode.
                    |Communication |
                    |   buffers    |  User specified size
                    |  BRUN40.EXE  |  Separately loaded run-time
                    |              |     code
 
   Figure 1 (above) The BRUN40.EXE Run-Time Module Environment
 
The following figure shows the run-time memory map when the run-time
library BCOM40.LIB is used: 
 
0000:0000----------> ______________
                    |    MS-DOS    |  MS-DOS Operating System
                    |              |
Low Memory--------->|   User Code  |  User codelinked
                    |              |     with BCOM40.LIB
                    |Run-time code |  Run-time code linked into
                    |              |     file
                    |    Library   |  .LIB Library code linked
                    |    file      |     into file
User data---------->|              |
Start DS:0          |    _DATA     |  QuickBASIC run-time data
                    |    CONST     |     areas, used during user
                    |    _BSS      |     code execution
                    |              |
                    |    Library   |  library data loaded during
                    |    data      |     startup (optional)
                    |              |
                    | Blank COMMON |  library and user
                    |              |     definitions
Up to               |   BC_CONST   |
64k bytes           |              |  User program constants
                    |   BC_DATA    |
                    |              |  User program variables
                    |    Named     |
                    |    COMMON    |  Named COMMON areas
                    |              |
                    |  User Stack  |  Preset to 512 bytes
                    | String heap  |
User data---------->|Run-time heap |  File buffers,dynamic arrays, etc
End DS:xxxx         |              |  This area contains less
                    |              |     frequently used items, such
                    |   FAR heap   |     as large numeric arrays, the
                    |              |     user environment table, and
                    |              |     error-information tables for
                    |              |     debugging mode.
                    |Communication |
                    |   buffers    |  User specified size
 
   Figure 2 (above) The BCOM40.LIB Run-Time Library Environment
 
The following figure shows the run-time memory map when the QuickBASIC
program is executed within the QuickBASIC Version 4.00 environment: 
 
0000:0000----------> ______________
                    |    MS-DOS    |  MS-DOS Operating System
                    |              |
Low Memory--------->|  QuickBASIC  |  QB.EXE
                    |    Code      |
                    |              |
User data---------->|  QB static   |
Start DS:0          |    data      |
                    |              |
                    |  Quick Lib   |
                    |    data      |
                    |              |
                    |  User Stack  |
                    | User Program |
                    |    data      |
                    |              |
                    | String heap  |
User data---------->|Run-time heap |  File buffers,dynamic arrays, etc
End DS:xxxx         |              |
                    |              |  This area contains items, such
                    |   FAR heap   |     as large/huge arrays and user
                    |              |     code
                    |              |
                    |              |
                    |Communication |
                    |   buffers    |  User specified size
                    |    Quick     |
                    |   Library    |
 
   Figure 3 (above) The Memory Map for the QuickBASIC Version 4.00
                        Environment 

Documentation Errata for the LOF Function
 
Changes for Programming in BASIC: Selected Topics
 
141   In the "Information Returned" column for the LOF function,
      the description should read: "The amount of space remaining
      (in bytes) in the output buffer." (Note: this is a change
      from the behavior of LOF in previous versions of QuickBASIC).

END OF ARTICLE.
