Retesting Accumulator flags

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Retesting Accumulator flags

Post 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?
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Retesting Accumulator flags

Post by BillG »

cmp #0

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

That is all I can say without additional requirements.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: Retesting Accumulator flags

Post 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 :-)
User avatar
BigDumbDinosaur
Posts: 9426
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Retesting Accumulator flags

Post 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.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Retesting Accumulator flags

Post 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.
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?
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: Retesting Accumulator flags

Post 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.
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Retesting Accumulator flags

Post 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...
IamRob
Posts: 357
Joined: 26 Apr 2020

Re: Retesting Accumulator flags

Post 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.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Retesting Accumulator flags

Post 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.)
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Retesting Accumulator flags

Post 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)
fachat
Posts: 1124
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Retesting Accumulator flags

Post 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
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Retesting Accumulator flags

Post 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.
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Retesting Accumulator flags

Post 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.
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Retesting Accumulator flags

Post 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.
Post Reply