6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Sep 28, 2024 3:29 pm

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Apr 04, 2016 10:12 am 
Offline

Joined: Mon Apr 04, 2016 10:04 am
Posts: 8
(I have been sent here from the 8 bit computer Clique facebook group, where I couldn't get a good answer)

Does anyone know enough about CPU design and layout to comment on whether the 6502's omission of an ADD instruction (in addition to the ADC instruction) was a carefully considered decision or a careless mistake?

It would have saved an awful lot of CLC instructions, and its "father" the 6800, and "nephew" the 6809 both had it.

But even the "grandson" 65816 lacks it.

Can someone point me at the reasons?

<Sidebar>
Does anyone "happen" to have a large assembler source base, and can count the proportion of instructions that are SEC/CLC ?

That number would clearly be a driving factor in the design process.
</Sidebar>

To be clear, I'm not trying to knock the decision, I'm trying to learn about it and understand it.

BugBear


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 04, 2016 10:40 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
I think a lot of aspects of the 6502 come from its original main aim, which was to be a just-good-enough super-cheap microprocessor. It was launched at $25, with the competition at $300. Why was it such a low price?
- lower overheads (smaller team, smaller company)
- smaller profit margin
- mask repair meant much higher yields
- small chip has higher yields and you get more on each silicon wafer.

That last point is key - the 6502 is smaller than the 6800 and much smaller than the (later) Z80. Indeed, during design there was a crunch where it looked like it would be too big and it was made smaller. We don't know what features (if any) had to be removed at that point.

So, ADD is almost certainly missing because you'd need more transistors and more wires to implement it, and the 6502 had to be small to be successful.

Also, as we know, ADD isn't needed. CLC doesn't cost much. If you only had ADD and no carry bit, life would be very different indeed.

As for instruction frequencies, there are some collections which I might try to dig up. Bear in mind the difference between static frequency, which you could get from disassembly and which tells you the density of each instruction in memory cost, and dynamic frequency, which you get from simulation or similar, and which tells you the time cost of each instruction. (See this thread:
viewtopic.php?f=2&t=3298
Edit: and my post in the more recent thread at
viewtopic.php?f=1&t=4132&p=45416#p45416
)

Cheers
Ed


Last edited by BigEd on Tue May 24, 2016 3:38 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 04, 2016 6:51 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8520
Location: Southern California
Welcome!

I expect it also had to do with filling out the op code table, and ideas for future added instructions. Adding ADD with all the addressing modes would take up more space in the op code table, space that could later be used for other things. ADC has 8 op codes for NMOS 6502, 9 for 65c02, and 15 for 65816. Note that the 65816's op code table is plum full. Adding ADD op codes would take away space from other more necessary op codes.

There may also be the matter of unnecessary instructions slowing down the instruction decoding, resulting in a lower maximum frequency. The 65c02's maximum frequency is an order of magnitude higher than that of the 6800, and two orders in the case of one of WDC's licensees who's putting the '02 in a custom IC for a particular control process, running over 200MHz. The '02 was originally intended for embedded control which tends to be less math-intensive anyway.

bugbear wrote:
Does anyone "happen" to have a large assembler source base, and can count the proportion of instructions that are SEC/CLC ?

That number would clearly be a driving factor in the design process.

I looked at a project I did in the 1980's that assembled to about 24K and was rather math-intensive. It has 48 CLC's before ADC's (and I see now I could have eliminated some of them if I hadn't been so green at the time), and 24 SEC's before SBC's. That puts CLC at about 0.2% of the bytes, and SEC at about 0.1%. I looked at another project, one I did in 1994, for embedded control. This one assembles to about 3.5K, and has 4 CLC's and 2 SEC's. These are all ones that precede ADC or SBC. That puts CLC at 0.1% and SEC at 0.05% of the bytes. Ones that precede ROL and ROR don't count.

_________________
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  
PostPosted: Mon Apr 04, 2016 7:48 pm 
Offline

Joined: Thu Mar 03, 2011 5:56 pm
Posts: 284
GARTHWILSON wrote:
I looked at a project I did in the 1980's that assembled to about 24K and was rather math-intensive. It has 48 CLC's before ADC's (and I see now I could have eliminated some of them if I hadn't been so green at the time), and 24 SEC's before SBC's. That puts CLC at about 0.2% of the bytes, and SEC at about 0.1%. I looked at another project, one I did in 1994, for embedded control. This one assembles to about 3.5K, and has 4 CLC's and 2 SEC's. These are all ones that precede ADC or SBC. That puts CLC at 0.1% and SEC at 0.05% of the bytes. Ones that precede ROL and ROR don't count.


Wouldn't you just just ASL/LSR instead of CLC + ROL/ROR?

(Why are not these called just LSL/LSR, by the way? The 6502 does not seem to actually have any arithmetic shift operations, and LSL and ASL are usually identical in effect.)


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 04, 2016 8:31 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8520
Location: Southern California
rwiker wrote:
Wouldn't you just just ASL/LSR instead of CLC + ROL/ROR?

True, for CLC. Sometimes you want to start by intentionally rotating a 1 in, which would require the SEC.

Quote:
(Why are not these called just LSL/LSR, by the way? The 6502 does not seem to actually have any arithmetic shift operations, and LSL and ASL are usually identical in effect.)

LSL seems to make sense to me too. Perhaps someone else here has thought this through more thoroughly. I would think LSL and ASL should be the same thing, but not LSR and ASR, since preserving the sign of a twos' compliment negative number when dividing by two would be different, for example $-6A (represented by 10010110 in binary) divided by two is $-35 (represented by 11001011 in binary). None of the shift or rotate instructions affect V.

_________________
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  
PostPosted: Mon Apr 04, 2016 8:34 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
Looks to me like the 6502 took the opcodes from the 6800 - not surprising at all, given that the 6501 was socket-compatible - taking 6800 market share was certainly a part of the plan. The 6800 has LSR, ASR and ASL. Evidently ASR cost too much in transistors or effort and was not implemented.


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 05, 2016 3:17 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
I actually think that it was a good decision to provide only the ADC/SBC instructions. As Garth has indicated from his review of a large program, the overhead associated with using the CLC/SEC instructions is fairly low.

These instructions are the foundation of multi-precision arithmetic. With only these two instructions, since the CLC/SEC are required for other reasons, multi-precision arithmetic can be easily implemented. As anyone whose worked with the instruction set of processors like the 8080 (or Z80) which has both instructions, forgetting to use the ADC instruction for the second (or higher) addition in a multi-precision operation is just as bad as failing to initialize the carry flag before the first 6502 ADC instruction. Similarly, the RISC-like 16-bit Inmos Transputer did not have a carry flag (or processor status register), and doing higher precision (32-bit or more) arithmetic was a bit difficult.

I also think that Garth is right on point about the complexity issue. For example, I started implementing a serial processor several years ago, and I opted to implement the add/sub operations like those of the 6502. I wanted to have a minimal number of instructions, 32/33, that would provide the capability to perform multi-precision arithmetic. Providing two kinds of add/sub instructions just didn't fit into my instruction set objectives. (Note: a great example of a minimal instruction set that is well matched to its application is that provided by James Bowman's J1 processor or Arlet Ottens' RISC processor.)

Finally, it's not that hard to implement arithmetic and logical shifts. In my 6502-compatible core, I implement these instructions with two simple structures:

Code:
// Carry In Multiplexer

always @(*)
begin
    case(CSel)
        2'b00 : Ci <= C;            // ADC/SBC/ROL/ROR
        2'b01 : Ci <= Q[7];         // ASR (Reserved for future use)
        2'b10 : Ci <= 0;            // DEC/ASL/LSR
        2'b11 : Ci <= 1;            // INC/CMP         
    endcase
end

and
Code:
always @(*)
begin
    if(En)
        {OV, Out} <= ((Op) ? {^SU[7:6], {SU[0], {Ci, SU[7:1]}}}     // LSR/ROR
                           : {^SU[7:6], {SU[7], {SU[6:0], Ci}}});   // ASL/ROL
    else
        {OV, Out} <= 0;
end

Although these structures appear to be fairly simple, I wonder how difficult it would be for a manually placed and routed device like the 6502, with a limited number of metal layers, to accommodate the multiplexers and XOR gates described in my code snippets. I also suspect that many decisions regarding the instruction set were driven by size as others have indicated above.

Extending this thought, I think that the 6502's PLA-based control logic was used to great advantage in creating a processor well matched to memory and providing much faster execution rates limited the layout options as well. A PLA-based control logic is more compact than the control logic of a microprogrammed processor. A microprogrammed processor like the 8080 could use multiple cycles to implement the large number of related instructions like ADD/ADC, SUB/SBB, ROL/RLC, ROR/RRC, etc. by breaking the operations down to units less than 8-bits, i.e. 4-bit nibbles. The lack of complex addressing modes in the 8080 unlike the 6502, simplifies the microprogram, provides room in the IC area and in the instruction set for its large number of similar instructions.

When all things are considered, the instruction set of the 6502 is very efficient, and does not lack any significant functionality; programs which have good performance can be compactly written. The indexed and indirect addressing modes are difficult to emulate with the simple addressing modes of the 8080: immediate, absolute, and 8-bit relative (for branches only).

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 05, 2016 3:43 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
GARTHWILSON wrote:
... LSL seems to make sense to me too. Perhaps someone else here has thought this through more thoroughly. I would think LSL and ASL should be the same thing, but not LSR and ASR, since preserving the sign of a twos' compliment negative number when dividing by two would be different, for example $-6A (represented by 10010110 in binary) divided by two is $-35 (represented by 11001011 in binary). None of the shift or rotate instructions affect V.

I have thought it through (as much as my addled brain can), and I am providing ash, lsh, asl, lsl, asr, lsr, rol and ror for my 65m32, made possible by my recent move to a 7-bit operation field.

ash and lsh only work on the accumulator/carry register pair; the operand provides the signed shift count (modulo 64).

The remaining six ops are more complex, and act differently in their literal mode than they do in their three read-modify-write addressing modes. Details are beyond the scope of this post.

The three "arithmetic" ops preserve the sign bit and may affect the overflow flag, but the three "logical" and the two "rotate" ones do neither of those activities.

Mike B.

[Edit: Looks like I'm missing rot in the first group :( ... still have op-code room for it :D ]


Top
 Profile  
Reply with quote  
PostPosted: Tue Apr 05, 2016 8:16 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
MichaelM wrote:
Similarly, the RISC-like 16-bit Inmos Transputer did not have a carry flag (or processor status register), and doing higher precision (32-bit or more) arithmetic was a bit difficult
Well, well - you are quite right. I hadn't realised that. The same is true of the modern RISC-V architecture, which comes in 32-bit and 64-bit flavours - multi-word arithmetic being less crucial on a wider machine. On an 8-bit machine it's essential.

(It turns out that the high level language Occam for the Transputer provided functions for wide arithmetic.)


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 2:25 am 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 452
Location: Canada
I think there is a slight difference between ASL and LSL in the way the overflow flag is set (on other processor). ASL sets the overflow if the sign bit changes and LSL does not.

_________________
http://www.finitron.ca


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 7:50 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
That sounds like the right thing to do!


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 8:48 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1948
Location: Sacramento, CA, USA
BigEd wrote:
That sounds like the right thing to do!


Yeah, but what about ROL? It's the last link of a multi-precision shift-left chain. ROR probably shouldn't mess with V, but I think that an argument could be made that ROL should.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 9:38 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
I'm not so sure - ROL would proceed from MSB to LSB, so calculating overflow on the last byte doesn't make too much sense. Wouldn't you start the shifting with an ASL?

Edit: I have confused left and right here, as pointed out below. They are so similar.


Last edited by BigEd on Wed Apr 06, 2016 10:25 am, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 10:18 am 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
Shift left must proceed from LSB to MSB. So 32 bits signed little endian would be shifted like this:

ASL op ;actually a LSL
ROL op+1
ROL op+2
ROL op+3 ;an overflow (sign bit change) needs to be detected here!

So yes, a V flag for ROL would help in this case. It would complement an ASR. The 6502 has neither.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 06, 2016 10:25 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10938
Location: England
I have of course confused my left and my right! Thanks for the correction.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 31 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: