This manual describes the 10K Microsoft BASIC available for the Microtan system and describes the enhancements to this package by TANGERINE. Microsoft BASIC is recognised as being "standard" BASIC and as such it is possible to run the many published programs for computers supporting BASIC. Microsoft BASIC for the Microtan consists of three Read Only Memories (ROM) which must be inserted into the TANEX board. Cassette SAVE and LOAD commands are available and use filenames and may be operated at two speeds, 300 Baud and 2400 Baud. Please note that XBUG must be used if you wish to use the SAVE and LOAD commands.
CHAPTER 1: Microtan's 10K Extended MICROSOFT BASIC
BASIC responds with:
Type either <CR> in which case BASIC calculates available memory space automatically or
where Decimal Number is a number representing the amount of store which you require BASIC to use. Store is then allocated from location 400 HEX upwards to the limit specified. The remaining store may be used to contain, for example, user subroutines.
Beware of typing in a number larger than the area you have available - Microsoft Basic uses the top part for variables and print statements, which will be assigned the wrong value.
BASIC next prompts:
For the MICROTAN VDU, responds with <CR> since the program looks after VDU scrolling.
BASIC responds with:
You can now use BASIC.
Exiting from BASIC
is issued, followed by the cursor prompt.
Note that when you exit from BASIC, all your program information is destroyed
(note 2). You should therefore SAVE any programs required
The minimum system requirement to run BASIC is as follows: MICROTAN 65 and TANEX connected via mini-motherboard or system motherboard, ASCII keyboard, 2K RAM (1K on MICROTAN, 1K on TANEX).
If you wish to use the cassette SAVE and LOAD functions, XBUG must be present in socket G2 on TANEX.
PROGRAM STORAGE USING CASSETTES
Note that in order to use this facility, the XBUG PROM must be resident in slot G2 of TANEX. If it is not, reference to these two commands will cause BASIC to crash with resultant loss of your current program. Cassette record and replay levels must have been set up in accordance with the instructions given in the XBUG manual.
These routines dump the BASIC code in its machine format, that is it is not in text form but in the packed-up form in which it is stored. Thus a considerable time saving is achieved during SAVE and LOAD functions. It is not possible to dump selected parts of programs, nor is it possible to load in additional lines to an existing program since memory is always cleared before a load occurs. To save the program which is in memory type:
BASIC responds with:
If you require the dump to be at fast speed, type:
otherwise just type <CR> to obtain slow speed.
BASIC responds with:
Type in the required filename - this can be up to 6 alphanumeric characters - start the cassette recorder in record mode, and type carriage return, for example:
BASIC appends a .B to this name and responds with:
The file is now dumped on to cassette, BASIC responding with:
when the dump is complete.
You may return to BASIC from the SAVE function at any time up to typing the final carriage return after the filename by typing CTRL C.The SAVE is then no executed. However, once you have started the SAVE, you cannot return to BASIC until the SAVE is complete.
To recover a program dumped to cassette, type:
BASIC responds with:
if the required file was recorded at fast speed, carriage return otherwise. BASIC responds with:
if you wish to compare what is on tape with what is in memory, carriage return only if you wish the tape to actually read into memory (see section on errors for result of an EXAM call). BASIC responds with:
Type in the filename that was given to the file when it was saved, omitting the .B, followed by carriage return. For example:
BASIC responds with the filename it is looking for:
Start the cassette recorder in playback mode. Now, as each file on tape is encountered, BASIC prints this out. When the correct file is found, BASIC loads or verifies it.When the load or verification is complete, the prompt
appears on the screen.
If any of the M, F, P, or C errors appear before this prompt, then read or verification errors were present - try reading the tape again. If errors persist, the recording is probably corrupt.
Errors may take the following forms:
Note that within the context of BASIC the hexadecimal status numbers are meaningless.
At any time until you actually start the tape search, you can return to BASIC
by typing CTRL C. Once the tape search has been started, the only way to stop
it, should it not find the correct file, is to type BREAK on the keyboard and
then restart BASIC.
EDITING BASIC PROGRAMS
MICROTAN BASIC allows you to edit programs either in the line mode or the character (screen edit) mode.
Line edit mode is usually used to enter new lines, or programs, delete complete existing lines, or modify existing lines where a large number of changes are required.
To enter a line in line edit mode, type in a line number, followed by the program statement, for example:
BASIC responds with a cursor character if line syntax is correct, and the line is entered into program memory. If syntax is incorrect, the message
is generated, and the line does not enter program memory.
MICROTAN BASIC allows a maximum program line length of 80 characters (VDU line length is immaterial because scrolling is done automatically). If more than this number is typed, the BELL character, or a question mark, will be displayed on the screen and the character ignored. All characters with ASCII codes of less then HEX 20 or greater than HEX 7E are also ignored. When entering a line, the DELETE key deletes the character previous to the cursor. The @ deletes the whole of the line currently being entered.
To delete a line within the stored program, type the line number followed by carriage return, for example:
deletes line 10 from program storage.
To edit a line in line edit mode, type in the whole new line. For example, say you wish to change 10 PRINT A to 10 INPUT A type:
The old line 10 is overwritten by the new line 10.
The LIST command is used to list parts of or a whole BASIC program. To list the whole program, type:
The first 5 lines of the program are displayed on the VDU. To obtain the next 5, type carriage return and so on until the end of the program. Should you wish to inhibit the paging pauses, type line feed - the program now lists to the end without pausing. Typing CTRL C at any time stops the listing and returns you to the BASIC prorgam. To list a single line, type LIST followed by the line number
To type a selected group of lines, type
and use the paging delimiters CR, LF and CTRL C as required.
If there is only one error in a long line of BASIC code, it is tedious to type in the whole line to correct it - MICROTAN BASIC includes a screen (cursor) editor to resolve this problem.
To enter screen edit mode, type in the required line number followed by CTRL E (hold down the CTRL key and depress key E). For example:
If your program does not contain a line 90, the message
is printed. Otherwise line 90 is displayed at the screen center between two sets of dashed lines. Above and below these lines appear the lines of code immediately above and below that being edited. A flashing cursor appears between the two dotted lines. The bottom line of the VDU displays the number of the line which you are going to change.
You may now move the cursor around within the two dotted lines and edit the text within them by using any of the following commands:
CTRL U Moves the cursor up.
CTRL D Moves the cursor down.
CTRL L Moves the cursor left.
CTRL R Moves the cursor right.
CTRL E Erases the character over which the cursor is flashing. The rest of the line is shifted back one space to fill the gap left by this character.
CTRL C Returns to BASIC without updating the main program, i.e. the edited line is ignored. Use this for gross error correction.
CHAPTER 2 : Introduction To The BASIC Language
This chapter will serve as an introduction for those of you unfamiliar with BASIC. To help get you started writing programs, the text introduces the primary concepts and uses of MICROTAN BASIC.
If your MICROTAN 65 does not have MICROTAN BASIC loaded and running, follow the procedure in Chapter 1 to bring it up. We recommend that you try each example in the chapter as it is presented. This will enhance your "feel" for BASIC and how it is used. If you are already accustomed to programming in BASIC, turn to Chapter 3 for more information about BASIC's characteristics.
When MICROTAN displays "OK", you are ready to use MICROTAN BASIC.
NOTE: All commands to BASIC end with a carriage return. The carriage return tells BASIC that you have finished typing the command. If you make a typing error, type a back-arrow or RUBOUT to eliminate the last character. An at-sign (@) eliminates the entire line that you are typing.
Now, try typing in the following:
BASIC will immediately print:
The PRINT statement you typed in was executed as soon as you hit the carriage return key. BASIC evaluated the formula after the PRINT and then typed out its value, in this case 6. Now try typing in this:
BASIC will print:
As you can see, BASIC can do division and multiplication as well as subtraction. Note how a comma was used in the PRINT command to print two values instead of just one. The comma divides the 72 character line into 5 fields, each 14 characters wide. The last two of the positions on the line are not used. The comma causes BASIC to slip to the next field on the line, where the value 30 was printed.
PROGRAMS AND LINE NUMBERS
Commands such as the PRINT statement you have just typed in are called direct commands. There is another type of command called an indirect command. Every indirect command begins with a line number. A line number may be any integer from 0 to 64000. Try typing in the following lines:
Notice that BASIC did not print either of the values. That is because BASIC recognizes by the line numbers that these lines are to be saved and executed as a sequence later. A sequence of indirect commands is called a program. BASIC saves indirect commands in memory. When you type RUN, BASIC executes the program, beginning with the lowest numbered line. If we type RUN now, BASIC will type out:
In the above example, we entered lines 10 and 20 in numerical order. However, it makes no difference in what order you enter indirect statements. BASIC always puts them into correct numerical order according to line number. To see a listing of the complete program currently in memory, type LIST. BASIC will reply with:
Sometimes it is desirable to delete a line of a program altogether. This is accomplished by typing the line number of the line to be deleted, followed only by a carriage return. Type in the following:
BASIC will reply with:
We have now deleted line 10 from the program. There is no way to get it back except to re-type it. To insert a new line 10, just type in 10 followed by the new line. Type in the following:
BASIC will reply with:
There is an easier way to replace line 10 than by deleting it and then inserting a new line. You can do this by just typing the new line 10 and hitting the carriage return. BASIC throws away the old line 10 and replaces it with the new one. Type in the following:
BASIC will reply with:
It is not recommended that lines be numbered in small increments. It may become necessary to insert a new line between two existing lines. An increment of 10 between line numbers is usually sufficient.
If you want to erase the complete program currently stored in memory, type in NEW. If you are finished running one program and are about to type in a new one, be sure to type NEW first. This should be done in order to prevent a mixture of the old and new programs. Type in the following:
BASIC will reply with:
Now type in:
BASIC will reply with:
NUMBERS, OPERATORS, AND STRINGS
Often it is desirable to include text along with answers that are printed out in order to explain the meaning of the numbers. Type in the following:
BASIC will reply with:
As explained earlier, including a comma in a PRINT statement causes it to space over to the next fourteen-column field before the value is printed. Using a semi-colon instead of a comma causes the value to be printed immediately, without spacing to the next field.
NOTE: Numbers are always printed with at least one trailing space. Any text
to be printed must always be enclosed in double quotes. Try the following
b) PRINT 1,2,3
c) PRINT 1;2;3
d) PRINT -1;2;-3
We will digress for a moment to explain the format of numbers in BASIC. Floating point numbers are stored internally to over nine digits accuracy. When a number is printed, only nine digits are shown. Any number may also have an exponent.
The largest number that may represented in MICROTAN BASIC is 1.70141*10E38,
while the smallest positive number is 2.93874*10E-39.
Scientific notation is formatted as follows:
Each X is an integer, 0 to 9. The leading S is the sign of the numbers: a space for a positive number and a minus sign for a negative number. One non-zero digit is printed before the decimal point. This is followed by the decimal point and then the other five digits of the mantissa. An E is then printed (for exponent), followed by the sign (S) of the exponent; then the two digits (TT) of the exponent itself. Leading zeros are never printed; i.e. the digit before the decimal is never zero. Also, trailing zeros are never printed. If there is only one digit to print after all trailing zeros are suppressed, no decimal point is printed. The exponent sign will be "+" for positive and "-" for negative. Two digits of the exponent are always printed; that is, zeros are not suppressed in the exponent field. The value of any number expressed thus is the number to the left of the E times 10 raised to the power of the number to the right of the E.
No matter what format is used, a space is always printed following a number. BASIC checks to see if the entire number will fit on the current line. If not, a carriage return/linefeed is executed before printing the number.
The following are examples of various numbers and the output format BASIC will use:
A number input from the terminal or a numberic constant used in a BASIC program may have as many digits as desired, up to a maximum length of a line (72 characters). However, only 9 digits are significant, with this version of BASIC. The final digit is rounded up.
So far we have used several different operators in order to inform BASIC of the calculations we wish to perform. Whenever a combination of these operators is used, it is necessary to know which operations are to be performed first. As in standard algebra, we can either specify which operations have the highest priority, or we can rely on BASIC's precedence of operators. That precedence is as follows:
Priority Of Operations
1) Parentheses - any expression enclosed in parentheses is always evaluated
7) Logical Operators in the order NOT, AND, then OR.
BASIC's relational and logical operators are described in detail in Chapter 3.
INPUT AND GOTO STATEMENTS
The following is an example of a program that reads a value from the terminal and uses that value to calculate and print a result:
Here is what is happening. When BASIC encounters the INPUT statement, it types a question mark on the terminal and then waits for a response. When you type in 10, execution continues with the next statement in the program, with the variable R set to 10. In executing line 20, BASIC prints 314.159.
As you can see, the program calculates the area of a circle with radius R. To calculate the area of different circles, we could keep re-running the program over for each value of R. But, there is an easier way to do this; simply add another line to the program as follows:
By putting a GOTO statement on the end of our program, we have caused it to go back to line 10 after it prints each answer. This could have gone on indefinitely, but we decided to stop after calculating the area for three circles. This was accomplished by typing a carriage return to the input statement (thus a blank line).
The letter R in the program we just used was termed a variable. A variable name consists of one or two characters, and the first character must be a letter. The second character may be a letter or a number (0-9). Any character after the first two are ignored.
Variable names may not be the same as BASIC reserved words, nor may then contain BASIC reserved words. Reserved words are those words used as BASIC commands, statements, or functions. For example, TO would be an illegal variable name and FEND would be illegal because it contains the reserved word END.
Here is a list of MICROTAN BASIC reserved words:
MICROTAN BASIC also has two other variable forms; "string" and "integer". String variables are used for character lists, and are described in this chapter.
Integer variables are very useful for saving memory space. A floating point number requires five bytes of memory space for storage in this particular version of BASIC. One byte stores the exponent of the number, and the other bytes are used to store the mantissa. BASIC requires only 2 bytes of memory to store integers, because of their smaller range; +32767 to -32767.
Integer variables are distinguished from numeric variables by a "%" after the variable name. You may assign values to an integer variable in the same way that you assign values to floating point variables. For example:
If you assign a non-integer value to an integer variable, the number will be truncated; that is, any value to the right of a decimal point will be lost. For example:
During program execution, when BASIC encounters a calculation to be done with an integer variable, these steps are followed:
If you use integer values in a program and wish to get accurate results from calculations, you must be very careful to ensure that values are not truncated. When you define a variable as an integer, be certain that it will never receive a floating point number that you may wish to recall. Although integer variables can save significant amounts of memory space, their use may cause some loss of execution speed.
Besides having values assigned to variables with an INPUT statement, you can also set the value of a variable with a LET or assignment statement. Try the following examples:
As can be seen from the examples, the LET is optional in an assignment statement. BASIC "remembers" the values that have been assigned to variables using this type of statement. This "remembering" process uses space in memory to store the data. The values of variables are thrown away and the space in memory used to store them is released when one of four things occurs:
Another important fact is that if a variable is encoutered in an expression before it is assigned a value, it is automatically assigned the value zero. Zero is then substituted as the value of the variable in the expression. For example:
REM is short for remark. This statement is used to insert comments or notes into a program. These comments can help avoid confusion - especially when you write long programs. They are also helpful to anyone else who reads your program.
REM statements often note the purpose of a program and describe the techniques used in accomplishing that purpose. REM statements are useful only to humans. No information is passed to BASIC through the notes in a REM statement. When a REM is encountered during execution of a BASIC program, everything on the rest of the line is ignored.
IF AND THEN STATEMENTS: RELATIONAL OPERATORS
Suppose we want to write a program to find out if a number is zero or not. With the statements we have gove over so far this could not be done. What is needed is a statement which can be used to conditionally branch to another statement. The IF and THEN statements do just that. Try typing in the following program:
When this program is typed into the computer and run, it will ask for a value for B. Type any value you wish. The computer will then come to the IF statement. Between the IF and THEN portion of the statement there are two expressions separated by a relational operator. A relational operator is one of the following six symbols:
The IF statement is either true or false, depending upon whether the two expressions satisfy the relation or not. For example, in the program we just did, if 0 were typed in for B, the IF statement would be true because 0=0. In this case, since the number after the THEN is 50, execution of the program would continue at line 50. Therefore, ZERO would be printed and then the program would jump back to line 0 (because of the GOTO statement in line 60).
Suppose a 1 were typed in for B. Since 1=0 is false, the IF statement would be false and the THEN clause would not be executed. The program would continue execution with the next line. Therefore, NON-ZERO would be printed and the GOTO in line 40 would send the program back to line 10.
Now try the following program for comparing two numbers:
When this program is run, line 10 receives two numbers from the terminal. At line 20, if A is greater than B, A<=B will be false. This will cause the next statement to be executed, printing "A IS BIGGER", and then line 40 sends the computer back to line 10 to begin again.
At line 20, if A has the same value as B, A<=B is true so we go to line 50. At line 20, if A is smaller than B, A<=B is true so we go to line 50. At line 50, A<B will be true so we go back to the beginning.
Try running the last two sample programs several times. Remember, to stop these programs, just give a carriage erturn to the input request. The try writing a few programs of your own using the IF-THEN statement. Writing programs of your own is the quickest and easiest way to understand how BASIC works.
FOR AND NEXT STATEMENTS
One advantage of computers is their ability to perform repetitive tasks. Let us take a closer look and see how this works. Suppose we want a table of square roots from 1 to 10. The BASIC function for square root is SQR, and the form is SQR(X). We could write the program as follows:
This program will do the job. But imagine how time consuming this would be if we wanted to make a table of 100 square roots, or 1000 square roots! The inefficient method above could be improved by using the IF statement as follows:
When this program is run, its output will look exactly like that of the ten-statement program above. Let us look at how it works. Line 10 has a LET statement which sets the value of the variable N to 1. Line 20 prints N and the square root of N using its current value. Line 30 is a LET statement that sets the value of N to N+1. In a LET statement, an equals sign means "to be replaced with".
Thus, the first time line 30 is executed, N becomes 2. At line 40, since N now equals 2, N<10 is true, so the THEN portion branches back to line 20, with N now at a value of 2. The overall result is that lines 20 through 40 are repeated, each time adding 1 to the value of N. When N finally equals 10 at line 20, line 30 will increment it to 11. This results in a false condition at line 40, and since there are no further statements to the program, it stops. This technique is referred to as "looping" or "iteration". Since it is used quite extensively in programming, there are special BASIC statements for using it. We can show these with the following program.
The output of the program listed above will be exactly the same as the previous two programs. But notice that the first method we used would require 1000 statements to create a table of 1000 square roots, whereas the final example could do it with just 3 lines.
At line 10, N is set to equal 1. Line 20 causes the value of N and the square root of N to be printed. At line 30 we see a new type of statement. The NEXT N statement causes 1 to be added to N, and then if N<=10, the program returns to the statement following the FOR statement. The overall effect is the same as with the previous program. Notice that the variable following the FOR is exactly the same as the variable after the NEXT.
It is also possible to add a STEP clause to the FOR statement to change the increment of the FOR loop variable.
This tells BASIC to start with N=10 and to add 2 to N each time, instead of 1 as in the previous program. If no STEP is given in a FOR statement, BASIC assumes that 1 is to be added each time. The STEP can be followed by any expression.
Suppose we want to count backwards from 10 to 1. A program for doing this would be as follows:
Notice that we are now checking to see that I is greater than or equal to the final value. The reason is that we are now counting by a negative number. In the previous examples it was the opposite, so we were checking for a variable less than or equal to the final value. The STEP statement previously shown can also be used with negative numbers to accomplish this same purpose. For example:
FOR loops can also be "nested". An example of this procedure follows:
Notice that the NEXT J comes before the NEXT I. This is because the J-loop is inside of the I-loop. The following program is incorrect; run it and see what happens.
It does not work because when the NEXT I is encoutered, all knowledge of the J-loop is lost. This happens because the J-loop is "inside" the I-loop.
ARRAYS - DIM STATEMENT
An array is a table of values. The name of this table, which is called the array name, can be any legal variable name, such as "A". The array name A is distinct and separate from the simple variable A, and both can be used in a single program. To identify an element of the array, a subscript is added in parentheses to the array name. A(I) represents the Ith element in the array A.
BASIC must be told how much space to allocate for the entire array A. This is done with a DIM (dimension) statement, for example,
In this example, space is reserved for the array A to have elements from A(0) to A(15). Array subscripts always start with zero. Therefore, an array dimensioned at 15 has space for 16 elements.
If "A(I)" is used in a program before it has been dimensioned, BASIC reserves space for 11 elements (0 through 10).
The following program illustrates the use of arrays. It asks you to input 8 numbers, which it then sorts into ascending order.
When line 10 is executed, BASIC sets aside space for 9 numeric values, A(0) through A(8). Lines 20 through 50 get the unsorted list from the user. The sort is accomplished by comparing adjacent numbers. If they are already ordered, the program procedes. If they are not ordered, their positions in the array are reversed. If any pairs are reversed, the variable "F" is set to 1 and at line 150, BASIC is told to repeat the comparison process. If all the numbers are in order, lines 160 through 180 print out the sorted list. Notice that a subscript can be any expression, as illustrated in line 110.
Arrays may also be dimensioned as integer arrays. If all elements of an array can be represented by integers, a significant amount of memory space can be saved. An integer array is dimensioned exactly like a numerice array, except that a % must follow the array name. For example:
This array will have 10 elements, each one an integer. As with other integer variables, BASIC will perform all computations in floating point arithmetic.
BASIC provides functions to perform a number of standard mathematical operations. These functions would be time-consuming for you to calculate and code in BASIC, especially if you used them more than once in your program. A BASIC function has a three- or four-letter call name followed by an argument in parentheses. A function may be used anywhere in a program. A list of the BASIC functions, numeric and string, appears in Chapter 3. Each function is defined and the parameters for its argument are given.
USER-DEFINED FUNCTIONS - DEF STATEMENT
You may also define your own functions when you require a reasonably simple calculation at more than one place in your program. The DEF statement allows you to create a function and use it in the same way that you would use any of BASIC's intrinsic functions. A legal user-defined function name begins with FN followed by any acceptable BASIC variable name. A function need be defined only once and can be defined anywhere in the program. For example:
The dummy argument must be a simple variable, but the expression after the equals sign may contain the argument variable or any other program variable. If, after defining the above function, BASIC encountered a line such as:
BASIC should respond with:
First 4*4 was calculated using the formula we defined above. Then 5 was added to this value. More information about particular user-defined functions appears in Chapter 3.
SUBROUTINES - GOSUB AND RETURN
A program may perform the same action in several different places. If this is expressed by a relativeley simple calculation, you can probably use a BASIC function or a user-defined function to perform it. However, often it is a more complicated series of calculations requiring many lines of programming. In such cases the "GOSUB" and "RETURN" statements can be used to avoid entering the same lines over and over. When a "GOSUB" statement is encountered, BASIC branches to a specified line number. BASIC keeps track of the point at which it branched from the main program, and when a "RETURN" is encountered, BASIC goes back to the statement following the last executed "GOSUB". Observe the following program.
This program asks for two numbers which must be integers and then prints the sum of the two. The subroutine in this program consists of lines 100 to 130. The subroutine asks for a number, and if it is not an integer, asks for another number. It will continue to ask for numbers until an integer is entered.
The main program prints "WHAT IS THE NUMBER" and then calls the subroutine to determine if the number is an integer. When the subroutine returns to line 40, the value input is saved in the variable T. This is done so that when the subroutine is called a second time, the value of the first number will not be lost. The program then prints "WHAT IS THE SECOND NUMBER" and the second value is entered when the subroutine is called again. When the subroutine returns the second time, "THE SUM OF THE TWO NUMBERS IS" is printed, followed by the value of their sum. T contains the value of the first number that was entered and N contains the value of the second number.
The next statement in the program is the "STOP" statement. It causes the program to stop execution at line 90. If the STOP statement were not included in the program, we would "fall into" the subroutine at line 100. It would then ask that another number be input. When program execution reached line 130, the subroutine would try to return to the main body of the program. But since it was never called by a GOSUB, a RETURN WITHOUT GOSUB error would occur. Each GOSUB executed in a program must have a corresponding RETURN to be executed later. The opposite also applies, i.e. a RETURN should be encountered only if it is part of a subroutine which has been called by a GOSUB.
Either "STOP" or "END" can be used to separate a program from its subroutines. STOP will print a message indicating the line at which the STOP was encountered.
READ, DATA, AND RESTORE STATEMENTS
Suppose that a program required that the same list of numbers be entered into the program every time it was run. BASIC contains two statements for accomplishing this purpose, the "READ" and "DATA" statements. These same statements also make it easy to change the list of numbers whenever necessary. Consider the following example:
When the program is run and the READ statement is encountered, the effect is similar to that of an INPUT statement. But instead of getting a number from the terminal, a number is read from the DATA statements.
The first time a number is needed for a READ, the first number in the first DATA statement is returned. The second time one is needed, the second number in the first DATA statement is returned. When the entire contents of the first DATA statement have been read in this manner, the second DATA statement will be used. DATA is always read sequentially in this manner, and there may be any number of DATA statements in a program.
The above program plays a game whose object is to guess one of the numbers contained in the DATA statements. For each guess that is typed in, the program reads through all of the numbers in the DATA statements until one is found that matches the guess. If more values are read than there are numbers in the DATA statements, an OUT OF DATA error occurs. Line 40 checks to see if -999999 was read. This number is used as a flag to indicate that all of the data has been read. If -999999 is read, then the guess given was incorrect.
Before returning to line 10 to make another guess, we need to make certain that the READs will begin with the first piece of data again. This is the function of the "RESTORE" statement. After the RESTORE is encountered, the next piece of data read will be the first piece in the first DATA statement.
DATA statements may be placed anywhere within the program. Only READ statements make use of the DATA statements in a program, and any DATA statements encountered at any other time during program execution will be ignored.
STRINGS AND STRING FUNCTIONS
A list of characters is referred to as a "string". HELLO, BASIC 6502, and THIS IS A TEST are all strings. Like numeric variables, string variables can be assigned specific values. String variable names are distinguished from numeric variable names in that they have a "$" as the last character of the variable name. For example:
This example assigns the string value "BASIC 6502" to the string variable A$. Note that a character string to be assigned to a variable must be entered in quotes.
Now that A$ has a string value, it is possible to use various string functions to learn more about that value. String functions are similar to numeric functions, and are called and passed arguments in the same way. One of these functions is the "LEN" or length function. When called, it returns an integer equal to the number of characters in a string. For example:
The number of characters in a string may range from 0 to 255. A string which contains 0 characters is called the "NULL" string. Before a string variable is set to a value in the program, it is initialized to the null string, in much the same way that numeric variables are initialized to 0. Printing a null string on the terminal will cause no characters to be printed, and the print head or cursor will not be advanced to the next column. For example:
Another way to create the null string is by using quotation marks with nothing between them, i.e. Q$="". Setting a string variable to the null string can be used to free up the string space used by a non-null string variable.
It is often desirable to be able to access parts of a string and manipulate those parts. The string A$ was previously defined. If we wished to see only some of its contents we might use:
"LEFT$" is a string function which returns a string composed of the leftmost characters of its string argument. Another example might read:
Since A$ has 10 characters, the loop will be executed with N=1,2,3,...,9,10. The first time though only the first character will be printed. The second time, the first two character will be printed, etc.
There is a similar string function called "RIGHT$" which returns the right N characters from a string expression. Try substituting RIGHT$ for LEFT$ in the previous example and note the result.
There is also a string function which allows us to take characters from the middle of a string. For example:
MID$ returns a string starting at the Nth position of A$ to the end (last character) of A$. The first position of the string is position 1 and the possible position of a string is position 255. Very often it is desirable to extract only the Nth character from a string. This can be done by calling MID$ with three arguments. The third argument specifies the number of characters to return. For example:
Strings may also be concatenated (joined together) through the use of the "+" operator. Try the following:
Concatenation is especially useful if you wish to take a string apart and then put it back together with slight modifications. For instance:
Sometimes it is desirable to convert a number to its string representation and vice-versa. "VAL" and "STR$" perform these functions. Try the following:
"STR$" can be used to perform formatted I/O on numbers. A number may be converted to a string and then LEFT$, RIGHT$, and MID$ can be used to re-format the number as desired. STR$ can also be used to find out how many print columns a number will requires. For example:
VAL is useful in many different applications. If a program accepted a question from a user such as:
"WHAT IS THE VOLUME OF A CYLINDER OF RADIUS 5.36 FEET, OF HEIGHT 5.1 FEET?"
VAL could be used to extract the numeric values 5.36 and 5.1 from the question.
The following program sorts a list of string data and prints out the sorted list. This program is quite similar to the one given earlier in this chapter that sorted a numeric list.
100 DIM A$(15):REM ALLOCATE SPACE FOR STRING MATRIX
Strings may also be elements of arrays. These are dimensioned exactly like numeric arrays, except that the variable used as the array name must be a string variable (habing character "$"). For instance
creates a string array of 121 elements, eleven rows by eleven columns (rows 0 to 10 and columns 0 to 10). Each array element is a complete string, which can be up to 255 characters in length.
CHAPTER 3 FEATURES OF 10K MICROSOFT BASIC
A command is usually given after BASIC has typed OK. This is called the
"command level". Commands may be used as program statements. Certain commands,
such as LIST, NEW, and LOAD will terminate program execution. The form and
function of each command is described below.
The following summary of BASIC statements defines the general format of each statement, and includes an example of each statement's application. In the following statements and descriptions, an argument of:
Truncation means that any fractional part of the number is lost, e.g. 3.9
becomes 3, 4.01 becomes 4. An expression is a series of variables, operations,
function calls and constants which, after the operation and function calls are
performed using the precedence rules, evaluates to a numeric or string value. A
constant is either a number (such as 3.14) or a string literal (such as "GOOD").
BASIC FUNCTIONS - NUMERIC AND STRING
BASIC Functions perform certain frequently used calculations so you do not
have to supply the formulas or write the code yourself. For these calculations,
you may "call" a BASIC function that is already resident in memory. You must
specify the argument to the function, which is represented in the descriptions
below as "X" or "I". X may be a number or numeric expression. X may contain
variable names. All of the following would be acceptable arguments for functions
receiving argument "X": 3, 3*5, A, A+2, (A+B)*7. Functions receiving the
argument "I" must receive an integer. Passing a non-integer as an argument will
cause the integer to be truncated.
A string, as described in Chapter 2, is a series of characters. A string may
be from 0 to 255 characters in length. All string variables must end in $, for
example, A$, B7$, HELLO$. The following functions return values and information
pertaining to strings. In the descriptions below, arguments are represented by:
BASIC ERROR MESSAGES
After an error occurs, BASIC gives an error message and then returns to command level and types OK. Variable values and the program text remain intact, but the program cannot be continued and all GOSUB and FOR context is lost. The format of error messages is:
In the above formats, "XX" represents a fully printed message. The "YYYY" is the line number in which the error occurred in the indirect statement. The following descriptions indicate the meaning of BASIC's error codes and messages.
NEXT WITHOUT FOR
OUT OF DATA
OUT OF MEMORY
RETURN WITHOUT GOSUB
DIVISION BY ZERO
STRING TOO LONG
STRING FORMULA TOO COMPLEX
BASIC's arithmetic operators perform 6 functions. They are:
Note that negation is quite separate and distinct from subtraction. When you use the minus sign to negate a variable or a number, BASIC treats such usage as zero minus the variable or number. For example: X=-Y is processed as X=0-Y by BASIC. However, X=10-Y is an example of the arithmetic operation subtraction, and as such takes its usual place in the precedence of operators.
Priority of operations
When more than one operation is performed in a single formula, BASIC evaluates each portion using the following schedule of priority:
1) Parentheses - any expression enclosed in parentheses is always evaluated
7) Logical Operators in the order NOT, AND, then OR.
If, in any given expression, the above rules do not clearly designate the order of priority, then evaluation proceeds from left to right.
Relational operators allow a comparison of two values and are most frequently
used to compare expressions or strings in an IF...THEN statement. The six
relational operators are:
Any expression that contains one of these operations will always have the value of TRUE(-1) or FALSE(0). For example, (4=7)=0, (4=4)=-1, (7<4)=0, and (7>4)=-1. The THEN clause of an IF statement is executed whenever the expression after the IF is not evaluated at 0. For example, IF X THEN... is equivalent to IF X<>0 THEN. When applied to strings, the relational operators test alphabetic sequence. Comparison is made on a character by character basis according to the ASCII codes until a difference is found. If the end of one string is reached before a difference is found, the shorter string is considered smaller than the other string.
The Logical Operators are used for bit manipulation and for performing Boolean operations. These three operators convert their arguments to sixteen bits, signed two's complement integers in the range -32768 to +32767. They then perform the specified logical operation on them and return a result within the same range. If the arguments are not in this range, an ILLEGAL QUANTITY error occurs.
The operations are performed in bitwise fashion. This means that each bit of the result is obtained by examining the bit in the same position for each argument. The following truth table shows the logical relationship between bits.
The examples below show some uses of the logical operators.
A typical use of the bitwise operators is to test bits set in I/O locations which reflect the state of some external device. Bit position 7 is the most significant bit of a byte, while position 0 is the least significant.
CHAPTER 4 : Aids To Efficient Programming
The following hints will help you save memory space.
1) Use multiple statements per line. There is a small amount of overhead (5 bytes) associated with each line in the program. Two of these 5 bytes contain the line number of the line in binary. This means that no matter how many digits you have in your line number, (minimum number is 0, maximum number is 64000), it takes the same number of bytes. Putting as many statements as possible on a line will cut down on the number of bytes used by your program.
2) Delete all unnecessary spaces from your program. The statement
uses three more bytes than
Note: All spaces between the line number and the first non-blank character are ignored.
3) Delete all REM statements. Each REM statement uses at least one byte plus the number of bytes in the comment text. For instance, the statement
uses 24 bytes of memory. In the statement
the REM uses 14 bytes of memory including the colon before the REM.
4) Use variables instead of constants. Suppose you use the constant 3.14159 ten times in your program. If you insert a statement 10 P=3.14159 into the program, and use P instead of 3.14159 each time it is needed, you will save 40 bytes. This will result in improved execution speed.
5) The END statement is entirely optional at the end of a program.
6) Re-use the same variables. If you have a variable T which is used to hold a temporary result in one part of the program and you need a temporary variable later in your program use T again. Or, if you are asking the terminal user to give a YES or NO answer to two different questions at two different times during the execution of the program, use the same temporary variable A$ to store the reply.
7) Use GOSUBs to execute sections of program statements that perform identical actions.
8) Use the zero elements of arrays; for instance A(0), B(0,X). Simple (non-matrix) numeric variables like V use 6 bytes; 2 for the variable name, and 4 for the value. Simple non-matrix string variables also use 6 bytes, 2 for the variable name, 2 for the length, and 2 for a pointer. Array variables use a minimum of 12 bytes. Two bytes are used for the variable name, 2 for the size of the array, 2 for the number of dimensions, and 2 for each dimension along with 4 bytes for each of the array elements.
String variables also use one byte of string space for each character in the string. This is true whether the string variable is a simple string variable like A$, or an element of a string array such as Q1$(5,3). When a new function is defined by a DEF statement, 6 bytes are used to store the definition.
9) Reserved words such as FOR, GOTO or NOT, and the names or intrinsic functions such as COS, INT and STR$ take up only one byte of program storage. All other characters in programs use one byte of program storage each. When a program is being executed, space is dynamically allocated on the stack as follows:
10) Use integer variables. Integer variables require 2 to 4 fewer bytes for storage than floating point variables.
The following hints should improve the execution time of your BASIC program. Note that some of these hints are the same as those used to decrease the space used by your programs. This means that in many cases you can increase the efficiency of both space and speed at the same time.
1) Delete all unnecessary spaces and REMs from the program. This may cause a small decrease in execution time because BASIC would otherwise have to ignore or skip over spaces and REM statements.
2) Use variables instead of constants. It takes more time to convert a constant to its floating point representation than it does to fetch the value of a simple or matrix variable. This is especially important within FOR...NEXT loops or other code that is executed repeatedly. THIS IS PROBABLY THE MOST IMPORTANT SPEED HINT BY A FACTOR OF 10!
3) Variables that are encountered first during the execution of a BASIC program are allocated at the start of the variable table. This means that a statement such as 5 A=0:B=A:C=A will place A first, B second, and C third in the symbol table (assuming line 5 is the first statement executed in the program). Later in the program, when BASIC finds a reference to the variable A, it will search only one entry in the symbol table to find A; whereas it would search 2 entries to find B, three to find C, etc.
4) Omit the index variable from NEXT statements. NEXT is somewhat faster than its equivalent NEXT I because no check is made to see if the variable specified in the NEXT is the same as the variable in the most recent FOR statement.
The following functions, while not intrinsic to BASIC, can be calculated using the existing BASIC functions. Use the DEF statement.
CONVERSION OF BASIC PROGRAMS
Though implementations of BASIC on different computers are in many ways similar, there are some incompatibilities for which you should watch if you are planning to convert some BASIC programs that were not written in Microsoft BASIC.
1) Array subscripts. Some BASIC's use "[" and "]" to denote array subscripts. Microsoft BASIC uses "(" and ")".
2) Strings. A number of BASIC's force you to dimension (declare) the length of strings before you use them. You should remove all dimension statements of this type from the program. In some of these BASICs, a declaration of the form DIMA$(I,J) declares a string matrix of J elements each of which has a length of I. Convert DIM statements of this type to equivalent ones in BASIC: DIM A$(J). Microsoft BASIC uses "+" for string concatenation, not "," or "&". Microsoft BASIC uses LEFT$, RIGHT$ and MID$ to take substrings of strings. Other BASIC's use A$(I) to access the Ith character of the string A$, and A$(I,J) to take a substring of A$ from character position I to character position J. Convert as follows:
This assumes that the reference to a substring of A$ is not an assignment. If the reference to A$ is on the lefthand side of an assignment, and X$ is the string expression used to replace characters in A$, convert as follows:
3) Multiple assignments. Some BASIC's allow statements of the form:
This statement would set the variables B and C to zero. In Microsoft BASIC this has an entirely different effect. All the "="'s to the right of the first one would be interpreted as logical comparison operators. This would set the variable B to -1 if C equalled to 0. If C did not equal 0, B would be set to zero. The easiest way to convert statements like this one is to rewrite them as follows:
4) Some BASIC's use a backslash instead of ":" to delimit multiple statements per line. Change the backslash to ":" in the program.
5) Programs which use the MAT functions available in some BASIC's will have to be re-written using FOR...NEXT loops to perform the appropriate operation.
In situations where sections of high-speed processing are required, it may be advantageous to use machine code subroutines. A user machine code subroutine must have the following characteristics:
Note that these zero page locations are corrupted by BASIC if an INPUT command is used. User subroutines should therefore save any zero page values in RAM adjacent to the subroutine, and restore them to zero-page when next called.
To call a user subroutine from BASIC, the following set of steps is required:
For example, to call a machine code subroutine whose start is located at
address HEX 1F00
Note that X and I (these may be any variable) are dummy locations which have no meaning within the program context.
Transfer of parameters between the user subroutine and BASIC program are effected by using the BASIC PEEK and POKE functions to access a common area of RAM. For example, to access a parameter calculated by the above subroutine call, the following code is required:
Note that the BASIC address parameters must be in decimal notation.
To enter a machine code subroutine to memory, you should carry out the following steps:
You are now ready to run the program.
Using Zero Page Locations
BASIC and the associated TANBUG subroutines together use up all zero page locations. Therefore, when employing user subroutines, you cannot use zero page RAM to hold information between one user subroutine and the next. The onlyexception to this rule is if you are not using the BASIC INPUT command, in which case you may use locations $35 (HEX) to $80 (HEX).
You may of course use any zero page location you like within your user subroutine providing you save its contents on entry (either on the stack or in memory allocated to your subroutine) and restore it on exit from the subroutine.
As will all machine code programs, a system crash occurs if you try to execute incorrectly entered code. Often, it will be impossible to recover BASIC after a crash, and the machine will behave in an unpredictable way until a RESET is executed. For this reason it is recommended that an up-to-date tape dump is kept of all code - minimum effort is then required for program re-entry.
Using Interrupts With BASIC
You can not directly enter a "BASIC" written interrupt routine via an interrupt. There are two ways to handle interrupts in BASIC.
A user machine code interrupt routine is loaded into memory in a similar way to that described for user machine code subroutines. The MICROTAN 65 manual gives details of the method of adding interrupt driven peripherals.
Note that user interrupt routines must obey the following rules:
Note also that 6502 interrupts are disabled during cassette file read and write.
USING MICROTAN'S GRAPHICS WITH BASIC
You can use the POKE and PEEK functions in BASIC to produce a graphics (or mixed alphanumeric and graphics) display. The required data is written directly to the memory-mapped VDU. Note, however, that if you use BASIC's PRINT or INPUT command the display is scrolled and the graphics information is lost.
In alphanumeric mode you can consider the display as being made up of 16 rows of 32 characters each. The following sub-routine (which may of course be allocated any line number) puts the character held in string Z$ out on the screen at the co-ordinates specified in X and Y. If X and Y are too large no action is taken.
(The comments shown are not part of the program but are used to explain each step).
The following subroutine can be used to address the 64x64 chunky graphics space. The input parameters X and Y specify the screen co-ordinates, while if Z is a 0 the pixel is obliterated, if Z is a 1 a pixel is displayed. If Z is negative then the screen is not changed but a value of 0 or 1 is returned in Z to indicate the state of that pixel. If X and Y are out of range then no action is taken.
Warning - do not re-enter command mode with graphics set or you may need to reset to normal mode. Note that, initially the screen contains all spaces and therefore some graphics information is already present when you run a program. You may need to clear it just to use this subroutine.
CASSETTE DATA FILE HANDLING
MICROTAN BASIC contains software to allow you to write data files to and read files from an ordinary cassette player. You can use this either to read in a complete data file, process it, and record the results (single cassette non remote mode) or implement a motor remote control facility and use two cassette units for a read-process-write facility.
Dual Cassette Recorder Connections
On the MICROTAN mini-rack, cassette socket 0 should be used for the replay machine and cassette socket 1 for the record machine. If you are using a single recorder only this should be plugged into socket 0.
The XBUG firmware is necessary to use the data file handling facility. BASIC will crash on these commands if the PROM is not present. Cassette players must have their input/output levels set up as described in the XBUG manual before use with BASIC.
Remote Control Connections
The 6522 on TANEX which handles the cassette I/O has pin PB5 allocated as control for the replay cassette, and PB6 as record cassette control. The cassette drive is off when the pin output is high or three-state.
Different types of cassette recorder have different remote control options, while some have none at all. You should check which type your recorder has and connect it up as required.
WARNING: IF YOU ARE USING A MAINS POWERED RECORDER ENSURE THAT IT IS NOT POSSIBLE FOR ANY EXTERNAL VOLTAGE OR MAINS VOLTAGE TO APPEAR ON YOUR MICROTAN SYSTEM. DO NOT CONNECT THE CONTROL OUTPUTS DIRECT TO THE REMOTE CONTROL INPUT OF YOUR CASSETTE PLAYER, AN INTERFACE CIRCUIT MUST BE USED.
The remote control circuit shown below will be suitable for most portable recorders. If you are using one cassette only but require remote control, you should wire the relays so that your cassette operates when either PB5 or PB6 is asserted. It may be necessary to incorporate an override switch to allow you to rewind your cassette.
BASIC Programming Commands
Data file manipulations are carried out by POKEing into certain zero page locations immediately prior to executing INPUT or PRINT statements. After execution of the statement, normal mode is automatically returned.
The legal operations are:
These do not need to precede I/O statements.
sets CUTS speed, records the message "FILE1", prints "NAMED" on the VDU, then exits.
USING THE CASSETTE FILES WITHOUT REMOTE CONTROL
First, record a filename of your choice as described in the example above. Then record all data generated by your program using the POKE 22,254 command. This may either be done as your program generates it (though if you are doing long calculations this could be inefficient), or from store at the end of the program.
Rewind the tape. Use the POKE 22,1 command to look for your filename (all individual records with short headers will be ignored). Once you have found this, you can then read in your data records. Note that if you take a long time to process each record then the cassette may play back the next record before you are ready for it.
Remote Control Operation
Remote control operation is similar to that described above. However, you can now read in one record at a time from your input cassette, process it, and record it on your output cassette.
If a parity error occurs on read, the message PARITY is printed, and the program returns to the command mode. By typing CONT<CR> you can then enter data manually and the program will continue.
Note that if you exit from a program while the PRINT or INPUT statements are set up for cassette (this may occur if you CTRL C out of a program, or if you do not find the file you are looking for), then it may be necessary to depress CTRL C a few times to regain command mode.
From the command description it is obvious that cassette input-output is entirely free format - the content is totally up to you the user. It is more time efficient if you store as many characters as possible, for example:
is almost three times as fast as recording each one separately. If you use this method care should be taken over 4 points: