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