6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 2:23 am

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: BIT Instruction
PostPosted: Wed Jan 05, 2022 10:49 pm 
Offline

Joined: Fri Jun 04, 2021 5:45 pm
Posts: 5
Location: Chelmsford, Essex
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!


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Wed Jan 05, 2022 10:57 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 37
Location: Tatooine
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.

Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Wed Jan 05, 2022 11:01 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
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..

_________________
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?


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Wed Jan 05, 2022 11:07 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 37
Location: Tatooine
BB8 wrote:
It will transfer bits 7 and 6 of the content of the location $C0 to the flags Z and V


sorry: it will transfer bit 7 and 6 to N and V.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Thu Jan 06, 2022 12:11 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
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.

For that particular example I would use CMP #$C0 ... if carry is set then bits 6 and 7 are both set, if carry is clear then one or both bits are clear. Woz used the negative flag after a CMP #$C0 in his 1976 floating point package's normalization routine to check if bits 6 and 7 were the same or not, a tidy hack that wouldn't have occurred in the minds of most mortals.

So, we have:
Code:
    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:
    ...
This untested example doesn't disturb any registers or memory, only the flags ... if that's not a concern then smaller versions are available.

_________________
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)


Last edited by barrym95838 on Thu Jan 06, 2022 4:34 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Thu Jan 06, 2022 12:42 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
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


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Thu Jan 06, 2022 8:07 pm 
Offline

Joined: Fri Jun 04, 2021 5:45 pm
Posts: 5
Location: Chelmsford, Essex
Brilliant - thanks for the responses and help - lots to consider.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Fri Jan 21, 2022 11:36 pm 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
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.

Code:
    LDA #$20
    BIT SOURCEBYTE
    BMI ++
    BVS +
    BEQ Act0
    BNE Act1
+   BEQ Act2
    BNE Act3

++  BVS +
    BEQ Act4
    BNE Act5
+   BEQ Act6
    BNE Act7


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.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 12:45 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
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.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 1:11 am 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
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.


AFAIU, that's the 6502 BIT I knew on the C64: https://www.masswerk.at/6502/6502_instruction_set.html#BIT

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 BIT address modes that the 65C02 adds are "BIT zp,X", "BIT addr,X" and "BIT #n" ... "BIT #n" is especially handy. However loading bit 7 and bit 6 of the operand doesn't do much good with "BIT #n", because it comes from the "n", so you already know whether it has bits 6 and 7 set.

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.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 1:36 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
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:
          lda some_value
          bit #%00000100

The above tests bit 2 of whatever is in the accumulator.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 1:36 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8544
Location: Southern California
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?


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 1:53 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
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.
Code:
   lda #0
   sta $6
   bit $6
   beq *+1
   rts
   brk
   brk

this is how I test If I want to know something specific about an instruction.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 12:59 pm 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
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.
Code:
   lda #0
   sta $6
   bit $6
   beq *+1
   rts
   brk
   brk

this is how I test If I want to know something specific about an instruction.


I don't know your assembler, but wouldn't *+1 as an operand be the first address after the address of the operand? That would be the address of the RTS instruction. So it could be taking the branch and returning, where you are concluding it failed to take the branch and returned.

Try *+2.


Top
 Profile  
Reply with quote  
 Post subject: Re: BIT Instruction
PostPosted: Sat Jan 22, 2022 1:50 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8507
Location: Midwestern USA
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... :D

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 32 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: