New items added 05/08/88 to 05/14/88:

Part 1 - READ (QB 4)
     2 - Watching a non-existant variable (Sample program #13)
-------------------------------------------------------------------------

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

  Part 1 - Description of bugs, quirks, etc.
  Part 2 - General points of interest
  Part 3 - Sample programs

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 -".

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 and
The MicroHelp Toolbox.

If you have additional information that should be added, please send it
to:
     Mark Novisoff
     MicroHelp, Inc.
     2220 Carlyle Drive
     Marietta GA 30062
     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: * Next to a QB 4 entry indicates that the problem has been
	fixed with the QB 4.00a that is included in BASCOM 6.

Command/Error  Compilers       Description
-------------- --------------- --------------------------------------------
$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/BSAVE    QB 4            When using these commands in DOS 2.x, you may
                               get an unexpected "too many files" error. This
			       problem can be solved using an assembly 
			       language routine to read/write the file.
			       (Mach 2 users should use MhFile/MhRWSub).
CALL (asm)     QB 4            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 INTERRUPT QB 4*           There is a bug in the source code (INTRPT.ASM).
                               If you have MASM 5.0, you can patch the source
			       code and reassemble. On line 49, the code
			       points to the DI register with "-1EH". This
			       should be changed to "-0EH", followed by
			       reassembly and library updates. If you don't
			       have MASM 5.0, the solution is to use INT86OLD,
			       or you can patch INTRPT.OBJ as follows (all
			       numbers are hexadecimal):
			       
			       Address   Old Value  New Value
			       -------   ---------  ----------
			         20E        E2          F2
				 253        E2          F2
				 28D        0B          EB
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). 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          QB 4            Unreliable when using DOS 2.x.
CIRCLE         QB 4            The start and end angles must be
                               LESS than 2*pi. Previously they could
			       be less than or equal to.
CLEAR          QB 4            If you use SETMEM to free up memory for
                               use by other routines or modules, the CLEAR
			       statement does 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.)
CLEAR,,Size    QB 3,4          If you receive an out of stack
                               space message. The stack size is
                               not reset between CHAIN'ing but if
                               you CHAIN back to your original
                               program, be sure to skip the CLEAR
                               instruction.
COMMON and     QB 2-4          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            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.
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.
CVL            QB 4*           This function is unreliable when a program
                               has been compiled with BC. See sample
			       program #8.
DATA           QB 4            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. 
DEFINT         QB 4            See $INCLUDE.
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.
DEF SEG        QB 4*          See sample program #11.
DIM            QB 3            See sample program #4. QB3 apparently has
                               a limit of 123 dynamic arrays.
DIM            QB 4            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            Static numeric arrays are stored on the
                               "heap" when you are inside the QB 4
			       environment. BC programs store them in the
			       default DS.
DIM (TYPE)     QB 4            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.
ERR            QB 4            Inside the QB 4 environment. If you watch
                               a variable, ERR does not get set properly
			       when an error occurs. See sample program #5.
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.
FILES          QB 3            There is a bug in the QB3-8087 compiler that
                               causes FILES not to work correctly.
FOR/NEXT       QB 4*           If you use a long integer as your loop
                               counter, with a negative STEP, your loop
			       will not execute.
FOR/NEXT       QB 4            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(-1)        QB 4            If a Quick Library is loaded, this value
                               may return incorrectly. QB 4 seems to
			       forget that the library is loaded and
			       thinks that the space is available. But,
			       QB 4 won't let you use the space for
			       dynamic arrays.
FRE("")        QB 4*           Using BRUN gives approximately 4K more
                               than BCOM. Here is a table showing the
			       difference between compilers for a one
			       line program PRINT FRE(""):
			          
				               BC     BC6
				       BRUN  57280   59912
				       BCOM  61560   61640
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            Cannot be used in $INCLUDE files.
GOTO           QB 4*           If you have a "GOTO GOTO" (two GOTOs) in
                               your program, QB 4.00 goes into never-never
			       land. You can still give a three-finger
			       salute, though.
HEX$           QB 4            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 compiler 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.
LEN            QB 4*           There is a problem using the LEN() function
                               with user defined types. See Sample Program #12.
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 INPUT     QB 4*           Don't attempt to LINE INPUT directly to a typed
                               variable (using TYPE...END TYPE) that has
			       a period in the name. Rather, LINE INPUT to a
			       temporary variable and then assign it to
			       the TYPE'd variable.
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. All QB 4
			       programs can use this switch. Syntax:
			         LINK /EXE Progname (etc.)
LINK           QB 4            When building a Quick Library, be sure
                               to specify BQLB40 in the library field. Example:
			         LINK /QU ObjMods,Lib,,BQLB40;
LOAD           QB 4            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.
ON ERROR        QB 4*          If you use "ON ERROR GOTO 0", two problems
			       can occur:
			         1. If an error occurs in your program,
				    your system will crash.
				 2. You may get a "Program memory overflow"
				    error from BC 4.
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.
OPEN COM        QB 4*          If you open the COM port within
                               the environment, then compile to an EXE
			       from within the environment, you get a
			       "far heap corrupt" error.
OPEN COM        QB 4*          If you open a COM port, close the port, then
                               do a SHELL, you cannot reopen the same port.
			       The compiler sets the COM port address
			       (at hex 40:0 through 40:7, depending on the
			       COM port number) to 0 and cannot find the
			       port. The solution is to leave the port
			       open during the SHELL. A fix is to save
			       these addresses before opening any ports:
			         DEF SEG=&H40
				 FOR I = 0 TO 7
				     PortAddress(I) = PEEK (I)
				 NEXT
				 DEF SEG
			       After closing a port, do:
			         DEF SEG = &H40
				 I = (PortYouOpened - 1) * 2
				 POKE I, PortAddress(I)
				 POKE I + 1, PortAddress(I + 1)
				 DEF SEG
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".
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)
PRINT #         QB 4           In order to print a blank line using QB 4,
                               use the syntax:
			         PRINT #, 
			       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           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.
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 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.
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.
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             QB 4           If you use SETMEM to free up memory for
                               use by other routines or modules, the RUN
			       statement does 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 CLEAR).
RUN             QB 4*          See sample program #3. If you use RUN in a
                               program that has soft key definitions, the
			       system will crash if the program was compiled
			       with BC. It will work OK in the environment.
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          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           You cannot have a line number or label 
                               between the SELECT CASE and the first CASE.
SELECT CASE     QB 4*          Doesn't allow periods in variable names that
                               are "plain" variables. If using a TYPE'd
			       record element (which does indeed use periods),
			       QB 4 will accept that with no problem.
SHELL           QB 4           Unreliable when using DOS 2.x.
SIGNAL          QB 4*          BC 6 - Similar to event trapping, but for OS/2.
SLEEP           QB 4*          BC 6 - Suspends the program, waiting for a
                               user-defined event.
SOUND           QB 3/87        Generates error 6 in all forms when the
                               emulator is used on non-87 machines.
STATIC          QB 4           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 Space    QB 4           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           Cannot be used in $INCLUDE files. Cannot
                               have the same name as a variable (regardless
			       of the variable type).
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 reportedly occurs when the record
			       length is an odd number of bytes. It 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.
VAL             QB 4           Generates an error (rather than value of 0)
                               when "%" is the first character in the string.
WINDOW          QB 2-4         Does not affect DRAW statements.
----------------------------------------------------------------------------
Part 2 - General points of interest

----------------------------------------------------------------------------
Watching a non-existant variable QB 4*

(Applies only when the subprogram does *not* have the STATIC keyword.)

If you have a program that does a CALL from within a subroutine (i.e., 
inside a GOSUB..RETURN), and you attempt to watch a variable that does
not exist (using Alt-D-Enter), your system will go into never-never land.
See sample program #13.

----------------------------------------------------------------------------
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.
----------------------------------------------------------------------------
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 

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
----------------------------------------------------------------------------
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.
----------------------------------------------------------------------------
Patching QB 4 menu and help colors.

This color table in this file was uploaded by Dave Engfer to the 
MicroHelp Basic Users Group BBS. Note that if you are running QB on a 
Hercules board, these patches won't have any effect.

If you don't like the colors that QB 4.0 uses, you can patch it to show
the colors you want. In order to effect your patches, do the following:

  Make a backup copy of QB.EXE.
  REN QB.EXE QB <Enter>
  DEBUG QB <Enter>
  R <Enter>
    
At this point, debug will show you the current register settings and
the current instruction. Something like this:

-r
AX=0000  BX=0003  CX=82A0 etc.
DS=xxxx  ES=xxxx  SS=xxxx etc.
xxxx:0100 RD       DEC     BP

The "xxxx" is the current code segment. On my machine, the value is 2A28.
The color table that QB uses is located near the end of the QB program, 
specifically 3 full segments higher than "xxxx". That means you will
need to add 3000 hex to the number of the segment shown. In my case,
I would patch segment 5A28. Note that adding 3 to the first of the four
hex numbers does the trick.

Now, with the higher segment address in mind, display the existing color
table. Remember, the segment on your machine is most likely different
from mine, but the offset "5B6F" should be the same. On my system:

   d 5A28:5B6F <Enter>

gives the following table (on my system, "xxxx" is 5A28):
   
xxxx:5B60                                              34
xxxx:5B70 30 4F 34 30 38 4F 47 34-38 70 71 74 07 47 0A 30
xxxx:5B80 3F 17 4A 00 07 70 70 0F-7F 70 78 0F 07 7F 70 70 etc.

Below you'll find a table of the colors and what Dave thinks they represent.
Note that some are marked "unknown". Dave suspects they may be related to
rodents.

You can change your copy of QB to display the various colors by changing
the values in the table. The formula for determining color is the same as
in Mach 2: Attribute=Background*16+Foreground.

As an example, suppose you want to change the "top line highlight" to
red on green. The color attribute we want (in HEX for debug) is
2*16+4 or 36 decimal or 24 HEX.

So, to patch that color:

-e xxxx:5B71 24 <Enter>
-w <Enter>
-q <Enter>
REN QB QB.EXE

Now, when you hold the Alt key (without pressing anything else), "File"
appears in red on green.

     Original Color        Addr  Byte   Effect        
     ---------------------------------------------------------------------
     Red on Cyan           5B6F   34    The outline for the pulldown boxes
     Black on Cyan         5B70   30    The Color for the top line
     Bright White on Red   5B71   4F    Top line Highlight (e.i. press 'Atl'
                                        and the option will highlight)
     Red on Cyan           5B72   34    Top line first letter highlight
     Black on Cyan         5B73   30    Pulldown box text and background-active
     Bright Black on Cyan  5B74   38    Pulldown box text/background-inactive
     Bright White on Red   5B75   4F    Pulldown box highlight line-active
     White on Red          5B76   47    Pulldown box highlight line-inactive
     Red on Cyan           5B77   34    Pulldown box first letters-active
     Bright Black on Cyan  5B78   38    Pulldown box first letters-inactive
     Black on White        5B79   70    Frame around the Help box- Shft F1
     Blue on white         5B7A   71    Help box selection area- Shft F1
     Red on White          5B7B   74    Help box first letter highlight- F1
     White on Black        5B7C   07    Normal text (Default)
     White on Red          5B7D   47    Breakpoint line (Default)
     Bright Green on Black 5B7E   0A    Current line (Default)
     Black on Cyan         5B7F   30    Bottom line prompt text
     Bright White on Cyan  5B80   3F    Microsoft Copyright Notice  

Notes-     
     * - Microsoft uses two different color bytes for the pulldown boxes.
     1 - This byte seems to be used for options with a highlight letter.
     2 - This byte seens to be used for options without a highlight letter.
----------------------------------------------------------------------------
DTR patch (QB4 BCOM)

See instructions on patching colors (above) for patching BCOM40.LIB so that
standalone programs do not drop DTR during a SHELL. A side effect is that
after closing the COM file, DTR remains up. Also all incoming data is lost
during the SHELL.

Patch the 1st segment above the default DS (add &H1000 to default). All
values are in HEX.

   Address  Old Value  New Value
   -------  ---------  ---------
    2A42       32         B0
    2A43       C0         01
    2D0C       32         B0
    2D0D       C0         B1

----------------------------------------------------------------------------
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 when "RUN" is used in a program
that contains soft key definitions. Compile with BC in QB 4.
* Note: This problem has been fixed in BC 6.

KEY 1, "Anything" + CHR$(13)	' Previous Quirks.Txt had "RUN"
KEY 2, "END" + CHR$(13)
PRINT "If you compiled with BC.EXE, RUN will crash your program"
INPUT "(F1=RUN  F2=END)  ", yn$
IF yn$ = "Anything" THEN RUN
END
----------------------------------------------------------------------------
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 that the ERR variable does not get set
when you "watch" a variable in a subprogram inside the QB 4 environment.

Load this program into the QB 4 environment. Alt-V to view the sub
"CheckFSpec". Alt-D <Enter> to watch any variable, then step through
the program using F8. When you get to the ERRORHANDLER routine, watch
ERR.

DECLARE SUB CheckFSpec (FlName$)
COMMON SHARED ErrCode%
ErrCode% = 0
a$ = "c:\quickey\data\tape2.000"
CALL CheckFSpec(a$)
CLOSE
END
ERRORHANDLER:
IF ErrCode% = 0 OR ERR <> 0 THEN ErrCode% = ERR
RESUME NEXT
SUB CheckFSpec (FlName$) STATIC
ON ERROR GOTO ERRORHANDLER
OPEN FlName$ FOR INPUT AS #1
ON ERROR GOTO 0
IF ErrCode% = 0 THEN
    PRINT "Opened "; FlName$; " successfully."
ELSE
    PRINT "Error"; ErrCode%; " attempting to open "; FlName$; "."
END IF
END SUB
----------------------------------------------------------------------------
Sample program #6. Demonstrates long integer calculation program. This 
program will run in QB 4.00 and 4.00a, but it gives incorrect results
using BC or BC 6.

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.
----------------------------------------------------------------------------
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 #8. Demonstrates unreliability of CVL in BC of QB4. The
problem has been fixed in the BC that comes with BASCOM 6.

DIM hold$(6), array&(6)
 
DATA 100,200,300,400,500,600
 
'Simulate an array of long integers packed to strings 
'(MKL$) as it might be read from a FIELDed random file 
 
FOR element = 1 TO 6
READ num&                                        
hold$(element) = MKL$(num&)
NEXT
 
'Convert the "fielded" strings to a long-integer array
 
FOR element = 1 TO 6
array&(element) = CVL(hold$(element))
PRINT array&(element)  '<-- Note different answers in QB4 and BC4
NEXT
----------------------------------------------------------------------------
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.

  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 #11. Demonstrates a problem occuring with BC in QB 4. The
problem has been corrected with BASCOM 6. This program will work as
expected inside the QB 4 environment.

  DEFINT A-Z
  DEF SEG = &HB000	' Monochrome video memory. Use &HB800 for color.
  X = PEEK(1)		' Attribute at column 1, row 1
  PRINT X
  DEF SEG
  X = PEEK(1)
  PRINT X
  
  However, BC, in its attempt to optimize, does not recognize
  the DEF SEG and (says) "I have already figured out PEEK(1), so
  why go thru the motions again?" and does not do the peek again,
  just returns the previous value. The fix is to do a different
  PEEK after the DEF SEG, thus "fixing" the code optimization bug.

----------------------------------------------------------------------------
Sample program #12. Demonstrates a problem with the LEN() function when
used with a user defined type. The program will generate a "string formula
too complex error in QB 4.

OPTION BASE 1
TYPE AccItem
   AccNumber AS STRING * 4
   Accname   AS STRING * 10
   January   AS DOUBLE
   February  AS DOUBLE
   March     AS DOUBLE
   April     AS DOUBLE
   May       AS DOUBLE
   June      AS DOUBLE
   July      AS DOUBLE
   August    AS DOUBLE
   September AS DOUBLE
   October   AS DOUBLE
   November  AS DOUBLE
   December  AS DOUBLE
END TYPE
 
DIM AccRecord(1 TO 56) AS AccItem
FOR I% = 1 TO 56
  PRINT LEN(AccRecord(I%).Accname);
  PRINT I%
NEXT
 
----------------------------------------------------------------------------
Sample program #13. Demonstrates a problem when watching a non-existant
variable in a subprogram that was CALLed from a subroutine. Note that
this only happens if the subprogram does *not* have the STATIC keyword.

Load this program into the QB 4 environment. Set a breakpoint on
the "I = I" statement. RUN the program. When you hit the breakpoint,
do an Alt-D-Enter, followed by a non-existant variable name. Presto,
you shall crash!

   DECLARE SUB NotStaticSub (ARG)
   GOSUB ASUB 'The CALL must be within a GOSUB..RETURN structure.
   END
ASUB:  CALL NotStaticSub(ARG)
   RETURN
SUB NotStaticSub (ARG)  'Note this is not a STATIC subprogram
   I = I  '********** SET A BREAK POINT HERE ***********
END SUB
