Jump to content
  • 0
Alfa

Access to the character screen memory

Question

I have been looking through the programmer's reference and the VERA reference, and can not find information accessing the memory behind the various character modes.   Everything seems to address the graphics modes.  The memory map does not show it, so I assume its located in VRAM.  Can someone point me in the right direction.  Ideally I would like to read values currently on the screen in character mode.  I apologize in advance if this in indeed in the documentation, and I just missed it. Thank you.

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

It's a bit hard to see at first, but the VERA doc does have it all documented. At boot, layer 1 is in text mode and layer 0 is not being used. So, you can peek at the layer 1 registers to see where the screen map and character set are, which thinking like tiles, are just a tile map and a tile set. So, if you do a PEEK($9F35) you will see the upper 8 bits of the 17-bit VRAM address of the beginning of the tile map, which by default is 0. There are no other bits for this address in the VERA I/O registers, which means that the tilemap has to be placed on 9-bit boundaries. So, by shifting 0 left by 9 bits, we still get zero, so we know that by doing a VPOKE 0,0,X will place the PETSCII character with the index value of X in the upper left corner. You can then set the background and foreground color of this character by pokeing the next VRAM address, $00001. Since it's by default white (1) on dark blue (6), we know the current value at that location is $61. Unless, of course, you haven't scrolled the startup logo past the top of the screen. At startup or reset, there is a magenta PETSCII triangle graphic character on a blue background, so at startup a VPEEK(0,1) will return $64 (or decimal 100) as magenta is color index 4.

Things change a bit if you switch to 256-color text mode by doing a POKE $9F34,$68. Then the odd VRAM addresses in the tile map contain 8-bit color indices from the complete 256-color palette, and the background color is always black. If you wanted other backgrounds with 256 color PETSCII, then you need to start setting up layer 0 with a bitmap, tiles, or more text, and set the backgrounds of different areas of the screen to be whatever color you want, even on a pixel-by-pixel basis.

I hope this isn't too much information, but I would recommend going through the VERA doc more carefully and trying out the different registers and seeing how they let you set up how VRAM is used and then start creating whatever you want on the screen.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

I'm not sure if you're asking to read the tilemap data (which would specify which characters to display, and with what colors), or whether you're asking to read the tile data itself (which would specify what the characters look like). So I'll answer both.

Reading tilemap data (which characters and their colors):

The tilemap data is described in the VERA documentation at the following link: https://github.com/commanderx16/x16-docs/blob/master/VERA Programmer's Reference.md#tile-mode-1-bpp-16-color-text-mode

The starting address of tilemap data is stored in the layer's MAPBASE register ($9F2E for layer 0, $9F35 for layer 1), and contains the upper 8 bits of the 17-bit address. The lower 9 bits must be 0 and are not stored anywhere. The height and width of the tilemap are stored in the CONFIG register for the layer ($9F2D for layer 0, $9F34 for layer 1), each as two bits selecting a map size of 32, 64, 128, or 256 tiles. Per the documentation, each tile/character in the map is described by two consecutive bytes, the first being which tile/character to display and the second being color data.

If you launch the X16 emulator, you can see how this works for the default console. The default console uses Layer 1, so let's inspect those registers:

`PRINT PEEK($9F35)` gives us 0. This means the tilemap starts in VRAM at address $00000.

`PRINT PEEK($9F34)` gives us 96. Converting to binary, this gives us %01100000, which means a map height of %01 (1, or 64 tiles) and a map width of %10 (2, or 128 tiles).

From this, we know that the characters and colors start at VRAM address $00000, and each line of characters 256 bytes (128 tiles). Finally, we know that there are 64 lines, so we can multiply all this out (2*128*64) to see that the tilemap data is 16KB, starting from VRAM address $00000 and going through $03FFFF.

`PRINT VPEEK(0, $0000)` gives us 95, which is the character at the top-left corner of the "X" logo (this logo is just PETSCII art, so it's just a text character). Let's suppose we wanted to swap it with another character. If we `VPOKE0, $0000, 3` we see that it swaps to a 'C'. If we wanted to change the next character, we could `VPOKE0, $0002,3` to change the next character to a 'C', as well.

Since the default console is 128 tiles wide, we know it's 256 bytes wide. This is convenient, it means that if we wanted to also the change the character beneath what we just VPOKE'd, we can add $0100 to the address. `VPOKE0,$0102,3` will change the character.

Another way to look at this is to think of some tilemap coordinate <X, Y>, where X is how many tiles from the left, and Y is how many tiles from the top, both starting at 0 for the left-most column and top row, respectively. Any character at <X, Y> is located at 2*X + 256*Y, and its color is located at 1 + 2*X + 256*Y. If the default console moved its starting location at some point in the future, you'd have to add that starting location, but for now it's $00000 so we can just forget about it. 😛

Now, to make sense of the tilemap when reading, you need a map that tells you which tile IDs map to which characters. It turns out, the X16 is using the same map as the default Commodore 64 did, and that's well known. They're called screen codes: http://c64os.com/post/c64screencodes

Reading tile/glyph data (what each character looks like):

The glyph data for character modes work the same way as tile image data for the other tilemap modes: The layer's TILEBASE register ($9F2F for Layer 0 and $9F36 for Layer 1) contains the upper 6 bits of the 17-bit address (and the lower 11 bits must be 0 and are not stored anywhere). The data there will be 1bpp, with a height and width determined by the Tile Height and Tile Width bits at the same registers (0 for 8 pixels, 1 for 16 pixels).

We can observe this with the default console when you launch the X16 emulator. It uses layer 1. Let's start by looking at the registers:

`PRINT PEEK($9F36)` gives us 124. In binary, this is %01111100, which gives us a tile height of %0 (8 pixels), a tile width of %0 (8 pixels), and a tile address of %011111 00000000000 (keeping in mind that we had to add 11 bits of 0 to what was stored there), or $0F800. So we know that tile data starts at $0F800.

We know that the X16 uses the same tiles, in the same order, as the Commodore 64, so we can look up where, for example, X should be: At tile 24 (the first tile being 0). Since the tiles are 1bpp, 8 pixels wide, and 8 pixels tall, we can multiply this out and know that each tile is 8 bytes. Tile 24, then, starts at $0F800 + 8*24, or $0F8C0. Let's take a look with a little basic:

FORI=0TO7:PRINT VPEEK(0,$F8C0+I):NEXTI gives us:

102
102
60
24
60
102
102

In binary, this looks like:
%01100110
%01100110
%00111100
%00011000
%00111100
%01100110
%01100110

That looks like an X to me.

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

Thank you both for your very detailed answers. You’re right, I wasn’t thinking of the tile map as a character screen.  It makes sense, now that I see it.   Again thank you for your patience. 

  • Like 3

Share this post


Link to post
Share on other sites
  • 0

@StephenHorn I don't think you should use a character that's reflected on both the left and right sides. People won't know if the VERA stores the left-most pixel in the LSB or MSB, since the "X" in the PETSCII font is stored the same way in memory regardless of which order.

The VERA Programmer's Reference doesn't mention this, but I'd want it to be mentioned (particularly for people who screwed up and accidentally reversed the bits in their graphics).

Share this post


Link to post
Share on other sites
  • 0
On 8/15/2020 at 11:20 PM, StinkerB06 said:

@StephenHorn I don't think you should use a character that's reflected on both the left and right sides. People won't know if the VERA stores the left-most pixel in the LSB or MSB, since the "X" in the PETSCII font is stored the same way in memory regardless of which order.

The VERA Programmer's Reference doesn't mention this, but I'd want it to be mentioned (particularly for people who screwed up and accidentally reversed the bits in their graphics).

I think that's a fair point. I wanted to pick something that had an easy-to-identify bit pattern, because I can't easily do things like recolor text in the webpage input. Will try harder. 😛

If we wanted to expand on this, to the letter '6', we can see that should be at tile 54, which should be at VRAM address $0F800 + 8*54, or $0F9B0.

FORI=0TO7:PRINT VPEEK(0,$F9B0+I):NEXTI gives us:

60
102
96
124
102
102
60

And in binary, thats:

%00111100
%01100110
%01100000
%01111100
%01100110
%01100110
%00111100

Which looks like a '6'. With some finagling with the colors, the '6' is easier to see.

%00111100
%01100110
%01100000
%01111100
%01100110
%01100110
%00111100

 

Further, you can see that the bit pattern puts the left-most pixel in the most significant bit ($80, or 128).

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