PBASRM.WS4
----------
- "Personal BASIC Reference Manual"
First Edition: April 1983
(Retyped by Emmanuel ROCHE.)
(ROCHE> The 16 pages of errata found in the READ.ME file dated August 1983 of
Personal BASIC Version 1.1 have been incorporated in this file which is, as
far as I know, the ultimate reference.)
Foreword
--------
Personal BASIC is an interpreted programming language designed for beginners,
hobbyists, and experienced programmers alike. You need no knowledge of
computers or programming to learn Personal BASIC. The Personal BASIC language
manuals supply all the information that you need to start programming your
computer. With a little practice, you can easily write programs custom-
tailored to your personal and professional needs.
If you are a newcomer to computer programming, start with the "Personal BASIC
Tutorial". The tutorial takes you through Personal BASIC one step at a time,
teaching you the elementary lessons of programming through examples,
participation, and challenges.
As your programming skill develop, the "Personal BASIC Reference Manual"
becomes your main source of information. The Reference Manual is divided into
5 sections:
- Section 1 explains how to write, edit, and debug a Personal BASIC
program.
- Section 2 explains how to represent data in a program -- constants,
variables, and arrays.
- Section 3 explains how to work with numbers and characters in a
program.
- Section 4 explains how to put information into a program, and get
information out.
- Section 5 presents every Personal BASIC command, statement, and
function in alphabetical order, with diagrams and examples.
Personal BASIC runs under the CP/M-86, MP/M-86, and Concurrent CP/M operating
systems, based on the Intel 8086, 8088 family of microprocessors.
We, at Digital Research, are interested in your comments on programs and
documentation. Please, use the Software Performance Reports enclosed in each
product package to help us provide you with better software products.
Table of Contents
-----------------
1 Programming in Personal BASIC
1.1 Personal BASIC basics
1.2 Personal BASIC characters
1.3 Line format
1.4 The Personal BASIC program editor
1.4.1 The Edit Mode
1.4.2 Syntax errors
1.5 Program errors and debugging
1.5.1 Break Mode
2 Constants and variables
2.1 Constants
2.1.1 Numeric constants
2.1.2 String constants
2.2 Variables
2.2.1 Variable names
2.2.2 Type declarations
2.2.3 Arrays
2.3 Type conversion
2.3.1 Numeric conversion
2.3.2 String conversion
3 Expressions and operators
3.1 Numeric expressions
3.1.1 Arithmetic operators
3.1.2 Relational operators
3.1.3 Logical operators
3.1.4 Numeric functions
3.1.5 Order of execution
3.2 String expressions
3.2.1 String concatenation
3.2.2 String comparisons
3.2.3 String functions
4 Input and output
4.1 Console input
4.2 Printing
4.2.1 Formatted printing
4.2.2 String field formatting characters
4.2.3 Numeric field formatting characters
4.3 Disk files
4.3.1 File specification
4.3.2 Sequential files
4.3.3 Random files
5 Commands, statements, and functions
Appendixes
----------
A Personal BASIC keywords
B Decimal-ASCII-Hex table
C Creating a Personal BASIC system disk under CP/M-86
D Personal BASIC error messages
E The Option Table
F Machine-language linking conventions
Tables
------
1-1. Personal BASIC Special characters
1-2. EDIT subcommands
1-3. Debugging commands in Break Mode
2-1. Variable declaration characters
2-2. String conversion functions
2-3. Buffer string conversion functions
3-1. Arithmetic operators
3-2. Relational operators
3-3. Numeric functions
3-4. Order of execution for operators
3-5. String functions
4-1. Print statements
4-2. Print functions
4-3. Sequential file statements
4-4. Sequential file functions
4-5. Random file statements
4-6. Random access functions
5-1. EDIT subcommands
5-2. String field formatting characters
5-3. Numeric field formatting characters
B-1. ASCII symbols
B-2. ASCII conversion table
D-1. Personal BASIC error messages
Figures
-------
2-1. One-dimensional array
2-2. Two-dimensional array
2-3. Example of two-dimensional array
3-1. Logical operation truth tables
4-1. PRINT USING syntax
Listings
--------
2-1. Program using one-dimensional array
4-1. Program creating a sequential file
4-2. Sample sequential file program
4-3. Random file program
4-4. Sample program accessing random file data
Section 1: Programming in Personal BASIC
----------------------------------------
Personal BASIC is an interpreted high-level programming language. A high-level
language is one that is close to the natural language that you speak every
day and, therefore, easy for you to use.
Computers, however, do not speak high-level languages. They respond to low-
level machine language, which is nothing but combinations of ones and zeros.
Personal BASIC is a language that both you and your computer can understand.
Personal BASIC contains an interpreter. An interpreter is a program that takes
each line as you enter it and translates it to the computer as ones and zeros.
The interpreter takes a program that you write in Personal BASIC as its
source, and interprets and runs each line, one after another.
Personal BASIC's interpreter lets you enter a program and run it immediately,
write a line and test it on the spot. Interpreted Personal BASIC tells you
when you make an error, checks your syntax and the spelling of your commands,
and provides you with an excellent editor to change and correct your programs.
The advantages of an interpreter, combined with Personal BASIC's versatility
and completeness, make Personal BASIC an outstanding language for beginners
and experienced programmers alike.
1.1 Personal BASIC basics
-------------------------
The PBASIC.CMD file on your product disk is the Personal BASIC program. See
Appendix C for start-up procedures. Once you start Personal BASIC, it displays
the prompt Ok in the left-hand column. The Ok indicates that Personal BASIC is
at command level and ready to accept your instructions. At command level, you
can enter Personal BASIC commands or statements.
Commands work mainly on programs that you have already written. For example,
you can RUN an existing program, LIST it on the screen, or bring it into
memory with the OLD command. Because Personal BASIC processes commands
directly, you cannot use commands inside a Personal BASIC program. You cannot
assign a line number to a command and put it in the middle of a program.
Personal BASIC programs contain mostly statements and functions, although a
program can consist of just one statement. There are 2 kinds of statements in
Personal BASIC: executable and non-executable.
Executable statements perform tasks and control the flow of execution within a
program. You PRINT a message, OPEN a disk file, and GOTO another part of the
program using executable statements.
Non-executable statements provide information. The DATA statement, which lists
data to assign to variables, and the REM statement, which signals a remark
within the program, are non-executable statements. A non-executable statement
causes no program action.
Functions are predefined routines that perform tasks and return values to the
program. A function works as part of a statement, not alone. If you want to
find the square of 7, for example, you can write:
PRINT SQR(7)
or you can assign the value to a variable in an assignment statement:
Ok 10 X = SQR(7)
You can write your own functions with the DEF FN statement described in
Section 5. You cannot define a function at command level.
You can instruct Personal BASIC in direct or indirect mode. Direct mode lets
you use Personal BASIC as a calculator for quick computations. Personal BASIC
can run only one line in direct mode. To write a program in direct mode, type
the statement without a line number, then press the Carriage Return [CR] key.
Personal BASIC runs the line and returns to command level. You can write more
than one statement on a line by separating the statements with colons [:]. The
number of characters in the line cannot exceed 255.
Here is an example of a program in direct mode. The bolded print is the part
that you type; the rest is printed by the computer.
PRINT "HOW DO YOU DO?" : PRINT 2 + 2 [CR]
HOW DO YOU DO?
4
Most programs consist of many program lines. Use indirect mode to write
programs that contain more than one line. To write a program in indirect mode,
begin each line with a new line number. The line number tells Personal BASIC
that the line is part of a program. Personal BASIC stores the lines in memory
for execution later. When the program is complete, type the command RUN to
execute it. Personal BASIC returns to command level after running the program.
Here is an example of a program in indirect mode:
Ok 10 INPUT "WHAT IS YOUR NAME"; NAME$
Ok 20 PRINT "HOW DO YOU DO, "NAME$"."
Ok 30 PRINT "SHALL WE BEGIN PROGRAMMING?"
Ok RUN
WHAT IS YOUR NAME? STEVEN STARTER
HOW DO YOU DO, STEVEN STARTER.
SHALL WE BEGIN PROGRAMMING?
1.2 Personal BASIC characters
-----------------------------
The Personal BASIC character set consists of the alphabetic characters A
through Z in upper- and lower-case, the numeric characters 0 through 9, and
special characters that have meaning in Personal BASIC. The following table
lists the special characters that Personal BASIC recognizes.
Table 1-1. Personal BASIC special characters
Char. Meaning
---- -------
Blank
= Equal sign or assignment symbol
+ Plus sign or concatenation symbol
- Minus sign
* Asterisk or multiplication symbol
/ Slash or division symbol
\ Backslash or integer division symbol
^ Caret or exponentiation symbol
( Left parenthesis
) Right parenthesis
% Percent sign or integer type declaration character
# Pound (or number) sign or double precision declaration character
$ Dollar sign or string type declaration character
, Comma
. Period or decimal point
' Single quotation mark (apostrophe) or remark delimiter symbol
; Semicolon
: Colon or multiple statement separator
? Question mark
< Less than symbol or left angle bracket
> Greater than symbol or right angle bracket
" Double quotation mark or string delimiter
_ Underline
[CR] Carriage Return
[LF] Line-Feed
tab Tab character
Personal BASIC can print many other characters, even though they have no
special meaning. See Appendix B for a list of ASCII characters and their
numeric values.
1.3 Line format
---------------
Most Personal BASIC programs use the indirect mode. In indirect mode, you must
begin every line in the program with a line number. The order in which a
program line runs depends on its line number. Lines automatically re-arrange
according to their line numbers if you write the numbers out of sequence. Line
numbers show the order in which Personal BASIC stores program lines in memory;
they serve as reference points for branching and editing. Lines that begin
with a line number are called source program lines.
Line numbers consist of a one- to five-digit number ranging from 1 to 65529.
Line number 0 is allowed if you do not use the renumber feature. You can use a
period [.] instead of a line number with the commands LIST, EDIT, AUTO, and
DELETE to refer to the current program line, the line that you are working on
at the moment. Write Personal BASIC source program lines according to the
following format:
10 PRINT "WELCOME TO PERSONAL BASIC":GOTO 10 'THIS PROGRAM LOOPS
│ └──────────────┬────────────────┘ │ └────┬────────────┘
│ │ │ └──> {'Remark}
└──> Line number └──> Statement └──> {:Statement}
Personal BASIC program lines can span more than one physical line if the
length of the logical line does not exceed 255 characters. Use the Line-Feed
(Ctrl-J) key to continue a program line on the next physical line without
ending the logical line. The Line-Feed [LF] is stored as a single character in
the line.
You can write remarks to document your program. Remarks make it easier for you
to remember what your program is supposed to do. Place remarks at the end of a
program line or use the REM statement. At the end of a program line, the
remark is separated from the rest of the line by a single quotation mark ['].
The following example illustrates Personal BASIC source program lines:
Ok 10 PRINT
Ok 20 FOR I = 1 TO 5 'Loop five times
Ok 30 PRINT I; "TESTING Personal BASIC"
Ok 40 NEXT I
Ok 50 PRINT : PRINT : PRINT
Ok 60 PRINT "FINISHED!"
Ok RUN
1 TESTING Personal BASIC
2 TESTING Personal BASIC
3 TESTING Personal BASIC
4 TESTING Personal BASIC
5 TESTING Personal BASIC
FINISHED!
1.4 The Personal BASIC program editor
-------------------------------------
The Personal BASIC editor lets you enter error-free programs. You can enter
commands and program lines, delete a character, a line, or an entire program
from memory, or change an existing program one line at a time. The editor
controls the cursor, which marks the position of the next character. To use
Personal BASIC effectively, you must become familiar with the editor's
features. Section 4 in the "Personal BASIC Tutorial" presents step-by-step
instructions on program editing.
1.4.1 The Edit Mode
-------------------
To begin editing, type the command EDIT, followed by the line number of the
program line that you want to change. The following example prepares Personal
BASIC to edit program line number 50.
EDIT 50
You can use a period [.] in place of line number 50 if 50 is the last line
that you wrote. The period tells Personal BASIC that you want to edit the
current program line. You can edit only one program line at a time.
Once in the edit mode, Personal BASIC displays the line that you request. The
prompt Ed indicates that Personal BASIC is in edit mode. Personal BASIC places
the cursor on the edit line, beneath the first character of the program line
that follows the line number, as shown:
Ok EDIT 50 Edit command
50 PRINT "The average is";AVG Program line
Ed _ Edit line
To edit, move the cursor along the edit line to the point in the program line
where you want to make a change. Then, use any of the EDIT subcommands. The
Personal BASIC edit subcommands perform the following tasks:
- Move the cursor to the right or left
- Insert characters
- Delete characters
- Search for characters
- Replace characters
- Exit and re-enter edit mode
Use the spacebar to move the cursor to the right. Use the BackSpace [BS],
RubOut, or Ctrl-H to move the cursor to the left. You can move any number of
characters to the left by typing a number and one backspace. The EDIT
subcommands R and L move the cursor to the rightmost and leftmost position in
the edit line, respectively.
Type a Carriage Return [CR] to save any editing changes that you make using
EDIT subcommands. The editor returns Personal BASIC to command level. The
following table lists the 17 EDIT subcommands.
Table 1-2. EDIT subcommands
Subcom. Description
------- -----------
A Instructs the editor to ignore all changes made to the current line,
and to place the cursor at the beginning of the edit line. Enables you
to start editing a line over again. This command is valid only if
there is no other subcommand on the line.
B Brings the cursor to the beginning of a logical line.
[n]C Deletes the character that appears directly above it in the program
line, and inserts the character that you specify to the right of the
C. nC deletes n characters, and inserts all characters after the C.
[n]D Deletes the character that appears directly above it in the edit line.
E Saves all changes and returns Personal BASIC to command level. Works
like a Carriage Return. This command is only valid if it is the only
subcommand on the line.
[ESC] Entered while typing in a program line, [ESC] drops Personal BASIC
into Edit mode. Used during insert mode, [ESC] ends insert mode
without ending the command line.
H Deletes all characters in the program line up to the next Line-Feed
[LF], then automatically activates the insert subcommand: I.
I Inserts characters into the program line, starting at the point
immediately above the cursor position. All characters up to the next
[ESC] or [CR] are inserted, including Line-Feeds. I[LF] works in the
way, but starts by inserting a Line-Feed. [ESC] ends insert mode
without ending the command line.
K Works much like subcommand S. Searches the program line for a
specified character, and positions the cursor directly beneath that
character. However, the editor deletes all characters up to the
specified character. Specify the character in the edit line
immediately after the K. If the character is not found, the cursor
does not move from the original position, and no characters are
deleted.
L Repositions the cursor below the leftmost character in the program
line.
[LF] To edit succeeding lines of multi-line statements, press [LF] before
entering insert mode. This brings you down to the next physical line.
Q Instructs the editor to ignore all changes made to the current line,
quits editing, and returns Personal BASIC to command level. This
command is valid only if it is the only subcommand on the line.
R Moves the cursor below an imaginary character one to the right of the
rightmost character in the program line.
[n]S Searches the program line for a specified character, and positions the
cursor under the character. Specify the character in the edit line
immediately after the S. If the character is not found, the cursor
does not move from the original position. A command like 99SX finds
the last occurrence of X in the line, and the cursor stays there.
U Moves the cursor back to the previous physical line.
X Positions the cursor at the end of a physical line, up to a Line-Feed,
and enters insert mode. X[LF] inserts a Line-Feed first. Subsequent
characters appear on a new physical line.
Z Deletes a Line-Feed [LF]. Merges 2 physical lines.
1.4.2 Syntax errors
-------------------
Syntax errors are usually typing mistakes, such as misspelled or misplaced
keywords, or misused characters. Personal BASIC detects syntax errors and
reports them, as shown in the following example:
Ok 10 PRINT "START"
Ok 20 PRINT
Ok 30 PRNIT "Testing Personal BASIC"
^
Something is wrong
Ok EDIT 30
30 PRNIT "Testing Personal BASIC"
Ed D IN
30 PRINT "Testing Personal BASIC"
Ed _
Personal BASIC detects the misspelled keyword "PRINT" in line 30 and puts a
caret [^] under the place where you made a mistake. To correct the error,
enter the edit mode by typing EDIT and the line number, or EDIT and a period
[.] if you want to edit the line that you just typed. The editor prints the
line containing the error, and places the cursor directly beneath the first
character that follows the line number. At this point, you can space forward
to the N in PRNIT, delete it with subcommand D, space to the T, and use
subcommand I to insert an N before the T. For short lines, it is sometimes
more efficient to retype the line from the beginning.
1.5 Program errors and debugging
--------------------------------
Program errors, or bugs, are common. Even the most experienced programmers
spend a lot of time finding and fixing errors that make their programs fail.
These errors might be mistakes in program flow, such as loops that do not end,
branches to statements that do not exist, or improper data type assignments,
such as assigning a person's name to a numeric variable. Personal BASIC
provides a break mode and a complete set of debugging command to helps you
find program errors.
1.5.1 Break Mode
----------------
In break mode, you can suspend execution anywhere in the program. To enter
break mode, type the BREAK command after the Ok prompt, and run the program.
Personal BASIC indicates break mode with the prompt Br. See the "Personal
BASIC Tutorial", Section 11.1, for a simple and thorough explanation of
debugging and break mode.
Ctrl-C is useful for breaking execution of an endless loop. The following
example shows a program that is interrupted by a break. Notice the Br prompt.
Ok RUN
10
...
100
-- Break -- at line 110
Br _
You can stop program execution wherever you want by using BREAK to set a
breakpoint at a given line number. You can set breakpoints from command level
or in break mode. The following example sets a breakpoint from command level
at program line 40:
Ok BREAK 40
If you omit the line number after the keyword BREAK, Personal BASIC sets a
breakpoint at every line in the program. Personal BASIC marks breakpoints in
the program listing with a lower-case b, as shown in the next example:
Ok LIST
10 PRINT:PRINT
20 FOR I% = 1 TO 10
30 PRINT "TESTING Personal BASIC!"
b 40 NEXT I%
50 END
If you run the preceding program after entering the BREAK 40 command,
execution breaks at line 40. Personal BASIC prints a b before the program line
where the break occurs, as shown in the following example:
Ok BREAK 40
Ok RUN
TESTING Personal BASIC!
b 40 NEXT I%
Br _
Once in break mode, you can use the debugging commands in Table 1-3 to monitor
the flow of execution. See Section 5 for more information and examples of each
command.
Table 1-3. Debugging commands in break mode
Command Explanation
------- -----------
CONT Resumes program execution following a break. You cannot use the CONT
command from command level.
STEP Lets you execute a program one line at a time. Each Carriage Return
[CR] executes the next line, prints the line and the output generated
by the line.
UNBREAK Removes all breakpoints from a program.
TRACE Prints each program line with its output, but does not stop program
execution. In other words, execution does not break unless you type a
Ctrl-C. Personal BASIC indicates tracing in the program listing with a
lower-case t.
UNTRACE Turns off the TRACE facility.
TRON Prints each program line number in the order it is run with the output
from each corresponding line. Line numbers are enclosed in square
brackets: [10].
TROFF Turns off the TRON facility.
FOLLOW Keeps track of all program variables as the value of each variable
changes. FOLLOW lists the value of each variable every time that value
changes. FOLLOW prints the variable name, the value of the variable,
and the line number where the value changes.
UNFOLLOW Turns off the FOLLOW facility.
You can use all of the commands listed in Table 1-3 from command level and in
break mode, except for CONT.
Section 2: Constants and variables
----------------------------------
Computers work with several types of data. This data consists of characters,
such as John Public, or numbers, such as 99. The letters and characters that
you use as text in your program are called strings, or string data. For
example, the address of an employee in a program that maintains personnel
information is a string.
Personal BASIC recognizes 4 data types. Strings and numbers are the 2 main
types of data. Numeric data is divided further into 3 types. The 4 data types
are:
- strings
- single-precision real numbers
- double-precision real numbers
- integers
Strings can consist of any combination of characters, including digits. You
can write a social security number in a personnel program as a string. If you
write it with dashes [-], as in 546-67-7845, you have to write it as a string,
because numbers cannot contain dashes.
Numbers, or numeric data, are the values that you use to make calculations in
a program. For example, an employee's net salary is numeric data. You
calculate it using other numeric data, such as gross salary and taxes. You can
represent the salary as a string. If you do, you cannot use it in
calculations. The computer treats it as a string of characters, not a number.
Using strings of numbers for arithmetic would be like subtracting the string
John from the string Bill.
Personal BASIC automatically converts one numeric type to another in programs.
You can also convert string and numeric data types by means of conversion
functions. You can represent any type of data in a Personal BASIC program as a
constant or a variable, and you can group the data in dynamic, multi-
dimensional arrays, as explained in Section 2.2.3.
2.1 Constants
-------------
Constants are the values that a program uses and processes. A constant is a
piece of data that does not change during the execution of a program.
For example, to write a program that calculates the area of a circle, you need
to use the value PI, or 3.14159. The value of PI never changes; it is a
constant. In Personal BASIC, you can give PI a name, such as X. The name for
PI might change. It might be X at one point, and X1 at another. But the value
behind that name, the value PI, is always the same.
In Personal BASIC, you can write constants that are numeric, such as PI, or
constants that are strings of characters, such as "Enter your name and
address". There are formal rules for writing both numeric and string
constants.
2.1.1 Numeric constants
-----------------------
Numeric constants, the numbers that you use as values in a program, can be
positive or negative. You write them without commas [,]: for example, 5,000 is
written 5000. There are 3 kinds of numeric constants in Personal BASIC:
- single-precision real numbers
- double-precision real numbers
- integers
A real number is a number that contains a decimal point [.] and a fraction.
Personal BASIC automatically converts whole numbers, or integers, to real
numbers where necessary.
You can write all real numbers in Personal BASIC in exponential form.
Exponential form is an especially convenient notation for very large and very
small numbers. Scientists use it as shorthand, to avoid writing a long series
of zeros. A number in exponential form consists of:
- a positive or negative real number (the mantissa)
- E or D (letters for single- and double-precision)
- a positive or negative whole number from -38 to +38 (the exponent)
The format for exponential notation is:
(mantissa)(E or D)(exponent)
Examples:
2E+2
2D+20
33E+5
3345D-5
.17E7
33.45D-5
There is an implied decimal point [.] after the mantissa. The exponent tells
you how many places to the right or left to move the decimal point in order to
get the value of the number in standard notation. A positive exponent gives
the number of places to move the decimal point to the right. A negative
exponent gives the number of places to move the decimal point to the left.
For example, 45E+4 tells you to move the decimal point 4 places to the right.
The number 45E+4 in standard notation is 450000. The decimal point moves 4
places to the right, and the gap is filled with zeros. The value 45E-4 in
standard notation is .0045. You move the decimal 4 places to the left. Do not
confuse the sign of the exponent with the sign of the mantissa.
The following examples lists some numbers in exponential notation and their
standard notation equivalents:
2E+2 = 200.
2D+10 = 20000000000.
33E+5 = 3300000.
3345D-5 = .03345
12345.678D-3 = 12.345678
-12345.678D+3 = -12345678.
Remember that there are 2 types of real numbers: single-precision and double-
precision. Double-precision numbers have a greater degree of accuracy than
single-precision numbers.
Single-precision numbers are accurate up to 6.8 digits internally, but print
with 6 digits of accuracy. Double-precision reals are accurate up to 15 digits
and print with 15 digits of accuracy.
You specify a number's degree of accuracy according to your needs and the
storage available to you -- double-precision reals take more room in memory.
If you do not dictate a number's precision, it is single-precision by default.
In exponential form, signify that the number is single precision by using E or
e after the mantissa. If the number is double precision, use D or d.
Single-precision numbers have one or more of the following characteristics:
- 6 or fewer digits
- E or e in the exponential form
- a trailing exclamation mark [!]
Double-precision numbers have one or more of the following characteristics:
- 7 or more digits
- D or d in the exponential form
- a trailing pound sign [#]
A real number might have characteristics of both types. For example, the
number 55D+2 is only 4 digits, but include a D. In such cases, the letter in
the exponential form overrules the length. So, 55D+2 is double precision. If a
number is 20 digits long but contains an E, it truncates to single precision.
The type declaration characters ! and # overrule both length and exponential
letter. The number 5# is double precision.
The following are single-precision numbers:
34.6! 23.9847423E+12 98.23023243!
The following are double-precision numbers:
34.6# 354634.3434D-3 43.54D-2
In addition to single- and double-precision reals, Personal BASIC accepts
integers as numeric constant data. An integer is a whole number, without a
fraction or a decimal point. Personal BASIC integers must be in the range -
32768 to +32767.
You can write integers in decimal notation (base 10), or in octal notation
(base 8), or in hexadecimal notation (base 16). For hexadecimal integers, the
letters A-F, in upper- or lower-case, stand for the digits 10 through 15. To
write integers in hexadecimal notation, prefix them with &H. To write integers
in octal notation, prefix them with &O, or simply &.
Here are some examples of hexadecimal and octal notation:
Hexadecimal notation:
&H234 (equals 564 in decimal)
&H234B (equals 9035 in decimal)
Octal notation:
&O567 (equals 375 in decimal)
&537 (equals 351 in decimal)
2.1.2 String constants
----------------------
A string constant is a character, or succession of characters, enclosed by
double quotation marks ["]. Strings constants cannot exceed 255 characters.
Strings can contain only the characters listed in Table 1-1. You can also
write strings with no characters. Two double adjacent quotation marks [""]
form a null string. A null string contains no characters, not even a space.
If you want to write a double quotation mark within a string, write it twice.
The following are examples of string constants.
"Please enter your name."
"9 to 5 "
"*$@!)"
"" (represents a null string)
"Today's story: Faulkner's ""The Bear"""
2.2 Variables
-------------
A variable is a name for a constant value. A variable can assume the value of
many different constants during the execution of a program. It is like a
mailbox that holds different pieces of mail on different days. A variable can
be assigned only one constant at a time.
You can write statements to assign constant values to variables, or a variable
can assume the result of some calculation or function in the program. The
initial value of a numeric variable is zero. The initial value of a string
variable is null.
2.2.1 Variable names
--------------------
A variable name can be as long as you like, but only the first 31 characters
are meaningful for distinguishing one name from another. Variable names must
start with a letter. They can contain letters, numbers, and decimal points
[.]. You cannot use spaces in a variable name.
Variables that represent strings must end with a string type-declaration
character. There are also type-declaration characters for numbers, but they
are optional. Type-declaration characters are described in Section 2.2.2.
If you write your own functions in Personal BASIC, the variable names that you
assign them must begin with FN. See the DEF FN statement in Section 5 to learn
how to write your own functions.
A variable name cannot be a Personal BASIC keyword. Keywords include all
Personal BASIC commands, statements, functions, and operators, such as TRON,
END, INT, and OLD. You can embed keywords in variables, however: for example,
PRINT1 or BLIST are legal variable names. See Appendix A for a list of
Personal BASIC keywords.
The following are valid variable names:
A! X99 ZIPCODE% Childrens.Names$
Printed% CHANGE.IN.VELOCITY# RADIUS! TOTAL%
The following are invalid variable names:
CHILDREN'S.AGES (The apostrophe ['] starts a remark)
Playing Field$ (Contains a blank)
1st.value (Start with a number)
2.2.2 Type declarations
-----------------------
Type-declaration characters determine the kind of constants a variable can
represent. You must declare string variables as strings. Numeric types are
optional. Declare a type by ending the variable name with a type-declaration
character. For example, in BIRTHPLACE$, the $ indicates that the variable
BIRTHPLACE is a string variable. Table 2-1 shows the Personal BASIC type-
declaration characters for variables.
Table 2-1. variable declaration characters
Char. Variable type Example
----- ------------- -------
$ String NAME$
% Integer RECORD.NUMBER%
! Single precision TOTAL.PROFIT!
# Double precision DIAMETER#
All string variables must end with a dollar sign [$]. If you omit the
declaration character at the end of a variable name, Personal BASIC assumes
that the variable stands for a single-precision real number.
You can also use declaration statements to specify variable data types. The
following declaration statements are described in more detail in Section 5:
- The DEFSTR statement declares string variables.
- The DEFINT statement declares integer variables.
- The DEFSNG statement declares single-precision variables.
- The DEFDBL statement declares double-precision variables.
If there is a conflict between statement type declarations and character type
declarations, the type that you declare using trailing characters on the
variable overrides the type that you gave in a type-declaration statement.
2.2.3 Arrays
------------
An array is a table of values referenced by the same variable name. You can
picture an array as a series of numbered pigeonholes or cells. An array of
colors with 4 cells looks like this:
┌───────┬────────┬──────────┬──────────┐
│ "RED" │ "BLUE" │ "YELLOW" │ "VIOLET" │
└───────┴────────┴──────────┴──────────┘
(0) (1) (2) (3)
Figure 2-1. One-dimensional array
You reference the elements in the array by array name and cell number, or
subscript. Subscripts are numeric expressions. For example, the cell with
subscript 3 of COLORS$ contains the element "VIOLET". To refer to it, you
write COLORS$(3).
COLORS$ is one-dimensional, but arrays can have more than one dimension.
COLORS$ as a two-dimensional array looks like this:
┌──────────┬─────────┐
Row 0 │ "GRAY" │ "GREEN" │
├───(0,0)──┼──(0,1)──┤
Row 1 │ "ORANGE" │ "BROWN" │
└───(1,0)──┴──(1,1)──┘
Column 0 Column 1
Figure 2-2. Two-dimensional array
Notice that the first number in the subscript refers to the row, the second to
the column. In a three-dimensional array, which would look like a cube, the
order is rows, columns, planes.
The elements in an array can be integers or single- or double-precision reals
or strings, but they must all have the type of the array variable that names
them. For example, all the elements in COLORS$ are string values. All the
elements in CHART% must be integers.
Array variables look like regular variables, with an added subscript list in
parentheses ["(" and ")"]. For example:
y$ (i$,j$,k$)
address% (5)
grade! (x,y,z)
Anything you can assign to a variable, you can assign to an array element.
Anywhere you can use a simple variable, you can use an array reference.
A(5) = 6
Q = J(4) + 3
Y% * WAGES! = COMPENSATION!(3,4)
An array subscript can be an expression, such as j(x+y) = 3. Integer
expressions are the most efficient subscripts, as real convert to the nearest
integer, anyway.
The subscript numbers in an array have an assumed base of 0 for each
dimension, which means that the elements in array X(3) are numbered 0, 1, 2,
and 3. If you want an array to begin numbering at 1, use an OPTION BASE
statement before the DIM statement declaring that array. See Section 5.
You use the DIM statement to set the number of dimensions and the number of
elements in each array. The fewer elements you have in each dimension, the
more dimensions you can have, and vice versa; the theoretical limits are 1
element and 15 dimensions. The syntax for a DIM statement is:
DIM (array variable name)'(subscript list)'
The following example establishes an array called SUBDIVISIONS with 2
dimensions.
DIM SUBDIVISIONS%(5,6)
There are 6 elements in the first dimension, and 7 elements in the second
dimension (remember that the base is zero). See the DIM statement in Section 5
for more information on DIM.
You need not use DIM to declare an array's dimensions. The default array
subscript range is 0 to 10 or 1 to 10, depending upon your option base. The
default number of dimensions allowed is 4 for integers, and 3 for strings and
single- and double-precision reals. The true maximum number of elements per
dimension for any data type is limited by the amount of available memory.
Elements of the different data types occupy different amounts of space:
- integer elements occupy 2 bytes
- single-precision number elements occupy 4 bytes
- double-precision number elements occupy 8 bytes
- string elements occupy 6 bytes
Personal BASIC arrays are dynamic, which means that you can declare an array
with DIM, erase it, and re-declare it later in the program, using the old name
with new dimensions. If you have a subroutine that references an array, you
can change the size of the array whenever you wish without changing the
reference in the subroutine. Dynamic arrays also let you use a variable to
dimension an array. Thus, you need not know the size of an array when you
dimension it.
10 INPUT "SIZE";N
20 DIM A(N)
...
1000 INPUT "NEW SIZE";N
1010 ERASE A
1020 DIM A(N)
This example uses a variable, N, that you enter at the keyboard in response to
an INPUT request. The number that you give for N can be different every time
that you run the program. The DIM statement uses N to dimension the array
instead of a constant number, so that you do not have to change the DIM
statement with every execution of the program. Halfway through the program,
you input a new number for the array's dimensions. Because Personal BASIC
arrays are dynamic, you can assign a new constant value to N, erase the old
array, and restate the array with DIM, the old array name, and the new value
for N.
You can access the elements in an array using a loop. The following FOR-NEXT
loop accesses all 4 elements in the COLORS$ array, and prints the 4 strings
"RED", "YELLOW", "BLUE", and "VIOLET".
Ok 10 FOR X% = 0 TO 3
Ok 20 PRINT COLORS$ (X%)
Ok 30 NEXT X%
Ok 40 END
The example program in Listing 2-1 creates an array called TEMPERATURE% to
calculate average daily temperatures for a week. TEMPERATURE% is a two-
dimensional integer array with 7 elements in the first dimension and 3 in the
second dimension.
The TEMPERATURE% array organizes temperature readings taken 3 times a day for
one week. The 7 elements in the first dimension correspond to the days in a
week. The 3 elements in the second dimension correspond to the 3 temperature
readings taken each day. The array holds a total of 21 temperature readings.
Try the program on your computer, and enter some sample temperature readings
to see how a multi-dimensional array works.
Ok 10 DIM TEMPERATURE% (6,2)
Ok 20 FOR I% = 0 TO 6
Ok 30 FOR J% = 0 TO 2
Ok 40 INPUT "Enter degree value", VAL%
Ok 50 TEMPERATURE% (I%, j%) = VAL%
Ok 60 NEXT J%
Ok 70 NEXT I%
Ok 80 FOR K% = 0 TO 6
Ok 90 FOR L% = 0 TO 2
Ok 100 TOTAL% = TOTAL% + TEMPERATURE% (K%, L%)
Ok 110 NEXT L%
Ok 120 AVERAGE% = TOTAL% / 3
Ok 130 PRINT "Average temp for day" ;K% ;"is" ;AVERAGE%
Ok 140 NEXT K%
Ok 150 END
Listing 2-1. Program using multi-dimensional array
(ROCHE> This example program is indented (sort of...). However, the only way I
manage to indent a Personal BASIC program is when using Line-Feeds (Ctrl-J) to
continue the logical line on the next physical line. Only then does Personal
BASIC keep the spaces that I insert. (It does not accept tabs [HT], too...)
One problem is that those lines cannot contain more than 255 characters...
Another is that you must not forget the colon [:], else Personal BASIC will
reject the line as an error...)
Line 130 prints the average temperature for each day, and indicates a day
number ranging from 0 to 6. Day 0 refers to Sunday, day 1 refers to Monday,
and so on. You can reset the day numbers any way you like. Personal BASIC
organizes a two-dimensional array like a grid, with the first dimension the
horizontal coordinate, or row, and the second dimension the vertical
coordinate, or column.
Figure 2-3 represents array TEMPERATURE% in the computer's memory.
(0) (1) (2)
┌─────────┬─────────┬─────────┐
(0) │ (0,0) │ (0,1) │ (0,2) │ SUN
├─────────┼─────────┼─────────┤
(1) │ (1,0) │ (1,1) │ (1,2) │ MON
├─────────┼─────────┼─────────┤
(2) │ (2,0) │ (2,1) │ (2,2) │ TUE
├─────────┼─────────┼─────────┤
(3) │ (3,0) │ (3,1) │ (3,2) │ WED
├─────────┼─────────┼─────────┤
(4) │ (4,0) │ (4,1) │ (4,2) │ THU
├─────────┼─────────┼─────────┤
(5) │ (5,0) │ (5,1) │ (5,2) │ FRI
├─────────┼─────────┼─────────┤
(6) │ (6,0) │ (6,1) │ (6,2) │ SAT
└─────────┴─────────┴─────────┘
6 A.M. 2 P.M. 10 P.M.
Figure 2-3. Two-dimensional array
Each temperature reading has a unique coordinate. For example, the 2 P.M.
temperature reading for Thursday has the array coordinates (4,1). Every
dimension that you add to an array creates an additional category or criterion
for the grouping of data.
2.3 Type conversion
-------------------
The type of a numeric constant converts automatically to the type of the
variable that you assign it. Real numbers convert to integers if you assign
them to an integer variable, for example. Strings do not automatically convert
to numbers, however, nor numbers to strings. To convert between numbers and
strings, you must use conversion functions. See Section 2.3.2 for a
description of string and numeric conversions.
2.3.1 Numeric conversion
------------------------
If you assign a number of one data type to a numeric variable of another type,
Personal BASIC stores the value using the type of the variable. In other
words, Personal BASIC automatically converts the number's data type to the
data type of the variable. For example, the following statements assign real
numbers to integer variables:
I% = 15.25 (Converts to 15)
J% = 33.56 (Converts to 34)
K% = 199.99 (Converts to 200)
Note that Personal BASIC does not truncate the digits after the decimal point
[.], but rounds to the nearest whole number instead.
When you assign a double-precision constant to a single-precision variable,
Personal BASIC rounds to the nearest digit. The following examples assign
double-precision constants to single-precision variables:
X! = 18.333346998999 (Converts to 18.3333)
Y! = 556.89755578884 (Converts to 556.898)
If you assign a single-precision constant to a double-precision variable,
Personal BASIC converts the data type of the value to double precision, but
the result is only as accurate as the original single-precision value.
Personal BASIC provides the following functions to convert between the
different numeric data types. See Section 5 for more detailed explanations and
examples of each function.
- The CDBL function converts a number to double precision.
- The CINT function converts a number to an integer, by rounding.
- The CSNG function converts a number to single-precision.
- The FIX function truncates a number to the integer portion.
- The INT function returns the largest integer that is less than or
equal to a specified number.
2.3.2 String conversion
-----------------------
Personal BASIC provides the following functions to convert strings to numbers,
and to convert ASCII characters to their numeric values. See Section 5 for
more detailed explanations and examples of each function.
Table 2-2. String conversion functions
Func. Explanation
----- -----------
ASC Returns the ASCII value of the first character in a string
CHR$ Returns the ASCII character that corresponds to a given
numeric value.
FLOAT Converts an integer to a single-precision real number
HEX$ Returns the hexadecimal equivalent of a specified decimal
number as a string.
OCT$ Returns the octal equivalent of a specified decimal number as
a string.
STR$ Returns a specified number as a string
VAL Returns the numeric value of a string
Personal BASIC supports conversion functions for use with random-access files.
Because random-access files work only with strings, you need to convert
numeric variables to buffer strings if you want to store them on a disk. To
retrieve them and use them in a program, convert them back into numbers. Table
2-3 lists the conversion functions for file buffer strings. These functions
are sometimes called mapping functions. See Section 5 for further information.
Table 2-3. Buffer string conversion functions
Func. Explanation
----- -----------
CVD Converts a string to a double-precision real
CVI Converts a string to an integer
CVS Converts a string to a single-precision real
MKD$ Converts a double-precision real to a string
MKI$ Converts an integer to a string
MKS$ Converts a single-precision real to a string
Section 3: Expressions and operators
------------------------------------
There are many ways to represent data in a computer program. For instance, you
can write the number ten as 10, 5 + 5, 12 - 2, 550/50-1, or I%, if you assign
10 to the variable I%. All of these groups of symbols and data express the
number 10. Each of these groups is an expression.
An expression is a combination of symbols, such as + and -, and data, such as
5 and I%, that expresses a single value. The value can be a number, like 10,
or a string, like ten. Finding the value is called evaluating the expression.
The symbols that tell you to add or subtract or multiply are called operators.
An operator indicates a kind of calculation, such as division, or a condition,
such as inequality. The strings and numbers they work on are called operands.
In the expression 5 + 5, the + is an operator and the fives are operands. The
expression evaluates to, or equals, 10.
You can write expressions using strings, numbers, or variables as operands.
Five + five, 5 + 5, and 5 + X are all valid. Personal BASIC expressions are
divided into 2 classes: numeric and string. 5 + 5 is a numeric expression;
Five + Five is a string expression. There are several kinds of expressions
within each class.
3.1 Numeric expressions
-----------------------
A numeric expression consists of at least one number and at least one numeric
operator. The numbers that you use can be reals, such as 12.3, or integers,
such as 12 (see Section 2.1.1). You can use constants or variables for
numbers.
Numeric operators are divided into 4 types:
- arithmetic
- relational
- logical
- functional
3.1.1 Arithmetic operators
--------------------------
The operators that perform arithmetic in Personal BASIC are listed in Table 3-
1. Personal BASIC integer division and modulus are explained in detail below.
Table 3-1. Arithmetic operators
Symbol Name Example
------ ---- -------
+ Addition X + Y
- Subtraction X - Y
* Multiplication X * Y
/ Division X / Y
\ Integer division X \ Y
MOD Modulus X MOD Y
^ Exponentiation X ^ Y
Integer division, unlike regular division, rounds the operands to integers
before dividing, and truncates the quotient to a whole number. Division by
zero is invalid.
The MOD operator is another integer function. It yields the remainder of an
integer division. MOD drops any fraction after the decimal point [.].
Integer division Modulus
45 \ 8 = 5 45 MOD 8 = 5
19.23 \ 5.25 = 3 19.23 MOD 5.25 = 4
19.50 \ 5.25 = 4 19.50 MOD 5.25 = 0
3.1.2 Relational operators
--------------------------
Every comparison is a statement that is either true or false. To say that an
acorn is smaller than an oak, for example, is to compare 2 values, the size of
an acorn and the size of an oak, and to state a relationship between them. In
this case, the statement is true.
In Personal BASIC, you can compare values by means of relational operators.
Relational operators make statements of comparison that are either true or
false. If a relational statement is true, its value is -1. If false, its value
is 0. For example, .50 > 1 = 0 (false). 50 * 4 < 400 = -1 (true). Used with
the IF and GOTO statements, relational operators commonly control program
flow.
9 > 10 returns 0 (0 = false)
9 < 10 returns -1 (-1 = true)
IF X * 5 <= 5^3 THEN GOTO 100
IF A! / 8 = 7 MOD X THEN PRINT Z$
Table 3-2. Relational operators
Symbol Name Example
------ ---- -------
= Equals X = Y
<> Does not equal X <> Y
< Is less than X < Y
> Is greater than X > Y
<= Is less than or equal to X <= Y
>= Is greater than or equal to X >= Y
The logical expression
IF (logical expression) THEN ...
should be evaluated only so far as is necessary to determine the result of the
expression. In the following example:
IF A% > 0 AND A% <= 10 AND B(A%) > 5 THEN ...
array elements outside the limits 1 to 10 should never be accessed, because if
A% <= 0, the whole expression is known to be false.
However, this is not the case. All the subexpressions in a logical expression
are always evaluated, which could give rise to a "Subscript refers to element
outside the array" error in the above example.
3.1.3 Logical operators
-----------------------
Logical operators perform another kind of comparison. Like relational
operators, they assert a relationship between 2 values, and that relationship
is either true or false. But logical operators are not concerned with numeric
values. They compare bit patterns.
Every piece of data that you put into a computer, including decimal numbers,
is stored in binary form. The number 8, for example, might be stored as
00001000. Every one of those digits is a bit (bit = Binary digIT: 0 or 1), and
the sequence of zeros and ones creates a pattern of bits. A logical operator
lines up the bit pattern of one binary value with the bit pattern of another:
00010000
01010101
If then tests each column of ones and zeros. The ones and zeros are not
important as numbers; rather, 1 stands for true and 0 stands for false. The
operator compares the columns to find whether each combination of bits yields
a true or false bit. As a result, a new bit pattern emerges.
An operator tests these bit patterns according to its truth table. There is a
truth table for each of the 6 logical operators. Truth tables are charts that
predict whether a given combination of 0s and 1s, or trues and falses, has a
true or a false value. The new bit pattern is made up of ones and zeros. If it
is all zeros, the truth value of the new pattern is false (0). If it contains
a one or ones, its truth value is true (1).
Notice that the truth values that logical operators return do not correspond
to the conventional symbols for true (-1) and false (0) that relational
operators return (see Section 3.1.2). Logical operators return 1 for true
because they work with bits to form new combination of bits. A single bit can
never have any other value than one or zero, meaning on or off, true or false.
The truth value of a new bit is one or zero, and the truth value of a new bit
pattern is one or zero.
Here is an example of a logical operation using the OR operator to compare 2
bit patterns. The truth table for OR is:
OR│ X Y X OR Y
├───────────────
│ 0 0 0
│ 0 1 1
│ 1 0 1
│ 1 1 1
We make the following comparison:
0 1 0 0 0 0 0 1 (bit pattern)
OR (logical operator)
0 0 0 0 0 0 0 1 (bit pattern)
Starting from the left column, compare the first bit of one pattern with the
first bit of the other. According to the truth table of the logical operator
OR, 0 OR 0 = 0. The first bit of the new bit pattern is zero.
In the second position, we have 1 and 0. The OR truth table indicates that 1
OR 0 equals 1. Therefore, the second bit of the pattern that results from this
operation is a 1.
In the third through seventh positions, both the first and second bit patterns
have zeros. Because 0 OR 0 equals 0, the new pattern also contains zeros in
the third through seventh positions.
There are 1s in the last place of both bit patterns. Looking at the OR truth
table, 1 OR 1 = 1.
The entire operation looks like this:
0 1 0 0 0 0 0 1
OR OR OR OR OR OR OR OR
0 0 0 0 0 0 0 1
── ── ── ── ── ── ── ──
0 1 0 0 0 0 0 1
The resulting bit pattern, because it contains 1s, has a value of true.
Notice that the new bit pattern is the same as the first bit pattern. You can
read these patterns as binary digits or control characters or ASCII codes,
depending upon context. But, for the purpose of logical operations, they are
no more than bit patterns. The important thing is whether their truth values
are true or false.
Logical operations are useful decision-making tools. They control program flow
and structure, and make assignments:
Ok 120 IF A OR B THEN X = Y
Ok 130 IF NOT A THEN GOTO 50
Logical operators look more like words than mathematical symbols. But they
operate just as any other mathematical symbol. Although the truth tables use 1
and 0, they are easier to read if you mentally substitute true and false. For
example:
NOT│ X NOT X
├───────────────
│ false true
│ true false
The NOT operator asserts that, if X is false, then NOT X is true; and, if X is
true, then NOT X must be false.
Here are the logical operators and their truth tables. In these tables, X and
Y are not bit patterns. They are single bits. Logical operators always compare
bit X with bit Y, one column at a time.
NOT│ X NOT X
├───────────────
│ 0 1
│ 1 0
AND│ X Y X AND Y
├───────────────
│ 0 0 0
│ 0 1 0
│ 1 0 0
│ 1 1 1
OR│ X Y X OR Y
├───────────────
│ 0 0 0
│ 0 1 1
│ 1 0 1
│ 1 1 1
XOR│ X Y X XOR Y
├───────────────
│ 0 0 0
│ 0 1 1
│ 1 0 1
│ 1 1 0
IMP│ X Y X IMP Y
├───────────────
│ 0 0 1
│ 0 1 1
│ 1 0 0
│ 1 1 1
EQV│ X Y X EQV Y
├───────────────
│ 0 0 1
│ 0 1 0
│ 1 0 0
│ 1 1 1
Figure 3-1. Logical operation truth tables
In the preceding figure, the following is true:
- The NOT operator is simple contradiction: if X is not true, then it is
false.
- The AND operator is true if both X and Y are true.
- The OR operator is true if either X or Y is true.
- XOR is the exclusive OR. XOR results in true when either X or Y is
true, but not both.
- IMP is the abbreviation for implies. IMP treats X as a premise and Y
as a conclusion. Logically, it is impossible for true premises to lead
to a false conclusion. You can have false premises and a true
conclusion, false premises and a false conclusion, or true premises
and a true conclusion. For this reason, IMP is true except where the
premise is true and the conclusion is false.
- EQV stands for equivalent. It is true when X and Y are the same.
3.1.4 Numeric functions
-----------------------
The numeric functions in Table 3-3 are built into Personal BASIC. You do not
have to write your own functions to make these computations. You can use the
functions anywhere a numeric operator is used in an expression.
Table 3-3. Numeric functions
Func. Explanation
----- -----------
ABS Returns the absolute value of a number
ATN Returns the arctangent of a number in radians
COS Returns the cosine of a number in radians
EXP Returns e to the power of a given value
LOG Returns the natural logarithm of a number
LOG10 Returns the base-10 logarithm of a number
RND Generates a sequence of random numbers
SIN Returns the sine of a number in radians
SQR Returns the square root of a number
TAN Returns the tangent of a number in radians
3.1.5 Order of execution
------------------------
Numeric expressions can contain a combination of arithmetic, relational,
logical, and functional operators, or only one operator. For expressions with
more than one operator, Table 3-4 gives the order in which they execute.
Expressions are evaluated from left to right. If two operators have the same
precedence, the one on the left is evaluated first.
Table 3-4. Order of execution for operators
Operator Explanation
-------- -----------
( ) Items in parentheses have highest priority
^ Exponentiation
- Negation
*, / Multiplication, floating-point division
\ Integer division
MOD Modulus
+, - Addition, subtraction
=, <> Relational operators
<, >
<=, >=
NOT, AND Logical operators, in order given
OR, XOR
IMP, EQV
3.2 String expressions
----------------------
The second class of expressions in Personal BASIC is string expressions. A
string expression consists of one or more strings or string variables and one
or more string operators. You can write string expressions to modify strings,
compare them, convert between strings and numbers, and manipulate strings in
programs and files.
3.2.1 String concatenation
--------------------------
To concatenate means to connect in a series; string concatenation means
linking two or more strings to form a new string. The operator for
concatenation is the plus sign [+]. Notice that + does not work for strings as
it does for numbers: it does not add. Concatenating five + five gives you
fivefive, not ten or 10. The syntax for concatenation is:
(string 1) + (string 2) = (new string 1 + 2)
The following program concatenate 3 strings, using their variable names:
Ok 10 X$ = "TO
Ok 20 Y$ = "GET"
Ok 30 Z$ = "HER"
Ok 40 A$ = X$ + Y$ + Z$
Ok 50 PRINT A$
Ok RUN
TOGETHER
The example forms a new string by concatenating string variable names. You can
also concatenate string constants directly, or combine constants and
variables:
Ok 10 Z$ = "look "
Ok 20 X$ = Z$ + "at " + "me " + "now!"
Ok 30 PRINT X$
Ok RUN
look at me now!
3.2.2 String comparisons
------------------------
You can compare one string to another or alphabetize strings with the
relational operators =, <>, <, >, <=, and >=. Personal BASIC reads the strings
and compares their ASCII values character by character, up to the end of the
string. As in the alphabet, a < b < c, and the lower value precedes the higher
value. See the ASCII value table in Appendix B. Notice that the ASCII values
for upper- and lower-case are different.
If one string is longer than another, but they are otherwise identical (at and
ate, for example), the longer string is greater. Because ate is greater than
at, and attenuate is greater than ate, their order is:
at
ate
attenuate
Remember that blanks are characters. If a string has a trailing blank, its
value increases because it is longer. If it has a leading blank, its value
decreases, because blanks have the smallest ASCII value of all the printable
characters.
"A" < "B" (A's ASCII value is 65; B's is 66.)
"A " > "A" (A trailing blank makes "A " longer and greater than
"A".)
"Dog" < "Dot" (These are alike until the last character. But,
because t > g, dot > dog.)
"yes" = "yes" (These are identical.)
You can use string comparisons for controlling program flow, as in the
following example:
Ok 100 INPUT "Are you calling heads or tails"; C$
Ok 110 IF C$ = "heads" THEN GOTO 160
Ok 120 IF C$ = "tails" THEN GOTO 170 ELSE GOTO 90
3.2.3 String functions
----------------------
With Personal BASIC string functions, you can find strings within strings,
convert numbers to strings, and pad lines with spaces. Personal BASIC provides
the string functions listed in Table 3-5. You can use these functions anywhere
you use a string operator. See Section 5 for more detailed explanations and
examples.
Table 3-5. String functions
Func. Explanation
----- -----------
INSTR Finds the first occurrence of a particular sequence of
characters within a string, and returns its position.
LEFT$ Returns the leftmost characters in a string.
LEN Returns the number of characters in a string.
MID$ Extracts a string from within a string, beginning at whatever
point you specify.
RIGHT$ Returns the rightmost characters in a string.
SPACE$ Returns a string of spaces.
STR$ Converts a number to a string.
STRING$ Returns a string of a given length.
Section 4: Input and output
---------------------------
Input and output refers to the passing of data between the various components
that make up your microcomputer system. For example, data can pass from a
program to the screen for display or to a disk drive for storage. Personal
BASIC provides a variety of statements and functions to control the
interaction between programs, consoles, printers, and disk drives.
4.1 Console input
-----------------
Console input is data that you enter into a program while the program is
running. The following Personal BASIC statements let you enter data from your
console. See Section 5 for detailed explanations and examples of each
statement.
- The INPUT statements asks you to enter data from the keyboard during
program execution. INPUT assigns the data to a string or numeric
variable.
- The LINE INPUT statement reads one entire line of data from the
keyboard, ignoring commas [,] and other delimiters. LINE INPUT assigns
the data to a string variable.
4.2 Printing
------------
To print with Personal BASIC means to send data to a screen, line printer, or
disk file. Your program can print information on the screen or on paper, using
a printer. You can write a program that sends the information to a disk file
for storage. The PRINT statement is the main data output statement in Personal
BASIC. PRINT sends data from a program to the screen. Variations of PRINT let
you send data to other destinations or tailor your print formats for different
kinds of data.
The statements in Table 4-1 and the functions in Table 4-2 control printing.
See Section 5 for details and examples of each statement and function.
Table 4-1. Print statements
Statement Explanation
--------- -----------
LPRINT Directs program output to the printer.
LPRINT USING Lets you specify a special format for program output
directed to the printer.
PRINT Directs program output to the screen.
PRINT USING Lets you specify a special format for program output
directed to the screen.
WRITE Similar to PRINT. WRITE directs program output to the
screen but inserts commas [,] between the items as
they display and delimits strings with quotation marks
["].
Table 4-2. Print functions
Func. Explanation
----- -----------
LPOS Returns the current position of the print head within the
printer buffer.
POS Returns the current cursor column position on the console.
SPC Moves the cursor a specified number of spaces on a line. Use
SPC with PRINT, LPRINT, or PRINT#.
TAB Moves the cursor to a specified column number on a line. Use
TAB with PRINT or LPRINT.
4.2.1 Formatted printing
------------------------
The PRINT USING statement lets you specify special formats for program output.
There are 2 variations of the PRINT USING statement: LPRINT USING and PRINT#
USING. Each statement specifies a different destination for formatted output.
- The PRINT USING statement sends formatted data to the console.
- The PRINT# USING statement sends formatted data to a specified disk
file.
- The LPRINT USING statement sends formatted data to the printer.
The syntax of the LPRINT USING and PRINT# USING statements differs slightly.
See Section 5 for the syntaxes of all PRINT statements. Write the PRINT USING
statement with the following syntax:
PRINT USING (format string); (expression list)
The following figure gives a literal example of a PRINT USING statement, and
points out the syntax elements.
Ok 10 PRINT USING BLOCKFORMAT$;NAME$,AGE%,ADDRESS$
└────┬────┘ └─────┬─────┘└────────┬────────┘
STATEMENT FORMAT STRING EXPRESSION LIST
Figure 4-1. PRINT USING syntax
The expression list consists of the string or numeric expressions to format
and print. You can use commas [,] or semicolons [;] to separate expressions in
the list. The format string is a model or image of the output. The format
string can be a string constant or variable that consists of special
formatting characters and literal characters. The formatting characters
determine fields of data for the printed strings or numbers. A formatted
printing statement contains only one format string, but can format any number
of expressions. The following example shows how the formatting characters
relate to the actual output.
Ok 10 A$ = "DAVID" Expressions
Ok 20 B$ = "ALAN"
Ok 30 C$ = "JONES"
Ok 40 N = 1500
Ok 50 FMAT$ = "!. !. & $####.##" Format string
Ok 60 PRINT USING FMAT$; A$, B$, C$, N Format statement
Ok RUN
D. A. JONES $1500.00 Output
The format string in the preceding example defines 4 fields of data: 3 string
and 1 numeric. Each field corresponds to an appropriate expression. If you
specify more fields in the format string than expressions, PRINT USING ignores
the additional fields. If you specify more expressions than fields in the
format string, PRINT USING re-uses the format string to format all the
expressions. The format types must be equal to the expression types.
4.2.2 String field formatting characters
----------------------------------------
Exclamation point
An exclamation point [!] tells the statement to print only the first character
from each specified string.
Ok 10 A$ = "TESTING"
Ok 20 B$ = "Personal BASIC"
Ok 30 PRINT USING "!";A$,B$
Ok RUN
TP
Spaces
The number of characters or spaces that you place between the 2 backslashes
[\] plus 2 indicates the number of characters to print from the specified
string. If you place no characters or spaces between the backslashes, 2
characters are printed. If you place one character or space between the
backslashes, 3 characters are printed. If the number of characters or spaces
plus 2 is less than the number of characters to output, the statement ignores
the extra characters. If the number of characters or spaces plus 2 is greater
than the number of characters to output, the string is left-justified and
padded on the right with spaces.
You can use periods [.] and numbers between the backslashes to easily see how
many characters are in your printing field. For example, this field:
\...5....0...4\
is 15 characters long.
Ok 10 A$ = "TESTING"
Ok 20 B$ = "Personal BASIC"
Ok 30 PRINT USING "\ \";A$;B$
Ok 40 PRINT USING "\ \";A$;B$;"!"
Ok RUN
TESTINGPersonal BASIC
TESTING Personal BASIC !
Ampersand
An ampersand [&] specifies a variable-length string field. The statement
prints the string exactly as entered.
Ok 10 A$ = "TESTING"
Ok 20 B$ = " Personal BASIC"
Ok 30 PRINT USING "&";A$,B$
Ok RUN
TESTING Personal BASIC
4.2.3 Numeric field formatting characters
-----------------------------------------
Pound sign
A pound sign [#] represents each digit position in a numeric field. The
statement fills all digit positions. If the number has fewer digits than
positions specified in the format string, the number is right-justified in the
field.
Ok PRINT USING "######";1024
1024
Decimal point
You can insert a decimal point [.] at any position in the field. The statement
inserts a zero to fill digit positions, and rounds numbers as necessary. In
the following example, the 2 spaces inserted at the end of the format string
separate the printed numbers on the line.
Ok 10 X = 765.432 : Y = 234.5
Ok 20 Z = .765
Ok 30 PRINT USING "###.## ";X;Y;Z
Ok RUN
765.43 234.50 0.77
Plus sign
A plus sign [+] at the beginning of the format string tells the statement to
print the sign of the number, plus [+] or minus [-], before the printed
number. If you place the plus sign at the end of the format string, the
statement prints the sign after the printed number.
Ok 10 X = 765.432 : Y = -234.5
Ok 20 Z = -.765 : W = 87.9
Ok 30 PRINT USING "+###.## ";X;Y;Z;W
Ok RUN
+765.43 -234.50 -0.77 +87.90
Minus sign
A minus sign [-] at the end of the format string tells the statement to print
negative numbers with a trailing minus sign.
Ok PRINT USING "##.##- ";-.765;87.9
0.77- 87.90
Asterisk
A double asterisk [**] at the beginning of the format string tells the
statement to fill leading spaces in the numeric field with asterisks. The
double asterisk reserves positions for 2 more digits.
Ok 10 X = 765.43
Ok 20 Y = -0.765 : Z = 2345.9
Ok 30 PRINT USING "**##.# ";X;Y;Z
Ok RUN
*765.4 **-0.8 2345.9
Dollar sign
A double dollar sign [$$] tells the statement to insert a dollar sign to the
immediate left of the printed number. The double dollar sign reserves 2 more
digit positions. One position is for the printed dollar sign. You can use the
double dollar sign with negative numbers only if the minus sign [-] trails to
the right. You cannot use exponential format with the double dollar sign.
Ok PRINT USING "$$###.##";765.486
$765.49
Asterisks and dollar signs
A double asterisk and dollar sign [**$] at the beginning of the format string
tells the statement to fill leading spaces with asterisks and insert a dollar
sign to the immediate left of the number. The **$ reserves 3 more digit
positions. One position is for the printed dollar sign.
Ok PRINT USING "**$##.## ";765.486;3.04
*$765.49 ***$3.04
Comma
A comma [,] placed to the left of the decimal point [.] in the format string
tells the statement to insert a comma between every 3rd digit on the left side
of the decimal point in the printed number. The comma reserves one more digit
position. A comma at the end of the format string prints as part of the
string.
Ok 10 X = 5432.1
Ok 20 PRINT USING "####,.##";X
Ok 30 PRINT USING "####.##,";X
Ok RUN
5,432.10
5432.10,
Carets
Four carets [^^^^] following the digit position characters specify exponential
format. The 4 carets reserve space for the characters E+nn. See Section 2.1.1
for information on Personal BASIC exponential notation. The position of the
decimal point [.] in the format string determines the exponent value.
Significant digits are left-justified. One digit position is reserved on the
left of the printed number for the sign. The statement prints a blank on the
left if the number is positive, and a minus sign [-] if negative, unless you
specify a leading + or trailing + or - in the format string.
Any number of carets following a numeric specification in a PRINT USING string
will cause the number to be printed in exponential form. If you wish to
specify that a caret [^] is to print immediately after a number, use the
literalising character [_] before the first caret. For example:
PRINT USING "###.##_^"; 79.5
prints as 79.50^.
Ok PRINT USING "##.##^^^^ ";-100.00;.0036
-1.00E+02 3.60E-03
Ok PRINT USING "+##.##^^^^ ";-100.00;.0036
-10.00E+01 +36.00E-04
Ok PRINT USING "####.##^^^^ ";100.00;.0036
100.00E+00 360.00E-05
Ok PRINT USING ".###^^^^- ";100.00;.0036
.100E+03 .360E-02-
Underscore
An underscore [_] in the format string tells the statement to print the next
character as a literal character. Place 2 adjacent underscores in the format
string to print one underscore as a literal character.
Ok PRINT USING "_#####_!";1024
#1024!
Percent sign
The statement places a percent sign [%] in front of the printed number if the
number has more digits than the numeric format string. If rounding causes the
printed number to exceed the field specified in the format string, the
statement places a percent sign in front of the printed number. The number of
digits specified in the format string cannot exceed 24.
Ok PRINT USING "##.##";333.42
%333.42
Ok PRINT USING ".###";.9999
%1.000
You can include string constants in the format string, as shown in the
following example:
Ok PRINT USING "THIS IS FILE _##";4
THIS IS FILE #4
4.3 Disk files
--------------
The operating system organizes information into files on the disk. Personal
BASIC supports a number of statements and functions that interface with your
operating system, enabling you to save your Personal BASIC programs and data
in disk files for later use. Personal BASIC supports 2 types of disk files:
sequential files and random files. You identify files by filename and
filetype.
4.3.1 File specification
------------------------
Each Personal BASIC file must have a unique file specification, or filespec,
that conform to standard Digital Research filespec format. A standard filespec
consists of 3 parts: a drive specifier, a filename, and a filetype. The drive
specifier and the filetype are optional. The following are examples of
Personal BASIC filespecs:
- B:ACCOUNTS.BAS
- TOTAL.FEB
- CLIENTS
The drive specifier, or drivespec, identifies which disk drive has the file.
The drivespec can be any letter from A to P that corresponds to any logical
disk drive. Place a colon [:] after the drive letter. If you omit the
drivespec, Personal BASIC assumes that the file is on the default drive.
The filename can contain 1 to 8 characters. It cannot contain blanks [ ],
periods [.], or colons [:]. It is good policy to choose filenames that
indicate what the file contains. For examples, the filename CLIENTS is
appropriate for a file containing information about clients. ACCOUNTS is
appropriate for a file that contains an accounts-receivable program.
The filetype can contain up to 3 characters. Separate the filename from the
filetype with a period [.]. Use filetypes to identify groups of similar files.
For example, the filetype BAS identifies a file as a BASIC program. A filetype
of FEB could identify a group of files that contain all your business data for
February, such as SALES.FEB, CLIENTS.FEB, or PROFITS.FEB. The filetype is
optional.
4.3.2 Sequential files
----------------------
Sequential files organize data in a continuous stream. Data items written to a
sequential file using PRINT#, PRINT# USING or WRITE# statements are stored
sequentially, one item after another. When you access data from a sequential
file using INPUT# or LINE INPUT# statements, the data items are read from the
file in the same sequential order as they were stored. All items in the file
are read from the first item to the last. Sequential files are easier to
create than random files, but are not as flexible when accessing the data.
Personal BASIC supports the statements in Table 4-3 and functions in Table 4-4
for use with sequential files. See Section 5 for more detailed explanations
and examples.
Table 4-3. Sequential file statements
Statement Explanation
--------- -----------
CLOSE Concludes input and output to a file.
INPUT# Reads data items from a sequential file, and assigns
them to program variables.
LINE INPUT# Reads one line of data from a sequential file into a
string variable. LINE INPUT# ignores delimiters.
OPEN Lets you read and write to a file.
PRINT# Writes data sequentially to a file. PRINT# writes the
data uncompressed, exactly as is. You must delimit
data fields.
PRINT# USING Writes formatted data sequentially to a file.
WRITE# Writes data sequentially to a file. WRITE# inserts
commas [,] between data items, and delimits strings
with quotation marks ["].
Table 4-4. Sequential file functions
Func. Explanation
----- -----------
LOC Returns the number of records read from, or written to, a
sequential file. LOC indicates the current position in the
file.
LOF Returns the number of 128-byte segments in a file while the
file is open.
EOF Indicates an end-of-file condition. EOF returns true (-1) if
the end of a given file has been reached, and false (0)
otherwise.
The following 4 steps outline the procedure used to create a sequential file
and access the data in the file:
1) OPEN the file to output data (O mode) from your program.
2) Output data to the file using the PRINT#, PRINT# USING, or WRITE#
statements.
3) CLOSE the file, then OPEN it to input data to your program.
4) Read the data from the new sequential file into your program using the
INPUT#, or LINE INPUT# statements.
In many cases, more than one program must access the data in a sequential
file. Therefore, the program that creates the sequential file, and the
programs that access the data in the file, can be separate programs. For
example, you can have one program that creates a new file upon each execution,
and several programs that use the data in the file. Alternatively, you can
have one large program that performs a variety of tasks.
The following example program creates a sequential file named BUSINESS that
lets you store some simple business information. Try the program on your
computer and enter some hypothetical data to see how a sequential file works.
Ok 5 REM - CREATE SEQUENTIAL BUSINESS INFO FILE
Ok 10 OPEN "O", #1, "BUSINESS"
Ok 20 PRINT "TO END THIS PROGRAM... TYPE ""DONE""."
Ok 30 INPUT "PLEASE ENTER DATE... MO/DA/YR"; DATE$
Ok 40 IF DATE$ = "DONE" THEN GOTO 80
Ok 50 INPUT "PLEASE ENTER TOTAL SALES..."; AMT
Ok 60 WRITE#1, DATE$, AMT
Ok 70 PRINT: GOTO 20
Ok 80 PRINT "FINISHED... THANK YOU!"
Ok 90 END
Listing 4-1. Program creating a sequential file
The first time that you RUN the program, it creates a sequential file named
BUSINESS. If you RUN the program again, it erases the existing BUSINESS file
and creates a new one.
Any number of programs can use the data in the BUSINESS file. For example, you
can write a program that lists the daily sales totals for each day in April.
You can write another program that calculates sales by month, and displays the
totals in a table. You can write one large program that performs both tasks.
The following example program uses the data in the BUSINESS file to display
the dates on which total sales exceeded $1,500.
Ok 5 REM - DISPLAY DATES WHEN SALES TOPPED $1500
Ok 10 OPEN "I", #1, "BUSINESS"
Ok 20 WHILE NOT EOF(1)
Ok 30 INPUT#1, DATE$, AMT
Ok 40 IF AMT > 1500.00 THEN PRINT DATE$
Ok 50 WEND
Ok 60 END
Listing 4-2. Sample sequential file program
This program searches all the data in the BUSINESS file from beginning to end.
Notice that line 20 searches BUSINESS for the end-of-file marker, enabling the
program to conclude properly. Personal BASIC reports an error message if there
is no end-of-file search during a sequential file access.
4.3.3 Random files
------------------
Random files organize data into records. Records cannot exceed 4,096 bytes.
Within a record, data is organized like a small sequential file.
Random files have advantages over sequential files, although random files
require a few more programming steps to create and access. Random files
usually store numbers in binary format. Sequential files store numbers in
ASCII format. Usually, random files require less disk space than sequential
files.
The most significant advantage to random files is random access. In other
words, you can access any record in a file by assigned number. It is not
necessary to read through all the data from beginning to end as with
sequential files. The PUT statement, used within the program that creates the
random file, assigns a record number automatically, beginning with the number
1. Or, you can specify a record number in the PUT statement. Record numbers
can range from 1 to 32767.
(ROCHE> Hum... 32767 records of 4,096 bytes = 134,213,632 bytes. Divided by
1,024 bytes (1 kilobyte) = 131,068 kilobytes. Divided again by 1,024 = 127.99
megabytes... Curious! I don't recognize the 8 megabyte limit of CP/M 2.2 or
the 32 megabyte limit of CP/M Plus? And Personal BASIC was only available, in
1983, under CP/M-86, the 8086 version of CP/M 2.2...)
Personal BASIC supports the statements in Table 4-5 and functions in Table 4-6
for use with random files. See Section 5 for more detailed information and
examples.
Table 4-5. Random file statements
Statement Explanation
--------- -----------
CLOSE Concludes input and output to a specified disk file.
FIELD Allocates space in a random file buffer, enabling a
program to write data to a random file. The FIELD
statement specifies the size of the data fields within
a record.
GET Reads a record from a random file into a random file
buffer.
LSET Assigns data to the string variables in a random file
buffer, and left-justifies the data in its proper
field.
OPEN Lets you read and write to a file.
PUT Writes a record from a random file buffer to a random
file. You can specify the record number in the PUT
statement.
RSET Assigns data to the string variables in a random file
buffer, and right-justifies the data in its proper
field.
Table 4-6. Random access functions
Func. Explanation
----- -----------
CVI Converts a 2-byte string to an integer, enabling integer
values to be read from a random file buffer.
CVD Converts an 8-byte string to a double-precision real number,
enabling double-precision real values to be read from a random
file buffer.
CVS Converts a 4-byte string to a single-precision real number,
enabling single-precision real numbers to be read from a
random file buffer.
LOC Returns the record number of the last record read or written
to a random file.
MKD$ Converts a double-precision real number to an 8-byte string,
enabling double-precision real values to be placed in a random
file buffer.
MKI$ Converts an integer to a 2-byte string, enabling integer
values to be placed in a random file buffer.
MKS$ Converts a single-precision real number to a 4-byte string,
enabling single-precision real numbers to be placed in a
random file buffer.
Take the following 4 steps to create a random file:
1) OPEN the file for random access (R mode).
2) Specify the size of the data fields in the random file buffer, using
the FIELD statement.
3) Use the LSET or RSET statements to read data from the program into the
random file buffer. Convert numeric values into strings, using the
MKI$, MKS$, and MKD$ functions.
4) Write the data from the buffer to the disk, using the PUT statement.
As with sequential files, more than one program can access the data in a
random file. Therefore, the program that creates the random file and the
programs that access the data in the file can be separate programs. The
following example program creates a random file named EMPLOYEE that lets you
store simple employee personnel information. Try the program on your computer
and enter some hypothetical information to see how a random file works. Notice
that the employee number also serves as the record number.
Ok 5 REM - CREATE A RANDOM PERSONNEL FILE
Ok 100 OPEN ""R", #2, "EMPLOYEE", 45
Ok 110 FIELD #2, 25 AS N$, 12 AS J$, 8 AS D$
Ok 120 INPUT "ENTER EMPLOYEE NUMBER... ENTER 0 TO STOP"; NUM%
Ok 130 IF NUM% = 0 THEN GOTO 220
Ok 140 INPUT "ENTER EMPLOYEE NAME..."; NAME$
Ok 150 INPUT "ENTER EMPLOYEE JOB TITLE..."; JOB$
Ok 160 INPUT "ENTER DATE HIRED... MO/DA/YR"; DATE$
Ok 170 LSET N$ = NAME$
Ok 180 LSET J$ = JOB$
Ok 190 LSET D$ = DATE$
Ok 200 PUT #2, NUM%
Ok 210 PRINT : GOTO 120
Ok 220 PRINT "FINISHED... THANK YOU!"
Ok 230 END
Listing 4-3. Random file program
The first time that you execute the program, it creates a random file named
EMPLOYEE. If you RUN the program again, it erases the existing EMPLOYEE file
and creates a new one. However, if you want to save the data in the file after
the first execution and add to it, you can write a new program or modify the
preceding program, enabling you to append data. You can change line 100 to
OPEN the EMPLOYEE file in the append mode. Then, run the program to add new
information to the file.
Notice that line 210 causes the program to loop continuously to line 120. The
program does not end until you instruct it to. Line 120 asks you to enter a
zero in response to the INPUT statement if you want to end the program. Line
130 checks for the zero. If you enter a zero, the program branches to line
220, ending the program.
Like sequential files, any number of programs can access the data in a random
file. You access data in a random file as follows:
1) OPEN the file for random access (R mode).
2) Specify the size of the data fields in the random file buffer, using
the FIELD statement.
3) Use the GET statement to read a specified record from the file into
the random file buffer.
4) The record in the buffer is available to the program. Convert numeric
string values back into numbers, using the CVI, CVS, and CVD
functions.
The following example program lets you access any data record in the EMPLOYEE
file. When you enter an employee number, the program returns a list of all the
personnel information contained in the random file pertaining to the employee.
The employee number also serves as the record number.
Ok 5 REM - DISPLAY PERSONNEL INFORMATION
Ok 500 OPEN "R", #2, "EMPLOYEE", 45
Ok 510 FIELD #2, 25 AS N$, 12 AS J$, 8 AS D%
Ok 520 INPUT "ENTER EMPLOYEE NUMBER... ENTER 0 TO STOP"; NUM%
Ok 530 IF NUM% = 0 THEN GOTO 610
Ok 540 GET #2, NUM%
Ok 550 ON ERROR GOTO 600
Ok 560 PRINT "EMPLOYEE NUMBER - "; NUM% : PRINT
Ok 570 PRINT N$, J$ : PRINT
Ok 580 PRINT "DATE HIRED - "; D$
Ok 590 GOTO 520
Ok 600 PRINT "UNASSIGNED EMPLOYEE NUMBER." : PRINT : GOTO 520
Ok 610 PRINT "FINISHED... THANK YOU!"
Ok 620 END
Listing 4-4. Sample program accessing random file data
If you enter an employee number that does not exist as a record number in the
EMPLOYEE file, Personal BASIC displays an error message and ends the program,
unless you write an ON ERROR statement. See the ON ERROR statement in Section
5. The ON ERROR statement in line 550 traps such errors, and sends control to
line 600. Line 600 prints a message telling you of the invalid employee number
and branches to line 520, so you can enter another number.
Section 5: Commands, statements, and functions
----------------------------------------------
This section describes the Personal BASIC commands, functions, and statements,
in alphabetical order. The syntax formats in this section conform to the
following typographical conventions:
- Words in single quotation marks ['] describe the kind of data that you
must insert in their places. They are self-explanatory. For example,
'variable' means that, when you are writing a statement, you write a
variable in 'variable's place.
- Items enclosed in square brackets, [ ], are optional and cannot be
repeated.
- Items enclosed in curly braces, { }, are optional and cannot be
repeated.
- Words in uppercase are Personal BASIC keywords.
ABS Function
The ABS function returns the absolute value of a number.
Syntax:
X = ABS ('numeric expression')
Explanation:
The absolute value of a number is always positive or zero. ABS returns a
number in the same form as its argument.
ABS returns an integer value for integers. For real numbers, the returned
value has the same precision as the argument. You can change the precision or
type of the number by assignment in the usual way (see Section 2.2.2).
Example:
Ok 10 I% = ABS(-9)
Ok 20 PRINT I%
Ok 30 X! = ABS(325556.244)
Ok 40 PRINT X!
Ok 50 Y# = ABS(-289878787.98992)
Ok 60 PRINT Y#
Ok 70 END
Ok RUN
9
325556
289878787.98992
ASC Function
The ASC function returns the ASCII value of the first character in a string.
Syntax:
I% = ASC ('string expression')
Explanation:
ASC returns an integer between 0 and 255. The string must contain at least one
character. If the string expression is a null string, error number 5 occurs
(see Appendix D for error messages).
The CHR$ function is the inverse of ASC. See Appendix B for a list of ASCII
characters and corresponding numeric values.
Example:
Ok 10 A$ = "Murphy, James"
Ok 20 PRINT ASC(A$)
Ok RUN
77
ATN Function
The ATN function returns the arctangent of a number.
Syntax:
X! = ATN('numeric expression')
Explanation:
The ATN function returns a single-precision real number. The number is an
angle in radians that ranges from -PI/2 to PI/2. The TAN function is the
inverse of ATN.
Example:
Ok 10 RADIANS! = ATN(0.99999)
Ok 20 PRINT "The angle in radians is ";RADIANS!
Ok 30 PRINT
Ok 40 PI = 3.14159
Ok 50 DEGREES = RADIANS! * 180/PI
Ok 60 PRINT "The angle in degrees is ";CINT(DEGREES)
Ok RUN
The angle in radians is 0.78540
The angle in degrees is 45
AUTO Command
The AUTO command generates a line number automatically each time that you
press the Carriage Return [CR] key. Ctrl-C turns AUTO off.
Syntax:
AUTO ['starting line number'] [,'increment']
Explanation:
You can specify the starting line number and an increment value after the
keyword AUTO. The increment value is a number added to each line number to
generate the next line number.
You can omit the starting line number or the increment, or both. If you omit
the starting line number, Personal BASIC starts numbering at 10. You must
write a comma [,] before the increment number, in place of the starting line
number.
If you omit the increment, Personal BASIC uses the increment of the most
recent AUTO command, or 10 if no other AUTO command.
Personal BASIC prints an asterisk [*] before the line number if that number
already exists in the program. If you enter a program line after the line
number, Personal BASIC deletes the existing line in the program. If you type a
Carriage Return [CR] after the line number, Personal BASIC does not replace
the existing line.
Ctrl-C turns AUTO off. Personal BASIC does not save the last line that AUTO
generates when you type the Ctrl-C. Anything on the last line is lost, and
does not become part of the program. If the line that you entered last would
have replaced a line already in the program, the existing line is retained.
Example:
The following command uses the AUTO default values, and generates the line
numbers 10, 20, 30, 40, 50, ...
Ok AUTO
The following command generates the line numbers 50, 75, 100, 125, 150, ...
Ok AUTO 50, 25
The following command generates the line numbers 10, 60, 110, 160, 210, ...
Ok AUTO , 50
The following command generates the line numbers 5, 55, 105, 155, 205, ...
Ok AUTO 5, 50
BLOAD Statement
The BLOAD statement loads a memory image file into memory.
Syntax:
BLOAD 'filespec'[,'address']
Explanation:
BLOAD and BSAVE are used to save and load machine-language programs and arrays
and their contents. These statements also save and display screen images.
BLOAD loads a file into memory at the address that you give. The filespec is
the full name of the file, the filename and filetype. The address is where you
want loading to start. The address is a numeric expression with a value from 0
to 65535, an offset into the segment declared by the last DEF SEG statement.
If you omit the address, the offset that you specified with BSAVE is assumed.
The file loads into the same address it came from.
BLOAD does not check addresses. Although it is possible to BLOAD anywhere, do
not BLOAD over Personal BASIC's data areas or your program.
Example:
Ok 100 DEF SEG = 34562
Ok 110 BLOAD "ARRAY",23
BREAK Command
The BREAK command stops a program at any line number.
Syntax:
BREAK ['list of line numbers']
Explanation:
The list of line numbers is optional. If you leave it out, BREAK stops
execution at every line number. You can direct where you want the BREAKs to
occur by supplying a line number, or line numbers separated by commas [,].
At a break, the program line and any output are printed. The UNBREAK command
removes breaks. The CONT command or a Carriage Return [CR] restarts the
program after a break.
Example:
Ok 5 N = 5
Ok 15 FOR X = 1 TO 5
Ok 25 N = N - 1
Ok 35 PRINT N
Ok 45 NEXT X
Ok BREAK 45
Ok RUN
4
b 45 NEXT X
Br
BSAVE Statement
The BSAVE statement saves part of memory on a specified device.
Syntax:
BSAVE 'filespec','address','length'
Explanation:
BSAVE works with BLOAD to load and save machine-language programs or any
program segment.
The filespec is the name of your file. It must conform to CP/M file-naming
standards.
The address is an offset from the segment declared in the last DEF SEG
statement, and must be in the range 0 to 65535.
The length is the length of the memory image to be saved. It must be in the
range 0 to 65535.
Example:
Ok 100 DEF SEG = 34562
Ok 110 BSAVE "ARRAY",23,650
CALL Statement
The CALL statement transfers control to an assembly-language subroutine.
Syntax:
CALL 'numeric variable' [('parameter list')]
Explanation:
The numeric variable must equate to the starting memory address of the
assembly routine. The address is an offset into the current memory segment, as
defined by the most recent DEF SEG statement.
The optional parameter list consists of expressions that serve as arguments to
pass data between the main program and the assembly routine. The parameter
list is enclosed in parentheses ["(" and ")"]. You must separate each
expression in the parameter list with commas [,].
See Appendix F for more information on using Personal BASIC with assembly-
language subroutines.
Example:
Ok 500 DEF SEG = &H1000
Ok 550 CHART = 0
Ok 600 CALL CHART(I%, A$, X)
CDBL Function
The CDBL function converts a number to a double-precision real number.
Syntax:
X# = CDBL('numeric expression')
Explanation:
You can use any numeric expression with the CDBL function.
See Section 2.3 for more information on conversion. See the CSNG and CINT
functions.
Example:
Ok 10 PRINT 7/3
Ok 20 PRINT CDBL(7/3)
Ok RUN
2.33333
2.333333253860047
CHAIN Statement
The CHAIN statement transfers control, and passes variables to another
program.
Syntax:
CHAIN 'filespec'[,'line number'][,ALL]
CHAIN MERGE 'filespec'[,'line number'][,DELETE 'line number list']
Explanation:
The program that you specify in the CHAIN statement actually replaces the
original program in memory. The program that is chained to is sometimes called
an overlay, because it overwrites all or part of the original program. The
filespec is the name of the new program to chain to. It can be any string
expression.
The MERGE option merges a program with an existing program, instead of
replacing it. CHAIN MERGE saves all variables, type declarations, statements,
and options. If you omit the MERGE option, you must restate all DEF type
statements in each new program chained to. The MERGE option interlists the
statements from the new program with the statements in the original program.
If some statements in the new program have the same line numbers as statements
in the original, the new program lines replace the original lines. The MERGE
option preserves the most recent OPTION BASE setting. See the OPTION BASE
statement in this section for more information.
If you execute a CHAIN MERGE in a subroutine, the subroutine stack is
preserved. A RETURN after the CHAIN MERGE has the expected effect, unless the
CHAIN MERGE replaced one of the lines to which you expect to RETURN at some
point. If you do this, the results are unpredictable.
You can specify a line number after the filespec, indicating where to begin
execution in the new program. Otherwise, execution begins with the first
executable statement. If you use the RENUM command to renumber the lines in
the new program, you might have to change the line number that you specify in
the CHAIN statement.
The ALL option indicates that all variables in the original program are passed
to the new program. ALL is not valid with CHAIN MERGE. If you omit the ALL
option, you must use the COMMON statement to declare which variables the
original program and the new program can share. See the COMMON statement in
this section for more information.
Use the DELETE option only with CHAIN MERGE. The DELETE option enables you to
remove parts of a program from memory after execution, to make room for
another program. The DELETE option works like the DELETE statement described
in this section. It deletes lines from the current program before merging the
program specified by 'filespec'. Specify the line numbers to delete after the
DELETE keyword.
Example:
The following statement chains to a program named CALCS.BAS.
Ok 400 CHAIN "CALCS.BAS"
The following statement chains to the CALCS.BAS program and begins execution
at line 1200. All program variables can pass from the original program to the
new program.
Ok 400 CHAIN "CALCS.BAS", 1200, ALL
The following statement merges the lines from an overlay named TOTAL.OVR with
the program already in memory. Execution begins at line 900. Before loading
the merged file, the statement deletes the lines ranging from line 900 through
line 2000.
Ok 710 CHAIN MERGE "TOTAL.OVR", 900, DELETE 900-2000
CHR$ Function
The CHR$ function returns the ASCII character that corresponds to the
specified ASCII decimal value.
Syntax:
A$ = CHR$('numeric expression')
Explanation:
CHR$ returns a one-character string.
The numeric expression must evaluate to a legal integer. The ASCII value of
the character returned is 'expression' MOD 256. CHR$ converts real numbers to
integers.
Use the CHR$ function to send special characters, such as Line-Feeds [LF] or
Carriage Returns [CR], to the terminal. The ASC function is the inverse
function of CHR$. See Appendix B for a listing of ASCII characters and their
numeric values.
Example:
Ok 10 PRINT CHR$(83)
Ok 20 PRINT CHR$(115)
Ok 30 PRINT CHR$(42)
Ok RUN
S
s
*
CINT Function
The CINT function rounds a number to the nearest integer.
Syntax:
I% = CINT('numeric expression')
Explanation:
The numeric expression must be within the acceptable range for integers.
Integers can range from -32768 to 32767. Otherwise, an overflow error occurs.
See Section 2.3 for more information on numeric conversion. See the CDBL,
CSNG, FIX, and INT functions for more information.
Example:
Ok 10 PRINT CINT(5.2)
Ok 20 PRINT CINT(62.89)
Ok 30 PRINT CINT(-456.61)
Ok RUN
5
63
-457
CLEAR Statement
The CLEAR statement frees all memory used for program data without erasing the
program currently in memory. CLEAR can define the amount of workspace
available to Personal BASIC.
Syntax:
CLEAR [,'numeric expression'][,'numeric expression']
Explanation:
CLEAR sets all numeric variables to zero, and string variables to null. The
CLEAR command undefines all arrays.
The numeric expression specifies the maximum number of bytes available as
Personal BASIC work space. Personal BASIC sets the top limit of the memory
that it uses as one less than the expression that you give in the CLEAR
command. Therefore, you can safely load a machine-language subroutine at the
address given in CLEAR.
If the memory limit specified is greater than the total memory available,
Personal BASIC resets the limit to its start-up value. Thus, CLEAR, 65535
resets memory to its start-up value. If the memory limit specified is zero, it
is ignored. Clear, 0 has the same effect as CLEAR.
Once you establish a memory limit with CLEAR, it remains in effect until you
change it with another CLEAR command. CHAINing and RUNning the program do not
affect a CLEAR command.
Example:
The following example clears all data from memory without erasing the original
program.
Ok CLEAR
The next example clears all data from memory, and defines the maximum amount
of Personal BASIC work space as 32K-bytes.
Ok CLEAR , 32768
CLOSE Statement
The CLOSE statement closes all open disk files, concluding any input or
output.
Syntax:
CLOSE {[#]'file number'}
Explanation:
The CLOSE statement closes all open files, releases the file numbers, and
frees all buffer space that the file use. The files must have been created
using the OPEN statement.
The file number is a unique identification number that you assign to a file in
the OPEN statement. You can specify any number of file numbers in the optional
CLOSE statement. Separate file numbers with commas [,]. A pound sign [#] in
front of the file number is optional.
File numbers can be any numeric expression. The expression must evaluate to a
number between 1 and 15, which is the maximum number of files allowed, or a
"Bad File Number" error occurs. If file numbers evaluate to real values, CLOSE
converts them to integers. If you do not specify file numbers after the
keyword CLOSE, the statement closes all files that have been opened.
RESET, NEW, END, RUN, and SYSTEM close all open files automatically. The STOP
statement does not close disk files.
Example:
The following statement closes all open disk files.
Ok 310 CLOSE
The following statement closes the open disk files that have been assigned the
file numbers 3 and 7.
Ok 600 CLOSE #3, #7
COMMON Statement
The COMMON statement declares the variables that a program can pass to a
chained program.
Syntax:
COMMON 'variable'{,'variable'}
Explanation:
Use the COMMON statement with the CHAIN statement. See the CHAIN statement in
this section for additional information.
Personal BASIC treats all COMMON statements in a program as one consecutive
list of variables. Therefore, a program can contain any number of COMMON
statements. For array variables, place a set of parentheses ["(" and ")"]
after the array name.
COMMON statements can appear anywhere in a program. However, it is good
practice to place them at the beginning of each program.
Example:
The following example chains to a program named EMPLOYEE, and passes the
variables VAL!, NAME$, and the array variable SCALE().
Ok 350 COMMON VAL!, NAME$, SCALE()
Ok 360 CHAIN "EMPLOYEE"
CONT Command
The CONT command ---> Missing Page! <---
Syntax:
---> Missing Page! <---
Explanation:
---> Missing Page! <---
Example:
---> Missing Page! <---
COS Function
The COS function returns the cosine of its argument expressed in radians.
Syntax:
X = COS('numeric expression')
Explanation:
The COS function assumes that the expression is an angle in radians. To
convert degrees to radians, multiply by PI/180, where PI = 3.141593. COS
converts integers to real numbers, and returns a single-precision real number.
Example:
Ok 10 PRINT COS(23)
Ok RUN
-.532838
CSNG Function
The CSNG function converts a number to single precision.
Syntax:
X = CSNG('numeric expression')
Explanation:
The numeric expression can be of any type. See Section 2.3 for more functions
for numeric conversion.
Example:
Ok 10 X# = 2757.9735265835
Ok 20 PRINT CSNG(X#)
Ok RUN
2757.97
CVD, CVI, and CVS Functions
CVD, CVI, and CVS functions convert strings to numeric variable types.
Syntax:
CVD('8-byte string')
CVI('2-byte string')
CVS('4-byte string')
Explanation:
Personal BASIC stores numbers in a random file as strings. To read the numbers
from the file, the strings must be converted to the proper numeric data type.
The functions do not change the value of the number, only the data type.
The CVD function converts and 8-byte string to a double-precision real number,
enabling double-precision real values to be read from a random file buffer.
The CVI function converts a 2-byte string to an integer, enabling integer
values to be read from a random file buffer.
The CVS function converts a 4-byte string to a single-precision real number,
enabling single-precision real values to be read from a random file buffer.
If the string is shorter than the length required, it is padded to the right
with binary zeros. See Section 4.3.3 for information on random files. The
reverse of these functions is the MKD$, MKI$, and MKS$ functions.
Example:
Ok 10 OPEN "R", #1, "NUMBERS"
Ok 20 FIELD #1, 2 AS A$, 4 AS B$, 8 AS C$
Ok 30 GET #1, REC%
Ok 40 I% = CVI(A$)
Ok 50 X! = CVS(B$)
Ok 60 Y# = CVD(C$)
DATA Statement
The DATA statement defines a list of constants that a READ statement can
assign to variables.
Syntax:
DATA 'constant'{,'constant'}
Explanation:
DATA statements allow you to assign variables to constants, according to their
order in a string. Every DATA constant must have a corresponding READ
variable, and vice versa. The constants and variables match according to their
order in the lists; the first DATA constant relates to the first READ
variable, and so on.
Members of the constant list can be integers, reals, or strings, in any
combination. The data types for the constants in the DATA list, however, must
match the variables assigned them in the READ statement. You need not put
quotation marks ["] around strings.
DATA statements can be as long as you like, but you cannot write other
statements on the same line. Though every constant must have a corresponding
variable, you do not need a READ statement for every DATA statement. You can
have many DATA statements scattered in the program, and you can assign them
variables in one READ statement. In such a case, they match according to the
constants' order in the program first, then by their order within the lines.
Example:
Ok 10 READ X
Ok 20 DATA 33.3, 5, "ALLOW ROOM FOR GROWTH"
Ok 30 PRINT X
Ok 40 READ X,Y$
Ok 50 PRINT X,Y$
Ok RUN
33.3
5 ALLOW ROOM FOR GROWTH
DEFDBL Statement
The DEFDBL statement declares a range of letters as defining double-precision
real numbers.
Syntax:
DEFDBL 'letter'{'-letter'}
Explanation:
The DEFDBL statement declares that the variables whose names start with one of
the given letters are double-precision reals. You can use a single letter as a
parameter or a range of letters, such as M-Z.
Type declaration characters always overrule DEFDBL statements. DEFDBL
statements can only be entered as the first statements in a program.
Note that DEFDBL statements alter Personal BASIC's interpretation of the
lines. If you declare variable as double precision with a DEFDBL statement,
Personal BASIC treats them as double precision, even if you erase the DEFDBL
statement.
Example:
Ok 10 DEFDBL X-Y
Ok 20 X = 123123412345123456
Ok 30 Y = &H333
Ok 40 PRINT X,Y
Ok RUN
1.23123412345D+17 819
DEF FN Statement
The DEF FN statement defines a user-written function.
Syntax:
DEF FN'function name'{('parameter','parameter')} = 'definition'
Explanation:
To use a function that you yourself have written, you must define it before
you call it in a program. The DEF FN statement defines user-written functions.
The function name must be a legal variable name.
You can list any variables in the function in the parameter list. Variables in
the parameter list are numeric or string. They cannot be array variables. They
are formal parameters only, acting as place markers for the actual values that
you will give to the function when you call it in a program. The number and
type of the actual values must match exactly the number and type of the formal
parameters. Parameters are local to the function; that is to say: they have no
effect on variables of the same name within the program.
You can have variables in a function without listing them among the
parameters. These variables are called global variables. Global variables take
their values from outside the function, in the program. It finds a variable of
the same name within the program, and adopts its current value. For example,
in the function definition:
Ok 10 DEF FNA%(A%) = A% * A% * B%
the variable A% is local because it is included in the parameter list. B% is
not in the parameter list. It is global: its value is taken from a B% in the
program.
Suppose that there is an A% and a B% in the program itself:
Ok 20 A% = 7
Ok 30 B% = 3
Because these are variables in the main program, they are global. Running the
function shows what happens to these variables:
Ok 40 PRINT FNA%(5)
Ok 50 PRINT A%
Ok 60 PRINT B%
Ok RUN
75
7
3
The function uses the value that you assign to the local A% variable, 5, in
the computation of A% * A% * B% (5 * 5 * 3 = 75). The global variable A% was
not involved in the computation. Because the variable B% is not in the
parameters, Personal BASIC found a variable named B% in the program and used
its value, 3.
If there is no identical name and the variable's value is not supplied within
the function, the value defaults to zero or null.
The definition is an expression that describes what the function does; it
contains the function's process or algorithm. The expression is limited to one
line. If the function name includes a type specification, such as a string,
the value of the expression must conform to that type. The types of the
function name and parameters must also match.
Example:
Ok 10 INPUT "WIDTH OF MATERIAL IN INCHES";MATERIAL.WIDTH
Ok 20 INPUT "WIDTH OF WINDOWSILL IN INCHES";WINDOW.WIDTH
Ok 30 PANELS.NEEDED = WINDOW.WIDTH / MATERIAL.WIDTH
Ok 40 INPUT "LENGTH OF WINDOWSILL IN INCHES";WINDOW.LENGTH
Ok 50 YARDAGE.NEEDED = PANELS.NEEDED * WINDOW.LENGTH
Ok 60 INPUT "PRICE OF MATERIAL PER YARD";PRICE.YARD!
Ok 70 DEF FNSLACK = YARDAGE.NEEDED + YARDAGE.NEEDED / 15
Ok 80 DEF FNCOST! = (PRICE.YARD!/36) * FNSLACK
Ok 90 PRINT "YOU NEED" FNSLACK "INCHES OF" MATERIAL.WIDTH [LF]
"INCH MATERIAL. YOUR COST IS" FNCOST!
Ok 100 DEF FNINYARD = FNSLACK / 36
Ok 110 PRINT FNSLACK "INCHES IN YARDS IS" FNINYARD
Ok RUN
WIDTH OF MATERIAL IN INCHES? 30
WIDTH OF WINDOWSILL IN INCHES? 60
LENGTH OF WINDOWSILL IN INCHES? 60
PRICE OF MATERIAL PER YARD? 2.00
YOU NEED 128 INCHES OF 30 INCH MATERIAL. YOUR COST IS 7.1111.
128 INCHES IN YARDS IS 3.5556
DEFINT Statement
The DEFINT statement declares a range of letters as defining integers.
Syntax:
DEFINT 'letter'{-'letter'}
Explanation:
The DEFINT statement declares that the variables whose names start with one of
the given letters are integers. You can use one letter as a parameter or a
range of letters, such as M-Z.
Type declaration characters overrule DEFINT statements. The default type for
numbers is single precision. The note of caution at DEFDBL applies also to
DEFINT.
Example:
Ok 10 DEFINT X-Y
Ok 20 X = 78.9
Ok 30 Y = 78.1
Ok 40 PRINT X,Y
Ok RUN
79 78
DEF SEG Statement
The DEF SEG statement defines the current segment of storage.
Syntax:
DEF SEG [='address']
Explanation:
After DEF SEG defines the current segment of storage, the physical addresses
of later BLOAD, BSAVE, CALL, PEEK, POKE, and VARPTR operations are offsets
into the segment DEF SEG sets. The default value of the segment is Personal
BASIC's Data Segment, the beginning of your workspace in memory.
The optional address is a numeric expression from 0 to 65535, based on a 16-
byte boundary. Shift the segment address 4 bits and add the offset, if any, to
get the absolute address for the current operation. Personal BASIC does not
check the validity of the segment value. If you omit the address, the segment
is set to the default data segment.
Example:
Ok DEF SEG = 35000
DEFSNG Statement
The DEFSNG statement declares a range of letters as defining single-precision
real numbers.
Syntax:
DEFSNG 'letter'{-'letter'}
Explanation:
The DEFSNG statement defines the variable names that start with one of the
given letters as single-precision reals. You can use one letter as a parameter
or a range of letters, such as M-Z.
Type declaration characters always overrule DEFSNG statements. The default
type for numbers is single-precision. The note of caution at DEFDBL applies
also to DEFSNG.
Example:
Ok 10 DEFSNG X-Y
Ok 20 X = 23D+26
Ok 30 Y = 456654456654
Ok 40 PRINT X,Y
Ok RUN
2.3E+27 4.56654E+11
DEFSTR Statement
The DEFSTR statement declares a range of letters as defining strings.
Syntax:
DEFSTR 'letter'{-'letter'}
Explanation:
The DEFSTR statement declares that all variables whose first letters are on
the parameter list are strings. The constant values of the strings must be in
quotation marks ["]. The parameters can be a single letter or a range of
letters, such as M-Z.
A type declaration character always overrules a DEFSTR statement. The default
type of variables is single-precision real numbers. The note of caution at
DEFDBL applies also to DEFSTR.
Example:
Ok 10 DEFSTR A-C
Ok 20 A = "12.7.42
Ok 30 B = "1066"
Ok 40 C = "4.12.XX"
Ok 50 PRINT A,B,C
Ok RUN
12.7.42 1066 4.12.XX
(ROCHE> 12.7.42 = 7 December 1942 = Date of birth of the author of this
manual? According to Wikipedia, "1066" is the date of the "Norman Conquest of
England" (in France, 1066 is totally unknown...). (This confirms that Personal
BASIC was created in England.) Finally, I could not find the meaning of
"4.12.XX".)
DEF USR Statement
The DEF USR statement gives the starting address of a machine-language
subroutine, to be called by the USR function.
Syntax:
DEF USR ['digit'] = 'offset'
Explanation:
The optional digit is any digit from 0 to 9, corresponding to the number of
the USR routine whose address you are specifying. If you omit the digit, DEF
USR0 is implied.
The offset must evaluate to an integer expression from 0 to 65535. Add the
value of the offset to the current segment value to yield the actual starting
address of the USR routine.
You can write any number of DEF USR statements to redefine subroutine starting
addresses and allow access to subroutines. You can redefine the address for a
USR routine. The most recently executed value is used for the offset.
Example:
Ok 100 DEF SEG = 3500
Ok 110 DEF USR0 = 40000
DELETE Command
The DELETE command erases program lines.
Syntax:
DELETE 'line number list'
Explanation:
DELETE erases the line or range of lines that you specify. A DELETE command
can be issued only at command level. Delete a single line by typing the line
number and pressing Carriage Return [CR].
Example:
Ok 10 X = 10
Ok 20 Z = 20
Ok 30 PRINT X,Z
Ok RUN
10 20
Ok DELETE 20-30
Ok LIST
10 X = 10
DIM Statement
The DIM statement defines the number of dimensions and the number of elements
in an array.
Syntax:
DIM 'array name'({'subscript'}{,'subscript'})
{,'array name'({'subscript'}{,'subscript'})}
Explanation:
The DIM statement reserves space for a string or numeric array by specifying
the number of dimensions and the upper bound of elements in each. The number
of dimensions depends upon the number of subscripts; one subscript means one
dimension, and so forth. The lower bound of each dimension is 0 or 1,
depending upon the OPTION BASE. DIM automatically sets the initial value of
the elements at zero or null.
In Personal BASIC, arrays are dynamic. That means that you can dimension the
array with DIM, erase the array later in the program, and declare it again
with DIM, using the same name but with new dimensions. With dynamic arrays,
you can also use a numeric variable to dimension the array.
You can use an array without declaring it first with a DIM statement. If you
do, the array is declared automatically with a default upper bound of 10
elements in each dimension. For example, if the first reference to array A is:
ARRAY A(7,3)
the array is set up as if it had been declared with:
DIM A(10,10)
The default number of dimensions allowed if 4 for integers, and 3 for strings
and single- and double-precision reals. See Section 2.2.3 for more information
on arrays.
Example:
Ok 10 DIM HOUSES$ (1,1,1)
Ok 20 HOUSES$ (0,0,0) = "FLOORPLAN1"
Ok 30 HOUSES$ (0,0,1) = "FLOORPLAN3"
Ok 40 HOUSES$ (0,1,0) = "FLOORPLAN3"
Ok 50 HOUSES$ (0,1,1) = "FLOORPLAN3"
Ok 60 HOUSES$ (1,0,0) = "FLOORPLAN1"
Ok 70 HOUSES$ (1,0,1) = "FLOORPLAN2"
Ok 80 HOUSES$ (1,1,1) = "FLOORPLAN2"
Ok 90 IF HOUSES$ (1,0,0) = "FLOORPLAN2" THEN GOTO 300
DIR Command
The DIR command lists the files on a disk.
Syntax:
DIR ['disk drive:']['filename.filetype']
Explanation:
The DIR command displays the directory of the disk on the current drive.
You can also request a list of a particular type of file, such as TEX files or
BAS files, by replacing the filename with a wild card character [*]. You can
replace the filetype with a * to find files of the same name but different
types, such as FORM.BAS, FORM.TEX, FORM.LIB, and FORM.BAK. You can replace a
character in the filename or type with a question mark [?] to list similarly
named files. For example, FIVE-A and FIVE-B are listed by the command DIR
FIVE-?.
Example:
A>DIR B:
B:TEST .BAS : FILE1 .BAS : WS .COM : FILE2 .TEX
A>DIR B:*.BAS
B:TEST .BAS : FILE1 .BAS
A>DIR B:FILE?.*
B:FILE1 .BAS : FILE2 .TEX
EDIT Command
The EDIT command lets you change a program line.
Syntax:
EDIT 'line number'
Explanation:
To edit a line, type EDIT, the line number, and press the Carriage Return,
[CR]. The line number appears underneath. You can make changes in the line
with the subcommands listed in Table 5-1. See Section 1.4 for more information
about the Personal BASIC program editor.
Table 5-1. EDIT subcommands
Subcom. Description
------- -----------
A Instructs the editor to ignore all changes made to the current line,
and to place the cursor at the beginning of the edit line. Enables you
to start editing a line over again. This command is valid only if
there is no other subcommand on the line.
B Brings the cursor to the beginning of a logical line.
[n]C Deletes the character that appears directly above it in the program
line, and inserts the character that you specify to the right of the
C. nC deletes n characters, and inserts all characters after the C.
[n]D Deletes the character that appears directly above it in the edit line.
E Saves all changes and returns Personal BASIC to command level. Works
like a Carriage Return. This command is only valid if it is the only
subcommand on the line.
[ESC] Entered while typing in a program line, [ESC] drops Personal BASIC
into Edit mode. Used during insert mode, [ESC] ends insert mode
without ending the command line.
H Deletes all characters in the program line up to the next Line-Feed,
[LF] then automatically activates the insert subcommand, I.
I Inserts characters into the program line, starting at the point
immediately above the cursor position. All characters up to the next
[ESC] or [CR] are inserted, including Line-Feeds. I[LF] works in the
way, but starts by inserting a Line-Feed. [ESC] ends insert mode
without ending the command line.
K Works much like subcommand S. Searches the program line for a
specified character, and positions the cursor directly beneath that
character. However, the editor deletes all characters up to the
specified character. Specify the character in the edit line
immediately after the K. If the character is not found, the cursor
does not move from the original position, and no characters are
deleted.
L Repositions the cursor below the leftmost character in the program
line.
[LF] To edit succeeding lines of multi-line statements, press [LF] before
entering insert mode. This brings you down to the next physical line.
Q Instructs the editor to ignore all changes made to the current line,
quits editing, and returns Personal BASIC to command level. This
command is valid only if it is the only subcommand on the line.
R Moves the cursor below an imaginary character one to the right of the
rightmost character in the program line.
[n]S Searches the program line for a specified character, and positions the
cursor under the character. Specify the character in the edit line
immediately after the S. If the character is not found, the cursor
does not move from the original position. A command like 99SX finds
the last occurrence of X in the line, and the cursor stays there.
U Moves the cursor back to the previous physical line.
X Positions the cursor at the end of a physical line, up to a Line-Feed,
and enters insert mode. X[LF] inserts a Line-Feed first. Subsequent
characters appear on a new physical line.
Z Deletes a Line-Feed [LF]. Merges 2 physical lines.
Example:
Ok 10 X=COS(Y+Z
^
Something is wrong
Ok EDIT 10
10 X=COS(Y+Z
Ed I) Missing parenthesis is added
10 X=COS(Y+Z) with the I subcommand.
END Statement
The END statement stops the program, closes all files, and return to command
level.
Syntax:
END
Explanation:
You can put an END statement anywhere you want to return to command level. An
END at the end of the program is optional. END differs from STOP in that it
closes all files, returns to command level, and it does not produce a STOP
message.
Example:
Ok 10 PRINT "THE PROGRAM"
Ok 20 PRINT "IS RUNNING"
Ok 30 PRINT "BUT WILL NEVER"
Ok 40 PRINT "REACH THE LAST"
Ok 50 PRINT "WORD OF THIS"
Ok 60 END
Ok 70 PRINT "PROGRAM"
Ok RUN
THE PROGRAM
IS RUNNING
BUT WILL NEVER
REACH THE LAST
WORD OF THIS
EOF Function
The EOF function returns true (-1) at the end of a sequential file.
Syntax:
X = EOF('file number')
Explanation:
When you write a sequential file, its end is automatically marked. While
inputting from the file, you can test whether you are at the end with the end-
of-file function, EOF. EOF returns -1 if you are at the end, 0 if not. If you
try to input past the end of a file, an error results. EOF is useful for
controlling program flow.
Example:
Ok NEW TYPE
Ok 90 REM THIS PROGRAM PRINTS A TEXT FILE AT THE TERMINAL
Ok 100 INPUT "FILE ";F$
Ok 110 IF LEN(F$) = 0 THEN END
Ok 120 ON ERROR GOTO 20000
Ok 130 OPEN "I", 1, F$
Ok 140 WHILE NOT EOF(1)
Ok 150 LINE INPUT #1,R$: ?R$
Ok 160 WEND
Ok 200 ?:CLOSE 1:GOTO 100
Ok 20000 IF ERR = 53 THEN [LF]
?"FILE ";F$;" NOT FOUND": RESUME 100 [LF]
ELSE ON ERROR GOTO 0
ERA Command
The ERA command deletes a file from the disk.
Syntax:
ERA ['disk drive']'filename'
Explanation:
The ERA command erases all files matching the filename, on the drive
specified. Once you ERAse a file, it is irrecoverable. Erasing everything with
ERA *.* is possible, but inadvisable.
Example:
Ok ERA B:GRAPHICS
ERASE Statement
The ERASE statement erases arrays.
Syntax:
ERASE 'array name'{,'array name'}
Explanation:
ERASE erases an array so that you can redimension it or reclaim its memory
space. You must erase arrays before you redimension them. See the DIM
statement in this section.
Example:
Ok 10 DIM PAYROLL$ (10,10)
Ok 20 PAYROLL$ (0,0) = "BECKWITH, JOSEPHINE"
...
Ok 500 ERASE PAYROLL$
Ok 510 DIM PAYROLL$ (10,10,10)
ERL, ERR Variables
The ERL and ERR variables are reserved variables used in error-handling
subroutines.
Syntax:
X = ERL
Y = ERR
Explanation:
ERL contains the line number where the error was found. ERR contains the
error's code. ERL and ERR are reserved variables, which means that you cannot
write them on the left of the equal sign [=] in an assignment statement.
If the statement or command in which the error occurred is in direct mode, the
value of ERL is 65530. If an error occurs in direct mode, the program always
halts.
If the statement is in indirect mode, write IF statements as follows:
IF ERL = 'error line' THEN 'executable statement'
IF ERR = 'error code' THEN 'executable statement'
See the ERROR statement for details on error trapping and examples of ERL and
ERR in an error-trapping subroutine.
ERROR Statement
The ERROR statement simulates a Personal BASIC run-time error, and transfers
control to an error-trapping routine.
Syntax:
ERROR 'numeric expression'
Explanation:
You can define errors and error messages in your programs with the ERROR
statement. ERROR assigns a 'numeric expression', corresponding to an error
code, to an error. The error code is an integer expression. Each time the
error occurs, the program refers to the error code number. If the error code
corresponds to a Personal BASIC error code, the Personal BASIC error message
prints. If an error trap that you have written is in effect, control passes to
the error trap routine.
Two predefined variables are associated with the ERROR statement and error
code: ERL and ERR. ERR assumes the value of the error code constant. You can
use it to write error messages: for example, IF ERR = 100 THEN PRINT "PLEASE
CHECK THE NUMBER AND RE-ENTER".
When an ERROR statement executes, the reserved variables ERR and ERL are set.
ERR is set to the value of the 'numeric expression', which must be within
integer range. ERL is set to the line that contains the ERROR statement.
If no user error trap is set, the message corresponding to the value in ERR is
printed, and the program halts. This occurs if an ERROR statement is executed
in direct mode whether you set a trap or not.
If you set a trap, the program enters the error-trapping routine. You can
examine ERR and ERL in the usual way. To exit the error trap, use RESUME,
whether you entered the trap because of a trappable Personal BASIC error or an
ERROR statement.
See the ERL and ERR variables in this section.
If the error code equals a predefined Personal BASIC error code, the program
simulates the error and prints the error message for that code. The Personal
BASIC error code messages are in Appendix D. When you define your own errors,
it is well to give your error codes values that are much greater than Personal
BASIC's codes. In this way, your programs will not need changing, even if
Personal BASIC's error codes are revised.
Example:
You can simulate errors in both direct and indirect mode. Here is an example
in direct mode:
Ok ERROR 55
You cannot OPEN or KILL a file already open
The following example is in indirect mode:
...
Ok 500 ON ERROR GOTO 550
Ok 510 INPUT "DO YOU WISH TO RECEIVE EARNED INCOME CREDIT"; E$
Ok 515 IF E$ = "NO" THEN GOTO 600
Ok 520 INPUT "IS THE AMOUNT LISTED ON LINE 33 LESS THAN $10,000";X$
Ok 525 IF X$ = "NO" THEN ERROR 200
Ok 530 IF ERR = 200 THEN [LF]
Ok 535 PRINT "YOU ARE INELIGIBLE FOR EARNED INCOME CREDIT."
Ok 540 IF ERL = 525 THEN GOTO 600
Ok 550 RESUME
...
Ok RUN
DO YOU WISH TO RECEIVE EARNED INCOME CREDIT? YES
IS THE AMOUNT LISTED ON LINE 33 LESS THAN $10,000? NO
YOU ARE INELIGIBLE FOR EARNED INCOME CREDIT.
EXP Function
The EXP function returns the constant e raised to an exponent.
Syntax:
X = EXP('numeric expression')
Explanation:
The constant e is the base of natural logarithms, approximately equal to
2.7182. EXP returns a real number.
The numeric expression must evaluate to <= 87.3365. An overflow results in an
error message and signed machine infinity; the program continues running.
Example:
The constant e with EXP function.
Ok 10 X = EXP(3.254)
Ok 20 Y = EXP(8.97)
Ok 30 PRINT X,Y
Ok RUN
25.8937 7863.6
FIELD Statement
The FIELD statement allocates variable space in random file buffers.
Syntax:
FIELD #'file number','field width' AS 'string variable'
{,'field width' AS 'string variable'}
Explanation:
You must write a FIELD statement to transfer information between random file
disks and random buffers. The FIELD statement only allocates variable space;
it does not move data.
The file number is the number that you gave to the file when you opened it.
The field width defines the number of bytes to give to the string variable.
For example, FIELD #10, 20 AS X$, 30 AS Z$ allocates the first 20 bytes of
space to X$, and the next 30 bytes to Z$.
You cannot allocate more space than you created when you opened the file. The
default record length is 128 bytes. For any file, you can write as many FIELD
statements as you want. Re-allocating field space does not cancel the original
mapping; rather, the two maps co-exist. For example, if you specify:
FIELD #10, 20 AS X$, 40 AS Z$, 10 AS Y$
and
FIELD #10, 70 AS N$
the first 20 bytes of N$ are also in X$, the next 40 also in Z$, and the final
10 also in Y$.
Do not use an INPUT or LET statement with a variable that was declared in a
FIELD statement. Otherwise, the variable's pointer moves to string space
instead of to the buffer.
Additional explanation:
In a file buffer, there can be many fields of characters. The arrangement of
variable fields in buffer constitutes a map. Fields have a starting point in
the buffer, and length, in bytes.
P$ is a string variable: P$
|
V
The map created by --------------------
the FIELD statement: | start | length |
----|--------|------
V _______V_______
This is part /-------------/---------------\-----\
of a file \ | | /
buffer: / | | \
\-----------------------------------/
The starting place is where the first character of a field variable is mapped.
The starting place for each variable depends on its place in the FIELD list.
It is the sum of the variable lengths that came before it. The first variable
in a list starts at the beginning of the buffer.
In line 110 of the example below, X$ is allocated bytes 1 to 20. Z$, the
second variable, is allotted bytes 21 to 60. The third variable, Y$, takes
bytes 61-70. Although the total size of the record is 128 bytes, the total
space mapped is 70 bytes.
You can have any number of FIELD statements for the same file number. A second
mapping does does not cancel the first. See the example mapping and its
depiction below:
100 OPEN "R", #10, "TAXES", 128
110 FIELD #10, 20 AS X$, 40 AS Z$, 10 AS Y$
Depiction of the above mapping:
50 bytes as P$ 20 bytes as Q$
^ ^
| |
/----------------^--------\ /---^---\
/ \ / \
| X$ Z$ | Y$ |
| ____^___ __________^_____|__ ^ |
| / 20 \ / 40 | \ /10 \|
/----------V-----------------|-----V-----\---\
| | | | | /
| F I L E | B U F F E R | | | \
+-----+-----+-----+-----+-----+-----+-----+---/
0 10 20 30 40 50 60 70
start----------- 128 total bytes ---------------->
Notice that you do not have to map all the space in a record; you can allocate
fewer bytes than are available to you. However, the total number of bytes that
you allocate cannot exceed the length of the record when you opened it, or an
error occurs.
Example:
Ok 100 OPEN "R", #5, "TAXES", 40
Ok 110 FIELD #5, 20 AS I$, 10 AS D$, 10 AS E$
FIX Function
The FIX function truncates a real number to an integer.
Syntax:
X = FIX(number)
Explanation:
Unlike CINT, FIX does not round the number. Unlike INT, FIX does not return
the next smallest integer for negative numbers; instead, it simply truncates
the number.
Example:
Ok 10 X = 239.77
Ok 20 PRINT FIX(X)
Ok 30 PRINT FIX (-678.3)
Ok RUN
239
-678
FLOAT Function
The FLOAT function converts an integer to a single-precision real number.
Syntax:
X = FLOAT('integer expression')
Explanation:
FLOAT does not change the appearance of the integer, but assigns it more room
in storage. The integer expression must be within legal integer range.
Example:
Ok 10 X = FLOAT(97)
Ok 20 PRINT X
Ok RUN
97
FOLLOW Command
The FOLLOW command traces program variables, and cites the line number.
Syntax:
FOLLOW 'variable'{,'variable'}
Explanation:
The FOLLOW command is a debugging facility that keeps track of all program
variables as the value of each variable changes. FOLLOW lists the value of the
given variable or variables as the value changes. FOLLOW prints a variable
name, the value of the variable, and the line number indicating where the
value changes. The UNFOLLOW command cancels FOLLOW. The FOLLOW command traces
only simple variables -- that is to say: not array variables.
Example:
Ok 10 FOR X = 1 TO 3
Ok 20 N = N + 1
Ok 30 B = B + 1
Ok 40 PRINT N
Ok 50 PRINT B
Ok 60 NEXT X
Ok RUN
1
1
2
2
3
3
Ok FOLLOW N,B
Ok RUN
Var N! = 1 At line 20
Var B! = 1 At line 30
1
1
Var N! = 2 At line 20
Var B! = 2 At line 30
2
2
Var N! = 3 At line 20
Var B! = 3 At line 30
3
3
Ok UNFOLLOW
FOR Statement
The FOR statement creates a loop that executes instructions a given number of
times.
Syntax:
FOR 'counter variable' = 'numeric expression' TO 'numeric expression'
[STEP 'numeric expression']
Explanation:
The FOR statement controls the execution of a FOR-NEXT loop. Statements
between a FOR statement and a corresponding NEXT execute repeatedly, to the
number of times that you specify. FOR-NEXT loops can contain any kind of
executable statement.
The expressions before and after TO determine how many times the loop repeats.
The first numeric expression is the value at which the loop begins; the second
is the value at which it stops. The counter is a numeric variable that takes
the value of the first expression before execution begins, and counts up or
down until it exceeds the value of the second expression. If the initial value
of the counter is outside the range specified by TO and STEP, the FOR loop is
never executed. See the second example below.
STEP is optional; its default value is 1. Every time the loop repeats, the
value of the counter increments or decrements by the value of STEP. For
example, in FOR X = 2 TO 10 STEP 2, the initial value of X is 2. After one
repetition of the loop, the value of X is 4; after two repetitions, 6. When X
= 10, the loop executes once more and stops. The number of execution is 5.
FOR is always used with NEXT. After an execution of a FOR loop, the NEXT
statement sends program control back to the counter. The sign of the STEP and
the value of the counter determine whether the loop ends. If STEP is positive,
the loop repeats as long as the value of the counter is less than or equal to
the value of the final expression. If STEP is negative, the loop repeats as
long as the counter is greater than or equal to the final expression.
You can write FOR-NEXT statements within FOR-NEXT statements; in other words,
you can have a loop within a loop. When you nest loops, the NEXT statement for
the second loop must come before that of the first loop. See the NEXT
statement in this section.
Example:
Ok 10 FOR X = 1 TO 5
Ok 20 PRINT X
Ok 30 NEXT
Ok 40 PRINT "THE VALUE OF THE COUNTER VARIABLE IS"X
Ok RUN
1
2
3
4
5
THE VALUE OF THE COUNTER VARIABLE IS 6
Ok 40
Ok 10 FOR X = 5 TO 1 STEP -1
Ok RUN
5
4
3
2
1
FRE Function
The FRE function returns the number of unused bytes in memory.
Syntax:
X = FRE(0)
Y = FRE(Z$)
Explanation:
FRE requires a dummy argument. Use any argument to find the number of free
bytes in memory. The number of free bytes is a whole number between 0 and
65535.
Example:
Ok PRINT FRE(0)
43000
GET Statement
The GET command reads a record from a random disk file into a file buffer.
Syntax:
GET [#]'file number'[,'record number']
Explanation:
The file number is the number that you gave to the file when you opened it.
The record number is optional. If you leave it out, the next record after the
last GET or PUT goes into the buffer. The greatest record number that you can
have is 32767. See the OPEN statement for an example of GET in context.
Example:
Ok 100 IF X$ = "YES" THEN GET#5, TYPE%: GOTO 200
GOSUB Statement
The GOSUB statement sends program control to a subroutine.
Syntax:
GOSUB 'line number'
Explanation:
The GOSUB statement is paired with the RETURN statement, which brings control
back to the main program at the point where it branched off. You can call a
subroutine from another subroutine.
The line number is the line on which the subroutine begins. You can call and
write subroutines as often as you like, wherever you like. If you write a
subroutine in the middle of a program, take care that the program does not
flow into it naturally by blocking it with STOP, END, or GOTO statements.
The RETURN statement directs execution back to the statement immediately
following the last GOSUB. You can write more than one RETURN statement through
GOSUB. If you are testing for conditions that determine the program's
progress, you might have several RETURNs in a subroutine. The example shows a
subroutine entered by the statement GOSUB 100.
Example:
Ok 10 GOSUB 100
Ok 20 REM RETURN POINT OF SUBROUTINE
Ok 30 PRINT A
Ok 40 GOTO 200
Ok 50 '
Ok 100 REM START OF SUBROUTINE
Ok 110 A=5^6
Ok 120 RETURN
Ok 130 '
Ok 200 END
Ok RUN
15625
GOTO Statement
The GOTO statement sends program control unconditionally to a given line
number.
Syntax:
GOTO 'line number'
Explanation:
The GOTO statement interrupts the normal order of program execution, jumps to
a given line number, and resumes execution from there. If you GOTO a non-
executable statement, execution begins at the first executable statement after
the given line number.
In Personal BASIC, GOTO and GO TO are equivalents. You can use them
interchangeably.
Example:
Ok 10 INPUT "PLEASE ENTER BENEFICIARY'S NAME"; NAME$
...
Ok 100 INPUT "DO YOU WISH TO END THIS PROGRAM";ANSWER$
Ok 120 IF ANSWER$ = "YES" THEN GOTO 1000
Ok 130 GOTO 10
Ok 140 '
Ok 1000 END
HEX$ Function
The HEX$ function returns a string that is the hexadecimal (base 16)
representation of a number.
Syntax:
X = HEX$(numeric expression)
Explanation:
A hexadecimal number is a base 16 integer. The legal symbols for hexadecimal
numbers are the digits 0 through 9 and the characters A through F, which
represent the values 10 through 15. HEX$ does not add a leading &H to the
hexadecimal number it returns. If you want to use the value in the program,
you must write it with &H to establish that it is in hexadecimal notation.
Real numbers round to integers before HEX$ evaluates.
Because HEX$ accepts machine addresses as arguments, the range of integers
HEX$ accepts is -32768 to 65535. The normal legal range for integers is -32768
to 32767. Attempting to assign an address expression to an integer variable
leads to an integer overflow error, unless you assign the value to the
variable with VAL, as in the following example.
Example:
Ok 10 A% = VAL("&H" + HEX$(FRE(0)))
Ok 20 PRINT A%
Ok RUN
-22536
IF Statement
The IF statement sets conditions that determine program flow.
Syntax:
IF 'logical expression' THEN 'statement'{':statement'}
[ELSE 'statement'{':statement'}]
Explanation:
The IF statement evaluates an expression that is either true (-1) or false
(0). If the expression is true, the statements following THEN are executed. If
false, execution continues at the statement after ELSE. If there is no ELSE,
execution continues at the next executable statement.
Separate statements with colons [:] and use a Line-Feed (Ctrl-J) to continue
statements over several lines. You can write IF statements within IF
statements. Each ELSE matches with the nearest lone THEN. THEN or ELSE clauses
are valid only within the context of an IF statement.
You can write a FOR or WHILE statement within the THEN or ELSE clause of an IF
statement. The FOR or WHILE statement must be complete within the THEN or ELSE
clause: the matching NEXT must be in the same clause as the FOR statement, and
the matching WEND must be in the same clause as the WHILE statement. See the
first example below.
If an IF statement occurs within a FOR or WHILE statement (all as part of the
same statement line), the closing NEXT or WEND also closes the IF construct.
See the second example below.
Example:
Ok 5 A% = 5
Ok 10 IF A% > 3 THEN [LF]
FOR K% = 1 TO 5: PRINT A% * K%: NEXT [LF]
ELSE FOR K% = 1 TO 5: PRINT A% / K%: NEXT
Ok RUN
5
10
15
20
25
Ok 10 FOR X = 1 TO 5: [LF]
IF X < 3 THEN PRINT X * X : [LF]
NEXT : [LF]
PRINT "DONE"
Ok RUN
1
4
DONE (The NEXT is always executed.)
INKEY$ Function
The INKEY$ function reads a character from the keyboard, if one is waiting.
Syntax:
X$ = INKEY$
Explanation:
INKEY$ scans the keyboard to detect whether you hit a key. If you do, INKEY$
returns the character. If you don't, INKEY$ returns a null string [""]. INKEY$
stores only one character at a time, namely, the last character entered; the
previous keystroke is replaced and lost.
Unlike the INPUT statement, which suspends program execution until you
respond, INKEY$ does not wait for your input. You can write a WHILE-WEND loop
that runs until you enter a character. In this case, INKEY$ constantly scans
for the character and the program is continuously looping; it has not halted
for your input.
You can test INKEY$ for a particular character. INKEY$ reads each character
from the keyboard buffer. Which character is there can determine program flow.
For example, INKEY$ can check a program to see whether you entered an
interrupt signal; the program jumps to an exit routine if so, or continues if
not.
None of the characters returned by INKEY$ print on the screen, unless you
print them with a subsequent PRINT statement. All characters pass on to the
program except Ctrl-C, Ctrl-S, and Ctrl-Q, which might or might not, depending
upon the exact timing of your entry.
Notice the example program below. It constructs a WHILE-WEND loop in which
INKEY$ reads and stores a keystroke, the current value of INKEY$ is assigned
to a variable, the ASCII value of the character is printed, and the program
loops back to the start. If you enter Ctrl-C while the program is on line 30,
the Ctrl-C is read by INKEY$ and passed on to the program; the program is not
interrupted. If you enter the Ctrl-C while the program is on any other line,
however, it interrupts the loop just as it would in any other Personal BASIC
program. It is possible to disable Ctrl-C's ability to break a program. See
Appendix E, option 1 for more information on Ctrl-C.
Example:
Ok 10 I$ = ""
Ok 20 WHILE I$ = ""
Ok 30 I$ = INKEY$
Ok 40 WEND
Ok 50 PRINT ASC(I$)
Ok 60 GOTO 10
Ok RUN
53 ("5" was hit)
27 ("ESC" was hit)
76 ("L" was hit)
65 ("A" was hit)
104 ("h" was hit)
INP Function
The INP function returns a byte value from a selected input/output port.
Syntax:
X = INP('port number')
Explanation:
The port number must be in the range 0 to 65535. The INP function is the
complement of the OUT statement.
Example:
Ok 200 IF INP(300) > X THEN GOTO 100
INPUT Statement
The INPUT statement lets you enter data while the program is running, and
assigns the data to program variables.
Syntax:
INPUT [;] ['prompt string' '; or ,'] 'variable' {,'variable'}
Explanation:
The INPUT statement prompts you for input with a question mark [?] during
program execution, and waits for your response. After you type a response,
press the Carriage Return [CR] to send it to the program.
The prompt string is a string constant, and must be in quotes ["]. The
variables can be string or numeric. Your responses must match the type of the
variables. String responses, however, need not be in quotes.
If you write a prompt string, the INPUT statement prints it on the screen as
the prompt. The prompt string appears as a question or a statement, depending
on whether you use a comma [,] or a semicolon [;].
If you separate the prompt string from the variables with a semicolon [;], the
INPUT statement adds a question mark [?] to the end of the prompt string. If
you separate the prompt string from the variables with a comma [,], the prompt
prints without a question mark, and without a space after the last character
in your prompt string. You type your response on the same line. For this
reason, you need to include a space as the last character in your prompt
string if you want a clean division between the prompt and your response.
If you do not write a prompt string, or if you write a null string, INPUT
prints a question mark [?] and a space, and awaits your input.
The INPUT statement prints a prompt for each variable, and each response
corresponds to an INPUT variable. If the number of variables and responses
differ, a warning appears. You must separate individual responses with commas
[,]; however, you can also use commas in your response if you enclose the
string in quotation marks ["].
You can enter one console line of characters in response to an INPUT request.
A Carriage Return [CR], Line-Feed [LF], or [ESC] ends the line of input. The
maximum line length is 255 characters.
If you include a semicolon [;] after INPUT in the statement line, pressing the
Carriage Return [CR] after your response does not skip you down to the next
line.
Example:
Ok 10 INPUT "ENTER TODAY'S DATE: ",X$
Ok 20 INPUT "ENTER YOUR IDENTIFICATION NUMBER: ",Z$
Ok 30 IF Z$ = ACCEPTABLE GOTO 100
Ok RUN
ENTER TODAY'S DATE: 9 JULY 1983
ENTER YOUR IDENTIFICATION NUMBER: 359152
(ROCHE> Notice that this book is dated April 1983... 3 months earlier!)
INPUT# Statement
The INPUT# statement assigns data from a sequential disk file to program
variables.
Syntax:
INPUT#'file number','variable'{,'variable'}
Explanation:
The file number is the number that you gave to the file when you opened it.
You assign the data in the file to variables. The types of a variable and its
assigned data must match.
The INPUT# statement works much like the INPUT statement, except that it does
not prompt. Before assigning the data item that you enter to the variable,
INPUT# skips any leading spaces [ ], tabs [HT], Carriage Returns [CR], and
Line-Feeds [LF] that you enter with the data. The first character that is not
one of these is taken as the start of the data. A space [ ], Carriage Return
[CR], Line-Feed [LF], comma [,], or reaching 255 characters signals the end of
the data.
There are 3 kinds of data for the INPUT# statement: numbers, in any of the
numeric formats; quoted strings; and unquoted strings. Data is interpreted as
a number if the variable that you assign it to is numeric. Otherwise, it is
taken as a string. Numbers are ended by reaching end-of-file or 255
characters, or by a Line-Feed [LF], Carriage Return [CR], comma [,], or any
character that is not a valid part of a number.
Strings are treated as quoted if the first non-space character is a quotation
mark ["]. Everything within a pair of quotation marks is taken as data in
quoted strings. You cannot use a quotation mark as a character within the
quoted string because the second quotation mark ends the string. Quoted
strings are also ended by reaching end-of-file or 255 characters.
Unquoted strings can include quotation marks ["]. They are ended by a Carriage
Return [CR], Line-Feed [LF], comma [,], or reaching end-of-file or 255
characters. Trailing spaces in unquoted strings are ignored.
See Section 4.3.2 for more information on sequential files and INPUT#.
Example:
Ok 10 OPEN "I", #10, "BILLING"
Ok 20 INPUT#10, CUSTOMER$, INVOICE%, DATE$
INPUT$ Function
The INPUT$ function returns a specified number of characters from the terminal
or a data file.
Syntax:
X$ = INPUT$('number of characters'[,[#]'file number'])
Explanation:
The string comes from the terminal or from a file, in which case you specify
the file number.
INPUT$ reads exactly the number of characters specified from the terminal or
file, and returns a string containing these characters. All characters are
returned without translation, that is to say: exactly as you put them in.
Control characters are passed to the variable without exception: for example,
Ctrl-C from the terminal and Ctrl-Z from a data file are passed.
If you input the string at the terminal, the characters are not echoed. They
do not appear on the screen. If you try to read beyond end-of-file, you cause
an error.
Example:
Ok 10 PRINT "PASSWORD? ";
Ok 20 X$ = INPUT$(6)
Ok 30 IF X$ = "GEORGE" THEN 1000 ELSE PRINT "WRONG": END
Ok 1000 PRINT "OK"
Ok RUN
PASSWORD? DANIEL
PASSWORD? WRONG
(ROCHE> In fact, Personal BASIC does not display "DANIEL" on the screen: you
type "DANIEL" blindly, then Personal BASIC displays "OK" or "WRONG" after
"PASSWORD? ", only after reading the 6-character input.)
INSTR Function
The INSTR function searches for one string within another, and returns its
position.
Syntax:
X = INSTR(['starting point',]'target string exp.','pattern string')
Explanation:
INSTR looks for the first occurrence of a pattern string within a target
string, and returns its position. The optional starting point is an integer
between 1 and 255. The target string and pattern strings can be string
constants, expressions, or variables.
You can specify a character as a starting point in a string by giving its
ordinal value in the string. For example, X=INSTR(3,"CBAABC","C") returns 6,
because starting at the 3rd character, A, the first C is the 6th character. If
you do not supply a starting point, the search starts from position 1.
If the pattern string is longer than the target pattern, or if the target
pattern is null, or if the pattern string is not in the target pattern, INSTR
returns 0. If the pattern string is null, INSTR returns the starting position,
I or 1.
Example:
Ok 10 X$ = "HOW DO YOU DO?"
Ok 20 X = INSTR(3,X$,"DO")
Ok 30 PRINT X
Ok RUN
5
INT Function
The INT function returns the integer portion of a number as a real number.
Syntax:
X = INT(numeric expression)
Explanation:
INT returns the largest whole number not greater than its argument. The result
is double precision if the argument is double precision; otherwise, it is
single precision.
Example:
Ok 10 X# = INT(5570372182.5)
Ok 20 PRINT X#
Ok RUN
5570372182
KILL Statement
The KILL statement deletes a disk file.
Syntax:
KILL 'string expression'
Explanation:
The string expression evaluates to a filename. KILL deletes the file
associated with that filename. For example, KILL A$ deletes the file ADDRESS
where A$ = ADDRESS. You can KILL any kind of disk file. You cannot kill a file
that is open at the time; an error occurs if you try. The example creates a
file named CALC.BAS and the file is deleted by KILL. KILL can be used within a
Personal BASIC program.
Example:
Ok NEW
Ok 10 A=45:B=56
Ok 20 PRINT A+B
Ok 30 END
Ok SAVE CALC
Ok B$="CALC.BAS"
Ok KILL B$
LEFT$ Function
The LEFT$ function returns a string that contains the leftmost characters of a
string.
Syntax:
X$ = LEFT$('target string','number of characters')
Explanation:
LEFT$ starts at the leftmost character, and returns as many consecutive
characters as you specify. The number of characters must be a positive number
or expression with a value from 0 to 255. Real expressions convert to
integers. The target string can be a string constant, variable, or expression.
If the number of characters is greater than the length of the target string,
LEFT$ returns the entire target string. If the number of characters is 0, the
null string returns.
Example:
Ok 10 INPUT "RADIUS";R
Ok 20 PRINT 3.1416*R^2
Ok 30 INPUT "ANOTHER AREA";C$
Ok 40 IF LEFT$(C$,1)="Y" THEN 10
Ok 50 END
LEN Function
The LEN function returns the length of a string.
Syntax:
X = LEN('string expression')
Explanation:
LEN returns the number of characters as an integer. If the expression is a
null string, LEN returns zero.
Example:
Ok 10 ADDRESS$ = "2114 PARKER ST, BIRDLAND, NEW YORK"
Ok 20 FOR X = 1 TO LEN(ADDRESS$)
Ok 30 PRINT CHR$(42);
Ok 40 NEXT X
Ok RUN
**********************************
LET Statement
The LET statement assigns a value to a variable or array variable.
Syntax:
LET 'variable'='expression'
Explanation:
Using LET to assign values to variables is optional. For example, LET X=Y and
X=Y are identical in meaning. The variable and the expression can be strings
or numbers. For numeric variables and expressions, the type of the expression
converts to match the type of the variable.
Example:
Ok 10 LET NAME$ = "ALYSON"
Ok 20 TICKETOFFICE$ = "BATH, ENGLAND"
Ok 30 LET DESTINATION$ = "CANTERBURY"
Ok 40 DATE.OF.DEPARTURE = 4.1
Ok 50 DATE.OF.ARRIVAL = 4.8
Ok 60 LENGTH.OF.TRIP = DATE.OF.ARRIVAL - DATE.OF.DEPARTURE
Ok 70 PRINT NAME$
Ok 80 PRINT TICKETOFFICE$
Ok 90 PRINT "DESTINATION: " DESTINATION$
Ok 100 PRINT "LENGTH OF TRIP: " LENGTH.OF.TRIP
Ok RUN
ALYSON
BATH, ENGLAND
DESTINATION: CANTERBURY
LENGTH OF TRIP: .7
(ROCHE> No doubt about it, Personal BASIC was made in England...)
LINE INPUT Statement
The LINE INPUT statement requests input from the keyboard, and assigns it to a
string variable.
Syntax:
LINE INPUT[;]["prompt"[, or ;]]'string variable'
Explanation:
LINE INPUT is like the INPUT statement in that it asks you to enter data at
the keyboard, but it accepts an entire line of up to 255 characters as a
response. Your response is assigned to the string variable. A Carriage Return
[CR], Line-Feed [LF], or [ESC] ends your input and sends it to the computer.
The optional prompt is a string that you write as an input request; LINE INPUT
prints it on the terminal and waits for your response. LINE INPUT does not
automatically add a question mark [?] or a space [ ] after the prompt, but you
can write a question mark or space within the prompt string. Including a space
is advisable, because otherwise your input abuts the prompt, on the same line.
If you include a semicolon [;] after LINE INPUT in the statement line,
pressing the Carriage Return [CR] after your response does not skip you down
to the next line.
Example:
Ok 10 LINE INPUT "REASON FOR RETURNING MERCHANDISE";R$
Ok 20 PRINT "THANK YOU. WE ARE PROCESSING YOUR COMPLAINT"
Ok RUN
REASON FOR RETURNING MERCHANDISE?
WRONG SIZE, WRONG COLOR, TASTELESS STYLE.
THANK YOU. WE ARE PROCESSING YOUR COMPLAINT
LINE INPUT# Statement
The LINE INPUT# statement requests input from a sequential disk file, and
assigns it to a string variable.
Syntax:
LINE INPUT#'file number','string variable'
Explanation:
Like LINE INPUT, LINE INPUT# assigns a line of up to 254 characters as input
to a string variable, but the input comes from a sequential disk file. The
file number is the number that you gave to the file when you opened it.
LINE INPUT# reads all characters in a sequential file until it comes to a
Carriage Return [CR], and assigns them to the string variable. The next LINE
INPUT# statement starts where the first left off, and assigns the next line,
up to a Carriage Return, to the next string variable. If a Line-Feed [LF]
immediately precedes a Carriage Return, they are treated as regular characters
and do not end the line.
Example:
Ok 10 OPEN "O", #4, "SCORES"
Ok 20 LINE INPUT "GIVE TEAMS, WINNERS, AND SCORES.", S$
Ok 30 PRINT#1, S$
Ok 40 CLOSE #4
Ok 50 OPEN "I", #4, "SCORES"
Ok 60 LINE INPUT#4,S$
Ok 70 PRINT S$
Ok 80 CLOSE #4
Ok RUN
GIVE TEAMS, WINNERS, AND SCORES.
USC & UCLA: USC. 50-3; CPSLO & FRESNO: CPSLO. 33-20
USC & UCLA: USC. 50-3; CPSLO & FRESNO: CPSLO. 33-20
(ROCHE> No doubt about it, Personal BASIC was bought by Digital Research...)
LIST Command
The LIST command displays a program.
Syntax:
LIST ['line number list']
Explanation:
LIST displays on the terminal the lines of the current program.
If you do not supply a line number, LIST lists the entire program, starting at
the beginning of the program, the lowest line number. If the program is long,
the beginning flies by, and all you see is the end of the program.
You can direct where you want the listing to start or stop by giving line
numbers in the line number list. You can direct the listing to begin with a
particular line number, by giving that line number alone. LIST prints the
program up to a particular line number if you supply a dash [-] followed by
the line number with which you want it to end. If you supply both a beginning
and ending line number, a range of line numbers, such as lines 30 to 70,
prints. You can give more than one range by specifying more than one pair of
line numbers: for example, LIST 20-100, 200-300.
Example:
LIST Lists entire program
LIST 70 Lists line 70 only
LIST -70 Lists all lines, up to line 70
LIST 30-70, 100- Lists lines 30-70 and lines after 100
LIST 30-70, 100-120, 300-999 Lists line 30-70, 100-120, and 300-999
LLIST Command
The LLIST command lists the program currently in memory on a printer.
Syntax:
LLIST ['line number list']
Explanation:
LLIST works in the same way as LIST, but prints the lines on the printer. You
can set the assumed width of the line printer with the WIDTH LPRINT statement.
Initially, it is 72 characters. After a LLIST, Personal BASIC returns to
command level.
(ROCHE> Notice that 72 characters was the width of the ASR-33 Teletype... and
that the LIST Command explanation does not mention any width, and how to set
it... See WIDTH in this section and Appendix E: "The option table".)
Example:
See the LIST command in this section.
LOC Function
The LOC function returns either a record number or the number of sectors read
from or written to a file.
Syntax:
X = LOC('file number')
Explanation:
When used after a GET or PUT in a random disk file, LOC returns the current
record number, that is to say: the record most recently read or written with
GET or PUT. For example:
GET #1
PUT #1,LOC(1)
replaces record #1 in the slot from which it is read.
Used with sequential files, LOC returns the number of sectors read or written
since the file was opened. A sector is a 128-byte block.
Example:
Ok 10 OPEN "R", #8, "FILE"
Ok 20 FIELD #8, 20 AS Z$, 3 AS V$
Ok 30 GET #8, C%
Ok 40 IF LOC(8) > 25 THEN GOTO 90
LOF Function
The LOF function returns the number of 128-byte sectors in the file.
Syntax:
X = LOF('file number')
Explanation:
For a file just opened for output, the number of 128-byte sectors is zero.
Example:
Ok 100 X = LOF(5)
Ok 110 IF X > 100 THEN PRINT "OPEN NEW FILE": GOTO 200
LOG Function
The LOG function returns the natural logarithm of a number.
Syntax:
X = LOG('numeric expression')
Explanation:
The numeric expression must evaluate to greater than zero.
Example:
Ok 10 REM This program finds the base-2 logarithm of 23
Ok 20 PRINT LOG(23)/LOG(2)
Ok RUN
4.52356
LOG10 Function
The LOG10 function returns the base-10 logarithm of a number.
Syntax:
X = LOG10('numeric expression')
Explanation:
The numeric expression must evaluate to greater than zero.
Example:
Ok 10 X = LOG10(1000)
Ok 20 PRINT X
Ok RUN
3
LPOS Function
The LPOS function returns the position of the line printer print head within
the line printer buffer.
Syntax:
LPOS( )
Explanation:
The position returned is the count of the characters printed since the last
Carriage Return [CR] character. The BackSpace [BS] counts as -1. If you have
printed control characters that alter the position of the print head, this
count will not reflect the true position of the head.
Example:
Ok 10 X = 90
Ok 20 IF LPOS(X) > 45 THEN GOTO 100
LPRINT Statement
The LPRINT statement directs output to a printer.
Syntax:
LPRINT ['list of expressions']
LPRINT USING 'format string expression';'list of expressions'
Explanation:
The LPRINT statement works like the PRINT and PRINT USING statements in this
section, except that output goes to a line printer. You can set the assumed
width of the line printer with the WIDTH LPRINT statement. Initially, it is 72
characters. The format string expression must be separated from the variable
list with a semicolon [;]. The listed expressions must be separated by commas
[,].
Example:
Ok 10 LPRINT USING "#####"; X$,Y,Z$,B
LSET Statement
The LSET statement moves a string into a specified string variable, without
reassigning the string variable.
Syntax:
LSET 'string variable'='string expression'
Explanation:
LSET is commonly used to move data to file buffers, by LSETing into variables
mapped into file buffers by a previous FIELD statement. LSET is not limited to
this use, however.
If the string expression takes fewer bytes than you assigned to the string
variable in a FIELD statement, LSET justifies the left margin, and pads the
string to the right with spaces. If the string is longer than the destination,
LSET ignores the extra characters. If a string takes more bytes than you
assigned it in the FIELD statement, characters on the right are dropped. You
must convert numbers to strings with MKD$, MKI$, or MKS$ before you LSET them.
The counterpart of LSET is RSET.
Example:
Ok 10 A$ = STRING$(20,"X")
Ok 20 INPUT "REPLACE"; B$
Ok 30 PRINT A$
Ok 40 LSET A$ = B$
Ok 50 PRINT A$
Ok 60 GOTO 10
Ok RUN
REPLACE? 3434DfrE~%^
XXXXXXXXXXXXXXXXXXXX
343DfrE~%^
REPLACE? 7474747474747474747474747474747
XXXXXXXXXXXXXXXXXXXX
74747474747474747474
MERGE Command
The MERGE command inserts a disk file into a program in memory.
Syntax:
MERGE 'filename'
Explanation:
The MERGE command inserts a file on disk into a file already in memory. As
long as the line numbers of the 2 files are different, MERGE does not erase
the original file. If any line numbers in the disk file duplicate line numbers
in the file in memory, the disk lines replace the memory lines.
For additional information, see the explanation of the CHAIN command.
Example:
Ok 10 PRINT "THIS IS THE ORIGINAL PROGRAM"
Ok 20 PRINT "THIS LINE WILL BE DELETED BY THE MERGE"
Ok 30 PRINT "THIS LINE STAYS BECAUSE IT HAS A UNIQUE LINE NUMBER"
Ok SAVE ORIGINAL
Ok 15 PRINT "THIS IS THE OVERLAY"
Ok 20 PRINT "THIS LINE REPLACES LINE 20 IN THE ORIGINAL PROGRAM"
Ok SAVE OVERLAY
Ok OLD ORIGINAL
Ok MERGE OVERLAY
Ok RUN
THIS IS THE ORIGINAL PROGRAM
THIS IS THE OVERLAY
THIS LINE REPLACES LINE 20 IN THE ORIGINAL PROGRAM
THIS LINE STAYS BECAUSE IT HAS A UNIQUE LINE NUMBER
MID$ Function
The MID$ function returns a segment of a string.
Syntax:
X$ = MID$('string expression','starting point'[,'length'])
Explanation:
MID$ returns a string from another string. The starting point is a numeric
expression representing the point in the original string where the string
segment begins. The length is a numeric expression specifying the length of
the segment, in number of characters to the right of the starting point. If
you omit the length parameter, MID$ returns all the characters after the
starting point.
If the starting number is greater than the string is long, MID$ returns a null
string. If the length of the segment is greater than the number of characters
to the right of the starting point, all characters after the starting point
return. See also the RIGHT$ and LEFT$ functions. You can also use MID$ as a
statement; see the MID$ Statement in this section.
Example:
Ok 10 X$ = "MR. JAMES GRAHAM SCOTT"
Ok 20 Y$ = MID$(X$,18,5)
Ok 30 PRINT Y$
Ok RUN
SCOTT
MID$ Statement
The MID$ statement replaces part of one string with another.
Syntax:
MID$('string variable','starting point'[,'length'])=('string expr.')
Explanation:
MID$ imposes a replacement string upon the original string, beginning at a
given starting point. Characters are replaced only to the length of the
original string.
You can specify the number of characters from the replacement string to
replace the characters in the original string. Otherwise, the replacement
characters substitute for the original characters to the length of the
original string or replacement string, whichever is shorter.
The number of characters replaced is the least of:
1) The length argument.
2) The number of characters in the original string to the right of the
starting point (that is to say: length - [starting point] + 1).
3) The length of the replacement.
Example:
Ok 10 DAY$ = "MONWEDFRI"
Ok 20 RESCHEDULE$ = "TUE"
Ok 30 INPUT "COURSE NUMBER";C$
Ok 40 IF RIGHT$(C$,3) ="003" THEN [LF]
MID$(DAY$,4,3) = RESCHEDULE$
Ok 50 PRINT DAY$
Ok RUN
COURSE NUMBER? 53-003
MONTUEFRI
MKD$, MKI$, MKS$ Functions
The MKD$, MKI$, and MKS$ functions convert numbers to strings, for use in
random file buffers.
Syntax:
X$ = MKD$('double-precision expression')
Y$ = MKI$''integer')
Z$ = MKS$('single-precision expression')
Explanation:
MKI$ returns a 2-byte string. MKS$ returns a 4-byte string. MKD$ returns an 8-
byte string. As an option, MKD$ can also change the internal representation of
a double-precision number from IEEE to Microsoft BASIC format. See Appendix E,
"The option table", for more information.
You must convert numbers to strings with these functions before you can move
them into a random file buffer with RSET or LSET. The CVD, CVI, and CVS
functions are the reverse of MKD$, MKI$, and MKS$.
Example:
Ok 100 FINAL = (100/X) * (100 - Y)
Ok 110 FIELD #2, 5 AS Z$, 5 AS B$
Ok 120 LSET Z$ = MKI$(FINAL)
Ok 130 LSET B$ = T$
Ok 140 PUT #2
...
NAME Statement
The NAME statement renames a file.
Syntax:
NAME 'old string expression' AS 'new string expression'
Explanation:
The NAME statement simply gives a new name to a file that already exists. NAME
does not alter the file or disk space in any way. Be sure that the old file
exists and the new name does not; otherwise, an error occurs.
Example:
Ok NAME "VERSION2.BAS" AS "FINAL.BAS"
NEW Command
The NEW command clears a file from memory, and optionally names the new
program.
Syntax:
NEW [filename]
Explanation:
Use NEW in preparation for writing a new program. If you have not saved the
current file, you lose it if you clear it with NEW. If you use the [filename]
option, you can use the SAVE command later without a name.
Example:
Ok 10 X = SQR(25)
Ok 20 PRINT X
Ok NEW
Ok LIST
NEXT Statement
The NEXT statement marks the end of a FOR-NEXT loop.
Syntax:
NEXT ['counter']{,counter}
Explanation:
The NEXT statement after the instructions in a FOR-NEXT loop sends program
control to the beginning of the loop. The loop runs again if the criteria for
stopping it are not fulfilled: that is to say: if the counter variable is not
greater than the second numeric expression in the FOR statement.
Supplying the name of the counter variable is optional. The NEXT statement
assumes the nearest counter variable. If you have nested loops, you must
specify which counter variable you are returning to at the end of the loop's
execution. Use NEXT to direct execution first to the nested loop, then to the
outer loop by specifying first the nested counter variable, then the outer.
Example:
Ok 10 FOR Z = 1 TO 3
Ok 20 PRINT "Y"
Ok 30 FOR Q = 1 TO 2
Ok 40 PRINT "X"
Ok 50 NEXT Q,Z
Ok RUN
Y
X
X
Y
X
X
Y
X
X
OCT$ Function
The OCT$ function returns a string expression of an octal (base 8) number.
Syntax:
X$ = OCT$('numeric expression')
Explanation:
OCT$ returns a string that is the base-8 equivalent of a decimal or
hexadecimal value. The value of the decimal or hexadecimal expression is
rounded to an integer before conversion. It must be in legal integer range,
-32768 to 32767.
OCT$ is similar to HEX$ and STR$. HEX$ returns the character representation of
a hexadecimal (base 16) number. STR$ returns the normal (base 10) character
representation of a number.
Example:
Ok 10 X$ = OCT$(3.4)
Ok 20 PRINT X$
Ok RUN
3
OLD Command
The OLD command loads an existing program file into memory.
Syntax:
OLD 'filename'
Explanation:
OLD closes all open files, and erases any variables or data in memory before
loading the named file. Thus, OLD performs an implicit NEW command. After
loading, Personal BASIC returns to command level.
The filename is the name that you gave to the file when you saved it. You need
not include the default filetype, BAS.
Example:
Ok OLD TEST
Ok (Program TEST in now in your working storage.)
ON Statement
The ON statement transfers program control to one of a list of line numbers,
depending on the computed result of the numeric expression. The ON statement
has 2 forms.
Syntax:
ON 'numeric expression' GOTO 'label'{,'label'}
ON 'numeric expression' GOSUB 'label'{,'label'}
Explanation:
The value of the numeric expression determines where program execution
transfers. If the expression evaluates to 1, ON branches to the first label.
If it evaluates to 2, ON branches to the second label, and so on.
You can specify an optional label to control the action taken when the value
of the expression falls outside the range of line numbers. If you use the
optional label and the numeric expression evaluates to zero or a value less
than or greater than the number of line numbers, control passes to the next
statement in order, with no error. Test the value of the expression before
writing an ON statement. Non-integer values round to the nearest whole number.
In the ON-GOSUB statement, each numeric expression must be the number of the
first line of a subroutine. The RETURN statement in the subroutine returns
control to the first executable statement following the ON statement. There is
no limit to the line numbers that you can use in an ON statement, and you can
write an ON statement anywhere in your program.
Example:
Ok 10 X = 1
Ok 20 ON X GOTO 70,80,90,990
Ok 70 PRINT "SEASON TO DATE:"X + 1
Ok 80 PRINT "SEASON TO DATE:"X + 2
Ok 90 PRINT "SEASON TO DATE:"X + 3
Ok 120 X=X+1: GOTO 20
Ok 990 END
Ok RUN
SEASON TO DATE: 2
SEASON TO DATE: 3
SEASON TO DATE: 4
SEASON TO DATE: 4
SEASON TO DATE: 5
SEASON TO DATE: 6
ON ERROR GOTO Statement
The ON ERROR GOTO statement enables you to trap run-time errors, and branch
control to a line number when an error occurs.
Syntax:
ON ERROR GOTO 'line number'
Explanation:
ON ERROR GOTO lets you trap run-time errors by jumping to a given line number
when Personal BASIC detects an error.
You can disable error trapping, or restore Personal BASIC's own error handling
in an error trapping routine, by using ON ERROR GOTO 0.
When you use ON ERROR GOTO 0 in an error trapping routine, Personal BASIC
prints its original error message and then stops. It is a good practice to
always use ON ERROR GOTO 0 in an error trapping routine, so that you can trap
unexpected errors.
If you have not written an error trap for numeric overflow, Personal BASIC
prints its error message and continues running. However, if you have an error
trap, Personal BASIC prints its message and then stops.
The following errors are trappable with ON ERROR GOTO: 4-6, 9, 11, 14, 15, 23,
50, 52-58, 61-64, 67, 99, 102, 107, 108. See Appendix D for the error message
text.
Example:
Ok 80 ON ERROR GOTO 100
OPEN Statement
The OPEN statement lets you input and output to a file or device.
Syntax:
OPEN 'mode',[#]'file number','filename'[,'record length']
Explanation:
You must OPEN a disk file before you can move data into it or out of it. The
OPEN statement assigns the file an I/O buffer, and determines the mode under
which the file is accessible to I/O.
The file number is an integer expression with a value between 1 and 15. A file
number belongs to a file for as long as it is open. Closing a file frees its
number for reassignment. The record length is an integer expression that sets
the record length for random files. It is optional. The default length is 128
bytes. A record length given for a sequential file is ignored.
The file mode is either sequential output or sequential input, or random input
and output. Specify the mode with one of the following initials:
O Output for sequential files
I Input for sequential files
R Input and output for random files
When you open a file for output in "O" mode, if the file did not exist
already, it is created. If it did exist, the existing file is erased, and a
new file by that name is created. In "I" mode, the file must exist, or an
error results. In "R" mode, if the file does not exist, it is created.
Example:
Ok 10 OPEN "R", #1, "FUNDS"
Ok 20 FIELD #1, 10 AS V$, 10 AS X$, 30 AS N$
Ok 30 INPUT "ENTER A 4-DIGIT CODE", CODE!
Ok 40 GET #1, CODE!
OPTION BASE Statement
The OPTION BASE statement sets the base for array dimensions.
Syntax:
OPTION BASE '0 or 1'
Explanation:
You use OPTION BASE to set the minimum value for array subscripts within a
dimension. The default base is zero; thus, the first element in an array has a
subscript of zero. You can set the array dimensions so they begin at 1, or
reset them to zero.
You can use OPTION BASE as many times as required. See the DIM statement and
Section 2.2.3.
Example:
Ok 10 OPTION BASE 1
Ok 20 DIM A%(10)
Ok 30 OPTION BASE 0
Ok 40 DIM B%(10)
A% now has 10 elements, 1-10. B% has 11 elements, 0-10.
OUT Statement
The OUT statement sends a byte to a CPU output port.
Syntax:
OUT 'integer expression','integer expression'
Explanation:
The first integer expression is the port number. The second expression is the
byte that you are sending to the port; it must evaluate to an integer between
0 and 65535.
Example:
Ok 100 IF X% > 5 THEN OUT 9,(X-2)
PEEK Function
The PEEK function returns the contents of a memory location.
Syntax:
X% = PEEK('memory location')
Explanation:
PEEK returns the contents of byte at the specified location. The value
returned is a decimal integer from 0 to 255. The memory location is an integer
from 0 to 65535. The complement of PEEK is the POKE statement.
Example:
Ok 100 BYTE% = PEEK(234)
POKE Statement
The POKE statement writes a byte of data to a memory location.
Syntax:
POKE 'location to poke','data to poke'
Explanation:
POKE stores a value as a 1-byte integer. The location to poke is an absolute
address expressed as an integer from 0 to 65535. The data to poke is an
integer expression from 0 to 255. If the data expression evaluates outside
this range, POKE stores the low-order byte of the result. For example:
Ok 10 POKE X%, 257
has the same effect as:
Ok 10 POKE X%, 1
The complement of POKE is PEEK. You can use PEEK and POKE for passing
arguments and data to machine-language subroutines.
Example:
Ok 100 FOR LOC% = 1 TO LEN(OUT.MSG$)
Ok 120 POKE MSG.LOC% + LOC%, ASC(MID$(OUT.MSG$,LOC$))
Ok 130 NEXT LOC%
POS Function
The POS function returns the current position of the cursor on a console or
printer.
Syntax:
X = POS('dummy argument')
Explanation:
The leftmost position of the cursor is zero. POS does not necessarily give the
physical position of the print head. See also the LPOS function.
Example:
Ok 40 X = POS(0)
Ok 50 PRINT "THE PRINT HEAD IS AT COLUMN: "; X
Ok 60 IF WIDTH.LINE < POS(0) THEN WIDTH.CHR = X
PRINT Statement
The PRINT statement outputs data to the console.
Syntax:
PRINT ['expression' {', or ;' 'expression'} [', or ;']]
Explanation:
PRINT outputs the expressions to the console. You can use any number of
expressions with the PRINT statement, separated by a comma [,] or semicolon
[;].
The punctuation used to separate the expressions determines the position of
the expressions on the screen. Personal BASIC divides a line into print zones,
consisting of 14 spaces each. When you use a comma [,] to separate the
expressions in the PRINT statement, Personal BASIC prints each expression
individually at the next available print zone. If you use a semicolon [;],
Personal BASIC prints string expressions consecutively, with no spaces
separating the expressions. Numerical expressions are printed together, with a
space for the sign.
If you end a list of expressions with a comma [,], Personal BASIC spaces to
the next print zone, but does not move to a new line. If you end a list with a
semicolon [;], Personal BASIC leaves the cursor at the end of the last
expression.
A question mark [?] can be used in Personal BASIC programs in place of PRINT.
? A means the same as PRINT A.
Example:
Ok 10 PRINT "TESTING Personal BASIC"
Ok 20 PRINT
Ok 30 A$ = "ONE" : B$ = "TWO" : C$ = "THREE"
Ok 35 A=23:B=567:C=5
Ok 40 PRINT A$,B$,C$
Ok 50 PRINT A$;B$;C$
Ok 60 PRINT A,B,C
Ok 70 PRINT A;B;C
Ok 80 END
Ok RUN
TESTING Personal BASIC
ONE TWO THREE
ONETWOTHREE
23 567 5
23 567 5
PRINT# Statement
The PRINT# statement outputs data to a disk file.
Syntax:
PRINT# 'file number','expression'{,'expression'}
Explanation:
The PRINT# statement writes expressions to the file specified by the file
number. The file number is the number that you gave to the file when you
opened it. Each PRINT# statement executed creates a single record. Each
expression used in the PRINT# statement creates a single field.
You can use any number of expressions with the PRINT# statement, and separate
each one with a comma [,] or semicolon [;].
PRINT# writes the data to the file exactly as it would print on the screen
using the PRINT statement.
You must express exactly how you want the data to appear on disk by
punctuating it properly.
For example, say:
X$ = "Lewis"
Z$ = " C. S."
and you want to write:
Lewis, C. S.
to disk. Since neither variable contains a comma [,], either before "Lewis" or
after " C. S.", the statement:
Ok PRINT#1,X$;Z$
writes the data to disk as:
Lewis C. S.
If you want to insert a comma [,] as a delimiter, you must use the statement:
Ok PRINT#1,X$;",";Z$
with the comma as a literal string in quotation marks [","].
For more information, see Section 4.2.
Example:
Ok 50 PRINT#FIVE.TEX, A$,B$,C$
PRINT USING Statement
The PRINT USING statement prints output according to a format.
Syntax:
PRINT USING 'string expression';'list of expressions'
PRINT#'file number', USING 'string expression';'list of expr.'
Explanation:
The PRINT USING statement prints the data on the screen. The PRINT# USING
statement prints the data on a disk file. You can print strings or numbers
with either statement. For the PRINT# USING statement, the file number is the
number that you give to the file when you open it.
For both statements, the string expression in quotation marks ["] is a list of
characters that determine the fields and formats of printed data. The list of
expressions contains the items to print, separated by commas [,] or semicolons
[;]. If the list ends with a semicolon [;], the cursor is left at the end of
the last expression. The characters in the format specification are replaced
by the data in the print list, unless they are literal characters.
The following table summarizes Personal BASIC's formatting characters. They
are described in detail in Section 4.2.1.
Table 5-2. String field formatting characters
Char. Explanation
----- -----------
! Tells the statement to print the first character of each specified
string.
\chars\ Chars plus 2 indicates the total number of characters to print from
the specified string.
& Specifies a variable-length string field.
# Represents each digit position in a numeric field.
. Inserts a zero to fill digit positions as necessary.
+ Prints the sign of the number, plus [+] or minus [-], before the
printed number.
- Prints negative numbers with a trailing minus sign [-].
** Fills leading spaces in the numeric field with asterisks [*].
$$ Prints a dollar sign [$] to the immediate left of the printed number.
**$ Fills leading spaces with asterisks [*] and inserts a dollar sign [$]
to the left of the number.
, Inserts a comma [,] between every 3rd digit on the left side of the
decimal point [.].
^^^^ Specifies exponential format.
_ (Underscore: _ ) Prints the next character as a literal character.
You can include string constants in the format string, as shown in the
following example.
Example:
Ok 10 PRINT USING "THIS IS FILE _##:";4%
Ok RUN
THIS IS FILE #4
PUT Statement
The PUT statement writes a record from a buffer to a random disk file.
Syntax:
PUT [#]'file number'[,'record number']
Explanation:
The file number is the number that you gave to the file when you opened it.
The record number is optional. If you do not give a record number, PUT uses
the next record number in sequence after the last GET or PUT. The largest
valid record number is 32767.
You should use LSET or RSET before a PUT, to place the data into the random
buffer.
Example:
Ok 100 LSET Q$ = X$
Ok 120 PUT#2, RCORD%
RANDOMIZE Statement
The RANDOMIZE statement seeds the random number generator.
Syntax:
RANDOMIZE ['numeric expression']
Explanation:
You use RANDOMIZE with the RND function to generate random numbers. If you
omit the optional numeric expression, Personal BASIC asks for a random seed
number on which to base RANDOMIZE.
If you do not use RANDOMIZE at the beginning of a program that relies on
random numbers, the RND function returns the same sequence of numbers every
time that you run the program. See the RND function for further information on
generating random numbers.
Example:
Ok 10 RANDOMIZE 45
Ok 20 FOR X = 1 TO 10
Ok 30 PRINT RND
Ok 40 NEXT X
Ok RUN
.957395
.427143
.806267
.0206223
.86628
.886706
.435054
.199773
.505868
.801594
READ Statement
The READ statement assigns values from a DATA statement to variables.
Syntax:
READ 'variable'{,'variable'}
Explanation:
The READ statement and DATA statement are always used together. READ assigns
the values listed in DATA to a corresponding list of variables, one by one.
The variables can be numeric and string. They must agree in type with the
constant values in the DATA statement; otherwise, an error results.
You can use one READ with several DATA statements, or vice versa. If the
number of values in the DATA statement is greater than the number of variables
in the READ statement, the next READ statement picks up the remaining
constants where the first left off, and assigns them to the variables in its
list. If there are no subsequent READ statements, however, the extra data is
ignored.
If there are fewer values in the DATA statement than variables in the READ
statement, the next data statement is found and read. If there is none, an
out-of-data error results.
You can use the RESTORE statement to re-read DATA items from the start of a
specified line number. See the RESTORE and DATA statements in this section.
Example:
Ok 10 READ X,Y,Z
Ok 20 RESTORE
Ok 30 AVERAGE = (X + Y + Z)/3
Ok 40 DATA 23.4, 89.2, 77
Ok 50 PRINT AVERAGE
Ok 60 READ X,Y,Z
Ok 70 PRODUCT = X * Y * Z
Ok 80 PRINT PRODUCT
Ok 90 END
Ok RUN
63.2
160721
REM Statement
The REM statement introduces a remark.
Syntax:
REM 'remark'
Explanation:
Remarks help clarify the logic of a program. Remarks appear in the program
listing as written, but they are not executable. Remarks can be as long as 255
characters. If you write a remark longer than the width of the screen, you can
extend the line with a Line-Feed [LF].
You can use a single apostrophe ['] to show a remark at the end of a line. If
you branch into a REM line with a GOTO statement, the program continues
executing at the first executable line after the REM.
The single apostrophe ['] character has the same effect as REM. For example:
Ok 100 'This is a comment
is a valid statement.
Example:
Ok 10 REM THIS PROGRAM FINDS THE SQUARE OF A NUMBER
Ok 20 INPUT "ENTER A NUMBER TO BE SQUARED";X
Ok 30 S = X * X
Ok 40 PRINT S
Ok 50 'RETURN FOR ANOTHER NUMBER
Ok 60 GOTO 20
Ok 70 END
RENUM Command
The RENUM command renumbers program lines.
Syntax:
RENUM ['new first number'][,'new first line'][,'increment']
Explanation:
If your program line numbers are irregular because you have inserted new lines
between existing lines, you can renumber the entire program without having to
change GOTO or other address-dependent statements.
Used alone, RENUM numbers the first line of the program 10 and increments
succeeding lines by 10. You can supply a new first number, which is the number
where you want the renumbering to begin. You can also supply a new first line,
which is the line number where you want the renumbering to begin.
You can also specify an increment for line numbering. For example:
RENUM 10,30,10
begins numbering at the old line 30, assigns it the line number 10, and sets
an increment of 10. The following line numbers are 20, 30, 40, and so on.
You can use any of the RENUM options alone. However, if you specify only an
increment, leave commas [,] as place markers to show that you are supplying an
incremental value, rather than a new first number or new first line. For
example, RENUM ,,20.
RENUM adjusts all line number references in GOTO, GOSUB, THEN, ON-GOTO, and
ON-GOSUB statement, to reflect the new line numbers. If you have a non-
existent line in one of these statements, an error results.
You cannot use RENUM to change the order of program lines.
Additional documentation:
When you RENUMber programs, you must have enough free space in memory. The
amount of free space you need is 2 bytes per numbered program line. For
example, a program with 1200 program lines needs at least 2400 bytes of free
memory for RENUM to work. Use the FRE function to find the bytes available.
You can now re-order lines and move program blocks with RENUM. The new syntax
is as follows:
RENUM ['new line'][',increment'][',start line'][',end line']
Notice the first 2 parameters refer to the new line numbers, the second 2 to
the old. The new first line number is the new number you give an old line. The
default is 10. For the increment, the default is also 10. The start line is
where you want renumbering to begin. The default is line 0. The end line is
the line where renumbering stops. The default is the end of the program --
take care not to renumber your whole program accidentally. RENUM with no
arguments or only the new first line number behaves as before.
Useful hint: you can use RENUM with SAVE to duplicate line numbers, as
follows:
SAVE CALC, 100-200
RENUM 1000,,100,200
MERGE CALC
This will result in lines 100-200 repeated both in their original positions
and as lines 1000-1100. BE CAREFUL: new line numbers overwrite old identical
line numbers. You might lose a line you wanted.
Example:
Ok 15 X = 5
Ok 20 Z = 3
Ok 25 Y = 10
Ok 30 PRINT X + Y - Z
Ok RENUM
10 X = 5
20 Z = 3
30 Y = 10
40 PRINT X + Y -Z
REPLACE Command
The REPLACE command replaces an old version of a file with a new version.
Syntax:
REPLACE ['filename'][,'line number list']
Explanation:
You use REPLACE with OLD. After you have loaded an old file and revised it,
REPLACE sends the revised version onto disk, replacing the old version.
If you specify a filename, REPLACE saves the source program in 'filename',
rather than the current program name. You can save parts of a program by
specifying a line number list.
In general, REPLACE works exactly like SAVE, except that with REPLACE the name
of the file that you want to save can already belong to another file. The
example brings program COUNTPROG into working storage, adds or replaces line
130, and stores the revised program in permanent storage on disk.
Example:
Ok OLD COUNTPROG
Ok 130 IF X = 10 THEN END
Ok REPLACE
(ROCHE> I hope that I am not the only one to notice that "COUNTPROG" is a 9-
characters filename...)
RESET Statement
The RESET statement allows you to change disks while the program is running.
Syntax:
RESET
Explanation:
RESET resets the CP/M disk system, then performs a log-in on the disk that was
current before your program executed the RESET. For example, if the current
disk is B, after you use RESET the current disk is B, but both drives A and B
will be logged in.
You must ensure that no files are open before you change disks. After you make
the change, use the RESET statement so your program can continue without
rebooting.
(ROCHE> So, this means that Personal BASIC was programmed for CP/M-86, itself
a direct Intel 8086 translation of CP/M 2.2 (using BDOS Version 2), since
CP/M-86 Plus and Concurrent CP/M (both using BDOS Version 3) no longer need to
reset the disk system when changing disks...)
Example:
200 RESET
RESTORE Statement
The RESTORE statement re-reads DATA statements.
Syntax:
RESTORE ['line number']
Explanation:
RESTORE lets you use more than one READ for a single DATA statement. After a
READ, a RESTORE finds the first item in the first DATA statement, and
establishes it as the starting point for the next READ statement.
You can specify any DATA statement in the program as the object of a RESTORE
statement, by giving its line number. The line number that you give with
RESTORE does not have to refer to a DATA statement, or even exist. The next
READ statement finds the next DATA statement after or equal to the line number
specified.
Example:
Ok 10 READ X,Y,Z
Ok 20 RESTORE
Ok 30 AVERAGE = (X + Y + Z)/3
Ok 40 DATA 23.4, 89.2, 77
Ok 50 PRINT AVERAGE
Ok 60 READ X,Y,Z
Ok 70 PRODUCT = X * Y * Z
Ok 80 PRINT PRODUCT
Ok 90 END
Ok RUN
63.2
160721
RESUME Statement
The RESUME statement continues execution after an error.
Syntax:
RESUME [0]
RESUME NEXT
RESUME 'line number'
Explanation:
After an error has been detected and trapped, RESUME restores the program to
normal execution. You write a RESUME statement at the end of an error trapping
routine, and only there. A RESUME statement executed anywhere except in an
active error trap causes an untrappable error.
RESUME used by itself, or followed by a zero, sends program control back to
the statement where the error occurred.
RESUME NEXT sends program control to the statement following the one that
caused the error.
RESUME 'line number' sends program control to a given line number.
Example:
Ok 100 ON ERROR GOTO 700
...
Ok 700 IF (ERR = 300) AND (ERL = 150) THEN PRINT
"MINIMUM NUMBER OF DEPENDENTS IS 1": RESUME 140
RETURN Statement
The RETURN statement transfers control from a subroutine back to the calling
program.
Syntax:
RETURN
Explanation:
RETURN transfers execution of a program to the first executable statement in
the main program following a subroutine call. The subroutine call can be a
GOSUB or ON-GOSUB statement.
Example:
Ok 10 GOSUB 100
Ok 20 REM RETURN POINT OF SUBROUTINE
Ok 30 PRINT A
Ok 40 GOTO 200
Ok 50 '
Ok 100 REM START OF SUBROUTINE
Ok 110 A=5^6
Ok 120 RETURN
Ok 130 '
Ok 200 END
Ok RUN
15625
RIGHT$ Function
The RIGHT$ function returns the rightmost characters of a string.
Syntax:
X$ = RIGHT$('target string','number of characters')
Explanation:
RIGHT$ assigns the number of characters that you specify on the right of a
target string to a new string variable. If the number of characters that you
ask for is greater than or equal to the length of the string, the entire
string returns; if you ask for zero characters, a null string returns.
Example:
Ok 10 A$ = "Marketing Strategies"
Ok 20 B$ = "Regional Responses"
Ok 30 C$ = "Test Results"
Ok 40 INPUT "CATALOG NUMBER"; CATALOG$
Ok 50 IF RIGHT$(CATALOG$,1) = "1" THEN PRINT "YOU HAVE CHOSEN"
Ok 60 PRINT "TESTPRO CATALOG SERIES1"
Ok 70 PRINT "PLEASE CHOOSE FROM THE FOLLOWING HEADINGS: "
Ok 80 PRINT A$
Ok 90 PRINT B$
Ok 100 PRINT C$
Ok RUN
CATALOG NUMBER? CASPAR BLEEBLEBOX CATALOG 201
YOU HAVE CHOSEN
TESTPRO CATALOG SERIES1.
PLEASE CHOOSE FROM THE FOLLOWING HEADINGS:
Marketing Strategies
Regional Responses
Test Results
RND Function
The RND function generates and returns a random number.
Syntax:
X = RND [('numeric expression')]
Explanation:
RND returns a uniformly-distributed random number in the open interval between
zero and 1. Unless you write a RANDOMIZE statement before the RND statement,
the same sequence of random numbers always generates on every run.
RND acts differently depending upon whether the numeric expression evaluates
to a positive number, negative number, or zero:
- RND ('positive expression') returns the next number in the current
sequence.
- RND ('negative expression') reseeds the random number generator with
the negative number, and returns the first random number in the new
sequence.
- RND (0) returns the last random number generated, without affecting
the current sequence.
The numeric expression is optional. If you do not give one, RND acts as if you
had given a positive expression as an argument.
Example:
Ok 10 RANDOMIZE
Ok 20 X = RND
Ok 30 ROLL$ = "TAILS"
Ok 40 IF X > .5 THEN ROLL$ = "HEADS"
Ok 50 INPUT "HEADS OR TAILS";R$
Ok 60 IF R$ = ROLL$ THEN PRINT "YOU WIN" ELSE PRINT "YOU LOSE"
Ok RUN
Random number seed (-32768 to 32767)? 2
HEADS OR TAILS? HEADS
YOU WIN
RSET Statement
The RSET statement moves a string into a specified string variable without re-
assigning the string variable.
Syntax:
RSET 'string variable'='string expression'
Explanation:
RSET is commonly used to move data to file buffers by resetting them into
variables dropped into file buffers by a previous FIELD statement.
If the string being moved is shorter than the destination, RSET right-
justifies the string and pads the left with spaces. If the string is longer
than the destination, RSET ignores the extra characters.
You must RSET or LSET numbers before you can use them with MKD$, MKI$, or
MKS$.
Example:
Ok 10 A$ = STRING$(20,"X")
Ok 20 INPUT "REPLACE"; B$
Ok 30 PRINT A$
Ok 40 RSET A$ = B$
Ok 50 PRINT A$
Ok 60 GOTO 10
Ok RUN
REPLACE? 3434DfrE~%^
XXXXXXXXXXXXXXXXXXXX
343DfrE~%^
REPLACE? 7474747474747474747474747474747
XXXXXXXXXXXXXXXXXXXX
74747474747474747474
RUN Command
The RUN command executes a program.
Syntax:
RUN
RUN 'filename'
RUN 'filename, line number'
RUN ', line number'
Explanation:
Written alone, RUN executes the program in memory from the start. You have
several options that determine where the program begins running.
With the second syntax, RUN 'filename', RUN loads a disk file into memory and
runs it from the start. The filename is the name that you gave to the file
when you saved it. The default filetype BAS is assumed. RUN closes all open
files, and clears memory before bringing in the file on disk.
With the 3rd syntax, RUN 'filename, line number', RUN loads the file and runs
it from the line number specified.
The 4th syntax, RUN ', line number', runs the current program from the line
number specified.
Example:
Ok 10 FOR Y = 1 TO 5
Ok 20 X = X + 1
Ok 30 PRINT X
Ok 40 NEXT Y
Ok RUN
1
2
3
4
5
SAVE Command
The SAVE command saves a program on disk.
Syntax:
SAVE ['filename'][,'line number list']
Explanation:
To make a file permanent, you must SAVE it. The filename is the name that you
assign to the file. You do not need to supply a filetype; filetype BAS is
assumed. If the filename already belongs to another file, an error occurs.
SAVE does not replace an old file in memory with a new version. Commonly, you
use SAVE to save a file that you just created with NEW, and REPLACE to save a
file that you summoned with OLD.
Example:
Ok SAVE MERGEFILE
(ROCHE> I hope that I am not the only one to notice that "MERGEFILE" is a 9-
characters filename...)
SGN Function
The SGN function returns the sign of a number.
Syntax:
X = SGN('numeric expression')
Explanation:
SGN returns 1 if the numeric expression is positive, -1 if the expression is
negative, and 0 if the expression evaluates to zero.
Example:
Ok 10 INPUT "CARGO CAPACITY"; X
Ok 20 INPUT "TONNAGE"; Y
Ok 30 INPUT "VOLUME"; V
Ok 40 C = X + Y - V
Ok 50 IF SGN(C) > 0 THEN PRINT "SUFFICIENT SPACE": GOTO 100
Ok 60 PRINT "INSUFFICIENT SPACE. CAN LOAD BE DIVIDED?"
Ok RUN
CARGO CAPACITY? 23
TONNAGE? 14
VOLUME? 450.5
INSUFFICIENT SPACE. CAN LOAD BE DIVIDED?
SIN Function
The SIN function returns the sine of its argument expressed in radians.
Syntax:
X = SIN('numeric expression')
Explanation:
The SIN function assumes that the expression is an angle in radians. To
convert degrees to radians, multiply by PI/180, where PI = 3.141593. SIN
converts integers to real numbers, and returns a single-precision real number.
Example:
Ok 10 PRINT SIN(23)
Ok RUN
-.84622
SPACE$ Function
The SPACE$ function returns a string of spaces.
Syntax:
X$ = SPACE$('numeric expression')
Explanation:
SPACE$ returns as many spaces as you specify in the numeric expression. The
value of the expression must be in the range 0 to 255.
Example:
Ok 10 X = 10
Ok 20 FOR V = 1 TO 5
Ok 30 PRINT SPACE$(X); "|"
Ok 40 NEXT V
Ok 50 FOR Z = 1 TO 21
Ok 60 PRINT "-";
Ok 70 NEXT Z
Ok RUN
|
|
|
|
|
---------------------
Note: If you want to generate a number of spaces purely for printing, it is
more efficient to use the SPC(X) function.
SPC Function
The SPC function outputs spaces to a PRINT statement.
Syntax:
PRINT SPC('numeric expression')
Explanation:
SPC prints as many spaces as you specify in the numeric expression. The
expression must evaluate to the range -32768 to 32767. If the number of spaces
is greater than the width of the printer, the value used is the numeric
expression MOD width. For example, if the width is 72 and the numeric
expression equals 100, 28 spaces will be inserted. If the numeric expression
is > 255, the number of spaces is n MOD 255.
You use SPC only with the PRINT, LPRINT, and PRINT# statements.
Example:
Ok 10 PRINT "ALPHABET"
Ok 20 PRINT
Ok 30 PRINT "A"SPC(3)"a"SPC(7)"B"SPC(3)"b"SPC(7)"C"SPC(3)"c"
Ok RUN
ALPHABET
A a B b C c
SQR Function
The SQR function returns the square root of a number.
Syntax:
X = SQR('numeric expression')
Explanation:
The number must not be negative. SQR returns a real number.
Example:
Ok 10 PRINT SQR(9)
Ok RUN
3
STEP Command
The STEP command executes a program line by line.
Syntax:
STEP
STEP 'filename'
STEP 'filename, line number'
STEP ',line number'
Explanation:
Written alone, STEP runs the program in memory from the start, single-stepping
line by line. The second syntax, STEP 'filename', brings a file into memory
and begins stepping through it from the start.
Written with the 3rd syntax, STEP brings a program into memory and begins
stepping through it at the line number specified. With the 4th syntax, STEP
steps through the current program, beginning at the specified line number.
Before a line executes, Personal BASIC prints the line and waits for a
Carriage Return [CR]. A Carriage Return executes the line. To exit from STEP,
use the CONT command.
Example:
Ok 10 X = 9
Ok 20 PRINT X
Ok 30 PRINT "HOW DO YOU DO?"
Ok 40 END
Ok STEP, 10
s 10 X = 9
Br [CR]
s 20 PRINT X
9
Br [CR]
s 30 PRINT "HOW DO YOU DO?"
Br [CR]
HOW DO YOU DO?
s 40 END
Br CONT
STOP Statement
The STOP statement stops program execution.
Syntax:
STOP
Explanation:
After a STOP, the program is at break level. You can stop a program anywhere.
Unlike END, STOP leaves files open, enters Break mode and can be continued,
and prints the message "STOP". A CONT command, explained in this section,
resumes program execution.
Example:
Ok 10 A=4:B=6:C=8
Ok 20 PRINT A, A*B
Ok 30 STOP
Ok 40 PRINT C*A
Ok 50 END
Ok RUN
4 24
Stop at line 30
Br CONT
32
STR$ Function
The STR$ function returns a string containing the decimal character
representation of its argument.
Syntax:
X$ = STR$('numeric expression')
Explanation:
The string returned contains the standard representation of the expression. It
contains the characters that would print if a PRINT statement was executed.
For positive numbers, STR$ adds a leading blank for the plus sign [+], and
STR$ deletes any space that follows a number. See also the complementary VAL
function, and OCT$ and HEX$.
Example:
Ok 10 ZIPCODE = 91889
Ok 20 PRINT STR$(ZIPCODE) + " (CALIFORNIA)"
Ok RUN
91889 (CALIFORNIA)
STRING$ Function
The STRING$ function returns a string of a given length. The characters are
defined by the second argument.
Syntax:
X$ = STRING$('numeric expression','numeric or string expression')
Explanation:
The first numeric expression is the length of the string that STRING$ returns.
It must be in the range 0 to 255. You can use a numeric or string expression
for the second parameter. A numeric expression must be an ASCII code for a
character. A string expression can be of any kind. STRING$ returns a string of
a given length consisting of the character for the given ASCII code or the
first character of the string expression.
STRING$ produces less memory fragmentation and works significantly faster than
concatenation. When building a string containing a number of different
characters, it is more efficient to use STRING$ or SPACE$ to create a string
of the required length, and then use MID$ to move individual characters into
the string than to concatenate.
Example:
Ok 20 Z$ = STRING$(20,"*")
Ok 30 PRINT Z$
Ok RUN
********************
SWAP Statement
The SWAP statement trades the values of 2 variables.
Syntax:
SWAP 'first variable','second variable'
Explanation:
You can swap any type of variable but the variables must be of the same type.
You can swap array variables, but not arrays themselves.
SWAP A%(3), B%(7,5) Is okay
SWAP A%(), B%() Does not work
Example:
Ok 10 X$ = "TOM BRENTMEYER"
Ok 20 Y$ = "SUSAN STEIGER"
Ok 30 O$ = "FORMER"
Ok 40 C$ = "CURRENT"
Ok 50 M$ = " MARKETING MANAGER: "
Ok 60 PRINT O$,M$,X$
Ok 70 SWAP X$, Y$
Ok 80 SWAP O$, C$
Ok 90 PRINT O$,M$,X$
Ok RUN
FORMER MARKETING MANAGER: TOM BRENTMEYER
CURRENT MARKETING MANAGER: SUSAN STEIGER
SYSTEM Command
The SYSTEM command leaves Personal BASIC and returns to CP/M.
Syntax:
SYSTEM
Explanation:
Unless you save the file you are working with, it is lost when you exit the
Personal BASIC interpreter. SYSTEM closes all files and returns you to CP/M
command level.
Example:
Ok SYSTEM
A>
TAB Function
The TAB function moves the cursor to a given tab position.
Syntax:
PRINT TAB('tab position')
Explanation:
TAB is used with PRINT, LPRINT, and PRINT#.
The tab position must evaluate to the range -32768 to 32767. If the current
print position is already beyond the tab position that you specify, TAB goes
to the next line and stops at the tab position that you specify. The leftmost
position is space 1; the rightmost is defined by a WIDTH statement. If the
position evaluates greater than 255, the position is n MOD 256. If the
position is greater than or equal to the width, n is n MOD width.
Example:
Ok 10 PRINT "1985 QUARTERLY EARNINGS"
Ok 20 PRINT
Ok 30 PRINT TAB (10)"WINTER"
Ok 40 PRINT TAB (70)"Too FAR"
Ok 50 PRINT TAB (100)"SUMMER"
Ok 60 END
Ok RUN
1985 QUARTERLY EARNINGS
WINTER
Too FAR
SUMMER
(ROCHE> For the record, this book, the program, and its READ.ME file are all
dated 1983... As delivered, Personal BASIC had a width of 72 columns, the
width of the ASR-33 Teletype. (See Appendix E: The option table.) So, the
PRINT TAB (70)"Too FAR" statement causes it to wrap to the next line. It is
the same thing with the PRINT TAB(100)"SUMMER" statement: 100 is greater than
72, so "SUMMER" is printed at column 28 of the next line.)
TAN Function
The TAN function returns the tangent of a number.
Syntax:
X = TAN('angle in radians')
Explanation:
The TAN function operates on radian values, and returns a single-precision
real number. To convert degrees to radians, multiply them by PI/180, where PI
= 3.141593.
Example:
Ok 10 RADIAN! = 34
Ok 20 TANGENT! = TAN(RADIAN!)
Ok 30 PRINT TANGENT!
Ok RUN
-.62351
TRACE Command Function
The TRACE command follows program execution line by line, and selectively
prints the entire line.
Syntax:
TRACE ['line number list']
Explanation:
You can use the TRACE command in debugging to print program lines as they run.
TRACE without a line number prints each line before executing it. If you
include a list of line numbers, TRACE prints only those lines. Unlike TRON,
TRACE prints the entire line, including line number, statements, functions,
and variables. The UNTRACE command turns TRACE off. See the TRON and FOLLOW
commands as well.
Example:
Ok 10 FOR X = 1 TO 2
Ok 20 N = N + 1
Ok 30 B = B + 1
Ok 40 PRINT N
Ok 50 PRINT B
Ok 60 NEXT X
Ok RUN
1
1
2
2
Ok TRACE
Ok RUN
t 10 FOR X = 1 TO 2
t 20 N = N + 1
t 30 B = B + 1
t 40 PRINT N
1
t 50 PRINT B
1
t 60 NEXT X
t 10 FOR X = 1 TO 2
t 20 N = N + 1
t 30 B = B + 1
t 40 PRINT N
2
t 50 PRINT B
2
t 60 NEXT Y
Ok UNTRACE
TRON Command
The TRON command selectively traces program execution line by line, and prints
the line numbers and variable values.
Syntax:
TRON ['line number list']
Explanation:
Use TRON in debugging to follow the course of the program line by line. TRON
prints each line number of the program as it executes, and traces the values
of variables. The line numbers appear in square brackets, [ ], followed by the
current variable values.
After you give a TRON command, Personal BASIC is at command level, prepared
for a RUN command. TRON is turned off by TROFF. See the TRACE and FOLLOW
commands as well.
Example:
Ok 10 FOR X = 1 TO 3
Ok 20 N = N + 1
Ok 30 B = B + 1
Ok 40 PRINT N
Ok 50 PRINT B
Ok 60 NEXT X
Ok RUN
1
1
2
2
3
3
Ok TRACE
Ok RUN
[10][20][30][40] 1
[50] 1
[60][20][30][40] 2
[50] 2
[60][20][30][40] 3
[50] 3
[60]
Ok TROFF
TROFF Command
The TROFF command turns off the TRON command.
Syntax:
TROFF ['line number list']
Explanation:
You can cancel TRON by writing TROFF alone, or stop tracing certain line
numbers by giving them in the line number list.
UNBREAK Command
The UNBREAK command selectively cancels a BREAK command.
Syntax:
UNBREAK ['line number list']
Explanation:
With no line number list, UNBREAK cancels all BREAKs within the program. You
can UNBREAK particular breaks by giving their line numbers in the line number
list.
Example:
Ok UNBREAK
UNFOLLOW Command
The UNFOLLOW command turns off the FOLLOW command.
Syntax:
UNFOLLOW ['variable']{,'variable'}
Explanation:
Used alone, UNFOLLOW cancels the FOLLOW command entirely. If you want to stop
following only one variable, or several variables, you can specify which
variables you want to leave out. List them after the UNFOLLOW command,
separated by commas [,]. See the example at the FOLLOW command.
USR Function
The USR function calls a machine-language subroutine, passing arguments values
on the stack.
Syntax:
X = USR['digit'](arg1[,arg2, ..., arg15])
Explanation:
The optional digit is the number that you supplied in a corresponding DEF USR
statement for the subroutine. It can be from 0 to 9. If you omit the digit,
USR0 is assumed.
The type of the result variable and the first argument must be the same
(string or numeric). Up to 15 arguments can be specified. The USR function
returns a value that BASIC assumes is the same type as the first argument.
If you use USR with small numeric constants from 0 to 15, BASIC returns system
error 3. You can correct this by forcing the constants to type integer with
CINT. For example,
A% = USR(CINT(0))
For variables and constants greater than 15, USR performs as documented. You
can also solve this problem by assigning small numeric constants to variables
and using the variables with USR.
Example:
Ok 10 DEF USR2 = 2350
Ok 20 X = USR2(C)
Ok 30 Z = USR2(45(8+Z))
UNTRACE Command
The UNTRACE command turns off the TRACE command.
Syntax:
UNTRACE ['line number list']
Explanation:
You can UNTRACE all traced lines by leaving out the line number list, or
UNTRACE certain lines by including them in the list. After an UNTRACE,
Personal BASIC returns to command level. See the TRACE command in this
section.
VAL Function
The VAL function scans a string of characters, and converts them to a real
number, if possible.
Syntax:
X = VAL('digit string expression')
Explanation:
VAL scans the string from left to right, skipping leading tabs [HT], spaces
[ ], and Line-Feeds [LF], until it reaches the end of the string or finds a
character that is not a digit. VAL scans strings in the same way that the
INPUT# statement reads into a numeric variable.
If the first character of the string is not a valid part of a number, VAL
returns 0. The VAL function is the counterpart of the STR$ function, described
in this section.
Example:
Ok 10 INPUT "ENTER ID NUMBER, 0 TO STOP: ",ID$
Ok 15 IF ID$ = "0" THEN END
Ok 20 IF VAL(ID$) <= 300 THEN [LF]
EXPIRATION$ = "JAN 1, 1985"
Ok 30 IF VAL(ID$) > 300 THEN [LF]
EXPIRATION$ = "JAN 1, 1990"
Ok 40 PRINT EXPIRATION$ : GOTO 10
Ok RUN
ENTER ID NUMBER, 0 TO STOP: 3443475949876
JAN 1, 1990
(ROCHE> Again, this book, the program, and its READ.ME file are all dated
1983... They were clearly planning into the future!)
VARPTR Function
The VARPTR function returns the address of a variable.
Syntax:
X = VARPTR('variable')
X = VARPTR(#'file number')
Explanation:
You can use VARPTR to find the address of a variable, so that you can pass it
to an assembly language subroutine.
In the first form, the variable can be of any type, including array, but you
must have assigned it a value before you can find its address with VARPTR. The
VARPTR function returns the address of the first byte of data associated with
the variable. The address is an integer between -32768 and 32767, representing
the offset into Personal BASIC's Data Segment. It is not affected by a DEF SEG
segment. If you get a negative address, add 65536 to it to find the actual
address.
When using VARPTR to pass array addresses, you usually give the form of the
VARPTR function as VARPTR ('array'(0)), so that the lowest-addressed element
of the array returns. Assign values to all simple variables before you pass
arrays, because the addresses of arrays change whenever you assign to a simple
variable.
In the second form, the file number is the number that you assigned to a disk
file when you opened it. VARPTR returns the starting address of the file's
input/output buffer.
Example:
Ok 50 X = VARPTR(MATERIALS)
WAIT Statement
The WAIT statement halts the program while waiting for an I/O port to develop
a bit pattern.
Syntax:
WAIT 'port number','integer expression'[,'integer expression']
Explanation:
WAIT stops program execution until a given bit pattern develops in a machine
input port. The logical operator XOR tests the data from the port to determine
whether it corresponds to the optional second integer expression. If you omit
the optional expression, it is assumed zero.
The AND operator then tests the data against the first integer expression. If
the result of the test is zero, execution loops back and grabs the next data
at the port. When the result is non-zero, execution goes on to the next
statement.
If WAIT does not find a bit pattern that results in zero, it loops
infinitely. You must reboot the machine.
Example:
Ok 100 WAIT 5, &H2, &H3
Ok 110 PRINT "NUMBER FOUND"
WEND Statement
The WEND statement signals the end of a WHILE-WEND loop.
Syntax:
WEND
Explanation:
WEND is used solely with WHILE, to direct program flow up to the WHILE
statement. Nested WENDs associate with the nearest WHILE. See the WHILE
statement in this section.
Example:
Ok 10 X=7
Ok 20 WHILE X
Ok 30 PRINT "$";
Ok 40 X=X-1
Ok 50 WEND
Ok 60 END
Ok RUN
$$$$$$
WHILE Statement
The WHILE statement states a condition that controls a WHILE-WEND loop.
Syntax:
WHILE 'logical expression'
Explanation:
WHILE initiates a WHILE-WEND loop of statements that continues running until
the logical expression is false (0). The statements between WHILE and WEND
execute while the conditional expression in the WHILE statement is true (-1).
The WEND statement at the end of the loop sends program flow back to the WHILE
condition. The condition at the WHILE loop is evaluated and the loop repeats
while the condition is true (non-zero). When the condition is false (zero),
execution continues at the statement following the end of the loop.
You can nest WHILE-WEND loops to any level. Each WEND matches the most recent
WHILE. A WHILE without a WEND or a WEND without a WHILE causes an error.
See the WEND statement in this section. Loops can also be written with FOR-
NEXT statements. In the example, the words COUNT LOOP are printed 5 times.
Example:
Ok 10 M=10
Ok 20 P=5
Ok 30 WHILE M > P
Ok 40 PRINT "COUNT LOOP"
Ok 50 M=M-1
Ok 60 WEND
Ok END
WIDTH Statement
The WIDTH statement sets the line width of a terminal or printer.
Syntax:
WIDTH [LPRINT] 'integer expression'
Explanation:
The default width on a terminal or printer is 72 characters. You can change it
with WIDTH.
The integer expression is the line width in number of characters; it must be
in the range 14 to 255. The LPRINT option sets the line width at the line
printer. Otherwise, the line width is set at the terminal.
When printing, Personal BASIC prints a Carriage Return [CR] before a character
that would, otherwise, run over the line width. To prevent unwanted Carriage
Returns in your output, set the line width to 255. Personal BASIC assumes then
that the device has infinite width, and does not insert Carriage Returns. The
position of the cursor or print head returned by LPOS or POS returns to zero
after reaching 255.
Example:
Ok 10 WIDTH 33
Ok 20 FOR I = 1 TO 50
Ok 30 PRINT "-";
Ok 40 NEXT
Ok RUN
---------------------------------
-----------------
WRITE Statement
The WRITE statement outputs data to the terminal.
Syntax:
WRITE ['expression']{,'expression'}
Explanation:
Like PRINT, WRITE sends output to the screen, but WRITE prints commas [,]
between the items, and quotation marks ["] around the strings. WRITE# is
preferable to PRINT# when you plan to read the data back with a series of
INPUT# statements. The output from WRITE# is in exactly the form required to
read back the data accurately.
The rules for forming the expression are the same as those for PRINT#. Each
item is separated from the next on the terminal with a comma [,]. String
values print with quotation marks ["] and, after the last item, the cursor
spaces down to the start of the next line.
WRITE sends a blank line to the terminal if you do not specify a list of
expressions to output. See the PRINT statement in this section for the
formatting of WRITE statements.
Example:
Ok 100 X$ = "HAPPY MOTORING"
Ok 110 Z = 010583
Ok 120 WRITE Z
Ok 130 WRITE
Ok 140 WRITE X$
Ok RUN
10583
"HAPPY MOTORING"
(ROCHE> Notice the "010583" date, that is to say: 5 January 1983...)
WRITE# Statement
The WRITE# statement writes data to a file.
Syntax:
WRITE# 'file number','expression'{,'expression'}
Explanation:
WRITE# works like WRITE but sends the data to a sequential file, not the
terminal. The file number is the number that you opened the file with. You
must have opened the file in O or R mode.
The expressions are string or numeric. They are written to the disk with
commas [,] between them, and quotation marks ["] around the strings. In this,
WRITE# differs from PRINT#. Personal BASIC inserts a Carriage Return / Line-
Feed [CR-LF] after the last item on the list.
Example:
Ok 10 KWH = 34.275
Ok 20 K$ = "AVERAGE KILOWATT HOURS PER WEEK"
Ok 30 WRITE#2,K$,KWH
This writes to disk as:
"AVERAGE KILOWATT HOURS PER WEEK",34.275
Close the file, re-open for input, then read the file:
Ok 40 INPUT#2,K$,KWH
This assigns:
"AVERAGE KILOWATT PER WEEK" to K$, and 34.275 to B$.
Appendix A: Personal BASIC keywords
-----------------------------------
Certain words, known as keywords, have fixed meanings in Personal BASIC. You
cannot use them as variable or function names, or assign them meanings of your
own.
ABS
ALL
AND
AS
ASC
ATN
AUTO
BASE
BLOAD
BREAK
BSAVE
CALL
CDBL
CHAIN
CHR$
CINT
CLEAR
CLOSE
COMMON
CONT
COS
CSNG
CVD
CVI
CVS
DATA
DEF
DEFDBL
DEFINT
DEFSNG
DEFSTR
DELETE
DIM
DIR
DO
EDIT
ELSE
END
EOF
EQV
ERA
ERASE
ERL
ERR
ERROR
EXP
FIELD
FIX
FLOAT
FOLLOW
FOR
FRE
GET
GO
GOSUB
GOTO
HEX$
IF
INKEY$
IMP
INP
INPUT
INPUT#
INPUT$
INSTR
INT
KILL
LEFT$
LEN
LET
LINE
LIST
LLIST
LOC
LOF
LOG
LOG10
LPOS
LPRINT
LSET
MERGE
MID$
MKD$
MKI$
MKS$
MOD
NAME
NEW
NEXT
NOT
OCT$
OLD
ON
OPEN
OPTION
OR
OUT
PEEK
POKE
POS
PRINT
PRINT#
PUT
RANDOMIZE
READ
REM
RENUM
REPLACE
RESET
RESTORE
RESUME
RETURN
RIGHT$
RND
RSET
RUN
SAVE
SEG
SGN
SIN
SPACE$
SPC
SQR
STEP
STOP
STRING$
STR$
SWAP
SYSTEM
TAB
TAN
THEN
TO
TRACE
TRON
TROFF
UNBREAK
UNFOLLOW
UNTRACE
USING
USR
VAL
VARPTR
WAIT
WEND
WHILE
WIDTH
WRITE
WRITE#
XOR
Appendix B: Decimal-ASCII-Hex table
-----------------------------------
ASCII stands for American Standard Code for Information Interchange. The code
contains 96 printing and 32 non-printing characters used to store data on a
disk. Table B-1 defines ASCII symbols, then Table B-2 lists the ASCII and
hexadecimal conversions. The table includes binary, decimal, hexadecimal, and
ASCII conversions.
Table B-1. ASCII Symbols
Symbol Meaning Symbol Meaning
------ ------- ------ -------
ACK acknowledge FS file separator
BEL bell GS group separator
BS backspace HT horizontal tabulation
CAN cancel LF line feed
CR carriage return NAK negative acknowledge
DC device control NUL null
DEL delete RS record separator
DLE data link escape SI shift in
EM end of medium SO shift out
ENQ enquiry SOH start of heading
EOT end of transmission SP space
ESC escape STX start of text
ETB end of transmission SUB substitute
ETX end of text SYN synchronous idle
FF form-feed US unit separator
VT vertical tabulation
Table B-2. ASCII Conversion Table
Binary Decimal Hexa ASCII
-------- ------- ---- -----
00000000 0 0 NUL (CTRL-@)
00000001 1 1 SOH (CTRL-A)
00000010 2 2 STX (CTRL-B)
00000011 3 3 ETX (CTRL-C)
00000100 4 4 EOT (CTRL-D)
00000101 5 5 ENQ (CTRL-E)
00000110 6 6 ACK (CTRL-F)
00000111 7 7 BEL (CTRL-G)
00001000 8 8 BS (CTRL-H)
00001001 9 9 HT (CTRL-I)
00001010 10 A LF (CTRL-J)
00001011 11 B VT (CTRL-K)
00001100 12 C FF (CTRL-L)
00001101 13 D CR (CTRL-M)
00001110 14 E SO (CTRL-N)
00001111 15 F SI (CTRL-O)
00010000 16 10 DLE (CTRL-P)
00010001 17 11 DC1 (CTRL-Q)
00010010 18 12 DC2 (CTRL-R)
00010011 19 13 DC3 (CTRL-S)
00010100 20 14 DC4 (CTRL-T)
00010101 21 15 NAK (CTRL-U)
00010110 22 16 SYN (CTRL-V)
00010111 23 17 ETB (CTRL-W)
00011000 24 18 CAN (CTRL-X)
00011001 25 19 EM (CTRL-Y)
00011010 26 1A SUB (CTRL-Z)
00011011 27 1B ESC (CTRL-[)
00011100 28 1C FS (CTRL-\)
00011101 29 1D GS (CTRL-])
00011110 30 1E RS (CTRL-^)
00011111 31 1F US (CTRL-_)
00100000 32 20 (SPACE)
00100001 33 21 !
00100010 34 22 "
00100011 35 23 #
00100100 36 24 $
00100101 37 25 %
00100110 38 26 &
00100111 39 27 '
00101000 40 28 (
00101001 41 29 )
00101010 42 2A *
00101011 43 2B +
00101100 44 2C ,
00101101 45 2D -
00101110 46 2E .
00101111 47 2F /
00110000 48 30 0
00110001 49 31 1
00110010 50 32 2
00110011 51 33 3
00110100 52 34 4
00110101 53 35 5
00110110 54 36 6
00110111 55 37 7
00111000 56 38 8
00111001 57 39 9
00111010 58 3A :
00111011 59 3B ;
00111100 60 3C <
00111101 61 3D =
00111110 62 3E >
00111111 63 3F ?
01000000 64 40 @
01000001 65 41 A
01000010 66 42 B
01000011 67 43 C
01000100 68 44 D
01000101 69 45 E
01000110 70 46 F
01000111 71 47 G
01001000 72 48 H
01001001 73 49 I
01001010 74 4A J
01001011 75 4B K
01001100 76 4C L
01001101 77 4D M
01001110 78 4E N
01001111 79 4F O
01010000 80 50 P
01010001 81 51 Q
01010010 82 52 R
01010011 83 53 S
01010100 84 54 T
01010101 85 55 U
01010110 86 56 V
01010111 87 57 W
01011000 88 58 X
01011001 89 59 Y
01011010 90 5A Z
01011011 91 5B [
01011100 92 5C \
01011101 93 5D ]
01011110 94 5E ^
01011111 95 5F _
01100000 96 60 '
01100001 97 61 a
01100010 98 62 b
01100011 99 63 c
01100100 100 64 d
01100101 101 65 e
01100110 102 66 f
01100111 103 67 g
01101000 104 68 h
01101001 105 69 i
01101010 106 6A j
01101011 107 6B k
01101100 108 6C l
01101101 109 6D m
01101110 110 6E n
01101111 111 6F o
01110000 112 70 p
01110001 113 71 q
01110010 114 72 r
01110011 115 73 s
01110100 116 74 t
01110101 117 75 u
01110110 118 76 v
01110111 119 77 w
01111000 120 78 x
01111001 121 79 y
01111010 122 7A z
01111011 123 7B {
01111100 124 7C |
01111101 125 7D }
01111110 126 7E ~
01111111 127 7F DEL
Appendix C: Creating a Personal BASIC system disk under CP/M-86
---------------------------------------------------------------
The most important step that you take before using Personal BASIC is to make a
copy of your Personal BASIC product disk. (ROCHE> This used to be called
a "Distribution Diskette"...) A mistyped command or an electrical failure can
accidentally erase these important programs permanently.
Copying an operating system onto a disk is called generating a system. The
COPYDISK program on your CP/M-86 disk generates an operating system on the
disk drive that you specify. Once you have generated a new CP/M-86 disk, you
can use the PIP program to copy Personal BASIC to the new system disk. The
instructions in this Appendix assume that you have CP/M-86 and 2 floppy disk
drives.
You should now create a system disk containing Personal BASIC. Consult the
operating manual with your operating system for instructions on how to create
a system disk.
When you have a new CP/M-86 disk with utilities, remove the original CP/M-86
disk from drive A and store it in a safe place. Remove the new CP/M-86 disk
from drive B and put it in drive A. Press the RESET button on your computer to
reboot the system on the new disk. (ROCHE> Intel microcomputers had a RESET
button...) Then, put your Personal BASIC product disk in drive B. PIP Personal
BASIC over to the new system disk in drive A. Type the following command:
A>PIP A:=B:PBASIC.CMD
Remove your Personal BASIC product disk from drive B and store it in a safe
place. Your new Personal BASIC system disk in drive A is now ready. Type the
following command to start Personal BASIC:
A>PBASIC
Personal BASIC responds with the prompt Ok.
--------------------------------------------------
Personal Basic Version 1.1
Serial No. xxxx-0000-654321 All Rights Reserved
Copyright (c) 1983 Digital Research, Inc.
--------------------------------------------------
Ok
To exit Personal BASIC and return control to CP/M-86, type the following
command:
Ok SYSTEM
Make copies of all your programs. Remember to store your original product
disks in a safe place.
Appendix D: Personal BASIC error messages
-----------------------------------------
The following table shows error numbers and their meanings.
Table D-1. Personal BASIC error messages
Number Message
------ -------
1 Undefined error
2 Something is wrong
3 RETURN statement needs matching GOSUB
4 READ statement ran out of data
5 Function call not allowed
6 Number too large
7 Program is too large for memory
8 A statement or command refers to a nonexistent line
9 Subscript refers to element outside the array
10 You defined an array more than once
11 You cannot divide by zero
12 Statement is illegal in direct mode
13 Types of values do not match
14 Undefined error
15 Strings cannot be over 255 characters long
16 Expression is too long or too complex
17 CONT works only in BREAK mode
18 Function needs prior definition with DEF FN
19 Undefined error
20 RESUME statement found before error routine entered
21 Undefined error
22 Expression has operator with no following operand
23 Program line too long
24-49 Undefined error
50 FIELD statement caused overflow
51 Undefined error
52 File number or filename invalid
53 File not found on disk drive specified
54 File mode is not valid
55 You cannot OPEN or KILL a file already open
56 Undefined error
57 Disk input/output error, restart your operation (MP/M)
58 File exists
59 Undefined error
60 Undefined error
61 Disk is full
62 You have reached end-of-file
63 The record number in PUT or GET is more than 32767 or zero
64 Invalid filename
65 Invalid character :123: in program file
66 Program file has statement with no line number
67-98 Undefined error
99 -- Break --
100 Undefined error
101 Program exceeds memory size
102 ON statement is out of range
103 Invalid line number
104 A variable is required
105 Undefined error
106 Line number does not exist
107 Number too large for an integer
108 Input data is not valid, restart input from first item
109 Stop
110 You have nested subroutine calls too deep
111 Invalid BLOAD file
112-201 Undefined error
202 Command not allowed here
203 Line number is required
204 FOR statement needs a NEXT or WHILE needs a WEND
205 NEXT statement needs a FOR or WEND needs a WHILE
206 A comma is expected
207 A parenthesis is expected
208 Option Base must be 0 or 1
209 Statement end is expected
210 Too many arguments in your list
211 Undefined error
212 Cannot re-define variable(s)
213 Function defined more than once
214 You are trying to jump into a loop
215-220 Undefined error
221 System error #216, please restart
222 Program not run
223 To many FOR loops
224-255 Undefined error
Appendix E: The Option Table
----------------------------
Personal BASIC has a table of option bytes at a fixed memory address. The
options determine how Personal BASIC treats certain features of the language.
You can examine the options' settings with PEEK, or change them with POKE.
Once you set an option, it remains set until you change it or exit Personal
BASIC.
The base of the option table is 102H, within the default Data Segment. The
default Data Segment is the location that you get if you execute a DEF SEG
without specifying an address. From version to version, the location of the
option table base might change.
(ROCHE> Well, as far as I know, there was only one version of Personal BASIC,
Version 1.1, so we have no problem of versions...)
Be careful when POKing or PEEKing around the Data Segment. You could
accidentally change data essential to the operation of Personal BASIC. You
might get unexpected results.
The following diagram summarizes the options and their offsets.
BASE + OFFSET
┌─────────────┐
│ DP │ &H102 + 0
├─────────────┤
│ Ctrl-C │ &H102 + 1
├─────────────┤
│ ON │ &H102 + 2
├─────────────┤
│ *UNUSED* │ &H102 + 3 to 13
├─────────────┤
│ CONSOLE │ &H102 + 14
├─────────────┤
│ PRINTER │ &H102 + 15
└─────────────┘
Figure E-1. Option table
The options, with their offsets within the table, are as follows:
Offset: 0
Regards: Microsoft BASIC double-precision format
Initial value: 0
If the value equals zero, double-precision numbers mapped to strings through
the MKD$ function are mapped in IEEE format, which is the format in which they
are held internally.
If the value does not equal zero, double-precision numbers are converted to
Microsoft BASIC format by the MKD$ function, and back to IEEE format by the
CVD function. By setting the switch, Personal BASIC can read files created
with Microsoft BASIC.
Note that double-precision overflow might occur when converting from IEEE to
Microsoft BASIC format.
Offset: 1
Regards: Control-C trap
Initial value: 0
If the value equals zero, a Ctrl-C entered at the terminal halts the program
and puts it into Break Mode. Ctrl-C never produces a break during the
execution of an INPUT$ statement.
If the value does not equal zero, and if an error trap has been set (that is
to say: an ON ERROR GOTO statement has been executed), then a Ctrl-C entered
at the terminal generates a trappable error with code 99. Further, the program
does not acknowledge a Ctrl-C during an error-trap routine. By setting this
switch, a program can make itself unbreakable.
(ROCHE> This is the OPTION STOP / OPTION RUN switch of Mallard BASIC...)
Note: If you set the switch and your program has an error that causes an
infinite loop, there is no way to stop it, unless you reboot the machine.
Offset: 2
Regards: ON 'expression' GOTO 'line number list'
Initial value: 0
This switch affects the way Personal BASIC handles an ON-GOTO statement if the
expression evaluates outside the range implied by the number of labels in the
line number list.
If the value equals zero, Personal BASIC drops through to the next statement.
If the value does not equal zero, Personal BASIC generates a trappable run-
time error.
*** Offsets 3 through 13 are unused. ***
Offset: 14
Regards: Default console width
Initial value: 72 (decimal)
The console width is set to this value every time a RUN, CHAIN, NEW, or OLD
command executes.
Offset: 15
Regards: Default printer width
Initial value: 72 (decimal)
The printer width is set to this value in the same way as the console width.
Appendix F: Machine-language linking conventions
------------------------------------------------
The linkage used for CALL statements and USR functions is identical. Before
the new routine is called, the expressions in the argument list are evaluated
and placed on the Personal BASIC (soft) stack, in the order in which they
appear in the argument list. All parameters are passed by value; if you want
to access a variable, the appropriate parameter is VARPTR('variable'), not the
variable name itself.
The address of the base of the argument list is placed in register BX and
Personal BASIC executes a Far Call (CALLF) to the offset specified by the CALL
variable or USR definition, in the segment defined by the most recent DEF SEG
statement.
Any expressions are allowed in the argument list, but it is the user's
responsibility to ensure that the argument types correspond to the types the
machine-language function is expecting. In particular, note that an expression
involving only integers might result in a floating-point result. For example,
A% * B%
gives a floating-point result.
If you want to pass the result of an expression as an integer, it is safest to
use CINT to force the result to an integer. For example,
CINT(A% * B%)
will generate an integer or an error.
The user routine must preserve the data segment register (DS) over the call,
and would normally return control via a Far Return (RETF), which restores
Personal BASIC's Code Segment register.
On return from a call to a user routine called in the context of a USRn
function, the resulting value is taken from the first argument area of the
soft stack; that is, the user function is assumed to have replaced the first
argument (pointed directly to by BX) with the function result.
Argument Types:
o Integers are stored in 2 bytes.
o Single-precision floating-point numbers are stored in 4 bytes.
o Double-precision floating-point numbers are stored in 8 bytes.
o String descriptors are stored in 6 bytes.
All numbers are stored in the following order: least significant byte first,
most significant byte last.
Integer Format
a a + 1
----------------------------------
: : :
: LSB : MSB :
----------------------------------
Single-Precision Format
a a + 1 a + 2 a + 3
-----------------------------------------------
: : : : : :
: LSB : : MSB : : :
: : : : : :
-----------------------------------------------
\ / | \ /
\\\\\\\\\\\\\\ ////////////// | \\\\ ////
\/ V \/
mantissa sign exponent
Double-Precision Format
a a+1 a+2 a+3 a+4 a+5 a+6 a+7
---------------------------------------------------
: : : : : : : : : :
:LSB : : : : : :MSB : : :
: : : : : : : : : :
---------------------------------------------------
\ /\ /|
\\\\\\\\\\\\\\\\ //////////////////// \\\\ // V
\/ \/ sign
mantissa, exponent,
53 bits 11 bits
String Format
-----------------------------------------------------
: : : : : : : :
: 4 : 12 : : : : : :
: : : : : : : :
-----------------------------------------------------
: \ /\ /\ /
: \\\\\\\ ////// \\\\\\ ////// \\\\\\ /////
V \/ \/ \/
type, length, address1 address2
4 bits 12 bits
Type is a 4-bit code, as follows:
0 = short string
Up to 4 bytes in length, the characters are in the address1 and
address2 fields.
1 = variable
Address1 and address2 combined give the address of the first byte in
the string. Address1 must be shifted left one before being added to
address2.
2 = field
Address1 is composed of a 4-bit file number and 12-bit offset into the
file user's buffer. Address2 is used for other purposes.
3 = constant
Address1 and address2 are combined as for type 1. The result address
may point at program text, so do not change the string to which this
points.
4 is not used
5 and 6 as for type 1.
Index
-----
To be done by WS4...
EOF