Jump to content

Read the screen address from VERA


TomXP411
 Share

Recommended Posts

  • Super Administrators

This snippet will let you query VERA to get the address of the text screen. M1 will contain the bank number and M2 is the first character of the screen:

10 M1=(PEEK($9F35)AND 128)/128 : M2=(PEEK($9F35)AND 127)*512
30 PRINT "BANK:";M1
40 PRINT"ADDR: $";HEX$(M2)

This program reads L1_MAPBASE at $9F35 and splits the value apart to get the bank and the top 7 bits of the address. We have to do some math to get there, because L1_MAPBASE actually contains the top 8 bits of a 17 bit address. 

So the first thing to do is split off the top bit. This bit's value is 128 or $80. So we use AND 128 to get just that one bit, then divide it by 128 to get the bank number. 

Next, we need the bottom 7 bits. The value of those combined bits is 127, so we can use an AND mask to read those. And since the VERA tile map always starts on a 512 byte boundary, we can just multiply that by 512 to get the correct starting address. 

This should return Bank 1 ADDR $B000 on the emulator version 41. On R38 or older, this should return BANK 0 ADDR $0. 

To use this address, you can use VPOKE with M1 for the bank and M2 for the address:

VPOKE M1, M2, 66 VPOKE M1, M2+1, 1

Should put a  symbol in the top left corner of the screen and set the color for that cell to white on black.

 

  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...

What Kernal APIs are there for asking it what the current settings are and for moving the screen elsewhere in VRAM? I know there's the SCREEN command, but what if I wanted to move mapbase somewhere else for whatever reason? Also, does the Kernal support map sizes other than 128x64?

The layer used is actually inconsequential - one of my programs just so happened to switch layers as part of its init, and was completely unaffected by the update to R39+ because it just copies L1 settings into L0 and then proceeds to use its own settings for L1 - the Kernal doesn't even know that the text is now L0 instead of L1.

Link to comment
Share on other sites

  • Super Administrators
On 7/12/2022 at 7:31 AM, ZeroByte said:

What Kernal APIs are there for asking it what the current settings are and for moving the screen elsewhere in VRAM? I know there's the SCREEN command, but what if I wanted to move mapbase somewhere else for whatever reason? Also, does the Kernal support map sizes other than 128x64?

The layer used is actually inconsequential - one of my programs just so happened to switch layers as part of its init, and was completely unaffected by the update to R39+ because it just copies L1 settings into L0 and then proceeds to use its own settings for L1 - the Kernal doesn't even know that the text is now L0 instead of L1.

That sounds like a @Michael Steil question. My understanding is that there are no prefab KERNAL functions for doing this, that the KERNAL just sets the values and uses those hardcoded settings. So if you were to change the map base to something else, the KERNAL would still try to use $1B000. As you discovered, when you moved Layer 1, an the KERNAL just kept dumping data into the same address.

 

Link to comment
Share on other sites

On 7/12/2022 at 1:06 PM, TomXP411 said:

As you discovered, when you moved Layer 1, an the KERNAL just kept dumping data into the same address.

Well, in my case, this was intentional. It was just a bonus perk that the way my program copied the layer configs made it impervious to the actual VRAM location also, as the only place it does any writing into VRAM is in the newly-defined region for layer1's map_base.
Of course, had that area been the new home of layer 0 after a "breaking change" like this, then it would've gotten me. 😉

 

Link to comment
Share on other sites

On 7/12/2022 at 10:31 AM, ZeroByte said:

What Kernal APIs are there for asking it what the current settings are and for moving the screen elsewhere in VRAM? I know there's the SCREEN command, but what if I wanted to move mapbase somewhere else for whatever reason? Also, does the Kernal support map sizes other than 128x64?

The layer used is actually inconsequential - one of my programs just so happened to switch layers as part of its init, and was completely unaffected by the update to R39+ because it just copies L1 settings into L0 and then proceeds to use its own settings for L1 - the Kernal doesn't even know that the text is now L0 instead of L1.

I'm pretty sure there isn't a kernel API for the map base, you just have to write to $9F2E for layer 0 or $9F35 for layer 1.  Same for reading the configuration, you just have to read the values at the VERA registers. The map height and width can be any of combination of 32, 64, 128, or 256 tiles.  The width/height of tiles can be 8 or 16 pixels.  All this info is in the VERA programmer's reference https://github.com/commanderx16/x16-docs/blob/master/VERA Programmer's Reference.md

Link to comment
Share on other sites

I understand how to check/set VERA's configuration. What I'm interested in is the Kernal.

Is there a way to say "Hey, Kernal, the screen is now at VRAM $1:0000" ?

It would be nice to be able to continue to use Kernal routines even in tile mode or whatever to just plop a row of tiles down, or clear the tilemap area instead of having to write your own routines to do so.

Link to comment
Share on other sites

  • Super Administrators
On 7/12/2022 at 7:20 PM, ZeroByte said:

Is there a way to say "Hey, Kernal, the screen is now at VRAM $1:0000" ?

No. The screen address is hardcoded to $1b000 in io.inc, and the screen_set_char and screen_get_char routines set the address using this hardcoded value. Also, there is no published method in the Programmer's Reference, which means that even if there is a routine that simply returns the screen_addr constant, it's not in a fixed location that will remain static from one KERNAL revision to the next. 

What would you expect a routine like this to do? Would it just decode the address by shifting it left 9 bits, then return that as a 3 byte address? Maybe it could write the address to a pointer specified by .Y and .X... 

Link to comment
Share on other sites

Honestly, the thing I was most interested in was the ability to set the Kernal to use any arbitrary location in VRAM as "the screen" but there are definitely advantages to having it hard-coded vs a lookup from a permanent home in memory of some flavor (RAM, ZP (ick), or Bank0)

So C64 was the same way with VIC-II?

Link to comment
Share on other sites

No on the c64 you could move the screen around in memory (with some limitations). There is a kernal variable that you could poke to tell the kernal the new address for the text screen as well.  only the color attributes were at a fixed address

Link to comment
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
Reply to this topic...

×   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.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use