Microsoft QuickBASIC: Language Reference ĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ Microsoft(R) QuickBASIC BASIC: Language Reference For IBM(R) Personal Computers and Compatibles ĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ Information in this document is subject to change without notice and does not represent a commitment on the part of Microsoft Corporation. The software described in this document is furnished under a license agreement or nondisclosure agreement. The software may be used or copied only in accordance with the terms of the agreement. It is against the law to copy the software on any medium except as specifically allowed in the license or nondisclosure agreement. No part of this manual may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose without the express written permission of Microsoft. (C)Copyright Microsoft Corporation 1987, 1988. All rights reserved. Simultaneously published in the U.S. and Canada. Printed and bound in the United States of America. Microsoft, MS, MS-DOS, CodeView, and XENIX are registered trademarks of Microsoft Corporation. AT&T is a registered trademark of American Telephone and Telegraph Company. Hercules is a registered trademark and InColor is a trademark of Hercules Computer Technology. IBM and PC/AT are registered trademarks and PC/XT is a trademark of International Business Machines Corporation. Intel is a registered trademark of Intel Corporation. Olivetti is a registered trademark of Ing. C. Olivetti. Document No. 410700018-450-R00-1188 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table of Contents Introduction Document Conventions Reference Page Format PART 1 LANGUAGE FUNDAMENTALS Chapter 1 Language Elements 1.1 Character Set 1.2 The BASIC Program Line 1.2.1 Using Line Identifiers 1.2.2 BASIC Statements 1.2.3 BASIC Line Length Chapter 2 Data Types 2.1 Data Types 2.1.1 Elementary Data TypesÄÄString 2.1.2 Elementary Data TypesÄÄNumeric 2.1.2.1 Integer Numbers 2.1.2.2 Floating-Point Numbers 2.1.3 User-Defined Data Types 2.2 Constants 2.2.1 Literal Constants 2.2.2 Symbolic Constants 2.3 Variables 2.3.1 Variable Names 2.3.2 Declaring Variable Types 2.3.2.1 Type-Declaration Suffix 2.3.2.2 AS Declaration Statements 2.3.2.3 DEFtype Declaration Statements 2.3.2.4 Declaring Array Variables 2.3.3 Variable Storage Allocation 2.4 Scope of Variables and Constants 2.4.1 Global Variables and Constants 2.4.2 Local Variables and Constants 2.4.3 Sharing Variables 2.4.4 DEF FN Functions 2.4.5 Summary of Scope Rules 2.5 Static and Dynamic Arrays 2.6 Automatic and Static Variables 2.7 Type Conversion Chapter 3 Expressions and Operators 3.1 Expressions and Operators Defined 3.2 Hierarchy of Operations 3.3 Arithmetic Operators 3.3.1 Integer Division 3.3.2 Modulo Arithmetic 3.3.3 Overflow and Division by Zero 3.4 Relational Operators 3.5 Logical Operators 3.6 Functional Operators 3.7 String Operators Chapter 4 Programs and Modules 4.1 Modules 4.2 Procedures 4.2.1 FUNCTION Procedures 4.2.2 SUB Procedures 4.2.3 DEF FN Functions 4.3 Passing by Reference and Passing by Value 4.4 Recursion PART 2 STATEMENT AND FUNCTION REFERENCE ABS Function ASC Function ATN Function BEEP Statement BLOAD Statement BSAVE Statement CALL Statement (BASIC) CALL, CALLS Statement (Non-BASIC) CALL ABSOLUTE Statement CALL INT86OLD Statements CALL INTERRUPT Statements CDBL Function CHAIN Statement CHDIR Statement CHR$ Function CINT Function CIRCLE Statement CLEAR Statement CLNG Function CLOSE Statement CLS Statement COLOR Statement COM Statements COMMAND$ Function COMMON Statement CONST Statement COS Function CSNG Function CSRLIN Function CVSMBF, CVDMBF Functions CVI, CVS, CVL, CVD Functions DATA Statement DATE$ Function DATE$ Statement DECLARE Statement (BASIC) DECLARE Statement (Non-BASIC) DEF FN Statement DEF SEG Statement DEFtype Statements DIM Statement DO...LOOP Statement DRAW Statement END Statement ENVIRON Statement ENVIRON$ Function EOF Function ERASE Statement ERDEV, ERDEV$ Functions ERR, ERL Functions ERROR Statement EXIT Statement EXP Function FIELD Statement FILEATTR Function FILES Statement FIX Function FOR...NEXT Statement FRE Function FREEFILE Function FUNCTION Statement GET StatementÄÄFile I/O GET StatementÄÄGraphics GOSUB...RETURN Statements GOTO Statement HEX$ Function IF...THEN...ELSE Statement INKEY$ Function INP Function INPUT$ Function INPUT Statement INPUT # Statement INSTR Function INT Function IOCTL$ Function IOCTL Statement KEY (n) Statements KEY Statements KILL Statement LBOUND Function LCASE$ Function LEFT$ Function LEN Function LET Statement LINE Statement LINE INPUT Statement LINE INPUT # Statement LOC Function LOCATE Statement LOCK...UNLOCK Statement LOF Function LOG Function LPOS Function LPRINT, LPRINT USING Statements LSET Statement LTRIM$ Function MID$ Function MID$ Statement MKD$, MKI$, MKL$, MKS$ Functions MKDIR Statement MKSMBF$, MKDMBF$ Functions NAME Statement OCT$ Function ON ERROR Statement ONevent Statements ON...GOSUB, ON...GOTO Statement ON UEVENT GOSUB Statement OPEN Statement OPEN COM Statement OPTION BASE Statement OUT Statement PAINT Statement PALETTE, PALETTE USING Statements PCOPY Statement PEEK Function PEN Function PEN ON, OFF, and STOP Statements PLAY Function PLAY Statement PLAY ON, OFF, and STOP StatementsP PMAP Function POINT Function POKE Statement POS Function PRESET Statement PRINT Statement PRINT USING Statement PRINT #, PRINT # USING Statements PSET Statement PUT StatementÄÄFile I/O PUT StatementÄÄGraphics RANDOMIZE Statement READ Statement REDIM Statement REM Statement RESET Statement RESTORE Statement RESUME Statement RETURN Statement RIGHT$ Function RMDIR Statement RND Function RSET Statement RTRIM$ Function RUN Statement SADD Function SCREEN Function SCREEN Statement SEEK Function SEEK Statement SELECT CASE Statement SETMEM Function SGN Function SHARED Statement SHELL Statement SIN Function SLEEP Statement SOUND Statement SPACE$ Function SPC Function SQR Function STATIC Statement STICK Function STOP Statement STR$ Function STRIG Function and Statement STRIG ON, OFF, and STOP Statements STRING$ Function SUB Statements SWAP Statement SYSTEM Statement TAB Function TAN Function TIME$ Function TIME$ Statement TIMER Function TIMER ON, OFF, and STOP Statements TRON/TROFF Statements TYPE Statement UBOUND Function UCASE$ Function UEVENT Statement UNLOCK Statement VAL Function VARPTR, VARSEG Functions VARPTR$ Function VIEW Statement VIEW PRINT Statement WAIT Statement WHILE...WEND Statement WIDTH Statement WINDOW Statement WRITE Statement WRITE # Statement Appendix A Keyboard Scan Codes and ASCII Character Codes A.1 Keyboard Scan Codes A.2 ASCII Character Codes Appendix B Error Messages B.1 Error-Message Display B.2 Invocation, Compile-Time, and Run-Time Error Messages B.3 LINK Error Messages B.4 LIB Error Messages Index Figures 2.1 BASIC Numeric Representations R.1 WINDOW and WINDOW SCREEN Tables 2.1 Types of Numeric Constants 2.2 Variable-Type Memory Requirements 3.1 Relational Operators and Their Functions 3.2 BASIC Logical Operators 3.3 Values Returned by Logical Operations R.1 INT86OLD and INT86XOLD Register Values R.2 FILEATTR Mode Codes R.3 Values for Bits per Pixel per Plane and for Planes R.4 Keyboard Scan Codes R.5 SCREEN Color and Attribute Ranges R.6 MDPA Screen Modes R.7 Hercules Screen Modes R.8 CGA Screen Modes R.9 EGA Screen Modes R.10 Default Attributes: SCREEN 10, Monochrome Display R.11 Color Values: SCREEN 10, Monochrome Display R.12 VGA Screen Modes R.13 MCGA Screen Modes R.14 Default Attributes and Colors for SCREEN Modes 1 and 9 R.15 Default Attributes and Colors for SCREEN Modes 2 and 11 R.16 Default Attributes and Colors for SCREEN Modes 0, 7, 8, 9, 12, and 13 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Introduction Microsoft(R) QuickBASIC 4.5 is a powerful programming language for either commercial applications or quick development of single-use programs. QuickBASIC is compatible with BASICA, adding advanced features such as user-defined data types and recursive procedures to the elements that have traditionally made BASIC an ideal language for new programmers. The Microsoft BASIC Language Reference describes the QuickBASIC programming language. Use this manual as a printed reference guide while you are programming to find the syntax or effect of particular statements and functions. You can also use this book to explore BASIC by reading about unfamiliar statements and trying them in the short example programs provided. The BASIC Language Reference has these parts: ž Part 1, "Language Fundamentals," describes the elements of the BASIC language: characters, program lines, data types, constants, variables, modules, programs, and procedures. ž Part 2, "Statement and Function Reference," contains reference material on each BASIC statement and function, organized alphabetically. ž The appendixes list the keyboard scan and ASCII character codes and provide quick reference information on error messages. This volume is a companion to the other books supplied with QuickBASIC Version 4.5. Learning to Use Microsoft QuickBASIC explains how to use the QuickBASIC environment and introduces BASIC programming. Programming in BASIC contains more advanced programming information. Document Conventions This manual uses the following typographic conventions: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Example of Convention Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ QB.LIB, ADD.EXE, COPY, Uppercase (capital) letters indicate file names LINK, /X and DOS-level commands. Uppercase is also used for command-line options (unless the application accepts only lowercase). SUB, IF, LOOP, PRINT, Bold capital letters indicate language-specific WHILE, TIME$ keywords with special meaning to Microsoft BASIC. Keywords are a required part of statement syntax, Example of Convention Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Keywords are a required part of statement syntax, unless they are enclosed in double brackets as explained below. In programs you write, you must enter keywords exactly as shown. However, you can use uppercase letters or lowercase letters. CALL NewProc(arg1!, This kind of type is used for program examples, var2%) program output, and error messages within the text. ›INCLUDE: BC.BI A column of three dots indicates that part of the . example program has been intentionally omitted. . . CHAIN "PROG1" END ' Make one pass The apostrophe (single right quotation mark) marks the beginning of a comment in sample Example of Convention Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  marks the beginning of a comment in sample programs. filespec Italic letters indicate placeholders for information you must supply, such as a file name. Italics are also occasionally used in the text for emphasis. ®optional-itemÆ Items inside chevrons are optional. {choice1 | choice2} Braces and a vertical bar indicate a choice among two or more items. You must choose one of the items unless all of the items are also enclosed in double square brackets. repeating elements... Three dots following an item indicate that more items having the same form may appear. ALT+F1 Capital letters are used for the names of keys Example of Convention Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ALT+F1 Capital letters are used for the names of keys and key sequences, such as ENTER and CTRL+R. A plus (+) indicates a combination of keys. For example, CTRL+E means to hold down the CTRL key while pressing the E key. The carriage-return key, sometimes marked with a bent arrow, is referred to as ENTER. The cursor movement ("arrow") keys on the numeric keypad are called DIRECTION keys. Individual DIRECTION keys are referred to by the direction of the arrow on the key top (LEFT, RIGHT, UP, DOWN) or the name on the key top (PGUP, PGDN). The key names used in this manual correspond to the names on the IBM(R) Personal Computer keys. Other machines may use different names. Example of Convention Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Other machines may use different names. "defined term" Quotation marks usually indicate a new term defined in the text. Video Graphics Array Acronyms are usually spelled out the first time (VGA) they are used. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The syntax below (for the "LOCK...UNLOCK" statements) illustrates many of the typographic conventions in this manual: LOCK®#Æfilenumber®,{record | ®startÆ TO end }Æ . . . UNLOCK®#Æfilenumber®,{record | ®startÆ TO end }Æ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Throughout this manual, the term "DOS" refers to both the MS-DOS(R) and IBM Personal Computer DOS operating systems. The name of a specific operating system is used when it is necessary to note features that are unique to that system. The term "BASICA" refers to interpreted versions of BASIC in general. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Reference Page Format Each statement and function description in Part 2, "Statement and Function Reference," uses the following format: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Heading Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Action Summarizes what the statement or function does. Syntax Gives the correct syntax for the statement or Heading Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Syntax Gives the correct syntax for the statement or function. Remarks Describes arguments and options in detail and explains how to use the statement or function. Differences from BASICA Optional section that tells whether or not the given statement or function is new, enhanced, or different from the same statement in the Microsoft BASIC 2.0 Interpreter described in the IBM Personal Computer BASICA reference manual. See Also Mentions related statements and functions (also an optional section). Example Gives sample commands, programs, and program segments illustrating the use of the statement or function (also an optional section). Heading Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PART 1 LANGUAGE FUNDAMENTALS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Part 1 describes aspects of the BASIC language. Chapter 1 gives information on the BASIC character set and the structure of a BASIC program line. Chapter 2 discusses data types, constants, variables, and arrays. Chapter 3 talks about BASIC operators and expressions. Chapter 4 explains how to use modules and procedures in BASIC programming. This chapter also describes the relationship between programs and modules and discusses the SUB and FUNCTION procedures available in QuickBASIC. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Chapter 1 Language Elements 1.1 Character Set 1.2 The BASIC Program Line 1.2.1 Using Line Identifiers 1.2.2 BASIC Statements 1.2.3 BASIC Line Length This chapter discusses some of the fundamental elements of the QuickBASIC version of the BASIC language. As in virtually all programming languages, characters from the BASIC character set form labels, keywords, variables, and operators. These then combine to form the statements that make up a program. ž The BASIC character set and the special meanings of some characters ž The format of a line in a BASIC program ž Line labels ž Executable and nonexecutable statements ž Program line length Chapter 2, "Data Types," and Chapter 3, "Expressions and Operators," discuss other parts of statements, including expressions. 1.1 Character Set The Microsoft BASIC character set consists of alphabetic characters, numeric characters, and special characters. The alphabetic characters in BASIC are the uppercase letters (A-Z) and lowercase letters (a-z) of the alphabet. The BASIC numeric characters are the digits 0-9. The letters A-F and a-f can be used as parts of hexadecimal numbers. The characters in Table 1.1 have special meanings in BASIC statements and expressions. Table 1.1 BASIC Character Set ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Character Name ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ENTER Terminates input of a line Blank (or space) ! Exclamation point (single-precision data-type suffix) # Number sign (double-precision data-type suffix) $ Dollar sign (suffix for string data type) % Percent (suffix for integer data type) & Ampersand (suffix for long-integer data type) ' Single quotation mark (apostrophe) ( Left parenthesis ) Right parenthesis * Asterisk (multiplication symbol) + Plus sign , Comma - Minus sign . Period (decimal point) Character Name ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  . Period (decimal point) / Slash (division symbol) : Colon ; Semicolon < Less than = Equal sign (relational operator or assignment symbol) > Greater than ? Question mark @ At symbol [ Left bracket ] Right bracket \ Backslash (integer division symbol) ^ Up arrow or caret (exponentiation symbol) _ Underscore (line continuation) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1.2 The BASIC Program Line BASIC program lines have the following syntax: [[line-identifier]] [[statement]] [[: statement]]...[[comment]] 1.2.1 Using Line Identifiers BASIC supports two types of line-identifiersÄÄline numbers and alpha-numeric line labels: 1. A line number may be any combination of digits from 0 to 65,529. The following are examples of valid line numbers: 1 200 300PRINT "hello" '300 is the line number. 65000 Using 0 as a line number is not recommended. Error- and event-trapping statements (ON ERROR and ONevent) interpret the presence of line number 0 to mean that trapping is disabled (stopped). For example, the following statement disables error trapping but does not branch to line 0 if an error occurs: ON ERROR GOTO 0 In addition, RESUME 0 continues execution on the line where the error occurred, not at line number 0. 2. An alphanumeric line label may be any combination of from 1 to 40 letters and digits, starting with a letter and ending with a colon. BASIC keywords are not permitted. The following are valid alphanumeric line labels: Alpha: ScreenSub: Test3A: Case is not significant. The following line labels are equivalent: alpha: Alpha: ALPHA: Line numbers and labels may begin in any column, as long as they are the first characters other than blanks or tabs on the line. Blanks and tabs are also allowed between an alphanumeric label and the colon following it. A line can have only one label. BASIC does not require each line in a source program to have the same type of identifier, either a line number or label. You may mix alphanumeric labels and line numbers in the same program, and you may use alphanumeric labels as objects of any BASIC statement where line numbers are permitted, except as the object of an IF...THEN statement. In IF...THEN statements, BASIC permits only a line number, unless you explicitly use a GOTO statement. For example, the form of the following statement is correct: IF A = 10 THEN 500 However, if the object of the IF...THEN statement is a line label, a GOTO statement is required: IF A = 10 THEN GOTO IncomeData If you are trapping errors, the ERL function returns only the last line number located before the error. Neither RESUME nor RESUME NEXT requires line labels or line numbers. See the entries for ERL and RESUME for more information. Line numbers do not determine the order in which statements are executed in QuickBASIC. For example, QuickBASIC executes statements in the following program in the order 100, 10, 5: 100 PRINT "The first line executed." 10 PRINT "The second line executed." 5 PRINT "The third and final line executed." Some older BASICs, such as BASICA, would execute the lines in numerical order: 5, 10, 100. 1.2.2 BASIC Statements A BASIC statement is either "executable" or nonexecutable." An executable statement advances the flow of a program's logic by telling the program what to do next (telling it to read input, write output, add two numbers together and store the resulting value in a variable, open a file, branch to another part of the program, or take some other action). In contrast, a nonexecutable statement does not advance the flow of a program's logic. Instead, nonexecutable statements perform tasks such as allocating storage for variables, declaring and defining variable types, and designating variables to be shared among all the procedures in a source file. The following BASIC statements are nonexecutable: ž COMMON ž CONST ž DATA ž DECLARE ž DEFtype ž DIM (static arrays only) ž OPTION BASE ž SHARED ž STATIC ž TYPE...END TYPE Another type of nonexecutable statement is a "comment" used to clarify a program's operation and purpose. A comment is introduced by the REM statement or a single quote character ('). The following lines are equivalent: PRINT "Quantity remaining" : REM Print report label. PRINT "Quantity remaining" ' Print report label. More than one BASIC statement can be placed on a line, but colons (:) must separate statements, as illustrated below: FOR I=1 TO 5 : PRINT "G'day, mate." : NEXT I 1.2.3 BASIC Line Length If you enter your programs using QuickBASIC's built-in editor, you are limited to lines of 256 characters. The QuickBASIC editor does not recognize the underscore character (_) as a line continuation. If you use your own editor, you may use an underscore as the last character to create a program line, like the following, that extends across more than one physical line: IF (TestChar$ = " " OR TestChar$ = ".") AND _ LineNumber < 23 AND NOT EOF(FileNumber) THEN When QuickBASIC loads your program, the underscores are removed and the continued lines are joined to form a single line. The line-length limit is relaxed in this case. Underscores cannot be used to continue DATA or REM statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Chapter 2 Data Types 2.1 Data Types 2.1.1 Elementary Data TypesÄÄString 2.1.2 Elementary Data TypesÄÄNumeric 2.1.2.1 Integer Numbers 2.1.2.2 Floating-Point Numbers 2.1.3 User-Defined Data Types 2.2 Constants 2.2.1 Literal Constants 2.2.2 Symbolic Constants 2.3 Variables 2.3.1 Variable Names 2.3.2 Declaring Variable Types 2.3.2.1 Type-Declaration Suffix 2.3.2.2 AS Declaration Statements 2.3.2.3 DEFtype Declaration Statements 2.3.2.4 Declaring Array Variables 2.3.3 Variable Storage Allocation 2.4 Scope of Variables and Constants 2.4.1 Global Variables and Constants 2.4.2 Local Variables and Constants 2.4.3 Sharing Variables 2.4.4 DEF FN Functions 2.4.5 Summary of Scope Rules 2.5 Static and Dynamic Arrays 2.6 Automatic and Static Variables 2.7 Type Conversion This chapter contains seven sections that provide the following information about the data types, constants, and variables in BASIC: ž The elementary data types (string and numeric) ž The formation of literal and symbolic constants ž The rules for naming a BASIC variable and for determining a variable's type, and how BASIC allocates variable storage ž The scope rules that BASIC follows to decide to which object a variable name refers ž The difference between static and dynamic arrays ž The use of automatic and static variables in SUB and FUNCTION procedures ž The conversions from one numeric type to another that BASIC may perform when doing calculations 2.1 Data Types Every variable in BASIC has a data type that determines what can be stored in the variable. There are two categories of data in BASIC: string data and numeric data. Each category includes elementary data types. The next section summarizes the elementary data types. 2.1.1 Elementary Data TypesÄÄString The two kinds of strings are as follows: ž Variable-length string A variable-length string is a sequence of up to 32,767 characters. The codes for these characters range from 0-127 for American Standard Code for Information Interchange (ASCII) characters, and from 128-255 for non-ASCII characters (see Appendix A, "Keyboard Scan Codes and ASCII Character Codes"). ž Fixed-length string A fixed-length string contains a declared number of characters. Fixed-length strings can be no longer than 32,767 characters. Fixed-length strings, like variable-length strings, contain characters with codes ranging from 0-255. 2.1.2 Elementary Data TypesÄÄNumeric BASIC has two types of integers and two types of floating-point values. Figure 2.1 shows the internal (memory) formats of these four different numeric types. The following table summarizes the types: Numeric Type Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Integer (2 bytes) Integers are stored as signed 16-bit binary numbers ranging in value from -32,768 to +32,767. Long integer (4 bytes) "Long" integers are stored as signed 32-bit binary numbers ranging in value from -2,147,483,648 to +2,147,483,647. Single-precision "Single-precision" numbers are accurate to seven floating point (4 bytes) decimal places, and have ranges of -3.402823E+38 to -1.40129E-45 for negative values and 1.40129E-45 to 3.402823E+38 for positive values. Double-precision "Double-precision" numbers are accurate to 15 or floating point (8 bytes) 16 digits and have an extended range: -1.797693134862316E+308 to -4.94065E-324 for negative numbers and 4.94065E-324 to 1.797693134862316E+308 for positive values. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2.1.2.1 Integer Numbers Integer 1514 0 ŚÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³ ³ ĄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ sign Long integer 31 30 0 ŚÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³ ³ ĄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ Single-precision real 31 30 23 22 0 ŚÄĀÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³ ³ ³ ĄÄĮÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ ĄÄĀÄŁ³ĄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ ³ ³ ³ sign ³Implied Mantissa ³ bit ³ Exponent Double Precision real 63 62 52 51 ŚÄĀÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³ ³ ³ ĄÄĮÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ ĄÄĀÄÄÄŁ³ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ ³ ³ ³ sign ³Implied Mantissa ³ bit ³ Exponent Figure 2.1 BASIC Numeric Representations All BASIC integers are represented as two's complement values, the most common way of representing integers on a computer. Integers use 16 bits (2 bytes) and long integers use 32 bits (4 bytes). In two's complement representation, positive values are represented as straightforward binary numbers. For example, BASIC would store an integer value of 4 as a sequence of the following 16 bits: 0000000000000100 Negative values are represented as the two's complement of the corresponding positive value. To form the two's complement (the negative) of the integer value 4, first take the representation above and change all ones to zeroes and all zeroes to ones: 1111111111111011 Then add one to the result: 1111111111111100 The final result is how BASIC represents -4 as a binary number. Because of the way two's complement numbers are formed, every combination of bits representing a negative value has a 1 as the leftmost bit. 2.1.2.2 Floating-Point Numbers QuickBASIC Version 4.5 uses IEEE-format floating-point numbers rather than the Microsoft Binary format used in earlier versions. (IEEE is an acronym for Institute of Electrical and Electronics Engineers, Inc.) IEEE format gives more accurate results and makes it possible to use an 8087 or 80287 math coprocessor. Floating-point values are represented in a different format from integers. In floating-point format each number consists of three parts: the sign, the exponent, and the mantissa. You can think of this format as a variation of scientific notation. In scientific notation, the number 1000 would be represented as 1.0 x 10^3. To save space, you could just remember the exponent, 3, and the mantissa, 1.0, and reconstruct the value later by raising 10 to the power 3 and multiplying by the mantissa. Floating-point notation works by saving just the exponent and the mantissa. The only difference from scientific notation is that in this format the exponent represents a power of 2, not a power of 10. In a single-precision number, the sign takes 1 bit, the exponent takes 8 bits, and the mantissa uses the remaining 23 bits and an additional implied bit. Double-precision values occupy 8 bytes or 64 bits: 1 bit for the sign, 11 bits for the exponent, and an implied bit and 52 actual bits for the mantissa. The following program (included on the QuickBASIC distribution disks in the file FLPT.BAS) can be used to examine the internal format of single-precision values: DECLARE FUNCTION MHex$ (X AS INTEGER) ' Display how a given real value is stored in memory. DEFINT A-Z DIM Bytes(3) CLS PRINT "Internal format of IEEE number (in hexadecimal)" PRINT DO ' Get the value. INPUT "Enter the value (END to end): ", A$ IF UCASE$(A$) = "END" THEN EXIT DO RealValue! = VAL(A$) ' Convert the real value to a long without changing any of ' the bits. AsLong& = CVL(MKS$(RealValue!)) ' Make a string of hex digits, and add leading zeroes. Strout$ = HEX$(AsLong&) Strout$ = STRING$(8 - LEN(Strout$), "0") + Strout$ ' Save the sign bit, and then eliminate it so it doesn't ' affect breaking out the bytes. SignBit&=AsLong& AND &H80000000& AsLong&=AsLong& AND &H7FFFFFFF& ' Split the real value into four separate bytes. ' --the AND removes unwanted bits; dividing by 256 shifts ' the value right 8 bit positions. FOR I = 0 TO 3 Bytes(I) = AsLong& AND &HFF& AsLong& = AsLong& 256& NEXT I ' Display how the value appears in memory. PRINT PRINT "Bytes in Memory" PRINT " High Low" FOR I = 1 TO 7 STEP 2 PRINT " "; MID$(Strout$, I, 2); NEXT I PRINT:PRINT ' Set the value displayed for the sign bit. Sign = ABS(SignBit& <> 0) ' The exponent is the right seven bits of byte 3 and the ' leftmost bit of byte 2. Multiplying by 2 shifts left and ' makes room for the additional bit from byte 2. Exponent = Bytes(3) * 2 + Bytes(2) 128 ' The first part of the mantissa is the right seven bits ' of byte 2. The OR operation makes sure the implied bit ' is displayed by setting the leftmost bit. Mant1 = (Bytes(2) OR &H80) PRINT " Bit 31 Bits 30-23 Implied Bit & Bits 22-0" PRINT "Sign Bit Exponent Bits Mantissa Bits" PRINT TAB(4); Sign; TAB(17); MHex$(Exponent); PRINT TAB(33); MHex$(Mant1);MHex$(Bytes(1));MHex$(Bytes(0)) PRINT LOOP ' MHex$ makes sure we always get two hex digits. FUNCTION MHex$ (X AS INTEGER) STATIC D$ = HEX$(X) IF LEN(D$) < 2 THEN D$ = "0" + D$ MHex$ = D$ END FUNCTION Output Enter the value (END to end): 4 Bytes in Memory High Low 40 80 00 00 Bit 31 Bits 30-23 Implied Bit & Bits 22-0 Sign Bit Exponent Bits Mantissa Bits 0 81 800000 The program displays the sign, exponent, and mantissa of the single-precision value. The mantissa's implied bit is automatically included. All values are printed out in hexadecimal values (base 16 numbers), which are a shorthand way of writing binary numbers. Each hexadecimal digit represents a pattern of 4 bits: 0 hexadecimal represents 0000 binary, 8 hexadecimal represents 1000, and F hexadecimal (a digit for the value 15 in decimal) represents 1111. Looking at the output from the program, the decimal value 4 is represented in memory as a series of 4 bytes: 40 80 00 00 These 4 bytes break down into a single-sign bit of 0, a 1-byte exponent of &H81, and a mantissa of &H800000. The exponent value of &H81 represents a biased exponent, not the true exponent. With a biased exponent, a fixed value (a "bias") is added to the true exponent and the result is stored as part of the number. For single-precision values, the bias is &H7F or 127. Double-precision values use a bias of &H3FF or 1023. Using a biased exponent avoids having to use one of the exponent bits to represent the sign. In the output, 4 is a power of 2, so the true exponent is 2. Adding the bias (&H7F) gives the stored exponent value of &H81. A normalized mantissa refers to a mantissa that is multiplied by 2 (shifted to the left) and the exponent decreased until the leftmost bit is a 1. By eliminating leading zeroes from the mantissa, more significant bits can be stored. In memory, the mantissa for a value of 4 is all zeroes. This is so because the mantissa is normalized and the leftmost bit is assumed. Because the mantissa is always normalized, the leftmost bit is always a 1. And because the leftmost bit is always a 1, there is no reason to store it as part of the number. BASIC thus stores 23 bits (number 22 to 0) for the mantissa of a single-precision number but also includes a 24th, implied bit that is always a 1. There is an implied "binary point" (analogous to a decimal point) to the right of the implied bit. The binary point indicates that bits 22 to 0 in the mantissa are really a binary fraction. Thus, in the example, the mantissa is really a single 1 (the implied bit) followed by a zero binary fraction (bits 22 to 0). The mantissa of 1 multiplied by 2 taken to the power of the exponent, 2, is 1 x 2^2, or 4. 2.1.3 User-Defined Data Types BASIC lets you define new data types using the TYPE statement. A user-defined type is an aggregate type made up of elementary BASIC types. For example, the following TYPE statement defines a type, SymTabEntry: TYPE SymTabEntry Identifier AS STRING*40 LineNumber AS LONG Value AS LONG END TYPE The new type contains a fixed-length string and two long integers. A variable of a user-defined type occupies only as much storage as the sum of its components. A SymTabEntry takes up 48 bytes: 40 bytes for the fixed-length string and 4 bytes each for the two long integers. You may use any of the BASIC data types (except variable-length strings) in a user-defined type: short and long integers, single- and double-precision floating-point values, and fixed-length strings. However, user-defined types cannot include arrays. 2.2 Constants Constants are predefined values that do not change during program execution. There are two general types of constants: literal constants (such as numbers and strings) and symbolic constants. 2.2.1 Literal Constants BASIC has two kinds of literal constants: string and numeric. A string constant is a sequence of up to 32,767 alphanumeric characters enclosed by double quotation marks. These alphanumeric characters can be any of the characters (except the double quote character and any carriage-return and line-feed sequences) whose ASCII codes fall within the range 0-255. This range includes both the actual ASCII characters (0-127) and the extended characters (128-255). The following are all valid string constants: "HELLO" "$25,000.000" "Number of Employees" Numeric constants are positive or negative numbers. There are four types of numeric constants: integer, long integer, fixed point, and floating point. Table 2.1 below describes these types and provides examples. Fixed-point and floating-point numeric constants can be either single-precision or double-precision numbers. Single-precision numeric constants are stored with 7 digits of precision (plus the exponent). Double-precision numbers are stored with 15 or 16 digits of precision (plus the exponent). A single-precision constant is any numeric constant that has one of the following properties: ž Exponential form denoted by "E" ž A trailing exclamation mark (!) ž A value containing a decimal point that does not have either a "D" in the exponent or a trailing number sign (#) and that has fewer than 15 digits ž A value without a decimal point that has fewer than 15 digits but cannot be represented as a long-integer value A double-precision constant is any numeric constant that has one of the following properties: ž Exponential form denoted by "D" ž A trailing number sign (#) ž A decimal point, no "E" in the exponent or trailing exclamation mark (!), and more than 15 digits Table 2.1 Types of Numeric Constants ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Integer Decimal One or more 68 +407 -1 decimal digits (0-9) with an optional sign prefix (+ or -). The range for integer decimal constants is -32,768 to +32,767. Integer Hexadecimal One or more &H76 &H32F hexadecimal digits Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  hexadecimal digits (0-9, a-f, or A-F) with the prefix &H or &h. The range for integer hexadecimal constants is &h0 to &hFFFF. Integer Octal One or more octal &o347 &1234 digits (0-7) with the prefix &O, &o, or &. The range for integer octal constants is &o0 to &o177777. Long integer Decimal One or more 95000000 -400141 decimal digits Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  decimal digits (0-9) with an optional sign prefix (+ or -) and the suffix &. The range for long decimal constants is -2,147,483,648 to +2,147,483,647. Long integer Hexadecimal One or more &H0& &H1AAAAA& hexadecimal digits (0-9, a-f, or A-F) with the prefix &H or &h and the suffix &. The range for long hexadecimal constants is &h0& Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  constants is &h0& to &hFFFFFFFF&. Long integer Octal One or more octal &o347& &555577733& digits (0-7) with the prefix &O, &o, or & and the suffix &. The range for long octal constants is &o0& to &o37777777777&. Fixed point Positive or 9.0846 negative real numbersÄÄnumbers containing decimal points. Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Floating point Single precision Positive or 2235.988E-7 2359E6 negative numbers represented in exponential form (similar to scientific notation). A single-precision floating-point constant is an optionally signed integer or fixed-point number (the mantissa) followed by the letter E and an optionally signed integer (the Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  integer (the exponent). The constant's value is the mantissa multiplied by the power of ten represented by the exponent. The range for single-precision constants is -3.37E+38 to 3.37E+38. Floating point Double precision Double-precision 4.35D-10 floating-point constants have the same form as single-precision Type Subtype Description Examples ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  single-precision floating-point constants, but use D, rather than E, to indicate the exponent. Double-precision constants have a range of -1.67D+308 to 1.67D+308. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Numeric constants in BASIC cannot contain commas. The following are examples of numeric constants: Single Precision Double Precision ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 46.8 345692811.5375901 -1.09E-6 -1.09432D-06 3489.0 3489.0# 22! 987654321.1234567 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2.2.2 Symbolic Constants BASIC provides symbolic constants that can be used in place of numeric or string values. The following fragment declares two symbolic constants and uses one to dimension an array: CONST MAXCHARS%=254, MAXBUF%=MAXCHARS%+1 DIM Buffer%(MAXBUF%) The name of a symbolic constant follows the same rules as a BASIC variable name. You may include a type-declaration character (%, #, !, or $) in the name to indicate its type, but this character is not part of the name. For example, after the following declaration, the names N!, N#, N$, N%, and N& cannot be used as variable names because they have the same name as the constant: CONST N=45 A constant's type is determined either by an explicit type-declaration character or the type of the expression. Symbolic constants are unaffected by DEFtype statements. If you omit the type-declaration character, the constant is given a type based on the expression. Strings always yield a string constant. With numeric expressions, the expression is evaluated and the constant is given the simplest type that can represent it. For example, if the expression gives a result that can be represented as an integer, the constant is given an integer type. See Section 2.4 below, "Scope of Variables and Constants," for information about the scope of constants. See the entry for CONST in Part 2, "Statement and Function Reference," for more information about where and how to use symbolic constants. 2.3 Variables A variable is a name that refers to an objectÄÄa particular number, string, or record. (A record is a variable declared to be a user-defined type.) Simple variables refer to a single number, string, or record. Array variables refer to a group of objects, all of the same type. A numeric variable, whether simple or array, can be assigned only a numeric value (either integer, long integer, single precision, or double precision); a string variable can be assigned only a character-string value. You can assign one record variable to another only if both variables are the same user-defined type. However, you can always assign individual elements of a record to a variable of the corresponding type. The following list shows some examples of variable assignments: Variable Assignment Example ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A constant value A = 4.5 The value of another B$ = "ship of fools" A$ = B$ Profits = string or numeric NetEarnings variable The value of a record TYPE EmployeeRec EName AS STRING*25 SocSec AS element STRING*9 END TYPE DIM CurrentEmp AS EmployeeRec . . . OutSocSec$=CurrentEmp.SocSec The value of one record TYPE FileBuffer EName AS STRING*25 JobClass AS variable to another of INTEGER END TYPE DIM Buffer1 AS FileBuffer DIM the same type Buffer2 AS FileBuffer . . . Buffer2=Buffer1 The value obtained by CONST PI = 3.141593 Conversion = 180/PI TempFile$ combining other = FileSpec$+".BAK" variables, constants, and operators ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ See Chapter 3, "Expressions and Operators," for more information on the operators used in BASIC for combining variables and constants. In any case, the variable must always match the type of data (numeric or string) assigned to it. Before a variable is assigned a value, its value is assumed to be zero (for numeric variables) or null (for string variables). All fields in a record, including string fields, are initialized to zero. 2.3.1 Variable Names A BASIC variable name may contain up to 40 characters. The characters allowed in a variable name are letters, numbers, the decimal point, and the type-declaration characters (%, &, !, #, and $). The first character in a variable name must be a letter. If a variable begins with FN, it is assumed to be a call to a DEF FN function. (As a general rule, the use of a FUNCTION is preferred over a DEF FN.) A variable name cannot be a reserved word, but embedded reserved words are allowed. For example, the following statement is illegal because LOG is a reserved word (BASIC is not case sensitive): Log = 8 However, the following statement is legal: TimeLog = 8 Reserved words include all BASIC commands, statements, function names, and operator names (see Appendix E, "BASIC Reserved Words," in Programming in BASIC for a complete list of reserved words). Variable names must also be distinct from both SUB and FUNCTION procedure names and symbolic constant (CONST) names. 2.3.2 Declaring Variable Types Simple variables can be numeric, string, or record variables. You may specify simple variable types by the use of a type-declaration suffix, in an AS declaration statement, or in a DEFtype declaration statement. Variables may also be declared as arrays. 2.3.2.1 Type-Declaration Suffix Append one of the following type-declaration suffixes to the variable name: % & ! # $ The dollar sign ($) is the type-declaration character for string variables; that is, it "declares" that the variable represents a string and that you can assign a string constant to it of up to 32,767 characters, as in the example below. A$ = "SALES REPORT" Numeric-variable names can declare integer values (denoted by the % suffix), long-integer values (denoted by the & suffix), single-precision values (denoted by the ! suffix), or double-precision values (denoted by the # suffix). Single precision is the default for variables without a type suffix. There is no type-declaration character for a user-defined type. 2.3.2.2 AS Declaration Statements Declare the variable in a declaration having the form declare variablename AS type where declare can be either DIM, COMMON, REDIM, SHARED, or STATIC, and type can be either INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. For example, the following statement declares the variable A as having a long-integer type: DIM A AS LONG String variables declared in an AS STRING clause can be either variable-length strings or fixed-length strings. Variable-length strings are "expandable": their length depends on the length of any string assigned to them. Fixed-length strings have a constant length, specified by adding * number to the AS STRING clause, where number is the length of the string in bytes. For example: ' String1 can have a variable length: DIM String1 AS STRING ' String2 has a fixed length of 7 bytes: DIM String2 AS STRING*7 String1 = "1234567890" String2 = "1234567890" PRINT String1 PRINT String2 Output 1234567890 1234567 For more on fixed-length and variable-length strings, see Chapter 4, "String Processing," in Programming in BASIC. Declare record variables by using the name of the user type in the AS clause: TYPE InventoryItem Description AS STRING*25 Number AS STRING*10 Quantity AS LONG OrderPoint AS LONG END TYPE DIM CurrentItem AS InventoryItem, PreviousItem AS InventoryItem Use the format variablename.elementname to refer to individual elements of the new variable, as in the following example: IF CurrentItem.Description = "Ergonomic Desk Chair" THEN PRINT CurrentItem.Number; CurrentItem.Quantity END IF If you declare a variable with an AS clause, every declaration of the variable must use the AS clause. For example, in the following fragment the AS clause is required in the COMMON statement because AS was also used in the DIM statement: CONST MAXEMPLOYEES=250 DIM EmpNames(MAXEMPLOYEES) AS STRING COMMON EmpNames() AS STRING . . . 2.3.2.3 DEFtype Declaration Statements Use the BASIC statements DEFINT, DEFLNG, DEFSTR, DEFSNG, and DEFDBL to declare the types for certain variable names. By using one of these DEFtype statements, you can specify that all variables starting with a given letter or range of letters are one of the elementary variable types, without using the trailing declaration character. DEFtype statements only affect variable names in the module in which they appear. See the DEFtype statement reference pages in Part 2, "Statement and Function Reference," for more information. The type-declaration suffixes for variable names, the type names accepted in AS type declarations, and the memory (in bytes) required for each variable type to store the variable's value are listed in Table 2.2. Table 2.2 Variable-Type Memory Requirements ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· AS Type Variable Size Suffix Name Type of Data AS Type Variable Size Suffix Name Type of Data ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ % INTEGER Integer 2 & LONG Long integer 4 ! SINGLE Single precision 4 # DOUBLE Double precision 8 $ STRING Variable-length Takes 4 bytes for string descriptor, 1 byte for each character in string $ STRING*num Fixed-length Takes num bytes string None Declared Record variable Takes as many user-defined type bytes as the individual AS Type Variable Size Suffix Name Type of Data ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  individual elements require ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2.3.2.4 Declaring Array Variables An array is a group of objects referenced with the same variable name. The individual values in an array are elements. Array elements are also variables and can be used in any BASIC statement or function that uses variables. You "dimension" an array when you use it the first time or when you declare the name, type, and number of elements in the array. Each element in an array is referred to by an array variable subscripted with an integer or an integer expression. (You may use noninteger numeric expressions as array subscripts; however, they are rounded to integer values.) The name of an array variable has as many subscripts as there are dimensions in the array. For example, V(10) refers to a value in a one-dimensional array, while T$(1,4) refers to a value in a two-dimensional string array. The default upper subscript value for any array dimension is 10. The maximum subscript value and the number of dimensions can be set by using the DIM statement. (See the reference pages for DIM in Part 2, "Statement and Function Reference," for more information.) The maximum number of dimensions for an array is 60. The maximum number of elements per dimension is 32,767. You may have arrays of any simple variable type, including records. To declare an array of records, first declare the data type in a TYPE statement and then dimension the array: TYPE TreeNode LeftPtr AS INTEGER RightPtr AS INTEGER DataField AS STRING*20 END TYPE DIM Tree(500) AS TreeNode Each element of the array Tree is a record of type TreeNode. To use a particular element of a record in an array, use form variablename.elementname (dot notation form): CONST MAXEMPLOYEES=500 TYPE EmployeeRec EName AS STRING*25 SocSec AS STRING*9 END TYPE DIM Employees(MAXEMPLOYEES) AS EmployeeRec . . . PRINT Employees(I).EName;" ";Employees(I).SocSec Array names are distinct from simple variable names. The array variable T and the simple variable T in the following example are two different variables: DIM T(11) T = 2 : T(0) = 1 'T is simple variable. FOR I% = 0 TO 10 'T(0) is element of array. T(I% + 1) = T * T(I%) NEXT Array elements, like simple variables, require a certain amount of memory, depending on the variable type. See Table 2.2 for information on the memory requirements for storing individual array elements. To find the total amount of memory required by an array, multiply the number of elements by the bytes per element required for the array type. For example, consider the following two arrays: DIM Array1(1 TO 100) AS INTEGER DIM Array#(-5 TO 5) The first array, Array1, has 100 integer elements, so its values take 200 bytes of memory. The second array, Array2, has 11 double-precision elements, so its values require 88 bytes of memory. Because BASIC must store information about the array along with the array's values, arrays take more memory than just the space for the values. 2.3.3 Variable Storage Allocation BASIC stores different kinds of variables in different areas in memory. You need to worry about where variables are stored only if you are either doing mixed-language programming or using one of the following BASIC statements or functions: ž CALL, CALLS (non-BASIC procedures) ž DECLARE (non-BASIC procedures) ž SADD ž SETMEM ž VARPTR ž VARSEG ž VARPTR$ BASIC stores variables either in an area called DGROUP or as far objects. (DGROUP is the name of the default data segment, the segment referenced when DEF SEG is used without an address.) Variables stored in DGROUP can be referenced by using near addresses or pointers. A near address consists of a single value or offset from the beginning of a segment or block of memory. Far objects are referenced by using far addresses or pointers. A far address consists of two parts: the starting address of a segment or block of memory and the offset within the segment. See the entries for the statements listed above for information about getting and using far pointers. Whether a variable is stored in DGROUP or as a far object depends first on whether it is a simple variable or an array. All simple variables are stored in DGROUP. Array storage is a little more complex and is slightly different between programs run as .EXE files and programs run within the QuickBASIC environment. In programs run as .EXE files, array variables are stored as follows: ž All static arrays are stored in DGROUP and can be referenced with near addresses. ž All dynamic arrays of variable-length strings are also stored in DGROUP and can also be referenced with near addresses. ž All other dynamic arrays are stored as far objects and require far addresses. See Section 2.5 for a description of static and dynamic arrays. In programs run within the QuickBASIC environment, array variable storage follows these rules: ž All static arrays in a COMMON block are stored in DGROUP and can be referenced with near addresses. ž All arrays of variable-length strings are also stored in DGROUP and can also be referenced with near addresses. ž All other arrays are stored as far objects and require far addresses. Because BASIC attempts to make the most efficient use of memory possible, several different things may cause a variable's memory location to change. These include a reference to a string literal or expression, the invocation of a DEF FN or FUNCTION, the use of a BASIC string or memory-related function, and a reference to an implicitly dimensioned array. To generate accurate results and because BASIC variables may move, use the results of VARPTR, VARSEG, VARTPR$, or SADD immediately after a function call that affects a variable. 2.4 Scope of Variables and Constants Any time a variable appears, BASIC follows a set of rules in determining to which object the variable refers. These rules describe a variable's scopeÄÄthe range of statements over which the variable is defined. The BASICA interpreter has a very simple scope rule: a variable exists when you first use it and persists until the program ends. The scope of a variable is from its first use through the end of the program. In QuickBASIC, you can control the scope of variables and symbolic constantsÄÄwhich helps you write compact, well-defined SUB and FUNCTION procedures that don't interfere with each other. You can also make some variables available to all procedures in a module, and thereby share important data structures among procedures. You may think of variables and constants as having one of two scopes: global or local. Global variables, once declared, may be used anywhere in a module to refer to some single object. Local variables are local to some part of the module, the module-level code or one of the procedures. In addition, variables can be shared in such a way that they aren't quite global, nor are they completely local. The rest of this section discusses global and local scope, and shared variables. The following skeleton of a program is used in this discussion. The program, a main program and two procedures, replaces runs of blanks in a file with tab charactersÄÄa simple first step in compressing a file. (The program is included on the QuickBASIC release disks in the file ENTAB.BAS.) DEFINT a-z DECLARE FUNCTION ThisIsATab(Column AS INTEGER) CONST MAXLINE=255, TABSPACE=8 CONST NO=0, YES=NOT NO DIM SHARED TabStops(MAXLINE) . . . ' Set the tab positions (uses the global array TabStops). CALL SetTabPos . . . IF ThisIsATab(CurrentColumn) THEN PRINT CHR$(9); LastColumn=CurrentColumn END IF . . . '==================SUB SetTabPos========================= ' Set the tab positions in the array TabStops. ' SUB SetTabPos STATIC FOR I=1 TO MAXLINE TabStops(I)=((I MOD TABSPACE)=1) NEXT I END SUB '===============FUNCTION ThisIsATab====================== ' Answer the question, "Is this a tab position?" ' FUNCTION ThisIsATab(LastColumn AS INTEGER) STATIC IF LastColumn>MAXLINE THEN ThisIsATab=YES ELSE ThisIsATab=TabStops(LastColumn) END IF END FUNCTION 2.4.1 Global Variables and Constants Both variables and symbolic constants can be global in BASIC programs. A global variable or global symbolic constant is defined for the entire module. For a variable, the only way to make it global is to declare it in the module-level code with the SHARED attribute in a DIM, REDIM, or COMMON statement. A symbolic constant is a global constant if it is declared in the module-level code using a CONST statement. In the sample program, the array TabStops is a global variable. Because TabStops is declared in a DIM statement with the SHARED attribute, it is shared with every procedure in the module. Notice that both procedures in the program (ThisIsATab and SetTabPos) use TabStops by making a reference to it. Global variables do not require any additional declarations to be used in procedures in the module. Similarly, the symbolic constants MAXLINE and TABSPACE are global constants. If you use the name of a global variable or constant in a procedure, you are referring to the global variable and not a local variable of the same name. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The SHARED statement allows procedures to share variables with the module-level code. This is not the same as making the variable global. See Section 2.4.3 below, "Sharing Variables," for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2.4.2 Local Variables and Constants A local variable or constant exists only within a procedure or the module-level code. If the name of a local variable is used in another procedure in a module, the name represents a different variable and refers to a different object. The sample program ENTAB.BAS above includes many local variables. The variables CurrentColumn and LastColumn are local to the module-level code. The variable I is local to the subprogram SetTabPos. Finally, the variable LastColumn in the parameter list of ThisIsATab can be thought of as a local variable because it is a formal parameter. (Remember, however, that a formal parameter stands for the actual argument passed to the procedure. See Section 4.3, "Passing by Reference and Passing by Value," for additional information.) It is simplest to think of a local variable as any variable that isn't global. Any variable that appears in module-level code or in a procedure is local if it isn't declared in a DIM, REDIM, or COMMON statement with the SHARED attribute. (There is one exception. See Section 2.4.3, "Sharing Variables," below.) Even if a variable appears in one of these statements, you may still use a local variable of the same name in a procedure by declaring the variable in a STATIC statement. If the sample program had a DIM SHARED statement declaring I to be a global variable in the main program, you could make I a local variable in SetTabPos by adding a STATIC statement just after the SUB statement: SUB SetTabPos STATIC STATIC I . . . Any symbolic constant declared inside a SUB or FUNCTION procedure is a local constant. For example, in the following fragment, ENDOFLIST is a local symbolic constant that exists only in the function FindElement: FUNCTION FindElement(X()) CONST ENDOFLIST = -32767 . . . END FUNCTION ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The STATIC statement not only declares a variable to be local: it also directs the compiler to save the value of the variable between procedure calls. Do not use STATIC statements in recursive procedures if you do not want a variable's value saved between calls. See Section 2.6, "Automatic and STATIC Variables," for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2.4.3 Sharing Variables You can share variables among parts of a module without making the variables global by using the SHARED statement. For example, to share TabStops without making it a global variable, you would remove the SHARED attribute in the module-level code and add SHARED statements to the two procedures: DIM TabStops(MAXLINE) . . . SUB SetTabPos STATIC SHARED TabStops() . . . FUNCTION ThisIsATab(LastColumn AS INTEGER) STATIC SHARED TabStops() . . . The SHARED statements indicate that the name TabStops in both procedures refers to the same variable defined at the module level. 2.4.4 DEF FN Functions The DEF FN function is an exception to the BASIC scope rules. Every variable in a DEF FN function that isn't in its parameter list is part of the module-level code. To make a variable local to a DEF FN, you must declare the variable in a STATIC statement. The STATIC statement in the following DEF FN function makes the variable I local: CONST NO = 0, YES = NOT NO DEF FNIsThereAZ (A$) STATIC I FOR I = 1 TO LEN(A$) IF UCASE$(MID$(A$, I, 1)) = "Z" THEN FNIsThereAZ = YES EXIT DEF END IF NEXT I FNIsThereAZ = NO END DEF Remember, as a general rule a FUNCTION is preferred over a DEF FN because of the improved portability and increased modularity the FUNCTION provides. 2.4.5 Summary of Scope Rules The following list summarizes BASIC's scope rules: ž A variable declared in a DIM, REDIM, or COMMON statement with the SHARED attribute is a global variable. Any SUB or FUNCTION procedure can refer to the variable. ž A symbolic constant is global if it is declared in a CONST statement in the module-level code. Symbolic constants declared in a SUB or FUNCTION are local. ž A variable is a local variable if it appears in a procedure and is not declared as a global variable. You can use the name of a global variable as a local variable in a procedure by declaring it in the procedure with the STATIC statement or by using it as a formal parameter. ž The SHARED statement lets you share a variable with the module-level code and other procedures with equivalent SHARED statements without making the variable a global variable. ž All variables in a DEF FN function are part of the module-level code unless they are either explicitly made local in a STATIC statement or are formal parameters. 2.5 Static and Dynamic Arrays You can get better control of your program's use of memory by controlling when storage is set aside for arrays. Storage for arrays can be set aside when the program is compiled or when the program is running. Arrays given storage when the program is compiled are static arrays. Dynamic arrays have storage set aside when the program is run. The storage taken by dynamic arrays can be eliminated while the program is not running in order to free memory for other uses. See the entries for DIM, ERASE, and REDIM in Part 2, "Statement and Function Reference," for specific information about manipulating dynamic arrays. How an array is declared can determine whether the array is static or dynamic. By default, arrays dimensioned with constant subscripts or arrays that are implicitly dimensioned are static arrays. Arrays dimensioned with variable subscripts or that are first declared in a COMMON statement are dynamic arrays. In a SUB or FUNCTION not declared static, all arrays are dynamic. You can also use the ›STATIC and ›DYNAMIC metacommands to control how array storage is allocated. However, the ›STATIC metacommand cannot force arays to be static in a procedure not declared static; in such a procedure all arrays are dynamic. See Appendix F, "Metacommands," in Programming in BASIC for more information. In some cases, you can allow more space for strings by replacing static arrays with dynamic arrays. In programs run as .EXE files, the space for static arrays is allocated from DGROUP, an area where strings are stored. On the other hand, dynamic arrays, other than variable-length string arrays, do not take any space in DGROUP; they are stored as far objects and require far addresses. 2.6 Automatic and Static Variables BASIC procedures can use both automatic and static variables. Automatic variables are initialized at the start of each call to the FUNCTION or SUB; static variables retain values between calls. You can control whether the default is automatic or static by using or omitting the STATIC keyword in the SUB or FUNCTION statement. If you omit STATIC, then the default for variables is automatic. When you use STATIC, the default for all variables in the procedure is static: the values of the variables are saved between procedure calls. You can make selected variables in a procedure static by making the default automatic (omitting STATIC from the SUB or FUNCTION statement) and using the STATIC statement. The following program uses a FUNCTION that has two static variables: Start% and SaveStr$. The other variables are automatic. The FUNCTION takes a string and returns one tokenÄÄa string of charactersÄÄuntil the end of the string is reached. On the first call, StrTok$ makes a local copy of the string Srce$ in the static variable SaveStr$. After the first call, StrTok$ returns additional tokens from the string using the static variable Start% to remember where it left off. All of the other variables (BegPos%, Ln%, etc.) are automatic. (This program is included on the QuickBASIC distribution disks under the file name TOKEN.BAS.) DECLARE FUNCTION StrTok$(Source$,Delimiters$) LINE INPUT "Enter string: ",P$ ' Set up the characters that separate tokens. Delimiters$=" ,;:().?"+CHR$(9)+CHR$(34) ' Invoke StrTok$ with the string to tokenize. Token$=StrTok$(P$,Delimiters$) WHILE Token$<>"" PRINT Token$ ' Call StrTok$ with a null string so it knows this ' isn't the first call. Token$=StrTok$("",Delimiters$) WEND FUNCTION StrTok$(Srce$,Delim$) STATIC Start%, SaveStr$ ' If first call, make a copy of the string. IF Srce$<>"" THEN Start%=1 : SaveStr$=Srce$ END IF BegPos%=Start% : Ln%=LEN(SaveStr$) ' Look for start of a token (character that isn't ' delimiter). WHILE(BegPos%<=Ln% AND INSTR(Delim$,MID$(SaveStr$,BegPos%,1))<>0) BegPos%=BegPos%+1 WEND ' Test for token start found. IF BegPos% > Ln% THEN StrTok$="" : EXIT FUNCTION END IF ' Find the end of the token. End%=BegPos% WHILE(End%<=Ln%AND INSTR(Delim$,MID$(SaveStr$,End%,1))=0) End%=End%+1 WEND StrTok$=MID$(SaveStr$,BegPos%,End%-BegPos%) ' Set starting point for search for next token. Start%=End% END FUNCTION Output Enter string: Allen spoke: "What's a hacker, anyway?" Allen spoke What's a hacker anyway 2.7 Type Conversion When necessary, BASIC converts a numeric constant from one type to another, according to the following rules: ž If a numeric constant of one type is set equal to a numeric variable of a different type, the numeric constant is stored as the type declared in the variable name, as in the following example: A% = 23.42 PRINT A% Output 23 If a string variable is set equal to a numeric value, or vice versa, an error message is generated that reads Type Mismatch. ž During expression evaluation, the operands in an arithmetic or relational operation are converted to the same degree of precision, that of the most precise operand, as each operation is performed. Also, the result of an arithmetic operation is returned to the final degree of precision, as in this example: X% = 2 : Y! = 1.5 : Z# = 100 A! = X% / Y! PRINT A! * Z# Output 133.3333373069763 Although the preceding result is displayed in double precision (because of the double-precision variable Z#), it has only single-precision accuracy because the assignment to A! forced the result of X% / Y! to be reduced to single-precision accuracy. This explains the nonsignificant digits (73069763) after the fifth decimal place. Contrast this with the output from the following example in which the intermediate result of X% / Y! is retained in double-precision: X% = 2 : Y# = 1.5 : Z# = 100 PRINT X% / Y# * Z# Output 133.3333333333333 ž Logical operators such as AND and NOT convert their operands to long integers if necessary. Operands must be in the range -2,147,483,648 to +2,147,483,647 or an Overflow error message is generated. See Chapter 3, "Expressions and Operators," for more information on logical operators. ž When a floating-point value is converted to an integer, the fractional portion is rounded, as in this example: Total% = 55.88 PRINT Total% Output 56 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Chapter 3 Expressions and Operators 3.1 Expressions and Operators Defined 3.2 Hierarchy of Operations 3.3 Arithmetic Operators 3.3.1 Integer Division 3.3.2 Modulo Arithmetic 3.3.3 Overflow and Division by Zero 3.4 Relational Operators 3.5 Logical Operators 3.6 Functional Operators 3.7 String Operators This chapter discusses how to combine, modify, compare, or get information about expressions by using the operators available in BASIC. Anytime you do a calculation or manipulate a string, you are using expressions and operators. This chapter describes how expressions are formed, discusses the order in which BASIC uses operators, and concludes by describing the following five kinds of operators: ž Arithmetic operators, used to perform calculations ž Relational operators, used to compare strings and numeric values ž Logical operators, used to test complex conditions or manipulate individual bits ž Functional operators, used to supplement simpler operators ž String operators, used to combine and compare strings 3.1 Expressions and Operators Defined An expression can be a string or numeric constant, a variable, or a single value obtained by combining constants, variables, and other expressions with operators. Operators perform mathematical or logical operations on values. The operators provided by BASIC can be divided into five categories, as follows: 1. Arithmetic 2. Relational 3. Logical 4. Functional 5. String 3.2 Hierarchy of Operations The BASIC operators have an order of precedence: when several operations take place within the same program statement, some operations are done before others. Operations are executed in the following order: 1. Arithmetic operations a. Exponentiation (^) b. Negation (-) c. Multiplication and division (*,/) d. Integer division (\) e. Modulo arithmetic (MOD) f. Addition and subtraction (+,-) 2. Relational operations (=, >, <, <>, <=, >=) 3. Logical operations a. NOT b. AND c. OR d. XOR e. EQV f. IMP An exception to the order of operations listed above occurs when an expression has adjacent exponentiation and negation operators. In this case, the negation is done first. For example, the following statement prints the value .0625 (equivalent to 4^-2), not -16 (equivalent to -(4^2)): PRINT 4 ^ - 2 If the operations are different and are of the same level, the leftmost one is executed first and the rightmost last, as explained below. A = 3 + 6 / 12 * 3 - 2 'A = 2.5 The order of operations in the preceding example is as follows: Operation Result ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 6 / 12 0.5 0.5 * 3 1.5 3 + 1.5 4.5 4.5 - 2 2.5 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ In a series of additions or a series of multiplications, there is no fixed evaluation order. Either 3 + 5 or 5 + 6 may be calculated first in the following statement: C = 3 + 5 + 6 Usually this does not cause problems. However, it may cause a problem if you have a series of FUNCTION procedure calls: C = Incr(X) + Decr(X) + F(X) If any of the three FUNCTION procedures modify X or change shared variables, the result depends on the order in which BASIC does the additions. You can avoid the situation by assigning the results of the FUNCTION calls to temporary variables and then performing the addition: T1 = Incr(X) : T2 = Decr(X) : T3 = F(X) C = T1 + T2 + T3 3.3 Arithmetic Operators Parentheses change the order in which arithmetic operations are performed. Operations within parentheses are performed first. Inside parentheses, the usual order of operation is maintained. Here are some sample algebraic expressions and their BASIC counterparts: Algebraic Expression BASIC Expression ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ X - Y ----- (X-Y)/Z Z XZ --- X*Y/Z Z X + Y ----- (X+Y)/Z Z (X<^>2)<^>Y (X^2)^Y X<^>YZ X^(Y*Z) X(-Y) X*(-Y) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ :BTGenerally, two consecutive operators must be separated by parentheses. Exceptions to this rule are * - , * +, ^ -, and ^ + . The last expression in the right-hand column above could also be written X*-Y. See the preceding section for information about the order in which arithmetic operations are performed. 3.3.1 Integer Division Integer division is denoted by the backslash (\) instead of the forward slash (/), which indicates floating-point division. Before integer division is performed, operands are rounded to integers or long integers, and thus must be greater than -2,147,483,648.5 and less than +2,147,483,647.5. The quotient of an integer division is truncated to an integer, as illustrated below: PRINT 10\4, 10/4, -32768.499\10, -32768.499/10 Output 2 2.5 -3276 -3276.8499 3.3.2 Modulo Arithmetic Modulo arithmetic is denoted by the modulus operator MOD. Modulo arithmetic provides the remainder, rather than the quotient, of an integer division, as in this example: X% = 10.4\4 REMAINDER% = INT(10.4) - 4*X% '10\4 = 2, with remainder 2 PRINT REMAINDER%, 10.4 MOD 4 Output 2 2 3.3.3 Overflow and Division by Zero Dividing by zero, raising zero to a negative power, and arithmetic overflow produce run-time errors. These errors can be trapped by an error-trapping routine. See Chapter 6, "Error and Event Trapping," in Programming in BASIC for more information about writing error-trapping routines. 3.4 Relational Operators Relational operators are used to compare two values, as shown in Table 3.1. The result of the comparison is either "true" (nonzero) or "false" (zero). This result can then be used to make a decision regarding program flow. Although BASIC treats any nonzero value as true, true is usually represented by -1. Table 3.1 Relational Operators and Their Functions Operator Relation Tested Expression ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ = Equality X = Y < > Inequality X < > Y < Less than X < Y > Greater than X > Y <= Less than or equal to X <= Y = Greater than or equal to X >= Y ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When arithmetic and relational operators are combined in one expression, the arithmetic operations are always done first. For example, the following expression is true if the value of X + Y is less than the value of (T - 1)/Z: X + Y < (T - 1)/Z Be careful using relational operators with single- and double-precision values. Calculations may give extremely close but not identical results. In particular, avoid testing for identity between two values. For example, the PRINT statement in the following IF statement is not executed unless A! is exactly equal to 0.0: IF A! = 0.0 THEN PRINT "Exact result." When A! is an extremely small value, for example 1.0E-23, the PRINT statement is not executed. In addition, a compiled program (an .EXE file) may give different results than the same program run in the QuickBASIC environment. Files with the .EXE extension23 contain more efficient code that may change the way single- and double-precision values are compared. For example, the following fragment prints Equal when run in the environment, but prints Not Equal when compiled: B!=1.0 A!=B!/3.0 IF A!=B!/3.0 THEN PRINT "Equal" ELSE PRINT "Not Equal" Because the .EXE file version makes more extensive use of a math coprocessor chip (or coprocessor emulation), A! and B!/3.0 are slightly different values. You can avoid problems in comparisons by performing calculations outside comparisons. The following rewritten fragment produces the same results in the environment and as an .EXE file: B!=1.0 A!=B!/3.0 Tmp!=B!/3.0 IF A!=Tmp! THEN PRINT "Equal" ELSE PRINT "Not Equal" 3.5 Logical Operators Logical operators perform tests on multiple relations, bit manipulations, or Boolean operations and return a true (nonzero) or false (zero) value to be used in making a decision. ž Examples IF D < 200 AND F < 4 THEN 80 WHILE I > 10 OR K < 0 . . . WEND IF NOT P THEN PRINT "Name not found" There are six logical operators in BASIC; they are listed in Table 3.2 in order of precedence: Table 3.2 BASIC Logical Operators Operator Meaning ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOT Logical complement AND Conjunction OR Disjunction (inclusive "or") XOR Exclusive "or" EQV Equivalence IMP Implication ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Each operator returns results as indicated in Table 3.3. A "T" indicates a true value and an "F" indicates a false value. Operators are listed in order of operator precedence. Table 3.3 Values Returned by Logical Operations Values of Value Returned by Logical Operator X X X X X NOT AND OR XOR EQV IMP X Y X Y Y Y Y Y ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ T T F T T F T T T F F F T T F F F T T F T T F T F F T F F F T T ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ In an expression, logical operations (also known as Boolean operations) are performed after arithmetic and relational operations. The operands of logical operators must be in the range -2,147,483,648 to +2,147,483,647. Operands are converted to integers (or, if necessary, long integers) before the logical operation is done. (If the operands are not in this range, an error results.) If the operands are either 0 or -1, logical operators return 0 or -1 as the result, as in the following example. (Note the similarity of the output from this program to Table 3.3: "T" becomes -1 and "F" becomes 0.) ž Example PRINT " X Y NOT AND OR "; PRINT "XOR EQV IMP" PRINT I = 10 : J = 15 X = (I = 10) : Y = (J = 15) 'X is true (-1); Y is true (-1) CALL TruthTable (X,Y) X = (I > 9) : Y = (J > 15) 'X is true (-1); Y is false (0) CALL TruthTable (X,Y) X = (I <> 10) : Y = (J < 16) 'X is false (0); Y is true (-1) CALL TruthTable (X,Y) X = (I < 10) : Y = (J < 15) 'X is false (0); Y is false (0) CALL TruthTable (X,Y) END SUB TruthTable(X,Y) STATIC PRINT X " " Y " ";NOT X " " X AND Y " " X OR Y; PRINT " " X XOR Y " " X EQV Y " " X IMP Y PRINT END SUB Output X Y NOT AND OR XOR EQV IMP -1 -1 0 -1 -1 0 -1 -1 -1 0 0 0 -1 -1 0 0 0 -1 -1 0 -1 -1 0 -1 0 0 -1 0 0 0 -1 -1 Logical operators compare each bit of the first operand with the corresponding bit in the second operand to compute the bit in the result; in these "bit-wise" comparisons, a 0 bit is equivalent to a "false" value (F) in Table 3.3, while a 1 bit is equivalent to a "true" value (T). It is possible to use logical operators to test bytes for a particular bit pattern. For example, the AND operator can be used to mask all but one of the bits of a status byte, while the OR operator can be used to merge two bytes to create a particular binary value. ž Example PRINT 63 AND 16 PRINT -1 AND 8 PRINT 10 OR 9 PRINT 10 XOR 10, 'Always 0 PRINT NOT 10, NOT 11, NOT 0 'NOT X = -(X + 1) Output 16 8 11 0 -11 -12 -1 The first PRINT statement uses AND to combine 63 (111111 binary) and 16 (10000). When BASIC calculates the result of an AND, it combines the numbers bit by bit, producing a one only when both bits are one. Because the only bit that is a one in both numbers is the fifth bit, only the fifth bit in the result is a one. The result is 16, or 10000 in binary. In the second PRINT statement, the numbers -1 (binary 1111111111111111) and 8 (binary 1000) are combined using another AND operation. The only bit that is a one in both numbers is the fourth bit, so the result is 8 decimal or 1000 binary. The third PRINT statement uses an OR to combine 10 (binary 1010) and 9 (binary 1001). An OR produces a one bit whenever either bit is a one, so the result of the OR in the third PRINT is 11 (binary 1011). The XOR in the fourth PRINT combines the number 10 (1010 binary) with itself. The result is a zero because an XOR produces a one only when either, but not both, bits are one. Performing a NOT on a number changes all one bits to zeros and all zero bits to ones. Because of the way two's complement numbers work, taking the NOT of a value is the same as adding one to the number and then negating the number. In the final PRINT statement, the expression NOT 10 yields a result of -11. 3.6 Functional Operators A function is used in an expression to call a predetermined operation to be performed on an operand. For example, SQR is a functional operator used twice in the following assignment statement: A = SQR (20.25) + SQR (37) BASIC incorporates two kinds of functions: intrinsic and user-defined. Many predefined (intrinsic) functions are built into the language. Examples are the SQR (square root) and SIN (sine) functions. You may define your own functions with the FUNCTION...END FUNCTION construction and the older, obsolete DEF FN...END DEF construction. Such functions are defined only for the life of the program (unless they are in a Quick library) and are not part of the BASIC language. In addition to FUNCTION and DEF FN, BASIC allows you to define subprograms with SUB. For more information on defining your own functions and subprograms, see the appropriate entries in Chapter 4, "Programs and Modules," and Part 2, "Statement and Function Reference," in this manual, as well as Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC. 3.7 String Operators A string expression consists of string constants, string variables, and other string expressions combined by string operators. There are two classes of string operations: concatenation and string function. The act of combining two strings is called concatenation. The plus symbol (+) is the concatenation operator for strings. For example, the following program fragment combines the string variables A$ and B$ to produce the output shown: A$ = "FILE": B$ = "NAME" PRINT A$ + B$ PRINT "NEW " + A$ + B$ Output FILENAME NEW FILENAME Strings can be compared using the following relational operators (see Table 3.1): < > = < > <= >= Note that these are the same relational operators used with numbers. String comparisons are made by taking corresponding characters from each string and comparing their ASCII codes. If the ASCII codes are the same for all the characters in both strings, the strings are equal. If the ASCII codes differ, the lower code number precedes the higher. If the end of one string is reached during string comparison, the shorter string is smaller if they are equal up to that point. Leading and trailing blanks are significant. The following are examples of true string expressions: "AA" < "AB" "FILENAME" = "FILE"+"NAME" "X&" > "X#" "CL " > "CL" "kg" > "KG" "SMYTH" < "SMYTHE" B$ < "9/12/78" 'where B$ = "8/12/85" String comparisons can be used to test string values or to alphabetize strings. All string constants used in comparison expressions must be enclosed in quotation marks. See Appendix A, "Keyboard Scan Codes and ASCII Character Codes," for more information about the ASCII codes. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Chapter 4 Programs and Modules 4.1 Modules 4.2 Procedures 4.2.1 FUNCTION Procedures 4.2.2 SUB Procedures 4.2.3 DEF FN Functions 4.3 Passing by Reference and Passing by Value 4.4 Recursion This chapter discusses the largest parts of a programÄÄmodules and procedures. The chapter describes how modules are organized and how BASIC procedures communicate with other parts of a program. Specifically, the chapter explains how to ž Organize modules ž Understand different kinds of QuickBASIC procedures ž Pass arguments to a procedure ž Write recursive code 4.1 Modules BASIC programs consist of one or more modules. A module is a source file that can be separately compiled. Declarations, executable statementsÄÄany BASIC statementÄÄcan appear in a module. A module may contain SUB and FUNCTION procedures, as well as code not directly part of a SUB or FUNCTION. Statements that are not part of a SUB or FUNCTION are called module-level code. Module-level code includes declarative statements like DIM and TYPE as well as error- and event-handling code. A program has one special module, the main module. The main module contains the entry point of the program (the place where the program starts running). Each program contains only one main module; module-level code it contains corresponds to what is often called the main program. 4.2 Procedures This section discusses the two newer QuickBASIC procedures: FUNCTION procedures and SUB procedures. It also covers the older DEF FN function and compares it with the newer procedures. See Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC for examples and information about when to use different kinds of procedures. 4.2.1 FUNCTION Procedures FUNCTION procedures provide a powerful alternative to DEF FN functions. Like DEF FN functions, FUNCTION procedures are used in expressions and directly return a single value. There are, however, important differences. FUNCTION procedures pass values by reference, so a FUNCTION procedure can return additional values by changing variables in its argument list. In addition, FUNCTION procedures can be used recursivelyÄÄa function can call itself (see Section 4.4 below for more information). Unlike DEF FN functions, a FUNCTION procedure may be used outside the module in which it is defined. You must include a DECLARE statement if you use a FUNCTION defined in another module. QuickBASIC automatically generates DECLARE statements for FUNCTION procedures defined and used in the same module. You can also enter the DECLARE yourself: DECLARE FUNCTION Log10(X) INPUT "Enter a number: ",Num PRINT "10 ^ Log10(";Num;") is" 10.0^Log10(Num) END ' Function to find log base 10 of a number using ' BASIC's built-in natural logarithm function. FUNCTION Log10 (X) STATIC Log10=LOG(X)/LOG(10.0) END FUNCTION FUNCTION procedures also differ from DEF FN functions in that they are not part of the module-level code. 4.2.2 SUB Procedures Unlike DEF FN functions and FUNCTION procedures, SUB is invoked as a separate statement: ' Print a message in the middle of the screen. CLS CALL PrntMsg(12,40,"Hello!") END ' Print message at the designated row and column. SUB PrntMsg(Row%,Col%,Message$) STATIC ' Save current cursor position. CurRow%=CSRLIN CurCol%=POS(0) ' Print the message at the location. LOCATE Row%,Col% : PRINT Message$; ' Restore cursor location. LOCATE CurRow%,CurCol% END SUB SUB procedures can be used to return multiple values to a calling routine and are not invoked as part of an expression. All SUB arguments are passed by reference. This allows SUB procedures to return values by changing variables in the argument listÄÄthe only way a SUB can return a value. You can invoke SUB procedures without using the CALL keyword if the SUB is declared: DECLARE SUB PrntMsg (Row%,Col%,Msg$) ' Print a message in the middle of the screen. CLS PrntMsg 12,40,"Hello!" 'Note the missing parentheses. END . . . SUB procedures can be used recursivelyÄÄthat is, you can write a SUB procedure that calls itself. 4.2.3 DEF FN Functions DEF FN functions are always part of a program's module-level code. For this reason, their use is more limited than that of SUB or FUNCTION procedures. Like FUNCTION procedures, DEF FN functions return single values and are used like built-in BASIC functions: ' Function to find log base 10 of a number using ' BASIC's built-in natural logarithm function. DEF FNLog10 (X) FNLog10=LOG(X)/LOG(10.0) END DEF INPUT "Enter a number: ",Num PRINT "10 ^ Log10(";Num;") is" 10.0^FNLog10(Num) END DEF FN function arguments are passed by value (see Section 4.3 below for more information). The name of a DEF FN function always begins with FN. In addition, DEF FN functions cannot be used recursively and must be defined before they are used. DEF FN functions cannot be called from outside the module in which they are defined. 4.3 Passing by Reference and Passing by Value BASIC uses two different ways of passing arguments to a procedure. The phrase "passing by reference," used with SUB and FUNCTION procedures, means the address of each argument is passed to the procedure by placing the address on the stack. The phrase "passing by value," used in DEF FN functions, indicates that the value of the argument is placed on the stack, rather than the address. Because the procedure does not have access to the variable when an argument is passed by value, the procedure cannot change the variable's value. Sometimes passing an argument by value to a SUB or FUNCTION is more convenient. You can simulate a pass by value by using an expression in the SUB call or FUNCTION invocation: Xcoordinate=Transform((A#)) Because(A#) is an expression, BASIC calculates its value, A#, and passes the address of a temporary location containing the value. An address is still passed, but because it is the address of a temporary location, the action simulates a pass by value. 4.4 Recursion QuickBASIC lets you write recursive SUB or FUNCTION procedures (procedures that call themselves). For example, the following program uses a recursive FUNCTION to reverse a string of characters: DECLARE FUNCTION Reverse$ (StringVar$) LINE INPUT "Enter string to reverse: ", X$ PRINT Reverse$(X$) END FUNCTION Reverse$ (S$) C$ = MID$(S$, 1, 1) IF C$ = "" THEN ' The first character is null, so return ' null--there's no more string left. Reverse$ = "" ELSE ' The reverse of a nonnull string is the first ' character appended to the reverse of the remaining ' string. Reverse$ = Reverse$(MID$(S$, 2)) + C$ END IF END FUNCTION Output Enter string to reverse: abcdefgh...tuvwxyz zyxwvut...hgfedcba Reverse$ reverses a string by first testing for the simplest caseÄÄa null string. If the string is null, then a null string is returned. If the string is not nullÄÄthere are charactersÄÄthen Reverse$ simplifies the problem. The reverse of a non-null string is the rest of the string (C$) with the first character of the string concatenated to it. So Reverse$ calls itself to reverse the rest of the string and when this is done concatenates the first character to the reversed string. Recursion can use a lot of memory because automatic variables inside the FUNCTION or SUB must be saved in order to restart the procedure when the recursive call is finished. Because automatic variables are saved on the stack, you may need to increase the stack size with the CLEAR statement to keep from running out of stack space. Use the FRE function to determine by how many bytes you need to adjust the stack size. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PART 2 STATEMENT AND FUNCTION REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Part 2 is a dictionary of BASIC statements and functions. Each entry includes information on the statement's action or effect and its syntax. The statement's arguments, options, and typical usage are explained further under "Remarks." The "See Also" sections refer you to related statements. Differences from BASICA are included where appropriate. Finally, a sample program (or a reference to one) is included for each QuickBASIC statement or function so you can see exactly how it works. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ABS Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the absolute value of a numeric expression ž Syntax ABS(numeric-expression) ž Remarks The absolute value function returns the unsigned magnitude of its argument. For example, ABS(-1) and ABS(1) are both 1. ž Example The following example finds an approximate value for a cube root. It uses ABS to find the difference between two guesses to see if the current guess is accurate enough. DEFDBL A-Z FUNCTION CubeRoot(Value,Precision) STATIC ' Make the first two guesses. X1=0.0# : X2=Value ' Go until the difference between two guesses is ' less than the required precision. DO UNTIL ABS(X1-X2) < Precision X=(X1+X2)/2.0# ' Adjust the guesses. IF X*X*X-Value < 0.0# THEN X1=X ELSE X2=X END IF LOOP CubeRoot=X END FUNCTION INPUT "Enter a value: ",X PRINT "The cube root is ";CubeRoot(X,.0000001#) ž Output Enter a value: 27 The cube root is 2.999999972060323 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ASC Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a numeric value that is the ASCII code for the first character in a string expression ž Syntax ASC(stringexpression) ž Remarks If stringexpression is null, ASC produces a run-time error message (Illegal function call). ž See Also CHR$; Appendix A, "Keyboard Scan Codes and ASCII Character Codes" ž Example The following example uses ASC to calculate a hash valueÄÄan index value for a table or fileÄÄfrom a string: CONST HASHTABSIZE=101 FUNCTION HashValue(S$,Size) STATIC TmpVal=0 FOR I=1 TO LEN(S$) ' Convert the string to a number by summing the values ' of individual letters. TmpVal=TmpVal+ASC(MID$(S$,I,1)) NEXT I ' Divide the sum by the size of the table. HashValue=TmpVal MOD Size END FUNCTION INPUT "Enter a name: ",Nm$ PRINT "The hash value is ";HashValue(Nm$,HASHTABSIZE) ž Output Enter a name: Bafflegab The hash value is 66 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ATN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the arctangent of a numeric expression (the angle whose tangent is equal to the numeric expression) ž Syntax ATN(numeric-expression) ž Remarks The numeric-expression can be of any numeric type. The result is given in radians and is in the range -ć/2 to ć/2 radians, where ć=3.141593. ATN is evaluated by default in single precision unless numeric-expression is a double-precision value. Then ATN is evaluated in double precision. ž Example The following example first finds the tangent of ć/4 and then takes the arctangent of the value. The result is ć/4. CONST PI=3.141592653 PRINT ATN(TAN(PI/4.0)), PI/4.0 ž Output .78539816325 .78539816325 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BEEP Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sounds the speaker ž Syntax BEEP ž Remarks The BEEP statement makes a sound through the loudspeaker. This statement makes the same sound as the following statement: PRINT CHR$(7) ž Example The following example uses BEEP to indicate an error in the response: DO INPUT "Continue (Y or N)";Response$ R$=UCASE$ (MID$ (Response$,1,1)) IF R$="Y" OR R$="N" THEN EXIT DO BEEP LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BLOAD Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Loads a memory-image file, created by BSAVE, into memory from an input file or device ž Syntax BLOAD filespec ®,offsetÆ ž Remarks The BLOAD statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filespec A string expression containing the file specification. Input devices other than the keyboard (KYBD:) are supported. offset The offset of the address where loading is to start. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The BLOAD statement allows a program or data saved as a memory-image file to be loaded anywhere in memory. A memory-image file is a byte-for-byte copy of what was originally in memory. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Programs written in earlier versions of BASIC no longer work if they use VARPTR to access numeric arrays. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The starting address for loading is determined by the specified offset and the most recent DEF SEG statement. If offset is omitted, the segment address and offset contained in the file (the address used in the BSAVE statement) are used. Thus, the file is loaded at the address used when saving the file. If you supply an offset, the segment address used is the segment set by the most recently executed DEF SEG statement. If there has been no DEF SEG statement, the BASIC data segment (DS) is used as the default. If the offset is a single-precision or double-precision number it is coerced to an integer. If the offset is a negative number in the range -1 to -32,768, it is treated as an unsigned 2-byte offset. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Because BLOAD does not perform an address-range check, it is possible to load a file anywhere in memory. You must be careful not to write over BASIC or the operating system. Since different screen modes use memory differently, do not load graphic images in a screen mode other than the one used when they were created. Also, because BASIC program code and data items are not always stored in the same locations as they were in BASICA, do not use BLOAD with files created by BASICA programs. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica BLOAD does not support the cassette device. ž See Also BSAVE, DEF SEG, VARPTR, VARSEG ž Example This example uses BLOAD to retrieve a drawing saved in a disk file using BSAVE. See the example for BSAVE to see how the drawing was saved. DIM Cube(1 TO 675) ' Set the screen mode--the mode should be the same as the ' mode used to create the original drawing. SCREEN 1 ' Load the drawing into the array Cube. DEF SEG=VARSEG(Cube(1)) ' Get the array's segment. BLOAD "magcube.grh",VARPTR(Cube(1)) DEF SEG ' Restore the default segment. ' Put the drawing on the screen. PUT (80,10),Cube ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BSAVE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transfers the contents of an area of memory to an output file or device ž Syntax BSAVE filespec,offset,length ž Remarks The BSAVE statement has the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filespec A string expression containing the file or device name. Output devices other than the console (SCRN: and CONS:) are supported. offset The offset of the starting address of the area in memory to be saved. length The number of bytes to save. This is a numeric expression returning an unsigned integer in the range 0-65,535. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The BSAVE statement allows data or programs to be saved as memory-image files on disk. A memory-image file is a byte-for-byte copy of what is in memory along with control information used by BLOAD to load the file. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Programs written in earlier versions of BASIC no longer work if they use VARPTR to access numeric arrays. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The starting address of the area saved is determined by the offset and the most recent DEF SEG statement. If no DEF SEG statement is executed before the BSAVE statement, the program uses the default BASIC data segment (DS). Otherwise, BSAVE begins saving at the address specified by the offset and by the segment set in the most recent DEF SEG statement. If the offset is a single- or double-precision floating-point value, it is coerced to an integer. If the offset is a negative number in the range -1 to -32,768, it is treated as an unsigned 2- byte offset. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Because different screen modes use memory differently, do not load graphic images in a screen mode other than the one used when the images were created. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica BSAVE does not support the cassette device. ž See Also BLOAD ž Example This example draws a graphic and then saves it as a memory-image file. See the example for the BLOAD statement to see how the file would be retrieved. ' This program draws on the screen, stores the drawing in an ' array, and then saves the drawing in a disk file using BSAVE. ' DIM Cube(1 TO 675) SCREEN 1 ' Draw a white box. LINE (140,25)-(140+100,125),3,b ' Draw the outline of a magenta cube inside the box. DRAW "C2 BM140,50 M+50,-25 M+50,25 M-50,25" DRAW "M-50,-25 M+0,50 M+50,25 M+50,-25 M+0,-50 BM190,75 M+0,50" ' Save the drawing in the array Cube. GET (140,25)-(240,125),Cube ' Store the drawing in a disk file. Note: 2700 is the number ' of bytes in Cube (4 bytes per array element * 675). DEF SEG=VARSEG(Cube(1)) ' Set segment to array's segment. BSAVE "magcube.grh",VARPTR(Cube(1)),2700 DEF SEG ' Restore BASIC segment. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALL Statement (BASIC Procedures) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transfers control to a BASIC SUB ž Syntax 1 CALL name®( argumentlist )Æ ž Syntax 2 name® argumentlist Æ ž Remarks The CALL statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ name The name, limited to 40 characters, of the BASIC SUB being called. The name must appear in a SUB statement if the SUB is in the same module. argumentlist The variables or constants passed to the subprogram. Arguments in the list are separated by commas. Arguments passed by reference can be changed by the subprogram. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If the argumentlist includes an array argument, the array is specified by the array name followed by empty parentheses: DIM IntArray(1 TO 20) . . . CALL ShellSort(IntArray()) When you use the CALL statement, the CALL keyword is optional. However, if you omit the CALL keyword, you must declare the procedure in a DECLARE statement. Notice also that when you omit the CALL keyword, you also omit the parentheses around the argument list. See Chapter 2 , "SUB and FUNCTION Procedures," in Programming in BASIC for more information. Arguments are passed by reference: the subprogram is given the address of the argument. This allows subprograms to change the argument values. BASIC can also pass arguments by value. The following statement calls a subprogram and passes a single argument by value: CALL SolvePuzzle((StartValue)) Because StartValue is in parentheses, BASIC evaluates it as an expression. The result is stored in a temporary location, and the address of the temporary location is passed to the SUB. Any change made by the subprogram SolvePuzzle is made only to the temporary location and not to the variable. ž See Also CALL, CALLS (Non BASIC); CALL ABSOLUTE; DECLARE (BASIC) ž Example The program below copies a series of files into a new file, the last file in the series entered from the command line. In the program, the BASIC subprogram PRINTOUT is called after first splitting the command line into separate file names and storing them in the array FILE$. The PRINTOUT subprogram copies the contents of the files to the final file in the list and to the standard output device (default is to your screen). DEFINT A-Z CONST MAXFILES=5, ARRAYDIM=MAXFILES+1 DIM File$(1 TO ARRAYDIM) ' Separate command line into arguments. CALL Comline (Numargs,File$(),ARRAYDIM) ' Test for too many or too few files. IF Numargs < 3 OR Numargs >MAXFILES THEN ' Too many or too few files. PRINT "Use more than 3 and fewer than";MAXFILES;"files" ELSE ' Send all files to Printout. CALL Printout(File$(),Numargs) END IF END ' See the example under COMMAND$ for the definition of ' Comline. Comline would appear here. SUB Printout(F$(1),N) STATIC ' Open target file. OPEN F$(N) FOR OUTPUT AS #3 ' Loop executes once for each file. ' Copy the first N-1 files onto the Nth file. FOR File = 1 TO N-1 OPEN F$(File) FOR INPUT AS #1 DO WHILE NOT EOF(1) 'Read file. LINE INPUT #1, Temp$ 'Write data to target file. PRINT #3, Temp$ PRINT Temp$ 'Write file to standard LOOP 'output. CLOSE #1 NEXT CLOSE END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALL, CALLS Statement (Non-BASIC Procedures) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transfers control to a procedure written in another language ž Syntax 1 CALL name ®(call-argumentlist)Æ ž Syntax 2 name ®call-argumentlistÆ ž Syntax 3 CALLS name ®(calls-argumentlist)Æ ž Remarks The following list describes the parts of the CALL statement: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ name The name of the procedure being called. A name is limited to 40 characters. call-argumentlist The variables or constants passed to the procedure. The syntax of a call-argumentlist is described below. calls-argumentlist A list containing the variables and constants that CALLS passes to the procedure. Entries are separated by commas. Note that these arguments are passed by reference as far addresses, using the segment and offset of the variable. You cannot use BYVAL or SEG in a calls-argumentlist. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A call-argumentlist has the following syntax: ®®{BYVAL|SEG}ÆargumentÆ®,®{BYVAL|SEG}ÆargumentÆ... If argument is an array, parentheses are required: ®®{BYVAL|SEG}Æargument®()ÆÆ®,®{BYVAL|SEG}ÆargumentÆ... Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BYVAL Indicates the argument is passed by value, rather than by near reference (the default) SEG Passes the argument as a segmented (far) address argument A BASIC variable, array, or constant passed to the procedure ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALLS is the same as using CALL with a SEG before each argument: every argument in a CALLS statement is passed as a segmented address. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The syntax described above does not correctly invoke a BASIC procedureÄÄonly procedures in other languages. See also the separate entry for CALL (BASIC). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If the argument list of either statement includes an array argument, the array is specified by the array name and a pair of parentheses: DIM IntArray(20) AS INTEGER . . . CALL ShellSort(IntArray() AS INTEGER) When you use the CALL statement, the CALL keyword is optional. However, when you omit CALL, you must declare the procedure in a DECLARE statement. Notice also that when you omit CALL, you also omit the parentheses around the argument list. See Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC for more information about invoking procedures without the CALL keyword. The result of the BYVAL keyword differs from BASIC's pass by value: CALL Difference (BYVAL A,(B)) For the first argument, only the value of A is passed to Difference. In contrast, (B) is evaluated, a temporary location is created for the value, and the address of the temporary location is passed to Difference. You can use BASIC's pass by value for an argument, but you must write the procedure in the other language so the procedure accepts an address. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE If name refers to an assembly-language procedure, it must be a PUBLIC name (symbol). PUBLIC names beginning with "$" and "_" may conflict with names used by the BASIC run-time system. Duplicate names cause a linker error message (symbol already defined) to be generated. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Be careful using the SEG keyword to pass arrays because BASIC may move variables in memory before the called routine begins execution. Anything in an argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables, arithmetic expressions, or arrays indexed without the use of intrinsic or user-defined functions. See Section 2.3.3, "Variable Storage Allocation," for a list of things that cause variable movement and for information about when to use near or far addresses for variables. ž Differences From Basica Assembly-language programs invoked from BASICA that have string arguments must be changed because the string descriptor is now four bytes long. The four bytes are the low byte and high byte of the length followed by the low byte and high byte of the address. To locate the routine being called, the BASICA CALLS statement uses the segment address defined by the most recently executed DEF SEG statement. There is no need to use DEF SEG with the CALLS statement because all arguments are passed as far (segmented) addresses. ž See Also CALL (BASIC); DECLARE (BASIC); DECLARE (Non-BASIC) ž Example See the example for VARPTR. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALL ABSOLUTE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transfers control to a machine-language procedure ž Syntax CALL ABSOLUTE (®argumentlist,Æintegervariable) ž Remarks The CALL ABSOLUTE statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ argumentlist Optional arguments passed to a machine-language procedure. integervariable An integer variable containing a value that is the offset from the beginning of the current code segment, set by DEF SEG, to the starting location of the procedure. The integervariable argument is not passed to the procedure. Your program may need to execute a DEF SEG statement before executing CALL ABSOLUTE to set the code segment for the called routine. Using a noninteger value for integervariable produces unpredictable results. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Arguments in argumentlist are passed to the machine-language program as offsets (near pointers) from the current data segment. Although arguments are passed as offsets, the machine-language program is invoked with a far call. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The CALL ABSOLUTE statement is provided to maintain compatibility with earlier versions of BASIC. Mixed-language programming using the CALL statement extensions and the new DECLARE statement provide a simpler way to use assembly language with BASIC. In order to use CALL ABSOLUTE you must start QuickBASIC with the correct Quick library, link your program with QB.LIB, or use the QB.QLB Quick library. See the disk-contents list for the locations of these files. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica Assembly-language programs that are invoked from BASICA and that have string arguments must be changed because string descriptors are now four bytes long. The four bytes are the low byte and high byte of the string length followed by the low byte and high byte of the string address. ž See Also CALL, CALLS (Non-BASIC) ž Example The following example uses CALL ABSOLUTE to execute a machine-language program stored in an array: CONST nASMBYTES=14 ' This program prints a message indicating whether or not ' a math coprocessor is installed. ' It uses a machine-language program stored in an array ' to get the information from the operating system. 'AsmBytes is a label; nASMBYTES is a symbolic constant. DEFINT A-Z DIM AsmProg(1 TO (nASMBYTES/2)) ' The machine-language program stored as data to read into ' the array. DATA &H55 :'PUSH BP Save base pointer. DATA &H8B, &HEC :'MOV BP,SP Get our own. DATA &HCD, &H11 :'INT 11H Make the ROM-BIOS call. DATA &H8B, &H5E, &H06 :'MOV BX,[BP+6] Get argument address. DATA &H89, &H07 :'MOV [BX],AX Save list in argument. DATA &H5D :'POP BP Restore base pointer. DATA &HCA, &H02, &H00 :'RET 2 Pop argument off stack ' and make far return. ' Get the starting offset of the array. P=VARPTR(AsmProg(1)) ' Poke the machine-language program into the array. DEF SEG=VARSEG(AsmProg(1)) ' Change the segment. Restore AsmBytes FOR I=0 TO nASMBYTES-1 READ J POKE(P+I),J NEXT I ' Execute the program. The program expects a single integer ' argument. CALL ABSOLUTE(X%,VARPTR(AsmProg(1))) DEF SEG ' Restore the segment. ' X% now contains bit-encoded equipment list returned by DOS. ' Mask off all but the coprocessor bit (bit 2). CoProcessor=X% AND &H2 ' Print the appropriate message. IF CoProcessor=2 THEN PRINT "Math coprocessor present." ELSE PRINT "No math coprocessor." END IF END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALL INT86OLD Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows programs to perform DOS system calls ž Syntax CALL INT86OLD (int_no,in_array(),out_array()) CALL INT86XOLD (int_no,in_array(),out_array()) ž 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 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ int_no The DOS interrupt to perform. It is an integer between 0 and 255. See your DOS documentation for the interrupt numbers. in_array() 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. out_array() Contains the postinterrupt register values. It has the same structure as in_array. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If an error occurs, int_no = -1 and values in out_array are unchanged. Errors are caused by int_no not being in the range 0-255. Table R.1 INT86OLD and INT86XOLD Register Values Array Element Register ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ in_array(x) AX in_array(x+1) BX in_array(x+2) CX in_array(x+3) DX in_array(x+4) BP in_array(x+5) SI in_array(x+6) DI in_array(x+7) FLAGS in_array(x+8) DS in_array(x+9) ES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The INT86OLD and INT86XOLD routines alter all registers except BP and DS. INT86OLD and INT86XOLD provide compatibility with older programs using INT86 and INT86X. Like the INT86 and INT86X routines, INT86OLD and INT86XOLD are distributed in a Quick library (QB.QLB) and in a conventional library (QB.LIB) on the distribution disks. The disks also contain a header file (QB.BI) 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 The following example uses INT86OLD to open a file and place some text in it: ' 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. INARY%(DX) = SADD("FOO.TXT"+CHR$(0)) '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. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CALL INTERRUPT Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows BASIC programs to perform DOS system calls ž Syntax CALL INTERRUPT (interruptnum,inregs,outregs) CALL INTERRUPTX (interruptnum,inregs,outregs) ž Remarks The following list describes the arguments for the CALL INTERRUPT and CALL INTERRUPTX statements: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ interruptnum The DOS interrupt number. It is an integer between 0 and 255. See your DOS documentation for information about interrupts. inregs The inregs variable contains the register values used when the interrupt is performed. It is declared as type RegType. The user-defined type RegType is described below. outregs The outregs variable contains the register values after the interrupt is performed. It is declared as type RegType. The user-defined type RegType is described below. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The CALL INTERRUPT and CALL INTERRUPTX statements replace the INT86 and INT86X routines used in earlier versions of BASIC. They provide a more convenient way for BASIC programs to use DOS interrupts and services. The register values before and after the interrupt are passed in variables declared as type RegType. The following statement defines the RegType user-defined type: TYPE RegType AX AS INTEGER BX AS INTEGER CX AS INTEGER DX AS INTEGER BP AS INTEGER SI AS INTEGER DI AS INTEGER FLAGS AS INTEGER DS AS INTEGER ES AS INTEGER END TYPE Each element of the type corresponds to a CPU register. INTERRUPTX uses the values in the DS and ES registers. To use the current values of these registers, set the record elements to -1. CALL INTERRUPT and CALL INTERRUPTX are available in a Quick Library (QB.QLB) and in a conventional library (QB.LIB) on your distribution disks. There is also a header file (QB.BI) on the disks with the necessary declarations for using these procedures. See the disk-contents list for specific information. To use CALL INTERRUPT or CALL INTERRUPTX when running a program within the QuickBASIC environment, the Quick library QB.QLB must be loaded with QuickBASIC. ž Example The following program uses CALL INTERRUPT to change a file's attribute list so the file does not appear when you use the DIR command from DOS: DECLARE SUB TestError (AXReg%, flags%) ' ›INCLUDE: 'QB.BI' DEFINT A-Z DIM InRegs AS RegType, OutRegs AS RegType ' Get the file name and action to perform. CLS PRINT "Hidden File Program": PRINT INPUT "Enter file name: ", FileName$ DO INPUT "Hide or unhide (H or U): ", Action$ Action$ = UCASE$(Action$) LOOP WHILE Action$ <> "H" AND Action$ <> "U" ' Tack a null (zero) byte onto the end of the string for the ' DOS function. FileName$ = FileName$ + CHR$(0) ' Get the current file attribute. ' Current attribute comes back in OutRegs.AX. InRegs.ax = &H4300 InRegs.dx = SADD(FileName$) CALL INTERRUPT(&H21, InRegs, OutRegs) CALL TestError(OutRegs.ax, OutRegs.flags) ' Change the hidden attribute bit in the old attribute value. IF Action$ = "U" THEN InRegs.cx = OutRegs.cx AND &HFD ELSE InRegs.cx = OutRegs.cx OR &H2 END IF ' Set AX to indicate the Change Attribute DOS function. InRegs.ax = &H4301 CALL INTERRUPT(&H21, InRegs, OutRegs) CALL TestError(OutRegs.ax, OutRegs.flags) END ' If carry flag set, print error message and end program. SUB TestError (AXReg, flags) STATIC IF (&H1 AND flags) <> 0 THEN ' Get the error number out of AX. SELECT CASE AXReg AND &HF CASE 2 PRINT "File not found." CASE 3 PRINT "Path not found." CASE 5 PRINT "Access denied." CASE ELSE PRINT "Unrecognized error." END SELECT END END IF END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CDBL Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts a numeric expression to a double-precision number ž Syntax CDBL(numeric-expression) ž Remarks The numeric-expression may be any numeric expression. This function has the same effect as assigning the numeric expression to a double-precision variable. Note that the results of CDBL are no more accurate than the original expression. The added digits of precision are not significant unless the expression is calculated with double-precision accuracy. ž Example The following example demonstrates how the precision of the numeric expression affects the result of using CDBL: X = 7/9 X# = 7/9 PRINT X 'Both X# and CDBL(X) will be accurate to only 7 decimal 'places, because 7/9 is evaluated in single precision. PRINT X# PRINT CDBL(X) 'Accurate to 15 decimal places. PRINT 7#/9# ž Output .7777778 .7777777910232544 .7777777910232544 .7777777777777778 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CHAIN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transfers control from the current program to another program ž Syntax CHAIN filespec ž Remarks The filespec is a string expression that identifies the program to which control is passed. The filespec may include a path specification. Programs running within the QuickBASIC environment assume a .BAS extension (if no extension is given) and cannot chain to executable files (files with a .COM or .EXE extension). Programs running outside the QuickBASIC environment assume an .EXE extension and cannot chain to QuickBASIC source files (files with a .BAS extension). You can pass variables between programs using the COMMON statement to set up a blank COMMON block. See the entry for COMMON. If you are compiling a program outside the QuickBASIC environment, note that the BCOM45.LIB library does not support COMMON. There are two ways to use COMMON with chained programs outside the environment: ž Use the default (BRUN45.EXE) by compiling the programs using the option in the Make EXE dialog box called EXE Requiring BRUN45.EXE. ž Use BRUN45.LIB by compiling from the command line without the /O option. The behavior of CHAIN and RUN is almost identical. The principal differences are that RUN closes all open files and does not support COMMON data blocks. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE When programs use BRUN45.LIB, files are left open during chaining unless they are explicitly closed with a CLOSE statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica BASICA assumes the extension .BAS. QuickBASIC assumes an extension of either .BAS or .EXE, depending on whether the program is run within the environment or compiled and run outside the environment. If you omit the file extension, CHAIN works the same in both QuickBASIC and BASICA. BASIC does not support the ALL, MERGE, or DELETE options available in BASICA, nor does it allow you to specify 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. ž See Also CALL (BASIC), COMMON, RUN ž Example See example for the COMMON statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CHDIR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Changes the current default directory for the specified drive ž Syntax CHDIR pathspec ž Remarks The pathspec is a string expression identifying the directory that is to become the default directory. The pathspec must have fewer than 64 characters. It has the following syntax: ®drive:Æ®\Ædirectory®\directoryÆ... The argument drive: is an optional drive specification. If you omit drive, CHDIR changes the default directory on the current drive. CHDIR differs from the CHDIR command in DOS in two ways: 1. The BASIC statement cannot be shortened to CD. 2. There is no form of the CHDIR statement that returns the current directory. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The CHDIR statement changes the default directory but not the default drive. For example, if the default drive is C, then the following CHDIR statement changes the default directory on drive D, but the default drive is still C: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CHDIR "D:\TMP" ž See Also MKDIR, RMDIR ž Examples ' Makes \HOME\SALES the current directory on the default ' drive. CHDIR "\HOME\SALES" 'Changes the current directory to USERS on drive B; it does 'not, however, change the default drive to B. CHDIR "B:USERS" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CHR$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a one-character string whose ASCII code is the argument ž Syntax CHR$(code) ž Remarks CHR$ is commonly used to send a special character to the screen or printer. For example, you can send a form feed (CHR$(12)) to clear the screen and return the cursor to the home position. CHR$ can also be used to include a double quote (") in a string: Msg$=CHR$(34)+"Quoted string"+CHR$(34) This line adds a double-quote character to the beginning and the end of the string. ž See Also ASC; Appendix A, "Keyboard Scan Codes and ASCII Character Codes" ž Example The following example uses CHR$ to display graphics characters in the extended character set: DEFINT A-Z ' Display two double-sided boxes. CALL DBox(5,22,18,40) CALL DBox(1,4,4,50) END ' Subroutine to display boxes on the screen. ' ' Parameters ' Urow%, Ucol% : Row and column of upper-left corner. ' Lrow%, Lcol% : Row and column of lower-right corner. ' Use constants for the extended character set graphic ' characters. CONST ULEFTC=201, URIGHTC=187, VERTICAL=186, HORIZONTAL=205 CONST LLEFTC=200, LRIGHTC=188 SUB DBox (Urow%, Ucol%, Lrow%, Lcol%) STATIC ' Draw top of box, starting with the upper left corner. LOCATE Urow%, Ucol% : PRINT CHR$(ULEFTC); LOCATE ,Ucol%+1 : PRINT STRING$(Lcol%-Ucol%,CHR$(HORIZONTAL)); LOCATE ,Lcol% : PRINT CHR$(URIGHTC); ' Draw the body of the box. FOR I=Urow%+1 TO Lrow%-1 LOCATE I,Ucol% : PRINT CHR$(VERTICAL); LOCATE ,Lcol% : PRINT CHR$(VERTICAL); NEXT I ' Draw the bottom of the box. LOCATE Lrow%, Ucol% : PRINT CHR$(LLEFTC); LOCATE ,Ucol%+1 : PRINT STRING$(Lcol%-Ucol%,CHR$(HORIZONTAL)); LOCATE ,Lcol% : PRINT CHR$(LRIGHTC); END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CINT Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts a numeric expression to an integer by rounding the expression's fractional part ž Syntax CINT(numeric-expression) ž Remarks If numeric-expression is not in the range -32,768 to 32,767, the function produces a run-time error message that reads Overflow. CINT differs from the FIX and INT functions, which truncate, rather than round, the fractional part. See the example for the INT function for an illustration of the differences among these functions. ž See Also CDBL, CSNG, FIX, INT ž Example The following example converts an angle in radians to an angle in degrees and minutes: 'Set up constants for converting radians to degrees. CONST PI=3.141593, RADTODEG=180./PI INPUT "Angle in radians = ",Angle 'Get the angle in radians. Angle = Angle * RADTODEG 'Convert radian input to degrees. Min = Angle - INT(Angle) 'Get the fractional part. 'Convert fraction to value between 0 and 60. Min = CINT(Min * 60) Angle = INT(Angle) 'Get whole number part. IF Min = 60 THEN '60 minutes = 1 degree. Angle = Angle + 1 Min = 0 END IF PRINT "Angle equals" Angle "degrees" Min "minutes" ž Output Angle in radians = 1.5708 Angle equals 90 degrees 0 minutes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CIRCLE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Draws an ellipse or circle with a specified center and radius ž Syntax CIRCLE ®STEPÆ (x,y),radius®,®colorÆ®,®startÆ®,®endÆ®,aspectÆÆÆÆ ž Remarks The following list describes the parts of the CIRCLE statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STEP The STEP option specifies that x and y are offsets relative to the current graphics cursor position. x,y The x- and y-coordinates for the center of the Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  x,y The x- and y-coordinates for the center of the circle or ellipse. radius The radius of the circle or ellipse in the current coordinate system. color The attribute of the desired color. See the entries for the COLOR and SCREEN statements for more information. The default color is the foreground color. start, end The start and end angles, in radians, for the arc to draw. The start and end arguments are used to draw partial circles or ellipses. The arguments may range in value from -2ć radians to 2ć radians, where ć = appx. 3.141593. The default value for start is 0 radians. The default value for end is 2ć radians. Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  If start or end is negative, then CIRCLE draws a radius to that point on the arc and treats the angle it were positive. The start angle can be less than the end angle. If you specify end but not start, the arc is drawn from 2ć to end; if you specify start but not end, the statement draws an arc from start to zero. aspect The aspect ratio, or the ratio of the y-radius to the x-radius. The default value for aspect is the value required to draw a round circle in the screen mode. This value is calculated as follows: 4 * (ypixels/xpixels)/3 where xpixels by ypixels is the screen Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  where xpixels by ypixels is the screen resolution. For example, in screen mode 1, where the resolution is 320 x 200, the default for aspect is 4 * (200/320)/3, or 5/6. If the aspect ratio is less than one, radius is the x-radius. If aspect is greater than one, radius is equal to the y-radius. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ To draw a radius to angle 0 (a horizontal line segment to the right), do not give the angle as -0; use a very small nonzero value instead as shown: ' Draws a pie-shaped one-quarter wedge of a circle: SCREEN 2 CIRCLE (200,100),60,,-.0001,-1.57 You may omit an argument in the middle of the statement, but you must include the argument's commas. In the following statement, the color argument has been omitted: CIRCLE STEP (150,200),94,,0.0,6.28 If you omit the last argument, you do not include the commas. The last point that CIRCLE references, after drawing, is the center of the ellipse or circle. You may use coordinates that are outside the screen or viewport. You may show coordinates as absolutes, or you may use the STEP option to show the position of the center point in relation to the previous point of reference. For example, if the previous point of reference is (10,10), then the following statement causes a circle to be drawn with radius 75 and center offset 10 from the current x coordinate and 5 from the current y coordinate. The circle's center is (20,15). CIRCLE STEP (10,5), 75 ž Example The following program first draws a circle with the upper left quarter missing. It then uses relative coordinates to position a second circle within the missing quarter circle. Finally, it uses a different aspect ratio to draw a small ellipse inside the small circle. CONST PI=3.141593 SCREEN 2 ' Draw a circle with the upper-left quarter missing. ' Use negative numbers so radii are drawn. CIRCLE (320,100), 200,, -PI, -PI/2 ' Use relative coordinates to draw a circle within the missing ' quarter. CIRCLE STEP (-100,-42),100 ' Draw a small ellipse inside the circle. CIRCLE STEP(0,0), 100,,,, 5/25 ' Display the drawing until a key is pressed. LOCATE 25,1 : PRINT "Press any key to end."; DO LOOP WHILE INKEY$="" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLEAR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reinitializes all program variables, closes files, and sets the stack size ž Syntax CLEAR ®,,stackÆ ž Remarks The CLEAR statement performs the following actions: ž Closes all files and releases the file buffers ž Clears all COMMON variables ž Sets numeric variables and arrays to zero ž Sets all string variables to null ž Reinitializes the stack and, optionally, changes its size The stack parameter sets aside stack space for your program. QuickBASIC takes the amount of stack space it requires, adds the number of bytes specified by stack, and sets the stack size to the result. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Two commas are used before stack to keep QuickBASIC compatible with BASICA. BASICA included an additional argument that set the size of the data segment. Because QuickBASIC automatically manages the data segment, the first parameter is no longer required . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If your program has deeply nested subroutines or procedures, or if you use recursive procedures, you may want to use a CLEAR statement to increase the stack size. You may also want to increase the stack size if your procedures have a large number of arguments. Clearing the stack destroys the return addresses placed on the stack during the execution of a GOSUB. This makes it impossible to execute a RETURN statement correctly and produces a RETURN without GOSUB run-time error message. Using a CLEAR statement in a SUB or FUNCTION produces a run-time error message that reads Illegal function call. ž Differences From Basica BASICA programs using CLEAR may require modification. In BASICA programs, any DEF FN functions or data types declared with DEFtype statements are lost after a CLEAR statement. In compiled programs, this information is not lost because these declarations are fixed at compile time. ž See Also FRE, SETMEMGT ž Example The following statement clears all program variables and sets aside 2,000 bytes on the stack for the program: CLEAR ,,2000 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLNG Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts a numeric expression to a long (4-byte) integer by rounding the fractional part of the expression ž Syntax CLNG(numeric-expression) ž Remarks If numeric-expression is not in the range -2,147,483,648 to 2,147,483,647, the function produces an error message that reads Overflow. ž Example The following example shows how CLNG rounds before converting the number: A=32767.45 B=32767.55 PRINT CLNG(A); CLNG(B) ž Output 32767 32768 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLOSE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Concludes I/O to a file or device ž Syntax CLOSE ®®#Æ filenumber ®,®#Æ filenumberÆ...Æ ž Remarks The CLOSE statement complements the OPEN statement. The filenumber is the number under which the file was opened. A CLOSE statement with no arguments closes all open files and devices. The association of a file with a file number ends when a CLOSE statement is executed. You may then reopen the file using the same or a different file number. Once you close a file, you may use that file's number for any unopened file. A CLOSE for a file or device that was opened for sequential output writes the final buffer of output to that file or device. CLOSE releases all buffer space associated with the closed file or files. The CLEAR, END, RESET, RUN, and SYSTEM statements automatically close all files. ž Example See the example for CALL (BASIC). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLS Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Clears the screen ž Syntax CLS ®{0 | 1 | 2}Æ ž Remarks There are several ways to use the CLS statement, as described in the following list: Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CLS 0 Clears the screen of all text and graphics. CLS 1 Clears only the graphics viewport if a VIEW statement has been executed. Otherwise, CLS 1 clears the entire screen. CLS 2 Clears only the text viewport, leaving the bottom screen line (line 25, 30, 43, or 60 depending on the screen mode) unchanged. CLS Clears either the graphics viewport or the text viewport. If the graphics viewport is active, then CLS with no argument clears only the viewport. If the graphics viewport is inactive, then CLS clears the text viewport and refreshes the function key display line (the bottom screen line). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The CLS statement also returns the cursor to the home position in the top left corner of the screen. ž See Also VIEW, VIEW PRINT, WINDOW ž Example The following program draws random circles in a graphics viewport and prints in a text viewport. The graphics viewport is cleared after 30 circles have been drawn. The program clears the text viewport after printing to it 45 times. RANDOMIZE TIMER SCREEN 1 ' Set up a graphics viewport with a border. VIEW (5,5)-(100,80),3,1 ' Set up a text viewport. VIEW PRINT 12 TO 24 ' Print a message on the screen outside the text viewport. LOCATE 25,1 : PRINT "Press any key to stop." Count=0 DO ' Draw a circle with a random radius. CIRCLE (50,40),INT((35-4)*RND+5),(Count MOD 4) ' Clear the graphics viewport every 30 times. IF (Count MOD 30)=0 THEN CLS 1 PRINT "Hello. "; ' Clear the text viewport every 45 times. IF (Count MOD 45)=0 THEN CLS 2 Count=Count+1 LOOP UNTIL INKEY$<>"" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COLOR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Selects display colors ž Syntax COLOR ®foregroundÆ®,®backgroundÆ®,borderÆÆ Screen mode 0 COLOR ®backgroundÆ®,paletteÆ Screen mode 1 COLOR ®foregroundÆ®,backgroundÆ Screen modes 7-10 COLOR ®foregroundÆ Screen modes 12-13 ž Remarks With the COLOR statement, you can set the foreground and background colors for the display. In screen mode 0 a border color can also be selected. In screen mode 1 no foreground color can be selected, but one of two four-color palettes can be selected for use with graphics statements. In screen modes 12-13 only the foreground color can be set. The values of foreground in screen modes 7-10, 12, and 13 are attribute numbers (not color numbers) and display the color assigned to that attribute. See the PALETTE statement for a description of attributes. The COLOR statement does not determine the range of available colors. The combination of adapter, display, and the mode set by the SCREEN statement determine the color range. See the SCREEN statement for more information. The different syntaxes and their effects in different screen modes are described below: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Modifies the current default text foreground and background colors and the screen border. The foreground color must be an integer expression in the range 0-31. It determines the "foreground" color in text modeÄÄthe default color of text. Sixteen colors can be selected with the integers 0-15. You can select a blinking version of a color by adding 16 to the color number. For example, a blinking color 7 is equal to 7 + 16, or 23. The background color is an integer expression in the range 0-7 and is the color of the background for each text character. Blinking background colors are not supported. The border colorÄÄthe color used to draw the screen borderÄÄis an integer expression in the range 0-15. The IBM Enhanced Graphics Adapter Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  range 0-15. The IBM Enhanced Graphics Adapter (EGA), the IBM Video Graphics Array adapter (VGA), and the IBM Multicolor Graphics Array adapter (MCGA) do not support the border argument. 1 In mode 1, the COLOR statement has a unique syntax that includes a palette argument that is an odd or even integer expression in the range 0 to 255. This argument determines which of two sets of colors to use when displaying particular color numbers. The default colors for the palette parameter are equivalent to the following PALETTE statements on a system equipped with an EGA: COLOR ,0 'Same as the next three 'PALETTE statements. Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  'PALETTE statements. PALETTE 1,2 'Attribute 1 = color 2 (green) PALETTE 2,4 'Attribute 2 = color 4 (red) PALETTE 3,6 'Attribute 3 = color 6 (yellow) COLOR ,1 'Same as the next three 'PALETTE statements. PALETTE 1,3 'Attribute 1 = color 3 (cyan) PALETTE 2,5 'Attribute 2 = color 5 (magenta) PALETTE 3,7 'Attribute 3 = color 7 (white) Note that in screen mode 1, a COLOR statement overrides previous PALETTE statements. 2 An Illegal function call message results if COLOR is used in this mode. 7-10 In these modes, no border color can be specified. The graphics background is given by the Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The graphics background is given by the background color number, which must be in the range of valid color numbers for the screen mode. The foreground color argument is the default line-drawing color. In screen modes 7 to 10 foreground is an attribute number, while background is a color number. See the SCREEN statement for more details. 11 Use the PALETTE statement to set color in screen mode 11. 12, 13 No background color can be specified in these modes. The foreground argument is the attribute used for the foreground graphics color. The attribute must be in the correct range for the screen mode. See the SCREEN statement for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Arguments that are outside the valid ranges produce error messages that read Illegal function call. The foreground can be the same color as the background, making displayed characters invisible. The default background is black, or color number 0 for all display hardware configurations and all screen modes. In screen modes 12 and 13 you can set the background color by assigning a color to attribute 0 with a PALETTE statement. For example, to make the background color 8224 (a light violet), you would use the following PALETTE statement: PALETTE 0,8224 In screen mode 11 you can set both the foreground and background color by assigning a color to attribute 0 with a PALETTE statement. With an EGA, VGA, or MCGA installed, the PALETTE statement gives you flexibility in assigning different display colors to the actual color-number ranges for the foreground, background, and border colors discussed above. See the PALETTE statement reference pages for more details. ž See Also PAINT, PALETTE, SCREEN ž Examples The following series of examples show COLOR statements and their effects in the various screen modes: SCREEN 0 'foreground=1, background=2, border=3 COLOR 1, 2, 3 SCREEN 1 'background=1, even palette number COLOR 1,0 'background=2, odd palette number COLOR 2,1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COM Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables, disables, or inhibits event trapping of communications activity on a specified port ž Syntax COM(n) ON COM(n) OFF COM(n) STOP ž Remarks The parameter n is the number of the communications port; n can be either 1 or 2. The COM ON statement enables communications event trapping. If a character arrives at a communications port after a COM ON statement, then the subroutine specified in the ON COM statement is executed. COM OFF disables communications event trapping. No communications trapping takes place until another COM ON statement is executed. Events occurring while trapping is off are ignored. COM STOP inhibits communications event trapping so no trapping takes place until a COM ON statement is executed. Events occurring while trapping is inhibited are remembered and processed when the next COM ON statement is executed. See Chapter 6, "Error and Event Trapping," in Programming in BASIC for an outline of event trapping. ž See Also ON event ž Example See the event-trapping examples in Chapter 6, "Error and Event Trapping," in Programming in BASIC for an illustration of how to do event trapping. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COMMAND$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the command line used to invoke the program ž Syntax COMMAND$ ž Remarks The COMMAND$ function returns the complete command line entered after your BASIC program name, including optional parameters. COMMAND$ removes all leading blanks from the command line and converts all letters to uppercase (capital letters). The COMMAND$ function can be used in stand-alone executable files or, if you are executing from the QuickBASIC environment, by using the /CMD command line option or by selecting Modify COMMAND$ on the Run menu. ž Example The Comline subprogram in the following example breaks the command line into separate arguments and stores them in an array. Each argument is separated from adjoining arguments by one or more blanks or tabs on the command line. ' Default variable type is integer in this module. DEFINT A-Z ' Declare the Comline subprogram, as well as the number and ' type of its parameters. DECLARE SUB Comline(N, A$(),Max) DIM A$(1 TO 15) ' Get what was typed on the command line. CALL Comline(N,A$(),10) ' Print out each part of the command line. PRINT "Number of arguments = ";N PRINT "Arguments are: " FOR I=1 TO N : PRINT A$(I) : NEXT I ' Subroutine to get command line and split into arguments. ' Parameters: NumArgs : Number of command line args found. ' Args$() : Array in which to return arguments. ' MaxArgs : Maximum number of arguments array ' can return. SUB Comline(NumArgs,Args$(),MaxArgs) STATIC CONST TRUE=-1, FALSE=0 NumArgs=0 : In=FALSE ' Get the command line using the COMMAND$ function. Cl$=COMMAND$ L=LEN(Cl$) ' Go through the command line a character at a time. FOR I=1 TO L C$=MID$(Cl$,I,1) 'Test for character being a blank or a tab. IF (C$<>" " AND C$<>CHR$(9)) THEN ' Neither blank nor tab. ' Test to see if you're already ' inside an argument. IF NOT In THEN ' You've found the start of a new argument. ' Test for too many arguments. IF NumArgs=MaxArgs THEN EXIT FOR NumArgs=NumArgs+1 In=TRUE END IF ' Add the character to the current argument. Args$(NumArgs)=Args$(NumArgs)+C$ ELSE ' Found a blank or a tab. ' Set "Not in an argument" flag to FALSE. In=FALSE END IF NEXT I END SUB The following is a sample command line and output for a stand-alone executable file (assumes program name is arg.exe): arg one two three four five six ž Output Number of arguments = 6 Arguments are: ONE TWO THREE FOUR FIVE SIX ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COMMON Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Defines global variables for sharing between modules or for chaining to another program ž Syntax COMMON ®SHAREDÆ ®/blockname/Æ variablelist ž Remarks The following list describes the parts of the COMMON statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SHARED An optional attribute indicating that the variables are to be shared with all SUB or FUNCTION procedures in the module. SHARED can eliminate the need for a SHARED statement inside SUB or FUNCTION procedures. blockname A valid BASIC identifier (up to 40 characters) used to identify a group of variables. Use a blockname to share only specific groups of variables. When a blockname is used, the COMMON block is a named COMMON block. When blockname is omitted, the block is a blank COMMON block. Items in a named COMMON block are not preserved across a chain to a new program. See "Using Named COMMON" and "Using COMMON with Chain," below. Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  variablelist A list of variables to be shared between modules or chained-to programs. The same variable may not appear in more than one COMMON statement in a module. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A variablelist has the following syntax: variable®( )Æ®AS typeÆ®, variable®( )Æ®AS typeÆÆ... The following list describes the parts of a variablelist: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ variable Any valid BASIC variable name. AS type Declares variable to be of type type. The type may be INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Older versions of BASIC required the number of dimensions to appear after the name of a dynamic array in a COMMON statement. The number of dimensions is no longer required, although QuickBASIC accepts the older syntax to maintain compatibility with earlier versions. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A COMMON statement establishes storage for variables in a special area that allows them to be shared between modules or with other programs invoked with a CHAIN statement. Because COMMON statements establish global variables for an entire program, they must appear before any executable statements. All statements are executable, except the following: ž COMMON ž CONST ž DATA ž DECLARE ž DEFtype ž DIM (for static arrays) ž OPTION BASE ž REM ž SHARED ž STATIC ž TYPE...END TYPE ž All metacommands Variables in COMMON blocks are matched by position and type, not by name. Thus, variable order is significant in COMMON statements. In the following fragment, it is the order of the variables in the COMMON statements that links the variables, not the names: ' Main program. COMMON A, D, E A = 5 : D = 8 : E = 10 . . . ' Common statement in another module. COMMON A, E, D 'A = 5, E = 8, D = 10 . . . Both static and dynamic arrays are placed in COMMON by using the array name followed by parentheses. A static array must be dimensioned with integer-constant subscripts in a DIM statement preceding the COMMON statement. A dynamic array must be dimensioned in a later DIM or REDIM statement. The elements of a dynamic array are not allocated in the COMMON block. Only an array descriptor is placed in common. (See Chapter 2, "Data Types," in this manual and Appendix F, "Metacommands," in Programming in BASIC for more information about static and dynamic arrays.) The size of a common area can be different from that in another module or chained program if a blank COMMON block has been used. When a BASIC program shares COMMON blocks with a routine in the user library, the calling program may not redefine the COMMON block to a larger size. Errors caused by mismatched COMMON statements are subtle and difficult to find. An easy way to avoid this problem is to place COMMON declarations in a single "include" file and use the ›INCLUDE metacommand in each program. See Appendix F, "Metacommands," in Programming in BASIC for a discussion of ›INCLUDE. The following program fragment shows how to use the ›INCLUDE metacommand to share a file containing COMMON statements among programs: 'This file is menu.bas. '›INCLUDE:'COMDEF.BI' . . . CHAIN "PROG1" END 'This file is prog1.bas. '›INCLUDE:'COMDEF.BI' . . . END 'This file is comdef.bi. DIM A(100),B$(200) COMMON I,J,K,A() COMMON A$,B$(),X,Y,Z 'End comdef.bi. The next three sections discuss using named COMMON blocks, using the SHARED keyword, and using COMMON when chaining programs. USING NAMED COMMON A named COMMON block provides a convenient way to group variables so that different modules have access only to the common variables that they need. The following program, which calculates the volume and density of a rectangular prism, uses named COMMON blocks to share different sets of data with two subprograms. The subprogram VOLUME needs to share only the variables representing the lengths of the sides (in COMMON block SIDES). The subprogram DENSITY also needs variables representing the weight (in COMMON block WEIGHT). 'Main program. DIM S(3) COMMON /Sides/ S() COMMON /Weight/ C C=52 S(1)=3:S(2)=3:S(3)=6 CALL Volume CALL Density END 'Subprogram VOLUME in a separate module. DIM S(3) COMMON SHARED /Sides/ S() SUB Volume STATIC Vol=S(1)*S(2)*S(3) PRINT "The volume is "; Vol END SUB 'Subprogram DENSITY in a separate module. DIM S(3) COMMON SHARED /Sides/ S() COMMON SHARED /Weight/ W SUB Density STATIC Vol=S(1)*S(2)*S(3) Dens=W/Vol PRINT "The density is "; Dens END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Named COMMON blocks are not preserved across chained programs. Use blank COMMON blocks to pass variables to a chained program. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ USING COMMON WITH CHAIN The COMMON statement provides the only way to pass the values of variables directly to a chained program. To pass variables, both programs must contain COMMON statements. Remember that variable order and type are significant, not variable names. The order and type of variables must be the same for all COMMON statements communicating between chaining programs. Although the order and type of variables is critical for making sure the right values are passed, the COMMON blocks do not have to be the same size. If the COMMON block in the chained-to program is smaller than the COMMON block in the chaining program, the extra COMMON variables in the chaining program are ignored. If the size of the COMMON block in the chained-to program is larger, then additional COMMON numeric variables are initialized to zero. Additional string variables are initialized to null strings. Static arrays passed in COMMON by the chaining program must be declared as static in the chained-to program. Similarly, dynamic arrays placed in common by the chaining program must be dynamic in the chained-to program. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE To use COMMON with CHAIN when you are compiling outside the BASIC environment, you must use the BRUN45.EXE module. This module is used when you compile from the command line without the /O option or when you use the option from the Make EXE dialog box called EXE Requiring BRUN45.EXE. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CALL (BASIC), CHAIN, FUNCTION, SUB ž Examples The following example uses a COMMON statement to pass variables between two chained programs. The first program reads in a series of numeric values, stores the values in an array, and then chains to the other program. The second program finds and prints the average of the values. DIM Values(1 TO 50) COMMON Values(), NumValues PRINT "Enter values one per line. Enter END to quit." NumValues=0 DO INPUT "-> ",N$ IF I>=50 OR UCASE$(N$)="END" THEN EXIT DO NumValues=NumValues+1 Values(NumValues)=VAL(N$) LOOP CHAIN "average" The program named average appears as follows (notice that average is an entirely separate program): DIM X(1 TO 50) COMMON X(), N IF N>0 THEN Sum=0 FOR I=1 TO N Sum=Sum+X(I) NEXT I PRINT "The average of the values is";Sum/N END IF ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CONST Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares symbolic constants for use in place of numeric or string values ž Syntax CONST constantname = expression ®,constantname = expressionÆ... ž Remarks Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ constantname A name following the same rules as a BASIC variable name. You may add to the name a type-declaration character (%, &, !, #, or $) to indicate its type, but this character is not part of the name. expression An expression consisting of literals (such as 1.0), other constants, or any of the arithmetic and logical operators except exponentiation (^). You may also use a single literal string such as "Error on input". You cannot use string concatenation, variables, user-defined functions, or intrinsic functions like SIN or CHR$ in expressions assigned to constants. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If you use a type-declaration character in the name, you may omit the character when the name is used, as shown in the following example: CONST MAXDIM% = 250 . . . DIM AccountNames$(MAXDIM) If you omit the type-declaration character, the constant is given a type based on the expression in the CONST statement. Strings always yield a string constant. With numeric expressions, the expression is evaluated and the constant is given the simplest type that can represent the constant. For example, if the expression gives a result that can be represented as an integer, the constant is given an integer type. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Names of constants are not affected by DEFtype statements such as DEFINT. A constant's type is determined either by an explicit type-declaration character or by the type of the expression. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Constants must be defined before they are referenced. The following example produces an error because the constant ONE is not defined before it is used to define TWO (constants are defined from left to right): CONST TWO = ONE + ONE, ONE = 1 Constants declared in a SUB or FUNCTION are local to the SUB or FUNCTION. A constant declared outside a procedure is defined throughout the module. You can use constants anywhere that you would use an expression. A common programming practice is to use a statement like the following (recall that any nonzero value represents "true"): TRUE=-1 Constants offer several advantages over using variables for constant values: ž Constants need to be defined only once for an entire module. ž Constants cannot be inadvertently changed. ž In stand-alone programs, using constants produces more efficient code than using variables. ž Constants make programs easier to modify. ž Examples The following program uses the CONST statement to declare symbolic constants for the ASCII values of nonprinting characters such as tab and line feed: ' This program counts words, lines, and characters. ' A word is any sequence of nonblank characters. DEFINT a-z CONST BLANK = 32, ENDFILE = 26, CR = 13, LF = 10 CONST TABC = 9, YES = -1, NO = 0 ' Get the file name from the command line. FileName$=COMMAND$ IF FileName$="" THEN INPUT "Enter input file name: ",FileName$ IF FileName$="" THEN END END IF OPEN FileName$ FOR INPUT AS #1 Words=0 Lines=0 Characters=0 ' Set a flag to indicate you're not looking at a ' word, then get the first character from the file. InaWord=NO DO UNTIL EOF(1) C=ASC(INPUT$(1,#1)) Characters=Characters+1 IF C=BLANK or C=CR or C=LF or C=TABC THEN ' If the character is a blank, carriage return, ' line feed, or tab, you're not in a word. IF C=CR THEN Lines=Lines+1 InaWord=NO ELSEIF InaWord=NO THEN ' The character is a printing character, ' so this is the start of a word. ' Count the word and set the flag. InaWord=YES Words=Words+1 END IF LOOP PRINT Characters, Words, Lines END Constants also make programs easier to modify. The following program fragment declares a single constant to dimension a series of arrays. To increase or decrease the size of the arrays, it is necessary to change only the value in the CONST statement. CONST MAXCUSTOMERS = 250 . . . DIM AccountNumber$(MAXCUSTOMERS), Balance(MAXCUSTOMERS) DIM Contact$(MAXCUSTOMERS), PastDueAmount(MAXCUSTOMERS) . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Using a variable here, instead of a symbolic constant, makes the arrays dynamic arrays. Using a symbolic constant, as in the previous example, declares these arrays as static arrays. See Chapter 2, "Data Types," in this manual and Appendix F, "Metacommands," in Programming in BASIC for more information about static and dynamic arrays. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COS Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the cosine of an angle given in radians ž Syntax COS(numeric-expression) ž Remarks The expression, numeric-expression, can be any numeric type. By default, the cosine is calculated in single precision. If numeric-expression is a double-precision value, the cosine is calculated in double precision. You can convert an angle measurement from degrees to radians by multiplying the degrees by ć/180, where ć = 3.141593. ž See Also ATN, SIN, TAN ž Example The following program plots the graph of the polar equation r = nq for values of n from 0.1-1.1. This program uses the conversion factors x = cos(q) and y = sin(q) to change polar coordinates to Cartesian x,y coordinates. The figure plotted is sometimes known as the Spiral of Archimedes. CONST PI = 3.141593 'Gray background. SCREEN 1 : COLOR 7 'Define window large enough for biggest spiral. WINDOW (-4,-6)-(8,2) 'Draw line from origin to the right. LINE (0,0)-(2.2*PI,0),1 'Draw ten spirals. FOR N = 1.1 TO .1 STEP -.1 'Plot starting point. PSET (0,0) FOR Angle = 0 TO 2*PI STEP .04 'Polar equation for spiral. R = N * Angle 'Convert polar coordinates to Cartesian coordinates. X = R * COS(Angle) Y = R * SIN(Angle) 'Draw line from previous point to new point. LINE -(X,Y),1 NEXT NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CSNG Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts a numeric expression to a single-precision value ž Syntax CSNG(numeric-expression) ž Remarks The CSNG function has the same effect as assigning the numeric-expression to a single-precision variable. CSNG rounds the value, if necessary, before converting it. ž See Also CDBL, CINT ž Example The following example shows how CSNG rounds before converting the value: A#=975.3421115# B#=975.3421555# PRINT A#; CSNG(A#); B#; CSNG(B#) ž Output 975.3421115 975.3421 975.3421555 975.3422 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CSRLIN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current line (row) position of the cursor ž Syntax CSRLIN ž Remarks To return the current column position, use the POS function. ž See Also LOCATE, POS ž Example The following program uses a subprogram that prints a message on the screen without disturbing the current cursor position: ' Move cursor to center of screen, then print message. ' Cursor returned to center of screen. LOCATE 12,40 CALL MsgNoMove("A message not to be missed.",9,35) INPUT "Enter anything to end: ",A$ ' Print a message without disturbing current ' cursor position. SUB MsgNoMove (Msg$,Row%,Col%) STATIC ' Save the current line. CurRow%=CSRLIN ' Save the current column. CurCol%=POS(0) ' Print the message at the given position. LOCATE Row%,Col% : PRINT Msg$; ' Move the cursor back to original position. LOCATE CurRow%, CurCol% END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CVSMBF, CVDMBF Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts strings containing Microsoft Binary format numbers to IEEE-format numbers ž Syntax CVSMBF (4-byte-string) CVDMBF (8-byte-string) ž Remarks The CVSMBF and CVDMBF functions allow you to read old random-access files containing real numbers stored as strings in Microsoft Binary format. These functions convert the string read from the old file to an IEEE-format number: Function Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CVSMBF Converts 4-byte-string containing a Microsoft Binary format number to a single-precision IEEE-format number. CVDMBF Converts 8-byte-string containing a Microsoft Binary format number to a double-precision IEEE-format number. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The example below shows you how to read data from an old file by using CVSMBF and user-defined types for records. See Appendix B, "Differences from Previous Versions of QuickBASIC," in Programming in BASIC for more information about converting old data files. ž See Also FIELD; MKSMBF$, MKDMBF$ ž Example The following program reads records from a random-access file containing Microsoft Binary format real numbers stored as strings. Each record contains a student's name and a test score. ' Define a user type for the data records. TYPE StudentRec NameField AS STRING*20 Score AS STRING*4 END TYPE ' Define a variable of the user type. DIM Rec AS StudentRec ' Open the file. OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN=LEN(Rec) Max=LOF(1)/LEN(Rec) ' Read and print all of the records. FOR I=1 TO Max ' Read a record into the user-type variable Rec. GET #1,I,Rec ' Convert the score from a string containing a Microsoft ' Binary format number to an IEEE-format number. ScoreOut=CVSMBF(Rec.Score) ' Display the name and score. PRINT Rec.NameField,ScoreOut NEXT I CLOSE #1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CVI, CVS, CVL, CVD Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts strings containing numeric values to numbers ž Syntax CVI(2-byte-string) CVS(4-byte-string) CVL(4-byte-string) CVD(8-byte-string) ž Remarks CVI, CVS, CVL, and CVD are used with a FIELD statement to read real numbers from a random-access file. The functions take strings defined in the FIELD statement and convert them to a value of the corresponding numeric type. The functions are the inverse of MKI$, MKS$, MKL$, and MKD$: Function Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CVI Converts 2-byte-string created with MKI$ back to an integer. CVS Converts 4-byte-string created with MKS$ back to a single-precision number. CVL Converts 4-byte-string created with MKL$ back to a long integer. CVD Converts 8-byte-string created with MKD$ back to a double-precision number. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The new BASIC record variables provide a more efficient and convenient way of reading and writing random-access files. See Chapter 3, "File and Device I/O," in Programming in BASIC for a complete example. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also FIELD; LSET; MKD$, MKI$, MKL$, MKS$ ž Example The following program illustrates the use of MKS$ and CVS: OPEN "ACCOUNT.INF" FOR RANDOM AS #2 LEN = 29 FIELD #2, 25 AS Name$, 4 AS Check$ Format$ = "$$#####.##" DO PRINT DO INPUT "Enter account # to update: ",Rec% GET #2, Rec% 'Get the record PRINT "This is the account for "; Name$ INPUT "Is this the account you wanted"; R$ LOOP WHILE UCASE$(MID$(R$,1,1)) <> "Y" 'Convert string to single-precision number. Checkamt! = CVS(Check$) PRINT PRINT "The opening balance for this account is"; PRINT USING Format$; Checkamt! PRINT "Enter the checks and cash withdrawals for this" PRINT "account below. Enter 0 when finished." DO INPUT Checkout! : Checkamt! = Checkamt! - Checkout! LOOP UNTIL Checkout! = 0 PRINT PRINT "Enter the deposits for this account below." PRINT "Enter 0 when finished." DO INPUT Checkin! : Checkamt! = Checkamt! + Checkin! LOOP UNTIL Checkin! = 0 PRINT PRINT "The closing balance for this account is"; PRINT USING Format$; Checkamt! 'Convert single-precision number to string. LSET Check$ = MKS$(Checkamt!) PUT #2, Rec% 'Store the record. INPUT "Update another"; R$ LOOP UNTIL UCASE$(MID$(R$,1,1)) <> "Y" CLOSE #2 END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DATA Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Stores the numeric and string constants used by a program's READ statements ž Syntax DATA constant1 ®,constant2Æ... ž Remarks The constant1, constant2, and so on in a DATA statement can be any valid numeric or string constant. Names of symbolic constants (defined in a CONST statement) appearing in DATA statements are interpreted as strings, rather than names of constants. For example, in the following program fragment the second data item is a string, "PI", and not the value 3.141593: CONST PI=3.141593 . . . DATA 2.20, PI,45,7 . . . A DATA statement may contain as many constants as will fit on a line. The constants are separated by commas. You may use any number of DATA statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE String constants in DATA statements require double quotes only if they contain commas, colons, or significant leading or trailing spaces. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Null data items (indicated by a missing value) can appear in a data list: DATA 1,2,,4,5 When a null item is read into a numeric variable, the variable has the value 0. When a null item is read into a string variable, the variable has the null string value (""). When working in the QuickBASIC environment, DATA statements can only be entered in the module-level code. QuickBASIC moves all DATA statements not in the module-level code to the module-level code when it reads a source file. READ statements using the DATA statements can appear anywhere in the program. DATA statements are used in the order in which they appear in the source file. You may think of the items in several DATA statements as one continuous list of items, regardless of how many items are in a statement or where the statement appears in the program. You may reread DATA statements by using the RESTORE statement. ž See Also READ RESTORE ž Examples The following example displays the current date by converting the date returned by the DATE$ function: ' Get the date. C$ = DATE$ ' Use VAL to split the month off the string returned by ' DATE$. FOR I% = 1 TO VAL(C$) READ Month$ NEXT DATA January, February, March, April, May, June, July DATA August, September, October, November, December ' Get the day. Day$ = MID$(C$,4,2) IF LEFT$(Day$,1) = "0" THEN Day$ = RIGHT$(Day$,1) ' Get the year. Year$ = RIGHT$(C$,4) PRINT "Today is " Month$ " " Day$ ", " Year$ ž Output Today is September 21, 1988 The following example shows how null data items are handled: DATA abc,,def DATA 1,,2 READ A$, B$, C$ 'B$ = "" PRINT A$, B$, C$ PRINT READ A, B, C 'B = 0 PRINT A, B, C OUTPUT abc def 1 0 2 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DATE$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string containing the current date ž Syntax DATE$ ž Remarks The DATE$ function returns a ten-character string in the form mm-dd-yyyy, where mm is the month (01-12), dd is the day (01-31), and yyyy is the year (1980-2099). ž See Also DATE$ Statement ž Example Note that the DATE$ function in the following example prints a zero in front of the month: PRINT DATE$ ž Output 09-21-88 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DATE$ Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sets the current date ž Syntax DATE$ = stringexpression ž Remarks The DATE$ statement is the complement of the DATE$ function. The stringexpression must have one of the following forms, where mm (01-12) and dd (01-31) are the month and day, and yy and yyyy (1980-2099) are the year: mm-dd-yy mm-dd-yyyy mm/dd/yy mm/dd/yyyy ž Example The following program sets the current date from an input numeric date: PRINT "Enter the date below (default year is 1989)." INPUT " Month: ",Month$ INPUT " Date: ",Day$ INPUT " Year: ",Year$ IF Year$ = "" THEN Year$ = "89" DATE$ = Month$ + "/" + Day$ + "/" + Year$ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DECLARE Statement (BASIC Procedures) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares references to BASIC procedures and invokes argument type checking ž Syntax DECLARE {FUNCTION | SUB } name ®(®parameterlistÆ)Æ ž Remarks The DECLARE statement uses the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ name The procedure's name. The name is limited to 40 characters. FUNCTION names can end in one of the type-declaration characters (%, &, !, #, or $) to indicate the type of value returned. parameterlist A list of parameters indicating the number and type of arguments used when calling the procedure. Syntax is shown below. Only the number and the type of the arguments are significant. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ For calls within BASIC, the DECLARE statement is required only if you call SUB procedures without the CALL keyword, or if you invoke a FUNCTION defined in another module. See Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC, for more information about invoking subprograms without CALL. A DECLARE statement also causes the compiler to check the number and type of arguments used to invoke the procedure. QuickBASIC automatically generates DECLARE statements when you save your program while you are working in the environment. The DECLARE statement can appear only in module-level code (not in a SUB or FUNCTION) and affects the entire module. The parameterlist serves as a prototype for checking the number and type of the arguments in SUB and FUNCTION calls. It has the following syntax: variable®AS typeÆ ®,variable®AS typeÆÆ... A variable is any valid BASIC variable name. If the variable is an array, it may be followed by the number of dimensions in parentheses: DECLARE SUB DisplayText (A(2) AS STRING) DIM Text$(100,5) . . . CALL DisplayText(Text$()) The number of dimensions is optional. The type is either INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. Again, only the number and types of arguments are significant. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE You cannot have fixed-length strings in DECLARE statements because only variable-length strings can be passed to SUB and FUNCTION procedures. Fixed-length strings can appear in an argument list but are converted to variable-length strings before being passed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A variable's type can also be indicated by including an explicit type character (%, &, !, #, or $) or by relying on the default type. The form of the parameter list determines whether or not argument checking is done, as shown in the following list: Declaration Meaning ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DECLARE SUB First You may only omit the parentheses if the SUB or FUNCTION is separately compiled. No argument checking is done. DECLARE SUB First () First has no parameters. Arguments in a CALL to First are flagged as an error. An empty parameter list indicates that the SUB or FUNCTION has no parameters. DECLARE SUB First (X AS LONG) First has one long-integer parameter. The number and type of the arguments in each CALL or invocation are checked when the parameter list appears in the DECLARE. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CALL, CALLS (Non-BASIC); FUNCTION; SUB ž Example In the following example, the DECLARE statement allows Sort to be invoked without the CALL keyword: ' Generate 20 random numbers, store them in an array, and sort. ' The sort subprogram is called without the CALL keyword. DECLARE SUB Sort(A(1) AS SINGLE, N AS INTEGER) DIM Array1(1 TO 20) ' Generate 20 random numbers. RANDOMIZE TIMER FOR I=1 TO 20 Array1(I)=RND NEXT I ' Sort the array and call Sort without the CALL keyword. ' Notice the absence of parentheses around the arguments in ' the call to Sort. Sort Array1(), 20% ' Print the sorted array. FOR I=1 TO 20 PRINT Array1(I) NEXT I END ' Sort subroutine. SUB Sort(A(1), N%) STATIC FOR I= 1 TO N%-1 FOR J=I+1 TO N% IF A(I)>A(J) THEN SWAP A(I), A(J) NEXT J NEXT I END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DECLARE Statement (Non-BASIC Procedures) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares calling sequences for external procedures written in other languages ž Syntax 1 DECLARE FUNCTION name ®CDECLÆ ®ALIAS "aliasname"Æ®(®parameterlistÆ)Æ ž Syntax 2 DECLARE SUB name ®CDECLÆ ®ALIAS "aliasname"Æ®(®parameterlistÆ)Æ ž Remarks The following list describes the parts of the DECLARE statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FUNCTION Indicates that the external procedure returns a Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FUNCTION Indicates that the external procedure returns a value and can be used in an expression. SUB Indicates that the external procedure is invoked in the same way as a BASIC SUB. name The name used in the BASIC program to invoke the procedure. Names may have up to 40 characters. FUNCTION names can include an explicit type character (%, &, !, #, or $) indicating the type of value the FUNCTION returns. CDECL Indicates that the procedure uses the C-language argument order. CDECL passes the arguments from right to left, rather than using the BASIC convention of left to right. CDECL also affects the name used in searches of object files and libraries. If there is no ALIAS Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  object files and libraries. If there is no ALIAS in the DECLARE, the name of the procedure (name) is converted to lowercase, the type-declaration character is removed, and an underscore is added to the beginning. This becomes the name used when searching libraries and external files. If CDECL is used with an ALIAS, the aliasname is used. ALIAS Indicates that the procedure has another name in the .OBJ or library file. aliasname The name the procedure has in the file or library. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A parameterlist has the following syntax: ®{BYVAL|SEG}Æ variable ®AS typeÆ ®,®{BYVAL|SEG}Æ variable ®AS typeÆÆ... The following list describes the parts of a parameterlist: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ BYVAL BYVAL indicates that the parameter is passed by value, rather than by reference. Reference is the default. BYVAL can be used only with INTEGER, LONG, SINGLE, and DOUBLE parameters. When BYVAL appears in front of a parameter, the actual argument is converted to the type indicated in the DECLARE statement before being passed. SEG Indicates the parameter is passed as a segmented address (far pointer). variable A valid BASIC variable name. Only the variable's type is significant. If the variable is an array Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  type is significant. If the variable is an array it may be followed by the number of dimensions in parentheses (to maintain compatibility with older versions of BASIC): DECLARE SUB EigenValue (A(2) AS DOUBLE) The number of dimensions is optional. AS type Indicates the variable's type. The type element may be either INTEGER, LONG, SINGLE, DOUBLE, STRING, ANY, or a user type. You can also indicate the variable's type by including an explicit type character (%, &, !, #, or $) in the variable name or by relying on the default type. When declaring external procedures written in other languages, you can use the ANY keyword in the AS clause. ANY overrides type checking for Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  the AS clause. ANY overrides type checking for that argument. You cannot use ANY with arguments passed by value. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE When neither BYVAL nor SEG is used, arguments are passed as near addresses (offsets). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This form of the DECLARE statement lets you reference procedures written in other languages. The DECLARE statement also causes the compiler to check the number and type of arguments used to invoke the procedure. A DECLARE statement can appear only in module-level code and affects the entire source file. The form of the parameter list determines whether or not argument type checking is done: Declaration Meaning ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DECLARE SUB First CDECL No argument checking is done when there is no parameter list. DECLARE SUB First CDECL () First has no parameters. Arguments in a CALL to First are flagged as an error. Empty parentheses indicate that the SUB or FUNCTION has no parameters. DECLARE SUB First CDECL (X AS LONG) First takes one long integer argument. When a parameter list appears, the number and type of the arguments are checked in each invocation. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A procedure that appears in a DECLARE statement can be invoked without the CALL keyword. See the entry for DECLARE (BASIC) for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE You cannot have fixed-length strings in DECLARE statements because only variable-length strings can be passed to SUB and FUNCTION procedures. Fixed-length strings can appear in an argument list but are converted to variable-length strings before being passed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Be careful when using the SEG keyword to pass arrays because BASIC may move variables in memory before the called routine begins execution. Anything in a CALL statement's argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables, arithmetic expressions, or arrays indexed without the use of intrinsic or user-defined functions. See Section 2.3.3, "Variable Storage Allocation," for a list of things that cause variable movement and for information about when to use near or far addresses for variables. ž See Also CALL, CALLS (Non-BASIC); DECLARE (BASIC) ž Example The following example shows a BASIC program that calls a short C function. The C program would be separately compiled and stored in a Quick library or explicitly linked to form the .EXE file. DEFINT a-z ' The function addone uses C argument passing and takes ' a single integer argument passed by value. DECLARE FUNCTION addone CDECL (BYVAL n AS INTEGER) INPUT x y=addone(x) PRINT "x and y are ";x;y END /* C function addone. Returns one more than the value of its integer argument. */ int far addone(n) int n; { return(++n); } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DEF FN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Defines and names a function ž Syntax 1 DEF FNname®(parameterlist)Æ = expression ž Syntax 2 DEF FNname®(parameterlist)Æ . . . FNname = expression . . . END DEF ž Remarks The DEF FN statement takes the following arguments: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ name A legal variable name, up to 40 characters long. This name, combined with FN, is the name of the Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  This name, combined with FN, is the name of the function. The name can include an explicit type-declaration character to indicate the type of value returned. Names that are the same except for the type-declaration character are distinct names. For example, the following are names of three different DEF FN functions: FNString$ FNString% FNString# To return a value from a DEF FN function, assign the value to the full function name: FNString$ = "No answer." Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  parameterlist A list of variable names, separated by commas. The syntax is explained below. When the function is called, BASIC assigns the value of each argument to its corresponding parameter. Function arguments are passed by value. DEF FN functions do not accept arrays, records, or fixed-length strings as arguments. expression In both syntaxes, expression is evaluated and the result is the function's value. In Syntax 1, expression is the entire body of the function and is limited to one logical line. When no expression is assigned to the name, the default return values are zero for a numeric DEF FN function, and the null string ("") for a string DEF FN function. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A parameterlist has the following syntax: variable ®AS typeÆ ®, variable ®AS typeÆÆ... A variable is any valid BASIC variable name. The type is INTEGER, LONG, SINGLE, DOUBLE, or STRING. You may also indicate a variable's type by including a type-declaration character (%, &, !, #, or $) in the name. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The FUNCTION procedure offers greater flexibility and control than the DEF FN function. See the entry for FUNCTION and Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You must define a DEF FN function with a DEF FN statement before the function is used. Calling a DEF FN function before it is defined produces an error message that reads Function not defined. DEF FN function definitions cannot appear inside other DEF FN definitions. In addition, DEF FN functions cannot be recursive. You must use the EXIT DEF statement to leave a multiline DEF FN early. DEF FN functions can only be used in the module in which they are defined. They cannot be referenced from other modules. A DEF FN function may share variables with the module-level code. Variables not in the parameterlist are globalÄÄtheir values are shared with the calling program. To keep a variable value local to a function definition, declare it in a STATIC statement. See Chapter 2, "Data Types," for a discussion of local and global variables. DEF FN can return either numeric or string values. DEF FN returns a string value if name is a string variable name, and a numeric value if name is a numeric variable name. Assigning a numeric value to a string function name or assigning a string value to a numeric function name produces the error message Type mismatch. If the function is numeric, DEF FNname returns a value with the precision specified by name. For example, if name specifies a double-precision variable, then the value returned by DEF FNname is double precision, regardless of the precision of expression. Because BASIC may rearrange arithmetic expressions for greater efficiency, avoid using DEF FN functions that change program variables in expressions that may be reordered. The following example may give different results: DEF FNShort I=10 FNShort=1 END DEF I=1 : PRINT FNShort + I + I If BASIC reorders the expression so FNShort is called after calculating (I+I), the result is 3 rather than 21. You can usually avoid this problem by isolating the DEF FN function call: I = 1 : X = FNShort : PRINT X + I + I Doing I/O operations in DEF FN functions used in I/O statements or doing graphics operations in DEF FN functions in graphics statements may cause similar problems. ž See Also EXIT, FUNCTION, STATIC ž Example The following example uses a DEF FN function to calculate the factorial of an input number (the factorial of 3 is 3*2*1): DEF FNFactorial#(X) STATIC Tmp#, I Tmp#=1 FOR I=2 TO X Tmp#=Tmp#*I NEXT I FNFactorial#=Tmp# END DEF INPUT "Enter a number: ",Num PRINT Num "factorial is" FNFactorial#(Num) ž Output Enter a number: 3 3 factorial is 6 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DEF SEG Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sets the current segment address for a subsequent PEEK function or a BLOAD, BSAVE, CALL ABSOLUTE, or POKE statement ž Syntax DEF SEG ®=addressÆ ž Remarks For BLOAD, BSAVE, CALL ABSOLUTE, PEEK, and POKE, address is used as the segment. The address is a numeric expression returning an unsigned integer in the range 0-65,535. A value outside this range produces the error message Illegal function call. The previous segment is retained if an error occurs. If you omit address, the BASIC data segment is used. Be sure to separate DEF and SEG with a space. Otherwise, BASIC interprets the statement to mean "assign a value to the variable DEFSEG." ž Differences From Basica In QuickBASIC, the CALL and CALLS statements do not use the segment address set by DEF SEG. ž Example The following program uses DEF SEG, PEEK, and POKE statements to turn the CAPS LOCK on and off: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE This program contains hardware-specific instructions. It works correctly on IBM PC, PC/XT(R), and PC/AT(R) computers. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DECLARE SUB CapsOn () DECLARE SUB CapsOff () DECLARE SUB PrntMsg (R%,C%,M$) CLS ' Turn Caps Lock on. CapsOn PrntMsg 24,1,"" ' Prompt for input to show keyboard has changed. LOCATE 12,10 LINE INPUT "Enter a string (all characters are caps): ",S$ ' Turn Caps Lock off. CapsOff PrntMsg 24,1," " PrntMsg 25,1,"Press any key to continue..." DO WHILE INKEY$="" : LOOP CLS END ' Turn Caps Lock on. SUB CapsOn STATIC ' Set segment to low memory. DEF SEG = 0 ' Set Caps Lock on (turn on bit 6 of &H0417). POKE &H0417,PEEK(&H0417) OR &H40 ' Restore segment. DEF SEG END SUB ' Turn Caps Lock off. SUB CapsOff STATIC DEF SEG=0 ' Set Caps Lock off (turn off bit 6 of &H0417). POKE &H0417,PEEK(&H0417) AND &HBF DEF SEG END SUB ' Print message at Row%, Col% without changing cursor. SUB PrntMsg (Row%, Col%, Message$) STATIC ' Save current cursor position. CurRow%=CSRLIN : CurCol%=POS(0) LOCATE Row%,Col% : PRINT Message$; ' Restore cursor position. LOCATE CurRow%,CurCol% END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DEFtype Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Set the default data type for variables, DEF FN functions, and FUNCTION procedures ž Syntax DEFINT letterrange ®,letterrangeÆ... DEFSNG letterrange ®,letterrangeÆ... DEFDBL letterrange ®,letterrangeÆ... DEFLNG letterrange ®,letterrangeÆ... DEFSTR letterrange ®,letterrangeÆ... ž Remarks The letterrange has the form: letter1®-letter2Æ where letter1 and letter2 are any of the uppercase or lowercase letters of the alphabet. Names beginning with the letters in letterrange have the type specified by the last three letters of the statement: integer (INT), long integer (LNG), single precision (SNG), double precision (DBL), or string (STR). For example, in the following program fragment, Message is a string variable: DEFSTR A-Q . . . Message="Out of stack space." The case of the letters in letterrange is not significant. All of the following statements are equivalent: DEFINT I-N DEFINT i-n DEFINT i-N A type-declaration character (%, &, !, #, or $) always takes precedence over a DEFtype statement. DEFtype statements do not affect record elements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE I!, I#, I&, I$, and I% are all distinct variables, and each may hold a different value. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica BASICA handles DEFtype statements differently. BASICA scans a statement each time before executing it. If the statement contains a variable without an explicit type (indicated by !, #, &, $, or %), the interpreter uses the current default type. In the example below, when BASICA interprets line 20, it determines that the current default type for variables beginning with I is integer. Line 30 changes the default type to single precision. When BASICA loops back to line 20, it rescans the line and uses IFLAG as a single-precision variable. 10 DEFINT I 20 PRINT IFLAG 30 DEFSNG I 40 GOTO 20 In contrast, QuickBASIC scans the text only once; once a variable appears in a program line, its type cannot be changed. ž Example See the example for the ABS function. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DIM Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares a variable and allocates storage space ž Syntax DIM ®SHAREDÆ variable®(subscripts)Æ®AS typeÆ®,variable®(subscripts)Æ®AStype ž Remarks The following list describes the parts of the DIM statement: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SHARED The optional SHARED attribute allows all procedures in a module to share arrays and simple variables. This differs from the SHARED statement, which affects only variables within a single SUB or FUNCTION. variable A BASIC variable name. subscripts The dimensions of the array. Multiple dimensions can be declared. The subscript syntax is described below. AS type Declares variable to be an elementary or user-defined type. The elementary types are INTEGER, LONG, SINGLE, DOUBLE, and STRING (variable or fixed). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Subscripts in DIM statements have the following form: ®lower TOÆ upper ®, ®lower TOÆ upperÆ... The TO keyword provides a way to indicate both the lower and the upper bounds of an array's subscripts. The following statements are equivalent (if there is no OPTION BASE statement): DIM A(8,3) DIM A(0 TO 8, 0 TO 3) DIM A(8,0 TO 3) With the TO keyword, you are no longer restricted to positive subscripts. You can use TO to specify any range of subscripts from -32,768 to 32,767: DIM A(-4 TO 10) DIM B(-99 TO -5,-3 TO 0) If you use an array in your program without including the array in a DIM statement, the maximum value of each subscript of the array is 10. If you use a subscript that is greater than the specified maximum, an error message appears that says Subscript out of range. The DIM statement initializes all elements of numeric arrays to zero and all the elements of string arrays to null strings. The fields of record variables are initialized to zero, including fixed-string fields. The maximum number of dimensions allowed in a DIM statement is 60. If you try to dimension an array variable with a DIM statement after you have referred to the array, an error message results that reads Array already dimensioned. It is good programming practice to put the required DIM statements at the beginning of a program, outside of any loops. STATIC AND DYNAMIC ARRAYS How you declare an array also determines whether it is static (allocated when the program is translated) or dynamic (allocated when the program is run). ž An array declared first in a COMMON statement is dynamic. ž Implicitly dimensioned arrays are static. ž Arrays dimensioned with numeric constants or CONST statement constants are static. ž Arrays dimensioned with variables as subscripts are dynamic. The following list shows the different combinations and results: Statement Result ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DIM A(0 TO 9) The array A is allocated as a static array if ›DYNAMIC is not in effect. DIM A(MAXDIM) If MAXDIM is defined in a CONST statement, A is a static array. If MAXDIM is a variable, then the array is a dynamic array and is only allocated when the program reaches the DIM statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ See Appendix F, "Metacommands," in Programming in BASIC and Chapter 2, "Data Types," in this manual for more information about static and dynamic arrays. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE If the array size exceeds 64K, if the array is not dynamic, and if the /AH option was not used, you may get an error message that reads Subscript out of range or one that reads Array too big. Reduce the size of the array or make the array dynamic and use the /AH command-line option. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TYPE DECLARATIONS In addition to declaring the dimensions of an array, the DIM statement may also be used to declare the type of a variable. For example, this statement declares the variable to be an integer, even though there is no type declaration character or DEFINT statement: DIM NumberOfBytes AS INTEGER The DIM statement provides a mechanism for declaring specific variables to be records. In the following example, the variable TopCard is declared as a record variable: TYPE Card Suit AS STRING*9 Value AS INTEGER END TYPE DIM TopCard AS Card You may also declare arrays of records: TYPE Card Suit AS STRING*9 Value AS INTEGER END TYPE DIM Deck(1 TO 52) AS Card See Appendix F, "Metacommands," in Programming in BASIC and Chapter 2, "Data Types," in this manual for more information. ž Differences From Basica BASICA executes a DIM statement when it encounters the statement in the program. The array is only allocated when the statement is executed, so all arrays in BASICA are dynamic. ž See Also ERASE, OPTION BASE, REDIM, SHARED ž Example The following example finds and prints the maximum and minimum of a set of values: ' Find the maximum and minimum of up to 20 values. ' ' Dimension an array to hold the values. CONST MAXDIM=20 DIM A(1 TO MAXDIM) ' Use DIM to set up two integer variables. ' All other variables are SINGLE. DIM NumValues AS INTEGER, I AS INTEGER ' Get the values. NumValues=0 PRINT "Enter values one per line. Type END to end." DO INPUT A$ IF UCASE$(A$)="END" OR NumValues>=MAXDIM THEN EXIT DO NumValues=NumValues+1 A(NumValues)=VAL(A$) LOOP ' Find the maximum and minimum values. IF NumValues>0 THEN Max=A(1) Min=A(1) FOR I=1 TO NumValues IF A(I)>Max THEN Max=A(I) IF A(I) Exes(I+1) THEN SWAP Exes(I),Exes(I+1) 'Exchange array elements. Exchange=I 'Record location of most END IF 'recent exchange. NEXT I Limit=Exchange 'Sort on next pass only to where 'last exchange was done. LOOP UNTIL Exchange=NOEXCH 'Sort until no elements 'are exchanged. END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DRAW Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Draws an object defined by stringexpression ž Syntax DRAW stringexpression ž Remarks The DRAW statement combines many of the capabilities of the other graphics statements into a graphics macro language, as described below under "Cursor-Movement Commands" and "Angle, Color, and Scale-Factor Commands." This macro language defines a set of characteristics that can be used to describe an image. These characteristics include motion (up, down, left, right), color, rotation angle, and scale factor. The stringexpression consists of these macro commands. CURSOR-MOVEMENT COMMANDS The following prefix commands can precede any of the movement commands: Prefix Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ B Move, but do not plot any points. N Move, but return to original position when done. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The following commands specify movement in units. The default unit size is one point; this unit size can be modified by the S command, which sets the scale factor. (S is described in "Angle, Color, and Scale-Factor Commands.") If no argument is supplied, the cursor is moved one unit. Each of the movement commands initiates movement from the current graphics position, which is usually the coordinate of the last graphics point plotted with another graphics macro-language command. The current position defaults to the center of the screen when a program is run. ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Movement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ U ®nÆ Move up n units. D ®nÆ Move down n units. L ®nÆ Move left n units. R ®nÆ Move right n units. E ®nÆ Move diagonally up and right n units. F ®nÆ Move diagonally down and right n units. Movement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  G ®nÆ Move diagonally down and left n units. H ®nÆ Move diagonally up and left n units. M x,y Move absolute or relative. If x is preceded by a plus (+) or minus (-), the movement is relative to the current point; that is, x and y are added to (or subtracted from) the coordinates of the current graphics position and connected with that position by a line. If no sign precedes x, the movement is absolute; that is, a line is drawn from the current cursor position to the point with coordinates x,y. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ANGLE, COLOR, AND SCALE-FACTOR COMMANDS The following commands let you change the appearance of a drawing by rotating it, changing colors, or scaling it: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Command Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A n Set angle of rotation n. The value of n may range from 0 to 3, where 0 is 0ų, 1 is 90ų, 2 is 180ų, and 3 is 270ų. Figures rotated 90ų or 270ų are scaled so they appear the same size using 0ų or 180ų on a monitor screen with a standard screen width-to-height ratio of 4/3. TA n Turn an angle of n degrees; n must be in the range -360 to 360. If n is positive, rotation is counterclockwise; if n is negative, rotation is clockwise. The following example uses TA to draw spokes: SCREEN 1 Command Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  SCREEN 1 FOR D=0 TO 360 STEP 10 DRAW "TA="+VARPTR$(D)+"NU50" NEXT D C n Set color to n. See COLOR, PALETTE, and SCREEN statements for discussions of valid colors, numbers, and attributes. S n Set scale factor n, which may range from 1 to 255. The scale factor multiplied by the distances given with U, D, L, R, or relative M commands gives the actual distance traveled. P paintcolor, The paintcolor is the paint color for a figure's bordercolor interior, while bordercolor is the paint color for the figure's border. Tile painting (painting an area with a graphic pattern) is not supported in DRAW. Command Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  in DRAW. X stringexpression Execute substring. This powerful command allows you to execute a second substring from a string. You may have one string expression execute another, which executes a third, and so on. Numeric arguments can be constants like 123 or variable names. QuickBASIC requires the "X" + VARPTR$(stringexpression) form of this command. (See "Differences from BASICA" below.) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica The DRAW statement requires modification of BASICA programs when used with QuickBASIC. Specifically, the compiler requires the VARPTR$ form for variables. Statements such as the following: DRAW "XA$" DRAW "TA = ANGLE" (where A$ and ANGLE are variables) must be changed as follows: DRAW "X" + VARPTR$(A$) DRAW "TA =" + VARPTR$(ANGLE) when using the compiler. The compiler does not support the Xstringexpression command. However, you may execute a substring by appending the character form of the address to X. For example, the following two statements are equivalent. The first statement works when within the environment and when using the compiler; the second works only within the environment. DRAW "X" + VARPTR$(A$) DRAW "XA$" ž Examples The following program draws a triangle's outline in magenta and paints the interior cyan: SCREEN 1 DRAW "C2" 'Set color to magenta. DRAW "F60 L120 E60" 'Draw a triangle. DRAW "BD30" 'Move down into the triangle. DRAW "P1,2" 'Paint interior. The following example shows different ways of using the M macro command: with absolute movement and relative movement; using string-variable arguments; and using numeric-variable arguments: SCREEN 2 'Absolute movement DRAW "M 50,80" DRAW "M 80,50" 'Relative movement DRAW "M+40,-20" DRAW "M-40,-20" DRAW "M-40,+20" DRAW "M+40,+20" 'Using a string variable. X$ = "400" : Y$ = "190" DRAW "M" + X$ + "," + Y$ 'Using numeric variables (note the two "=" signs). A = 300 : B = 120 DRAW "M="+VARPTR$(A)+",="+VARPTR$(B) The following example draws a clock on the screen using the TIME$ function: ' Declare procedure. DECLARE SUB Face (Min$) ' Select 640 x 200 pixel high-resolution graphics screen. SCREEN 2 DO ' Clear the screen. CLS ' Get the string containing the minutes value. Min$ = MID$(TIME$,4,2) ' Draw the clock face. Face Min$ ' Wait until the minute changes or a key is pressed. DO ' Print the time at the top of the screen. LOCATE 2,37 PRINT TIME$ ' Test for a key press. Test$ = INKEY$ LOOP WHILE Min$ = MID$(TIME$,4,2) AND Test$ = "" ' End the program when a key is pressed. LOOP WHILE Test$ = "" END ' Draw the clock face. SUB Face (Min$) STATIC LOCATE 23,30 PRINT "Press any key to end" CIRCLE (320,100),175 ' Convert strings to numbers. Hr = VAL(TIME$) Min = VAL(Min$) ' Convert numbers to angles. Little = 360 - (30 * Hr + Min/2) Big = 360 - (6*Min) ' Draw the hands. DRAW "TA=" + VARPTR$(Little) + "NU40" DRAW "TA=" + VARPTR$(Big) + "NU70" END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ END Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Ends a BASIC program, procedure, or block ž Syntax END ®{DEF | FUNCTION | IF | SELECT | SUB | TYPE}Æ ž Remarks There are several ways to use the END statement, as described in the following list: Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ END DEF Ends a multiline DEF FN function definition. You must use END DEF with a multiline DEF FN. END FUNCTION Ends a FUNCTION procedure definition. You must use END FUNCTION with FUNCTION. END IF Ends a block IF...THEN...ELSE statement. You must use END IF with block IF...THEN...ELSE. END SELECT Ends a SELECT CASE block. You must use END SELECT with a SELECT CASE statement. END SUB Ends a BASIC subprogram. You must use END SUB with SUB. END TYPE Ends a user-defined type definition. You must use END TYPE with TYPE. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ By itself, the END statement stops program execution and closes all files. In a stand-alone program, END returns control to the operating system. When running inside the QuickBASIC environment, END returns you to that environment. The compiler always assumes an END statement at the conclusion of any program, so omitting an END statement at the end of a program still produces proper program termination. You may place END statements anywhere in the program to end program execution. ž See Also DEF FN; FUNCTION; IF...THEN...ELSE; SELECT CASE; SUB; TYPE ž Example The following example uses a subprogram to query the user about continuing some action. If the user enters n or N the subprogram ends the program. DO . . . CALL ContinueQuery LOOP SUB ContinueQuery STATIC DO INPUT "Continue (Y or N)"; Response$ R$=UCASE$(LEFT$(Response$,1)) IF R$="N" THEN END IF R$="Y" THEN EXIT DO BEEP LOOP END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ENVIRON$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Retrieves an environment string from the DOS environment-string table ž Syntax ENVIRON$ (environmentstring) ENVIRON$ (n) ž Remarks The environmentstring is a string constant or variable containing the name of an environment variable. The argument n is a numeric expression. If you specify an environmentstring name, but it cannot be found in the environment-string table, or there is no text following it, then ENVIRON$ returns a null string. Otherwise, ENVIRON$ returns the text following the equal sign in the environment-string table. If you specify a numeric argument (n), the nth string in the environment-string table is returned. In this case, the string includes all of the text, including the environmentstring name. If the nth string does not exist, ENVIRON$ returns a null string. The n argument can be any numeric expression; it is rounded to an integer. ž Example The following example prints the current environment-string table settings: I = 1 DO WHILE ENVIRON$(I) <> "" PRINT ENVIRON$(I) I = I + 1 LOOP ž Output COMSPEC=C:\COMMAND.COM TMP=c:\tmp PATH=C:\TOOLS;C:\BIN PROMPT=›ec4$l›ec7$p›ec4$g›ec7›eb1 INIT=c:\tools LIB=c:\lib INCLUDE=c:\include ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ENVIRON Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Modifies a parameter in the DOS environment-string table ž Syntax ENVIRON stringexpression ž Remarks The stringexpression must be of the form parameterid=text, or the form parameterid text. Everything to the left of the equal sign or space is assumed to be a parameter, and everything to the right, text. If the parameterid has not previously existed in the environment-string table, it is appended to the end of the table. If a parameterid exists in the table when the ENVIRON statement is executed, it is deleted and the new parameterid is appended to the end of the table. The text string is the new parameter text. If the text is a null string ("") or a semicolon (";"), then the existing parameter is removed from the environment-string table and the remaining body of the table is compressed. DOS discards the environment-string table modified by this function when your program ends. The environment-string table is the same as it was before your program ran. You may use this statement to change the PATH parameter for a "child" process (a program or command started by a SHELL statement) or to pass parameters to a child by inventing a new environment parameter. Errors in environment-string tables include parameters that are not strings and lack of free space. An Out of memory error message is printed when no more space can be allocated to the environment-string table. The amount of free space in the table is usually quite small. ž See Also ENVIRON$, SHELL ž Example The following example changes the value of the PATH environment variable to that shown: 'Change value of PATH environment variable. ENVIRON "PATH=A:\SALES;A:\ACCOUNTING" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ EOF Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Tests for the end-of-file condition ž Syntax EOF(filenumber) ž Remarks The EOF function returns -1 (true) if the end of a sequential file has been reached. Use the EOF function to test for end-of-file while inputting data. In this way you may avoid the Input past end error message. When EOF is used with random-access or binary files, it returns "true" if the last executed GET statement was unable to read an entire record. This happens because of an attempt to read beyond the end of the file. EOF cannot be used with the BASIC devices SCRN:, KYBD:, CONS:, and LPTn:. When you use EOF with a communications device, the definition of the end-of-file condition is dependent on the mode (ASCII or binary) in which you opened the device. In ASCII mode, EOF is false until you receive CTRL+Z, after which it remains true until you close the device. In binary mode, EOF is true when the input queue is empty (LOC(n)=0). It becomes "false" when the input queue is not empty. ž Example The fragment below reads single-precision values from a file until all values have been read: DIM M(0 TO 2000) OPEN "DATA" FOR INPUT AS 1 C = 0 DO WHILE NOT EOF(1) AND C <= 2000 INPUT #1, M(C) C = C+1 LOOP . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ERASE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reinitializes the elements of static arrays; deallocates dynamic arrays ž Syntax ERASE arrayname ®,arrayname...Æ ž Remarks The arrayname arguments are the names of arrays to erase. ERASE has different effects on static and dynamic arrays. The ERASE statement sets the elements of a static array to zeros in the case of a numeric array or null strings ("") in the case of a string array. If the array is an array of records, the ERASE statement sets all elements of each record to zeros, including fixed-string elements. However, using ERASE on a dynamic array frees the memory used by the array. Before your program can refer to the dynamic array again, it must first redimension the array with a DIM or REDIM statement. Redimensioning an array with a DIM statement without first erasing it produces a duplicate definition run-time error message that reads Array already dimensioned. The ERASE statement is not required when arrays are redimensioned with REDIM. See Chapter 2, "Data Types," in this manual and Appendix F, "Metacommands," in Programming in BASIC for more information on declaring dynamic and static arrays. ž See Also DIM, REDIM ž Example The following program fragment shows the use of ERASE with the ›DYNAMIC and ›STATIC metacommands: REM ›DYNAMIC DIM A(100,100) . . . 'This deallocates array A. ERASE A 'Redimension array A. REDIM A(5,5) REM ›STATIC DIM B(50,50) . . . 'This sets all elements of B equal to zero. 'B still has the dimensions assigned by DIM. ERASE B ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ERDEV, ERDEV$ Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Provides device-specific status information after an error ž Syntax ERDEV ERDEV$ ž Remarks ERDEV is an integer function that returns an error code from the last device to declare an error. ERDEV$ is a string function that returns the name of the device generating the error. Because ERDEV and ERDEV$ return meaningful information only after an error, they are usually used in error handlers specified by an ON ERROR statement. ERDEV and ERDEV$ cannot be used on the left side of an assignment. ERDEV is set by the critical error handler (interrupt 24H) when DOS detects an error that prevents continuing. The value of ERDEV is a bit-encoded value containing the DOS error information. The lower eight bits (first byte) contain the DOS error code, a value from 0 to 12. The upper eight bits (second byte) contain bits 15, 14, 13, XX, 3, 2, 1, and 0, in that order, of the device-attribute word. XX indicates the bit is always zero. See the Microsoft MS-DOS Programmer's Reference for more information about device-attribute words. ž See Also ERR, ERL; ON ERROR ž Example The following example prints the values of ERDEV and ERDEV$ when an error occurs: DEFINT A-Z ' Indicate first line of error handler. ON ERROR GO TO ErrorHandler ' Attempt to open the file. OPEN "A:JUNK.DAT" FOR INPUT AS #1 END ' Error handling routine. ' Prints values of ERDEV and ERDEV$ and dies. ErrorHandler: PRINT "ERDEV value is ";ERDEV PRINT "Device name is ";ERDEV$ ON ERROR GOTO 0 ž Output Running the program with drive A unlatched produces the following output (2 is the error code for "Drive not ready"): ERDEV value is 2 Device name is A: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ERR, ERL Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Return error status ž Syntax ERR ERL ž Remarks After an error, the function ERR returns the code for the error, and the ERL function returns the line number where the error occurred. Because ERR and ERL return meaningful values only after an error, they are usually used in error-handling routines to determine the error and the corrective action. Because ERL and ERR are functions, you cannot use them on the left-hand side of an assignment statement. However, you may indirectly set them with the ERROR statement. ž Differences From Basica The ERL function returns only the line number, not line label, located before the line producing the error. If your program has no line numbers, ERL always returns 0. ž See Also ERDEV, ERROR, ON ERROR, RESUME ž Example See the example for ON ERROR. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ERROR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Simulates the occurrence of a BASIC error or allows the user to define error codes ž Syntax ERROR integerexpression ž Remarks The integerexpression represents the error code. It must be greater than 0 and less than or equal to 255. If the integerexpression is an error code already used by BASIC, then the ERROR statement simulates the occurrence of that error and prints the corresponding error message. To define your own error code, use a value that is greater than any used by the standard BASIC error codes. (Start at 255 and work down to maintain compatibility with future Microsoft BASIC error codes.) If an ERROR statement specifies a code for which no error message has been defined, the message Unprintable error is printed. Executing an ERROR statement for which there is no error-handling routine causes an error message to be printed and execution to halt. ž See Also ERR, ERL; ON ERROR; RESUME ž Example The following fragment uses an ERROR statement to trap a user input error: ON ERROR GOTO Handler OpenFile: INPUT "Name of file to update";FileSpec$ IF FileSpec$ = "" THEN END OPEN FileSpec$ FOR INPUT AS #1 PRINT "The first five lines of ";FILESPEC$;" are:" : PRINT FOR I = 1 TO 5 LINE INPUT #1, Temp$ PRINT Temp$ NEXT PRINT : INPUT "Is this the correct file";R$ 'Define error 200. IF LEFT$(R$,1) <> "y" THEN ERROR 200 . . . END Handler: 'Error-handling routine. Number = ERR 'Run-time error for "file not found." IF Number = 53 THEN CLOSE #1 PRINT "File not in this directory" PRINT "Enter new file spec ([d:]xxx...xxx) or" PRINT "press to end program" RESUME OpenFile ELSEIF Number = 200 THEN 'User entered "n" CLOSE #1 RESUME OpenFile ELSE ERROR Number 'Error other than 53 or 200. ON ERROR GOTO 0 'Print message, disable error END IF 'handling, and stop program. ž Output Name of file to update? c:novelallenadv.txt File not in this directory Enter new file spec ([d:]xxx...xxx) or press to end program Name of file to update? c:toryallenadv.txt The first five lines of c:toryallenadv.txt are: Allen gripped the microphone. Small beads of perspiration glistened on his forehead like cheap pearls. He knew that what he said would change his life and the lives of those he loved. In a trembling voice, Is this the correct file? y ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ EXIT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Exits a DEF FN function, DO...LOOP or FOR...NEXT loop, FUNCTION, or SUB ž Syntax EXIT {DEF | DO | FOR | FUNCTION | SUB } ž Remarks There are several ways to use the EXIT statement as described in the following list: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ EXIT DEF Causes an immediate exit from the executing DEF FN function. Program execution continues where the DEF FN function was invoked. EXIT DO Provides an alternative exit from a DO...LOOP. Can be used only inside a DO...LOOP statement; EXIT DO transfers control to the statement following the LOOP statement. When used within nested DO...LOOP statements, transfers out of the immediately enclosing loop. Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  EXIT FOR Provides another way to exit a FOR...NEXT loop. May appear only in a FOR...NEXT loop; transfers control to the statement following the NEXT statement. When used within nested FOR...NEXT loops, transfers out of the immediately enclosing loop. EXIT FUNCTION Causes an immediate exit from a FUNCTION procedure. Program execution continues where the FUNCTION was invoked. Can only be used in a FUNCTION procedure. EXIT SUB Immediately exits a SUB procedure. Program execution continues with the statement after the CALL statement. Can only be used in a SUB procedure. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  None of the EXIT statements define the end of the structure in which they are used. EXIT statements only provide an alternative exit from the structure. ž See Also DEF FN; DO...LOOP; FOR...NEXT; FUNCTION; SUB ž Examples See the third example for STATIC for a use of EXIT SUB. The following subprogram is an extended RTRIM$ that removes trailing blanks, tabs, carriage returns, and line feeds from a string. The subprogram begins looking at the end of the string and uses EXIT FOR to jump out of the loop when the first printing character is found. ' Rtrim removes trailing blanks, tabs, carriage returns, ' and line feeds from a string. SUB Rtrim(S$) STATIC J=0 ' Begin at the end of the string and find the first ' character that isn't a blank, tab, carriage return, or ' line feed. FOR I=LEN(S$) TO 1 STEP -1 C$=MID$(S$,I,1) IF C$<>" " AND C$<>CHR$(9) AND C$<>CHR$(10) AND C$<>CHR$(13) THEN J=I EXIT FOR END IF NEXT I ' Remove the unwanted trailing characters. S$=LEFT$(S$,J) END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ EXP Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Calculates the exponential function ž Syntax EXP(x) ž Remarks The EXP function returns e (the base of natural logarithms) to the power of x. The exponent x must be less than or equal to 88.02969. A value of x greater than 88.02969 produces an Overflow error message. The calculation of EXP is performed in single precision by default; if the argument x is double precision, EXP is calculated in double precision. ž See Also LOG ž Example The following program uses the EXP function to calculate the growth of a bacterial colony over a 15-day period. Since the growth of the population is related to its ever-changing size, its growth is exponential. INPUT "Initial bacterial population"; Colony0 INPUT "Growth rate per day as a percentage of population"; Rate R = Rate/100 : Form$="## ###,###" PRINT : PRINT "Day Population" FOR T = 0 TO 15 STEP 5 PRINT USING Form$; T, Colony0 * EXP(R*T) NEXT ž Output Initial bacterial population? 10000 Growth rate per day as a percentage of population? 10 Day Population 0 10,000 5 16,487 10 27,183 15 44,817 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FIELD Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allocates space for variables in a random-access file buffer ž Syntax FIELD ®#Æfilenumber, fieldwidth AS stringvariable... ž Remarks The following list describes the FIELD statement's arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filenumber The number used in the file's OPEN statement fieldwidth The width of the field in the record stringvariable The string variable that contains the date read from a record or data that is used in an assignment when information is written to a record ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The total number of bytes that you allocate in a FIELD statement must not exceed the record length that you had specified when opening the file. Otherwise, an error message is generated that reads FIELD overflow. (The default record length is 128 bytes.) Any number of FIELD statements may be executed for the same file. All FIELD statements that have been executed remain in effect at the same time. All field definitions for a file are removed when the file is closed; that is, all strings defined as fields associated with the file are set to null. Do not use a variable name defined as a field in an INPUT or assignment statement if you wish the variable to remain a field. Once a variable name is a field, it points to the correct place in the random-access file buffer. If a subsequent INPUT or assignment statement with that variable name is executed, the variable's pointer no longer refers to the random-access record buffer, but to string space. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE BASIC's record variables and extended OPEN statement syntax provide a more convenient way to use random-access files. See Chapter 3, "File and Device I/O," in Programming in BASIC for an extended discussion of using record variables for file I/O. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica When a random-access file is closed with a CLOSE or RESET statement in a compiled program, all variables that are fields associated with that file are reset to null strings. When a random-access file is closed in a BASICA program, variables that are fields retain the last value assigned to them by a GET statement. ž See Also GET, LSET, OPEN, PUT, RSET ž Example This example illustrates a random-access file buffer with multiple definitions. In the first FIELD statement, the 67-byte buffer is broken up into five separate variables for name, address, city, state, and zip code. In the second FIELD statement, the same buffer is assigned entirely to one variable, PLIST$. The remainder of this example checks to see if ZIP$, which contains the zip code, falls within a certain range; if it does, the complete address string is printed. ' Define field and record lengths with constants. CONST LNAML=25, ADDRL=25, CTYL=10, STL=2, ZIPL=5 CONST RECLEN=LNAML+ADDRL+CTYL+STL+ZIPL OPEN "MAILLIST" FOR RANDOM AS #1 LEN=RECLEN FIELD #1, LNAML AS Lnam$, ADDRL AS Addr$, CTYL AS Cty$, STL AS St$, ZIPL AS Zip$ FIELD #1, RECLEN AS Plist$ GET #1, 1 ' Read the file, looking for zip codes in the range 85699 to ' 85801. DO WHILE NOT EOF(1) Zcheck$ = Zip$ IF (Zcheck$ >= "85699" AND Zcheck$ <= "85801") THEN Info$ = Plist$ PRINT LEFT$(Info$,25) PRINT MID$(Info$,26,25) PRINT RIGHT$(Info$,17) END IF GET #1 LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FILEATTR Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns information about an open file ž Syntax FILEATTR(filenumber,attribute) ž Remarks The FILEATTR function takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filenumber The number of an open file. This is the same number used in the OPEN statement. You can use a numeric expression as long as it evaluates to the number of an open file. attribute Indicates the type of information to return. When attribute is 1, FILEATTR returns a code indicating a file's mode (see below). When attribute is 2, FILEATTR returns the file's DOS file handle. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table R.2 lists the return values and corresponding file modes when attribute is 1. Table R.2 FILEATTR Mode Codes Return Value Mode ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1 INPUT 2 OUTPUT 4 RANDOM 8 APPEND 32 BINARY ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also OPEN ž Example The following example opens two files and prints out the DOS file handles and modes returned by FILEATTR: OPEN "tempfile.dat" FOR APPEND AS #1 OPEN "tempfl2.dat" FOR RANDOM AS #2 PRINT "Number Handle Mode" PRINT TAB(2);1;TAB(10);FILEATTR(1,2);TAB(15);FILEATTR(1,1) PRINT TAB(2);2;TAB(10);FILEATTR(2,2);TAB(15);FILEATTR(2,1) END ž Output Number Handle Mode 1 5 8 2 6 4 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FILES Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Prints the names of files residing on the specified disk ž Syntax FILES ®filespecÆ ž Remarks The filespec is a string variable or constant that includes either a file name or a path name, and an optional device designation. If you omit filespec, the FILES statement lists all the files in the current directory. You may use the DOS wild card charactersÄÄquestion marks (?) or asterisks (*). A question mark matches any single character in the file name or extension. An asterisk matches one or more characters starting at that position. If you use a filespec without an explicit path, the current directory is the default. Note that, regardless of the path name contained in filespec, the header printed by FILES is always the current directory. ž Examples The following statements illustrate the use of FILES: FILES 'Shows all files on the current directory. FILES "*.BAS" 'Shows all files with the extension .BAS. FILES "B:*.*" 'Shows all files on drive B. FILES "B:" 'Equivalent to "B:*.*". FILES "TEST?.BAS" 'Shows all five-letter files whose names 'start with "TEST" and end with the .BAS 'extension. FILES "\SALES" 'If SALES is a directory, this statement 'displays all files in SALES; if SALES is 'a file in the current directory, this 'statement displays the name SALES. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FIX Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the truncated integer part of x ž Syntax FIX(x) ž Remarks The x is a numeric expression. FIX(x) is equivalent to SGN(x)*INT(ABS(x)). The difference between FIX and INT is that for negative x, FIX returns the first negative integer greater than x, while INT returns the first negative integer less than x. ž See Also CINT, INT ž Example The following four statements illustrate the differences between INT and FIX: PRINT INT(-99.8) PRINT FIX(-99.8) PRINT INT(-99.2) PRINT FIX(-99.2) ž Output -100 -99 -100 -99 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FOR...NEXT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Repeats a group of instructions a specified number of times ž Syntax FOR counter = start TO end ®STEP incrementÆ . . . NEXT ®counter ®,counter...ÆÆ ž Remarks The FOR statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ counter A numeric variable used as the loop counter. The variable cannot be an array element or a record element. start The initial value of the counter. end The final value of the counter. increment The amount the counter is incremented each time through the loop. If you do not specify STEP, increment defaults to one. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A FOR...NEXT loop executes only if start and end are consistent with increment. If end is greater than start, increment must be positive. If end is less than start, increment must be negative. This is checked at run-time by comparing the sign of (end - start) with the sign of step. If both have the same sign, the FOR...NEXT loop is entered. If not, the entire loop is skipped over. Within the FOR...NEXT loop, the program lines following the FOR statement are executed until the NEXT statement is encountered. Then counter is changed by the amount specified by STEP, and compared with the final value, end. If counter is less than or equal to end, control returns to the statement after the FOR statement and the process repeats. If counter is greater than end, the loop is exited; execution continues with the statement following the NEXT statement. (If STEP is negative, the loop repeats until counter is less than end.) If start and end have the same value, the loop executes once, regardless of the value of STEP. If STEP is zero, the loop repeats indefinitely. Avoid changing the value of counter within the loop. Changing the loop counter is poor programming practice; it makes the program more difficult to read and debug. You can nest FOR...NEXT loops; that is, you can place a FOR...NEXT loop within another FOR...NEXT loop. To ensure that nested loops work properly, give each loop a unique variable name as its counter. The NEXT statement for the inside loop must appear before the NEXT statement for the outside loop. The following construction is correct: FOR I = 1 TO 10 FOR J = 1 TO 10 FOR K = 1 TO 10 . . . NEXT K NEXT J NEXT I A NEXT statement with the form NEXT K, J, I is equivalent to the following sequence of statements: NEXT K NEXT J NEXT I The EXIT FOR statement is a convenient alternative exit from FOR...NEXT loops. See the EXIT FOR statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE If you omit the variable in a NEXT statement, the NEXT statement matches the most recent FOR statement. If a NEXT statement is encountered before its corresponding FOR statement, an error message is generated that reads NEXT without FOR. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica Unlike BASICA, QuickBASIC supports double-precision control values (start, end, and counter) in its FOR...NEXT loops. However, if the control values fall within the range for integers, you should use integer control values for maximum speed. ž Example The following example prints the first 11 columns of Pascal's triangle: 'Print the first MAXCOL columns of Pascal's Triangle, in which 'each number is the sum of the number immediately above it 'and the number immediately below it in the preceding column. CONST MAXCOL=11 DIM A(MAXCOL,MAXCOL) FOR M = 1 TO MAXCOL A(M,1) = 1 : A(M,M) = 1 'Top and bottom of each column is 1. NEXT FOR M = 3 TO MAXCOL FOR N = 2 TO M-1 A(M,N) = A(M-1,N-1) + A(M-1,N) NEXT NEXT Startrow = 13 'Go to the middle of the screen. FOR M = 1 TO MAXCOL Col = 6 * M Row = Startrow FOR N = 1 TO M LOCATE Row,Col : PRINT A(M,N) Row = Row + 2 'Go down 2 rows to print next number. NEXT PRINT Startrow = Startrow - 1 'Next column starts 1 row above NEXT 'preceding column. ž Output 1 1 1 10 1 9 1 8 45 1 7 36 1 6 28 120 1 5 21 84 1 4 15 56 210 1 3 10 35 126 1 2 6 20 70 252 1 3 10 35 126 1 4 15 56 210 1 5 21 84 1 6 28 120 1 7 36 1 8 45 1 9 1 10 1 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FRE Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the amount of available memory ž Syntax 1 FRE(numeric-expression) ž Syntax 2 FRE(stringexpression) ž Remarks The FRE function returns the following values when it has a numeric argument (numeric-expression): Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ -1 The size, in bytes, of the largest nonstring array that could be dimensioned -2 The amount, in bytes, of unused stack space available to the program Any other numeric value The size of the next free block of string storage ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When the argument is a string expression (stringexpression), FRE returns the size, in bytes, of the free string storage. Before FRE returns the number of free bytes, it compacts the free string storage into a single block. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE FRE(-2) returns meaningful values only when a program is executing. Values returned by FRE(-2) are not accurate when the function is called from the Immediate window, during program tracing, or when watching a variable. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Example The following example shows some of the values FRE returns before and after dimensioning an array: ' ›DYNAMIC PRINT "Before dimensioning arrays: " FRE(""),FRE(0),FRE(-1) DIM LARGE%(150,150), BIG$(5000) PRINT "After dimensioning arrays: " FRE(""),FRE(0),FRE(-1) ž Output The actual values FRE will return on your own computer may be different. Before dimensioning arrays: 58420 58420 322120 After dimensioning arrays: 38404 38404 276496 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FREEFILE Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the next free BASIC file number ž Syntax FREEFILE ž Remarks The FREEFILE function returns the next valid unused file number. You can use this function to avoid having SUB or FUNCTION procedures use file numbers that are already in use. ž Example The example below uses FREEFILE to obtain a file number for opening a file: INPUT "Enter file name ", Filename$ Filenum = FREEFILE OPEN Filename$ for Input as Filenum PRINT Filename$;" Opened as File # "; Filenum ž Output Enter file name: Data.dat Data.dat Opened as File # 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ FUNCTION Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares the name, the parameters, and the code that form the body of a FUNCTION procedure ž Syntax FUNCTION name ®(parameterlist)Æ®STATICÆ . . . name = expression . . . END FUNCTION ž Remarks The following list describes the parts of the FUNCTION statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ name The name of the function. FUNCTION names follow the same rules as BASIC variable names and can include a type-declaration character (%, &, !, #, or $). Note that the type of the name determines the type of value the function returns. For example, to create a function that returns a string, you would include a dollar sign in the name or give it a name defined as a string name by a DEFSTR statement. parameterlist The list of variables, separated by commas, passed to the FUNCTION. The parameters are passed by reference, so any change to a parameter's value inside the function changes its value in the calling program. STATIC Indicates that the function's local variables are to be saved between calls. Without STATIC, the local variables are allocated each time the Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  local variables are allocated each time the function is invoked, and the variables' values are lost when the function returns to the calling program. The STATIC attribute does not affect variables that are used in a FUNCTION but declared outside the FUNCTION in DIM or COMMON statements by use of the SHARED attribute. expression The return value of the function. A FUNCTION returns a value by assigning a value to the function name. If no value is assigned to the FUNCTION name, the FUNCTION returns a default value: a numeric function returns a value of zero, and a string function returns the null string (""). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A parameterlist has the following syntax: variable®( )Æ® AS typeÆ®, variable®( )Æ® AS typeÆ...Æ A variable is any valid BASIC variable. The optional type can be either INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. Earlier versions of BASIC required the number of dimensions in parentheses after an array name. The number of dimensions is no longer required. Only the parentheses are required to indicate the parameter is an array. For example, the following statement indicates that both Keywords$ and KeywordTypes are arrays: FUNCTION ParseLine(Keywords$(),KeywordTypes()) A FUNCTION procedure is like a SUB procedure: it can accept parameters, perform a series of statements, and change the values of its parameters. Unlike a SUB, a FUNCTION is used in an expression in the same manner as a BASIC intrinsic function. Like SUB procedures, FUNCTION procedures use local variables. Any variable not in the parameter list is local to the FUNCTION unless it is declared as a shared variable in a SHARED statement, or unless the variable appears in a DIM or COMMON statement with the SHARED attribute. To return a value from a function, assign the value to the function name. For example, in a function named BinarySearch, you might assign the value of the constant FALSE to the name to indicate the value was not found: FUNCTION BinarySearch(...) CONST FALSE=0 . . . ' Value not found. Return a value of FALSE. IF Lower>Upper THEN BinarySearch=FALSE EXIT FUNCTION END IF . . . END FUNCTION Using the STATIC keyword slightly increases execution speed. STATIC is not usually used with recursive FUNCTION procedures. See the examples below. The EXIT FUNCTION statement provides an alternative exit from a FUNCTION. See the EXIT statement. Because BASIC may rearrange arithmetic expressions to attain 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. QuickBASIC FUNCTION procedures are recursiveÄÄthey can call themselves to perform a given task. See the second example below and Chapter 4, "Programs and Modules." ž See Also DECLARE (BASIC), DEF FN, EXIT, STATIC, SUB ž Examples The following example uses a function to count the number of vowels in a string: ' Function definition. FUNCTION NumVowels (A$) STATIC Num = 0 ' Go through A$ a character at a time. FOR I = 1 TO LEN (A$) C$ = UCASE$ (MID$(A$,I,1)) IF INSTR ("AEIOU",C$)<> 0 THEN ' Find a vowel--count it. Num = Num + 1 END IF NEXT I NumVowels = Num END FUNCTION A$ = "The ultimate answer to the ultimate question is 42" PRINT CHR$(34)+A$+CHR$(34) PRINT "The number of vowels in the string is :";NumVowels (A$) ž Output "The ultimate answer to the ultimate question is 42" The number of vowels in the string is : 18 The following example uses a recursive function (a function that calls itself) to find the length of a string. Notice that the STATIC keyword is not used. FUNCTION StrLen(X$) IF X$ = "" THEN ' The length of a null string is zero. StrLen=0 ELSE ' Non-null string--make a recursive call. ' The length of a non-null string is 1 ' plus the length of the rest of the string. StrLen=1+StrLen(MID$(X$,2)) END IF END FUNCTION LINE INPUT "Enter a string: ",InString$ PRINT "The string length is"; StrLen(InString$) ž Output Enter a string: Once upon a time The string length is 16 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ GET StatementÄÄGraphics ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Stores graphic images from the screen ž Syntax GET ®STEPÆ(x1,y1) - ®STEPÆ(x2,y2),arrayname®(indices)Æ ž Remarks The list below describes the parts of the GET statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ x1,y1,x2,y2 Coordinates marking a rectangular area on the screen. The placeholders x1, y1, x2, and y2 are numeric expressions that are the coordinates of diagonally opposite corners of the rectangle. STEP Keyword indicating that coordinates are relative to the most recently plotted point. For example, if the last point plotted were (10,10), then the actual coordinates referred to by STEP (5,10) would be (5+10,10+10) or (15,20). If the second coordinate pair in a GET statement has a STEP argument, it is relative to the first coordinate Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  argument, it is relative to the first coordinate pair in the statement. arrayname Name assigned to the array that holds the image. This array can be of any numeric type; its dimensions must be large enough to hold the entire image. indices Numeric constants or variables indicating the element of the array where the saved image starts. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The GET statement transfers a screen image into the array specified by arrayname. The PUT statement, associated with GET, transfers the image stored in the array onto the screen. The following formula gives the required size of the array in bytes: 4 + INT(((x2 - x1 + 1) * (bits-per-pixel-per-plane) + 7)/8) * planes * ((y2 - y1) + 1) The bits-per-pixel-per-plane and planes values depend on the specification set in the SCREEN statement. Table R.3 shows the number of bits per pixel per plane and the number of planes for each screen mode. Table R.3 Values for Bits per Pixel per Plane and for Planes ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Bits per Pixel Screen Mode per Plane Planes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1 2 1 2 1 1 7 1 4 8 1 4 Bits per Pixel Screen Mode per Plane Planes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  8 1 4 9 1 2 (if 64K of EGA memory) 4 (if > 64K EGA memory) 10 1 2 11 1 1 12 1 4 13 8 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The bytes per element of an array are as follows: ž Two bytes for an integer array element ž Four bytes for a long-integer array element ž Four bytes for a single-precision array element ž Eight bytes for a double-precision array element For example, suppose you wanted to use the GET statement to store an image in high resolution (SCREEN 2). If the coordinates of the upper-left corner of the image are (0,0), and the coordinates of the lower- right corner are (32,32), then the required size of the array in bytes is 4 + INT((33 * 1 + 7)/8) * 1 * (33), or 169. This means an integer array with 85 elements would be large enough to hold the image. Unless the array type is integer or long, the contents of an array after a GET appear meaningless when inspected directly. Examining or manipulating noninteger arrays containing graphics images may cause run-time errors. One of the most useful things that can be done with GET and PUT is animation. See Chapter 5, "Graphics," in Programming in BASIC for a discussion of animation. ž See Also PUT (Graphics) ž Example See the example for BSAVE. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ GET StatementÄÄFile I/O ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads from a disk file into a random-access buffer or variable ž Syntax GET ®#Æfilenumber®,®recordnumberÆ®,variableÆÆ ž Remarks The following list describes the GET statement's arguments: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filenumber The number used in the OPEN statement to open the file. recordnumber For random-access files, the number of the record to be read. For binary-mode files, the byte position in the file where reading starts. The first record or byte position in a file is 1. If you omit recordnumber, the next record or byte (the one after the last GET or PUT, or the one pointed to by the last SEEK) is read into the buffer. The largest possible record number is 2^31-1, or 2,147,483,647. Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  2^31-1, or 2,147,483,647. variable The variable used to receive input from the file. If you use a variable, you do not need to use CVD, CVL, CVI, or CVS to convert record fields to numbers. You may not use a FIELD statement with the file if you use the variable argument. For random-access files, you can use any variable as long as the length of the variable is less than or equal to the length of the record. Usually, a record variable defined to match the fields in a data record is used. For binary-mode files, you can use any variable. The GET statement reads as many bytes as there are in the variable. When you use a variable-length string variable, the statement reads as many bytes as there are Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  the statement reads as many bytes as there are characters in the string's value. For example, the following two statements read 10 bytes from file number 1: VarStrings$=STRING$ (10, " ") GET #1,,VarString$ See the examples and Chapter 3, "File and Device I/O," in Programming in BASIC for more information about using variables rather than FIELD statements for random-access files. A record cannot be longer than 32,767 bytes. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You may omit the recordnumber, the variable, or both. If you omit the recordnumber but include the variable, you must still include the commas: GET #4,,FileBuffer If you omit both arguments, you do not include the commas: GET #4 The GET and PUT statements allow fixed-length input and output for BASIC communications files. Use GET carefully because if there is a communications failure, GET waits indefinitely for recordnumber characters. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE When you use GET with the FIELD statement, you can use either INPUT # or LINE INPUT # after a GET statement to read characters from the random-access file buffer. You may use the EOF function after GET to see if the GET went beyond the end of the file. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CVI, CVS, CVL, CVD; FIELD; INPUT #; LINE INPUT #; LSET; MKD$, MKI$, MKL$, MKS$; PUT (File I/O); RSET; TYPE ž Example The following program opens the file TESTDAT.DAT for random access and displays the contents on the screen: ' Read and display the contents of a file containing a ' name of up to 20 characters and a test score. ' Define record fields. TYPE TestRecord NameField AS STRING*20 ScoreField AS SINGLE END TYPE ' Open the test data file. DIM FileBuffer AS TestRecord OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN=LEN(FileBuffer) ' Calculate number of records in the file. Max=LOF(1)/LEN(FileBuffer) ' Read and print contents of each record. FOR I=1 TO Max GET #1,I,FileBuffer PRINT FileBuffer.NameField,FileBuffer.ScoreField NEXT I CLOSE #1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ GOSUB...RETURN Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Branches to, and returns from, a subroutine ž Syntax GOSUB {linelabel1 | linenumber1 } . . . RETURN ®linelabel2 | linenumber2 Æ ž Remarks The GOSUB...RETURN statements take the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ linelabel1, linenumber1 The line number or line label that is the first line of the subroutine. linelabel2, linenumber2 The line label or line number where the subroutine returns. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE BASIC's SUB and FUNCTION procedures provide a more well-structured alternative to GOSUB... RETURN subroutines. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ In addition to RETURN with no argument, BASIC supports RETURN with a line label or line number allowing a return from a subroutine to the statement having the specified line number or label, instead of returning to the statement after the GOSUB statement. Use this line-specific type of return with care. You may call a subroutine any number of times in a program. You may also call a subroutine from within another subroutine. How deeply you can nest subroutines is limited only by the available stack space (you may increase the stack space with the CLEAR statement). Subroutines that call themselves (recursive subroutines) can easily run out of stack space. RETURN with a line label or line number can only return control to a statement in the module-level code, not procedure-level code. See the example program. A subroutine may contain more than one RETURN statement. Simple RETURN statements (without the linelabel2, linenumber2 option) in a subroutine make BASIC branch back to the statement following the most recent GOSUB statement. Subroutines may appear anywhere in the program, but it is good programming practice to make them readily distinguishable from the main program. To prevent inadvertent entry into a subroutine, precede it with a STOP, END, or GOTO statement that directs program control around the subroutine. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IMPORTANT The preceding discussion of subroutines applies only to the targets of GOSUB statements, not subprograms delimited by SUB statements. Entering and exiting SUB blocks with GOSUB...RETURN statements is not supported. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also RETURN, SUB ž Example The following example shows the use of RETURN linelabel statements in module-level code: PRINT "in module-level code" GOSUB Sub1 PRINT "this line in main routine should be skipped" Label1: PRINT "back in module-level code" END Sub1: PRINT "in subroutine one" GOSUB Sub2 PRINT "this line in subroutine one should be skipped" Label2: PRINT "back in subroutine one" RETURN Label1 Sub2: PRINT "in subroutine two" RETURN Label2 ž Output in module-level code in subroutine one in subroutine two back in subroutine one back in module-level code ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ GOTO Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Branches unconditionally to the specified line ž Syntax GOTO {linelabel | linenumber} ž Remarks The GOTO statement provides a way to branch unconditionally to another line (linelabel or linenumber). A GOTO statement can branch only to another statement at the same level of a program. You cannot use GOTO to enter or exit a SUB, FUNCTION, or multiline DEF FN function. You can, however, use GOTO to control program flow within any of these program structures. It is good programming practice to use structured control statements (DO...LOOP, FOR, IF..THEN...ELSE, SELECT CASE) instead of GOTO statements because a program with many GOTO statements is difficult to read and debug. ž Example The following program prints the area of the circle with the input radius: PRINT "Input 0 to end." Start: INPUT R IF R = 0 THEN END ELSE A = 3.14 * R^2 PRINT "Area =";A END IF GOTO Start ž Output Input 0 to end. ? 5 Area = 78.5 ? 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ HEX$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string that represents the hexadecimal value of the decimal argument expression ž Syntax HEX$(expression) ž Remarks The argument expression is rounded to an integer or, if the expression is outside the integer range, a long integer before the HEX$ function evaluates it. ž See Also OCT$ ž Example The following example prints the hexadecimal representation of an input value: INPUT X A$ = HEX$(X) PRINT X "decimal is " A$ " hexadecimal" ž Output ? 32 32 decimal is 20 hexadecimal ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IF...THEN...ELSE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows conditional execution, based on the evaluation of a Boolean expression ž Syntax 1 (Single Line) IF booleanexpression THEN thenpart ®ELSE elsepartÆ ž Syntax 2 (Block) IF booleanexpression1 THEN ®statementblock-1Æ ®ELSEIF booleanexpression2 THEN ®statementblock-2ÆÆ . . . ®ELSE ®statementblock-nÆÆ END IF ž Remarks The single-line form of the statement is best used for short, straightforward tests where only one action is taken. The block form provides several advantages: ž The block form provides more structure and flexibility than the single-line form by allowing conditional branches across several lines. ž With the block form, more complex conditions can be tested. ž The block form lets you use longer statements and structures within the THEN...ELSE portion of the statement. ž The block form allows your program's structure to be guided by logic rather than by how many statements fit on a line. Programs that use block-form IF...THEN...ELSE are usually easier to read, maintain, and debug. The single-line form is never required. Any program using single-line IF...THEN...ELSE statements can be written using block form. SINGLE-LINE IF...THEN...ELSE The following list describes the parts of the single-line form: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ booleanexpression Any expression that evaluates to true (nonzero) or false (zero). thenpart, elsepart The statements or branches performed when booleanexpression is true (thenpart) or false (elsepart). Both parts have the same syntax, which is described below. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The thenpart and the elsepart both have the following syntax: {statements | ®GOTOÆ linenumber | GOTO linelabel } The following list describes the parts of the thenpart and elsepart syntax: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ statements One or more BASIC statements, separated by colons linenumber A valid BASIC program line number linelabel A valid BASIC line label ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Note that GOTO is optional with a line number but is required with a line label. The thenpart is executed if the booleanexpression is true; if the booleanexpression is false, the elsepart is executed. If the ELSE clause is not present, control passes to the next statement in the program. You can have multiple statements with a condition, but they must be on the same line and separated by colons: IF A > 10 THEN A=A+1:B=B+A:LOCATE 10,22:PRINT B,A BLOCK IF...THEN...ELSE The following list describes the parts of the block IF...THEN...ELSE: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ booleanexpression1, Any expression that evaluates to true (nonzero) booleanexpression2 or false (zero) statementblock-1, One or more BASIC statements on one or more lines statementblock-2, statementblock-n ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ In executing a block-form IF, QuickBASIC tests booleanexpression1, the first Boolean expression. If the Boolean expression is true (nonzero), the statements following THEN are executed. If the first Boolean expression is false (zero), QuickBASIC begins evaluating each ELSEIF condition in turn. When QuickBASIC finds a true condition, the statements following the associated THEN are executed. If none of the ELSEIF conditions are true, the statements following the ELSE are executed. After the statements following a THEN or ELSE are executed, the program continues with the statement following the END IF. The ELSE and ELSEIF blocks are both optional. You can have as many ELSEIF clauses as you would like in a block IF. Any of the statement blocks can contain nested block IF statements. QuickBASIC looks at what appears after the THEN keyword to determine whether or not an IF statement is a block IF. If anything other than a comment appears after THEN, the statement is treated as a single-line IF statement. A block IF statement must be the first statement on a line. The ELSE, ELSEIF, and END IF parts of the statement can only have a line number or line label in front of them. The block must end with an END IF statement. For more information, see Chapter 1, "Control-Flow Structures," in Programming in BASIC. ž See Also SELECT CASE ž Examples The following program fragments demonstrate the use of single-line and block IF...THEN...ELSE and illustrate the differences. The first example demonstrates the single-line IF...THEN...ELSE form: DO INPUT "Enter a number greater than 0 and less than 10,000:",X IF X>=0 AND X<10000 THEN EXIT DO ELSE PRINT X;"out of range" LOOP IF X<10 THEN Y=1 ELSE IF X<100 THEN Y=2 ELSE IF X<1000 THEN Y=3 ELSE Y=4 PRINT "The number has";Y;"digits" In the second example the block IF...THEN...ELSE makes the code more readable and more powerful: DO INPUT "Enter a number greater than 0 and less than 100,000:",X IF X>0 AND X<100000 THEN EXIT DO ELSE PRINT X;"out of range" END IF LOOP IF X<10 THEN Y=1 ELSEIF X<100 THEN Y=2 ELSEIF X<1000 THEN Y=3 ELSEIF X<10000 THEN Y=4 ELSE Y=5 END IF PRINT "The number has";Y;"digits" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INKEY$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads a character from the keyboard ž Syntax INKEY$ ž Remarks The INKEY$ function returns a one- or two-byte string containing a character read from the standard input device. A null string is returned if no character is waiting there. A one-character string contains the actual character read from the keyboard, while a two-character string indicates an extended code, the first character of which is hexadecimal 00. For a complete list of these codes, see Appendix A, "Keyboard Scan Codes and ASCII Character Codes." The standard input device is usually the keyboard. INKEY$ does not echo characters to the screen; instead, all characters are passed through to the program except for these: ž CTRL+BREAK, which halts program execution ž CTRL+ALT+DEL, which does a system reboot ž CTRL+NUMLOCK, which causes program execution to pause ž PRTSC, which prints the screen ž Example The following program fragment shows a common use of INKEY$ÄÄpausing until the user presses a key: PRINT "Press any key to continue..." DO LOOP WHILE INKEY$="" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INP Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the byte read from an I/O port ž Syntax INP(port) ž Remarks The port must be an integer in the range 0-65,535. The INP function complements the OUT statement. The INP and OUT statements give a BASIC program direct control over the hardware in a system through the I/O ports. These statements must be used carefully because they directly manipulate the system hardware. ž See Also OUT, WAIT ž Example See the example for the OUT statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INPUT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows input from the keyboard during program execution ž Syntax INPUT®;Æ®"promptstring"{; | ,}Æ variablelist ž Remarks The following list describes the parts of the INPUT statement: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; A semicolon immediately after INPUT keeps the cursor on the same line after the user presses ENTER. promptstring A string constant printed before the prompt character. ; Prints a question mark at the end of the promptstring. , Prints the promptstring without a question mark. variablelist A list of variables, separated by commas, to accept the input values. See the discussion below. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The INPUT statement causes the program to pause and wait for data. You can then enter the required data at the keyboard. The data that you enter is assigned to the variables in variablelist. The number of data items that you supply must be the same as the number of variables in the list. The first character encountered after a comma that is not a space, carriage return, or line feed is assumed to be the start of a new item. The variable names in the list may be numeric- or string-variable names (including subscripted variables), array elements, or elements of records. The type of each data item that you input must agree with the type of the variable. (Strings input to an INPUT statement need not be surrounded by quotation marks.) If this first character is a quotation mark ("), the string item will consist of all characters read between the first quotation mark and the second. This means a quoted string may not contain a quotation mark as a character. If the first character of the string is not a quotation mark, the string is an unquoted string and terminates on a comma, carriage return, or line feed. Input stored in elements of a record must be input as single elements: TYPE Demograph FullName AS STRING*25 Age AS INTEGER END TYPE DIM Person AS Demograph INPUT "Enter name and age: ";Person.FullName,Person.Age Responding to an INPUT statement with too many or too few items, or with the wrong type of value (for example, numeric instead of string), produces this error message: Redo from start No assignment of input values is made until you give an acceptable response. It is possible to edit a line of input before you press ENTER. The following list describes the key combinations that allow you to move the cursor, delete text, and insert text on the input line: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Keys Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ CTRL+\ or RIGHT Moves cursor one character to the right. Keys Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  CTRL+] or LEFT Moves cursor one character to the left. CTRL+F or CTRL+RIGHT Moves cursor one word to the right. CTRL+B or CTRL+LEFT Moves cursor one word to the left. CTRL+K or HOME Moves cursor to the beginning of the input line. CTRL+N or END Moves cursor to the end of the input line. CTRL+R or INS Toggles insert mode on and off. When insert mode is on, character above and those to the right of the cursor are shifted to the right as new characters are entered. CTRL+I or TAB Tabs right and inserts (insert mode on), or overwrites (insert mode off). Keys Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  DEL Deletes the character at the cursor. CTRL+H or BACKSPACE Deletes the character to the left of the cursor, unless the cursor is at the beginning of the input, in which case it deletes the character at the cursor. CTRL+E or CTRL+END Deletes to the end of the line. CTRL+U or ESC Deletes entire line, regardless of cursor position. CTRL+M or RETURN Stores input line. CTRL+T Toggles function key label display on and off at bottom of screen. CTRL+BREAK or CTRL+C Terminates input (exits compiled program). Keys Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  CTRL+BREAK or CTRL+C Terminates input (exits compiled program). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Example The following example calculates the area of a circle from an input radius: PI = 3.141593 : R = -1 PRINT "Enter radius (0 to end)." DO WHILE R PRINT INPUT;"If radius = ", R IF R > 0 THEN A = PI*R^2 PRINT ", the area of the circle =" A END IF LOOP ž Output Enter radius (0 to end). If radius = 3, the area of the circle = 28.27434 If radius = 4, the area of the circle = 50.26549 If radius = 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INPUT # Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads data items from a sequential device or file and assigns them to variables ž Syntax INPUT #filenumber, variablelist ž Remarks The filenumber is the number used when the file was opened for input. The variablelist contains the names of the variables that are assigned values read from the file. (The variable type must match the type specified by the variable name.) The data items in the file should appear just as they would if you were entering data in response to an INPUT statement. Separate numbers with a space, carriage return, line feed, or comma. Separate strings with a carriage return or linefeed (leading spaces are ignored). The end-of-file character will end either a numeric or string entry. If BASIC is scanning the sequential data file for a string item, it will also ignore leading spaces, carriage returns, and line feeds. If end-of-file is reached when a numeric or string item is being INPUT, the item is terminated. ž See Also INPUT, INPUT$ ž Example The following program reads a series of test scores from a sequential file and calculates the average score: DEFINT A-Z OPEN "class.dat" FOR INPUT AS #1 DO WHILE NOT EOF(1) Count=Count+1 INPUT #1,Score Total=Total+Score PRINT Count;Score LOOP PRINT PRINT "Total students:";Count;" Average score:";Total/Count END ž Output 1 97 2 84 3 63 4 89 5 100 Total students: 5 Average score: 86.6 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INPUT$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string of characters read from the specified file ž Syntax INPUT$(n®,®#ÆfilenumberÆ) ž Remarks The n is the number of characters (bytes) to read from the file. The filenumber is the number that was used in opening the file. If the file is opened for random access, the argument n must be less than or equal to the record length set by the LEN clause in the OPEN statement (or less than or equal to 128 if the record length is not set). If the given file is opened for binary or sequential access, then n must be less than or equal to 32,767. If the filenumber is not specified, the characters are read from the standard input device. (If input has not been redirected, the keyboard is the standard input device). You can use the DOS redirection symbols (<, >, or >>) or the pipe symbol (|) to redefine the standard input or standard output for an executable file created with BASIC. (See your operating system manual for a complete discussion of redirection and pipes.) No characters are echoed on the screen. All control characters are passed through except CTRL+BREAK, which interrupts execution of the function. ž Example The following program prints a file on the screen. It uses INPUT$ to read one character at a time, then converts the character, as necessary, and displays it. 'ASCII codes for tab, and line feed. CONST HTAB = 9, LFEED = 10 INPUT "Display which file"; Filename$ OPEN Filename$ FOR INPUT AS #1 CLS DO WHILE NOT EOF(1) ' Input a single character from the file. S$=INPUT$(1,#1) ' Convert the character to an integer and ' turn off the high bit so WordStar(R) files ' can be displayed. C=ASC(S$) AND &H7F ' Is it a printable character? IF (C >= 32 AND C <= 126) OR C = HTAB OR C = LFEED THEN PRINT CHR$(C); END IF LOOP END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INSTR Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the character position of the first occurrence of a string in another string ž Syntax INSTR(®start,Æstringexpression1,stringexpression2) ž Remarks The following list describes the INSTR function arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ start An optional offset that sets the position for starting the search; start must be in the range 1-32,767. If start is not given, the INSTR function begins the search at the first character of stringexpression1. stringexpression1 The string being searched. stringexpression2 The string to look for. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The arguments stringexpression1 and stringexpression2 can be string variables, string expressions, or string literals. The value returned by INSTR depends on these conditions: Condition Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ stringexpression2 found in The position at which the match is stringexpression1 found start greater than length of 0 stringexpression1 stringexpression1 is null string 0 stringexpression2 cannot be found 0 stringexpression2 is null string start (if given); otherwise, 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Use the LEN function to find the length of stringexpression1. ž Example The following fragment uses INSTR and UCASE$ to look for Mr., Mrs., or Ms. in a name in order to deduce the person's sex: ' Get a name. DO INPUT "Enter name: ", Nm$ LOOP UNTIL LEN(Nm$)>=3 ' Convert lowercase letters to uppercase. Nm$ = UCASE$(Nm$) ' Look for MS., MRS., or MR. to set Sex$. IF INSTR(Nm$,"MS.") > 0 OR INSTR(Nm$,"MRS.") > 0 THEN Sex$ = "F" ELSEIF INSTR(Nm$,"MR.") > 0 THEN Sex$ = "M" ELSE ' Can't deduce sex, so query user. DO INPUT "Enter sex (M/F): ", Sex$ Sex$ = UCASE$(Sex$) LOOP WHILE Sex$ <> "M" AND Sex$ <> "F" END IF ž Output Enter name: Elspeth Brandtkeep Enter sex (M/F): x Enter sex (M/F): F ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INT Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the largest integer less than or equal to numeric-expression ž Syntax INT(numeric-expression) ž Remarks The INT function removes the fractional part of its argument. ž See Also CINT, FIX ž Example The following example compares the output from the three functions that convert numeric data to integers: PRINT " N","INT(N)","CINT(N)","FIX(N)" : PRINT FOR I% = 1 TO 6 READ N PRINT N, INT(N), CINT(N), FIX(N) NEXT DATA 99.3, 99.5, 99.7, -99.3, -99.5, -99.7 ž Output N INT(N) CINT(N) FIX(N) 99.3 99 99 99 99.5 99 100 99 99.7 99 100 99 -99.3 -100 -99 -99 -99.5 -100 -100 -99 -99.7 -100 -100 -99 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IOCTL$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Receives a control data string from a device driver ž Syntax IOCTL$ (®#Æ filenumber) ž Remarks The filenumber is the BASIC file number used to open the device. The IOCTL$ function is most frequently used to test whether an IOCTL statement succeeded or failed or to obtain current status information. You could use IOCTL$ to ask a communications device to return the current baud rate, information on the last error, logical line width, and so on. The exact information returned would depend on the specific device driver. The IOCTL$ function works only if all three of the following conditions are met: 1. The device driver is installed. 2. The device driver states that it processes IOCTL strings. See the documentation for the driver. You can also test for IOCTL support through DOS function &H44 by using interrupt &H21 and the CALL INTERRUPT routine. See the CALL INTERRUPT statement for more information. 3. BASIC performs an OPEN statement on a file on that device. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE BASIC devices (LPT1:, COM1:, COM2:, SCRN:, CONS:) and DOS block devices (A: through Z:) do not support IOCTL. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also IOCTL ž Example The following example opens the device driver ENGINE and uses the IOCTL$ function to test for raw data mode being set: OPEN "\DEV\ENGINE" FOR OUTPUT AS #1 IOCTL #1, "RAW" 'Tells the device that the data is raw. ' If the character driver "ENGINE" responds "false" from ' the raw data mode in the IOCTL statement, then the file ' is closed. IF IOCTL$(1) = "0" THEN CLOSE 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IOCTL Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Transmits a control data string to a device driver ž Syntax IOCTL ®#Æfilenumber, string ž Remarks The filenumber is the BASIC file number used to open the device. The string is the command sent to the device. Commands are specific to the device driver. See the documentation for the device driver to find out what the valid IOCTL commands are. An IOCTL control data string can be up to 32,767 bytes long. The IOCTL statement works only if all three of the following conditions are met: 1. The device driver is installed. 2. The device driver states that it processes IOCTL strings. See the documentation for the driver. You can also test for IOCTL support through DOS function &H44 by using interrupt &H21 and the CALL INTERRUPT routine. See the Microsoft MS-DOS Programmer's Reference and the CALL INTERRUPT statement for more information. 3. BASIC performs an OPEN on a file on that device, and the file is still open. Most standard DOS device drivers do not process IOCTL strings, and you must determine if the specific driver accepts the command. ž See Also IOCTL$ ž Example If you wanted to set the page length to 66 lines per page on LPT1, your statement might look like this: OPEN "\DEV\LPT1" FOR OUTPUT AS 1 IOCTL #1, "PL66" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ KEY Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Assign soft-key string values to FUNCTION keys, then display the values and enable or disable the FUNCTION key display line ž Syntax KEY n, stringexpression KEY LIST KEY ON KEY OFF ž Remarks The placeholder n is a number representing the FUNCTION key. The values for n are 1 to 10 for the FUNCTION keys, and 30 and 31 for FUNCTION keys F11 and F12 on 101-key keyboards. The stringexpression is a string of up to 15 characters that is returned when the FUNCTION key is pressed. If the stringexpression is longer than 15 characters, the extra characters are ignored. The KEY statement allows you to designate special "soft-key" functionsÄÄstrings that are returned when FUNCTION keys are pressed. Assigning a null string to a soft key disables the FUNCTION key as a soft key. If the FUNCTION key number is not in the correct range, an error message is displayed that reads Illegal function call, and the previous key string expression is retained. You may display soft keys with the KEY ON, KEY OFF, and KEY LIST statements: Statement Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ KEY ON Displays the first six characters of the soft-key string values on the bottom line of the screen. KEY OFF Erases the soft-key display from the bottom line, making that line available for program use. It does not disable the FUNCTION keys. KEY LIST Displays all soft-key values on the screen, with all 15 characters of each key displayed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If a soft key is pressed, the effect is the same as if the user typed the string associated with the soft key. INPUT$, INPUT, and INKEY$ can all be used to read the string produced by pressing the soft key. ž Examples The following examples show how to assign a string to a soft key and how to disable a soft key: KEY 1,"MENU"+CHR$(13) 'Assigns to soft key 1 the string '"MENU" followed by a carriage return. KEY 1,"" 'Disables soft key 1. The following program uses KEY statements to set up one-key equivalents of menu selections. For example, pressing F1 is the same as entering the string Add: DIM KeyText$(3) DATA Add, Delete, Quit ' Assign soft-key strings to F1 to F3. FOR I=1 TO 3 READ KeyText$(I) KEY I, KeyText$(I)+CHR$(13) NEXT I ' Print menu. PRINT " Main Menu" : PRINT PRINT " Add to list (F1)" PRINT " Delete from list (F2)" PRINT " Quit (F3)" : PRINT ' Get input and respond. DO LOCATE 7,1 : PRINT SPACE$(50); LOCATE 7,1 : INPUT " Enter your choice:",R$ SELECT CASE R$ CASE "Add", "Delete" LOCATE 10,1 : PRINT SPACE$(15); LOCATE 10,1 : PRINT R$; CASE "Quit" EXIT DO CASE ELSE LOCATE 10,1 : PRINT "Enter first word or press key." END SELECT LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ KEY (n) Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Start or stop trapping of specified keys ž Syntax KEY(n) ON KEY(n) OFF KEY(n) STOP ž Remarks The argument n is the number of a FUNCTION key, a cursor-direction key, or a user-defined key. (See the KEY statement for information on assigning soft-key values to FUNCTION keys.) The values of n are as follows: Value Key ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1-10 The FUNCTION keys F1-F10 11 UP 12 LEFT 13 RIGHT 14 DOWN 15-25 User-defined keys 30-31 The FUNCTION keys F11-F12 on 101-key keyboards ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LEFT, RIGHT, UP, and DOWN refer to the direction keys. You can enable trapping of combination keys by using a variation of the KEY statement: KEY n, CHR$(keyboardflag) + CHR$(scancode) The argument n is in the range 15-25 to indicate a user-defined key. The keyboardflag can be any combination of the following hexadecimal values: Value Key ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ &H00 No keyboard flag &H01-&H03 Either SHIFT key &H04 CTRL &H08 ALT &H20 NUMLOCK &H40 CAPSLOCK &H80 101-key keyboard extended keys ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can add the values together to test for multiple shift states. A keyboardflag value of &H12 would test for both CTRL and ALT being pressed, for example. Because key trapping assumes the left and right SHIFT keys are the same, you can use either &H01, &H02, or &H03 to indicate a SHIFT key. The scancode argument is a number identifying one of the 83 keys to trap, as shown in Table R.4. Table R.4 Keyboard Scan Codes ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄ· Code Code Code Key in Hex Key in Hex Key in Hex ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ESC 01 CTRL 1D SPACEBAR 39 ! or 1 02 A 1E CAPS LOCK 3A # or 3 04 D 20 F2 3C Code Code Code Key in Hex Key in Hex Key in Hex ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  # or 3 04 D 20 F2 3C $ or 4 05 F 21 F3 3D % or 5 06 G 22 F4 3E ^ or 6 07 H 23 F5 3F & or 7 08 J 24 F6 40 * or 8 09 K 25 F7 41 ( or 9 0A L 26 F8 42 ) or 0 0B : or ; 27 F9 43 _ or - 0C " or ' 28 F10 44 + or = 0D ~ or ` 29 NUM LOCK 45 LEFT 0E LEFT SHIFT 2A SCROLL LOCK 46 TAB 0F | or \ 2B HOME or 7 47 Q 10 Z 2C UP or 8 48 W 11 X 2D PGUP or 9 49 E 12 C 2E - 4A R 13 V 2F LEFT or 4 4B T 14 B 30 5 4C Y 15 N 31 RIGHT or 6 4D Code Code Code Key in Hex Key in Hex Key in Hex ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Y 15 N 31 RIGHT or 6 4D U 16 M 32 + 4E I 17 < or , 33 END or 1 4F O 18 > or . 34 DOWN or 2 50 P 19 ? or / 35 PGDN or 3 51 { or [ 1A RIGHT SHIFT 36 INS or 0 52 } or ] 1B PRTSC or * 37 DEL or . 53 RETURN 1C ALT 38 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The scan codes in Table R.4 are equivalent to the first column of the scan code table in Appendix A, "Keyboard Scan Codes and ASCII Character Codes." The codes in the other columns of the table in the appendix should not be used for key trapping. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The KEY(n) ON statement enables soft-key or cursor-direction-key event trapping by an ON KEY statement. If you specify a nonzero line number in the ON KEY statement while trapping is enabled, BASIC checks to see if you have pressed KEY(n). If you have, BASIC executes the GOSUB clause in the ON KEY statement. The text that would normally be associated with a FUNCTION key is not input. When you are working in the environment, QuickBASIC tests between statements for key presses. In stand-alone programs, you can specify checking between lines. KEY(n) OFF disables the event trap; even if an event takes place, it is not remembered. KEY(n) STOP inhibits the event trap; that is, if you press the specified key your action is remembered and an ON KEY event trap is executed as soon as a KEY(n) ON statement is executed. ž See Also ON event ž Example This example traps the DOWN direction key and CTRL+S (control key and lowercase "s"). To trap the combination of the CTRL key and uppercase "s," you need to trap CTRL+SHIFT and CTRL+CAPS LOCK+S. I = 0 PRINT "Press DOWN direction key to end." KEY 15,CHR$(&H04)+CHR$(&H1f) KEY(15) ON 'Trap CTRL+s. KEY(14) ON 'Trap DOWN direction key. ON KEY(15) GOSUB Keytrap ON KEY(14) GOSUB Endprog Idle: GOTO Idle 'Endless loop Keytrap: 'Counts the number of times CTRL+s pressed. I = I + 1 RETURN Endprog: PRINT "CTRL+s trapped"; I; "times" END RETURN ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ KILL Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Deletes a file from disk ž Syntax KILL filespec ž Remarks The KILL statement is similar to the DOS ERASE or DEL commands. KILL is used for all types of disk files: program files, random data files, and sequential data files. The filespec may contain question marks (?) or asterisks (*) used as wild cards. A question mark matches any single character in the file name or extension. An asterisk matches one or more characters starting at its position. You can use KILL only to delete files. To delete directories, use the RMDIR command. Using KILL to delete a file that is currently open produces an error message that reads File already open. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WARNING Be extremely careful when using wild cards with KILL. You can delete files unintentionally with the wild card characters. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Examples The following examples show the effect of wild-card characters when used with KILL: KILL "DATA1?.DAT" 'Kills any file with a six-character 'base name starting with DATA1 and 'also with the extension .DAT. KILL "DATA1.*" 'Kills any file with the base name 'DATA1 and any extension. KILL "\GREG\*.DAT" 'Kills any file with the extension '.DAT in a subdirectory called GREG. The following program deletes the file specified in the command line: DEFINT A-Z ON ERROR GOTO Errorhandle 'Set up error handling. FileName$ = COMMAND$ 'Get file name. KILL FileName$ END Errorhandle: Number = ERR IF Number = 53 THEN PRINT "Couldn't delete " FileName$ ; PRINT "; file does not exist in current directory" ELSE PRINT "Unrecoverable error:";Number ON ERROR GOTO 0 'ON ERROR GOTO zero aborts program. END IF RESUME NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LBOUND Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the lower bound (smallest available subscript) for the indicated dimension of an array ž Syntax LBOUND(array®,dimensionÆ) ž Remarks The LBOUND function is used with the UBOUND function to determine the size of an array. LBOUND takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ array The name of the array being dimensioned dimension An integer ranging from 1 to the number of dimensions in array: indicates which dimension's lower bound is returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ For an array dimensioned as follows, LBOUND returns the values listed below: DIM A(1 TO 100, 0 TO 50, -3 TO 4) Invocation Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LBOUND(A,1) 1 LBOUND(A,2) 0 LBOUND(A,3) -3 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The default lower bound for any dimension is either 0 or 1, depending on the setting of the OPTION BASE statement. If OPTION BASE is 0, the default lower bound is 0, and if OPTION BASE is 1, the default lower bound is 1. Arrays dimensioned using the TO clause in the DIM statement may have any integer value as a lower bound. You may use the shortened syntax LBOUND(array) for one-dimensional arrays, since the default value for dimension is 1. Use the UBOUND function to find the upper limit of an array dimension. ž See Also UBOUND ž Example The LBOUND and UBOUND functions may be used to determine the size of an array passed to a subprogram, as in the following program fragment: CALL Prntmat(Array()) . . . ' Print a matrix (two-dimensional array). SUB Prntmat(A(2)) STATIC ' Outer loop controls row (dimension 1). FOR I% = LBOUND(A,1) TO UBOUND(A,1) ' Inner loop controls column (dimension 2). FOR J% = LBOUND(A,2) TO UBOUND(A,2) PRINT A(I%,J%);" "; NEXT J% PRINT:PRINT NEXT I% END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LCASE$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string expression with all letters in lowercase ž Syntax LCASE$ (stringexpression) ž Remarks The LCASE$ function takes a string variable, string constant, or string expression as its single argument. LCASE$ works with both variable- and fixed-length strings. LCASE$ and UCASE$ are helpful in string comparison operations where tests need to be case insensitive. ž See Also UCASE$ ž Example The following example converts uppercase characters in a string to lowercase characters: ' Program to convert to lowercase. READ Word$ PRINT LCASE$(Word$); DATA "THIS IS THE STRING in lowercase." ž Output this is the string in lowercase. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LEFT$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string consisting of the leftmost n characters of a string ž Syntax LEFT$(stringexpression,n) ž Remarks The argument stringexpression can be any string variable, any string constant, or any string expression. The argument n is a numeric expression in the range 0-32,767 indicating how many characters are to be returned. If n is greater than the number of characters in stringexpression, the entire string is returned. To find the number of characters in stringexpression, use LEN(stringexpression). If n is zero, the null string (length zero) is returned. ž See Also MID$, RIGHT$ ž Example The following example prints the leftmost five characters of A$: A$="BASIC LANGUAGE" B$=LEFT$(A$,5) PRINT B$ ž Output BASIC ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LEN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the number of characters in a string or the number of bytes required by a variable ž Syntax LEN(stringexpression) LEN(variable) ž Remarks In the first form, LEN returns the number of characters in the argument stringexpression. The second syntax returns the number of bytes required by a BASIC variable. This syntax is particularly useful for determining the correct record size of a random-access file. ž Example The following example prints the sizes of BASIC variables of several different types and also prints the length of a string: TYPE EmpRec EmpName AS STRING*20 EmpNum AS INTEGER END TYPE DIM A AS INTEGER, B AS LONG, C AS SINGLE, D AS DOUBLE DIM E AS EmpRec PRINT "Integer:" LEN(A) PRINT "Long:" LEN(B) PRINT "Single:" LEN(C) PRINT "Double:" LEN(D) PRINT "EmpRec:" LEN(E) PRINT "A string:" LEN("A string.") END ž Output Integer: 2 Long: 4 Single: 4 Double: 8 EmpRec: 22 A string: 9 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Assigns the value of an expression to a variable ž Syntax ®LETÆvariable=expression ž Remarks Notice that the word LET is optional. The equal sign in the statement is enough to inform QuickBASIC that the statement is an assignment statement. LET statements can be used with record variables only when both variables are the same user-defined type. Use the LSET statement for assigning record variables of different user-defined types. ž See Also LSET ž Examples Corresponding lines perform the same function in these two examples: LET D=12 LET E=12-2 LET F=12-4 LET SUM=D+E+F . . . or D=12 E=12-2 F=12-4 SUM=D+E+F . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LINE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Draws a line or box on the screen ž Syntax LINE ®®STEPÆ (x1,y1)Æ-®STEPÆ (x2,y2) ®,®colorÆ®,®B®FÆÆ®,styleÆÆÆ ž Remarks The coordinates (x1,y1) and (x2,y2) specify the endpoints of the line; note that the order in which these endpoints appear is unimportant, since a line from (10,20) to (120,130) is the same as a line from (120,130) to (10,20). The STEP option makes the specified coordinates relative to the most recent point, instead of absolute, mapped coordinates. For example, if the most recent point referred to by the program is (10,10), then LINE -STEP (10,5) draws a line from (10,10) to the point with x-coordinate equal to 10 + 10 and y-coordinate equal to 10 + 5, or (20,15). You may establish a new most recent point by initializing the screen with the CLS and SCREEN statements. Using the PSET, PRESET, CIRCLE, and DRAW statements will also establish a new most recent point. Variations of the STEP argument are shown below. For the following examples, assume that the last point plotted was (10,10): ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LINE -(50,50) Draws from (10,10) to (50,50) LINE -STEP(50,50) Draws from (10,10) to (60,60); that is, to 10 plus offset 50 LINE (25,25)-STEP(50,50) Draws from (25,25) to (75,75); that is, to 25 plus offset 50 Statement Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  LINE STEP(25,25)-STEP(50,50) Draws from (35,35) to (85,85); that is, from 10 plus offset 25 to that point plus offset 50 LINE STEP(25,25)-(50,50) Draws from (35,35) to (50,50); that is, from 10 plus offset 25 to absolute 50 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The color is the number of the color in which the line is drawn. (If the B or BF options are used, the box is drawn in this color.) See the SCREEN statement for information on valid colors. The B option draws a box with the points (x1,y1) and (x2,y2) specifying diagonally opposite corners. The BF option draws a filled box. This option is similar to the B option; BF also paints the interior of the box with the selected color. The style is a 16-bit integer mask used to put pixels on the screen. Using the style argument is called "line styling." With line styling, LINE reads the bits in style from left to right. If a bit is 0, then no point is plotted; if the bit is 1, a point is plotted. After plotting a point, LINE selects the next bit position in style. Because a 0 bit in style does not change the point on the screen, you may want to draw a background line before using styling so you can have a known background. Style is used for normal lines and boxes, but has no effect on filled boxes. When coordinates specify a point that is not in the current viewport, the line segment is clipped to the viewport. See Chapter 5, "Graphics," in Programming in BASIC for more information on the LINE statement. ž See Also SCREEN ž Examples The following examples are different LINE statements that assume a screen 320 pixels wide by 200 pixels high: SCREEN 1 'Sets up the screen mode. LINE -(X2,Y2) 'Draws a line (in the 'foreground color) from 'the most recent point 'to X2,Y2. LINE(0,0)-(319,199) 'Draws a diagonal line across 'the screen (downward). LINE(0,100)-(319,100) 'Draws a horizontal line 'across the screen. LINE(10,10)-(20,20),2 'Draws a line in color 2. FOR X=0 to 319 'Draws an alternating pattern LINE(X,0)-(X,199),X AND 1 '(line on/line off) on mono- NEXT 'chrome display. LINE (0,0)-(100,100),,B 'Draws a box in the fore- 'ground color (note that the 'color is not included). LINE STEP(0,0)-STEP(200,200),2,BF 'Draws a filled box in color '2 (coordinates are given as 'offsets with the STEP option). LINE(0,0)-(160,100),3,,&HFF00 'Draws a dashed line from 'the upper lefthand corner to 'the center of the screen in 'color 3. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LINE INPUT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Inputs an entire line (up to 255 characters) to a string variable, without the use of delimiters ž Syntax LINE INPUT®;Æ ®"promptstring";Æ stringvariable ž Remarks The promptstring is a string constant displayed on the screen before input is accepted. A question mark is not printed unless it is part of the promptstring. All input from the end of promptstring to the carriage return is assigned to stringvariable. A semicolon immediately after the LINE INPUT statement keeps the cursor on the same line after the user presses ENTER. LINE INPUT uses the same editing characters as INPUT. ž See Also INPUT ž Example The following program enables the user to enter text in a notes file. The LINE INPUT statement allows you to enter any characters, including those (such as a comma) that are delimiters in a regular INPUT statement. 'Opens and writes lines to a notes file until you 'enter a blank line. DO CLS PRINT "Enter text. To stop, press without "; PRINT "entering any new text." : PRINT OPEN "NOTES.TXT" FOR OUTPUT AS #1 ' Take lines until a blank line is entered. DO LINE INPUT "->";Inline$ IF Inline$ <> "" THEN PRINT #1, Inline$ LOOP WHILE Inline$ <> "" CLS : CLOSE #1 ' Echo the notes back and see if they are correct. OPEN "NOTES.TXT" FOR INPUT AS #1 PRINT "You entered: " : PRINT DO WHILE NOT EOF(1) LINE INPUT #1, Inline$ PRINT Inline$ LOOP CLOSE #1 PRINT : INPUT "Is this correct (Y/N)"; R$ LOOP WHILE UCASE$(R$)="N" END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LINE INPUT # Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads an entire line without delimiters from a sequential file to a string variable ž Syntax LINE INPUT #filenumber,stringvariable ž Remarks The filenumber is the number used to open the file. The stringvariable is the variable the line is assigned to. The LINE INPUT # statement reads all characters in the sequential file up to a carriage return. It then skips over the carriage-return and line-feed sequence. The next LINE INPUT # reads all characters up to the next carriage return. LINE INPUT # is especially useful if each line of a data file has been broken into fields or a text file is being read a line at a time. ž See Also INPUT$, LINE INPUT ž Example The following uses LINE INPUT # to echo data input to a file: OPEN "LIST" FOR OUTPUT AS #1 PRINT "CUSTOMER INFORMATION:" ' Get customer information. DO PRINT INPUT " LAST NAME: ", LName$ INPUT " FIRST NAME: ", FrName$ INPUT " AGE: ", Age$ INPUT " SEX: ", Sex$ Sex$=UCASE$(Sex$) WRITE #1, LName$, FrName$, Age$, Sex$ INPUT "Add another"; R$ LOOP WHILE UCASE$(R$)="Y" CLOSE #1 ' Echo the file back. OPEN "LIST" FOR INPUT AS #1 CLS PRINT "Records in file:" : PRINT DO WHILE NOT EOF(1) LINE INPUT #1, REC$ 'Read records from file with PRINT REC$ 'LINE INPUT #. Print the 'records on the screen. LOOP ž Output CUSTOMER INFORMATION: LAST NAME: Saintsbury FIRST NAME: Aloysius AGE: 35 SEX: m Add another? y LAST NAME: Frangio FIRST NAME: Louisa AGE: 27 SEX: f Add another? n Records in file: "Saintsbury","Aloysius","35","M" "Frangio","Louisa","27","F" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LOC Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current position within the file ž Syntax LOC(filenumber) ž Remarks The filenumber is the number used in the OPEN statement to open the file. With random-access files, the LOC function returns the number of the last record read from or written to the file. With sequential files, LOC returns the current byte position in the file, divided by 128. With binary mode files, LOC returns the position of the last byte read or written. For a COM device, LOC(filenumber) returns the number of characters in the input queue waiting to be read. The value returned depends on whether the device was opened in ASCII or binary mode. In ASCII mode, the low-level routines stop queuing characters as soon as end-of-file is received. The end-of-file itself is not queued and cannot be read. An attempt to read the end-of-file produces an error message that reads Input past end of file. In binary mode, the end-of-file character is ignored and the entire file can therefore be read. The LOC function cannot be used on the SCRN:, KYBD:, or LPTn: devices. ž See Also OPEN COM ž Example The following line stops the program if the current file position is beyond 50: IF LOC(1) > 50 THEN STOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LOCATE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Moves the cursor to the specified position ž Syntax LOCATE®rowÆ®,®columnÆ®,®cursorÆ®,®startÆ®,stopÆÆÆÆ ž Remarks The following list describes the LOCATE statement's arguments: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ row The number of a row on the screen; row is a numeric expression returning an integer. If row is not specified, then the line (row) does not change. column The number of a column on the screen; column is a numeric expression returning an integer. If column is not specified, then the column location does not change. cursor A Boolean value indicating whether the cursor is visible or not. A value of 0 (zero) indicates cursor off; a value of 1 indicates cursor on. start The starting scan line of cursor on the screen. It must be a numeric expression returning an integer. stop The ending scan line of cursor on the screen. It Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  stop The ending scan line of cursor on the screen. It must be a numeric expression returning an integer. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You may omit any argument from the statement except that if stop is specified, start must also be specified. When you omit the row or column, LOCATE leaves the cursor at the row or column where it was moved by a previous LOCATE or a previous input or output statement, whichever occurred most recently. When you omit other arguments, QuickBASIC assumes the previous value for the argument. Note that the start and stop lines are the CRT scan lines that specify which pixels on the screen are lit. A wider range between the start and stop lines produces a taller cursor, such as one that occupies an entire character block. When start is greater than stop, LOCATE produces a two-part cursor. If the start line is given but the stop line is omitted, stop assumes the same value as start. The last line on the screen is reserved for the soft-key display and is not accessible to the cursor unless the soft-key display is off (KEY OFF) and LOCATE is used with PRINT to write on the line. ž See Also CSRLIN, POS ž Examples The following statements show the effects on the cursor of different LOCATE statements: LOCATE 1,1 'Moves cursor to upper-left corner of the screen. LOCATE,,1 'Makes the cursor visible; position remains 'unchanged. LOCATE,,,7 'Position and cursor visibility remain unchanged; 'sets the cursor to display at the bottom of 'the character box starting and ending on 'scan line 7. LOCATE 5,1,1,0,7 'Moves the cursor to line 5, column 1; 'turns cursor on; cursor covers entire 'character cell starting at scan line '0 and ending on scan line 7. The following example prints a menu on the screen, then waits for input in the allowable range (1-4). If a number outside that range is entered, the program continues to prompt for a selection. CONST FALSE=0, TRUE=NOT FALSE DO CLS PRINT "MAIN MENU" : PRINT PRINT "1) Add Records" PRINT "2) Display/Update/Delete a Record" PRINT "3) Print Out List of People Staying at Hotel" PRINT "4) End Program" ' Change cursor to a block. LOCATE ,,1,1,12 LOCATE 12,1 PRINT "What is your selection?"; DO CH$ = INPUT$(1) LOOP WHILE (CH$ < "1" OR CH$ > "4") PRINT CH$ ' Call the appropriate subprogram. SELECT CASE VAL(CH$) CASE 1 CALL Add CASE 2 CALL Search CASE 3 CALL Hotel CASE 4 CALL Quit END SELECT LOOP WHILE NOT ENDPROG . . . END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LOCK...UNLOCK Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Controls access by other processes to all or part of an opened file ž Syntax LOCK ®#Æ filenumber ®,{record | ®startÆ TO end}Æ . . . UNLOCK ®#Æ filenumber ®,{record | ®startÆ TO end}Æ ž Remarks These statements are used in networked environments where several processes might need access to the same file. The LOCK and UNLOCK statements take the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filenumber The number with which the file was opened. record The number of the record or byte to be locked; record can be any number from 1 to 2,147,483,647 (equivalent to 2^31-1). A record may be up to 32,767 bytes in length. start The number of the first record or byte to be locked. end The number of the last record or byte to be locked. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ For binary-mode files, the arguments record, start, and end represent the number of a byte relative to the beginning of the file. The first byte in a file is byte 1. For random-access files, the arguments record, start, and end are the number of a record relative to the beginning of the file. The first record is record 1. The LOCK and UNLOCK statements are always used in pairs. The arguments to LOCK and UNLOCK must match exactly when you use them. See the second example below. If you specify just one record, then only that record is locked or unlocked. If you specify a range of records and omit a starting record (start), then all records from the first record to the end of the range (end) are locked or unlocked. LOCK with no record arguments locks the entire file, while UNLOCK with no record arguments unlocks the entire file. If the file has been opened for sequential input or output, LOCK and UNLOCK affect the entire file, regardless of the range specified by start and end. LOCK and UNLOCK only function at run time if you are using versions of DOS that support networking (version 3.1 or later). In addition, each terminal (or the network setup programs) must run the DOS SHARE.EXE program to enable locking operations. Earlier versions of DOS return an error message that reads Advanced feature unavailable if LOCK and UNLOCK are executed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Be sure to remove all locks with an UNLOCK statement before closing a file or terminating your program. Failing to remove locks produces unpredictable results. The arguments to LOCK and UNLOCK must match exactly. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If you attempt to access a file that is locked, the following error messages may appear: Bad record number Permission denied ž Examples These examples assume a random-access file. The following statement locks the entire file opened as number 2: LOCK #2 The following statement locks only record 32 in file number 2: LOCK #2, 32 The following statement locks records 1-32 in file number 2: LOCK #2, TO 32 The two UNLOCK statements below unlock the records locked by the preceding LOCK statements: LOCK #1, 1 TO 4 LOCK #1, 5 TO 8 UNLOCK #1, 1 TO 4 UNLOCK #1, 5 TO 8 The following UNLOCK statement is illegal because the range in an UNLOCK statement must exactly match the range in the corresponding LOCK statements (no error is reported, but the statements produce unpredictable results): LOCK #1, 1 TO 4 LOCK #1, 5 TO 8 UNLOCK #1, 1 TO 8 The following program fragment opens a file and allows a user to lock an individual record before updating the information in that record. When the user is done, the program unlocks the locked record. (Unlocking the locked records allows other processes to use the data in the file.) TYPE AccountRec Payer AS STRING*15 Address AS STRING*20 Place AS STRING*20 Owe AS SINGLE END TYPE DIM CustRec AS AccountRec OPEN "MONITOR" SHARED AS #1 LEN = LEN(CustRec) DO CLS:LOCATE 10,10 INPUT "Customer Number? #"; Number% ' Lock the current record so another process ' doesn't change it while you're using it. LOCK #1, Number% GET #1, Number% LOCATE 11,10: PRINT "Customer: ";CustRec.Payer LOCATE 12,10: PRINT "Address: ";CustRec.Address LOCATE 13,10: PRINT "Currently owes: $";CustRec.Owe LOCATE 15,10: INPUT "Change (+ or -)", Change! CustRec.Owe=CustRec.Owe+Change! PUT #1, Number% ' Unlock the record. UNLOCK #1, Number% LOCATE 17,10: INPUT "Update another? ", Continue$ Update$ = UCASE$(LEFT$(Continue$,1)) LOOP WHILE Update$="Y" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LOF Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the length of the named file in bytes ž Syntax LOF(filenumber) ž Remarks The argument filenumber is the number used in the OPEN statement. When a file is opened in any mode, the LOF function returns the size of the file in bytes. LOF cannot be used with the BASIC devices SCRN:, KYBD:, CONS:, and LPTn:. When used on a device opened as a file with the statement OPEN COM, the LOF function returns the number of bytes free in the output buffer. ž Example See the example for the GET statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LOG Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the natural logarithm of a numeric expression ž Syntax LOG(n) ž Remarks The numeric expression, n, must be greater than zero. The natural logarithm is the logarithm to the base e. The constant e is approximately equal to 2.718282. The LOG function calculates the natural logarithm with single-precision accuracy, unless the argument n is a double-precision value. In this case LOG is calculated with double-precision accuracy. You may calculate base-10 logarithms by dividing the natural logarithm of the number by the logarithm of 10. The following FUNCTION calculates base-10 logarithms: FUNCTION Log10(X) STATIC Log10=LOG(X)/LOG(10.#) END FUNCTION ž Example The following example first prints the value of e and then prints the natural logarithms of e taken to the first, second, and third powers: PRINT EXP(1), FOR I = 1 TO 3 PRINT LOG(EXP(1)^I), NEXT ž Output 2.718282 1 2 3 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LPOS Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current position of the line printer's print head within the printer buffer ž Syntax LPOS(n) ž Remarks The argument n is the index of the printer being tested. For example, LPT1: would be tested with LPOS(1), while LPT2: would be tested with LPOS(2), and so on. The LPOS function does not necessarily give the physical position of the print head because it does not expand tab characters. In addition, some printers may buffer characters. ž Example The following program prompts the user for team names and the names of players on each team. It then prints the players and their teams on the printer. LPRINT"Team Members"; TAB(76); "TEAM" : LPRINT INPUT "How many teams"; TEAMS INPUT "How many players per team";PPT PRINT FOR T = 1 TO TEAMS INPUT "Team name: ", TEAM$ FOR P = 1 TO PPT INPUT " Enter player name: ", PLAYER$ LPRINT PLAYER$; IF P < PPT THEN IF LPOS(0) > 55 THEN 'Print a new line if print 'head past column 55. LPRINT : LPRINT " "; ELSE LPRINT ", "; 'Otherwise, print a comma. END IF END IF NEXT P LPRINT STRING$(80-LPOS(0)-LEN(TEAM$),"."); TEAM$ NEXT T ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LPRINT, LPRINT USING Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Prints data on the printer LPT1: ž Syntax 1 LPRINT ®expressionlistÆ ®{;|,}Æ ž Syntax 2 LPRINT USING formatstring; expressionlist ®{;|,}Æ ž Remarks These statements function in the same way as the PRINT and PRINT USING statements except that output goes to the line printer and the filenumber option is not permitted. The LPRINT statement assumes an 80-character-wide printer. This width can be changed with a WIDTH LPRINT statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WARNING Since the LPRINT statement uses the LPT1 printer device, you should not use LPRINT in a program that also contains an OPEN LPT1 statement. Using these two statements together produces unpredictable results. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica An LPRINT CHR$(13) statement actually outputs both CHR$(13) and CHR$(10). This feature was created to provide compatibility with BASICA. ž See Also PRINT, PRINT USING, WIDTH ž Example See examples for PRINT, PRINT USING. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LSET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Moves data from memory to a random-access file buffer (in preparation for a PUT statement), copies one record variable to another, or left-justifies the value of a string in a string variable ž Syntax LSET {stringvariable=stringexpression | stringexpression1= stringexpression2} ž Remarks The stringvariable is usually a random-access file field defined in a FIELD statement, although it can be any string variable. The stringexpression is the value assigned to the variable. If stringexpression requires fewer bytes than were defined for stringvariable in the FIELD statement, the LSET function left-justifies the string in the field (RSET will right-justify the string). Spaces are used to pad the extra positions. If the string is too long for the field, both LSET and RSET truncate characters from the right. Numeric values must be converted to strings before they are justified with the LSET or RSET statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE You may also use LSET or RSET with a string variable not defined in a FIELD statement to left-justify or right-justify a string in a given field. For example, the program lines A$=SPACE$(20) RSET A$=N$ will right-justify the string N$ in a 20-character field. This can be useful for formatting printed output. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can use LSET to assign one record variable to another. The following example copies the contents of RecTwo to RecOne: TYPE TwoString StrFld AS STRING * 2 END TYPE TYPE ThreeString StrFld AS STRING * 3 END TYPE DIM RecOne AS TwoString, RecTwo AS ThreeString . . . LSET RecOne = RecTwo Notice that LSET is used to assign record variables of differing types. Record variables of the same type can be assigned using LET. Also, because RecOne is only two bytes long, only two bytes are copied from RecTwo. LSET copies only the number of bytes in the shorter of the two record variables. ž See Also LET; MKD$, MKI$, MKL$, MKS$; PUT (File I/O); RSET ž Example The first line of the following example converts the single-precision numeric variable AMT to a 4-byte string and stores that string in A$, left-justified. The second line converts the integer numeric variable COUNT% to a 2-byte string and stores that string in D$, right-justified. LSET A$ = MKS$(AMT) RSET D$ = MKI$(COUNT%) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LTRIM$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a copy of a string with leading spaces removed ž Syntax LTRIM$(stringexpression) ž Remarks The stringexpression can be any string expression. ž See Also RTRIM$ ž Example This program copies a file to a new file, removing all leading and trailing spaces: CLS ' Get the file names. INPUT "Enter input file name:",InFile$ INPUT "Enter output file name:",OutFile$ OPEN InFile$ FOR INPUT AS #1 OPEN OutFile$ FOR OUTPUT AS #2 ' Read, trim, and write each line. DO WHILE NOT EOF(1) LINE INPUT #1,LineIn$ ' Remove leading and trailing blanks. LineIn$=LTRIM$(RTRIM$(LineIn$)) PRINT #2, LineIn$ LOOP CLOSE #1,#2 END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MID$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a substring of a string ž Syntax MID$(stringexpression,start®,lengthÆ) ž Remarks The MID$ function takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ stringexpression The string expression that the substring is extracted from. This can be any string expression. start The character position in stringexpression where the substring starts. length The number of characters to extract. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The arguments start and length must be in the range 1 to 32,767. If length is omitted or if there are fewer than length characters to the right of the start character, the MID$ function returns all characters to the right of the start character. If start is greater than the number of characters in stringexpression, MID$ returns a null string. Use the LEN function to find the number of characters in stringexpression. ž See Also LEFT$, LEN, MID$ Statement, RIGHT$ ž Example The following program converts a binary number to a decimal number. Digits are extracted from the binary number (input as a string) using MID$. INPUT "Binary number = ",Binary$ 'Input binary number as 'string. Length = LEN(Binary$) 'Get length of string. Decimal = 0 FOR K = 1 TO Length 'Get individual digits from string, from left to right. Digit$ = MID$(Binary$,K,1) 'Test for valid binary digit. IF Digit$="0" OR Digit$="1" THEN 'Convert digit characters to numbers. Decimal = 2*Decimal + VAL(Digit$) ELSE PRINT "Error--invalid binary digit: ";Digit$ EXIT FOR END IF NEXT PRINT "Decimal number =" Decimal ž Output Binary number = 10110 Decimal number = 22 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MID$ Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Replaces a portion of a string variable with another string ž Syntax MID$(stringvariable,start®,lengthÆ)=stringexpression ž Remarks The MID$ statement has the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ stringvariable The string variable being modified. start A numeric expression giving the position in stringvariable where the replacement starts. length The length of the string being replaced. The length is a numeric expression. stringexpression The string expression that replaces part of the stringvariable. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The arguments start and length are integer expressions. The argument stringvariable is a string variable, but stringexpression can be a string variable, a string constant, or a string expression. The optional length refers to the number of characters from the argument stringexpression that are used in the replacement. If length is omitted, all of stringexpression is used. However, regardless of whether length is omitted or included, the replacement of characters never goes beyond the original length of stringvariable. ž See Also MID$ Function ž Example The following example uses the MID$ statement to get characters from a string: Test$ = "Paris, France" PRINT Test$ MID$(Test$,8)="Texas " PRINT Test$ ž Output Paris, France Paris, Texas ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MKDIR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Creates a new directory ž Syntax MKDIR pathname ž Remarks The pathname is a string expression specifying the name of the directory to be created. The pathname must be a string of less than 128 characters. The MKDIR statement works like the DOS command MKDIR; the syntax in BASIC cannot, however, be shortened to MD, as in DOS. ž See Also CHDIR, RMDIR ž Example The following fragment creates a new directory (if the directory does not exist) and copies files into that directory: ON ERROR GOTO Errorhandler PRINT "This program creates a new directory named MONTHS" PRINT "in this directory, then creates files in that directory" MKDIR "MONTHS" DO INPUT "Filename"; File$ IF File$ = "" THEN END OPEN "MONTHS\" + File$ FOR OUTPUT AS #1 . . . CLOSE #1 LOOP Errorhandler: 'Error 75 means MONTHS directory already exists IF ERR = 75 THEN RESUME NEXT ON ERROR GOTO 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MKSMBF$, MKDMBF$ Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts an IEEE-format number to a string containing a Microsoft Binary format number. ž Syntax MKSMBF$(single-precision-expression) MKDMBF$(double-precision-expression) ž Remarks These functions are used to write real numbers to random-access files using Microsoft Binary format. They are particularly useful for maintaining data files created with older versions of BASIC. The MKSMBF$ and MKDMBF$ functions convert real numbers in IEEE-format to strings so they can be written to the random-access file. To write a real number to a random-access file in Microsoft Binary format, convert the number to a string using MKSMBF$ (for a single-precision number) or MKDMBF$ (for a double-precision number). Then store the result in the corresponding field (defined in the FIELD statement) and write the record to the file using the PUT statement. ž Example The following example uses MKSMBF$ to store real values in a file as Microsoft Binary format numbers: ' Read a name and a test score from the console. ' Store as a record in a random-access file. ' Scores are written out as ' Microsoft Binary format single-precision values. TYPE Buffer NameField AS STRING * 20 ScoreField AS STRING * 4 END TYPE DIM RecBuffer AS Buffer OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN=LEN(RecBuffer) PRINT "Enter names and scores, one name and score per line." PRINT "Enter END, 0 to end input." INPUT NameIn$, Score I=0 ' Read pairs of names and scores from the console ' until the name is END. DO WHILE UCASE$(NameIn$) <> "END" I=I+1 RecBuffer.NameField=NameIn$ ' Convert the score to a string. RecBuffer.ScoreField=MKSMBF$(Score) PUT #1,I,RecBuffer INPUT NameIn$, Score LOOP PRINT I;" records written." CLOSE #1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MKD$, MKI$, MKL$, MKS$ Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Converts numeric values to string values ž Syntax MKI$(integerexpression) MKS$(single-precision-expression) MKL$(long-integer-expression) MKD$(double-precision-expression) ž Remarks The MKI$, MKS$, MKL$, and MKD$ functions are used with FIELD and PUT statements to write real numbers to a random-access file. The functions take numeric expressions and convert them to strings that can be stored in the strings defined in the FIELD statement. The functions are the inverse of CVI, CVS, CVL, and CVD. Function Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MKI$ Converts an integer to a two-byte string MKS$ Converts a single-precision value to a four-byte string MKL$ Converts a long-integer value to a four-byte string MKD$ Converts a double-precision value to an eight-byte string ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE BASIC record variables provide a more efficient and convenient way of reading and writing random-access files. See Chapter 3, "File and Device I/O," in Programming in BASIC for a discussion of the new method. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CVI, CVS, CVL, CVD; FIELD; PUT ž Example See the example for the CVI, CVS, CVL, CVD statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NAME Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Changes the name of a disk file or directory ž Syntax NAME oldfilename AS newfilename ž Remarks The NAME statement is similar to the DOS RENAME command. NAME can move a file from one directory to another but cannot move a directory. The arguments oldfilename and newfilename are string expressions each of which contains a file or directory name and an optional path. If the path in newfilename is different from the path in oldfilename, the NAME statement changes the pathname as well as renames the file as indicated. A file named oldfilename must exist and the newfilename must not be in use. Both files must be on the same drive. Using NAME with different drive designations in the old and new file names produces an error message that reads Rename across disks. After a NAME statement, the file or directory exists on the same disk, in the same disk space, but with the new name. Using NAME on an open file causes a run-time error message reading File already open. You must close an open file before renaming it. ž Examples The following statements show NAME used with and without a path specification: 'Changes the name of file ACCTS to LEDGER. NAME "ACCTS" AS "LEDGER" 'Moves file CLIENTS from directory X to directory \XYZ\P. NAME "\X\CLIENTS" AS "\XYZ\P\CLIENTS" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OCT$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string representing the octal value of the numeric argument ž Syntax OCT$(numeric-expression) ž Remarks The numeric-expression may be of any type. The numeric-expression is rounded to an integer or long integer before the OCT$ function evaluates it. ž See Also HEX$ ž Example The following line prints the octal representation of 24: PRINT OCT$(24) ž Output 30 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ON event Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Indicates the first line of an event-trapping subroutine ž Syntax ON event GOSUB {linenumber | linelabel } ž Remarks The ON event statement lets you specify a subroutine that is executed whenever an event occurs on a specified device. The following list describes the parts of the statement: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ event Specifies the event that causes a branch to the event-trapping subroutine. An event is a condition on a specific device. See below for more information about specific devices. linenumber linelabel The number or label of the first line in the event-trapping subroutine. This line must be in the module-level code. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A linenumber of 0 disables event trapping and does not specify line 0 as the start of the subroutine. The following list describes the events that can be trapped: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Event Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COM(n) Branches to the subroutine when characters are received at a communications port. The integer expression n indicates one of the serial ports, either 1 or 2. KEY(n) Branches to the subroutine when a specified key is pressed. The integer expression n is the number of a function key, direction key, or user-defined key. See Appendix A, "Keyboard Scan Codes and ASCII Character Codes," and the KEY statement for more information about these values. PEN Branches to the subroutine when a lightpen is activated. Event Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  activated. PLAY(queuelimit) Branches when the number of notes in the music buffer goes from queuelimit to queuelimit-1. The value of queuelimit is an integer expression from 1 to 32. A PLAY event-trapping subroutine can be used with a PLAY statement to play music in the background while a program is running. STRIG(n) Branches to the event-trapping subroutine when a joystick trigger is pressed. The integer expression n is the joystick trigger number: 0 for the lower button and 4 for the upper button on the first joystick; 2 for the lower button and 6 for the upper button on the second joystick. TIMER(n) Branches to the subroutine when n seconds have Event Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  TIMER(n) Branches to the subroutine when n seconds have passed. The integer expression n is in the range 1 to 86,400 (1 second to 24 hours). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The ON event statement only specifies the start of an event-trapping subroutine. Another set of statements determines whether or not the subroutine is called. This set of statements turns event trapping on or off and determines how events are handled when trapping is off. The following list describes these statements in a general way. See the entries for particular statements for more specific information. Event Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ event ON Enables event trapping. Event trapping occurs only after an event ON statement is executed. event OFF Disables event trapping. No trapping takes place until the execution of another event ON statement. Events occurring while trapping is off are ignored. event STOP Inhibits event trapping so no trapping takes place until an event ON statement is executed. Events occurring while trapping is inhibited are remembered and processed when an event ON statement is executed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When an event trap occurs (the subroutine is called), BASIC performs an automatic event STOP that prevents recursive traps. The RETURN from the trapping subroutine automatically performs an event ON statement unless an explicit event OFF is performed inside the subroutine. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Because of the implicit event STOP and event ON statements, the events during execution of the trapping subroutine are remembered and processed when the trapping subroutine ends. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The RETURN linenumber or RETURN linelabel forms of RETURN can be used to return to a specific line number from the trapping subroutine. Use this type of return with care, however, because any other GOSUB, WHILE, or FOR statements active at the time of the trap remain active. This may produce 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ÄÄthe line number or label must be in the module-level code. The next three sections contain additional information about the ON COM, ON KEY, and ON PLAY statements. USING ON COM If your program receives data using an asynchronous communications adapter, the BASIC command-line option /C can be used to set the size of the data buffer. USING ON KEY Keys are processed in the following order: 1. The line printer's echo-toggle key is processed first. Making this key a user-defined key trap does not prevent characters from being echoed to the line printer when pressed. 2. Function keys and the cursor-direction keys are examined next. Defining a FUNCTION key or DIRECTION key as a user-defined key trap has no effect because these keys are predefined. 3. Finally, the user-defined keys are examined. The ON KEY statement can trap any key, including BREAK or system reset. This makes it possible to prevent accidentally breaking out of a program or rebooting the machine. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE When a key is trapped, the key event is destroyed. You cannot subsequently use INPUT or INKEY$ statements to find out which key caused the trap. Because there is no way to know which key press caused the branch to the trap, you must set up a subroutine for each key if you want to assign different functions to particular keys. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ USING ON PLAY The following three rules apply to the use of ON PLAY: 1. A play event trap occurs only when music is playing in the background. Play event traps do not occur when music is running in the foreground. 2. A play event trap does not occur if the background music queue has already gone from having queuelimit to queuelimit-1 notes when a PLAY ON is executed. 3. If queuelimit is a large number, event traps may occur often enough to slow down the program. ž Differences From Basica If you use BC from the DOS prompt, you must use /V or /W if a program contains ON event statements to allow the compiler to function correctly when event-trapping subroutines are included in a program. BASICA does not require additional options. ž See Also COM, KEY (n), PEN ON, PLAY ON, RETURN, STRIG ON, TIMER ON ž Examples The following example plays continuous music by calling an event-handling subroutine whenever the music buffer goes from three to two notes: ' Call subroutine Background when the music buffer goes from ' 3 to 2 notes. ON PLAY(3) GOSUB Background ' Turn on event trapping for PLAY. PLAY ON ' Define a string containing the melody. Lizzie$="o3 L8 E D+ E D+ E o2 B o3 D C L2 o2 A" ' Play the melody for the first time. PLAY "MB X" + VARPTR$(Lizzie$) ' Continue until a key is pressed. LOCATE 2,1 : PRINT "Press any key to stop."; DO WHILE INKEY$="" LOOP END ' PLAY event-handling subroutine. Background: ' Increment and print a counter each time. Count% = Count% + 1 LOCATE 1,1 : PRINT "Background called ";Count%;"time(s)"; ' Execute another PLAY to fill the buffer. PLAY "MB X" + VARPTR$(Lizzie$) RETURN The following example draws a polygon every three seconds with a random shape (three to seven sides), size, and location: SCREEN 1 DEFINT A-Z DIM X(6), Y(6) TIMER ON 'Enable timer event trapping. ON TIMER(3) GOSUB Drawpoly 'Draw a new polygon every 'three seconds. PRINT "Press any key to end program" INPUT "Press to start",Test$ DO LOOP WHILE INKEY$="" 'End program if any key pressed. END Drawpoly: CLS 'Erase old polygon. N = INT(5*RND + 2) 'N is random number from 2 to 6. FOR I = 0 TO N X(I) = INT(RND*319) 'Get coordinates of vertices of Y(I) = INT(RND*199) 'polygon. NEXT PSET (X(N),Y(N)) FOR I = 0 TO N LINE -(X(I),Y(I)),2 'Draw new polygon. NEXT RETURN ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ON ERROR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables error handling and specifies the first line of the error-handling routine ž Syntax ON ERROR GOTO line ž Remarks The line argument is the line number or line label of the first line in the error-handling routine. This line must appear in module-level code. If line cannot be found in the module where the error occurred, or if there is no ON ERROR GOTO statement, a backward search is made through the modules that invoked the module with the error. If an active error handler is found, it is used. If no active error handler is found, an error message is printed and program execution halts. The specific error message depends on the type of error. Only modules in the invocation path are searched. Modules outside the path are not searched, even if there is no active error handler in the search path. A line number of 0 disables error handling. It does not specify line 0 as the start of the error-handling code, even if the program contains a line numbered 0. Subsequent errors print an error message and halt the program. Once error handling is enabled, any error that can be trapped causes a jump to the specified error-handling routine. Inside an error handler, executing an ON ERROR statement with a line number of 0 halts program execution and prints the error message for the error that caused the trap. This is a convenient way to halt a program in response to errors that cannot be processed by the error-handling routine. Note that an error-handling routine is not a SUB or FUNCTION procedure or a DEF FN function. An error-handling routine is a module-level block of code marked by a line label or line number. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Errors occurring within an error-handling routine are not trapped. These errors halt program execution after printing an error message. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica Compiling from the BC command line requires additional options when you use ON ERROR GOTO. BASICA does not require any additional options. If a program contains ON ERROR GOTO or RESUME linenumber statements, you must use the On Error /E compile option when compiling from the BC command line. If a program contains the statements RESUME, RESUME NEXT, or RESUME 0, you must also use the Resume Next /X compile option when compiling from the command line. No compile options are required when compiling within the QuickBASIC environment. ž See Also ERR, ERL; ERROR; RESUME ž Example The following program gets a file name from the user and displays the file on the screen. If the file cannot be opened, an error-handling routine traps the error and starts the program again at the prompt for the file name. DEFINT A-Z ' Establish the error-handling routine. ON ERROR GOTO ErrorHandler CLS ' Get a file name. INPUT "Enter the file to display: ",filename$ ' Open the file. OPEN filename$ FOR INPUT AS #1 ' Display the file on the screen. DO WHILE NOT EOF(1) LINE INPUT #1, aline$ PRINT aline$ LOOP END ' Error handling routine handles only "Bad file name," ' aborts on any other error. CONST BADFILENAME=64 ErrorHandler: IF ERR=BADFILENAME THEN ' Get another file name. PRINT "File "; UCASE$(filename$); " not found." INPUT "Enter the file to display: ",filename$ RESUME ELSE ' Some other error, so print message and abort. PRINT "Unrecoverable error--";ERR ON ERROR GOTO 0 END IF ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ON...GOSUB, ON...GOTO Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Branches to one of several specified lines, depending on the value of an expression ž Syntax 1 ON expression GOSUB {line-number-list | line-label-list } ž Syntax 2 ON expression GOTO {line-number-list | line-label-list } ž Remarks The expression argument can be any numeric expression (expression is rounded to an integer before the ON...GOSUB or ON...GOTO is evaluated). The line-number-list or line-label-list consists of a list of line numbers or line labels, separated by commas. The value of expression determines which line the program branches to. For example, if the value is 3, the third line specified in the list is the destination of the branch. The value of expression should be greater than or equal to 1 and less than or equal to the number of items in the list. If the value falls outside this range, one of the following results occurs: Value Result ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Number equal to 0 or greater than number of Control drops to the next items in list BASIC statement. Negative number or a number greater than 255 An error message appears that reads Illegal function call. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You may mix line numbers and labels in the same list. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The ON...GOTO statement accepts a maximum of 60 line labels or line numbers. The SELECT CASE statement provides a more powerful, convenient, and flexible way to do multiple branches. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also GOSUB, RETURN, SELECT CASE ž Example The following program fragment causes program control to branch to one of the four subroutines listed, depending on the value of Chval: DO CLS PRINT "1) Display attendance at workshops." PRINT "2) Calculate total registration fees paid." PRINT "3) Print mailing list." PRINT "4) End program." PRINT : PRINT "What is your choice?" DO Ch$=INKEY$ LOOP WHILE Ch$="" Chval = VAL(Ch$) IF Chval > 0 AND Chval < 5 THEN ON Chval GOSUB Shop, Fees, Mailer, Progend END IF LOOP END . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ON UEVENT GOSUB Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Defines the event-handler for a user-defined event ž Syntax ON UEVENT GOSUB { linenumber | linelabel } ž Remarks The linenumber or linelabel argument is the number or label of the first line in the event-handling routine. ON UEVENT GOSUB lets your program branch to an event-handling routine when a user-defined event occurs. The event is usually a hardware interrupt. This gives user-defined events one of the features enjoyed by the COM, KEY, and other events in BASIC. Once these events have been defined with an ON event statement, they act like interrupts. The program does not need to poll for the event. Likewise, once ON UEVENT GOSUB and UEVENT ON have been executed, the user-defined event automatically triggers execution of the BASIC routine to handle it. The program does not have to poll. At least two (and sometimes three) pieces of code are needed to set up a user-defined event. The first is the interrupt service routine. The second is an initialization routine to insert the address of the service routine into the interrupt vector table. The third is the routine your BASIC program calls to retrieve the data (if any) collected by the interrupt service routine. If the initialization routine "steals" an interrupt used by another service routine, the original address must be restored before your program terminates. These routines are usually written in assembly language. However, any language whose compiler can generate interrupt service routines and whose object code can be linked with BASIC may be used. There are four steps in creating a user-defined event: 1. Write an event-handling routine and add it to your BASIC program. 2. Execute the ON UEVENT GOSUB statement to specify the user-event handling routine. 3. Execute the UEVENT ON statement to enable user-event trapping. 4. Call the interrupt-initialization routine to insert the address of the interrupt service routine into the interrupt vector table. You're now ready for the interrupt when it occurs. The interrupt transfers execution to the interrupt service routine. The service routine collects and stores the data the user wants. It then calls SetUEvent. SetUEvent sets a flag checked by QuickBASIC before going to the next BASIC statement (or label if executing compiled code using /W instead of /V). When the flag is set, control transfers to the event-handling routine designated in ON UEVENT GOSUB. The SetUEvent procedure is a part of BASIC, and is automatically included in compiled applications or when running QuickBASIC with the /L command-line option. Your interrupt service routine must call SetUEvent; it is the only way to alert your program that the event has occurred. You can call SetUEvent from any language, not just from assembly language. SetUEvent is not a function; it cannot return a value to BASIC. If you wish to return a value, you must write a function for your BASIC program to call. (It would usually be called by your event-handling routine.) This function must be described in a DECLARE statement so your BASIC program can find and use it. Although ON UEVENT GOSUB ties an event-handling routine to a user-defined event, it does not enable the event trap. The UEVENT statement is used to enable, disable, and suspend user-defined event trapping. ž See Also UEVENT ž Example The following example illustrates the use of ON UEVENT GOSUB: DECLARE SUB test (a) ON UEVENT GOSUB Event1 UEVENT ON INPUT "Enter a number";a CALL test(a) END Event1: PRINT "Got to the event handler" RETURN SUB test(a) IF a=5 THEN CALL SetUEvent END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OPEN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables I/O to a file or device ž Syntax 1 OPEN file ®FOR mode1Æ ®ACCESS accessÆ ®lockÆ AS ®#Æ filenum ®LEN=reclenÆ ž Syntax 2 OPEN mode2,®#Æfilenum, file ®,reclenÆ ž Remarks The file is a string expression that specifies an optional device, followed by a file name or path name conforming to the DOS file-naming conventions. You must open a file before any I/O operation can be performed on it. OPEN allocates a buffer for I/O to the file or device and determines the mode of access used with the buffer. SYNTAX 1 In the first syntax, mode1 is one of the following: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OUTPUT Specifies sequential output mode. Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  INPUT Specifies sequential input mode. APPEND Specifies sequential output mode and sets the file pointer to the end of file and the record number to the last record of the file. A PRINT # or WRITE # statement then extends (appends to) the file. RANDOM Specifies random-access file mode, the default mode. In RANDOM mode, if no ACCESS clause is present, three attempts are made to open the file when the OPEN statement is executed. Access is attempted in the following order: 1. Read/write 2. Write-only Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  3. Read-only BINARY Specifies binary file mode. In binary mode, you may read or write information to any byte position in the file using GET and PUT. In binary mode, if no ACCESS clause is present, three attempts are made to open the file. The attempts follow the same order as those for RANDOM files. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If mode1 is omitted, the default random-access mode is assumed. The access expression specifies the operation performed on the opened file. If the file is already opened by another process and the specified type of access is not allowed, the OPEN fails and an error message is generated that reads Permission denied. The ACCESS clause works in an OPEN statement only if you are using a version of DOS that supports networking (DOS Versions 3.0 or later). In addition, you must run the SHARE.EXE program (or the network startup program must run it) to perform any locking operation. If ACCESS is used with OPEN, earlier versions of DOS return an error message that reads Advanced feature unavailable. The access argument can be one of the following: Access Type Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ READ Opens the file for reading only. WRITE Opens the file for writing only. READ WRITE Opens the file for both reading and writing. This mode is valid only for RANDOM and BINARY files and files opened for APPEND. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The lock clause works in a multiprocessing environment to restrict access by other processes to an open file. The lock types are as follows: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Lock Type Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Default If locktype is not specified, the file may be opened for reading and writing any number of times by this process, but other processes are denied access to the file while it is opened. SHARED Any process on any machine may read from or write to this file. Do not confuse the SHARED lock type with the SHARED statement or the SHARED attribute appearing in other statements. LOCK READ No other process is granted read access to this file. This access is granted only if no other process has a previous READ access to the file. LOCK WRITE No other process is granted write access to this file. This lock is granted only if no other process has a previous WRITE access to the file. Lock Type Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  process has a previous WRITE access to the file. LOCK READ WRITE No other process is granted either read or write access to this file. This access is granted only if READ or WRITE access has not already been granted to another process, or if a LOCK READ or LOCK WRITE is not already in place. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When the OPEN is restricted by a previous process, it generates error 70, Permission denied, under DOS. The filenum (file number) argument is an integer expression whose value is between 1 and 255. When an OPEN is executed, the file number is associated with the file as long as it is open. Other I/O statements may use the number to refer to the file. The reclen (record length) argument is an integer expression that, if included, sets the record length (number of characters in one record) for random-access files. For sequential files, the default length for records is 512 bytes; for random-access files, the default is 128 bytes. The value of reclen cannot exceed 32,767 bytes. If the file mode is binary, then the LEN clause is ignored. For sequential files, reclen need not correspond to an individual record size, since a sequential file may have records of different sizes. When used to open a sequential file, reclen specifies the number of characters to be loaded into the buffer before the buffer is written to, or read from, the disk. A larger buffer means more room taken from BASIC, but faster file I/O. A smaller buffer means more room in memory for BASIC, but slower I/O. The default buffer size is 512 bytes. SYNTAX 2 In the second form of the OPEN syntax, mode2 is a string expression the first character of which must be one of the following: Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ O Specifies sequential output mode. I Specifies sequential input mode. R Specifies random-access file input/output mode. B Specifies binary file mode. A Specifies sequential output mode and sets the file pointer to the end of the file and the record number to the last record of the file. A PRINT # or WRITE # statement extends (appends to) the file. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The second form of the OPEN syntax does not support any of the access and file-sharing options found in the first syntax and is supported for compatibility with programs written in earlier versions of BASIC. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The following devices are supported by BASIC and can be named and opened with the file argument: KYBD:, SCRN:, COMn:, LPTn:, CONS:. The BASIC file I/O system allows you to take advantage of user-installed devices. (See your DOS manual for information on character devices.) Character devices are opened and used in the same manner as disk files. However, characters are not buffered by BASIC as they are for disk files. The record length for the device files is set to one. BASIC only sends a carriage return at the end of a line. If the device requires a line feed, the driver must provide it. When writing device drivers, keep in mind that other BASIC users will want to read and write control information. The writing and reading of device-control data is handled by the IOCTL statement and IOCTL$ function. None of the BASIC devices directly supports binary mode. However, the line printer devices (LPT1:, LPT2:) can be opened in binary mode by adding the BIN keyword: OPEN "LPT1:BIN" FOR OUTPUT AS #1 Opening a printer in BIN mode eliminates printing a carriage return at the end of a line. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE In INPUT, RANDOM, and BINARY modes you can open a file under a different file number without first closing the file. In OUTPUT or APPEND mode you must close a file before opening it with a different file number. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also FREEFILE ž Examples The following statement opens MAILING.DAT as file number 1 and allows data to be added without destroying what is already in MAILING.DAT: OPEN "MAILING.DAT" FOR APPEND AS #1 If you wrote and installed a device driver named ROBOT, then the OPEN statement might appear as OPEN "\DEV\ROBOT" FOR OUTPUT AS #1 To open the printer for output, you could use either of the following two lines. (The first line uses the BASIC device LPT1: while the second line uses the DOS device LPT1.) OPEN "LPT1:" FOR OUTPUT AS #1 OPEN "LPT1" FOR OUTPUT AS #1 The following statement opens the file RECORDS in random-access mode, for reading only. The statement locks the file for writing, but allows reading by other processes while the OPEN is in effect. OPEN "RECORDS" FOR RANDOM ACCESS READ LOCK WRITE AS #1 The following example opens the file named INVEN for input as file number 2: OPEN "I",2,"INVEN" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OPEN COM Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Opens and initializes a communications channel for I/O ž Syntax OPEN "COMn: optlist1 optlist2" ®FOR modeÆ AS ®#Æfilenum ®LEN=reclenÆ ž Remarks COMn: is the name of the device to be opened. The n argument is the number of a legal communications device, such as COM1: or COM2:. The first list of options, optlist1, has the following form: ®speedÆ®,®parityÆ ®,®dataÆ®,®stopÆÆÆÆ The following list describes the possible options: Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ speed The "baud" rate (baud means "bits per second") of the device to be opened. Valid speeds are 75, 110, 150, 300, 600, 1200, 1800, 2400, 4800, and 9600. The default is 300 bps. parity The parity of the device to be opened. Valid entries for parity are: N (none), E (even), O (odd), S (space), or M (mark). data The number of data bits per byte. Valid entries are 5, 6, 7, or 8. stop The number of stop bits. Valid entries are 1, 1.5, or 2. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Options from this list must be entered in the order shown; moreover, if any options from optlist2 are chosen, comma placeholders must still be used even if none of the options from optlist1 are chosen. For example: OPEN "COM1: ,,,,CD1500" FOR INPUT AS #1 If you set the data bits per byte to eight, you must specify no parity (N). Because QuickBASIC uses complete bytes (eight bits) for numbers, you must specify eight data bits when transmitting or receiving numeric data. The choices for optlist2 are described in the following list. The argument m is given in milliseconds; the default value for m is 1000. ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ASC Opens the device in ASCII mode. In ASCII mode, Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ASC Opens the device in ASCII mode. In ASCII mode, tabs are expanded to spaces, carriage returns are forced at end-of-line, and CTRL+Z is treated as end-of-file. When the channel is closed, CTRL+Z is sent over the RS-232 line. BIN Opens the device in binary mode. This option supersedes the LF option. BIN is selected by default unless ASC is specified. In the BIN mode, tabs are not expanded to spaces, a carriage return is not forced at the end-of-line, and CTRL+Z is not treated as end-of-file. When the channel is closed, CTRL+Z will not be sent over the RS-232 line. CD®mÆ Controls the timeout on the Data Carrier Detect line (DCD). If DCD is low for more than m milliseconds, a device timeout occurs. Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  CS®mÆ Controls the timeout on the Clear To Send line (CTS). If CTS is low (there is no signal) for more than m milliseconds, a device timeout occurs. DS®mÆ Controls the timeout on the Data Set Ready line (DSR). If DSR is low for more than m milliseconds, a device timeout occurs. LF Allows communication files to be printed on a serial line printer. When LF is specified, a line-feed character (0AH) is automatically sent after each carriage-return character (0DH). This includes the carriage return sent as a result of the width setting. Note that INPUT and LINE INPUT, when used to read from a COM file that was opened with the LF option, stop when they see a carriage return, ignoring the line feed. Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  carriage return, ignoring the line feed. OP®mÆ Controls how long the statement waits for the open to be successful. The parameter m is a value in the range 0 to 65,535 representing the number of milliseconds to wait for the communications lines to become active. If OP is specified without a value, the statement waits indefinitely. If OP is omitted, OPEN COM waits for ten times the maximum value of the CD or DS timeout values. RB®nÆ Sets the size of the receive buffer to n bytes. If n is omitted, or the option is omitted, the current value is used. The current value can be set by the /C option on the QuickBASIC or BC command line. The default is 512 bytes. The maximum size is 32,767 bytes. Option Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  RS Suppresses detection of Request To Send (RTS). TB®nÆ Sets the size of the transmit buffer to n bytes. If n is omitted, or the option is omitted, the current value is used. The default size is 512 bytes. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The options from the list above can be entered in any order, but they must be separated from one another by commas. For CS®mÆ, DS®mÆ, and CD®mÆ, if there is no signal within m milliseconds, a timeout occurs. The value for m may range from 0 to 65,535, with 1000 as the default value. (The CD default is 0.) If m is equal to 0 for any of these options the option is ignored. The CTS line is checked whenever there is data in the transmit buffer if the CS option is specified. The DSR and DCD lines are continuously checked for timeouts if the corresponding options (DS, CD) are specified. The mode argument is one of the following string expressions: Mode Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OUTPUT Specifies sequential output mode INPUT Specifies sequential input mode RANDOM Specifies random-access mode ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If the mode expression is omitted, it is assumed to be random-access input/output. The filenum is the number used to open the file. The OPEN COM statement must be executed before a device can be used for communication using an RS-232 interface. If the device is opened in RANDOM mode, the LEN option specifies the length of an associated random-access buffer. The default value for length is 128. You can use any of the random-access I/O statements, such as GET and PUT, to treat the device as if it were a random-access file. The OPEN COM statement performs the following steps in opening a communications device: 1. The communications buffers are allocated and interrupts are enabled. 2. The Data Terminal Ready line (DTR) is set high. 3. If either of the OP or DS options is nonzero, the statement waits up to the indicated time for the Data Set Ready line (DSR) to be high. If a timeout occurs, the process goes to step 6. 4. The Request To Send line (RTS) is set high if the RS option is not specified. 5. If either of the OP or CD options is nonzero, OPEN COM waits up to the indicated time for the Data Carrier Detect line (DCD) to be high. If a timeout occurs, the process goes to step 6. Otherwise, OPEN COM has succeeded. 6. The open has failed due to a timeout. The process deallocates the buffers, disables interrupts, and clears all of the control lines. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Use a relatively large value for the OP option compared to the CS, DS, or CD options. If two programs are attempting to establish a communications link, they both need to attempt an OPEN during at least half of the time they are executing. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Any syntax errors in the OPEN COM statement produce an error message that reads Bad file name. ž Example The following program fragment opens communications channel 1 in random-access mode at a speed of 9600 baud, no parity bit, eight data bits, and one stop bit. Input/output will be in the binary mode. Other lines in the program can now access channel 1 as file number 2. OPEN "COM1:9600,N,8,1,BIN" AS 2 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OPTION BASE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Declares the default lower bound for array subscripts ž Syntax OPTION BASE n ž Remarks The OPTION BASE statement is never required. It is used to change the default lower bound for array subscripts. The value of n must be either 0 or 1. The default base is 0. If the following statement OPTION BASE 1 is executed, the lowest value an array subscript can have is 1. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The TO clause in the DIM statement provides an easier, more flexible way to control the range of an array's subscripts. If the lower bound of an array subscript is not explicitly set, then OPTION BASE can be used to change the default lower bound to 1. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The OPTION BASE statement can be used only once in a module (source file) and can only appear in the module-level code. An OPTION BASE statement must be used before any arrays are dimensioned. Chained programs may have an OPTION BASE statement if no arrays are passed in COMMON between them or if the specified base is identical in the chained programs. The chained-to program inherits the OPTION BASE value of the chaining program if OPTION BASE is omitted in the latter. ž See Also DIM, LBOUND, REDIM ž Example The following statement overrides the default value of zero, so the lowest value a subscript in an array can have in this program is 1: OPTION BASE 1 DIM A(20) PRINT LBOUND(A), UBOUND(A) ž Output 1 20 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ OUT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sends a byte to a machine I/O port ž Syntax OUT port, data ž Remarks The following list describes the arguments of the OUT statement: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ port The number of the port. The number must be an integer expression in the range 0-65,535. data The data to be sent to the port. It must be an integer expression in the range 0-255. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The OUT and INP statements give a BASIC program direct control over the hardware in a system through the I/O ports. These statements must be used carefully because they directly manipulate the hardware. ž See Also INP, WAIT ž Example The following example uses OUT and INP to control the timer and speaker to produce a note. (This example is specific to the IBM PC and close compatibles and produces unpredictable results on other machines.) ' Play a scale using the speaker and timer. CONST WHOLE=5000!, QRTR=WHOLE/4. CONST C=523.0, D=587.33, E=659.26, F=698.46, G=783.99, A=880.00 CONST B=987.77, C1=1046.50 CALL Sounds(C,QRTR) : CALL Sounds(D,QRTR) CALL Sounds(E,QRTR) : CALL Sounds(F,QRTR) CALL Sounds(G,QRTR) : CALL Sounds(A,QRTR) CALL Sounds(B,QRTR) : CALL Sounds(C1,WHOLE) ' Use ports 66, 67, and 97 to control the timer and speaker ' to produce a sound. SUB Sounds (Freq!,Length!) STATIC ' Divide the clock frequency by the sound frequency to ' get the number of "clicks" the clock must produce. Clicks%=CINT(1193280!/Freq!) LoByte%=Clicks% AND &H00FF HiByte%=Clicks%\256 ' Tell timer that data is coming. OUT 67,182 ' Send the low byte followed by the high byte of the count. OUT 66,LoByte% OUT 66,HiByte% ' Turn the speaker on by setting bits 0 and 1 of the PPI chip. ' Get the current value, and turn the bits on. SpkrOn%=INP(97) OR &H03 OUT 97,SpkrOn% ' Leave the speaker on for a while. FOR I!=1 TO Length! : NEXT I! ' Turn the speaker off. SpkrOff%=INP(97) AND &HFC OUT 97,SpkrOff% END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PAINT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Fills a graphics area with the color or pattern specified ž Syntax PAINT ®STEPÆ (x,y)®,®paintÆ ®,®bordercolorÆ ®,backgroundÆÆÆ ž Remarks The following list describes the parts of the PAINT statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STEP Defines coordinates to be relative to the most recently plotted point. For example, if the last point plotted were (10,10), then the coordinates referred to by STEP (4,5) would be (4+10, 5+10) or (14,15). (x,y) The coordinates where painting begins. The point must be inside or outside a figure, not on the border itself. If this point is inside, the figure's interior is painted; if the point is on the outside, the background is painted. paint A numeric or string expression. If paint is a numeric expression, then the number must be a valid color attribute. The corresponding color is Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  valid color attribute. The corresponding color is used to paint the area. If you do not specify paint, the foreground color attribute is used. (See the COLOR, PALETTE, and SCREEN statements for discussions of valid colors, numbers, and attributes.) If the paint argument is a string expression, then PAINT does "tiling," a process that paints a pattern rather than a solid color. Tiling is similar to "line styling," which creates dashed lines rather than solid lines. bordercolor A numeric expression identifying the color attribute to use to paint the border of the figure. When the border color is encountered, painting of the current line stops. If the border color is not specified, the paint argument is used. Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  used. background A string value giving the "background tile slice" to skip when checking for termination of the boundary. Painting is terminated when adjacent points display the paint color. Specifying a background tile slice allows you to paint over an already painted area. When you omit background the default is CHR$ (0). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Painting is complete when a line is painted without changing the color of any pixel, in other words, when the entire line is equal to the paint color. The PAINT command permits coordinates outside the screen or viewport. Tiling "Tiling" is the design of a PAINT pattern that is eight bits wide and up to 64 bytes long. In the tile string, each byte masks eight bits along the x-axis when putting down points. The syntax for constructing this tile mask is PAINT (x,y), CHR$(arg1)+CHR$(arg2)+...+CHR$(argn) The arguments to CHR$ are numbers between 0 and 255, represented in binary form across the x axis of the tile. There can be up to 64 of these CHR$ elements; each generates an image not of the assigned character, but of the bit arrangement of the code for that character. For example, the decimal number 85 is binary 01010101; the graphic image line on a black-and-white screen generated by CHR$(85) is an eight-pixel line, with even-numbered points white and odd-numbered points black. That is, each bit equal to 1 turns the associated pixel on and each bit equal to 0 turns the associated bit off in a black-and-white system. The ASCII character CHR$(85), which is U, is not displayed in this case. When supplied, background defines the "background tile slice" to skip when checking for boundary termination. You cannot specify more than two consecutive bytes that match the tile string in the tile background slice. Specifying more than two consecutive bytes produces an error message that reads Illegal function call. Tiling can also be done to produce various patterns of different colors. See Chapter 5, "Graphics," in Programming in BASIC for a complete description of how to do tiling. ž See Also CHR$, CIRCLE, DRAW, LINE, SCREEN ž Example The following program draws a magenta fish with a cyan tail: CONST PI=3.1415926536 CLS SCREEN 1 CIRCLE (190,100),100,1,,,.3 'Outline fish body in cyan. CIRCLE (265,92),5,1,,,.7 'Outline fish eye in cyan. PAINT (190,100),2,1 'Fill in fish body with magenta. LINE (40,120)-STEP (0,-40),2 'Outline LINE -STEP (60,+20),2 ' tail in LINE -STEP (-60,+20),2 ' magenta. PAINT (50,100),1,2 'Paint tail cyan. CIRCLE (250,100),30,0,PI*3/4,PI* 5/4,1.5 'Draw gills in black. FOR Y = 90 TO 110 STEP 4 LINE (40,Y)-(52,Y),0 'Draw comb in tail. NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PALETTE, PALETTE USING Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Changes one or more of the colors in the palette ž Syntax PALETTE ®attribute,colorÆ PALETTE USING array-name ®(array-index)Æ ž Remarks The PALETTE statement takes the following arguments: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ attribute The palette attribute to be changed. color The display color number to be assigned to the attribute. The color must be a long integer expression for the IBM Video Graphics Array adapter (VGA) and IBM Multicolor Graphics Array adapter (MCGA) in screen modes 11 to 13. Integer or long-integer expressions may be used with the Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  or long-integer expressions may be used with the IBM Enhanced Graphics Adapter (EGA). array-name An array containing the color numbers to be assigned to the attributes available in the current screen mode. The VGA and MCGA adapters require a long integer array in screen modes 11 to 13. With the EGA this can be either an integer or long-integer array. array-index The index of the first array element to use in setting the palette. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The PALETTE statement works only on systems equipped with the EGA, VGA, or MCGA adapters. The statement provides a way of mapping display colors (the actual binary values used by the adapter) to color attributes (a smaller set of values). All BASIC graphics statements such as CIRCLE, COLOR, DRAW, or LINE use color attributes rather than display-color values. When a program enters a screen mode, the attributes are set to a series of default color values. (See the SCREEN statement for a list of the default colors.) In the EGA, VGA, and MCGA adapters these default values have been selected so the display shows the same colors, even though the EGA uses different color values. With the palette statement you can assign different colors to the attributes, giving you greater control over the colors on the display. A PALETTE statement with no arguments sets the palette back to the default color values. When you execute a PALETTE statement with arguments, the adapter subsequently uses the display color (indicated by color) whenever the value attribute appears in a statement like DRAW or LINE that specifies a color. Changing the display color assigned to an attribute changes the color on the screen immediately. For example, assume that the current palette contains colors 0, 1, 2, and 3 in the four attributes numbered 0, 1, 2, and 3. The DRAW statement DRAW "C3L100" selects attribute 3, and draws a line of 100 pixels using the display color associated with attribute 3, in this case also 3. If the statement PALETTE 3,2 is executed, then the color associated with attribute 3 is changed to color 2. All text or graphics currently on the screen displayed using attribute 3 are instantaneously changed to color 2. Text or graphics subsequently displayed with attribute 3 are also displayed in color 2. The new palette of colors contains 0, 1, 2, and 2. With the USING option, all entries in the palette can be modified in one PALETTE statement. The array-name argument is the name of an integer or long-integer array and the array-index specifies the index of the first array element in the array-name to use in setting the palette. Each attribute in the palette is assigned a corresponding color from this array. The array must be dimensioned large enough to set all the palette entries after array-index. For example, if you are assigning colors to all 16 attributes, and the index of the first array element that is given in your PALETTE USING statement is 5, then the array must be dimensioned to hold at least 20 elements (since the number of elements from 5-20, inclusive, is 16): DIM PAL%(20) . . . PALETTE USING PAL%(5) A color argument of -1 in the array leaves the attribute unchanged. All other negative numbers are invalid values for color. You can use the COLOR statement to set the default foreground color and the background display color. The foreground color argument specifies the way text characters appear on the display screen. Under a common initial palette setting, points colored with the attribute 0 appear black on the display screen. Using the PALETTE statement, you could, for example, change the mapping of attribute 0 from black to white. Table R.5 lists attribute and color ranges for various adapter types and screen modes. Table R.5 Screen Color and Attribute Ranges ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄ· Screen Monitor Attribute Color Mode Attached Adapter Range Range ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Monochrome MDPA 0-15 N/A Monochrome EGA 0-15 0-2 Color CGA 0-15 N/A Color/Enhanced EGA 0-15 0-63 N/A VGA 0-15 0-63 N/A MCGA 0-15 N/A 1 Color CGA 0-3 N/A Color/Enhanced EGA 0-3 0-15 N/A VGA 0-3 0-15 N/A MCGA 0-3 N/A 2 Color CGA 0-1 N/A Color/Enhanced EGA 0-1 0-15 Screen Monitor Attribute Color Mode Attached Adapter Range Range ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Color/Enhanced EGA 0-1 0-15 N/A VGA 0-1 0-15 N/A MCGA 0-1 N/A 7 Color/Enhanced EGA 0-15 0-15 N/A VGA 0-15 0-15 8 Color/Enhanced EGA 0-15 0-15 N/A VGA 0-15 0-15 9 Enhanced EGA 0-3 0-63 Enhanced EGA 0-15 0-63 N/A VGA 0-16 0-63 10 Monochrome EGA 0-3 0-8 N/A VGA 0-3 0-8 11 N/A VGA 0-1 0-262,143 N/A MCGA 0-1 0-262,143 12 N/A VGA 0-15 0-262,143 13 N/A VGA 0-255 0-262,143 N/A MCGA 0-255 0-262,143 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen Monitor Attribute Color Mode Attached Adapter Range Range ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The VGA uses a different way of calculating color values from the EGA. To calculate a color value, select the intensities of red, green, and blue. The intensity of a color is a number from 0 (low intensity) to 63 (high intensity). Then use the following formula to calculate the actual color number: color number = 65536 * blue + 256 * green + red Because there are gaps in the range of color numbers, you should use the formula rather than just select a number. When used with the IBM Analog Monochrome Monitor, the VGA color values are converted to a gray-scale value by taking a weighted sum of the red, blue, and green intensities as follows: gray value = 11% blue + 59% green + 30% red For example if the blue, green, and red intensities are 45, 20, and 20, the gray value would be .11*45+.59*20+.30*20 or 22 (the fraction in the result is dropped). See the SCREEN statement for the list of colors available for various screen-mode, monitor, and graphics-adapter combinations. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Because of their wide range of colors, the VGA and MCGA adapters require a long-integer array in the PALETTE USING statement in screen modes 11 to 13. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CIRCLE, COLOR, DRAW, LINE, SCREEN ž Examples The following lines show the different forms of the PALETTE and PALETTE USING statements: PALETTE 0,2 'Changes all points colored with attribute 0 to 'color 2. PALETTE USING A%(0) 'Changes each palette entry. Since the 'array is initialized to zero when it 'is first declared, all attributes are 'now mapped to display color zero. The 'screen will now appear as one single 'color. However, it will still be 'possible to execute BASIC statements. PALETTE 'Sets each palette entry to its appropriate 'initial display color. Actual initial colors 'depend on your screen-hardware configuration. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PCOPY Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Copies one screen page to another ž Syntax PCOPY sourcepage, destinationpage ž Remarks The sourcepage is an integer expression in the range 0 to n, where n is the maximum number of pages determined by the current video-memory size and the size per page for the current screen mode. The destinationpage has the same requirements as the sourcepage. See the SCREEN statement for more information about the number of pages available in different modes. ž See Also CLEAR, SCREEN ž Example The following example copies the contents of page 1 to page 2: PCOPY 1,2 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PEEK Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the byte stored at a specified memory location ž Syntax PEEK(address) ž Remarks The returned value is an integer in the range 0-255. The argument address is a value in the range 0-65,535. The argument address is treated as the offset from the current default segment (as set by the DEF SEG statement). If the argument is a single- or double-precision floating-point value or a long integer, it is converted to a two-byte integer. The PEEK function complements the POKE statement. ž See Also DEF SEG, POKE, VARPTR ž Example See the example for DEF SEG. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PEN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads the lightpen coordinates ž Syntax PEN(n) ž Remarks The argument n indicates what value is to be returned. It is a numeric expression in the range 0-9. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The PEN function does not work when the mouse driver is enabled because the mouse driver uses the PEN function's BIOS calls. Use mouse function 14 to disable the driver's lightpen emulation. Mouse function 13 turns emulation back on. See your mouse manual for more information. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The following list describes the values for n and the corresponding values returned by PEN: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 The most recent pen use: -1 if pen was down since last poll, 0 if not 1 The x pixel coordinate where pen was last pressed 2 The y pixel coordinate where pen was last pressed 3 The current pen-switch value: -1 if down, 0 if up Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  4 The last known valid x pixel coordinate 5 The last known valid y pixel coordinate 6 The character row position where pen was last pressed 7 The character column position where pen was last pressed 8 The last known character row where the pen was positioned 9 The last known character column where the pen was positioned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Example The following example produces an endless loop to print the current pen-switch status (UP/DOWN): CLS PEN ON DO P = PEN(3) LOCATE 1,1 : PRINT "PEN IS "; IF P THEN PRINT "DOWN" ELSE PRINT "UP" X = PEN(4) : Y = PEN(5) PRINT "X =" X, "Y =" Y LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PEN ON, OFF, and STOP Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables, disables, or suspends lightpen-event trapping ž Syntax PEN ON PEN OFF PEN STOP ž Remarks The PEN ON statement enables lightpen-event trapping by using an ON PEN statement. The pen is initially off. A lightpen event occurs whenever the lightpen is activated by pressing the tip to the screen or pressing the touch ring. A PEN ON statement must be executed before any read-pen function calls. If a read-pen function is called when the pen is off, an error message results that reads Illegal function call. The PEN OFF statement disables lightpen event trapping. The PEN STOP statement suspends lightpen event trapping; a pen event is remembered and trapped as soon as event trapping is enabled. To speed program execution, the pen should be turned off by using a PEN OFF statement when pen trapping is not needed. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The lightpen requires an IBM Color Graphics Adapter. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also ON event, PEN Function ž Example See the example for the PEN function. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PLAY Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Plays music as specified by a string ž Syntax PLAY commandstring ž Remarks The commandstring is a string expression containing one or more of the commands listed below. The PLAY statement uses a concept similar to DRAW in that it embeds a music macro language (described below) in one statement. A set of commands, used as part of the PLAY statement, specifies a particular action. In compiled programs, you should use the VARPTR$(variable) form for variables. For example, the BASICA statements PLAY "XA$" PLAY "O=I" should be written for the compiler like this: PLAY "X" + VARPTR$(A$) PLAY "O=" + VARPTR$(I) The commandstring music macros are described as follows: Octave Commands Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ o n Sets the current octave. There are seven octaves, numbered 0-6. > Increases octave by 1. Octave cannot go beyond 6. < Decreases octave by 1. Octave cannot drop below 0. Tone Commands Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A-G Plays a note in the range A-G. The "#" symbol or the "+" symbol after a note specifies sharp; a "-" specifies flat. N n Plays note n. The range for n is 0-84 (in the seven possible octaves, there are 84 notes); n = 0 means a rest. Duration Commands Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ L n Sets the length of each note. L4 is a quarter note, L1 is a whole note, etc. The range for n is 1-64. The length may also follow the note when a change of length only is desired for a particular note. In this case, A16 is equivalent to L16A. MN Sets "music normal" so that each note will play 7/8 of the time determined by the length (L). ML Sets "music legato" so that each note will play the full period set by length (L). MS Sets "music staccato" so that each note will play 3/4 of the time determined by the length (L). Tempo Commands Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ P n Specifies a pause, ranging from 1-64. This option corresponds to the length of each note, set with L n. T n Sets the "tempo," or the number of L4 quarter notes in one minute. The range for n is 32-255. The default for n is 120. Operation Commands Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MF Sets music (PLAY statement) and SOUND to run in the foreground. That is, each subsequent note or sound will not start until the previous note or sound has finished. This is the default setting. MB Music (PLAY statement) and SOUND are set to run in the background. That is, each note or sound is placed in a buffer, allowing the BASIC program to continue executing while the note or sound plays in the background. The maximum number of notes that can be played in the background at one time is 32. Suffixes Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ # or + Follows a specified note and turns it into a sharp. - Follows a specified note and turns it into a flat. . A period after a note causes the note to play 3/2 times the length determined by L (length) times T (tempo). The period has the same meaning as in a musical score. Multiple periods can appear after a note. Each period adds a length equal to one half the length of the previous period. The command A. plays 1 + 1/2 or 3/2 times the length; A.. plays 1 + 1/2 + 1/4 or 7/4 times the length; and so on. Periods can appear after a pause (P). In this case, the pause length is scaled in the same way notes are scaled. Substring Command Action ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ "X" + VARPTR$(string) Executes a substring. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Because of the slow clock-interrupt rate, some notes will not play at higher tempos (L64 at T255, for example). ž Examples The following example uses ">" to play the scales from octave 0 to octave 6, then reverses with "<" to play the scales from octave 6 to octave 0: SCALE$ = "CDEFGAB" PLAY "o0 X" + VARPTR$(SCALE$) FOR I = 1 TO 6 PLAY ">X" + VARPTR$(SCALE$) NEXT PLAY "o6 X" + VARPTR$(SCALE$) FOR I = 1 TO 6 PLAY " 0 THEN 'If the point is in the ellipse, plot a corresponding 'point in the "tilted" ellipse. Xnew = (X*Cs - Y*Sn) + 200 : Ynew = (X*Sn + Y*Cs) PSET(Xnew,Ynew),2 END IF NEXT NEXT END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ POKE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Writes a byte into a memory location ž Syntax POKE address,byte ž Remarks The expression address is a value that represents the address of the memory location; address must be in the range 0-65,535. The expression byte is the data byte to be written; it is an integer value in the range 0-255. The address is treated as the offset from the current default segment (as set by the DEF SEG statement). If the argument is a single- or double-precision floating-point value or a long integer, it is converted to a two-byte integer. The complementary function to POKE is PEEK. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WARNING Use POKE carefully. If used incorrectly, it can cause BASIC or the operating system to fail. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also DEF SEG, PEEK, VARPTR ž Example See the example for the DEF SEG statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ POS Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current horizontal position of the cursor ž Syntax POS(0) ž Remarks The leftmost cursor position is numbered 1. To return the current vertical-line position of the cursor, use the CSRLIN function. ž See Also CSRLIN, LPOS ž Example The following example uses POS to start input on a new line after every 40 characters: PRINT "This program starts a new line after every forty" PRINT "characters are printed. Press to end." PRINT DO DO WHILE POS(0) < 41 'Stay on same line until 40 characters DO 'printed. Char$=INKEY$ LOOP WHILE Char$="" 'If input is key combination CTRL-C then end; otherwise, 'print the character. IF ASC(Char$) = 3 THEN END ELSE PRINT Char$; LOOP PRINT 'Print a new line. LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PRESET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Draws a specified point on the screen ž Syntax PRESET ®STEPÆ(xcoordinate,ycoordinate) ®,colorÆ ž Remarks PRESET works exactly like PSET, except that if the color is not specified, the background color is selected. The following list describes the parts of the PRESET statement: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STEP Indicates that the given x- and y-coordinates are relative, not absolute. The coordinates are treated as distances from the most recent cursor location, not distances from the (0,0) screen coordinate. For example, if the most recent point referenced were (10,10), PRESET STEP (10,5) would reference the point at (20,15). xcoordinate The x-coordinate of the pixel that is to be set. ycoordinate The y-coordinate of the pixel that is to be set. color The color attribute for the specified point. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If a coordinate is outside the current viewport, no action is taken, nor is an error message given. ž See Also PSET ž Example The following example draws a line 20 pixels long. The line then moves across the screen from left to right: SCREEN 1 : COLOR 1,1 : CLS FOR I = 0 TO 299 STEP 3 FOR J = I TO 20+I PSET (J,50),2 'Draw the line in new location. NEXT FOR J = I TO 20+I PRESET (J,50) 'Erase the line. NEXT NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PRINT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Outputs data on the screen ž Syntax PRINT ®expressionlistÆ ®{, | ;}Æ ž Remarks If expressionlist is omitted, a blank line is printed. If expressionlist is included, the values of the expressions are printed on the screen. The expressions in the list may be numeric or string expressions. (String literals must be enclosed in quotation marks.) A printed number is always followed by a space. If the number is positive, it is also preceded by a space; if the number is negative, it is preceded by a minus sign (-). There are two formats that PRINT uses to display single- and double-precision numbers: fixed point and floating point. If PRINT can represent a single-precision number in the fixed-point format with seven or fewer digits and no loss of accuracy, then it uses the fixed-point format; otherwise, it uses the floating-point format. For example, the number 1.1E-6 is output as .0000011, but the number 1.1E-7 is output as 1.1E-7. Similarly, if PRINT can represent a double-precision number in the fixed-point format with 16 or fewer digits and no loss of accuracy, then it uses the fixed-point format; otherwise, it uses the floating-point format. For example, the number 1.1D-15 is output as .0000000000000011, but the number 1.1D-16 is output as 1.1D-16. The PRINT statement supports only elementary BASIC data types (integers, long integers, single-precision real numbers, double-precision real numbers, and strings). To print information in a record, use the PRINT statement with individual record elements as in the following fragment: TYPE MyType Word AS STRING*20 Count AS LONG END TYPE DIM Myrec AS MyType PRINT Myrec.Word PRINT POSITIONS 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. Typing one or more spaces or tabs between expressions has the same effect as typing a semicolon. If a comma or a semicolon terminates the list of expressions, the next PRINT statement prints on the same line, after spacing accordingly. If the expression list ends without a comma or a semicolon, a carriage-return and line-feed sequence is printed at the end of the line. If the printed line is wider than the screen width, BASIC goes to the next physical line and continues printing. ž Examples In the following example, the commas in the PRINT statement print each value at the beginning of the next print zone: X=5 PRINT X+5, X-5, X*(-5), X^5 END ž Output 10 0 -25 3125 In the following example, the semicolon at the end of the first PRINT statement makes the first two PRINT statements print on the same line. The last PRINT statement prints a blank line before the next prompt. DO INPUT "Input X (input 0 to end): ", X IF X = 0 THEN EXIT DO ELSE PRINT X "squared is" X^2 "and"; PRINT X "cubed is" X^3 PRINT END IF LOOP ž Output Input X (input 0 to end): 9 9 squared is 81 and 9 cubed is 729 Input X (input 0 to end): 21 21 squared is 441 and 21 cubed is 9261 Input X (input 0 to end): 0 In the following example, the semicolons in the PRINT statement print each value immediately after the preceding value. (Remember, a space always follows a number and a space precedes a positive number.) FOR X=1 TO 5 J=J+5 K=K+10 PRINT J;K; NEXT X ž Output 5 10 10 20 15 30 20 40 25 50 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PRINT #, PRINT # USING Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Writes data to a sequential file ž Syntax PRINT #filenumber,®USING stringexpression;Æ expressionlist ®{, | ;}Æ ž Remarks The filenumber is the number specified when the file was opened for output. The stringexpression consists of formatting characters as described under PRINT USING. The expressions in expressionlist are the numeric or string expressions to be written to the file. Spaces, commas, and semicolons in the expressionlist have the same meaning they have in a PRINT statement. If you omit expressionlist, the PRINT # statement prints a blank line in the file. PRINT # works like PRINT and writes an image of the data to the file, just as the data would be displayed on the terminal screen. For this reason, be careful to delimit the data so it is output correctly. If you use commas as delimiters, the blanks between print fields are also written to the file. For more information, see Chapter 3, "File and Device I/O," in Programming in BASIC. ž See Also PRINT; PRINT USING; WRITE# ž Example The following example shows the effects of omitting and of including delimiters in data written out with PRINT #: A$ = "CAMERA, AUTOFOCUS" : B$= "September 20, 1985" : C$ = "42" Q$ = CHR$(34) OPEN "INVENT.DAT" FOR OUTPUT AS #1 'Open INVENT.DAT for writing 'Write A$, B$, C$ without delimiters. PRINT #1, A$ B$ C$ 'Write A$, B$, C$ with delimiters. PRINT #1, Q$ A$ Q$ Q$ B$ Q$ Q$ C$ Q$ CLOSE #1 OPEN "INVENT.DAT" FOR INPUT AS #1 'Open INVENT.DAT for reading. FOR I% = 1 TO 2 'Read first two records and INPUT #1, First$,Second$,Third$ 'print. PRINT First$ TAB(30) Second$ TAB(60) Third$ : PRINT NEXT CLOSE #1 ž Output CAMERA AUTOFOCUSSeptember 20 198542 CAMERA, AUTOFOCUS September 20, 1985 42 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PRINT USING Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Prints strings or numbers using a specified format ž Syntax PRINT USING formatstring; expressionlist ®{, | ;}Æ ž Remarks The formatstring is a string literal (or variable) containing literal characters to print (such as labels) and special formatting characters. These formatting characters determine the field and the format of the printed strings or numbers. Spaces, commas, and semicolons in the expressionlist have the same meaning they do in a PRINT statement. The expressionlist contains the string expressions or numeric expressions to be printed, separated by semicolons. When PRINT USING is used to print strings, you may use one of three formatting characters to format the string field, as described in the following list: Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ! Only the first character in the given string is to be printed. \ \ Prints 2 + n characters from the string, where n is the number of spaces between the two backslashes. If the backslashes are typed with no spaces, two characters are printed. With one space, three characters are printed, and so on. If the field is longer than the string, the string is left-justified in the field and padded with spaces on the right. & Indicates a variable-length string field. When the field is specified with the ampersand (&), the string is output without modification. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When PRINT USING is used to print numbers, the following special characters can be used to format the numeric field: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ # Represents each digit position. Digit positions are always filled. If the number to be printed has fewer digits than positions specified, the number is right-justified (preceded by spaces) in the field. . Prints a decimal point. A decimal point may be inserted at any position in the field. If the format string specifies that a digit is to precede the decimal point, the digit is always printed (as 0, if necessary). If necessary, Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  printed (as 0, if necessary). If necessary, numbers are rounded. + Causes the sign of the number (plus or minus) to be printed before the number (if it appears at the beginning of the format string) or after (if it appears at the end of the format string). - Causes a negative number to be printed with a trailing minus sign if it appears at the end of the format string. ** Causes leading spaces in the numeric field to be filled with asterisks. The double asterisk also specifies positions for two more digits. $$ Causes a dollar sign to be printed to the immediate left of the formatted number. The $$ specifies two more digit positions, one of which Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  specifies two more digit positions, one of which is the dollar sign. **$ Combines the effects of the double-asterisk and double-dollar-sign symbols. Leading spaces are asterisk-filled and a dollar sign is printed before the number. The **$ symbols specify three more digit positions, one of which is the dollar sign. When negative numbers are printed, the minus sign appears to the immediate left of the dollar sign. , If the comma appears to the left of the decimal point in a format string, it causes a comma to be printed to the left of every third digit left of the decimal point. If it appears at the end of the format string, it is printed as part of the string. A comma specifies another digit position. The comma has no effect if used with exponential Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The comma has no effect if used with exponential (^^^^ or ^^^^^) format. ^^^^ Specifies exponential format. You can also use five carets (^^^^^) to allow E+xxx to be printed for larger numbers. Any decimal point position may be specified. The significant digits are left-justified and the exponent is adjusted. Unless a leading +, trailing +, or - is specified, one digit position is used to the left of the decimal point to print a space or a minus sign. _ An underscore in the format string prints the next character as a literal character. A literal underscore is printed as the result of two underscores ( __ ) in the format string. % If the number to be printed is larger than the Character Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  % If the number to be printed is larger than the specified numeric field, a percent sign (%) is printed in front of the number. If rounding causes the number to exceed the field, a percent sign is printed in front of the rounded number. If the number of digits specified exceeds 24, an error message results that reads Illegal function call. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Examples The following example shows the results of using the three string-formatting characters: 'Using the three string-formatting characters to modify the 'appearance of printed output. A$ = "LOOK" : B$ = "OUT" PRINT USING "!";A$;B$ PRINT USING "\ \";A$;B$ 'Two spaces between back- 'slashes, will print four 'characters from A$. PRINT USING "\ \";A$;B$;"!!" 'Three spaces, will print PRINT USING "!";A$; 'A$ and a blank. PRINT USING "&";B$ ž Output LO LOOKOUT LOOK OUT !! LOUT The following example shows the effects of different combinations of numeric formatting characters: 'Format and print numeric data. PRINT USING "##.##";.78 PRINT USING "###.##";987.654 PRINT USING "##.## ";10.2,5.3,66.789,.234 PRINT USING "+##.## ";-68.95,2.4,55.6,-.9 PRINT USING "##.##- ";-68.95,22.449,-7.01 PRINT USING "**#.# ";12.39,-0.9,765.1 PRINT USING "$$###.##";456.78 PRINT USING "**$##.##";2.34 PRINT USING "####,.##";1234.5 PRINT USING "##.##^^^^";234.56 PRINT USING ".####^^^^-";-888888 PRINT USING "+.##^^^^";123 PRINT USING "+.##^^^^^";123 PRINT USING "_!##.##_!";12.34 PRINT USING "##.##";111.22 PRINT USING ".##";.999 ž Output 0.78 987.65 10.20 5.30 66.79 0.23 -68.95 +2.40 +55.60 -0.90 68.95- 22.45 7.01- *12.4 *-0.9 765.1 $456.78 ***$2.34 1,234.50 2.35E+02 .8889E+06- +.12E+03 +.12E+003 !12.34! %111.22 %1.00 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PSET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Draws a point on the screen ž Syntax PSET ®STEPÆ(xcoordinate,ycoordinate) ®,colorÆ ž Remarks The following list describes the parts of the PSET statement: Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STEP Indicates that the given xcoordinate and ycoordinate are relative, not absolute. The coordinates are treated as distances from the most recent cursor location, not distances from the (0,0) screen coordinate. For example, if the most recent point referenced were (10,10) then PSET STEP (10,5) would reference the point at (20,15). xcoordinate The x-coordinate of the pixel that is to be set. ycoordinate The y-coordinate of the pixel that is to be set. color The color attribute for the specified point. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ If a coordinate is outside the current viewport, no action is taken nor is an error message given. PSET allows the color to be left off the command line. If it is omitted, the default is the foreground color. ž See Also PRESET ž Example The following example draws a line from (0,0) to (100,100) and then erases that line by writing over it with the background color: SCREEN 2 'Draw a line from (0,0) to (100,100). FOR I=0 TO 100 PSET (I,I) NEXT I FOR I=0 TO 100 'Now erase that line. PSET STEP (-1,-1),0 NEXT I ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PUT StatementÄÄGraphics ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Places a graphic image obtained by a GET statement onto the screen ž Syntax PUT ®STEPÆ (x, y), arrayname®(indices)Æ ®,actionverbÆ ž Remarks The parts of the PUT statement are described as follows: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STEP Indicates that the given x- and y-coordinates are relative, not absolute. The coordinates are treated as distances from the most recent cursor location, not distances from the (0,0) screen coordinate. For example, if the most recent point referenced were (10,10) then the statement PUT STEP (10,5),Ball would put the object stored in Ball at (20,15). Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  would put the object stored in Ball at (20,15). (x,y) Coordinates specifying the top-left corner of the rectangle enclosing the image to be placed in the current output window. arrayname The name of the array that holds the image. See the entry for GET (Graphics) for the formula that computes the size of this array. The array can be a multidimensional array. indices Specifies that the image is retrieved starting from the designated array element, rather than at the first array element. actionverb The actionverb determines the interaction between the stored image and the one already on the screen. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Part Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The different values for actionverb are described in the following list. The default for actionverb is XOR. ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Verb Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PSET Transfers the data point-by-point onto the screen. Each point has the exact color attribute it had when it was taken from the screen with GET. PRESET The same as PSET except that a negative image (for example, black on white) is produced. AND Used when the image is to be transferred over an existing image on the screen. The resulting image Verb Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  existing image on the screen. The resulting image is the result of a logical AND of the stored image and the screen; points that had the same color in both the existing image and the stored image remain the same color, while those points that do not have the same color in both the existing image and the stored image do not. OR Used to superimpose the image onto an existing image; the stored image does not erase the previous screen contents. The resulting image is the product of a logical OR of the stored image and the screen image. XOR A special mode often used for animation. XOR causes the points on the screen to be inverted where a point exists in the array image. This behavior is exactly like that of the cursor: when an image is placed on the screen against a Verb Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  an image is placed on the screen against a complex background twice, the background is restored. This allows you to move an object around the screen without erasing the background. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ See Chapter 5, "Graphics," in Programming in BASIC for a detailed description of doing animation with the PUT statement. ž See Also GET (Graphics), PRESET, PRINT, PSET ž Example The following example creates a moving white ball that ricochets off the sides of the screen until you press a key to end the program: DEFINT A-Z DIM Ball(84) 'Dimension integer array large enough 'to hold ball. SCREEN 2 '640 pixels by 200 pixels screen resolution. INPUT "Press any key to end; press to start",Test$ CLS CIRCLE (16,16),14 'Draw and paint ball. PAINT (16,16),1 GET (0,0)-(32,32),Ball X = 0 : Y = 0 Xdelta = 2 : Ydelta = 1 DO 'Continue moving in same direction as long as ball is within 'the boundaries of the screen - (0,0) to (640,200). X = X + Xdelta : Y = Y + Ydelta IF INKEY$<>"" THEN END ' Test for key press. 'Change X direction if ball hits left or right edge. IF (X < 1 OR X > 600) THEN Xdelta = -Xdelta BEEP END IF 'Change Y direction if ball hits top or bottom edge. IF (Y < 1 OR Y > 160) THEN Ydelta = -Ydelta BEEP END IF 'Put new image on screen, simultaneously erasing old image. PUT (X,Y),Ball,PSET LOOP END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PUT StatementÄÄFile I/O ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Writes from a variable or a random-access buffer to a file ž Syntax PUT ®#Æfilenumber®,®recordnumberÆ®,variableÆÆ PUT ®#Æfilenumber®,{recordnumber|recordnumber, variable|,variable}Æ ž Remarks The following list describes the parts of the PUT statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ filenumber The number used in the OPEN statement to open the file. recordnumber For random-mode files, the number of the record to be written. For binary-mode files, the byte position in the file where writing is done. The Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  position in the file where writing is done. The first record in a file is record 1. If you omit recordnumber, the next record or byte (the one after the last GET or PUT statement, or the one pointed to by the last SEEK) is written to. The largest possible record number is 2^31-1 or 2,147,483,647. variable The variable containing the output to be written to the file. The PUT statement writes as many bytes to the file as there are bytes in the variable. If you use a variable, you do not need to use MKI$, MKL$, MKS$, or MKD$ to convert numeric fields before writing. You may not use a FIELD statement with the file if you use the variable argument. Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  For random-access files, you can use any variable as long as the length of the variable is less than or equal to the length of the record. Usually, a record variable defined to match the fields in a data record is used. For binary-mode files, you can use any variable. When you use a variable-length string variable, the statement writes as many bytes as there are characters in the string's value. For example, the following two statements write 15 bytes to file number 1: VarString$=STRING$ (15, "X") PUT #1,,VarString$ See the examples below and Chapter 3, "File and Device I/O," in Programming in BASIC, for more Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Device I/O," in Programming in BASIC, for more information about using variables rather than FIELD statements for random-access files. A record cannot contain more than 32,767 bytes. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can omit the recordnumber, the variable, or both. If you omit only the recordnumber, you must still include the commas: PUT #4,,FileBuffer If you omit both arguments, you do not include the commas: PUT #4 The GET and PUT statements allow fixed-length input and output for BASIC communications files. Be careful using GET and PUT for communications because PUT writes a fixed number of characters and may wait indefinitely if there is a communications failure. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE When using a file buffer defined by a FIELD statement, LSET, RSET, PRINT #, PRINT # USING, and WRITE # may be used to put characters in the random-file buffer before executing a PUT statement. In the case of WRITE # , BASIC pads the buffer with spaces up to the carriage return. Any attempt to read or write past the end of the buffer causes an error message that reads FIELD overflow. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CVI, CVS, CVL, CVD; GET (File I/O);LSET; MKD$, MKI$, MKL$, MKS$ ž Example The following example reads names and test scores from the console and stores the names and scores in a random-access file: ' Read a name and a test score from the console. ' Store each name and score as a record in a ' random-access file. ' Define record fields. TYPE TestRecord NameField AS STRING*20 ScoreField AS SINGLE END TYPE ' Open the test data file. DIM FileBuffer AS TestRecord OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN=LEN(FileBuffer) ' Read pairs of names and scores from the console. I=0 DO I=I+1 INPUT "Name ? ",FileBuffer.NameField INPUT "Score? ",FileBuffer.ScoreField INPUT "-->More (y/n)? ",Resp$ PUT #1,I,FileBuffer LOOP UNTIL UCASE$(MID$(Resp$,1,1))="N" PRINT I;" records written." CLOSE #1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RANDOMIZE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Initializes (reseeds) the random-number generator ž Syntax RANDOMIZE®expressionÆ ž Remarks If you omit expression, BASIC pauses and asks for a value by printing Random Number Seed (-32768 to 32767)? before executing the RANDOMIZE statement. When you use the argument expression, QuickBASIC uses this value to initialize the random-number generator. If the random-number generator is not reseeded, the RND function returns the same sequence of random numbers each time the program is run. To change the sequence of random numbers every time the program is run, place a RANDOMIZE statement at the beginning of the program and change the argument with each run. A convenient way to initialize the random-number generator is to use the TIMER function. Using TIMER ensures a new series of random numbers each time you use the program. See the example below. ž See Also RND, TIMER ž Example The following program simulates rolling two dice. The RANDOMIZE statement initializes the random-number generator so the program produces different numbers each time. ' Use the timer as the seed for the number generator. RANDOMIZE TIMER DO ' Simulate rolling two dice using RND. D1=INT(RND*6)+1 D2=INT(RND*6)+1 ' Report the roll. PRINT "You rolled a";D1;"and a";D2;"for a total of";D1+D2 INPUT "Roll again (Y/N)";Resp$ PRINT LOOP UNTIL UCASE$(MID$(Resp$,1,1))="N" END ž Output You rolled a 3 and a 5 for a total of 8 Roll again (Y/N)? y You rolled a 4 and a 1 for a total of 5 Roll again (Y/N)? y You rolled a 5 and a 6 for a total of 11 Roll again (Y/N)? n ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ READ Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads values from a DATA statement and assigns the values to variables ž Syntax READ variablelist ž Remarks A variablelist is a series of valid BASIC variables separated by commas. READ statements are always used with DATA statements. READ assigns DATA values to variables on a one-to-one basis. These variables may be numeric or string. Attempting to read a string value into a numeric variable produces a run-time syntax error. Reading a numeric value into a string variable does not produce an error, but stores the value as a string of numerals. Values read into integer variables are rounded before the value is assigned to the variable. Reading a numeric value too large for a variable produces a run-time error. String values read into fixed-length string variables are truncated if the string is too long. String values shorter than the string-variable length are left-justified and padded with blanks. Only individual elements of a record variable may appear in a READ statement. See example below. A single READ statement may use one or more DATA statements (they will be used in order); several READ statements may use the same DATA statement. If there are more variables in variablelist than there are values in the DATA statement or statements, an error message is printed that reads Out of DATA. If there are fewer variables than the number of elements in the DATA statement or statements, subsequent READ statements begin reading data at the first unread element. If there are no subsequent READ statements, the extra items are ignored. Use the RESTORE statement to reread DATA statements. ž See Also DATA, RESTORE ž Example The following fragment shows how a READ statement can be used to read information into the user-defined type named Employee: TYPE Employee FullName AS STRING*35 SocSec AS STRING*9 JobClass AS INTEGER END TYPE DIM ThisEmp AS Employee DATA "Julia Magruder","300-32-3403",3 DATA "Amelie Reeves Troubetzkoy","777-29-3206",7 . . . READ ThisEmp.FullName, ThisEmp.SocSec, ThisEmp.JobClass . . . See also the examples for DATA and RESTORE. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ REDIM Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Changes the space allocated to an array that has been declared ›DYNAMIC ž Syntax REDIM ®SHAREDÆ variable(subscripts)®AS typeÆ ®,variable(subscripts)®AS typ eÆÆ... ž Remarks The REDIM statement has the following arguments: Arguments Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SHARED The optional SHARED attribute allows a module to share variables with all the procedures in the module; this differs from the SHARED statement, which affects only the variables within a single module. SHARED can only be used in REDIM statements in the module-level code. variable A BASIC variable name. subscripts The dimensions of the array. Multiple dimensions can be declared. The subscript syntax is described below. AS type Declares variable as an elementary or user-defined type. The elementary types are INTEGER, LONG, SINGLE, DOUBLE, and STRING. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Subscripts in REDIM statements have the following form: ®lower TOÆ upper ®, ®lower TOÆ upperÆ... The TO keyword provides a way to indicate both the lower and the upper bounds of an array's subscripts. The arguments lower and upper are numeric expressions specifying the lowest and highest value for the subscript. See the DIM statement for more information about using the TO keyword. The REDIM statement changes the space allocated to an array that has been declared dynamic. See Chapter 2, "Data Types," for more information about both static and dynamic arrays. When a REDIM statement is compiled, all arrays declared in the statement are treated as dynamic. At run time, when a REDIM statement is executed, the array is deallocated (if it is already allocated) and then reallocated with the new dimensions. Old array-element values are lost because all numeric elements are reset to 0 and all string elements are reset to null strings. Although you may change the size of an array's dimensions with the REDIM statement, you may not change the number of dimensions. For example, the following statements are legal: ' ›DYNAMIC DIM A(50,50) ERASE A REDIM A(20,15) 'Array A still has two dimensions. However, the following statements are not legal and produce an error message that reads Wrong number of dimensions: ' ›DYNAMIC DIM A(50,50) ERASE A REDIM A(5,5,5) 'Changed number of dimensions from 'two to three. ž See Also DIM, ERASE, LBOUND, OPTION BASE, SHARED, UBOUND ž Example The following program fragment shows one way to use REDIM to allocate an array of records when the records are needed and later to free the memory that the records use: TYPE KeyElement Word AS STRING*20 Count AS INTEGER END TYPE ' Make arrays dynamic. ' ›DYNAMIC . . . ' Allocate an array of records when you need it. REDIM Keywords(500) AS KeyElement Keywords(99).Word="ERASE" Keywords(99).Count=2 PRINT Keywords(99).Word,Keywords(99).Count . . . ' Free the space taken by Keywords when you're finished. ERASE Keywords . . . END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ REM Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows explanatory remarks to be inserted in a program ž Syntax 1 REM remark ž Syntax 2 ' remark ž Remarks REM statements are not compiled, but they appear exactly as entered when the program is listed. You may branch from a GOTO or GOSUB statement to a REM statement. Execution continues with the first executable statement after the REM statement. A single quotation mark can be used instead of the REM keyword. If the REM keyword follows other statements on a line, it must be separated from the statements by a colon. REM statements are also used to introduce metacommands (see Appendix F, "Metacommands," in Programming in BASIC for more information). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Do not use the single quotation form of the REM statement in a DATA statement because it will be considered valid data. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Examples The following two lines are equivalent (notice that the colon is not required with the single quote): FOR I=1 TO 23 : Array(I)=1 : NEXT I : REM Initialize the array. FOR I=1 TO 23 : Array(I)=1 : NEXT I ' Initialize the array. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RESET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Closes all disk files ž Syntax RESET ž Remarks The RESET statement closes all open disk files and writes data still in the file buffers to disk. All files must be closed before a disk is removed from its drive. ž See Also CLOSE, END, SYSTEM ž Example There are no programming examples for the RESET statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RESTORE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Allows DATA statements to be reread from a specified line ž Syntax RESTORE ®{linenumber | linelabel }Æ ž Remarks After executing a RESTORE statement without a specified linenumber or linelabel, the next READ statement gets the first item in the first DATA statement in the program. If linenumber or linelabel is specified, the next READ statement gets the first item in the specified DATA statement. If a line is specified, the line number or line label must be in the module-level code. (Note that in the QuickBASIC environment, DATA statements are automatically moved to the module-level code.) ž See Also DATA, READ ž Example The RESTORE statement in the following fragment (from a program that generates random bridge hands) allows the program to reread the prompts in the DATA statement so the user can enter new boundary conditions for the different suits: DEFINT A-Z DIM X(13), Param(5,2) DATA Spades, Hearts, Diamonds, Clubs, Points CALL GetParameters(Param()) DO . . . INPUT "Repeat with same parameters"; Ch$ IF UCASE$(Ch$) <> "Y" THEN INPUT "Repeat with new parameters"; Ch$ IF UCASE$(Ch$) <> "Y" THEN EXIT DO ELSE RESTORE CALL GetParameters(Param()) END IF END IF LOOP END SUB GetParameters(Param(2)) STATIC CLS FOR I = 0 TO 4 READ SUIT$ PRINT SUIT$ " (low, high)"; INPUT Param(I,0), Param(I,1) NEXT END SUB ž Output Spades (low, high)? 5,10 Hearts (low, high)? 5,10 Diamonds (low, high)? 6,8 Clubs (low, high)? 6,8 Points (low, high)? 5,15 . . . Repeat with same parameters? n Repeat with new parameters? y Spades (low, high)? 4,8 Hearts (low, high)? 4,8 . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RESUME Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Continues program execution after an error-trapping routine has been invoked ž Syntax RESUME ®0Æ RESUME NEXT RESUME { linenumber | linelabel } ž Remarks The different forms of the RESUME statement redirect program flow as described in the following list: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Statement Where Execution Resumes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RESUME ®0Æ At the last statement executed in the module containing the error handler. If an active error handler is found in the module where the error occurs, execution resumes with the statement that caused the error. RESUME NEXT At the statement immediately following the last statement executed in the module containing the error handler. If an active error handler is found in the module where the error occurs, execution resumes with the statement immediately following the statement that caused the error. Statement Where Execution Resumes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  RESUME linenumber At linenumber. RESUME linelabel At linelabel. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A RESUME statement that is not in an error-handling routine produces the error message RESUME without error. Reaching the end of an error-handling routine without finding RESUME produces the error message No RESUME. The line specified in a RESUME { linenumber | linelabel } statement must be defined at module level. As a rule, avoid using a line number or line label with a RESUME statement. Omitting the line number allows your program to continue no matter where the error occurred. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Programs containing error-handling routines must be compiled with either the /E (On Error) or /X (Resume Next) options when you are compiling from the BC command line. No options are required when compiling in the QuickBASIC environment, or using the Make EXE command from the QuickBASIC Run menu. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž DIFFERENCES FROM BASICA In BASICA, if an error occurs in a DEF FN function, both RESUME and RESUME NEXT attempt to resume program execution at the line containing the function. ž See Also ERR, ERL; ERROR; ON ERROR ž Example This example has an error-handling routine starting at line 900. In BASICA, this routine would cause an error message (No negative arguments) to be printed for I= -1 and -2. The routine would then end. In BASIC, the error-handling routine prints its message when I= -1, then resumes at the beginning of the FOR...NEXT loop with I reset to 4, as seen below. 10 ON ERROR GOTO 900 20 DEF FNTEST(A) = 1 - SQR(A) 30 FOR I = 4 TO -2 STEP -1 40 PRINT I,FNTEST(I) 50 NEXT 60 END 900 'Error-handling routine 910 PRINT "No negative arguments" 920 RESUME NEXT ž Output 4 -1 3 -.7320509 2 -.4142136 1 0 0 1 -1 No negative arguments 4 -1 3 -.7320509 2 -.4142136 . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RETURN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns control from a subroutine ž Syntax RETURN ®{linenumber | linelabel }Æ ž Remarks Without a line label or number, RETURN continues execution where an event occurred (for event handling) or at the statement following the GOSUB (for subroutine calls). GOSUB and RETURN without a line number can be used anywhere in a program, but the GOSUB and corresponding RETURN must be at the same level. The linenumber or linelabel in the RETURN statement causes an unconditional return from a GOSUB subroutine to the specified line. RETURN with a line label or line number can only return control to a statement in the module-level code. A RETURN statement cannot be used to return control to a calling program from a subprogram defined by SUB. Use EXIT SUB. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE BASIC's SUB procedures provide a more well-structured alternative to GOSUB subroutines. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also EXIT, GOSUB, ON event ž Example See the example for the GOSUB statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RIGHT$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the rightmost n characters of a string ž Syntax RIGHT$(stringexpression,n) ž Remarks The argument stringexpression can be any string variable, string constant, or string expression. If n is equal to the number of characters in the argument stringexpression, then the RIGHT$ function returns stringexpression. If n = 0, RIGHT$ returns the null string (length zero). ž See Also LEFT$, MID$ ž Example This program converts names that have been input in the form "Firstname [Middlename] Lastname" to the form "Lastname, Firstname [Middlename]": LINE INPUT "Name: "; Nm$ I = 1 : Sppos = 0 DO WHILE I > 0 I = INSTR(Sppos+1,Nm$," ") 'Get position of next space. IF I > 0 THEN Sppos = I LOOP 'SPPOS now points to the position of the last space. IF Sppos = 0 THEN PRINT Nm$ 'There was just a last name. ELSE 'Everything after last space. Lastname$ = RIGHT$(Nm$,LEN(Nm$)-Sppos) 'Everything before last space. Firstname$ = LEFT$(Nm$,Sppos-1) PRINT Lastname$ ", " Firstname$ END IF END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RMDIR Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Removes an existing directory ž Syntax RMDIR pathname ž Remarks The pathname is the name of the directory that is to be deleted. The pathname must be a string of less than 128 characters. The directory to be removed must be empty except for the working directory ('.') and the parent directory ('..'); otherwise, one of two error messages is printed, either Path not found or Path/File access error. RMDIR works like the DOS command of the same name; the syntax in BASIC cannot be shortened to RD, as in DOS. ž See Also CHDIR, MKDIR ž Example The following example illustrates the use of the RMDIR statement: CHDIR "C:\SALES\TEMP" 'Move to \TEMP subdirectory in \SALES. KILL "*.*" 'Remove all files in \TEMP. CHDIR ".." 'Move back up to \SALES. RMDIR "TEMP" 'Remove \TEMP subdirectory. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RND Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a single-precision random number between 0 and 1 ž Syntax RND®(n)Æ ž Remarks The value of n determines how RND generates the next random number: Argument Number Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ n < 0 Always returns the same number for any given n n > 0 or n omitted Returns the next random number in the sequence n = 0 Returns the last number generated ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Even if n>0, the same sequence of random numbers is generated each time the program is run unless you initialize the random-number generator each time you run the program. (See the RANDOMIZE statement entry for more information about initializing the random-number generator.) To produce random integers in a given range, use the formula INT ((upperbound - lowerbound + 1)*RND + lowerbound) where upperbound is the highest number in the range, and lowerbound is the lowest number in the range. ž Example See the examples for the RANDOMIZE and TYPE statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RSET Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Moves data from memory to a random-access file buffer (in preparation for a PUT statement) or right-justifies the value of a string in a string variable ž Syntax RSET stringvariable=stringexpression ž Remarks The stringvariable is usually a random-access file field defined in a FIELD statement, although it can be any string variable. The stringexpression is the value assigned to the variable. If stringexpression requires fewer bytes than were defined for stringvariable in the FIELD statement, the RSET statement right-justifies the string in the field (LSET left-justifies the string). Spaces are used to pad the extra positions. If the string is too long for the field, both LSET and RSET truncate characters from the right. Numeric values must be converted to strings before they are justified with the RSET or LSET statements. The RSET statement can be used with string variables unrelated to FIELD statements. When used with a fixed-length string variable, the value is right-justified and left-padded with blanks. When RSET is used with a variable-length string, the string is treated as a fixed field. The length of the field is the length of the value the variable had before the RSET statement. See the example below. ž See Also FIELD; LSET; MKD$, MKI$, MKL$, MKS$; PUT ž Example The following example shows the effects of using RSET to assign values to fixed- and variable-length strings: DIM TmpStr2 AS STRING * 10 PRINT " 1 2 3" PRINT "123456789012345678901234567890" ' Use RSET on null variable-length string of length. ' Nothing prints because TmpStr$ is a zero-length field. TmpStr$ = "" RSET TmpStr$ = "Another" PRINT TmpStr$ ' Use RSET on variable-length string with a value. TmpStr$ = SPACE$(20) RSET TmpStr$ = "Another" PRINT TmpStr$ ' Use RSET on fixed-length string of length 10. RSET TmpStr2 = "Another" PRINT TmpStr2 ž Output 1 2 3 123456789012345678901234567890 Another Another ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RTRIM$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string with trailing (right-hand) spaces removed ž Syntax RTRIM$(stringexpression) ž Remarks The stringexpression can be any string expression. The RTRIM$ function works with both fixed- and variable-length string variables. ž See Also LTRIM$ ž Example The example shows the effects of the RTRIM$ function on fixed- and variable-length strings. See also the example for the LTRIM$ function. DIM FixStr AS STRING * 10 PRINT " 1 2" PRINT "12345678901234567890" FixStr = "Twine" PRINT FixStr + "*" PRINT RTRIM$(FixStr) + "*" VarStr$ = "Braided" + SPACE$(10) PRINT VarStr$ + "*" PRINT RTRIM$(VarStr$) + "*" ž Output 1 2 12345678901234567890 Twine * Twine* Braided * Braided* ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ RUN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Restarts the program currently in memory or executes a specified program ž Syntax RUN ®{ linenumber | filespec }Æ ž Remarks The RUN statement accepts the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ linenumber The numeric label of the line where execution begins. If no argument is given, execution begins at the first executable line of code. filespec A string expression naming the program file to load and run. The current program is cleared from memory before the specified program is loaded. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The line where execution begins must be in the module-level code. 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 program's main module. During compilation, if linenumber cannot be found in the module-level code, compilation halts and the error message Label not defined appears. Program lines can have line numbers or alphanumeric labels, such as OpenWindow:. If an alphanumeric label is the target of a RUN statement, execution halts, and the error message Type mismatch appears. Note that the QuickBASIC syntax checker does not warn you if you give the RUN statement an alphanumeric label instead of a line number. You do not need to specify the file name extension in filespec. The .BAS extension is assumed in the QuickBASIC environment, and the .EXE extension is assumed when running compiled, stand-alone programs. If the program you wish to run has a different extension, you must give the extension. If the program name has no extension, the file name given must end with a period. For example, RUN "CATCHALL" would execute CATCHALL.EXE from a BC-compiled program, and CATCHALL.BAS from within QuickBASIC. Programs running within the QuickBASIC environment must call only QuickBASIC program files. The file is loaded and run as if it were a QuickBASIC program; if it is not in the QuickBASIC program format, execution halts. The error message that appears varies, depending on the file's contents. Likewise, programs compiled with BC must not invoke QuickBASIC source files, as these run only within the QuickBASIC environment. An executable file need not have been written in QuickBASIC. Any executable file may be run. When running a program under QuickBASIC, if an executable file matching the file name in filespec cannot be found, the error message File not found appears, and control returns to QuickBASIC. When running a program compiled by BC, the error message File not found in module programname appears, and control returns to DOS. When the invoked program completes execution, control does not return to the invoking program. If the invoking program ran outside QuickBASIC, control returns to DOS. If the invoking program ran under QuickBASIC, control returns to QuickBASIC. If you edit a QuickBASIC program containing a RUN statement, then run the program before saving the changes, QuickBASIC asks if you wish to save the new version of the program before RUN clears it from memory. RUN closes all files and clears program memory before loading the designated program.The BC compiler does not support the R option from BASICA. (This option keeps all open data files open.) If you want to run a different program, but leave open files open, use the CHAIN statement. ž See Also CHAIN ž Examples The following example shows how RUN linenumber resets all numeric variables to 0. As the line number following RUN increases in lines 60, 70, 80, and 90, the variables in the earlier statements lose their assigned values. 10 A = 9 20 B = 7 30 C = 5 40 D = 4 50 PRINT A,B,C,D 60 IF A = 0 THEN 70 ELSE RUN 20 70 IF B = 0 THEN 80 ELSE RUN 30 80 IF C = 0 THEN 90 ELSE RUN 40 90 IF D = 0 THEN END ELSE RUN 50 ž Output 9 7 5 4 0 7 5 4 0 0 5 4 0 0 0 4 0 0 0 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SADD Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the address of the specified string expression ž Syntax SADD(stringvariable) ž Remarks The SADD function returns the address of a string as an offset (near pointer) from the current data segment. The offset is a two-byte integer. SADD is most often used in mixed-language programming. The argument may be a simple string variable or a single element of a string array. You may not use fixed-length string arguments. Use this function with care because strings can move in the BASIC string space (storage area) at any time. SADD works only with string variables stored in DGROUP. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Do not add characters to the beginning or end of a string passed using SADD and LEN. Adding characters may produce a run-time error. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also CALL, CALLS (Non-BASIC); DECLARE (Non-BASIC); FRE; PEEK; POKE; VARPTR; VARPTR$; VARSEG ž Example The following example uses SADD and LEN to pass a string to a function written in C. The C function returns the ASCII value of a character at a given position in the string. The C program would be separately compiled and stored in a Quick library or explicitly linked to form an .EXE file. Note that BYVAL is the default for C. ' Pass a string to a C function using SADD and LEN. DEFINT A-Z ' Declare the function; DECLARE FUNCTION MyAsc CDECL (BYVAL A%, BYVAL B%, BYVAL C%) A$="abcdefghijklmnopqrstuvwxyz" PRINT "Enter a character position (1-26). Enter 0 to Quit." DO ' Get a character position. INPUT N ' End if the position is less than zero. IF N<=0 THEN EXIT DO ' Call C function; the function returns the ASCII code of the ' character at position N in A$. AscValue=MyAsc(SADD(A$),LEN(A$),N) PRINT "ASCII value: ";AscValue;"Character: ";CHR$(AscValue) LOOP END /* C function to return the ASCII value of the character at position pos in string c of length len. */ int far myasc(c,len,pos) char near *c; int len, pos; { if(pos>len) return(c[--len]);/* Avoid indexing off end. */ else if (pos<1) return(c[0]);/* Avoid indexing off start. */ else return(c[--pos]);/* pos is good. Return the character at pos-1 because C arrays (strings) are zero-indexed. */ } ž Output Enter a character position (1-26). Enter -1 to Quit. ? 24 ASCII value: 120 Character: x ? -1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SCREEN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Reads a character's ASCII value or its color from a specified screen location ž Syntax SCREEN(row,column®,colorflagÆ) ž Remarks The following list describes the SCREEN function's arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ row The row number of the screen location. The row is a numeric expression that evaluates to an unsigned integer. column The column number of the screen location. The column is a numeric expression that evaluates to an unsigned integer. colorflag A numeric expression. When colorflag is nonzero, SCREEN returns the number of the color at the screen location. If the colorflag is zero or absent, the ASCII code of the character at the location is returned as an integer. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Examples If the character at (10,10) in the following examples is A, then the function would return 65, the ASCII code for A: X=SCREEN(10,10) The following example returns the color attribute of the character in the upper-left corner of the screen: X=SCREEN(1,1,1) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SCREEN Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sets the specifications for the display screen ž Syntax SCREEN ®modeÆ ®,®colorswitchÆ Æ®,®apageÆ Æ®,®vpageÆÆ ž Remarks The SCREEN statement selects a screen mode appropriate for a particular combination of display and adapter. Later sections describe the available modes for specific adapters. The following list describes the arguments of the SCREEN statement: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ mode An integer constant or expression indicating the screen mode. The valid modes are described below for each of the supported adapters. colorswitch Determines whether color is displayed on composite monitors. The colorswitch is a numeric expression in the range 0-255. When it is true (nonzero), color is disabled and only black-and-white images are displayed. When colorswitch is false (zero), images are in color. The colorswitch argument's meaning is inverted in screen mode 0. In screen modes 2 and up, colorswitch is ignored. apage A numeric expression that is the number of the screen page that text output or graphics commands write to. Tables below indicate valid values for apage with various adapters. Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  apage with various adapters. vpage A numeric expression that is the number of the screen page being displayed. Tables below indicate valid values for vpage with various adapters. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The next two subsections summarize the screen modes and discuss the modes available with specific combinations of adapters and displays. The final subsection summarizes attributes and colors. SUMMARY OF SCREEN MODES The following paragraphs briefly summarize each of the screen modes. The color adapters referred to are the IBM Color Graphics Adapter (CGA), the IBM Enhanced Graphics Adapter (EGA), the IBM Video Graphics Array (VGA) and the IBM Multicolor Graphics Array (MCGA). The Hercules(R) Graphics Card, Graphics Card Plus and InColor(R) adapters are supported, but only with monochrome monitors. The next subsection supplies detailed information about the effects of a screen mode when used with a specific combination of display and adapter. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Many screen modes support more than one combination of rows and columns on the screen. See the entry for the WIDTH statement for more information about changing the number of rows and columns on the display. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen 0 ž Text mode only ž Either 40 x 25, 40 x 43, 40 x 50, 80 x 25, 80 x 43, or 80 x 50 text format with character-box size of 8 x 8 (8 x 14, 9 x 14, or 9 x 16 with EGA or VGA) ž Assignment of 16 colors to 2 attributes ž Assignment of 16 colors to any of 16 attributes (with CGA or EGA) ž Assignment of 64 colors to any of 16 attributes (with EGA or VGA) Screen 1 ž 320 x 200 pixel medium-resolution graphics ž 40 x 25 text format with character-box size of 8 x 8 ž Assignment of 16 colors to 4 attributes with EGA or VGA ž Supports CGA, EGA, VGA, and MCGA Screen 2 ž 640 x 200 pixel high-resolution graphics ž 80 x 25 text format with character-box size of 8 x 8 ž Assignment of 16 colors to 2 attributes with EGA or VGA ž Supports CGA, EGA, VGA, and MCGA Screen 3 ž Hercules adapter required ž Monochrome monitor only ž 720 x 348 pixel resolution, monochrome ž 80 x 25 text format with character-box size of 9 x 14; bottom two scan lines of 25th row not visible ž Two screen pages (one only if a second display adapter is installed) ž PALETTE statement not supported ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The Hercules driver (MSHERC.COM) must be loaded for the Hercules card to function. This file is supplied with QuickBASIC. Type MSHERC before running QuickBASIC. If a compatible color adapter is also installed (eg, CGA), type MSHERC /H instead. This limits the Hercules card to one screen page but permits normal operation of the color adapter. If the Hercules driver is not loaded, the Hercules card operates like an IBM Monochrome Display Adapter (MDA). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen 4 ž 640 x 400 pixel high-resolution graphics ž 80 x 25 text format with character-box size of 8 x 16 ž Assignment of 1 of 16 colors as the foreground color (selected by the COLOR statement); background fixed at black ž Supports Olivetti(R) Personal Computers, models M24, M240, M28, M280, M380, M380/C, and M380/T, and AT&T(R) Personal Computers 6300 series ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WARNING Olivetti personal computers running in DOS-compatibility mode under Microsoft Operating System/2 should avoid this screen mode. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Screen 7 ž 320 x 200 pixel medium-resolution graphics ž 40 x 25 text format with character-box size of 8 x 8 ž Multiple screen pages ž Assignment of 16 colors to any of 16 attributes ž EGA or VGA required Screen 8 ž 640 x 200 pixel high-resolution graphics ž 80 x 25 text format with character-box size of 8 x 8 ž Multiple screen pages ž Assignment of 16 colors to any of 16 attributes ž EGA or VGA required Screen 9 ž 640 x 350 pixel enhanced-resolution graphics ž 80 x 25 or 80 x 43 text format with character-box size of 8 x 14 or 8 x 8 ž Assignment of either 64 colors to 16 attributes (more than 64K of EGA or VGA memory) or 16 colors to 4 attributes (64K of EGA or VGA memory) ž Multiple screen pages ž EGA or VGA required Screen 10 ž Monochrome only ž 640 x 350 pixel enhanced-resolution graphics ž 80 x 25 or 80 x 43 text format with character-box size of 8 x 14 or 8 x 8 ž Multiple screen pages ž Assignment of up to nine pseudocolors to 4 attributes (refer to Tables R.9 and R.10 in the next section) ž EGA or VGA required Screen 11 ž 640 x 480 pixel very high-resolution graphics ž 80 x 30 or 80 x 60 text format with character-box size of 8 x 16 or 8 x 8 ž Assignment of up to 256K colors to 2 attributes ž VGA or MCGA required Screen 12 ž 640 x 480 pixel very-high-resolution graphics ž 80 x 30 or 80 x 60 text format with character-box size of 8 x 16 or 8 x 8 ž Assignment of up to 256K colors to 16 attributes ž VGA required Screen 13 ž 320 x 200 pixel medium-resolution graphics ž 40 x 25 text format with character-box size of 8 x 8 ž Assignment of up to 256K colors to up to 256 attributes ž VGA or MCGA required SCREEN MODES, ADAPTERS, AND DISPLAYS This section describes the screen modes for specific combinations of adapters and displays. The IBM Monochrome Display and Printer Adapter (MDPA) can be used only with a monochrome display. Only screen mode 0, text mode, can be used with the MDPA. Table R.6 summarizes the effect of using screen mode 0 with an MDPA. Table R.6 MDPA Screen Modes Screen Rows and Mode Columns Attributes Colors Resolution Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 80x25 16 3 720x350 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table R.7 summarizes the screen modes available with Hercules adapters. Table R.7 Hercules Screen Modes Screen Rows and Mode Columns Attributes Colors Resolution Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 80x25 16 1 720x348 2 3 80x25 16 1 720x348 2 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The IBM Color Graphics Adapter (CGA) and Color Display are typically paired. This combination permits running text-mode programs and both medium-resolution and high-resolution graphics programs. Table R.8 summarizes the screen modes available with the CGA. Table R.8 CGA Screen Modes Screen Rows and Mode Columns Colors Resolution Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 40x25 16 320x200 8 80x25 16 640x200 4 1 40x25 4 320x200 1 2 80x25 2 640x200 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The IBM Enhanced Graphics Adapter (EGA) may be used with either the IBM Color Display or the Enhanced Color Display. In screen modes 0, 1, 2, 7, and 8, these pairings produce similar results, except for the following possible differences: 1. The border color cannot be set on an Enhanced Color Display when it is in 640 x 350 text mode. 2. The text quality is better on the Enhanced Color Display (an 8 x 14 character box for Enhanced Color Display versus an 8 x 8 character box for Color Display). Screen mode 9 takes full advantage of the capabilities of the Enhanced Color Display and provides for the highest resolution possible for the EGA/Enhanced Color Display configuration. Programs written for this mode will not work for any other hardware configuration except the VGA. Table R.9 summarizes the screen modes that can be used with an EGA. Table R.9 EGA Screen Modes ÖŚÄŚÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄ· Screen Rows and Page Mode Columns Display Attributes Colors Resolution Size Pages  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 40x25 C 16 16 320x200 N/A 8 40x25 E 16 64 320x350 N/A 8 40x43 E 16 64 320x350 N/A 8 80x25 C 16 16 640x200 N/A 8 80x25 E 16 64 640x350 N/A 8 80x25 C 16 16 640x200 N/A 8 80x25 M 16 3 720x350 N/A 8 80x43 E 16 64 640x350 N/A 4 80x43 M 16 3 720x350 N/A 4 Screen Rows and Page Mode Columns Display Attributes Colors Resolution Size Pages  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  80x43 M 16 3 720x350 N/A 4 1 40x25 N/A 4 16 320x200 16K 1 2 80x25 N/A 2 16 640x200 16K 1 7 40x25 N/A 16 16 320x200 32K  8 80x25 N/A 16 16 640x200 64K  9 80x25 E 4 64 640x350 64K 1 80x43 E 4 64 640x350 64K 1 80x25 E 16 64 640x350 128K  80x43 E 16 64 640x350 128K  10 80x25 M 4 9 640x350 64K  80x43 M 4 9 640x350 64K  ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Only the EGA and VGA can be paired with the IBM Monochrome Display to run programs in screen mode 10. This mode can be used to display monochrome graphics at a very high resolution. The following two tables summarize the default attributes and colors for screen mode 10 used with a monochrome display. Table R.10 Default Attributes: Screen Mode 10, Monochrome Display Attribute Displayed Value Pseudocolor ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Off 1 On, normal intensity 2 Blink 3 On, high intensity ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table R.11 Color Values: Screen Mode 10, Monochrome Display Color Displayed Value Pseudocolor ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Off 1 Blink, off to on 2 Blink, off to high intensity 3 Blink, on to off 4 On 5 Blink, on to high intensity 6 Blink, high intensity to off 7 Blink, high intensity to on 8 High intensity ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The IBM Video Graphics Array (VGA) adapter offers significantly enhanced text and graphics in all screen modes. Table R.12 summarizes the modes available with the VGA. Table R.12 VGA Screen Modes ÖŚÄŚÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄ· Rows and Page Mode Columns Attributes Colors Resolution Size Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 40x25 16 64 360x400 N/A 8 Rows and Page Mode Columns Attributes Colors Resolution Size Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 40x25 16 64 360x400 N/A 8 40x43 16 64 320x350 N/A 8 40x50 16 64 320x400 N/A 4 80x25 16 64 720x400 N/A 8 80x43 16 64 640x350 N/A 4 80x43 16 3 720x350 N/A 4 80x50 16 64 640x400 N/A 4 80x50 16 3 720x400 N/A 4 1 40x25 4 16 320x200 16K 1 2 80x25 2 16 640x200 16K 1 7 40x25 16 16 320x200 32K  8 80x25 16 16 640x200 64K  9 80x25 16 64 640x350 128K  80x43 16 64 640x350 128K  10 80x25 4 9 640x350 64K  80x43 4 9 640x350 64K  11 80x30 2 256K 640x480 64K 1 80x60 2 256K 640x480 64K 1 Rows and Page Mode Columns Attributes Colors Resolution Size Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  80x60 2 256K 640x480 64K 1 12 80x30 16 256K 640x480 256K 1 80x60 16 256K 640x480 256K 1 13 40x25 256 256K 320x200 64K 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ See the PALETTE statement for a description of how the VGA calculates color values. The IBM Multicolor Graphics Array (MCGA) combines the modes of the CGA with the very high resolution and 256K color modes of the VGA to provide enhanced text and graphics in all modes. Table R.13 summarizes the modes supported by the MCGA. Table R.13 MCGA Screen Modes Rows and Page Mode Columns Attributes Colors Resolution Size Pages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 40x25 16 N/A 320x400 N/A 8 80x25 16 N/A 640x400 N/A 8 1 40x25 4 N/A 320x200 16K 1 2 80x25 2 N/A 640x200 16K 1 11 80x30 2 256K 640x480 64K 1 80x60 2 256K 640x480 64K 1 13 40x25 256 256K 320x200 64K 1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The MCGA uses the same color values as the VGA. See the PALETTE statement for a description of how the MCGA calculates color values. ATTRIBUTES AND COLORS For various screen modes and display hardware configurations, different attribute and color settings exist. (See the PALETTE statement for a discussion of attribute and color number.) The majority of these attribute and color configurations are summarized in Tables R.14-R.16. Table R.14 Default Attributes and Colors for Screen Modes 1 and 9 Attributes Color Display Monochrome Display Number Color Number Color ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 0 Black 0 Off 1 11 Light cyan 2 High intensity 2 13 Light magenta 2 High intensity 3 15 High-intensity 0 Off white ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table R.15 Default Attributes and Colors for Screen Modes 2 and 11 Attributes Color Display Monochrome Display Number Color NumberColor ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 0 Black 0 Off 1 15 High-intensity 0 Off white ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Table R.16 Default Attributes and Colors for Screen Modes 0, 7, 8, 9, 12, and 13 ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Attributes Color Display Monochrome Display Number Color Number Color ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 0 Black 0 Off 1 1 Blue Underlined 2 2 Green 1 On 3 3 Cyan 1 On 4 4 Red 1 On 5 5 Magenta 1 On 6 6 Brown 1 On 7 7 White 1 On 8 8 Gray 0 Off 9 9 Light blue High intensity Underlined 10 10 Light green 2 High intensity 11 11 Light cyan 2 High intensity Attributes Color Display Monochrome Display Number Color Number Color ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  11 11 Light cyan 2 High intensity 12 12 Light red 2 High intensity 13 13 Light magenta 2 High intensity 14 14 Yellow 2 High intensity 15 15 High-intensity 0 Off white ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Example See the LINE, CIRCLE, and DRAW statements for examples of the SCREEN statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SEEK Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current file position ž Syntax SEEK(filenumber) ž Remarks The filenumber is the number used in the OPEN statement to open the file. SEEK returns a value in the range 1 to 2,147,483,647 (equivalent to 2^31-1). SEEK returns the number of the next record read or written when used on RANDOM mode files. For files opened in BINARY, OUTPUT, APPEND, or INPUT mode, SEEK returns the byte position in the file where the next operation is to take place. The first byte in a file is 1. When used on a device that does not support SEEK, the function returns zero. The BASIC devices (SCRN:, CONS:, KYBD:, COMn:, and LPTn:) do not support SEEK. See Chapter 3, "File and Device I/O," in Programming in BASIC for more information. ž See Also GET (File I/O), OPEN, PUT (File I/O), SEEK Statement ž Example The following code fragment prints a message indicating whether the last read or write was done in the first, second, or final third of the file: SELECT CASE (SEEK(1)) CASE IS < .333*LOF(1) PRINT "In first third of file." CASE .333*LOF(1) TO .667*LOF(1) PRINT "In second third of file." CASE IS >= .667*LOF(1) PRINT "In last third of file." CASE ELSE END SELECT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SEEK Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sets the position in a file for the next read or write ž Syntax SEEK ®#Æfilenumber,position ž Remarks The filenumber is an integer number used in the OPEN statement to open the file. The position is a numeric expression indicating where the next read or write is done. The position must be in the range 1 to 2,147,483,647 (equivalent to 2^31-1). For files opened in RANDOM mode, position is the number of a record in the file. For files opened in BINARY, INPUT, OUTPUT, or APPEND modes, position is the number of a byte from the beginning of the file. The first byte in a file is 1. After a SEEK, the next file I/O operation starts at that byte in the file. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Record numbers on a GET or PUT override the file positioning done by SEEK. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Performing a file write after doing a SEEK beyond the end of a file extends the file. A SEEK to a negative or zero position produces an error message that reads Bad record number. When used on a device that does not support SEEK, BASIC ignores SEEK and leaves the file position unchanged. The BASIC devices (SCRN:, CONS:, KYBD:, COMn:, and LPTn:) do not support SEEK. See Chapter 3, "File and Device I/O," in Programming in BASIC for more information. ž See Also GET (File I/O), OPEN, PUT (File I/O), SEEK Function ž Example The following code fragment uses a combination of the SEEK function and SEEK statement to back up the file position and rewrite a record if a variable is true (nonzero): CONST FALSE=0, TRUE=NOT FALSE . . . IF ReWriteFlag = TRUE THEN ' Back up file by the length of the record variable that ' is used to write to the file. SEEK #1, SEEK(1)-LEN(RecordVar) PUT #1,,RecordVar END IF ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SELECT CASE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Executes one of several statement blocks depending on the value of an expression ž Syntax SELECT CASE testexpression CASE expressionlist1 ®statementblock-1Æ ®CASE expressionlist2 ®statementblock-2ÆÆ . . . ®CASE ELSE ®statementblock-nÆÆ END SELECT ž Remarks The following list describes the parts of the SELECT CASE statement: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ testexpression Any numeric or string expression. statementblock-1, The elements statementblock-1 to statementblock-n statementblock-2, consist of any number of statements on one or statementblock-n more lines. expressionlist1, These elements can have any of the three expressionlist2 following forms: expression®,expression...Æ expression TO expression IS relational-operator expression ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The following list describes the parts of an expressionlist: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ expression Any numeric or string expression. The type of the expression must match the type of the expression being tested. Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  relational-operator Any of the following operators: Symbol Meaning < Less than <= Less than or equal to > Greater than >= Greater than or equal to <> Not equal = Equal ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  If the testexpression matches the expressionlist associated with a CASE clause, then the statement block following that CASE clause is executed up to the next CASE clause or, for the last one, up to END SELECT. Control then passes to the statement following END SELECT. If you use the TO keyword to indicate a range of values, the smaller value must appear first. For example, the statements associated with the line CASE -1 TO -5 are not executed if the testexpression is -4. The line should be written as CASE -5 TO -1. You may use a relational operator only if the IS keyword appears. If CASE ELSE is used, its associated statements are executed only if the testexpression does not match any of the other CASE selections. It is a good idea to have a CASE ELSE statement in your SELECT CASE block to handle unforeseen testexpression values. When there is no CASE ELSE statement and no expression listed in the CASE clauses matches testexpression, program execution continues normally. No error occurs. You may use multiple expressions or ranges in each CASE clause. For example, the following line is valid: CASE 1 TO 4, 7 TO 9, 11, 13, IS > MaxNumber% You may also specify ranges and multiple expressions for strings: CASE "everything", "nuts" TO "soup", TestItem$ CASE matches strings that are exactly equal to everything, the current value of TestItem$, or that fall between nuts and soup in alphabetical order. Strings are evaluated according to the ASCII values of their characters. Lowercase letters have larger ASCII values than uppercase letters, so nuts > Nuts > NUTS If an expression appears in more than one CASE clause, only the statements associated with the first appearance of the expression are executed. SELECT CASE statements may be nested. Each SELECT CASE statement must have a matching END SELECT statement. ž Example In the following program, the SELECT CASE statement is used to take different actions based on the input value: ' Program demonstrates various forms of CASE items INPUT "Enter acceptable level of risk (1-10): ", Total SELECT CASE Total CASE IS >= 10 PRINT "Maximum risk and potential return" PRINT "Choose stock investment plan" CASE 6 TO 9 PRINT "High risk and potential return" PRINT "Choose corporate bonds" CASE 2 TO 5 PRINT "Moderate risk and return" PRINT "Choose mutual fund" CASE 1 PRINT "No risk, low return" PRINT "Choose IRA" CASE ELSE PRINT "RESPONSE OUT OF RANGE" END SELECT ž Output Enter acceptable level of risk (1-10): 10 Maximum risk and potential return Choose stock investment plan Enter acceptable level of risk (1-10): 0 RESPONSE OUT OF RANGE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SETMEM Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Changes the amount of memory used by the far heapÄÄthe area where far objects and internal tables are stored ž Syntax SETMEM(numeric-expression) ž Remarks The SETMEM function increases or decreases the far heap by the number of bytes indicated by numeric-expression. If the numeric-expression is negative, SETMEM decreases the far heap by the indicated number of bytes. When the numeric-expression is positive, SETMEM attempts to increase the far heap space by the number of bytes. SETMEM returns the total number of bytes in the far heap. If the numeric-expression is zero, SETMEM returns the current size of the far heap. If SETMEM cannot change the far heap by the requested number of bytes, it reallocates as many bytes as possible. SETMEM can be used in mixed-language programming to decrease the far heap space so procedures in other languages can dynamically allocate far memory. A first call to SETMEM trying to increase the far heap has no effect because BASIC allocates as much memory as possible to the far heap when a program starts. ž Example The following program outlines how SETMEM could be used to free memory for a C function that uses malloc to get dynamic memory. The C function is separately compiled and then put in a Quick library or linked to the BASIC program. The C function is compiled using the large memory model, so calls to malloc use the far space freed by the BASIC program. DEFINT A-Z DECLARE SUB CFunc CDECL (BYVAL X AS INTEGER) ' Decrease the size of the far heap so CFunc can use ' malloc to get dynamic memory. BeforeCall=SETMEM(-2048) ' Call the C function. CFunc(1024%) ' Return the memory to the far heap; use a larger value so ' all space goes back into the heap. AfterCall=SETMEM(3500) IF AfterCall <= BeforeCall THEN PRINT "Memory not reallocated." END void far cfunc(bytes) int bytes; { char *malloc(); char *workspace; /* Allocate working memory using amount BASIC freed. */ workspace=malloc((unsigned) bytes); /* Working space would be used here. */ /* Free memory before returning to BASIC. */ free(workspace); } ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SGN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Indicates the sign of a numeric expression ž Syntax SGN(numeric-expression) ž Remarks The SGN function returns a value depending on the sign of its argument: If numeric-expression > 0, then SGN(numeric-expression) returns 1. If numeric-expression = 0, then SGN(numeric-expression) returns 0. If numeric-expression < 0, then SGN(numeric-expression) returns -1. ž Example The following program calculates and prints the solution for a quadratic (or for a second-degree) equation. The program uses the sign of a test expression to determine how to calculate the solution. CONST NoRealSoln=-1, OneSoln=0, TwoSolns=1 ' Input coefficients of quadratic equation: ' ax^2 + bx + c = 0. INPUT;"a = ", A INPUT;", b = ",B INPUT ", c = ",C Test = B^2 - 4*A*C SELECT CASE SGN(Test) CASE NoRealSoln PRINT "This equation has no real-number solutions." CASE OneSoln PRINT "This equation has one solution: "; PRINT -B/(2*A) CASE TwoSolns PRINT "This equation has two solutions: "; PRINT (-B + SQR(Test))/(2*A) " and "; PRINT (-B - SQR(Test))/(2*A) END SELECT ž Output a = 12, b = -5, c = -2 This equation has two solutions: .6666667 -.25 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SHARED Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Gives a SUB or FUNCTION procedure access to variables declared at the module level without passing them as parameters ž Syntax SHARED variable ®AS typeÆ ®, variable ®AS typeÆÆ... ž Remarks The argument variable is either an array name followed by () or a variable name. The AS clause can be used to indicate the variable's type. The type argument can be INTEGER, LONG, SINGLE, DOUBLE, STRING, fixed-length string (STRING*length), or a user-defined type. By using either the SHARED statement in a SUB or FUNCTION procedure, or the SHARED attribute with COMMON or DIM in the module-level code, you can use variables in a procedure without passing them as parameters. The SHARED attribute shares variables among all procedures in a module, while the SHARED statement shares variables between a single procedure and the module-level code. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The SHARED statement only shares variables within a single compiled module. It does not share variables with programs in the Quick library or with procedures compiled separately and linked to the program. The SHARED statement only shares variables between the module-level code and a SUB or FUNCTION in the same module. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The SHARED statement can appear only in a SUB or FUNCTION. For more information see Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC and Chapter 4, "Programs and Modules," in this manual. ž See Also COMMON, DIM, SUB ž Example The following program calls a subprogram named CONVERT that converts the input decimal number to its string representation in the given new base. The string N$ is shared by the subprogram and the main program. DEFINT A-Z DO INPUT "Decimal number (input number <= 0 to quit): ",Decimal IF Decimal <= 0 THEN EXIT DO INPUT "New base: ",Newbase N$ = "" PRINT Decimal "base 10 equals "; DO WHILE Decimal > 0 CALL Convert (Decimal,Newbase) Decimal = Decimal\Newbase LOOP PRINT N$ " base" Newbase PRINT LOOP SUB Convert (D,Nb) STATIC SHARED N$ ' Take the remainder to find the value of the current ' digit. R = D MOD Nb ' If the digit is less than ten, return a digit (0...9). ' Otherwise, return a letter (A...Z). IF R < 10 THEN Digit$ = CHR$(R+48) ELSE Digit$ = CHR$(R+55) N$ = RIGHT$(Digit$,1) + N$ END SUB ž Output Decimal number (input number <= 0 to quit): 256 New base: 2 256 base 10 equals 100000000 base 2 Decimal number (input number <= 0 to quit): 31 New base: 16 31 base 10 equals 1F base 16 Decimal number (input number <= 0 to quit): -1 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SHELL Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Exits the BASIC program, runs a .COM, .EXE, or .BAT program or a DOS command, and returns to the program at the line following the SHELL statement ž Syntax SHELL ®commandstringÆ ž Remarks The commandstring must be a valid string expression containing the name of a program to run and any program options. Any .COM file, .EXE file, .BAT program, or DOS function that runs under the SHELL statement is called a "child process." Child processes are executed by the SHELL statement, loading and running a copy of COMMAND.COM with the /C option automatically; this option allows any parameters in commandstring to be passed to the child process. It also allows redirection of standard input and output, and execution of built-in commands such as DIR, PATH, and SORT. The program name in commandstring may have any extension you wish. If no extension is supplied, COMMAND.COM looks for a .COM file, then an .EXE file, and finally, a .BAT file. If COMMAND.COM is not found, SHELL issues an error message that reads File not found. BASIC does not generate an error if COMMAND.COM cannot find the file specified in commandstring. Any text separated from the program name by at least one blank is treated as program parameters by COMMAND.COM. BASIC remains in memory while the child process is running. When the child process finishes, BASIC continues. SHELL with no commandstring gives you a new COMMAND.COM shell. You may now do anything that COMMAND.COM allows. Enter the DOS command EXIT when you are ready to return to BASIC. ž Examples This example shows how a SHELL statement starts up a new COMMAND.COM: SHELL 'Get a new COMMAND.COM. ž Output The IBM Personal Computer DOS Version 3.20 (C)Copyright International Business Machines Corp 1981, 1986 (C)Copyright Microsoft Corp 1981, 1986 D:\QB4> The following example copies all files modified on a certain date from a specified directory: ' This program copies all files in this directory modified ' on a certain date to the drive and directory you specify. DECLARE FUNCTION GetName$ (DirLine$) LINE INPUT "Enter target drive and directory: ",PathSpec$ SHELL "DIR > DIRFILE" 'Store directory listing in DIRFILE. DO OPEN "DIRFILE" FOR INPUT AS #1 INPUT "Enter date (MM-DD-YY): ",MDate$ PRINT ' Read DIRFILE, test for input date. DO LINE INPUT #1, DirLine$ ' Test directory line to see if date matches and the line ' is not one of the special directories ( . or .. ). IF INSTR(DirLine$,MDate$) > 0 AND LEFT$(DirLine$,1) <> "." THEN FileSpec$ = GetName$(DirLine$) ' Make sure we don't move our temporary file. IF FileSpec$ <> "DIRFILE" THEN ' Build the DOS command line to copy the file. DoLine$ = "COPY " + FileSpec$ + " " + PathSpec$ PRINT DoLine$ ' Copy the file. SHELL DoLine$ END IF END IF LOOP UNTIL EOF(1) CLOSE #1 PRINT "New date?" R$ = INPUT$(1) CLS LOOP UNTIL UCASE$(R$) <> "Y" ' KILL "DIRFILE". END ' This function gets the file name and extension from ' the directory-listing line. FUNCTION GetName$ (DirLine$) STATIC BaseName$ = RTRIM$(LEFT$(DirLine$,8)) ' Check for extension. ExtName$ = RTRIM$(MID$(DirLine$,10,3)) IF ExtName$ <> "" THEN BaseName$ = BaseName$ + "." + ExtName$ END IF GetName$ = BaseName$ END FUNCTION ž Output Enter target drive and directory: c:\bas\temp Enter date (MM-DD-YY): 6-11-87 COPY CONF.DAT c:\bas\temp COPY TEST.BAS c:\bas\temp COPY TEMPFILE c:\bas\temp New date? n ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SIN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the sine of the angle x, where x is in radians ž Syntax SIN(x) ž Remarks When x is a double-precision value, the SIN function is calculated with double-precision accuracy. When x is not double precision, SIN is calculated with single-precision accuracy. ž See Also ATN, COS, TAN ž Example The example plots the graph of the polar equation r = 1 + sin n (é). This figure is sometimes known as a cardioid, owing to its resemblance to a heart when n equals 1. CONST PI = 3.141593 SCREEN 1 : COLOR 1,1 'Medium resolution, blue background. WINDOW (-3,-2)-(3,2) 'Convert screen to Cartesian 'coordinates. INPUT "Number of petals = ", N CLS PSET (1,0) 'Set initial point. FOR Angle = 0 TO 2*PI STEP .02 R = 1 + SIN(N*Angle) 'Polar equation for "flower." X = R * COS(Angle) 'Convert polar coordinates to Y = R * SIN(Angle) 'Cartesian coordinates. LINE -(X,Y) 'Draw line from previous point to 'new point. NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SLEEP Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Suspends execution of the calling program ž Syntax SLEEP ® seconds Æ ž Remarks The optional argument seconds determines the number of seconds the program is suspended. The SLEEP statement suspends the program until one of the following events occurs: ž The time period in the seconds argument elapses. ž A key is pressed. ž An enabled event occurs. If seconds is zero or not specified, the program is suspended indefinitely. Only an enabled event or a keystroke can interrupt an indefinite suspension. SLEEP responds only to keystrokes that occur after it executes. SLEEP ignores characters in the keyboard buffer that were typed before it executed. An event (such as ON COM or ON TIMER) cannot interrupt a SLEEP suspension unless its trapping is active when the event occurs. This means that trapping must have been initialized with an ON event statement, turned on with an event ON statement, and not have been disabled with an event OFF statement or an event STOP statement. ž See Also WAIT ž Example The following program suspends execution for 10 seconds. There is no ON event statement, so the only way to interrupt the suspension before 10 seconds have passed is to press a key. PRINT "Taking a 10 second nap..." SLEEP 10 PRINT "Awake!" END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SOUND Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Generates sound through the speaker ž Syntax SOUND frequency,duration ž Remarks The frequency is the desired frequency in hertz (cycles/second). It must be a numeric expression returning an integer in the range 37-32,767. The duration is the duration in clock ticks. (There are 18.2 clock ticks per second regardless of CPU speed.) The duration must be a numeric expression returning an unsigned integer in the range 0-65,535. If the duration is zero, any current SOUND statement that is running is turned off. If no SOUND statement is running, a SOUND statement with a duration of zero has no effect. ž SEE ALSO PLAY ž Example This program fragment produces a rising and descending glissando: FOR I = 440 TO 1000 STEP 5 SOUND I, I/1000 NEXT FOR I = 1000 TO 440 STEP -5 SOUND I, I/1000 NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SPACE$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string of spaces of length n ž Syntax SPACE$(n) ž Remarks The expression n is rounded to an integer and must be in the range 0-32,767. ž See Also SPC ž Example This example illustrates the use of SPACE$: FOR I=1 TO 5 X$=SPACE$(I) PRINT X$;I NEXT I ž Output 1 2 3 4 5 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SPC Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Skips n spaces in a PRINT statement ž Syntax SPC(n) ž Remarks SPC may only be used with PRINT and LPRINT statements. The argument n must be in the range 0-32,767. A semicolon (;) is assumed to follow the SPC(n) command. ž See Also SPACE$ ž Example This example illustrates the use of SPC: PRINT "OVER";SPC(15) "THERE" ž Output OVER THERE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SQR Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the square root of n ž Syntax SQR(n) ž Remarks The argument n must be >= 0. ž Example The following program plots the graphs of y = ū-x for -9 <= x < 0 and of y = ūx for 0 <= x <= 9: SCREEN 1 : COLOR 1 'Low-resolution color graphics mode. WINDOW (-9,-.25)-(9,3.25) 'Convert screen to Cartesian 'coordinates. LINE (-9,0)-(9,0) 'Draw X-axis. LINE (0,-.25)-(0,3.25) 'Draw Y-axis. FOR X = -9 TO 9 LINE(X,.04)-(X,-.04) 'Put tick marks on X-axis. NEXT FOR Y = .25 TO 3.25 STEP .25 LINE (-.08,Y)-(.12,Y) 'Put tick marks on Y-axis. NEXT PSET (-9,3) 'Plot the first point of function. FOR X = -9 TO 9 STEP .25 Y = SQR(ABS(X)) 'SQR argument cannot be negative. LINE -(X,Y),2 'Draw a line to the next point. NEXT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STATIC Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Makes simple variables or arrays local to either a DEF FN function, a FUNCTION, or a SUB and preserves values between calls ž Syntax STATIC variablelist ž Remarks A STATIC statement variablelist has the following syntax: variable®( )Æ®AS typeÆ ®, variable®( )Æ®AS typeÆÆ... The variablelist takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ variable Either a variable name or an array name. AS type Declares the type of variable. The type argument can be INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The STATIC statement can appear only in a SUB, FUNCTION, or DEF FN function. Earlier versions of BASIC required the number of dimensions in parentheses after an array name. In QuickBASIC, the number of dimensions is optional. Variables declared in a STATIC statement override variables of the same name shared by DIM or COMMON statements in the module-level code. Variables in a STATIC statement also override global constants of the same name. Usually, variables used in DEF FN functions are global to the module; however, you can use the STATIC statement inside a DEF FN statement to declare a variable as local to only that function. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The STATIC attribute on SUB and FUNCTION statements declares the default for variables to be static. Variables having the same name as variables shared by the module-level code are still shared. In contrast, the STATIC statement makes specific variables static and overrides any variables shared by the module-level code. The ›STATIC metacommand affects how memory is allocated for arrays. See Chapter 2, "Data Types," for a discussion of the differences among these statements and attributes. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also COMMON, DEF FN, DIM, FUNCTION, SHARED, SUB ž Examples This example contrasts the STATIC and SHARED statements within a subprogram AUGMENT. The variables R and N are both local to this subprogram, while the variables REP and NUM are shared between the main program and the subprogram. The STATIC R,N statement ensures that R and N retain the last values assigned to them each time the main program calls the subprogram. Rep = 0 : Num = 0 PRINT "Before loop, REP = ";Rep;", NUM = ";Num; PRINT ", R = ";R;", N = ";N FOR I = 1 TO 10 CALL Augment NEXT PRINT "After loop, REP = ";Rep;", NUM = ";Num; PRINT ", R = ";R;", N = ";N END SUB Augment STATIC SHARED Rep,Num 'Shared with main program. STATIC R,N 'Not shared with main program. R = R + 1 'Both R and N initially equal 0. N = N + 2 Rep = R Num = N END SUB ž Output Before loop, REP = 0 , NUM = 0 , R = 0 , N = 0 After loop, REP = 10 , NUM = 20 , R = 0 , N = 0 The following program searches for every occurrence of a certain string expression (stored in the variable OLD$) in the specified file and replaces that string with the string stored in NW$. The name of the file with these changes is the old filename with the extension .NEW. The program also prints the number of substitutions and the number of lines changed. INPUT "Name of file";F1$ INPUT "String to replace";Old$ INPUT "Replace with";Nw$ Rep = 0 : Num = 0 M = LEN(Old$) OPEN F1$ FOR INPUT AS #1 CALL Extension OPEN F2$ FOR OUTPUT AS #2 DO WHILE NOT EOF(1) LINE INPUT #1, Temp$ CALL Search PRINT #2, Temp$ LOOP CLOSE PRINT "There were ";Rep;" substitutions in ";Num;" lines." PRINT "Substitutions are in file ";F2$ END SUB Extension STATIC SHARED F1$,F2$ Mark = INSTR(F1$,".") IF Mark = 0 THEN F2$ = F1$ + ".NEW" ELSE F2$ = LEFT$(F1$,Mark - 1) + ".NEW" END IF END SUB SUB Search STATIC SHARED Temp$,Old$,Nw$,Rep,Num,M STATIC R Mark = INSTR(Temp$,Old$) WHILE Mark Part1 = LEFT$(Temp$,Mark - 1) Part2 = MID$(Temp$,Mark + M) Temp$ = Part1$ + Nw$ + Part2$ R = R + 1 Mark = INSTR(Temp$,Old$) WEND IF Rep = R THEN EXIT SUB ELSE Rep = R Num = Num + 1 END IF END SUB ž Output Name of file? CHAP1.S String to replace? CHAPTER 1 Replace with? INTRODUCTION There were 23 substitutions in 19 lines. Substitutions are in file CHAP1.NEW The file CHAP1.NEW now contains every line in CHAP1.S, with each occurrence of the string CHAPTER 1 replaced by INTRODUCTION. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STICK Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the x- and y-coordinates of the two joysticks ž Syntax STICK(n) ž Remarks The argument n is a numeric expression whose value is an unsigned integer in the range 0 to 3: Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 The x-coordinate of joystick A 1 The y-coordinate of joystick A when STICK(0) was last called 2 The x-coordinate of joystick B when STICK(0) was last called 3 The y-coordinate of joystick B when STICK(0) was last called ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The x- and y-coordinates have a range of 1 to 200. You must use STICK(0) before you use STICK(1), STICK(2), or STICK(3). STICK(0) not only returns the x-coordinate of joystick A, it also records the other joystick coordinates. These recorded coordinates are returned by calling STICK(1)-STICK(3). ž Example The following fragment prints the coordinates of joystick B: TEMP = STICK(0) PRINT STICK(2), STICK(3) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STOP Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Terminates the program ž Syntax STOP ž Remarks STOP statements can be used anywhere in a program to terminate execution. When running in the QuickBASIC environment, the STOP statement leaves files open and does not exit to the operating system. In contrast, a STOP statement in a stand-alone .EXE file does close all files and return to the operating system. If you use the /D, /E, or /X compile options on the bc command line, the STOP statement prints the number of the line where execution stopped, if your program has line numbers. If there is no line number associated with the STOP statement, the most recent line number is printed. If your program has no line numbers, then the line number printed is 0. In the past, STOP statements were used for debugging. QuickBASIC's new debugging features make this use of STOP unnecessary. ž Example There is no programming example for the STOP statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STR$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string representation of the value of a numeric expression ž Syntax STR$(numeric-expression) ž Remarks If numeric-expression is positive, the string returned by the STR$ function contains a leading blank. The VAL function complements STR$. ž See Also VAL ž Example The following example contains a FUNCTION that uses the STR$ function to convert a number to its string representation. The FUNCTION then strips out the leading and trailing blanks that BASIC prints with numeric output. FUNCTION NumRemBlanks$(X) STATIC X$ = STR$(X) NumRemBlanks$ = LTRIM$(RTRIM$(X$)) END FUNCTION PRINT "Enter 0 to end." DO INPUT "Find cosine of: ",Num IF Num = 0 THEN EXIT DO PRINT "COS(" NumRemBlanks$(Num) ") = " COS(Num) LOOP ž Output Enter 0 to end. Find cosine of: 3.1 COS(3.1) = -.9991351 Find cosine of: 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STRIG Function and Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the status of a specified joystick trigger ž Syntax 1 (Function) STRIG(n) ž Syntax 2 (Statement) STRIG {ON | OFF} ž Remarks The STRIG function is used to test the joystick trigger status. In previous versions of BASIC, the statement STRIG ON enables testing of the joystick triggers; STRIG OFF disables joystick trigger testing. QuickBASIC ignores STRIG ON and STRIG OFF statementsÄÄthe statements are provided for compatibility with earlier versions. The numeric expression n is an unsigned integer in the range 0-7, indicating the joystick and trigger to check. The following list describes the values returned by the STRIG(n) function for different values of n: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Returns -1 if the lower button on joystick A has been pressed since the last STRIG(0) call; otherwise returns 0 1 Returns -1 if the lower button on joystick A is currently down; otherwise returns 0 2 Returns -1 if the lower button on joystick B has Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  2 Returns -1 if the lower button on joystick B has been pressed since the last STRIG(2) call; otherwise returns 0 3 Returns -1 if the lower button on joystick B is currently down; otherwise returns 0 4 Returns -1 if the upper button on joystick A has been pressed since the last STRIG(4) call; otherwise returns 0 5 Returns -1 if the upper button on joystick A is currently down; otherwise returns 0 6 Returns -1 if the upper button on joystick B has been pressed since the last STRIG(6) call; otherwise returns 0 7 Returns -1 if the upper button on joystick B is Argument Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  7 Returns -1 if the upper button on joystick B is currently down; otherwise returns 0 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can also use event trapping to get information from the joystick by using the ON STRIG statement (see the ON event statement). You cannot use the STRIG function inside a joystick event trap because the event that caused the trap is destroyed. ž Differences From Basica If you are compiling from the BC command line, you must use the /V or /W option if a program contains a STRIG statement. ž See Also ON event; STRIG ON, OFF, and STOP ž Example The following example illustrates STRIG: 'Wait for trigger A to be pressed. DO GotATrig = STRIG(0) LOOP UNTIL GotATrig 'As long as trigger A is down, beep. DO GotATrig = STRIG(1) BEEP LOOP WHILE GotATrig ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STRIG ON, OFF, and STOP Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables, disables, or inhibits trapping of joystick activity ž Syntax STRIG(n) ON STRIG(n) OFF STRIG(n) STOP ž Remarks The argument, n, is a numeric expression indicating the joystick button to trap: Value Button ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 Lower button, joystick A 2 Lower button, joystick B 4 Upper button, joystick A 6 Upper button, joystick B ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ The STRIG(n) ON statement enables joystick event trapping by an ON STRIG statement (see the ON event statement). While trapping is enabled, and if a nonzero line number is specified in the ON STRIG statement, BASIC checks between every statement to see if the joystick trigger has been pressed. The STRIG(n) OFF statement disables event trapping. If a subsequent event occurs (i.e., if the trigger is pressed), it will not be remembered when the next STRIG ON is executed. The STRIG(n) STOP statement inhibits event trapping. If an event occurs it is remembered, and the event trap takes place as soon as trapping is reenabled. ž See Also ON event, STRIG ž Example There is no programming example for the STRIG statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ STRING$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string whose characters all have a given ASCII code or whose characters are all the first character of a string expression ž Syntax STRING$(m,n) STRING$(m,stringexpression) ž Remarks The STRING$ function has the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ m A numeric expression indicating the length of the string to return. n The ASCII code of the character to use to build the string. It is a numeric expression that evaluates to an integer value in the range 0-255. stringexpression The string expression whose first character is used to build the return string. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Examples The following example uses STRING$ to create part of a report heading: Dash$ = STRING$(10,45) PRINT Dash$;"MONTHLY REPORT";Dash$ ž Output ----------MONTHLY REPORT---------- The following program uses STRING$ to generate a bar graph: PRINT TAB(7);"Daily Mean Temperature in Seattle" : PRINT 'Get data for each month and graph. FOR Month = 1 TO 12 STEP 2 READ Month$, Temp 'Print Temp-35 stars. PRINT Month$;" +"; STRING$(Temp-35,"*") PRINT " |" NEXT Month 'Print horizontal line. PRINT " +"; FOR X = 1 TO 7 PRINT "----+"; NEXT X PRINT 'Print temperature labels. FOR X = 4 TO 39 STEP 5 PRINT TAB(X); X+31; NEXT X PRINT DATA Jan, 40, Mar, 46, May, 56 DATA Jul, 66, Sep, 61, Nov, 46 ž Output Daily Mean Temperature in Seattle Jan +***** | Mar +*********** | May +********************* | Jul +******************************* | Sep +************************** | Nov +*********** | +----+----+----+----+----+----+----+ 35 40 45 50 55 60 65 70 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SUB Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Marks the beginning and end of a subprogram ž Syntax SUB globalname®(parameterlist)Æ ®STATICÆ . . . ®EXIT SUBÆ . . . END SUB ž Remarks The SUB statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ globalname A variable name up to 40 characters long. This name cannot appear in any other FUNCTION or SUB statement in the same program or the user library. parameterlist Contains the names of simple variables and arrays passed to the subprogram when the SUB is invoked. Each name is separated from the preceding name by a comma. Note that these variables and arrays are passed by reference, so any change to an argument's value in the subprogram also changes its value in the calling program. See below for a complete description of the syntax. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A SUB parameterlist has the following syntax: variable®( )Æ ®AS typeÆ ®, variable®( )Æ ®AS typeÆÆ... A variable is a BASIC variable name. Previous versions of BASIC required the number of dimensions in parentheses after an array name. In QuickBASIC, the number of dimensions is not required. The argument type is the type of the variable. The type argument can be INTEGER, LONG, SINGLE, DOUBLE, STRING, or a user-defined type. You may not use a fixed-length string, or an array of fixed-length strings, as a parameter. However, you may use a simple fixed-length string as an argument in a CALL statementÄÄQuickBASIC converts a simple fixed-length string argument to a variable-length string argument before passing the string to a SUB. A subprogram is a separate procedure, like a FUNCTION. However, a SUB cannot be used in an expression, unlike a FUNCTION. SUB and END SUB mark the beginning and end of a subprogram. You may also use the optional EXIT SUB statement to exit a subprogram. Subprograms are called by a CALL statement or by using the subprogram name followed by the argument list. See the entry for the CALL statement. QuickBASIC subprograms can be recursiveÄÄthey can call themselves to perform a given task. See the second example below and Section 4.4, "Recursion." The STATIC attribute indicates that all variables local to the SUB are staticÄÄtheir values are saved between calls. Using the STATIC keyword slightly increases execution speed. STATIC is not usually used with recursive subprograms. See the examples below. Any subprogram variables or arrays are considered local to that subprogram unless they are explicitly declared as shared variables in a SHARED statement. You cannot define SUB procedures, DEF FN functions, or FUNCTION procedures inside a SUB procedure. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE You cannot use GOSUB, GOTO, or RETURN to enter or exit a subprogram. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ See Chapter 2, "SUB and FUNCTION Procedures," in Programming in BASIC for more information. ž See Also CALL (BASIC), DECLARE (BASIC), SHARED, STATIC ž Examples In this example, the main program calls a subprogram, LINESEARCH, which searches for the given string, P$, in each line of input from file F$. When the subprogram finds P$ in a line, it prints the line, along with the number of the line. Notice that the value of Num is saved between calls because the STATIC keyword is used on the SUB statement. INPUT "File to be searched";F$ INPUT "Pattern to search for";P$ OPEN F$ FOR INPUT AS #1 DO WHILE NOT EOF(1) LINE INPUT #1, Test$ CALL Linesearch(Test$,P$) LOOP SUB Linesearch(Test$,P$) STATIC Num = Num + 1 X = INSTR(Test$,P$) IF X > 0 THEN PRINT "Line #";Num;": ";Test$ END SUB ž Output File to be searched? search.bas Pattern to search for? SUB Line # 9 : SUB Linesearch(Test$,P$) STATIC Line # 13 : END SUB The following example uses a recursive SUB to solve the classic Tower of Hanoi puzzle for a variable number of disks. For large numbers of disks, the stack size must be increased using the CLEAR statement. DECLARE SUB Hanoi (N%, Srce%, Dest%, Hold%) DEFINT A-Z DIM SHARED MoveCount MoveCount = 0 CLS PRINT "Tower of Hanoi Puzzle" INPUT "Enter number of disks: ", Disks ' Call the recursive Hanoi SUB to solve the puzzle. CALL Hanoi(Disks, 1, 3, 2) PRINT "Puzzle complete in"; MoveCount; "moves." END ' Move N disks from Srce to Dest using Hold as holding peg. SUB Hanoi (N, Srce, Dest, Hold) IF N <= 1 THEN ' Only 1 disk. Move it directly to Dest. PRINT "Move a disk from"; Srce; "to"; Dest MoveCount = MoveCount + 1 ELSE ' More than one disk. ' Move the N-1 disks to Hold, using Dest as holding peg. CALL Hanoi(N - 1, Srce, Hold, Dest) ' Move the Nth disk directly to Dest. PRINT "Move a disk from"; Srce; "to"; Dest: MoveCount = MoveCount + 1 ' Move the N-1 disks to Dest, using Srce as holding peg. CALL Hanoi(N - 1, Hold, Dest, Srce) END IF END SUB ž Output Tower of Hanoi Puzzle Enter number of disks: 3 Move a disk from 1 to 3 Move a disk from 1 to 2 Move a disk from 3 to 2 Move a disk from 1 to 3 Move a disk from 2 to 1 Move a disk from 2 to 3 Move a disk from 1 to 3 Puzzle complete in 7 moves. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SWAP Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Exchanges the values of two variables ž Syntax SWAP variable1,variable2 ž Remarks Any type of variable can be swapped (integer, long, single precision, double precision, string, or record). However, the two variables must be exactly the same type or an error message appears (Type mismatch). For example, trying to swap an integer with a single-precision value produces Type mismatch. ž Example The following subroutine (ShellSort) sorts the elements of a string array in descending order using a Shell sort. ShellSort uses SWAP to exchange array elements that are out of order. ' Sort the word list using a Shell sort. SUB ShellSort (Array$(), Num%) STATIC Span% = Num% \ 2 DO WHILE Span% > 0 FOR I% = Span% TO Num% - 1 J% = I% - Span% + 1 FOR J% = (I% - Span% + 1) TO 1 STEP -Span% IF Array$(J%) <= Array$(J% + Span%) THEN EXIT FOR ' Swap array elements that are out of order. SWAP Array$(J%), Array$(J% + Span%) NEXT J% NEXT I% Span% = Span% \ 2 LOOP END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SYSTEM Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Closes all open files and returns control to the operating system ž Syntax SYSTEM ž Remarks When a SYSTEM command is executed, all files are closed and BASIC exits to the operating system (for stand-alone executable programs) or stops program execution (if the program is run in the QuickBASIC environment). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE A program containing a SYSTEM statement exits to the operating system if run from the QuickBASIC command line with the /RUN option. Entering a SYSTEM statement in the Immediate window terminates QuickBASIC. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Differences From Basica END and SYSTEM are distinct in BASICA but act identically in QuickBASIC. ž Example There is no programming example for the SYSTEM statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TAB Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Moves the print position ž Syntax TAB(column) ž Remarks The argument, column, is a numeric expression that is the column number of the new print position. If the current print position is already beyond column, the TAB function moves the print position to that column on the next line. Column 1 is the leftmost position, and the rightmost position is the current line width of the output device minus one. If column is greater than the output width, TAB wraps the output and the print position becomes 1 + (column MOD width). If column is less than 1, TAB moves the print position to column 1. TAB can only be used in PRINT and LPRINT statements. ž See Also WIDTH ž Examples The following example uses TAB to locate columns of output: FOR I = 1 TO 4 READ A$,B$ PRINT A$ TAB(25) B$ NEXT DATA NAME, AMOUNT,,, G.T. JONES, $25.00, H.L. STEVENS, $32.25 ž Output NAME AMOUNT G.T. JONES $25.00 H.L. STEVENS $32.25 The following example shows the effects of different values used as arguments to TAB: 'Assumes 80-column screen width. PRINT TAB(1287); "one" PRINT TAB(255); "two" PRINT TAB(-5); "three" PRINT "123456789012345678901234567890" TAB(20) "four" ž Output one two three 123456789012345678901234567890 four ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TAN Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the tangent of the angle x, where x is in radians ž Syntax TAN(x) ž Remarks TAN is calculated with single-precision accuracy unless x is a double-precision value, in which case TAN is calculated with double-precision accuracy. ž Differences From Basica In BASICA, if TAN overflows, the interpreter displays the Overflow error message, returns machine infinity as the result, and continues execution. If TAN overflows, QuickBASIC does not display machine infinity and execution halts (unless the program has an error-handling routine). ž Example The following example computes the height of an object using the distance from the object and the angle of elevation. The program draws the triangle produced by the base and the computed height. SCREEN 2 INPUT "LENGTH OF BASE: ",Baselen INPUT "ANGLE OF ELEVATION (DEGREES,MINUTES): ",Deg,Min Ang = (3.141593/180)*(Deg + Min/60) 'Convert to radians. Height = Baselen*TAN(Ang) 'Calculate height. PRINT "HEIGHT =" Height H = 180 - Height B = 15 + Baselen LINE (15,180)-(B,180):LINE -(B,H) 'Draw triangle. LINE -(10,180) LOCATE 24,1 : PRINT "Press any key to continue..."; DO LOOP WHILE INKEY$="" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TIME$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the current time from the operating system ž Syntax TIME$ ž Remarks The TIME$ function returns an eight-character string in the pattern hh:mm:ss, where hh is the hour (00-23), mm is minutes (00-59), and ss is seconds (00-59). A 24-hour clock is used; therefore, 8:00 PM is shown as 20:00:00. To set the time, use the TIME$ statement. ž See Also TIME$ Statement, TIMER ž Example The following example converts the 24-hour time returned by TIME$ to a 12-hour time: 'Convert the 24-hour clock used by TIME$ to '12-hour output followed by "AM" or "PM." T$ = TIME$ Hr = VAL(T$) IF Hr < 12 THEN Ampm$ = " AM" ELSE Ampm$ = " PM" IF Hr > 12 THEN Hr = Hr - 12 PRINT "The time is" STR$(Hr) RIGHT$(T$,6) Ampm$ ž Output The time is 11:26:31 AM ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TIMER Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the number of seconds elapsed since midnight ž Syntax TIMER ž Remarks The TIMER function can be used with the RANDOMIZE statement to generate a random number. It can also be used to time programs or parts of programs. ž Example The following program searches for the prime numbers from 3 to 10,000 using a variation of the Sieve of Eratosthenes. The TIMER function is used to time the program. DEFINT A-Z CONST UNMARK = 0, MARKIT = NOT UNMARK DIM Mark(10000) Start! = TIMER Num = 0 FOR N = 3 TO 10000 STEP 2 IF NOT Mark(N) THEN 'PRINT N, 'To print the primes, remove the 'remark delimiter in front of the 'PRINT statement. Delta = 2*N FOR I = 3*N TO 10000 STEP Delta Mark(I) = MARKIT NEXT Num = Num + 1 END IF NEXT Finish! = TIMER PRINT : PRINT "Program took"; Finish!-Start!; PRINT "seconds to find the"; Num; "primes" END ž Output Program took .1601563 seconds to find the 1228 primes ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TIMER ON, OFF, and STOP Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables, disables, or inhibits timer event trapping ž Syntax TIMER ON TIMER OFF TIMER STOP ž Remarks TIMER ON enables timer event trapping by an ON TIMER statement (see the statement ON event). While trapping is enabled, a check is made after every statement to see if the specified time has elapsed. If it has, the ON TIMER event-handling routine is executed. TIMER OFF disables timer event trapping. If an event takes place, it is not remembered if a subsequent TIMER ON is executed. TIMER STOP disables the timer event trapping. However, if an event occurs, it is remembered and the ON TIMER event-handling routine is executed as soon as trapping is reenabled with TIMER ON. ž See Also ON event ž Example The following example displays the time of day on line 1, and updates the display once a minute: TIMER ON ON TIMER(60) GOSUB Display DO WHILE INKEY$ = "" : LOOP END Display: Oldrow = CSRLIN 'Save current row. Oldcol = POS(0) 'Save current column. LOCATE 1,1 : PRINT TIME$; LOCATE Oldrow,Oldcol 'Restore row & column. RETURN ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TIME$ Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sets the time ž Syntax TIME$=stringexpression ž Remarks The stringexpression must be in one of the following forms: Form Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ hh Sets the hour; minutes and seconds default to 00 hh:mm Sets the hour and minutes; seconds default to 00 hh:mm:ss Sets the hour, minutes, and seconds ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A 24-hour clock is used, so 8:00 PM would be entered as 20:00:00. This statement complements the TIME$ function, which returns the current time. ž See Also TIME$ Function ž Example The following example sets the current time to 8:00 AM: TIME$="08:00:00" ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TRON/TROFF Statements ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Traces the execution of program statements ž Syntax TRON TROFF ž Remarks In the QuickBASIC environment, executing a TRON statement has the same effect as selecting Trace On from the Debug menuÄÄeach statement is highlighted on the screen as it executes. The TROFF statement turns off the program trace. The TRON and TROFF statements only display line numbers when compiled with the Debug option or the /D option on the BC command line. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE The debugging features of the QuickBASIC environment make these statements unnecessary. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Example There is no programming example for the TRON statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ TYPE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Defines a data type containing one or more elements ž Syntax TYPE usertype elementname AS typename elementname AS typename . . . END TYPE ž Remarks The TYPE statement takes the following arguments: Argument Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ usertype A name given to the user-defined data type. Follows the same rules as a BASIC variable name. elementname The name of an element of the user-defined data type. Follows the same rules as a BASIC variable name. Cannot be the name of an array. typename May be any of the following BASIC data types: INTEGER, LONG, SINGLE, DOUBLE, fixed-length string (see note below), or user-defined type. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Strings in user types must be fixed-length strings. String lengths are indicated by an asterisk and a numeric constant. For example, the following line defines an element named Keyword in a user-defined type as a string with length 40: Keyword AS STRING*40 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A user-defined type must be declared in a TYPE declaration before it can be used in the program. Although a user-defined type can only be declared in the module-level code, you may declare a variable to be of a user-defined type anywhere in the module, even in a SUB or FUNCTION. Use the DIM, REDIM, COMMON, STATIC, or SHARED statements to declare a variable to be of a user-defined type. ž Example The following example simulates a deck of cards by using a user-defined type. The program builds a deck of cards (an array of user-defined type Card), shuffles the deck, and displays the first five cards. ' This program uses a user-defined type to ' simulate a deck of cards. ' Define the Card type--an integer value and a string ' representing the suit. TYPE Card Value AS INTEGER Suit AS STRING*9 END TYPE DEFINT A-Z ' Define the Deck as a 52-element array of Cards. DIM Deck(1 TO 52) AS Card ' Build, shuffle, and deal the top five cards. CALL BuildDeck(Deck()) CALL Shuffle(Deck()) FOR I%=1 TO 5 CALL ShowCard(Deck(I%)) NEXT I% ' Build the deck--fill the array of Cards with ' appropriate values. SUB BuildDeck(Deck(1) AS Card) STATIC DIM Suits(4) AS STRING*9 Suits(1)="Hearts" Suits(2)="Clubs" Suits(3)="Diamonds" Suits(4)="Spades" ' This loop controls the suit. FOR I%=1 TO 4 ' This loop controls the face value. FOR J%=1 TO 13 ' Figure out which card (1...52) you're creating. CardNum%=J%+(I%-1)*13 ' Place the face value and suit into the Card. Deck(CardNum%).Value=J% Deck(CardNum%).Suit=Suits(I%) NEXT J% NEXT I% END SUB ' Shuffle a deck (an array containing Card elements). SUB Shuffle(Deck(1) AS Card) STATIC RANDOMIZE TIMER ' Shuffle by transposing 1000 randomly selected pairs of cards. FOR I%=1 TO 1000 CardOne%=INT(52*RND+1) CardTwo%=INT(52*RND+1) ' Notice that SWAP works on arrays of user types. SWAP Deck(CardOne%),Deck(CardTwo%) NEXT I% END SUB ' Display a single card by converting and printing the ' face value and the suit. SUB ShowCard (SingleCard AS Card) STATIC SELECT CASE SingleCard.Value CASE 13 PRINT "King "; CASE 12 PRINT "Queen"; CASE 11 PRINT "Jack "; CASE 1 PRINT "Ace "; CASE ELSE PRINT USING " ## ";SingleCard.Value; END SELECT PRINT " ";SingleCard.Suit END SUB ž Output 3 Clubs 4 Hearts 3 Diamonds Jack Clubs 8 Spades ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ UBOUND Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the upper bound (largest available subscript) for the indicated dimension of an array ž Syntax UBOUND(array®,dimensionÆ) ž Remarks The argument dimension is an integer from 1 to the number of dimensions in array. For an array dimensioned as follows, UBOUND returns the values listed below: DIM A(1 TO 100, 1 TO 50, -3 TO 4) Invocation Value Returned ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ UBOUND(A,1) 100 UBOUND(A,2) 50 UBOUND(A,3) 4 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ You can use the shortened syntax UBOUND(array) for one-dimensional arrays since the default value for dimension is 1. Use the LBOUND function to find the lower limit of an array dimension. ž See Also LBOUND ž Example LBOUND and UBOUND can be used together to determine the size of an array passed to a subprogram, as in the following program fragment: CALL PRNTMAT(ARRAY()) . . . SUB PRNTMAT(A()) STATIC FOR I% = LBOUND(A,1) TO UBOUND(A,1) FOR J% = LBOUND(A,2) TO UBOUND(A,2) PRINT A(I%,J%);" "; NEXT J% PRINT:PRINT NEXT I% END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ UCASE$ Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns a string expression with all letters in uppercase ž Syntax UCASE$ (stringexpression) ž Remarks The stringexpression argument can be any string expression. The UCASE$ function works with both variable- and fixed-length strings. The UCASE$ and LCASE$ statements are helpful in making string comparisons case insensitive. ž See Also LCASE$ ž Example The following program contains a FUNCTION, YesQues, that returns a Boolean value depending on how the user responds. The program YesQues uses UCASE$ to make a case-insensitive test of the user's response. DEFINT A-Z FUNCTION YesQues(Prompt$,Row,Col) STATIC OldRow=CSRLIN OldCol=POS(0) ' Print prompt at Row, Col. LOCATE Row,Col : PRINT Prompt$ "(Y/N):"; DO ' Get the user to press a key. DO Resp$=INKEY$ LOOP WHILE Resp$="" Resp$=UCASE$(Resp$) ' Test to see if it's yes or no. IF Resp$="Y" OR Resp$="N" THEN EXIT DO ELSE BEEP END IF LOOP ' Print the response on the line. PRINT Resp$; ' Move the cursor back to the old position. LOCATE OldRow,OldCol ' Return a Boolean value by returning the result of a test. YesQues=(Resp$="Y") END FUNCTION DO LOOP WHILE NOT YesQues("Do you know the frequency?",12,5) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ UEVENT Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Enables, disables, or suspends event trapping for a user-defined event ž Syntax UEVENT ON UEVENT OFF UEVENT STOP ž Remarks The effects of the UEVENT statements are like that of other event-trapping statements. When UEVENT ON is executed, the event-trapping routine is enabled. Occurrences of the event trigger execution of the event-handling routine. When UEVENT OFF is executed, the event-trapping routine is disabled. Any occurrences of the event are ignored. When UEVENT STOP is executed, the event-trapping routine is suspended. An event occurrence is remembered and the event-trapping routine performed as soon as a UEVENT ON statement is executed. ž See Also ON UEVENT ž Example See the example for ON UEVENT. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ UNLOCK Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Releases locks applied to parts of a file ž Syntax UNLOCK ®#Æ filenumber ®,{record | ®startÆ TO end}Æ ž Remarks The UNLOCK statement is used only after a LOCK statement. See the LOCK statement for a complete discussion. For binary-mode files, the arguments record, start, and end represent the number of a byte relative to the beginning of the file. The first byte in a file is byte 1. For random-access files, these arguments are the number of a record relative to the beginning of the file. The first record is record 1. ž See Also LOCK ž Example See the example for LOCK. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Creating a User-Defined Event ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ In previous versions of QuickBASIC, the only events that could be trapped were those already defined in the language: COM, KEY, PEN, PLAY, STRIG and TIMER. There was no way to define your own event. QuickBASIC 4.5 allows you to define your own event trap. When the event occurs, BASIC calls the routine that handles the trap, just as if the event were part of the QuickBASIC language. A user-defined event has three elements. The first is a routine that detects the event. The second is this routine's call to the BASIC procedure SetUEvent, which traps the event. The third is BASIC's call to a routine that handles the event. You create a user-defined event by writing two pieces of code. The first is the routine that detects the event. (The event could be a hardware interrupt, or perhaps an altered data value at a special memory location.) This routine can be written in BASIC, or other languages, such as C and assembler. (BASIC routines can be included in the main module. Code written in other languages must be separately compiled and added to a Quick Library.) The event-detecting routine must block; that is, it must sit waiting for the event. (A routine that does not block would have to be called repeatedly to see if the event has occurred. This defeats the purpose of a user-defined event, as it is no different from conventional polling.) When the event occurs, it calls the BASIC routine SetUEvent. It is this call that traps the event. BASIC then calls the event handler. The event handler is the second piece of code. The advantage of separating event trapping from event handling is that the handling can be tailored to the needs of the moment; the same event can be handled differently in different parts of the program. Let's consider a simple example to see how this works. Our hypothetical programmer has designed an interface board for home monitoring and control. One of its features is a mailbox alarm: opening the mailbox door closes a switch that sets the most-significant bit at a specific buss address. Here is a simple BASIC routine to monitor this switch. (The segment and address quantities are for illustration only. They are in the video RAM space, and probably wouldn't be useful for other kinds of interfaces.) MailBoxOpened: DEF SEG = &h9000 ' set the address segment value% = PEEK (&h1234) ' read value at address in that segment IF value% THEN CALL SetUEvent ' tell BASIC event has occurred DEF SEG ' return to BASIC data segment ž RETURN Value% is either zero, or has its MSB set. In the latter case it is logically "true" (indicating that the mailbox was opened), and the SetUEvent routine is called. This routine (which is part of BASIC) tells BASIC that the expected event has occurred, and it is time to execute the event-handling routine. All event-detecting routines, regardless of the languages they are written in, must call SetUEvent. If the event-detecting routine is in a language other than BASIC, the Quick Library containing it has to be loaded before a QuickBASIC program that uses it can run or be compiled. Include a DECLARE SUB statement in the module calling the event-detection routine, so that BASIC knows how to find it. Now let's write an event-handling routine to tell our programmer his mail has arrived: MailCame: PRINT "Ta-Dah! Your day is made! The mail came!" ž RETURN All that's left is to tell BASIC about the user-defined event handler, using the ON UEVENT statement. ON UEVENT works just like ON EVENT; it associates the user-defined event with the event-handling routine: ON UEVENT GOSUB MailCame ' associate the handler routine with user event UEVENT ON ' initiate user-event trapping . . . CALL MailBoxOpened ' call the routine that looks for the event . . . END Note that ON UEVENT deals only with the event-handler; it is not concerned with event-detection. Once the UEVENT ON statement has been executed, any call to SetUEvent will trigger the specified event-handler, regardless of how or where the call is issued. Here is a summary of the steps in creating and using a user-defined event handler: 1. Write the routine that detects the event. When the event occurs, the routine must call the BASIC routine SetUEvent. 2. If the event-detecting routine is in BASIC, place it after the END statement in the module where it will be called. If the event-detecting routine is not in BASIC, compile it and include it in a BASIC Quick Library. The module(s) that call this routine must include a DECLARE SUB statement so that BASIC can find the routine. 3. Write the routine that handles the event. 4. Use the ON UEVENT statement to tell BASIC the name of the event-handling routine associated with the user-defined event. 5. Use the UEVENT ON statement to initiate trapping. (UEVENT OFF and UEVENT STOP may be used to terminate or postpone trapping.) 6. Call the event-detecting routine. When the event occurs, BASIC will call the event-handling routine named in the ON UEVENT statement. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ VAL Function ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the numeric value of a string of digits ž Syntax VAL(stringexpression) ž Remarks The stringexpression is a sequence of characters that can be interpreted as a numeric value. The VAL function stops reading the string at the first character that it cannot recognize as part of a number. The VAL function also strips leading blanks, tabs, and line feeds from the argument string. For example, VAL(" -33/LP") returns the value -33. ž See Also STR$ ž Example The following program prints the names and addresses of people with specific telephone area codes: INPUT "Search for which area: ", Targetarea OPEN "MAIL.DAT" FOR INPUT AS #1 DO WHILE NOT EOF(1) INPUT #1, Nm$, Phonenum$, Street$, Citystate$ 'VAL reads everything up to the first non-numeric 'character ("-" in this case). Area = VAL(Phonenum$) IF Area = Targetarea THEN PRINT : PRINT Nm$ PRINT Street$ PRINT Citystate$ END IF LOOP CLOSE : END ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ VARPTR, VARSEG Functions ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Returns the address of a variable ž Syntax VARPTR(variablename) VARSEG(variablename) ž Remarks The variablename may be any BASIC variable, including a record variable or record element. The VARPTR function returns an unsigned integer that is the offset of the variable within its segment. The VARSEG function returns an unsigned integer that is the segment part of the variable's address. If variablename is not defined before either VARPTR or VARSEG is called, the variable is created and its address is returned. When variablename is a string variable, VARPTR and VARSEG return the location of the first byte of the string descriptor. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE Because many BASIC statements change the locations of variables in memory, use the values returned by VARPTR and VARSEG immediately after the functions are used. See Section 2.3.3, "Variable Storage Allocation," for a list of things that cause variable locations to move. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ VARPTR and VARSEG are often used with BLOAD, BSAVE, CALL ABSOLUTE, CALL INTERRUPT, PEEK, POKE, or when passing arrays to procedures written in other languages. When using VARPTR or VARSEG to get the address of an array, use the first element of the array as the argument: DIM A(150) . . . ArrAddress=VARPTR(A(1)) You may no longer use VARPTR to get the address of a file's buffer. Use the function FILEATTR to get information about a file. In addition, programs written in earlier versions of BASIC that used VARPTR to access numeric arrays may no longer work. You must now use a combination of VARPTR and VARSEG. For example, the following QuickBASIC Version 3.0 fragment no longer works correctly: DIM Cube(675) . . . BSAVE "graph.dat",VARPTR(Cube(1)),2700 The fragment would be rewritten as follows: DIM Cube(675) . . . ' Change segment to segment containing Cube. DEF SEG=VARSEG(Cube(1)) BSAVE "graph.dat",VARPTR(Cube(1)),2700 ' Restore BASIC segment. DEF SEG You may use VARPTR alone to get the address of a variable stored in DGROUP. You must use both VARPTR and VARSEG to get the complete address of a variable stored as a far object. See Section 2.3.3, "Variable Storage Allocation," for rules to determine when a variable is stored in DGROUP. The VARSEG function combined with VARPTR replaces the PTR86 subprogram used in previous versions of QuickBASIC. ž See Also BLOAD, BSAVE, CALL ABSOLUTE, CALL INTERRUPT, DEF SEG, PEEK, POKE ž Example See the entries for BLOAD, BSAVE, CALL ABSOLUTE, and CALL INTERRUPT for examples of how to use VARPTR and VARSEG with those statements. The following program illustrates how to use VARPTR and VARSEG to pass a BASIC array to a C function. The C function would be separately compiled and then placed in a Quick library or linked to the BASIC main program. ' BASIC program passing an array to C function. DECLARE SUB AddArr CDECL (BYVAL Offs%, BYVAL Segm%, BYVAL Num%) DIM A(1 TO 100) AS INTEGER ' Fill the array with the numbers 1 to 15. FOR I=1 TO 15 A(I)=I NEXT I ' Call the C function. AddArr expects a far address (segment ' and offset). Because CDECL puts things on the stack from ' right to left, put the offset ( VARPTR(A(1)) ) first in the ' list, followed by the segment ( VARSEG(A(1)) ). CALL AddArr(VARPTR(A(1)),VARSEG(A(1)),15%) ' Print the modified array. FOR I=1 TO 15 PRINT A(I) NEXT I END /* Add one to the first num elements of array arr.*/ void far addarr(arr,num) int far *arr; int num; { int i; for(i=0;i A$(I) THEN Exchange=TRUE SWAP A$(I-1),A$(I) END IF NEXT WEND . . . ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WIDTH Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Assigns an output-line width to a file or device or changes the number of columns and lines displayed on the screen ž Syntax WIDTH ®columnsÆ®,linesÆ WIDTH {#filenumber | device},width WIDTH LPRINT width ž Remarks Both files and devices can be assigned an output-line width. The different forms of the WIDTH statement are explained in the following list: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Syntax Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WIDTH ®columnsÆ®,linesÆ Sets the number of columns and lines to display on the screen. The value of columns must be either 40 or 80. The default value is 80. The value of lines may be 25, 30, 43, 50, or 60, depending on both the display adapter used and the screen mode. The number of lines displayed when the program started will determine the default value. See the SCREEN statement for more information. WIDTH #filenumber, width Sets to width the line width of an output device opened as a file (for example, LPT1: or CONS:). The Syntax Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  example, LPT1: or CONS:). The filenumber argument is the number associated with the file in the OPEN statement. This form permits altering the width while a file is open, since the statement takes place immediately. WIDTH device,width Sets to width the line width of device (a device file name). The device should be a string expression (for example, "CONS:"). Note that this width assignment is deferred until the next OPEN statement affecting the device; the assignment does not affect output for an already open file. Syntax Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  an already open file. WIDTH LPRINT width Sets to width the line width of the line printer for use by subsequent LPRINT statements. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž See Also SCREEN Statement ž Example In the following example, the record width for file #1 (the lineprinter) is set to different widths: OPEN "LPT1:" FOR OUTPUT AS #1 Test$ = "1234567890" WIDTH #1, 3 PRINT #1, Test$ WIDTH #1, 4 PRINT #1, Test$ CLOSE ž Output 123 456 789 0 1234 5678 90 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WINDOW Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Defines the dimensions of the current viewport ž Syntax WINDOW ®®SCREENÆ (x1,y1)-(x2,y2)Æ ž Remarks The WINDOW statement allows the user to create a customized coordinate system to draw lines, graphs, or objects without being constrained by the screen's physical coordinates (the dimensions of the screen). This is done by redefining the screen-border coordinates with the "view coordinates" (x1, y1) and (x2, y2). These view coordinates are single-precision numbers. WINDOW defines the section of the view coordinate system that is mapped to the physical coordinates of the screen. All subsequent graphics statements use these new view coordinates and are displayed within the current viewport. (The size of the viewport can be changed with the VIEW statement.) Either the RUN statement or WINDOW with no arguments disables the window transformation. The WINDOW SCREEN variant inverts the normal Cartesian direction of the y-coordinate, so y values go from negative to positive from top to bottom. Figure R.1 shows the effects of WINDOW and WINDOW SCREEN on a line drawn in screen mode 2. Notice the change in the coordinates of the screen corners. ž Examples The following example illustrates two lines with the same end-point coordinates. The first is drawn on the default screen, and the second is on a redefined window. SCREEN 2 LINE (100,100) - (150,150), 1 LOCATE 2,20 : PRINT "The line on the default screen" WINDOW SCREEN (100,100) - (200,200) LINE (100,100) - (150,150), 1 LOCATE 8,18 : PRINT"& the same line on a redefined window" Increasing X ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³ ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³(0,0) (639,0)³ Increasing³ ³ ³ Y ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³(0,199) (639,199)³  ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ / \ / \ / \ WINDOW (-25,-15) / WINDOW SCREEN (-25,-15)-(5,10) LINE (-15,-10)-(-5,-5) LINE (-15,-10)-(-5,-5) / \ / \ / \ / \ Increas ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ³(-25,10) (5,10)³ ³ ŚÄÄÄÄÄÄÄÄÄÄÄÄÄ ³ ³ ³ ³ ³(-25,-15) Increasing³ ³ (0,0) ³ Increasing ³ ³ Y ³ ³ ³ Y ³ ³ ł\(-15, ³ ³ (-5,-5)ł ³ ³ ³ \ ³ ³ / ³ ³ ³ \ł ³ ³ / ³ ³ ³ ³ ³ (-15,-10)ł ³ ³ ³ ³ ³(-25,-15) (5,-15)³ ³ ³ ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ³ ³(-25,10) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ĄÄÄÄÄÄÄÄÄÄÄÄÄÄ Increasing X Figure R.1 WINDOW and WINDOW SCREEN The following example shows how changing the window size changes the size of a figure drawn on the screen. The effect is one of zooming in and out; as the window gets smaller, the figure appears larger on the screen, until parts of it are finally clipped because they lie outside the window. As the window gets larger, the figure appears smaller on the screen. PRINT "Press ENTER to start." INPUT;"",A$ SCREEN 1 : COLOR 7 'Grey screen. X = 500 : Xdelta = 50 DO DO WHILE X < 525 AND X > 50 X = X + Xdelta 'Change window size. CALL Zoom(X) FOR I = 1 TO 1000 'Delay loop. IF INKEY$ <> "" THEN END 'Stop if key pressed. NEXT LOOP X = X - Xdelta Xdelta = -Xdelta 'Reverse size change. LOOP SUB Zoom(X) STATIC CLS WINDOW (-X,-X)-(X,X) 'Define new window. LINE (-X,-X)-(X,X),1,B 'Draw window border. CIRCLE (0,0),60,1,,,.5 'Draw ellipse with x-radius 60. PAINT (0,0),1 'Paint ellipse. END SUB ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WRITE Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Sends data to the screen ž Syntax WRITE ®expressionlistÆ ž Remarks If expressionlist is omitted, a blank line is written. If expressionlist is included, the values of the expressions are written to the screen. The expressions in the list may be numeric and/or string expressions. They must be separated by commas. When the printed items are written, each item is separated from the last by a comma. Printed strings are delimited by quotation marks. After the last item in the list is printed, BASIC inserts a carriage-return and line-feed. The WRITE statement writes numeric values without leading or trailing spaces. ž See Also PRINT ž Example The following example shows the difference between the PRINT and WRITE statements: A=80 : B=90 : C$="That's all." : D=-1.0E-13 WRITE A,B,C$,D PRINT A,B,C$,D ž Output 80,90,"That's all.",-1E-13 80 90 That's all. -1E-13 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ WRITE # Statement ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ž Action Writes data to a sequential file ž Syntax WRITE #filenumber,expressionlist ž Remarks The filenumber is the number used in the OPEN statement. The file must be opened in OUTPUT or APPEND mode. The expressions in the argument expressionlist are string and/or numeric expressions, separated by commas. If you omit the expressionlist, the WRITE # statement writes a blank line to the file. The WRITE # statement, unlike the PRINT # statement, inserts commas between items as they are written to the file. You do not have to put explicit delimiters in the list. A new line is inserted once the last item in the list has been written to the file. If WRITE # attempts to write data to a sequential file restricted by a LOCK statement, an error message appears that reads Permission denied unless the error is trapped by the program. All of BASIC's usual error-handling routines can trap and examine this error. ž See Also LOCK, OPEN, PRINT #, WRITE ž Example The output from the following program illustrates the difference between the WRITE # and PRINT # statements: A$ = "VCR, remote control" : B$ = "$399.00" OPEN "PRICES" FOR OUTPUT AS #1 'Open PRICES for writing. PRINT #1,A$,B$ 'Store A$ and B$ in first record with PRINT #. WRITE #1,A$,B$ 'Store A$ and B$ in second record with WRITE #. CLOSE #1 ž Output VCR, remote control $399.00 "VCR, remote control","$399.00" ĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ Glossary CONTROL FLOW FOR...NEXT Repeats statements between FOR and NEXT a specific number of times. EXIT FOR alternative exit from FOR...NEXT DO...LOOP Repeats statements between DO and LOOP, while (until) a condition is(becomes) true. EXIT DO alternative exit from DO...LOOP WHILE...WEND Repeats statements between WHILE and WEND while a given condition is true. IF...THEN...ELSE... END IF Conditionally executes or branches todifferent statements. SELECT CASE Conditionally executes statements based on value of a variable. GOSUB...RETURN Transfers contol to a specific line in a module; control returns to the line following GOSUB. (Old style; SUB is a more powerful alternative.) RUN Restarts current program, or loads and runs another program. CHAIN "program" Passes execution to program specified, then returns. SLEEP Suspends program execution. WAIT Suspends program execution while monitoring status of a machine input port. PROCEDURES SUB...END SUB Mark the beginning and end of a SUBprocedure. EXIT SUB alternative exit from a SUB procedure FUNCTION... END FUNCTION Mark the beginning and end of aFUNCTION procedure. EXIT FUNCTION alternative exit from aFUNCTION procedure DEF FN...END DEF Mark the beginning and end of a DEF FN function. (Old style; FUNCTION is a more powerful alternative.) EXIT DEF alternative exit from aDEF FN function CALL, CALLS Transfers control to a BASIC SUB procedure, or a procedure written in another language and compiled separately. STANDARD I/O BEEP Makes the speaker beep. SOUND Makes a sound of specified frequency and duration. PRINT [USING] Outputs [formatted] text to the screen. WIDTH Sets screen width and number of lines. INKEY$ Reads a character from the keyboard. INP (n) Returns the value read from I/O port n. INPUT Reads string and/or numerical input from the keyboard and stores it in a list ofvariables. INPUT$ Reads characters from the keyboard into a string variable. LINE INPUT Reads an entire line (up to 255 chars) into a string variable. LOCATE Moves cursor to a specified screen row and column. SPC Skips spaces in printed output. TAB Skips to a specified display column. CSRLIN Returns row number of cursor. POS Returns line number of cursor. LPOS Returns position of line printer's print head within the printer buffer. VIEW PRINT Sets top and bottom rows for displaying print. LPRINT [USING] Prints [formatted] data on LPT1: printer. OPEN COMn: Opens and initializes a communications channel for I/O. OUT Sends a byte to a machine I/O port. PEN Returns the light pen coordinates. STICK Returns the x and y coordinates of the two joysticks. STRIG Returns the status of a specified joystick trigger (fire button). READ Returns values from a DATA statement and assigns them to variables. RESTORE Allows DATA statements to be reread from a specified line. FILE I/O OPEN Opens a file for reading or writing records. CLOSE Ends I/O operations to a file. RESET Closes all disk files. PRINT [USING] # Stores a [formatted] list of variables in a file. WRITE # Stores a list of variables as record fields in a file. FIELD Allocates space for variables in a random-access file buffer. WIDTH Specifies a standard length for each record in a file. PUT Stores contents of a variable in a file. INPUT # Reads fields from a record; assigns each to a variable. INPUT$ Reads a string of characters from a file. LINE INPUT # Reads a record and stores it in a string variable. GET Reads data from a file; assigns data to elements of a variable. FREEFILE Returns the next available file number. EOF Tests whether the end of a disk file has been reached. FILEATTR Returns a number indicating the mode in which a file was opened. LOC Gives the current position within a file. LOF Gives the number of bytes in an open file. SEEK (function) Gives the location where the next file I/O operation will occur. SEEK (statement) Sets the byte position for the next file I/O operation. IOCTL Transmits a control data string to a device driver. IOCTL$ Receives a control data string from a device driver. LOCK...UNLOCK Controls access by other processes to all or part of an open file. STRING PROCESSING LEFT$ Returns characters from the left side of the string. RIGHT$ Returns characters from the right side of the string. MID$ function Returns characters from anywhere in the string. MID$ statement Replaces part of a string with another string. LTRIM$ Strips leading blanks from string. RTRIM$ Strips trailing blanks from string. INSTR Searches for a string within another string. LCASE$ Converts a string to all lower-case letters. UCASE$ Converts a string to all upper-case letters. LSET Left-justifies a fixed-length string. RSET Right-justifies a fixed-length string. STR$ Returns the string representation of the decimal value of a numeric expression. HEX$ Returns the string representation of the hex value of a numeric expression. VAL Returns the numeric value of a stringexpression. SPACE$ Returns a string of blanks. STRING$ Returns a string of one repeatedcharacter. LEN Returns the number of characters in a string. ASC Returns the ASCII value of a character. CHR$ Returns the character with the given ASCII value. SADD Returns the address of the specifiedstring expression. GRAPHICS SCREEN Specifies a BASIC screen mode. PSET Sets a pixel to the foreground color. PRESET Sets a pixel to the background color. LINE Draws a straight line or a box. CIRCLE Draws a circle or an ellipse. DRAW Combines BASIC graphics features into a graphics macro language. WINDOW Sets the logical coordinates for a screen viewport. VIEW Specifies a viewport rectangle for graphics output. PMAP Maps pixel physical coordinates to logical coordinates. POINT Returns physical or logical coordinates of cursor, or color number of pixel. COLOR Sets default colors for graphics output. PALETTE Assigns colors to color numbers. PAINT Fills an area with color or a pattern. GET Saves a rectangular area of graphics screen in memory. PUT Displays graphics stored by GET. PCOPY Copies one screen storage page to another. ERROR AND EVENT TRAPPING ON ERROR GOTO line Program branches to line number or line label when error occurs. RESUME Returns control after executing error-handling routine. ERR Returns code for run-time error. ERL Returns line number on which erroroccurred. ERDEV Returns code for last device which caused an error. ERDEV$ Returns name of last device which caused an error. ERROR Simulates occurrence of a BASIC error. ON event GOSUB line Branches to routine labelled with line, whenever event occurs. event ON Enables trapping of event. event OFF ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Appendix A Keyboard Scan Codes and ASCII Character Codes A.1 Keyboard Scan Codes A.2 ASCII Character Codes A.1 Keyboard Scan Codes The table on the next page shows the DOS keyboard scan codes. These codes are returned by the INKEY$ function. Key combinations with NUL in the Char column return two bytesÄÄa null byte (&H00) followed by the value listed in the Dec and Hex columns. For example, pressing ALT+F1 returns a null byte followed by a byte containing 104 (&H68). ŚÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄĀÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ³ ³ ³ ³ASCII or ³ASCII or ³ ASCII or ³ ³ ³Scan ³ ASCII or ³Extended ³Extended ³ Extended ³ ³ Key ³Code ³ Extended ³with SHIFT ³with CTRL ³ with ALT ³ ĆÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³Dec Hex³Dec Hex Char³Dec Hex Char ³Dec Hex Char ³ Dec Hex Char ³ ĆÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ESC ³ 1 01 ³ 27 1B ³ 27 1B ³ 27 1B ³ ³ ³1! ³ 2 02 ³ 49 31 1 ³ 33 21 ! ³ ³ 120 78 NUL ³ ³2@ ³ 3 03 ³ 50 32 2 ³ 64 40 @ ³ 3 03 NUL ³ 121 79 NUL ³ ³3# ³ 4 04 ³ 51 33 3 ³ 35 23 # ³ ³ 122 7A NUL ³ ³4$ ³ 5 05 ³ 52 34 4 ³ 36 24 $ ³ ³ 123 7B NUL ³ ³5% ³ 6 06 ³ 53 35 5 ³ 37 25 % ³ ³ 124 7C NUL ³ ³6^ ³ 7 07 ³ 54 36 6 ³ 94 5E ^ ³ 30 IE ³ 125 7D NUL ³ ³7& ³ 8 08 ³ 55 37 7 ³ 38 26 & ³ ³ 126 7E NUL ³ ³8* ³ 9 09 ³ 56 38 8 ³ 42 2A * ³ ³ 127 7F NUL ³ ³9( ³10 0A ³ 57 39 9 ³ 40 28 ( ³ ³ 128 80 NUL ³ ³0) ³11 0B ³ 48 30 0 ³ 41 29 ) ³ ³ 129 81 NUL ³ ³-_ ³12 0C ³ 45 2D - ³ 95 5F - ³ 31 IF ³ 130 82 NUL ³ ³=+ ³13 0D ³ 61 3D = ³ 43 2B + ³ ³ 131 83 NUL ³ ³BKSP ³14 0E ³ 8 08 ³ 8 08 ³127 7F ³ ³ ³TAB ³15 0F ³ 9 09 ³ 15 OF NUL³ ³ ³ ³Q ³16 10 ³113 71 q ³ 81 51 Q ³ 17 11 ³ 16 10 NUL ³ ³W ³17 11 ³119 77 w ³ 87 57 W ³ 23 17 ³ 17 11 NUL ³ ³E ³18 12 ³101 65 e ³ 69 45 E ³ 5 05 ³ 18 12 NUL ³ ³R ³19 13³114 72 r ³ 82 52 R ³ 18 12 ³ 19 13 NUL ³ ³T ³20 14³116 74 t ³ 84 54 T ³ 20 14 ³ 20 14 NUL ³ ³Y ³21 15³121 79 y ³ 89 59 Y ³ 25 19 ³ 21 15 NUL ³ ³U ³22 16³117 75 u ³ 85 55 U ³ 21 15 ³ 22 16 NUL ³ ³I ³23 17³105 69 i ³ 73 49 I ³ 9 09 ³ 23 17 NUL ³ ³O ³24 18³111 6F o ³ 79 4F O ³ 15 0F ³ 24 18 NUL ³ ³P ³25 19³112 70 p ³ 80 50 P ³ 16 10 ³ 25 19 NUL ³ ³[{ ³26 1A³ 91 5B [ ³123 7B { ³ 27 1B ³ ³ ³]} ³27 1B³ 93 5D ] ³125 7D } ³ 29 1D ³ ³ ³ENTER ³28 1C³ 13 OD CR³ 13 OD CR ³ 10 OA LF ³ ³ ³CTRL ³29 1D³ ³ ³ ³ ³ ³A ³30 1E³ 97 61 a ³ 65 41 A ³ 1 01 ³ 30 1E NUL ³ ³S ³31 1F³115 73 s ³ 83 53 S ³ 19 13 ³ 31 1F NUL ³ ³D ³32 20³100 64 d ³ 68 44 D ³ 4 04 ³ 32 20 NUL ³ ³F ³33 21³102 66 f ³ 70 46 F ³ 6 06 ³ 33 21 NUL ³ ³G ³34 22³103 67 g ³ 71 47 G ³ 7 07 ³ 34 22 NUL ³ ³H ³35 23³104 68 h ³ 72 48 H ³ 8 08 ³ 35 23 NUL ³ ³J ³36 24³106 6A j ³ 74 4A J ³ 10 0A ³ 36 24 NUL ³ ³K ³37 25³107 6B k ³ 75 4B K ³ 11 0B ³ 37 25 NUL ³ ³L ³38 26³108 6C l ³ 76 4C L ³ 12 0C ³ 38 26 NUL ³ ³;: ³39 27³ 59 3B ; ³ 58 3A : ³ ³ ³ ³'" ³40 28³ 39 27 ' ³ 34 22 " ³ ³ ³ ³`~ ³41 29³ 96 60 ` ³126 7E ~ ³ ³ ³ ³L SHIFT ³42 2A³ ³ ³ ³ ³ ³\| ³43 2B³ 92 5C \ ³124 7C | ³ 28 1C ³ ³ ³Z ³44 2C ³122 7A z ³ 90 5A Z ³ 26 1A ³ 44 2C NUL ³ ³X ³45 2D ³120 78 x ³ 88 58 X ³ 24 18 ³ 45 2D NUL ³ ³C ³46 2E ³ 99 63 c ³ 67 43 C ³ 3 03 ³ 46 2E NUL ³ ³V ³47 2F ³118 76 v ³ 86 56 V ³ 22 16 ³ 47 2F NUL ³ ³B ³48 30 ³ 98 62 b ³ 66 42 B ³ 2 OE ³ 48 30 NUL ³ ³N ³49 31 ³110 6E n ³ 78 4E N ³ 14 OD ³ 49 31 NUL ³ ³M ³50 32 ³109 6D m ³ 77 4D M ³ 13 ³ 50 32 NUL ³ ³,< ³51 33 ³ 44 2C ' ³ 60 3C < ³ ³ ³ ³.> ³52 34 ³ 46 2E . ³ 62 3E > ³ ³ ³ ³/? ³53 35 ³ 47 2F / ³ 63 3F ? ³ ³ ³ ³R SHIFT ³54 36 ³ ³ ³ ³ ³ ³* PRTSC ³55 37 ³ 42 2A * ³ INT 5 ³ 16 10 ³ ³ ³ALT ³56 38 ³ ³ ³ ³ ³ ³SPACE ³57 39 ³ 32 20 SPC³ 32 20 SPC³ 32 20 SPC ³ 32 20 SPC ³ ³CAPS ³58 3A ³ ³ ³ ³ ³ ³F1 ³59 3B ³ 59 3B NUL³ 84 54 NUL³ 94 5E NUL ³ 104 68 NUL ³ ³F2 ³60 3C ³ 60 3C NUL³ 85 55 NUL³ 95 5F NUL ³ 105 69 NUL ³ ³F3 ³61 3D ³ 61 3D NUL³ 86 56 NUL³ 96 60 NUL ³ 106 6A NUL ³ ³F4 ³62 3E ³ 62 3E NUL³ 87 57 NUL³ 97 61 NUL ³ 107 6B NUL ³ ³F5 ³63 3F ³ 63 3F NUL³ 88 58 NUL³ 98 62 NUL ³ 108 6C NUL ³ ³F6 ³64 40 ³ 64 40 NUL³ 89 59 NUL³ 99 63 NUL ³ 109 6D NUL ³ ³F7 ³65 41 ³ 65 41 NUL³ 90 5A NUL³100 64 NUL ³ 110 6E NUL ³ ³F8 ³66 42 ³ 66 46 NUL³ 91 5B NUL³101 65 NUL ³ 111 6F NUL ³ ³F9 ³67 43 ³ 67 43 NUL³ 92 5C NUL³102 66 NUL ³ 112 70 NUL ³ ³F10 ³68 44 ³ 68 44 NUL³ 93 5D NUL³103 67 NUL ³ 113 71 NUL ³ ³NUM ³69 45 ³ ³ ³ ³ ³ ³SCROLL ³70 46 ³ ³ ³ ³ ³ ³HOME ³71 47 ³ 71 47 NUL ³ 55 37 7 ³119 77 NUL ³ ³ ³UP ³72 48 ³ 72 48 NUL ³ 56 38 8 ³ ³ ³ ³PGUP ³73 49 ³ 73 49 NUL ³ 57 39 9 ³132 84 NUL ³ ³ ³GREY- ³74 4A ³ 45 2D - ³ 45 2D - ³ ³ ³ ³LEFT ³75 4B ³ 75 4B NUL ³ 52 34 4 ³115 73 NUL ³ ³ ³CENTER ³76 4C ³ ³ 53 35 5 ³ ³ ³ ³RIGHT ³77 4D ³ 77 4D NUL ³ 54 36 6 ³116 74 NUL ³ ³ ³GREY+ ³78 4E ³ 43 2B + ³ 43 2b + ³ ³ ³ ³END ³79 4F ³ 79 4F NUL ³ 49 31 1 ³117 75 NUL ³ ³ ³DOWN ³80 50 ³ 80 50 NUL ³ 50 32 2 ³ ³ ³ ³PGDN ³81 51 ³ 81 51 NUL ³ 51 33 3 ³118 76 NUL ³ ³ ³INS ³82 52 ³ 82 52 NUL ³ 48 30 0 ³ ³ ³ ³DEL ³83 53 ³ 83 53 NUL ³ 46 2E . ³ ³ ³ ĄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄĮÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ³Ctrl Dec Hex Char Code³ ³Dec Hex Char³ ³Dec Hex Char³ ³Dec Hex Char³ ĆÄÄÄÄĀÄÄÄĀÄÄÄĀÄÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ³ ^@ ³ 0³00 ³ ³ NUL³ ³ 32³ 20³ ³ ³ 64³40 ³ @ ³ ³ 96³60 ³ ` ³ ³ ^A ³ 1³01 ³  ³ SOH³ ³ 33³ 21³ ! ³ ³ 65³41 ³ A ³ ³ 97³61 ³ a ³ ³ ^B ³ 2³02 ³  ³ STX³ ³ 34³ 22³ " ³ ³ 66³42 ³ B ³ ³ 98³62 ³ b ³ ³ ^C ³ 3³03 ³  ³ ETX³ ³ 35³ 23³ # ³ ³ 67³43 ³ C ³ ³ 99³63 ³ c ³ ³ ^D ³ 4³04 ³  ³ EOT³ ³ 36³ 24³ $ ³ ³ 68³44 ³ D ³ ³100³64 ³ d ³ ³ ^E ³ 5³05 ³  ³ ENQ³ ³ 37³ 25³ % ³ ³ 69³45 ³ E ³ ³101³65 ³ e ³ ³ ^F ³ 6³06 ³  ³ ACK³ ³ 38³ 26³ & ³ ³ 70³46 ³ F ³ ³102³66 ³ f ³ ³ ^G ³ 7³07 ³  ³ BEL³ ³ 39³ 27³ ' ³ ³ 71³47 ³ G ³ ³103³67 ³ g ³ ³ ^H ³ 8³08 ³  ³ BS ³ ³ 40³ 28³ ( ³ ³ 72³48 ³ H ³ ³104³68 ³ h ³ ³ ^I ³ 9³09 ³ ³ HT ³ ³ 41³ 29³ ) ³ ³ 73³49 ³ I ³ ³105³69 ³ i ³ ³ ^J ³ 10³0A ³ ³ LF ³ ³ 42³ 2A³ * ³ ³ 74³4A ³ J ³ ³106³6A ³ j ³ ³ ^K ³ 11³0B ³ ³ VT ³ ³ 43³ 2B³ + ³ ³ 75³4B ³ K ³ ³107³6B ³ k ³ ³ ^L ³ 12³0C ³ ³ FF ³ ³ 44³ 2C³ , ³ ³ 76³4C ³ L ³ ³108³6C ³ l ³ ³ ^M ³ 13³0D ³ ³ CR ³ ³ 45³ 2D³ - ³ ³ 77³4D ³ M ³ ³109³6D ³ m ³ ³ ^N ³ 14³0E ³  ³ SO ³ ³ 46³ 2E³ . ³ ³ 78³4E ³ N ³ ³110³6E ³ n ³ ³ ^O ³ 15³0F ³ ³ SI ³ ³ 47³ 2F³ / ³ ³ 79³4F ³ O ³ ³111³6F ³ o ³ ³ ^P ³ 16³10 ³  ³ DLE³ ³ 48³ 30³ 0 ³ ³ 80³50 ³ P ³ ³112³70 ³ p ³ ³ ^Q ³ 17³11 ³  ³ DC1³ ³ 49³ 31³ 1 ³ ³ 81³51 ³ Q ³ ³113³71 ³ q ³ ³ ^R ³ 18³12 ³  ³ DC2³ ³ 50³ 32³ 2 ³ ³ 82³52 ³ R ³ ³114³72 ³ r ³ ³ ^S ³ 19³13 ³  ³ DC3³ ³ 51³ 33³ 3 ³ ³ 83³53 ³ S ³ ³115³73 ³ s ³ ³ ^T ³ 20³14 ³  ³ DC4³ ³ 52³ 34³ 4 ³ ³ 84³54 ³ T ³ ³116³74 ³ t ³ ³ ^U ³ 21³15 ³  ³ NAK³ ³ 53³ 35³ 5 ³ ³ 85³55 ³ U ³ ³117³75 ³ u ³ ³ ^V ³ 22³ 16³  ³ SYN³ ³ 54³ 36³ 6 ³ ³ 86³ 56³ V ³ ³118³ 76³ v ³ ³ ^W ³ 23³ 17³  ³ ETB³ ³ 55³ 37³ 7 ³ ³ 87³ 57³ W ³ ³119³ 77³ w ³ ³ ^X ³ 24³ 18³  ³ CAN³ ³ 56³ 38³ 8 ³ ³ 88³ 58³ X ³ ³120³ 78³ x ³ ³ ^Y ³ 25³ 19³  ³ EM ³ ³ 57³ 39³ 9 ³ ³ 89³ 59³ Y ³ ³121³ 79³ y ³ ³ ^Z ³ 26³ 1A³ ³ SUB³ ³ 58³ 3A³ : ³ ³ 90³ 5A³ Z ³ ³122³ 7A³ z ³ ³ ^[ ³ 27³ 1B³  ³ ESC³ ³ 59³ 3B³ ; ³ ³ 91³ 5B³ [ ³ ³123³ 7B³ { ³ ³ ^\ ³ 28³ 1C³  ³ FS ³ ³ 60³ 3C³ < ³ ³ 92³ 5C³ \ ³ ³124³ 7C³ | ³ ³ ^} ³ 29³ 1D³  ³ GS ³ ³ 61³ 3D³ = ³ ³ 93³ 5D³ ] ³ ³125³ 7D³ } ³ ³ ^^ ³ 30³ 1E³  ³ RS ³ ³ 62³ 3E³ > ³ ³ 94³ 5E³ ^ ³ ³126³ 7E³ ~ ³ ³ ^_ ³ 31³ 1F³  ³ US ³ ³ 63³ 3F³ ? ³ ³ 95³ 5F³ _ ³ ³127³ 7F³ ³ ĄÄÄÄÄĮÄÄÄĮÄÄÄĮÄÄÄÄĮÄÄÄÄŁ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ŚÄÄÄÄÄÄÄÄÄÄÄÄæ ³Dec Hex Char³ ³Dec Hex Char³ ³Dec Hex Char³ ³Dec Hex Char³ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ĆÄÄÄĀÄÄÄĀÄÄÄÄ´ ³128³ 80³ € ³ ³160³ A0³   ³ ³192³ C0³ Ą ³ ³224³ E0³ ą ³ ³129³ 81³ ³ ³161³ A1³ ³ ³193³ C1³ Į ³ ³225³ E1³ į ³ ³130³ 82³ ‚ ³ ³162³ A2³ ¢ ³ ³194³ C2³ Ā ³ ³226³ E2³ ā ³ ³131³ 83³ ³ ³163³ A3³ £ ³ ³195³ C3³ Ć ³ ³227³ E3³ ć ³ ³132³ 84³ „ ³ ³164³ A4³ ¤ ³ ³196³ C4³ Ä ³ ³228³ E4³ ä ³ ³133³ 85³ … ³ ³165³ A5³ ³ ³197³ C5³ Å ³ ³229³ E5³ å ³ ³134³ 86³ † ³ ³166³ A6³ ¦ ³ ³198³ C6³ Ę ³ ³230³ E6³ ę ³ ³135³ 87³ ‡ ³ ³167³ A7³ § ³ ³199³ C7³ Ē ³ ³231³ E7³ ē ³ ³136³ 88³ ³ ³168³ A8³ Ø ³ ³200³ C8³ Č ³ ³232³ E8³ č ³ ³137³ 89³ ‰ ³ ³169³ A9³ © ³ ³201³ C9³ É ³ ³233³ E9³ é ³ ³138³ 90³ ³ ³170³ AA³ Ŗ ³ ³202³ CA³ Ź ³ ³234³ EA³ ź ³ ³139³ 91³ ‹ ³ ³171³ AB³ « ³ ³203³ CB³ Ė ³ ³235³ EB³ ė ³ ³140³ 92³ ³ ³172³ AC³ ¬ ³ ³204³ CC³ Ģ ³ ³236³ EC³ ģ ³ ³141³ 93³ ¨ ³ ³173³ AD³ ­ ³ ³205³ CD³ Ķ ³ ³237³ ED³ ķ ³ ³142³ 94³ ˇ ³ ³174³ AE³ ® ³ ³206³ CE³ Ī ³ ³238³ EE³ ī ³ ³143³ 95³ ¸ ³ ³175³ AF³ Æ ³ ³207³ CF³ Ļ ³ ³239³ EF³ ļ ³ ³144³ 96³ ³ ³176³ B0³ ° ³ ³208³ D0³ Š ³ ³240³ F0³ š ³ ³145³ 97³ ‘ ³ ³177³ B1³ ± ³ ³209³ D1³ Ń ³ ³241³ F1³ ń ³ ³146³ 98³ ’ ³ ³178³ B2³ ² ³ ³210³ D2³ Ņ ³ ³242³ F2³ ņ ³ ³147³ 99³ “ ³ ³179³ B3³ ³ ³ ³211³ D3³ Ó ³ ³243³ F3³ ó ³ ³148³ 9A³ ” ³ ³180³ B4³ ´ ³ ³212³ D4³ Ō ³ ³244³ F4³ ō ³ ³149³ 9B³ • ³ ³181³ B5³ µ ³ ³213³ D5³ Õ ³ ³245³ F5³ õ ³ ³150³ 96³ – ³ ³182³ B6³ ¶ ³ ³214³ D6³ Ö ³ ³246³ F6³ ö ³ ³151³ 97³ — ³ ³183³ B7³ · ³ ³215³ D7³ × ³ ³247³ F7³ ÷ ³ ³152³ 98³ ³ ³184³ B8³ ø ³ ³216³ D8³ Ų ³ ³248³ F8³ ų ³ ³153³ 99³ ™ ³ ³185³ B9³ ¹ ³ ³217³ D9³ ÷ ³ ³249³ F9³ ł ³ ³154³ 9A³ ³ ³186³ BA³ ŗ ³ ³218³ DA³ Ś ³ ³250³ FA³ ś ³ ³155³ 9B³ › ³ ³187³ BB³ » ³ ³219³ DB³ Ū ³ ³251³ FB³ ū ³ ³156³ 9C³ ³ ³188³ BC³ ¼ ³ ³220³ DC³ Ü ³ ³252³ FC³ ü ³ ³157³ 9D³ ¯ ³ ³189³ BD³ ½ ³ ³221³ DD³ Ż ³ ³253³ FD³ ż ³ ³158³ 9E³ ˛ ³ ³190³ BE³ ¾ ³ ³222³ DE³ Ž ³ ³254³ FE³ ž ³ ³159³ 9F³ ³ ³191³ BF³ æ ³ ³223³ DF³ ß ³ ³255³ FF³ ˙ ³ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ ĄÄÄÄĮÄÄÄĮÄĮÄÄŁ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ ĄÄÄÄĮÄÄÄĮÄÄÄÄŁ A.2 ASCII Character Codes ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 00H NUL (Null)  1 01H SOH (Start of heading)  2 02H STX (Start of text)  3 03H ETX (End of text)  4 04H EOT (End of transmission)  5 05H ENQ (Enquiry)  6 06H ACK (Acknowledge)  7 07H BEL (Bell) Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ   7 07H BEL (Bell)  8 08H BS (Backspace) 9 09H HT (Horizontal tab) 10 0AH LF (Linefeed) 11 0BH VT (Vertical tab) 12 0CH FF (Formfeed) 13 0DH CR (Carriage return)  14 EH SO (Shift out) 15 0FH SI (Shift in)  16 10H DLE (Data link escape)  17 11H DC1 (Device control 1)  18 12H DC2 (Device control 2)  19 13H DC3 (Device control 3)  20 14H DC4 (Device control 4)  21 15H NAK (Negative acknowledge)  22 16H SYN (Synchronous idle)  23 17H ETB (End transmission block)  24 18H CAN (Cancel) Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ   24 18H CAN (Cancel)  25 19H EM (End of medium) 26 1AH SUB (Substitute)  27 1BH ESC (Escape)  28 1CH FS (File separator)  29 1DH GS (Group separator)  30 1EH RS (Record separator)  31 1FH US (Unit separator) 32 20H ! 33 21H " 34 22H # 35 23H $ 36 24H % 37 25H & 38 26H ' 39 27H ( 40 28H ) 41 29H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ) 41 29H * 42 2AH + 43 2BH , 44 2CH - 45 2DH . 46 2EH / 47 2FH 0 48 30H 1 49 31H 2 50 32H 3 51 33H 4 52 34H 5 53 35H 6 54 36H 7 55 37H 8 56 38H 9 57 39H : 58 3AH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  : 58 3AH ; 59 3BH < 60 3CH = 61 3DH > 62 3EH ? 63 3FH @ 64 40H A 65 41H B 66 42H C 67 43H D 68 44H E 69 45H F 70 46H G 71 47H H 72 48H I 73 49H J 74 4AH K 75 4BH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  K 75 4BH L 76 4CH M 77 4DH N 78 4EH O 79 4FH P 80 50H Q 81 51H R 82 52H S 83 53H T 84 54H U 85 55H V 86 56H W 87 57H X 88 58H Y 89 59H Z 90 5AH [ 91 5BH \ 92 5CH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  \ 92 5CH ] 93 5DH ^ 94 5EH _ 95 5FH g 96 60H a 97 61H b 98 62H c 99 63H d 100 64H e 101 65H f 102 66H g 103 67H h 104 68H i 105 69H j 106 6AH k 107 6BH l 108 6CH m 109 6DH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  m 109 6DH n 110 6EH o 111 6FH p 112 70H q 113 71H r 114 72H s 115 73H t 116 74H u 117 75H v 118 76H w 119 77H x 120 78H y 121 79H z 122 7AH { 123 7BH | 124 7CH } 125 7DH ~ 126 7EH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ~ 126 7EH 127 7FH DEL (Delete) € 128 80H 129 81H ‚ 130 82H 131 83H „ 132 84H … 133 85H † 134 86H ‡ 135 87H 136 88H ‰ 137 89H 138 8AH ‹ 139 8BH 140 8CH ¨ 141 8DH ˇ 142 8EH ¸ 143 8FH Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ¸ 143 8FH 144 90H ‘ 145 91H ’ 146 92H “ 147 93H ” 148 94H • 149 95H – 150 96H — 151 97H 152 98H ™ 153 99H 154 9AH › 155 9BH 156 9CH ¯ 157 9DH ˛ 158 9EH 159 9FH   160 A0H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ    160 A0H 161 A1H ¢ 162 A2H £ 163 A3H ¤ 164 A4H 165 A5H ¦ 166 A6H § 167 A7H Ø 168 A8H © 169 A9H Ŗ 170 AAH « 171 ABH ¬ 172 ACH ­ 173 ADH ® 174 AEH Æ 175 AFH ° 176 B0H ± 177 B1H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ± 177 B1H ² 178 B2H ³ 179 B3H ´ 180 B4H µ 181 B5H ¶ 182 B6H · 183 B7H ø 184 B8H ¹ 185 B9H ŗ 186 BAH » 187 BBH ¼ 188 BCH ½ 189 BDH ¾ 190 BEH æ 191 BFH Ą 192 C0H Į 193 C1H Ā 194 C2H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Ā 194 C2H Ć 195 C3H Ä 196 C4H Å 197 C5H Ę 198 C6H Ē 199 C7H Č 200 C8H É 201 C9H Ź 202 CAH Ė 203 CBH Ģ 204 CCH Ķ 205 CDH Ī 206 CEH Ļ 207 CFH Š 208 D0H Ń 209 D1H Ņ 210 D2H Ó 211 D3H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  Ó 211 D3H Ō 212 D4H Õ 213 D5H Ö 214 D6H × 215 D7H Ų 216 D8H Ł 217 D9H Ś 218 DAH Ū 219 DBH Ü 220 DCH Ż 221 DDH Ž 222 DEH ß 223 DFH 224 E0H į 225 E1H ā 226 E2H ć 227 E3H ä 228 E4H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ä 228 E4H å 229 E5H ę 230 E6H ē 231 E7H č 232 E8H é 233 E9H ź 234 EAH ė 235 EBH ģ 236 ECH ķ 237 EDH ī 238 EEH ļ 239 EFH š 240 F0H ń 241 F1H ņ 242 F2H ó 243 F3H ō 244 F4H õ 245 F5H Number Char Dec Hex Control ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  õ 245 F5H ö 246 F6H ÷ 247 F7H ų 248 F8H ł 249 F9H ś 250 FAH ū 251 FBH ü 252 FCH ż 253 FDH ž 254 FEH ˙ 255 FFH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Appendix B Error Messages B.1 Error-Message Display B.2 Invocation, Compile-Time, and Run-Time Error Messages B.3 LINK Error Messages B.4 LIB Error Messages During development of a BASIC program with QuickBASIC, the following types of errors can occur: ž Invocation errors ž Compile-time errors ž Link-time errors ž Run-time errors Each type of error is associated with a particular step in the program development process. Invocation errors occur when you invoke QuickBASIC with the QB or BC commands. Compile-time errors (and warnings) occur during compilation, and run-time errors occur when the program is executing. Link-time errors occur only when you use the LINK command to link object files created with BC or other language compilers. Section B.2 lists alphabetically the invocation, compile-time, and run-time error messages, along with any error codes that are assigned. Table B.1 lists the run-time error messages and error codes in numerical order. Section B.3 lists the Microsoft Overlay Linker error messages, and Section B.4, the Microsoft Library Manager error messages. B.1 Error-Message Display When a run-time error occurs within the QuickBASIC environment (with default screen options), the error message appears in a dialog box and the cursor is placed on the line where the error occurred. In stand-alone executable programs (that is, programs that are executed by entering the base name of the executable file at the system prompt), the run-time system prints the error messages followed by an address, unless the /D, /E, or /W option is specified on the BC command line. In those cases, the error message is followed by the number of the line in which the error occurred. The standard forms of this type of error message are as follows: Error n in module module-name at address segment:offset and Error n in line linenumber of module module-name at address segment:offset An ERR code is listed for some errors. If an error occurs, the value returned by ERR is set to the appropriate code when an error-trapping subroutine is entered. (Error-trapping routines are entered via the ON ERROR statement.) The ERR value remains unchanged until a RESUME statement returns control to the main program. See Chapter 6, "Error and Event Trapping," in Programming in BASIC for more information. Table B.1 lists the error codes in numerical order. See the alphabetical listing for explanations of the errors. Table B.1 Run-Time Error Codes ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Code Description Code Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 2 Syntax error 53 File not found 3 RETURN without GOSUB 54 Bad file mode 4 Out of DATA 55 File already open 5 Illegal function call 56 FIELD statement active 6 Overflow 57 Device I/O error 7 Out of memory 58 File already exists 9 Subscript out of range 59 Bad record length 10 Duplicate definition 61 Disk full 11 Division by zero 62 Input past end of file Code Description Code Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  13 Type mismatch 63 Bad record number 14 Out of string space 64 Bad file name 16 String formula too 67 Too many files complex 19 No RESUME 68 Device unavailable 20 RESUME without error 69 Communication-buffer overflow 24 Device timeout 70 Permission denied 25 Device fault 71 Disk not ready 27 Out of paper 72 Disk-media error Code Description Code Description ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  39 CASE ELSE expected 73 Advanced feature unavailable 40 Variable required 74 Rename across disks 50 FIELD overflow 75 Path/File access error 51 Internal error 76 Path not found 52 Bad file name or number ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ QYInvocation Error B.2 Invocation, Compile-Time, and Run-Time Error Messages Advanced feature unavailable You are attempting to use a feature of QuickBASIC that is available with another version of BASIC, or supported only under a later version of DOS. (Compile-time or run-time error) ERR code: 73 Argument-count mismatch You are using an incorrect number of arguments with a BASIC subprogram or function. (Compile-time error) Array already dimensioned This error can be caused by any of the following: ž More than one DIM statement for the same static array. ž A DIM statement after the initial use of an array. Dynamic arrays must be deallocated with the ERASE statement before they can be redimensioned with DIM; dynamic arrays may also be redimensioned with the REDIM statement. ž An OPTION BASE statement that occurs after an array is dimensioned. (Compile-time or run-time error) Array not defined An array is referenced but never defined. (Compile-time error) Array not dimensioned An array is referenced but not dimensioned. If you are compiling the program with BC, this error is not "fatal"; the program will execute, although program results may be incorrect. (Compile-time warning) Array too big There is not enough user data space to accommodate the array declaration. Reduce the size of the array or use the ›DYNAMIC metacommand. You may also get this error if the array size exceeds 64K, the array is not dynamic, and the /AH option is not used. Reduce the size of the array, or make the array dynamic and use the /AH command-line option. (Compile-time error) AS clause required A variable declared with an AS clause is referenced without one. If the first declaration of a variable has an AS clause, every subsequent DIM, REDIM, SHARED, and COMMON statement that references that variable must have an AS clause. (Compile-time error) AS clause required on first declaration A variable that has not been declared using an AS clause is being referenced with an AS clause. (Compile-time error) AS missing The compiler expects an AS keyword, as in OPEN "FILENAME" FOR INPUT AS #1. (Compile-time error) Asterisk missing The asterisk is missing from a string definition in a user type. (Compile-time error) Bad file mode This error occurs in the following situations: ž The program tries to use PUT or GET with a sequential file or execute an OPEN statement with a file mode other than I, O, or R. ž The program tries to use a FIELD statement with a file not opened for random access. ž The program tries to print to a file opened for input. ž The program tries to read from a file opened for output or appending. ž QuickBASIC tries to use an include file previously saved in compressed format. Include files must be saved in text format. Reload the include file, save it in text format, then try to run the program again. ž You try to load a corrupt binary program. (Run-time error) ERR code: 54 Bad file name An illegal form is used for the file name with LOAD, SAVE, KILL, or OPEN (for example, the file name has too many characters). (Run-time error) ERR code: 64 Bad file name or number A statement or command references a file with a file name or number that is not specified in the OPEN statement or is out of the range of file numbers specified earlier in the program. (Run-time error) ERR code: 52 Bad record length A GET or PUT statement that specified a record variable whose length did not match the record length specified in the corresponding OPEN statement was executed. (Run-time error) ERR code: 59 Bad record number In a PUT or GET statement, the record number is less than or equal to zero. (Run-time error) ERR code: 63 BASE missing QuickBASIC expected the keyword BASE here, as in OPTION BASE. (Compile-time error) Binary source file The file you have attempted to compile is not an ASCII file. All source files saved by BASICA should be saved with the ,A option. QuickBASIC also uses this message to warn you when you try to use the /ZI or /ZD CodeView options with binary source files. (Compile-time error) Block IF without END IF There is no corresponding END IF in a block IF construct. (Compile-time error) Buffer size expected after /C: You must specify a buffer size after the /C option. (BC invocation error) BYVAL allowed only with numeric arguments BYVAL does not accept string or record arguments. (Compile-time error) /C: buffer size too large The maximum size of the communications buffer is 32,767 bytes. (BC invocation error) Cannot continue While debugging, you have made a change that prevents execution from continuing. (Run-time error) Cannot find file (filename). Input path: This error occurs when QuickBASIC cannot find a Quick library or utility (BC.EXE, LINK.EXE, LIB.EXE, or QB.EXE) required by the program. Enter the correct path name, or press CTRL+C to return to the DOS prompt. (QB invocation error) Cannot generate listing for BASIC binary source files You are attempting to compile a binary source file with the BC command and the /A option. Recompile without the /A option. (BC invocation error) Cannot start with `FN' You used "FN" as the first two letters of a subprogram or variable name. "FN" can only be used as the first two letters when calling a DEF FN function. (Compile-time error) CASE ELSE expected No matching case was found for an expression in a SELECT CASE statement. (Run-time error) ERR code: 39 CASE without SELECT The first part of a SELECT CASE statement is missing or misspelled. (Compile-time error) Colon expected after /C A colon is required between the option and the buffer size argument. (BC invocation error) Comma missing QuickBASIC expects a comma. (Compile-time error) COMMON and DECLARE must precede executable statements A COMMON statement or a DECLARE statement is misplaced. COMMON and DECLARE statements must appear before any executable statements. All BASIC statements are executable except the following: ž COMMON ž DEFtype ž DIM (for static arrays) ž OPTION BASE ž REM ž TYPE ž All metacommands (Compile-time error) COMMON in Quick library too small More common variables are specified in the module than in the currently loaded Quick library. (Compile-time error) COMMON name illegal QuickBASIC encountered an illegal /blockname/ specification (for example, a blockname that is a BASIC reserved word) in a named COMMON block. (Compile-time error). Communication-buffer overflow During remote communications, the receive buffer overflowed. The size of the receive buffer is set by the /C command line option or the RB option in the OPEN COM statement. Try checking the buffer more frequently (with the LOC function) or emptying it more often (with the INPUT$ function). (Run-time error) ERR code: 69 CONST/DIM SHARED follows SUB/FUNCTION CONST and DIM SHARED statements should appear before any subprogram or FUNCTION procedure definitions. If you are compiling your program with BC, this error is not "fatal"; the program will execute, although the results may be incorrect. (Compile-time warning) Control structure in IF...THEN...ELSE incomplete An unmatched NEXT, WEND, END IF, END SELECT, or LOOP statement appears in a single-line IF...THEN...ELSE statement. (Compile-time error) Data-memory overflow There is too much program data to fit in memory. This error is often caused by too many constants, or too much static array data. If you are using the BC command, or the Make EXE File or Make Library commands, try turning off any debugging options. If memory is still exhausted, break your program into parts and use the CHAIN statement or use the ›DYNAMIC metacommand. (Compile-time error) DECLARE required An implicit SUB or FUNCTION procedure call appears before the procedure definition. (An implicit call does not use the CALL statement.) All procedures must be defined or declared before they are implicitly called. (Compile-time error) DEF FN not allowed in control statements DEF FN function definitions are not permitted inside control constructs such as IF...THEN...ELSE and SELECT CASE. (Compile-time error) DEF without END DEF There is no corresponding END DEF in a multiline function definition. (Compile-time error) DEFtype character specification illegal A DEFtype statement is entered incorrectly. DEF can only be followed by LNG, DBL, INT, SNG, STR, or (for user-defined functions) a blank space. (Compile-time error) Device fault A device has returned a hardware error. If this message occurs while data are being transmitted to a communications file, it indicates that the signals being tested with the OPEN COM statement were not found in the specified period of time. (Run-time error) ERR code: 25 Device I/O error An I/O error occurred on a device I/O operation. The operating system cannot recover from the error. (Run-time error) ERR code: 57 Device timeout The program did not receive information from an I/O device within a predetermined amount of time. (Run-time error) ERR code: 24 Device unavailable The device you are attempting to access is not on line or does not exist. (Run-time error) ERR code: 68 Disk full There is not enough room on the disk for the completion of a PRINT, WRITE, or CLOSE operation. This error can also occur if there is not enough room for QuickBASIC to write out an object or executable file. (Run-time error) ERR code: 61 Disk-media error Disk-drive hardware has detected a physical flaw on the disk. (Run-time error) ERR code: 72 Disk not ready The disk-drive door is open, or no disk is in the drive. (Run-time error) ERR code: 71 Division by zero A division by zero is encountered in an expression, or an exponentiation operation results in zero being raised to a negative power. (Compile-time or run-time error) ERR code: 11 DO without LOOP The terminating LOOP clause is missing from a DO...LOOP statement. (Compile-time error) Document too large Your document exceeds QuickBASIC's internal limit. Divide the document into separate files. Duplicate definition You are using an identifier that has already been defined. For example, you are attempting to use the same name in a CONST statement and as a variable definition, or the same name for a procedure and a variable. This error also occurs if you attempt to redimension an array. You must use DIM or REDIM when redimensioning dynamic arrays. (Compile-time or run-time error) ERR code: 10 Duplicate label Two program lines are assigned the same number or label. Each line number or label in a module must be unique. (Compile-time error) Dynamic array element illegal Dynamic array elements are not allowed with VARPTR$. (Compile-time error) Element not defined A user-defined type element is referenced but not defined. For example, if the user-defined type MYTYPE contained elements A, B, and C, then an attempt to use the variable D as an element of MYTYPE would cause this message to appear. (Compile-time error) ELSE without IF An ELSE clause appears without a corresponding IF. Sometimes this error is caused by incorrectly nested IF statements. (Compile-time error) ELSEIF without IF An ELSEIF statement appears without a corresponding IF. Sometimes this error is caused by incorrectly nested IF statements. (Compile-time error) END DEF without DEF An END DEF statement has no corresponding DEF statement. (Compile-time error) END IF without block IF The beginning of an IF block is missing. (Compile-time error) END SELECT without SELECT The end of a SELECT CASE statement appears without a beginning SELECT CASE. The beginning of the SELECT CASE statement may be missing or misspelled. (Compile-time error) END SUB or END FUNCTION must be last line in window You are attempting to add code after a procedure. You must either return to the main module or open another module. (Compile-time error) END SUB/FUNCTION without SUB/FUNCTION You deleted the SUB or FUNCTION statement. (Compile-time error) END TYPE without TYPE An END TYPE statement is used outside a TYPE declaration. (Compile-time error) Equal sign missing QuickBASIC expects an equal sign. (Compile-time error) Error during QuickBASIC initialization Several conditions can cause this error. It is most commonly caused when there is not enough memory in the machine to load QuickBASIC. If you are loading a Quick library, try reducing the size of the library. This error may occur when you attempt to use QuickBASIC on unsupported hardware. (QB invocation error) Error in loading file (filename)ÄÄCannot find file This error occurs when redirecting input to QuickBASIC from a file. The input file is not at the location specified on the command line. (QB invocation error) Error in loading file (filename)ÄÄDisk I/O error This error is caused by physical problems accessing the disk, for example, if the drive door is left open. (QB invocation error) Error in loading file (filename)ÄÄDOS memory-area error The area of memory used by DOS has been written to, either by an assembly language routine or with the POKE statement. (QB invocation error) Error in loading file (filename)ÄÄInvalid format You are attempting to load a Quick library that is not in the correct format. This error can occur if you are attempting to use a Quick library created with a previous version of QuickBASIC, if you are trying to use a file that has not been processed with QuickBASIC's Make Library command or the /QU option from LINK, or if you are trying to load a stand-alone (.LIB) library with QuickBASIC. (QB invocation error) Error in loading file (filename)ÄÄOut of memory More memory is required than is available. For example, there may not be enough memory to allocate a file buffer. Try reducing the size of your DOS buffers, getting rid of any terminate-and-stay resident programs, or eliminating some device drivers. If you have large arrays, try placing a ›DYNAMIC metacommand at the top of your program. If you have documents loaded, then unloading them will free some memory. (Run-time error) EXIT DO not within DO...LOOP An EXIT DO statement is used outside of a DO...LOOP statement. (Compile-time error) EXIT not within FOR...NEXT An EXIT FOR statement is used outside of a FOR...NEXT statement. (Compile-time error) Expected: item This is a syntax error. The cursor is positioned at the unexpected item. (Compile-time error) Expression too complex This error is caused when certain internal limitations are exceeded. For example, during expression evaluation, strings that are not associated with variables are assigned temporary locations. A large number of such strings can cause this error to occur. Try simplifying expressions, and assigning strings to variables. (Compile-time error) Extra file name ignored You specified too many files on the command line; the last file name on the line is ignored. (BC invocation error) Far heap corrupt The far-heap memory has been corrupted by one of the following: ž The QB compiler does not support a terminate-and-stay-resident program resident in DOS. ž The POKE statement modified areas of memory used by QuickBASIC. (This may modify the descriptor for a dynamic array of numbers or fixed-length strings.) ž The program called an other-language routine that modified areas of memory used by QuickBASIC. (This may modify the descriptor for a dynamic array of numbers or fixed-length strings. (Compile-time error) FIELD overflow A FIELD statement is attempting to allocate more bytes than were specified for the record length of a random file. (Run-time error) ERR code: 50 FIELD statement active A GET or PUT statement referred to a record variable used in a a file with space previously allocated by the FIELD statement. GET or PUT with a record variable argument may only be used on files where no FIELD statements have been executed. (Run-time error) ERR code: 56 File already exists The file name specified in a NAME statement is identical to a file name already in use on the disk. (Run-time error) ERR code: 58 File already open A sequential-output-mode OPEN statement is issued for a file that is already open, or a KILL statement is given for a file that is open. (Run-time error) ERR code: 55 File not found A FILES, KILL, NAME, OPEN or RUN statement references a file that does not exist. (Run-time error) ERR code: 53 File not found in module module-name at address segment:offset A FILES, KILL, NAME, OPEN or RUN statement references a file that does not exist. This error message is equivalent to the File not found message, but it occurs during execution of compiled programs. The module-name is the name of the calling module. The address is the location of the error in the code. (Run-time error) ERR code: 53 File previously loaded You are attempting to load a file that is already in memory. (Compile-time error) Fixed-length string illegal You are attempting to use a fixed-length string as a formal parameter. (Compile-time error) FOR index variable already in use This error occurs when an index variable is used more than once in nested FOR loops. (Compile-time error) FOR index variable illegal This error is usually caused when an incorrect variable type is used in a FOR-loop index. A FOR-loop index variable must be a simple numeric variable. (Compile-time error) FOR without NEXT Each FOR statement must have a matching NEXT statement. (Compile-time error) Formal parameter specification illegal There is an error in a function or subprogram parameter list. (Compile-time error) Formal parameters not unique A FUNCTION or SUB declaration contains duplicate parameters, as in this example: SUB GetName(A,B,C,A) STATIC. (Compile-time error) Function already defined This error occurs when a previously defined FUNCTION is redefined. (Compile-time error) Function name illegal A BASIC reserved word is used as a user-defined FUNCTION name. (Compile-time error) Function not defined You must declare or define a FUNCTION before using it. (Compile-time error) GOSUB missing The GOSUB is missing from an ON event statement. (Compile-time error) GOTO missing The GOTO is missing from an ON ERROR statement. (Compile-time error) GOTO or GOSUB expected QuickBASIC expects a GOTO or GOSUB statement. (Compile-time error) Help not found Help was requested but not found, and the program contains errors prohibiting QuickBASIC from building a variable table. Press F5 to view the line that caused the error. Identifier cannot end with %, &, !, #, or $ The above suffixes are not allowed in type identifiers, subprogram names, or names appearing in COMMON statements. (Compile-time error) Identifier cannot include period User-defined type identifier and record element names cannot contain periods. The period should only be used as a record variable separator. In addition, a variable name cannot contain a period if the part of the name before the period has been used in an identifier AS usertype clause anywhere in the program. If you have programs that use the period in variable names, it is recommended that you change them to use mixed case instead. For example, variable ALPHA.BETA would become AlphaBeta. (Compile-time error) Identifier expected You are attempting to use a number or a BASIC reserved word where an identifier is expected. (Compile-time error) Identifier too long Identifiers must not be longer than 40 characters. (Compile-time error) Illegal function call A parameter that is out of range is passed to a math or string function. A function-call error can also occur for the following reasons: ž A negative or unreasonably large subscript is used. ž A negative number is raised to a power that is not an integer. ž A negative record number is given when using GET file or PUT file. ž An improper or out-of-range argument is given to a function. ž A BLOAD or BSAVE operation is directed to a nondisk device. ž An I/O function or statement (LOC or LOF, for example) is performed on a device that does not support it. ž Strings are concatenated to create a string greater than 32,767 characters in length. (Run-time error) ERR code: 5 Illegal in direct mode The statement is valid only within a program and cannot be used in the Immediate window. (Compile-time error) Illegal in procedure or DEF FN The statement is not allowed inside a procedure. (Compile-time error) Illegal number The format of the number does not correspond to a valid number format. You have probably made a typographical error. For example, the number 2p3 will produce this error. (Compile-time error) Illegal outside of SUB, FUNCTION, or DEF FN This statement is not allowed in module-level code. (Compile-time error) Illegal outside of SUB/FUNCTION The statement is not allowed in module-level code or DEF FN functions. (Compile-time error) Illegal outside of TYPE block The element AS type clause is permitted only within a TYPE...END TYPE block. (Compile-time error) Illegal type character in numeric constant A numeric constant contains an inappropriate type-declaration character. (Compile-time error) ›INCLUDE-file access error The include file named in the ›INCLUDE metacommand cannot be located. (Compile-time error) Include file too large Your include file exceeds QuickBASIC's internal limit. Break the file into separate files. (Compile-time error) Input file not found The source file you gave on the command line is not in the specified location. (BC invocation error) INPUT missing The compiler expects the keyword INPUT. (Compile-time error) Input past end of file An INPUT statement reads from a null (empty) file or from a file in which all data have already been read. To avoid this error, use the EOF function to detect the end of file. (Run-time error) ERR code: 62 Input runtime module path: This prompt appears if the run-time module BRUN45.EXE is not found. Enter the correct path specification. This error is severe and cannot be trapped. (Run-time error) Integer between 1 and 32767 required The statement requires an integer argument. (Compile-time error) Internal error An internal malfunction occurred in QuickBASIC. Use the Product Assistance Request form included with your documentation to report to Microsoft the conditions under which the message appeared. (Run-time error) ERR code: 51 Internal error near xxxx An internal malfunction occurred in QuickBASIC at location xxxx. Use the Product Assistance Request form included with your documentation to report the conditions under which the message appeared. (Compile-time error) Invalid character QuickBASIC found an invalid character, such as a control character, in the source file. (Compile-time error) Invalid constant An invalid expression is used to assign a value to a constant. Remember that expressions assigned to constants may contain numeric constants, symbolic constants, and any of the arithmetic or logical operators except exponentiation. A string expression assigned to a constant may consist only of a single literal string. (Compile-time error) Invalid DECLARE for BASIC procedure You are attempting to use the DECLARE statement keywords ALIAS, CDECL, or BYVAL with a BASIC procedure. ALIAS, CDECL, and BYVAL can only be used with non-BASIC procedures. (Compile-time error) Label not defined A line label is referenced (in a GOTO statement, for example), but does not occur in the program. (Compile-time error) Label not defined: label A GOTO linelabel statement refers to a nonexistent line label. (Compile-time error) Left parenthesis missing QuickBASIC expected a left parenthesis, or a REDIM statement tried to reallocate space for a scalar. (Compile-time error) Line invalid. Start again An invalid file-name character was used following the path characters "\" (backslash) or ":" (colon). (BC invocation error) Line number or label missing A line number or label is missing from a statement that requires one, for example, GOTO. (Compile-time error) Line too long Lines are limited to 255 characters. (Compile-time error) LOOP without DO The DO starting a DO...LOOP statement is missing or misspelled. (Compile-time error) Lower bound exceeds upper bound The lower bound exceeds the upper bound defined in a DIM statement. (Compile-time error) Math overflow The result of a calculation is too large to be represented in BASIC number format. (Compile-time error) ›Metacommand error A metacommand is incorrect. If you are compiling the program with BC this error is not "fatal"; the program will execute, although the results may be incorrect. (Compile-time warning) Minus sign missing QuickBASIC expects a minus sign. (Compile-time error) Missing Event Trapping (/W) or Checking Between Statements (/V) option The program contains an ON event statement requiring one of these options. (Compile-time error) Missing On Error (/E) option When using the BC command, programs containing ON ERROR statements must be compiled with the On Error (/E) option. (Compile-time error) Missing Resume Next (/X) option When using the BC command, programs containing RESUME, RESUME NEXT, and RESUME 0 statements must be compiled with the Resume Next (/X) option. (Compile-time error) Module level code too large Your module-level code exceeds QuickBASIC's internal limit. Try moving some of the code into SUB or FUNCTION procedures. (Compile-time error) Module not found. Unload module from program? When loading the program, QuickBASIC did not find the file containing the indicated module. QuickBASIC created an empty module instead. You must delete the empty module before you can run the program. Must be first statement on the line In block IF...THEN...ELSE constructs, IF, ELSE, ELSEIF, and END IF can be preceded only by a line number or label. (Compile-time error) Name of subprogram illegal The error is caused when a subprogram name is a BASIC reserved word, or a subprogram name is used twice. (Compile-time error) Nested function definition A FUNCTION definition appears inside another FUNCTION definition, or inside an IF...THEN...ELSE clause. (Compile-time error) NEXT missing for variable A FOR statement is missing a corresponding NEXT statement. The variable is the FOR-loop index variable. (Compile-time error) NEXT without FOR Each NEXT statement must have a matching FOR statement. (Compile-time error) No line number in module-name at address segment:offset This error occurs when the error address cannot be found in the line-number table during error trapping. This happens if there are no integer line numbers between 0 and 65,527. It may also occur if the line-number table has been accidentally overwritten by the user program. This error is severe and cannot be trapped. (Run-time error) No main module. Choose Set Main Module from the Run menu to select one You are attempting to run the program after you have unloaded the main module. Every program must have a main module. (Compile-time error) No RESUME The end of the program was encountered while the program was in an error-handling routine. A RESUME statement is needed to remedy this situation. (Run-time error) ERR code: 19 Not watchable This error occurs when you are specifying a variable in a watch expression. Make sure the module or procedure in the active View window has access to the variable you want to watch. For example, module-level code cannot access variables that are local to a SUB or FUNCTION. (Run-time error) Numeric array illegal Numeric arrays are not allowed as arguments to VARPTR$. Only simple variables and string array elements are permitted. (Compile-time error) Only simple variables allowed User-defined types and arrays are not permitted in READ and INPUT statements. Array elements that are not of a user-defined type are permitted. (Compile-time error) Operation requires disk You are attempting to load from, or save to, a nondisk device such as the printer or keyboard. (Compile-time error) Option unknown: option You have given an illegal option. (BC invocation error) Out of DATA A READ statement is executed when there are no DATA statements with unread data remaining in the program. (Run-time error) ERR code: 4 Out of data space Try modifying your data space requirements as follows: ž Use a smaller file buffer in the OPEN statement's LEN clause. ž Use the ›DYNAMIC metacommand to create dynamic arrays. Dynamic array data can usually be much larger than static array data. ž Use fixed-length string arrays instead of variable-length string arrays. ž Use the smallest data type that will accomplish your task. Use integers whenever possible. ž Try not to use many small procedures. QuickBASIC must create several bytes of control information for each procedure. ž Use CLEAR to modify the size of the stack. Use only enough stack space to accomplish your task. ž Do not use source lines longer than 255 characters. Such lines require allocation of additional text buffer space. (Compile-time or run-time error) Out of memory More memory is required than is available. For example, there may not be enough memory to allocate a file buffer. Try reducing the size of your DOS buffers, or getting rid of any terminate-and-stay-resident programs, or eliminating some device drivers. If you have large arrays, try placing a ›DYNAMIC metacommand at the top of your program. If you have documents loaded, unloading them will free some memory. (BC invocation, compile-time, or run-time error) ERR code: 7 Out of paper The printer is out of paper or is not turned on. (Run-time error) ERR code: 27 Out of stack space This error can occur when a recursive FUNCTION procedure nests too deeply, or there are too many active subroutine, FUNCTION, and SUB calls. You can use the CLEAR statement to increase the program's allotted stack space. This error cannot be trapped. (Run-time error) Out of string space String variables exceed the allocated amount of string space. (Run-time error) ERR code: 14 Overflow The result of a calculation is too large to be represented within the range allowed for either floating-point or integer numbers. (Run-time error) ERR code: 6 Overflow in numeric constant The numeric constant is too large. (Compile-time error) Parameter type mismatch A subprogram or FUNCTION parameter type does not match the DECLARE statement argument or the calling argument. (Compile-time error) Path not found During an OPEN, MKDIR, CHDIR, or RMDIR operation, DOS was unable to find the path specified. The operation is not completed. (Run-time error) ERR code: 76 Path/File access error During an OPEN, MKDIR, CHDIR, or RMDIR operation, DOS was unable to make a correct connection between the path and file name. The operation is not completed. (Compile-time or run-time error) ERR code: 75 Permission denied An attempt was made to write to a write-protected disk, or to access a locked file. (Run-time error) ERR code: 70 Procedure already defined in Quick library A procedure in the Quick library has the same name as a procedure in your program. (Compile-time error) Procedure too large The procedure has exceeded QuickBASIC's internal limit. Make the procedure smaller by dividing it into several procedures. (Compile-time error) Program-memory overflow You are attempting to compile a program whose code segment is larger than 64K. Try splitting the program into separate modules, or use the CHAIN statement. (Compile-time error) Read error on standard input A system error occurred while reading from the console or a redirected input file. (BC invocation error) Record/string assignment required The string or record variable assignment is missing from the LSET statement. (Compile-time error) Redo from start You have responded to an INPUT prompt with the wrong number or type of items. Retype your response in the correct form. (Run-time error) Rename across disks An attempt was made to rename a file with a new drive designation. This is not allowed. (Run-time prompt) ERR code: 74 Requires DOS 2.10 or later You are attempting to use QuickBASIC with an incorrect version of DOS. (QB invocation or run-time error) RESUME without error A RESUME statement is encountered before an error-trapping routine is entered. (Run-time error) ERR code: 20 RETURN without GOSUB A RETURN statement is encountered for which there is no previous, unmatched GOSUB statement. (Run-time error) ERR code: 3 Right parenthesis missing QuickBASIC expects a right (closing) parenthesis. (Compile-time error) SEG or BYVAL not allowed in CALLS BYVAL and SEG are permitted only in a CALL statement. (Compile-time error) SELECT without END SELECT The end of a SELECT CASE statement is missing or misspelled. (Compile-time error) Semicolon missing QuickBASIC expects a semicolon. (Compile-time error) Separator illegal There is an illegal delimiting character in a PRINT USING or WRITE statement. Use a semicolon or a comma as a delimiter. (Compile-time error) Simple or array variable expected The compiler expects a variable argument. (Compile-time error) Skipping forward to END TYPE statement An error in the TYPE statement has caused QuickBASIC to ignore everything between the TYPE and END TYPE statement. (Compile-time error) Statement cannot occur within $INCLUDE file SUB...END SUB and FUNCTION...END FUNCTION statement blocks are not permitted in include files. Use the Merge command from the File menu to insert the include file into the current module, or load the include file as a separate module. If you load the include file as a separate module, some restructuring may be necessary because shared variables are shared only within the scope of the module. (Compile-time error) Statement cannot precede SUB/FUNCTION definition The only statements allowed before a procedure definition are the statements REM and DEFtype. (Compile-time error) Statement ignored You are using the BC command to compile a program that contains TRON and TROFF statements without using the /D option. This error is not "fatal" ; the program will execute, although the results may be incorrect. (Compile-time warning) Statement illegal in TYPE block The only statements allowed between the TYPE and END TYPE statements are REM and element AS typename. (Compile-time error) Statement unrecognizable You have probably mistyped a BASIC statement. (Compile-time error) Statements/labels illegal between SELECT CASE and CASE Statements and line labels are not permitted between SELECT CASE and the first CASE statement. Comments and statement separators are permitted. (Compile-time error) STOP in module name at address segment:offset A STOP statement was encountered in the program. (Run-time error) String assignment required The string assignment is missing from an RSET statement. (Compile-time error) String constant required for ALIAS The DECLARE statement ALIAS keyword requires a string-constant argument. (Compile-time error) String expression required The statement requires a string-expression argument. (Compile-time error) String formula too complex Either a string formula is too long or an INPUT statement requests more than 15 string variables. Break the formula or INPUT statement into parts for correct execution. (Run-time error) ERR code: 16 String space corrupt This error occurs when an invalid string in string space is being deleted during heap compaction. The probable causes of this error are as follows: ž A string descriptor or string back pointer has been improperly modified. This may occur if you use an assembly-language subroutine to modify strings. ž Out-of-range array subscripts are used and string space is inadvertently modified. The Produce Debug Code option can be used at compile time to check for array subscripts that exceed the array bounds. ž Incorrect use of the POKE and/or DEF SEG statements may modify string space improperly. ž Mismatched COMMON declarations may occur between two chained programs. (Run-time error) String variable required The statement requires a string-variable argument. (Compile-time error) SUB or FUNCTION missing A DECLARE statement has no corresponding procedure. (Compile-time error) SUB/FUNCTION without END SUB/FUNCTION The terminating statement is missing from a procedure. (Compile-time error) Subprogram error This is a SUB or FUNCTION definition error and is usually caused by one of the following: ž The SUB or FUNCTION is already defined. ž The program contains incorrectly nested FUNCTION or SUB statements. ž The SUB or FUNCTION does not terminate with an END SUB or END FUNCTION statement. (Compile-time error) Subprogram not defined A subprogram is called but never defined. (Compile-time error) Subprograms not allowed in control statements Subprogram FUNCTION definitions are not permitted inside control constructs such as IF...THEN...ELSE and SELECT CASE. (Compile-time error) Subscript out of range An array element was referenced with a subscript that was outside the dimensions of the array, or an element of an undimensioned dynamic array was accessed. This message may be generated if the Debug (/D) option was specified at compile time. You may also get this error if the array size exceeds 64K, the array is not dynamic, and the /AH option was not used. Reduce the size of the array, or make the array dynamic and use the /AH command-line option. (Run-time error) ERR code: 9 Subscript syntax illegal An array subscript contains a syntax error: for example, an array subscript contains both string and integer data types. (Compile-time error) Syntax error Several conditions can cause this error. The most common cause at compile time is a mistyped BASIC keyword or argument. At run-time, it is often caused by an improperly formatted DATA statement. (Compile-time or run-time error) ERR code: 2 Syntax error in numeric constant A numeric constant is not properly formed. (Compile-time error) THEN missing QuickBASIC expects a THEN keyword. (Compile-time error) TO missing QuickBASIC expects a TO keyword. (Compile-time error) Too many arguments in function call Function calls are limited to 60 arguments. (Compile-time error) Too many dimensions Arrays are limited to 60 dimensions. (Compile-time error) Too many files At compile time, this error occurs when include files are nested more than five levels deep. It occurs at run time when the 255-file directory maximum is exceeded by an attempt to create a new file with a SAVE or OPEN statement. (Compile-time or run-time error) ERR code: 67 Too many labels The number of lines in the line list following an ON...GOTO or ON...GOSUB statement exceeds 255 (Compile-time error) or 59 (Run-time error in compiled applications). Too many named COMMON blocks The maximum number of named COMMON blocks permitted is 126. (Compile-time error) Too many TYPE definitions The maximum number of user-defined types permitted is 240. (Compile-time error) Too many variables for INPUT An INPUT statement is limited to 60 variables. (Compile-time error) Too many variables for LINE INPUT Only one variable is allowed in a LINE INPUT statement. (Compile-time error) Type mismatch The variable is not of the required type. For example, you are trying to use the SWAP statement with a string variable and a numeric variable. (Compile-time or run-time error) ERR code: 13 TYPE missing The TYPE keyword is missing from an END TYPE statement. (Compile-time error) Type more than 65535 bytes A user-defined type cannot exceed 64K. (Compile-time error) Type not defined The usertype argument to the TYPE statement is not defined. (Compile-time error) TYPE statement improperly nested User-defined type definitions are not allowed in procedures. (Compile-time error) TYPE without END TYPE There is no END TYPE statement associated with a TYPE statement. (Compile-time error) Typed variable not allowed in expression Variables that are user-defined types are not permitted in expressions such as CALL ALPHA((X)), where X is a user-defined type. (Compile-time error) Unexpected end of file in TYPE declaration There is an end-of-file character inside a TYPE...END TYPE block. Unprintable error An error message is not available for the error condition that exists. This may be caused by an ERROR statement that doesn't have a defined error code. (Run-time error) Unrecognized switch error: "QU" You are attempting to create an .EXE file or Quick library with an incorrect version of the Microsoft Overlay Linker. You must use the linker supplied on the QuickBASIC distribution disks to create an .EXE file or Quick library. (Compile-time error) Valid options: [/RUN] file /AH /B /C:buf /G /NOHI /H /L [lib] /MBF /CMD string This message appears when you invoke QuickBASIC with an invalid option. (QB invocation error) Variable-length string required Only variable-length strings are permitted in a FIELD statement. (Compile-time error) Variable name not unique You are attempting to define the variable x as a user-defined type after x.y has been used. (Compile-time error) Variable required QuickBASIC encountered an INPUT, LET, READ, or SHARED statement without a variable argument. (Compile-time error) Variable required A GET or PUT statement didn't specify a variable when an operation is performed on a file opened in BINARY mode. (Run-time error) ERR code: 40 WEND without WHILE This error is caused when a WEND statement has no corresponding WHILE statement. (Compile-time error) WHILE without WEND This error is caused when a WHILE statement has no corresponding WEND statement. (Compile-time error) Wrong number of dimensions An array reference contains the wrong number of dimensions. (Compile-time error) B.3 LINK Error Messages This section lists and describes error messages generated by the Microsoft Overlay Linker, LINK. Fatal errors cause the linker to stop execution. Fatal error messages have the following format: location : fatal error L1xxx:messagetext Nonfatal errors indicate problems in the executable file. LINK produces the executable file. Nonfatal error messages have the following format: location : error L2xxx: messagetext Warnings indicate possible problems in the executable file. LINK produces the executable file. Warnings have the following format: location : warning L4xxx: messagetext In these messages, location is the input file associated with the error, or LINK if there is no input file. The following error messages may appear when you link object files with LINK: ÖŚÄŚÄÄÄÄÄÄÄÄÄÄÄŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ· Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ L1001 option : option name ambiguous A unique option name did not appear after the option indicator (/). For example, the command LINK /N main; generates this error, since LINK cannot tell which of the three options beginning with the letter "N" was intended. L1002 option : unrecognized option name Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L1002 option : unrecognized option name An unrecognized character followed the option indicator (/), as in the following example: LINK /ABCDEF main; L1003 /QUICKLIB, /EXEPACK incompatible You specified two options that cannot be used together: /QUICKLIB and /EXEPACK. L1004 option : invalid numeric value An incorrect value appeared for one of the LINK options. For example, a character string was given for an option that requires a numeric value. L1006 option : stack size exceeds 65535 bytes The value given as a parameter to the /STACKSIZE option Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The value given as a parameter to the /STACKSIZE option exceeds the maximum allowed. L1007 option : interrupt number exceeds 255 For the /OVERLAYINTERRUPT option, a number greater than 255 was given as a value. L1008 option : segment limit set too high The limit on the number of segments allowed was set to greater than 3072 using the /SEGMENTS option. L1009 number : CPARMAXALLOC : illegal value The number specified in the /CPARMAXALLOC option was not in the range 1-65,535. L1020 no object modules specified Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L1020 no object modules specified No object-file names were specified to LINK. L1021 cannot nest response files A response file occurred within a response file. L1022 response line too long A line in a response file was longer than 127 characters. L1023 terminated by user You entered CTRL+C or CRTL+BREAK. L1024 nested right parentheses The contents of an overlay were typed incorrectly on the Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The contents of an overlay were typed incorrectly on the command line. L1025 nested left parentheses The contents of an overlay were typed incorrectly on the command line. L1026 unmatched right parenthesis A right parenthesis was missing from the contents specification of an overlay on the command line. L1027 unmatched left parenthesis A left parenthesis was missing from the contents specification of an overlay on the command line. L1043 relocation table overflow Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L1043 relocation table overflow More than 32,768 long calls, long jumps, or other long pointers appeared in the program. Try replacing long references with short references, where possible, and recreate the object module. L1045 too many TYPDEF records An object module contained more than 255 TYPDEF records. These records describe communal variables. This error can appear only with programs produced by the Microsoft FORTRAN Compiler or other compilers that support communal variables. (TYPDEF is a DOS term. It is explained in the Microsoft MS-DOS Programmer's Reference and in other reference books on DOS.) L1046 too many external symbols in one module An object module specified more than the limit of 1023 Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  An object module specified more than the limit of 1023 external symbols. Break the module into smaller parts. L1047 too many group, segment, and class names in one module The program contained too many group, segment, and class names. Reduce the number of groups, segments, or classes, and recreate the object file. L1048 too many segments in one module An object module had more than 255 segments. Split the module or combine segments. L1049 too many segments The program had more than the maximum number of segments. Use the /SEGMENTS option, which has a default value of 128, to specify the maximum legal number of segments. The default is Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  specify the maximum legal number of segments. The default is 128 in the /SEGMENTS option, which specifies the maximum legal number. Relink using the /SEGMENTS option with an appropriate number of segments. L1050 too many groups in one module LINK encountered over 21 group definitions (GRPDEF) in a single module. Reduce the number of group definitions or split the module. (Group definitions are explained in the Microsoft MS-DOS Programmer's Reference and in other reference books on DOS.) L1051 too many groups The program defined more than 20 groups, not counting DGROUP. Reduce the number of groups. L1052 too many libraries Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L1052 too many libraries An attempt was made to link with more than 32 libraries. Combine libraries, or use modules that require fewer libraries. L1053 out of memory for symbol table There is no fixed limit to the size of the symbol table. However, it is limited by the amount of available memory. Combine modules or segments and recreate the object files. Eliminate as many public symbols as possible. L1054 requested segment limit too high LINK did not have enough memory to allocate tables describing the number of segments requested. (The default is 128 or the value specified with the /SEGMENTS option.) Try linking again using the /SEGMENTS option to select a smaller number of Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  using the /SEGMENTS option to select a smaller number of segments (for example, use 64 if the default was used previously), or free some memory by eliminating resident programs or shells. L1056 too many overlays The program defined more than 63 overlays. L1057 data record too large A LEDATA record (in an object module) contained more than 1024 bytes of data. This is a translator error. (LEDATA is a DOS term, which is explained in the Microsoft MS-DOS Programmer's Reference and in other DOS reference books.) Note which translator (compiler or assembler) produced the incorrect object module and the circumstances. Please report this error to Microsoft Corporation using the Product Assistance Request form included with the documentation. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  form included with the documentation. L1063 out of memory for CodeView information Too many linked object (".OBJ") files contain debugging information. Turn off the Produce Debug Code option in the Make EXE file dialog box. L1070 segment size exceeds 64K A single segment contained more than 64K of code or data. Try compiling and linking using the large model. L1071 segment _TEXT larger than 65520 bytes This error is likely to occur only in small-model C programs, but it can occur when any program with a segment named _TEXT is linked using the /DOSSEG option. Small-model C programs must reserve code addresses 0 and 1; this range is increased Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  must reserve code addresses 0 and 1; this range is increased to 16 for alignment purposes. L1072 common area longer than 65536 bytes The program had more than 64K of communal variables. This error occurs only with programs produced by compilers that support communal variables. L1080 cannot open list file The disk or the root directory was full. Delete or move files to make space. L1081 out of space for run file The disk on which the executable file was being written was full. Free more space on the disk and restart LINK. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L1083 cannot open run file The disk or the root directory was full. Delete or move files to make space. L1084 cannot create temporary file The disk or root directory was full. Free more space in the directory and restart LINK. L1085 cannot open temporary file The disk or the root directory was full. Delete or move files to make space. L1086 scratch file missing An internal error has occurred. Note the circumstances of the Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  An internal error has occurred. Note the circumstances of the problem and contact Microsoft Corporation using the Product Assistance Request form included with the documentation. L1087 unexpected end-of-file on scratch file The disk with the temporary output file from LINK was removed. L1088 out of space for list file The disk where the listing file is being written is full. Free more space on the disk and restart LINK. L1089 filename : cannot open response file LINK could not find the specified response file. This usually indicates a typing error. L1090 cannot reopen list file Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The original disk was not replaced at the prompt. Restart LINK. L1091 unexpected end-of-file on library The disk containing the library probably was removed. Replace the disk containing the library and run LINK again. L1093 object not found One of the object files specified in the input to LINK was not found. Restart LINK and specify the object file. L1101 invalid object module One of the object modules was invalid. If the error persists after recompiling, please contact Microsoft Corporation using the Product Assistance Request form included with the Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  the Product Assistance Request form included with the documentation. L1102 unexpected end-of-file An invalid format for a library was encountered. L1103 attempt to access data outside segment bounds A data record in an object module specified data extending beyond the end of a segment. This is a translator error. Note which translator (compiler or assembler) produced the incorrect object module and the circumstances in which it was produced. Please report this error to Microsoft Corporation using the Product Assistance Request form included with the documentation. L1104 filename : not valid library Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  The specified file was not a valid library file. This error causes LINK to abort. L1113 unresolved COMDEF; internal error Note the circumstances of the failure and contact Microsoft Corporation using the Product Assistance Request form included with the documentation. L1114 file not suitable for /EXEPACK; relink without For the linked program, the size of the packed load image plus packing overhead was larger than that of the unpacked load image. Relink without the /EXEPACK option. L1115 /QUICKLIB, overlays incompatible You specified overlays and used the /QUICKLIB option. These Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  You specified overlays and used the /QUICKLIB option. These cannot be used together. L2001 fixup(s) without data A FIXUPP record occurred without a data record immediately preceding it. This is probably a compiler error. (See the Microsoft MS-DOS Programmer's Reference for more information on FIXUPP.) L2002 fixup overflow near number in frame seg segname target seg segname target offset number The following conditions can cause this error: ž A group is larger than 64K. ž The program contains an intersegment short jump or intersegment short call. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  ž The name of a data item in the program conflicts with the name of a library subroutine included in the link. ž An EXTRN declaration in an assembly-language source file appeared inside the body of a segment, as in the following example: code SEGMENT public 'CODE' EXTRN main:far start PROC far call main ret start ENDP code ENDS The following construction is preferred: EXTRN main:far Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  EXTRN main:far code SEGMENT public 'CODE' start PROC far call main ret start ENDP code ENDS Revise the source file and recreate the object file. (See the Microsoft MS-DOS Programmer's Reference for information about frame and target segments. L2003 intersegment self-relative fixup at offset in segment segname You tried to make a near call or jump to a far entry in segment segname at offset. Change the call or jump to far or make the entry near. L2004 LOBYTE-type fixup overflow Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L2004 LOBYTE-type fixup overflow A LOBYTE fixup generated an address overflow. (See the Microsoft MS-DOS Programmer's Reference for more information.) L2005 fixup type unsupported A fixup type occurred that is not supported by the Microsoft linker. This is probably a compiler error. Note the circumstances of the failure and contact Microsoft Corporation using the Product Assistance Request form included with the documentation. L2011 name : NEAR/HUGE conflict Conflicting NEAR and HUGE attributes were given for a communal variable. This error can occur only with programs produced by compilers that support communal variables. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L2012 name : array-element size mismatch A far communal array was declared with two or more different array-element sizes (for instance, an array was declared once as an array of characters and once as an array of real numbers). This error occurs only with compilers that support far communal arrays. L2013 LIDATA record too large A LIDATA record contains more than 512 bytes. This error is usually caused by a compiler error. L2024 name : symbol already defined LINK has found a public-symbol redefinition. Remove extra definition(s). Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L2025 name : symbol defined more than once Remove the extra symbol definition from the object file. L2029 unresolved externals One or more symbols were declared to be external in one or more modules, but they were not publicly defined in any of the modules or libraries. A list of the unresolved external references appears after the message, as shown in the following example: unresolved externals EXIT in file(s): MAIN.OBJ (main.for) OPEN in file(s): MAIN.OBJ (main.for) The name that comes before in file(s) is the unresolved external symbol. On the next line is a list of object modules that have made references to this symbol. This message and the list are also written to the map file, if one exists. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  list are also written to the map file, if one exists. L2041 stack plus data exceed 64K The total size of near data and the stack exceeds 64K. Reduce the stack size to control the error. LINK tests for this condition only if the /DOSSEG option is enabled. This option is automatically enabled by the library startup module. L2043 Quick library support module missing You did not specify, or LINK could not find, the object module or library required for creating a Quick library. In the case of QuickBASIC, the library provided is BQLB45.LIB. L2044 name : symbol multiply defined, use /NOE LINK has found a possible public-symbol redefinition. This error is often caused by redefining a symbol defined in a Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  error is often caused by redefining a symbol defined in a library. Relink using the /NOEXTDICTIONARY option. This error in combination with error L2025 for the same symbol indicates a real redefinition error. L4011 PACKCODE value exceeding 65500 unreliable Packcode segment sizes that exceed 65,500 bytes may be unreliable on the Intel(R) 80286 processor. L4012 load-high disables EXEPACK The /HIGH and /EXEPACK options cannot be used at the same time. L4015 /CODEVIEW disables /DSALLOCATE The /CODEVIEW and /DSALLOCATE options cannot be used at the same time. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  same time. L4016 /CODEVIEW disables /EXEPACK The /CODEVIEW and /EXEPACK options cannot be used at the same time. L4020 name : code-segment size exceeds 65500 Code segments of 65,501-65,536 bytes in length may be unreliable on the Intel 80286 processor. L4021 no stack segment The program did not contain a stack segment defined with STACK combine type. This message should not appear for modules compiled with Microsoft QuickBASIC, but it could appear for an assembly-language module. Normally, every program should have a stack segment with the combine type specified as STACK. You Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  a stack segment with the combine type specified as STACK. You can ignore this message if you have a specific reason for not defining a stack or for defining one without the STACK combine type. Linking with versions of LINK earlier than Version 2.40 might cause this message, since these linkers search libraries only once. L4031 name : segment declared in more than one group A segment was declared to be a member of two different groups. Correct the source file and recreate the object files. L4034 more than 239 overlay segments; extra put in root The program designates more than 239 segments to go in overlays. When this error occurs, segments beginning with number 234 are placed in the root, the permanently resident portion. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L4045 name of output file is name The prompt for the run-file field gave an inaccurate default because the /QUICKLIB option was not used early enough. The output will be a Quick library with the name given in the error message. L4050 too many public symbols for sorting The number of public symbols exceeds the space available for sorting the symbols as requested by the /MAP option. The symbols are left unsorted. L4051 filename : cannot find library LINK could not find the specified file. Enter a new file name, a new path specification, or both. Number LINK Error Message ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ  L4053 VM.TMP : illegal file name; ignored VM.TMP appeared as an object-file name. Rename the file and rerun LINK. L4054 filename : cannot find file LINK could not find the specified file. Enter a new file name, a new path specification, or both. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ B.4 LIB Error Messages Error messages generated by the Microsoft Library Manager, LIB, have one of the following formats: {filename | LIB} : fatal error U1xxx: messagetext {filename | LIB} : error U2xxx: messagetext {filename | LIB} : warning U4xxx: messagetext The message begins with the input-file name (filename), if one exists, or with the name of the utility. If possible, LIB prints a warning and continues operation. In some cases errors are fatal, and LIB terminates processing. LIB may display the following error messages: Number LIB Error Message< ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ U1150 page size too small The page size of an input library was too small, which indicates an invalid input .LIB file. U1151 syntax error : illegal file specification A command operator such as a minus sign (-) was given without a following module name. U1152 syntax error : option name missing A forward slash (/) was given without an option after it. U1153 syntax error : option value missing The /PAGESIZE option was given without a value following it. U1154 option unknown An unknown option was given. Currently, LIB recognizes only the /PAGESIZE option. U1155 syntax error : illegal input The given command did not follow correct LIB syntax as specified in Appendix G, "Compiling and Linking from DOS." U1156 syntax error The given command did not follow correct LIB syntax as specified in Appendix G, "Compiling and Linking from DOS." U1157 comma or new line missing A comma or carriage return was expected in the command line but did not appear. This may indicate an inappropriately placed comma, as in the line that follows: LIB math.lib,-mod1+mod2; The line should have been entered as follows: LIB math.lib -mod1+mod2; U1158 terminator missing Either the response to the "Output library" prompt or the last line of the response file used to start LIB did not end with a carriage return. U1161 cannot rename old library LIB could not rename the old library to have a .BAK extension because the .BAK version already existed with read-only protection. Change the protection on the old .BAK version. U1162 cannot reopen library The old library could not be reopened after it was renamed to have a .BAK extension. U1163 error writing to cross-reference file The disk or root directory was full. Delete or move files to make space. U1170 too many symbols More than 4609 symbols appeared in the library file. U1171 insufficient memory LIB did not have enough memory to run. Remove any shells or resident programs and try again, or add more memory. U1172 no more virtual memory Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form included with the documentation. U1173 internal failure Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form included with the documentation. U1174 mark: not allocated Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form included with the documentation. U1175 free: not allocated Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form included with the documentation. U1180 write to extract file failed The disk or root directory was full. Delete or move files to make space. U1181 write to library file failed The disk or root directory was full. Delete or move files to make space. U1182 filename : cannot create extract file The disk or root directory was full, or the specified extract file already existed with read-only protection. Make space on the disk or change the protection of the extract file. U1183 cannot open response file The response file was not found. U1184 unexpected end-of-file on command input An end-of-file character was received prematurely in response to a prompt. U1185 cannot create new library The disk or root directory was full, or the library file already existed with read-only protection. Make space on the disk or change the protection of the library file. U1186 error writing to new library The disk or root directory was full. Delete or move files to make space. U1187 cannot open VM.TMP The disk or root directory was full. Delete or move files to make space. U1188 cannot write to VM Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form. U1189 cannot read from VM Note the circumstances of the failure and notify Microsoft Corporation using the Product Assistance Request form. U1190 interrupted by user The user pressed CTRL+C or CTRL+BREAK. U1200 name : invalid library header The input library file had an invalid format. It was either not a library file, or it had been corrupted. U1203 name : invalid object module near location The module specified by name was not a valid object module. U2152 filename : cannot create listing The directory or disk was full, or the cross-reference-listing file already existed with read-only protection. Either make space on the disk or change the protection of the cross-reference-listing file. U2155 modulename : module not in library; ignored The specified module was not found in the input library. U2157 filename : cannot access file LIB was unable to open the specified file. U2158 libraryname : invalid library header; file ignored The input library had an incorrect format. U2159 filename : invalid format hexnumber; file ignored The signature byte or word hexnumber of the given file was not one of the following recognized types: Microsoft library, Intel library, Microsoft object, or XENIX(R) archive. U4150 modulename : module redefinition ignored A module was specified to be added to a library but a module with the same name was already in the library. Or, a module with the same name was found more than once in the library. U4151 symbol : symbol redefined in module modulename, redefinition ignored The specified symbol was defined in more than one module. U4153 number : page size too small; ignored The value specified in the /PAGESIZE option was less than 16. U4155 modulename : module not in library A module to be replaced is not in the library. LIB adds the module to the library. U4156 libraryname : output-library specification ignored An output library was specified in addition to a new library name. For example, specifying LIB new.lib+one.obj,new.lst,new.lib where new.lib does not already exist causes this error. U4157 Insufficient memory, extended dictionary not created. LIB was unable to create the extended dictionary. The library is still valid, but LINK cannot take advantage of extended dictionaries to link faster. U4158 Internal error, extended dictionary not created. LIB was unable to create the extended dictionary. The library is still valid, but LINK cannot take advantage of extended dictionaries to link faster. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Index Symbols ' (apostrophe) entering + (concatenation operator) A ABS function ALIAS, use in DECLARE statement Alphanumeric line labelsLine labels Angle measurement degrees to radians, converting from radians to degrees, converting from Animation Apostrophe (') entering Arctangent, ATN function Argument passing Arithmetic operators Arithmetic overflow Arrays dimensioning dynamic ERASE statement REDIM statement elements INT86OLD statements LBOUND function location in memory of records static, ERASE statement subscripts, specifying changing lower bound for described maximum value for number of UBOUND function variables AS clause ASC function ASCII character codes special character string expression (table) Assembly language subroutines calling name, PUBLIC symbol string descriptor length Assignment statements ATN function AT&T displays Automatic variables B Background music .BAS files BASIC error codes run-time errors BASICA, differences from BLOAD statement BSAVE statement CALL ABSOLUTE statement CALL statement CLEAR statement COM statement DEF SEG statement DEF type statements DIM statement DRAW statement ERL function FIELD statement RESUME statement STRIG function SYSTEM statement TAN function VARPTR$ function basica, Differences From Chain Statement For...Next Statement BEEP statement Binary mode functions FILEATTR LOC statements GET (File I/O) LOCK OPEN PUT (File I/O) SEEK BLOAD statement Block IF...THEN...ELSE statement Bold text, indicating keywords Boolean operations BSAVE statement Built-in functions BYVAL, use in DECLARE statement C CALL ABSOLUTE statement CALL INT86OLD statement CALL INT86XOLD statement CALL INTERRUPT statement CALL INTERRUPTX statement CALL statement (BASIC procedures) CALL statement (non-BASIC procedures) described location of arguments Calling conventions CALLS statement described location of arguments Cardioid Carriage return CASE clause Case, line labels CDBL function CDECL, use in DECLARE statement CGA adapter CHAIN statement Chaining programs, statements for CHAIN COMMON RUN Chainingprograms, statements for COMMON Characters recognized by BASIC CHDIR statement CHR$ function CINT function CIRCLE statement CLEAR statement CLNG function CLOSE statement CLS statement /CMD option Color Graphics AdapterCGA adapter COLOR statement COM devices COM statements COMMAND$ function COMMAND.COM Commandline, passing to BASIC program Comments introducing REM statement COMMON statement blank chaining programs declaring variables named order of variables SHARED attribute Compile-time error messages Concatenation operator(+) CONST statement Constants global local scope rules symbolic Control-flow statements CALL CALL ABSOLUTE CALLS CHAIN DEF FN DO...LOOP FOR...NEXT FUNCTION GOSUB...RETURN GOTO IF...THEN...ELSE ON GOSUB ON GOTO RETURN SELECT CASE WHILE...WEND COS function Cosine, COS function CSNG function CSRLIN function CVD function CVDMBF function CVI function CVL function CVS function CVSMBF function D DATA statement Data types double-precision floating-point numeric fixed-length string four-byte integer numeric integer numeric long-integer numeric single-precision floating-point numeric specifying two-byte integer numeric TYPE statement variable-length string Date and time functions DATE$ TIME$ statements DATE$ TIME$ DATE$ function DATE$ statement Debugging statements Declarations CONST statement DECLARE statement (BASIC procedures) DECLARE statement (non-BASIC procedures) DEF type statements DIM statement fixed-length strings simple variables variable types DECLARE statements described location of arguments DEF FN functions BASIC, used in exit from, alternative variable scope DEF FN statement DEF SEG statement DEF type statements Default data segments DEFDBL statement DEFINT statement DEFLNG statement DEFSNG statement DEFSTR statement Device errors Devices, handling functions IOCTL$ LPOS PEN statements IOCTL OPEN COM OUT WAIT Device-status information DGROUP, defined DIM statement description SHARED attribute variable types Directory statements CHDIR FILES MKDIR NAME RMDIR Display memory, PCOPY statement Division by zero DO UNTIL statement DO WHILE statement Document conventions DO...LOOP statement exit from, alternative flow control DOS environment variables interrupts DOS-level commands Double precision numbers converting to description PRINT, displayed by variables DRAW statement description DRAWstatement VARPTR$ function, using ›DYNAMIC arrays described location in memory Dynamic arrays ERASE statement REDIM statement E EGA adapter COLOR statement PALETTE statement SCREEN statement EGAadapter COLOR statement END CASE clause END DEF statement END FUNCTION statement END IF statement END SELECT statement END statement END SUB statement END TYPE statement Enhanced Graphics AdapterEGA adapter ENVIRON$ function ENVIRON statement Environment variables Environment-string table EOF function ERASE statement ERDEV function ERDEV$ function ERL function described line labels with ERR code ERR function Error codes Error handling error line number statements ERDEV ERR, ERL ERROR ON ERROR RESUME Error messages compile-time described invocation LIB LINK run-time ERROR statement Error trapping ERROR statement line 0, using Event-trapping statements COM KEY(n) ON event ON UEVENT PEN ON, OFF, and STOP PLAY ON, OFF, and STOP TIMER ON, OFF, and STOP UEVENT .EXE files EXIT DEF statement EXIT DO statement EXIT FOR statement EXIT FUNCTION statement EXIT statement description multiline functions, use in subprograms, use in EXIT SUB statement EXP function Expressions conversion of operands definition F Far addresses FIELD statement File access LOCK statement UNLOCK statement File conversion File handling functions EOF FILEATTR FREEFILE LOC LOF SEEK statements CHDIR CLOSE FIELD GET INPUT # KILL LOCK NAME OPEN RESET SEEK UNLOCK File names, described FILEATTR function Files attributes binary mode, statements and functions FILEATTR GET LOC LOCK OPEN PUT SEEK function SEEK statement random access, statements and functions EOF FIELD GETIO KILL LOC LOCK LSET MKI$, MKS$, MKD$, MKL$ OPEN PUT RSET SEEK function SEEK statement sequential, statements and functions EOF INPUT # KILL LINE INPUT # LOC LOF OPEN PRINT # WRITE # FILES statement FIX function Fixed-point constants Floating point double precision constants range numbers single precision, range Formatting output FOR...NEXT statements description exit from, alternative FRE function FREEFILE function FUNCTION procedures DECLARE statements exit from, alternative module organization STATIC keyword FUNCTION statements Functional operators Functions built-in intrinsic user-defined variables, declaring as local G GET statements FIELD statement File I/O Graphics Global constants Global variables GOSUB statement GOTO statement description line labels, using subroutines, use with Graphics functions PMAP POINT macro language statements BLOAD BSAVE CIRCLE COLOR DRAW GET LINE PAINT PALETTE PALETTE USING PRESET PSET PUT VIEW WINDOW H Hercules adapters HEX$ function Hexadecimal numbers Hierarchy, of operators I IEEE-format numbers IF...THEN...ELSE statements description GOTO statement, when required line labels INKEY$ function INP function INPUT$ function Input functions COMMAND$ INP INPUT$ INPUT # statement INPUT statement description FIELD statement line editor commands Input statements DATA INPUT INPUT # LINE INPUT LINE INPUT # READ RESTORE WAIT INSTR function INT function INT86, INT86X replacements CALL INT86OLD statements CALL INTERRUPT statements Integers constants decimal hexadecimal octal converting to division FIX function Intrinsic functions Invocation error messages I/O ports IOCTL$ function IOCTL statement Italic text, showing placeholders J Joysticks K KEY OFF statement Keyboard scan codes KEY(n) statements KILL statement L LBOUND function LCASE$ function LEFT$ function LEN function LET statement LIB error messages Line 0, effect on error trapping Line feed LINE INPUT # statement LINE INPUT statement Line labels alphanumeric case, significance of GOTO statement, use with RESUME statement use of Line numbers example of restrictions RESUME statement use of Line printer LINE statement Line styling Line-editor commands LINK error messages LOC function Local constants Local variables LOCATE statement LOCK statement LOF function LOG function Logical operators description type conversion Long integers constants converting to Loops LPOS function LPRINT statement description SPC function LPRINT USING statement LSET statement LTRIM$ function M Main module Math functions ABS ATN COS CVSMBF EXP LOG MKSMBF$, MKDMBF$ SIN SQR TAN MCGA adapter COLOR statement PALETTE statement SCREEN statement MDPA adapter, PALETTE statement Memory management functions FRE SETMEM statements CLEAR DEF SEG ERASE PCOPY Microsoft Binary format numbers MID$ function MID$ statement Mixed-language programming ALIAS, use of BYVAL, use of CALL, CALLS statement (non-BASIC) CDECL, use of DECLARE statement (non-BASIC) SADD function SEG, use of variable storage allocation VARPTR function MKD$ function MKDIR statement MKI$ function MKL$ function MKS$ function MKSMBF$ function MOD, module arithmetic operator Module-level code Modules Modulo arithmetic Modulus operator MulticolorGraphics Array adapterMCGA Multiline functions, run-time features, nesting Music background macro language N NAME statement Near addresses NEXT statement Notational conventions Numeric constants Numeric conversions CVD function CVI function CVL function CVS function double precision integer single precision Numeric functions CDBL CINT CLNG CSNG CVD CVI CVL CVS FIX INT RND SGN O OCT$ function Octal conversion Olivetti displays OS/2 warning ON COM statement ON ERROR statement description line 0, effect of line labels ON event statements ON KEY statement ON PEN statement ON PLAY statement ON STRIG statement ON TIMER statement ON UEVENT statement ON...GOSUB statement ON...GOTO statement OPEN COM statement OPEN statement Operators arithmetic concatenation definition functional logical precedence relational string OPTION BASE statement OUT statement Output functions LPOS POS TAB line width statements BEEP CLS LPRINT OUT PRINT PRINT # PRINT # USING PRINT USING PUT WRITE WRITE # Overflow P PAINT statement PALETTE statement PALETTE USING statement Passing arguments PCOPY statement PEEK function PEN function PEN OFF statement PEN ON statement PEN STOP statement Physical coordinates mapping to logical coordinates view Physicalviewport PLAY function PLAY OFF statement PLAY ON statement PLAY statement description VARPTR$ function,using PLAY STOP statement PMAP function POINT function POKE statement POS function Precedence of operators PRESET statement PRINT # statement PRINT statement description SPC function PRINT # USING statement PRINT USING statement Procedures Program suspension Program termination PSET statement PUBLIC symbol PUT statements FIELD statement File I/O Graphics R Random numbers Random-access files, statements and functions EOF FIELD GET KILL LOC LOCK MKD$, MKI$, MKL$, MKS$ OPEN PUT SEEK function SEEK statement storing data in buffer RANDOMIZE statement READ statement Real numbers Record elements, reference Record variables Records arrays of variable length Recursion REDIM statement description SHARED attribute variables, declaring Referencing record elements Register values, INT86OLD, INT86XOLD Relational operators REM statement RESET statement RESTORE statement RESUME NEXT statement RESUME statement alphanumeric line labels BASICA, differences from description RESUME 0, effect of RETURN statement description EXIT statement, not equivalent to GOSUB statement RIGHT$ function RMDIR statement RND function RSET statement RTRIM$ function RUN statement Run-time error messages S SADD function described movement of variables Scan codes, keyboard Scope SCREEN 10, using Screen functions CSRLIN POS SCREEN Screen statements CLS COLOR LOCATE PCOPY SCREEN VIEW PRINT Screenstatements WIDTH SEEK function statement SEG, use in DECLARE statement SELECT CASE statement Sequential files, statements and functions EOF INPUT # KILL LINE INPUT # LOC LOF OPEN PRINT # WRITE # SETMEM function described movement of variables SetUEvent routine SGN function SHARED statement described variables declaring local sharing Shared variables among modules within a module Shell escape SHELL statement Simple variables declaring location in memory SIN function Sine, SIN function Single-precision numbers converting to PRINT, displayed by types of constants SLEEP statement SOUND statement Source files SPACE$ function SPC function Special characters Spiral of Archimedes SQR function Statements ›STATIC arrays described location in memory Static arrays, ERASE statement STATIC keyword STATIC statement description variables declaring local STATIC, creating STICK function STOP statement Storage requirements, variables STR$ function STRIG function STRIG OFF statement STRIG ON statement STRIG(n) statements String concatenation constants descriptor length functions ASC CHR$ DATE$ HEX$ INPUT$ INSTR LCASE$ LEFT$ LEN LTRIM$ MID$ RIGHT$ RTRIM$ SADD SPACE$ STR$ STRING$ UCASE$ VAL operators processing statements LSET MID$ RSET variables STRING$ function String-space compaction SUB procedures DECLARE statements exit from, alternative STATIC keyword using SUB statement Subprograms CALL statement CALLS statement CHAIN statement SUB statement user library, example variables Subroutines Subscripts, specifying lower bound for maximum value for number of SWAP statement Symbolic constants CONST use of Syntax notation choices optional items placeholders System calls SYSTEM statement T TAB function TAN function Tangent, TAN function Tiling TIME$ function TIME$ statement TIMER function TIMER OFF statement TIMER ON statement TIMER STOP statement Timing function Trigonometric functions ATN COS SIN TAN TROFF statement TRON statement Type conversion logical operators rules for TYPE statements Typeface key names keywords placeholders program Type-mismatch error message Typographic conventions U UBOUND function UCASE$ function UEVENT statement UNLOCK statement User-defined data types User-defined events User-defined functions V VAL function Variable-length records Variable-length strings, location in memory Variables array automatic data type definition global function definitions subprograms using local function definitions subprograms using names length rules record scope shared variables STATIC variables storage allocation storage requirements string type-declaration suffixes VARPTR function described movement of variables VARPTR$ function described movement of variables VARSEG function described movement of variables VGA adapter COLOR statement PALETTE statement SCREEN statement VGAadapter COLOR statement Video GraphicsArray adapterVGA adapter Video memory View coordinates mapping to physical coordinates WINDOW statement VIEW PRINT statement VIEW statement W WAIT statement WEND statement WHILE statement WIDTH statement WINDOW statement WRITE # statement WRITE statement