Memory (BASIC)

From C64-Wiki
Jump to navigationJump to search

This article is about the using memory in BASIC of a C64.

General[edit | edit source]

The usable BASIC memory area starts normally at $0801 (2049) and ends at $A000 (40960). This area is used by BASIC programs and the declared variables, strings and arrays by a running BASIC program.

BASIC-MEM eng.png
TXTTAB - BASIC program start
Zeropage pointer: 43/44 (decimal), $2B/$2C (hexadecimal)
normal values: $01 / $08
VARTAB - start address normal variables
Pointer: 45/46 (decimal), $2D/$2E (hexadecimal)
ARYTAB - start address indexed variables (arrays)
Pointer: 47/48 (decimal), $2F/$30 (hexadecimal)
STREND - end address(+1) indexed variables
Pointer: 49/50 (decimal), $31/$32 (hexadecimal)
FRETOP - (lower) end for strings
Pointer: 51/52 (decimal), $33/$34 (hexadecimal)
MEMSIZ - (upper) start strings / end of BASIC-RAM
Pointer: 55/56 (decimal), $37/$38 (hexadecimal)
normal values: $00 / $A0

Leading Zero Byte[edit | edit source]

A byte value of 0 must be stored here. Otherwise the BASIC program refuses to run.

By default, it is at $0800, 2048.

BASIC Program Code[edit | edit source]

The lines of the BASIC program are stored here. Each line begins with a memory address pointer to the beginning of the next line, followed by the line number in 16-bit little-endian format. Each line is terminated by a null character (CHR$(0)). The end of the program consists of a two nulls. BASIC commands are tokenized, the rest of each line is PETSCII-coded.

By default, starts from $0801, 2049 but start address can be set at $002B, 43:

LO=address AND 255:HI=INT(address/256)

Area grows each time you enter a line of code. A LOAD command also fills this area.

This is the part of the BASIC RAM that will be written on disk or tape when issuing a SAVE command.

Note that if you plan to free up some memory with raising the BASIC RAM start address then:

  • You should issue a NEW command before starting to enter lines of code to rearrange all pointers.
  • A BASIC program cannot redo this within its own code while running.
  • SAVE will save your program from the start address.
  • LOAD with 3rd parameter other than 0 (i.e. LOAD"PROGRAM",8,1) will load to the location from where it was saved and so, before running, the same start address has to be set again (either by POKE commands like above or some tricky machine-coded ways).
  • LOAD with no 3rd parameter (i.e. LOAD"PROGRAM",8) will load to the default BASIC RAM and so, the memory that was free for use before saving may become reserved for the code this time.

Variable Values[edit | edit source]

Variable area start address is set automatically one byte after the end of program code each time a program is LOADed or a line of code entered.

You can read the start address from $002D, 45:


Start address of this area is the first byte that will not be SAVEd.

CLR will release this area, and variable values stored here cannot be used after that. RUN also starts with releasing variable (and array) values. After releasing, variable usage will even overwrite contents of this area.

Array Memory[edit | edit source]

Array area start and end address is automatically set while a BASIC program is running. Grows each time a DIM instruction is interpreted.

You can query its start address from $002F, 47:


And the end address from $0031, 49:


This area will not be SAVEd.

CLR will release this area, and array values stored here cannot be used after that. RUN also starts with releasing (variable and) array values.

String Variables[edit | edit source]

String variable area start address is automatically set while a BASIC program is running. Grows downwards from the top of BASIC RAM.

You can query its start address from $0033, 51:


End address equals to BASIC RAM end address.

This area will not be SAVEd.

This is a garbage collected heap.

End of BASIC RAM[edit | edit source]

This is the absolute limit for the BASIC program code when entering lines or LOADing a BASIC program. However, the LOADed or entered code, together with the variable values, the array memory and the strings must fit between the BASIC Program code start address and this address to RUN the program.

The address itself is not included in the range: the last byte allowed to be used for BASIC purposes is one byte before this address.

Default value is $A000, 40960, which, counting from the default BASIC program code start address, $0800, 2048, gives the 38911 bytes well known from the C64 startup screen.

You can set the BASIC RAM end address at $0037, 55:

10 POKE55,0:POKE56,52:CLR:REM now memory from 13312 is free and safe to POKE

Note that the above snippet must appear in the first few lines of your BASIC code where you did not yet use any variables. CLR command is to set string variable start address, etc. properly and automatically, but also clears variable values if there were any.

Pros and Cons of Straying from the Default Path

If you fill up the BASIC RAM with lines of code, you get ?OUT OF MEMORY ERROR. Same error occurs if you almost reach the end of BASIC RAM and try to run the program: the BASIC RAM is shared between variable values, arrays and the program code – variables need some more RAM while running. This typically happens if you set the BASIC RAM end address lower than the default.

Still, if you want the character set to be redefined or more than four different sprite shapes, you need to free up some of the low 16k of the memory (because VIC pointers cannot point to higher addresses). The above way is the easiest to do so while still having a reasonable space for your BASIC program. It also allows for additional machine code space between 13312 and 40959.