Page 1 of 1

Any reason for a 65[C]02 to read an I/O port more than once?

Posted: Tue May 13, 2014 1:27 am
by jac_goudsmit
Hi guys,

I'm working on some firmware to make my Propeddle Software Defined 6502 Computer (http://www.propeddle.com) project work, and I'm running into a little problem. I wanted to verify with you guys that it's not going to be a big deal.

One module that I'm writing on the Propeller emulates the keyboard and display electronics on the Apple-1. So when the 6502 reads a byte from address $D010, it sees the last character that was typed on the keyboard. But a read from this address also needs to reset the msb of address $D011, and the bottom line is, I cant get all that processing done on the Propeller in one microsecond. So the processing ends in the cycle AFTER the 6502 reads $D010 and if the 6502 would read or write any byte between $D010 and $D013 (inclusive) immediately after reading from $D010, the Propeller would ignore what the 6502 is trying to do during that cycle.

My question is: As far as I know, the only time when the 6502 puts the same address on the address bus two clock cycles in a row, is for instructions that are one byte (like NOP or CLC) or when it does a read-then-write instruction (such as INC). Am I correct?

In other words: do I need to worry about the possibility that in clock cycle n, it reads (doesn't write - that's a different story) $D010 and in clock cycle n+1, it reads $D010 again, or reads another address other than the next instruction to execute?

Thanks!

===Jac

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Tue May 13, 2014 2:03 am
by GARTHWILSON
The "Instruction Operation Table" in the back of the data sheets tells what's on the various buses and lines in each cycle. You can look through that, specifically the "Address bus" column, and see what instructions could be helpful or harmful to what you're trying to do. There are plenty that read the same one a second cycle in a row when there's an internal operation (designated "IO"), and ones that read consecutive addresses in consecutive cycles.

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Tue May 13, 2014 2:30 am
by Dr Jefyll
jac_goudsmit wrote:
I wanted to verify with you guys that it's not going to be a big deal.
Hi, Jac! I think you'll be okay if, as you say, it's a read (not a write), and the read is a data access not a code fetch. Not much chance we'll be doing a JMP to $D010, so you're safe!
Quote:
As far as I know, the only time when the 6502 puts the same address on the address bus two clock cycles in a row, is for instructions that are one byte (like NOP or CLC) or when it does a read-then-write instruction (such as INC). Am I correct?
The NMOS 6502 has different read-modify-write behavior than the 65C02. I don't think that will cause trouble for you, but some may find the info pertinent. (The '02 does 1 read & 2 writes; the 'C02 does 2 reads & 1 write.) As for instructions that are one byte (like NOP or CLC), it's actually the op-code following the one-byte op-code which gets fetched twice -- I guess you know that; I'm just clarifying.

Finally, there's another case where an op-code can be fetched twice, and it's not confined to single-byte instructions. The beginning of a 65xx interrupt sequence invariably results in an op-code being fetched and discarded... then fetched again and discarded again! This applies from the NMOS '02 right up to the '816.

I expect I've missed some other cases where the 6502 puts the same address on the address bus two clock cycles in a row -- for example, later in the interrupt sequence. But I don't think they'll spoil your fun with the Propeddle!

cheers
Jeff

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Tue May 13, 2014 9:01 pm
by MichaelM
Jac:

Garth pointed me to this datasheet. In Table V there's a good discussion of the behavioral differences between the NMOS and CMOS 6502s.

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Tue May 13, 2014 9:33 pm
by BigEd
Interesting that this device pushes three bytes to the stack at reset. On the one hand, it allows a reset to work as an interrupt (it knows what what happening and can even return) but on the other hand it's making a change. Previously I've opined that it's better not to write. But on reflection, when the stack is always in page one, it's unlikely that anything of interest would be overwritten.

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Tue May 13, 2014 9:58 pm
by jac_goudsmit
Thanks for all the replies, folks! I think since no-one has found an obvious reason why it wouldn't work, it'll probably work. :-)
BigEd wrote:
Interesting that this device pushes three bytes to the stack at reset. On the one hand, it allows a reset to work as an interrupt (it knows what what happening and can even return) but on the other hand it's making a change. Previously I've opined that it's better not to write. But on reflection, when the stack is always in page one, it's unlikely that anything of interest would be overwritten.
(Going off-topic, that's okay)

The WDC 65C02 also appears to handle a reset as a half-ass interrupt: during three of the six reset cycles, it appears to read from three decrementing(!) addresses in the stack area.

I suspect that handling all three signals (~IRQ, ~NMI and ~RESET) the same way (pushing the flags and PC onto the stack) made sense in the electronics design, but the team at MOS decided to add an extra gate or diode or PLA entry to change the three stack pushes during reset from writes into reads so that no memory would be affected by the reset. And apparently the company that made this 6502 clone decided to leave that gate out.

Indeed, nothing of interest is likely to be overwritten unless you're in a very restricted system (e.g. a system with just a 6532 or 6530 where the zero page and stack are likely mirrored). And one could argue that when the system is reset, it shouldn't assume anything about the state of the RAM, so who cares if it writes something to the stack. But I reckon Chuck and Bill and the guys figured that one extra gate to prevent writes wouldn't change the size of the chip too much, and would save a lot of headaches in cases that they couldn't possibly foresee.

I wonder how hard it would be to find where the stack pushes during reset are changed into reads in Visual6502.org.

===Jac

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Wed May 14, 2014 2:15 pm
by jbevren
jac_goudsmit wrote:
The WDC 65C02 also appears to handle a reset as a half-ass interrupt: during three of the six reset cycles, it appears to read from three decrementing(!) addresses in the stack area.

I suspect that handling all three signals (~IRQ, ~NMI and ~RESET) the same way (pushing the flags and PC onto the stack) made sense in the electronics design, but the team at MOS decided to add an extra gate or diode or PLA entry to change the three stack pushes during reset from writes into reads so that no memory would be affected by the reset.
===Jac
The 6502 has apparently always handled /RESET as an interrupt with the exception of stack writes not following through. This and some other very low level items were covered by Michael Steil in 27c3. You can see his presentation on youtube (search: [27C3] (en) Reverse Engineering the MOS 6502 CPU, make sure you include (en)). If anyone's remotely interested in how interrupts are processed, or especially why a NMOS 6502 jams up when it executes a $02 (or most $x2) opcodes, watch Stiel's presentation.

Regarding design choices on working with /RESET, that would make some sense as it could save on logic cost.

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Wed May 14, 2014 4:45 pm
by BigEd
I've taken some quotes from this side adventure about reset, and started a new topic:
viewtopic.php?t=2967

Cheers
Ed

Re: Any reason for a 65[C]02 to read an I/O port more than o

Posted: Wed May 14, 2014 5:40 pm
by GARTHWILSON
I seem to remember reading that the reset's write-to-stack feature was to help in debugging, so you could figure out where the computer crashed (as in: stuck in an endless loop) before you pressed the reset button.