Page 1 of 1
Mini fun quiz: return a boolean in Z
Posted: Mon Apr 23, 2018 8:54 pm
by BigEd
It's not unusual for a routine to return a byte-sized value in A and a bit-sized value in C.
Suppose you also wanted to return a second bit-sized value, in Z - how would you tackle that?
Extra points for using fewer resources to do it.
For spoiler control, so you don't have to peek at previous responses if you don't want to, I'm going to put a lot of blank lines in - there's nothing more to see.
nothing to see here
-eot-
Re: Mini fun quiz: return a boolean in Z
Posted: Mon Apr 23, 2018 9:15 pm
by yzoer
Doesn't 'bit' perform a logical and between the accumulator and an address? IIRC it leaves the carry intact?
[Edit: It doesn't change the accumulator. So you could do something else here? I.e. ASL/BIT $nnnn]
Re: Mini fun quiz: return a boolean in Z
Posted: Mon Apr 23, 2018 9:26 pm
by BigEd
Ah, yes, BIT is well-made for that sort of thing. I was thinking of INC or DEC. But you do need a memory location to work with. Maybe that's fine... I was thinking of somehow using stack space. But it all gets rather tangled.
Re: Mini fun quiz: return a boolean in Z
Posted: Mon Apr 23, 2018 10:35 pm
by White Flame
BIT could constrain which value you're holding in .A, so I don't think that would be great. If you wanted to return zero in .A and the Z flag unset, that'd be quite difficult to do with just BIT.
I was thinking you'd set up a RAM byte with %000000ZC (with Z inverted), load up .A with your return value, then LSR that byte to set up C and Z.
Alternatively, if you wanted to use the stack instead of a scratch ZP location, push a flag byte to the stack, set up .A, then PLP and RTS. This way might be a few cycles faster, without a read-modify-write instruction involved, but the flags byte also might take a bit more setup than the LSR method.
Re: Mini fun quiz: return a boolean in Z
Posted: Tue Apr 24, 2018 7:59 am
by BigEd
Ah, PLP, that's a good thought. I'd been thinking about indirecting into the stack, but then you need to use or preserve X, and it's all too much.
Re: Mini fun quiz: return a boolean in Z
Posted: Mon Apr 30, 2018 9:53 pm
by GaBuZoMeu
With a 65802 or 65816 the SEP or REP should work (allthough not tested).
If you use the V Flag instead of Z you may set/clear V before reaching the end of the subroutine where you wish to return with a valid A and C.
The easiest way to return with an additional flag IMHO is using the D flag.
my 2 cents
Re: Mini fun quiz: return a boolean in Z
Posted: Tue May 01, 2018 12:22 am
by MichaelM
I vote for White Flame's LSR scheme.

Re: Mini fun quiz: return a boolean in Z
Posted: Sun May 06, 2018 12:04 am
by CurtisP
PHA/PLA don't affect the status register at all flag, so maybe something like this:
Code: Select all
;code to calculate byte value
PHA
;code to set C
;code to set Z
PLA
for example
Code: Select all
LDA VALUE ;Byte to Return
PLA
LDA CARRY ;Set Carry if Not Zero
CLC
ADC #255
LDA ZERO ;Set Z if Zero
PHA
Re: Mini fun quiz: return a boolean in Z
Posted: Sun May 06, 2018 12:26 am
by White Flame
PHA doesn't affect flags, but PLA does set N and Z to match the newly loaded accumulator value, as with any other load instruction. I also think your example might have PHA/PLA reversed, unless you're doing something even more clever.
Re: Mini fun quiz: return a boolean in Z
Posted: Mon May 28, 2018 7:45 am
by Chromatix
The D flag is easy to set and clear, but hard to test (requires PHP, PLA, BIT#) and interferes with arithmetic if the caller forgets to clear it. The V flag is easy to test but harder to set (though easy to clear) because there's no SEV (unless you're on a 65816). N and Z are easy to test, but are interfered with by almost every ALU operation.
In practice, 6502 software does use the V flag for this purpose since it's corrupted by relatively few instructions - only ADC. SBC, BIT (not #), RTI and PLP. You can set it reliably using LDA #&40, ADC #&40, which also sets N, and clears C and Z. Similar two-instruction sequences (substitute #&80 or #&C0 in the LDA) can leave N and Z in different states, though it's not possible to set both N and Z simultaneously this way. Only BIT is capable of altering Z independently of N, besides directly loading the status register. To preserve N and Z while loading A with the return value, you'll need PHP, PLP.
C, V, N and Z can be set simultaneously in arbitrary combinations using LDA#, PHA, ..., PLP. On CMOS chips you can also build these flags using the index registers. On the 65816 you can set and clear the flags explicitly using SEP/REP.