GOTO

From C64-Wiki
Jump to navigationJump to search
BASIC keyword
Keyword: GOTO
Abbreviation: G Shift+O
Type: Command
Token code: 137/$89
Handling routine
in BASIC ROM:
43168–43217
$A8A0–A8D1
List of all BASIC keywords


Remark: This article describes the BASIC command GOTO in BASIC V2 of the Commodore 64.

Typ: Command
General Programming-Syntax: GOTO [<line>]

The BASIC command GOTO makes the BASIC interpreter branch to the indicated line and the execution of the BASIC program is continued at that line. In Commodore BASIC, legal line numbers are from 0 to 63999. Exceeding the upper limit leads to an ?SYNTAX ERROR. If the targeted line number doesn't exist, the BASIC error ?UNDEF'D STATEMENT ERROR occurs. A special case is the usage without a parameter which implicitly refers to line number 0.

The line number is expected to be a numeric constant consisting of digits only (possibly intermixed with spaces) until the first non-digit character. All the following characters until the end of the line are ignored and can be regarded as a comment.

GOTO can be used to construct infinite loops. The code sample 55 GOTO 55 won't terminate, but can be aborted manually by pushing RUN/STOP .

The IF-THEN construction allows the alternative usage of GOTO instead of THEN (see first example, line 31).

See also ON-GOTO construction for multiple GOTO targets selected by a numeric expression.

Technical aspects[edit | edit source]

The BASIC command GOTO can be used to start or continue a program at a specified line number like the BASIC command RUN <line>. In contrast to RUN, which clears variables and closes open files before starting the program, GOTO continues keeping the current state. While CONT just continues at the last break-point, GOTO has the advantage of allowing the program to be started at any point, for instance, just beyond code that causes an error.

After parsing the line number from the ASCII-encoded number, the system then looks for the target line using the line-lookup routine. If the target line number is higher than the current one, the system searches forward from the current line. If the target line number is lower than the current one, the system searches from program start.

It should be noted that FOR-NEXT loops do not use the line number when they branch back from the NEXT to the FOR, but instead store the address of the code and move directly and thereby avoid performing a line lookup. This means their performance is independent of program length, and should be used wherever possible.

GOTO has an alternate encoding if written as GO TO. It takes 2 tokens instead of one, which is not recommended because consumes more program space and is (slightly) slower to process. This variation cannot be used in the alternate version of IF <expression> GOTO <line>. In this case an explicit THEN is mandatory leading to IF <expression> THEN GO TO <line> otherwise a ?SYNTAX ERROR is raised.

Bugs[edit | edit source]

Line number anomaly[edit | edit source]

Effect
For a (at least 6 digit) line number starting with number in range from 35072 to 35327 (e.g. GOTO 350720) some unexpected behavior arises instead showing ?SYNTAX ERROR:
  • C64: reaches the state similar after a RUN/STOP +RESTORE 
  • VC20: Crashes after a subsequent action, showing sometimes an error beforehand.
  • C116/C16/Plus/4 BASIC 3.5: the display gets corrupted, but the cursor reappears.
  • PET with versions up to BASIC 4.0: crashes silently.
Not effected:
Cause
While parsing the line number the maximum is checked on the fly ($A97D). If the first 4 digits gives a value of hex $89xx, the comparison for a maximum against $1900 (=6400 decimal if a digit follows) will exceed and the nearby syntax error call-out is tried to be used chaining to a conditional branch located in the ON code part ($A953). It is expected that the accumulator does not contain $89 (the code for the GOTO token), but unluckily right this value from the high byte of the line number has been left in the accumulator. The branch to the syntax error code is therefore not taken and the following code of the ON command expects a different stack constellation and eventually produces an erroneous call by the later RTS.

Slow performance[edit | edit source]

Originally, the generic Microsoft 6502 BASIC code always looked for a target line by scanning through the program line from line from the first line of code. This causes the performance of GOTO to slow significantly as program length grew. In Commodore BASIC versions after the first model PETs, a small enhancement was added to search forward from the current line if the target line number was higher. Initially, this included a bug that would cause the search for the target line to start from the beginning of the program even if the target line number was higher than the current one but shared the same high byte in hexadecimal representation (see line-lookup). This bug was fixed in BASIC 3.0 as well as BASIC V2.

Examples[edit | edit source]

10 C=0: PRINT CHR$(147);: INPUT "Input a number, please "; A
20 PRINT "Input a second number, please "; 
30 INPUT B: IF C=1 AND B=0 GOTO 30
31 IF C=1 AND B<>0 GOTO 74
40 C=1: INPUT "Input an arithmetic operator (+-/*) "; A$
50 IF A$<>"+" OR A$<>"-" OR A$<>"*" OR A$<>"/" GOTO 30
60 IF B=0 AND A$="/" THEN PRINT "Division by 0 is not allowed, correction:";: GO TO 30
70 IF A$="+" THEN C=A+B: B$="ADDITION"
71 IF A$="-" THEN C=A-B: B$="SUBTRACTION"
72 IF A$="*" THEN C=A*B: B$="MULTIPLICATION"
73 IF A$="/" THEN C=A/B: B$="DIVISION"
74 PRINT "Your choice: " B$
75 PRINT "The output is: " C
80 INPUT "Another calculation (Y=YES, End with other chars)"; A$
90 IF A$="Y" THEN GOTO 10

Demonstration of direct GOTO vs. RUN:

10 INPUT A
20 PRINT A

A=7:GOTO20
7

READY.
A=7:RUN20
0

READY.

Buggy error handling:

GOTO 350720

Crashes instead showing ?SYNTAX ERROR (see Bugs section).


BASIC V2.0 (second release) Commands

ABS | AND | ASC | ATN | CHR$ | CLOSE | CLR | CMD | CONT | COS | DATA | DEF | DIM | END | EXP | FN | FOR | FRE | GET | GET# | GOSUB | GOTO | IF | INPUT | INPUT# | INT | LEFT$ | LEN | LET | LIST | LOAD | LOG | MID$ | NEW | NEXT | NOT | ON | OPEN | OR | PEEK | π | POKE | POS | PRINT | PRINT# | READ | REM | RESTORE | RETURN | RIGHT$ | RND | RUN | SAVE | SGN | SIN | SPC | SQR | STATUS/ST | STEP | STOP | STR$ | SYS | TAB | TAN | THEN | TIME/TI | TIME$/TI$ | TO | USR | VAL | VERIFY | WAIT