8

I'm just creating my own .prg file using NCurses Hexeditor in Ubuntu which I load using load"file.prg",8 in Vice. I followed the information in this link explaining how to create a .prg file. It says basic starts at 2048 ($0800) but loads the .prg code starting at $0801:

Memory Locations Value
$0801–$0802 2-byte pointer to the next line of BASIC code ($080C).
$0803–$0804 2-byte line number ($000A = 10).
$0805 Byte code for the SYS command.
$0806–$080A The rest of the line, which is just the string " 2064".
$080B Null byte, terminating the line.
$080C–$080D 2-byte pointer to the next line of BASIC code ($0000 = end of program).

Is there any reason for this? I tried it at $0800 and all works fine (see below). I guess it wouldn't matter because the Assembly code starts at 2064 ($0810), but just thought I might be missing something as to why they chose $0801 and not $0800.

What I tried

First of all, according to the C64 Programmer's Reference Guide (C64PRM, p.59):

Programs will LOAD starting at memory location 2048 unless a secondary <address> of 1 is used. If you use the secondary address of 1 this will cause the program to LOAD to the memory location from which it was saved.

Tests show that no matter what PRG header I use my bytes are always loaded into 2048 when using ,8 as per C64PRM. But let's just suppose I use a header for $0800, then I have the following bytes in Hexeditor:

00000000  00 08 0B 08  0A 00 9E 20   32 30 36 34  00 00 00 00   ....... 2064....
00000010  00 EE 20 D0  4C 10 08                                 .. .L..

and I don't get an error, e.g.:

enter image description here

3
  • I think that if you look at the monitor after loading your program you will see that it is actually loaded at $0801.
    – Brian H
    Dec 27, 2020 at 16:09
  • @BrianH yes the monitor seems to show everything stored at $0801 and the next BASIC instruction pointer is automatically incremented. Strange, but there it is.
    – user16295
    Dec 27, 2020 at 19:32
  • FWIW, I looked at the reason for $0800 vs. $0801 in Applesoft, which is also a Microsoft BASIC; see retrocomputing.stackexchange.com/a/20180/56
    – fadden
    Aug 13, 2021 at 15:47

2 Answers 2

10

It is not strictly true that "all works fine" for machine-language programs with a standard BASIC header starting at $0800 vice $0801. The idea of the BASIC header is that your program is easily loaded and then started using the RUN command:

LOAD"MYPROG",8 REM NOTE ABSENCE OF ",1"
RUN

If you move the header one-byte down to $0800, then BASIC no longer parses it correctly. Your line number will be messed up, and RUNing your program will likely return ?SYNTAX ERROR. It is true that your actual machine code is unaffected and you could still start it with the appropriate SYS command manually entered. But the desire is for it to work by just using the standard LOAD & RUN. Screen shot below shows this for a quick & dirty test program I created to load at $0800. The list of the program should read as:

2020 SYS 4864

Looking at the disassembly of Commodore BASIC v2, this assumption of the actual first line being at $0801 is probably related to the fact that the RUN command is a special case of the GOTO command. Because of this, I think the first byte is skipped just to simplify the coding of the interpreter.

Demonstration in VICE of the above, resulting in an error message: ?SYNTAX  ERROR IN 58376

5
  • Thanks @BrianH I'm a little uncertain as the C64 Programmers Reference Manual says that programs will LOAD into 2048 unless the secondary address ,8,1 is used. And if I change my PRG header to anything I like, it always loads into 2048 when I use ,8 and I don't get the corrupt line number or crash you show above.
    – user16295
    Dec 27, 2020 at 9:18
  • No it does not load to $0800 (2048) if the secondary address is not given, it loads to $0801 (2049), always.
    – Retrograde
    Dec 27, 2020 at 19:06
  • @Retrograde yes, the monitor seems show everything stored at $0801 and the next BASIC instruction pointer is automatically incremented. Strange, but there it is.
    – user16295
    Dec 27, 2020 at 19:32
  • 3
    It seems the C64 Programmers Reference Manual is wrong in saying that programs will LOAD to 2048. Many other publications describes it correctly (with load start at $0801 or 2049). There is some confusion about the start of the BASIC program area which is actually $0800, but on the first location a 0 is needed because the RUN command starts with the BASIC text pointer pointing to the last read character. This 0 byte provides an end-of-line condition, which let the interpreter search for the next line (an implicit GOTO 0) and advance to $801 as the first line to interpret. Jan 20, 2021 at 19:35
  • @JohannKlasek Thanks. That explanation makes sense with what I was also seeing in the BASIC interpreter source code.
    – Brian H
    Jan 21, 2021 at 0:01
3

When you do a LOAD"MYPROG",8 on C64, the computer will relocate the program to start at $0801 -- ignoring the load address from the file header.

If you do a LOAD"MYPROG",8,1 it will load the program to the load address specified in the file header.

If you load your test program to $0800 using the ,8,1 option, my expectation is that it won't be linked correctly by the BASIC interpreter and will not run.

You must log in to answer this question.