Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > How is carry affected by compare?
2010-11-10 19:40
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?
2010-11-10 19:44
chatGPZ

Registered: Dec 2001
Posts: 11154
cmp works exactly like sbc, except the result isnt stored in A
2010-11-10 19:46
Oswald

Registered: Apr 2002
Posts: 5031
http://www.6502.org/tutorials/compare_beyond.html#2.1
2010-11-10 20:01
JackAsser

Registered: Jun 2002
Posts: 1995
@Groepaz: Is a CMP really affected by the decimal-bit, like SBC is?
2010-11-10 20:01
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.
2010-11-10 20:18
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.
2010-11-10 20:36
Oswald

Registered: Apr 2002
Posts: 5031
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)
2010-11-10 20:47
chatGPZ

Registered: Dec 2001
Posts: 11154
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 :)
2010-11-10 20:59
JackAsser

Registered: Jun 2002
Posts: 1995
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
2010-11-10 21:07
Mace

Registered: May 2002
Posts: 1799
\o/
I love hardcore coding like this :-D
2010-11-10 22:11
Oswald

Registered: Apr 2002
Posts: 5031
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 :)
2010-11-11 10:31
Mace

Registered: May 2002
Posts: 1799
This is now on Codebase64.

The route is CPU (6502/6510) >> General Stuff >> Changing Registers.
2010-11-11 12:26
Oswald

Registered: Apr 2002
Posts: 5031
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.
2010-11-11 14:06
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?
2010-11-11 14:30
JackAsser

Registered: Jun 2002
Posts: 1995
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.
2010-11-11 16:07
yago

Registered: May 2002
Posts: 332
The Part about "CMP is exactly like SBC" is also wrong
2010-11-11 19:15
Mace

Registered: May 2002
Posts: 1799
@Yago: it's Wiki, anyone can change it ;-)

I removed the page.
2010-11-12 09:21
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

2010-11-12 09:42
Oswald

Registered: Apr 2002
Posts: 5031
the carry is set because of the result of the cmp, and not beforehand.
2010-11-12 09:56
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.
2010-11-12 13:43
Oswald

Registered: Apr 2002
Posts: 5031
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.
2010-11-12 14:05
JackAsser

Registered: Jun 2002
Posts: 1995
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)

2010-11-12 14:06
JackAsser

Registered: Jun 2002
Posts: 1995
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.
2010-11-12 14:17
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.
2010-11-12 14:29
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.
2010-11-12 14:34
Oswald

Registered: Apr 2002
Posts: 5031
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.
2010-11-12 14:50
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).
2010-11-12 15:08
JackAsser

Registered: Jun 2002
Posts: 1995
@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.
2010-11-12 15:12
Oswald

Registered: Apr 2002
Posts: 5031
agreed :)
2010-11-12 15:13
JackAsser

Registered: Jun 2002
Posts: 1995
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
2010-11-12 15:37
Oswald

Registered: Apr 2002
Posts: 5031
"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 :)
2010-11-12 15:57
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.

;-)
2010-11-12 16:16
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?! :)
2010-11-12 18:29
JackAsser

Registered: Jun 2002
Posts: 1995
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!
2010-11-12 18:40
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 ;-)
2010-11-12 20:56
Oswald

Registered: Apr 2002
Posts: 5031
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 :)
2010-11-13 09:57
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.
2010-11-13 10:31
Oswald

Registered: Apr 2002
Posts: 5031
I speculate about how cmp does its thing, wether it has a built in sec, or it just ignores the carry.
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
zzarko
DJ Gruby/TRiAD
Guests online: 74
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.7)
5 Edge of Disgrace  (9.7)
6 Aliens in Wonderland  (9.6)
7 Comaland 100%  (9.6)
8 Uncensored  (9.6)
9 No Bounds  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 Cubic Dream  (9.6)
3 Party Elk 2  (9.6)
4 Copper Booze  (9.6)
5 Rainbow Connection  (9.5)
6 It's More Fun to Com..  (9.5)
7 Dawnfall V1.1  (9.5)
8 Daah, Those Acid Pil..  (9.5)
9 Birth of a Flower  (9.5)
10 Quadrants  (9.5)
Top Groups
1 Nostalgia  (9.4)
2 Oxyron  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 SHAPE  (9.3)
Top Fullscreen Graphicians
1 Joe  (9.7)
2 Veto  (9.6)
3 Facet  (9.6)
4 The Sarge  (9.6)
5 Carrion  (9.5)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.095 sec.