Page 1 of 1
BIT instruction sets Z flag differently than AND instruction
Posted: Fri Aug 10, 2018 6:43 pm
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?
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 7:06 pm
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.
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 7:12 pm
by Chromatix
Does sim65 pass the test suites?
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 7:13 pm
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
I had just been assuming that it must be user error on my part, and not a bug in the simulator!
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 7:16 pm
by ppelleti
Does sim65 pass the test suites?
What test suites should I be running on sim65?
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 7:38 pm
by BigEd
Klaus' suite is a very good one. Several linked here:
http://visual6502.org/wiki/index.php?ti ... stPrograms
Welcome, by the way!
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 11:19 pm
by ppelleti
I've gone ahead and submitted a
pull request to fix sim65.
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.)
Thanks! I'm coming back to 6502 programming after being away for about 25 years.
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Fri Aug 10, 2018 11:26 pm
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%.
Re: BIT instruction sets Z flag differently than AND instruc
Posted: Tue Aug 14, 2018 4:58 pm
by whartung
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.