Jump to content
  • 0
Snickers11001001

Probably a dumb question (VARTAB)

Question

Posted (edited)

I'm doing a little playing around with a simple hacky little assembly routine I would be calling from BASIC, and it just occurred to me that it would be nice if my routine could directly interact with (well, at least read) the value of an integer type variable that gets set by BASIC before calling the routine.   I'll initialize that variable as the very first one used in the BASIC program, which means it would be directly after the triple-zed that marks the end of the BASIC program in memory.      

Consequently, I need to know VARTAB (pointer for the start of variables in BASIC)  so I can calculate the memory locations for the bytes holding the value.   

I see 'basic.sym' included with the official emulator r38 release which tells me an address for VARTAB, but unless I'm mistaken that particular .sym file is the result of compiling this particular ROM version build.  Glancing at the current repo of the rom source it seems clear VARTAB could (perhaps would?) change between builds and in the official version shipped with the release hardware.    Even once the hardware is actually in circulation, if there's a facility for reflashing the ROM with updates or fixes or whatever, that could mean one probably shouldn't rely on this address as set in stone.   

For now, I'm just going to hard-code in the current address for VARTAB as I go about experimenting with this, but if I wind up using this routine I'd be really reluctant to release the program with a hard-coded VARTAB that would break the program if the address for VARTAB changes in a future rom release.  

Now, I suppose  I can write a loop that runs through memory values from start of BASIC and stops when it finds three consecutive zeros and calculates VARTAB as the next byte after the triplet,  but ... is there an easier way?    Also, come to think of it...   has there been any indication that things like VARTAB or other 'important BASIC addresses/pointers'  that come up a lot in more advanced BASIC work would be normalized/standardized so they don't change once the final ROM is put to bed, even in the event of little ROM updates or whatever? 

cheers, Snick.

 

Edited by Snickers11001001

Share this post


Link to post
Share on other sites

15 answers to this question

Recommended Posts

  • 0

Don’t forget that you can redefine the BASIC memory size on the fly as well so it’s probably even less reliable than just the location of VARTAB.

BASIC sets A,X, and Y from certain well-known addresses when you call SYS, so there’s that. You could POKE your value into a known address, or you could do something like 8bit Show And Tell recently did a video on where you can pass arguments like a command line parser. (Not sure if that’s only feasible for interactive mode though)

Share this post


Link to post
Share on other sites
  • 0

Now you mention it, I wasn't sure whether the same 4 poke addresses that set X,Y,A and the status register for the C64 'SYS' command were carried over into the X16.   That's cool if they were.     

The 8 bit Show and Tell approach was what I originally wanted to do.    As you know, it works by having your machine language routine basically hijack some stuff from the BASIC parser internals to grab its own parameters from the crunched program listing in memory starting right after the SYS command.    But its a bad fit for the x16 (well, right now it is), because it also requires using "known location"  routines/addresses from the BASIC ROM  (things that got published about the C64 and other Commodore machines' ROMS, like  "check if next character is a comma and if so skip it,'" and "read a parameter, a comma, and another parameter and stick them [places/registers]").   Alas, these are also among the things that are not guaranteed to stay at the same place in the X16 as the ROM evolves.     One more reason to look forward to the official release!

Cheers!

 

Share this post


Link to post
Share on other sites
  • 0

There's also the 16 pseudo-registers (r0 - r15) located in zeropage ($02 - $21) that you can use to pass data to and from assembly, I suppose.

 

Share this post


Link to post
Share on other sites
  • 0
On 7/17/2021 at 7:17 AM, Snickers11001001 said:

I'm doing a little playing around with a simple hacky little assembly routine I would be calling from BASIC, and it just occurred to me that it would be nice if my routine could directly interact with (well, at least read) the value of an integer type variable that gets set by BASIC before calling the routine.   I'll initialize that variable as the very first one used in the BASIC program, which means it would be directly after the triple-zed that marks the end of the BASIC program in memory.      

Consequently, I need to know VARTAB (pointer for the start of variables in BASIC)  so I can calculate the memory locations for the bytes holding the value.   

I see 'basic.sym' included with the official emulator r38 release which tells me an address for VARTAB, but unless I'm mistaken that particular .sym file is the result of compiling this particular ROM version build.  Glancing at the current repo of the rom source it seems clear VARTAB could (perhaps would?) change between builds and in the official version shipped with the release hardware.    Even once the hardware is actually in circulation, if there's a facility for reflashing the ROM with updates or fixes or whatever, that could mean one probably shouldn't rely on this address as set in stone.   

For now, I'm just going to hard-code in the current address for VARTAB as I go about experimenting with this, but if I wind up using this routine I'd be really reluctant to release the program with a hard-coded VARTAB that would break the program if the address for VARTAB changes in a future rom release.  

Now, I suppose  I can write a loop that runs through memory values from start of BASIC and stops when it finds three consecutive zeros and calculates VARTAB as the next byte after the triplet,  but ... is there an easier way?    Also, come to think of it...   has there been any indication that things like VARTAB or other 'important BASIC addresses/pointers'  that come up a lot in more advanced BASIC work would be normalized/standardized so they don't change once the final ROM is put to bed, even in the event of little ROM updates or whatever? 

cheers, Snick.

 

There are no guarantees, but VARTAB seems to be at $03E2 both in R38 and the upcoming R39.

I would expect low RAM usage to be quite stable. "Non-public" KERNAL functions in ROM I expect to move around quite a lot between versions.

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, desertfish said:

There's also the 16 pseudo-registers (r0 - r15) located in zeropage ($02 - $21) that you can use to pass data to and from assembly, I suppose.

 

Interesting.   I remember writing off $02 to $21 for 'BASIC' purposes early in my X16 adventures after first downloading the emulator and playing around with it.    I think it was when I was reading the Ref. Guide about the new kernal APIs (which if memory serves has a bunch of those labeled as 'scratch' space) where I decided the use of addresses treated as word registers by a bunch of new APIs might not be anything to be POKEing at from BASIC; especially with all the space to play with starting at page 4 of the memory anyway.    

 

Share this post


Link to post
Share on other sites
  • 0
2 hours ago, Stefan said:

There are no guarantees, but VARTAB seems to be at $03E2 both in R38 and the upcoming R39.

I would expect low RAM usage to be quite stable. "Non-public" KERNAL functions in ROM I expect to move around quite a lot between versions.

Gosh, I have a build of R39 that someone linked to for me and I didn't even check that.   Thanks!

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)
Quote

There's also the 16 pseudo-registers (r0 - r15) located in zeropage ($02 - $21) that you can use to pass data to and from assembly, I suppose.

 

Quote

 

Interesting.   I remember writing off $02 to $21 for 'BASIC' purposes early in my X16 adventures after first downloading the emulator and playing around with it.    I think it was when I was reading the Ref. Guide about the new kernal APIs (which if memory serves has a bunch of those labeled as 'scratch' space) where I decided the use of addresses treated as word registers by a bunch of new APIs might not be anything to be POKEing at from BASIC; especially with all the space to play with starting at page 4 of the memory anyway.    

 

@desertfish:     As a follow up to the above exchange....   I investigated those pseudo registers at $02 to $021.   They are indeed utilized by BASIC commands.    Which means the following line in the Ref. Guide is probably a little misleading:  "The following zero page locations are completely unused by KERNAL/BASIC/FPLIB and are available to the user:   Addresses  $0002-$007F"   

I believe that probably what it SHOULD say is that the addresses from $0022 to $007F are unused.    Almost certainly a typo, i.e., putting $02 instead of $22 as the first number in that range.  

More info:   You can write a quick BASIC program to just print-peek the contents of $02 to $21 to the screen, then do stuff like change the 'SCREEN' mode; or print or reset the TI$ variable; or do bitmap graphics commands like 'PSET' or 'LINE' or 'CHAR' and watch the contents of those zero page values at $02 to $21 change.   This makes sense, they're the parameter, return and scratch for a bunch of those new rom APIs, and obviously many of the BASIC extensions and other rom routines will make EXTENSIVE use of them. 

Now, it appears to me that they're only 'used' by BASIC  when some routine needs them for their intended purpose as pseudo registers; i.e., to pass or return values to/from the APIs or serve as scratch pads.   That means  (at least so far as I can tell) that they absolutely CAN be used to pass values to a user machine code routine , IF (and ONLY) you do the pokes to put the parameters in those zero-page slots RIGHT before your BASIC program executes the SYS command, and THEN read any results your machine code puts there immediately after control returns to BASIC from the SYS call.   But those locations can't be used to hold values on a read/modify/write basis (i.e., don't use them in a complicated BASIC program to simple 'hold' sprite positions or, a buffer of notes to be played in a sound routine, or as important pointers or other values that need to be used periodically throughout the runtime, because if your program does something else that invokes one of the new APIs that rely on those addresses as registers the contents will be thrashed.

In my testing, I've also displayed the contents of $22 through $7F and they are indeed left unmolested by any BASIC activities I could come up with.  

SO...   if anyone knows who is running project management for the X16, maybe have them look at this post (or put the docs person in contact with me) so we can get that line of the Reference Guide fixed. 

Cheers, Snick. 

 

Edited by Snickers11001001
  • Like 1

Share this post


Link to post
Share on other sites
  • 0

Let's be evil and make BASIC support pointer passing by naming a variable &V, &V$, &V%  🙈🙉🙊

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, ZeroByte said:

Let's be evil and make BASIC support pointer passing by naming a variable &V, &V$, &V%  🙈🙉🙊

Or at least add a POINTER function (I'm assuming it hasn't already been added). That would be useful to BASIC programmers.

Share this post


Link to post
Share on other sites
  • 0
2 hours ago, Scott Robison said:

Or at least add a POINTER function (I'm assuming it hasn't already been added). That would be useful to BASIC programmers.

As long as we're wishing, how about being able to define functions that take more than one parameter?

Share this post


Link to post
Share on other sites
  • 0
1 hour ago, Ed Minchau said:

As long as we're wishing, how about being able to define functions that take more than one parameter?

That would be nice, but I think it would be significantly more complicated than a function that simply returns the address of a variable without extending the syntax. But I've never dug too deep into the implementation details of the interpreter, really just enough to write my basic preprocessor to depend on the line crunch code.

Share this post


Link to post
Share on other sites
  • 0
On 7/18/2021 at 9:17 AM, Snickers11001001 said:

Gosh, I have a build of R39 that someone linked to for me and I didn't even check that.   Thanks!

There’s actually a text file in the emulator directory that shows all of the ROM variables. They are the SYM files: BASIC.SYM, KERNAL.SYM, and so on. I’ve been contemplating writing a simple script to pull those into a project template and update my template and projects automatically when that gets updated. 

Anyway, address $3E2 is VARTAB in R38. I haven’t looked at in R39, but you should be able to always find it in the BASIC.SYM file…

Share this post


Link to post
Share on other sites
  • 0
16 hours ago, TomXP411 said:

There’s actually a text file in the emulator directory that shows all of the ROM variables. They are the SYM files: BASIC.SYM, KERNAL.SYM, and so on. I’ve been contemplating writing a simple script to pull those into a project template and update my template and projects automatically when that gets updated. 

Anyway, address $3E2 is VARTAB in R38. I haven’t looked at in R39, but you should be able to always find it in the BASIC.SYM file…

Thanks!    I realized I'm an idiot and what I want to do might be something that can be accomplished by the all-too-frequently neglected 'USR()' command in BASIC. 

We will see!   Cheers, Snick 

Share this post


Link to post
Share on other sites
  • 0

OK, ...  the following is a BASIC routine to ascertain the location where VARIABLE memory starts (i.e., the value kept in 'VARTAB') from within a BASIC program.   This avoids the need to rely on the actual [but potentially-not-guaranteed-to-continue-to-live-there]  'VARTAB' address utilized in any particular pre-release ROM build.   As noted, I'm doing this because I want a ML routine I'm working on (and which will be called repeatedly from within a BASIC program) to grab its parameters straight out of the first couple of integer variables and this is how I'm accomplishing that for now.      

Ascertain start of variables address from within BASIC:
	 
	Listing A: (sanity/error checks included) 
	 
	1 A=$801:FOR L=0TO1:C=C+1:A=PEEK(A)+256*PEEK(A+1):IF A<$801 OR A>$9EFF THEN4
	2 L=PEEK(A)+PEEK(A+1)+PEEK(A-1)=0:IF L THEN IF PEEK(A-2)=0 OR PEEK(A-3)=0 THEN4
	3 L=ABS(L):NEXT:IF PEEK(A+2) THENIF((A-$801)/C)<256 THENPRINT "VARTAB =";A+2:END
	4 PRINT"ERROR.":END
	 
	Listing  B: (big-boy pants version w/ no error checking - make darn SURE start of BASIC is correct!) 
	 
	1 A=$801:FORL=0TO1:A=PEEK(A)+256*PEEK(A+1):L=ABS(PEEK(A)+PEEK(A+1)+PEEK(A-1)=0)
	2 NEXT:PRINT "VARTAB =";A+2:END

What it does:     'A' is set to the known start of BASIC.   The routine then walks along the BASIC program line-link pointers until it gets to the program terminator.   At that point, it knows what 'VARTAB' is.   When you've found the end of the BASIC program in memory, you also know where scalar variable space begins, i.e., the value known as 'VARTAB'.   

This approach depends on following all of the BASIC program line-links, so it is essential that it starts from the correct address for the start of BASIC (which is also the first line-link).   Since any 2 bytes in a row taken together refer to a location in the 16 bit address space, the wrong starting point would have it jumping all over in memory until it happened upon a series of 3 zeros in a row.    Keeping that in mind, the 'Version A' listing contains several evaluations to accomplish some validity/sanity/error checking.  I cannot guaranty it to be foolproof; however, I did a lot of testing and whenever Version A was pointed to some random  (incorrect) starting address, whether in the middle of a program listing (or variable space, or array land, or zero page, or even the stings heap), it would fairly reliably figure that out and raise an error via line 4. 

Of course, if you use this in your program, it seems reasonable to assume that YOU will know without any question whether or not you've moved the start of BASIC from the standard $0801 location, so I've also included Version B which is materially faster but makes no attempt whatsoever at error/sanity checking.    In my experience, although moving the end of BASIC down to make room up above for sprite data or something was common on Commodore machines; it was really rare to see a C64 or other program moving the start of BASIC upwards.   So there really shouldn't be a problem here.     

Ultimately, I think both versions are actually fast enough for most purposes.   Version A walks the line-links of a 1000 line program in about 5 seconds.   Version B walks the links of a 1000 line program in just a hair under 3 seconds.  

So there you go.   For what it's worth, this is just my attempt at  something of a stop-gap.   Once the X16 is officially in 'final' release, I would hope the BASIC address used by ROM to store VARTAB will be fairly stable and perhaps the devs could even ensure it won't change with ROM revisions     

Cheers!

Edited by Snickers11001001

Share this post


Link to post
Share on other sites
  • 0

Your code should work.

I made a simple test to enter a two line BASIC program, and then deleting the last line, and then another test to insert a new line in the middle of a program. I could not find a situation where the VARTAB pointer in $03e2 is not moved to the first address after the end of the program.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use