6

Applesoft programs start at location $0801 in memory (usually). If you put a nonzero value at address $0800, though, you get an error when you try to run the program:

?SYNTAX ERROR IN 65124

Why does this happen?

9

The Applesoft RUN command ($d912) begins by calling SETPTRS ($d665), which calls STXTPT ($d697) to initialize TXTPTR ($b8-b9) to the value in TEXTTAB ($67-68) minus one. In simple terms, parsing of the program actually starts at $0800 when the program is loaded at $0801.

When the RUN command finishes, Applesoft falls back into its command execution loop (NEWSTT $d7d2), which had just finished calling EXECUTE_STATEMENT from $d820. When it jumps back to the top of the loop, it pulls the next byte from memory and evaluates it.

Normally, at the start of the program, it will read a zero, which causes it to behave is if it had reached the end of a line, and it will start processing the line. If it doesn't see a zero, it acts like it's in the middle of processing a line, and looks for a ':'. If it doesn't see that, it reports a syntax error (jump from SYNERR_1 at $d846), because statements must be separated by a colon or line break.

Setting $0800 to $3a (':') doesn't generally work, because Applesoft will think it's mid-line, but the next things it finds in memory at $0801 are a 16-bit next-line address followed by a 16-bit line number. These are unlikely to form a valid Applesoft statement.

The syntax error message uses the contents of CURLIN ($75-76), which was partially initialized: CURLIN+1 ($76) is set to $ff in "command" mode, and RUN decrements it to $fe to indicate that we're in "run" mode. The line number reported will thus be somewhere in the range $fe00-feff (65024-65279).

See also the Applesoft disassembly.

3
  • I wonder why TXTTAB is set to point to the byte following the zero byte, rather than pointing at the zero byte itself? Does that allow other parts of the code to be simplified?
    – supercat
    Jun 21 at 18:00
  • @supercat TXTTAB points to the start of the program code, which is technically $0801, since the $00 is an end-of-line indicator, not a start-of-line indicator. This situation is an artifact of keeping the interpreter design simple: when it finishes with the RUN command it wants to find a statement separator, and relies on the coldstart code to have put one there (see $f1b0). No need to waste space for that byte on tape/disk since it's supposed to have been taken care of already. (DOS/ProDOS LOAD really ought to zero it out though.)
    – fadden
    Jun 21 at 18:56
  • Saved BASIC programs have quite a bit of redundant information, such as line links (which, on the 6502 could have been reduced to one byte if they'd specified the length of input lines. Actually, if program lines and strings had been stored in reverse order, that would have made a lot of things more efficient on the 6502, since code to iterate through a string could simply output (stringPtr),y and decrement y until it hits zero, rather than having to check each index against the string length.
    – supercat
    Jun 21 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.