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?
 
... 27 posts hidden. Click here to view all posts....
 
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.
Previous - 1 | 2 | 3 | 4 - Next
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
t0m3000/HF^BOOM!^IBX
acrouzet/G★P
Didi/Laxity
Guests online: 45
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 Coders
1 Axis  (9.8)
2 Graham  (9.8)
3 Lft  (9.8)
4 Crossbow  (9.8)
5 HCL  (9.8)

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