14

When you power up a Commodore 64 you are greeted with a friendly message telling the user it has 38911 BASIC bytes free. 38,911 is one byte shy of a 38 KiB (1,024 * 38 = 38,912).

What was the reason for this "missing" byte?

2
  • 3
    My guess would be nul termnated ascii. Dec 13, 2018 at 21:03
  • 7
    The start is counted from $0801 rather than $0800 because at $0800 is the #$00 token of the "previous" line. It's needed for odd reasons.
    – Janka
    Dec 13, 2018 at 21:10

2 Answers 2

24

Well, it's a 'trick' to simplify the editor as well as the BASIC editor. After Reset (or NEW) three bytes of Zero are placed at the beginning of the basic RAM. They make it look to the basic interpreter as this looks like the tokenisation of a single, empty BASIC line. Consisting of

  • One byte 00 as line end marker and
  • Two bytes 00 as pointer to the next BASIC line - zero means end of program

(For more details check here)

To display the amount of free memory the startup code then uses the FRE function (*1), which in turn walks through BASIC memory ($0800..$9FFF) to see what's unused. Its logic counts the byte at $0800 as part of the current program, as it's the last byte of the line stored here (*2).

So basically a Commodore with no program holds a NULL-program :))

As weird as this seems, it saved the addition (and management) of another zero page pointer, thus simplifying the Interpreter (*3) by allowing all parts to assume that there's always a valid program loaded.


*1 - The displayed value is also corrected for values greater than 32767 which would seem negative.

*2 - Now, why the two bytes Zero aren't counted as well is weird, as they are always present as well. The whole issue can as well be seen as the usual +/-1 Error programs often show.

*3 - At least when intending to keep the advantage of not having to manage the various variable pointers (VARTAB, ARYTAB, STREND) during edit (they just get reset by RUN).

Plus the side effect to be able to reserve space between the program end and variables for additional machine code, allowing tricks to load it from tape in one turn.

6
  • 1
    Two bytes of 0 at the beginning of tokenized string are not the line number, but pointer to the next tokenized string. NULL pointer means end of program. Line number follows such pointer.
    – Anonymous
    Dec 15, 2018 at 12:27
  • 1
    You're right. It's always helpul to doublechcek instead of writing only from memory - especially when already linking to the correct description :)
    – Raffzahn
    Dec 15, 2018 at 15:32
  • I wonder why the interpreter requires that the byte before start-of-program be zero, rather than requiring that start-of-pointer point at the zero byte.
    – supercat
    Dec 15, 2018 at 23:22
  • 1
    Note that "PRINT FRE(0) + 65536" on the C-64 would return 38909 bytes free, not 38911. As far as I can recall, the startup banner didn't count the double null termination of the program area, while the FRE(0) function did.
    – throx
    Jan 11, 2019 at 5:58
  • @throx: I think the value was displayed before the null program was placed into memory, consuming two bytes.
    – supercat
    Sep 29, 2021 at 15:16
2

The begin of the basic area is set in the addresses 43/44, the default value is 01 and 08, which means a start address of $0801 = 2049. The end of the basic area is in addresses 55/56, default values are 160 and 0, meaning $A000 = 40960. 40960 minus 2049 is 38911, the value that is also reported at the startup screen.

The byte before the basic area must contain a value of 0 so that the BASIC program can be run, that is why 2048 is used for that and BASIC starts at 2049 (2047 could not be used as the zero-holder, since it is already in use as a sprite costume pointer). Entering RUN when the byte before the BASIC area is not zero results in a SYNTAX ERROR message, because the RUN command sets the current character pointer (addresses 122/123) to the start of the BASIC area minus one. The basic interpreter then sees a zero, which tells it that a new line starts here.

4
  • Why must it contain a zero? (Also, welcome to the site! Here's our tour.)
    – wizzwizz4
    Jan 12, 2019 at 16:17
  • I extended my answer with an explanantion. Thanks for the welcome btw.
    – Peter B.
    Jan 12, 2019 at 21:15
  • Why does BASIC subtract one from the address at 43/44, rather than simply storing an address that's one smaller there?
    – supercat
    Jan 12, 2019 at 21:31
  • 1
    The address vector is used a couple of times in the implementation of the BASIC interpreter, it is only one time where the value -1 is needed.
    – Peter B.
    Jan 12, 2019 at 21:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .