please help me!
please help me!
Why do I have to set C when I use SBC #dd?
Thanks
Thanks
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
> 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
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
Alternate subtraction operation mnemonics
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
Willi
Re: please help me!
cao9981 wrote:
Why do I have to set C when I use SBC #dd?
Thanks
Thanks
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)
Subtract with borrow
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
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
Re: Subtract with borrow
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).
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).
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.
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
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
-
schidester
- Posts: 57
- Joined: 04 Sep 2002
- 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.
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
>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.
> 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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
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
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
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.
At 1Mhz (similar bus speed as 4Mhz 8085) a 6502 executes the
shortest instruction in two useconds.
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: Select all
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
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
> 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
> 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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
6502 and speed
Hi Everyone,
I tabulated some instruction times for an 8085 at 4Mhz and
a 6502 at 1Mhz.
ADD immediate
I tabulated some instruction times for an 8085 at 4Mhz and
a 6502 at 1Mhz.
ADD immediate
6502 times
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
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
6502 at 1Mhz (no wait states)
8085 at 4Mhz (no wait states)
all times are in useconds
Code: Select all
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
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