Jump to content
IGNORED

Created English translation of the Extended Turbo Basic (Turex.com) documentation


markmiller

Recommended Posts

Like with Microsoft Basic II, Basic XE has an extension disk that you boot with the cartridge. You don't have to have it to run Basic XE, but you lose some capabilities.

 

You are right, Mark. That works fine now. That also explains "RENUM" not working. In a perfect world, when you boot up Basic XL it would inform you that the extension disk was not detected. But given that you work just as well, if not better, as a sort of 8-bit helpbot, who needs it: :) Thanks for the info.

Link to comment
Share on other sites

Hi!

21 hours ago, Brad Nelson said:

You can accelerate it a lot by replacing it with a newer mathpack, for example the Altirra mathpack. 

 

DMSC, I had run into that same recommendation elsewhere online. But there were no instructions on how to do it. If it's not too time-consuming, could you or someone else list the instructions for that? Thanks in advance. And note that I'm not using the FastBasic Windows app. I'm just running it off an ATR disk. I suppose swapping math packages involves, at the very least, using the FastBasic app for Windows. But I'm not sure. If it involves using the FastBasic Windows app, I probably won't be trying that app for a while, so don't bother if that's the case.

If you have an XL or XE, just run the attached file before loading FastBasic (or any other program using the OS mathpack), it will copy ROM to RAM and install the Altirra mathpack.

 

Have Fun!

 

mathpack.com

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Thanks very much, dmsc. I was able to install it into Atari Basic via DOS (the "L" command). I have a small prime sieve program (not of my making) that I used to test it. Here are the times for finding all the primes under 1000:

 

Atari Basic: With mathpack: 29.81 seconds

Atari Basic: Without mathpack: 35.26 seconds.

 

It did seem to create some stability problems. But I guess if you want to speed up an Atari Basic program, running it in Turbo-BASIC XL will do the trick:

 

Atari Basic program run via TBXL: 14.53 seconds

Compiled TBXL: 9.00 seconds

 

I couldn't get it to do anything but crash TBXL, but then doesn't it already have upgraded math routines? I was going to do a comparison in FastBasic, but for the life of me I couldn't fix the syntax errors in the prime sieve program (and obviously there are a couple"goto's" that need resolving as well). The first syntax error is as the "SL=SQR(LI)" line. Change "SL" to "SL%" (make it floating point) and it will pass the syntax check. But then the "FOR P=2 TO SL" loop is messed up as you move that "SL%" downstream. I gave up finally. The manual for the language is sparse regarding examples. If someone takes this as a challenge to fix it and thus educate a newbie, you get a twofer. :) Just fixing the syntax would be grand. I wouldn't mind the practice of converting the goto sections to procedures.

 

PRINT "LIMIT";:INPUT LI
POKE 19,0:POKE 20,0
DIM N(LI):FOR I=0 TO LI:N(I)=1:NEXT I
SL=SQR(LI)
N(0)=0:N(1)=0
FOR P=2 TO SL
IF N(P)=0 THEN 200 [aka "NEXT I]
FOR I=P*P TO LI STEP P
N(I)=0
NEXT I
NEXT P
C=0
FOR I=2 TO LI
IF N(I)=0 THEN 260 [aka "NEXT I]
PRINT I,:C=C+1
IF C=3 THEN PRINT :C=0
NEXT I
IF C THEN PRINT
TIME=PEEK(20)+256*PEEK(19)
PRINT "TIME = ";TIME/60;" SECONDS"

 

Edited by Brad Nelson
Link to comment
Share on other sites

@dmsc - I found through a different AtariAge discussion some ROM images with the fast FP routines already patched in. I'm able to just load up this patched ROM in my emulator. People can find the roms at:

 

https://atariwiki.org/wiki/Wiki.jsp?page=Articles#section-Articles-OperatingSystemsOS

 

Like Brad, I tried doing some benchmarks on it in Atari Basic. Sometimes I did a comparison to TBXL.

 

Here are my results:

 

I tried the same "Fedora" program I listed earlier (one of your revisions), and got a time of 36.6 minutes w/ fast FP. I believe you said the time for TBXL was around 17 minutes (~54% faster).

 

I tried a prime sieve that went up to 8,191 primes(!), and got a 20% speed improvement with AB w/ fast FP than without (200 seconds vs. 250 seconds, for 1 round).

 

I tried David Ahl's benchmark (from Byte Magazine), and got a 65% speed improvement over AB w/o fast FP (143.2 seconds vs. 404.4 seconds). Though, TB was 71% faster than fast FP (41 seconds)!

 

I tried a "Mandelbrot" benchmark, which draws a pseudo-Mandelbrot set (in ASCII), taking some computing time to do it. I saw a 27% improvement over AB w/o fast FP (301.4 seconds vs. 412 seconds), but again, TB was 52% faster than fast FP, with 144.2 seconds.

 

The worst performance for AB w/ fast FP was in Noel's Retro Lab benchmark, giving an improvement of just 5% (52.6 seconds vs. 55.3 seconds), and still, TB did it 55% faster than fast FP (23.8 seconds).

 

The efficiency improvement I saw with Atari Basic and fast FP varied widely, from as little as 5% to as high as 65%, with an average of 24.5%.

 

The low end I saw was with Noel's Retro Lab (5%). Its best performance was with David Ahl's benchmark (65%).

 

What I saw consistently, though, was that TB was ~50% faster than Atari Basic with fast FP. Sometimes it was significantly faster, as with Ahl's benchmark (71%).

 

I know there are other optimizations in TB besides just its own fast FP routines, but could these alone account for this significant speed improvement?

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

@Brad Nelson - I found the problem with your prime sieve. Arrays go from 0 to n-1, n being whatever you dimension the array to. So, I fixed the for-next loops.

 

I also changed the timing method. I got the formula out of the Compute! book "Mapping The Atari." I've never tried poking into locations 19 and 20 before (maybe that's why you were getting crashes?). I've always just saved the value, and then subtracted at the end. It seems to work.

 

100 ? "LIMIT";:INPUT LI
110 GOSUB 300:LET RUNT=TIME
120 DIM N(LI):FOR I=0 TO LI-1:N(I)=1:NEXT I
130 SL=SQR(LI)
140 N(0)=0:N(1)=0
150 FOR P=2 TO SL
160 IF N(P)=0 THEN 200:REM NEXT P
170 FOR I=P*P TO LI-1 STEP P
180 N(I)=0
190 NEXT I
200 NEXT P
210 C=0
220 FOR I=2 TO LI-1
230 IF N(I)=0 THEN 260:REM NEXT I
240 ? I,:C=C+1
250 IF C=3 THEN ? :C=0
260 NEXT I
270 IF C>0 THEN ?
280 GOSUB 300:? "TIME=";(TIME-RUNT)/60;" seconds"
290 END
300 TIME=INT((PEEK(18)*65536+PEEK(19)*256+PEEK(20)))
310 RETURN

 

I did a test run, with the limit set at 100, and got:

 

Atari Basic with XL ROM: 3.3 seconds

Atari Basic with fast FP ROM: 3 seconds (9% faster than AB)

TBXL: 1.6 seconds (47% faster than fast FP)

 

Speaking of how arrays are referenced, this had to be one of the hardest things I had to learn about Atari Basic when I was first learning it as a kid. (Numeric) arrays are indexed from 0 to n-1, but string buffers are indexed from 1 to n! Ugh! Talk about a language that's confusing for beginners!

 

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

@dmsc 

I realized I got my percentages wrong...

 

"Fedora" was ~115% faster with TBXL vs. Atari Basic and fast FP.

My prime sieve test was 25% faster with fast FP than without.

Ahl's benchmark was 182% faster with fast FP, and TB was 249% faster than fast FP.

The Mandelbrot benchmark was 37% faster with fast FP, and TB was 109% faster than that.

Noel's Retro Lab test was 5% faster with fast FP (as before), and TB was 121% faster than that.

 

Once again, the Noel Retro Lab benchmark was the low end for fast FP, and Ahl's benchmark was the high end.

 

On average, fast FP gave a 49% speed boost to Atari Basic, and TB was 142% faster than that.

 

And for your prime sieve, @Brad Nelson, the percentages were 10% faster with fast FP, and 88% faster with TB.

 

 

Link to comment
Share on other sites

Wow. Very cool, Mark. And thanks for the link. I installed the fast floating point ROMs into Atari800Win Plus 4.1. (Yes, a dinosaur, but it still works.) I saw the same speed improvement in Atari Basic as when manually running the MATHPACK.COM program supplied by dmsc. Your tests, of course, are much more comprehensive than mine.

 

I think I'll leave those new ROMS in there. :) I don't offhand see how to add them to Altirra 6.4. But it would seem to be via: Configure System...>Firmware>Firmware Manager>XL/XE Kernel, right? I've never spelunked in that setting before and don't want to screw anything up.

Link to comment
Share on other sites

Mark, you've given me a lot to think about so I'm going to have to take my time with this. But I first want to thank you for fixing that FastBasic prime sieve program. I'm going to learn a lot from that, I'm sure.

 

I've never tried poking into locations 19 and 20 before

 

FastBasic has its very convenient TIME and TIMER command, as you no doubt know, but just referencing this for the home audience, so to speak. TIMER resets the clock to zero. TIME gives the time in jiffies, so it's as easy as invoking TIMER in your program where you want to start the clock and then reading TIME at the end and dividing by 60 (NTSC, I presume) to get seconds.

 

As you well know, Turbo-BASIC XL has the same TIME function (but not the TIMER reset feature). But it's just as easy. But I don't think Atari Basic has any of that, so in a lot of programs you'll find:

 

TIME=(PEEK(18)*65536+PEEK(19)*256+PEEK(20))/60 [divided by 50 for PAL]

 

Peek locations 19 and 20 (presumably low byte/high byte) give you seconds (up to whatever the logical limit is...forgive my bad HEX math). If you factor in the Peek 18 location, you can count up to hours. But since many timers don't need anything over a few minutes, just using Peek 19 and 20 will often do.

 

And I should mention that you reset the clock (put this where you want the timer to start) with: POKE 18,0:POKE 19,0:POKE 20,0

Edited by Brad Nelson
Link to comment
Share on other sites

By the way, Mark. That program I had listed for the prime sieve worked fine in BASIC. What I'm trying to do is convert it to FastBasic. And I get parsing errors that make no sense to me. Give it a try if you get a chance. If you make it to the "for" loops, I'd love to see your code. There are some comments added below to the code that I'm trying to convert:

 

PRINT "LIMIT";:INPUT LI
POKE 19,0:POKE 20,0
DIM N(LI):FOR I=0 TO LI:N(I)=1:NEXT I
SL=SQR(LI)
N(0)=0:N(1)=0

! I can't get the above to make it through
! the parser no matter what I try.
! It could hinge on defining some of the variables
! explicitely as floating point. I don't know.
! The parser isn't much help.
! If I can get code that works in that first part,
!I should be able to finish this and convert the
!for/next loops to a while/wend loop or something like that.

FOR P=2 TO SL
  IF N(P)=0 THEN 200 ! originally pointed to "NEXT I"
  FOR I=P*P TO LI STEP P
    N(I)=0
  NEXT I
NEXT P

C=0

FOR I=2 TO LI
  IF N(I)=0 THEN 260 ! originally pointed to "NEXT I"
  PRINT I,:C=C+1
  IF C=3 THEN PRINT :C=0
NEXT I

IF C THEN PRINT 
TIME=PEEK(20)+256*PEEK(19)
PRINT "TIME = ";TIME/60;" SECONDS"

 

Link to comment
Share on other sites

Hi!

19 hours ago, Brad Nelson said:

I couldn't get it to do anything but crash TBXL, but then doesn't it already have upgraded math routines?

TBXL uses the RAM under the ROM for its own code, so you can't load a ROM replacement - and also it would not make a difference, as it has it's own math code.

 

19 hours ago, Brad Nelson said:

I was going to do a comparison in FastBasic, but for the life of me I couldn't fix the syntax errors in the prime sieve program (and obviously there are a couple"goto's" that need resolving as well). The first syntax error is as the "SL=SQR(LI)" line. Change "SL" to "SL%" (make it floating point) and it will pass the syntax check. But then the "FOR P=2 TO SL" loop is messed up as you move that "SL%" downstream. I gave up finally. The manual for the language is sparse regarding examples. If someone takes this as a challenge to fix it and thus educate a newbie, you get a twofer. :) Just fixing the syntax would be grand. I wouldn't mind the practice of converting the goto sections to procedures.

 

There is a version of the sieve benchmark included in the FastBasic distribution, at https://github.com/dmsc/fastbasic/blob/master/samples/int/sieve.bas . It does 10 iterations search all primes less than 16380, as the standard "byte sieve benchmark".

 

Comments on your version:

 

Quote

PRINT "LIMIT";:INPUT LI
POKE 19,0:POKE 20,0          '
 This is the same as:  TIMER
DIM N(LI)                    ' As you are storing 1 or 0 you can use a BYTE array to make the code faster.
FOR I=0 TO LI:N(I)=1:NEXT I
SL=SQR(LI)                   '
 This should be SL=INT(SQR(LI)), you need the integer approximation
N(0)=0:N(1)=0
FOR P=2 TO SL
IF N(P)=0 THEN 200           '
 You need to skip the above, so use IF N(P)<>0  and add ENDIF after the NEXT I.
FOR I=P*P TO LI STEP P
N(I)=0
NEXT I
                             '
 Here insert the ENDIF
NEXT P
C=0
FOR I=2 TO LI
IF N(I)=0 THEN 260           '
Same as above, skip with IF N(I)<>0 and ENDIF before the NEXT I
PRINT I,:C=C+1
IF C=3 THEN PRINT :C=0       '
You need to remove the THEN and use an ENDIF after the C=0 to skip both.
NEXT I
IF C THEN PRINT
TIME=PEEK(20)+256*PEEK(19)   '
You can delete this line, as TIME already gives the correct value.
PRINT "TIME = ";TIME/60;" SECONDS"

 

Have Fun!

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, Brad Nelson said:

What I'm trying to do is convert it to FastBasic. And I get parsing errors that make no sense to me. Give it a try if you get a chance. If you make it to the "for" loops, I'd love to see your code.

I got your sieve to run in FastBasic. I'd be interested in knowing how you're getting the listing out of it. I saved the program, but I've been trying to export it, to no avail. Are you just transcribing it off the screen to here? That's what I'm doing.

 

It seems the FastBasic disk I have is using its own DOS format. If I try to copy a file to a standard DOS 2.5 disk, it doesn't transfer (though, no errors reported), and if I try to boot into DOS 2.5, and get a directory off my FastBasic disk, I get garbage...

 

The difficulty you were having is in using floating-point vs. integer variables. SQR() only works on a float value, and only returns a float value. FastBasic is finicky in certain contexts. It is possible to convert between integer and floating-point, and you have to do this somewhat explicitly.

 

Its only branching logic is procedures and loops. There is no "THEN" in its IF statements. It's like what TBXL uses for if-else logic. So, I changed that logic around.

 

It turned out your logic was fine for numeric arrays, as you said. Indexing goes from 0 to n.

 

I kept getting "0 seconds" for the time, and realized this was because it was doing integer division on the time value (since I used an integer variable to hold it), and since it took less than a second, it was coming out 0 (I was choosing a limit of 100). So, I use a float variable to hold the time value, and so I get fractional time units when I divide.

 

A couple things I noticed about float variables, too. The % is not part of the name, but you have to use it wherever that variable is used, anyway. It's not just a declaration syntax. However, it considers, for example, LI and LI% as referring to the same variable (but of different types), and doesn't like that (parser error). So, I have to name it something different (I chose "LIF%").

 

?"LIMIT";:INPUT LI
POKE 19,0:POKE 20,0
DIM N(LI):FOR I=0 TO LI:N(I)=1:NEXT I
LIF%=LI:REM Convert to FP ("LIF" = "LI float")
SL%=SQR(LIF%)
N(0)=0:N(1)=0
SLI=INT(SL%):REM Convert to Int. ("SLI" = "SL integer")
FOR P=2 TO SLI
  IF N(P)<>0
    FOR I=P*P TO LI STEP P
      N(I)=0
    NEXT I
  ENDIF
NEXT P

C=0

FOR I=2 TO LI
  IF N(I)<>0
    ?I,:C=C+1
    IF C=3:?:C=0:ENDIF
  ENDIF
NEXT I

IF C<>0:?:ENDIF
TI%=PEEK(20)+256*PEEK(19)
?"TIME = ";TI%/60;" SECONDS"

 

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

Hi!

1 hour ago, markmiller said:

I'd be interested in knowing how you're getting the listing out of it. I saved the program, but I've been trying to export it, to no avail. Are you just transcribing it off the screen to here? That's what I'm doing.

 

It seems the FastBasic disk I have is using its own DOS format. If I try to copy a file to a standard DOS 2.5 disk, it doesn't transfer (though, no errors reported), and if I try to boot into DOS 2.5, and get a directory off my FastBasic disk, I get garbage...

The standard FastBasic disk is in SpartaDOS format, and uses BW-DOS. This is because I really like BW-DOS, it is a powerful and small DOS, with support for folders, time/date, loadable drivers and command line parsing.

 

To get your files to a DOS 2.5 disk, you can use the BW-DOS menu program, that can read/write DOS 2 disks. Or if using an emulator, just save it to the "H:" emulated device. In Altirra, you can even browse the disk image and extract the files by drag and drop.

 

 

1 hour ago, markmiller said:

The difficulty you were having is in using floating-point vs. integer variables. SQR() only works on a float value, and only returns a float value. FastBasic is finicky in certain contexts. It is possible to convert between integer and floating-point, and you have to do this somewhat explicitly.

Yes, FastBasic converts integer to floating point implicitly, but not the other way around, to avoid errors. So, you must use INT().

1 hour ago, markmiller said:

Its only branching logic is procedures and loops. There is no "THEN" in its IF statements. It's like what TBXL uses for if-else logic. So, I changed that logic around.

 

It turned out your logic was fine for numeric arrays, as you said. Indexing goes from 0 to n.

Yes, for compatibility reasons, a " DIM A(N) " defines an array from 0 to N inclusive, this means that the array has N+1 elements.

 

1 hour ago, markmiller said:

I kept getting "0 seconds" for the time, and realized this was because it was doing integer division on the time value (since I used an integer variable to hold it), and since it took less than a second, it was coming out 0 (I was choosing a limit of 100). So, I use a float variable to hold the time value, and so I get fractional time units when I divide.

Instead, you can simply divide by "60.0" instead of by 60, to force a floating point computation: PRINT "TIME = ";(TIME/60.0)

 

1 hour ago, markmiller said:

A couple things I noticed about float variables, too. The % is not part of the name, but you have to use it wherever that variable is used, anyway. It's not just a declaration syntax. However, it considers, for example, LI and LI% as referring to the same variable (but of different types), and doesn't like that (parser error). So, I have to name it something different (I chose "LIF%").

Yes, there is two list of names: variable names and procedure/data names, so you can have a variable with the same name as a procedure or a data but no two variables with the same name.

 

Your program can be simplified as:

INPUT "LIMIT?"; LI ' You can specify a prompt for INPUT
TIMER              ' this sets the time to 0
DIM N(LI) BYTE     ' Byte arrays are faster than integer arrays
' N(0)=0:N(1)=0	   ' This is not needed, arrays are cleared on DIM
FOR I=2 TO LI:N(I)=1:NEXT I

SL=INT(SQR(LI))    ' No need for conversions

FOR P=2 TO SL
  IF N(P)<>0
    FOR I=P*P TO LI STEP P
      N(I)=0
    NEXT I
  ENDIF
NEXT P

C=0

FOR I=2 TO LI
  IF N(I)<>0
    ?I,:C=C+1
    IF C=3:?:C=0:ENDIF
  ENDIF
NEXT I

IF C<>0 THEN ?   ' Here you can use THEN, as there is only one statement folowing the IF
? "TIME = ";(TIME/60.0);" SECONDS"

 

Have Fun!

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

dmsc, thanks for the link to that prime sieve program. I will definitely try it and study it.

 

As for your suggestions to convert that prime sieve program from Turbo-BASIC XL to FastBasic, all I can say is that you are a very good teacher. You give the student just enough to whet his appetite and give some direction, but not too much to just solve the problem for him.

 

However, not in a hundred years would I have figured out the syntax needed for the square root function. Thank you for that.

 

I had thought it would take a REPEAT/UNTIL or WHILE/WEND structures to fix those GOTO references in the original Turbo-BASIC XL program. But – duh, I can hear many of you thinking – all it took was the IF/ENDIF.
 

I also had to jigger with the timing routine at the end to try to force the final time into floating point. To make it work, I had to transfer TIME into a specifically initialized floating-point variable. It worked.

 

I specifically didn't read your instructions regarding fixing those FOR loops that had the GOTO in them. I needed to figure this out for myself. Somehow I did. Looking at what you wrote, I probably did it differently, and likely not as elegantly or efficiently.

 

But...this sieve (especially this FastBasic program) is blazing fast. It calculated all the primes up to 1000 in 3.2 seconds. Turbo-BASIC XL, no slouch compared to Atari Basic, did it in 9 seconds (via a compiled version).

 

Here's the final (well, is any program ever final?) prime sieve program converted to FastBasic. Regarding the original TBXL program, I don't remember where I found it but I didn't write it.

 

PRINT "LIMIT";:INPUT LI
TIMER
DIM N(LI)BYTE
FOR I=0 TO LI:N(I)=1:NEXT I
SL=INT(SQR(LI))
N(0)=0:N(1)=0

FOR P=2 TO SL

  IF N(P)<>0
    FOR I=P*P TO LI STEP P
    N(I)=0
    NEXT I
  ENDIF

NEXT P

C=0

FOR I=2 TO LI

  IF N(I)<>0
    PRINT I,:C=C+1
    IF C=3 THEN PRINT :C=0
  ENDIF

NEXT I

IF C THEN PRINT
ELAPSED%=TIME 
? "TIME = ";ELAPSED%/60;" SECONDS"

 

Edited by Brad Nelson
Link to comment
Share on other sites

I got your sieve to run in FastBasic. I'd be interested in knowing how you're getting the listing out of it. I saved the program, but I've been trying to export it, to no avail.

 

Excellent, Mark.  You're the man. And I know that dmsc has already answered this. But I thought I'd mention my method of opening FastBasic files.

 

First, I'm using an emulator and use the "H:" drive to setup a folder on my Windows machine as a hard drive. Then I can open the files with regular text-editing tools.

 

I use Notepad++. When you open a "listed" BASIC file (or a FastBasic file), it will present it all on one line with "›" between lines. That's not at all workable or particularly readable. I then use the search and replace menu item in Notepad++. I do a global replace of "›" with "\r\n". This will turn it into a copy-and-pastable (as well as editable) format.

 

I will often write programs in Notepad++ and then do the search-and-replace function in reverse to make it readable by whatever BASIC program you use. Obviously for Notepad++ to read BASIC programs they must be "listed" not "saved," although it seems FastBasic's native format is not tokenized and is readable by Notepad++. Be sure (at least in Notepad++) to set the encoding to "ANSI" in the Encoding menu.

 

I know this isn't a particularly efficient workflow, but it does work. Surely a macro or something could automate this process. I'm just not sure what steps to take to do that. Maybe someone has an idea.

Edited by Brad Nelson
Link to comment
Share on other sites

Instead, you can simply divide by "60.0" instead of by 60

 

That was my first thought as well, dmsc. But that gave me a parsing error. I saw that you put quotes around it as well in your version. (TIME/60.0). I still got the parsing error. Not a big deal and not worth working out. It could be an emulator thing. I don't know. That's why I put TIME into an assigned floating-point variable first. That worked.

 

By the way, what is the official 3-letter extension for FastBasic? I've been using FILENAME.FBA. What is everyone else doing? Did I miss that meeting?

Edited by Brad Nelson
Link to comment
Share on other sites

@dmsc - I'm trying to build a new version of FastBasic from sources. Everything seems to be going well, except for the mkatr part. I have mkatr compiled. Mkatr downloaded into its own directory, and I ran make on it separately. However, I'm having trouble locating it so make can find it in the fastbasic build process. Where should I locate it?

 

Thanks.

 

Edit: Answered my own question, put it in the path. It worked.

Edited by markmiller
Link to comment
Share on other sites

@dmsc - Just to add to what you said, for anyone else, the menu you're talking about is not on the FastBasic disk. I got BW-DOS separately (download the zip, decompress) https://github.com/HolgerJanz/BW-DOS. You mount the BW-DOS atr file into your emulator. Go into its DOS directory, and you'll find any missing commands you need (including MENU). Be sure to get the .COM files of the commands you want, and install them in your DOS directory. Those are the external commands that BW-DOS will execute.

 

Your manual doesn't mention this. I thought I would, in case people are wondering, but you can delete a whole line in the FastBasic editor using Shift-Delete, like in typical Atari editing. The corresponding insert-line keystroke (Shift->) doesn't do anything, but like you say, you can go to the end of a line (Ctrl-E), and hit Return.

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

you can delete a whole line in the FastBasic editor using Shift-Delete

 

That's very useful. Thanks.

 

The following is not a criticism of FastBasic. It's just an observation about the different types of BASICs. This is not a perfect world and there are always trade-offs.

 

But one thing I really miss in FastBasic is the "immediate mode" of Turbo-BASIC XL or Atari Basic. That immediate mode gives you the ability try out a command or syntax. You type something in, hit the return key, and get a result. If it works, you can then put a line number in front of it and add it to the existing program that you already have loaded. Etc. In this way you can easily work out a problem or idea in sort of the "scratch pad" of immediate mode.

 

Yes, you could simply (via an emulator) have another instance of FastBasic running with a blank editor that you can use as a scratchpad. That would allow that as well (and I've done that). But it's not nearly as convenient. This is obviously another instance of feature-creep. I really like dmsc's attitude of keeping the code nimble and tight. In this world of bloated software, where else do you hear something like this? And no doubt this is why FastBasic is fast.

 

But a what-if feature would be the ability to, say, mark a line or lines in the editor (double asterisk or apostrophe?) that you wish to RUN all by itself. For instance:

 

For X = 1 TO 100

? "FastBasic is fast! ";

NEXT X

 

**? SQR(36)

 

Result of the run is "6" printed on the screen. The other lines are temporarily ignored. Just an idea.

Link to comment
Share on other sites

6 hours ago, Brad Nelson said:

one thing I really miss in FastBasic is the "immediate mode" of Turbo-BASIC XL or Atari Basic. That immediate mode gives you the ability try out a command or syntax. You type something in, hit the return key, and get a result.

Agree. It seems many other retro Atarians like the cross-compilers, since it allows them to work with a modern system and tools to write code. I like that idea, too, but I still go for TB on the 8-bit, because I can do stuff in immediate mode. I will put up with a lot to have that. In fact, when I was working on an assembler for the stack machine I mentioned earlier, I worked hard to make it interactive like this, having the assembler work incrementally, as you entered code. I'm not finished with that project. So, I don't have anything out there for people to try, but I ended up taking two tracks with it, because TB was still too slow to do this(!) (It would take something like one to two seconds for each line to be entered, even though I've worked hard to optimize the process.) So, I'm thinking okay, I'll go the cross-compiler route, to build the interactive assembler, and for the assembler in TB, I'll make it more like the Atari Assembler, where you have an "edit mode," where you can enter and modify code, and then an "assembler mode," where you can assemble code, and run it.

 

I had the thought while I was using FB that it could be interactive, if code was compiled incrementally, as in Atari Basic and TB. I also like your idea of being able to highlight code in a listing to execute immediately, and get results back.

 

Incidentally, this is the way Squeak Smalltalk works (a dev. system you run on a modern computer). You can try out code anywhere you can type text. If you're familiar with object-oriented programming, programming in Smalltalk is nice! :)

 

Typically, you have a window called a "workspace" where you do this. You type out some code, highlight it using the mouse, or cursor keys (while pressing Shift), and then press Ctrl-D (for "DoIt"), or Ctrl-P (for "PrintIt") (which will show the value that's returned, right after your highlighted code). Very interactive.

 

Here's a short demo showing that.

 

 

In fact, there is this thing you can do with it, where if you insert calls to "self halt" strategically within a class, or classes, you can write your code incrementally, and run and test it in stages, such that you're not always starting over, every time you test. The reason for this is the thread is paused, not killed, when the runtime comes to a "self halt" call. So, you can "edit and continue," rerunning a method in cycles, editing and testing it, but not losing the state you had before you entered the method, so you can just focus on the area you're working on, not worrying about getting back to the spot you're testing, each time. I tried this out once. Interesting experience.

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

programming in Smalltalk is nice!

 

How can you argue with something whose website is squeak.org? :D

 

Typically, you have a window called a "workspace" where you do this. You type out some code, highlight it using the mouse, or cursor keys (while pressing Shift), and then press Ctrl-D (for "DoIt"), or Ctrl-P (for "PrintIt") (which will show the value that's returned, right after your highlighted code). Very interactive.

 

Mark,I watched that video and that seemed like a workable solution. Of course, mice are rare in the Atari world so I would presume (and I presume a lot...dmsc doesn't need any more work or feature-creep ideas) that you'd mark the text somehow via the keyboard. Perhaps double apostrophes would be good. An apostrophe already marks text (used singly) as non-functional (aka, a comment). Two for "run me immediately." There might be some logic there. :) Double periods could work as well and (for me) would be easier to type.

 

..lickety_split = INT (SQR(37))

For x = 1 to lickety_split

? "FastBasic is fast ";

Next x/..

 

When I first considered this, I thought asterisks might work best because they offer better visibility:

 

**lickety_split = INT (SQR(37))

For x = 1 to lickety_split

? "FastBasic is fast ";

Next x/**

 

Maybe /'' at the end of a block of text so that you don't have to have a double apostrophe at the start of every line? Easier to remove too. You might mark the start with Ctr+C (keeping with current conventions), cursor to the end of the block that you want to run, and then Option+R to run that bit. That seems a little fiddly but could work and you wouldn't have to mess about with extra characters trying to mark the lines.

 

Can't wait to see your project. You are obviously doing some deep diving into the bowels of the 6502 and Atari. Very impressive.

 

By the way, I self-halt over a cup of coffee several times a day. Makes sense that the concept would be useful for coding as well. 

Edited by Brad Nelson
Link to comment
Share on other sites

3 hours ago, Brad Nelson said:

How can you argue with something whose website is squeak.org? :D

I heard from Alan Kay recently that the name came from a project he and some other Xerox pals were working on while at Disney (think Mickey Mouse), in the late '90s. The backstory is Apple Computer had been one of the original licensees for Smalltalk-80, but they hadn't used it much (except as inspiration for their Macintosh interface. It was also available on request for Mac developers). This group convinced Apple to open source it. The group then updated it, and had the intent to use it to develop a mobile app. for use by patrons at Disney World. I don't know if it actually got deployed, but the name stuck.

 

I wasn't expecting anyone to start using a mouse in an Atari IDE. :) Though, I saw some demos from someone years ago showing off a multitasking OS with a GUI for the Atari 8-bit, in graphics mode 8, which used a mouse.

 

Really, a mouse is a trackball with the lower half rotated 180 degrees.

  • Like 1
Link to comment
Share on other sites

I'm getting the hang of procedures in FastBasic, at least a bit. I noticed (unless I missed it) that FastBasic has no Right$ function. Left$ is its counterpart, as is Mid$. This is fairly common in BASIC, at least in Microsoft Basic.

 

The Left$ function is equivalent to the built in FastBasic bracket operation which can easily enough give you the equivalent of Left$ (or Mid$) as in: A$ = B$[1,3]. That assigns three characters of B$ to A$ starting with the first position. Maybe there's a better way to do Right$. But the procedure does at least work:

 

PROC RIGHT_STR RIGHT_QTY
COUNT2 = LEN(NAME$)
RIGHT_STR$ = NAME$[COUNT2-RIGHT_QTY+1,RIGHT_QTY]
ENDPROC

INPUT "ENTER NAME: ";NAME$
INPUT "ENTER RIGHT$ AMOUNT: ";RIGHT_QTY

EXEC RIGHT_STR RIGHT_QTY
? RIGHT_STR$

It would be nice if you could pass strings as arguments. But that isn't apparently implemented yet.

Link to comment
Share on other sites

Regarding replicating the RIGHT$ command in FastBasic, I guess it could be as simple as:

 

SUBSTRING$=NAME$[(LEN(NAME$)-3)]

 

Where the "3" is one number smaller than the amount of characters you want to pull from the right. (The above would put the rightmost 4 characters into SUBSTRING$.) Of course, if you didn't want to commit that to memory, you could just implement a RIGHT$ procedure. It might be easier to avoids mistakes that way, although without the ability to pass a string as a parameter, probably the above method would be better. However, I did clean up the procedure a bit. Syntax errors can be a beast to work out, especially regarding parentheses.

 

PROC RIGHT_STR RIGHT_QTY
RIGHT_STR$ = NAME$[(LEN(NAME$)-RIGHT_QTY)+1]
ENDPROC

INPUT "ENTER NAME: ";NAME$
INPUT "ENTER RIGHT$ AMOUNT: ";RIGHT_QTY

EXEC RIGHT_STR RIGHT_QTY
? RIGHT_STR$

 

 

Really, a mouse is a trackball with the lower half rotated 180 degrees.

 

A long time ago, I used to have an Atari trackball. I think it was of some use playing Missile Command. A nice input device, well built. But it didn't get a lot of use. Back to string things...

 

Turbo-BASIC XL has pretty sparse string commands, as does Atari Basic. The bracket operation of FastBasic is really pretty nifty.

 

Both TBXL and Microsoft Basic II have an INSTR command. I wonder if I can turn that into a procedure for FastBasic. I would copy the syntax of TBXL which is a little different. Same parameters, just a different order. I'm on a string bling. Back later.

Edited by Brad Nelson
Link to comment
Share on other sites

The INSTR function returns the beginning position of a substring found inside a source string. It is case-sensitive (as well as inverse-character sensitive). In Turbo-BASIC XL, there is the UINSTR function that is not case- or inverse-sensitive. I don't offhand know how to implement that. It would be rarely-used in any case, pun sort of intended.

 

This procedure does seem to work fine in FastBasic, although I did have one anomaly but can't repeat it. You should get a "0" if the search is false, even if  your search is invalid because you choose a starting position longer than the source string. Without being able to pass strings as parameters, it's a little klunky. You'd have to manually assign your strings to "SRC$" and "FND$" beforehand. But you can assign the starting position for the search as a parameter when invoking the procedure.

 

INPUT "ENTER SOURCE STRING: ";SRC$
INPUT "ENTER SUBSTRING TO FIND: ";FND$
INPUT "STARTING SEARCH POSITION: ";POS

PROC INSTR POS
C=LEN(SRC$):D=LEN(FND$)
FOR A = POS TO C
  IF SRC$[A,D]=FND$
    LOC=A
    EXIT
  ENDIF
NEXT A
ENDPROC

EXEC INSTR POS
? LOC

 

Edited by Brad Nelson
Link to comment
Share on other sites

6 hours ago, Brad Nelson said:

Turbo-BASIC XL has pretty sparse string commands, as does Atari Basic.

This seems to be partly because of the way strings were implemented in Atari Basic and TB. They're what in Pascal were once called "packed character arrays." You can see an explanation of that here:

 

https://www.tutorialspoint.com/pascal/pascal_packed_array.htm

 

They're just seen by the language designers as byte buffers, even though they're called "strings." If anyone asked, "How do you do Left$ in Atari Basic," the answer you'd get is index from 1 to the character you want, like STR$(1,3). Though, these languages have a "shortcut" for getting Right$. If you just give Basic a single index, and it acts just like Right$: STR$(5).

DIM STR$(10):STR$="ABCDEFGHIJ"
?STR$(5)
RUN
EFGHIJ

 

You can do what MID$ does by giving the first and last character you want: STR$(5,7)

 

By the same token, the procedures you wrote for FB can do the same thing in TB. It takes management, but you can set up variables, which can act as "parameters" to PROC's in TB.

  • Like 2
Link to comment
Share on other sites

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...