It is currently Mon Mar 27, 2017 1:28 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Wed Apr 04, 2007 1:15 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 6947
Location: Jongny, VD, Switzerland
It's a question that tortures me for a while.
What is present on the CPU bus, when the CPU rests (or does an internal operation wihtout any acess on the bus) ? CPUs with dual /RD and /WR lines (like the NES's PPU too) can just leave them both high for a cicle. However, CPUs with only one R/W line and a validation/clock like (PHI2) cannot do this.

For example when the 6502 exectutes a STA $xx (as a exemple) the sequence is the following :
1 - Fetch the opcode (the CPU bus reads at the programm counter location)
2 - Fetch the argument (the CPU bus reads at the programm counter location+1)
3 - Writes the accumulator to memors (the CPU bus writes to the adress specified by the argument read in 2).

So each step effectively takes an acess to the bus (the opcode is 3 cycles).

However, this don't work for all opcodes. Here you are a NOP sequence :
1 - Fetch the opcode (the CPU bus reads the NOP opcode)
2 - Do nothing (what is present on the CPU bus ??)

Or another example for ROL A :
1 - Fetch the opcode (the CPU reads the ROL A opcode)
2 - Rotate the acumulator (no acess to the CPU bus, what is present on it ?)

I can see only 2 solutions :
1 - The M2 lines stay low for one (or more) cycles.
2 - The CPU reads a dummy adress.


Top
 Profile  
 
PostPosted: Wed Apr 04, 2007 2:23 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 17984
Location: NE Indiana, USA (NTSC)
Bregalad wrote:
It's a question that tortures me for a while.
What is present on the CPU bus, when the CPU rests (or does an internal operation wihtout any acess on the bus) ?

The second cycle of an instruction is always a read of the byte after the opcode. This is true even of "implied" instructions such as NOP, INX, and ROL A. Yes, this wastes memory bandwidth, but memory bandwidth was cheaper than CPU logic in the 1970s when the 6502 architecture was developed.

Quote:
I can see only 2 solutions :
1 - The M2 lines stay low for one (or more) cycles.
2 - The CPU reads a dummy adress.

The latter is the case.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 2:28 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 6947
Location: Jongny, VD, Switzerland
Hah, this explains everything. So yeah, today CPUs are fast enough to fetch and execute on a single clock, but that's not the case for the 6502, so it makes dummy fetches (and never 'rests', even in NOPs).


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 04, 2007 8:28 pm 
Offline

Joined: Thu Nov 30, 2006 10:54 pm
Posts: 8
Bregalad wrote:
Hah, this explains everything. So yeah, today CPUs are fast enough to fetch and execute on a single clock, but that's not the case for the 6502, so it makes dummy fetches (and never 'rests', even in NOPs).


Actually the reason today's CPUs are able to execute one instruction (and more) per cycle is Pipelining. What happens is internally you get a number N of stages that gets filled up. When the cpu makes access to memory, it checks the cache first then goes to the main memory, halting the whole pipeline until ready.

The 6502 used no cache and actually accesses the memory every cycle. There is no way to know when a "good" access is made. Also, keep in mind RESET is implemented just like NMI, INT and BRK are. The difference is R/W is forced high, the int vector is set to $FFFC/$FFFD and writes are disabled but the stack still is decremented by 2.

Inside the 6502, NOPs are just like any other instruction except for the fact that nothing happens. That means you can get 1-byte, 2-byte etc nops. Think of it as LDA but without saving anything: the operands are still fetched.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2007 1:20 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 6947
Location: Jongny, VD, Switzerland
You mean on reset, that the CPU actually READS 3 stack locations (instead of writing to it) ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 05, 2007 4:23 am 
Offline

Joined: Thu Nov 30, 2006 10:54 pm
Posts: 8
Bregalad wrote:
You mean on reset, that the CPU actually READS 3 stack locations (instead of writing to it) ?


Yep. Dummy read


Top
 Profile  
 
 Post subject:
PostPosted: Sun Apr 08, 2007 2:09 pm 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
Summary of dummy memory accesses:

* Single-byte instructions have a dummy PC fetch on the second cycle.
* Stack pull operations (PLA, RTS, etc.) have a dummy stack read on the third cycle (before S is incremented).
* JSR has a dummy stack read on the third cycle (for some unknown reason). The last byte of the JSR instruction isn't read until the last cycle.
* Hardware interrupts have two dummy PC reads (with PC held unchanged) on the first two cycles.
* RESET has three dummy stack reads (with S being decremented) on the third, fourth, and fifth cycles.
* BRK has a dummy PC read on the second cycle (PC is still incremented, however).
* Read-modify-write instructions (such as INC) have a dummy WRITE after the operand is read and before it is modified and written back. For example, if INC is performed on an address currently containing the value $17, the instruction reads $17, writes $17, then writes $18.
* Zero page indexed addressing has a dummy zero page access on the third cycle, before the index is added.
* Absolute indexed addressing has a dummy read on the fourth cycle, after the index is added to the lower byte but before the upper byte is adjusted. Note that if the instruction is a read operation and if the upper byte does not change (no page crossing), this dummy read becomes valid and one cycle of execution is saved.
* For branch instructions, the first byte of the instruction following the branch is read on the third cycle. If the branch is taken, this result is thrown away and another byte is fetched after adjusting the lower byte of the PC. If a page boundary is crossed, this result is also thrown out and a new byte is read after fixing the upper byte of the PC.

_________________
"Last version was better," says Floyd. "More bugs. Bugs make game fun."


Top
 Profile  
 
 Post subject: Re:
PostPosted: Mon Feb 06, 2017 9:35 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 676
Ah,good, finding an answer to my question before asking…
Myask's question wrote:
When a branch crosses a page boundary, is there a read at the address that disgregards carry (like, if branching from 80FF to +10, is there a read of 800F on the cycle before the fixup where it reads 810F?)

dvdmth wrote:
* For branch instructions, the first byte of the instruction following the branch is read on the third cycle. If the branch is taken, this result is thrown away and another byte is fetched after adjusting the lower byte of the PC. If a page boundary is crossed, this result is also thrown out and a new byte is read after fixing the upper byte of the PC.

IS this still the state-of-the-knowledge? IT aligns with all I've read, but I do not yet grok processor foibles.

Bummer, that'll make a hardware stacktracing branches significantly harder to pull off.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: glutock, Google [Bot] and 3 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:  
Powered by phpBB® Forum Software © phpBB Group