Archive-name: apple2/applesoft
Posting-Frequency: monthly
Last-modified: February 16 1998
Version: 0.27
URL: http://www.visi.com/~nathan/a2/faq/asoft.html
The Applesoft BASIC FAQ
NOTE: this FAQ is in beta form, and is still being written. Expect a few
minor continuing changes in its layout, content, and correctness. Most info
should be correct-- I'd like to be notified of any problems noted in the FAQ.
This document attempts to give a detailed and correct set of answers
about Applesoft BASIC, an interpreted programming language for the
Apple II series of computers. It is also intended as a reference for
commands and the like; it may at once time in the future include
tutorials, but does not do so now.
DOS 3.3 and ProDOS command line commands are not included in this FAQ;
they have a FAQ of their own at
http://www.visi.com/~nathan/a2/faq/dos.html. I do cover some disk I/O
from within Applesoft programs, however, in this FAQ.
Copyright (c) 1997 by Nathan Mates (email: nathan@visi.com), all
rights reserved. This document can be freely copied so long as 1) it
is not sold, 2) any sections reposted elsewhere from it are credited
back to this FAQ with the FAQ's copyright info and official WWW
location (http://www.visi.com/~nathan/a2/faq/asoft.html) left in
place.
This FAQ may not be sold, bundled on disks or CD-ROMs, reprinted in
magazines, books, periodicals, or the like without prior consent from
the maintainer, Nathan Mates. Exceptions are explicitly granted for
Joe Kohn's Shareware Solutions II newsletter, and Jim Maricondo's
Golden Orchard CD-ROM collection. Email me for permission otherwise.
Further, please do NOT make a copy of this FAQ and post it on the web;
I'm continually updating and fixing sections of it. A html link is
fine.
Disclaimer: I've tried to make this FAQ as accurate as possible, but
there's the chance that it's not perfect. I apologize in advance for
any slipups. Until I am confident that all information is 100%
accurate, you are advised that you are following all info at your own
risk. I will fix any problems found with this FAQ, but will not be
held liable for the results of problems.
Table of Contents
Section 1: General Intro to this FAQ and Applesoft Environment
1.1 Statement of purpose
1.2 Conventions and the like used by this FAQ
1.3 Determining which OS is running
1.4 Immediate mode vs. Deferred execution
1.5 Entering and running programs
Section 2: General language reference
2.1 Numeric Expressions and Assignments
2.2 String Expressions and Assignments
2.3 Flow of control
2.4 Variable names & conventions
2.5 Memory Management/Use
Section 3: Input/Output to Text and Graphics screens
3.1 'PRINT' and text formatting
3.2 Mousetext and special text output
3.3 Text input from the keyboard
3.4 Low Resolution (Lores) Graphics
3.5 High Resolution (Hires) Graphics
3.6 Hires 'Shapes' [Not done yet]
3.7 Double High Resolution (Double Hires) Graphics
Section 4: Miscellaneous tasks
4.1 Sound Generation
4.2 Reading paddles/joysticks
4.3 Program comments
4.4 Internal data storage
4.5 Error Handling
4.6 Random numbers
Section 5: Disk Input/Output
5.1 General Intro and simple commands
5.2 Binary files
5.3 Text File I/O
Section 6: Applesoft command reference by name
ABS, AND, ASC, AT, ATN, CALL, CHR$, CLEAR, COLOR=, CONT, COS,
DATA, DEF, DEL, DIM, DRAW, END, EXP, FLASH, FN, FOR, FRE, GET,
GOSUB, GOTO, GR, HCOLOR=, HGR, HGR2, HIMEM:, HLIN, HOME, HPLOT,
HTAB, IF, IN#, INPUT, INT, INVERSE, LEFT$, LEN, LET, LIST,
LOAD, LOG, LOMEM:, MID$, NEW, NEXT, NORMAL, NOT, NOTRACE, ON,
ONERR, OR, PDL, PEEK, PLOT, POKE, POP, POS, PRINT, PR#, READ,
RECALL, REM, RESTORE, RESUME, RETURN, RIGHT$, RND, ROT=, RUN,
SAVE, SCALE=, SCRN, SGN, SHLOAD, SIN, SPC, SPEED=, SQR, STEP,
STOP, STORE, STR$, TAB, TAN, TEXT, THEN, TO, TRACE, USR, VAL,
VLIN, VTAB, WAIT, XDRAW, &
Section 7: Error codes and messages
7.1 Applesoft Error codes
7.2 DOS 3.3 Error codes
7.3 ProDOS Error codes
Section 8: Miscellaneous Questions
8.1 How do I list to a file or transfer Applesoft to another
platform?
_________________________________________________________________
Sections planned to add to this FAQ:
Error codes in more detail
Fun tricks: Loading at alternate addresses, optimizing for size/speed
Peeks, Pokes, Calls, ROM, memory reference [I don't trust any out
there to be correct, given the number of holes that have been poked in
existing ones]
_________________________________________________________________
Section 1: General Intro to this FAQ and Applesoft Environment
1.1: Statement of Purpose
This document is not (yet?) a tutorial, instructions on how to
program, or the like. It is assumed that the reader has at least a
basic introduction to programming, such as variables, flow of
execution, as well as a general understanding of either DOS 3.3 or
ProDOS for the Apple II.
With the proliferation of Applesoft BASIC addons in the 70s, 80s and
90s, this FAQ does not attempt to cover any of them, though it may
make reference to a few of them from time to time. The only "variants"
to Applesoft that will be commented on in this FAQ are (1) the version
built into the ROM of all Apples since the ][+, (2) the ROM version
running under DOS 3.3 and 100% compatible clones, (3) the ROM version
running in conjunction with ProDOS's BASIC.SYSTEM. Most of the time,
these versions are nearly identical, so Applesoft information should
be regarded as applying to all 3 unless otherwise specified.
A few versions of Applesoft, namely the ones loaded from cassette and
disk on systems without Applesoft in ROM, lack a few features. Those
differences may be noted from time to time, but those notations may
not be complete yet.
About the only change in the ROM versions of Applesoft was the
inclusion of lowercase support starting with the //c and then
spreading to the enhanced //e, GS and IIc+. With that, Applesoft could
be entered in lowercase, but everything except for strings which
remained untouched would be uppercased. Also, the //c, IIc+ and GS
have no cassette port, so the cassette functions were removed. Support
for double lo-res was added instead.
1.2 Conventions and the like used by this FAQ:
Applesoft commands and the like are shown in uppercase and usually
within single quotes ('). For example, 'PRINT "HELLO, WORLD"' is the
way for the computer to announce to the world that it's alive, and
also a simple test of Applesoft. All Applesoft keywords are noted in
uppercase, and should be a hypertext link to the fuller description in
this FAQ. Optional parts of commands are noted in brackets '[]'. Words
in lowercase are usually intended to represent variables, expressions,
line numbers, etc.
1.3 Determining which OS is running, etc.
First, make sure you are at the Applesoft ']' prompt. Type 'CATALOG'
(case sensitive, even if you're running on a //c, enhanced //e, GS or
the like) and hit return. If you got a '?SYNTAX ERROR' and a beep
despite typing it correctly, you're likely not running under any
operating system. If you get a disk listing of files, you're under DOS
3.x or ProDOS. A DOS 3.x (3.2, 3.2.1 and 3.3, though 3.3 is by far the
most common) catalog would tend to look like
DISK VOLUME 254
*A 003 HELLO
*I 003 APPLESOFT
*B 006 LOADER.OBJ0
[Snip...]
while a ProDOS would tend to look like (in 40-column mode, these would
be wrapped to two lines)
BINSCII.TXT TXT 12 20-AUG-96 20-AUG-96 3:14 5645
Alternatively, you can type 'cat' (ProDOS is not case sensitive; also
this command does not exist in DOS 3.3 in any capitalization
sequence). If you get a disk catalog (and only 40 columns wide), this
is ProDOS. A '?SYNTAX ERROR' is a sign of DOS 3.3.
1.4 Immediate mode vs. Deferred execution
Most Applesoft statements can be typed at the ']' prompt, and they
will be executed immediately. You can set variables, do math, draw
graphics, and a fair number of other things directly. However, stuff
like inputting from the user, most text disk input/output and the like
can only be done from within a running program; an '?ILLEGAL DIRECT
ERROR' will be generated by commands not runnable from the prompt. If
you prepend a 'POKE 51,0' to a command, this will trick BASIC into
thinking your program is running and not complain about immediate
mode. DOS commands may be much harder to fool.
Multiple commands can be entered on one line of immediate or deferred
mode by placing a colon (':') between them. For example, 'A=5: B=6'
sets the values of both variables. [Exception: the 'HIMEM: memaddr'
and 'LOMEM: memaddr' statements must have the colon as part of their
actual syntax]
1.5 Entering and running programs
From immediate mode, if a line starts with a line number, it goes into
the current program and is not immediately executed. Valid line
numbers are 0 through 63999; lines are always kept in sorted order. As
there are no such things as named subroutines or the like, choices for
line numbering are somewhat important. It is usually a good idea to
use a spacing of 5 or 10 between line numbers to make inserting code
later on much easier-- renumbering programs can be a headache. The DOS
3.3 System Master disk came with a renumber program on it ('RUN
RENUMBER' to install it and get some information on how to use it),
but unfortunately ProDOS's BASIC.SYSTEM doesn't have that
functionality, though the disk bundled with Apple's "BASIC Programming
with ProDOS" book has a similar program.
If a line does not start with a line number, it is immediately
executed, should it be a command that can be run from the prompt.
[GOTO, GET, INPUT, and a few others won't work from the prompt.] Any
errors detected will be noted. However, errors (even syntactic) are
not caught within lines you enter into the current program-- they're
only caught at runtime.
Due to the size of the input buffer, a single line of the program is
limited to 255 characters. [Applesoft will start beeping when you get
to 248 characters]. There are several strategies for getting around
this. (1) When typing a line, use '?' instead of 'PRINT'-- it'll be
expanded to the full 'PRINT' when parsed. (2) Use no unneeded spaces--
only type them if they're in the middle of a string (" ") or a DATA
statement. They are not needed to separate terms in mathematical
expressions, etc. (3) Split the line into several lines.
When parsing lines without spaces, Applesoft looks for reserved words
first and separates them automatically, unless they're in the middle
of strings. For example, the following (nonsense) line of code
'10IFPRINT"HINPUT TETHEN"GOTOHLIN56=5' will appear as '10 IF PRINT
"HINPUT TETHEN" GOTO HLIN 56 = 5'
The command 'NEW' clears out any Applesoft program in memory and
clears the contents of all variables; it is not easily undoable. 'RUN'
starts the current program after clearing the contents of all
variables, starting at the lowest numbered line, and continues until
'STOP', 'END', flow of execution reaches the end of the code, or an
unhandled error is encoutered. Altenatively, you can use 'RUN linenum'
to clear all variables and start the program at line #linenum. You can
also do 'POKE 51,0: GOTO n' to start a program at line n without
losing the contents of the current variables.
To delete a single line of code, you can type simply the line number
and press return-- that 'replaces' it with an empty line.
There is minimal text mode support for line editing. When you 'LIST' a
program, you can press the 'esc'[ape] key and then use the diamond of
I/J/K/M (capitalization not important on an enhanced //e, //c, IIc+
and GS; may be necessary on an unenhanced //e) or the arrow keys (//e,
//c, GS and IIc+ only) to move around the screen and the spacebar to
move out of the movement mode. [The ][+ also exits escape mode with
the right or left arrows.] Once out of movement mode, the right arrow
can be used to "type" whatever character the cursor is on. This is
very handy for fixing part of a line, inserting or deleting sections.
When 'LIST'ing off a program, you'll notice that the default list has
quite a lot of padding on the right and left margins, which may make
it hard to "retype" a line without running afoul of the 255 character
limit. However, if you type a 'POKE 33,33' before 'LIST 'ing, (or you
can use 'POKE 33,72' if you're in 80-column mode), you'll signify to
Applesoft that you don't want the big margins, which'll help.
[Unenhanced //es must have an even screen width in 80-column mode;
'POKE 33,73' will work fine on an enhanced //e, //c, IIc+ and GS]
The 'TEXT' command will restore the screen to the normal margins.
_________________________________________________________________
Section 2: General language reference
2.1 Numeric Expressions and Assignments:
All variables can be set by '[LET] varb = expression'. The 'LET' is
totally optional, and is usually omitted as being redundant.
For integer and floating point (real) math, normal arithmatic
precedence and operations are followed. Thus, 'A=5+2*3' will set A to
11, not 21, as that expression with (redundant) parentheses is
'A=5+(2*3)'. Exponentiation can be performed with the '^' operator
('A=2^3' sets A to 8), but there is no remainder (modulus) operator
like in other languages.
The '=' operator behaves as an assignment the first time it's
encountered in an assignment, and equality at all other times. Thus,
'A=B=C' sets A to 1 (true) if B is equal to C, 0 otherwise. This is
significantly different from a number of other languages. However, 'IF
A=B THEN x' does not set the value of A to B. The "not equals" test is
'<>' or '><'.
Integers are automatically promoted to reals when needed. To do the
reverse, use 'varb=INT(expr)'. That converts the value to the highest
integer less than or equal to the expression. Integer values have a
fixed range of -32767 to 32767, so trying to convert from outside that
range will result in an error.
Boolean operators are also available-- integers and reals are treated
as true or 1 if not zero, and false or 0 if zero. Thus, 'A%=5.0 AND 2'
is true. The only boolean operations available are 'NOT', 'AND' and
'OR'
Bitwise operations are not directly supported, even on integers.
Operators have the following precedence; things within the same
precedence level are evaluated left to right:
* Highest precedence: () [parentheses]
* ^ [exponentiation]
* - [unary minus]
* * [multiplication], / [division]
* + [addition], - [subtraction]
* = [equal], <> or >< [not equal], < [less than], > [greater than],
<= or =< [less than or equal], >= or => [greater than or equal]
* NOT [logical complement]
* AND [logical AND]
* Lowest precedence: OR [logical OR]
Applesoft is somewhat concerned about variable types-- if you try and
directly assign a string to a number or vice versa, it'll stop and
complain. There are single-character conversions such as
'varb$=CHR$(varb2)' and 'varb=ASC(varb2$)'. Also, for string to number
coverstions, there is 'var$=STR$(expr)' (converts number to string
form) and 'val=VAL(expr$)' (converts first number found in string to
numeric value)
2.2 String expressions and Assignments
Strings have their own sets of operations-- the '+' operator acts to
concatenate strings, so 'A$=B$+C$' sets A$ to the full text of B$
followed immediately by the full text of C$, no spaces in between.
[Also assuming that the resulting size of A$ is under the limit of 255
characters per string, otherwise there'd be an error.] You can also
use '=', '<>' and the rest of the arithmatic comparisons on strings.
Note that string comparisons are case sensitive, and normal ASCII
order is used. The end of a string is considered to be less than any
character, in case of comparing strings of unequal length.
The individual characters in a string are not immediately accessible,
but can be gotten without too much trouble. 'LEN(expr$)' is the length
in characters of a string (can be a single string or any expression of
string type); 'LEFT$(varb$,n)' returns the n leftmost characters in
the variable, if n is greater than the length of the string, it
returns the entire string. Similarly 'RIGHT$(varb$,n)' is the n
rightmost characters. 'MID$(varb$,start[,len])' starts 'start'
characters into the string, and returns the "len" characters after
that, or the rest of the string if len is not specified. If "start" is
greater than the length of the string, the null string is returned.
2.3 Flow of control
Applesoft programs when 'RUN' start at the lowst numbered program line
with no variables set and proceed sequentially through the program.
Variables' contents are retained after the program exits until the
program's code is changed. While Applesoft does not have while loops,
named subroutines or the like, you can do all of them with what
Applesoft does have to offer.
The most basic flow of control statement is the 'IF x THEN y' clause.
Expression x is evaluated, and if true, then the rest of the line is
parsed. If x is false, then control skips to the next line of code. No
parentheses are needed around the x clause, but they don't really
hurt. There is no else clause in the language, but it is easy to get
around that-- put a GOTO at the end of the IF line to skip the next
line(s) of code, where the "else" clause is.
'IF x THEN GOTO n' can also be written as 'IF x GOTO n' or 'IF x THEN
n', but this abbreviation can only be done for 'THEN GOTO', no other
statements.
'GOTO n' transfers control to line n, if it exists. [And an error if
it doesn't.] 'GOSUB n' goes to a subroutine, and 'RETURN' goes back to
the site of the most recent GOSUB. GOSUBs can be nested up to about 12
or 16 deep, so recursion should be avoided if possible. The 'POP'
statement cancels the last return address, and continues on to the
next statement. [Essentially changing the last GOSUB to a GOTO.]
GOSUBs should be balanced by RETURN or POP, as there is only a limited
amount of space to store return addresses. If you try and RETURN or
POP more times than you've GOSUB'd, you'll get an error.
'FOR varb = start TO end [STEP increment]' sets up a loop. You can
only loop over reals; the increment defaults to 1 unless specified.
The loop stops when 'varb' is greater than 'end' if 'increment' is
positive, or less than 'end' if 'increment' is negative. The counter
variable 'increment' can be zero, in which case this is an infinite
loop. It is legal to modify the loop variable in the middle of a loop.
The contents of a FOR loop are always executed at least once, since it
only exits from the NEXT statement.
In addition, the start, end and increment parameters are evaluated
only once, at the start of the loop, so any changes to them will not
be reflected.
NEXT [varb][,varb2[,varb3]]' adds the step to the looping variable and
goes back to the top of the FOR..NEXT loop if it should continue. The
specification of the variable is optional-- if omitted, Applesoft will
use the innermost active loop to deal with. Crossing loops such as
'FOR I=1 TO 5: FOR J=1 TO 3: NEXT I: NEXT J' will cause errors, and
generally are a bad idea. However, if specified with the innermost
loop variable to the left separated by commas, it is doable: 'FOR I=1
TO 5: FOR J=1 TO 3: NEXT J,I'
Loops should be terminated with a 'NEXT', not a GOTO, since there is a
limited amount of space for tracking active loops, and the loop is
still active. One recommended solution is to change the loop variable
to a terminal value, do the 'NEXT' and then do whatever you want.
'END' will stop execution of the currently running program and cleanly
exit to the Applesoft prompt. Contents of variables are still set and
can be read. 'STOP' halts the currently running program with a
message; you can use 'CONT' from the prompt to attempt to restart
where you left off. In either case, a 'POKE 51,0: GOTO n' will attempt
to jump to a specified line in the code. [The 'POKE 51,0' tricks
Applesoft into thinking a program is running; INPUTs and other
deferred mode only commands won't work from the prompt without that.]
2.4 Variable names & conventions
All variables are identified by their first two characters and an
optional extension denoting the variable type. The first character
must be a letter, A-Z. The second can be blank (giving essentially a
single-letter variable name), A-Z, or 0-9. All continuing characters
([A-Z0-9]) past the first two are ignored-- NA is the same as NAME.
The total variable name has a maximum of 238 characters. [Applesoft's
236 character per line limit will restrict what you could do with such
long names.]
After the variable name, a character can be used to override the
default type of floating point [range of approx +/- 1.7*10^38 to
+/-2.29388*10^-39] variable. Use '$' to specify a string (255
characters maximum), or '%' for an integer (16 bits, with range -32767
to 32767). These three types are independent-- assigning to NM% will
not affect NM$ or NM. Also, all variables are assumed to be 0 (real
and integers) or an empty string if they are accessed before a value
is written to them.
When you type in your program, keywords are parsed before your
variable names, so do not use a keyword at anywhere in the variable
name. 'FORMATION=5' parses as 'FOR M AT I ON =5' which won't work when
run.
To extend these basic types, you can make arrays. To do this, do a
'DIM varname(size [, size [,size...]])' before using the array, where
size is an integer size greater than zero. Unlike C, DIM A(10) gives
you eleven places: A(0), A(1), A(2)... A(10). The values in each
position in the array can be set or read by giving the array variable
name, and the subscript in parentheses; this subscript can be
specified on the fly. For example 'DIM A(10): FOR X=1 TO 10: A(X)=X:
NEXT'. The subscript is converted to an integer value on accessing, as
the above example shows.
The size does not need to be a constant in the code-- you can do
'A%=50: DIM B(A%)'. Arrays can be of integer, real, or string type.
The presence of an array does not affect the basic (nonarray)
variable: A(x) for all x is independent from A.
If an array is referenced before being DIM'd, Applesoft assigns the
array a size of 11 (0-10), and it cannot be redimensioned.
You can make multidimensional arrays by specifying them in the DIM; a
3x3x3 integer array can be created by doing 'DIM B%(2,2,2)'. Please
note the section on Applesoft's memory management, as trying to
allocate too much memory for an array can overflow Applesoft's pool of
at most 35K.
2.5 Memory Management/Use:
Applesoft BASIC is rather poor in its memory management, mostly at the
cost of backwards compatability-- a standard (no machine-language
assistance) program that runs on a //e will run on any other Apple II
with at least 64K. The downside is that no memory past the first 64K
is recognized or usable. The operating system and other reserved
blocks of memory (text screen, system globals, etc) leave only 35K
($800-$9600) available for both your program and all variables. The
Hires graphics screens will use 8K each from that 35K; lores uses the
text screen at no memory penalty.
Space is used for storing variable names and their contents in
memory-- an integer will use 2 bytes for the actual data, and 2-3 for
the name. Beyond the name overhead, array Integer variables use 2
bytes of memory each, reals 5.
Strings are dynamically allocated, and use their length plus 1 in
bytes. If a lot of string manipulations are done, the space used by
the old versions of the strings are not recycled-- they remain in
memory. Thus, periodic garbage collections can be necessary. The FRE()
statement was built into Applesoft to both report on memory management
and perform garbage collection. 'FRE(x)' (parameter ignored, though 0
or 1 is customary) will report how much memory is free--
'AVAIL=FRE(1)' sets the result to a variable and does the garbage
collection. If the free memory is greater than 32K, it will be
returned as a number less than zero; add 65536 to that to get the real
number.
This memory operation may take many seconds to perform, leaving a user
to wonder what is happening. If this happens, it may be to your
advantage to do more FRE(0)'s in your code, thus doing more (hopefully
smaller) compactions. Alternatively, under ProDOS's BASIC.SYSTEM,
'PRINT CHR$(4)"FRE"' is a much faster version. [There were several
addon machine language packages for faster FREs under DOS 3.3, but
that's outside of the scope of this FAQ.]
To reserve off some space for your own purposes, you can use the
'HIMEM:' and 'LOMEM:' statements. The two define the top and bottom of
the memory pool Applesoft uses for variable storage. To read the
current value of lomem, use 'PEEK(106)*256+PEEK(105)', himem can be
read by 'PEEK (116)*256+PEEK(115)'. Normally, lomem is the top of your
basic program, and himem is the highest available address under the OS
and its buffers; you should not lower the lomem or raise the himem
unless you are darn sure what you're doing. Also, it's usually a good
plan to change the himem or lomem at the start of your program before
using any variables.
ProDOS's BASIC.SYSTEM grabs space on the fly for things, so moving
HIMEM under ProDOS may be a risky job. In all cases, it must be a
multiple of 256 under ProDOS.
_________________________________________________________________
Section 3: Input/Output to Text and Graphics screens
3.1 The 'PRINT' command and text formatting
PRINT (can be abbreviated as '?' when typing, but will be expanded
when LISTed) will print string constants ('PRINT "HELLO"'), numeric
constants and expressions ('PRINT 2+2'), strings ('PRINT NAME$'),
reals ('PRINT FOO'), or integers ('PRINT SP%'). It can also print
several of these at once if semicolons (';') or commas are between the
sections: 'PRINT "The Answer:"; 2+2'. Semicolons are not really needed
before the start of a string constant or after them-- 'PRINT
D$"CLOSE"' is perfectly legal.
If a semicolon is present at the end of a PRINT statement, the
'default' of a concluding carriage return is surpressed. 'PRINT's are
not really buffered-- they appear as soon as ready, even if the
trailing carriage return is surpressed. If a PRINT exists by itself,
it will print a 'carriage return' and go to the left edge of the next
screen row, scrolling if necessary. The 'SPEED=n' command (x=0..255,
255 is default of no delay, 0 is rather glacial) can be used to insert
a pause after each and every character outputted.
A comma present separating items jumps to the next 'tab' stop, which
are located 16 columns apart at columns 1, 17, 33, etc. The second tab
stop exists only if column 16 for that line is empty (i.e. filled with
spaces), and the third only if columns 24-32 are empty.
For floating-point values, scientific notation is used for values with
absolute value less than 0.01 or if there are more than 9 digits in
front of the decimal point.
'PRINT's of numeric values are always left-justified, and the output
will take up however much space is needed to represent it. Strings
similarly take up as much room as necessary and no wordwrapping is
done. No print formatting (such as the 'PRINT USING' of other Basics)
for other forms is built in; you'll have to write your own if this is
needed.
There are a few commands to do other fun things with the text output.
'INVERSE' will set text to come up in the reverse of the normal
background and foreground text colors. [All text output from Applesoft
is monochrome, but the GS has user-definable foreground and background
colors, versus the fixed white foreground, black background of
previous Apple II models.] If the 80-column card is not active,
'FLASH' will set the text to blinking. [See next section for special
notes on getting flashing text working when 80-column cards are
active.] 'NORMAL' will set the text to appear normal again. All three
do not affect what's currently on the screen, but only affect future
text output.
'HOME' will clear the screen and leave the cursor in the top left.
'VTAB n' will set the cursor's vertical position on the screen-- 1 is
the top row on the screen, 24 is on the bottom. 'HTAB n' similarly
sets the horizontal position of the cursor from columns 1 to 80.
[80-column mode on an unenhanced //e tends not to support HTAB well
past the 39th column; you may want to do 'POKE 1403,n' to set to
column n-1.
3.2 Mousetext and special 80-column text output
Enhanced //es with 80 column cards, //cs, IIc+s, and IIGSs have the
ability to display a special set of characters onscreen, useful for
text menuing/windowing, and the like. To enable it, make sure that the
80 column card is on (use PR#3), set INVERSE text, and then set the
mousetext mode on with a 'PRINT CHR$(27)'.
Once that is done, you can use any of the mousetext characters, which
are A-Z, and the punctuation "@[\]_\". [Sorry, HTML does not really
have Mousetext, so you're going to have to determine what they look
like for yourself.] To exit Mousetext mode, do 'PRINT CHR$(24)'
Also, you can get FLASHing text under 80-columns if you're willing to
not use any Mousetext characters at the same time. POKE 49166,0 sets
any Mousetext characters onscreen to flashing charactes, and 49167,0
turns all flashing text to Mousetext.
3.3 Text Input from the keyboard
For text input, there are three main methods-- INPUT, GET, and some
fun with PEEKs and POKEs. The first two are blocking methods that stop
the current program and wait for input to be typed in; the third hits
the hardware on the machine to see if a character has been typed and
get the currently typed character.
INPUT is the most powerful of the lot. It can get integers, reals, and
strings, as well as getting several at once. 'INPUT A' displays a '?',
flashes the cursor and lets the user type in a number. 'INPUT A,B'
wants two numbers, separated by a comma. If the user hits return
instead of a comma after the first number, a '??' will appear and the
user can type the next number. Strings and integer variables can be
similarly inputted. You can also use a string constant as the first
parameter of an INPUT to give a line of text to be printed before
anything is input: 'INPUT "What is your name?";NAME$' will do just
that.
Note: INPUT can be very poor about parsing multiple strings, numbers,
and the like. You may wish to program your own ones that have much
better functionality.
'GET' is like INPUT except that it only waits for one character, and
returns immediately on getting that without printing it to the screen.
Thus, 'GET A$' is an excellent way of waiting for any key, or building
a better INPUT, etc. GETting a real or an integer is not really
recommended-- if the user types a non-numeric character (0-9, +, -, ,,
E, etc), the program will stop with an error.
The final, and most on the metal method, is to read the 1-character
input buffer yourself. If the return value from 'PEEK (49152)' ('PEEK
(-16384)') is identical, but uses one more character) is less than
128, nothing has been hit. If it is greater than 128, the key hit has
ascii value of the return value minus 128. Thus, 'A$=CHR$(PEEK
(49152)-128)' will set A$ to the key that was hit. 'POKE 49168,0'
('POKE -16368,0' is also identical) will tell the system that you've
dealt with the keypress; if this is not done, it'll continually report
that one key down.
It is also possible to combine this: 'WAIT 49152,128' (identical in
function to 'WAIT -16384,128') pauses the system without flashing the
cursor until a key is hit without eating the key, so an immediate GET
will grab the key just hit.
3.4 Low Resolution (Lores) graphics
This graphics mode is always available, and provides 40x40 + 4 lines
of text or 40x48 graphics on the screen with 16 fixed colors
available. It does this by replacing each character on the text screen
with two blocks. [Since the screens are in the same memory location,
you can use Lores graphics commands to put stuff on your screen.
Experiment around!]
The Lores graphics screen can be turned on in "mixed" mode of 40x40
with 4 lines of text at the bottom with the 'GR' command. This clears
all of the 40x40 field to black, and puts the current prompt line in
the space at the bottom. 'COLOR=n' sets the color to the appropriate
selection. Valid colors are 0 (Black), 1 (Magenta), 2 (Dark Blue), 3
(Violet), 4 (Dark Green), 5 (Dark Gray), 6 (Medium Blue), 7 (Light
Blue), 8 (Brown), 9 (Orange), 10 (Light Gray), 11 (Pink), 12 (Bright
Green), 13 (Yellow), 14 (Aqua) and 15 (White). If the value for your
color is greater than 15, only the remainder when divided by 16 is
used, so 'COLOR=16' is equivalent to 'COLOR=0' and the like.
'PLOT x,y' sets the specified point to the current color. Coordinates
start with 0,0 in the top-left corner of the screen, and increase
towards the bottom and right. While there is no arbitrary lores line
function, there is functionality to draw horizontal or vertical lines.
They have the following form: 'HLIN x1,x2 AT y' and 'VLIN y1,y2 AT x'
'SCRN(x,y)' will return the color (0-15) of the pixel at coordinated
x,y.
'TEXT' will get you out of Lores or hires graphics mode (with a lot of
ugly garbage where your lores screen was; you may want to do a 'HOME'
to clear the screen after switching out.
3.5 High Resolution (Hires) graphics:
Apple IIs with at least 16K of memory (24-32K if you want to use an OS
as well) have the ability to draw on a 280x192 hires graphics screen;
24K (36-48K if an OS is desired) for the second independent screen.
All Apple IIs capable of drawing that can draw in 4 fixed colors; past
the first few revisions of the Apple ][ motherboard, there are 6 fixed
colors. [Technically 8 colors, but since there are two slightly
different whites and two blacks, that's 6 real colors]
Hires is also a root beer, but that's outside the scope of this FAQ.
[And no, I don't have that picture online.]
The 'HGR' command will turn on the first hires screen to a mixed
280x160 mode with 4 lines of text at the bottom, and clears the
graphical section to all black. [It may not move the current prompt
down there, so hit return if you seem to have lost the cursor.]
'HCOLOR=n' sets the color for drawing. Valid color numbers are 0
(Black 1), 1 (Green), 2 (Violet), 3 (White 1), 4 (Black 2), 5
(Orange), 6 (Blue), 7 (White 2).
The graphics drawing commands are much more intelligent than in
lores-- you can draw lines of any angle, as well as points. 'HPLOT
x,y' turns on that pixel. 'HPLOT x1,y1 TO x2,y2 [TO x3, y3 [TO
x4,y4]]' draws a line or series of lines in a row; you can also do
'HPLOT x1,y1: HPLOT TO x2,y2' and the like. Coordinates start with 0,0
in the top-left corner of the screen, and increase towards the bottom
and right.
Colors have some strange properties-- colors 1 and 5 can only appear
in even numbered columns, 2 and 6 only in odd-numbered columns. Any
two adjacent "on" pixels will appear white. [This is all due to the
hardware display methods]
'HGR2' turns on the second hires screen, and clears it to black. It
also displays all of it (280x192) with no text visible at the bottom.
[There's no easy way to get both the second hires screen and 4 lines
of text onscreen in a "mixed" mode as with lores and the first hires
screen without relocating the BASIC program in memory, some loops to
do memory copying and the like.] You can draw to the second hires
screen the same way as with the first-- the commands are identical. By
tweaking softswitches and other locations, you can draw on one page
while displaying the other, and other fun tricks.
For the technically inclined, some more info about the single
(regular) hires screen. It's 280x192 pixels in size, taking a $2000
byte chunk of memory starting at either $2000 ("page 1") or $4000
("page 2"). It's not linearized either, and has some 'holes' in the
display to make it fill up to $2000 bytes in size. [Each row takes 40
bytes, so after 3 rows, there's 8 unused bytes to make it an even 128
bytes]
There are 6 truly distinct colors, with 2 duplicated (2 whites and 2
blacks). Here's a general rundown of the rules: 2 (or more) adjacent 1
bits display as white. Next, a pair of bytes hold 14 pixels
horizontally, with the high bits in each not counting as pixels. Bits
are displayed from the least significant in each pair, so an 01 in
$2000 is the column 0 of row 0 on the first hires screen.
A 0 in an even numbered column and a 1 immediately to its right
(assuming that 1 is not part of a white chunk) is green or orange.
[More on that in a second] Similarly, a 1 and 0 in the same position
gives violet or blue. If there's two 0s in such a pair, it'll come out
as black.
For Apple IIs past the first few revisions of the Apple ][, the high
bit of each byte shifts colors up for each pixel contained within to
the second palette of 4 colors. Black and white are duplicated between
the two, but green becomes orange and violet becomes blue if the high
bit is set.
'TEXT' will get you out of Lores or hires graphics mode.
3.6 Hires Shapes
The hires screens do have the ability to draw and erase "shapes"
(consisting of simple vectors). These are are not the same as
bitmapped graphics like on other systems; simply vector based. [This
section is not quite yet written. Please be patient. -NJM]
3.7 Double High Resolution (Double Hires) graphics:
This mode is not directly accessible from Basic, as the memory map for
it is unlinearized and split between the first 64K blocks of memory.
[Thus it requires an enhanced //e w/ extended 80 column card, //c,
IIc+ or GS to do.] You'll need a machine language addon package to use
this mode; several existed, such as Beagle Bros' Beagle Graphics. (Not
yet legally available online to my knowledge)
_________________________________________________________________
Section 4: Miscellaneous tasks
4.1 Sound Generation
A simple default system beep can be done with a 'PRINT CHR$(7)'
(control-G); Applesoft BASIC can also only do simple clicks.
'PEEK(49200)' will produce a click every *other* time it's done; 'POKE
49200,x' is more erratic and either produce essentialyl silence or a
click every time. [Addresses are accessed twice on a POKE, but only
once with a PEEK.] Some claim that by oddball combinations of
accessing this softswitch (and usually in mathematical operations)
that you can get something resembling sound and/or music out of the
speaker. However, these, are wild hacks, and not very usable or easy
to generate/modify. Other beep tones and music require
machine-language subroutines which are currently beyond the scope of
this FAQ.
4.2 Reading paddles/joysticks
Up to 4 single-axis analog devices can be connected to an Apple II;
these can be either paddles or 2-axis joysicks. The 'PDL(n)' command
reads a single axis. n=0 for the first paddle or the horizontal axis
of a joystick, n=1 for the second paddle or the vertical axis of a
joystick (n=2,3 for the third and fourth paddles or second joystick).
PDL() returns a value between 0 and 255; the 'center' is approximately
127. There should be a slight pause between calls to PDL to allow the
hardware time to recover from the analog reading and prepare for
another. A quick FOR-NEXT loop does the job nicely: 'XP%=PDL(0): FOR
PD=1 TO 10:NEXT: YP%=PDL(1)'
Using a paddle number greater than 3 is a BAD idea-- you'll blindly
stomp over various softswitches, which can have very disastrous
effects on your computer.
Button #n (n==0..2) can be read with a 'PEEK (49249+n)'. If the
returned value is <127, it's being pressed or is not connected. There
is no way to tell in Applesoft whether a 'button down' is due to a
paddle/joystick or the corresponding apple key. [Open-apple (command)
on the keyboard appears like button 0, closed apple (option) appears
like button 1]
4.3 Program comments
Anything following a 'REM' command until the end of the line is
regarded as a comment, even if it's valid code. 'REM GOTO 500: GOTO
500' is just a comment, and neither GOTO will work.
4.4 Internal Data Storage.
Applesoft allows you to store a number of numeric or string constants
within your code and get them. The format for storing them is 'DATA
const1[,const2[,const3]]', with string constants enclosed in quotes.
To read them, use 'READ varb1[,varb2[,varb3]]'. The position of the
DATA and READ statements in the body program doesn't matter, but you
should READ out elements from your DATAs with the correct variable
type to avoid an error.
The DATA list is sequential access only-- it starts at the first DATA
in the code and works its way down, one element at a time. The
'RESTORE' command resets the DATA list pointer to the first DATA
statement in the program. [Unlike other BASICs, there is no way to
restore to an arbitrary data index number or data line number; you'll
have to manually do other things.]
4.5 Error Handling
Applesoft lets you define a section of your code that'll be executed
when an error occurs. Use 'ONERR GOTO line' to jump to that line when
an error occurrs; only one line can be specified. At that time, use
'PEEK(222)' to get the error code number. 'RESUME' will attempt to go
back to where the error happened if you've dealt with it, however, if
in the middle of a FOR-NEXT loop or a subroutine call, you cannot use
RESUME correctly without running a short machine-language patch for a
bug.
Also note that due to a bug, any program statements after the onerr
are ignored.
'POKE 216,0' will cancel any pending ONERR. It is recommended that
thisPOKE be the first statement of your error handling routine, to
prevent any errors in the error handler from calling the error
handling again.
4.6 Random Numbers:
Applesoft's 'RND(x)' function returns a pseudo-random number based on
the value of x. If x=0, the last-returned random number is returned,
If x>0, then the result is in the range 0<=RND(x)<1. If x<0, the
random number generator is seeded based on x; subsequent calls with
x>0 will return the same sequence.
The random number generator is fairly predictable; you may want to
investigate other methods for heavy-duty number generation.
If you want a integral random number between 1 and N, you should use
an expression like 'VALUE%=INT(RND(1)*N)+1'
_________________________________________________________________
Section 5: Disk I/O
5.1: General intro and simple commands
This is only available once you've started up your computer with DOS
3.3 or ProDOS. [If you haven't, then reboot into one of those before
typing in your program. With some trickery, you can boot a DOS 3.3
"slave" disk and recover a BASIC program you've already typed in, but
this is too technical for here.] For the most part, DOS 3.3 and ProDOS
can act almost identically to a running program until you try and use
the features available only in one of them. For more information on
DOS 3.3 and ProDOS commands, see their FAQ at
http://www.visi.com/~nathan/a2/faq/dos.html.
Also, the restrictions on filenames differs significantly between the
two. DOS 3.3 must start with a letter, but the rest of the 30
characters can be pretty much anything, and the file are case
sensitive. [Certain other characters are very difficult to type from
the command line, such as the comma, return and other control
characters like control-H] ProDOS must start with a letter, but the
remaining 14 characters (15 total) can only be letters, 0-9 and '.'.
ProDOS filenames are stored as uppercase only, so it's case
insensitive.
Note that all DOS commands are done as an addon to Basic, so their
commands can not be inserted in the middle of your program code. You
must 'PRINT' all your commands, preceeded by a control-D character.
The most common way of doing this is to assign the control-D to a
string variable, usually D$. Then, use D$ before all disk commands.
For example, 'D$=CHR$(4): PRINT D$"CATALOG"' You can also use a 'PRINT
CHR$(4)"CATALOG"' to achieve the same effect. This FAQ uses the second
method to be clearer.
In addition, DOS 3.3 wants the control-D to be the first character in
an output line; if you are having troubles, prepend a blank 'PRINT'
before the command, e.g. 'PRINT : PRINT CHR$(4)"CATALOG"'. ProDOS
wants the control-D to be the first character PRINTed.
DOS 3.3 does have a few bugs related to the GET command. If the first
character printed after a GET is a control character, it will get
eaten. This prevents all DOS commands from working, unless you print a
sacrifice control character after GETs. Control-A (CHR$(1)) doesn't
acffect the screen or anything else, which makes it nice and useful.
The most simple commands to use the disk are to load and save your
Applesoft program, called 'LOAD filename' and 'SAVE filename'
respectively. [If you omit the filename on a machine with cassette
ports (][, ][+ and //e), it will attempt to read/write from the
cassette ports in back, and seem to hang if a system is not connected]
Once saved to disk, you can access the program later; 'RUN filename'
can be used to both LOAD and RUN a saved Applesoft program.
'CATALOG' (case sensitive) under DOS 3.3 will show a listing of all
files. Under ProDOS, 'catalog' (case insensitive) gives a listing
formatted for 80-column displays; 'cat' deletes a few lesser used
(date/time modified, file size, etc) columns to fit nicely on a
40-column display.
'DELETE filename' deletes a file. File recovery is very difficult
under certain versions of ProDOS, so be sure only to delete what you
want.
5.2 Binary Files
Binary files (literally a memory image) can also be loaded and saved.
They can be saved with a 'BSAVE filename,Astart,Llen'. The starting
address in memory to save from and the length can be specified in
decimal or in hexadecimal (hex is preceeded by a $, so that 8192
decimal is represented by $2000). Under DOS 3.3, the start and length
parameters are required; under ProDOS, if they are omitted, the
parameters used when the file was created are used. [There are also
some more fun options under ProDOS; I'll get around to those later]
'BLOAD filename[,Astart][,Llen]' loads a file later. If omitted, the
address and length default to what was used when the file was saved;
if used, they override what was used when the file was saved. [Once
again, extra fun ProDOS options]
'BRUN filename[,Astart]' loads a binary file and starts executing it.
If it is not program code, the computer will probably have a nasty
crash. If omitted, the address defaults to what was used when the file
was saved.
5.3 Text File I/O
Text files written to under Basic can be of two forms: "Sequential
Access" and "Random Access." Sequential files can only be accessed a
line at a time, with each line accessed after the one before them.
Random Access files allow you to define 'records' for your input, and
then go to any records at will.
Both methods require you to 'OPEN' a file before any reading or
writing to it take place. 'OPEN'ing a file creates it on disk if it
does not exist. A sequential file is opened with a 'PRINT CHR$(4)"OPEN
filename"'.
A random access file has record of a certain length in bytes. Each one
may contain multiple pieces of text, but the text in them should not
go over the length, or you will write into the next record. When first
opened, you must specify the field length, e.g. 'PRINT CHR$(4)"OPEN
filename,Llen"'. Under DOS 3.3, you must specify the record length
each time you open the file; ProDOS recalls that for you from the
first time you created the file and can omit that parameter when
reopening a file.
When done with a file, your program should 'PRINT CHR$(4)"CLOSE
filename"' to close that specific file, or 'PRINT CHR$(4)"CLOSE"' to
close all open files. Applesoft or ProDOS does not automatically close
all open files when your program ends, and as output is buffered, your
disk file may not be complete.
After opening, you need to speficy whether the file is to be read or
written to. 'PRINT CHR$(4)"READ filename"' and 'PRINT CHR$(4)"WRITE
filename"' do the appropriate action. It is not possible to have a
file open for both reading and writing at once. With random access
files, you can specify which record you want to move to in the READ or
WRITE statement (it is allowable to READ or WRITE an open file
multiple times) with the ',Rrecord' parameter-- the first record is
record 0. For example, to read from the 10th record, 'PRINT
CHR$(4)"READ filename,R9"'
Once your file is ready for reading or writing, you can use simple
INPUT or GET commands to read data, and PRINT to write to the file.
All input or output is redirected to the files until you either close
off the file, or issue any DOS command, including the DOS null command
of a single control-D, e.g. 'PRINT CHR$(4)'.
If you OPEN an existing file, and try to WRITE to it, you'll write to
the start of it. If you wish to WRITE to the end of an existing file,
you can 'PRINT CHR$(4)"APPEND filename"' before WRITEing to it instead
of OPENing the file. DOS 3.3 had several nasty bugs in the APPEND code
that made it not always correctly locate the end of the file; you
should write a null character (CHR$(0)) at the end of your last data
to go into the file. ProDOS finally fixed that bug.
_________________________________________________________________
Section 6: Applesoft command reference by name
ABS(expr)
The absolute value of the expression.
AND
Logical anding of two logical expressions, yielding 0 or 1. Applesoft
treats 0 as false and any other number as true on input.
ASC(expr$)
Returns the ASCII code for the first character in the string. If the
first character has ascii value of 0, a '?SYNTAX ERROR' will occur. If
the input string is a null string, a '?ILLEGAL QUANTITY ERROR' will
occur.
AT
Reserved word required in the middle of HLIN and VLIN statements,
optional in the middle of DRAW and XDRAW.
ATN(expr)
Arctangent of the expression in radians. Results range from -Pi/2 to
+Pi/2.
CALL memaddr
Calls an assembly language subroutine at 'memaddr'. [The subroutine
should end with a 'RTS' instruction; no need to preserve register
contents]
CHR$( byte)
Converts a specified ascii value (must be in the range 0..255) to a
string.
CLEAR
Dumps the contents of all variables from memory, effectively assigning
a value of 0 to all integer and real values, and a null string to all
strings. Also undimensions all arrays. Can be called from with a
program, or at the command prompt.
COLOR=num
Sets the Lores plotting color. Valid colors are 0 (Black), 1
(Magenta), 2 (Dark Blue), 3 (Violet), 4 (Dark Green), 5 (Dark Gray), 6
(Medium Blue), 7 (Light Blue), 8 (Brown), 9 (Orange), 10 (Light Gray),
11 (Pink), 12 (Bright Green), 13 (Yellow), 14 (Aqua) and 15 (White).
If the value for your color is greater than 15, only the remainder
when divided by 16 is used, so 'COLOR=16' is equivalent to 'COLOR=0'
and the like.
CONT
Immediate-mode command to attempt to continue running a program after
it was stopped by STOP, END or a Control-C. You cannot continue after
Control-C'ing an INPUT statement, no program was running, or the
program has been modified since stopping.
COS( ang)
Computes the cosine of ang, with ang measured in radians.
DATA const[,const...]
Stores a list of constant values to be assigned by READ. Values can
either be numeric or strings; quotes are not needed unless the string
contains spaces, commas or colons. Constants can be blank (i.e.
nothing between the commas), leading to a zero (if read as numeric) or
a null string.
DATA statements are essentially ignored in immediate mode; strange
behavior has been occasinally observed if program flow reaches them.
DEF FN var(arg)=expr
Defines a mathematical function of at most one line for later use as
'FN var(arg)'. 'arg' is a placeholder variable name; it can be used in
expr to pass variables in. However, 'arg' can be used elsewhere in the
program without worrying about side effects from function definition
or calls. Functions can call other functions, but may not be
recursive.
Functions may be redefined if desired with another DEF FN block.
DEL line1,line2
Deletes a line or range of lines. Line2 must be greater than or equal
to line1; all lines between them (inclusive) are deleted. It can be
used in deferred mode under Applesoft, at which point the lines are
deleted and the program stops, no possibility of a CONT.
To delete a single line of code from the prompt, you can type simply
the line number and press return-- that 'replaces' it with an empty
line.
DIM var(size1[,size2...])[,var2(size1[,size2]...)...] Creates space
for an array of the specific type (real, integer or string) and the
specific size. n+1 elements in each dimension are created, referenced
0..N. Given that Applesoft only has a limited memory pool, you cannot
create very large arrays. Multiple arrays can be DIM'd at once by
separating them with commas in the DIM statement. If an array is
referenced before being DIM'd, Applesoft assigns the array a size of
10. You may not DIM an array a second time.
DRAW shapenum [AT x,y]
Draws the hires shape specified in the current HCOLOR, SCALE and ROT
on the current hires screen. The position is optional; if omitted, it
defaults to the last point done by the last DRAW, XDRAW or HPLOT.
Drawing shapes when no shape table has been defined or loaded is a bad
idea.
END
Stops the currently running program, leaves variables intact.
EXP( expr)
Raises e (2.71828183...) to the specified power.
FLASH
Sets future output from PRINT statements to flash on the 40-column
text screen. Not easily available in 80-column modes.
Several to all of ProDOS's BASIC.SYSTEM versions went into TRACE mode
if your code had a 'THEN FLASH' evaluated.
FN var(arg)
Executes the named function (previously defined with DEF FN and
arguments.
FOR varb = start TO end [STEP increment]
This sets up a loop. You can only loop over reals; the increment
defaults to 1 unless specified. The loop stops when 'varb' is greater
than 'end' if 'increment' is positive, or less than 'end' if
'increment' is negative. The counter variable 'increment' can be zero,
in which case this is an infinite loop. It is legal to modify the loop
variable in the middle of a loop. The contents of a FOR loop are
always executed at least once, since it only exits from the NEXT
statement.
In addition, the start, end and increment parameters are evaluated
only once, at the start of the loop, so any changes to them will not
be reflected.
FRE(expr)
If expr is not zero, this returns the amount of free memory is
available to Applesoft. [If the return value is greater than 32767,
will return the 2's complement value; add 65536 to the value to get
the correct value.] FRE(0) forces a garbage collection of unused
strings from the memory pool; it may be fairly slow at times.
GET varb
GET only waits for one character, and returns immediately on getting
that without printing it to the screen. Thus, 'GET A$' is an excellent
way of waiting for any key, or building a better INPUT, etc. GETting a
real or an integer is not really recommended-- if the user types a
non-numeric character (0-9, +, -, ,, E, etc), the program will stop
with an error.
GOSUB linenum
Saves the current position within the code, and branches to linenum,
which must exist. With a RETURN, you can go back to the original
position, or use POP to 'forget' the most recent gosub return address.
There is a limit of 24 nested GOSUBs, though active FOR loops and an
error handler will reduce this.
GOTO linenum
Branches program execution to the specified line, an error if the line
doesn't exist.
GR
Sets the screen to Mixed Lores graphics mode (40x40+4 lines of text),
and sets the top 40 graphics rows (20 text screen lines) to all black.
HCOLOR=val
Sets the color used for Hires graphics drawing. Valid colors are 0
(Black 1), 1 (Green), 2 (Violet), 3 (White 1), 4 (Black 2), 5
(Orange), 6 (Blue), 7 (White 2).
HGR
Turns on the first hires screen to a mixed 280x160 mode with 4 lines
of text at the bottom, and clears the graphical section to all black.
Does not move the cursor or set a 4-line text window like GR does.
HGR2
Turns on the second hires screen, and clears it to black. It also
displays all of it (280x192) with no text visible at the bottom.
[There's no easy way to get both the second hires screen and 4 lines
of text onscreen in a "mixed" mode as with lores and the first hires
screen without some loops to do memory copying and the like.]
HIMEM:val
Sets the highest memory position available for Applesoft's variables.
Used to reserve some space off for binary program code and the like.
The ':' is part of the command; if you do 'HIMEM=x', you will set the
real variable HI. The himem position is normally set by default; only
mess with it if you know what you're doing; under ProDOS it should be
an even multiple of 1024 (1K).
ProDOS's BASIC.SYSTEM grabs space on the fly for things, so moving
HIMEM under ProDOS may be a risky job. In all cases, it must be a
multiple of 256 under ProDOS.
HLIN x1,x2 AT y
Draws a horizontal line on the lores graphics screen from x1,y to
x2,y. x1 and x2 do not need to be in sorted order. x1, x2, and y
should be within the limits of the lores graphics screen (0..39 for x,
0..47 for y), or the results may be unpredictable.
HOME
Clears the text display screen and positions the cursor in the
top-left. Note that when in Lores mixed mode (40x40+4), the text
screen consists of only 4 lines of text. Use the TEXT command to exit
the graphics mode.
HPLOT [TO] x,y [ TO x1,y1 [ TO x2,y2]]
Draws a point, line, or series of line segments. If only a single
point is specified, it is drawn. With a TO, a line segment is drawn
from the last drawn point to the new location. Use HCOLOR= to set the
color of the line before drawing.
HTAB x
Sets the cursor's horizontal position to x. Under 80-column modes, you
may find that 'POKE 1403,x-1' works more reliably. [Htab uses 1-80 to
set the column; the POKE uses 0-79]
IF expr ...
Expression expr is parsed, and if true (not zero), then the rest of
the line is parsed. If expr is false (logical and numeric zero), then
control skips to the next line of code. No parentheses are needed
around the x clause, but they don't really hurt. There is no else
clause in the language, but it is easy to get around that. 'IF x THEN
GOTO n' can also be written as 'IF x GOTO n' or 'IF x THEN n', but
this abbreviation can only be done for 'THEN GOTO', no other
statements.
Several to all of ProDOS's BASIC.SYSTEM versions went into TRACE mode
if your code had a 'THEN FLASH' evaluated.
IN#slotnum
Accepts input from the specified slot, 0..7. Slot 0 is not a real slot
for input here, so it defaults to the keyboard. However, when running
under DOS 3.3 or ProDOS, you should use the DOS command version of
this, namely 'PRINT CHR$(4)"IN#"slot'
INPUT ["prompt";]var[,var2...]
This can get integers, reals, and strings, as well as getting several
at once. The prompt string is printed before user input is gotten.
Multiple variables can be entered at once, separated by commas or
returns.
INT(expr)
Returns the largest integer less than or equal to the input value.
INVERSE
Sets future output from PRINT statements to appear in reverse video
(background on foreground color).
LEFT$(expr$,num)
Returns the leftmost 'num' (num=0..255) characters of the string, if
num is larger than the length of the input string, the input string is
the result.
LEN(expr$)
The length of the string.
LET var=expr
Sets a variable. The 'LET' is redundant, though it may be used for
readability.
LIST [line1][,-][line2]
Displays the program specified. If no options are given, it lists the
entire program. If followed by one line number, it lists just that
line. Using a line number followed by a comma or a hyphen lists all
lines starting at that point. Using a comma or hyphen followed by a
line number lists all lines to that point. Using two line numbers
separated by a comma or hyphen lists all lines between the two,
inclusive.
'LIST 0' will list all lines in the program, not just line 0.
LOAD
Attempts to load a program off the cassette port, if available. Mostly
outdated now; the //c, IIc+ and IIGS don't have a cassette port, so
this command does nothing.
LOG(expr)
The natural logarithm (base e) of expr, for expr>0. To get the common
(base 10) logarithm, use 'LOG(expr)/LOG(10)'
LOMEM:
Sets the lowest memory position available for Applesoft's variables.
Used to reserve some space off for binary program code and the like.
The ':' is part of the command; if you do 'LOMEM=x', you will set the
real variable HI. The value is normally set by default; only mess with
it if you know what you're doing.
MID$(expr$,start[,len])
Returns 'len' (1..255) characters starting at 'start' (1..255)
characters from the left edge of the string. If the 'len' parameter is
omitted, returns to the end of the string; if 'start' is larger than
the size of the string, returns a null string.
NEW
Clears any Applesoft program and all variables from memory. Not easily
undoable, so be careful what you do.
NEXT [varb1][,varb2...]
Updates a loop started with a FOR. The loop's variable is updated by
the appropriate amount, and if the loop is to continue, program flow
goes back to the top of the loop. The specification of the variable is
optional-- if omitted, Applesoft will use the innermost active loop to
deal with. Multiple loops can be terminated with a single NEXT-- 'NEXT
J,I' is equivalent to 'NEXT J: NEXT I'
NORMAL
Sets future output from PRINT statements to appear in normal video
(foreground on background color).
NOT
Logical negation. 0 becomes 1, anything non-zero becomes zero.
NOTRACE
Stops any program flow tracing set up by TRACE.
ON expr [GOSUB|GOTO] line1[,line2...]
Sets up a GOSUB or GOTO to a series of lines listed depending on the
expression, which must have resulting value 0..255. The program
branches to the first listed line number if the result is 1, the
second if 2, and so on. If the result is 0 or a value higher than the
number of listed lines, program flow goes to the next instruction
after this ON-GOSUB or ON-GOTO.
ONERR GOTO line
Registers a function to GOTO when an error occurs. ONERR GOTO must be
executed before the error happens. When the specified function is
called, PEEK(222) contains the error code. To attempt recovery from
where the problem started, use RESUME.
Due to a bug, if you wish to safely use RESUME to go back to loops,
subroutines, and the like, you should POKE the following values
someplace in memory (they're relocatable, so the address doesn't
matter) and CALL the subroutine before RESUMEing: 104, 168, 104, 166,
223, 154, 72, 152, 72, 96. This cleans up the stack to what it should
be.
OR
Logical oring of two logical expressions, yielding 0 or 1. Applesoft
treats 0 as false and any other number as true on input.
PDL(n)
Returns the value based on the position of the analog device numbered
0 to 3. n=0 for the first paddle or the horizontal axis of a joystick,
n=1 for the second paddle or the vertical axis of a joystick (n=2,3
for the third and fourth paddles or second joystick). PDL() returns a
value between 0 and 255; the 'center' is approximately 127. There
should be a slight pause between calls to PDL to allow the hardware
time to recover from the analog reading and prepare for another. A
quick FOR-NEXT loop does the job nicely: 'XP%=PDL(0): FOR PD=1 TO
10:NEXT: YP%=PDL(1)'
PEEK(addr)
Returns the contents of the memory byte #addr in decimal. addr must be
in the range -32768 to 65535. [Memory addresses less than zero have
65536 added to them to get the real address] A canonical, verified,
trustable table of PEEKs, POKEs and the like has been planned by
Nathan Mates, but is not available yet. Randomly PEEKing around memory
is a bad idea.
PLOT x,y Sets the specified point on the Lores graphics screen
(x=0..39, y=0..47) to the currently set COLOR. If the lores screen is
not on, you will affect the text screen.
POKE memaddr, byte
Stores byte (0..255) into the specified memory address. Don't POKE
randomly; you can cause bad things to happen. A canonical, verified,
trustable table of PEEKs, POKEs and the like has been planned by
Nathan Mates, but is not available yet.
POP
Disposes of the last RETURN address, effectively changing the most
recent GOSUB to a GOTO.
POS(expr)
Ignores expr, returns the horizontal position of the cursor, from 0 to
39. In 80-column mode, this always returns 0.
PRINT[expr][[;,]expr2...]
Sends characters to the current output device. PRINT will print string
constants ('PRINT "HELLO"'), numeric constants and expressions ('PRINT
2+2'), strings ('PRINT NAME$'), reals ('PRINT FOO'), or integers
('PRINT SP%'). It can also print several of these at once if
semicolons (';') or commas are between the sections: 'PRINT "The
Answer:"; 2+2'. Semicolons are not really needed before the start of a
string constant or after them-- 'PRINT D$"CLOSE"' is perfectly legal.
If a semicolon is present at the end of a PRINT statement, the
'default' of a concluding carriage return is surpressed. 'PRINT's are
not really buffered-- they appear as soon as ready, even if the
trailing carriage return is surpressed. If a PRINT exists by itself,
it will print a 'carriage return' and go to the left edge of the next
screen row, scrolling if necessary. A comma present separating items
jumps to the next 'tab' stop, which are located 16 columns apart at
columns 1, 17, 33, etc. The second tab stop exists only if column 16
for that line is empty (i.e. filled with spaces), and the third only
if columns 24-32 are empty.
For floating-point values, scientific notation is used for values with
absolute value less than 0.01 or if there are more than 9 digits in
front of the decimal point.
'PRINT's of numeric values are always left-justified, and the output
will take up however much space is needed to represent it. Strings
similarly take up as much room as necessary and no wordwrapping is
done. No print formatting for other forms is built in; you'll have to
write your own if this is needed.
'PRINT' can be abbreviated as '?' when entering programs.
PR# slotnum
Sends output to the specified slot, 0..7. Slot 0 is not a real slot
for output, so it defaults to the 40-column text screen. However, when
running under DOS 3.3 or ProDOS, you should use the DOS command
version of this, namely 'PRINT CHR$(4)"PR#"slot'
READ var1[,var2...]
Reads the next available item(s) from a DATA statement into the
specified variables. It is sequential access only, travelling through
the list from the first items in the first DATA to the last. See also
RESTORE.
RECALL varname
Attempts to load an array off the cassette port, if available. Mostly
outdated now; the //c, IIc+ and IIGS don't have a cassette port, so
this command does nothing.
REM [comment]
Marks the start of a comment. Any and all text following it to the end
of the line is treated as a comment, and will not be executed.
RESTORE
Moves the DATA pointer back to the first DATA statement, so that
following READs will get data from there.
RESUME
Attempts program recovery at the point where an error occurred, but
was caught with an ONERR GOTO. Do not use if no error has occurred.
RETURN
Moves program flow back to just after the most recently executed
GOSUB. See also POP.
RIGHT$(expr$,num)
Returns the 'num' rightmost characters in the input string. If num is
greater than the length of the input string, the entire string is
returned.
RND(expr)
Returns a pseudo-random number based on the value of expr. If expr=0,
the last-returned random number is returned, If expr>0, then the
result is in the range 0<=RND(expr)<1. If expr<0, the random number
generator is seeded based on expr; subsequent calls with expr>0 will
return the same sequence.
ROT= expr
Sets the rotation value for hires shapes. Rot 0 is normal, 16 is 90
degrees clockwise, 32 upside down, and 64 is normal again. For
SCALE=1, the only available rotation values are 0, 16, 32 and 48;
SCALE=2 yields 8 positions, etc.
RUN [linenum]
Clears all variables, and starts execution from linenum, if specified,
otherwise from the lowest numbered line.
SAVE
Attempts to save a program to the cassette port, if available. Mostly
outdated now; the //c, IIc+ and IIGS don't have a cassette port, so
this command does nothing.
SCALE= expr Sets the scaling value for hires shapes. 1 is normal size,
2 is twice normal size, and the like, up to a maximum of 255.
SCRN(x,y)
Returns the color (0..15) of lores graphics screen pixel x,y. In text
mode, returns part of the ascii value for the character at x,y/2.
There is no corresponding Applesoft function for the Hires screen.
SGN(expr)
Returns -1, 0, or 1, depending on whether the input number was
negative, zero, or positive, respectively.
SHLOAD
Attempts to load a Hires shape table off the cassette port, if
available, and sets the shape table pointers. Mostly outdated now; the
//c, IIc+ and IIGS don't have a cassette port, so this command does
nothing.
SIN(ang)
Computes the sine of ang, with ang measured in radians.
SPC(num)
Print num blank spaces; this statement may only be used inside a PRINT
statement. Faster than a FOR-NEXT loop.
SPEED= val
Sets the text output speed. 255 is the fastest, 0 is the slowest.
SQR(num)
Computes the square root for num>=0, and an error if num<0.
STEP
Please see the FOR statement for use.
STOP
Halts program execution, notifying the user which line the program
stopped at. Use CONT to continue, assuming no changes have been made
to the program's code.
STORE
Attempts to store an array to the cassette port, if available. Mostly
outdated now; the //c, IIc+ and IIGS don't have a cassette port, so
this command does nothing.
STR$(expr)
Converts a numeric value to a string, using the same formatting as
used by PRINT.
TAB(xposn)
Used inside a PRINT statement, and moves the cursor right to column
'xposn' if the current position is left of xposn, does not move the
cursor if the current position is right of xposn.
HTAB is normally used instead.
TAN(ang)
Computes the tangent of ang, with ang measured in radians.
TEXT Switches the display to text mode, full screen (40x24 or 80x24),
and moves the cursor to the bottom row of the screen. If Lores
graphics were just on, the top 20 lines of the screen may be filled
with garbage. Use HOME to clear them off.
THEN
See syntax details under IF.
TO
Used as part of FOR and HPLOT; see syntax there.
TRACE Displays the line number for each statement as it is executed.
Multiple statements on a line may cause that line to be displayed
several times. Use NOTRACE to cancel. Since DOS 3.3 commands from
within a program require a return (CHR$(13)) before the DOS command,
the trace line numbers can interfere with this.
USR(expr)
Jumps to memory location $0A (which can contain a JMP to wherever you
want); the return value is whatever the floating point accumulator
held on returning.
VAL(expr$)
Converts the first number found in string to a numeric value,
returning 0 if there is no number in the string.
VLIN y1,y2 AT x
Draws a vertical line on the lores screen from x,y1 to x,y2 in the
currently set COLOR. y1 and y2 do not need to be in sorted order. If
the lores screen is not active, garbage may appear on the text screen.
x, y1, and y2 should be within the limits of the lores graphics screen
(0..39 for x, 0..47 for y), or the results may be unpredictable.
VTAB val Sets the cursor's vertical position on the screen. 1 is the
top row on the screen, 24 is the bottom.
WAIT memaddr,val1[,val2]
Goes into an uninterruptable loop (except by control-Reset) looking at
a memory address. The contents of memaddr are bitwise AND'd with val1,
and compared to val2 (or 0 as a default). If the two are identical,
then it keeps looping, else it exits.
XDRAW shapehum [AT x,y]
Erases the hires shape specified in the current HCOLOR, SCALE and ROT
on the current hires screen. (Technically, it draws in an opposite
color from the current pixel on the screen) The position is optional;
if omitted, it defaults to the last point done by the last DRAW, XDRAW
or HPLOT.
Drawing shapes when no shape table has been defined or loaded is a bad
idea.
& [parameters vary]
Jumps to a vector at $3F5 (1013); machine language programs may use
this as a hook to calling them. Smarter programs can be passed
parameters; the exact syntax for those depends on the program.
_________________________________________________________________
Section 7: Error codes and messages
7.1: Applesoft Error codes
Following is a list of the error codes returned on a PEEK(222), as
well as the message printed if the error remains untrapped.
Code Message:
0 ?Next Without For
16 ?Syntax Error
22 ?Return Without Gosub
42 ?Out of Data
53 ?Illegal Quantity
69 ?Overflow
77 ?Out of Memory
90 ?Undefined Statement
107 ?Bad Subscript Error
120 ?Redim'd Array
133 ?Division By Zero
163 ?Type Mismatch
176 ?String Too Long
191 ?Formula Too Complex
224 ?Undef'd Function
254 ?Reenter
255 (Control-C interrupt)
Error codes not possible within a program:
?Can't Continue Error
?Illegal Direct Error
7.2 DOS 3.3 Error Codes
Following is a list of the error codes returned on a PEEK(222), as
well as the message printed if the error remains untrapped.
Code Message:
1 Language Not Available
2 or 3 Range Error
4 Write Protected
5 End of Data
6 File not Found
7 Volume Mismatch
8 I/O Error
9 Disk Full
10 File Locked
11 Syntax Error
[Different from Applesoft's ?Syntax Error; this one is triggered by a
Syntax error in a DOS 3.3 command]
12 No buffers available
13 File type mismatch
14 Program too large
15 Not direct command
7.2 ProDOS Error Codes
Following is a list of the error codes returned on a PEEK(222), as
well as the message printed if the error remains untrapped.
Code Message:
2 Range Error
3 No device connected
4 Write Protected
5 End of Data
6 Path not Found
8 I/O Error
9 Disk Full
10 File Locked
11 Invalid Parameter
12 No buffers available
13 File type mismatch
14 Program too large
15 Not direct command
16 Syntax Error
[Different from Applesoft's ?Syntax Error; this one is triggered by a
Syntax error in a ProDOS command]
17 Directory Full
18 File not open
19 Duplicate File Name
20 File Busy
21 File(s) still open
_________________________________________________________________
Section 8: Miscellaneous Questions
8.1 How do I list to a file or transfer Applesoft to another platform?
Applesoft Basic files are not stored as ascii files on disk; all of
the keywords are tokenized and stored as single byte values in the
code. Thus, you cannot open the file in a word processor and expect it
to work.
To save a file off to an ascii file, do the following, assuming you
have DOS 3.3 or ProDOS loaded. Tack this line of code on to the
beginning of that file and run the program. It'll create a file on
disk with name 'ASOFT.LISTING'; replace the two occurrances of that
name below to write to something else.
1 D$=CHR$(4): PRINT D$"OPEN ASOFT.LISTING": PRINT D$"WRITE
ASOFT.LISTING" : POKE 33,73: LIST : PRINT D$"CLOSE": TEXT: END
[That's all one line, despite being formatted here]
_________________________________________________________________
Email suggestions to nathan@visi.com. As always, let me know of any
mistakes, updates, corrections, additions, etc.
There are a lot more questions with answers not included directly in
this FAQ; please see http://www.visi.com/~nathan/a2/faq for more of
them.
Copyright 1997 by Nathan Mates ( Nathan Mates)
--
<*> Nathan Mates http://www.visi.com/~nathan/ <*>
# What are the facts? Again and again and again-- what are the _facts_?
# Shun wishful thinking, avoid opinion, care not what the neighbors
# think-- what are the facts, and to how many decimal places? -R.A. Heinlein