This directory contains the sources and make files for an
Atari BASIC compatible basic dialect.

This is based on Atari Basic, as developed by Paul Laughton and Kathleen O'Brien,
Shepardson Microsystems, as found in: The Atari BASIC SOURCE BOOK by
Bill Wilkinson, Compute! Publications (1983)

Basic++ fixes a couple of known Atari Basic bugs and includes a couple of improvmenents
without impacting compatibility with existing basic code. It does not attempt to
extend the Atari Basic dialect beyond its current syntax. If you are interested in a
more powerful Atari Basic, get TurboBasic, Basic XL or Basic XE. Basic++ is a
"best efford" to squeeze as many useful Basic features into the 8K cartridge ROM space
as possible.

Basic++ sources are based on Rev.A Atari Basic, as published in the Compute! book
cited above, with many improvements and refinements. Source code was completely reviewed
and refined, and was made more concise to the original leaving headroom for some new
features.

At this time, the following Atari Basic bugs have been fixed:

- The parser allowed INPUT without any parameters. Now it needs to take at least one
  variable.
- A Ctrl-U as last component of a string argument to PRINT worked as if the PRINT
  statement included a semicolon.
- It was possible to DIM two-dimensional arrays overrunning the available memory
  because any type of overflow check was missing.
- A downwards block move of an exact multiple of 256 bytes moved the wrong memory.
- Basic Rev. A crashed on cascaded versions of multiple unary operators, in particular
  PRINT NOT NOT A or PRINT ++2 or PRINT --X crashed. Atari "resolved" this issue in
  Rev.B by not parsing such expressions, Basic++ allows then and implements them
  correctly.
- LOCATE apparently did not restore the input buffer pointer correctly and could have
  caused errors if followed by a VAL() that required the pointer to be seated
  correctly. Basic++ fixes VAL.
- NOTE and STATUS were also parsed correctly if their arguments were arrays.
  However, none of them worked with arrays correclty, so the parser was adapted
  accordingly to accept only simple numeric variables.
- POINT did not accept arbitrary expressions, though it could. Fixed that.
- CHR$(a)=CHR$(b) was always true, regardless of a and b, the same bug holds true
  for STR$(a)=STR$(b). Fixed both bugs.

The following improvements have been made:

- The SQR function in Atari Basic was unbearably slow and unprecise as it uses the
  ancient Heron method. Numerical inaccuracies of the math pack division pile up and
  resulted in loss of accuracy. The new code uses a "digit by digit" algorithm that
  is not only faster, but precise up to the last digit ("one ulp" precision).
- The power function ("^" operator) was implemented in a very naive way and resulted
  in precision loss. Atari "fixed" that in Rev.B by rounding results, Basic++ uses a
  "divide and conquer" method by first computing the integer part and splitting off
  the fractional part when necessary. This improves precision and stability and
  ensures correct results for integer arguments.
- Atari Basic stored line numbers and offsets as return address for FOR-NEXT loops and
  GOSUB expressions and hence required a complete line-search to return to the
  previous statement. Similar to TurboBasic, Basic++ stores in addition an absolute
  address and continues from this address directly bypassing the search if it can
  ensure that the source code has not been modified in between.
- Atari Basic used a very ugly and hacky method of temporarily fiddling an EOL into
  strings used as file specifications when interfacing to CIO. Basic++ avoids touching
  the user program or code and copies the string before modifying it.
- Basic++ allows an empty second argument to LIST to list up to the end of the source,
  i.e. "LIST 100," lists all lines from line 100 on.
- Basic++ handles denormalized floating point numbers now correclty, especially when
  comparing numbers and testing numbers for zero.
- Basic++ "string variable splicing" now also allows empty splices. In particular,
  if "A$="HELLO"", then A$(6) is valid and returns the empty string. Similarly,
  A$(4,3) is the empty string. This avoids some pointless boundary checks when splicing
  strings.
- If RESET was pressed in the middle of a line or variable insertion, Atari Basic might
  have left an unusable program that crashed the system on a LIST. Basic++ will detect
  such cases and will clean up its program areas in such a case.
<<<<<<< README
  
Hi folks,

currently working on a new release of Atari++, the Linux Atari emulator. This release will feature (amongst others) an updated Os++ operating system and also a built-in Atari-basic compatible basic dialect, named "Basic++". I'm attaching both the new Os++ release and the Basic++ binary plus sources (note it's an 8K cartridge image!). I'm kindly asking for testing. Also, there are still around 300 bytes free in Basic++ that could be utilized for something "small and useful". I could use it to unroll some of the loops (improving performance, maybe) or I could use it from some small Turbo Basic compatible extensions. Note that I'm not trying to create a new Basic dialect here, compatibility is one one of the goals.

[attachment=409485:basic++.zip][attachment=409486:os++.zip]

From the README of Basic++:

This is based on Atari Basic, as developed by Paul Laughton and Kathleen O'Brien,
Shepardson Microsystems, as found in: The Atari BASIC SOURCE BOOK by
Bill Wilkinson, Compute! Publications (1983)

Basic++ fixes a couple of known Atari Basic bugs and includes a couple of improvmenents
without impacting compatibility with existing basic code. It does not attempt to
extend the Atari Basic dialect beyond its current syntax. If you are interested in a
more powerful Atari Basic, get TurboBasic, Basic XL or Basic XE. Basic++ is a
"best efford" to squeeze as many useful Basic features into the 8K cartridge ROM space
as possible.

Basic++ sources are based on Rev.A Atari Basic, as published in the Compute! book
cited above, with many improvements and refinements. Source code was completely reviewed
and refined, and was made more concise to the original leaving headroom for some new
features.

At this time, the following Atari Basic bugs have been fixed:

- The parser allowed INPUT without any parameters. Now it needs to take at least one
  variable.
- A Ctrl-U as last component of a string argument to PRINT worked as if the PRINT
  statement included a semicolon.
- It was possible to DIM two-dimensional arrays overrunning the available memory
  because any type of overflow check was missing.
- A downwards block move of an exact multiple of 256 bytes moved the wrong memory.
- Basic Rev. A crashed on cascaded versions of multiple unary operators, in particular
  PRINT NOT NOT A or PRINT ++2 or PRINT --X crashed. Atari "resolved" this issue in
  Rev.B by not parsing such expressions, Basic++ allows then and implements them
  correctly.
- LOCATE apparently did not restore the input buffer pointer correctly and could have
  caused errors if followed by a VAL() that required the pointer to be seated
  correctly. Basic++ fixes VAL.

The following improvements have been made:

- The SQR function in Atari Basic was unbearably slow and unprecise as it uses the
  ancient Heron method. Numerical inaccuracies of the math pack division pile up and
  resulted in loss of accuracy. The new code uses a "digit by digit" algorithm that
  is not only faster, but precise up to the last digit ("one ulp" precision).
- The power function ("^" operator) was implemented in a very naive way and resulted
  in precision loss. Atari "fixed" that in Rev.B by rounding results, Basic++ uses a
  "divide and conquer" method by first computing the integer part and splitting off
  the fractional part when necessary. This improves precision and stability and
  ensures correct results for integer arguments.
- Atari Basic stored line numbers and offsets as return address for FOR-NEXT loops and
  GOSUB expressions and hence required a complete line-search to return to the
  previous statement. Similar to TurboBasic, Basic++ stores in addition an absolute
  address and continues from this address directly bypassing the search if it can
  ensure that the source code has not been modified in between.
- Atari Basic used a very ugly and hacky method of temporarily fiddling an EOL into
  strings used as file specifications when interfacing to CIO. Basic++ avoids touching
  the user program or code and copies the string before modifying it.
- Basic++ allows an empty second argument to LIST to list up to the end of the source,
  i.e. "LIST 100," lists all lines from line 100 on.
- Basic++ handles denormalized floating point numbers now correclty, especially when
  comparing numbers and testing numbers for zero.
- Basic++ "string variable splicing" now also allows empty splices. In particular,
  if "A$="HELLO"", then A$(6) is valid and returns the empty string. Similarly,
  A$(4,3) is the empty string. This avoids some pointless boundary checks when splicing
  strings.
- If RESET was pressed in the middle of a line or variable insertion, Atari Basic might
  have left an unusable program that crashed the system on a LIST. Basic++ will detect
  such cases and will clean up its program areas in such a case.
 
=======
- The line seach for GOTO and GOSUB has been improved by avoiding a full search in case
  the target line is known to lie below the current line. It is then sufficient to search
  from the current line instead.

>>>>>>> 1.5
