D (decimal) flag
Moderator: Moderators
-
- Posts: 20
- Joined: Fri Jun 26, 2020 2:57 am
- Contact:
D (decimal) flag
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.
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.
Re: D (decimal) flag
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.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?
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
Re: D (decimal) flag
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:
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:
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.
Code: Select all
PHP (3cyc)
PLA (4cyc)
AND #$08 (2cyc)
BEQ ...
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...
Re: D (decimal) flag
(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.
-
- Posts: 20
- Joined: Fri Jun 26, 2020 2:57 am
- Contact:
Re: D (decimal) 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.
Re: D (decimal) flag
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.wendelscardua wrote: ↑Sun May 23, 2021 8:12 pmFortunately 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.
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: D (decimal) flag
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.
Re: D (decimal) flag
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.
-
- Posts: 20
- Joined: Fri Jun 26, 2020 2:57 am
- Contact:
Re: D (decimal) flag
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)Ben Boldt wrote: ↑Sun May 23, 2021 8:24 pmOh 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.wendelscardua wrote: ↑Sun May 23, 2021 8:12 pmFortunately 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.
PHP + PLA sure is better
Re: D (decimal) flag
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.