Getting the Address of BASIC Variables on the VIC-20

Getting the address of a BASIC variable can be useful if you want to pass data to a machine code routine or want to access the bytes of a variable directly to improve speed and reduce garbage collection.

Getting Variable Address with BASIC

The easiest way to get the address of a variable from BASIC is by using SYS to call the EVLVAR routine at 53387 ($D08B) and placing the variable name directly after the SYS 53387 command. After calling, registers A/X will contain the address in the variable descriptor just past the two letter variable name. The address is stored as an LSB/MSB pair and we can access registers A/X through locations 780/781 in memory.

Getting Integer Address

The following program uses the EVLVAR routine at 53387 to get an address in the variable descriptor for the variable N%. D will contain the address of the 16-bit integer, stored in MSB/LSB order. This address is then used to get the integer and put it in V. The program prints the bytes of the variable descriptor and the value of the variable.

10 N%=312
20 SYS 53387N%
30 D=PEEK(780)+256*PEEK(781)
40 V=256*PEEK(D)+PEEK(D+1)

100 PRINT "VARIABLE DESCRIPTOR:"
110 FOR I=-2TO4
120 PRINT PEEK(D+I);
130 NEXT I
140 PRINT

200 PRINT "INTEGER VALUE:"
210 PRINT V

The variable descriptor for N% looks like the following. Char1 and Char2 are for the two letter variable name with 128 added to each letter to indicate that it is an integer. In the BASIC program above D points to the MSB of the integer value.

Char1
+128
Char2
+128
MSBLSB000
206128156000

Get String Address

Getting the address of a string is very similar to getting that of an integer. D will again contain an address in the variable descriptor, however it now points to the length of the string which is stored in L and is followed by an address, which is stored in P, which points to the actual string. The program prints the bytes of the variable descriptor and the string. There is a small bug that will prevent this being used with the E$ variable. It is possible to overcome this bug with other routines to handle parenthesis around it but I think that it's probably easier to just use another variable name.

10 N$="FRED"
20 SYS 53387N$
30 D=PEEK(780)+256*PEEK(781)
40 L=PEEK(D)
50 P=PEEK(D+1)+256*PEEK(D+2)

100 PRINT "VARIABLE DESCRIPTOR:"
110 FOR I=-2TO4
120 PRINT PEEK(D+I);
130 NEXT I
140 PRINT

200 PRINT "STRING VALUE:"
210 FOR I=0 TO L-1
220 PRINT CHR$(PEEK(P+I));
230 NEXT I

The variable descriptor for N$ looks like the following. Char1 and Char2 are for the two letter variable name with 128 added to Char2 to indicate that it is a string. In the BASIC program above D points to the length of the string. The string length is then followed by a pointer to the string.

Char 1
+0
Char 2
+128
LengthPointer
LSB MSB
00
781284410500

Getting Variable Address with Assembly Language

From assembly language we can call the FNDVAR routine at $D0E7 (53479). This routine expects the name of the variable to search for to be in $45/$46 (69/70) with 128 added as needed to indicate the type of the variable. The address in the variable descriptor just past the name will be returned at $47/$48 (71/72), in LSB/MSB order.

The examples uses VICMON, which we start with:

SYS 24576

Enter the following routine at $02A1 (673) to get the address of the value of variable N% and print it to screen. The routine uses the PRTFIX routine at $DDCD (56781) to print the integer value of the variable. I have added comments but ignore these if entering into VICMON.

.E1500                       ; Enable virtual zero page
.A 02A1 LDA #$CE             ; Variable letter 'N' + 128
.A 02A3 STA $45              ; Store first letter of variable
.A 02A5 LDA #$80             ; Blank variable letter + 128
.A 02A7 STA $46              ; Store second letter of variable
.A 02A9 JSR $D0E7            ; Call FNDVAR to get address
.A 02AC LDY #$01
.A 02AE LDA ($47), Y
.A 02B0 TAX                  ; Put LSB of integer in X
.A 02B1 DEY
.A 02B2 LDA ($47), Y         ; Put MSB of integer in A
.A 02B4 JSR $DDCD            ; Call PRTFIX to printer integer in A/X
.A 02B7 RTS
.X                           ; Exit VICMON and return to BASIC

Initialize the variable N% with the value 312 and call the routine we created to print the value of N%.

10 N%=312
20 SYS 673

Floating Point, Function Descriptor and Array Variables

There is probably less need to get the address of floating point, function descriptor and array variables. These are more complicated and are therefore more difficult to access. However, if their address is needed their storage is explained in detail in Mapping the Vic, pp. 308-312.

Video

The following video shows these methods for getting the address of a variable in action.

Creative Commons License
Getting the Address of BASIC Variables on the VIC-20 by Lawrence Woodman is licensed under a Creative Commons Attribution 4.0 International License.

Share This Post

Feedback/Discuss

Related Articles

Saving and Loading Memory on the VIC-20

Saving and loading memory is quite easy on the VIC-20 once you know how. However, it isn't obvious how to do this and therefore this article will present a few simple ways of doing it from BASIC and A...   Read More

Storing Machine Code in REM Statements on the VIC-20

BASIC programs often contain machine code routines but they take up quite a lot of space in BASIC. An interesting way to reduce the amount of space that they take is to store the machine code in REM s...   Read More

Adding Basic Stubs to Assembly Language on the Commodore VIC-20

To make machine language programs more friendly it's nice to add a Basic stub which contains a line with a SYS statement to start the code. This is easy to do on the VIC-20 and the process gives you a...   Read More

Basic Line Storage on the VIC-20

BASIC programs are stored in memory using a simple structure that we can investigate and manipulate. This article will show how they are stored and contains a BASIC program to go through each line of ...   Read More

Programming in Assembly with VICMON on the VIC-20

VICMON is a machine language monitor released by Commodore in 1982 and is great for programming the VIC-20. Its interactive nature means that it can often be quicker to develop via this rather than us...   Read More