Jump to content
José Pereira

Some Bugs in Basic

Recommended Posts

Most Basic interpretors incorporate the Floating-Point routines, so you can effectively say it's 10K for Atari Basic.

 

We also have the advantage of the OS having the plot/draw embedded within, so that's another saving.

As well as a few more little things like STICK/PADDLE, etc.

Share this post


Link to post
Share on other sites
Most Basic interpretors incorporate the Floating-Point routines, so you can effectively say it's 10K for Atari Basic.

 

We also have the advantage of the OS having the plot/draw embedded within, so that's another saving.

As well as a few more little things like STICK/PADDLE, etc.

 

Floating point is best avoided. Looks like there's integer operations going on there in BASIC but you don't have much control over them.

 

Try this (fetching LSB of a WORD):

 

10 FOR T=0 TO 65536

20 POKE 1536,ASC(CHR$(T))

30 NEXT T

 

This takes 12 minutes and 20 seconds (740 seconds) and CHR$ only takes 16-bit unsigned integer value (program gives error on last iteration).

 

Now try normal method:

 

10 FOR T=0 TO 65536

20 POKE 1536,T-INT(T/256)*256

30 NEXT T

 

This takes 26 minutes (1560 seconds)-- that's more than 2X slower. Now if there was only a way to get the MSB of a WORD in BASIC in a fast way without employing INT and DIV.

Share this post


Link to post
Share on other sites

I'd not thought of using that little trick... typing "T-INT(T/256)*256" is a pain, although you normally want the high byte so have "H=INT(T/256) : L=T-H*256".

 

Get the MSB... a USR routine could do that for us... PLA - PLA - STA $D4 - PLA - LDA #0 - STA $D5 - RTS

 

H=USR(ADR(MSB$),T)

Share this post


Link to post
Share on other sites
Most Basic interpretors incorporate the Floating-Point routines, so you can effectively say it's 10K for Atari Basic.

 

We also have the advantage of the OS having the plot/draw embedded within, so that's another saving.

As well as a few more little things like STICK/PADDLE, etc.

Indeed. Interestingly, parts of the constants used only by BASIC are part of the floating point ROM, for example the interpolation polynoms for ATN. The floating point ROM has no use for it, nor is it ever referenced in there. Just BASIC expects it. However, a couple of third-party products also makes use of the floating point ROM, e.g. Mac/65.

 

So long,

Thomas

Share this post


Link to post
Share on other sites
Floating point is best avoided. Looks like there's integer operations going on there in BASIC but you don't have much control over them.

...

This takes 26 minutes (1560 seconds)-- that's more than 2X slower. Now if there was only a way to get the MSB of a WORD in BASIC in a fast way without employing INT and DIV.

The problem is that you cannot really avoid floating point with Atari BASIC. About everything *is* floating point there - no integers around. The slowness is mostly due to the naive implementation of the floating point routines. Even in the limited ROM space as it is, one can create routines that are twice as fast, neither require additional RAM or ROM space, and are perfectly compatible to what is there.

 

TurboBasic came with its own floating point which gained most of its speed from loop-unrolling the ROM routines, but then also requiring more program space.

 

So long,

Thomas

Share this post


Link to post
Share on other sites
I'd not thought of using that little trick... typing "T-INT(T/256)*256" is a pain, although you normally want the high byte so have "H=INT(T/256) : L=T-H*256".

 

Get the MSB... a USR routine could do that for us... PLA - PLA - STA $D4 - PLA - LDA #0 - STA $D5 - RTS

 

H=USR(ADR(MSB$),T)

 

That's pretty good. So one argument passed to USR requires string assignment like A$="hhh<ctrl+.>" What if there's more than one argument-- which one gets popped off the stack first?

Share this post


Link to post
Share on other sites
The following prints 0, so it should probably do that for PRINT ASC("") to be consistent.

 

It is consistant, because a string has an actual memory location(s) of it's contents. When you DIMension a variable, a stretch of ram is picked for it to reside (as mentioned, ram which has already been zeroed during powerup). Calling a string directly in PRINT ASC("") is doing exactly the same thing. There is no string...what exists there in memory is the closing parenthesis of the line.

 

In both cases, it's reporting what value exists in memory. Not really a bug. Just an oversight. Hey, it's better than locking up the machine!

 

Bugs are also consistent but is it consistent with definition of ASC(String$)? It's better to return NULL (if there's such a char in ATASCII) or give error.

 

Actually, the CHR$() is also defined for 0..255 in most BASICs I have tried.

Share this post


Link to post
Share on other sites

Maybe it would have if R&D was given the time to finish beta testing Atari Basic? ;)

 

@atariksi

Last in, first out. The number of arguments is last (which is why USR routines called from Basic usually begin with a PLA even if no arguments are used). The 16-bit value you want returned to Basic should reside in $CB/$CC (203-4 decimal).

Share this post


Link to post
Share on other sites

Other way around, actually.

 

# of arguments is first off the stack, 8 bit unsigned. Then each 16 bit unsigned parameter in the order they were specified, high byte first.

 

$D4,$D5 contains the base address of the USR routine, and you can also use it to pass a value directly back, Basic then calls FP to convert it to BCD.

Edited by Rybags

Share this post


Link to post
Share on other sites
It's better to return NULL (if there's such a char in ATASCII)

 

There is not. And you probably mean NUL, not NULL, anyways.

Share this post


Link to post
Share on other sites
It's better to return NULL (if there's such a char in ATASCII)

 

There is not. And you probably mean NUL, not NULL, anyways.

 

Of course, some bugs are good if they work consistently like the CHR$(0..65535) vs. CHR$(0..255).

 

Just tried CHR$() range on PC, C128, Apple IIC, and few others.

 

They all give errors past 255.

Apple IIC states "Illegal Quantity..."

 

However, in ASC(A$) where it returns value in memory vs. 44 is inconsistent unless there's a memory location where this 44 is being picked out from.

Share this post


Link to post
Share on other sites

If you mean ASC(""), there is. The memory location is the address of the tokenized line itself (where the interpreter is trying to figure out the value of the empty string, but gives you the value of the parenthesis instead becase the string has no length to fetch a value from).

 

I dunno what the problem is, since you would never use ASC("") in a program anyway...regardless of Basic version or platform. Since it's not assigned to a string variable, it will always produce the same effect...whether it's a constant value of 44 in Atari Basic, or an error in other Basics. It's unnecessary program bloat to even use a character in there. Why use A=ASC("A") when you can just use A=65? If it's to make the line more understandable for somebody reading the code, that is what REM is for. A=65:REM ATASCII CODE OF LETTER "A"

Share this post


Link to post
Share on other sites
If you mean ASC(""), there is. The memory location is the address of the tokenized line itself (where the interpreter is trying to figure out the value of the empty string, but gives you the value of the parenthesis instead becase the string has no length to fetch a value from).

 

I dunno what the problem is, since you would never use ASC("") in a program anyway...regardless of Basic version or platform. Since it's not assigned to a string variable, it will always produce the same effect...whether it's a constant value of 44 in Atari Basic, or an error in other Basics. It's unnecessary program bloat to even use a character in there. Why use A=ASC("A") when you can just use A=65? If it's to make the line more understandable for somebody reading the code, that is what REM is for. A=65:REM ATASCII CODE OF LETTER "A"

 

Sure there are work arounds and it's a minor issue but the logic is:

 

(1) If Atari BASIC does NOT support ZERO length strings for ASC() function then the bug is that it does not return an error for the ZERO length strings.

(2) If Atari BASIC does support ZERO length strings for ASC() function then the bug is that setting a string like A$="" does not equate to ASC("") so that's then the bug.

Share this post


Link to post
Share on other sites
If you mean ASC(""), there is. The memory location is the address of the tokenized line itself (where the interpreter is trying to figure out the value of the empty string, but gives you the value of the parenthesis instead becase the string has no length to fetch a value from).

 

I dunno what the problem is, since you would never use ASC("") in a program anyway...regardless of Basic version or platform. Since it's not assigned to a string variable, it will always produce the same effect...whether it's a constant value of 44 in Atari Basic, or an error in other Basics. It's unnecessary program bloat to even use a character in there. Why use A=ASC("A") when you can just use A=65? If it's to make the line more understandable for somebody reading the code, that is what REM is for. A=65:REM ATASCII CODE OF LETTER "A"

 

P.S.: It's ASC("")=44 = ASC(",") not parenthesis.

Share this post


Link to post
Share on other sites
P.S.: It's ASC("")=44 = ASC(",") not parenthesis.

 

It _is_ parenthesis. You're mixing up the parenthesis _character_ ASCII value and the ASCII value of its _token_.

 

I would agree that it is a bug, and the interpreter should return a value error (as there is no concept of a null value in BASIC), but it is minor anyways. And, as it was explained above, the behaviour of ASC("") and ASC(A$) for A$="", even if not desired, is consistent.

 

CHR$(x), and many other functions, simply cut down the integer value to 8 bits, if this range is desired. That other BASIC interpreters return an error here, it doesn't itself make it a bug in Atari BASIC, it is rather a simplification, and a harmless one. There are loads of such stuff in Atari BASIC, and, for that matter, in every other interpreter (I believe).

Share this post


Link to post
Share on other sites
P.S.: It's ASC("")=44 = ASC(",") not parenthesis.

 

It _is_ parenthesis. You're mixing up the parenthesis _character_ ASCII value and the ASCII value of its _token_.

 

I would agree that it is a bug, and the interpreter should return a value error (as there is no concept of a null value in BASIC), but it is minor anyways. And, as it was explained above, the behaviour of ASC("") and ASC(A$) for A$="", even if not desired, is consistent.

 

CHR$(x), and many other functions, simply cut down the integer value to 8 bits, if this range is desired. That other BASIC interpreters return an error here, it doesn't itself make it a bug in Atari BASIC, it is rather a simplification, and a harmless one. There are loads of such stuff in Atari BASIC, and, for that matter, in every other interpreter (I believe).

 

Yeah, the CHR$() is a useful bug-- perhaps the other BASICs should have employed it as well. So far neither C128 Basic nor QuickBasic nor Apple IIC basic allow extended range.

Share this post


Link to post
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.

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