BIT Instruction
BIT Instruction
Hi,
I'm hoping to get some advise on the 6502 BIT instruction, as I can't seem to get it to do what I need.
So I understand that the instruction can be used to check if some bits are set (or not set) and it sets the zero flag accordingly.
I would like to check if bits 6 and 7 of a value stored in the Accumulator are set, I'm not interested in if the other bits are set or not.
So I've tried:
LDA #255 (Example value with bits 6 and 7 set)
BIT $C0 ($C0 = %11000000 - this indicates the two bits I want to check).
BEQ bitsareset
<some code to indicate bits 6 and 7 are not set>
.bitsareset
<some code to indicate bits 6 and 7 are set>
So the above code would indicate that 6 and 7 are set, is this correct? (Obviously not as I can't get it to work!).
I'd appreciate some advice - Thanks!
I'm hoping to get some advise on the 6502 BIT instruction, as I can't seem to get it to do what I need.
So I understand that the instruction can be used to check if some bits are set (or not set) and it sets the zero flag accordingly.
I would like to check if bits 6 and 7 of a value stored in the Accumulator are set, I'm not interested in if the other bits are set or not.
So I've tried:
LDA #255 (Example value with bits 6 and 7 set)
BIT $C0 ($C0 = %11000000 - this indicates the two bits I want to check).
BEQ bitsareset
<some code to indicate bits 6 and 7 are not set>
.bitsareset
<some code to indicate bits 6 and 7 are set>
So the above code would indicate that 6 and 7 are set, is this correct? (Obviously not as I can't get it to work!).
I'd appreciate some advice - Thanks!
Re: BIT Instruction
The BIT instruction performs an AND between the Accumulator and the content of a location in memory. So, in your example, it will take the content of the location $C0 and will perform an AND with the accumulator. It will transfer bits 7 and 6 of the content of the location $C0 to the flags Z and V. It will not transfer the bits of the value $C0, nor will AND the $C0 value with the accumulator: the argument of BIT is a location in memory, and will fetch the content of that location to do the work.
Last edited by BB8 on Wed Jan 05, 2022 11:26 pm, edited 2 times in total.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: BIT Instruction
I see BB8 posted while I was writing. I'll finish anyway.
The Z flag reflects the result of an AND operation, without affecting anything but the status register. $FF ANDed with $C0 will still have a couple of bits set, which is not zero, so Z will be clear, not set.
Note also that without regard to what's in the accumulator, you can do BIT on a memory location (or I/O) (not BIT-immediate) to get its bit 7 into the N flag and bit 6 into the V flag. Related instructions are TSB and TRB.
I cannot pass up the opportunity to recommend the excellent programming manual, "Programming the 65816 including the 6502, 65C02, and 65802" by David Eyes and Ron Lichty. This is a .pdf file of a rather large book that is well laid out and is much better than the description there lets on. Note: There were many problems with the earlier .pdf version that were not in the original paper manual; but in late March 2015, WDC scanned and OCR'ed the paper manual and posted the new, repaired .pdf. Chapter 18 gives at least a page for every instruction, telling exactly what it does, and covering all the addressing modes, cycle counts, etc..
The Z flag reflects the result of an AND operation, without affecting anything but the status register. $FF ANDed with $C0 will still have a couple of bits set, which is not zero, so Z will be clear, not set.
Note also that without regard to what's in the accumulator, you can do BIT on a memory location (or I/O) (not BIT-immediate) to get its bit 7 into the N flag and bit 6 into the V flag. Related instructions are TSB and TRB.
I cannot pass up the opportunity to recommend the excellent programming manual, "Programming the 65816 including the 6502, 65C02, and 65802" by David Eyes and Ron Lichty. This is a .pdf file of a rather large book that is well laid out and is much better than the description there lets on. Note: There were many problems with the earlier .pdf version that were not in the original paper manual; but in late March 2015, WDC scanned and OCR'ed the paper manual and posted the new, repaired .pdf. Chapter 18 gives at least a page for every instruction, telling exactly what it does, and covering all the addressing modes, cycle counts, etc..
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: BIT Instruction
BB8 wrote:
It will transfer bits 7 and 6 of the content of the location $C0 to the flags Z and V
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: BIT Instruction
archie456 wrote:
I would like to check if bits 6 and 7 of a value stored in the Accumulator are set, I'm not interested in if the other bits are set or not.
So, we have:
Code: Select all
cmp #$c0
bcs both_set ; 11xxxxxx
bpl both_clr ; 00xxxxxx
ora #0
bmi only_7 ; 10xxxxxx
only_6: ; 01xxxxxx
...
only_7:
...
both_set:
...
both_clr:
...
Last edited by barrym95838 on Thu Jan 06, 2022 4:34 am, edited 3 times in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: BIT Instruction
I think I will put my 2 cents in here as well. Depending on you want to do after you have checked the bits in the Accumulator, but your branching instructions already have the hi-bit covered. If bit #7 is set, then you can branch using BMI/BPL without checking what is specifically in the hi-bit. I usually like to use bits 0 & 1, and 6 & 7 for flag indicators. They can then easily be checked like so.
LDA BYTE
BMI - branch if bit#7 set
ASL
BMI - branch if bit#6 set
or
LDA BYTE
LSR
BCS - branch if bit #0 set
ROR - preserve bit #0
BCS - branch if bit #1 set
some advantages of this method is that the you retain the original value in BYTE, if it is an address and not an immediate value. But also the Accumulator can be restored to its original value with a simple ROR for the first method and a ROL ROL for the second.
Also instead of using BIT on an immediate value, you can use BIT on a zero-page location, then it is just a matter of doing this:
Note: This method does not affect what is in the Accumulator.
BIT ZP_BYTE
BMI *+2 - branch on bit #7 set
BVS - branch on bit #6 set
BVS - branch if both bits #6 and #7 are set
... - code falls through if neither bit #6 or #7 are set
LDA BYTE
BMI - branch if bit#7 set
ASL
BMI - branch if bit#6 set
or
LDA BYTE
LSR
BCS - branch if bit #0 set
ROR - preserve bit #0
BCS - branch if bit #1 set
some advantages of this method is that the you retain the original value in BYTE, if it is an address and not an immediate value. But also the Accumulator can be restored to its original value with a simple ROR for the first method and a ROL ROL for the second.
Also instead of using BIT on an immediate value, you can use BIT on a zero-page location, then it is just a matter of doing this:
Note: This method does not affect what is in the Accumulator.
BIT ZP_BYTE
BMI *+2 - branch on bit #7 set
BVS - branch on bit #6 set
BVS - branch if both bits #6 and #7 are set
... - code falls through if neither bit #6 or #7 are set
Re: BIT Instruction
Brilliant - thanks for the responses and help - lots to consider.
Re: BIT Instruction
Note that while CMP is often best if you need ALL target bits set, "BIT addr" does let individually testing bits 5-7 with a single test and then a sequence of branches based on the sign, overflow and zero flags.
I tried something along those lines in a recent effort to "crunch" an implementation of a Sweet16 VM ... https://github.com/BruceMcF/Sweeter16 ... but the space saved wasn't worth the trouble. Still, maybe someday it'll come in handy.
Code: Select all
LDA #$20
BIT SOURCEBYTE
BMI ++
BVS +
BEQ Act0
BNE Act1
+ BEQ Act2
BNE Act3
++ BVS +
BEQ Act4
BNE Act5
+ BEQ Act6
BNE Act7
Re: BIT Instruction
I think only the 65c02 and 65816 support BEQ/BNE with BIT that way. The 6502 does not, or at least one of the 6502's chips do not.
Re: BIT Instruction
IamRob wrote:
I think only the 65c02 and 65816 support BEQ/BNE with BIT that way. The 6502 does not, or at least one of the 6502's chips do not.
Quote:
bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V);
the zero-flag is set to the result of operand AND accumulator.
the zero-flag is set to the result of operand AND accumulator.
IOW, in the original opcodes, the mask is normally loaded into the accumulator before the BIT instruction, and the target is the operand, so pulling bit 7 and bit 6 into the sign and overflow flag is extra information "for free". But with "BIT #n" addressing, the mask is normally the operand and the target is normally in the accumulator, so reading in bits 7 and 6 of the constant "n" is not as useful.
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: BIT Instruction
IamRob wrote:
I think only the 65c02 and 65816 support BEQ/BNE with BIT that way. The 6502 does not, or at least one of the 6502's chips do not.
His example works with all members of the 6502 family. The improvement offered by the 65C02 and 65C816 is BIT immediate, which is handy for testing a value already loaded into the accumulator, e.g.:
Code: Select all
lda some_value
bit #%00000100The above tests bit 2 of whatever is in the accumulator.
x86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: BIT Instruction
The NMOS 6502 didn't have BIT# at all, nor BIT abs,X nor BIT ZP,X.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: BIT Instruction
Boy! do I look silly.
I have had this bit of code fail on me many times as a test, and assumed it wasn't supported.
It should have crashed and it didn't.
this is how I test If I want to know something specific about an instruction.
I have had this bit of code fail on me many times as a test, and assumed it wasn't supported.
It should have crashed and it didn't.
Code: Select all
lda #0
sta $6
bit $6
beq *+1
rts
brk
brk
Re: BIT Instruction
IamRob wrote:
Boy! do I look silly.
I have had this bit of code fail on me many times as a test, and assumed it wasn't supported.
It should have crashed and it didn't.
this is how I test If I want to know something specific about an instruction.
I have had this bit of code fail on me many times as a test, and assumed it wasn't supported.
It should have crashed and it didn't.
Code: Select all
lda #0
sta $6
bit $6
beq *+1
rts
brk
brk
Try *+2.
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: BIT Instruction
BruceRMcF wrote:
I don't know your assembler, but wouldn't *+1 as an operand be the first address after the address of the operand?
Good catch. I never use absolute references to the program counter in that way, as they can easily introduce pernicious bugs. There's a reason labels exist...
x86? We ain't got no x86. We don't NEED no stinking x86!