[comp.sys.apple] Applesoft Bugs

stowekeller@pro-carolina.cts.com (Stowe Keller) (01/15/90)

Re: kadickey@phoenix.Princeton.EDU (Kent Andrew Dickey) who asks:
 
> ... I ask anyone to name an actual *BUG* in Applesoft, other than 
> the ONERR cannot-have-another statement-on-the same-line quirk?
> Applesoft is amazingly stable for v1.0...
 
     Methinks you don't use Applesloth very much!    8-)
 
     There are a fair number of bugs in Applesoft, ranging from 
annoyingly common to extremely obscure.  I don't have a single list of 
them, but I will pass along a few here.  I had found a few of my own 
about ten years ago, but Cornelis Bongers (of the Netherlands) and 
Glen Bredon (of Merlin and ProSel fame) have probably done some of the 
most extensive research into Applesoft's internals and its bugs.  The 
older versions of the Merlin assembler used to have Bredon's own 
commented disassembly of Applesoft in which, among other things, he 
found bugs and often told how to fix them.  Those of us who used DOS 
3.3 and had 16K language cards could place a patched version of 
Applesoft into that RAM and run Applesoft from there instead of from 
the ROMs.
 
     Here are some of the Applesoft bugs that I can think of:
 
     -As someone else mentioned, there is a bug in the floating point 
multiply routine which can cause the bottom 8 bits to be wrong, 
resulting in loss of precision.  Bredon's examples of this are:
           PRINT 1*998244415   or   PRINT 1*10.0000009
 
Calculations which make use of the multiply routine, like SIN() and 
COS(), EXP() etc also suffer as a result of this bug.
 
     -I believe there is a bug with the sign bit in certain divide 
calculations.  I think that   PRINT -3E-39 / 1   will show this.
 
     -Applesoft in some situations, like PRINT statements, fails to 
trap excessive decimal points in a number.  Instead of giving a
SYNTAX ERROR, it ends up with a silly number.  Try something like:
           PRINT  1...3..4
 
     -The integer constant for -32768 in the ROMs is incorrect, 
causing certain range comparisons for integers to fail.  Try
           X% = -32768.00049   : REM illegal value for integer var.
           PRINT X%            <---- will yield POSITIVE 32767 !!
 
     -Placing ridiculously large line numbers after a GOTO or GOSUB 
can cause Applesoft to crash into the monitor.  Try something like:
           GOTO 437761     or    GOTO 440319    or values in between.
 
     -The pseudo random number generator is essentially worthless, and 
the most authoritative articles say that there is no way to patch the 
existing algorithm to get it to work - it should be completely 
replaced with a new algorithm.  Call-APPLE published such an article 
using machine language and the USR() function several years ago.
 
     -Not only is the string garbage collection routine unbearably 
slow, it too can screw up and trash variables.  Bredon gives the 
example: 
          LOMEM: 10000: HIMEM: 10012: A$ = "A":A$=A$+"B":
          A$=A$+"C":PRINT A$
which incorrectly yields "ABA" instead of "ABC".
 
     -Due to conflicting use of the keyboard buffer, using an 
immediate mode GOSUB command which invokes a subroutine that uses 
INPUT or GET can give a very bizarre error.  Try the following:
          10 GET A$
          20 RETURN
          GOSUB 10: PRINT A$     <-- from immediate mode; you will get 
an error message along the lines of  ?SYNTAX ERROR IN 16826 .  This 
results from the fact that your immediate mode commands which reside 
in tokenized form in the keyboard input buffer get overwritten by the 
ASCII chr(s) that you enter for the GET or INPUT statement, and when 
Applesoft tries to resume execution after the RETURN, it sees junk and 
generates a syntax error for a bogus line number.
 
     -Cornelis Bongers wrote another article for Call-APPLE explaining 
how an incorrect RETURN WITHOUT GOSUB error can occur.  It's too long 
to explain here, but it involves FOR-NEXT loops and GOSUBs and having 
a loop variable stored across a page boundary and exiting from a 
subroutine that still has a FOR loop active.
 
     -I vaguely recall reading other articles about problems that 
could arise with overflowing the stack and Applesoft wouldn't 
correctly trap it as an OUT OF MEMORY condition.  And I think there 
was a problem that could arise because the decimal printout routine 
uses memory locations $00FF through $110 (for building the ASCII 
string when printing out a floating point number) and if the stack 
grew low enough without getting caught by the out-of-memory test, 
something would get overwritten.  Alas, I forget the details.
 
     If anyone has access to Randy Wigginton (sp?), who did most of 
Apple's work on the Applesoft code when they got it from Microsoft, he 
might be able to list off a few other known bugs of Applesoft.
 
     Hope this answers your question!
 
                            Stowe Keller
------------------------------------------------------------------------
Stowe Keller               Author of ProDOS8 LIST utility
CompuServe: 71540,725   GEnie: SKELLER   BIX: stowekeller
UUCP: [ sdcsvax nosc ] !crash!pro-carolina!stowekeller
ARPA: crash!pro-carolina!stowekeller@nosc.mil
INET: stowekeller@pro-carolina.cts.com

------------------------------------------------------------------------
Stowe Keller                            Author of ProDOS8 LIST utility
CompuServe: 71540,725       GEnie: SKELLER       BIX: stowekeller
UUCP: [ sdcsvax nosc ] !crash!pro-carolina!stowekeller
ARPA: crash!pro-carolina!stowekeller@nosc.mil
INET: stowekeller@pro-carolina.cts.com

davidbrierley@lynx.northeastern.edu (01/16/90)

     Here's some info from various sources on Applesoft bugs:

 ONERR bugs

      Certain combinations of errors will cause the machine to lock up or
crash if an ONERR statement is active.  The cure for some of these problems
is to add these lines to the BASIC program and use a CALL 768 at the beginning
of an error-handling routine:

  60 DATA 104,168,104,166,223,154,72,152,72,96
  70 FOR ML = 768 TO 777: READ MC: POKE ML,MC: NEXT ML

(Source: _Apple II User's Guide_, 3rd ed. Lon Poole 1985  pp. 276-277)

      Leaving an error-handling routine with a GOTO statement (instead of a
RESUME statement) doesn't clear information from an internal control stack,
causing the machine to crash in some cases.  The solution for this is to use
the RESUME statement or to use a CALL -3288 before leaving the routine with a
GOTO statement.

(Source: _Applesoft BASIC Programmers Reference Manual_, 1987  p. 65)

------------------------------------------------------------------------------
VAL bug

     Program example:

  10 A$="1E99":REM DISAPPEARING REMARK
  20 PRINT VAL(A$)

  When run, an overflow error occurs.  When listed, the REM statement and the
accompanying message disappear.  The line looks like: 10 A$="1E99
The error causes VAL to give up evaluating the argument, without restoring the
closing quote - which is normally temporarily replaced by a zero byte to 
signify the end of the string.  The only cure appears to be to avoid overflows
and keep string assignments at the end of program lines or in lines by th            y
themselves.

(Source: Compute's Apple Applications, June, 1988. (Vol. 6, No. 3) p. 63)
Note:  Compute's Apple Applications is now a defunct magazine.
-------------------------------------------------------------------------------
INT bug

  Program example:

  10 A = 1 / 7: B = 0
  20 FOR I = 1 TO 14
  30 B = B + A
  40 NEXT I
  50 PRINT INT (B)

     The resulting answer is 1 instead of two.  One suggestion was to add a
very small constant (.000001) to the variable just before using INT; however
it may produce an inaccurate result in some cases.  The other suggestion was
to use the STR$ function:
  
  50 PRINT INT( VAL ( STR$ (B)))

     The problem here is that the STR$ function is slower.

(Source: Compute's Apple Applications, February 1988, (Vol. 6, No. 1) p. 76)
----------------------------------------------------------------------------

     Please note that the above are not quotations from the sources.  The
February, 1988, issue of CAA also describes other errors with the TRACE
command, CHAIN, and the loss of data when accessing locked text files.  These
errors will need more or less verbatim discussion so I'll e-mail the article
to anyone who sends e-mail to me with the subject BUGS.

                                           David R. Brierley
                                           davidbrierley@lynx.northeastern.edu