Jump to content
IGNORED

Asking for Basic++ beta testing


thorfdbg

Recommended Posts

Hi folks,

 

now the promised update for basic++ which I delayed for testing purposes. So in this release:

 

PRINT and INPUT "work" again with IOCB #16. Even though they should not. Really.

 

INPUT, GET, STATUS, NOTE and LOCATE may now take array elements. Actually, NOTE and STATUS already accepted this syntax, though created nonsense when tried. Thus, "STATUS #1,A(0)" or "NOTE #2,SECTOR(i),BYTE(i)" work now. Surprisingly "POINT #2,SECTOR(i),BYTE(i)" worked since ever, so this is either an overview or a bug...

 

ENTER now also updates the internal "stack generation counter" to allow programs to continue working that call "ENTER" during program execution to set variables ("KAISER" did this).

 

ATN() of very large or small numbers returns now +/-90 degrees precisely. Actually, the result was precise already before, but not exactly 90 due to the conversion from RAD to DEG. The RAD result was actually perfect to begin with.

 

LOG and CLOG return now 0 precisely for 1.0. CLOG() also returns precise results for powers of ten, but for that you need to use the updated math pack of Os++.

 

LIST with missing last argument ("LIST 10,") still had a bug because the last line number listed was not 0x7fff (32767) but 0x7f00 due to a double use of the list end line number low byte.

 

basic++.zip

 

Link to comment
Share on other sites

Hi Thor,

Screw this compatibility-shmity and add fokking integer arithmetic. This will make basic++ rule in 10 liners contest. Who needs these wretched floats anyway?

Yes, if this would be just so easy. I thought about the concept of adding "integer representations" to the Atari internal floating point logic. The idea would be that whenever the mantissa is non-valid, e.g. first mantissa byte is FF which is a non-BCD byte, the remaining mantissa bytes are integers. This requires of course to extend the basic part of the math-pack to check for such representations, and potentially convert them to float whenever needed, i.e. think of expressions like "1+2.5" where the first part is stored as integer, the second is a float, or expressions like LOG(1) where LOG requires, in the end, a float, not an int.

 

Thus, in the end, a lot of additional tests come into the code (question is whether there is enough ROM space - with all the fixes I'm now down to 256 bytes), plus a lot of additional mathematics for the integer logic. I'm not quite sure whether that will give you a speed advantage in the end.

 

Atari Basic, and hence Basic++ work on the basis of a big "stack machine", i.e. whenever an expression is evaluated, results are pushed and popped onto a runtime stack, eight bytes per entry. That already costs a lot of time, not only the arithmetics. Thus, when evaluating an expression like 2*(3+4), Basic will more or less execute

 

PUSH 2

PUSH 3

PUSH 4

ADD (POP,POP,+,PUSH)

MUL (POP,POP,*,PUSH)

 

as you can image, just copying the data around accounts for some degree to the speed (or lack thereof).

 

Anyhow, Basic++ became already surpringly fast, pretty close to TurboBasic, and the improvements were not due to the floating point stuff (Ok, Os++ adds some of being a bit "snappier", but that's really not that much). The biggest contribution to speed were that Basic++ not only stores line numbers, but also absolute addresses on its run time stack, so "RETURN" and "FOR - NEXT" do not require a complete scan through the program, and GOTO and GOSUB and friends no longer scan from the top of the program if they can, but start at the current program line.

 

The former - namely the reworked run-time stack - required some care as in some cases, absolute addresses can point into the desert, for example if the user stopped the program, made some edits and then returned by CONT or RETURN to the program flow.

Link to comment
Share on other sites

I see. And what about a different domain with integer arithmetic only on (e.g.) hex numbers? like $4000+$200 --> $4200. No mixing of floats and integers without explicit conversions:

 

B = 512

A=$4000+HEX$(B)

?A

$4200

 

A=$4000+B

ERROR 69 - INTERMATHRACIALFOKKING PROHIBITED

 

Or rather

 

B = 512

A%=$4000+HEX$(B)

?A%

$4200

Edited by pirx
  • Like 1
Link to comment
Share on other sites

Just made a short benchmark. This is again AHI's benchmark, with all its deficiencies and problems, but here's what I got:

 

Basic++ on Os++ runs the benchmark in exactly one minute, gives an accuracy of 9.6E-3 = 0.00096 (smaller is better) and a "rand accuracy" of 1.891 (smaller is better).

 

Atari Basic Rev. C on the XL Os runs the same benchmark in 6minutes, 20 seconds (big big outch!), gives an accuracy of 0.013 (one magnitude worse) and a "rand accuracy" of 19.587 (also one magnitude worse).

 

Turbo Basic on Os++ (Os actually irrelevant) runs the benchmark in 40 seconds, and gives the same (lousy) accuracy values as Atari Basic.

 

So actually, that is quite close, and a lot better than I hoped for. Note that Basic++ *does not* unroll any loops (no ROM space for that), but it has a much better power function (A^2 in AHI's benchmark) and

a much better square root function (SQR in AHI's benchmark). I believe these two are really the major contributions to the relatively high speed in this specific benchmark. If you'll use another benchmark,

the relative speedup compared to Atari Basic will be less, but still visible.

 

If there would be enough ROM space, one could also unroll the loops in Basic++ and in the math pack of Os++.

Link to comment
Share on other sites

Here is as promised the next version, this time including an executable. The executable you want of course to run without the basic cart (otherwise, 8K of RAM is stolen for nothing). It is a self-relocating binary that places Basic++ just above the DOS buffers.

 

As far as Basic++ is concerned, here are the new features in this release:

 

* On coldstart (or loading), D:AUTORUN.BAS is loaded and executed.

* For one-dimensional arrays, one (rather long) multiplication has been removed from the execution path, again making Basic++ a bit faster.

 

basic++.zip

Edited by thorfdbg
  • Like 1
Link to comment
Share on other sites

Are the Os++ and Basic++ emulator friendly or do I have to keep getting out my eprom's burner every time you have a change. I am asking because Atari800 Plus just gives me a PINK screen..

Most certainly. Actually, Os++ is and Basic++ will be a component of the Atari++ emulator (guess what!) you'll find here:

 

http://www.xl-project.com/

 

I'm sorry that this project is currently progressing so slowly, even though you're currently participating in its development - in a way. I've currently so many other obligations (amongst others, JPEG XT to name the most prominent one) that it's hard to find the time to work on it, though the next release is certainly coming. And will feature (you guessed right) a Basic dialect, built into the emulator. Amongst other new stuff...

 

Thus, it's probably best to try this in its native habitat.

 

Anyhow, I don't know why Atari800 is not running it, but by best guess is that you need to switch the machine type to an 800XL. As always, I'm very low on ROM space, and the new Os++ features (documentation again on http://www.xl-project.com/)requires quite a bit of room, so the self-test area not only contains the DUP, it also contains part of the reset start up code - so the bank-switching logic for the self-test ROM must be present. Of course it is not on the old series, which might explain what you're seeing.

  • Like 1
Link to comment
Share on other sites

So here is the 1.01 of Basic++. Again, some new features, mostly bug-fixes, and most bugs actually left over from Atari Basic. Thanks to anyone helping in the bug hunt:

 

basic++.zip

 

Here are the new/old bugs that are no longer in this release:

 

- GRAPHICS closes the stream before testing whether its argument is valid, and hence
could leave the screen unavailable for graphics operations.
- If the line READ reads from is deleted, the next READ started from the same offset
of the following DATA line, and not from the beginning of the next DATA line. This
got fixed.
- CONT continued two lines after the STOP line in case the line containing the STOP
was removed.
- SOUND no longer overwrites Pokey SkCtrl, but rather uses the shadow register at
SkCtrlShadw (0x232) to reset only the bits it needs for a proper sound output.
- The parser treated the ESC-character as a line-feed character and hence as a
separator between commands. This got fixed and creates a parsing error now.
- Operator-typed keywords could be used as variable names, though not consistently.
This was mostly due to a bug in the parser. Thus, one could write "PRINT GOSUB"
but not "GOSUB=1", but "THEN=1" and "PRINT THEN". Depending on the parser
context, some reserved token names worked, others not. The test for conflicts
of string variables and operators was also incorrect. Now you can declare
variables like ABS$ (no conflict possible), but an array named ABS() is forbidden.
Similarly, an ordinary variable of the name ABS is not possible either, and
neither THEN or GOSUB are valid as variable names, but THEN0 or GOSUB$ are
non ambigious and hence valid.
- An error that is caused in the direct mode can no longer TRAP and hence cause
confusion. Causing an error executing a command directly through ENTER will,
however, cause a trap.
- If memory allocation failed when parsing a new variable, the variable name could be
allocated without having allocated the memory for storing the variable value. If then
a value is assigned to the variable, parts of the program memory were overwritten.
Now the order is reversed, which means that in worst case 8 bytes of memory are lost,
though the program remains functional.

 

Luckily, I was able to streamline parts of the code again, so this release is actually not longer than the previous one. Still approximately 128 bytes free that could be filled with something. Hopefully bug fixes, if there are any new bugs, or any old bugs...

 

  • Like 1
Link to comment
Share on other sites

So more streamlining was done, and I was able to gain enough bytes to add a single new, and most-wanted command. DIR. The DIR command here is fully compatible both in its syntax and its token to its Turbo-Basic equivalent, and I hope it really makes the live a bit easier.

 

basic++.zip

 

Then, I collected more bugs and fixed them:

 

- An error that is caused in the direct mode can no longer TRAP and hence cause
confusion. Causing an error executing a command directly through ENTER will,
however, cause a trap.
- If memory allocation failed when parsing a new variable, the variable name could be
allocated without having allocated the memory for storing the variable value. If then
a value is assigned to the variable, parts of the program memory were overwritten.
Now the order is reversed, which means that in worst case 8 bytes of memory are lost,
though the program remains functional.
- GOSUB or ON x GOSUB left the source line on the run time stack in case either the
evaluation of the GOSUB argument failed, or the target line was not found. Hence,
if the TRAP handler invoked return, it returned the origin of the faulty GOSUB
and not to he caller of the function including the GOSUB.
- The ENTER command could not be aborted with BREAK.
- The DSPFLG (DirectFlag under Os++) which prohibits the execution of control characters
is no longer implicitly reset by the error handler and by I/O errors. It is now
reset whenever a new line is requested from the user (or by ENTER).
- An END or falling off the end of the program no longer allows usage of CONT
to continue behind the end of the program.
- LIST now first checks whether it can open the output filespec before it
attempts to store the program position onto the run-time stack. This avoids
at least one race condition where a failed LIST resumes program execution with
RETURN.

So that's the 1.02 of Basic++. It *seems* that it's getting pretty stable now, but any test or bug report is of course highly welcome.

 

 

  • Like 1
Link to comment
Share on other sites

Well,

 

here is an ATR image with Basic++ V1.02 on it (ROM and XEX versions) and some collected information from this topic (converted into ATASCII with max. 38 chars per line). I used Bill Wilkinson`s Basoff.OBJ file with the XEX version, so that Basic++ will automatically switch off Atari Basic.

 

There is a version named TitBasPP.XEX on the image, this one is almost the same as the original version posted here, I only attached a Gr.2 title which currently displays "Here comes the title" - but you can change it to anything you like with a disk/sector-editor (and since its Gr. 2 you have max. 20 chars. available for a title).

 

I did not have much time to test Basic++ on my real 800XL with standard XL-OS, but so far the ten Basic programs I did run with it worked fine (e.g. "Schatzhoehle" by Peter Bluemer)...

 

 

Basicpp.zip

  • Like 2
Link to comment
Share on other sites

No news here, still at 1.02. Just played a bit with benchmarks and I tried to find a somewhat more realistic benchmark than AHI's. So I digged out the old ABC basic compiler (Monarch Data Systems), which is written in Basic, and gave it a try how long it takes to compile itself. It's quite telling, actually, though you should keep in mind that ABC only processes integers, there is no floating point logic.

 

So, Atari Basic requires wopping 81 minutes to compile ABC.BAS to ABC.COM.

Basic++ requires 32 minutes, so that's less than half the time.

TurboBasic requires 9 minutes (wow!)

ABC compiled with itself requires 5 minutes.

 

One should note here, however, that ABC does not exactly generate machine code. It generates a p-code that is interpreted by the ABC runtime engine. This p-code minimics (to some extend I wasn't aware of before) the inner workings of Atari Basic, but only uses integers. Thus, if one would write the ABC compiler in pure machine code, it would be again quite a bit faster.

 

Analyzing the situation a bit, I found at least one issue that is common to Atari Basic and Basic++, and that is the handling of its statement stack. So whenever an expression like A+B is evaluated, both Basics first move the operands to a hold area (which is really the math-pack register fr0 plus two bytes ahead of it), and then copies again this hold area to the stack. Which is one copy too much, obviously. At least one copy. I don't know what Turbo does here, but hopefully something more elegant.

 

Anyhow, whether that's the source of the (still) slower (but not quite as slow) Basic++, I don't know, but it's worth trying something. Problem is that I'm down to about 10 bytes free, and that's not sufficient to add better operand handling. Something has to go.

 

What about the following? CLOAD and CSAVE (tape handling) are my prime candidates to get rid of. First, Os++ has no tape handling anyhow, only as an external handler, and if that is used, the "short-gap mode" for tape can be emulated with SAVE "C:/S", so it's not a functional loss.

 

My third candidate would probably be LPRINT. It might be used in some programs, though it's due to its interference with the printer buffer problematic anyhow. Due to the way how the P: device works, a semicolon or comma at the end of LPRINT is ignored. Hence, it is advisable to open a channel to P: directly anyhow.

 

Any comments or remarks?

Link to comment
Share on other sites

Although pretty easy to work around, LPRINT can be useful in quite a few situations. For instance, let's say that you want to (quickly) open APE's Virtual MX atascii mode printer to your PC. You need to

 

LPRINT "escape-escape ! A"

 

-- and it opens. So my vote is to leave LPRINT in there.

 

BTW, you should see the ABC compiler zip through code at 7 and 14 MHz with Bob's XL14 accelerator. Presumably it will work even faster with Rapidus at 20 MHz. And FWIW, I've always wished that your OS++ supported hard drives -- again, a "speed thing" with me.

 

-Larry

  • Like 1
Link to comment
Share on other sites

Although pretty easy to work around, LPRINT can be useful in quite a few situations. For instance, let's say that you want to (quickly) open APE's Virtual MX atascii mode printer to your PC. You need to

 

LPRINT "escape-escape ! A"

 

-- and it opens. So my vote is to leave LPRINT in there.

 

BTW, you should see the ABC compiler zip through code at 7 and 14 MHz with Bob's XL14 accelerator. Presumably it will work even faster with Rapidus at 20 MHz. And FWIW, I've always wished that your OS++ supported hard drives -- again, a "speed thing" with me.

 

-Larry

 

Checked, but even with CLOAD,CSAVE,LPRINT and DIR removed, there is not enough ROM space left to replace the stack routines by faster unrolled and optimized code. 56 bytes missing. )-:

 

Concerning the second comment: It's not harddisks Os++ doesn't support, it is the PBI that is not supported. No ROM space left.

Link to comment
Share on other sites

  • 1 month later...

So here is an update of Basic++ to release 1.04:

 

basic++.zip

 

This is the list of changes:

 

- The "IF" statement did not properly test its argument for zero and might
have failed for denormalized numbers.
- An open IOCB #7 broke several Basic I/O functions, which caused an
incompatibility with KAISER.
- The "PRINT" statement did not reset one offset (cix) the original mathpack
touched but Os++ left alone.
- Allocating memory did not always check correctly for out-of-memory situations.
- Optimized the ^ (power) function a bit.
- Optimized the NEXT statement and stack deallocation a bit which makes
short loops a bit faster.
- Added a workaround against an original math-pack bug that fails printing
signed zeros.
- Added a short-cut evaluation of the numeric compare operator.

 

Link to comment
Share on other sites

  • 3 weeks later...

Did some testing today with 11 Atari Basic games.

 

Result: Atari Basic runs all 11 games ;-)

 

 

(Of course it does.) Alas, Basic++ did only run 4 of them correctly and since I am no programmer, I have no clue why. But I did write you a pm with descriptions of what errors/bugs/etc. appeared and attached the ATR image(s) with the games...

 

I do not call this beta-testing, this would be the job of a real Basic programmer, while I only tested some available Basic programs, but maybe its better than nothing...

 

Greetings, Andreas Koch.

Edited by CharlieChaplin
Link to comment
Share on other sites

Did some testing today with 11 Atari Basic games.

 

Result: Atari Basic runs all 11 games ;-)

Greetings, Andreas Koch.

Thanks, I'll have a look at these as soon as I have some time. Hopefully soon, as in "next week". I'm currently in Miami for work - and I won't have time to go to the beach. Oh *sigh*.

 

Besides - I'm currently internally here at 1.06 which includes a couple of minor changes, but only one bug fix. CLR did not work correctly.

Link to comment
Share on other sites

  • 5 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...