6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Apr 25, 2024 2:26 am

All times are UTC




Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: please help me!
PostPosted: Fri Nov 15, 2002 1:50 am 
Offline

Joined: Fri Nov 15, 2002 1:44 am
Posts: 1
Why do I have to set C when I use SBC #dd?

Thanks


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Nov 15, 2002 6:02 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
> Why do I have to set C when I use SBC #dd?

SBC is "SuBtract with Carry." C (the "carry" flag), when used in subtraction, is really a "borrow-not" flag. Starting with it clear generally means a borrow occurred in a previous subtraction, so you will be subtracting one additional unit. For example:

Starting with C set, 8-8 gives 0, and C remains set.
Starting with C clear, 8-8 gives -1 and C remains clear.
Starting with C set, 8-9 gives -1 and C gets cleared.
Starting with C clear, 9-8 gives 0, and C gets set.

If the state of the carry flag is guaranteed to be a certain way before starting a subtraction, sometimes you can eliminate the SEC instruction. (The same goes for CLC and addition.)

Garth


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 13, 2002 1:08 am 
Offline

Joined: Fri Dec 13, 2002 12:57 am
Posts: 1
Location: Blackwood, NJ
One way to make it easier to code subtractions in assembly language is to make 'CLB' (Clear Borrow) a synonym for 'SEC'. Similarly, make 'BNB' a synonym for 'BCS' and 'BB' a synonym for 'BCC'. Of course, this will confuse anyone else who might read your code.

Willi


Top
 Profile  
Reply with quote  
 Post subject: Re: please help me!
PostPosted: Sat Jan 04, 2003 10:22 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
cao9981 wrote:
Why do I have to set C when I use SBC #dd?

Thanks


As you know, subtraction is really addition:

3 - 2 = 1 and 3 + (-2) = 1

Because it's easier to perform a 1's compliment in hardware (a bunch of XOR gates) than a 2's compliment (a bunch of XOR gates, and a full-adder). As a result, subtraction in the 6502 engages the 1's compliment of one of the operands to the ALU, where the ALU just performs a simple addition.

BUT, since performing a 1's compliment also yields a result that is one less than what's expected, to get proper results, we also need a way to re-add that 1 back into the result. The cheapest way to do this is to set the carry bit. So, to the computer, it looks like this:

3 + (2 XOR #$FF) + 1 = 1

(the +1 is from setting the carry!)

So, if you ever need to solve a math problem like A-B-1, you can code it simply enough:

LDA operand_A
CLC
SBC operand_B

(note that the CLC guarantees we have A-B-1, and not just A-B)


Top
 Profile  
Reply with quote  
 Post subject: Subtract with borrow
PostPosted: Sun Jan 05, 2003 8:12 pm 
Offline

Joined: Sat Aug 31, 2002 12:33 pm
Posts: 64
Location: USA
Hi Everyone,

What was said is true but I just want to explain it a little bit
differently.

On most processors when you want to subtract two bytes
with the "subtract-with-carry or subtract-with-borrow" instruction,
you make sure that the carry bit is clear. This by the way
also applies when using the "add with carry or add-with borrow"
instruction. Again, for single-byte arithmatic you always want
the carry-bit clear at the start.

On the 6502, the ADC instruction follows this industry standard
convention.

Now here is where the confusion comes-in...

On the 6502, the SBC instruction DOESN'T follow this industry
standard convention. Instead, the carry-bit is cleared after
a larger number is subtracted from the contents of the
accumulator. Consequently, the carry-bit is set after a smaller
number is subtracted from the contents of the accumulator.

This is why the carry-bit must be SET (instead of normally cleared)
before an SBC instruction.

This was probably a bug in the original design of the chip because it
departs from the industry standard and by-the-way goes
against the convention that the ADC instruction uses (in the 6502).


Cheers,

Paul


Top
 Profile  
Reply with quote  
 Post subject: Re: Subtract with borrow
PostPosted: Mon Jan 06, 2003 1:52 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
orac wrote:
Hi Everyone,
This was probably a bug in the original design of the chip because it
departs from the industry standard and by-the-way goes
against the convention that the ADC instruction uses (in the 6502).


As I've outlined above, I've demonstrated how "going against industry standards," and thinking about what really makes something tick, can cut a whole full-adder (and associated look-ahead carry generation logic) from the ALU logic, which is one of the contributing factors to the 6502's extremely low prices (especially when it was first introduced) and, today, high execution speeds. The observation that the 2's compliment is the 1's-compliment plus 1 is not something discovered recently. It was well known for decades before the 6502 was introduced.

In fact, this kind of hardware simplification is largely the reason for the existance of little-endian number formatting (which you'll note the 6502 also uses). Too many people think it's a number formatting that has no real, practical use, and that Intel invented it purely for the torment of programmers everywhere. Nothing could be further from the truth.

Little-endian numbers permits an 8-bit ALU to manipulate 16-bit or larger data as it's being fed in over the 8-bit bus. This greatly simplifies the hardware. In contrast, something like the 680x series of CPUs has to read in the whole set of 16-bit words first, then process the data with a 16-bit ALU. That's a lot of hardware overhead for a processor that only has an 8-bit bus.

Remember that the inventor of the 6502 also is responsible for the Motorola 6800. He saw the 6800 as an incredibly inefficient machine that could be simplified with a large performance boost. He originally brought his idea to his boss at Motorola, who told him 'no'. He later left Motorola, and went to MosTek (later bought out by Commodore Semiconductors, Ltd.), where he was free to design and implement the 6500, and later the 6502. Ultimately, he founded Western Design Center.

Desigining hardware is somewhat like designing efficient software. The 6502 is an exercise in designing efficient hardware (for its time; indeed, for an 8-bit CISC architecture, it's still arguably the most efficient in the world). Remember that the Z-80, and all other "industry standard" processors of the day, cost between $100 and $200 each. The 6502, in stark contrast, was as cheap as $25 if you knew where to get it, and it was easily twice the performance of its competitors. "Bugs" like the one discussed above are the sole contributor to this price/performance ratio. Indeed, no matter where you look, the most powerful, the most flexible, and the least costly hardware is always the one with the least amount of gates and the highest interconnection possibilities.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 06, 2003 2:20 am 
Offline

Joined: Sun Sep 15, 2002 10:42 pm
Posts: 214
Uh. You're confusing MOS Technologies and Mostek, which are totally different companies.

Mostek was a company in Carrollton, Texas (I think) which second-sourced the Z80, among other things. Their Z80 part number was the MK3880 iirc.
They also did one of the first byte-wide static RAMs, the MK4118.

MOS Technologies is the Pennsylvania company that manufactured the 6502. Not Mostek. This is a very common misconception.

Toshi


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 06, 2003 4:29 pm 
Offline

Joined: Wed Sep 04, 2002 4:08 pm
Posts: 57
Location: Iowa
I doubt the 6502 was the first processor to eliminate two 8-bit full adders in a subtraction unit and feed an inverted carry to the first bit's full adder. I'd bet the processors that use a cleared carry instead of a set carry as the increment in the two's complement simply inverted the carry flag on subtraction. This would cost one XOR gate, not an extra full adder.

The Z-80 was more expensive, but it also had more features, such as two banks of registers (and more registers at that), a dynamic RAM refresh, and (I think) separate ADD/ADC and SUB/SBC instructions.

I believe the 6502 (which I love dearly) was cheaper because of a reduced feature set, MOS's fabrication technology, and even a few unfixed or overlooked bugs.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jan 06, 2003 8:33 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
>The Z-80 was more expensive, but it also had more features, such as
> two banks of registers (and more registers at that), a dynamic RAM
> refresh, and (I think) separate ADD/ADC and SUB/SBC instructions.

That did not make it faster though. In a sense, all 256 bytes of zero page is processor registers for the 6502. The '02 took a lot less clocks to do a job.

There were a couple of paragraphs in an article by Jack Crenshaw in the 9/98 issue of Embedded Systems Programming where he talks about different BASICs he used on computers in the 70's and 80's, and said the 6800 and 6502 always seemed to run them faster than any other processor. He says that to him, the 6502 was a "near knock-off" of the 6800, and says he liked the 6800 architecture far more than that of the 80 family, even though his work made him much more familiar with the latter. Quoting two paragraphs:

"To me, the 8080 and Z80 always seemed to be superior chips
to the 6800 and 6502. The 8080 had seven registers to the
6800's two (plus two index registers). The Z80 added
another seven, plus two more index registers. Nevertheless,
I can't deny that, benchmark after benchmark, BASIC
interpreters based on the 68s consistently outperformed
those for the 80s.

"The biggest problem with the 68s was that they had no
16-bit arithmetic. Though the 8080 and Z80 were basically
8-bit processors, at least they had 16-bit registers (three
for the 8080, eight for the Z80), and you could actually
perform arithmetic in them, shift them, test them, and so
on. You couldn't do any of these things with the 6800 or
6502, which is one reason I still don't understand, to this
day, how the 68s could outperform the 80s in benchmarks."

After learning the 6502's instruction set and bus usage, I remember being impressed by the relative inefficiency of the 80 family, including the number of clock cycles it took to execute a single instruction, and how many extra instructions were needed because it did not have things like the 6502's automatic decimal arithmetic with the D flag, and the compare-to-0 implied in all logical, bit, arithmetic, and load instructions. Even on a PIC (which is supposedly a blazingly fast little RISC), an interrupt, saving the status register (which is automatic on the '02) and W (the working register, which is equivalent to our accumulator) takes 28 clocks compared to the 6502's 11.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jan 07, 2003 1:52 am 
Offline

Joined: Sat Aug 31, 2002 12:33 pm
Posts: 64
Location: USA
Hi Garth,

Good post. I started assembly language on the 6800 and wrote
some interesting applications. The 6800 is fast because it has
two accumulators. 16-bit arithmatic was fast because of this
and you didn't have to waste an instruction setting or clearing
the carry bit. The 8085 and 6800 both have 16-bit loads and
stores. Even in a controller application you deal with 16-bit
quantities a lot (like pointers). The 6800 had a CPX instruction
which could test a 16-bit quantity for equal or not equal.
The 8085/Z80 had a faster clock for the ALU so even though the
bus-speed was the same as the 6502 they could do complex instructions faster.

At 4Mhz an 8085 executes the shortest instruction in one usecond.
At 1Mhz (similar bus speed as 4Mhz 8085) a 6502 executes the
shortest instruction in two useconds.

It is interesting that nintendo had 6502 experience but went with
an 8085 clone for the gameboy where Atari had 6502 experience
and went with same for their pocket PC. Psion incidently went with
the 6303 which was a 6803 clone (that's a whole other post) from
hitachi.

The 6502 being-cheaper-than-the-6800 was (and is) a major factor
in its value. As far as comparing instruction-sets, just take your
favorite routine (like downloading s-records) code-it-up in both 6502
and 6800 assembly languages and see which one you like. It's
that simple!


Cheers,

Paul


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jan 07, 2003 2:55 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
orac wrote:
At 4Mhz an 8085 executes the shortest instruction in one usecond.
At 1Mhz (similar bus speed as 4Mhz 8085) a 6502 executes the
shortest instruction in two useconds.


How fortunate it is that the shortest operations performed in 6502 assembly language also happen to NOT be the most frequently executed. Nearly all 2-byte operations that do not involve auxiliary memory accesses (typically instructions which take an immediate value) ALSO execute in only two microseconds. Those that DO perform auxiliary bus transactions do so with (usually) one microsecond per byte transfered (e.g., a LDA Absolute instruction takes four cycles: three for the opcode and one for the byte fetched). Thus, most cycle times for the most commonly used 6502 instructions end up being SHORTER than their 8085/Z-80 equivalents. The *ONLY* time the Z-80 is faster is when executing the LDIR/LDDR instructions (block move). I don't know how the 65816's MVP/MVN instructions compete with LDIR, but I suspect they're on par, if not faster, due to the 65816's single-clock memory cycle.

All assuming a 1MHz clock, of course.

This is why an 8MHz 65816 is actually quite competitive with an 8MHz 68000, and utterly decimates the 8085/8086 at those speeds. It takes at least an 80286 before you start coming into the ballpark.

According to my programmers book on the 65816, the January, 1983 issue of BYTE magazine had a set of benchmarks posted for the 65816 in comparison to other processors: a 4MHz 65816 completed the seive in 1.56 seconds. A 5MHz 8088 took 4.0 seconds (!!), while an 8 MHz 8086 took 1.90 seconds.

That being said, note how the 65816 soundly kicks the 808x series butts. According to the article, it's true that the 65816 was twice as fast as the equivalent 6502 program. Thus, the 6502 at 4MHz (having taken roughly 3 seconds to complete) clearly defeated the 5MHz 8088 (having taken 4 seconds). Thus, an 8088 at 4MHz would have taken longer still. An 8-bit CPU defeated a 16-bit CPU! How do you explain this?

Looking at it a different way:

Code:
Estimated coefficient of "work" involved in completing a task:

  68000  8MHz * 0.49 seconds = 3.92
  65816  4MHz * 1.53 seconds = 6.12
   6502  4MHz * 3.06 seconds = 12.24
   8086  8MHz * 1.90 seconds = 15.20
   8088  5MHz * 4.00 seconds = 20.00

Normalized performances:

  68000  8MHz = 0.49 seconds
  65816  8MHz = 0.73 seconds
   6502  8MHz = 1.53 seconds
   8086  8MHz = 1.90 seconds
   8088  8MHz = 2.50 seconds


Looking at the numbers, it's clear that even the 4MHz 6502 is better than the 8MHz 8086.

The only processor it couldn't match was an 8MHz 68000, which completed its task in only 0.49 seconds. That being said, note that a relatively choked 8MHz 65816 would come awfully close to that 68000, completing the task in only 0.73 seconds.

Now before you argue that the 65816 is a totally different processor, let me remind you it's just a 16-bit extended 6502, complete with an 8-bit data bus. If the 65816 wasn't so choked by its data bus, and using even addresses for all 16-bit quantities stored in memory, it would equal or exceed the 68000 for most tasks.

The clocks-per-memory-cycle ratio is critical, and the closer to unity it is (and you really can't get much better than the 6502 unless you go full-bore RISC), the better. That, along with its pipelining and reduced gate counts, is why the 6502 is fast.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Jan 07, 2003 5:36 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
> As far as comparing instruction-sets, just take your
> favorite routine (like downloading s-records) code-it-up in both 6502
> and 6800 assembly languages and see which one you like. It's
> that simple!

We had such a comparison thread some time back on the Delphi forum that really made me hit the books since I'm not all that familiar with the 6800. (It's still there if you want to go back and read it.) There were several minor differences between the 6800 and 6502, with pros and cons on both sides.

In the last decade, the 6800 developed more in the microcontroller area, but the 65's are available at much higher clock speeds and now as kc5tja points out, the 65816 really added a whole lot of extra power to the family.

But going back to when it was just the 6800 versus 6502-- Bill Ragsdale's FIG-Forth ran about 25% faster on the 6502 than it did on the 6800 at a given clock speed.

Garth

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Jan 08, 2003 12:08 am 
Offline

Joined: Mon Dec 23, 2002 8:47 pm
Posts: 70
I wonder how it would run, a DOS+Windows 3.10 clone on a 20 MHz 65816. :þ


Top
 Profile  
Reply with quote  
 Post subject: 6502 and speed
PostPosted: Wed Jan 08, 2003 12:19 am 
Offline

Joined: Sat Aug 31, 2002 12:33 pm
Posts: 64
Location: USA
Hi Everyone,

I tabulated some instruction times for an 8085 at 4Mhz and
a 6502 at 1Mhz.


ADD immediate


Top
 Profile  
Reply with quote  
 Post subject: 6502 times
PostPosted: Wed Jan 08, 2003 12:56 am 
Offline

Joined: Sat Aug 31, 2002 12:33 pm
Posts: 64
Location: USA
Sorry, I accidently hit the send key too early.

6502 at 1Mhz (no wait states)
8085 at 4Mhz (no wait states)

all times are in useconds

Code:
                6502     8085         Notes
ADD immediate    4       1.75         extra instr. to clear carry (6502)
AND immediate    2       1.75
SUB immediate    4       1.75         extra instr to set carry (6502)
BRANCH COND.    2/3     1.75/2.5      not-taken/taken
CALL immediate   6       4.5
RET              6       2.6
PUSH ACC         3       3
POP  ACC         4       2.5

Note, CALL/RET is significantly faster on 8085. Also passing
parameters in registers is a very powerful feature when crafting
programs.

The benefits of the 65C02 are extremely low power consumption
because in CMOS chips, power-consumption is almost directly
proportional to clock-speed.

Cheers,

Paul


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron