Stupid VARPTR tricks

A recent e-mail exchange with CoCo user Torsten D. inspired me to try something stupid.

The Radio Shack Color Computer gained the VARPTR command in the Extended BASIC ROM. As has been discussed here many times, VARPTR returns the memory location of a 5-byte variable descriptor. There are actually seven bytes total, since the two bytes before the VARPTR address is the two byte variable name.

0 'MAKE42-1.BAS
10 DIM A,B,C:A=42:B=VARPTR(A)
20 FOR C=B-2 TO B+4
30 PRINT C,PEEK(C):NEXT

Running this will show the full seven bytes required to represent the A variable:

VARPTR is returning 9792 as the location of the start of the 5-byte floating point value for the numeric A variable. The two bytes before it are the variable name: 65 (uppercase “A”) and 0 (no second letter). Had the variable name been “AA” that would be 65 65.

The five bytes of 134, 40, 0, 0 and 0 are the floating point representation of 42.0.

If you got the VARPTR address of one numeric variable, and of a second numeric variable, you could just copy those five bytes and clone the variable value:

0 'MAKE42-2.BAS
10 DIM A,B,I
20 A=42:B=0
30 PRINT "A =";A,"B =";B
40 FOR I=0 TO 4:POKE VARPTR(B)+I,PEEK(VARPTR(A)+I):NEXT
50 PRINT "A =";A,"B =";B

If you run this, you will see output showing “A = 42” and “B = 0”, followed by output showing “A = 42” and “B = 42”. The code in line 40 copies the five bytes (offset 0 to 4) from the VARPTR address of variable A into the VARPTR address of variable B.

But why would you want to do that?

B=A is would have been much simpler.

Here’s where it gets more stupid…

And if you can clone a variable, you could also change a variable if you knew what five bytes represented the number you wanted. In the first example, we saw that the five bytes that represent 42.0 are 134, 40, 0, 0 and 0. Knowing that, you could do something like this:

0 'MAKE42-3.BAS
10 DIM A,V
20 PRINT "A =";A
30 V=VARPTR(A):POKE V,134:POKE V+1,40: POKE V+2,0:POKE V+3,0:POKE V+4,0
40 PRINT "A =";A

The “DIM” is not really needed in this example, but it is a good habit to get into if you want to control the order your variables exist in the variable table. Variables that need to be the fastest should be at the front of the list, and variables use infrequently or ones that can be slow can be at the end.

But I digress.

The point of this stupid code is that an “A” variable is created with 0 as its default value, then VARPTR is used to see where that variable is in memory. Five POKE commands put that floating point representation of 42.0 into that variable’s storage… So when you print A, you get a value of 42, even though A=42 (or indeed, A= ANYTHING) was nowhere in the program.

I have no idea why you would want to do that.

Until next time…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.