Understanding 6502 assembly on the Commodore 64 - (19) The Truth of the matter

If you haven't done much programming in the past, you will probably still remember Learning Truth tables in mathematics, wondering why you would ever need to know such a thing.  Well,   question answered.   Logical operations are a fundamental part of digital electronics.  The 6502 is no exception.  Before breaking into Mathematics,  we will first learn logical operations.








     One method I remember, way back in the day, walking five miles to school, up hill, both ways, and barefoot,  was simply drawing a set of squares and writing an X and a Y, being told what values should be placed inside them because the book said so.  In the case of AND, the condition was that both X and Y had to be 1 for the resulting value to be 1.   Kind of like this.......



     I can't imagine trying to explain to a 12 year old why this is useful.  You could be forgiven for not remembering this. Or maybe just maybe, A light bulb turned on inside your head!!!!!











AND



     Yes, that was a pun.   Ok, I know.... But seriously.  When we demonstrate visually, or better yet with a real light bulb and batteries, we can see a tangible result processed by our "Computer".  I realize were taking a step back in technology to arrive at an answer, but you can see the point.

Where the lightbulb off represents 0.  It can only turn on when both A and B are set closed.  So when:

A AND B are set then the light bulb is ON
If either A or B are not set, the build is OFF
If neither A and B are set, the build is OFF



ORA


     Heres another one, with this circuit we can see that if A OR B is set then the lightbulb will turn on.  It will turn on in all conditions except for where A and B are both unset as shown.






EOR


Ok, this one is just a little tricky.  In order to be ON, A and B must be different. Notice the eXclusive X in our diagram!!!!!  That has nothing to do with it, I'm just being funny......

If BOTH A and B are off, the bulb is off
If BOTH A and B are on, the bulb is off
If either just A or just B is on, the bulb is on


These are the three logical operations in our 6502,  which is good for me, because I'm not very good at illustrations, as you have seen.  We shall refer to:

A - As the original value
B - As the mask
Light Bulb - The result

For our logical operations:

AND - Logical AND
ORA - Logical OR
EOR - Logical Exclusive OR

Note that these operations only take place in the Accumulator. There will be no logical operations in X and Y.


So moving on............

Our 6502 can process 8 bits at once, where our lightbulb could only do 1.  Consider the 6502 an upgrade.  For our purposes, it might be easier to use our Binary notation in Assembly rather than HEX for obvious reasons.  I shall demonstrate:




AND




LDA #$3B        
AND #$50  ; A=$10     

Our result in A will be $10.  If this means absolutely nothing to you, then you are correct!!!  Hex is a poor means to demonstrate logical operations.


Perhaps a more appropriate method (space added after %, for browser compatibility)

LDA #% 00111011
AND #% 01010000 ; A=$10

Our result will still be $10, but we can see why....

Value:   0 0 1 1 1 0 1 1
Mask:    0 1 0 1 0 0 0 0
Result:  0 0 0 1 0 0 0 0

We will evaluate all 8 rows from left to right, separately

0 AND 0 is 0
0 AND 1 is 0
1 AND 0 is 0 
1 AND 1 is 1
1 AND 0 is 0
0 AND 0 is 0
1 AND 0 is 0
1 AND 0 is 0

$10 = 0 0 0 1 0 0 0 0, This is how we arrived at our answer.




Lets see how this could be useful......

In chapter 11, Sprite Movement and Collision, we had 2 sprites, SPRITE0 and SPRITE1.  Using memory address SPENA we were able to turn both of them on at once, we learned that the hex value corresponds to 8 bits which in turn represent SPRITE0 through SPRITE7.


lda #% 00000011
sta SPENA ; Activate SPRITE 0,1





                        1   0





Granted, we were only working with two sprites, its not very complicated.  Lest pretend that we had several enabled...

lda #% 11010011
sta SPENA ; Activate SPRITE 7,6,4,1,0





7   6       4           1   0




For whatever reason, we want to shut off ALL except sprites 6 and 4


lda SPENA       ;   Load the value of SPENA back into A (11010011)
and #% 01010000 ; (NEW A VALUE IS 01010000)
sta SPENA       ;  Turn off all sprites except 6 and 4


    6       4                

Well, we see what happened but what else.  Lets try again.....


lda #% 11010011
sta SPENA      ; Activate SPRITE 7,6,4,1,0

and #% 00000000  ; Turn off all sprites
sta SPENA



Nothing to see here.......



So what would 11111111 do.....


lda #% 11010011
sta SPENA      ; Activate SPRITE 7,6,4,1,0

and #% 11111111  ; Accomplish nothing
sta SPENA


7   6       4           1   0



With a mask of 11111111 essentially we changed nothing in A and left everything as it was.



How about more specific


lda #% 11010011
sta SPENA      ; Activate SPRITE 7,6,4,1,0

and #% 11000000  ; Turn off all sprites but leave 6,7 alone
sta SPENA


7   6                        

In summary, for AND, a 1 bit in the mask will leave the original bit alone, any 0 in the mask will shut the bit off.  If it was off it stays off, If it was on it turns off.







ORA




Where AND's mask forced bits to off, OR's mask forces bits ON


LDA #% 00111011
ORA #% 01010000 ; A=$7B

Our result will still be $7B, lets see why....

Value:   0 0 1 1 1 0 1 1
Mask:    0 1 0 1 0 0 0 0
Result:  0 1 1 1 1 0 1 1

We will evaluate all 8 rows from left to right, separately

0 OR 0 is 0
0 OR 1 is 1
1 OR 0 is 1 
1 OR 1 is 1
1 OR 0 is 1
0 OR 0 is 0
1 OR 0 is 1
1 OR 0 is 1

$7B = 0 1 1 1 1 0 1 1, This is how we arrived at our answer.


Looking at our example from before:


lda #% 11010011

sta SPENA ; Activate SPRITE 7,6,4,1,0




7   6       4           1   0




For whatever reason, we want force on ALL except sprites 6 and 4, leaving the others as they were:


lda SPENA   ;   Load the value of SPENA back into A (11010011)
ora #% 01010000  (NEW A VALUE IS 11010011)
sta SPENA  ;  Force on sprites except 6 and 4





7   6       4           1   0

Note that apparently nothing happened. 6 and 4 were already on.





Lets turn on all SPRITES .....

lda #% 11010011
sta SPENA      ; Activate SPRITE 7,6,4,1,0

ora #% 11111111  ; Turn on all sprites
sta SPENA



7   6   5   4   3   2   1   0




SO what would 00000000 do.....


lda #% 11010011
sta SPENA      ; Activate SPRITE 7,6,4,1,0

ora #% 00000000  ; Accomplish nothing
sta SPENA



7   6       4           1   0



With a mask of 00000000 essentially we changed nothing in A and left everything as it was.  By now you realize that this isn't complicated, theres no trickery here.  Its simply logical and operates just as it appears.





EOR


EOR is a bit different than the first 2.  So long as the value and the mask are the same, the output will be 0.  If the value and the mask are different, the output will be 1.


LDA #% 00111011
EOR #% 01010000 ; A=$6B

Our result will still be $6B, lets see why....

Value:   0 0 1 1 1 0 1 1
Mask:    0 1 0 1 0 0 0 0
Result:  1 1 0 1 0 1 1

We will evaluate all 8 rows from left to right, separately

0 XOR 0 is 0
0 XOR 1 is 1
1 XOR 0 is 1 
1 XOR 1 is 0
1 XOR 0 is 1
0 XOR 0 is 0
1 XOR 0 is 1
1 XOR 0 is 1

$6B = 0 1 1 0 1 0 1 1, This is how we arrived at our answer.

Actually of all 3, XOR is the coolest one to demonstrate, it is the bit flipper, and can produce the inverse value of the input.  We will use a different values to see the effect better.


lda #% 11111111 ; $FF
sta SPENA      ; Activate SPRITE 7,5,3,1


Imagine, if you would, that I now have these color coded sprites on the screen, set up with the coordinates and colors to display as such.


7   6   5   4   3   2   1   0

We shut of Sprites 6 4 2 and 0 with AND......

and #% 1010101
sta SPENA

7       5        3        1


Good, now we want to flip the values, So what is ON will be OFF, and what is OFF will be on:



eor #% 11111111
sta SPENA      ; Activate SPRITE 6,4,2,0



6      4      2      0

Good, now we want to flip the values back

eor #% 11111111
sta SPENA      ; Activate SPRITE 7,5,3,1



7       5        3        1


We could now turn all back on with OR


ora #% 11111111
sta SPENA      ; Activate SPRITE 7,6,5,4,3,2,1,0



7   6   5   4   3   2   1   0





NEXT----->


No comments:

Post a Comment