Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Commodore BASIC
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Performance=== Like the original [[Microsoft BASIC]] [[interpreter (programming)|interpreter]], Commodore BASIC is slower than native [[machine code]]. Test results have shown that copying 16 [[kilobytes]] from [[read-only memory|ROM]] to [[random-access memory|RAM]] takes less than a second in machine code, compared to over a minute in BASIC.{{citation needed|date=March 2018}} To execute faster than the interpreter, programmers started using various techniques to speed up execution. One was to store often-used floating point values in variables rather than using literal values, as interpreting a variable name was faster than interpreting a literal number. Since floating point is default type for all commands, it's faster to use floating point numbers as arguments, rather than integers. When speed was important, some programmers converted sections of BASIC programs to [[MOS Technology 6502|6502]] or [[MOS Technology 6510|6510]] assembly language that was loaded separately from a file or POKEd into memory from DATA statements at the end of the BASIC program, and executed from BASIC using the {{mono|SYS}} command, either from [[direct mode]] or [[BASIC loader|from the program itself]]. When the execution speed of machine language was too great, such as for a game or when waiting for user input, programmers could [[polling (computer science)|poll]] by reading selected memory locations (such as {{mono|$C6}}<ref name="map64">{{cite book|title=Mapping the Commodore 64 & 64C|last=Leemon|first=Sheldon|publisher=COMPUTE! Publications|page=37|year=1987|isbn=9780874550825|url=https://archive.org/stream/Compute_s_Mapping_the_64_and_64C#page/n49/mode/2up|access-date=2018-03-25}}</ref> for the 64, or {{mono|$D0}}<ref name="map128">{{cite book|title=Mapping the Commodore 128|url=https://archive.org/details/Compute_s_Mapping_the_Commodore_128|last=Cowper|first=Ottis R.|publisher=COMPUTE! Publications|page=[https://archive.org/details/Compute_s_Mapping_the_Commodore_128/page/n70 66]|year=1986|isbn=9780874550603}}</ref> for the 128, denoting size of the keyboard queue) to delay or halt execution. A unique feature of Commodore BASIC is the use of control codes to perform tasks such as clearing the screen or positioning the cursor within a program; these can be invoked either by issuing a {{code|2=cbmbas|1=PRINT CHR$(X)}} command where X corresponds to the control code to be issued (for example, {{code|2=cbmbas|1=PRINT CHR$(147)}} is the control code to clear the screen) or by pressing the key in question between quote marks, thus pressing {{keypress|SHIFT|CLR HOME}} following a quote mark will cause BASIC to display the visual representation of the control code (in this case, a reversed heart) which is then acted upon at program execution (directly printing out the control codes uses less memory and executes faster than invoking a {{mono|CHR$}} function). This is in comparison to other implementations of BASIC which typically have dedicated commands to clear the screen or move the cursor. BASIC 3.5 and up have proper commands for clearing the screen and moving the cursor. Program lines in Commodore BASIC do not require spaces anywhere (but the {{mono|LIST}} command will always display one between the line number and the statement), e.g., {{code|lang=cbmbas|1=100 IFA=5THENPRINT"YES":GOTO160}}, and it was common to write programs with no spacing. This feature was added to conserve memory since the tokenizer never removes any space inserted between keywords: the presence of spaces results in extra {{mono|0x20}} bytes in the tokenized program which are merely skipped during execution. Spaces between the line number and program statement are removed by the tokenizer. Program lines can be 80 characters total on most machines, but machines with 40 column text would cause the line to wrap around to the next line on the screen, and on the VIC-20, which had a 22 column display, program lines could occupy as many as four. BASIC 7.0 on the Commodore 128 increased the limit of a program line to 160 characters (four 40-column lines or two 80-column lines). By using abbreviations such as {{code|?}} instead of {{code|PRINT}}, it is possible to fit even more on a line. BASIC 7.0 displays a {{samp|?STRING TOO LONG}} error if the user enters a program line over 160 characters in length. Earlier versions do not produced an error and simply display the READY prompt two lines down if the line length is exceeded. The line number is counted in the number of characters in the program line, so a five digit line number will result in four fewer characters allowed than a one digit number. The order of execution of Commodore BASIC lines was not determined by line numbering; instead, it followed the order in which the lines were linked in memory.<ref>{{Cite web|url=http://www.unusedino.de/ec64/technical/project64/mapping_c64.html|title=Mapping The C64|website=www.unusedino.de|accessdate=21 August 2023}}</ref> Program lines were stored in memory as a [[singly linked list]] with a pointer (containing the address of the beginning of the next program line), a line number, and then the tokenized code for the line. While a program was being entered, BASIC would constantly reorder program lines in memory so that the line numbers and pointers were all in ascending order. However, after a program was entered, manually altering the line numbers and pointers with the [[PEEK and POKE|POKE]] commands could allow for out-of-order execution or even give each line the same line number. In the early days, when BASIC was used commercially, this was a [[software protection]] technique to discourage casual modification of the program. Line numbers can range from 0 to 65520 and take five bytes to store regardless of how many digits are in the line number, although execution is faster the fewer digits there are. Putting multiple statements on a line will use less memory and execute faster. {{mono|GOTO}} and {{mono|GOSUB}} statements will search downward from the current line to find a line number if a forward jump is performed, in case of a backwards jump, they will return to the start of the program to begin searching. This will slow down larger programs, so it is preferable to put commonly used subroutines near the start of a program. Variable names are only significant to 2 characters; thus the variable names {{mono|VARIABLE1}}, {{mono|VARIABLE2}}, and {{mono|VA}} all refer to the same variable. Commodore BASIC also supports the (two-byte, signed, [[twos' complement]]) bitwise operators {{--}} {{mono|NOT}}, {{mono|AND}}, and {{mono|OR}}. Although this feature was part of the core Microsoft 6502 BASIC code, it was usually omitted in other implementations such as [[Applesoft BASIC]]. The native number format of Commodore BASIC, like that of its parent [[MS BASIC]], was [[floating point]]. Most contemporary BASIC implementations used one byte for the characteristic ([[exponent]]) and three bytes for the [[significand|mantissa]]. The accuracy of a floating point number using a three-byte mantissa is only about 6.5 decimal digits, and [[round-off error]] is common. 6502 implementations of Microsoft BASIC utilized 40-bit floating point arithmetic, meaning that variables took five bytes to store (four byte mantissa and one byte for the exponent) unlike the 32-bit floating point found in BASIC-80. While 8080/Z80 implementations of [[Microsoft BASIC]] supported integer and double precision variables, 6502 implementations were floating point only. Although Commodore BASIC supports [[Signed number representations|signed integer]] variables (denoted with a percent sign) in the range −32768 to 32767, in practice they are only used for array variables and serve the function of conserving memory by limiting array elements to two bytes each (an array of 2000 elements will occupy 10,000 bytes if declared as a floating point array, but only 4000 if declared as an integer array). Denoting any variable as integer simply causes BASIC to convert it back to floating point, slowing down program execution and wasting memory as each percent sign takes one additional byte to store (since this also applies to integer arrays, the programmer should avoid using them unless very large arrays are used that would exceed available memory if stored as floating point). Also, it is not possible to {{mono|POKE}} or {{mono|PEEK}} memory locations above 32767 with address defined as a signed integer. A period (.) can be used in place of the number 0 (thus {{code|2=cbmbas|1=10 A=.}} instead of {{code|2=cbmbas|1=10 A=0}} or {{code|2=cbmbas|1=10 FOR A=. TO 100}} instead of {{code|2=cbmbas|1=10 FOR A=0 to 100}}), this will execute slightly faster. The {{mono|SYS}} statement, used to start machine language programs, was added by Commodore and was not in the original Microsoft BASIC code, which featured only the [[BASIC#USR|USR function]] for invoking machine language routines. It automatically loads the CPU's registers with the values in {{mono|$30C-$30F}} (C64, varies on other machines)--this can be used to pass data to machine language routines or as a means of calling kernal functions from BASIC (as an example, {{code|2=cbmbas|1=POKE 780,147:SYS 65490}} clears the screen). Since Commodore 8-bit machines other than the C128 cannot automatically boot disk software, the usual technique is to include a BASIC stub like {{code|lang=cbmbas|1= 10 SYS 2048}} to begin program execution. It is possible to automatically start software after loading and not require the user to type a {{mono|RUN}} statement, this is done by having a piece of code that hooks the BASIC "ready" vector at {{code|$0302}}. As with most other versions of [[Microsoft BASIC]], if an array is not declared with a {{mono|DIM}} statement, it is automatically set to ten elements (in practice 11 since array elements are counted from 0). Larger arrays must be declared or BASIC will display an error when the program is run and an array cannot be re-dimensioned in a program unless all variables are wiped via a CLR statement. Numeric arrays are automatically filled with zeros when they are created, there may be a momentary delay in program execution if a large array is dimensioned. String variables are represented by tagging the variable name with a dollar sign. Thus, the variables {{mono|AA$}}, {{mono|AA}}, and {{mono|AA%}} would each be understood as distinct. Array variables are also considered distinct from simple variables, thus {{mono|A}} and {{mono|A(1)}} do not refer to the same variable. The size of a string array merely refers to how many strings are stored in the array, not the size of each element, which is allocated dynamically. Unlike some other implementations of Microsoft BASIC, Commodore BASIC does not require string space to be reserved at the start of a program. Unlike other 8-bit machines such as the Apple II, Commodore's machines all have a built-in clock that is initialized to 0 at power on and updated with every tick of the PIA/VIA/TED/CIA timer, thus 60 times per second. It is assigned two system variables in BASIC, {{mono|TI}} and {{mono|TI$}}, which both contain the current time. TI is read-only and cannot be modified; doing so will result in a Syntax Error message. {{mono|TI$}} may be used to set the time via a six number string (an error results from using a string other than six numbers). The clock is not a very reliable method of timekeeping since it stops whenever interrupts are turned off (done by some kernal routines) and accessing the IEC (or IEEE port on the PET) port will slow the clock update by a few ticks. The {{mono|RND}} function in Commodore BASIC can use the clock to generate random numbers; this is accomplished by {{code|RND(0)}}, however it is of relatively limited use as only numbers between 0 and 255 are returned. Otherwise, {{mono|RND}} works the same as other implementations of Microsoft BASIC in that a pseudo-random sequence is used via a fixed 5-byte seed value stored at power on in memory locations {{mono|$8B-$8F}} on the C64 (the location differs on other machines). {{mono|RND}} with any number higher than 0 will generate a random number amalgamated from the value included with the {{mono|RND}} function and the seed value, which is updated by 1 each time an RND function is executed. {{mono|RND}} with a negative number goes to a point in the sequence of the current seed value specified by the number. Since true random number generation is impossible with the {{mono|RND}} statement, it is more typical on the C64 and C128 to utilize the SID chip's white noise channel for random numbers. BASIC 2.0 notoriously suffered from extremely slow garbage collection of strings. Garbage collection is automatically invoked any time a {{mono|FRE}} function is executed and if there are many string variables and arrays that have been manipulated over the course of a program, clearing them can take more than an hour under the worst conditions. It is also not possible to abort garbage collection as BASIC does not scan the RUN/STOP key while performing this routine. BASIC 4.0 introduced an improved garbage collection system with back pointers and all later implementations of Commodore BASIC also have it. The {{mono|FRE}} function in BASIC 2.0 suffered from another technical flaw in that it cannot handle signed numbers over 32768, thus if the function is invoked on a C64 (38k BASIC memory), a negative amount of free BASIC memory will be displayed (adding 65535 to the reported number will obtain the correct amount of free memory). The PET and VIC-20 never had more than 32k of total memory available to BASIC, so this limitation did not become apparent until the C64 was developed. The {{mono|FRE}} function on BASIC 3.5 and 7.0 corrected this problem and {{mono|FRE}} on BASIC 7.0 was also "split" into two functions, one to display free BASIC program text memory and the other to display free variable memory.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)