The Magic of EOR
EOR is a useful function. I often use it in a situation where I already have "myNumber" in the accumulator, and I want to do a subtraction. Instead of doing this:
sta temp ; myNumber (0 to 255) lda #$FF ; 255 sec sbc temp ; 255 - myNumber
You can just do this:
eor #$FF ; 255 - myNumber
You save a lot of cycles and bytes. You can apply the same idea in other situations. Another common one is EOR $0F with a value of 0-15 to get the result of 15 - myNumber. You can also preserve signed bits while flipping the other used bits... although I've never really played around with that as I only ever seem to use positive values.
EOR is also useful to help optimize a look up table. Here is a routine I once wrote to dynamically convert a color from NTSC to PAL. EOR saves me several cycles here, because I can predetermine what bits I need to flip. It's a lot easier then storing a nibble to a temp register, OR'ing it later, etc...
tax ; save current NTSC color lsr lsr lsr lsr tay txa eor ConvertColTab,Y ; color is now PAL...... ConvertColTab: .byte $00 ; $0x ---> $0x .byte $30 ; $1x ---> $2x could also use ".byte $20", $1x ---> $3x .byte $00 ; $2x ---> $2x .byte $70 ; $3x ---> $4x .byte $20 ; $4x ---> $6x .byte $D0 ; $5x ---> $8x .byte $C0 ; $6x ---> $Ax .byte $B0 ; $7x ---> $Cx .byte $50 ; $8x ---> $Dx .byte $20 ; $9x ---> $Bx .byte $30 ; $Ax ---> $9x .byte $C0 ; $Bx ---> $7x .byte $90 ; $Cx ---> $5x .byte $E0 ; $Dx ---> $3x .byte $D0 ; $Ex ---> $3x .byte $D0 ; $Fx ---> $2x
Then there is also a famous EOR trick to swap two values without using a temp register (or X and Y):
lda ValueOne eor ValueTwo sta ValueTwo eor ValueOne sta ValueOne eor ValueTwo sta ValueTwo
I find this mostly academic though. It wastes a lot of cycles, and bytes. If you really don't have a temp register left then your code has other problems. Still a neat trick though.
Here is something useful that a user on NesDev named tepples showed me. Without delving into the code, I'm basically in a situation where I'm splitting the nibbles apart (although the top nibble is also times by 4). My code:
lda hexHigh ;3 @3 and #$F0 ;2 @5 lsr ;2 @7 lsr ;2 @9 tay ;2 @11 lda hexHigh ;3 @14 and #$0F ;2 @16 tax ;2 @18
And his code with EOR:
lda hexHigh ;3 @3 and #$0F ;2 @5 tax ;2 @7 eor hexHigh ;3 @10 lsr ;2 @12 lsr ;2 @14 tay ;2 @16
That saves 2 bytes and 2 cycles. I was so impressed with that bit of code. I can't begin to tell you how many times I've come across this and similar situations. I've never thought about blowing the other nibble away like that (maybe you guys have). I've always known that if you EOR something with the same value then you get 0, but it just never occurred to me to use it in this situation. I was so happy with this solution. I've been thinking about that simple trick for days.
- 4
3 Comments
Recommended Comments