home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progbas
/
knowbase.arj
/
KNOWBASE.ASC
Wrap
Text File
|
1991-05-01
|
256KB
|
6,879 lines
This is a download of current messages under the QUICKBASIC and BASIC 7
topics in the KnowledgeBase section of Microsoft Online.
_____________________________________________________________________________
Q41149 Single Precision Numbers Have 1 to 7 Digits; Double Have 8+
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The documentation below should be changed to say that a constant is
single precision if it has fewer than eight digits and is double
precision if it has eight or more digits.
This correction applies to the following documentation:
1. Page 24 of "Microsoft QuickBASIC: BASIC Language Reference" manual
for Versions 4.00 and 4.00b for MS-DOS.
2. Page 24 of "Microsoft BASIC Compiler: BASIC Language Reference" for
Versions 6.00 and 6.00b for MS OS/2 and MS-DOS. (Note: This is the
same as QuickBASIC's language reference manual.)
3. Page 18 of the "Microsoft QuickBASIC: BASIC Language Reference"
manual for QuickBASIC Version 4.50. This manual must be ordered
separately from the Version 4.50 package.
4. The QuickBASIC Version 4.50 QB Advisor on-line help system, when
you select "Help - Contents - Data Types - Constants".
More Information:
The above pages INCORRECTLY state that a number is single precision if
it has fewer than 15 digits and is double precision if it has more than
15 digits.
This documentation error was corrected in the "Microsoft BASIC 7.0:
Language Reference" manual of Microsoft BASIC PDS Version 7.00 for
MS-DOS and MS OS/2.
The above products follow the IEEE standard format for storage of
floating-point numbers.
Keywords: docerr B_BasicCom SR# S890208-209
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/13 04:12
_____________________________________________________________________________
Q51605 Example of Gaussian Elimination; Matrix Math in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
This article explains the purpose of Gaussian elimination and gives
a code example.
In Microsoft BASIC PDS (Professional Development System) Version 7.00
for MS-DOS and MS OS/2, the following FUNCTION procedures perform
Gaussian elimination:
MatSEqnS% (for single-precision)
MatSEqnD% (for double-precision)
MatSEqnC% (for currency data type)
The source code of all of these functions is provided in the MATB.BAS
source file on one of the release disks. To use these functions in the
QuickBASIC Extended editor, load the MATBEFR.QLB Quick library as
follows:
QBX /L MATBEFR.QLB
MATFEFR.QLB and the related .LIB files are mentioned in the $INCLUDE
file MATB.BI. MATB.BI contains DECLARE FUNCTION statements necessary
for the matrix math routines.
More Information:
Definitions
-----------
1. A matrix is a two-dimensional array in BASIC.
2. A vector is a one-dimensional array in BASIC.
3. An identity matrix is a square array composed of 1's along the
diagonal from upper left to lower right, with all else 0's (zeros).
Gaussian Elimination
--------------------
A linear equation of n variables (unknowns) has the following form:
a1*x1 + a2*x2 + an*xn = b
where:
a1 through an and b are known constants, and x1 through xn are
variables with unknown values.
Linear equations do not involve any products or roots of variables.
All variables are to the first power, and don't appear as arguments
of trigonometric, logarithmic, or exponential functions.
A solution of a linear equation is a sequence of n numbers (s1 through
sn) such that the equation is satisfied when we substitute x1=s1,
x2=s2, ..., xn=sn.
A set of multiple linear equations in the variables x1 through xn is
called a system of linear equations. The set (vector) of constants s1
through sn is called a solution of the system if it provides a
solution for every equation in the system. Every system of linear
equations has either no solutions, exactly one solution, or infinitely
many solutions.
A system of m linear equations in n unknowns can be written as follows
in BASIC:
a(1,1)*x1 + a(1,2)*x2 + ... + a(1,n)*xn = b(1)
a(2,1)*x1 + a(2,2)*x2 + ... + a(2,n)*xn = b(2)
... ...
a(m,1)*x1 + a(m,2)*x2 + ... + a(m,n)*xn = b(m)
If you mentally keep track of the location of the +'s, the x's, and
the ='s, the arrays a(m,n) and b(m) provide a shorthand notation for
the system of linear equations. In elementary linear algebra texts,
a(m,n) and b(m) together make what is called the "augmented matrix."
Again, our goal is to discover the unknown values s1 through sn that,
when assigned to variables x1 through xn, solve every equation.
Gaussian elimination reduces the augmented matrix [the combination of
a(m,n) and b(m)] to a matrix of reduced row-echelon form, which looks
like a square identity matrix attached to a 1 by m vector [ b() ]. The
vector b() contains the solution set (s1 through sn) of the system of
linear equations.
The Gaussian elimination functions MatSEqnS%, MatSEqnD%, and MatSEqnC%
accept a square matrix a() and a vector b() as input arguments
(together composing the input-augmented matrix), and give the solution
in the one-dimensional array b(). After you invoke the function, a()
is replaced with the identity matrix, and the solution values
overwrite the input arguments that you had placed in b(). The n
solution values in b(), when assigned to variables x1 through xn,
satisfy every equation in the system.
For more information about linear algebra, the following is an
excellent text:
"Elementary Linear Algebra, Second Edition", by Howard Anton,
published by John Wiley & Sons, 1977
Code Example
------------
' This program demonstrates Gaussian elimination to solve a set of
' linear equations using double-precision variables.
' The MATSEQND, MATSEQNS, and MATSEQNC matrix math routines are
' provided in the Matrix Math Toolbox in Microsoft BASIC 7.00 for
' MS-DOS and MS OS/2.
'
' To run this program in the QuickBASIC Extended editor, load the
' MATBEFR.QLB Quick library as follows:
'
' QBX /L MATBEFR.QLB
'
' MATFEFR.QLB and the related .LIB files are documented in the INCLUDE
' file 'MATB.BI' but NOT in "Microsoft BASIC 7.0: Language Reference."
DECLARE FUNCTION MatSEqnD% (A() AS DOUBLE, b() AS DOUBLE)
' The above DECLARE statement is all that is needed from the following
' include file: REM $INCLUDE: 'matb.bi'
DEFDBL A-Z
OPTION BASE 1 ' Use OPTION BASE 1 for easier reference.
DIM A(3, 3), b(3)
' The following system of linear equations:
PRINT " x + y + 2*z = 9"
PRINT " 2*x + 4*y - 3*z = 1"
PRINT " 3*x + 6*y - 5*z = 0"
' ...can be represented in the following matrix:
' 1 1 2 9
' 2 4 -3 1
' 3 6 -5 0
' ...which can be placed in arrays a() and b() respectively as follows:
' a(1,1) a(1,2) a(1,3) b(1)
' a(2,1) a(2,2) a(2,3) b(2)
' a(3,1) a(3,2) a(3,3) b(3)
A(1, 1) = 1
A(1, 2) = 1
A(1, 3) = 2
A(2, 1) = 2
A(2, 2) = 4
A(2, 3) = -3
A(3, 1) = 3
A(3, 2) = 6
A(3, 3) = -5
b(1) = 9
b(2) = 1
b(3) = 0
errcode% = MatSEqnD%(A(), b())
PRINT "The following values for x, y, and z solve all three equations:"
PRINT "x="; b(1)
PRINT "y="; b(2)
PRINT "z="; b(3)
' Here is the output, accurate to within double-precision limits:
' x= 1.00000000000001
' y= 2
' z= 3
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/14 05:20
_____________________________________________________________________________
Q45170 Using CALL INTERRUPT to Return DOS Version Number
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The program shown below demonstrates how to use CALL INTERRUPT to
return the DOS version number.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50 and to the Microsoft BASIC Compiler Versions 6.00, and 6.00b
for MS-DOS, and to Microsoft BASIC PDS Version 7.00 for MS-DOS.
The following program is INTVER.BAS:
' $INCLUDE: 'qb.bi'
' For BC.EXE and QBX.EXE in BASIC 7.00 the include is 'QBX.BI'
DIM inregs AS RegType, outregs AS RegType
inregs.ax = &H3000
CALL INTERRUPT(&H21, inregs, outregs)
majorver = outregs.ax AND &HFF
minorver = (outregs.ax AND &HFF00) / 256
PRINT "MS-DOS Version: "; majorver; "."; minorver
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/14 05:20
_____________________________________________________________________________
Q45171 How to Detect Keypress in BASIC without Reading in Character
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The program shown below demonstrates how to check for a keypress
without reading in the character, thus leaving the character in the
keyboard buffer.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50 and to Microsoft BASIC Compiler Versions 6.00, and 6.00b for
MS-DOS, and to Microsoft BASIC PDS Version 7.00 for MS-DOS.
More Information:
The following program, INTKEY.BAS, uses an MS-DOS interrupt to check
if a key has been pressed. This can be used to check for a keypress
before doing an INPUT, LINE INPUT, or INKEY$ statement. This approach
is an alternative to invoking the INKEY$ function, which takes one
character at a time out of the keyboard buffer.
This example uses MS-DOS interrupt 33 (21 hex) with function call 11
(0B hex), "Check Input Status." For more information about MS-DOS
interrupts, please refer to "Advanced MS-DOS Programming" (Second
Edition) by Ray Duncan (published by Microsoft Press, 1988).
Example
-------
' $INCLUDE: 'qb.bi'
' For BC.EXE and QBX.EXE in BASIC 7.00 the include file is 'QBX.BI'
DIM inregs AS RegType, outregs AS RegType
inregs.ax = &HB00 ' Move a hex value of B into the AH register
outregs.ax = 0
PRINT "Press any key: "
DO
CALL INTERRUPT(&H21, inregs, outregs)
LOOP UNTIL (outregs.ax AND &HFF) = &HFF
INPUT X$ ' The first character typed appears in the INPUT line.
' Or you can PRINT INKEY$ instead of using INPUT X$ to see the
' character waiting in the keyboard buffer.
Keywords: B_BASICCOM
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/14 05:20
_____________________________________________________________________________
Q43256 CALL INTERRUPT RegType in Manual Inconsistent with QB.BI File
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
In the following manuals, the RegType (user-defined TYPE) documented
with the CALL INTERRUPT statement is inconsistent with the TYPE in
QB.BI, the $INCLUDE file:
1. Page 90 of the "Microsoft QuickBASIC 4.0: BASIC Language Reference"
for QuickBASIC Versions 4.00 and 4.00b for MS-DOS and for
Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS
OS/2
2. Page 74 of the "Microsoft QuickBASIC 4.5: BASIC Language
Reference," which is available for separate purchase after you buy
QuickBASIC Version 4.50
More Information:
To correct the inconsistency, remove the following two statements from
the RegType in the manual:
DS AS INTEGER
ES AS INTEGER
The RegType shown in the manual is actually the RegTypeX in the QB.BI
$INCLUDE file.
This documentation error has been corrected in Microsoft BASIC PDS
Version 7.00 for MS-DOS and MS OS/2. The TYPE descriptions in the
"Microsoft BASIC 7.0: Language Reference" for RegType and RegTypeX on
Pages 172-173 agree with the TYPE declarations in the QBX.BI $INCLUDE
file supplied with BASIC PDS 7.00.
The RegType defined in the QB.BI file (used with $INCLUDE) does not
contain the DS and ES registers. The DS and ES registers are only
needed for the CALL INTERRUPTX statement, which uses RegTypeX.
Keywords: SR# S890406-35 docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/15 04:02
_____________________________________________________________________________
Q50943 Using CALL INTERRUPT to Get Current SCREEN Video Mode
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
It is possible to get the current SCREEN mode using the CALL INTERRUPT
statement in compiled BASIC. This is useful if the program does not
keep track of the current SCREEN mode, and the current video state
needs to be saved.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50 for MS-DOS, Microsoft BASIC Compiler Versions 6.00, and 6.00b
for MS-DOS, and to Microsoft BASIC PDS Version 7.00 for MS-DOS.
More Information:
The following BASIC program allows you to change the video mode, then
uses CALL INTERRUPT to return the current video mode. The return
values from the CALL INTERRUPT are not the same as the BASIC SCREEN
modes, so the program creates an array that is used to translate the
returned values back to BASIC SCREEN modes.
Code Example: SCRMODE.BAS
-------------------------
REM $INCLUDE: 'qb.bi' ' defines for CALL INTERRUPT
' For BC.EXE and QBX.EXE for BASIC 7.00, use the include file 'QBX.BI'
' and the Quick library QBX.QLB.
DIM inregs AS regtype
DIM outregs AS regtype
DIM screenarray(19) AS INTEGER
FOR i% = 0 TO 19
READ screenarray(i%)
NEXT
INPUT "enter screen mode: "; smode%
inregs.ax = &HF00 ' BIOS interrupt to return video mode
CALL interrupt(&H10, inregs, outregs)
smode% = outregs.ax AND &HFF ' mask off contents of AL register
PRINT "Current screen mode = "; screenarray(smode%)
' Define conversion array for SCREEN modes
DATA 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 7, 8, 10, 9, 11, 12, 12
END
To demonstrate this program from an .EXE program, compile and link as
follows:
BC SCRMODE.BAS;
LINK SCRMODE,,,QB.LIB;
For BASIC PDS 7.00, use QBX.LIB instead of QB.LIB.
If you run the program within the QuickBASIC QB.EXE editor, the
default Quick library QB.QLB must be loaded in, as follows:
QB SCRMODE /L
For QBX.EXE 7.00, the default Quick library QBX.QLB must be loaded in,
as follows:
QBX SCRMODE /L
Keywords: SR# S891113-112 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/15 04:02
_____________________________________________________________________________
Q50947 How to Get Extended Error in QuickBASIC Like EXTERR in GWBASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The EXTERR function found in GW-BASIC Versions 3.20, 3.22, and 3.23 is
not built into QuickBASIC Versions 4.00, 4,00b, 4.50, or earlier, but
below is a code example calling a DOS interrupt that returns the same
information (concerning extended errors in MS-DOS 3.00 and later).
This code example applies to Microsoft QuickBASIC Versions 4.00,
4.00b, and 4.50 for MS-DOS, Microsoft BASIC Compiler Versions 6.00,
and 6.00b for MS-DOS, and to Microsoft BASIC PDS Version 7.00 for
MS-DOS.
More Information:
The EXTERR function found in GW-BASIC takes a value of n as an
argument and returns a different set of values, depending on the value
of n. This return value gives detailed information on the most recent
DOS error. For all values of n, EXTERR returns 0 (zero) if there was
no previous DOS error, or if the version of DOS is earlier than 3.00.
Value of n EXTERR(n) Return Value
---------- ----------------------
0 Extended error code
1 Extended error class
2 Extended error suggested action
3 Extended error locus
To find what the error codes returned by EXTERR mean, look up the
values in "Advanced MS-DOS Programming, 2nd Edition" by Ray Duncan
(published by Microsoft Press, 1988) on Pages 145 and 146. This book
also documents the interrupt used below, along with the extended error
codes on Pages 453 through 456.
Compile and link with Microsoft QuickBASIC 4.00, 4.00b. and 4.50, or
with Microsoft BASIC Compiler 6.00 and 6.00b as follows:
BC Test.bas;
LINK Test.bas,,,BRUNxx.Lib+QB.Lib;
The "xx" in the library name is for the current version of the product
you are using (40, 41, 45, 60, or 61). For BASIC compiler 6.00 and
6.00b, use BRUNxxER.LIB (emulation math package) or BRUNxxAR.LIB
(alternate math package). For the alternate math library, you must
compile with the BC /FPa switch. If you compile with BC /O, link with
BCOMxx.LIB instead of BRUNxx.LIB.
Also, if you run this program in the QB.EXE environment, you must load
the Quick library QB.QLB as follows:
QB /L QB.QLB
For BASIC PDS 7.00, compile and link as follows:
BC Test.bas;
LINK Test.bas,,,BRT70ENR.Lib+QBX.Lib;
The above example is for the math emulation, near strings, and real
mode run-time library. The other posible run-time libraries and their
corresponding compiler switches are as follows:
Library Name Compiler Switches Comments
------------ ----------------- --------
BRT70ENR.LIB Emulation math, near strings
BRT70ANR.LIB /FPa Alternate math, near strings
BRT70EFR.LIB /Fs Emulation math, far strings
BRT70AFR.LIB /FPa /Fs Alternate math, far strings
To use stand-alone libraries, use BCL70xxx.LIB instead of
BRT70xxx.LIB, and you must add the compiler switch BC /O.
For the QBX.EXE 7.00 environment, use QBX.QLB as follows:
QBX /L QBX.QLB
Code Example
------------
REM $INCLUDE: 'QB.BI'
' For BC.EXE and QBX.EXE in BASIC 7.00, use the include file 'QBX.BI'
DIM Inregs AS RegTypeX, Outregs AS RegTypeX
CLS
INPUT "Enter the filename "; test$
test$ = test$ + CHR$(0)
Inregs.ax = &H3D00
Inregs.ds = VARSEG(test$)
' For BASIC Compiler 7.00 and QBX.EXE use SSEG(test$)
' instead of VARSEG(test$)
Inregs.dx = SADD(test$)
CALL INTERRUPTX(&H21, inregs, outregs)
check = outregs.flags AND &H1
IF check = 1 THEN
PRINT "The file was not found"
Inregs.ax = &H5900
Inregs.bx = inregs.bx AND &HFF
CALL INTERRUPTX(&H21, Inregs, Outregs)
PRINT "This is the error number"; Outregs.ax
ELSE
PRINT "Your file was found, no extended error information is needed"
END IF
END
Keywords: SR# S891107-92 B_BasicCom B_GWBasicI
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/15 04:02
_____________________________________________________________________________
Q40886 PUT Statement Correction, Page 342 QB Language Reference
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b
MS-DOS
Summary:
Page 342 of the "Microsoft QuickBASIC: BASIC Language Reference"
manual for Versions 4.00 and 4.00b and the "Microsoft BASIC 6.0
Compiler: BASIC Language Reference" manual for Versions 6.00 and
6.00b, ("PUT Statement - File I/O") incorrectly states the following:
...characters in the string's value. For example,
the following two statements write 15 bytes to file
number 1:
VarString$=STRING$ (15, "X")
GET #1,,VarString$
The GET should be changed to PUT as follows:
VarString$=STRING$ (15, "X")
PUT #1,,VarString$
This documentation error was corrected in the QuickBASIC Version 4.50
QB Advisor on-line Help system and in the "Microsoft QuickBASIC 4.5:
BASIC Language Reference" manual for Version 4.50 and in the
"Microsoft BASIC 7.0: Language Reference" manual for Microsoft BASIC
PDS Version 7.00 for MS-DOS and MS OS/2.
Keywords: B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/16 04:03
_____________________________________________________________________________
Q41389 SIGNAL Is BASIC Reserved Word; SIGNAL ON Usable Only in OS/2
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The ON SIGNAL(n) GOSUB and SIGNAL ON statements are implemented only
in OS/2 protected mode for programs compiled with BC.EXE in Microsoft
BASIC Compiler Versions 6.00 and 6.00b or Microsoft BASIC PDS Version
7.00.
SIGNAL is a reserved word in QuickBASIC Versions 4.00, 4.00b, and
4.50, Microsoft BASIC Compiler Versions 6.00 and 6.00b, and Microsoft
BASIC PDS Version 7.00. However, the SIGNAL statements will be
accepted only by BASIC compiler 6.00 and 6.00b and BASIC PDS 7.00 when
compiling in protected mode under OS/2. In all other situations, a
SIGNAL statement results in an "Advanced feature unavailable" error
message.
More Information:
The BC.EXE compiler that comes with BASIC compiler 6.00 and 6.00b and
BASIC PDS 7.00 supports the ON SIGNAL(n) GOSUB and SIGNAL ON
statements, as documented in Section 5 (Pages 27-29) of "Microsoft
BASIC Compiler 6.0: User's Guide" for Versions 6.00 and 6.00b for MS
OS/2 and MS-DOS and the "Microsoft BASIC 7.0: Language Reference"
manual on Pages 341-342.
Below is an example of the correct use of the ON SIGNAL(n) GOSUB and
SIGNAL ON statements. This program is supported only if you compile in
OS/2 protected mode with BC.EXE from Microsoft BASIC Compiler Version
6.00 or 6.00b, or Microsoft BASIC PDS Version 7.00, and run the
resulting executable in protected mode:
PRINT "This program traps CTRL+BREAK in OS/2. Try it."
ON SIGNAL(4) GOSUB trap
SIGNAL(4) ON
10 a$ = INKEY$
IF a$ = "" THEN GOTO 10
END
trap:
PRINT "CTRL+BREAK trapped. Press any key to quit"
RETURN
The above program always reports "Advanced feature unavailable" when
run in real mode (DOS) as a compiled executable or when run inside the
QuickBASIC QB.EXE or the BASIC PDS 7.00 QBX.EXE environments.
Keywords: B_BasicCom SR# S890125-25
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/16 04:03
_____________________________________________________________________________
Q43252 Must DECLARE a FUNCTION Invoked from an External Library
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
To use a FUNCTION that is in a library (.LIB) or Quick Library (.QLB),
you must have a DECLARE statement at the top of each module that uses
the FUNCTION. This is documented in the "Microsoft QuickBASIC 4.0:
BASIC Language Reference" manual for Versions 4.00 and 4.00b, Page
139, and the QuickBASIC 4.50 on-line QB Advisor by choosing <Help>
<Index> DECLARE Statement (BASIC Procedures) <Details> and in the
"Microsoft BASIC 7.0: Programmer's Guide" on Page 53.
The documentation states that you must use DECLARE if you invoke a
FUNCTION that is defined in another module. Library files (.LIB and
.QLB) are "other modules," as are SUBprogram or FUNCTION modules
that start from a separate .BAS or MS-DOS file.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50 for MS-DOS, to Microsoft BASIC Compiler Versions 6.00 and
6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC PDS Version 7.00
for MS-DOS and MS OS/2.
More Information:
There are two reasons that DECLAREs are necessary for FUNCTIONs and
not for SUBprograms.
1. The only way to identify a SUBprogram without a DECLARE is with a
CALL. You cannot use CALL with a FUNCTION because a FUNCTION
returns a value and must be used in an assignment statement.
2. Without the DECLARE, the compiler cannot know if you are referring
to a variable, array, or FUNCTION.
Consider the following BASIC statements:
'Is this a FUNCTION call or assignment of a variable?
VAR1# = Func1#
' Is this a FUNCTION call or is this assigning
' an array element to a variable?
VAR1# = Func1#(VAR2,VAR3)
The DECLARE FUNCTION Func1#(<variables>) statement tells the compiler
that you are using a FUNCTION when you use the name Func1# and that
this is not a variable or an array.
Keywords: SR# S890405-127 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/16 04:03
_____________________________________________________________________________
Q44035 WAIT Statement Can Access All 65535 Ports, Not Just 0 to 255
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
The documentation for the WAIT statement incorrectly states that the
input port number given as an argument to a WAIT statement can range
from 0 to 255 only. WAIT can actually address all 65,536 machine ports
(0 to 65535).
This information applies to the WAIT statement in the following
manuals:
1. Page 446 of "Microsoft QuickBASIC 4.0: BASIC Language Reference"
for Versions 4.00 and 4.00b for MS-DOS
2. Page 446 of "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Versions 6.00 and 6.00b for MS-DOS and MS OS/2
3. Page 507 of "Microsoft QuickBASIC Compiler" manual for Versions
2.0x and 3.00 for MS-DOS
This documentation error has been corrected in the "Microsoft BASIC
7.0: Language Reference" manual and in the Microsoft BASIC PDS 7.00
QBX.EXE Microsoft Advisor on-line Help system.
Keywords: B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/16 04:03
_____________________________________________________________________________
Q48059 "String Space Corrupt" If BSAVE Variable-Length-String Array
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
If you want to use BSAVE and BLOAD with string arrays, you must use an
array of fixed-length strings. Fixed-length strings are available in
Microsoft QuickBASIC Versions 4.00, 4.00b, and 4.50 for MS-DOS, in
Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS, and in
Microsoft BASIC PDS Version 7.00, but not in earlier versions.
Arrays of variable-length strings CANNOT be BSAVEd to a file, nor can
a file that was BSAVEd from a variable-length-string array be BLOADed
into another variable-length-string array. A "String space corrupt"
error message can display if you attempt to BLOAD a file into a
variable-length-string array, because the pointers in the BSAVEd
string descriptors will overlay and tangle existing pointers to string
space. This is the same mistake as POKEing a spurious value into a
string descriptor, which can corrupt the integrity of string space.
This information applies to Microsoft QuickBASIC Versions 1.00, 1.01,
1.02, 2.00, 2.01, 3.00, 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft
BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to
Microsoft BASIC PDS Version 7.00 for MS-DOS and MS OS/2.
More Information:
Each element of variable-length-string array has a 4-byte string
descriptor composed of an offset (a 2-byte pointer) and length field
(2 bytes). The array of string descriptors is stored sequentially, but
the actual contents of the strings are stored separately in the
dynamic string space. Each 2-byte offset points to a location in the
string space. The string space memory is very dynamic, and strings are
given new offsets whenever new string values are reassigned. The
string contents of an array are not usually adjacent, especially if
they have been reassigned values. As a result, BSAVEing a certain
number of bytes does not mean that you've BSAVEd the contents of the
variable-length-string array.
The following code example attempts to BSAVE a variable-length-string
array, but generates the error "String Space Corrupt" when run within
the QuickBASIC QB.EXE Version 4.00, 4.00b, or 4.50 environment.
To work around this situation, create fixed-length-string arrays and
BSAVE that information. Fixed-length-string space is allocated
statically and sequentially in memory, and can be BSAVEd and BLOADed.
Code Example
------------
This example requires Microsoft QuickBASIC Version 4.00, 4.00b, or
4.50 for MS-DOS, Microsoft BASIC Compiler Version 6.00 or 6.00b for
MS-DOS, or Microsoft BASIC PDS Version 7.00 for MS-DOS.
To alter this program to work correctly, change the DIMension
statements to create a fixed-length-string array and BSAVE just that
many bytes.
OPTION BASE 1
DIM Arr1$(10) ' Instead, use DIM Arr1(10) AS STRING*20
DIM Arr2$(10) ' Instead, use DIM Arr2(10) AS STRING*20
StrDesc% = 4
ArrayLength% = 0
PRINT "This is the BSAVE array:"
PRINT
FOR I = 1 TO 10
Arr1$(I) = "TEST" + STR$(I)
ArrayLength% = ArrayLength% + LEN(Arr1$(I))
PRINT Arr1$(I)
NEXT I
DEF SEG = VARSEG(Arr1$(1))
' In BC.EXE and QBX.EXE for BASIC 7.00 use SSEG for far variable
' length strings.
BSAVE "Test.Dat", VARPTR(Arr1$(1)), ArrayLength% + StrDesc%
DEF SEG
PRINT
PRINT "Hit a Key"
PRINT
SLEEP
DEF SEG = VARSEG(Arr2$(1))
' In BC.EXE and QBX.EXE for BASIC 7.00 use SSEG for far variable
' length strings.
BLOAD "Test.Dat", VARPTR(Arr2$(1))
DEF SEG
PRINT "This is the BLOADed array:"
PRINT
FOR I = 1 TO 10
PRINT Arr2$(I)
NEXT I
Keywords: SR# S890724-71 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/16 04:03
_____________________________________________________________________________
Q47753 List of Run-Time Error Numbers and Messages for QuickBASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
This article contains a complete list of run-time errors and their
corresponding numbers (returned by the ERR function). These errors can
be trapped with the ON ERROR GOTO statement.
This information applies to Microsoft QuickBASIC Versions 1.00, 1.01,
1.02, 2.00, 2.01, 3.00, 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft
BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to
Microsoft BASIC PDS Version 7.00 for MS-DOS and MS OS/2.
More Information:
Error Error
Code Description Code Description
----- ----------- ----- -----------
1* NEXT without FOR 37* Argument-count mismatch
2* SYNTAX error 38* Array not defined
3 RETURN without GOSUB 39** CASE ELSE expected
4 Out of DATA 40 Variable required
5 Illegal function call 50 Field Overflow
6 Overflow 51 Internal Error
7 Out of memory 52 Bad file name or number
8 Label not defined 53 File not found
9 Subscript out of range 54 Bad file mode
10 Duplicate definition 55 File already open
11 Division by zero 56 FIELD statement active
12* Illegal in direct mode 57 Device I/O error
13* Type mismatch 58 File already exists
14 Out of string space 59 Bad record length
16* String formula too complex 61 Disk Full
17* Cannot continue 62 Input past end-of-file
18 Function not defined 63 Bad record number
19 No RESUME 64 Bad file name
20 RESUME without error 67 Too many files
24 Device timeout 68 Device Unavailable
25 Device Fault 69 Communications-buffer overflow
26* FOR without NEXT 70 Permission denied
27 Out of paper 71 Disk not ready
29* WHILE without WEND 72 Disk-media error
30* WEND without WHILE 73 Advanced feature unavailable
33* Duplicate LABEL 74 Rename across disks
35* Subprogram not defined 75 Path/file access error
76 Path not found
* Denotes errors that usually occur at COMPILE TIME, but may
occur and be trapped during RUN TIME under special circumstances
** Denotes that the error number was removed in BASIC PDS 7.00
The following errors appear in Microsoft BASIC PDS Version 7.00 only:
80 Feature removed
81 Invalid name
82 Table not found
83 Index not found
84 Invalid column
85 No current record
86 Duplicate value for unique index
87 Invalid operation on null index
88 Database needs repair
The following undefined error numbers produce an "Unprintable error"
message if they are not trapped with the ON ERROR GOTO statement:
15, 21, 22, 23, 28, 31, 32, 34, 41-49, 60, 65, 66, 77, and upwards
For Microsoft BASIC PDS 7.00, the numbers that generate the
"Unprintable error" message are as follows:
15 ,21, 22, 23, 28, 31, 32, 34, 39, 41-49, 60, 65, 66, 77-79, 89
and upwards
For a more detailed explanation of the above errors, please consult
your language reference manual for BASIC or QuickBASIC, or your
"Microsoft QuickBASIC 4.5: Programming in BASIC" manual for Version
4.50, Appendix I, or the QB Advisor on-line Help system for QuickBASIC
Version 4.50, or your "Microsoft BASIC 7.0: Language Reference" manual
for BASIC PDS 7.00, Appendix D, or the Microsoft Advisor on-line Help
system for BASIC PDS Version 7.00.
You can invoke any error in the QB.EXE or QBX.EXE environment with the
ERROR statement. In QB.EXE 4.50 or QBX.EXE 7.00, the ERROR statement
displays the error message with the choice to receive Help on the
error. Choosing Help gives a brief explanation and some key points to
consider when tracking down the cause of the error.
Keywords: B_BasicCom SR# S890720-59
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/19 06:13
_____________________________________________________________________________
Q44492 Mandelbrot Example Needs to Change "LogicY" to a SINGLE
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The MANDEL.BAS program example on Pages 213-217 of the "Microsoft
QuickBASIC 4.5: Programming in BASIC" manual for Version 4.50, on
Pages 263-267 of the "Microsoft QuickBASIC 4.0: Programming in BASIC:
Selected Topics" manual for Versions 4.00 and 4.00b, and on Pages
211-215 of the "Microsoft BASIC 7.0: Programmer's Guide" for Microsoft
BASIC PDS Version 7.00 does not work correctly for all WINDOW
coordinates, unless the variable "LogicY" is changed to a SINGLE or
DOUBLE precision variable.
To correct the problem, change all occurrences of LogicY to LogicY! or
add the following line to the beginning of the program:
DIM LogicY AS SINGLE
This information applies to QuickBASIC Versions 4.00, 4.00b, and 4.50
for MS-DOS, to Microsoft BASIC Compiler Versions 6.00 and 6.00b for
MS-DOS and MS OS/2, and to Microsoft BASIC PDS Version 7.00 for MS-DOS
and MS OS/2.
For more information, query on the following words in this
Knowledge Base:
PMAP and MAP and WINDOW and INTEGER
Keywords: B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/21 04:37
_____________________________________________________________________________
Q44494 QuickBASIC 4.50 Arrays Can Have 60 Elements, Not Just 8
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
Appendix C, "Limits of QuickBASIC," on Page 337 of the "Microsoft
QuickBASIC 4.5: Programming in BASIC" manual for Version 4.50 and the
QuickBASIC Advisor on-line Help system incorrectly state that there
is a limit of 8 dimensions for arrays. The actual limit is 60.
Appendix C and the on-line Help system should read as follows:
Arrays Maximum Minimum
-----------------------------------------------------------------
Array Dimensions 60 1
This information was not included in the documentation for earlier
versions of QuickBASIC or Microsoft BASIC compiler.
This documentation error has been corrected in the "Microsoft BASIC
7.0: Programmer's Guide" for Microsoft BASIC PDS Version 7.00 and in
the Microsoft Advisor on-line Help system of the QBX.EXE environment
in Microsoft BASIC PDS 7.00.
Keywords: SR# S890423-1 docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/21 04:37
_____________________________________________________________________________
Q45483 Incorrect Number of Parameters to Quick Library Can Hang QB
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
When using FUNCTIONs or SUBprograms that are located in a Quick
library under QuickBASIC Versions 4.00, 4.00b, and 4.50 and under
QuickBASIC Extended in BASIC PDS Version 7.00, it is important to
DECLARE all Quick library routines that your program will be CALLing.
If fewer parameters than expected are passed to a SUBprogram in a
Quick library, your machine may hang, sometimes requiring the power to
be cycled to reboot the machine. This problem occurs only within the
environment and only when CALLing a Quick library routine.
If the program is CALLing a routine in another module that is loaded
into the QB.EXE environment, the expected error of "Argument count
mismatch" displays. When compiled to an EXE file, the error "Illegal
function call" displays.
Microsoft does not consider this to be a problem with QuickBASIC or
QBX.EXE of any version. The environment cannot perform parameter
checking without a DECLARE statement for each SUB or FUNCTION.
Therefore a DECLARE statement is required for each routine in a Quick
library in order for a program to function normally.
More Information:
If SUBprograms are not DECLAREd at the top of the module that makes
the calls, the SUBroutine must be CALLed. If you have a DECLARE SUB
for that SUBroutine, you need only to mention the SUBprograms followed
by any expected parameters.
When using FUNCTIONs, whether in another module or a Quick library,
the FUNCTION must be DECLAREd at the top of the calling module. If the
FUNCTION is not DECLAREd, the QuickBASIC environment interprets the
FUNCTION as an array.
For more information on SUBprograms and FUNCTIONs, consult Chapter 2
of the "Microsoft QuickBASIC 4.5: Programming in BASIC" manual for
Microsoft QuickBASIC Version 4.50 or Chapter 2 of the "Microsoft BASIC
7.0: Programmer's Guide" for Microsoft BASIC PDS Version 7.00.
The code example below illustrates the necessity of the DECLARE
statement. If the FUNCTION and SUBroutine are combined into a Quick
library and only one of the arguments is passed to the SUBprogram, the
computer hangs. If both arguments are passed, it executes as expected.
If the DECLARE FUNCTION is removed, a "Subscript out of range" is
generated when the FUNCTION is referenced.
Code Example
------------
Main Program
------------
DECLARE FUNCTION calculatesomething%(t AS INTEGER)
DEFINT A-Z
t = 100
x = 100 'to hang machine, change CALL statement to:
CALL printhello(t, x) 'CALL printhello(t)
a = calculatesomething(t)
PRINT a
Quick Library Routines
----------------------
SUB printhello(t AS INTEGER, x AS INTEGER)
PRINT "Hello from the SUBprogram: "; t, x
END SUB
FUNCTION calculatesomething%(t AS INTEGER)
calculatesomething% = t + t * t
END FUNCTION
Keywords: SR# S890525-13
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/21 04:37
_____________________________________________________________________________
Q46848 TAB Function Documentation Error in QuickBASIC 4.50 Manual
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
The example for the TAB function on Page 369 of the "Microsoft
QuickBASIC 4.5: BASIC Language Reference" for Version 4.50 is
incorrect. The output for the first display is in Column 1 when it
should be in Column 7.
This is not an error in the following:
1. The on-line help for the QuickBASIC 4.50 environment
2. The on-line help for the BASIC PDS 7.00 QuickBASIC Extended
environment
3. The "Microsoft BASIC Compiler 6.0: BASIC Language Reference" for
Versions 6.00 and 6.00b for MS OS/2 and MS-DOS
4. The "Microsoft BASIC 7.0: BASIC Language Reference" manual for
Version 7.00
5. The "Microsoft QuickBASIC 4.0: BASIC Language Reference" manual for
Versions 4.00 and 4.00b
The output on Page 369 should correctly show
one
two
three
0123456789012345678901234567890
four
to correspond to the code given for the TAB function.
Keywords: SR# S890627-141 docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/21 04:37
_____________________________________________________________________________
Q31882 DATA Statements Not Allowed in SUB or FUNCTION Procedures
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The DATA statement should be included in the list of statements
prohibited in procedure-level code on Page 50 of the following
manuals
1. "Microsoft QuickBASIC 4.0: Programming in BASIC: Selected Topics"
2. "Microsoft BASIC Compiler 6.0: Programming in BASIC: Selected
Topics"
3. Page 41 of the "Microsoft BASIC 7.0: Programmer's Guide"
manual.
More Information:
The DATA statement documentation on Page 135 in the BASIC language
reference manual correctly states that "DATA statements can only be
entered in the module-level code."
A module is defined as an individual source file, but "module level"
is a special term with a different meaning. The glossary on Page 350
of the "Microsoft QuickBASIC 4.0: Learning and Using QuickBASIC"
manual defines "module-level code" as follows:
(Module-level code is defined as) program statements within any
module that are outside a SUB or FUNCTION definition. Error- or
event-handling code and declarative statements such as COMMON,
DECLARE, and TYPE can appear only at the module level.
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/22 04:23
_____________________________________________________________________________
Q32789 Correction for COMMAND$ Function Example in Manual
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The correction below applies to the example program for the COMMAND$
function on Page 114 of the following manuals:
1. "Microsoft QuickBASIC 4.0: BASIC Language Reference"
2. "Microsoft BASIC Compiler 6.0: BASIC Language Reference"
On Page 114, the SUB statement on line seven incorrectly reads as
follows:
SUB Comline(NumArgs, Args$(1), MaxArgs) STATIC
This line should read as follows:
SUB Comline(NumArgs, Args$(), MaxArgs) STATIC
In brief, replace Args$(1) in the first statement with Args$().
This information also applies to the example program on Page 61 of the
"Microsoft BASIC 7.0: Language Reference" manual which comes with
Microsoft BASIC PDS Version 7.00.
On Page 61, the SUB statement on line five incorrectly reads as
follows:
SUB Comline(NumArgs,Args$,MaxArgs) STATIC
This line should read as follows:
SUB Comline(NumArgs,Args$(),MaxArgs) STATIC
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/22 04:23
_____________________________________________________________________________
Q40371 Using Medium and Large Memory FORTRAN Models with BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
The information below applies to QuickBASIC Versions 4.00, 4.00b, and
4.50, and Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS
and OS/2.
This information also applies to Microsoft BASIC PDS Version 7.00 for
MS-DOS and MS OS/2, but only when using near strings. (For more
information on using far strings in mixed-language programs, please
refer to Chapter 13, "Mixed Language Programming with Far Strings," in
the "Microsoft BASIC 7.0: Programmer's Guide." Note that far strings
are only available with BASIC PDS 7.00.)
Variables in a FORTRAN subroutine may be specified as being [NEAR] or
[FAR]. Likewise, QuickBASIC can pass parameters to a subroutine by
near or far reference. When parameters are passed as near and the
FORTRAN subroutine is compiled under the medium memory model or the
parameters are passed as far and the subroutine is compiled with the
large memory model option, the variables are passed correctly.
More Information:
The run-time error message "F2729 I/O item illegal in namelist I/O" is
reported if you try to use far pointers while compiling in the
medium memory model.
Example 1 below demonstrates a program that performs correctly when
near parameters are used and the FORTRAN subroutine is compiled using
the medium model (FL /AM) option. The parameters are passed
incorrectly when the FORTRAN subroutine in Example 1 is compiled with
the large model (FL /AL) option.
Example 2 is the equivalent program using the far option. Example 2
performs correctly when the FORTRAN subroutine is compiled with the
large model option.
The following is Example 1, which uses the medium memory model:
Compile in BASIC as follows: BC basprog/o;
Compile in FORTRAN as follows: fl /AM /APi /c forsub.for
Link as follows: LINK basprog forsub/noe;
The following BASIC program is BASPROG.BAS:
DECLARE FUNCTION MAKEIT$(S$,SIZE%)
DECLARE SUB DUM1(BYVAL S1%, BYVAL S2%, BYVAL S3%, BYVAL S4%)
DIM NAM%(3000)
COMMON /NMALLOC/ NAM%()
STR1$ = MAKEIT ("TEST OF PARAMETER VALUE PASSING" ,44)
STR2$ = MAKEIT ( "STRING 2" ,43)
STR3$ = MAKEIT ("STRING 3", 14)
STR4$ = MAKEIT ("STRING 4" ,14)
CALL DUM1(SADD(STR1$), SADD(STR2$), SADD(STR3$), SADD(STR4$))
END
FUNCTION MAKEIT$ (S$,SIZE%)
MAKEIT$ = LEFT$(S$+STRING$(80, 32),SIZE%)
END FUNCTION
The following FORTRAN program is FORSUB.FOR:
SUBROUTINE DUM1(STR1, STR2, STR3, STR4)
CHARACTER*14 STR3, STR4 [NEAR]
CHARACTER*43 STR1 [NEAR]
CHARACTER*44 STR2 [NEAR]
WRITE (*,*) STR1, STR2, STR3, STR4
END
The following is Example 2, which uses the large memory model:
Compile in BASIC as follows: BC basprog/o;
Compile in FORTRAN as follows: fl /AL /FPi /c forsub.for
Link as follows: LINK basprog forsub/noe;
The following BASIC program is BASPROG.BAS:
DECLARE FUNCTION MAKEIT$(S$,SIZE%)
DECLARE SUB DUM1(BYVAL S1%, BYVAL S2%, BYVAL S3%, BYVAL S4%,_
BYVAL S5%, BYVAL S6%, BYVAL S7%, BYVAL S8%)
DIM NAM%(3000)
COMMON /NMALLOC/ NAM%()
STR1$ = MAKEIT ("TEST OF PARAMETER VALUE PASSING" ,44)
STR2$ = MAKEIT ( "STRING 2" ,43)
STR3$ = MAKEIT ("STRING 3", 14)
STR4$ = MAKEIT ("STRING 4", 14)
CLS
LOCATE 10,1
CALL DUM1(VARSEG(STR1$),SADD(STR1$), VARSEG(STR2$),SADD(STR2$),_
VARSEG(STR3$), SADD(STR3$), VARSEG(STR4$), SADD(STR4$) )
LOCATE 24,1
END
FUNCTION MAKEIT$ (S$,SIZE%)
MAKEIT$ = LEFT$(S$+STRING$(80, 32),SIZE%)
END FUNCTION
The following FORTRAN program is FORSUB.FOR:
SUBROUTINE DUM1(STR1, STR2, STR3, STR4)
CHARACTER*14 STR3, STR4 [FAR]
CHARACTER*43 STR1 [FAR]
CHARACTER*44 STR2 [FAR]
WRITE (*,*) STR1, STR2, STR3, STR4
END
Keywords: H_Fortran B_BasicCom SR# S890110-32
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/22 04:23
_____________________________________________________________________________
Q32788 Example of Trapping CTRL+ALT+DEL Keys in QuickBASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The correction below applies to the KEY statement on Page 236 of the
following manuals:
1. Page 236 of "Microsoft QuickBASIC 4.0: BASIC Language Reference"
for Versions 4.00 and 4.00b
2. Page 236 of "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Versions 6.00 and 6.00b for MS-DOS and MS OS/2
3. Page 180 of the "Microsoft BASIC 7.0: Language Reference" manual
for Microsoft BASIC PDS Version 7.00
4. Page 198 of the "Microsoft QuickBASIC: BASIC Language Reference" manual
for QuickBASIC Version 4.50
The following phrase for the KEY(n) statement is incorrect:
...a keyboardflag value of &H12 would test for both CTRL and ALT
being pressed.
The keyboardflag value should be &H0C on a non-extended keyboard, not
&H12, to test for both CTRL and ALT being pressed. The keyboardflag
value should be &H8C on an extended keyboard. This example incorrectly
uses decimal addition on hexadecimal numbers.
More Information:
The following BASIC program gives an example of trapping the
CTRL+ALT+DEL key sequence for both extended and non-extended
keyboards:
' This example works in QuickBASIC Versions 4.00 and later.
' &H80 = keyboard flag value to add for extended keyboard keys
' &H0C = keyboard flag for CTRL (&H04) plus ALT (&H08), pressed
' together.
' &H53 = scan code for DELETE (or DEL) key
CLS
KEY 15, CHR$(&HC) + CHR$(&H53) ' Trap CTRL+ALT+DEL for
ON KEY(15) GOSUB ctrlaltdelwhite ' white DEL key
KEY(15) ON
KEY 16, CHR$(&H8C) + CHR$(&H53) ' Trap CTRL+ALT+DELETE for
ON KEY(16) GOSUB ctrlaltdelgrey ' grey (extended) DELETE key
KEY(16) ON
DO
LOOP UNTIL INKEY$ = "q" ' Idle loop
END
ctrlaltdelgrey:
PRINT "pressed CTRL+ALT+DELETE (grey DELETE key) on extended keyboard"
RETURN
ctrlaltdelwhite:
PRINT "Pressed CTRL+ALT+DEL (white DEL key) on either keyboard"
RETURN
Please note that when you run this program, pressing CTRL+ALT+DEL will
reboot the computer if any of the following key states are also
active:
SHIFT, NUM LOCK, or CAPS LOCK
You must define separate ON KEY(n) statements for trapping
CTRL+ALT+DEL in combination with the different states of the SHIFT,
NUM LOCK, or CAPS LOCK keys. In the ON KEY(n) statement, n can be 15
through 25; this limits you to 11 user-defined keys.
The keyboardflag value &H0C in the KEY statement is obtained by adding
together the keyboardflag values from Page 236 for the CTRL and ALT
keys, as in the following example:
&H04 + &H08 => &H0C
(CTRL) (ALT) (keyboardflag for KEY statement)
When adding together keyboardflag values to trap different
combinations of SHIFT, CTRL, ALT, NUM LOCK, CAPS LOCK, or
Advanced-101-keyboard extended keys, it is important to remember that
the values on Page 236 are in hexadecimal (base 16) notation, where
numbers are preceded with &H. If you wish, you can convert the number
to decimal notation (base 10) and use that value. Be sure not to use
&H in front of the value in BASIC if the value is in decimal notation.
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/23 04:07
_____________________________________________________________________________
Q46376 How to Pipe ( | ) Input into a QuickBASIC Program
Microsoft QuickBASIC Compiler (QUICKBAS)
3.00 4.00 4.00b 4.50
MS-DOS
Summary:
It is possible to use DOS redirection to pipe output from a program
into a QuickBASIC program. To do this, the QuickBASIC program must
CALL INTERRUPT 21 Hex, with function 3F Hex, to get the input from the
DOS device CON.
This information applies to Microsoft QuickBASIC Versions 3.00, 4.00,
4.00b, and 4.50 for MS-DOS, to Microsoft BASIC Compiler Versions 6.00
and 6.00b for MS-DOS, and to Microsoft BASIC PDS Version 7.00 for
MS-DOS.
More Information:
DOS redirection is a feature of DOS Versions 2.00 and later. It allows
you to take the output that would normally go to a device like the
terminal's screen and redirect or "pipe" the output into another
program. The program on the receiving end then takes the input and
processes or "filters" the input. This is why these programs are often
called "filters." The syntax for the DOS pipe command is the
following:
DOS-PROMPT> p1 | p2
In this command, p1 is the program performing the output, | is called
the pipe symbol, and p2 is the program performing the input or
filtering. An example of a common use for this feature of DOS is as
follows:
DOS-PROMPT> dir | sort
The "dir" command gives a listing of the current directory, which is
piped into the DOS "sort" program. Sort then filters the input and
displays the directory listing in sorted order.
However, the output from p1, the first program, can be piped into a
QuickBASIC program as well. The QuickBASIC program can then read the
input from the DOS device CON. This is possible because DOS stores the
output from the first program in a temporary file. The QuickBASIC
program can then CALL INTERRUPT 21H function 3FH to retrieve the
input. This function inputs a specific number of bytes from a file or
device, such as the CON device.
Interrupt 21 Hex, with function 3F hex, requires five register
parameters to be passed:
AH = The function number, 3F Hex.
BX = Handle to the file or device.
CX = The number of bytes to read.
DS = Segment of the buffer area. The buffer will be a string.
DX = Offset of the buffer area.
For more detailed information on INTERRUPT 21 Hex and function 3F Hex,
redirection, and filters, consult "Advanced MS-DOS Programming" by Ray
Duncan, published by Microsoft Press, copyright 1988.
For more information on using the QuickBASIC CALL INTERRUPT, search on
the following word:
QB4INT
Note: You can pipe information into a QuickBASIC program, but it is
more difficult to pipe information from a QuickBASIC program to
another program. QuickBASIC usually does not output information
through DOS services but accesses the hardware directly. The PRINT
statement, for example, displays text directly to video memory, not to
the DOS CON device. To direct output from a BASIC program to CON, you
must either OPEN the BASIC device "CONS" (with no colon) for output as
a file and PRINT#n all information to that file number (#n), or use
INTERRUPT 21 Hex, with function 40 Hex, to output to the CON device.
This output could be piped into another program.
Code Example
------------
'***********************************************************
'* This program calls the DOS INTerrupt 21H function 3FH *
'* in order to read any input that has been redirected *
'* to it with the | operator from DOS. It then echoes the *
'* input to the screen, and filters out any extra Line *
'* Feed characters. *
'***********************************************************
REM $INCLUDE: 'qb.bi'
' For BC.EXE and QBX.EXE for BASIC 7.00 use the include file 'QBX.BI'
DIM inregs AS RegTypeX, outregs AS RegTypeX
REM $DYNAMIC
DIM tempvar(10) AS STRING * 10
'NOTE: The length of the string and the number of bytes read
' (inregs.cx) should be the same.
DO
' Set up the parameters for the CALL INTERRUPTX
inregs.ax = &H3F00 ' AH gets the functions number.
inregs.bx = 0 ' The is the handle to the CON device is 0.
inregs.cx = 10 ' Request to read 10 characters at a time.
inregs.ds = VARSEG(tempvar(1)) ' Segment of the buffer area.
inregs.dx = VARPTR(tempvar(1)) ' Offset of the buffer area.
'INT 21H function 3FH to read a file or device.
CALL INTERRUPTX(&H21, inregs, outregs)
'The number of bytes actually read is returned in AX.
'We requested 10, so if it reads fewer, then we are done.
IF outregs.ax < 10 THEN EXIT DO
' Filter the string returned
FOR i = 1 TO LEN(tempvar(1))
a$ = MID$(tempvar(1), i, 1)
' DOS puts a line feed (LF) after its carriage return.
' We want to avoid this, because the PRINT will add an
' extra carriage return after this line feed.
IF NOT (a$ = CHR$(10)) THEN
PRINT a$;
END IF
NEXT
LOOP
END
Keywords: SR# S890621-89 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/28 08:08
_____________________________________________________________________________
Q31426 "Duplicate Definition" on STATIC Array in Second CALL to SUB
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
In the following sources, the example of using the STATIC statement
does not clearly explain what will happen with a second call to the
SUB:
1. Page 80 of the "Microsoft QuickBASIC 4.0: Programming in BASIC:
Selected Topics" manual for Versions 4.00 and 4.00b
2. Page 70 of the "Microsoft QuickBASIC: Programming in BASIC" manual
for Version 4.50
If SubProg2 is called more than once, the DIM statement gives you a
"Duplicate Definition" error message. This is because in a recursive
procedure, arrays are always dimensioned dynamically (that is, at run
time), and making the array retain its values between calls (with the
STATIC statement) means that the array was already dimensioned at the
second call.
The example should be changed as follows:
1. Declare an additional STATIC variable as a flag.
2. Put the DIM in an IF...END IF block that executes only upon first
call to the routine, and not on subsequent calls, as determined by
the flag variable.
This correction also applies to the following:
1. Page 80 of "Microsoft BASIC Compiler Version 6.00 for MS OS/2 and
MS-DOS: Programming in BASIC: Selected Topics" for the BASIC
compiler Versions 6.00 and 6.00b
2. Page 66 of "Microsoft BASIC 7.0: Programmer's Guide" for Microsoft
BASIC PDS Version 7.00 for MS-DOS and MS OS/2
More Information:
Removing the array from the STATIC statement also eliminates the
"Duplicate Definition."
The following code demonstrates how to avoid the "Duplicate
Definition" error:
DECLARE SUB dummy ()
PRINT "call the subroutine"
CALL dummy
PRINT "call the routine again"
CALL dummy
SUB dummy
STATIC a(), FirstPassFlag ' STATIC retains values between CALLs
' FirstPassFlag assures that array gets DIMensioned only once.
IF FirstPassFlag = 0 THEN
DIM a(1)
FirstPassFlag = 1
END IF
print "continuing on"
END SUB
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/29 05:36
_____________________________________________________________________________
Q36806 Softkey String for KEY 10 Has 5-Character Maximum Display
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
The following manuals incorrectly specify that the first six
characters of the softkey string expression will be shown when the
KEY ON statement is invoked. This is true, except for KEY 10. For KEY
10, only the first 5 characters are shown:
1. Page 233 of "Microsoft QuickBASIC 4.0: BASIC Language Reference" for
Versions 4.00 and 4.00b
2. Page 233 of "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Versions 6.00 and 6.00b for MS-DOS and MS OS/2
3. "Microsoft QuickBASIC 4.5: BASIC Language Reference" for Version 4.50
4. "Microsoft BASIC 7.0: BASIC Language Reference" for BASIC PDS Version
7.00
This is a design limitation. The display of KEY 10 uses 2 character
spaces to display the number "10". This second digit uses the first
available space of the string expression and leaves only 5 character
spaces for that string expression.
More Information:
The following is a code example:
KEY 9, "ABCDEF"
KEY 10, "abcdef"
KEY ON
10 goto 10 ' Press CTRL+BREAK to quit.
The following function key labels display on the bottom of the screen:
1 2 3 . . . 8 9ABCDEF10abcde
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/29 05:36
_____________________________________________________________________________
Q45687 "Out of String Space" Concatenating Variable-Length String
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
For variable-length string concatenation to execute successfully, even
if only 1 byte is to be added, there must be enough available memory
[reported by FRE("")] for the length of a copy of the existing string,
plus the length of the string being added, plus its new 4-byte string
descriptor. Otherwise, you will get an "Out of String Space" error,
caused by the temporary old string remaining in memory during the
string concatenation. The old string is deallocated only after a
successful concatenation.
This information applies to QuickBASIC Versions 1.00, 1.01, 1.02,
2.00, 2.01, 3.00, 4.00, 4.00b, and 4.50, and to BASIC Compiler
Versions 6.00 and 6.00b for MS-DOS and OS/2.
This information also applies to Microsoft BASIC PDS Version 7.00 when
using BC.EXE without the /Fs compiler switch. Inside the QBX.EXE
environment and when using /Fs compiler switch, BASIC 7.00 uses a 64K
segment for temporary string storage and procedure-level strings (that
is, strings declared inside subroutines). To see how much temporary
string space you have when using far strings, use FRE("StringLiteral"),
where StringLiteral is any constant string (for example, "Hello"). For
more information about far strings, read Chapter 11 in the "Microsoft
BASIC 7.0: Programmer's Guide" for BASIC PDS Version 7.00.
More Information:
When you concatenate a variable-length string with another string in
BASIC, a new 4-byte string descriptor is created. A copy of the
original string is moved to a new location in string space and the
string to be concatenated is appended to it. The length field in the
new string descriptor is updated to reflect the length of the
concatenated string. Only then is the memory used by the original
string and its descriptor released (deallocated).
New strings are allocated above existing strings and deallocated
strings in DGROUP. When deallocated strings fragment string space to
the point where a new string fills the last space at the top of
DGROUP, BASIC automatically performs string space compaction (garbage
collection) to make free string space contiguous again. Passing a
string argument (such as "", the null string) to the FRE("") function
always forces string space compaction before reporting the amount of
string space available in DGROUP.
For example, assume FRE("") returns 20,004. An attempt to add a single
byte to an existing string of 20,000 bytes would fail because 20,005
bytes are needed for the concatenation to be successful:
Existing string = 20,000 bytes
String to add = 1 byte longer
String descriptor = 4 bytes
-----------
Memory needed 20,005 bytes
Because only 20,004 bytes of memory are available, an "Out of String
Space" message will be generated.
Keywords: SR# S890606-8 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/29 05:36
_____________________________________________________________________________
Q48401 Multi-DIMensioned Arrays Are in Column Order; BC /R Row Order
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
By default, multidimensional arrays are stored in contiguous columns
in memory (that is, column-major order) in compiled BASIC. With
column-major order, the leftmost subscript (the row dimension)
changes the fastest.
You can force executable .EXE programs to store arrays in rows by
using the BC /R option. However, the /R option (for row-major order)
is not available in the QB.EXE or the QBX.EXE editor environment. With
row-major order, the rightmost subscript (the column dimension)
changes the fastest.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50 for MS-DOS, to Microsoft BASIC Compiler Versions 6.00 and
6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC PDS Version 7.00
for MS-DOS.
More Information:
In the DIM X(row,column) statement, arrays are stored by default in
column order in memory. When looking at a contiguous block of memory
that is storing a two-dimensional array, you'll find one column stored
after another. For example, for DIM X(2,2), the array elements are
stored by default in the following column-major order:
X(0,0), X(1,0), X(2,0), X(0,1), X(1,1), X(2,1), X(0,2), X(1,2), X(2,2)
If you compile the program with BC /R, you get row-major order, as
follows:
X(0,0), X(0,1), X(0,2), X(1,0), X(1,1), X(1,2), X(2,0), X(2,1), X(2,2)
An easy way to demonstrate the storage order is to BSAVE a two-
dimensional array and then BLOAD the same data into a one-dimensional
array. You then have a firsthand view of how the array is stored.
Unlike BASIC, Microsoft C defaults to row-major order.
This array-order information is taken from Page 313 of the "Microsoft
QuickBASIC 4.0: Learning and Using" manual for QuickBASIC Versions
4.00 and 4.00b, from Page 313 of the "Microsoft BASIC Compiler 6.0:
Learning and Using Microsoft QuickBASIC" manual for Versions 6.00 and
6.00b, and from Page 560 of the "Microsoft BASIC 7.0: Programmer's
Guide" for BASIC PDS Version 7.00.
Keywords: SR# S890801-7 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/29 05:36
_____________________________________________________________________________
Q45897 How to Make QuickBASIC 4.50 Recognize Custom Help Files
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
You can use the HELPMAKE.EXE utility that is included with QuickC
Version 2.00 and Quick Pascal Version 1.00 to make customized Help
files for QuickBASIC Version 4.50. However, QuickBASIC 4.50 does not
acknowledge the "HELPFILES" environment setting. The only Help file
that it acknowledges is QB45QCK.HLP. How you implement support for
your customized Help files depends upon whether you want to replace
QuickBASIC's original Help file or merely to supplement it.
This information applies to QuickBASIC Version 4.50.
Microsoft BASIC PDS Version 7.00 includes the HELPMAKE.EXE utility. To
use HELPMAKE.EXE with QBX.EXE 7.00, see Chapter 22 of the "Microsoft
BASIC 7.0: Programmer's Guide" for Microsoft BASIC PDS Version 7.00.
More Information:
If you want to replace QuickBASIC's Help file, rename your customized
Help file as QB45QCK.HLP and place it in the directory with QB.EXE.
You can now access your own customized contexts but have no access to
the original Help screens for QuickBASIC.
If you want to supplement QuickBASIC's Help file, do the following:
1. Use HELPMAKE to decode QuickBASIC's QB45QCK.HLP as follows:
HELPMAKE /D /OQB45QCK.TXT QB45QCK.HLP
(Note: There is no space when using HELPMAKE's /Odestfile switch,
which specifies the output destination filename.)
2. Load QB45QCK.TXT into a text editor or word processor.
3. Append the source for your customized contexts to the end of
QB45QCK.HLP.
4. Save the file under the name QB45QCK.TXT.
5. Rename QB45QCK.HLP to QB45QCK.OLD.
6. Use HELPMAKE to encode the new Help file, as follows:
HELPMAKE /A: /E /OQB45QCK.HLP QB45QCK.TXT
(Note: The /A: switch specifies a colon (:) to be the control
character to mark lines containing special control information
for use by the QB.EXE application's Help system.)
You can now access your customized Help contexts, in addition to the
original contents of the Help screens, with QuickBASIC's Help system.
For more information about running HELPMAKE, please refer to Chapter 8
of the "Microsoft QuickC Tool Kit" manual for Version 2.0.
Keywords: S_QuickC S_QuickPas S_UTILity
COPYRIGHT Microsoft Corporation, 1989.
Updated 89/12/30 05:05
_____________________________________________________________________________
Q37481 PRINT USING Statement Fails to Use Print Zones
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The PRINT USING statement is not designed to print the values of an
expression list in the 14-character print zones. Instead, it ignores
the comma and treats it like a semicolon. In QuickBASIC Version 4.50,
the syntax checker correctly changes the comma to a semicolon.
However, several manuals (listed below) and the online help system
incorrectly state that the comma is syntactically legal.
More Information:
The incorrect syntax for the PRINT USING statement is as follows:
PRINT USING formatstring; expressionlist [{,|;}]
The incorrect definition for the PRINT USING statement is as follows:
The position of each printed item is determined by the punctuation
used to separate the items in the list. BASIC divides the line into
print zones of 14 spaces each. In the expression list, a comma
makes the next value print at the start of the next zone. A
semicolon makes the next value print immediately after the last
value.
This incorrect syntax or definition is given in each of the following
references:
1. Page 275 of the "Microsoft BASIC 7.0: BASIC Language Reference" for
Microsoft BASIC PDS Version 7.00
2. Page 335 of the "Microsoft QuickBASIC 4.0: BASIC Language
Reference" for QuickBASIC 4.00 and 4.00b
3. Page 287 of the "Microsoft QuickBASIC: BASIC Language Reference"
for QuickBASIC 4.50
4. Page 335 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Microsoft BASIC Compiler Versions 6.00 and 6.00b
5. The online help system for Microsoft QuickBASIC 4.50 under the
entry for PRINT USING statement
6. The online help system for BASIC PDS 7.00 under the entry for the
PRINT USING statement
The following is a code example that demonstrates that PRINT USING
treats commas as if they were semicolons. When run in the environment,
the code example will correctly substitute a semicolon between the
variables "a" and "b" for the comma:
a=3.45
b=5.23
PRINT USING "##.##";a,b
The output is as follows:
3.45 5.23
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/13 15:50
_____________________________________________________________________________
Q40635 "Permission Denied" Is Only Error for BASIC Record/File LOCK
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The only error message that you will get for locked files or records
is "Permission denied," error number 70.
Normally, you only get a "Bad record number" error message when
attempting to access record number zero. However, the message "Bad
record number" has nothing to do with the LOCK statement, contrary to
a statement in the documentation (listed below).
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50, to Microsoft BASIC Compiler Versions 6.00 and 6.00b for
MS-DOS and MS OS/2, and to Microsoft BASIC PDS Version 7.00 for MS-DOS
and MS OS/2.
More Information:
This documentation error occurs in the following places. Each of these
references is in the language reference manual for that product and is
under the entry describing the LOCK... UNLOCK statement.
1. Page 259 of the "Microsoft QuickBASIC 4.0: BASIC Language
Reference" manual for QuickBASIC Versions 4.00 and 4.00b
2. Page 259 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" manual for Microsoft BASIC Compiler Versions 6.00 and
6.00b
3. Page 220 of the "Microsoft QuickBASIC 4.5: BASIC Language
Reference" manual for QuickBASIC Version 4.50
4. Page 200 of the "Microsoft BASIC 7.0: Language Reference" manual
for Microsoft BASIC PDS Version 7.00
Each of the references above makes the following misleading statement:
If you attempt to access a file that is locked, the following
error messages may appear:
Bad record number
Permission denied
This same incorrect information appears in the QB Advisor online Help
system for QuickBASIC Version 4.50 and in the Microsoft Advisor online
Help system for QBX.EXE, which comes with Microsoft BASIC PDS Version
7.00. The error occurs under the entry for the "LOCK... UNLOCK
Statement Details" in both Help systems.
The program example below demonstrates that a "Permission Denied"
error occurs if a program does any of the following:
1. LOCKs a file that is already LOCKed.
2. Reads any record from a random access file where the whole file is
LOCKed.
3. Reads any part of a sequential file where any part of that file is
LOCKed.
4. Reads the portion of a BINARY access file that was LOCKed.
The following is sample code:
OPEN "test5" FOR BINARY AS #1 'Open the same file as #1 and #2.
OPEN "test5" FOR BINARY AS #2
OPEN "test4" FOR RANDOM AS #3 LEN = 11 'Open as #3 and #4.
OPEN "test4" FOR RANDOM AS #4 LEN = 11
OPEN "test3" FOR INPUT AS #5 'Open as #5 and #6.
OPEN "test3" FOR INPUT AS #6
OPEN "test3" FOR INPUT AS #7 'Open the same file as #5 and #6.
FIELD #3, 11 AS f3$
FIELD #4, 11 AS f4$
LOCK #1, 30 TO 32 'Lock some bytes in #1.
LOCK #3 'lock entire file #3
LOCK #5, 1 'Lock first record in #5.
CLS
n = 10
LOCK #7 'Permission denied attempt to lock a locked file
a$ = INPUT$(34, #2) 'Permission denied if any part is locked.
GET #4, n 'Permission denied for any n except n=0
'n=0 gives a bad file number
INPUT #6, a$ 'Permission denied for record 1
UNLOCK #1, 30 TO 32
UNLOCK #3
UNLOCK #5, 1
CLOSE
Keywords: docerr B_BasicCom SR# S881221-115
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/13 15:50
_____________________________________________________________________________
Q52068 Example of Using NPV and IRR Financial Functions in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
This article explains how to use the NPV and IRR financial functions
in Microsoft BASIC PDS (Professional Development System) Version 7.00
for MS-DOS and MS OS/2.
More Information:
Note that the NPV#, IRR#, and MIRR# functions are used for investments
that are a series of nonconstant cash payments made at equal
intervals. You pass the series of nonconstant payments in an array.
[This contrasts with the financial functions for annuity investments
(FV#, IPmt#, Rate#, NPer#, PV#, Pmt#, and PPmt#). In an annuity, each
cash payment is the same constant amount, made at equal intervals.]
The present value (PV) of a future cash receipt is the amount of money
that, if received today, would be considered equivalent to the future
receipt, at a given interest rate. The present value is less than the
future receipt because you can earn interest on money received today.
NPV (Net Present Value) compares (subtracts) the current value of a
series of future cash flows with an amount invested today.
NPV is useful to compare investment opportunities at a given discount
(interest) rate. The discount rate (rate#) can be viewed as the rate
of return you want out of your investment. If NPV is greater than or
equal to 0, the investment equals or exceeds your interest (discount)
rate requirement; if NPV is less than 0, the investment does not meet
your interest rate requirement.
The NPV#(rate#,valuearray#(),valuecount%,status%) function returns
Net Present Value. You input the values rate#, valuearray#(), and
valuecount% (which is the number of array elements), and get back
status% equals 0 for success, 1 for failure.
The IRR#(valuearray#(),valuecount%,guess#,status%) function returns
Internal Rate of Return. IRR returns the discount rate at which NPV
would return 0 (zero). For a given array of cash flow values, IRR can
be thought of as an average interest rate (which compounds at each
period). If IRR is lower than the interest rate you desire for this
investment, then it is not a good investment.
The first element of the input cash-flow array should usually be
negative, indicating your initial investment. A high (positive) income
early in the value array will make IRR higher than if the same high
income instead occurred later in the array. This is an example of the
time value of money.
Please refer to an elementary accounting textbook for more information
about these standard Accounting functions.
Code Example
------------
You can run this program in the QuickBASIC Extended environment with
QBX /L FINANCER.QLB. To run outside this environment, you must link
with the appropriate library (FINANCER.LIB, FINANCAR.LIB,
FINANCEP.LIB, or FINANCAP.LIB).
REM $INCLUDE: 'FINANC.BI
DEFDBL A-Z
OPTION BASE 1
CLS
valuecount% = 5 ' = number of cash-flow values in valuearray()
' Array holds cash flow values, one value per period (such as per
' year):
DIM valuearray(valuecount%)
guess = .1 ' Guess the IRR (use .1 if in doubt)
valuearray(1) = -1000 ' 0. First value negative as initial investment.
valuearray(2) = 100 ' 1. Return on investment after 1 period.
valuearray(3) = 200 ' 2. (Positive value is return on investment.)
valuearray(4) = -300 ' 3. (Negative value is additional investment.)
valuearray(5) = 1200 ' 4. Return on investment after 4 periods.
' For the above values, IRR returns .0514. (5.14% return per period)
status% = 0
irreturn = IRR(valuearray(), valuecount%, guess, status%)
IF status% THEN PRINT "IRR error occurred; try different guess";
discountrate = irreturn
netpresval = NPV#(discountrate, valuearray(), valuecount%, status%)
'Notes for NPV#() function:
' If discountrate = value returned by IRR(), then NPV returns zero, as
' in the IRR example in the "Microsoft BASIC 7.0: Language
' Reference" manual, and also as in this code example.
' If discountrate = zero, NPV returns sum of values in valuearray().
' If discountrate > zero, NPV returns an amount smaller than sum of
' values in valuearray() due to the discount effect at each period.
' If discountrate < zero, NPV returns an amount larger than the sum of
' the values in valuearray().
IF status% THEN PRINT "NPV error occurred"
PRINT "IRR (fractional return on investment per period) = ";
PRINT USING "##.####"; irreturn
PRINT "NPV = ";
PRINT USING "#######.##"; netpresval
Output
------
For the above values, IRR returns .0514 (5.14 percent return per
period). NPV returns 0 (zero), since IRR returns the discount rate at
which NPV returns 0.
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/16 04:57
_____________________________________________________________________________
Q32217 Using B_OnExit Across a CHAIN Hangs System; Compiled BASIC
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 | 6.00 6.00b 7.00
MS-DOS | OS/2
Summary:
Chaining to and from programs that use B_OnExit causes the system to
hang.
Microsoft has confirmed this to be a problem in Microsoft QuickBASIC
Versions 4.00 and 4.00b (buglist4.00, buglist4.00b), in Microsoft
BASIC Compiler Version 6.00 and 6.00b for MS-DOS and MS OS/2, and in
Microsoft BASIC Professional Development System (PDS) Version 7.00 for
MS-DOS and MS OS/2. We are researching this problem and will post new
information here as it becomes available.
More Information:
Please note that the B_OnExit routine is documented on Pages 319-321
of the "Microsoft QuickBASIC 4.0: Learning and Using" manual for
Microsoft QuickBASIC Versions 4.00 and 4.00b (this is the same manual
for Microsoft BASIC Compiler Versions 6.00 and 6.00b), and in the
"Microsoft BASIC 7.0: Programmer's Guide" on Pages 474-475.
The following steps reproduce the problem using source code provided
farther below:
1. Use the following software to reproduce the problem:
a. Microsoft QuickBASIC Versions 4.00, 4.00b, Microsoft BASIC
Compiler Version 6.00 or 6.00b, or Microsoft BASIC PDS Version
7.00.
b. Microsoft C Compiler Version 5.10
2. Type the following command lines:
BC BUGTEST.BAS;
BC BUGNEXT.BAS;
CL /c /AM BUGC.C
LINK /NOE BUGTEST+BUGC;
LINK /NOE BUGNEXT+BUGC;
3. Run BUGTEST.EXE from the DOS prompt.
4. At the "CHAIN Y/N?" prompt, type Y.
The system locks up when BUGNEXT exits.
Please note the following:
1. You must link BUGC.OBJ with BUGNEXT.OBJ even though it is not
called.
2. Both programs apparently run correctly until you exit BUGNEXT.
Code Example
------------
'BUGTEST.BAS
DECLARE SUB IntProc CDECL
DEFINT A-Z
PRINT "[***** ENTRY TO MAIN *****]"
CALL InProc
INPUT "CHAIN Y/N";T$
IF T$="Y" OR T$="y" THEN
CHAIN "BUGNEXT.EXE"
END IF
SYSTEM
END
'BUGNEXT.BAS
DEFINT A-Z
PRINT "[***** CHAIN *****]"
SYSTEM
END
/* BUGC.C */
#include <malloc.h>
extern pascal far B_OnExit(); /* Declare the routine */
void IntProc()
{
void TermProc(); /* Declare TermProc routine */
printf ("\nIn the C IntProc routine\n");
B_OnExit(TermProc); /* Log termination routine with BASIC */
}
void TermProc() /* The TermProc function is */
{ /* called before any restarting */
printf ("\nIn C TermProc routine\n"); /* or termination of the program. */
}
Keywords: buglist6.00 buglist6.00b buglist7.00 B_QuickBas
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/18 03:45
_____________________________________________________________________________
Q57866 BASIC PDS 7.00 Supports Short-Circuit Boolean Expressions
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
Microsoft BASIC Professional Development System (PDS) Version 7.00
supports "short-circuit" optimization of Boolean expressions, as
described below. To take advantage of this speed optimization in
complex IF, WHILE, DO LOOP WHILE, or DO LOOP UNTIL statements, the
quickest Boolean conditions should appear first.
Microsoft QuickBASIC Versions 1.00, 1.01, 1.02, 2.00, 2.01, 3.00,
4.00, 4.00b, and 4.50 and Microsoft BASIC Compiler Versions 6.00 and
6.00b DON'T support short-circuit Boolean expressions.
More Information:
Boolean expressions are those expressions in BASIC that evaluate to
true or false. In BASIC, the IF, WHILE, and DO LOOP {WHILE | UNTIL}
statements all require Boolean expressions as part of their syntax.
A "short-circuit" Boolean expression is a unique kind of Boolean
expression. If a Boolean expression consists of more than one part,
not all the parts may be evaluated. The evaluation of the expression
may stop, or "short circuit," partway through. Consider the following
two-part Boolean expression:
IF <condition1> AND <condition2> THEN
If <condition1> evaluates to false, it isn't necessary to evaluate
<condition2>, because "false" AND "anything else" is still false.
Therefore, we can short circuit the expression and not evaluate
<condition2>.
The same rule applies to the following expression:
IF <condition1> OR <condition2> THEN
If <condition1> is true, we do not need to evaluate <condition2>
because "true" OR "anything else" always evaluates to true.
Short-circuit Boolean expressions are desirable for two reasons.
First, they allow you to optimize code by evaluating only as much of
the Boolean expression as necessary. This can generate faster, more
efficient code. In the examples above, if <condition2> were very
complex, a short-circuit Boolean might speed up program execution by
evaluating the whole expression only when absolutely necessary.
Second, short-circuit Booleans can be used to prevent error
conditions. In the code example below, BASIC PDS 7.00 prevents the
"Division by zero" error in .EXE programs since it supports
short-circuit Booleans. QBX.EXE programs in BASIC 7.00, and QB.EXE and
.EXE programs in QuickBASIC 4.00, 4.00b, and 4.50, give the "Division by
zero" error.
BASIC 7.00 will short circuit IF expressions as long as doing so does
not change the semantics of the statement. The following is an
example:
IF (a% < b%) OR (c! < d!) THEN PRINT
The compiler compares a% and b%. If a% is less than b%, the compiler
skips the floating-point comparison. On the other hand, consider the
following statements:
DECLARE FUNCTION Foo! (p!)
IF (a% < b%) OR (c! < Foo!(d!)) THEN PRINT
The compiler avoids the floating-point comparison when a% is less
than b%, but it still calls the function Foo. This is because existing
programs may rely on the side effects of the function Foo.
This feature affects the best way to write code in BASIC PDS 7.00.
Specifically, in complex IF, WHILE, DO LOOP WHILE, or DO LOOP UNTIL
conditions, the quickest conditions should appear first.
Code Example
------------
The following program determines if a compiler supports short-circuit
Boolean optimization for an IF statement. Since it supports
short-circuit Booleans, BASIC PDS Version 7.00 prevents the "Division
by zero" error in the .EXE program. QBX.EXE programs in BASIC 7.00,
and QB.EXE and .EXE programs in QuickBASIC 4.00, 4.00b, and 4.50, give
the "Division by zero" error.
DEFINT A-Z
ON ERROR GOTO errorhandle
a = 1
b = 1
c = 0
CLS
LOCATE 10, 10
' In the following IF statement, b / c is not executed if
' short-circuit Booleans are supported because a = 1 evaluates to
' true, and therefore, the whole expression is true. This is
' because (true OR <anything>) evaluates to true.
IF (a = 1 OR ((b / c) = 1)) THEN
' If this PRINTs, then short-circuit Booleans are supported.
PRINT "This compiler supports short-circuit Booleans"
END IF
terminate:
PRINT "End of program reached"
END
errorhandle:
IF ERR = 11 THEN PRINT "Division by zero, Error="; ERR
LOCATE 11, 10
PRINT "This compiler does not support short-circuit Booleans"
RESUME terminate ' End the program.
Keywords: B_QuickBas SR# S890703-44
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/22 03:09
_____________________________________________________________________________
Q58122 CHAIN Line-Number Option Is in BASICA, Not in QuickBASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The documentation for the CHAIN statement misleadingly refers to the
line-number option. The line-number option is supported in the BASICA
and GW-BASIC Interpreters, but not in compiled BASICs. This fact is
documented in the same section, "Differences from BASICA," but not in
the same paragraph, and thus might cause confusion. References to the
line-number option apply only to modifying BASICA and GW-BASIC code.
This information applies to the following manuals:
1. Page 94 of the "Microsoft QuickBASIC 4.0: BASIC Language Reference"
manual for QuickBASIC Versions 4.00 and 4.00b for MS-DOS
2. Page 94 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" manual for Versions 6.00 and 6.00b for MS OS/2 and
MS-DOS
3. Page 38 of the "Microsoft BASIC 7.0: Language Reference" manual for
Microsoft BASIC Professional Development System (PDS) Version 7.00
for MS-DOS and MS OS/2
More Information:
The last two paragraphs of the "Differences from BASICA" section read
as follows:
BASIC does not support the ALL, MERGE, or DELETE, OPTIONS available
in BASICA, nor does it allow the specification of a line number.
Without the line-number option, execution always starts at the
beginning of the chained-to program. Thus, a chained-to program
that chains back to a carelessly written chaining program can cause
an endless loop.
Keywords: SR# S900125-125 B_BasicCom B_GWBasicI
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/01/31 04:08
_____________________________________________________________________________
Q57890 Overhead for /V and /W Event Trapping Is Reduced in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 | 6.00 6.00b 7.00
MS-DOS | OS/2
Summary:
The code overhead for BC /V is only 3 bytes per statement, and the
code overhead for BC /W is only 3 bytes per labeled or numbered line,
in Microsoft BASIC Professional Development System (PDS) Version 7.00
for MS-DOS and MS OS/2.
The overhead for these event trapping options is 5 bytes in Microsoft
QuickBASIC Versions 4.00, 4.00b, and 4.50 for MS-DOS, and in Microsoft
BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS OS/2.
More Information:
Event trapping for the ON <event> GOSUB statements is handled by
polling. The <event> can be COM(n), KEY(n), PEN, PLAY(), STRIG, and
TIMER. In BASIC 6.00, 6.00b, and 7.00, you can also use ON SIGNAL and
ON UEVENT.
At various points in your code, as controlled by the /V and /W options
and the <event> ON and <event> OFF statements, the compiler places a
call instruction to a routine that checks for events. /V places the
call on every statement in the module. /W only places the call on
every numbered or labeled line in the module. In QuickBASIC Versions
4.00, 4.00b, and 4.50 and in Microsoft BASIC Compiler 6.00 and 6.00b,
this call occupies 5 bytes. In BASIC 7.00, this has been reduced to 3
bytes per call.
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/01 05:04
_____________________________________________________________________________
Q33178 Example to Load OS/2 Disk Directory into String Array
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00
OS/2
Summary:
This article discusses two methods to put a disk directory listing
into a string array under OS/2 protected mode. (Note: This article was
written because the FILES statement in BASIC only outputs to the
screen, not to a file or to string variables.)
Example 1 shows a simple method to SHELL to the DIR command, redirect
the output to a file, and input from the file into string variables.
(Example 1 also works correctly in MS-DOS.)
Example 2 shows how to invoke OS/2 API functions (DosFindFirst and
DosFindNext) to retrieve a disk directory into string variables.
This article applies to Microsoft BASIC Compiler Versions 6.00 and
6.00b for MS-DOS and MS OS/2 and to Microsoft BASIC Professional
Development System (PDS) Version 7.00 for MS-DOS and MS OS/2.
Note: In Microsoft BASIC PDS 7.00, the DIR$ function can be used to
accomplish the same thing as these two routines show. The use of DIR$
is documented on Page 107 of the "Microsoft BASIC 7.0: Language
Reference" manual.
For an article about how to invoke MS-DOS (or OS/2 real mode)
functions to accomplish the same thing, query in this Knowledge Base
on the following keywords:
INTERRUPT and FINDFIRST and FINDNEXT
More Information:
In MS OS/2 protected mode, you can use the API CALLs DosFindFirst and
DosFindNext to retrieve a disk directory listing and load it into a
string array, as shown in Example 2 below. Example 2 does NOT apply to
QuickBASIC Versions 4.50 and earlier because they cannot compile
programs for OS/2 protected mode.
Example 1 (the simplest technique) is as follows:
' Works in QuickBASIC 2.00, 2.01, 3.00, 4.00, 4.00b, 4.50, and
' BASIC compiler 6.00 and 6.00b.
nf = 200 ' Handles directory listing up to 200 lines.
DIM buffer$(nf)
INPUT "Enter Search Path: ", path$ ' Enter path such as c:
SHELLSTRING$ = "dir " + path$ + " >dirfile.dat"
SHELL SHELLSTRING$ ' SHELL to the MS-DOS DIRectory command.
OPEN "dirfile.dat" FOR INPUT AS #1
pntr% = 0
WHILE NOT EOF(1) AND pntr% < nf
pntr% = pntr% + 1
INPUT #1, buffer$(pntr%) ' Inputs one directory line at a time.
PRINT buffer$(pntr%)
WEND
CLOSE #1
KILL "dirfile.dat"
END
Example 2 is as follows:
The following sample program is for MS OS/2 protected mode (to be
compiled only in BASIC compiler Version 6.00 or 6.00b in MS OS/2
protected mode or BASIC PDS Version 7.00 in MS OS/2 protected mode):
'The TYPE below is taken from the following include file: BSEDOSFL.BI
TYPE FILEFINDBUF
fdateCreation AS INTEGER
ftimeCreation AS INTEGER
fdateLastAccess AS INTEGER
ftimeLastAccess AS INTEGER
fdateLastWrite AS INTEGER
ftimeLastWrite AS INTEGER
cbFile AS LONG
cbFileAlloc AS LONG
attrFile AS INTEGER
cchName AS STRING * 1
achName AS STRING * 13
END TYPE
DECLARE FUNCTION DosFindFirst%( _
BYVAL P1s AS INTEGER,_
BYVAL P1o AS INTEGER,_
SEG P2 AS INTEGER,_
BYVAL P3 AS INTEGER,_
SEG P4 AS FILEFINDBUF,_
BYVAL P5 AS INTEGER,_
SEG P6 AS INTEGER,_
BYVAL P7 AS LONG)
DECLARE FUNCTION DosFindNext%( _
BYVAL P1 AS INTEGER,_
SEG P2 AS FILEFINDBUF,_
BYVAL P3 AS INTEGER,_
SEG P4 AS INTEGER)
DEFINT a-z
DIM buffer AS FileFindBuf
DIM filelist(255) as string*13
DIM reserved AS LONG
CLS
INPUT "Enter the Filename(s) : ";flname$
flname$=flname$+chr$(0)
atr= 0+2+4+16 'normal + hidden + system + subdirectory
dirh=1
searchcount=1
bufflen=36
x=DosFindFirst%(varseg(flname$),sadd(flname$),_
dirh,atr,buffer,bufflen,searchcount,reserved)
IF (X=0) THEN
DO
counter=counter+1
filelist(counter)=buffer.achName
buffer.achName=string$(13,32) 'assign blanks
LOOP WHILE (DosFindNext%(dirh,buffer,bufflen,searchcount) = 0 )
ELSE
PRINT "No MATCH was found"
END
END IF
for i = 1 to counter
print filelist(i)
next i
END
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/01 05:04
_____________________________________________________________________________
Q36023 "Statement Illegal in TYPE block" Due to Line Identifier
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
Line labels and line numbers are not permitted within TYPE ... END
TYPE statement blocks. A "Statement illegal in TYPE block" error
message appears if this is attempted.
Under the TYPE ... END TYPE statement (listed alphabetically) in the
"Microsoft QuickBASIC 4.0: BASIC Language Reference" manual for
QuickBASIC Versions 4.00 and 4.00b, in the "Microsoft QuickBASIC 4.5:
BASIC Language Reference" manual for QuickBASIC Version 4.50, and in
the "Microsoft BASIC Compiler 6.0: BASIC Language Reference" manual
for Microsoft BASIC Compiler Versions 6.00 and 6.00b, it needs to
mention that line identifiers are forbidden in TYPE ... END TYPE
statements.
This documentation omission has been corrected in the "Microsoft BASIC
7.0: Language Reference" for Microsoft BASIC Professional Development
System (PDS) Version 7.00 for MS-DOS and MS OS/2.
More Information:
The BC.EXE compiler correctly gives the following error message in all
of the above products when you compile the code example farther below:
10 partnumber AS STRING * 6
^ Identifier expected
^ Skipping forward to END TYPE statement
DIM stockrecord AS stockitem
^ TYPE not defined
Code Example
------------
'This gives "Statement illegal in TYPE block message,
'due to the presence of line identifiers.
TYPE stockitem
10 partnumber AS STRING * 6
description AS STRING * 20
unitprice AS SINGLE
abcd: quantity AS INTEGER
END TYPE
DIM stockrecord AS stockitem
Keywords: docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/01 05:04
_____________________________________________________________________________
Q39361 Sample Program; BASIC Invoking C Function That Returns String
Microsoft BASIC Compiler (BASICCOM)
4.00 4.00b 4.50
MS-DOS
Summary:
The sample program below demonstrates a BASIC program calling a C
routine that returns a BASIC string descriptor. This programming
example is a variation of the sample program located on Page 310 of
the "Microsoft QuickBASIC 4.0: Learning and Using" manual.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50, to Microsoft BASIC Compiler Versions 6.00 and 6.00b for
MS-DOS and MS OS/2, and to Microsoft BASIC Professional Development
System (PDS) Version 7.00 for MS-DOS and MS OS/2.
More Information:
Note: The Microsoft C medium-memory model should be used to ensure
that the C string is in DGROUP.
Note: This information does not apply if using far string support in
BASIC PDS Version 7.00 or when running inside the QuickBASIC extended
(QBX.EXE) environment with BASIC PDS Version 7.00. For information on
programming with mixed-languages using far strings refer to Chapter
13, "Mixed-Language Programming with Far Strings," in the "Microsoft
BASIC 7.0: Programmer's Guide."
The COMPILE and LINK instructions are as follows:
BC test.bas;
CL /AM /c tc.c
LINK test tc /noe;
The BASIC routine is as follows:
DECLARE FUNCTION t1$()
a$ = t1$
PRINT a$
The C function is as follows:
struct bas_str{
int sd_len;
char *sd_addr;
};
char cstr[]="ABC";
struct bas_str pascal t1()
{
struct bas_str str_des;
str_des.sd_addr = cstr;
str_des.sd_len = strlen(cstr);
return (str_des);
}
Keywords: B_BasicCom SR# S881207-17
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/02 05:05
_____________________________________________________________________________
Q45420 LPOS(0) and LPOS(1) Both Return Print Head Position for LPT1
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b | 6.00 6.00b
MS-DOS | OS/2
Summary:
The LPOS(0) and LPOS(1) functions both return the current position of
the print head within the printer buffer for LPT1. LPOS(2) returns
the current print position for LPT2.
On Page 263 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" manual for Versions 6.00 and 6.00b for MS OS/2 and MS-DOS,
the program example uses LPOS(0) to return the current position of the
line printer's print head within the print buffer, but no mention is
made of LPOS(0) in the function description. LPOS(0) operates the same
as LPOS(1), and there is no difference between the two functions.
This information applies also to Page 263 of the "Microsoft QuickBASIC
4.0: BASIC Language Reference" manual for QuickBASIC Versions 4.00 and
4.00b, to Page 224 of the "Microsoft QuickBASIC 4.5: BASIC Language
Reference" for Version 4.50, and to the QuickBASIC Version 4.50 QB
Advisor online Help system.
This documentation error was corrected on Page 204 of the "Microsoft
BASIC 7.0: Language Reference" manual for Microsoft BASIC Professional
Development System (PDS) Version 7.00.
Keywords: docerr B_QuickBas
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/03 04:18
_____________________________________________________________________________
Q58025 DRAW Statement's Scale (S) Command Has Default Scale Factor 4
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
The DRAW statement can scale the lines that it draws. The scale factor
is specified by including the "S" command, followed by a number from 1
to 255, before the commands that actually draw the lines.
Certain manuals listed below fail to state that the default DRAW scale
factor is 4, and they give the wrong formula to calculate the actual
distance drawn.
A scale factor of 8 must follow the "S" command to make a drawing
twice as large. A scale factor of 2 makes a drawing half as large (4 *
1/2 = 2).
More Information:
The following is the corrected formula for the DRAW "S n" (set Scale
factor n) command:
The default scale factor n is 4, which causes no scaling. The scale
factor multiplied by movement-command arguments (U, D, L, R, or
relative M commands) divided by 4 gives the actual distance moved.
This correction applies to the DRAW "S n" command in the following
manuals:
1. Page 138 of the "Microsoft QuickBASIC 4.5: BASIC Language
Reference" manual for Version 4.50
Note: The QB Advisor online Help of QuickBASIC 4.50 correctly
includes the fact that 4 is the default scale factor.
2. Page 165 of the "Microsoft QuickBASIC 4.0: BASIC Language
Reference" manual for Versions 4.00 and 4.00b
3. Page 165 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" manual for Versions 6.00 and 6.00b
4. Page 255 of the "Microsoft QuickBASIC Compiler" Version 2.0x and
3.00 manual
This documentation error was corrected in the "Microsoft BASIC 7.0:
Language Reference" manual, provided with Microsoft BASIC Professional
Development System (PDS) Version 7.00 for MS-DOS and MS OS/2.
Knowing that the default scale factor is 4, it is easy to calculate
the length of any line given any possible scale factor. The following
formula can be used to do this:
<scaled line length> = (<scale factor> / 4) * <unscaled line length>
Here <unscaled line length> is the unscaled distance that is given
immediately after the drawing commands.
Code Example
------------
The following program examples illustrate the correct use of the "S"
command and how some scale factors affect what will be drawn. This
example requires an EGA or VGA card. If you have a different card,
change the SCREEN statement to an appropriate SCREEN mode.
SCREEN 9
'The "R" command of the DRAW statement draws a line to the right of
'the current pixel position. The distance traveled is the number
'entered after the command.
DRAW "R10" 'No scale factor, line is 10 pixels long.
DRAW "S1R10" '(1/4) * 10 = 3 pixels long (rounded up).
DRAW "S2R10" '(2/4) * 10 = 5 pixels long.
DRAW "S3R10" '(3/4) * 10 = 8 pixels long (rounded up).
DRAW "S4R10" '(4/4) * 10 = 10 pixels long.
DRAW "S5R10" '(5/4) * 10 = 13 pixels long (rounded up.
DRAW "S6R10" '(6/4) * 10 = 15 pixels long.
DRAW "S7R10" '(7/4) * 10 = 18 pixels long (rounded up).
DRAW "S8R10" '(8/4) * 10 = 20 pixels long.
Keywords: docerr B_BasicCom SR# S891228-74
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/06 03:46
_____________________________________________________________________________
Q44034 How Bits in PAINT Tiling String Represent Pixels in BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
For the best explanation of tiling with the PAINT statement, please
refer to one of the following manuals:
1. Pages 181 to 191 (Section 5.8.2, "Painting with Patterns: Tiling")
of the "Microsoft QuickBASIC 4.5: Programming in BASIC" manual for
Version 4.50
2. Pages 228 to 239 (Section 5.8.2, "Painting with Patterns: Tiling")
of the "Microsoft QuickBASIC 4.0: Programming in BASIC: Selected
Topics" manual for Versions 4.00 and 4.00b
3. Pages 228 to 239 (Section 5.8.2, "Painting with Patterns: Tiling")
of "Microsoft BASIC Compiler 6.0: Programming in BASIC: Selected
Topics" for Versions 6.00 and 6.00b for MS OS/2 and MS-DOS
4. Pages 179 to 189 ("Painting with Patterns: Tiling") of "Microsoft
BASIC 7.0: Programmer's Guide" for Microsoft BASIC Professional
Development System (PDS) Version 7.00 for MS OS/2 and MS-DOS
The tiling information on these pages also applies to QuickBASIC 2.00,
2.01, and 3.00 (which support only SCREENs 0, 1, 2, 7, 8, 9, 10).
Please also see a separate article in this Knowledge Base, which can be
found by querying on the following words:
PAINT and tiling and QuickBASIC
More Information:
Consider the following sentence taken from the PAINT statement in the
language reference manual:
In the tile string, each byte masks eight bits along the x-axis
when putting down points.
The effect of each bit on screen pixels depends upon how many
attributes are in that screen mode. On two-attribute screen modes
(SCREENs 2, 3, 4, 11), each bit in the tile string directly represents
a pixel, and each byte in the tile string represents 8 pixels along
the x-axis. In graphics screens with more than two attributes (1, 7,
8, 9, 10, 12, 13), each pixel is represented by more than 1 bit (in
order to carry the extra color information). In SCREEN 13, which has 8
bits per pixel, tiling is not very useful. Tiling is most flexible in
SCREENs 2, 3, 4, and 11.
Keywords: SR# S890427-81 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/08 04:25
_____________________________________________________________________________
Q58567 Any EGA/VGA Video RAM Above 256K Not Usable in Compiled BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
Any RAM above 256K on an EGA or VGA video card cannot be used to store
screen pages during the execution of a compiled BASIC program.
This information applies to Microsoft QuickBASIC Versions 2.00, 2.01,
3.00, 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft BASIC Compiler
Versions 6.00 and 6.00b for MS-DOS, and to Microsoft BASIC
Professional Development System (PDS) Version 7.00 for MS-DOS.
These compilers are compatible with video cards that conform to the
IBM standard. Accessing video RAM above 256K is not part of this
standard.
More Information:
For example, when reading the documentation on the SCREEN statement in
either the manuals or online Help included with the above products, it
may appear that more than 2 pages of screen memory are available to a
512K VGA card operating in screen mode 9. Footnote 2 on the bottom of
Page 314 of the "Microsoft BASIC 7.0: Language Reference" manual
states the following:
Pages = Screen memory divided by page size. Eight page maximum,
one page minimum.
The page size of screen 9 for VGA is 128K. Applying the above formula,
we get the following:
Pages = 512K / 128K = 4 pages
However, 4 pages is incorrect because all the memory above 256K on
the VGA card is not usable. Therefore, the maximum number of pages is
as follows:
Pages = 256K / 128K = 2 pages
Keywords: SR# S900201-17 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/14 04:06
_____________________________________________________________________________
Q58123 "Feature Unavailable" Using FRE(-3) in .EXE Compiled in 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00
MS-DOS
Summary:
The FRE(-3) function, which returns available expanded memory in the
QuickBASIC Extended (QBX.EXE) environment, normally gives a "Feature
Unavailable" (run-time error 73) in .EXE files created with BC.EXE. An
exception is if an executable .EXE file is linked with overlays that
are each no larger than 64K, and if a LIM 4.0 EMS expanded memory
driver (defined below) is installed, then the FRE(-3) function returns
a value for the amount of free expanded memory. This information
applies to Microsoft BASIC Professional Development System (PDS)
Version 7.00 for MS-DOS.
More Information:
The FRE(-3) function returns the amount of free LIM 4.0 EMS expanded
memory available for arrays, SUBs, and functions in the QBX.EXE
environment.
Note that the only way that compiled BASIC .EXE applications can take
advantage of expanded memory is with linked overlays, but then only if
each overlay is smaller than 64K. (If expanded memory is not
accessible, overlays just swap to disk.) The FRE(-3) function returns
a value for an .EXE program only when a LIM 4.0 EMS driver is
installed and the .EXE program is able to successfully store its
overlays in expanded memory.
To check the amount of available expanded memory from an EXE program,
see Pages 204-206 in Ray Duncan's "Advanced MS-DOS Programming, 2nd
Edition" (Microsoft Press, 1988). The method described there uses
assembly language and interrupts.
Note: LIM 4.0 EMS is defined as follows:
LIM = Lotus, Intel, Microsoft
4.0 = Version number 4.0 (of the standard LIM EMS)
EMS = Expanded Memory Specification, a standard for addressing
expanded memory
For more information about linker overlays in BASIC PDS 7.00, search
for a separate article with the following keywords:
BASIC and 7.00 and linker and overlays and modules
Also see Pages 612-614 of the "Microsoft BASIC 7.0: Programmer's
Guide," in the section "Linking with Overlays".
Keywords: SR# S900125-132
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/27 06:36
_____________________________________________________________________________
Q58125 "Error Loading File (x.QLB)" After QBX /L x; Must Compile /Fs
Microsoft BASIC Compiler (BASICCOM)
7.00
MS-DOS
Summary:
The error "Error in loading file (xxx.QLB )" occurs when loading a
Quick library into QBX.EXE if the Quick library contains BASIC modules
compiled without the BC /Fs (far strings) option. The BC /Fs option is
needed because far strings are always used in the QuickBASIC Extended
(QBX) environment.
To create a Quick library that is usable in QBX, recompile with the BC
/Fs option and relink (LINK /QU) to make a new Quick library.
This information applies to Microsoft BASIC Professional Development
System (PDS) Version 7.00 for MS-DOS.
The necessity of using the /Fs option to make Quick libraries is
documented on Page 617 of the "Microsoft BASIC 7.0: Programmer's
Guide." For more information on Quick libraries, see Chapter 19,
"Creating and Using Quick Libraries."
Keywords: SR# S900126-5
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/27 06:36
_____________________________________________________________________________
Q32787 "Overflow," "Subscript Out of Range," >32,767 Array Elements
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
Page 156 of the "Microsoft QuickBASIC 4.0: BASIC Language Reference"
for Versions 4.00 and 4.00b and the "Microsoft BASIC Compiler 6.0:
BASIC Language Reference" for Versions 6.00 and 6.00b for MS-DOS and
MS OS/2 correctly states that an array dimension can have subscripts
from -32,768 to 32,767. This is also stated on Page 103 of the
"Microsoft BASIC 7.0: Language Reference" manual for Microsoft BASIC
Professional Development System (PDS) Version 7.00. For example DIM
Z%(-2000 TO 3000), which has 5001 elements, is legal.
However, these pages fail to mention that the TOTAL NUMBER of elements
in any one dimension of an array cannot exceed 32,767 (32K minus one).
For example, the following DIM statements are not allowed because they
make an array with more than 32,767 elements in one dimension:
DIM X(-10000 TO 25000) ' 35,001 elements is too many.
DIM A%(0 TO 32767) ' 32,768 elements is one too many.
To make an array that exceeds 32,767 total elements, you must
dimension it with two or more dimensions (making sure that no one
dimension has more than 32,767 elements; you must also compile with
the /AH option).
Below is an explanation of array usages that could give one of the
following errors:
"Overflow," "Math Overflow," "Subscript Out of Range,"
"Array Too Big," "Out of Memory"
More Information:
To dimension an array larger than 64K, you must make the array dynamic
and compile with the /AH (huge array) option, as in the following
example:
REM This program must be compiled with the /AH option
' $DYNAMIC
OPTION BASE 1
DIM A%(20000, 2) ' 40000 elements, taking 80000 bytes in memory.
DIM B%(20000, 4) ' 80000 elements, taking 160000 bytes in memory.
The following is a list of array-related error messages and their
possible causes:
1. Compiling an array that has a subscript larger than +32,767 or
smaller than -32,768 in the DIM statement causes an "Overflow"
error in the QB.EXE editor. If you compile it with BC.EXE, you
receive a "Math Overflow" error, as follows:
' $DYNAMIC
DIM s%(33000) ' produces "overflow" error in QB.EXE editor
' and "math overflow" error in BC.EXE.
2. A "Subscript out of range" error occurs in the QB.EXE editor at
run time if you DIMension more than 32,767 elements in one
dimension, as in the following example (invoke QB /AH):
' $DYNAMIC
DIM X%(-10000 TO 25000) ' Cannot use 35,000 elements in
' one dimension.
Compiling the above program with BC.EXE does not cause a compile
error, but gives a "Subscript Out of Range" error at run time in
the .EXE program. (Be sure to compile with the BC /D (debug) option
to properly trap array-bounds errors.)
Note that if the array has exactly 32,768 elements, the error will
not occur on the DIM statement in QB.EXE or a compiled .EXE program;
the error will occur only when an array element is used later:
REM $DYNAMIC
DIM Y%(0 TO 32767) ' Cannot use 32768 elements in one dimension.
PRINT Y%(2000) ' "Subscript Out of Range" occurs here, not on DIM.
3. An "Array Too Big" or "Subscript Out of Range" error will
display if the array exceeds 64K, is not dynamic, and was not
compiled with the /AH option. You must either make the array
dynamic and compile with /AH or make the array smaller than 64K.
If a dynamic array is larger than 128K, its array elements must
have a size that is a power of 2 (2, 4, 8, 16, 32, 64, 128, 256,
512, etc.) so that array elements do not overlap on boundaries
that are divisible by 64K.
4. An "Out of Memory" error means you have exceeded available RAM
at run time. You should reduce the size of arrays or code, or
try running the program as an .EXE program instead of inside the
QB.EXE environment. You can use the FRE function to determine
run-time memory usage.
Note that QuickBASIC Versions 2.00, 2.01, and 3.00 are limited to
arrays that do not exceed 64K in size or 32,767 elements per
dimension.
Note: 1K is equal to 1024 bytes.
Keywords: B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/27 06:36
_____________________________________________________________________________
Q57385 INT86OLD & INT86XOLD Not in QB 4.50 or BASIC 7.00 Help, Manual
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
The "Microsoft BASIC 7.0: BASIC Language Reference" manual fails to
document the INT86OLD and INT86XOLD routines.
Also, CALL INT86OLD and CALL INT86XOLD are not documented in the
online Help systems for either QB.EXE in QuickBASIC 4.50 or for
QBX.EXE, which comes with Microsoft BASIC Professional Development
System (PDS) Version 7.00.
A complete description of INT86OLD and INT86XOLD are provided below
for owners of BASIC PDS 7.00, and for owners of QuickBASIC 4.50 who do
not own a copy of the "Microsoft QuickBASIC 4.5: BASIC Language
Reference."
This information applies to Microsoft BASIC PDS 7.00 for MS-DOS and to
Microsoft QuickBASIC 4.50 for MS-DOS.
More Information:
Note that CALL INT86OLD and CALL INT86XOLD are documented in the
"Microsoft QuickBASIC 4.5: BASIC Language Reference" manual for
QuickBASIC 4.50. The following description of INT86OLD and INT86XOLD
is taken from Page 72 of that manual [additional comments are in
brackets ([])]:
CALL INT86OLD Statements
ACTION: Allows programs to perform DOS system calls
SYNTAX: CALL INT86OLD (intno, inarray(), outarray())
CALL INT86XOLD (intno, inarray(), outarray())
REMARKS: The CALL INTERRUPT statement provides an easier way to make
DOS system calls. See the entry for CALL INTERRUPT for more
information. The following list describes the arguments to
INT86OLD and INT86XOLD:
Argument Description
-----------------------
intno The DOS interrupt to perform. It is an integer between 0
and 255. See your DOS documentation for the interrupt
numbers.
inarray() An integer array specifying the register values when the
interrupt is performed.
INT86OLD uses an eight-element array, while INT86XOLD
uses a ten-element array. Table R.1 lists the array
elements and the corresponding registers.
outarray() Contains the post-interrupt register values. It has the
same structure as inarray().
If an error occurs, intno = -1 and values in outarray are
unchanged. Errors are caused by in_no not being in the range 0 - 255.
Table R.1 INT86OLD and INT86XOLD Register Values
------------------------------------------------
Array Element Register
------------------------------------------------
inarray(x) AX
inarray(x+1) BX
inarray(x+2) CX
inarray(x+3) DX
inarray(x+4) BP
inarray(x+5) SI
inarray(x+6) DI
inarray(x+7) FLAGS
inarray(x+8)* DS
inarray(x+9)* ES
------------------------------------------------
* These array elements are used only by INT86XOLD. To use the
current run-time values of DS and ES, assign the value -1 to array
elements 8 and 9.
The INT86OLD and INT86XOLD routines alter all registers except
BP and DS.
INT86OLD and INT86XOLD provide compatibility with older [QuickBASIC
2.00, 2.01, or 3.00] programs using INT86 and INT86X. Like the INT86
and INT86X routines, INT86OLD and INT86XOLD are distributed in a Quick
library [QB.QLB for QB.EXE and QBX.QLB for QBX. EXE] and in a
conventional library [QB.LIB for QuickBASIC 4.x and QBX.LIB for BASIC
PDS 7.00] on the distribution disks. The disks also contain a header
file [QB.BI for QuickBASIC 4.x or QBX.BI for BASIC PDS 7.00] for use
with the procedures. See the disk-contents list for specific
information.
Note that INT86OLD and INT86XOLD do not require the use of VARPTR.
Also, the register values are stored in the arrays beginning with the
first array element.
EXAMPLE
-------
'This example uses INT86OLD to open a file and place some text in it.
' Note: To use CALL INTERRUPT, you must load the Quick library QB.LIB
' with QuickBASIC. The program also uses the QB.BI header file.
' Include header file for INT86OLD, etc.
$INCLUDE:'QB.BI'
DIM INARY%(7),OUTARY%(7) 'Define input and output
'arrays for INT86.
'
' Define register-array indices to
' make program easier to understand.
CONST AX=0, BX=1, CX=2, DX=3, BP=4, SI=5, DI=6, FL=7
'
INARY%(AX) = &H3C00 'DOS function to create a file.
INARY%(CX) = 0 'DOS attribute for created file.
TEMP$="FOO.TXT"+CHR$(0)
INARY%(DX) = SADD(TEMP$)
'Pointer to file-name string
'with zero byte termination.
CALL INT86OLD(&H21,INARY%(),OUTARY%())
'Perform the creation.
'
INARY%(BX) = OUTARY%(AX) 'Move created file handle for write.
INARY%(AX) = &H4000 'DOS function to write to file.
TEXT$ = "hello, world"+CHR$(13)+CHR$(10)
'Define text to write to file.
INARY%(CX) = LEN(TEXT$) 'Get length of text string.
INARY%(DX) = SADD(TEXT$) 'Get address of text string.
CALL INT86OLD(&H21,INARY%(),OUTARY%())
'Perform the write.
'
INARY%(AX) = &H3E00 'DOS function to close a file.
CALL INT86OLD(&H21,INARY%(),OUTARY%())
'Perform the close.
Keywords: SR# S891226-2 docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/02/27 06:36
_____________________________________________________________________________
Q58790 Limits for Nesting Arrays in TYPE Statements in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
In the QBX.EXE (QuickBASIC Extended) environment for MS-DOS, you can
have up to 16 nested-array TYPE definitions (see Code Example 1,
below). If you exceed 16 nestings, you get a "Subscript out of range"
error.
In the QBX.EXE environment, nonarray nested TYPEs (see Code Example 2,
below) can be nested until you run out of memory.
As for the BC.EXE compiler, the limit on the number of TYPE statements
for one module is 240 whether they are nested or nonnested TYPE
definitions. If the number of TYPEs of all kinds exceeds 240, the
BC.EXE compiler gives an error of "Too Many Type statements".
This information applies to Microsoft BASIC Professional Development
System (PDS) Version 7.00 for MS-DOS and MS OS/2.
More Information:
(This information does not apply to versions of Microsoft BASIC
earlier than 7.00 because they do not support arrays in user-defined
TYPEs.)
Note that only static (nondynamic) arrays can be placed in TYPE
statements in BASIC PDS 7.00.
Code Example 1 (Arrays of Nested TYPEs)
---------------------------------------
OPTION BASE 1
TYPE test1
a AS STRING * 1
END TYPE
TYPE test2
b2(1) AS test1 'Nest it as the first TYPE
END TYPE
.
.
.
TYPE test15
b15(1) AS test14
END TYPE
TYPE test16
b16(1) AS test15
END TYPE
DIM temp(1000) AS test16
Code Example 2 (Nonarray Variables of Nested TYPEs)
---------------------------------------------------
TYPE test1
a AS INTEGER
END TYPE
TYPE test2
b2 AS test1
END TYPE
TYPE test3
b3 AS test2
END TYPE
.
.
.
TYPE test237
b237 AS test236
END TYPE
TYPE test238
b238 AS test237
END TYPE
TYPE new
none AS INTEGER 'Put in to see if the TYPEs had to be nested
END TYPE
TYPE new2
none2 AS INTEGER
END TYPE
DIM temp(100) as test238
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/01 07:19
_____________________________________________________________________________
Q38278 User-Defined TYPE vs. FIELD & MKS in Random-Access File PUT#
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
When a numeric data type (INTEGER, LONG, SINGLE, DOUBLE, or CURRENCY)
stored in a user-defined TYPE is PUT directly to a random-access file
as the third argument of the PUT statement, the values stored in the
file are stored the same as those written with PUT using variables
defined in a FIELD statement and initialized with LSET A$ = MKI$(i).
This is true for all TYPEs, except if you compile with the /MBF
option. When you compile with /MBF, SINGLE or DOUBLE user-defined
TYPEs still store on disk in IEEE format instead of in MBF format,
which is not what you desire when you compile /MBF.
This information applies to QuickBASIC Versions 4.00, 4.00b, and 4.50,
to Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS
OS/2, and to Microsoft BASIC Professional Development System (PDS)
Version 7.00 for MS-DOS and MS OS/2.
More Information:
When you compile with the /MBF compiler option, you cannot use a
SINGLE or DOUBLE declaration in user-defined variables that are used
as the third argument of a random-access PUT. When compiling /MBF, you
must use STRING*4 and STRING*8 to PUT single- and double-precision
numbers that are in a user-defined TYPE; this requires using MKS, MKD,
CVS, and CVD for conversion of those numbers between string and
numeric TYPEs.
More information on this subject can be found under "Using
Random-Access Files" on Pages 126-134 in the "Microsoft QuickBASIC
4.0: Programming in BASIC: Selected Topics" manual supplied with
QuickBASIC Version 4.00 or 4.00b and in the "Microsoft BASIC Compiler
6.0: Programming in BASIC: Selected Topics" manual supplied with
Microsoft BASIC Compiler Version 6.00 or 6.00b, or starting on Page
102 in the "Microsoft BASIC 7.0: Programmer's Guide" for Microsoft
BASIC PDS 7.00.
User-defined TYPEs are not available in earlier versions.
If you define an integer, such as in a user-defined TYPE, it is stored
as 2 bytes. A long integer is stored as 4 bytes. A single-precision
variable is stored as 4 bytes. A double-precision variable is stored
as 8 bytes. Fixed-length strings are stored with 1 byte per character.
Variable-length-string variables (such as x$ AS STRING) cannot be
placed in a user-defined TYPE record. For information about the
special way variable-length strings are stored on disk when written
directly as the third argument of the PUT# statement, search for a
separate article with the following words:
PUT and THIRD and "BAD RECORD LENGTH" and VARIABLE and STRING
Code Example
------------
The code example below shows two equivalent methods of reading and
writing to random files when you compile without the /MBF option. One
method uses user-defined-TYPE records, and the other (older) method
uses variable-length strings in a FIELD statement to define the file
record. Note how much simpler your code is when you use user-defined
TYPE records instead of records defined by a FIELD statement.
' Note: This program is NOT compatible with the /MBF compiler
' option because of the single- and double-precision TYPEs in the
' user-defined TYPE. When compiling /MBF, you must use STRING*4
' and STRING*8 to PUT single- and double-precision numbers that
' are in a user-defined TYPE, which requires rewriting this program
' to use MKS, MKD, CVS, and CVD for conversion of those numbers.
' INTEGER, LONG, and STRING TYPEs are independent of the /MBF option.
TYPE Users
i AS INTEGER
l AS LONG
s AS SINGLE
d AS DOUBLE
a AS STRING * 15
END TYPE
DIM dat AS Users
dat.i = 32000
dat.l = 21345678
dat.s = 1234.567
dat.d = 98765.54321#
dat.a = "first data set"
CLS
' The following outputs a user-defined-TYPE record to the file all
' at once:
OPEN "test.dat" FOR RANDOM AS #1 LEN = LEN(dat)
PUT #1, 1, dat
CLOSE
' The following inputs from the file into FIELDed variables:
OPEN "test.dat" FOR RANDOM AS #1 LEN = 33
FIELD #1, 2 AS a$, 4 AS B$, 4 AS C$, 8 AS d$, 15 AS e$
GET #1, 1
i1% = CVI(a$)
l1& = CVL(B$)
s1! = CVS(C$)
d1# = CVD(d$)
PRINT i1%, l1&, s1!, d1#, e$
' The following outputs a new record using the FIELDed variables:
LSET e$ = "New data "
PUT #1, 2
CLOSE
' The following inputs from the file into a user-defined variable:
OPEN "test.dat" FOR RANDOM AS #1 LEN = 33
GET #1, 2, dat
PRINT dat.i, dat.l, dat.s, dat.d, dat.a
CLOSE
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/03 05:29
_____________________________________________________________________________
Q58105 Explanation of Tiling in BASIC; PAINTing with Patterns
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
The QuickBASIC PAINT statement can be used to paint a region of the
screen in a particular color or pattern. PAINTing with a pattern is
called "tiling."
The syntax for the paint statement is as follows:
PAINT [STEP] (x,y) [,[paint] [,[bordercolor] [,[background]]]
The variable labeled "paint" is used to control the color of the
painted region. If it is a numeric value, then the number must be a
valid color attribute. The corresponding color is used to paint the
area. If paint is left blank, then the foreground color attribute is
used.
However, if you use a string in this part of the PAINT statement, then
this string is used to do "tiling." This article describes how to do
tiling in different screen modes.
For an in-depth explanation of tiling, please see the following
manuals:
1. "Microsoft QuickBASIC 4.5: Programming in BASIC," Pages 181-191
2. "Microsoft QuickBASIC 4.0: Programming in BASIC: Selected Topics,"
Pages 226-239
3. "Microsoft BASIC 7.0: Programmer's Guide," Pages 179-189
4. "Microsoft BASIC Compiler 6.0: Programming in BASIC: Selected
Topics," Pages 226-239
5. "Microsoft QuickBASIC Compiler" manual for Versions 2.00, 2.01, and
3.00, Pages 380-382
This information applies to Microsoft QuickBASIC Versions 1.00, 1.01,
1.02, 2.00, 2.01, 3.00, 4.00, 4.00b, 4.50 for MS-DOS; to Microsoft
BASIC Compiler Versions 6.00 and 6.00b for MS-DOS and MS OS/2; and to
Microsoft BASIC Professional Development System (PDS) Version 7.00 for
MS-DOS and MS OS/2.
More Information:
Each tile for a pattern is composed of a rectangular grid of pixels.
This tile grid can have up to 64 rows in all screen modes. However,
the number of pixels in each row depends on the screen mode. This is
because, depending on the number of color attributes per screen, each
pixel can be represented by a varying number of bits.
The formula for the number of bits per pixel is as follows:
Bits-per-pixel = Log (base 2) of the number-of-attributes
The number-of-attributes is the number of color attributes in that
screen mode.
The following table gives the bits-per-pixel and length-of-tile-row
for each screen mode:
Screen Mode Bits-per-Pixel Length-of-Tile-Row
----------- -------------- ------------------
1 1 8 pixels
2 2 4 pixels
3 1 8 pixels
4 1 8 pixels
7 4 2 pixels
8 4 2 pixels
9 2 4 pixels
10 2 4 pixels
11 1 8 pixels
12 4 2 pixels
13 8 1 pixel
The easiest way to define a tile row is with the CHR$() function. This
function defines one byte (8 bits) in the tiling string. It is also
easiest to use two hexadecimal digits per byte since they are easily
converted to 4 bits per digit. For instance, the following line
TILE$ = CHR$(&HF0)
sets up a tiling string with the value 11110000. It is used in a
PAINT statement, such as the following:
PAINT (100,100), TILE$
SCREENS 2, 3, 4, and 11
-----------------------
In screen modes with only two attributes (modes 2, 3, 4, and 11), the
tiling string is very simple since each bit equals one pixel. A one
(1) means that the pixel is on and a zero (0) means that the pixel is
off.
SCREENS 1, 9, and 10
--------------------
In screen modes with four attributes (modes 1, 9, and 10), the tiling
is only a little more complicated since a pixel is represented by two
bits. For instance, if the two bits were 01, then the pixel would be
drawn in color 1. If they were 11, then the pixel would be color 3.
One byte would equal 4 pixels. The byte 00011011 would draw 4 pixels
in color 0, 1, 2, and 3 consecutively. The tiling string for 00011011
would be the following:
TILE$ = CHR$(&H1B) '0001 = &H1, 1101 = &HB
SCREENS 7, 8, and 12
--------------------
Tiling in EGA and VGA screen modes with more than 4 colors is a lot
more complicated. In these modes, it takes more than one row (byte) to
define a tiling row. This is because each pixel is represented
three-dimensionally in a stack of "bit planes," rather than
sequentially in a single plane.
Below is an example of how to define a multicolored pattern consisting
of rows of alternating yellow and magenta in a screen mode with 16
color attributes (modes 7, 8, and 12). The following table shows how
the colors are defined for each pixel and how to arrange them into
CHR$() statements:
Column
1 2 3 4 5 6 7 8
-------------------
Row 1 1 1 0 0 0 0 1 1 = CHR$(&HC3)
Row 2 0 0 1 1 1 1 0 0 = CHR$(&H3C)
Row 3 1 1 1 1 1 1 1 1 = CHR$(&HFF)
Row 4 0 0 1 1 1 1 0 0 = CHR$(&H3C)
TILE$ = CHR$(&HC3)+CHR$(&H3C)+CHR$(&HFF)+CHR$(&H3C)
The preceding line defines 8 pixels of the colors magenta, magenta,
yellow, yellow, yellow, yellow, magenta, magenta. This combination
results in alternating stripes of magenta and yellow. You can get the
color by reading each column from BOTTOM to TOP. For instance, the
first pixel is defined in column 1 by the color number 0101. This is
color 5, which defaults to magenta. The sixth pixel is defined by the
number 1110, or color 14, which is yellow in the default palette.
To paint a circle with this pattern, you would do the following:
SCREEN 12
TILE$ = CHR$(&HC3)+CHR$(&H3C)+CHR$(&HFF)+CHR$(&H3C)
CIRCLE (100,100),50 'a circle of radius 50
PAINT (100,100),TILE$
END
SCREEN 13
---------
Screen mode 13, which has 256 attributes, works differently than the
other EGA and VGA modes. You have a lot less flexibility with screen
13 than you do with even the two-color screens. The most that you can
do with screen 13 tiling is to create horizontal lines of different
colors. This is very simple since one byte is equal to one pixel
color. Therefore, one CHR$() statement defines one line or row.
To paint a circle with alternating lines of color 5 (magenta) and
color 14 (yellow), you would do the following:
SCREEN 13
TILE$ = CHR$(&H5) + CHR$(&HE) 'colors 5 and 14
CIRCLE (100,100),50
PAINT (100,100),TILE$
END
Keywords: SR# S900114-17 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/06 04:31
_____________________________________________________________________________
Q58825 How BASIC Can Determine VGA Palette Colors with BIOS Interrupt
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The easiest way to determine the color value associated with a given
VGA palette register is to use BIOS Interrupt 10 Hex, with Function 10
Hex, and Subfunction 15 Hex. This information applies only to machines
that have VGA adapters and return information only on the VGA palette.
This interrupt does not supply information on the EGA or CGA palettes.
The sample program below applies only to Microsoft QuickBASIC Versions
4.00, 4.00b, and 4.50, to Microsoft BASIC Compiler Versions 6.00 and
6.00b, and to Microsoft BASIC Professional Development System (PDS)
Version 7.00 under MS-DOS. It does not apply to earlier versions of
QuickBASIC or BASIC compiler because they do support VGA SCREEN modes.
(However, the information on Interrupt 10 Hex, with Function 10 Hex
applies to any language with the ability to call BIOS routines,
including QuickBASIC Versions 2.00, 2.01, and 3.00.)
More Information:
Interrupt 10 hex (16 decimal) contains all of the advanced video
services available through the BIOS of the PC. Function 10 hex (16
decimal) of interrupt 10 hex contains the color or palette services.
These include services for setting or retrieving color information.
Subfunction 15 hex (21 decimal) of these services returns the red,
green, and blue intensities associated with a particular palette
register. From this, you can determine the color number associated
with that attribute.
There are 16 (0-15) attributes in VGA Screen 12, and 256 (0-255)
attributes in VGA Screen 13. Screen 11 has only 1. Each of these
attributes has a corresponding palette register. When you do a PALETTE
or PALETTE USING statement, you change the values in one or all of
these registers. However, BASIC has no built-in procedure for reading
these registers. Therefore, you must use CALL INTERRUPT.
The sample program below uses CALL INTERRUPT to find the default
values for all of the palette registers associated with screen mode
12. This program can easily be modified to find all 256 registers
available in screen mode 13 by looping 256 times instead of 16. The
output of the program lists the register number and the red, green,
and blue intensity values for each palette register. It also
calculates the corresponding color number with the following formula:
Colornumber = (65536 * Blue) + (256 * Green) + Red
For more information about BIOS interrupts and video graphics, see the
following books:
1. "Advanced MS-DOS Programming, 2nd Edition," by Ray Duncan
(Microsoft Press, 1988)
2. "Programmer's Guide to PC & PS/2 Video Systems," by Richard Wilton
(Microsoft Press, 1987)
Code Example
------------
The following program can be run in the QuickBASIC 4.00, 4.00b, or
4.50 environment and in the QuickBASIC environment included with
Microsoft BASIC Compiler Versions 6.00 and 6.00b by loading QB.EXE
with the QB.QLB Quick library. In the BASIC PDS 7.00 environment, load
QBX.EXE with the QBX.QLB Quick library. If the program is compiled, it
must be linked with either QB.LIB or QBX.LIB, respectively.
'PALINFO.BAS
'*** You must load QB.QLB or link with QB.LIB for QuickBASIC 4.x ***
'*** You must load QBX.QLB or link with QBX.LIB for BASIC 7.00 ***
REM $INCLUDE: 'qb.bi' 'qbx.bi for BASIC 7.00 and QBX
DIM inregs AS regtype, outregs AS regtype
SCREEN 12
PRINT "Palette Information"
PRINT "Register #", "Green", "Blue", "Red", "Color Number"
PRINT "----------", "-----", "----", "---", "-------------"
FOR i = 0 TO 15 '0 to 255 for screen 13
inregs.ax = &H1015 'AH = 10H, AL=15H
inregs.bx = i 'BL = register #
CALL interrupt(&H10, inregs, outregs)
'The following lines mask off the high/low bites of the registers
'CH = green, CL = blue, DH = red
a% = (outregs.cx AND &HFF00) / &HFF
b% = (outregs.cx AND &HFF)
c% = (outregs.dx AND &HFF00) / &HFF
d& = 65536 * b% + 256 * a% + c%
PRINT i, a%, b%, c%, d&
NEXT i
END ' End of example code.
Additional reference words: &H10 10H &H15 15H
Keywords: SR# S900214-79 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/07 05:12
_____________________________________________________________________________
Q50736 How to Enter Extended ASCII Characters in QB.EXE Using ALT Key
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
To enter most ASCII character byte values in the QB.EXE editor,
including characters without their own keys, you can hold down the ALT
key while typing in the numeric value for the character on the numeric
keypad and then releasing the ALT key. The character with that code
will be inserted at the current cursor position. For example,
ALT+1+7+2 is the symbol for one-fourth (1/4).
Extended ASCII characters (values 128 to 255) are useful for typing
line-drawing characters, foreign alphabet characters, or other special
symbols into quoted strings or comments (REM or ') in your code. For
example, QCARDS.BAS for QuickBASIC 4.50 uses extended ASCII characters
to make attractive screen boxes.
This information applies to QB.EXE in Microsoft QuickBASIC Versions
2.00, 2.01, 3.00, 4.00, 4.00b, and 4.50 for MS-DOS, to QB.EXE in
Microsoft BASIC Compiler Versions 6.00 and 6.00b for MS-DOS, and to
QBX.EXE in Microsoft BASIC Professional Development System (PDS)
Version 7.00 for MS-DOS.
More Information:
Most of the ASCII characters (32 through 255) can be entered using the
ALT key, including the normal alphabetic characters. For example, if
the ALT key is held down while the number 65 is typed on the numeric
keypad (with NUM LOCK active) and then ALT is released, "A" is
inserted at the current cursor position, since the ASCII code for "A"
is 65 (decimal). This ALT key technique also works at the MS-DOS
command line and in many other programs in MS-DOS.
How to Handle ASCII 0-31 Control Codes
--------------------------------------
Note that you cannot use the above ALT key method to embed ASCII
character codes 0 through 31 into your source code. (ASCII characters
0 through 31, which are often called control characters, have special
program-specific meanings.) You also cannot type ASCII 240 using the
ALT key in QB.EXE or QBX.EXE (ALT+2+4+0). If you want to use a
character with ASCII value 0-31 or 240 as output from your BASIC
program, you can use the CHR$() function to generate the character.
The CHR$() function can be used to generate any ASCII (0-127) or
extended-ASCII (128-255) character for output from a BASIC program.
However, in QuickBASIC 4.00, 4.00b, and 4.50, and in Microsoft BASIC
Compiler Versions 6.00 and 6.00b, the PRINT statement does not display
any character for control codes 7, 9-13, and 28-31 at run time
(whether the character is embedded in a string with CTRL+P or created
with the CHR$() function). For more information, query on the
following words:
ASCII and PRINT and SCRN and CONS
NOTE: In QB.EXE 4.00 and later and in QBX.EXE 7.00, you can use the
CTRL+P key to enter some of the control codes from 1 through 31. As an
example, for 1 press CTRL+P+A, for 2 press CTRL+P+B, for 3 press
CTRL+P+C, ..., and for 31 press CTRL+P+_ (CTRL+P+underscore).
Many of these control codes can be typed into string constants or
comments in your source code. WARNING: BC.EXE may not accept some
control codes embedded in your source file. Also, the QBX.EXE editor
does not let you enter the following CTRL+P sequences: CTRL+P+@ (0),
CTRL+P+J (10), CTRL+P+M (13), CTRL+P+\ (28), or CTRL+P+^ (30).
Microsoft recommends using the CHR$() function to generate the control
characters you need instead of typing control characters directly into
the source file.
References for ASCII Symbols 0-255
----------------------------------
The numeric character codes 0-255 are documented in the following
ASCII and extended-ASCII tables:
1. In the QuickBASIC 4.50 QB Advisor online Help system under
Contents, "ASCII Character Codes"
2. In the Microsoft Advisor online Help system for BASIC PDS 7.00
under Contents, "ASCII Character Codes"
3. Pages 464-465 of "Microsoft QuickBASIC 4.0: BASIC Language
Reference" manual for Versions 4.00 and 4.00b
4. Pages 464-465 of "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Versions 6.00 and 6.00b for MS OS/2 and MS-DOS
5. Pages 602-603 of "Microsoft BASIC 7.0: Language Reference"
Keywords: SR# S890925-102 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/14 03:54
_____________________________________________________________________________
Q51076 PE Option in OPEN COM Statement Enables Parity Checking
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
When opening a communications port (COM1 or COM2) in Microsoft
QuickBASIC or Microsoft BASIC Compiler, the parity is not checked
unless the PE option is specified in the OPEN COM statement.
The PE option must be added under the OPEN COM statement (listed
alphabetically under OPEN) in the following BASIC language references:
1. The QB Advisor on-line Help system for QuickBASIC Version 4.50,
under the OPEN COM statement
2. Page 297 of "Microsoft QuickBASIC 4.0: BASIC Language Reference"
manual for Versions 4.00 and 4.00b
3. Page 297 of "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" for Versions 6.00 and 6.00b for MS OS/2 and MS-DOS
4. Page 241 of "Microsoft BASIC 7.0: BASIC Language Reference" for
Microsoft PDS Version 7.00 for MS OS/2 and MS-DOS
5. The Microsoft Advisor on-line Help system for QuickBASIC Extended
Version 7.00, under the OPEN COM statement.
6. Page 375 of "Microsoft QuickBASIC Compiler" Versions 2.0x and 3.00
manual
The PE option is documented in the "Microsoft GW-BASIC Interpreter:
User's Reference" for Versions 3.20, 3.22, and 3.23, under the OPEN
COM statement.
More Information:
The PE option enables parity checking during communications. A "Device
I/O error" occurs if the two communicating programs have two different
parities. (Parity can be even, odd, none, space, or mark). For
example, a "Device I/O error" occurs when two programs try to talk to
each other across a serial line using the following two different OPEN
COM statements:
OPEN "COM1:1200,O,7,2,PE" FOR RANDOM AS #1
and
OPEN "COM2:1200,E,7,2,PE" FOR RANDOM AS #2
If the PE option is removed from the OPEN COM statements above, no
error occurs.
This information applies to Microsoft QuickBASIC Versions 1.00, 1.01,
2.00, 2.01, 3.00, 4.00, 4.00b, 4.50, to Microsoft BASIC Compiler
Versions 6.00 and 6.00b for MS-DOS, and to Microsoft BASIC PDS Version
7.00 for MS-DOS.
Keywords: SR# S891114-52 docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/16 05:06
_____________________________________________________________________________
Q59725 INTERRUPT for Clock Tick Counter Returns Negative Value
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
Interrupt 1A Hex, with Function 0, returns the current value of the
clock tick counter in registers CX and DX. When the low-order portion
of the clock tick counter (returned in DX) exceeds 32,767, it becomes
negative when stored as an integer in BASIC, because 32,767 is the
maximum value for a 2-byte signed integer. Below is an example to
convert the negative value to the equivalent unsigned long integer
value.
This information applies to Microsoft QuickBASIC Versions 4.00, 4.00b,
and 4.50, to Microsoft BASIC Compiler Versions 6.00 and 6.00b, and to
Microsoft BASIC Professional Development System (PDS) Version 7.00 for
MS-DOS.
More Information:
For a more complete description of converting negative signed integers
to unsigned integers, query on the following words:
CALL and INTERRUPT and negative and signed and integer
The following QuickBASIC program outputs only positive values by
removing the sign bit and adding the remaining number plus 1 to
32,767:
' $INCLUDE: 'qb.bi'
REM In BASIC 7.00, use $INCLUDE: 'qbx.bi' instead of 'qb.bi'.
REM To use CALL INTERRUPT in this program, you must do the following:
REM If you run this program in QB.EXE, use QB /L QB.QLB.
REM If you run this program in QBX.EXE, use QBX /L QBX.QLB.
REM LINK with QB.LIB (or QBX.LIB for BASIC 7.00).
DIM inregs AS regtype, outregs AS regtype
LOCATE 23, 1: PRINT "Push any key to end program."
DO
inregs.ax = 0
CALL interrupt(&H1A, inregs, outregs)
high& = outregs.cx
low& = outregs.dx
IF low& < 0 THEN 'if the low-order portion is negative:
low& = low& AND &H7FFF 'remove sign bit
low& = low& + &H7FFF + 1 'add remaining number plus 1 to 32,767
END IF
LOCATE 24, 1: PRINT high&; ":"; low&; " ";
LOOP UNTIL INKEY$ <> ""
END
Keywords: SR# S900222-218 B_BasicCom
COPYRIGHT Microsoft Corporation, 1989.
Updated 90/03/27 04:30
_____________________________________________________________________________
Q60966 QB.EXE and QBX.EXE Erase Line If You Type STRIG ON
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
If the following code example is typed into the Microsoft QuickBASIC
(QB.EXE) or QuickBASIC extended (QBX.EXE) editors, the line "STRIG ON"
will disappear when you either move the cursor off that line, press
RETURN, or try to run the program.
More Information:
This is not considered a problem with QB.EXE or QBX.EXE. Page 411 of
the "Microsoft QuickBASIC 4.0: BASIC Language Reference," Page 411 of
the "Microsoft BASIC Compiler 6.0: BASIC Language Reference," and Page
361 of the "Microsoft BASIC 7.0: Language Reference" state that the
STRIG ON and STRIG OFF statements are ignored. These statements are
provided for compatibility with earlier versions of BASIC.
Code Example
------------
PRINT "Before Line"
STRIG ON 'This line will disappear if entered
'in CAPS or not
PRINT "After Line"
Output
------
Before Line
After Line
Keywords: B_BasicCom SR# S900410-80
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/05/31 06:21
_____________________________________________________________________________
Q33301 FUNCTION Procedures Cannot Be Invoked in I/O Statements
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
You should avoid invoking (or nesting) a FUNCTION procedure in a BASIC
statement that performs output to a file. Instead, the returned value
of the FUNCTION procedure should be assigned to an intermediate
variable, and the intermediate variable can then be used in the I/O
statement. (A FUNCTION procedure is defined in a FUNCTION...END
FUNCTION block.)
This and other restrictions are described on Page 201 of the
"Microsoft QuickBASIC 4.0: BASIC Language Reference" manual for
versions 4.00 and 4.00b, as follows:
Because BASIC may rearrange arithmetic expressions for greater
efficiency, avoid using FUNCTION procedures that change program
variables in arithmetic expressions. Also avoid using FUNCTION
procedures that perform I/O in I/O statements. Using FUNCTION
procedures that perform graphics operations in graphics statements
may also cause side effects.
The same restriction is mentioned on Page 201 of the "Microsoft BASIC
Compiler 6.0: BASIC Language Reference" for versions 6.00 and 6.00b
for MS OS/2 and MS-DOS. It is also mentioned on Page 146 of the
"Microsoft BASIC 7.0: Language Reference" manual.
Please note that user-defined functions defined with the DEF FN
statement do not have the above restrictions.
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/07/10 15:43
_____________________________________________________________________________
Q58658 Quick Libraries in BASIC 7.00 Don't Use Expanded Memory
Microsoft BASIC Compiler (BASICCOM)
7.00 7.10
MS-DOS
Summary:
When using a Quick library in QBX.EXE, the programming environment
included with Microsoft BASIC Professional Development System (PDS)
version 7.00 or 7.10, the Quick library is always placed in
conventional memory. If you have expanded memory (as defined in the
LIM 4.0 EMS), QBX.EXE utilizes this expanded memory for loaded source
code segments that are smaller than 16K; however, Quick libraries are
always placed in conventional memory.
Microsoft BASIC PDS 7.00 or 7.10 is the only Microsoft BASIC product
that supports expanded memory, so this is not a consideration in
earlier versions of Microsoft BASIC Compiler or QuickBASIC.
Note: (LIM 4.0 EMS is an acronym for the Lotus/Intel/Microsoft version
4.0 Expanded Memory Specification for MS-DOS.)
Keywords: SR# S900207-70
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/07/28 07:00
_____________________________________________________________________________
Q61349 BASIC PDS 7.00 "Program Memory Overflow" with Too Many CONST
Microsoft BASIC Compiler (BASICCOM)
7.00 7.10 | 7.00 7.10
MS-DOS | OS/2
Summary:
When used with the /V switch, the BC.EXE compiler that comes with
Microsoft BASIC Professional Development System (PDS) version 7.00
produces a "Program memory overflow" error when compiling a program
that has approximately 680+ CONSTants. The compiler can still have up
to 13K "bytes free" of compiler workspace when reporting this error.
"Program memory overflow" also occurs when compiling the TEST1.BAS
program generated below using 756+ CONSTants with the BC /Fs (far
strings) option.
The CONST limits are improved in BASIC PDS version 7.10, which can
handle significantly more CONSTants than BASIC 7.00.
The error message "Program memory overflow" is misleading because
normally the compiler only gives that error when more than 64K of code
has been generated for the module being compiled. This error
represents a limitation of the compiler. This error is generated when
the number of CONSTants that can be included in a BASIC module has
been exceeded.
More Information:
The "Program memory overflow" error above is due to the amount of
internal overhead that the compiler sets aside to do its work with
CONSTants. The error message is not generated because of a lack of
compiler workspace. In this case, 13K "bytes free" is a valid number.
There is actually 13K of compiler workspace free. A different
limitation has been encountered -- the number of CONSTants BC.EXE can
handle.
The BC.EXE in QuickBASIC version 4.50 and the BC.EXE compiler in BASIC
versions 6.00b and 7.10 will successfully compile a program with over
1000 CONSTants.
Illustration
------------
To demonstrate the limitation in 7.00, use the FIRST.BAS program below
to create the BASIC program TEST1.BAS with "n" number of CONSTants.
For example, a TEST1.BAS program created with approximately 650
CONSTants will compile with no errors in BASIC PDS 7.00. A program
with 680+ CONSTants compiled with BC /V gives "Program-memory
overflow" in BASIC PDS 7.00.
As a comparison to versions earlier than 7.00, if you create a
TEST1.BAS program with 1000 CONSTants, it will compile correctly with
BC.EXE 4.50 and BC.EXE 6.00b (which have a greater capacity for
CONSTants than 7.00).
As a comparison to 7.10, in TEST1.BAS created below, 7.10 can handle
1100 CONSTants when compiled BC /V (but 1200 CONSTants gives "Program
memory overflow"). In TEST1.BAS created below, 7.10 can handle 2100
CONSTants when compiled BC /Fs (but 2200 CONSTants gives "Compiler out
of memory, 0 bytes free"). BASIC 7.10 can thus handle many more
CONSTants than 7.00.
FIRST.BAS
---------
FIRST.BAS prompts you for a number, and then creates another BASIC
program, TEST1.BAS, with that many CONSTants. Compile the resulting
TEST1.BAS with BC /V or /Fs to test for compiler limitations.
DEFINT A-Z
CLS
INPUT "How many CONSTants to you want in the file: ", Num%
OPEN "test1.bas" FOR OUTPUT AS #1
beg$ = "CONST p"
equals$ = " ="
FOR i = 1 TO Num%
constant$ = beg$ + LTRIM$(RTRIM$(STR$(i))) + equals$ + STR$(i)
PRINT #1, constant$
NEXT
CLOSE
PRINT "File 'test.bas' successfully created"
END
Keywords: SR# S900329-74
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/07/28 07:00
_____________________________________________________________________________
Q58108 BASIC 7.00 Wrong Integer FOR-NEXT Index Results in .EXE
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
In a compiled .EXE program, a FOR ... NEXT loop with an ending loop
counter value that is a variable and with a body that contains an
integer or long integer array assigned to a single- or
double-precision value can PRINT an incorrect value for the loop
counter. This problem occurs in a compiled .EXE program only, not in
the QuickBASIC Extended environment (QBX.EXE). An example of this
problem is shown in the program below.
Microsoft has confirmed this to be a problem in Microsoft BASIC
Professional Development System (PDS) version 7.00 for MS-DOS and MS
OS/2. This problem was corrected in Microsoft BASIC PDS version 7.10.
More Information:
The program below illustrates two conditions that, when occurring
together, can produce an undesirable effect. The root of this error is
embedded in the BASIC compiler (BC.EXE) optimization techniques. The
two conditions necessary to show this problem are as follows:
1. A variable (not a constant) is used as the stop (ending) loop
counter value on a FOR ... NEXT statement.
2. An integer or long integer array (which is subscripted with the
loop counter) is assigned to a single- or double-precision number.
(This is known as "typecasting" -- a single- or double-precision
number is typecasted to an integer or long integer.)
The problem occurs only on the first PRINT statement in the source
file that prints the loop counter (i%). For all loop iterations, that
PRINT i% statement incorrectly displays the fixed value of t#, the
ending loop value. PRINT i% statements farther down in the source code
work correctly.
To eliminate the problem, use one of the following workarounds:
1. Compile with the BC /X option.
Note: In the example below, the debug compiler option (/D) does
not correct the problem.
2. Use the CINT() function to convert the real number to an integer
before assigning it to the integer or long integer array.
3. Use a numeric constant (instead of a variable) for the ending
value of the FOR loop counter.
4. Compile with the BC /FPa option (instead of the default /FPi).
Code Example
------------
Dim ia%(10) 'An integer or long array shows problem.
t# = 5 't# can be any numeric type (!, @, #, %, or &)
FOR i% = 1 to t# 't# is the ending value of the loop counter, i%
PRINT i%; 'This value incorrectly prints equal to t# in .EXE
ia%(i%) = 46.7 'A real number is typecast to an integer or
'long-integer value and assigned to the array
REM ia%(i%) = CINT(46.7) 'Workaround: use CINT(46.7) in the above line.
PRINT i%; 'This value prints correctly.
PRINT ia%(i%) 'This value prints correctly.
NEXT i%
END
Below is the (incorrect) output from this .EXE (compiled without
BC /X):
5 1 46.7
5 2 46.7
5 3 46.7
5 4 46.7
5 5 46.7
The output should be as follows:
1 1 46.7
2 2 46.7
3 3 46.7
4 4 46.7
5 5 46.7
Keywords: SR# S900123-121 buglist7.00 fixlist7.10
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/02 05:32
_____________________________________________________________________________
Q59008 Bad Integer Output Using DEF FN, VAL, FOR-NEXT in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
When run as an .EXE program (compiled with BC.EXE), the program below
gives incorrect output in Microsoft BASIC Professional Development
System (PDS) version 7.00 for MS-DOS and MS OS/2. The same program
gives correct output when run in the QBX.EXE environment or compiled
with the BC /D option.
The program fails when it assigns an integer array (which is
subscripted by a FOR...NEXT loop counter) to the VAL of a DEF FN
string function operating on a temporary string that was assigned to
an array element that is subscripted by the FOR...NEXT loop counter.
Microsoft has confirmed this to be a problem in Microsoft BASIC
Professional Development System (PDS) version 7.00. This problem was
corrected in BASIC PDS version 7.10.
More Information:
This problem does not occur with an .EXE compiled in QuickBASIC
version 4.50 or earlier.
The program below outputs "2 2" instead of "1 2" from an .EXE program.
(The problem occurs whether compiled as a stand-alone .EXE or as an
.EXE requiring the BRT module). This problem is corrected by doing any
one of the following:
1. Compiling with the BC /D option.
2. Removing the DEFINT A-Z line.
3. Replacing n (the ending value of the FOR...NEXT loop counter) with
the constant 2 in the FOR...NEXT statement.
4. Eliminating the use of the temporary (placeholder) variable t$ by
putting s$(i) in place of it in the VAL function.
5. Replacing d(i) with a nonarray (scalar) variable.
Code Example
------------
DEFINT A-Z
DIM s$(1 TO 2), d(1 TO 2)
DEF FNa$ (x$)
FNa$ = x$
END DEF
CLS
n = 2
s$(1) = "1"
s$(2) = "2"
PRINT
FOR i = 1 TO n
t$ = s$(i)
d(i) = VAL(FNa$(t$))
' One workaround is to use: d(i) = VAL(FNa$(s$(i)))
PRINT d(i);
NEXT
END
Keywords: SR# S900217-5 buglist7.00 fixlist7.10
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/02 05:32
_____________________________________________________________________________
Q60965 Problem When Using Integer Array and FOR Loop in BASIC 7.00
Microsoft BASIC Compiler (BASICCOM)
7.00 | 7.00
MS-DOS | OS/2
Summary:
The code example below shows a case where using an integer variable
for a FOR loop-counter can produce incorrect results in a compiled
BASIC program. The program must have the following elements to
reproduce the problem:
1. The program must contain a simple FOR loop (not nested, etc.).
2. The FOR loop must contain a call to the INT function.
3. The upper bound of the FOR loop must be specified with a
variable, not a literal.
4. The loop-counter variable and upper-bound variable must be
integers.
The code example below demonstrates these conditions and prints out
the value of the loop counter each time it loops. In a compiled BASIC
program, this example always prints the upper bound of the loop
counter.
Microsoft has confirmed this to be a problem in the BC.EXE compiler
that comes with Microsoft BASIC Professional Development System (PDS)
version 7.00 for MS-DOS and MS OS/2. This problem was corrected in
BASIC PDS version 7.10.
More Information:
This problem does not occur in QBX.EXE (the QuickBASIC extended
environment that comes with BASIC PDS 7.00). This problem also does
not occur in the BC.EXE or QB.EXE environments that come with
QuickBASIC versions 4.00, 4.00b, or 4.50.
Any of the following workarounds corrects the problem:
1. Compile with the BC /X option.
2. Compile with the BC /FPa option.
3. Change the DEFINT statement to DEFtype, where "type" is anything
but INT (integer).
4. Change the upper bound on the FOR-LOOP to a literal.
Code Example
------------
DEFINT A-Z 'Change to something other than INT
'or remove the line
DIM test(4)
temp = 4
FOR k = 1 TO temp 'Use 4 instead of temp.
PRINT k 'In a compiled program, this line
'always prints the upper bound
'of the FOR-LOOP.
test(k) = INT(1.0) 'Remove the INT function CALL.
NEXT k
The following is the output in the QBX.EXE environment (correct):
1
2
3
4
The following is the output from a compiled 7.00 .EXE program
(incorrect):
4
4
4
4
Keywords: SR# S900411-147 buglist7.00 fixlist7.10
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/02 05:32
_____________________________________________________________________________
Q64430 Abrupt Branch to ON Event GOSUB Handler from Separate Handler
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
When program control is within an ON <event> GOSUB handler, it is
still possible to trap other events (where <event> can be COM, KEY,
PEN, PLAY, STRIG, TIMER, etc.). This is normal behavior for ON <event>
GOSUB trapping, but may be undesirable for those who want to disable
all event trapping within an ON <event> handler. This article gives a
code example demonstrating normal flow of control when a second
trappable key is pressed within a given ON KEY GOSUB handler. The
comments in this program show a method of temporarily disabling KEY
and other event trapping within an ON KEY GOSUB handler.
This information applies to Microsoft QuickBASIC versions 2.00, 2.01,
3.00, 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft BASIC Compiler
versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC
PDS (Professional Development System) versions 7.00 and 7.10 for
MS-DOS and MS OS/2.
More Information:
Within an ON <event> GOSUB handler, event trapping is suspended within
the handler for only the trapped event. Any other active event traps
(set with other ON <event> GOSUB statements) triggered within an event
handler will cause control to immediately branch to the other ON
<event> handler during execution of the initial handler. Upon
terminating the second handler, control resumes where it left off in
the original handler. This abrupt transfer of control may be
problematic for those who want all actions surrounding a particular
event, a key press for example, to be processed in full before
subsequent key presses or events are handled.
The code example below demonstrates a case of control branching from
one ON KEY handler to another when a second key is pressed within the
first handler. The example contains the code (remarked out) necessary
to temporarily disable all ON KEY and other event trapping within the
initial ON KEY handler. If you unremark (uncomment) the code shown,
the program will complete each handler without interruption.
Code Example
------------
'DECLARE SUB EventsStop () ' These are the DECLARE statements for the
'DECLARE SUB EventsOn () ' SUBs that disable and enable key and
' event trapping. (DECLARE statements are
' not needed or supported for QuickBASIC
' 3.00 or earlier versions.)
CLS
ON KEY(1) GOSUB F1KeyHandler ' Trapping for F1 function key.
ON KEY(2) GOSUB F2KeyHandler ' Trapping for F2 function key.
KEY(1) ON
KEY(2) ON
PRINT "Please, press the F1 key"
SLEEP
PRINT "Exiting program"
END
' To temporarily disable all key and event trapping within an
' event handler, the CALL to SUB EventsStop must be the first
' statement and the CALL to SUB EventsOn must be the last statement
' of the handler before the RETURN.
F1KeyHandler:
'CALL EventsStop ' Include this statement to temporarily
' disable all or selected ON KEY and
' event statements
PRINT "In F1 key handler"
PRINT "Press F2 to jump to F2 key handler"
SLEEP
PRINT "Exiting F1 key handler"
'CALL EventsOn ' Include this statement so that any
' keys pressed or events occurring
' during the execution of this handler
' will be processed at this point.
RETURN
F2KeyHandler:
'CALL EventsStop ' Include this statement to temporarily
' disable all or selected key and event
' trapping within this handler.
PRINT "In F2 key handler"
PRINT "Exiting F2 key handler"
'CALL EventsOn ' Include this statement so that
' any trappable keys or events triggered
' during the execution of this handler
' will be processed at this point.
RETURN
SUB EventsOn 'All keys and events to enable go in here
KEY(1) ON
KEY(2) ON
'TIMER ON 'Examples of events that may be enabled
'COM(1) ON
END SUB
SUB EventsStop 'All keys and events to temporarily disable
KEY(1) STOP 'go in here
KEY(2) STOP
'TIMER STOP 'Examples of events that may be temporarily
'COM(1) STOP 'disabled
END SUB
Additional References
---------------------
For more description of normal program flow within an ON <event> GOSUB
handler, please see the following:
1. Page 315 of "Microsoft BASIC 7.0: Programmer's Guide" for BASIC PDS
versions 7.00 and 7.10
2. Page 234 of "Microsoft QuickBASIC 4.5: Programming in BASIC" manual
for QuickBASIC version 4.50
3. Page 289 of "Microsoft QuickBASIC 4.0: Programming in BASIC:
Selected Topics" manual for QuickBASIC versions 4.00 and 4.00b
4. Page 357 of "Microsoft QuickBASIC Compiler" manual for versions
2.00, 2.01, and 3.00
Keywords: SR# S900712-87 B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/04 05:35
_____________________________________________________________________________
Q59734 BASIC 7.00 Can Write Whole Array (in TYPE) to Disk at Once
Microsoft BASIC Compiler (BASICCOM)
7.00 7.10 | 7.00 7.10
MS-DOS | OS/2
Summary:
Microsoft BASIC Professional Development System (PDS) versions 7.00
and 7.10 introduce support for static arrays in user-defined TYPE
definitions. This means that you can write an entire array (in a user
TYPE record) to a disk file at once. The code example below writes an
entire array to a RANDOM or BINARY file using a single PUT# statement.
More Information:
Note that you cannot output arrays all at once (in one PRINT# or
WRITE# statement) to files opened with sequential access (OPEN FOR
OUTPUT). With sequential access (OPEN FOR OUTPUT or INPUT), you must
output or input just one array element at a time.
You must use RANDOM or BINARY access to write a static
nonvariable-length string array to a file all at once (as shown in the
examples below).
Note that in Microsoft QuickBASIC versions 4.00, 4.00b, and 4.50 for
MS-DOS, in Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS
and MS OS/2, and in Microsoft BASIC PDS versions 7.00 and 7.10 for
MS-DOS and MS OS/2, you can directly write whole records (variables)
of a given user-defined TYPE to disk as the third argument of the PUT#
statement. Each and every element of the user-defined TYPE record is
automatically copied to the file. If the data is numeric and you
output to a file OPENed with RANDOM or BINARY access, the data is
automatically stored in numeric format (without requiring a lengthy
FIELD statement or numeric-to-string conversion functions such as
MKS$, MKD$, MKI$, or MKL$).
Since an array can be an element of a record of user-defined TYPE in
BASIC 7.00 and 7.10 (but not in earlier versions), you can write a
whole array at once into a disk file, as shown below.
Code Example
------------
The following example, compiled in BASIC PDS 7.00 or 7.10, shows how
to write a whole array to disk at once, using just one PUT# statement:
TYPE rec1
array1(20) AS INTEGER
END TYPE
DIM var1 AS rec1, var2 AS rec1 'DIMension var1 & var2 with TYPE rec1
FOR i = 1 TO 20 ' Fill each element of the array:
var1.array1(i) = i
NEXT
' The following OPEN statements may OPEN FOR either RANDOM or BINARY:
OPEN "test.dat" FOR RANDOM AS #1
PUT #1, , var1 ' Write whole array to disk all at once.
CLOSE
OPEN "test.dat" FOR RANDOM AS #1
GET #1, , var2 ' Reads array all at once into var2.
FOR i = 1 TO 20 ' Print the contents of the array var2.array1:
PRINT var2.array1(i);
NEXT
CLOSE
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/04 05:35
_____________________________________________________________________________
Q32216 Two Ways to Pass Arrays in Compiled BASIC to Assembler Routine
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 7.10 | 6.00 6.00b 7.00 7.10
MS-DOS | OS/2
Summary:
An array in a compiled BASIC program can be passed to an assembly
language program in the two ways shown below. The array can be passed
either through the CALL statement's parameter list or, for static
arrays only, through a COMMON block.
Microsoft does not support passing dynamic arrays through COMMON to
assembler (since this depends upon a Microsoft proprietary dynamic
array descriptor format that changes from version to version). Dynamic
arrays can be passed to assembler only as parameters in the CALL
statement.
This information applies to the following products:
1. Microsoft QuickBASIC Compiler versions 4.00, 4.00b, and 4.50
2. Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS and
MS OS/2
3. Microsoft BASIC Professional Development System (PDS) versions 7.00
and 7.10 for MS-DOS and MS OS/2
More Information:
For more information about passing other types of parameters between
BASIC and MASM, search in the Software/Data Library for the following
word:
BAS2MASM
The following information pertains to passing an array to an assembly
routine through the CALL parameter list:
If the array is passed through the parameter list, all the information
about the array must be passed. This includes the length of each item,
the number of items, and the segment and offset of the base element of
the array. The first two items may be hardcoded into the assembler
program, but the latter two must be passed because there is no way of
knowing where the array will be located before the program starts. The
following is an example:
DECLARE SUB PutInfo (BYVAL Segment%, BYVAL Offset%)
DIM a%(100)
CALL PutInfo(VARSEG(a%(0)),VARPTR(a%(0)))
The assembly-language program pulls the information off the stack,
then continues with its purpose. Please note that this method works
with both static and dynamic arrays.
The following information pertains to passing an array to an assembly
language routine through a COMMON block:
Passing information through a COMMON block to an assembly language
program is fairly simple. In the assembly language program, a segment
is set up with the same name as the COMMON block and then grouped with
DGROUP, as follows:
BNAME segment 'BC_VARS'
x dw 1 dup (?)
y dw 1 dup (?)
z dw 1 dup (?)
BNAME ends
dgroup group BNAME
The above assembler code matches the following BASIC code named COMMON
block:
DEFINT A-Z
COMMON /BNAME/ x,y,z
Passing arrays through the COMMON block is done in a similar fashion.
However, only static arrays may be passed to assembler through COMMON.
Note: This information does not apply to passing far
variable-length-strings in BASIC PDS version 7.00 or 7.10. For
information on accessing far variable-length-strings in BASIC PDS
version 7.00 or 7.10, see Chapter 13, "Mixed-Language Programming with
Far Strings," in the "Microsoft BASIC 7.0: Programmer's Guide" for
versions 7.00 and 7.10.
When static arrays are used, the entire array is stored in the COMMON
block. Consider the following example:
BASIC Program
-------------
DECLARE SUB PutInfo ()
DIM b%(100)
COMMON /BNAME/ a%, b%(), c%
CALL PutInfo
CLS
PRINT a%, c%
FOR i = 0 TO 100
PRINT b%(i);
NEXT i
END
Assembly Program
-----------------
;Note, this program uses MASM version 5.x directives.
.model Medium
BNAME segment COMMON 'BC_VARS'
a dw 1 dup (?)
b db 202 dup (?) ;Note that all the space for the
;array is set up
c dw 1 dup (?)
BNAME ends
dgroup group BNAME
.code
public PutInfo
PutInfo proc far
push bp
mov bp,sp
push di
inc word ptr dgroup:a
inc word ptr dgroup:c
mov cx,101
mov di,offset dgroup:b
repeat:
mov [di],cx
add di,2
loop repeat
pop di
pop bp
ret
PutInfo endp
end
As noted in the assembly source, the space for the array must be set up
in the COMMON segment.
When dynamic arrays are used, the array is not placed in the COMMON
block. Instead, a multibyte array descriptor is placed on the COMMON
block. The dynamic array descriptor changes from version to version,
and is not released by Microsoft -- it is considered Microsoft
proprietary information.
Keywords: B_QuickBas
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/09 05:31
_____________________________________________________________________________
Q37770 "Program Memory Overflow": Break into SUBprograms
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 7.10 | 6.00 6.00b 7.00 7.10
MS-DOS | OS/2
Summary:
The code generated by BC.EXE in Microsoft BASIC Compiler versions 6.00
and 6.00b, Microsoft BASIC Professional Development System (PDS)
versions 7.00 and 7.10, and QuickBASIC versions 4.00, 4.00b, and 4.50
may be larger (on disk or in run-time memory) than that compiled with
previous versions. With the increase in product features, the program
size has grown. Therefore, it is possible that your program will no
longer compile and will give a "Program Memory Overflow" error. This
error can be avoided by breaking the program into smaller, separately
compiled subprograms or FUNCTION procedures.
More Information:
At compile time, the BC.EXE compiler options can make a big difference
in object file size. The /D (debug), /E (error handling with RESUME
label), and /V (event handling between statements) compiler options
generate the largest amount of code. The /X (error handling with
RESUME NEXT, RESUME, and RESUME 0) and /W (event handling between
lines) options generate less code than /E and /V; however, /X and /W
still generate a fair amount of code.
If you find that even with a careful choice of compiler options the
program is still too big to compile, the program should be broken up
into smaller modules that can be linked together.
Each module can contain up to 64K in code and share a 64K data segment
with the other modules. For code to be placed into its own module, it
must be a subprogram or FUNCTION procedure. A subprogram procedure is
surrounded by the SUB and END SUB statements. A FUNCTION procedure is
surrounded by the FUNCTION and END FUNCTION statements. For more
information about the memory the compiler uses and how to determine
segment sizes for code and data, query in this Knowledge Base for the
following words:
determining and segment and sizes and LINK and /Map
Also, if a program works in the QuickBASIC environment, BC.EXE usually
compiles it to an executable program. However, there are two
exceptions. If the program contains a large $INCLUDE file with RESUME
and RESUME NEXT in it, the BC.EXE compiler may fail. The BC.EXE
compiler builds a table of line numbers for RESUME/RESUME NEXT
statements at 4 bytes each so it can tell where to resume back to.
This adds additional code to the program and causes memory depletion.
The QB.EXE interpreter does not have to keep the table, so less code
is generated.
To work around this situation, you can do the following two things:
1. Use RESUME <label> instead of RESUME NEXT. Note that RESUME <label>
should only be used to return to the same procedure level as where
the error occurred, or else stack space will be consumed without
being released, which can result in an "Out of stack space" error.
For example, if an error occurs in a SUB procedure that is handled
by an error handler in the main level code that performs RESUME
<label> to a label in the main level code, then return addresses
for the SUB remain unused on the stack and unavailable to the
program.
2. Break the program into smaller separate modules.
If you have a large number of static numeric arrays, the BC.EXE
compiler can run out of memory. In the QuickBASIC QB.EXE or QBX.EXE
environment, static numeric arrays are not stored in the DGROUP data
segment; they are stored in an additional segment. When the program is
compiled with BC.EXE, these arrays are placed into the DGROUP data
segment. This segment is limited to 64K. One way to work around this
segment limitation is to make the static arrays dynamic to put them in
the far heap.
Dynamic non-variable-length-string arrays are stored on the far heap
and not in the DGROUP data segment. There are three different ways to
make an array dynamic, as follows:
1. Use the REM $DYNAMIC metacommand to make all arrays dynamic.
2. Use a variable as the number of elements in the DIM statement, as
in the following example:
x=20
DIM array(x)
3. Place the array in COMMON and dimension the array after the COMMON
statement:
COMMON SHARED array()
DIM array(100)
Once the program compiles, there are a few things that can be done to
reduce the size of the linked executable file. The following is a list
of ways to help reduce the size of .EXE files:
1. Use the /E (/EXEPACK) linker option. This linker option removes
sequences of repeated bytes and optimizes the load-time relocation
table. The result is that executable files linked with this option
may be smaller and may load faster than files linked without this
option. Note: The /EXEPACK option cannot be used with the /Q
option.
2. For stand-alone .EXE files (that is, those compiled with the BC /O
option) that use a string variable for the filename in the OPEN
statement, linking in the file NOCOM.OBJ reduces the size of the
programs by about 4K. (NOCOM.OBJ should be used only if your
program contains no OPEN "COM" statements.) For example, the
following is a program that NOCOM.OBJ will help make smaller:
X$="test.dat"
OPEN X$ FOR OUTPUT AS #1
In addition to NOCOM.OBJ, BASIC compiler version 6.00 provides other
NOxxx.OBJ files, including NOCGA.OBJ, NOEGA.OBJ, NOGRAPH.OBJ,
NOHERC.OBJ, NOLPT.OBJ, NOVGA.OBJ, and SMALLERR.OBJ. These files are
discussed in both the "Microsoft BASIC Compiler 6.0: User's Guide" and
the README.DOC found on Disk 1. These NOxxx.OBJ files can also be used
when a custom run-time module is built with the BUILDRTM.EXE utility.
For more information about stub files and optimizing code for size and
speed, see Chapter 15, "Optimizing Program Size and Speed," in the
"Microsoft BASIC 7.0: Programmer's Guide" for versions 7.00 and 7.10.
Keywords: SR# G881028-5376 B_QuickBas
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/11 05:20
_____________________________________________________________________________
Q60968 QBX.EXE 7.10 Expanded Memory Usage Better Than 7.00; 32K Table
Microsoft BASIC Compiler (BASICCOM)
7.00 7.10
MS-DOS
Summary:
The QuickBASIC Extended environment (QBX.EXE) can use up to 16 MB
(megabytes) of Lotus-Intel-Microsoft (LIM) 4.0 expanded memory
under MS-DOS. If the expanded memory is available, QBX.EXE
automatically stores in it SUBs, FUNCTIONs, and module-level code
units that are no greater than 16K in size. If QBX.EXE is invoked with
the /Ea switch, arrays that are no greater than 16K in size are also
stored in expanded memory.
In QBX.EXE in BASIC PDS version 7.00, the memory is allocated in 16K
pages; for example, a 2K procedure consumes 16K and wastes 14K (16K
minus 2K) of expanded memory. Also, when one or more SUBs or FUNCTIONs
are stored in expanded memory, QBX.EXE makes a one-time allocation of
32K (two 16K pages) in expanded memory as overhead for its own
internal tables.
QBX.EXE in BASIC PDS version 7.10 is enhanced so that memory is
allocated in 1K pages; for example, a 1K procedure or array takes up
1K, thus using expanded memory much more efficiently than in QBX.EXE
7.00.
This article applies to Microsoft BASIC Professional Development
System (PDS) versions 7.00 and 7.10 for MS-DOS.
More Information:
Examples of Expanded Memory Usage in QBX.EXE 7.00
-------------------------------------------------
As an example for BASIC PDS 7.00, suppose QBX.EXE is run on a machine
for which FRE(-3) reports that 2720K of expanded memory is available.
When the first module-level statement is entered, FRE(-3) would then
return 2704K, 16K less. When the first SUB or FUNCTION is created
after that, FRE(-3) would return 2656K, 48K less -- 16K for the SUB or
FUNCTION itself and 32K for QBX.EXE's internal tables.
When SUBs, FUNCTIONs, module-level code units, or arrays (if /Ea is
used) are deleted, QBX.EXE deallocates the expanded memory they were
using. The tables, however, will not be deallocated unless New Program
is chosen from the File menu.
In 7.00, a single-element integer array takes the same expanded memory
space (16K) as an array with 8192 elements. Likewise, a SUB with a
single PRINT statement takes the same space (16K) as a large SUB with
hundreds of statements. (This is no longer true in 7.10, where
expanded memory usage is more efficient.)
To use expanded memory to its best potential in the QBX.EXE 7.00
environment, you should try to make your SUBs as close to the 16K
limit as possible without exceeding it. (This is not necessary in
7.10.) The size of the SUBs (in kilobytes) is listed in the View Subs
(F2) dialog box to the right of each SUB.
Likewise, arrays in QBX.EXE 7.00 will use expanded memory more
efficiently if they are dimensioned to be just under the 16K page
size. (This is not necessary in 7.10.)
References:
Microsoft BASIC Professional Development System (PDS) versions 7.00
and 7.10 offer expanded memory support under the Lotus-Intel-Microsoft
version 4.0 Expanded Memory Specification (LIM 4.0 EMS) for code and
data in the QBX.EXE environment under MS-DOS. Earlier versions do not
offer any expanded memory support. LIM 4.0 EMS support is discussed in
the "Microsoft BASIC 7.0: Getting Started" manual and in the
"Microsoft BASIC 7.1: Getting Started" manual.
To be compatible with BASIC PDS 7.00 or 7.10, the expanded-memory
device driver must observe the LIM 4.0 EMS.
Keywords: SR# S900228-5
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/11 05:20
_____________________________________________________________________________
Q48205 Example of BASIC Function Returning a String to C
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The two programs below demonstrate how a Microsoft BASIC function can
return a string to C.
This information about interlanguage calling applies to QuickBASIC
versions 4.00, 4.00b, 4.50 for MS-DOS, to Microsoft BASIC Compiler
versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC
Professional Development System (PDS) versions 7.00 and 7.10 for
MS-DOS and MS OS/2.
For BASIC PDS 7.00 and 7.10, this example applies to near strings
only. If you are using far strings (/Fs during compile or in the
QBX.EXE environment), you must use the string-manipulation routines
supplied with BASIC PDS 7.00 and 7.10 (StringAssign, StringRelease,
StringAddress, and StringLength). For more information about using far
strings, see Chapter 13 of the "Microsoft BASIC 7.0: Programmer's
Guide" for versions 7.00 and 7.10.
More Information:
For more information about passing other types of parameters between
BASIC and C, and a list of which BASIC and C versions are compatible
with each other, search in the Software/Data Library for the following
word:
BAS2C
Code Example
------------
The following BASIC program is BSTRF.BAS, which contains a function
that returns a string to a calling C routine:
DECLARE SUB CSUB CDECL ()
CALL CSUB
END
FUNCTION basvarfunc$(dummy%)
basvarfunc$ = "This is the string"
END FUNCTION
The following program is CSTRF.C, which calls a BASIC routine that
returns a string. A string descriptor is created to receive the data
returned by the BASIC function.
#include <stdio.h>
struct stringdesc
{
int length; /* string length */
char *string; /* string address */
};
extern struct stringdesc * pascal basvarfunc(int *dummy);
struct stringdesc *std;
void csub()
{
int i;
std = basvarfunc(0);
printf("Length of string: %2d\r\n", std->length);
for(i = 0; i < std->length; i++)
printf("%c", std->string[i]);
printf("\r\n");
}
To demonstrate these programs from an .EXE program, compile and link
as follows:
BC BSTRF.BAS;
CL /c /AM CSTRF.C;
LINK /NOE BSTRF CSTRF;
BSTRF.EXE produces the following output:
Length of String: 18
This is the string
Keywords: B_BasicCom S_C S_QuickC
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/11 05:20
_____________________________________________________________________________
Q48207 Example of Passing Strings from C to BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The two programs below demonstrate how Microsoft C can create and pass
both fixed-length and variable-length strings to Microsoft BASIC.
This information about interlanguage calling applies to QuickBASIC
versions 4.00, 4.00b, 4.50 for MS-DOS, to Microsoft BASIC Compiler
versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC
Professional Development System (PDS) versions 7.00 and 7.10 for
MS-DOS and MS OS/2.
For BASIC PDS 7.00 and 7.10, this example works only with near
strings. If you are using far strings (BC /Fs compile switch or in
QBX.EXE), you must use the string-manipulation routines provided with
BASIC PDS 7.00 and 7.10 to change variable-length strings
(StringAssign, StringRelease, StringAddress, and StringLength). For
more information about using far strings, see Chapter 13 of the
"Microsoft BASIC 7.0: Programmer's Guide" for versions 7.00 and 7.10.
More Information:
For more information about passing other types of parameters between
BASIC and C and a list of which BASIC and C versions are compatible
with each other, search in the Software/Data Library for the following
word:
BAS2C
Code Example
------------
The following BASIC program is BSUB.BAS, which invokes a C routine
that creates two strings and passes them to a BASIC subroutine. The
BASIC subroutine prints out the string (and the string's length)
received from the C routine.
DECLARE SUB CSUB CDECL()
TYPE fixstringtype ' Must use type to pass fixed-length string
B AS STRING * 26 ' in parameter list.
END TYPE
CALL CSUB
END
SUB BASSUB(A$, B AS fixstringtype) ' Subroutine called from C
PRINT A$
PRINT LEN(A$)
PRINT B.B
PRINT LEN(B.B)
END SUB
The following program is CSUB.C, which builds a string descriptor that
is passed to a called BASIC subroutine:
#include <string.h>
struct stringdesc
{
int length; /* string length */
char *string; /* near address of the string */
};
extern void pascal bassub(struct stringdesc *basstring,
char *basfixstring);
struct stringdesc *std;
char thesecondstring[26];
void csub()
{ /* create the strings */
std->length = 18;
strcpy(std->string, "This is the string");
strcpy(thesecondstring, "This is the second string");
bassub(std, thesecondstring); /* call BASIC subroutine */
}
To demonstrate these programs from an .EXE program, compile and link
as follows:
BC BSUB.BAS;
CL /c /AM CSUB.C;
LINK /NOE BSUB CSUB;
BSUB.EXE produces the following output:
This is the string
18
This is the second string
26
Keywords: B_BasicCom S_C S_QuickC
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/11 05:20
_____________________________________________________________________________
Q59727 Legal Data Delimiters When Using INPUT #n Statement
Microsoft QuickBASIC Compiler (QUICKBAS)
2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
This article corrects several documentation errors concerning how to
delimit data in a sequential file that is to be read by the INPUT#
statement.
The INPUT# statement reads data items from a sequential device or file
and assigns them to variables. If the data items in the file are
numeric values, they should be separated with a space, carriage return
(CR), or comma. Strings should be separated with a carriage return or
a comma, or enclosed in double quotation marks. A linefeed (LF) by
itself should not be used as a file delimiter in either case.
More Information:
The following references incorrectly state that a linefeed may be used
as a delimiter between data items in a file. These references also
omit the fact that string data may be delimited by a comma.
1. Page 304 of the "Microsoft QuickBASIC Compiler" manual for versions
2.00, 2.01, and 3.00
2. Page 225 of the "Microsoft QuickBASIC 4.0: BASIC Language
Reference" manual for QuickBASIC versions 4.00 and 4.00b
3. Page 225 of the "Microsoft BASIC Compiler 6.0: BASIC Language
Reference" manual for versions 6.00 and 6.00b
4. Page 167 of the "Microsoft BASIC 7.0: Language Reference" manual
for Microsoft BASIC Professional Development System (PDS)
versions 7.00 and 7.10
5. Under the INPUT# statement in the QB Advisor online Help system
for QuickBASIC version 4.50
In addition, all the above references (except #4) incorrectly state
that string data items may be delimited with spaces. Only numeric data
items may be delimited with spaces. String data items must be
delimited by a comma or a carriage return, or enclosed in double
quotation marks.
If you need some other character, such as a linefeed by itself, to act
as a delimiter, then a file may be read in BINARY mode. When a file is
opened in BINARY mode, the data is not interpreted and the program
must be written to interpret or "filter" each character as needed.
The following is a description of how the INPUT# statement handles a
linefeed, carriage return, space, and comma if one of these characters
is used as a delimiter between data items. Also, the program below
exhibits the behavior of these characters when used as delimiters.
Numeric Input Syntax: INPUT #n, <numeric variable>
--------------------------------------------------
This reads a linefeed in as a numeric value instead of a delimiter.
Each time a linefeed is encountered, the linefeed character is treated
as a data item and a value of 0 is returned for the input.
A carriage return, space, or comma functions correctly as a delimiter
for numeric input.
String Input Syntax: INPUT #n, <string variable>
-------------------------------------------------
This ignores the linefeed character completely. If two data items are
separated by a linefeed and read in as strings, the two data items are
read in as one string that is a concatenation of the two data items.
A space between two data items causes the two data items to be read in
as one string, and the space is an actual character in that string.
A carriage return or comma functions correctly as a delimiter. If a
comma appears between a pair of double quotation marks, the comma is
treated as part of the string. A carriage return always acts as a
delimiter, terminating any string delimited by a beginning double
quotation mark.
Sample Code
-----------
CLS
INPUT "Enter 'q' to quit. Enter 'c' to continue==> ", start$
WHILE start$ <> "q"
CLS
OPEN "numeric.dat" FOR OUTPUT AS #1
OPEN "string.dat" FOR OUTPUT AS #2
PRINT "Input the ASCII code for the delimiter you wish to attempt:"
PRINT " 10 = line feed"
PRINT " 13 = carriage return"
PRINT " 32 = space"
INPUT " 44 = comma =============>", delimit%
num1% = 5: num2% = 10 'define data to be put in numeric file
str1$ = "hi": str2$ = "mom" 'define data to be put in string file
PRINT #1, num1%; CHR$(delimit%); num2% 'write data separated by
PRINT #2, str1$; CHR$(delimit%); str2$ 'chosen delimiter to file
CLOSE
OPEN "numeric.dat" FOR INPUT AS #1
OPEN "string.dat" FOR INPUT AS #2
PRINT
count% = 0
PRINT "This file contains the numeric values 5 and 10."
PRINT "==============================================="
DO UNTIL EOF(1)
count% = count% + 1
INPUT #1, inp1%
PRINT "Value read in after"; count%; "input(s):"; inp1%
LOOP
PRINT
count% = 0
PRINT "This file contains the string values 'hi' and 'mom'."
PRINT "===================================================="
DO UNTIL EOF(2)
count% = count% + 1
INPUT #2, inp2$
PRINT "Value read in after"; count%; "input(s): "; inp2$
LOOP
CLOSE
PRINT : PRINT
INPUT "Press 'q' to quit. Press 'c' to continue==> ", start$
WEND
END
Keywords: SR# S900312-105 B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/11 05:20
_____________________________________________________________________________
Q64428 Assembly Function Returning Variable-Length String to BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The two programs below demonstrate how an assembly language function
can return a variable-length string to a Microsoft BASIC program.
Note: This routine will not work inside the QuickBASIC Extended
environment (QBX.EXE) or when compiled using the Far Strings option
(BC /Fs) in Microsoft BASIC Professional Development System (PDS)
version 7.00 or 7.10. For information on interlanguage programming
with far strings in Microsoft BASIC PDS, see Chapter 13, "Mixed
Language Programming with Far Strings," in the "Microsoft BASIC 7.0:
Programmer's Guide" for versions 7.00 and 7.10.
This information about interlanguage calling applies to QuickBASIC
versions 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft BASIC Compiler
versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC
PDS versions 7.00 and 7.10 for MS-DOS and MS OS/2.
More Information:
For more information about passing other types of parameters between
BASIC and MASM, query in the Software/Data Library or this Knowledge
Base for the following word:
BAS2MASM
Code Example
------------
The following BASIC program is SFUNC.BAS, which displays a
variable-length string returned from an assembly language function
(QPrint).
DECLARE FUNCTION QPrint$(slen%)
CLS
FOR i% = 1 to 3
TString$ = QPrint$(i%) ' i% is the length of the string
PRINT TSTring$, LEN(TString$)
NEXT
The following assembly language program is ASTR.ASM, which contains
the function QPrint. The QPrint function returns a string, and the
passed integer parameter (argument) returns the length of the string.
; The following handy .MODEL MEDIUM,BASIC directive is found in MASM
; 5.10 but not in earlier versions:
.MODEL MEDIUM, BASIC
.DATA
str db 10 dup (?) ; my own string
mystring dw ? ; my own descriptor (length)
dw ? ; (offset)
.CODE
PUBLIC QPrint
QPrint PROC
push bp
mov bp, sp
push ds
push es
mov bx, [bp+6] ; get the ptr to the string descriptor.
mov cx, [bx]
push ds
pop es ; set es = ds
mov di, offset dgroup:str ; load the offset into di
mov al, 'a' ; load character to fill
rep stosb ; store "a" into the string
mov cx, [bx] ; put the length in cx again
mov bx, offset dgroup:mystring ; put offset of string
; descriptor in bx
mov [bx], cx ; length in first two bytes
mov [bx+2], offset dgroup:str ; offset into second two bytes
mov ax, bx ; load address of descriptor
; into ax
pop es
pop ds
pop bp
ret 2
QPrint ENDP
END
To demonstrate these programs from an .EXE program, compile and link
as follows:
BC SFUNC.BAS;
MASM ASTR.ASM;
LINK SFUNC ASTR;
SFUNC.EXE produces the following output:
a
aa
aaa
Keywords: B_BasicCom H_MASM S_QUICKASM SR# S900718-47
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/08/14 05:27
_____________________________________________________________________________
Q65177 "Out of Stack Space" Using RETURN <linenumber> for SUB Event
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 7.10 | 6.00 6.00b 7.00 7.10
MS-DOS | OS/2
Summary:
If an event occurs in a procedure (SUB or FUNCTION), then returning
from event-handling with the RETURN <linenumber> statement always
leaves unrecoverable information on the stack, which can lead to the
error message "Out of Stack Space" after many trapped events.
This behavior is a result of violating the following design rule: to
correctly restore (pop) the stack after handling an event, you must
always return to the procedure level where the event occurred. This
applies to all events trapped with the ON <event> GOSUB statement
(where <event> includes COM, KEY, PEN, PLAY, TIMER, STRIG, and
others).
RETURN <linenumber> or <linelabel> is only designed to return from
events that occur at the module-level (main-level) code. This
correctly pops the stack.
You must use RETURN without the <linenumber> or <linelabel> option if
you want to RETURN to a SUB or FUNCTION procedure where an event was
trapped. This correctly pops the stack.
This information applies to Microsoft BASIC Professional Development
System (PDS) versions 7.00 and 7.10 for MS-DOS and MS OS/2; to
Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS and MS
OS/2; and to Microsoft QuickBASIC versions 1.00, 1.01, 1.02, 2.00,
2.01, 3.00, 4.00, 4.00b, and 4.50 for MS-DOS.
More Information:
To demonstrate the "Out of stack space" message, run the following
program and hold down the ESC key, which will be trapped in a loop
until the error occurs. The "Out of stack space" error occurs because
this program incorrectly allows events in the SUB to be handled by the
RETURN <linelabel> instead of an ordinary RETURN.
Code Example
------------
DECLARE SUB test ()
' This is an example where the RETURN <linenumber>
' statement gives you "Out of Stack Space" (after about 53 ESC key
' trap iterations in QBX.EXE, or 118 if compiled in BC.EXE) when the
' event (pressing the ESC key) is trapped in a SUB procedure.
KEY 15, CHR$(0) + CHR$(1) ' Trap ESC key
ON KEY(15) GOSUB escape
KEY(15) ON
PRINT "now in main"
again:
CALL test
PRINT "Done"
END
escape:
j = j + 1
' The FRE(-2) function returns a value decreased at each iteration by
' the number of bytes of stack (associated with the SUBprogram) that
' were lost:
PRINT j; "ESC key was pressed. Continue in main. FRE(-2)="; FRE(-2)
KEY(15) ON ' <-- Must say KEY(15) ON here or else the
' RETURN <linelabel> statement will leave the
' ON KEY(15) GOSUB trap still active, which does an
' implied KEY(15) STOP. If the key had been trapped
' in the main program, then RETURN <linelabel> would
' work normally, and you wouldn't have to use
' KEY(15) ON here.
RETURN again
SUB test STATIC
PRINT "Now in SUB"
WHILE INKEY$ = "": WEND
PRINT "You pressed some key other than ESC."
END SUB
References:
The following is taken from Page 296 (under the "RETURN Statement") of
"Microsoft BASIC 7.0: Language Reference" for versions 7.00 and 7.10:
RETURN with a line label or line number can return control to a
statement in the module-level code only, not in procedure-level
code.
The following is taken from Page 227 (under the heading "ON event
Statement") of "Microsoft BASIC 7.0: Language Reference" for versions
7.00 and 7.10:
The RETURN linenumber or RETURN linelabel forms of RETURN can be
used to return to a specific line from the trapping routine. Use
this type of return with care, however, because any GOSUB, WHILE,
or FOR statements active at the time of the trap remain active.
BASIC may generate error messages such as NEXT without FOR. In
addition, if an event occurs in a procedure, a RETURN linenumber or
RETURN linelabel statement cannot get back into the procedure
because the line number or label must be in the module-level code.
The above information is accurate, but it should be added that if an
event occurs in a procedure (SUB or FUNCTION), then returning from
event-handling with the RETURN <linenumber> statement leaves
unrecoverable information on the stack, which eventually leads to the
error message "Out of Stack Space" after many trapped events.
Keywords: B_QuickBas
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/05 05:25
_____________________________________________________________________________
Q65287 Must Use BYVAL at Both Ends When CALLing 7.10 SUB or FUNCTION
Microsoft BASIC Compiler (BASICCOM)
7.10 | 7.10
MS-DOS | OS/2
Summary:
When passing parameters by value to a BASIC SUBprogram or FUNCTION
procedure, you must use the BYVAL attribute from both the calling end
and the receiving end.
By itself, using BYVAL in the SUB or FUNCTION statement (at the
receiving end) isn't enough to tell the SUB or FUNCTION to pass by
value. If you don't also use the BYVAL attribute in the CALL statement
or the DECLARE statement, then by default BASIC will pass by reference
and push only the address of the variable on the stack. If you
mistakenly use BYVAL only at the calling end or only at the receiving
end, then an incorrect value will be passed.
This information only applies to Microsoft BASIC Professional
Development System (PDS) version 7.10, since passing parameters to
BASIC SUBprograms and FUNCTIONS with the BYVAL attribute was first
introduced version 7.10.
More Information:
Note for Versions Earlier Than 7.10: In Microsoft BASIC PDS version
7.00, in Microsoft BASIC Compiler versions 6.00 and 6.00b, and in
QuickBASIC versions 4.00, 4.00b, and 4.50, you could not DECLARE or
CALL a BASIC routine with parameters having the BYVAL attribute, since
BYVAL could be used only for parameters of non-BASIC routines (such as
C or Macro Assembler).
NOTE: If you create a program in an editor outside the QBX.EXE
environment without DECLARE statements at the top of the program,
DECLARE statements will not automatically be added to your code. As a
result, a SUB statement that contains a formal parameter with the
BYVAL attribute (at the receiving end) will have no BYVAL declaration
at the calling end. Instead of specifying BYVAL in a DECLARE
statement, you can specify BYVAL in the CALL statement.
Code Example: Incorrect Way to Pass by Value
--------------------------------------------
The program below, written in an editor outside of the QBX.EXE
environment, will pass the offset of the variable A& to the
SUBprogram, although the SUBprogram is expecting the actual value
contained in A&. This happens because each end of the call to the
SUBprogram acts blindly on the information that it has. The call to
TestPass blindly assumes that it is passing a value by reference,
which is the default. It therefore passes the offset (in this case
3030) of the variable A& to the SUBprogram TestPass. The SUBprogram
TestPass is expecting to receive the value of the variable A&, as is
dictated by the BYVAL attribute in the SUB statement. The program
therefore prints 3030 (the offset) on the screen, instead of the
constant 2 (the value).
CALL TestPass (2&) 'Notice no declaration of BYVAL in CALL or
'DECLARE, so default is pass (send) by reference.
SUB TestPass(BYVAL A&) 'BYVAL in SUB says to pass (receive) by value.
B& = A&
PRINT A& ' Prints 3030, the offset of A&.
END SUB
Correct Way to Pass by Value, Using BYVAL in DECLARE and SUB
------------------------------------------------------------
DECLARE SUB TestPass(BYVAL A&)
' BYVAL in the above DECLARE means to pass (send) by value.
CALL TestPass (2&)
SUB TestPass(BYVAL A&) 'BYVAL in SUB means pass (receive) by value.
B& = A&
PRINT A& ' prints 2, the value (contents) of A&
END SUB
Another Correct Way to Pass by Value, Using BYVAL in CALL and SUB
-----------------------------------------------------------------
CALL TestPass (BYVAL 2&) 'BYVAL in CALL means pass (send) by value.
SUB TestPass(BYVAL A&) 'BYVAL in SUB means pass (receive) by value.
B& = A&
PRINT A& ' prints 2, the value (contents) of A&
END SUB
References
----------
The following is taken from the README.DOC file for BASIC 7.10:
In version 7.10, BASIC supports the use of the BYVAL keyword
in CALL, DECLARE, SUB, and FUNCTION statements for BASIC
procedures. You can use BYVAL to pass parameters by value
rather than by reference (the default). It is no longer
necessary to enclose parameters in parentheses to emulate
passing by value. For more information and an example of using
BYVAL in BASIC procedures, see the online Help for the DECLARE
statement (BASIC procedures). For specifics on using BYVAL with
CALL, see the online Help for the CALL statement (BASIC
procedures).
Keywords: SR# S900820-85
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/05 05:25
_____________________________________________________________________________
Q41533 BASIC 7.00 Can Return Exit Code (Error Level) to Batch File
Microsoft QuickBASIC Compiler (QUICKBAS)
1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
MS-DOS
Summary:
MS-DOS batch processing (.BAT) files can use an "IF ERRORLEVEL n"
statement to detect exit code levels returned by some programs.
However, the only versions of Microsoft BASIC that allow a program to
return an error level code to MS-DOS are Microsoft BASIC Professional
Development System (PDS) versions 7.00 and 7.10. The END n or STOP n
statement returns error level n to the batch file that invoked the
BASIC 7.00 or 7.10 .EXE program. The IF ERRORLEVEL n statement in the
batch file can detect if the returned exit code is equal to or greater
than n.
In all other versions of Microsoft BASIC, the error level (exit) code
returned by a BASIC program is controlled by the BASIC run-time
module, not by your program. As an alternative, you can create a file
in the BASIC program to serve as a flag when a certain condition
occurs. The batch file that called your program can then check for the
existence of the flag file in place of checking for an error level. In
batch files, the "IF EXIST filename" command can be used.
The following products do not allow your program to return an error
level to MS-DOS batch files:
1. QuickBASIC versions 1.00, 1.01, 1.02, 2.00, 2.01, 3.00, 4.00,
4.00b, and 4.50 for MS-DOS
2. Microsoft GW-BASIC versions 3.20, 3.22, and 3.23 for MS-DOS
3. Microsoft BASIC Compiler versions 5.35 and 5.36 for MS-DOS and
versions 6.00 and 6.00b for MS-DOS and MS OS/2
More Information:
Your BASIC program must not attempt to invoke any MS-DOS interrupts
(CALL INTERRUPT) to terminate the program with an error level;
otherwise, strange results may occur and the machine may hang. BASIC
must handle program termination by itself.
BASIC 7.00 or 7.10 Can Return Exit Code (ERRORLEVEL) to Batch File
------------------------------------------------------------------
An .EXE program compiled in BASIC 7.00 or 7.10 can use the STOP n% or
END n% statement to return an exit code (n%) to MS-DOS, as follows:
' TEST.BAS
PRINT "This is a BASIC program that returns an exit code of 5."
n% = 5
END n%
The exit code can be trapped in a MS-DOS batch file with the IF
ERRORLEVEL n GOTO statement, as follows:
TEST
ECHO OFF
IF NOT ERRORLEVEL 1 GOTO DONE
ECHO An error occurred with exit code 1 or higher.
:DONE
ECHO End of batch file.
Using a File as a Flag for a Batch File
---------------------------------------
The following technique lets any BASIC version give a simple yes or no
message to a batch file.
The following batch file, ERRT.BAT, calls the BASIC program ERRTST,
which drops back to the batch file. It then checks for the existence
of the file ERRFIL (which is an arbitrary name) to see if an error
occurred while running the BASIC program:
echo off
del errfil
errtst
if not exist errfil goto end
echo An error occurred during program running
:end
echo End of batch file
The following file is ERRTST.BAS; it creates the error file if it
cannot open the file GARBAGE.DAT:
' set up to error out if "GARBAGE.DAT" does not exist
ON ERROR GOTO errorlevel
OPEN "garbage.dat" FOR INPUT AS #1
CLOSE #1
END
errorlevel:
CLOSE #1
OPEN "errfil" FOR OUTPUT AS #1 'Create file that acts as a flag
CLOSE #1
SYSTEM ' Returns to DOS.
To demonstrate this procedure, compile and link ERRTST.BAS as follows:
BC ERRTST.BAS;
LINK ERRTST.OBJ;
Now run the batch file ERRT.BAT. If the BASIC program cannot find
GARBAGE.DAT, ERRT.BAT shows "An error occurred during program
running."
Keywords: B_BasicCom B_GWBasicI SR# S890216-141
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/05 05:25
_____________________________________________________________________________
Q37340 MS-DOS QuickBASIC 4.00 Differs from XENIX BASIC Compiler 5.70
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
This article compares Microsoft BASIC Compiler versions 5.70 and 5.70a
for XENIX 286 to the following compilers:
1. Microsoft QuickBASIC versions 4.00, 4.00b, 4.50 for MS-DOS
2. Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS
Microsoft BASIC Compiler for XENIX 286 provides a library for ISAM
file handling that is not available with the above Microsoft BASIC
compilers for MS-DOS.
Microsoft BASIC Professional Development System (PDS) versions 7.00
and 7.10 provide ISAM file support under MS-DOS (and under MS OS/2 in
BASIC 7.10). BASIC PDS 7.00 and 7.10 offer additional features beyond
those found in 6.00 and 6.00b.
The BASIC compilers for MS-DOS have a graphic capability not found in
the XENIX BASIC compiler.
Compilers under both XENIX and MS-DOS have SUB...END SUB structures
for defining subprograms, which can be called with the CALL statement.
More Information:
Note: All support and upgrades for Microsoft BASIC Compilers and
Interpreters for XENIX have been assumed by SCO (the Santa Cruz
Operation). For more information on XENIX BASIC and SCO, query on the
following words:
SCO and XENIX and BASIC and support
The list below outlines commands that differ between the BASIC
compiler for XENIX versus the BASIC products for MS-DOS.
An asterisk (*) marks words that are reserved, but not functionally
implemented in the compiler.
Reserved words in Microsoft BASIC Compiler version 6.00b for MS-DOS or
QuickBASIC version 4.50 that are not found in Microsoft BASIC Compiler
version 5.70a for XENIX are as follows:
ACCESS ALIAS ANY BEEP BINARY
BLOAD BSAVE BYVAL CASE CDECL
CIRCLE CLNG COLOR COM COMMAND$
CONST CSRLIN CVDMBF CVSMBF DECLARE
DEFLNG DO DOUBLE DRAW ELSEIF
ENVIRON ENVIRON$ ERDEV ERDEV$ EXIT
FILEATTR FREEFILE FUNCTION INP INTEGER
IOCTL IOTCL$ IS KEY LCASE$
* LIST LOCAL LONG LOOP LTRIM$
MKDMBF$ MKL$ MKSMBF$ OFF OUT
PAINT PALETTE PCOPY PEN PLAY
PMAP PRESET PSET RANDOM REDIM
RTRIM$ SCREEN SEEK SEG SELECT
SETMEM SHARED SIGNAL SINGLE SLEEP
SOUND STATIC STICK STRING TYPE
UCASE$ UNTIL VARPTR$ VARSEG VIEW
WINDOW
Reserved words in Microsoft BASIC Compiler version 5.70a for XENIX
that are not reserved in Microsoft BASIC Compiler version 6.00b for
MS-DOS or QuickBASIC version 4.50 are as follows:
* DELETE
* EDIT
* USR
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/06 06:19
_____________________________________________________________________________
Q47122 Example of Passing a Variable-Length String to Assembly
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The program shown below demonstrates how to pass a variable-length
string by far reference to an assembly language routine.
This information applies to QuickBASIC versions 4.00, 4.00b, and 4.50,
to Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS and MS
OS/2, and to near variable-length strings in Microsoft BASIC
Professional Development System (PDS) versions 7.00 and 7.10 for
MS-DOS and MS OS/2.
More Information:
The following program is PSTRING.BAS, which passes a string to an
assembly language routine using the VARSEG and SADD functions. SADD
gives the actual address of the string, whereas VARPTR gives the
address of the string descriptor.
This example cannot be used in BASIC PDS 7.00 or 7.10 with far strings
(BC /Fs) or with QBX.EXE (which always uses far strings). For more
information about far strings, see Chapter 13 of "Microsoft BASIC 7.0:
Programmer's Guide" for versions 7.00 and 7.10.
DECLARE SUB PSTRING(BYVAL STRSEG AS INTEGER, BYVAL STROFF AS INTEGER)
A$ = "Hello World"
PRINT "Before call: ";
PRINT A$
CALL PSTRING(VARSEG(A$), SADD(A$))
PRINT "After call : ";
PRINT A$
The following separately compiled routine is PSTR.ASM:
; The following handy .MODEL MEDIUM,BASIC directive is found in MASM
; 5.10 but not in earlier versions:
.MODEL MEDIUM, BASIC
.CODE
pstring PROC sseg:WORD, soff:WORD
push bx ; save bx register, dx, and es
push dx
push es
mov ax, sseg ; get segment of string
mov es, ax ; put into segment register
mov bx, soff
; 65 is ASCII value for letter 'A'.
mov BYTE PTR es:[bx], 65 ; Move the 'A' to the first character
; in the string.
pop es
pop dx
pop bx ; restore (pop) es, dx, and bx
ret
pstring ENDP
end
Compile and link the program as follows:
BC PSTRING;
MASM PSTR;
LINK PSTRING PSTR;
When run, PSTRING should print the following:
Before call: Hello World
After call : Aello World
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/06 06:19
_____________________________________________________________________________
Q47756 Example of C Function Returning a String to BASIC
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The two programs shown below demonstrate how a C function can return a
string to a compiled BASIC program.
This information about interlanguage calling applies to QuickBASIC
versions 4.00, 4.00b, and 4.50 for MS-DOS, to Microsoft BASIC Compiler
versions 6.00 and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC
Professional Development System (PDS) versions 7.00 and 7.10 for
MS-DOS and MS OS/2.
For Microsoft BASIC PDS 7.00 and 7.10, this example applies only to
near strings. If you are using far strings (BC /Fs on compile or when
using QBX.EXE), you must use the string-manipulation routines supplied
with BASIC PDS 7.00 and 7.10 (StringAssign, StringRelease,
StringAddress, and StringLength). For more information about far
strings, see Chapter 13 of "Microsoft BASIC 7.0: Programmer's Guide"
for versions 7.00 and 7.10.
More Information:
For more information about passing other types of parameters between
BASIC and C and a list of which BASIC and C versions are compatible
with each other, query in the Software/Data Library on the following
word:
BAS2C
Code Example
------------
The following BASIC program is BSTRF.BAS, which calls the C function
and prints out the returned string and its length:
DECLARE FUNCTION CFUNC$ CDECL ()
a$ = CFUNC$
PRINT a$
PRINT len(a$)
The following program is CSTRF.C, which builds a string descriptor
that is passed back to the calling BASIC program:
#include <string.h>
struct stringdesc
{
int length; /* length of the string */
char *string; /* near pointer to the string */
};
struct stringdesc *std;
char thestring[18]; /* In the medium memory model this */
/* string will be in DGROUP - which */
/* is required for BASIC */
struct stringdesc *cfunc()
{
std->length = 18; /* length of the string */
strcpy(thestring, "This is the string");
std->string = thestring;
return(std); /* return pointer to string descriptor */
}
To demonstrate these programs from an .EXE program, compile and link
as follows:
BC BSTRF.BAS;
CL /c /AM CSTRF.C;
LINK /NOE BSTRF CSTRF;
BSTRF.EXE produces the following output:
This is the string
18
Keywords: B_BasicCom S_C S_QuickC
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/06 06:19
_____________________________________________________________________________
Q57501 QBX May Incorrectly Parse Array Element in User-Defined TYPE
Microsoft BASIC Compiler (BASICCOM)
7.00
MS-DOS
Summary:
The QuickBASIC Extended editor (QBX.EXE), which is shipped with
Microsoft BASIC Professional Development System (PDS) version 7.00 for
MS-DOS, incorrectly parses a line of code that uses incorrect syntax
for an array element in a user-defined TYPE. The following is an
example:
TYPE abc
a(1 to 10) AS STRING * 8
END TYPE
DIM y AS abc
PRINT y.a$(3)
When you enter the last line into QBX.EXE and press the ENTER key,
the line is interpreted (parsed) incorrectly and is displayed
incorrectly as follows:
3yGOTO
If the correct line of code "PRINT y.a(3)" is entered, the code is
interpreted correctly.
Microsoft has confirmed this to be problem in the QBX.EXE editor in
Microsoft BASIC PDS version 7.00. This problem was corrected in
QBX.EXE in BASIC PDS 7.10.
This problem relates only to QBX.EXE and does not relate to the BC.EXE
compiler in BASIC 7.00.
Keywords: buglist7.00 fixlist7.10
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/09/25 06:42
_____________________________________________________________________________
Q35825 Undocumented BC.EXE Metacommands That Affect .LST Listing
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
Placing the following metacommands into your source file affects the
list (.LST) file generated by the compiler:
REM $List
REM $linesize
REM $title
REM $subtitle
REM $page
REM $pagesize
These metacommands are correctly documented in the "Microsoft
QuickBASIC Compiler" version 1.0x manual, and are used by the
BASCOM.EXE compiler in QuickBASIC versions 1.00, 1.01, and 1.02. Note
that these metacommands do not apply to QuickBASIC versions 2.00,
2.01, and 3.00, which do not output a source-listing .LST file.
The above metacommands work with the BC.EXE compiler that is provided
with Microsoft QuickBASIC versions 4.00, 4.00b, and 4.50; with
Microsoft BASIC Compiler versions 6.00 and 6.00b; and with Microsoft
BASIC Professional Development System (PDS) versions 7.00 and 7.10 for
MS-DOS and MS OS/2. However, these metacommands need to be added to
the following manuals:
1. "Microsoft QuickBASIC 4.0: BASIC Language Reference," Appendix C,
"Metacommands," for versions 4.00 and 4.00b
2. "Microsoft QuickBASIC 4.5: BASIC Language Reference," Appendix C,
"Metacommands," for version 4.50
3. "Microsoft BASIC Compiler 6.0: BASIC Language Reference," Appendix C,
"Metacommands," for versions 6.00 and 6.00b
4. "Microsoft BASIC 7.0: BASIC Language Reference" (metacommands are
listed alphabetically) for BASIC PDS versions 7.00 and 7.10.
More Information:
REM $LIST{+ -}
The $LIST metacommand turns on and off portions of the source listing
generated by the compiler. The $LIST metacommand has no effect on
whether or not a source code listing is produced; it only affects what
parts of the source code are placed in the listing. A source code
listing is produced only if you request it when you start the
compiler. To turn source code listing off at any point in the program,
add the following line:
REM $LIST-
To turn source code listing on at any point in the program, add the
following line:
REM $LIST+
The following metacommand sets the width of the listing output. Its
default is 80 characters:
REM $LINESIZE:n
The following is an example of how to set the list file to 132
columns:
REM $LINESIZE:132
The following metacommand places a title on each page of the list
(.LST) file:
REM $TITLE:'text'
The following metacommand places a subtitle on all pages except the
first:
REM $SUBTITLE:'text'
The following metacommand forces a new page in the compiler listing
file:
REM $Page
The following metacommand forces a new page in the compiler listing
after n minus 6 lines have been printed.
REM $Pagesize:n
Keywords: B_BasicCom docerr
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/10/18 05:15
_____________________________________________________________________________
Q44236 Only One Video Page with Hercules SCREEN 0; HELP Correction
Microsoft QuickBASIC Compiler (QUICKBAS)
4.50
MS-DOS
Summary:
Only one page (page 0) is supported in SCREEN mode 0 on a Hercules
adapter. To obtain two pages, Hercules graphics mode (SCREEN 3) should
be used.
The indicated documentation sources below incorrectly show two pages
(pages 0 and 1) available in SCREEN mode 0 (TEXT mode) on a Hercules
adapter. This is incorrect.
More Information:
The information covering "Hercules Adapter Screen Modes" in the
following sources incorrectly states you can have 2 pages under SCREEN
mode 0 when using a Hercules video adapter:
1. The documentation error occurs in QB.EXE 4.50 QB Advisor online
Help system under the HELP menu, SCREEN statement, Details section,
Adapters and Displays ("HELP: SCREEN Statement Details - Adapters")
This documentation error has been corrected in the Microsoft
Advisor on-line Help system of the QBX.EXE environment supplied
with Microsoft BASIC PDS versions 7.00 and 7.10 for MS-DOS.
2. This documentation error occurs on Page 327 of the "Microsoft
QuickBASIC 4.5: BASIC Language Reference" manual.
This documentation error has been corrected in the "Microsoft BASIC
7.0: Language Reference" manual for BASIC PDS version 7.00 and 7.10.
3. This documentation error occurs in the QBX.EXE 7.00 and 7.10
Microsoft Advisor online Help system under the HELP menu, PCOPY
statement, Details section ("HELP: PCOPY Statement Details").
This documentation error does not occur for PCOPY HELP in QB.EXE
4.50.
Keywords: SR# S890502-115 docerr B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/10/18 05:15
_____________________________________________________________________________
Q35965 Which BASIC Versions Can CALL C, FORTRAN, Pascal, MASM
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
Certain versions of Microsoft QuickBASIC and Microsoft BASIC Compiler
can CALL routines from certain other Microsoft languages (and pass
parameters), depending upon the product version number, as explained
below.
More Information:
Microsoft BASIC Professional Development System (PDS) version 7.10 can
be linked with Microsoft C PDS version 6.00 or QuickC version 2.50 or
2.51.
The following application note, which can be requested from Microsoft
Product Support Services, is required if you wish to perform BASIC
7.10 mixed-language programming with C 5.10, FORTRAN 5.00, or Pascal
4.00:
"How to Link BASIC PDS 7.10 with C 5.10, FORTRAN 5.00, or
Pascal 4.00" (application note number BB0345)
QuickBASIC 4.50 and BASIC PDS 7.00 (but not earlier versions) can
create .OBJ modules that can be linked with .OBJ modules from
Microsoft FORTRAN version 5.00 and Microsoft QuickC version 2.01.
QuickBASIC versions 4.00b and 4.50, Microsoft BASIC Compiler versions
6.00 and 6.00b for MS-DOS and MS OS/2, and Microsoft BASIC PDS version
7.00 for MS-DOS and MS OS/2 create .OBJ modules that can be linked
with .OBJ modules from the following languages:
1. Microsoft Pascal version 4.00.
2. Microsoft FORTRAN version 4.10.
3. Microsoft C version 5.10 and QuickC versions 1.01 and 2.00.
4. Microsoft Macro Assembler (MASM) version 5.00 or later recommended,
but earlier versions should also work.
For more information on interlanguage CALLing between Microsoft C and
BASIC, query in this Knowledge Base on the word "BAS2C".
For more information on interlanguage CALLing between Microsoft MASM
and BASIC, query in this Knowledge Base on the word "BAS2MASM".
For more information about using the CALL statement to pass parameters
from BASIC to other languages, query in this Knowledge Base on the
following words:
CALL and (PASSING or PASS) and [language name]
QuickBASIC 4.00
---------------
QuickBASIC version 4.00 creates .OBJ modules that can be linked with
.OBJ modules from the following languages (Microsoft has performed
successful interlanguage test suites for QuickBASIC version 4.00 with
these language versions):
1. Microsoft C version 5.00, QuickC version 1.00.
2. Microsoft FORTRAN version 4.00.
3. Microsoft Pascal version 4.00.
4. Microsoft Macro Assembler (MASM) versions 4.00 and later
recommended, but earlier versions should also work.
Note that QuickBASIC version 4.00b might link with these earlier
language versions, but Microsoft cannot guarantee success because the
4.00b test suites were performed only on the later language versions
mentioned further above in this article.
QuickBASIC 1.x, 2.x, 3.00
-------------------------
In QuickBASIC versions 1.00, 1.01, 1.02, 2.00, 2.01, and 3.00, you can
link only to .OBJ modules from Microsoft Macro Assembler (versions
1.2x, 2.x, or later) or the given version of QuickBASIC. In other
words, QuickBASIC versions 3.00 and earlier can CALL only QuickBASIC
subprograms or assembly routines.
Important Information About Interlanguage CALLing
-------------------------------------------------
To be compatible with compiled BASIC, programs should be assembled or
compiled using the medium, large, or huge memory model, and BASIC must
be linked first (as the main module).
When you link compiled BASIC to other compiled BASIC modules, compiler
versions should not be mixed. For example, an .OBJ module compiled in
QuickBASIC version 4.00 should not be linked with an .OBJ module
compiled in QuickBASIC version 4.00b or 4.50 or Microsoft BASIC
Compiler version 6.00 or 6.00b or Microsoft BASIC PDS version 7.00 or
7.10.
As an alternative to the CALL statement for interlanguage invocation,
you may use the SHELL statement to invoke most (non-TSR) .EXE, .COM,
or .BAT programs that you can also invoke from DOS. SHELL works
differently than CALL. SHELL invokes another copy of the DOS
COMMAND.COM command processor before running a requested executable
program.
Keywords: B_BasicCom S_C H_Fortran S_PasCal H_MASM S_QuickASM S_QuickC
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/10/23 06:15
_____________________________________________________________________________
Q65568 How to Add Other Language Compilers to PWB's Build Options
Microsoft Programmer's WorkBench (PWB)
1.00 1.10 | 1.00 1.10
MS-DOS | OS/2
Summary:
The Programmer's WorkBench (PWB) is an environment capable of
utilizing different compilers for mixed-language programming. When
installed during BASIC version 7.10 setup, PWB version 1.10 shows
build options for the BASIC language only. However, it is possible to
include other language compilers to utilize the full features of the
PWB utility.
The following information applies to the Programmer's WorkBench
version 1.10 utility supplied with Microsoft BASIC Professional
Development System (PDS) version 7.10 for MS-DOS and MS OS/2.
More Information:
Note that the 1.00 version of PWB is shipped with Microsoft C
Professional Development System (PDS) version 6.00. The steps below
should also apply to PWB version 1.00.
The Programmer's WorkBench (PWB.EXE) is an advanced development
environment capable of integrating several language compilers,
NMAKE.EXE, LINK.EXE, and the CodeView debugger. It offers the ability
to accomplish tasks, such as program development under protected mode
and mixed-language programming. This ability is not available in the
QuickBASIC extended development environment (QBX.EXE).
Two special files, PWBC.PX$ (for protected mode OS/2) and PWBC.MX$
(for DOS mode), reside on the BASIC PDS 7.10 disks and support the
option of using the C compiler in PWB. Since SETUP.EXE (in BASIC PDS
7.10) does not copy PWBC.PX$ and PWBC.MX$ during installation, these
files must be unpacked and transferred to your machine, for example to
the \BINP subdirectory located in the \BC7 directory. (Note: The
UNPACK.EXE utility is found on disk 1 of the BASIC PDS package.) After
unpacking, the files will have the names PWBC.PXT and PWBC.MXT.
Next, the following command lines must be added to the TOOLS.INI file
to make the C compiler available to PWB:
[pwb - .BAS .BI]
LOAD: LogicalDrive:\[Path]\PWBC.PXT
For further information about installing PWBC.PXT and PWBC.MXT, see
Page 54 of the "Microsoft BASIC 7.1: Getting Started" manual.
If you want to program in languages other than BASIC or C [such as
Microsoft Macro Assembler (MASM), Microsoft Pascal, Microsoft FORTRAN,
or Microsoft COBOL 3.00/3.00a], the following steps will insert the
initial build options to include other languages to PWB's build
options menu. In the example below, options to include the MASM.EXE
assembler are specified. If some other language's compiler is desired,
substitute appropriate changes for that compiler, where noted in the
specified areas:
1. In PWB, go to the Options menu and select Build Options.
2. Choose Save Current Build Options.
3. Enter a meaningful message, such as "Options to Include MASM" in
the window's edit field (if some other language is desired, change
MASM to the appropriate name). Select the OK button from the "Save
Current Build Options" and "Build Options" windows.
4. Open the "TOOLS.INI" file in the PWB utility and go down to the
bottom of the file. Somewhere near the bottom should be the tag
"[PWB-Build Options: Options to Include MASM]" (or the language
that was specified).
5. In this section, add the following NMAKE instructions:
build: inference .asm.obj masm_asm_obj
build: command masm_asm_obj "masm $<;"
Note: For languages other than MASM, distinguish a variable name
in the inference rule to be used in the commands line (such as
masm_asm_obj has been used above) and then specify the appropriate
compiler in the commands line within the quotation marks. The
special filename macro specified in the quotation marks, "$<",
applies the command to any object that has an out-of-date
executable file.
6. Press SHIFT+F8 to reinitialize the file and then close it.
7. Go to the File menu and select New (it is a good idea to close any
files that are currently open before this step).
8. Go to the Options menu and select Build Options.
9. Choose Initial Build Options.
10. Select the "Options to Include MASM" option (it should be near the
bottom of the list).
After completing these instructions, the PWB utility will now be ready
to compile assembler along with BASIC source code, provided that paths
to the necessary compilers are furnished.
Keywords: s_pascal b_basiccom s_c h_masm h_fortran b_cobol
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/10/31 18:22
_____________________________________________________________________________
Q66744 How to POKE Keystrokes Such as F3 (Last Command) into Keyboard
Microsoft QuickBASIC Compiler (QUICKBAS)
3.00 4.00 4.00b 4.50
MS-DOS
Summary:
Instead of using CALL INTERRUPT to push keystrokes into the keyboard
buffer, the code example below POKEs a key directly into the keyboard
buffer area in memory under MS-DOS.
This information applies to QuickBASIC versions 3.00, 4.00, 4.00b, and
4.50 for MS-DOS; to Microsoft BASIC Compiler versions 6.00 and 6.00b
for MS-DOS; and to Microsoft BASIC Professional Development System
(PDS) versions 7.00 and 7.10 for MS-DOS.
More Information:
In many applications, it is often useful to echo the command line to
the screen during repetitive execution of a program. This makes the
program easier to use by allowing you to avoid typing in the command
line at the completion of each instance of the program. The code
example below shows a quick way to push the F3 keystroke into the
keyboard buffer, which echoes the previously entered command line to
the screen.
Code Example
------------
DEF SEG = 0 ' Set default segment to 0
POKE 1054,0 ' Push 0 for extended key into keyboard buffer
POKE 1055, 61 ' Push F3 key scan code into keyboard buffer
POKE 1050, 30 ' Set beginning (head) buffer position
POKE 0152, 32 ' Set ending (tail) buffer position
DEF SEG ' Return current segment pointer to default segment
References
----------
For more articles about reading from and writing to the keyboard
buffer, search in this Knowledge Base for the following words:
interrupt and keyboard and buffer
The addresses for the keyboard buffer area, head, and tail (used in
the above code example) are documented in "The New Peter Norton
Programmer's Guide to the IBM PC & PS/2" by Peter Norton and Richard
Wilton, published by Microsoft Press (1988).
Keyboard scan codes are documented in Appendix D of "Microsoft
QuickBASIC 4.5: Programming in BASIC"; in Appendix A of "Microsoft
QuickBASIC 4.0: Language Reference" for 4.00 and 4.00b; in Appendix A
of "Microsoft BASIC Compiler 6.0: Language Reference" for 6.00 and
6.00b; and in Appendix A of "Microsoft BASIC 7.0: Language Reference"
manual for BASIC PDS versions 7.00 and 7.10.
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/09 06:23
_____________________________________________________________________________
Q48398 Using RUN with No Argument Inside SUB Should Cause Error
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
In the QB.EXE or QBX.EXE environment, a RUN statement with no
<filename> argument fails to give a "Subprogram Error" and may hang
under certain conditions (see Program #3 below) when invoked inside a
SUBprogram (SUB .. END SUB). This improper use of RUN correctly
produces a "Subprogram Error" when compiled with BC.EXE in QuickBASIC
versions 4.00, 4.00b, and 4.50 and in Microsoft BASIC Professional
Development System (PDS) versions 7.00 and 7.10.
Microsoft has confirmed this to be a problem in the QB.EXE environment
of QuickBASIC versions 4.00, 4.00b, and 4.50 for MS-DOS; in the QB.EXE
environment of Microsoft BASIC Compiler versions 6.00 and 6.00b
(buglist6.00, buglist6.00b) for MS-DOS; and in the QBX.EXE environment
of Microsoft BASIC PDS versions 7.00 and 7.10 (buglist7.00,
buglist7.10) for MS-DOS. We are researching this problem and will post
new information here as it becomes available.
More Information:
Normally, the RUN statement with no argument restarts the current
program. However, using RUN with no argument to restart a program is
allowed only in the module-level code of a program, not in a
SUBprogram or FUNCTION procedure. In a SUBprogram or FUNCTION
procedure, you must use RUN <filename>, since RUN <linenumber> and RUN
with no argument are not allowed in SUBprograms. However, you can use
RUN <filename> to have a program run itself from within a SUBprogram
or FUNCTION.
The appropriate use of RUN is correctly documented on Page 367 of the
"Microsoft QuickBASIC 4.0: BASIC Language Reference" manual:
Because a line number in a RUN statement must refer to a line in
the module-level code, only the RUN "filespec" form of the
statement is allowed in a SUB or FUNCTION.
The above correct statement should replace the incorrect statements
described further below.
Documentation Error
-------------------
The RUN <linenumber> option is incorrectly documented on Page 317 of
the "Microsoft QuickBASIC 4.5: BASIC Language Reference" manual for
version 4.50 and on Page 303 of the "Microsoft BASIC 7.0: Language
Reference" manual for BASIC PDS versions 7.00 and 7.10. These pages
give the following incorrect statements:
Therefore, a RUN statement in a SUB or FUNCTION procedure must
point to labels at module level. If no line label is given,
execution always starts with the first executable line of the
main module.
This same documentation error occurs in the QB Advisor online Help
system for QuickBASIC 4.50 and in the Microsoft Advisor online Help
system for BASIC PDS 7.00 and 7.10 and can be found as follows from
within the QB.EXE environment or QBX.EXE environment:
1. Press SHIFT+F1.
2. Select Index.
3. Type "R".
4. Double-click the left mouse button on "RUN statement" or position
the cursor on "RUN" and press ENTER.
5. Select Details.
Program #1
----------
Program #1 below correctly causes a "Subprogram Error" during
compilation with BC.EXE 4.00, 4.00b, and 4.50, but the QB.EXE or
QBX.EXE editor fails to give you an error message, and the RUN
executes:
' **** PROGRAM #1: Test.Bas
' Main level (module level):
PRINT "Inside Main Level"
CALL Test
' Subprogram level:
SUB Test
PRINT "Inside Test"
RUN
END SUB
Program #2
----------
Program #2 below is the correct method for using RUN (with a
<filename> argument) in a SUBprogram, and it works when the program is
either compiled with BC.EXE or run in the QB.EXE or QBX.EXE editor:
' **** Program #2: Test.Bas
' Main level (module level):
PRINT "Inside Main Level"
CALL Test
' Subprogram level:
SUB Test
PRINT "Inside Test"
RUN "Test" ' This is legal for both QB.EXE/QBX.EXE and BC.EXE
END SUB
Program #3
----------
In QB.EXE or QBX.EXE, your program may hang if the RUN statement is
invoked with no parameters (or with a line number) in a non-STATIC SUB
or FUNCTION procedure, and the SUB or FUNCTION procedure uses DIM or
REDIM to dimension a dynamic array local to that procedure:
'Warning!!!!! This program is going to hang your machine.
DECLARE SUB sub1 ()
sub1
END
SUB sub1
DIM y(1)
y(1) = 1
PRINT y(1);
' Note: Invoking ERASE Y before the RUN will prevent the hang.
' Must then press CTRL+BREAK to stop the program, since it keeps
' running itself.
RUN
END SUB
You can change Program #3 to run successfully without hanging in
QB.EXE/QBX.EXE if you do one of the following:
1. ERASE the local dynamic array(s) before the RUN.
2. Make the SUB STATIC.
3. Make the array global by dimensioning it with DIM SHARED or COMMON
SHARED at the module level of the program.
4. Pass the array as a parameter to the SUBprogram.
Additional reference words: B_BasicCom SR# S900919-42 SR# S890801-4
Keywords: buglist4.00 buglist4.00b buglist4.50 docerr
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/10 05:19
_____________________________________________________________________________
Q58733 BASIC 7.00 Can Assign an Array to an Array If in a TYPE
Microsoft BASIC Compiler (BASICCOM)
7.00 7.10 | 7.00 7.10
MS-DOS | OS/2
Summary:
Some languages, such as Pascal, allow you to assign one array directly
to another, which copies all the elements from one array to another.
Microsoft BASIC cannot do this, except in Microsoft BASIC Professional
Development System (PDS) versions 7.00 and 7.10 where you can now
directly assign one static array to another by defining the array in a
user-defined-TYPE variable and then assigning one variable of this
TYPE to another.
Using a variable of a TYPE that contains an array, you can also write
an entire array to a file using a single PUT# statement.
More Information:
Note that in Microsoft QuickBASIC versions 4.00, 4.00b, and 4.50 for
MS-DOS, in Microsoft BASIC Compiler versions 6.00 and 6.00b for MS-DOS
and MS OS/2, and in Microsoft BASIC PDS versions 7.00 and 7.10 for
MS-DOS and MS OS/2, you can directly assign variables of a
user-defined TYPE directly to one another if they are of the same
TYPE. (LSET can be used for assignment if the record variables differ
in TYPE.) The TYPEd variables are assigned in one simple statement,
and each and every element of the user-defined TYPE is automatically
copied.
Microsoft BASIC PDS version 7.00 for MS-DOS and MS OS/2 introduces
support for static arrays in user-defined TYPEs. In BASIC PDS 7.00 and
7.10, you can directly assign one static array to another by defining
the array in a user-defined-TYPE variable and then assigning one
variable of this TYPE to another, as shown in Example 1.
You can also write a whole array at once into a disk file, as shown in
Example 2.
Code Example 1
--------------
The following program can be used in BASIC PDS 7.00 and 7.10 to
demonstrate the assignment of the contents of one static array to
another. (Note that dynamic arrays cannot be placed in user-defined
TYPEs.)
TYPE rec1
array1(20) AS INTEGER
END TYPE
DIM var1 AS rec1, var2 AS rec1
CLS
FOR i = 1 TO 20 ' Fill the array in var1:
var1.array1(i) = i
NEXT
var2 = var1 ' Make the assignment.
FOR i = 1 TO 20 ' Confirm that the array was copied to var2:
PRINT var2.array1(i)
NEXT
END
Code Example 2
--------------
The following example, compiled in BASIC PDS 7.00 or 7.10, shows how
to write a whole array to disk at once, using just one PUT# statement:
TYPE rec1
array1(20) AS INTEGER
END TYPE
DIM var1 AS rec1, var2 AS rec1
CLS
FOR i = 1 TO 20 ' Fill the array in var1:
var1.array1(i) = i
NEXT
OPEN "test.dat" FOR RANDOM AS #1
PUT #1, , var1 ' write whole array to disk all at once.
CLOSE
OPEN "test.dat" FOR RANDOM AS #1
GET #1, , var2 ' Reads array all at once into var2.
FOR i = 1 TO 20 ' Print the contents of array var2:
PRINT var2.array1(i);
NEXT
CLOSE
Keywords: SR# S900131-59 B_QuickBas
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/20 14:26
_____________________________________________________________________________
Q66455 Problems May Occur When Passing the Same Array Element Twice
Microsoft BASIC Compiler (BASICCOM)
6.00 6.00b 7.00 7.10 | 6.00 6.00b 7.00 7.10
MS-DOS | OS/2
Summary:
The following program may give unexpected results when the same array
element is passed twice to the subprogram. The problem results from a
form of variable aliasing, where the same memory location is
referenced by two different variables.
To avoid aliasing problems, never pass the same variable twice in a
given parameter list.
More Information:
Passing the same array element twice in the same parameter list can
give incorrect or unexpected results regardless of array type or
dynamic or static array allocation. The results may also vary between
compiler versions. A customer reported that the program below gave the
results that he wanted in QuickBASIC 4.00, but not in Microsoft BASIC
Professional Development System (PDS) version 7.10; Microsoft has not
confirmed this report.
This behavior results from the fact the BASIC often requires a far
pointer to access arrays, but parameters need to be passed as near
pointers. On a CALL, BASIC sets aside a temporary location holding the
array element and then passes a pointer to the temporary area.
There are two options in this sort of situation: Recode the subprogram
so that it is not necessary to pass the array element twice, or assign
one of the parameters to a temporary variable and then pass the
temporary variable.
References:
For a similar article on variable aliasing when a parameter is both
SHARED and passed as a parameter to a subprogram, query in this
Knowledge Base on the following words:
DYNAMIC and ARRAY and ALIASES
A variable should not be passed twice in the list of arguments passed
to a procedure; otherwise, variable-aliasing problems will occur. This
restriction is documented under "The Problem of Variable Aliasing" on
Page 64 in the "Microsoft BASIC 7.0: Programmer's Guide" for BASIC PDS
versions 7.00 and 7.10, on Page 68 of the "Microsoft QuickBASIC 4.5:
Programming in BASIC" manual, and on Page 78 of the "Microsoft
QuickBASIC 4.0: Programming in BASIC: Selected Topics" manual for
QuickBASIC versions 4.00 and 4.00b.
Code Example
------------
DECLARE SUB MakeUpper(instring AS STRING, outstring AS STRING)
DIM a$(15)
a$(4)="abcdefg"
CALL MakeUpper(a$(4), a$(4))
PRINT a$(4)
END
SUB MakeUpper(instring AS STRING, outstring AS STRING)
outstring = UCASE$(instring)
END SUB
Keywords: SR# S901018-67 B_QuickBAS
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/20 14:26
_____________________________________________________________________________
Q47566 SHARED Dynamic Array Element Passed as Parameter Aliases to 0
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
If you attempt to alter an element of a SHARED or COMMON SHARED
$DYNAMIC array while inside a SUBprogram and that element has also
been passed as a parameter to the SUBprogram, the value returned in
the parameter will be the value assigned to the array element upon
exit from the SUBprogram, and will replace whatever value may have
been assigned directly to the array in the SUBprogram.
This behavior occurs in Microsoft QuickBASIC versions 4.00, 4.00b, and
4.50, Microsoft BASIC Compiler 6.00 and 6.00b for MS-DOS and MS OS/2,
and Microsoft BASIC PDS 7.00 for MS-DOS and MS OS/2.
This is a form of variable aliasing, which is a programming practice
not recommended by Microsoft. A variable passed in an argument list to
a procedure should not also be shared by means of the SHARED statement
or the SHARED attribute (of the DIM or COMMON statement) in that
procedure's module.
Similarly, a variable should not be passed twice in the list of
arguments passed to a procedure, or else variable aliasing problems
occur. This information can be found under "The Problem of Variable
Aliasing" section, on Page 64 in the "Microsoft BASIC 7.0:
Programmer's Guide" for BASIC PDS versions 7.00 and 7.10, on Page 68
of the "Microsoft QuickBASIC 4.5: Programming in BASIC" manual, and on
Page 78 of "Microsoft QuickBASIC 4.0: Programming in BASIC: Selected
Topics" manual for versions 4.00 and 4.00b.
More Information:
The behavior in the first example above results from the way
QuickBASIC accesses $DYNAMIC arrays. Since access to these arrays
requires a far pointer, and all parameters use near pointers, a
temporary location is set aside for the parameter before and during
the CALL, and the value in this location is assigned to the actual
array element following the return from the CALL. Thus, whatever value
you assign to the array element inside the SUBprogram using the SHARED
array name will be replaced with the value of the parameter when the
SUBprogram ends.
Note that when inside the QuickBASIC environment, virtually all arrays
are treated as $DYNAMIC. It is only at compile time that $STATIC
arrays are actually made $STATIC by allocation in the data segment.
Since the QuickBASIC editor treats most arrays as $DYNAMIC, this
behavior can be observed in the editor even for arrays declared
$STATIC. Please see Pages 32-33 in the "Microsoft QuickBASIC 4.0:
BASIC Language Reference" manual for versions 4.00 and 4.00b, and
Pages 719-721 in the "Microsoft BASIC 7.0: Programmer's Guide" for
BASIC PDS Version 7.00, for a complete description of where arrays are
stored.
The following example demonstrates this behavior:
DECLARE SUB test (a!)
CLS
' *** The DYNAMIC metacommand is not required to reproduce
' this behavior inside the QuickBASIC environment.
'$DYNAMIC
DIM SHARED b(20) 'Step 1. b(20) initially is 0.
CALL test(b(20))
PRINT b(20) 'Step 3. PRINTs 0 -- global has been
END ' replaced by returned value.
SUB test (a!)
b(20) = 10
PRINT b(20) 'Step 2. PRINTs 10 -- Global value is
END SUB ' changed. Parameter a! is still 0.
Keywords: B_BasicCom
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/20 14:26
_____________________________________________________________________________
Q60140 Location of Keyboard Buffer Area in MS-DOS; BASIC PEEK, POKE
Microsoft QuickBASIC Compiler (QUICKBAS)
4.00 4.00b 4.50
MS-DOS
Summary:
The actual location of the keyboard buffer on the IBM PC or PS/2 is
variable, but by default, the buffer is a 32-byte area located at
segment 0, offset 1054 (41E hex). Because many applications assume
that this is the default location, please be careful if you change its
address or size.
More Information:
The buffer is composed of 16 2-byte entries. It holds up to 16
keystrokes until they are read via the BIOS services through interrupt
22 (16 hex). Because this is a circular queue buffer, two pointers
indicate the head and tail of the queue. It is usually best to
manipulate the pointers rather than the actual data.
This information is taken from "The New Peter Norton Programmer's
Guide To The IBM PC and PS/2" on pages 56-60, published by Microsoft
Press (1988).
There are other adjacent memory locations that are used in conjunction
with the keyboard buffer. The most important of these are listed
below. All of these addresses are in segment 0.
Offset 1050 (41A hex)
---------------------
A 2-byte address that points to the current head of the BIOS keyboard
buffer at offset 1054.
Offset 1052 (41C hex)
---------------------
A 2-byte address that points to the current tail of the BIOS keyboard
buffer at offset 1054.
Note: One interesting way to clear the keyboard buffer is to set the
head of the queue equal to the tail. To do this in BASIC, simply PEEK
the two bytes at 1052 and POKE them into location 1050.
Offset 1152 (480 hex)
---------------------
A 2-byte word pointing to the start of the keyboard buffer area.
Offset 1154 (482 hex)
---------------------
A 2-byte word pointing to the end of the keyboard buffer area.
Note: Be careful if you choose to change the addresses at 1152 or 1154
because many applications may not check these memory locations to
determine the keyboard buffer area. These applications will assume the
default configuration.
References:
For more articles about reading from and writing to the keyboard
buffer, search in this Knowledge Base for the following words:
interrupt AND keyboard AND buffer
Keyboard scan codes are documented in Appendix D of "Microsoft
QuickBASIC 4.5: Programming in BASIC"; in Appendix A of "Microsoft
QuickBASIC 4.0: Language Reference" for 4.00 and 4.00b; in Appendix A
of "Microsoft BASIC Compiler 6.0: Language Reference" for 6.00 and
6.00b; and in Appendix A of "Microsoft BASIC 7.0: Language Reference"
manual for BASIC PDS versions 7.00 and 7.10.
Keywords: SR# S900326-109 b_basiccom pss
COPYRIGHT Microsoft Corporation, 1990.
Updated 90/11/20 14:26