Manipulating the Screen (VIC-II Chip)


Last time we talked about the memory map we’ve put together for the Lunar Lander game.  Before we start manipulating the memory map, I want to give a little primer for the use of AND and OR.  I will be using those two expressions a lot while putting the game together and it was something I struggled with as a kid.

All of the Commodore 64 functions are controlled by changing information in memory locations.  Sometimes, memory locations have multiple functions.  If you only need to change one thing and the memory location controls 2 or more, you should use AND/OR in your statements.

Using them always confused me.  If I typed PRINT 223 AND 111, the result would be 79.  Where did the 79 come from?

When dealing with AND and OR, you need to understand that the computer is seeing these numbers in binary.  Once you see and understand how it evaluates these statements, making changes to memory locations using them will make a lot more sense.

A Look At The Binary

A memory location can store an 8-bit number.  In decimal, that number is 0 to 255.  Converted to binary, that number is 00000000 to 11111111.  The right-most number is binary is the 0 bit and the left most is the 7th bit.  Thus, 00000001 in binary is equal to 1 in decimal and 10000000 in binary is equal to 128 in decimal.  You can convert binary to decimal by adding the values of all 8 bits together.  The value of each bit is 2 to the power of the bit.  This 10000000 = 2 to the power of 7 (2^7) or 128.  So for the number 223, you would add up each digit’s value; 11011111 = (2^7)+(2^6)+(2^4)+(2^3)+(2^2)+(2^1)+(2^0) = 128+64+16+8+4+2+1 = 223.


If you take a look at the number in the image to the right, you can see the binary numbers stacked above each other.  Go from top to bottom and perform the AND function.  Is it true in both 223 and 111 the 7th bit = 1?  Since it is not true, the result in the 7th bit of the answer equals 0.  Do that for each bit and you get the result pictured right.  Convert that number back to decimal and you get 79.  Easy, right?


Looking at the same numbers and the OR statement.  Looking from top to bottom, if either bit has a 1 in it, the resulting  bit in the answer = 1.  So going through all the bits, you end up with 11111111, or 255 in decimal.

Why Is This Important?

So why the lesson in binary and logic functions?  Well, as I said earlier, it becomes important when dealing with memory locations that do multiple things like the control register for the VIC-II chip.  It will also become really important when dealing with the Commodore 64 bitmap screen.

Changing the screen location is pretty easy once you understand what needs to be done.  There are four major things you need to tell the computer when you want to change where the screen is in memory:

  1. You need to tell the VIC-II chip which 16K block of memory it should use for video memory.
  2. You need to tell the VIC-II chip the starting location within the 16K block of memory where the screen is located.
  3. You need to tell the VIC-II chip where it can find character definition information see that the screen is legible.
  4. You need to tell the Operating System where the screen is located so it can read and write info to the screen.

To start, type in the short program below (or download the .d64).  It will identify where the screen, and,characters are located, and what bank the VIC-II chip is looking at.



Go ahead and run the program, your result should look like this image to the right.  This is the default setup for the C64.  The VIC-II chip is set to bank 0 which is the first 16K of memory.  The screen memory starts at 1024.  The character definitions start at 4096 and the OS knows the screen is at 1024.

Looking at the program, you can see that there are four memory locations that hold that information.  Once we examine what each one does, you should be able to move your screen around to where you like.

56576 (bits 1 and 0)

Most of what memory location 56576 deals with are the communication ports of the serial bus, RS-232 device and user port.  Bits 1 and 0, however, are used to determine which section of memory the VIC-II chip is going to be looking at.  There are four possible options:

  • xxxxxx11, Bank 0, Memory 0 – 16383.
  • xxxxxx10, Bank 1, Memory 16384 – 32767
  • xxxxxx01, Bank 2, Memory 32768 – 49151
  • xxxxxx00, Bank 3, Memory 49152 – 65535

The BASIC statement to change the VIC-II chip to use bank 2 would be:

POKE 56576,(PEEK(56576)AND252)OR1

So we start by PEEKing into the memory location and seeing what is in there.  We execute an AND statement followed by an OR statement and POKE that number back into the memory location.  The image on the right shows what is happening.  (normally a PEEK into 56576 will return the decimal number 151)  The number 252 is binary 11111100.  It is allowing bits 2 through 7 to pass through to the result while zeroing out bits 1 and 0.  The OR statement that follows turns bit 0 on.  The result of 149 is what is then POKEd back into memory.  

Go ahead and try the statement out.  Your screen should look something like this:

It looks like the computer has locked up, but it hasn’t.  What has happened is that the VIC-II chip is looking at a different part of memory for image data.  It is currently looking in the upper part of BASIC ram.  On startup, the C64 fills free memory with zeros and 255s in an alternating pattern.  You are seeing that pattern on the screen.  The screen is a section of memory that is currently 33792 to 34791.  If you carefully type POKE33792,65 and hit RETURN, a spade character will show up in the upper left corner of the screen.  

So how did we know the screen started at 33792?  The only thing we changed was which bank the VIC-II chip was able to see.  We have not manipulated any other memory locations yet.  Pointers are in relation to where the VIC-II bank starts.  In the default settings, the screen is located at 1024 and the bank starts at 0.  (see Making the Plan for VIC-II map) When we changed the VIC-II bank to 2, the bank starting address changed to 32768.  The screen moves relative to the start of the VIC-II addressing so 32768+1024=33792.

Now What?

Having a different view of the screen while not being able to see what you’re typing is not very helpful.  We need to tell the C64 operating system where this new screen location is.  We do that by changing the value in memory location 648.  Type in the following command carefully:

POKE648,132 and hit RETURN.

screenshot-from-2016-11-13-22-35-55READY. should pop up somewhere on the screen.  Clear the screen like normal and everything should look and react normally.  Run the program again and you should come up with different numbers for VIC-II bank, screen location, etc.  The computer is now using a section of upper RAM as it’s screen space.  Figuring out what to poke into 648 is simple.  We know the current screen space on the VIC-II chip is 33792.  Simply divide that number by 256 to get the number needed to poke into 648.  33792/256=132.

A couple of things to know.

First thing you should know is that the character data is stored in both VIC-II banks 0 and 2.  Had we gone to bank 1 or 3, you would not have any readable text on the screen because the VIC-II chip has no character reference information.  That’s not a big deal beacause copying the stock character data is easy, and you can also create your own font and program it into RAM.  That will be covered in a future article.

The other thing to know is that we’ve only talked about changing what bank the VIC-II chip is using to look at the screen.  We still have options to change where the screen and character data is relative to the starting address.  There is also the option to go into HI-RES mode as well.  Most of this is controlled by the memory location 53272.  We’ll talk about that soon as well.

Finally, if you are moving the screen around and still plan to program in BASIC, you need to let the OS know that the memory is no longer free so it won’t accidentally start writing variable data onto your screen or custom character data.


Leave a Reply

Your email address will not be published. Required fields are marked *