Jump to content
  • entries
    17
  • comments
    28
  • views
    32,103

The Magic of EOR


Omegamatrix

1,747 views

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. :D

  • Like 4

3 Comments


Recommended Comments

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...