Do you want to check whether a certain variable is odd or even? This is fairly easy in Assembly: simply check if the lowest bit is odd or even, and you know that the entire byte is or isn’t as well. There are a few ways to code this though. In this post, I’ll briefly go through all methods, explain why they work and tell you my favorite way to do it.
The straightforward way: AND
LDA variable AND #%00000001 BNE +isOdd ;; isEven +isOdd:
This method is probably the easiest to understand, and the one you’ll find throughout the NESMaker source code – especially for odd/even nametable checks. This code evaluates the lowest bit of the variable. If it is 1, which is odd, the entire byte is odd as well. Likewise, if the lowest bit is 0 (even), the entire bit is even as well. The advantage to this method is that it is quite easy to understand what it does; it affects the accumulator though, which means that if you still need the variable’s value, you’ll have to LDA variable again.
The carry way: ROR
LDA variable ROR BCS +isOdd ;; isEven +isOdd:
This method is a tad bit more creative, but has its advantages. It rolls all bits of the accumulator’s value one place to the right, and places the lowest bit of the accumulator (the one which defines if the variable is odd or even) into the carry flag. The BCS instruction then checks if the carry is set (1, or odd) or not (0, or even). The advantage of this method over the AND method is that it saves one byte of ROM data. This method also modifies the accumulator, although the original value can be restored by a ROL instruction, which takes one less byte in ROM and one cycle faster than the LDA $zp instruction.
The other carry way: LSR
LDA variable LSR BCS +isOdd ;; isEven +isOdd:
This method works pretty much the same as the ROR method, except the carry value is not placed in the highest bit of the accumulator. All other advantages and caveats that apply to the ROR method still apply though, as we don’t use the highest bit of the value to determine if it’s odd or even anyway.
The creative way: BIT
LDA #$01 BIT variable BNE +isOdd ;; isEven +isOdd:
The BIT instruction works like the AND instruction, with a few differences. The biggest advantage is that it does not change the value of the accumulator. The drawback is that in 6502, the BIT instruction can’t be used with an immediate value, but only with a memory address. In other words: BIT #$01 is not a valid instruction. Therefore, the preservation of the accumulator’s value usually isn’t too big of an advantage in this case. Another property of the BIT instruction is that it sets the negative and overflow status flags to the value of bits 7 and 6 respectively, which makes for easy and fast higher bit checks. If you only want to check for odd/even, this has no advantage, but this property will come in handy in specific situations.
My preferred method
These were four ways to check if a variable is odd or even. My personal preferred methods are the ROR and LSR methods, as these can shave off a few bytes and cycles, which gives you additional game ROM data and speed. It’s a tiny little difference which probably won’t make too much of an impact, but in a world where ROM space is scarce, every byte counts. The BIT method might come in handy in certain edge cases where you need to evaluate bits 6 and/or 7 of the variabale as well (for example, if you need to check if a signed integer is both even and positive). Finally, while the AND method does not have any technical advantages over the other ones, it is the easiest to understand for beginning NES developers. In conclusion, you might say every method has its advantages, and it depends per use case which one is best. As in a lot of development cases, there’s no right or wrong, just alternatives, each of which may be a useful tool in your 6502 arsenal.