| |
Mace
Registered: May 2002 Posts: 1799 |
How is carry affected by compare?
Somewhere I read that the carry is affected by the result of a compare.
It's not in the Prog.Ref.Guide, other than a flag in the register table.
How does this work?
|
|
... 27 posts hidden. Click here to view all posts.... |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
the carry is set because of the result of the cmp, and not beforehand. |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
Quote: the carry is set because of the result of the cmp, and not beforehand.
What does the CPU do?
1. C=1
2. subtracts
3. changes C depending on result
It does it quicker than a sec+sbc, of course. Saving 2 cycles. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: What does the CPU do?
1. C=1
2. subtracts
3. changes C depending on result
It does it quicker than a sec+sbc, of course. Saving 2 cycles.
cmp does not do that. IMHO.
http://www.6502.org/tutorials/compare_beyond.html#2.1
also check the illegals, it clearly shows there's a separate sbc instruction that works without the 'C' bit. fex. DCP is a sideeffect of CMP. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: cmp does not do that. IMHO.
http://www.6502.org/tutorials/compare_beyond.html#2.1
also check the illegals, it clearly shows there's a separate sbc instruction that works without the 'C' bit. fex. DCP is a sideeffect of CMP.
Cut'n'pasting from the VICE source, have fun:
SBC:
#define SBC(value, clk_inc, pc_inc) \
do { \
WORD src, tmp; \
\
src = (WORD)(value); \
CLK_ADD(CLK, (clk_inc)); \
tmp = reg_a_read - src - ((reg_p & P_CARRY) ? 0 : 1); \
if (reg_p & P_DECIMAL) { \
unsigned int tmp_a; \
tmp_a = (reg_a_read & 0xf) - (src & 0xf) - ((reg_p & P_CARRY) ? 0 : 1); \
if (tmp_a & 0x10) \
tmp_a = ((tmp_a - 6) & 0xf) \
| ((reg_a_read & 0xf0) - (src & 0xf0) - 0x10); \
else \
tmp_a = (tmp_a & 0xf) | ((reg_a_read & 0xf0) - (src & 0xf0)); \
if (tmp_a & 0x100) \
tmp_a -= 0x60; \
LOCAL_SET_CARRY(tmp < 0x100); \
LOCAL_SET_NZ(tmp & 0xff); \
LOCAL_SET_OVERFLOW(((reg_a_read ^ tmp) & 0x80) \
&& ((reg_a_read ^ src) & 0x80)); \
reg_a_write = (BYTE) tmp_a; \
} else { \
LOCAL_SET_NZ(tmp & 0xff); \
LOCAL_SET_CARRY(tmp < 0x100); \
LOCAL_SET_OVERFLOW(((reg_a_read ^ tmp) & 0x80) \
&& ((reg_a_read ^ src) & 0x80)); \
reg_a_write = (BYTE) tmp; \
} \
INC_PC(pc_inc); \
} \
while (0)
CMP:
#define CMP(value, clk_inc, pc_inc) \
do { \
unsigned int tmp; \
\
tmp = reg_a_read - (value); \
LOCAL_SET_CARRY(tmp < 0x100); \
LOCAL_SET_NZ(tmp & 0xff); \
CLK_ADD(CLK, (clk_inc)); \
INC_PC(pc_inc); \
} while (0)
|
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
As you can see, when in non-decimal mode, they're extremly similar and basically what Geir said.
SBC honous the C-bit on input and also affects the register and the overflow-bit on return, where as CMP does not. |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
Basically I was just pointing out that a sec+sbc gives you the same result in the processorstatusregister as a CMP. Period. What the 6510 does to accomplish it, I don't give a damn actually. |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
Quote: cmp does not do that. IMHO.
http://www.6502.org/tutorials/compare_beyond.html#2.1
also check the illegals, it clearly shows there's a separate sbc instruction that works without the 'C' bit. fex. DCP is a sideeffect of CMP.
It does a subtraction, and writes the result to the processorstatusregister. As Jackasser said, a compare doesn't carry the carry in (lol), but overwrites it.
Instead of:
lda freq_lo
sec
sbc freq_lo2
lda freq_hi
sbc freq_hi2
bcs portamento_direction
I do:
lda freq_lo
cmp freq_lo2
lda freq_hi
sbc freq_hi2
bcs portamento_direction
You save 2 cycles, yay!
And if you do smart stuff like this, it can get quite some cycles in the end. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: As you can see, when in non-decimal mode, they're extremly similar and basically what Geir said.
SBC honous the C-bit on input and also affects the register and the overflow-bit on return, where as CMP does not.
I can see some C code that doesnt proves much of the true inner workings of the 6502. Back to the original, my point is that CMP does not do a SEC. |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
Quote: I can see some C code that doesnt proves much of the true inner workings of the 6502. Back to the original, my point is that CMP does not do a SEC.
It doesn't do a SEC, okay, the cmp, cpx, cpy does its own inner subtraction thing then. But a compare gives the same result as a sec+sbc, except touching the A (X or Y). |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
@Oswald: Let me save the weekend for you with http://visual6502.org/JSSim/index.html :D Why not spend the time to check exactly how much chip-area that is common for SBC and CMP. I do not have the answer but I suspect it's alot. |
Previous - 1 | 2 | 3 | 4 - Next |