[ess_grid alias=”membergrid”]

This section will introduce you to some tips to learn when writing your Commodore 64 assembly language programs. It is the goal of this website to help your succeed in your field and accomplish great things in life.


Assembly language allows you to speak directly to the CPU of your 8-bit computer. In return this allows for extremely fast processing of instructions to perform tasks at a lightning speed!

C64 Binary Bits

At the lowest level (binary) the Commodore 64 computer works with individual bits to accomplish tasks in memory. The following screenshots below depict how screen memory looks when plotting a character in the upper left hand corner with POKE 1024, 33.

The next sequence then breaks down a character into larger digits (known as bytes) and extracts the character form the ASCII (“Pet ASCII”) character set to display it properly.

Finally the last section discusses how bits look at the lowest level in binary. A binary is considered off when a “0” (zero) is seen and on when a “1” is resident in a memory location.  Bits can be used in masking by turning off active bits in a number and using ORA to turn on specific bit. The masking  is utilized by the AND instruction and will not affect other bits not being turned off. The ORA instruction also while turning on specific bits will not affect other bits that have been turned off already.

Bytes count from 0-255 are are made up of 8 bits (0’s and 1’s). These are also known as bit rows (ranging from 0-7). When all bits are combined together they create something called a byte.

C64 Scrolling Bits

The example below is a program that scrolls the screen. It is accomplished by shifting bits (pixels) on the screen a frame at a time. This is managed most effectively by setting the loop inside a raster routine. The raster controls the timing and allows for a smooth motion.

The values and #%00010111 uses a binary value that is used to mask out bits and the ora #%011111000 is used to set the individual bits in a byte. In this example the values are being loaded and stored into 53265 ($d011). The full program is below. Although this is an advanced topic, paying attention to what the bits are doing should hopefully start connecting the dots more to see how the values are being shifted in memory.

Therefore, the example code below is used to scroll the screen in a vertical (upward) direction. It works by turning off bits 3-6 and then turns on active bits at the yscroll position. We will explore this in later tutorials, but for now be sure to examine the code samples to study how the bits work.

A pixel can be shifted in any direction (up, down, left or right). Since there are 8 pixels in a row, it is necessary therefore to scroll from 0-7 to achieve the scrolling affect. When combined with proper timing, it creates the nice effect seen in scrolling games for the Commodore 64! Be sure to check out my article called Commodore 64 Screen Scrolling to learn more about how this works in an actual demo.

Character data is copied to another screen (known as a “backbuffer”) to save cycle count time. If the screen is not copied then it will appear jerky when scrolled since updates are always occurring to the screen. However by placing it on the “hidden screen” and recalling it later during frame time syncing, the nice scrolling effect is successful.

When I have time, I will write a better tutorial, but for now I hope this is beneficial enough. Feel free to always leave comments (below) about anything you get stuck on.

lda $d011 ; set screen scroll position
and #%01111000
ora yscroll ; Smooth Scroll to Y Dot-Position (0-7)
sta $d011

Finally below is another visual description of how pixels (bits) are shifted on the Commodore 64 background screen. The top shows memory location 53270 which can move pixels horizontally to either the left or right. After 7 dots are shifted the pixels are reset in the original position.

Be sure to examine the graph on the right that shows single blocks going down the screen. When a map is read from a file (such as CharPad), the data exists here and then is shifted onto the screen after a scroll. The first bits are read going from the top to the bottom and pushed going to the left. Also at the same time the data that exists at the far edge of the screen (in the rows 0-7 > the larger graph), the pixels then must be shifted to the left to make room for the new pixels coming from the map (file). Just imagine a bunch of flowing dots moving across the screen with the old dots to the immediate left and you should hopefully get the picture. This creates a scrolling effect as the motion continues in a loop.

Scrolling Screen Code Example

setup
lda $D018 ; set the computer to were the new chars set are and use them
and #241 ; 11110001
ora #2 ; 00000010
sta $D018 ; set it at bank 1

lda #%00010111 ; Select 24/25 Row Text Display: 1 = 25 Rows
sta $d011
lda $d011 ; set screen scroll position
and #%01111000
ora yscroll ; Smooth Scroll to Y Dot-Position (0-7)
sta $d011

updownscroll

lda $d011 ; set screen scroll position
and #%01111000
ora #3 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

ckcontinuey4b
lda $d011 ; set screen scroll position
and #%01111000
ora #4 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

ckcontinuey3b
lda $d011 ; set screen scroll position
and #%01111000
ora #3 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

ck2quit1
lda $d011 ; set screen scroll position
and #%01111000
ora #2 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

ck1quit1
lda $d011 ; set screen scroll position
and #%01111000
ora #0 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

HORIZONTAL SCROLLING

leftrightscroll
lda $d016 ; set screen scroll position
and #%11111000
ora #7 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

HIDDENSCREEN(X)

CK5_1
lda Ptrhiddenscreen ; hidden screen address
sta temp1
lda Ptrhiddenscreen+1
sta temp2

lda $d016 ; set screen scroll position
and #%11111000
ora #5 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

ckcontinue4b
lda $d016 ; set screen scroll position
and #%11111000
ora #4 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

ckcontinuex3b
lda $d016 ; set screen scroll position
and #%11111000
ora #3 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

HIDDENSCREEN(X)

CK2_1
lda Ptrhiddenscreen ; hidden screen address
sta temp1
lda Ptrhiddenscreen+1
sta temp2

lda $d016 ; set screen scroll position
and #%11111000
ora #2 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

CK0_1
lda $d016 ; set screen scroll position
and #%11111000
ora #0 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

HIDDENSCREEN(X2)

IRQSWAPSCREEN
lda VIC_MEMORY_CONTROL
and #%00001111
ora #%00000000
sta VIC_MEMORY_CONTROL

lda #hiddenscreen/256 ; not need on pcKERNAL’S screen editor
sta 648
lda #SCREEN_MEM
sta Ptrscreen+1 ; set current screen bitmap
lda #hiddenscreen
sta Ptrhiddenscreen+1 ; set hidden screen bitmap

lda $d011 ; set screen scroll position
and #%01111000
ora #3 ; Smooth Scroll to x Dot-Position (0-7)
sta $d011

buf2
lda VIC_MEMORY_CONTROL
and #%00001111
ora #%00010000
sta VIC_MEMORY_CONTROL

lda #SCREEN_MEM/256 ; not need on pc KERNAL’S screen editor
sta 648
lda #hiddenscreen
sta Ptrscreen+1 ; set current screen bitmap
lda #SCREEN_MEM
sta Ptrhiddenscreen+1 ; set hidden screen bitmap

IRQSWAPSCREEN2
lda VIC_MEMORY_CONTROL
and #%00001111
ora #%00000000
sta VIC_MEMORY_CONTROL

lda #hiddenscreen/256 ; not need on pcKERNAL’S screen editor
sta 648
lda #SCREEN_MEM
sta Ptrscreen+1 ; set current screen bitmap
lda #hiddenscreen
sta Ptrhiddenscreen+1 ; set hidden screen bitmap

buf3
lda VIC_MEMORY_CONTROL
and #%00001111
ora #%00010000
sta VIC_MEMORY_CONTROL

lda #SCREEN_MEM/256 ; not need on pc KERNAL’S screen editor
sta 648
lda #hiddenscreen
sta Ptrscreen+1 ; set current screen bitmap
lda #SCREEN_MEM
sta Ptrhiddenscreen+1 ; set hidden screen bitmap

lda $d016 ; set screen scroll position
and #%11111000
ora #3 ; Smooth Scroll to x Dot-Position (0-7)
sta $d016

[wpforms id=”2316″]