C64 Assembly Logical Operators

When writing code using C64 Assembly Language Bit Manipulation you will eventually come across logical operators. These are used to manipulate bits to obtain specific results.

On the Commodore 64, there are three logical operators that work with only with the accumulator. In no specific order they are:

AND (Logical AND)

ORA (Logical OR)

EOR (Exclusive OR)

Before exploring these in depth, it is necessary to understand what a byte is. A byte is the total sum of bits calculated in powers of 2. Below is an example of a byte broken down in bits

Hex Value:$C7
Decimal: 199
11000111

==================================================================

AND (Logical AND to Accumulator)

Each logical operator in assembly language performs specific actions. And manages actions on bits like this:

Original A Bit Mask Resulting A Bit
0 0 0
1 0 0
0 1 0
1 1 1

AND is used to turn bits off within a byte. All the other bits will remain unchanged if they are on already.

Example for demonstrating AND.

Original value: 11000111
Mask AND 10001111
——–
Result 10000111

==================================================================

ORA (Logical OR to Accumulator)

The specific action for ORA is:

Original A Bit

ORA is used to turn bits on within a byte

Original A Bit Mask Resulting A Bit
0 0 0
1 0 1
0 1 1
1 1 1

C64 Assembly language Bytes

In the book Machine Language for the Commodore 64 and other Commodore computers, Jim Butterfield uses an example of turning on numbers in a byte, such as 4, 5, and 6 in the value of $C7. A byte can be any number between 0-255. Each byte is made up of 8 bits (binary number as a whole).

Example (as listed):

Original value: 11000111
Mask EOR 01110000
——–
Result 11110111

EOR is used to invert bits in a byte (flips them over).

Example (as listed):

Original value: 11
Mask EOR 01110000
——–
Result 11110111

A good example of an using AND in a C64 Assembly Language Bit Manipulation example is turning sprites on or off. The example below turns on sprites 0 & 2

LDA $d015 ; Examine sprite memory (enable byte)

and #%00000101 ; Turn on sprite 0 and 2

sta $d015 ; Save the sprite data

So bits zero and two are active. The bits start at the right side (at “zero”) and move to the left side. So the last bit would be bit 8 (currently “zero”) also.

For this example, the AND command will turn off all sprites that are active. Perhaps this is not the best example, but for the time allotted it will have to do for now. In the future, I may change this to mask with the ORA command instead.

Also when you turn off other bits (sprites, etc), all of the other bits are unaffected. That is where you could utilize an ORA instruction to restore specific bits without impacting the others as well.

C64 Assembly Language Bits

You could also just look at the individual bits and see which sprite is active. According to our example, that would pan out as follows. When you see a “1” in that position, that indicates that the sprite has been turned on and can be seen on the screen once it is positioned at its’ horizontal and vertical position.

The black image below indicates that no sprite was found there, therefore setting it to bit “0”.

00000101

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Sprite 7 Sprite 6 Sprite 5 Sprite 4 Sprite 3 Sprite 2 Sprite 1 Sprite 0
C64 Assembly language Bit C64 Assembly Language Sprite Bit
0 0 0 0 0 1 0 1

An example below from the Parkour game (accessible through the Paid Membership) demonstrates how to walk a sprite across the street by flipping the bits after reaching the 256th position. On the Commodore 64, a sprite’s X position ranges from 0-255. Anything beyond this requires writing to the highest bit. The program below demonstrates this. The BIT_TABLE can handle either left or right range limits (according to the value in memory register $d010).

lda BIT_TABLE, x

eor SPRITE_POS_X_EXTEND   ; Sprite X value saved here

sta SPRITE_POS_X_EXTEND   ; Sprite X value saved here

sta VIC_SPRITE_X_EXTEND ; Sprite’s X MSB position


BIT_TABLE byte  1,2,4,8,16,32,64,128

SPRITE_POS_X_EXTEND byte 0

VIC_SPRITE_X_EXTEND = $d010

Now listed below is a the number and binary bit values found based on the values that exist in the BIT_TABLE variab le. It is necessary to examine the bits (not the byte) to actually understand what is going on mathematically in memory. Here you can examine that setting one of these bits to one adds 256 to the horizontal position of the sprite (stored within SPRITE_POS_X_EXTEND). Notice that each increase in the number table increases by the power of two.

1.

2.

4.

8.

16.

32.

64.

128.

0 0 0 0 0 0 0 1

0 0 0 0 0 0 1 0

0 0 0 0 0 1 0 0

0 0 0 0 1 0 0 0

0 0 0 1 0 0 0 0

0 0 1 0 0 0 0 0

0 1 0 0 0 0 0 0

1 0 0 0 0 0 0 0

Hopefully that makes it more crystal clear. 🙂

Please follow and like us: