Rybags #26 Posted August 16, 2009 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. Quote Share this post Link to post Share on other sites
atariksi #27 Posted August 16, 2009 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. Quote Share this post Link to post Share on other sites
Rybags #28 Posted August 16, 2009 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) Quote Share this post Link to post Share on other sites
thorfdbg #29 Posted August 16, 2009 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 Quote Share this post Link to post Share on other sites
thorfdbg #30 Posted August 16, 2009 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 Quote Share this post Link to post Share on other sites
atariksi #31 Posted August 16, 2009 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? Quote Share this post Link to post Share on other sites
atariksi #32 Posted August 16, 2009 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. Quote Share this post Link to post Share on other sites
Nukey Shay #33 Posted August 16, 2009 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). Quote Share this post Link to post Share on other sites
Rybags #34 Posted August 17, 2009 (edited) 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 August 17, 2009 by Rybags Quote Share this post Link to post Share on other sites
drac030 #35 Posted August 17, 2009 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. Quote Share this post Link to post Share on other sites
atariksi #36 Posted August 17, 2009 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. Quote Share this post Link to post Share on other sites
Nukey Shay #37 Posted August 17, 2009 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" Quote Share this post Link to post Share on other sites
atariksi #38 Posted August 18, 2009 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. Quote Share this post Link to post Share on other sites
atariksi #39 Posted August 18, 2009 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. Quote Share this post Link to post Share on other sites
drac030 #40 Posted August 18, 2009 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). Quote Share this post Link to post Share on other sites
atariksi #41 Posted August 18, 2009 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. Quote Share this post Link to post Share on other sites