Question about AND

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Question about AND
by on (#29785)
Alright. I know that in DOS assembly, you can use AND on a register to clear bits by having a binary mask of what you want cleared set to 0 and what you don't want cleared as 1. Then it stores the new number in the same register.

What I want to be able to do in 6502 is use an AND statement on something, use a mask to clear all but one bit. Say I want to look at bit #1 (mask of %00000010). Can I then take that bit I looked at and store its 1 or 0 into something or do I have to use a LSR and store after that?

Basically say I had a variable that had the binary value: %11111101, I loaded that into A and then performed AND with %00000010. Obviously bit #1 is 0. Can I take that 0 and store it without having to use a bunch of CMP statements?

Sorry if this sounds strange, but I tried wording it as best I could.

by on (#29786)
Code:
lda #%11111111
and #%00000010
sta flag
; flag = %00000010

lda #%00000000
and #%00000010
sta flag
; flag = %00000000

If you don't mind flag being 0 for false and %00000010 for true, then no LSR is needed. For example:
Code:
lda flag
bne flag_is_true
flag_is_false:
...

flag_is_true:
...

Don't you have something you can run 6502 code with to try these things?

by on (#29787)
Yes, you can store the result of an AND to memory.
Code:
  ; prepare memory
  lda #%11111101
  sta $00
  lda #%11111111
  sta $01

  ; test AND instruction
  lda $00  ; A has %11111101
  and #%00000010  ; A has 00000000
  sta $02  ; $02 has 00000000

  lda $00  ; A has %11111111
  and #%00000010  ; A has 00000000
  sta $03  ; $03 has 00000010

Then when you load it back again, you can use BNE or BEQ to test whether the result was zero or nonzero:
Code:
  lda $03
  beq dontRedraw
  jsr redrawLine
dontRedraw:

by on (#29789)
If you use many flags, which I'm sure you will, you may want to have 8 flags in a byte instead of just 1. It will take a few extra cycles to do AND before every comparison. So if you wanted to test bit #5, you'd have to do this:

Code:
lda FlagHolder ;This byte holds 8 flags
and #$20 ; We test bit 5 by clearing all other bits except bit 5
beq FlagNotSet ;If the flag is not set, the value will be EQual to 0, so branch.
jsr FlagSet ;If the flag is set, the value will Not be Equal to 0, and will not branch, and it will come to here.


The only reason I say this is because the first minigame I made had me checking for flags, and I only used the first bit of every bit to determine if a flag was set. The code was ugly, sloppy, and a terrible space-waster.