New items added 03/02/90 to 08/23/90

Part 1
  PRINT TAB(x) and PRINT USING QB4.5
  SWAP of single precision array elements with BC7.
  RUN using far strings in a runtime program with BC7.1
Part 2
  OPEN QB4.x BC7
Part 3
  BC7 Type coercion from floating point to integer (revised workaround)
-------------------------------------------------------------------------

This file contains information about bugs, quirks, and general points
of interest to programmers working with compiled BASIC. It is divided
into four parts:

  Part 1 - Description of bugs, quirks, etc.
  Part 2 - General points of interest
  Part 3 - Sample programs
  Part 4 - Video adapters compatible with QB 4.50

If you want to find one of the above quickly, use your text editor to
search for the text shown above. i.e., Search for "Part 1 -".

As of 12/3/88, all new or changed entries will be marked with the date
that the information as added or changed. The date will appear in the
entry in the format (yy/mm/dd).

As of 2/8/89, all references to problems with QB4.00 and QB4.00a have
been removed from this file. It is presumed that all QB programmers
have upgraded either to QB4.50 or QB4.00b. If you are still using
QB4.00 or 4.00a, call Microsoft at 206-454-2030 and ask for a free
upgrade to 4.00b. If you are using BASCOM 6, there is a similar upgrade
available to BASCOM 6.00b.

This file is maintained by Mark Novisoff of MicroHelp, Inc. Much of the
information was contributed by members of MicroHelp's BASIC Users Group,
users of the MSSYS forum on Compuserve and users of Mach 2, Stay-Res,
The MicroHelp Toolbox and the QB/Pro Professional series.

If you have additional information that should be added, please send it
to:
     Mark Novisoff
     MicroHelp, Inc.
     4636 Huntridge Drive
     Roswell GA 30075
     Compuserve ID 73047,3706 in MSSYS (Microsoft Systems Forum)
     
If possible, please include a *small* sample program that will demonstrate
the problem and cause it to happen whenever the program is run.     

-------------------------------------------------------------------------
Part 1 - Description of bugs, quirks, etc.
-------------------------------------------------------------------------

Note:   QB 4 under "Compilers" refers QB4.00b and 4.50.
        
	` Next to a QB 4 entry indicates that the problem has been
        fixed in QB 4.50 and/or the accompanying BC program.
	
	* Next to an entry indicates that the problem has been
        fixed in QBX and/or the accompanying BC 7.0 program.
	
	@ Next to an entry indicates that the problem has been
	fixed in QBX/BC7.1.
	

Command/Error  Compilers       Description
-------------- --------------- --------------------------------------------
$INCLUDE       All             If the last line of your $INLUDE file does
                               not have a carriage return/line feed pair,
			       spurious errors can occur!
$INCLUDE       QB 4            If you have a DEFINT statement in an include
                               file and you wish to use it within subprograms/
			       functions in a module, you must $INCLUDE it
			       within each sub/function structure. If you
			       simply include it in the mainline code, the
			       DEFINT statement is not recognized. However,
			       if you have a statement DEFINT in your mainline
			       code (as opposed to $INCLUDE), it will work ok.
BLOAD          All             When running on an XT with SMARTDRV.SYS, you
                               may find that the BLOAD will display only the
			       first two screen lines. If so, removing 
			       SMARTDRV.SYS will solve the problem. (89/12/22)
BLOAD          All             In order to BLOAD a file, the file must have
                               been previously BSAVEd so that the 7 byte
			       "header" is present. Although it may be
			       possible to BLOAD files that were not saved
			       with this header, it is dangerous because
			       BASIC presumes that the header is there and
			       will not load the first 7 bytes into memory.
			       (89/03/31)
CALL (asm)     QB 4*           If you pass a static string array as a 
                               parameter to a subprogram, and the string
			       array represents FIELDed data (as in a
			       random file), AND you call an assembly
			       subroutine that displays the data, your
			       position in the file can be wiped out!
			       See sample program #22. The fix is to place
			       the string array in a COMMON SHARED statement
			       and remove it from the parameter list.
			       
			       Added (88/12/19). Even if the string array
			       is NOT a FIELDed array, the data can become
			       corrupt. The new solution is to move all
			       CALL or CALLS statements that have string
			       arrays as parameters to the MAIN program
			       and remove them from SUBs.
CALL           QB 4            If you want to pass a single element from a
                               string array to a subprogram, be sure to put
			       an extra pair of parentheses around the
			       variable name in the parameter list. For 
			       example, you may have a problem with:
			          CALL MySub(A,B,C$(3),D)
			       However, the following should work:
			          CALL MySub((A,B,(C$(3)),D)
CALL (asm)     QB 4+/BC6+      Effective with QB 4, assembly
                               language subroutines must preserve
                               the SI and DI registers and make
                               sure the direction flag is cleared
                               before returning to BASIC.
			       In addition, you must not have a label name
			       after the END statement in your assembler code.
CALL INIT      QB 2-3          Do not name a precompiled subprogram "INIT".
                               If you do, the compiler will go into never-
			       never land when your user library is loaded.
CALL vs GOSUB  All             If you have many calls to the same
                               asm routine or subprogram, you'll
                               use less memory if you set
                               variables and GOSUB to a routine
                               that performs the CALL instead of
                               having the CALL "in line". CALL is
                               much faster using variables than
                               using "literals".
CALLS          QB 4*           If you are passing string arrays to an
                               assembler subroutine, make sure that
			       $Static is in effect (not $Dynamic) when
			       you dimension your array. If
			       you do not, the data are not pushed onto
			       the stack correctly by BC. This affects
			       the use of MhBasStringSort in Mach 2.
CALLS          QB 4*           When CALLS (note the "S") is used and you
                               compile with "/D" (debug), the segment of
			       of a string element descriptor does not get
			       passed on the stack. In other words, if you
			       have an assembly language subroutine that
			       uses CALLS, you should not compile with "/d".
CHAIN          QB4/BC6*        CHAINing from a small .EXE to a large .EXE
                               can cause unpredictable problems. This has
			       been corrected in QB 4.50. (89/07/29)
CHAIN          BC6.0x*         If you are using extended runtime libraries,
                               there are known problems with CHAIN. This
			       includes problems in COMMON SHARED data.
			       (89/07/29)
CHAIN          BC6.0x BC7.0    Contrary to the docs, the stack size is *not*
                               preserved across a CHAIN. The workaround is
			       to use the /ST:xxxx switch when LINKing your
			       programs. (89/07/29)			       			       
CHAIN          QB 4, QB 3 &    CHAIN and RUN will work correctly in DOS 2.1
               BASCOM 6        when you compile with the BRUN library. They
			       will not work correctly on the second CHAIN
			       or run attempt if you compile with
			       the BCOM library (/O). You will get one of
			       the following errors: Out of memory, EXE
			       failure, or Error R6005. (89/04/24)
CINT           QB 4/QBX        If the number you want to convert is exactly
                               halfway between two integers (i.e., .5), the
			       rounding is done incorrectly when the number
			       that would normally be the result is an odd
			       number. See example program #30. (89/01/03)
			       It turns out that this works exactly as
			       Microsoft designed it - for statisticians.
			       If the whole portion of the number is odd,
			       the number is rounded up. If the whole portion
			       is even, the number is rounded down. (89/11/03)
CIRCLE         QB 4/QBX        The start and end angles must be
                               LESS than 2*pi. Previously they could
			       be less than or equal to.
CLEAR          QB 4/QBX        If you use SETMEM to free up memory for
                               use by other routines or modules, the CLEAR
			       statement does not force the compiler to give
			       up that memory. In other words, you must
			       explicitly do a SETMEM(640*1024), or 
			       other large number. (Also see RUN.)
			       Added 89/02/08: If you have an assembler
			       routine that has allocated memory from
			       the pool created by SETMEM (Mach 2's huge
			       string arrays, for example), using
			       SETMEM(640*1024) will still not release
			       the memory. That's because the underlying
			       program has may have done its own allocation
			       of memory via DOS. In this case, you must
			       force the assembler routine to free up
			       the memory. In the case of Mach 2's huge
			       string arrays, this is done by telling
			       Mach 2 to release the memory.
CLEAR,,Size    QB 3,4/QBX      If you receive an out of stack
                               space message. The stack size is
                               reset between CHAIN'ing but if
                               you CHAIN back to your original
                               program, be sure to skip the CLEAR
                               instruction.
			       Added 89/02/08: This is very important
			       in QB4 if you have recursive subprograms
			       and/or functions. "Recursive" means that
			       the procedure can be invoked from inside
			       the procedure.
COMMON and     QB 2-4/QBX      All statements that use COMMON or variations
  COMMON SHARED                thereon with CHAIN must use parameter lists
                               that match exactly. Best done with $INCLUDE.
COMMON with TYPE
               QB 4/QBX        The TYPE statement must appear before
	                       the COMMON statement and must appear in
			       all programs that use it. The COMMON
			       statement must contain "AS". See sample
			       program #1 at the end of this file.
Compile to EXE QB 4`*          QB issues an unusual LINK command in the
                               form of:
			         LINK Prog+YourLib.Lib;
			       This causes LINK to bring the entire
			       library into your program! The solution is
			       to exit QB, and run BC and LINK yourself.
			       Note also that the LIB environment variable
			       is not used to search for libraries in this
			       context, since the library name is in
			       the object module field.
CONST          QB 4*           Must be included in all program modules
                               that use the constant. Place in the file
			       at the top, rather than inside SUB's.
DATA           BC4.00b/6.00b*  See READ
DATA           QB 4/QBX        When a DATA statement is encountered inside
                               a SUB...END SUB structure, QB moves it
			       into the "mainline" portion of the code when
			       you are in the environment. 
DECLARE        QB 4/QBX        QB4 allows you to use a procedure name as a
                               label. See example program #32. (89/02/10)
DEFINT         QB 4            See $INCLUDE.
DEF FN         All             These functions cause temporary strings
                               to be held in memory. See example program #36.
			       (89/10/10)
DEF FN         All             Functions are local to the module
                               in which the DEF FN appears. Use
                               QB 4's FUNCTION..END FUNCTION for
                               global functions.
Device Unavailable (QB4+)      This error has been reported, especially when
                               using a fast machine (such as a 386), even
			       though the device is present. The problem 
			       appears to be a matter of timing. The solution
			       is to use error trapping and if "Device
			       Unavailable" occurs, retry the OPEN statement
			       three or more times. (90/01/19)
DIM            QB 3            See sample program #4. QB3 apparently has
                               a limit of 123 dynamic arrays.
DIM            QB 4/QBX        Any array that is DIMmed inside of a subprogram
                               that does not have the STATIC keyword is a
			       DYNAMIC array.			       
DIM            QB 4/QBX        In order to take advantage of the /AH switch
                               with TYPE..END TYPE records, the record
			       length must be a power of 2 (4,8,16,32, etc.)
DIM            QB 4/QBX        Static numeric arrays are stored on the
                               "heap" when you are inside the QB
			       environment. BC programs store them in the
			       default DS.
DIM (TYPE)     QB 4/QBX        See sample program #1 for dimensioning
                               arrays of TYPE'd variables.
Division       All             Using integer division "\" when an
                               integer result is desired is much
                               faster than normal division "/".
DRAW           QB 2-4          Does not respect the boundaries designated
                               by WINDOW.
Duplicate Definition
               QB 4            If you receive an otherwise unjustified
	                       "Duplicate definition" error, check to see
			       if your program has variables called
			       F$ or F%. When programs reach an undefined
			       "critical mass" (in terms of size), variables
			       using those names will cause the error. The
			       solution is to find and replace all occurrences
			       of those names with other names. (88/12/03)
			       Added 89/02/08: These variable names can
			       also cause "FUNCTION not defined" errors.
ENVIRON        QB 2-4/QBX      If you attempt to create a new environment
                               variable inside a program, you are likely
			       to get an "out of memory" error, because the
			       amount of environment space available when
			       your program runs is very small. To get around
			       this problem, create a good sized dummy
			       variable in your AUTOEXEC.BAT, then inside your
			       program, eliminate it before attempting to
			       setup new variables. Eliminate the variable
			       by using the semicolon:  ENVIRON "DUMMY=;".
Error R6005                    See CHAIN (QB 4) (89/04/24)
EXEC Failure                   See CHAIN (QB 4) (89/04/24)
Expression Too
  Complex         QB 4.50/BC7  QB will generate this error if you try to
                               concatenate more than 19 expressions. BC will
			       do the same, but it may point to the wrong
			       line. Specifically, if the BC4.5 compiler
			       gives you this error, check the line *above*
			       the indicated line. You may even get this
			       error when the offending line has been REMmed.
			       (89/07/29)
			       This problem has been fixed in QBX, but still
			       exists in BC 7.0.
Far heap corrupt  QB 4         When working in the environment, this error
                               can occur when you are *saving* a file that
			       uses several user-defined types and arrays
			       in COMMON. (89/03/31)
/FPA           BASCOM 6/7      If you use VAL on a string "E9999" (or 
                               a similar string with a leading "E")
			       and you compile with /FPA, you'll get an
			       overflow error. Compiling without /FPA
			       yields a VAL of zero. (89/03/31)
/FPA           BASCOM 6/7      If you use the /FPA switch (alternate
                               floating point math library) when compiling
			       one or more modules, you must use the
			       same switch in ALL modules in the same
			       program.
FIELD          QB 4            We've had a report that if you use array
                               elements for FIELD'ing a Btrieve file, and
			       you don't DIM the string array (i.e., you
			       default to 10 elements) that you can get
			       string space corrupt errors. The solution
			       is always to DIM the arrays.
File not found All             See KILL (Network).
FILES          QB 3            There is a bug in the QB3-8087 compiler that
                               causes FILES not to work correctly.
Fixup Overflow BASCOM 6        If you include the Microsoft mouse object
                               module (MOUSE.OBJ) in an extended runtime
			       library, you will get a fixup overflow error.
			       There are two solutions: Put MOUSE.OBJ in
			       your program instead of the ERL, or use an
			       alternate set of mouse routines, such as those
			       in MicroHelp's QB/Pro Volume 4. (89/03/31)
FOR/NEXT       QB 4/BC7        If you use an integer for a loop counter,
                               and the top of the loop is 32767 (when
			       STEP is positive) or the bottom of the
			       loop is -32768 (when STEP is negative),
			       you'll get an overflow when inside the QB
			       environment or when compiled with BC using
			       "/d". With BC,if you don't use "/d", the loop 
			       does not stop at the top/bottom - it wraps 
			       around and executes your loop indefinitely.
FRE(-2)        All             Fre(-2) is unreliable in all versions
                               of QuickBASIC 2-4. See sample program #26.
			       The BC 7.0 documentation explains this.
			       (89/11/03)
FUNCTION       QB 4            Provides global functions for all
                               modules in a program. All that is
                               needed is a DECLARE statement in
                               any module that needs to use the
                               function. In addition, this type
                               of function can be recursive. See DEF FN.
FUNCTION       QB 4/QBX/BC7    Cannot be used in $INCLUDE files.
GOTO           QB 4`           See sample program #17.
HEX$           QB 4/QBX/BC7    Be careful when using with non-integer
                               values. For example, the output from
			       the two lines shown is "FFFF8002".
			         E&=&H8002
			         PRINT HEX$(E&)
IF..THEN..ELSE QB 3            More than two nestings for ELSE on a single
                               line will not compile properly.
IF..THEN..ELSE QB 4 `          See Sample program #9.
INPUT          QB 4 `          Using INPUT directly to an array element that
                               should generate a "subscript out of range"
			       error causes a hard crash. LINE INPUT
			       generates the error just fine. Note that
			       this error occurs only inside the environment.
			       See Sample program #10.
INSTR          BC 4.x          See Sample Program #37. (89/10/12)
INT            QB 4/QBX/BC7    See Sample Program #29. (88/12/19)
Internal Error QB 4`           More problems with long integers. See sample
  in BC                        program #25. 
KILL (Network) All             If you get a "file not found" error when
                               attempting to KILL a file on a network drive,
			       and you know the file exists, the problem is
			       most likely due to the user not having
			       "delete" rights in the network. In this case,
			       the network will issue an "access denied" 
			       error, which BASIC will translate to
			       "file not found".
LIB.EXE        n/a             LIB cannot recognize the name of a library
                               if you precede the library name with a path
			       that contains a hyphen "-". For example, if
			       you enter the following, LIB will fail:
			          LIB Test-Dir\MyLib <Enter>
LINE           All*            LINE does not respect the boundaries set
                               with VIEW if you draw a filled box with LINE.
			       See sample program #38.
LINK with /PAC                 See sample program #31. Note that the /PAC
                               switch is supported only by the latest 
			       versions of LINK. (89/02/10)
LINK           All             Use the /EXEPACK switch to condense the
                               file. Can be used on any program except
			       programs that are CHAIN'ed to using
			       all compilers except QB 4/BC7. All QB 4/BC7
			       programs can use this switch. Syntax:
			         LINK /EXE Progname (etc.)
LINK           QB 4            When building a Quick Library, be sure
                               to specify BQLB4x in the library field. Example:
			         LINK /QU ObjMods,Lib,,BQLB40;
			       This also applies to BQLB41 if using BC6
			       or QB 4.00b and BQLB45 when using QB4.50.
			       Similarly, with QBX use QBXQLB.
LOAD           QB 4/QBX/BC7    If you receive an "out of memory"
                               error, try breaking your program
                               into logical pieces (using
                               subprograms). Then use COMMON
                               SHARED for all variables that you
                               need in the entire program. The
                               exact same COMMON SHARED
                               declaration must appear in all the
                               modules in the program that need
                               access to the variables.
LOAD            QB 4*          If you download a QB 4 program in "fast load"
                               format, many modem transfer protocols
			       pad the file out using a number of
			       CHR$(0)'s. This will cause QB 4 to
			       crash when you attempt to load the program.
			       Use DEBUG to view the file, then write
			       the program to disk after changing the
			       CX register to shorten the length of the
			       file so that the trailing CHR$(0)'s are
			       not included. The other solution is to
			       download this type of file using an ARC
			       program that restores the original length
			       of the file.
LOCK            QB 4           If you LOCK records, then perform a
                               SHELL, then you try to UNLOCK the same
			       records, you may get a "permission
			       denied" error (error 70). (88/12/19)
LPRINT          QB 4.50*       See TAB with REDIM (QB 4.50)
ON ERROR        QB 4`          See "RESUME" for QB 4.
ON ERROR        QB 2-4         Error handler routines must be located
                               outside SUB...END SUB structures. You
			       can RESUME to a line number/label that
			       is outside SUB...END SUB structures 
			       (using /E) or to code inside the sub
			       using plain RESUME or RESUME 
			       NEXT (/X). Much better is to $INCLUDE
			       subroutines that perform error trapping
			       instead of having them in subprograms.
			       This allows the use of RESUME line number/
			       label and avoids the /X.
			       Note - with BASCOM 6 and QB 4.00b, error
			       handling has been improved. See the docs.
			       BC7 has "ON LOCAL ERROR", which is even
			       better.
OPEN COM        QB 4`          If you compile with /S, and use OPEN COM
                               with a literal string, the statement will
			       generate "Device Unavailable".
			       See sample program #18.
OPEN            All            With Novell NetWare, using OPEN on a file that
                               does not exist does not always create the file.
			       Novell has acknowledged the problem but they 
			       don't have a solution available as of 12/19/87.
			       A workaround for the problem when using
			       Btrieve is to open the NUL device on the local
			       system instead of the network. For example,
			       OPEN "R",1,"A:NUL".
Out of memory   QB 4 BASCOM 6  See CHAIN (QB 4)
Overflow        All            BASIC uses integer types for all
                               calculations and processes the
                               right side of the equal sign
                               before the left side. To force
                               BASIC to use a different numeric
                               type, place a type identifier on
                               the right of the equal sign.
                               Example: A=Peek(2)+256!*Peek(3)
PAINT           QBX/BC7@       PAINT can't handle a CHR$(0). See Sample
                               program #3. (90/02/17)
Periods in variable names
                QB 4*          We have found numerous problems using periods
		               in variable names. We believe the problems
			       are somehow associated with TYPE..END TYPE
			       user defined records. Because of these problems,
			       we recommend that you do NOT use periods in
			       variable names. See sample program #28 for
			       one example of this problem. (88/12/03)
PRINT TAB(x) and PRINT USING
                QB 4.50*      Don't use PRINT TAB(x) to position the
		               cursor immediately before using PRINT USING.
			       See sample program #5. 90/03/05
PRINT CHR$(128) QB 4.50        If you have a program that contains a
                               PRINT "" and you save it in "fast load"
			       format, BC4.50 will not compile it. The
			       solution is to save your programs in
			       text format. (90/02/20)
PRINT           QB 4.50*       See TAB with REDIM (QB 4.50)
PRINT           All            Try this program in QB: (89/02/10)
                                 FOR N = 29 TO 31
				     PRINT N, CHR$(N)
				 NEXT
			       The number "N" will print just fine, but
			       the characters will not. In order to display
			       these characters, use an assembler subroutine,
			       such as MhScr in Mach 2.	 
PRINT #         QB 4           In order to print a blank line using QB 4,
                               use the syntax:
			         PRINT #n,
			       Note the absence of the null string after
			       the comma. We've had an unconfirmed report
			       that if the print buffer is filled, using
			       the null string causes characters to be
			       dropped.
PRINT USING     QB 4/BC7       With previous compilers, you could place TAB
                               statements, variable names, or most anything
			       else between PRINT and USING. With QB 4, 
			       nothing should come between PRINT and USING.
PUT             4.00b/BC7      See sample program #21. When using the
                               syntax PUT Filenumber,RecordNumber,Variable
			       you'll get a "bad record length".
			       Added 89/10/07 - see sample program #21
			       for another solution.
READ        BC4.00b & 6.00b*   RUN does not do an implicit RESTORE. See
                               Sample program #34. (89/07/29)
READ            QB 4`          If you want a REMark on a line that contains
                               DATA statements, be sure to put a colon on
			       the line between the end of your data and
			       the REM or '.
REDIM           QB 2.01        In EXE programs (not in the environment),
                               the following logic will cause your FIELDed
			       variables to go haywire:
			       
			         REM $DYNAMIC
				 DIM StringArray$(SomeNumber)
				 FIELD #SomeFile....
				 ...
				 ERASE StringArray$
				 REDIM StringArray$(ADifferentNumber)
				 SomeVariable = FRE("")
			       
			       The solution to the problem is to reFIELD
			       the file after a REDIM and a FRE("").
REDIM           QB 3           If you have a subprogram that REDIM's arrays,
                               and you get a "string space corrupt" message
			       after calling the subprogram several times,
			       try using ERASE on the array before you do
			       the REDIM.
REM $INCLUDE    QB 4`          See sample program #24.
REM $TITLE      QB1-4/BC7      When you use the REM $TITLE metacommand,
                               you are limited to 60 chars of title. If
			       the title is longer, you'll get an error
			       message "Metacommand error". Note that QB2.01
			       does not print an error message, but still
			       shows "1 severe error".
RESTORE         QB 4/BC6       If you have two object modules with the same
                               name (for example, one compiled from TEST.BAS
			       and one from TEST.SUB), and you use RESTORE,
			       and you get an error (or the wrong data) when
			       you use READ, use the '$MODULE metacommand to 
			       give one of the modules a different name as far
			       as LINK is concerned. Example:
			          '$Module: 'TEST2'
			       (90/02/26)
RESUME          All            If you always use RESUME
                               <linenumber> or RESUME <label> you
                               can use the "/e" switch instead of
                               "/x". Makes programs smaller!
                               This is not practical for
                               subprograms, so error trapping is
                               better handled in mainline code.
			       See ON ERROR.
			       Note - BC7's ON LOCAL ERROR takes care
			       of RESUME within modules.
RESUME          QB 4`          If you compile to an EXE from
                               inside the environment, a "/X" is
                               generated by QB even though it's
                               not needed. Be sure to recompile
                               with "/E" outside of the
                               environment if your program
                               doesn't need "/X".
RUN             BC7.1          If you are using far strings, and your program
                               is "runtime" (using BRT71EFR.LIB), and the
			       program is running on a network, and the
			       program you attempt to RUN is in the same
			       directory as the program trying to perform
			       the RUN (whew!), you may get a message asking
			       you to "input path for runtime module". The
			       workaround is to use /O, or to always RUN
			       programs from alternate directories, or to
			       have copies of the runtime library whereever
			       it might be needed. (90/08/23)
RUN             QB 4           See CLEAR (QB 4) and CHAIN (QB 4)
SADD            QB 4           When using SADD-188 for Btrieve,
                               be sure to make this calculation
                               EACH TIME you are going to CALL
                               Btrieve. This is because QB 4 can
                               move the FIELD'ed strings around
                               in memory.
SAVE            QB 4           If you edit a new program and save it,
                               QB defaults to "fast load" format. The
			       file cannot be handled by a text editor.
			       Fix by using "save as".
SCREEN (Page)   QB 3           If you have a VGA, your system is in 40
                               column mode, and you use a video page
                               other than 0, you will find that QB3 stores
			       the pages beginning at an offset that is
			       &H100 (decimal 256) higher than it should.
			       Instead of beginning page 1 at offset 2048,
			       (&H800) it starts at offset 2304 (&H900).
SCREEN          QB 3           If you have a VGA and run the following
                               program, you'll find that your screen
			       has 28 lines!
			         SCREEN 2
				 SCREEN 0
				 PRINT "Hello world"
				 
			       The solution is to use MhDos2 (Mach 2) or
			       CALL INTERRUPT (or one of its variations),
			       with the AH register set to 0 and the AL
			       register set to 3. After that, do another
			       SCREEN 0, and you will have 25 lines.
SCREEN          All ?          When reading characters from the screen using
                               SCREEN (X,Y), if the character on the screen
			       is CHR$(0), 32 (blank space) is returned as
			       the result from this function. Using Mach 2's
			       MHRSCR will overcome this problem.
SELECT CASE     QB 3           Much less forgiving than QB 4. For example,
                               when using a string, you can't say:
			         CASE CHR$(3)
			       However, you can embed the literal character
			       with an ASCII value of 3 in quotes!	 
SELECT CASE     QB 4`          If you set a breakpoint (using F9) on a CASE
                               statement, the logic of the SELECT CASE...
			       END SELECT fails. See sample program #19.
			       QB 4.50 tells you that you cannot set a
			       breakpoint on a CASE or END SELECT statement.
			       Some fix!!!
SELECT CASE     QB 4/QBX       You cannot have a line number or label 
                               between the SELECT CASE and the first CASE.
SHARED          QB 4	       See sample program #23.
SOUND           QB 3/87        Generates error 6 in all forms when the
                               emulator is used on non-87 machines.
STACK OVERFLOW  4.00b          You may get this problem when compiling
                               with BC or BASCOM 6. This is a compiler
			       bug, not an error in your program. Contact
			       MS at 206-454-2030 if you have this problem.
STATIC          QB 4/BC7       When used with a subprogram, makes
                               the subprogram faster, since local
                               variables are not initialized on
                               each call.
STR$(Value)     QB 4*          Considerably slower than in QB 3. See 
                               benchmarks in sample program #7.
String Formula Too Complex
                QB 2/3         These compilers have a 19 item limit on
		               string concatenation. If you have more than
			       19 variables/literals, you get a 
			       "String formula too complex" error. (89/03/31)
String Space    QB 4/QBX       Drops you out to DOS without saving
  Corrupt                      your program. The solution is to save
                               often!
STRING$         All            A$=String$(5,65) takes less code than
                               A$=String$(5,"A") and both are smaller
			       than A$="AAAAA".
SUB...END SUB   QB 4/BC7       Cannot be used in $INCLUDE files. Cannot
                               have the same name as a variable (regardless
			       of the variable type).
SWAP            QB4/QBX        Swapping *portions* of a user-defined type
                               in the environment can cause a crash during
			       binding. Swapping the *entire record* will
			       not cause a crash. (89/12/22)
SWAP of single precision array elements with BC7
		BC 7           See sample program #39. (90/07/30)
SWAP with CONST QB 4.50        See sample program #35. (89/09/07)
TAB with REDIM  QB 4.50*       See sample program #33. (89/04/24)
Too Many Files  ???            A QB user has reported a problem that we are
                               unable to duplicate. He says that the "Too
			       many files" error can occur when a disk is
			       full or there are too many files in the root
			       directory. (89/02/10)
Too Many Files  4.00b          When you use QB to make an EXE program, if
                               you get this error, it usually indicates that
			       a module's complete file spec (i.e., drive,
			       path and filename) is longer than 60 chars.
			       60 is the longest name that QB can handle.
			       The solution is to shorten the file name.
TYPE..END TYPE  QB 4           There has been an unverified problem reported
                               in QB when the record length is an odd number.
			       A "FAR HEAP CORRUPT" error is generated.
			       The problem does not seem to appear in BC,
			       only QB. If you have an unusual, otherwise 
			       unexplained problem, try changing the record
			       length to an even number.
TYPE..END TYPE  QB 4           See "DIM" for QB 4.
TYPE..END TYPE
 (with COMMON)  QB 4           See COMMON (with TYPE) and sample program #1.
UBOUND          QB 2-3         If you ERASE an array, UBOUND will return the
                               upper bound of the array BEFORE it was erased.
			       This works OK in QB 4.
UNLOCK          QB 4           See LOCK QB 4 (88/12/19)
VAL             QB 4 BC6/BC7   Much slower than QB3, including when /FPA
                               switch is used. See part 2, under "VAL" for
			       a workaround if you have Microsoft C. If you
			       don't have C, you may want to consider
			       MicroHelp's QB/Pro Volumes 1-4, which have
			       routines that convert strings to integers
			       and long integers. (90/01/08)
VAL             QB 4 BC6*      Generates an error (rather than value of 0)
                               when "e%" or "d%" (case doesn't matter) are 
			       the first characters in a string, or when
			       "%" is the first character. (89/04/24)
VAL             QB 4*          When you use VAL("&"), you get 203 instead of 0.
WINDOW          QB 2-4         Does not affect DRAW statements.
----------------------------------------------------------------------------
Part 2 - General points of interest
----------------------------------------------------------------------------
OPEN QB4.x BC7

When OPENing a file for APPEND and locking that file for write
operations in a networking environment, you should be sure to
specify an access clause of *both* read and write.
 
If your access clause just specifies "write" it is possible
that QB will return error 75 "Path/file access error" for the OPEN
command. (90/03/03)
----------------------------------------------------------------------------
BC7 Type coercion from floating point to integer (90/06/19)

The following program demonstrates a problem when coercing a floating point
number to an integer in BC7. The program will work fine in the QBX 
environment, but returns spurious values for C% when compiled to an .EXE

	c2% = 10
	a! = 1
	DIM t%(10)
	FOR c% = 1 TO c2%
	    PRINT c%, c2%
	    t%(c%) = a!
	NEXT

The perceived value of C% is not spurious, it is the value of C2%.

A workaround:

By not allowing automatic coercion to be the last operation in the
loop, the perceived value of C% remains correct.
The coercion in the VAL function also causes the same problem.

        c2% = 10
        a! = 1
        DIM t%(10)
        FOR c% = 1 TO c2%
            PRINT c%, c2%
            t%(c%) = a!
            i%=i%+1             ' Added dummy instruction
        NEXT
----------------------------------------------------------------------------
BC7 with Inboard/PC and CoProcessor (90/01/08)

Effective with BC7, Microsoft has changed the way they test for the presence
of a math coprocessor (80x87). They now test to see if the motherboard
switch indicating a coprocessor is on or off. The Inboard/PC has to have
the motherboard switch off. This means that BC7 won't recognize a 
coprocessor on such a system.
----------------------------------------------------------------------------
VAL Workaround (90/01/08)

If you have Microsoft C, you can take advantage of two functions built into
the C library that will speed up the VAL function when used with integers and
long integers.. In your BASIC program, you need to declare two FUNCTIONs and
you must work with ASCIIZ strings (a BASIC string with a CHR$(0) on the end):

   DECLARE FUNCTION ATOI% CDECL (BYVAL ST%)
   DECLARE FUNCTION ATOL& CDECL (BYVAL ST%)
   ST$ = "1" + CHR$(0)
   NUM% = ATOI%(SADD(ST$))
   NUM& = ATOL&(SADD(ST$))
   
You'll also need to make a "dummy" C program, compile it and include it
in your Quick Library (for use in the environment) and on the LINK command
line:

   void dummy()
   int n; long l; char near *ST;
   n = atoi(st);
   l = atol(st)

(90/01/18) Another suggestion from the same person is to read
numeric DATA statements into strings and then use the ATOI
function to get the integer value.
----------------------------------------------------------------------------
Converting large numbers to integers (89/12/22)

A common technique to stuff a large number (between 32767 and 65536)
into a BASIC integer is:
 
number! = 50000
number% = VAL("&H" + HEX$(number!))
 
However, QB's VAL() function is quite sluggish.  The following technique
produces the same result, and runs approximately 20-30% faster, depending
on the compiler:
 
number! = 50000
number% = CVI(CHR$(number! MOD 256) + CHR$(number! \ 256))
 
----------------------------------------------------------------------------
Using CALL with literals takes lots of stack space.  (89/10/10)

	' Demonstrate the effect on stack space when using literals
	' in CALL statements.
	
	' First, run the program as is and note the low point for
	' stack space. Then REM the line with variables in the CALL
	' and unREM the line with literals and run the program again.
	
	' Note that the low stack point is ten bytes lower when
	' literals are used. In a large program with a lot of CALL
	' statements, this can really add up.
	
	DEFINT A-Z
	PRINT "Lowest amount of stack space before CALL:"; FRE(-2)
	A% = 1
	B% = 2
	C% = 3
	D% = 4
	E% = 5
	' REM next line for second pass
	CALL TestStack(A%, B%, C%, D%, E%)
	' UNREM next line for second pass
	'CALL TestStack(1, 2, 3, 4, 5)
	PRINT "Lowest amount of stack space after CALL:"; FRE(-2)

SUB TestStack (A%, B%, C%, D%, E%)

END SUB

----------------------------------------------------------------------------
Long Integers in TYPE..END TYPE (BC 4.5*)

When long integers are part of a user defined type, and used in a SUB,
the results are unpredictable. If you compile the following, you'll get
different results in BC4.5 with and without /O.

 TYPE BugRecord
 nbr AS LONG
 END TYPE

 CALL bugsub
 END

 SUB Bugsub

 DIM BUG(100) AS BugRecord

 BUG(1).nbr = 4
 BUG(2).nbr = 6

 PRINT BUG(1).nbr + BUG(2).nbr

 END SUB


----------------------------------------------------------------------------
BC 6 with math coprocessor (89/07/29)

If you are using the Microsoft BASIC Compiler 6 (version 6.00 or
6.00b) and are using the default math library (/FPI), you may
experience unexplained "overflow" errors if your program is
running on a 286/386 with a math coprocessor AND under DOS 3.2
or 3.3. The solution is to use the alternate floating point math
library (/FPA), however:

If you are running on a machine with a math coprocessor,
you're using Btrieve 4.x or 5.x, you've compiled
with the /FPA switch, AND your program CHAINs, then you
must perform a Btrieve "reset" (Op%=28) before CHAINing
or an "illegal function call" error will result.
----------------------------------------------------------------------------
AB45ACVR.HLP and QB45ACVR.HLP (QB 4.50)
                               The actual hypertext help file is QB45ACVR.HLP.
			       Some of the entries in the help screens try
			       to find AB45ACVR.HLP instead (i.e., the "Q"
			       is changed to an "A". If you have a hard disk,
			       you can remedy this by copying the "Q" file
			       to the "A" file. (89/04/24)
----------------------------------------------------------------------------
BUILDRTM (BC7)                 Has a limit of 127 exports in a single 
                               extended runtime library. (89/04/24)
			       Note that the error you receive is
			       "Fixup overflow" when you run the BUILDRTM
			       program.
----------------------------------------------------------------------------
BUILDRTM (BC7)                 Has a limit of 255 exports. (89/11/03)
----------------------------------------------------------------------------
Wyse PC Keyboard Problem

Some early versions of the BIOS used by Wyse incorrectly set a byte in the
BIOS data area that tells QB that an enhanced keyboard is present. This
causes a lockup, since QB is using an "enhanced" BIOS call to read the 
keyboard and is not getting a response.
----------------------------------------------------------------------------
ATI EGA Wonder Cards

If you find that you are unable to set EGA modes on a system with one
of these cards, call ATI for a free BIOS upgrade.

----------------------------------------------------------------------------
Editor problem in QB 4.50

If the QB 4.50 editor seems to be "changing" your programs, including
placing "garbage" characters on the screen, it may be due to your
math "coprocessor" (80x87 chip). Two solutions:

1. Check to make sure that the coprocessor chip is firmly seated.
2. Make sure that the motherboard switch indicating the presence of the
   coprocessor is set correctly.
----------------------------------------------------------------------------
Keeping DTR High QB 4 

According to Microsoft, you can keep DTR high when exiting from QB 4.x by
performing the following steps:

1. Close the serial port.
2. Immediately perform one of the following statements:
   a. For COM1:  OUT &H3FC,3
   b. For COM2:  OUT &H2FC,3
   
The OUT command will force pin 20 (DTR) to stay high. DTR will actually
be dropped for an instant between the CLOSE and the OUT, but it should
be too short for the modem to care. If this does cause a problem, try
adjusting the "S" register (see your modem manual) to allow a larger
time-out period before dropping the carrier.   
----------------------------------------------------------------------------
Logitech Mouse Info QB 4.50 (88/12/19)

When running QB 4.5, if DOS is in 25 line mode and the QB editor
is started with the /h option for 43 line mode, a Logitech
Hi-Rez Bus mouse cursor disappears below line 25.  Solution: use
the Microsoft vers.  6.24 mouse driver that came with QB4.5 or
get the Logitech vers.  3.43 or later driver.  Contact Logitech
at 1-415-795-8500.  Another solution is to use MODE43.COM from
earlier QB versions to put the screen in 43 line mode before
starting QB4.5.

----------------------------------------------------------------------------
Non-IBM EGA cards QB4.50 (88/12/19)

After running a program that uses the 25 line mode and a return
is made to the editor, press F4 to review the Output screen and
then press any key to return to the editor.  The screen will
return to 43 line mode but the lines below line 25 will be
blacked out.  The problem was found to be the Tseng EVA-480 EGA
card.  A temporary fix is to do 'Alt-F' and then 'D' to execute
a shell to DOS and immediately return or else press F5 to rerun
the loaded program to restore the full 43 lines.  The better
solution is to just not use the F4 key until the Tseng card's
rom is updated or QB is fixed.

----------------------------------------------------------------------------
Cut and Paste Problems QB 4.50 (88/12/19)

On some "clone" computers, the Cut and Paste keys (Ctrl-Ins) and (Shift-Ins)
do not work correctly. There are two things you can try:

1. Turn off Caps Lock, Num Lock and Scroll Lock.
2. Run FIXSHIFT.COM with the "/I" switch to force installation.

If neither of the above work, contact Microsoft and let them know what
your hardware configuration is.
----------------------------------------------------------------------------
Avoiding unwanted line feeds when printing to LPT         

When you LPRINT a CHR$(13), QB4 automatically appends a CHR$(10) character
causing "unwanted" line feeds. To avoid this problem:

  OPEN "LPT1:BIN" FOR OUTPUT AS #1

Then instead of using LPRINT, use PRINT #1,String. This causes the output
to the printer to be "unfiltered".  
----------------------------------------------------------------------------
DOS 4.00

On August 29, 1988, Infoworld reported several known problems with IBM DOS
4.0. Their suggestions include:

1. If you use the DOS "Shell", run it in text mode to avoid conflicts with
   TSR programs.
2. Disk un-fragment programs, such as Norton Utilities, Mac Utilities, 
   VOPT, etc. don't work.
3. Lotus Metro doesn't work.
4. Don't use the EMS driver that comes with DOS if you have a third-party
   memory board. Instead, use the driver that came with the board.
5. Don't try to install IBM DOS 4.0 on a hard disk that already has a
   non-IBM version of DOS 3.x.
6. Don't use the "/X" switch with any itmes in CONFIG.SYS.

In the same issue, Cringely reports that IBM is working on DOS 4.1.   
----------------------------------------------------------------------------
Problems when moving SUBs between modules in the environment.

The following is unedited text uploaded by a Compuserve user. The
problems described have not been confirmed - this is included for your
info and so that you can avoid doing what he did.

On SOME occations, QB will not let you save your program,
giving instead an "Out of Memory" error.  Automatically, you
lose everything you've done since you last saved.  But upon
exiting, you also find that the file was erased from the disk!
GONE!  Using Norton can RARELY bring it back (usually trying to
load the resurected file causes a complete system hang).  This
has happened at least 10 times to me.  The program is VERY large
(over 1200 lines) with many Subprograms.  The most notable cause
(but not ONLY) is when moving a SUBprogram from one program to
another (i.e. copying it).  When deleting the original SUB line
in the target program and substituting the one to be copied
(with <Sift><Ins>), everything appears fine until the next save.
This does not always happen, but USUALLY.  If I do not remove
the original SUB line, it doesn't seem as likely to happen.
These are all the clues I have on this one.  Also, jumping
between programs using <F>ile <O>pen tends to aggrivate the
problem.  If I do this frequently, a <F>ile <N>ew is likely to
give me a "string space corrupt" or "far heap corrupt" error and
dump me back to DOS.  Remember, these are large programs, with
large arrays (the /AH switch).

----------------------------------------------------------------------------
Embedded Ctrl Characters (QB 4*)

Pressing Ctrl-P, followed by CHR$(12) (regardless of how you enter it),
does not embed a CHR$(12) in the text. However, if you use another text
editor to embed the CHR$(12), QB will display it just fine.

----------------------------------------------------------------------------
Using DECLARE (QB 4*) without a CALL

The following code demonstrates a quirk after a SUB has been DECLAREd and
you invoke it without a CALL:

  DECLARE SUB XSUB (A!)
  start=0
  XSUB (start-1)\20+1        	' This does not work. QB cannot parse it.
  XSUB ((start - 1) \ 20 + 1)	' This works. Note that the entire
  				' expression is enclosed in parentheses.
SUB XSUB(A!)
    A!=A!+1
END SUB
----------------------------------------------------------------------------
QB4 editor and marked blocks

If you mark a block, using the SHIFT and cursor keys, and then you type
a space (while still pressing the SHIFT key), your marked block will
disappear.
----------------------------------------------------------------------------
Scan Codes for F11-F12 and Variations:

        F11=133
        F12=134
  Shift-F11=135
  Shift-F12=136
  Ctrl -F11=137
  Ctrl -F12=138
  Alt  -F11=139
  Alt  -F12=140
----------------------------------------------------------------------------
Long integers with QB 4*

When you have a long integer array with two dimensions, BC may not handle
the zeroth elements correctly on machines without a math coprocessor
unless you use the "/d" switch. QB handles the situation OK because "debug"
is always on when working in the environment.

Secondly, if you dimension the same two-dimensional array using a variable
name instead of a numeric constant, BC may not handle your array at all! The
fix is to use only constant numbers in dimensioning the array. Another fix
that DOES work with dynamic arrays, is to use the /R switch when compiling.
----------------------------------------------------------------------------
More on long integers *

If you pass a long integer array to a subprogram, QB will work OK, but
BC does not. See Sample Program #2.
----------------------------------------------------------------------------
Long Integers and Calculations QB 4 `

Calculations using long integers should be tested thoroughly after compilation
with BC. Sample Program #6 demonstrates the problem.
----------------------------------------------------------------------------
LIB environment variable

If you set the LIB environment variable, you will find that QB, BC, BUILDLIB
and LINK will all search the specified path whenever a User Lib, Quick Lib or
LINK lib is needed. The syntax is similar to the DOS Path syntax:

  SET LIB=C:\Libs;C:\DOS;C:\QB
  
Note that this does not have any effect when you are compiling from 
within the QB4` environment, and QB sticks the name of a library in the
object module field.
----------------------------------------------------------------------------
Undocumented switches in QuickBASIC 3

QB ProgramName/F compiles the specified program to an EXE file without 
starting up the QB editor.

QB ProgramName/Z tells QB to load and execute ProgramName and exit to DOS
when the program ends.
----------------------------------------------------------------------------
Response files

BUILDLIB and LINK both accept input from response files. This is exactly the
same as redirection of input, but the programs will continue running when
the end of the file is reached prematurely. Example:

Response file contains:
  Prog1+Prog2+Prog3+
  Prog4+Prog5+Prog6 Rem Don't include ANY additional blank lines
  
Buildlib batch file contains:
  Buildlib @Response.Fil,MyLib.Exe;
  
Buildlib will take its input from the response file because the "@" sign
tells it to!      
----------------------------------------------------------------------------
BUILDLIB and "too many segments" error

Where "nnnn" is a number from 1 to 1024, use:

   BUILDLIB /SEG:nnnn

That increases (or decreases) the number of allowable segments. Default=255.
----------------------------------------------------------------------------
Entering unusual ASCII values.

If you're not familiar with WordStar, you may not know that you can enter
unusual characters into the QB4 editor by doing the following:

  Hold the Ctrl key and press "P" once (nothing will happen).
  Release the Ctrl key.
  Press and hold the Alt key.
  Using the keypad number keys (not the keys on the top of the keyboard),
    enter the ASCII value for the key you want. For example, the 'Esc' key
    is ASCII 27, so press the "2", then the "7".
  Release the Alt key, and your special character will appear!  
----------------------------------------------------------------------------
Part 3 - Sample programs
----------------------------------------------------------------------------
Sample program #1. How to use COMMON with TYPE'd variables.

       ' Prog1.bas

         TYPE Namerec
           LastName AS STRING * 20
           FirstName AS STRING *15
         END TYPE
         COMMON Filename() AS Namerec
         DIM Filename(5) AS Namerec
         Filename(1).LastName="Novisoff"
         Filename(1).FirstName="Mark"
         CHAIN "Prog2"

       ' Prog2.bas
       
         TYPE Namerec
           LastName AS STRING * 20
           FirstName AS STRING * 15
         END TYPE
         COMMON Filename() AS Namerec
         PRINT Filename(1).LastName, Filename(1).FirstName

----------------------------------------------------------------------------
Sample program #2. Demonstrates problem with long integers in subprograms.

DECLARE SUB TestLong (LongArray&())
'Demonstration to show difference between return values of long integers

'Returns desired value if compiled in the environment, but not if compiled
'by BC.

'This fault only appears if the code is in a subprogram and compiled with BC
REM $Dynamic
DIM LongArray&(10)
DIM MainArray%(10)

CLS
LongArray&(1) = 100
MainArray%(1) = 10

FOR x% = 1 TO 2
    LongArray&(1) = MainArray%(1) + LongArray&(1)
    ' Note: if you change the above into the following two lines, this part
    '       of the program will run correctly.
    'Temp& = MainArray%(1)
    'LongArray&(1) = Temp& + LongArray&(1)
NEXT

PRINT "TestLong should = 120"
PRINT "Long Array from MAIN = "; LongArray&(1)
PRINT : PRINT "Same code in a subprogram"
PRINT

CALL TestLong(LongArray&())

PRINT "TestLong should return 120"
PRINT "Long Array from TestLong sub = "; LongArray&(1)

SUB TestLong (LongArray&())
DIM IntArray%(10)

LongArray&(1) = 100
IntArray%(1) = 10

FOR x% = 1 TO 2
    LongArray&(1) = IntArray%(1) + LongArray&(1)
    ' Note: if you change the above into the following two lines, this part
    '       of the program will run correctly.
    'Temp& = IntArray%(1)
    'LongArray&(1) = Temp& + LongArray&(1)
NEXT
END SUB

----------------------------------------------------------------------------
Sample program #3. Demonstrates problem with PAINT in QBX and BC7 when
chr$(0) is used.

	' This code erases the yellow line in earlier compilers,
	' but QBX/BC7 can't handle the CHR$(0) in the PAINT statement.
	
	SCREEN 8
	LINE (0,0)-(150,150),15,B
	LINE -(0,0),14
	PAINT (1,1),chr$(0),15

----------------------------------------------------------------------------
Sample program #4. Demonstrates the limit on dynamic numeric
arrays in QB 3.  This program generates a program called
ARRAY.BAS. Compile ARRAY.BAS with the "/d" switch, LINK it and
RUN it. The sole function of ARRAY.BAS is to generate arrays.
Regardless of the value of I%, and regardless if you use "#",
"%" or "!" as the array type, the program gives an "Out of
memory" error when the 124th array is DIMmed.

OPEN "O",#1,"ARRAY.BAS"
PRINT #1,"I%=1"
FOR J=1 TO 126
  L=L+10:PRINT #1,MID$(STR$(L),2);" DIM A";MID$(STR$(J),2);"#(I%):PRINT FRE(-1)"
NEXT 
CLOSE
END
----------------------------------------------------------------------------
Sample program #5. Demonstrates the a problem with PRINT TAB(x) followed
by PRINT USING in QB4.50. Fixed in MS PDS 7.0.

The program works OK in the QB4.50 environment. However, if you
use BC 4.50 to compile and LINK this program, you'll get strange results.
The workaround is to REM the PRINT TAB statements and UNREM the LOCATE
statements.

	CLS
	OPTION BASE 1
	DEFINT C, I
	C = 2
        DIM N$(C)
        DIM B(C)
	FOR I = 1 TO 2                        'Generate data
	    N$(I) = CHR$(64 + I)                  'Row labels array
	    B(I) = .08 * (I) ^ 4                  'Arbitrary array of numbers to print
	NEXT I
	PRINT TAB(5); "Char"

	FOR I = 1 TO 2

		PRINT TAB(5); N$(I);
		PRINT TAB(10); B(I);

		PRINT TAB(23);
		'LOCATE , 23
		PRINT USING "###.####"; B(I);

		PRINT TAB(40);
		'LOCATE , 40
		PRINT USING "###.###"; B(I);

		PRINT TAB(60);
		'LOCATE , 60
		PRINT USING "####.##"; B(I)
	NEXT I
	END

----------------------------------------------------------------------------
Sample program #6. Demonstrates long integer calculation problem. This 
program will run in QB 4.00 and 4.00a, but it gives incorrect results
using BC or BC 6. This problem has been fixed in the BC that comes with
QB 4.50.

DEFINT J: DEFLNG T
 
DIM tum(2), ttm(2), th(2)
 
ttm(2) = 100000: th(2) = 1000000: j = 2
 
PRINT th(j) * VAL("9") + ttm(j) * VAL("9")

'    Result should be "9900000"
 
'    Substituting th(2) for th(j) (etc). makes it work.  So does using
'    CLNG(VAL("9")).  It also works when the array tum(2) isn't there.
'    Compiling with "/d" may fix the problem in some cases. Substituting
'    a single precision number seems to work.
----------------------------------------------------------------------------
Sample program #7. Demonstrates slowdown in STR$ function in QB 4.

  defint a-z
  a!=timer
  for n=1 to 5000
      a$=str$(n)
  next
  print "elapsed:" timer-a!
----------------------------------------------------------------------------
Sample program #9. Demonstrates a problem with IF..THEN..ELSE. Using any
compiler except QB4.00 and QB4.00a, the string "THIS IS AN ERROR" is
never printed. Using these two environments causes the string to print
whenever X<>2.

  10 INPUT "TYPE A NUMBER ", X
  20 IF X = 2 THEN 50 : PRINT "THIS IS AN ERROR"
  30 PRINT "AT LINE 30"
  40 GOTO 10
  50 PRINT "AT LINE 50"
  60 GOTO 10
----------------------------------------------------------------------------
Sample program #10. Demonstrates a problem when INPUT is used directly
to an array element that is beyond the maximum dimension of the array.
When run inside the QB 4 environment, this program will cause a hard crash.
This problem does not apply to LINE INPUT.

This problem has been fixed in QB 4.50.

  DIM A$(20)
  FOR I = 1 TO 20
      A$(I) = STR$(I)
  NEXT
  INPUT "Enter something: ", A$(I)     ' At this point, I=21

----------------------------------------------------------------------------
Sample program #17. Demonstrates a problem using GOTO inside an
IF..THEN..ELSE block. This program will work fine in the QB4.00 and QB4.00a
environment, but will fail when compiled with BC or BASCOM 6. By "fail",
I mean that both PRINT statements are executed. The problem has been fixed
in the BC that comes with QB 4.50.

   x% = 1
   IF x% = x% THEN
     PRINT "1 equals 1"
     GOTO 10
10   x% = x%
   ELSE
     PRINT "1 does not equal 1"
   END IF
 
----------------------------------------------------------------------------
Sample program #18. Demonstrates a problem using /S in conjunction with
/O and communications, where a string literal (in quotes) is used for the
COM parameters. This problem has been fixed in the BC that comes with QB 4.50.

   ' compile with BC:
   '        BC prog/s/o;  (produces device unavailable error but runs
   '                       fine in the environment)
   '            and
   '        BC prog/o; (runs fine)
   CLS
   OPEN "COM1:1200,O,7,1,CS,DS,CD" FOR RANDOM AS #1 LEN = 256
   PRINT #1, "ATM1X2E1 S11=72DT 999-9999;"
   PRINT "Press any key to continue..."
   DO WHILE LEN(INKEY$) = 0: LOOP
   PRINT #1, "ATH"
   CLOSE
   END

The solution to the above is to assign the COM specifications to a string
before doing the OPEN:

   A$ = "COM1:1200,O,7,1,CS,DS,CD"
   OPEN A$ FOR RANDOM AS #1 LEN = 256
----------------------------------------------------------------------------
Sample program #19. Demonstrates a problem where If a breakpoint
is set on a CASE line of a SELECT CASE ... END SELECT
statement, the SELECT CASE structure is not executed properly.
QB 4.50 tells you that you cannot set a breakpoint on a CASE or
END SELECT statement.  Some fix!!!

'Set a breakpoint (F9) on the 'CASE 1' line, and RUN the program (F5)

DEFINT A-Z
A = 2
SELECT CASE A
       CASE 1
            PRINT "A equals 1"
       CASE 2
            PRINT "A equals 2"
       CASE ELSE
            PRINT "A is not equal to 1 or 2"
END SELECT
----------------------------------------------------------------------------
Sample program #21. Demonstrates a problem with PUT and QB4.00b

   OPEN "test.dat" FOR RANDOM AS 1 LEN = 140
   t$ = STRING$(140, "A")
   LSET buffer$ = t$
   PUT #1, , t$
   CLOSE 1

This program will work with QB4.00a but not with QB4.00b

The solution is to use the "old-style" FIELD statement:

   OPEN "test.dat" FOR RANDOM AS 1 LEN = 140
   FIELD 1,140 as Buffer$
   LSET Buffer$ = STRING$(140, "A")
   PUT #1,1
   CLOSE 1

The following info was added 89/10/07 (contributed by Phil Weber):

The reason for this is that, beginning with version 4.00b, when PUTting a
variable-length string into a RANDOM file, QB precedes the string with its
length (a two-byte integer).  Thus the (apparently) 140-byte T$ above becomes
142 bytes in length.  Your recommended solution is to declare a file buffer
using the FIELD statement -- that works because FIELDed strings are not
variable-length.  Two other options are to declare the record length two bytes
longer than you actually need (albeit a bit wasteful, but it works!), or to
DIM your string variable to a fixed length, like this:

       OPEN "Test.Dat" FOR RANDOM AS #1 LEN = 140
       REDIM T AS STRING * 140
       T = STRING$(140, 32)
       PUT 1, , T
       CLOSE

Thought the above info might help anyone who's been perplexed by the "Bad
Record Length" error.
----------------------------------------------------------------------------
Sample program #22. Demonstrates a problem with CALL:

Note that this program requires TEST.DAT, which is part of the ARC file.
It also requires that you use an assembly subroutine to display a
string from the array.

The fix is to place A$() in a COMMON SHARED statement and take it out
of the parameter list in the CALL and the SUB statements.

 DEFINT A - Z
 DIM A$(3)
 CLS
 OPEN "R", 1, "TEST.DAT", 128
 FIELD 1, 32 AS A$(1), 6 AS A$(2), 90 AS A$(3)
 PRINT "Getting Record One"
 GET 1, 1
 PRINT "A$(1) Contains: "; A$(1)
 PRINT "A$(2) Contains: "; A$(2)
 CALL AnotherWay (A$())
 PRINT
 PRINT "Getting Record Two"
 GET 1, 2
 PRINT "A$(1) Contains: "; A$(1)
 PRINT "A$(2) Contains: "; A$(2)
 CALL AnotherWay (A$())
 CLOSE
 END

SUB AnotherWay (A$()) STATIC

stop
 ' Insert a call to an assembler routine to display A$(1)
 ' The following 2 lines are included for the benefit of Mach 2 users.
 ' R%=CSRLIN:C%=POS(0)
 ' CALL MhScr(A$(1),0%,R%,C%,7%)
 PRINT
 PRINT A$(2)
END SUB
----------------------------------------------------------------------------
Sample program #23. Demonstrates a problem with SHARED in QB4.00b. The
problem did not exist in QB4.00.

If you change the name of db to something else, or you place db and db()
in the parameter list, all is well. The problem seems to be that if
you have a scalar with the same name as an array, and you name it in the
SHARED statement, QB thinks that the scalar and the array are one in the
same.

DIM db(10)
db(1) = 1
db = 2
CALL Test(db)

SUB Test (db)
    SHARED db()      '<= duplicate definition error
    PRINT db, db(1)
END SUB
----------------------------------------------------------------------------
Sample program #24. Demonstrates a problem with '$Include in all versions
of QB 4.00x:

' Load this program into QB, move the cursor to the end of the first
' rem $include line and press the Del key. You will get "string space
' corrupt" and when you go to run another program, you are hung!

REM $INCLUDE: 'c:\subprogs\done\ssinput.cal'
REM $INCLUDE: 'c:\subprogs\done\vinput.cal'
----------------------------------------------------------------------------
Sample program #25. Demonstrates a problem with long integers used
in user defined types. When you attempt to compile the following program
with BC, you'll get an "Internal error" message from the compiler. The
problem has been fixed in the BC that is included with QB4.50.

   DEFINT A-Z
   TYPE Bt
      a   AS INTEGER
      b   AS LONG
      c   AS LONG
   END TYPE
   DIM Bt(1) AS Bt
   Bt(y).b = x&
   Bt(y).c = Bt(y).b

There are several ways of "fixing" the above:

1. Swap the last two lines.
2. Change a variable subscript (y) to literal subscript (1)
3. Change the order of the variables a,b,c.
4. Add a line between the last two lines, like "j=k*3"
5. Break the last line up into: 
     temp&=Bt(y).b
     Bt(y).c=temp&

The problem apparently has to do with optimization of the last two
lines of code.
----------------------------------------------------------------------------
Sample program #26. Demonstrates a problem with FRE(-2) in all versions
of QuickBASIC 2-4.

DEFINT A-Z
PRINT "before call", FRE(-2)
CALL test
PRINT "after call", FRE(-2)

' For QB2/3, add the STATIC keyword after SUB test
SUB test 

    PRINT "entering sub", FRE(-2)
    REDIM a$(100)
    FOR i = 0 TO 100
	a$(i) = "this is a test"
    NEXT i
    PRINT "before erase", FRE(-2)
    ERASE a$
    PRINT "after erase", FRE(-2)
END SUB
----------------------------------------------------------------------------
Sample program #28. Demonstrates a problem with periods in variable names.

' Note - name this program TEST1.BAS

     DEFINT A-Z
     DIM STG$(10), DBLP#(10), INTG(10)
     COMMON SHARED STG$(), DBLP#(), INTG(), message$
     message$ = "Hello there."
     CHAIN "TEST2"

' Note - name this program TEST2.BAS
     DEFINT A-Z
     DIM STG$(10), DBLP#(10), INTG(10)
     COMMON SHARED STG$(), DBLP#(), INTG(), message$
     DIM er.Mem(1024)             'Bad Guy
     TYPE item
        store AS STRING * 1
        item AS STRING * 5
     END TYPE
     DIM itemrec AS item          'Contributor to the problem
     PRINT "OK, This is the message...  "; message$
     END

Note that the error occurs in QB 4.00b and QB 4.50. The second DIM in
TEST2.BAS combined with the DIM of an array with a period, causes the
problem.

----------------------------------------------------------------------------
Sample program #29. Demonstrates a problem with INT in all versions of QB 4
and QBX. (88/12/19).

'This bug only happens using BC4.50/7.0 and QB4.50/QBX. It works
'fine in the environment using earlier versions of QB4.  
'The INT(numeric expression) statement does not always return the
'correct value if the numeric expression is a calculation.  The
'following example will illustrate:
 
    A = .9
    B = 10
    C = INT(A * B)   'This will produce a result of 8 instead of 9.
    PRINT "All numbers shown should be 9"
    PRINT C
    D = A * B
    PRINT D
    C = INT(D)       'This will produce the correct result.
    PRINT C
    C = INT(.9 * 10) 'This will also produce the correct result.
    PRINT C
----------------------------------------------------------------------------
Sample program #30. Demonstrates a problem with CINT in all versions of QB 4.
(88/01/03)

FOR I = -10.5 TO 10.5
  PRINT I, CINT(I)
NEXT
----------------------------------------------------------------------------
Sample program #31. Demonstrates two problems when you LINK with /PAC.
(89/02/10)

If you use the /PAC switch, strange things can happen to your
programs. Compile the code shown below into two object modules using
the /X switch.

' This is TEST1.BAS
CALL Test2
DATA "This is string 1"
DATA "This is string 2"


' This is TEST2.BAS
Ehandler:
  RESUME NEXT
Test2Data:
  DATA "This is string 3"
  DATA "This is string 4"

SUB Test2
  ON ERROR GOTO Ehandler
  RESTORE Test2Data
  READ A$
  PRINT A$
  READ A$
  PRINT A$
  PRINT "Error was handled ok."
END SUB

If you LINK the programs normally, the strings are printed correctly
and the error is handled properly. If you LINK the same modules with
/PAC, the data are not read and the error is not handled!

----------------------------------------------------------------------------
Sample program #32. Demonstrates a problem with DECLARE.
(89/02/10)

In the following program, "MySub1" is not executed. Instead, QB
treats the invocation of the SUB as a label. Note that this happens
only when there are no parameters, and you omit the CALL keyword
(requiring that you DECLARE the procedure). In addition, there must
obviously be a colon on the line after the name of the SUB.

DECLARE SUB MySub1 ()
DECLARE SUB MySub2 ()

    MySub1: MySub2

SUB MySub1
    PRINT "Hello"
END SUB

SUB MySub2
    PRINT "Goodbye"
END SUB
----------------------------------------------------------------------------
Sample program #33. Demonstrates a problem using TAB with REDIM in QB 4.50.
(89/04/24)

        REDIM Text$(4)
        Text$(1) = "1111"
        PRINT TAB(4); Text$(1);

Remove the TAB(4); or change REDIM to DIM and it'll work. As it sits it bombs
the computer requiring a reboot. Variables vs literals in the TAB argument
don't appear to affect it after all. This affects both PRINT and LPRINT.
----------------------------------------------------------------------------
Sample program #34. Demonstrates a problem using DATA, READ and RUN with
BC4.00b and BC6.00b (89/07/29)

' On the second and subsequent executions of this program, BC4.00b gives
' a SYNTAX error, while BC6.00b just prints zeros.

 READ A%
 PRINT A%
 IF INKEY$ <> "" THEN END
 RUN
 DATA 1

----------------------------------------------------------------------------
Sample program #35. Demonstrates a problem using SWAP and CONST in QB 4.50
(89/09/07)

** Warning - this program will crash your system **

Load the following program into QB4.50 and press F5:

  const Nul$=""
  z$="hello"
  swap z$,Nul$
  
QB4.50 gives different results, depending on if Nul$ is "" or has a length.

QB4.00b and QBX correctly trap the error of trying to SWAP a constant.
----------------------------------------------------------------------------
Sample program #36. Demonstrates a problem using temporary strings with
DEF FN in all compilers.

When a string is passed as an argument to a DEF FN function, it
remains in memory until the next time that function is invoked.
In (almost) all other situations where BC/QB has to create a
temporary string, it calls the "String Delete" routine to mark
it as free for the garbage collection.  So if you pass, say, a
10K string as an argument, you just lost 10K of string space.
Ouch, no?  This happens only when compiled to disk though, not
in the environment.  Proof follows.

   DEF FNOuch% (Work$)
       X = LEN(Work$)
   END DEF
   PRINT FRE("")
   Dummy = FNOuch%(STRING$(10000, "A"))
   PRINT FRE("")

----------------------------------------------------------------------------
Sample program #37. Demonstrates a problem with INSTR in BC 4.x

     DEFINT A-Z
     CLS
     Literal$ =""            'This string is made in the QB Editor by
                             'typing Ctrl-P and then holding down Alt
                             'while typing ASCII code of character.
			     'Enter ASCII 1 through 5.
     FOR I = 1 TO 5
         Found = INSTR(Literal$, CHR$(I))
         PRINT "INSTR reports CHR$("; MID$(STR$(I), 2);
         PRINT ") at position"; Found; "of Literal$."
     NEXT
     PRINT

     Char$ = CHR$(1) + CHR$(2) + CHR$(3) + CHR$(4) + CHR$(5)
     FOR I = 1 TO 5
         Found = INSTR(Char$, CHR$(I))
         PRINT "INSTR reports CHR$("; MID$(STR$(I), 2);
         PRINT ") at position"; Found; "of Char$."
     NEXT
     END

In the environment, as one would expect, the above program
reports CHR$(1) at position 1, CHR$(2) at position 2, etc. for
*both* strings.  But compiled to an EXE file, INSTR reports
position 0 for CHR$(1) and CHR$(2) in Literal$

Note: BC7 documents that you cannot use CHR$(1) and CHR$(2) in a string.
Actually, you can have those characters in a string, but INSTR and possibly
PRINT won't work correctly.

----------------------------------------------------------------------------
Sample program #38. Demonstrates a problem with LINE (filled box) and
VIEW that was not fixed until BC7.

SCREEN 9
VIEW (1,1)-(150,150)
LINE (-50,50)-(-100,100),12,B
LINE INPUT "Image clipped correctly";Z$
LINE (-50,50)-(-100,100),12,BF
LINE INPUT "Image *not* clipped correctly";Z$

----------------------------------------------------------------------------
Sample program #39. Demonstrates a problem with SWAP and single precision
array elements using BC7.

	DIM dt!(2), rn%(2)
	n = 1	
	a! = dt!(n) * 100000! + rn%(n)
	b! = dt!(n + 1) * 100000! + rn%(n + 1)
	SWAP dt!(n), dt!(n + 1)
	
The above program gives an "out of memory" error. Remming the "+ rn%(.."
in two places solves the problem.

Microsoft suggests a SUB to do the SWAP:

    CALL SwapSub(DT!(n), DT!(n+1)
    
    SUB SwapSub(A!, B!)
        SWAP A!, B!
    END SUB	

----------------------------------------------------------------------------
Part 4 - Video adapters compatible with QB 4.50
----------------------------------------------------------------------------
The following cards are available "in-house" at Microsoft and were tested
with QB4.50

Cards that PASSED:

(Note - if the card is a VGA but not an IBM PS/2 VGA,
        there will be problems swapping on screen 10.)

          AST EGA (256k)
          Compaq Portable (Monochrome)
          Compaq VGC (Their name for VGA)
          Daewoo (Leading Edge/AT) EGA (256k) Monochrome
          Genoa EGA (256k)
          Genoa EGA (256k) monochrome
          Hercules Monochrome
          IBM EGA 256k
          IBM EGA 64k
          IBM PC Convertible
          IBM VGA (Non-PS/2)
          IBM PS/2 VGA
          IBM MCGA
          IBM EGA (64k) with monochrome
          IBM CGA
          IBM MDPA
          NCR EGA
          Olivetti Monochrome
          Olivetti EGA (256k)
          Olivetti VGA
          Paradise Autoswitch EGA (256k)
          PC's Limited VGA
          Tandy EGA (256k)
          Vega Video-7 Deluxe EGA (256k)
          Zenith EGA monochrome
________________________________________________________________________

Cards that loaded QB, but had numerous problems with screen swapping

          Techmar VGA
          Quadram VGA
          Vega-Video 7 Fastwrite VGA
          Vega VGA
 ________________________________________________________________________

Cards not guarenteed to load QB (cards in this section would not load QB,
but may)

          Compaq Laptop (BIOS problem - no fix)
          Genoa SuperVGA HiRes (models 5100 and 5200)
          VIP ATi VGA
          Sigma EGA!
________________________________________________________________________

In addition, these cards have been reported by support as potential
problem cards.

          Older Quadram CGA adapters
          Sperry Hercules compatible and CGA adapters
          (stock in Sperry machines)
          Leading Edge CGA and Hercules compatible adapters
          (stock in Leading Edge Model M machines)
________________________________________________________________________

{End of QUIRKS.TXT file}
