| |
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?
|
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
cmp works exactly like sbc, except the result isnt stored in A |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
http://www.6502.org/tutorials/compare_beyond.html#2.1 |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
@Groepaz: Is a CMP really affected by the decimal-bit, like SBC is? |
| |
Mr. SID
Registered: Jan 2003 Posts: 424 |
cmp is like sbc but the carry is set before automatically, so you don't have to do that.
|
| |
Mace
Registered: May 2002 Posts: 1799 |
So in the following code, both SEC and CLC are useless?
lda #{some value}
sec
cmp #$00
beq !fwrd+
clc
!fwrd:
rts
I know that the whole CMP is not needed, but the purpose of the routine is to SEC when A<>0 and CLC when A=0. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
according to my link this should work:
cmp #$00
beq +
clc
+
(If the C flag is 1, then A (unsigned) >= NUM (unsigned) and BCS will branch) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:@Groepaz: Is a CMP really affected by the decimal-bit, like SBC is?
i dont know - but internally a CMP really _is_ a SBC, ie the exact same operation is performed, using the same logic blocks. so it should be like you say, would make sense at least :) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: according to my link this should work:
cmp #$00
beq +
clc
+
(If the C flag is 1, then A (unsigned) >= NUM (unsigned) and BCS will branch)
cmp #$01
>=1 => C=1
<1 => C=0
|
| |
Mace
Registered: May 2002 Posts: 1799 |
\o/
I love hardcore coding like this :-D |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: cmp #$01
>=1 => C=1
<1 => C=0
you win. I had the idea that one cmp may be enough, but too tired to think it trough :P :) |
| |
Mace
Registered: May 2002 Posts: 1799 |
This is now on Codebase64.
The route is CPU (6502/6510) >> General Stuff >> Changing Registers. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
uhh, rather remove that.. and add a link to the 6502.org tutorials... checking when A is zero is generally done with the Z bit anyway. It will just confuse newcomers. |
| |
Mace
Registered: May 2002 Posts: 1799 |
Better extend the tut on Codebase, because I found the 6502.org explanation rather confusing.
It's not wrong what I wrote on Codebase, so why remove it? |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: Better extend the tut on Codebase, because I found the 6502.org explanation rather confusing.
It's not wrong what I wrote on Codebase, so why remove it?
@Mace: Indeed confusing. Personally I use the more simple explanation they have on: http://www.6502.org/tutorials/compare_instructions.html
Check the table labeled "Use of Branch Instructions with Compare". That is really all you need, promise.
|
| |
yago
Registered: May 2002 Posts: 333 |
The Part about "CMP is exactly like SBC" is also wrong
|
| |
Mace
Registered: May 2002 Posts: 1799 |
@Yago: it's Wiki, anyone can change it ;-)
I removed the page. |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
CMP is:
sec
sbc
I use this method alot in 16-bits checks:
lda freq_low
cmp freq_low2
lda freq_high
sbc freq_high2
bcs/bcc whatever
|
| |
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. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
agreed :) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: agreed :)
Also, I'm quite sure both SBC and CMP uses the ALU-block of the CPU to perform the subtraction. It would be quite wasteful otherwise. :D |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"check exactly how much chip-area that is common for SBC and CMP"
yes, probably a lot, thats why its an sbc without carry IMHO,and not a sec+sbc :) |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
IMHO Oswald and Jackasser are confusing newbe's with "big-coca-cola-glasses", trying to explain what goes on inside the silicon.
CMP #$40 for instance, gives you the same result(READ RESULT) except touching the A, as:
SEC
SBC #$40
Don't listen to them newbe's.
;-) |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
I do admire Oswald and Jackasser coding skills. Don't take me wrong. :)
I'm curious, though, about the inner workings. I guess Mace got his answer how the CMP affects the carry by now?! :) |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: I do admire Oswald and Jackasser coding skills. Don't take me wrong. :)
I'm curious, though, about the inner workings. I guess Mace got his answer how the CMP affects the carry by now?! :)
Mnaw! :D But yeah, we're just attention whores really! :D Happy WE! |
| |
Mace
Registered: May 2002 Posts: 1799 |
Yes, the answer is clear. Thanks for that!
And although the related subjects are interesting too, I think most if not all is said by now ;-) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
what jackie said, and as I think about it, implementing it with the "implied" SEC way may be just as simple as doing an SBC which just ignores the carry. Someone ask Chuck Peddle :) |
| |
GT Account closed
Registered: Sep 2008 Posts: 308 |
Quote: what jackie said, and as I think about it, implementing it with the "implied" SEC way may be just as simple as doing an SBC which just ignores the carry. Someone ask Chuck Peddle :)
A simple SBC doesn't ignore the carry. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
I speculate about how cmp does its thing, wether it has a built in sec, or it just ignores the carry. |