Manipulating the Screen (Part 2)

Part 2 (Finally)
Last time I talked about this, I discussed the usage of AND OR and how they are used to manipulate individual bits in the VIC II registers.  I also talked about location 53576 and how is it used to select which 16K bank of memory the VIC II chip is looking at for display information.

Now we are going to take a look at location 53272.  This is a very important register for all graphics operations.  It does two main things.

  1. Tells the VIC II chip where to look for its character set information.
  2. Tells the VIC II Chip where to look for the screen matrix is located.

Boot up your 64 (or emulator) and peek into 53272:        

So let’s unpack this information.  The byte in 53272 is broken down like this:

  • bit 0 – unused
  • bits 1-3: Character Location
  • bits 4-7: Video Screen Base Location

Character Set:

To figure out the actual address of the character information, you want to filter bits 1-3.  As we talked about previously we use AND in the peek statement. Bits 1-3 add up to 14 (2+4+8).  So we PRINT PEEK(53272)AND14.  

The VIC II Chips can see character information in 2K block increments, but addressing is done in 1K increments.  So we take that number (4) and multiply it by 1024 to get 4096, the default location for character information.  Because bit 0 is unused we skip every other 1K block for addressing. You will always POKE or PEEK an even number into this register if you are using filters.  You will always get an odd number if you just do a PEEK with no logic functions.  Bit 0 is always 1 when peeking into this address.

  • Remember that this number is offset by which 16K bank of memory the VIC II chip is looking at.  The default is bank 0 so the VIC II chip is looking at addresses starting at 0.  In part 1, we changed the VIC II to bank 2 which starts at location 32768.  In that case, we would add 4096 to 32768 to come up with 36864.  As I mentioned in that other article.  The C64 also has character information at that address so changing to bank 2 didn’t effect the look of the characters.

Video Screen Location:

Now we can take a look at the screen location information.  Bits 4-7 is the upper nybble of the byte. To get the screen information from it, do a PRINT (PEEK(53272)AND240)/16.  What are we doing here?  First, we’re looking into memory location 53272 and filtering it so we only see bit 4-7. The AND 240 is binary 11110000.  This will only let information from the top 4 bit through.  Then we are dividing 16 from it.  The reason for that is the computer is treating it as a lone 4 bit number instead of the top 4 bits of an 8 bit number.  We are removing the bottom 4 bits and shifting the top 4 over. Think of it as shifting the bits 4 times to the right. Each time you do, you are dividing by 2.

The number we end up with is 1.  The VIC II chip looks at Video memory in 1 kilobyte chunks.  This allows it  to see the entire 16K bank available to it.  We multiply the result by 1024 to get the memory location relative to the start of the bank.  Since the video bank is defaulted to 0 and 53272 points to 1, we multiply 1 * 1024 and then add 0 for the bank location.  This gives up our default screen location of 1024.

Try This!  

To demonstrate this concept of the video just looking at any memory in the computer, type in the following program:

Be sure to set the character set to lower case letters:

Now type the following line:


Again, let’s unpack this command.  First, we want to pull the information out of 53272 and filter out everything except bits 1-3.  Those bits we don’t want to change.  We do this with AND14. Next we decided we want to set the video screen at locations starting at 2048.  We know that that the VIC II chip looks at video memory in 1k chunks, so 2048/1024 = 2.   We then have to shift that number (2) into the proper bit location of 53272’s byte.  We do that by multiplying the number 2 by 16. Imagine shifting the bits 4 times to the left.  Each time you do that, you are essentially multiplying the number by 2, so, 2*2*2*2=16.  You include that into your poke by using OR(2*16) function. Location 2048 in the Commodore 64 is the start of program memory.


Once you hit enter, you will see the program you typed above as it is stored in the C64’s memory. There is no cursor or READY. showing because the OS still thinks the screen is located at 1024. If you were to type 40 END (you won’t be able to see what you type) and hit enter, you would see the basic token added to the end of the section of code on the screen.

Type RUN. The program will run fine regardless of the fact that it is displayed on the screen. Hitting any key should bring you back to the normal screen.  If not, a RUN STOP/RESTORE will.

One Last Thing.

Since we are still using the lower case characters right now (if not, go ahead and put the computer in lower case mode).  Check to see where the computer is looking for its character information. Like before, type PRINT PEEK(53272)AND14. You should get a 6. Before when we were all caps, the result was 4. So switching to lower case simply tells the computer to look at a different memory location for its character set.  In this case, 6144 (6*1024). You may have noticed that this address and the address for the all caps character set (4096) are right in the middle of Basic RAM. How this works is that Basic RAM and Character ROM share the same addresses, the VIC II is only looking at the ROM and the OS is only looking at the RAM.  The reverse is true in upper memory where Basic and Kernal are located.


So, with a single memory/register location we are able to move where the C64 looks for its character set and display location within the 16K range that the VIC II chip can see.  Combine that with 56576 (from part 1), you can place the screen and character information anywhere within the C64’s full 64K of RAM.  You will be limited by certain parameters, like where the built-in character ROM of the C64 is located can not be over-written.  Placing the information where Basic and the Kernal is located is possible in machine language, but problematic if you are still planning to use Basic or the Kernal.  Zero page is busy with doing the work of the machine, so also not a good location.

Finally, when moving these parameters around, be aware that when locating the screen within what the computer normally uses at program memory, there is a good possibility of variables encroaching into the block of memory you are using for character / screen information.  Setting the basic pointers where variable are stored would be necessary to prevent your new character / screen from getting overwritten by program variables.

We have these basics covered. Next time we’ll talk about making smooth scrolling work.





Leave a Reply

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