How does memory address 36869 (character set) work?

Basic and Machine Language

Moderator: Moderators

Post Reply
The Geek on Skates
Vic 20 Drifter
Posts: 33
Joined: Fri Jul 12, 2019 6:11 am
Website: http://www.geekonskates.com
Occupation: Code Monkey

How does memory address 36869 (character set) work?

Post by The Geek on Skates »

Hi everyone, hope you all had a great weekend (Thanksgiving weekend here in the States)! :)

I have this BASIC program that works great when VICE is set up like an unexpanded VIC, but not under other configurations. I learned it following a tutorial, but the tutorial doesn't really explain it as well as I'd like. I've been all over the net and some old books, but haven't found a clear explanation of exactly how this works. Here's the program:

Code: Select all

0 rem tells the VIC to use 7168 as the start of the character set
10 poke 36869, 255

11 rem and the rest is redefining my characters!
12 rem first, the smiley-face from the 8-bit guy's Commodore History video
20 poke 7168, 126
30 poke 7169, 129
40 poke 7170, 165
50 poke 7171, 129
60 poke 7172, 165
70 poke 7173, 153
80 poke 7174, 129
90 poke 7175, 126

100 rem next, a skate (my profile icon on most forums lol)
110 poke 7176, 192
120 poke 7177, 192
130 poke 7178, 224
140 poke 7179, 254
150 poke 7180, 255
160 poke 7181, 255
170 poke 7182, 195
180 poke 7183, 126
When I run this, my @s are now smileys and my A's are now skates. I didn't define any other characters or copy any others over from ROM, so I get why the others are basically "garbage" (though I do plan to look up the memory addresses in ROM and do that if I ever build a real game in C - that's a simple for-loop and not really related to my questions).

Okay, so my first question is, what is the logic behind line 10? How does POKE'ing 255 into that address give it 7168 (not 255 or some multiple of 255)? I know if I put 240 or 242 in there it gives me the standard character sets (defined in ROM), but these numbers seem to be totally random/arbitrary. I'm sure it has to do with how the computer is wired under the hood, but from a programming perspective it makes less sense than trying to build a web app in BASIC. :D

My second question is, where does the character RAM start if I do the same thing with the full 32K? If I run the program, I see moving the cursor around makes it a blinking smiley-face (lol) in some locations, so I'm guessing it's still somewhere in the 7100-8100-ish range, but haven't been able to pinpoint exactly where that could be. This could be related to the first question - if there is some formula involved in transforming 255 into 7168, then it's possible that maybe that same formula could be applied to other RAM layouts as well... or is there? It's all still Greek to me lol
Vic20-Ian
Vic 20 Scientist
Posts: 1218
Joined: Sun Aug 24, 2008 1:58 pm

Re: How does memory address 36869 (character set) work?

Post by Vic20-Ian »

https://commodore.bombjack.org/vic-20/books-vic.htm

Download Compute's Programming the Vic and look at Page 578 and 579.

There are also several threads on this in the forum.

Best regards,
Ian
Vic20-Ian

The best things in life are Vic-20

Upgrade all new gadgets and mobiles to 3583 Bytes Free today! Ready
User avatar
chysn
Vic 20 Scientist
Posts: 1204
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: How does memory address 36869 (character set) work?

Post by chysn »

The VIC chip register at 36869 has two functions. The high nybble (bits 4-7) are part of the screen memory location. The character memory is determined by bits 0-3. The location of character memory is independent of whether your VIC-20 is expanded or not. But it seems related in this case because you're setting the whole byte, when you really want to set only bits 0-3.

Bits 0-3 are the high four bits of a 14-bit address mapped to 32768 ($8000). We can walk though the math later, if you care to. But the bottom line is that there are only two good options for the bit 2/3 combination, 00xx and 11xx. 01xx and 10xx both point to memory that the system can't use, or that it makes no sense to use. So:

00xx: Start character memory at 32768 ($8000)
11xx: Start character memory at 4096 ($1000)

Then add 1024 ($400) bytes times whatever xx is.

So, if your character memory register is 15 (binary 1111), that's 4096 plus (3 x $400), or 7168 ($1c00). That's where you're putting your custom characters in your program. Now, in line 10, you want to leave the high four bits alone, so as not to move screen memory:

Code: Select all

10 POKE 36869, (PEEK(36869) AND 240) OR 15
That modifies the character memory register without modifying the start of screen memory, so you don't need to worry about whether memory is expanded or not. Hope that helps. If I haven't been clear about something, feel free to follow up and I or somebody who knows more can add more info.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
The Geek on Skates
Vic 20 Drifter
Posts: 33
Joined: Fri Jul 12, 2019 6:11 am
Website: http://www.geekonskates.com
Occupation: Code Monkey

Re: How does memory address 36869 (character set) work?

Post by The Geek on Skates »

Wow, thanks for the quick replies! I feel like I've just been handed the last piece of a puzzle I've been working on for months, which was lying wrapped up under the Christmas tree! This is a huge, huge help! Heck, just learning that I had to use 36869 took forever, so I was NOT expecting such a complete solution to even exist!

@chysn: I've never heard of a 14-bit memory address before, so that was a bit odd (no pun intended lol), but I think your code speaks for itself. I'm used to bitwise math, so I know what the AND and OR do and all that. That definitely explains why it worked in one scenario but not the other - kind of like that other register that uses 4 bits for sound volume and 4 bits for the auxiliary color in multi-color mode (I was used to just doing POKE <that address>, 15 and ran into a similar problem there lol).

@Vic20-Ian: Thanks for the great reference book! With a couple more POKEs I didn't know about (648 and 36866 - in fact, the exact code is shown in the instructions on page 579, in case others are interested) I was able to get my BASIC program working like it was before. I also feel like now I have a better idea of how this info is set up in memory. I have a feeling I'll be coming back to this book again very soon (it looks super-useful and totally awesome)!

PS: love your signature ("the best things in life are VIC-20" etc.)! Very cool. :)

Thanks again! You rock! :)
User avatar
chysn
Vic 20 Scientist
Posts: 1204
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: How does memory address 36869 (character set) work?

Post by chysn »

The Geek on Skates wrote: Sun Nov 29, 2020 8:36 pm @chysn: I've never heard of a 14-bit memory address before, so that was a bit odd (no pun intended lol), but I think your code speaks for itself.
Yeah, it sounds like you get how the byte is split up. It's worth understanding a little bit about the addressing because there's a cool corollary. You certainly know that you can address 65536 bytes with 16 bits. Chop two bits off, and you can address 16384 bytes. The VIC chip has 14 address lines, so it sees part of the VIC-20's memory as a contiguous 16K. It actually sees $8000-$9fff, and $0000-$1fff although, as I mentioned earlier, the $9000-$9fff and $0000-$0fff ranges aren't usable.

Now, in ROM, the unreversed uppercase characters are from $8000-$83ff, and the reversed uppercase characters are from $8400-$87ff. Reverse mode (bit 7 set) always shifts the character memory up by 1K.

When you have characters at $1c00, like you do, something useful happens. That's the topmost kilobyte of the VIC chip's addressing space. So when reverse mode is on, the VIC chip's address wraps back to its $0000, or the 6502's $8000. This happens to be the unreversed uppercase ROM! It allows you to use your own custom characters in combination with regular characters, using reverse mode.

To illustrate this idea, try this on an unexpanded VIC:

Code: Select all

FOR I=7168 TO 7679:POKE I, RND(0)*255:NEXT I
POKE 36869,255
Now you'll see random junk for every character. But now, turn on RVS mode with CTRL-9 and start typing. You're seeing the consequences of the VIC chip wrapping back to what it thinks is $0000.
User avatar
srowe
Vic 20 Scientist
Posts: 1432
Joined: Mon Jun 16, 2014 3:19 pm

Re: How does memory address 36869 (character set) work?

Post by srowe »

I created this table as a reminder of how to set both the screen address and the character set
CombinedMemMap.png
The VIC address space spans the first and last 8K of the CPU address space, which makes it confusing.

[Edit:] It's not the last 8K, it starts at $8000.
Post Reply