Posted By
JamesD on 2017-12-05 21:14:22
| Re: Does the Plus/4 support some form of VARPTR() command?
On other versions of Microsoft BASIC you can do this... I have adapted if for the Plus/4 but i don't know if the variable descriptor is the same format as other machines. The address of the variable is assumed to be in little endian format.
0 ML$="012345678901234567890123456789012345678901234567890123456789" 10 'Never put any other line ahead of that line 20 'define other variables here 30 V=VARPTR(ML$ : ;Get address of the ML$ variable descriptor 40 Z=PEEK(V+1)+256*PEEK(V+2) : 'Get address of ML$ contents 50 FOR I=0 TO 39 60 READ D:POKE Z+I,D : 'Overwrite bytes of string with machine code 70 NEXT I 80 POKE1281,PEEK(V+1):POKE1282,PEEK(V+2) : 'Point USR() to address of ML$ using variable descriptor data 90 ' Note that PEEK(V) would give us the length of ML$
100 ' rest of program goes here 110 ' to call machine language subroutine just call USR() function
10000 DATA machine language program bytes go here
In other versions of Microsoft BASIC, ML$ actually points to where the string is stored in line 0 until you modify it. So as long as you don't use any string functions to modify it, it is located at a fixed address. This lets you assemble some code to execute at that address. Your code is limited by the maximum line length, but it's very handy for a small function.
The real advantage here, is that once you run the program, you can delete the code that reads the data and the lines with the data statements, then save the program and it will contain your USR function on load. If you list the program, BASIC barfs out garbage for the first line (which you should never edit), but it does no harm.
I used this in high school to embed a reverse screen scroll in an application I wrote. The program let the user scroll up and down through data and it made BASIC look almost like it was written in machine code without compiling it.
Here I wanted to embed a patch to make basic only use RAM that doesn't have to be paged in and out as well as the routines used to access it so it would run much faster. It would be handy for smaller programs.
*edit* I can probably do the same thing by directly loading the binary from a file into the address the string is at, but I'll have to use a debugger to find the address it resides at. And yes, SYS would work here. The machines I'm used to require using USR(). But I'd have to hard code the address in this case.
FWIW, on CPUs that support relocatable code, the string doesn't have to always reside at the very start of the program.
*edit* The string resides at $0CCF.
|