Day 16 - Bit Masking/Toggling

Published: 2005-07-22
Updated: 2010-12-19
Author: Mike Huber

Masking

Before we begin, there's something very important to remember: You can only do math and bit operations on the A register. There are no math and bit operation instructions for the X and Y registers.

Masking, as in clearing certain bits while leaving the others intact. This is done (atleast alot of the time) with the AND instruction. The syntax is like this:

and (number or memory)

Say we want to clear the last 4bits of A, but leave the others intact:

and #$F0

Remember ANDing a bit with 1 will give the same value that you started with, and ANDing with 0 will always have an answer of 0, since the AND logic table is like this:


        AND Table
    -----------------------------
    Start  | ANDed with | Result
    -----------------------------
      0    |     1      |   0
      0    |     0      |   0
      1    |     0      |   0
      1    |     1      |   1

It's OK if you already knew that, the tables today are for the people who are going to have to figure out all this bit logic stuff (ANDs, ORs, XORs, NOTs) on their own because they haven't used ASM before encountering the NES.

Alright, now your probably wondering (maybe) how hex maps out to binary. (HEX to BINARY conversion). Here's a table of hex digits:

        Hex 2 Binary
    ---------------------------------
        0   |    0000
        1   |    0001
        2   |    0010
        3   |    0011
        4   |    0100
        5   |    0101
        6   |    0110
        7   |    0111
        8   |    1000
        9   |    1001
        A   |    1010
        B   |    1011
        C   |    1100
        D   |    1101
        E   |    1110
        F   |    1111

So now you know (if you couldn't already) how to convert each hex digit to binary. So #$0F becomes #%00001111 . The percent is the symbol NESASM.exe uses for binary numbers.

Now what if you only want to mask certain bits out (to 0). You might want to do the AND instruction in binary. What ever bits you make 0 will be 0 when the AND is complete, and whatever bits are 1 will make the corresponding bit in the A register stay the same (wether it be 1 or 0). Example:

;we want to make bits #3 and #7 clear (0). Remember to count bits ; from #0 on far right. and #%01110111

Note the underlined '0's, the corresponding bits in A will be '0's, but everything else will remain unchanged.

Now, what if we wanted to mask bits to be set (change to a 1). Then we would have to use OR. Take a look at the OR table below:

        OR Table
    -----------------------------
    Start  | ORed with | Result
    -----------------------------
      0    |     1      |   1
      0    |     0      |   0
      1    |     0      |   1
      1    |     1      |   1

You should see that AND's result is 1 if BOTH inputs are 1. OR's result is 1, if one or both inputs are 1.

To set individual bits to 1 (I don't actually know why you'd want to do this, but the method I tell DOES work), you just OR with 1. The bits you don't want to change, you OR with 0. So to set bits #6 and #4 of A to 1 , we would go like this:

ora #%01010000

Note that the instruction for OR is ORA, I guess it's like semi-traditional to have 3 letter ASM instructions. I hope you understood that, we OR the bits we want set to 1 with 1 and the bits we want to leave alone with 0.

Also note that the NES is a 8bit system so we need all 8bits in our binary numbers. If you don't put all 8bits in, I think NESASM will interpret it as having 0's on the left as in being the number you think it'll be, but I'm not sure about this, you might need all 8bits.

Toggling

First of all, let's define toggling. Toggling is switching between 0 and 1. The method shown here is useful for toggling bits on (1) and off (0) with one instruction if you execute that instruction repeatedly.

To toggle bits, you need the XOR. Here's a table for XOR:

        XOR Table
    -----------------------------
    Start  | XORed with | Result
    -----------------------------
      0    |     1      |   1
      0    |     0      |   0
      1    |     0      |   1
      1    |     1      |   0

XOR only results in 1 if one (not both) of the inputs is 1. So XORing with a 1 will toggle the bit (and XORing with 0 will make a bit stay the same). The syntax of XOR is:

eor (number or memory)

Note that the instruction for XOR is EOR. The thing is that they both stand for (Exclusive OR (EOR)) or XOR (eXclusive OR). So if we wanted to toggle bits #1 and #6:

eor #%01000010

XORing with 0 will make the bit stay the same, but XORing with 1 will make the bit opposite of what it is.

This Day In Review

I seriously hope you learned something today. Toggling and Masking bits is fun! Have fun!

Happy coding!,
-Mike H a.k.a GbaGuy

P.S. This is a direct conversion from the GBA Day 16, so if you find anything wrong, please tell me (via email).