The MOS 6502 and the ROR bug, again

To common wisdom, the “ROR bug” of the early 6502 processors (the series prior to June 1976) isn’t so much a bug, but it wasn’t really implemented, as seems to be confirmed by analyses of the silicon.

E.g., see this video:

and Bill Mensch is said to have supported this version, as well:

With regard to the ROR ‘bug’, Bill Mensch (who did circuit design on the 6502) relates that it wasn’t so much a ‘bug’ as Chuck Peddle left it off the specification so the early 6502s were missing ROR as designed. However they found a way to add it soon after the first version was released.

Source: https://news.ycombinator.com/item?id=26053692

Now I came across this anecdote featuring Chuck Peddle and the “ROR bug” (found in what is a great article on the development of and stories around the Commodore CHESSmate, by its programmer, Peter Jennings):

One morning, I came into the Commodore office to find that Chuck Peddle had been working all night, playing with some code to improve the sounds the computer made for various events. He demonstrated the sounds, which were much more interesting than my simple beeps. I looked at his code, usually extremely efficient and compact. Why, I asked, do you have seven ROL (rotate a byte in the accumulator one bit to the left) commands in a row here? He rolled his eyes. I forgot. We fixed the ROR bug. Up until mid 1976, the 6502 shipped with no ROR op code in the instruction set because of a bug in the silicon. After that the ROR was fixed and could be used to rotate a byte one bit to the right. He forgot! We replaced the seven ROL instructions with one ROR.

So, according to this (and I see no reason to question the varacity of this account) Chuck Peddle very much so recognized this as a bug (and, apparently, a rather annoying one), which had to be fixed, rather than an intentional shortcut in the initial design.

Now, I’m confused, to say the least…
(At least for me, these two versions of the ROR story don’t match too well.)

2 Likes

PS: The about only middle ground, I can imagine, is the 6502 team recognizing a bug in the initial ROR implementation, but also recognizing that they won’t be able to fix this in time for the initial release, and consequently stripping the related section from the initial design. Which made this both a bug and an intentional omission. Or was this simply a case of “we’ll come back to this later” and then just forgetting to do so? – But this is, of course, pure speculation.

1 Like

Nice find, and an interesting read about Jennings’ adventures.

My own inclination is to go with the bug theory, and take Mensch’s recollections as being biased towards hiding (or forgetting) any mis-steps. But it would be great to see the early silicon photographed and analysed!

Ror is not used that often, so it was fair trade in my mind to get the 6502 out the door.
Other hardware bugs are more important, like with IRQ’s

The video does show some of the Rev. A at around 6:19!
https://youtu.be/Uk_QC1eU0Fg?si=t-sdIHkukECp80i2&t=379

From the transcript:

I traced out that control line on the rev A 6502 and found that it goes basically nowhere. It’s not connected to anything! No instruction activates this line. It branches into two paths, and neither connects to any transistors. My best guess is that it was used for a different instruction that was later removed or changed during the design process.

Continuing on the above path of speculation, this other instruction could have been an original, but flawed implementation of ROR, as well.

1 Like

Which would you be more tempted to use: an instruction that seems to kind of work most of the time, or one that does absolutely nothing?

It does seem both bug and unimplemented are true, case of “can’t get it working so we’ll just rip it out so people don’t try to use it.”

1 Like

The problem being, it did something, namely, it behaved much like ASL, shifting in a zero bit, but preserving (i.e., not adjusting) the carry flag. (So it ended up being a buggy version of ASL.)

So it behaves more like an illegal opcode than a NOP.

I notice the possible low nybbles of the opcode for ASL and ROR are the same. Maybe that has something to do with why?

In the “aaabbbcc” layout, b and c are the same (c = 2 and b encoding the address mode) while a is 1 for ROL and 3 for ROR and 0 for ASL. (So ROL is 001xxx10, ROR is 011xxx10 and ASL is 000xxx10.)
This may be consistent with that control line not being connected to anything (thus “a” decoding as zero), but doesn’t really explain why the carry flag isn’t adjusted (like it is for ROL or ASL). So, I guess, we’re still missing some.

Edit: Notably, LSR is a = 2, which rules out that the adjustment of the carry flag is somehow related to a & 2 == 0. That is, this may trigger just for the MSB, so if a is zero, and this doesn’t trigger, but there’s also no right shift/rotate decoded, there may be no trigger for the LSB…

ah, so much I seem to forget - I’ve seen this video before! One possibility that comes to mind is that they ran out of time, having realised too late that they needed to handle the preservation of C. Another possibility is that they ran out of space: we know that the 6502 layout had to be hacked down a bit to fit, and things perhaps needed to be removed, or things planned to be included were dropped.

For the die photos, the links in the video description are dead, but see here.

1 Like

While I have no idea of the actual silicon design of the 6502, as I imagine it, there are three things to consider: the shift/rotate operation itself, whether to shift in the carry or a zero-bit, and, finally, the adjustment of the carry according to the preserved LSB (and that we want to preserve this, in the first place). But, following to this video and its analysis, there are just two paths from that control line, not three. (On the other hand, the adjustment of the carry is implied in the very direction of the shift/rotate operation. So I really don’t know.)

Anyways, if we were to discover that we need an additional control path, this may require a redesign of a substantial part of the chip, which perfectly explains, why we’d want to release this anyway, especially given the very time, this happened.

2 Likes

The book Designing Video Game Hardware in Verilog says the way the 6502 does a ROL is by adding a value to itself because it doesn’t have ALU hardware to rotate left itself, only right.

See page 124.

1 Like

Or to put it another way, it doesn’t need any such hardware, because addition is enough. Whereas rotating right would appear to need some wires (and therefore some transistors) - but of course LSR already provides the bulk of that machinery. It’s only the carry looping around to bit 7 that’s extra.

Possibly exploring around this visual6502 simulation would be fruitful. And this might be the area to watch.

Same area (sorry for 90 degree rotation) in the rev A you see there’s one fewer control line, and instead of one line which stops at bit 6 with a separate one to bit 7 only, there’s a single merged line. That needs fixing!

1 Like

Well I’m not too sure how to decipher all that (mostly just see node/transistor numbers when I click on stuff) as it’s not labeled as much as a nice block diagram, but I think the book was trying to get at was that you’d think rotation to be a simpler operation than addition. There’s more or less one operand (throw in the carry flag too) and that’s all you need to know to compute the rotated output. With addition, even though you are sending the same input to both addends, the ALU doesn’t know that, so it has to do the add and carry work involved with addition. Kind of like when you’re in gradeschool and are told to follow the algorithm you were taught and and not to use shortcuts even if you can see a better way. Show your work and don’t memorize the answer! The teacher being able to easily see that you did exactly what you were told is more important than being creative.

Now, the book does say the ALU is always outputting something and processors just ignore the result if they aren’t running an opcode cycle that needs it, so maybe a dedicated rotate left aluop wouldn’t help save any energy at all.

One thing is clear though - one ROR is way better than 7 ROLs.

Indeed, the considerations at the software level (cheaper to shift than add) might be different at the hardware level. The ALU is already bought and paid for, and operates in a single cycle, so it’s a good way to shift left. (In an emulator, the costs might be different, but against that’s software level.)

It’s kind of nice that the omission of ROR left a very visible trace, in the form of multiple ROLs, in code and in brains, and then in conversations.