Page 1 of 1

Retesting Accumulator flags

Posted: Tue Mar 05, 2024 7:02 am
by SparkyNZ
I am trying to wedge/hack some existing 6502 code that does a BMI instruction. Note that I don't want to insert any new code into the existing code - I'm replacing 3 bytes where possible with a JSR to my patch routine.

e.g.

Code: Select all

    nop            ; These 3 bytes I will replace with a jsr to my patch routine
    lda ($10),y  
return_point:
    bmi blah
I need to look ahead a bit further in my patch routine, but I need to restore Y, so I'm currently doing this:

Code: Select all

my_routine:
    lda ($10),y  
    cmp #$02
    bne skip_done
    iny             ; Skip my $02 byte
    lda ($10),y  ; Load A with next byte so original code doesn't realise there was a $02
    ; Negative flag is set here because it reads $DB
    dey            ; Decrement Y so that it can be used with a destination copy
    ; Negative flag no longer set
    rts
I apologise if I'm tired and talking complete rubbish but I am correct in that the DEY instruction will clear/set the negative flag based on the result of Y, yes?

Assuming I'm right about this, then how can I re-test the value in A so that the N flag becomes set according to the value of A?

I wonder if ORA #$00 would do the trick?

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 7:20 am
by BillG
cmp #0

will set the N flag according to the value in A.

That is all I can say without additional requirements.

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 7:40 am
by SparkyNZ
BillG wrote:
cmp #0

will set the N flag according to the value in A.

That is all I can say without additional requirements.
Perfect! I see ora #$00 seems to work too :-)

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 7:41 am
by BigDumbDinosaur
SparkyNZ wrote:
I wonder if ORA #$00 would do the trick?

Yes, and it’s a more “transparent” choice than CMP #$00.  By ORing with zero, the only flags that will be affected are n and z.

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 8:51 am
by GARTHWILSON
SparkyNZ wrote:
then how can I re-test the value in A so that the N flag becomes set according to the value of A?
You're using Y, so that's not available; but if X is not in use, you could meet your goal with a single byte using TAX.

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 9:04 am
by SparkyNZ
GARTHWILSON wrote:
SparkyNZ wrote:
then how can I re-test the value in A so that the N flag becomes set according to the value of A?
You're using Y, so that's not available; but if X is not in use, you could meet your goal with a single byte using TAX.
That's a cool idea - which will be helpful in the future. :-) Unfortunately there is a larger context here so I have to preserve the registers as best as I can.. I forgot to restore the contents of A before and got into trouble.. but PHA/PLA did the trick.

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 10:02 am
by BillG
SparkyNZ wrote:
I forgot to restore the contents of A before and got into trouble.. but PHA/PLA did the trick.
Be aware that PLA clobbers the flags...

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 1:50 pm
by IamRob
I have to say, that seems like a poor data structure. The 2 is being used as a signal byte for the next byte and the 2 is basically discarded. What a waste of a byte. If it is not a 2, then use that value. If it is a 2, then check the next byte to see if it is negative. A lot of times they can be combined and just use the byte with the hi-bit value with what I call a signal bit. The hi-bit is the signal to do something else. Then it is just a matter of BMI or BPL.

Re: Retesting Accumulator flags

Posted: Tue Mar 05, 2024 3:27 pm
by BigEd
(I'm thinking PHP, PLP is a natural way to save status. Of course it costs some cycles, but that will not usually matter.)

Re: Retesting Accumulator flags

Posted: Wed Mar 06, 2024 4:53 pm
by BruceRMcF
SparkyNZ wrote:
BillG wrote:
cmp #0

will set the N flag according to the value in A.

That is all I can say without additional requirements.
Perfect! I see ora #$00 seems to work too :-)
IIRC ...
CMP #0 -- will set/reset the S, Z and C flags

AND #$FF, ORA #0 -- will set/reset the S and Z flags, but not the C flag

For completeness, BIT #$80 -- will set/reset the Z flag based on the content of bit7, won't affect S or C (though not what you need here, since you need to restore the S flag to what it was when A was loaded)

Re: Retesting Accumulator flags

Posted: Thu Mar 07, 2024 6:51 am
by fachat
No, BIT will set the N(S?) and V flags to the bit 7 and bit 6 values of the tested location, and set the Z flag to the result of ANDing the accumulator with the value from the memory location. C is not changed.

Edit: sorry I described BIT abs/zp. Bruce wrote about BIT immediate. He's very likely right. BIT immediate is a CMOS opcode if I remember correctly, so will work on 65c02 and up, but not on an NMOS 6502

Re: Retesting Accumulator flags

Posted: Thu Mar 07, 2024 1:36 pm
by BruceRMcF
fachat wrote:
No, BIT will set the N(S?) and V flags to the bit 7 and bit 6 values of the tested location, and set the Z flag to the result of ANDing the accumulator with the value from the memory location. C is not changed.

Edit: sorry I described BIT abs/zp. Bruce wrote about BIT immediate. He's very likely right. BIT immediate is a CMOS opcode if I remember correctly, so will work on 65c02 and up, but not on an NMOS 6502
In the opcode summary I was looking out, it noted that BIT immediate is the only opcode where the immediate sets the flags differently from the other address modes. The operand of the BIT immediate would have been the source of the Sign and Overflow flags, and when they designed the 65C02 instructions, they must have decided that it was better to leave them alone than to set/clear them to a known state based on the immediate operand.

Re: Retesting Accumulator flags

Posted: Fri Mar 08, 2024 2:52 am
by BillG
There is one use case they did not foresee or chose to ignore: self-modifying the immediate operand of a BIT instruction to set or clear the N and V flags.

Re: Retesting Accumulator flags

Posted: Sat Mar 09, 2024 8:02 pm
by BruceRMcF
BillG wrote:
There is one use case they did not foresee or chose to ignore: self-modifying the immediate operand of a BIT instruction to set or clear the N and V flags.
Yeah, I reckon if someone wants to store a four way state, they can store it in the high two bits of a STATE value in zero page, and use "BIT STATE" to set the N and V flags simultaneously. So they may have figured that as already provided for by the NMOS 6502 instruction set.