BIT instruction sets Z flag differently than AND instruction

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
ppelleti
Posts: 9
Joined: 10 Aug 2018
Location: Ventura, CA USA
Contact:

BIT instruction sets Z flag differently than AND instruction

Post by ppelleti »

I seem to not be understanding how the BIT instruction sets the Z flag. I had thought that the Z flag should be set if the accumulator anded with the value at the given address is zero? But I've written a simple test program that seems to show otherwise:

Code: Select all

        .export _main
        .import _exit

        .rodata
foo:    .byte $F0
        .code

.proc _main
        lda #$0F
        bit foo
        beq zero
        lda #1
        ldx #0
        jmp _exit
zero:   lda #2
        ldx #0
        jmp _exit
.endproc                        ; _main
If I assemble this with ca65 and then run it with sim65, it returns exit code 1, indicating it did not branch to the label "zero":

Code: Select all

WhiteAndNerdy:misc ppelleti$ cl65 -t sim6502 -o testbit testbit.s
WhiteAndNerdy:misc ppelleti$ sim65 testbit; echo $?
1
However, if I change the BIT instruction to an AND instruction, then it returns exit code 2, indicating it branched to the label "zero":

Code: Select all

WhiteAndNerdy:misc ppelleti$ cl65 -t sim6502 -o testbit testbit.s
WhiteAndNerdy:misc ppelleti$ sim65 testbit; echo $?
2
What am I missing here? Why does the BIT instruction set the Z flag differently than the AND instruction?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by GARTHWILSON »

Strange. If you look at the assembled output, do you get what you would expect? That part of BIT works the same as AND except that it does not store the result, only the zero or non-zero status in the Z flag. From the programming manual which every 65xx enthusiast should have, "Programming the 65816—Including the 6502, 65C02 and 65802" by David Eyes and Ron Lichty, in the section in the back entitled "The Instruction Sets," on the BIT page:
  • Second, it logically ANDs the data located at the effective address with the contents of the accumulator; it changes neither value, but sets the z flag if the result is zero, or clears it if the result is non-zero.
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?
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: BIT instruction sets Z flag differently than AND instruc

Post by Chromatix »

Does sim65 pass the test suites?
ppelleti
Posts: 9
Joined: 10 Aug 2018
Location: Ventura, CA USA
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by ppelleti »

It looks like this is a bug in sim65:

Code: Select all

static void OPC_6502_2C (void)
/* Opcode $2C: BIT abs */
{
    unsigned Addr;
    unsigned char Val;
    Cycles = 4;
    Addr = MemReadByte (Regs.PC+1);
    Val = MemReadByte (Addr);
    SET_SF (Val & 0x80);
    SET_OF (Val & 0x40);
    SET_ZF ((Val & Regs.AC) == 0);
    Regs.PC += 3;
}
I think that it should actually be

Code: Select all

    Addr = MemReadWord (Regs.PC+1);
I had just been assuming that it must be user error on my part, and not a bug in the simulator!
ppelleti
Posts: 9
Joined: 10 Aug 2018
Location: Ventura, CA USA
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by ppelleti »

Chromatix wrote:
Does sim65 pass the test suites?
What test suites should I be running on sim65?
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by BigEd »

Klaus' suite is a very good one. Several linked here:
http://visual6502.org/wiki/index.php?ti ... stPrograms

Welcome, by the way!
ppelleti
Posts: 9
Joined: 10 Aug 2018
Location: Ventura, CA USA
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by ppelleti »

I've gone ahead and submitted a pull request to fix sim65.
BigEd wrote:
Klaus' suite is a very good one. Several linked here:
http://visual6502.org/wiki/index.php?ti ... stPrograms
Thanks! I might look into porting it to sim65, to make sure there aren't any more bugs lurking there. sim65 doesn't seem to have its own test suite, and the overall test suite for cc65 only tests C programs. (I'm betting that the compiler never emits the BIT instruction, or only emits the zero-page version of it, which is why this bug hasn't been found before.)
BigEd wrote:
Welcome, by the way!
Thanks! I'm coming back to 6502 programming after being away for about 25 years.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: BIT instruction sets Z flag differently than AND instruc

Post by BigEd »

I don't think it's quite true that Klaus' suite has found problems in every emulator it's been tried on, but it's the great majority. Well worth using it as a regression test, or an acceptance test. If you find decimal mode is failing, it can be more convenient to switch to Bruce's tests for that, until things pass.

Testing a stateful system like an emulator is an art: there is too much complexity to be exhaustive, so you need to try to cover all the plausible failures. Sometimes it can be useful to try to measure coverage of a test suite and try to maximise it, but I don't think I've seen that approach in 6502 land. It's usually a surprise as to how low coverage is when you first measure it, and how difficult it is to get it to 100%.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: BIT instruction sets Z flag differently than AND instruc

Post by whartung »

BigEd wrote:
I don't think it's quite true that Klaus' suite has found problems in every emulator it's been tried on, but it's the great majority. Well worth using it as a regression test, or an acceptance test. If you find decimal mode is failing, it can be more convenient to switch to Bruce's tests for that, until things pass.

Testing a stateful system like an emulator is an art: there is too much complexity to be exhaustive, so you need to try to cover all the plausible failures. Sometimes it can be useful to try to measure coverage of a test suite and try to maximise it, but I don't think I've seen that approach in 6502 land. It's usually a surprise as to how low coverage is when you first measure it, and how difficult it is to get it to 100%.
Can't say that Klaus' suite catches everything, but I know it found issues in mine (not that I can recall what they were), and that I wouldn't trust any sim that can't pass this test.

Having developed a sim and an assembler side by side, with bugs in each, life can get very interesting.
Post Reply