Some of the most essential operations in 6502 assembly are logical operations. These operations compare two variables and modify the result accordingly. In assembly, there are three basic logical operations. I’ll explain which they are and what they do here.
AND
The AND operation compares two values bit by bit, if both compared bits are 1, it returns 1. In all other cases, it returns 0. So:
0 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 1
Because assembly does logical operations on bytes instead of bits, every bit within a byte gets compared this way. So, for example, if we do #%01010011 AND #%10011001, the result will be #%00010001:
ORA
The ORA operation is a logical OR comparison. This checks the bits of a byte, and if either one of those bits is 1, the resulting bit will also be 1:
0 ORA 0 = 0 0 ORA 1 = 1 1 ORA 0 = 1 1 ORA 1 = 1
So if we take the same values as before, #%01010011 ORA #% 10011001 will result in #%11011011:
EOR
The last operation, EOR, does an exclusive-or (or XOR) comparison. This checks the bits of a byte, and returns 1 if either one of the checked bits is 1 but not both:
0 EOR 0 = 0 0 EOR 1 = 1 1 EOR 0 = 1 1 EOR 1 = 0
So, #%01010011 EOR #% 10011001 will result in #%11011011:
Also good to know is that these logical operators modify the contents of the accumulator. So whatever is in A, gets overwritten by the AND, ORA and EOR operators.
A visual explanation
For those of you who are more visually oriented, check the following image that pretty clearly explains how AND, EOR (XOR) and ORA (OR) work:
Why are these useful?
Let’s say you’re using a byte to save different settings. A good example of this within NESmaker are the Object_flags, where each bit holds a certain type of data:
#%76543210 0: object is persistent 1: object is the player 2: object is a player weapon 3: object is a monster 4: object is a monster weapon 5: object is a pickup/powerup 6: object is a target type 7: object is an NPC
Now in code, you want to check if an object is a monster. You might code something like this:
LDA Object_flags,x CMP #%00001000 BEQ +isMonster
This code will work, but only if the object is a monster and nothing else. In theory, the object can be both a monster and persistent. This will result in the Object_flags variable having a value of #%00001001, which is not equal to #%00001000, which means the check will fail in this case. To only check for a monster, you want to ignore the other settings. This is where you can use the AND operator:
LDA Object_flags,x AND #%00001000 CMP #%00001000 BEQ +isMonster
This code will check if the object is a monster, while ignoring the other settings contained by the Object_flags variable. If the object were both a monster and persistent, the AND operator would do the following:
Not only for comparison this comes in handy. Also if you want to change a single bit while leaving the other bits unchanged, you can use logical operators. Three examples (:
;; Switch off bit 4 LDA variableName AND #%11101111 STA variableName ;; Switch on bit 4 LDA variableName ORA #%00010000 STA variableName ;; Toggle bit 4 (i.e. turn it off when it's on, and turn it on when it's off) LDA variableName EOR #%00010000 STA variableName
Long story short: you can’t really code a game without these logical operations!