D (decimal) flag

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
wendelscardua
Posts: 20
Joined: Fri Jun 26, 2020 2:57 am
Contact:

D (decimal) flag

Post by wendelscardua »

I know the D flag doesn't affect ADC/SBC operations on the NES, but... is the flag itself affected by SED/CLD on the real hardware?

Context: I'm porting some bcd floating point math package to ca65 for fun, but it uses both binary and bcd versions of ADC/SBC. The code seems to be optimized (i.e. lots of jmps) so it's not trivial to know if a given ADC/SBC is expected to be a binary or bcd operation. My plan is to replace uses of those operations with calls to procedures that will check the D flag and then compute the binary or bcd result based on it.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: D (decimal) flag

Post by Quietust »

wendelscardua wrote: Sun May 23, 2021 9:26 am I know the D flag doesn't affect ADC/SBC operations on the NES, but... is the flag itself affected by SED/CLD on the real hardware?
Yes, it is - the flag still exists and is affected by the SED/CLD/PLP/RTI instructions. The only thing that is known to have been changed in the 6502 embedded within the RP2A03/RP2A07 is that the D flag was disconnected from the ALU.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: D (decimal) flag

Post by Ben Boldt »

Is there any reasonable way to use this flag on the NES? It seems potentially useful to have a general-use flag that gets pushed and pulled from the stack automatically. It is easy to set and clear the flag, but how on earth do you branch based on the flag? The only way I can think of is to do:

Code: Select all

PHP (3cyc)
PLA (4cyc)
AND #$08 (2cyc)
BEQ ...
That's 9 extra cycles setting up for the branch, pretty inefficient. I guess there isn't a BRA instruction either so "BRD" wouldn't have had much chance.

Another way:

Code: Select all

PHP (3cyc)
TSX (2cyc)
LDA #$08 (2cyc)
AND $0100,X (4cyc)   ; This may need DEX or AND $00FF,X, +2 or +1 cycles (respectively) as I understand)
BEQ...
11 cycles, so that's worse and also uses X. And I left the stack messed up. Probably could use the DEX option and then add a TXS, making 15 cycles. I don't see a path to an improvement there.
strat
Posts: 409
Joined: Mon Apr 07, 2008 6:08 pm
Location: Missouri

Re: D (decimal) flag

Post by strat »

(Edited to clarify the overflow flag.) The carry flag pretty much is your general use flag. And if you need an unconditional branch, anything is going to be more wasteful than just using jmp (bvc might work if the numbers always stay within a positive or negative range - the flag is set by any math that results in an invalid signed number).
Last edited by strat on Mon May 24, 2021 2:11 pm, edited 1 time in total.
wendelscardua
Posts: 20
Joined: Fri Jun 26, 2020 2:57 am
Contact:

Re: D (decimal) flag

Post by wendelscardua »

Ben Boldt wrote: Sun May 23, 2021 3:42 pm It is easy to set and clear the flag, but how on earth do you branch based on the flag?
Fortunately my use of the flag doesn't have to be optimized (I'm just trying to make a NES calculator for fun), so I just PHP, check the value of the flag on the stack, then PLP later to preserve the flags.
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: D (decimal) flag

Post by Ben Boldt »

wendelscardua wrote: Sun May 23, 2021 8:12 pm
Ben Boldt wrote: Sun May 23, 2021 3:42 pm It is easy to set and clear the flag, but how on earth do you branch based on the flag?
Fortunately my use of the flag doesn't have to be optimized (I'm just trying to make a NES calculator for fun), so I just PHP, check the value of the flag on the stack, then PLP later to preserve the flags.
Oh you should do what I did in the first example: PHP then PLA. It pushes the status register to the stack, then pulls it straight back from the stack into A. This restores the stack and now you don't have to directly access the stack memory. Let me know if you don't understand that and I can try to explain it better.
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: D (decimal) flag

Post by Oziphantom »

Run the code on something else with a 6502, Commodore 64 for example, then you can step through the code and get a register state as you step in the monitor. You can run if for an operation and use chis to get a run in a decent compact form.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: D (decimal) flag

Post by Bregalad »

Ben Boldt wrote: Sun May 23, 2021 3:42 pm Is there any reasonable way to use this flag on the NES? It seems potentially useful to have a general-use flag that gets pushed and pulled from the stack automatically.
It is automatically pushed to and pulled from the stack only on interrupts (NMI and IRQs).
I fail to see any practical use of this flag to store information for the program running on the platform. Sure it is easy to clear and set, and is affected by no instructions (other than PLP and RTI), so it can easiy keep a "state" bit. However checking it is inneficient because PHP/PLA/AND #$08 is required. As such, storing game state in RAM is overall faster and easier.

The only exeption would be if you'd need to set/clear this bit in a lot of places and check it only once or twice. In that case it might be faster/smaller to use the D flag to store the information... but I fail to see any example where this'd be the case.
Useless, lumbering half-wits don't scare us.
wendelscardua
Posts: 20
Joined: Fri Jun 26, 2020 2:57 am
Contact:

Re: D (decimal) flag

Post by wendelscardua »

Ben Boldt wrote: Sun May 23, 2021 8:24 pm
wendelscardua wrote: Sun May 23, 2021 8:12 pm
Ben Boldt wrote: Sun May 23, 2021 3:42 pm It is easy to set and clear the flag, but how on earth do you branch based on the flag?
Fortunately my use of the flag doesn't have to be optimized (I'm just trying to make a NES calculator for fun), so I just PHP, check the value of the flag on the stack, then PLP later to preserve the flags.
Oh you should do what I did in the first example: PHP then PLA. It pushes the status register to the stack, then pulls it straight back from the stack into A. This restores the stack and now you don't have to directly access the stack memory.
Oh, I was just being dumb - somehow I thought doing PLA would mess with the C flag 😅 (like I didn't have a 6502 Reference tab open at all times)

PHP + PLA sure is better :)
User avatar
Ben Boldt
Posts: 1149
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: D (decimal) flag

Post by Ben Boldt »

Bregalad wrote: Mon May 24, 2021 1:46 am The only exeption would be if you'd need to set/clear this bit in a lot of places and check it only once or twice. In that case it might be faster/smaller to use the D flag to store the information... but I fail to see any example where this'd be the case.
Yes I agree. Even in that case, dedicating a byte of RAM is probably always faster and easier. 65C02 has those awesome zero-page bitwise set and branch opcodes. I am just trying to think of a way to do something like that with this D bit which is otherwise completely useless.
Post Reply