One of the differences between the (NMOS) 6502 and the 65C02 are the
instructions:
ASL Absolute,X
LSR Absolute,X
ROL Absolute,X
ROR Absolute,X
INC Absolute,X
DEC Absolute,X
each of which takes:
6 cycles on a 65C02 when a page boundary IS NOT crossed
7 cycles on a 65C02 when a page boundary IS crossed
7 cycles on a 6502 no matter what
On the 65C02s I have, the ASL, LSR, ROL, and ROR instructions behave this way but the DEC and INC instructions behave like the 6502 (7 cycles no matter what). I have only two 65C02s, both of which were manufactured by GTE, and I have had them for about 10 years or so, so they are at least that old, but possibly older. The 65C02 was introduced in 1984-1985 or so, but I don't think they are that old. If anyone knows how to decipher the datecodes stamped on the IC itself, I would be happy to post that information here.
Do all 65C02s behave like this? Can anyone explain this behavior?
Incidentally, I discovered this when I was writing a routine that needed to hit an exact number of cycles. This routine used a JMP (Absolute) instruction. All was well until I realized that this instruction takes 5 cycles on the 6502 and 6 cycles on a 65C02, which meant that I needed something that was one cycle longer on a 6502 than on a 65C02. My first attempt was:
INC $0000,X ; note: Absolute, not Zero Page, i.e. FE 00 00
DEC $00,X ; note: Zero Page, i.e. D6 00
JMP (Absolute)
which should take 7+6+5=18 cycles on a 6502 and 6+6+6=18 cycles on a 65C02, since the INC $0000,X cannot possibly cross a page boundary no matter what X is. The DEC $00,X was simply to undo the effect of the INC $0000,X. I had the additional cycles to spare; the key was hitting an exact number of cycles. The trouble was that it didn't work, because the INC $0000,X took 7 cycles on the 65C02, not the 6 cycles that I expected. I wound up using:
ROL $0000,X ; note: Absolute, not Zero Page, i.e. 3E 00 00
ROR $00,X ; note: Zero Page, i.e. 76 00
JMP (Absolute)
which did take 7+6+5=18 cycles on the 6502 and 6+6+6=18 cycles on the 65C02, as expected. I chose ROL and ROR since that would preserve the carry flag, which would not be the case for ASL and LSR.
A 65C02 bug?
- BitWise
- In Memoriam
- Posts: 996
- Joined: 02 Mar 2004
- Location: Berkshire, UK
- Contact:
The WDC data sheet contains a list of the differences between the 6502 and 65C02 (including your one) in a caveats section near the end.
http://www.westerndesigncenter.com/data ... 65c02s.pdf
http://www.westerndesigncenter.com/data ... 65c02s.pdf
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
> but the DEC and INC instructions behave like the 6502 (7 cycles no matter what)
The WDC programming book says they take 6 clocks on the 65c02 also, unless a page boundary is crossed.
> This routine used a JMP (Absolute) instruction. All was well until I
> realized that this instruction takes 5 cycles on the 6502 and 6 cycles on
> a 65C02
The NMOS 6502 had plenty of bugs, but they were all fixed in the 65c02. One of the bugs is, as the list said, that JMP (XXFF) would grab the low byte of the effective address at XXFF and the high byte from XX00 instead of incrementing XX to the next page. The 65c02 adds an extra clock to increment the high byte if the page boundary requires it, so that it works right.
> The 65C02 was introduced in 1984-1985 or so
1980, according to the designer Bill Mensch himself in an interview. We were told about it in the spring of '82, in the semester in school that I got into this stuff, even though we worked on AIM-65's with NMOS parts.
Other things will have differing clock counts depending on page-boundary crossings too. For example, branch instructions add a clock if they have to cross a page boundary. (If you look at all your branch instructions in the whole program however, you'll find that a very small percentage of them branch across page boundaries.) If it's a potential timing problem, you could use a macro in the assembly code to check the assembly address when it gets to that part and use a .ORG directive if necessary to start the routine in such a place so as to avoid the problem, or put a couple of NOPs in right before the JMP (xxxx).
The WDC programming book says they take 6 clocks on the 65c02 also, unless a page boundary is crossed.
> This routine used a JMP (Absolute) instruction. All was well until I
> realized that this instruction takes 5 cycles on the 6502 and 6 cycles on
> a 65C02
The NMOS 6502 had plenty of bugs, but they were all fixed in the 65c02. One of the bugs is, as the list said, that JMP (XXFF) would grab the low byte of the effective address at XXFF and the high byte from XX00 instead of incrementing XX to the next page. The 65c02 adds an extra clock to increment the high byte if the page boundary requires it, so that it works right.
> The 65C02 was introduced in 1984-1985 or so
1980, according to the designer Bill Mensch himself in an interview. We were told about it in the spring of '82, in the semester in school that I got into this stuff, even though we worked on AIM-65's with NMOS parts.
Other things will have differing clock counts depending on page-boundary crossings too. For example, branch instructions add a clock if they have to cross a page boundary. (If you look at all your branch instructions in the whole program however, you'll find that a very small percentage of them branch across page boundaries.) If it's a potential timing problem, you could use a macro in the assembly code to check the assembly address when it gets to that part and use a .ORG directive if necessary to start the routine in such a place so as to avoid the problem, or put a couple of NOPs in right before the JMP (xxxx).
>> but the DEC and INC instructions behave like the 6502 (7 cycles no matter what)
>
> The WDC programming book says they take 6 clocks on the 65c02 also, unless a page boundary is crossed.
All the documentation I have ever seen on the 65C02 says this as well, which is why I was VERY surprized when my 65C02s did not behave this way. I swear, I can change a single byte (without changing or moving any other code) on my 65C02s, to change DEC or INC (DE or FE) to/from ASL, LSR, ROL, or ROR (1E, 5E, 3E, or 7E) and INC and DEC will take one cycle more than the ASL, LSR, ROL and ROR will.
Try measuring the number of cycles on an actual 65C02 and tell me what you get. I'd like to know. I've tested each of the 6 instructions dozens of times apiece, and they all behave as I've described without exception. Just to make sure I wasn't losing my mind, I even tried measuring cycles in more than one way. More than once, I've written code to test this behavior from scratch. INC and DEC on my 65C02s simply do not behave as documented.
> The NMOS 6502 had plenty of bugs, but they were all fixed in the 65c02.
This is exactly the impression I was under until I discovered what is either a 65C02 bug or a couple of oddball 65C02s in my possession.
>> The 65C02 was introduced in 1984-1985 or so
>
> 1980, according to the designer Bill Mensch himself in an interview. We were told about it in the spring of '82, in the semester in school that I got into this stuff, even though we worked on AIM-65's with NMOS parts.
Were they introduced (in mass quanities) to the public that far back? The information I've seen (admittedly, I have very little to go on here) would suggest that GTE (who manufactured my 65C02s) wasn't producing 65C02s until '84-'85 or so. Anyway, the point I was trying to make is that I don't think that what I have is early silicon, but if it is in fact early silicon that might explain why my 65C02s are oddballs. Both of my 65C02s are from the same manufacturer and it wouldn't surprise me in the least to discover that they're from the same production lot.
>
> The WDC programming book says they take 6 clocks on the 65c02 also, unless a page boundary is crossed.
All the documentation I have ever seen on the 65C02 says this as well, which is why I was VERY surprized when my 65C02s did not behave this way. I swear, I can change a single byte (without changing or moving any other code) on my 65C02s, to change DEC or INC (DE or FE) to/from ASL, LSR, ROL, or ROR (1E, 5E, 3E, or 7E) and INC and DEC will take one cycle more than the ASL, LSR, ROL and ROR will.
Try measuring the number of cycles on an actual 65C02 and tell me what you get. I'd like to know. I've tested each of the 6 instructions dozens of times apiece, and they all behave as I've described without exception. Just to make sure I wasn't losing my mind, I even tried measuring cycles in more than one way. More than once, I've written code to test this behavior from scratch. INC and DEC on my 65C02s simply do not behave as documented.
> The NMOS 6502 had plenty of bugs, but they were all fixed in the 65c02.
This is exactly the impression I was under until I discovered what is either a 65C02 bug or a couple of oddball 65C02s in my possession.
>> The 65C02 was introduced in 1984-1985 or so
>
> 1980, according to the designer Bill Mensch himself in an interview. We were told about it in the spring of '82, in the semester in school that I got into this stuff, even though we worked on AIM-65's with NMOS parts.
Were they introduced (in mass quanities) to the public that far back? The information I've seen (admittedly, I have very little to go on here) would suggest that GTE (who manufactured my 65C02s) wasn't producing 65C02s until '84-'85 or so. Anyway, the point I was trying to make is that I don't think that what I have is early silicon, but if it is in fact early silicon that might explain why my 65C02s are oddballs. Both of my 65C02s are from the same manufacturer and it wouldn't surprise me in the least to discover that they're from the same production lot.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
I tried it on a Rockwell 65c02. (All my WDC 65c02's are in PLCC, but my fixture for observing detailed behavior while single-clocking only holds a 6502 DIP, not PLCC.) You're right about the cycle count. Here's the cycle-by-cycle activity:
1: Read the op code ($FE for INC abs,X)
2: Read the operand low byte.
3: Read the operand high byte while adding X to the low byte.
4: Add to the high byte any potential carry from the low-byte addition.
5: Read the effective address.
6: Increment the data.
7: Store the incremented number back to memory.
Cycle #4 is there even if adding the X value to the address does not cause a carry to increment the high byte. This is unlike some other 6502 op codes where the corresponding cycle does not take place if there's no carry.
Although this disagrees with the INC page in the instruction list in the programming manual, it does not disagree with the detailed instruction operation table that WDC publishes.
In any case, the bug is in the documentation, not the processor. The instruction works correctly under all circumstances. If you're trying to get an exact number of clocks' delay, then the consistent 7 clocks should only help.
1: Read the op code ($FE for INC abs,X)
2: Read the operand low byte.
3: Read the operand high byte while adding X to the low byte.
4: Add to the high byte any potential carry from the low-byte addition.
5: Read the effective address.
6: Increment the data.
7: Store the incremented number back to memory.
Cycle #4 is there even if adding the X value to the address does not cause a carry to increment the high byte. This is unlike some other 6502 op codes where the corresponding cycle does not take place if there's no carry.
Although this disagrees with the INC page in the instruction list in the programming manual, it does not disagree with the detailed instruction operation table that WDC publishes.
In any case, the bug is in the documentation, not the processor. The instruction works correctly under all circumstances. If you're trying to get an exact number of clocks' delay, then the consistent 7 clocks should only help.
Re: A 65C02 bug?
dclxvi wrote:
If anyone knows how to decipher the datecodes stamped on the IC itself, I would be happy to post that information here.
Having said that, sometimes you'd get '2084' and sometimes even '420', where there's only one digit of the year shown.
This information is given (somewhere) in the Art of Electronics, by Horowitz and Hill.
> Although this disagrees with the INC page in the instruction list in the
> programming manual, it does not disagree with the detailed instruction
> operation table that WDC publishes.
The closest thing I have to something like that is the WDC 65C02 datasheet, which does gloss over some details (only 4 cycles are given the play-by-play treatment for LDA Absolute,X for instance). I certainly can't claim to have world's most extensive collection of 65C02 documentation, but I have never seen anything that draws a distinction between ASL Absolute,X and DEC Absolute,X which have different timing. It's analogous to LDA Absolute,X (4 or 5 cycles) and STA Absolute,X (5 cycles no matter what), which is a distinction that is (clearly) drawn in almost all of the documentation on 6502/65C02 timing.
> In any case, the bug is in the documentation, not the processor. The
> instruction works correctly under all circumstances.
INC and DEC increment and decrement the byte at the specified address correctly, and it was not my intention to suggest otherwise. It may not be the most conventional point of view, but I would consider the timing to be part of the function of the instruction also. I don't know what the timing was intended to be, but it appeared to me that the timing was intended to be the same as ASL, LSR, ROL, and ROR. If this is indeed the case, the actual operation of INC and DEC does not match the intended operation. For these reasons, I decided to call it a 65C02 bug.
Certainly the case could be made for calling it a documentation bug. After all, the timing is what it is and INC and DEC do what they are expected to do, just a little slower than advertized when there isn't a page boundary crossing. There always seems to be a degree of subjectivity when it comes to bugs.
P.S. It's a moot point now, but for anyone who is still curious, the datecodes on my 65C02s are 8628 and 8638. Mid-1986 is older than I'd have guessed.
> programming manual, it does not disagree with the detailed instruction
> operation table that WDC publishes.
The closest thing I have to something like that is the WDC 65C02 datasheet, which does gloss over some details (only 4 cycles are given the play-by-play treatment for LDA Absolute,X for instance). I certainly can't claim to have world's most extensive collection of 65C02 documentation, but I have never seen anything that draws a distinction between ASL Absolute,X and DEC Absolute,X which have different timing. It's analogous to LDA Absolute,X (4 or 5 cycles) and STA Absolute,X (5 cycles no matter what), which is a distinction that is (clearly) drawn in almost all of the documentation on 6502/65C02 timing.
> In any case, the bug is in the documentation, not the processor. The
> instruction works correctly under all circumstances.
INC and DEC increment and decrement the byte at the specified address correctly, and it was not my intention to suggest otherwise. It may not be the most conventional point of view, but I would consider the timing to be part of the function of the instruction also. I don't know what the timing was intended to be, but it appeared to me that the timing was intended to be the same as ASL, LSR, ROL, and ROR. If this is indeed the case, the actual operation of INC and DEC does not match the intended operation. For these reasons, I decided to call it a 65C02 bug.
Certainly the case could be made for calling it a documentation bug. After all, the timing is what it is and INC and DEC do what they are expected to do, just a little slower than advertized when there isn't a page boundary crossing. There always seems to be a degree of subjectivity when it comes to bugs.
P.S. It's a moot point now, but for anyone who is still curious, the datecodes on my 65C02s are 8628 and 8638. Mid-1986 is older than I'd have guessed.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
> I would consider the timing to be part of the function of the instruction
> also. I don't know what the timing was intended to be, but it appeared
> to me that the timing was intended to be the same as ASL, LSR, ROL,
> and ROR. If this is indeed the case, the actual operation of INC and
> DEC does not match the intended operation. For these reasons, I
> decided to call it a 65C02 bug.
I'm sure the designer, Bill Mensch, knew exactly how many cycles were involved and what took place in every cycle. What may have happened is that the cycle-by-cycle information is preliminary and never got updated after the design was finalized. I have had other minor frustrations with their documentation too. Not being an "insider" at microprocessor design, I can only guess that although INC abs,X and DEC abs,X were intended to have the same timing as ASL and others, perhaps some physical circuit limitation meant that adding the extra clock unconditionally to INC and DEC freed up silicon resources so everything else could be clocked faster, producing a beneficial net effect.
Unfortunately our own tiny company is not perfect in the manual department either, although the little problems have different origins. I want the manuals perfect; but when I find little problems, I have to decide how big a stink I'm going to make over them when the person responsible for making the manuals attractive and getting them printed has tons of other work to do as he tries to make the company finally profitable.
> also. I don't know what the timing was intended to be, but it appeared
> to me that the timing was intended to be the same as ASL, LSR, ROL,
> and ROR. If this is indeed the case, the actual operation of INC and
> DEC does not match the intended operation. For these reasons, I
> decided to call it a 65C02 bug.
I'm sure the designer, Bill Mensch, knew exactly how many cycles were involved and what took place in every cycle. What may have happened is that the cycle-by-cycle information is preliminary and never got updated after the design was finalized. I have had other minor frustrations with their documentation too. Not being an "insider" at microprocessor design, I can only guess that although INC abs,X and DEC abs,X were intended to have the same timing as ASL and others, perhaps some physical circuit limitation meant that adding the extra clock unconditionally to INC and DEC freed up silicon resources so everything else could be clocked faster, producing a beneficial net effect.
Unfortunately our own tiny company is not perfect in the manual department either, although the little problems have different origins. I want the manuals perfect; but when I find little problems, I have to decide how big a stink I'm going to make over them when the person responsible for making the manuals attractive and getting them printed has tons of other work to do as he tries to make the company finally profitable.
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?
Re: A 65C02 bug?
dclxvi wrote:
Do all 65C02s behave like this?
The matter is unimportant except where exact cycle counts are required. And it reminds us -- as if a reminder were needed -- that documentation can't be trusted!
Recap: indexed addressing raises the possibility of a page crossing, which means an extra cycle may be required prior to the memory access. But for some indexed Read-Modify-Write instructions an NMOS chip will always include an extra cycle, even when no page crossing occurs. Specifically, Read-Modify-Write instructions using Absolute,X address mode -- opcodes $1E, $3E, $5E, $7E, $DE and $FE -- always include the extra cycle, which is unnecessary if there's been no page crossing.
Table 7-1 of the WDC datasheet (excerpt above) claims this issue has been corrected for the CMOS chip. But in fact that's only true regarding ROL ROR ASL and LSR. The fix does not apply to INC and DEC.
Table 7-1 should read as shown below. (I edited the image to create a corrected version.) As noted, ROL ROR ASL and LSR are fixed. Without a page crossing there'll be no extra cycle. With a page crossing there will be an extra cycle, during which PC presumably (I didn't check) appears on the address bus -- thus needlessly but harmlessly re-fetching the third byte of the instruction.
INC and DEC aren't fixed. Without a page crossing the extra cycle needlessly appears anyway, and the address is the same as that during the following cycle when the RMW actually commences. IOW the same address is accessed four times in a row -- three reads then a write. With a page crossing there will be an extra cycle, during which PC appears on the address bus; then the RMW commences.
The Rockwell and WDC chips behave identically. As for the doc, Rockwell neglects to mention the quirk and the incomplete fix. OTOH the Rockwell doc lists all RMW instructions using Abs,X as seven cycles, making it inaccurate in a different way than the WDC doc.
-- Jeff
ps: -- thanks to dclxvi, who first brought this to our attention.
Edit: clarify wording
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html