cycle for cycle stuff
-
6502 Timing
cycle for cycle stuff
Does anybody have any accurate documents on 6502 timing (i.e. cycle for cycle stuff). I have used 6502_cpu.txt and the w65c02s.pdf document but they don't make sense or have conflicting theories. I am trying to implement accurate emulation so that I can execute 1 CPU cycle then 3 PPU cycles for my emulator. What did you use for your emulator?
For instance:
inline void TYA( int Cycle )
{
switch(Cycle)
{
case 0: increment CPU cc break;
case 1: A = Y break;
}
}
For instance:
inline void TYA( int Cycle )
{
switch(Cycle)
{
case 0: increment CPU cc break;
case 1: A = Y break;
}
}
-
Quietust
- Posts: 2030
- Joined: Sun Sep 19, 2004 10:59 pm
Executing partial CPU instructions is largely a waste, since it takes so much overhead and provides no benefit. If you want the precision, just emulate the CPU one instruction at a time, but have each instruction update the PPU/APU/etc. during each cycle of each instruction.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
-
Guest
-
Bregalad
- Posts: 8181
- Joined: Fri Nov 12, 2004 2:49 pm
- Location: Divonne-les-bains, France
-
Disch
- Posts: 1848
- Joined: Wed Nov 10, 2004 6:47 pm
I was under the impression that the following had accurate per-cycle operations of the CPU:
http://nesdev.com/6502_cpu.txt
near the end it gets into which reads/writes are performed on every cycle of the instruction.
As for implimentation, the easiest would probably be to pass an additional timestamp to your read/write proc indicated the number of cycles into the instruction. For example, the code for STA absolute might look something like this:
cpu_timestamp would contain the overall cycle (which in incremented by the time determined by each instruction). the last parameter passed to Read()/Write() indicates the number of cycles to add to the cpu_timestamp when "catching up" other systems. This value can usually be ignored for areas which dont' need it (for example, when reading from ROM, or reading/writing RAM... the last param will be tossed). However for register writes/reads the extra given cycle will allow you to have cycle-accurate precision when catching up the PPU and APU to the current CPU time -- at little processing cost.
}
http://nesdev.com/6502_cpu.txt
near the end it gets into which reads/writes are performed on every cycle of the instruction.
As for implimentation, the easiest would probably be to pass an additional timestamp to your read/write proc indicated the number of cycles into the instruction. For example, the code for STA absolute might look something like this:
Code: Select all
byte opcode = Read( PC, 0 );
PC++;
switch(opcode)
{
case 0x8D:
adr = Read( PC, 1 );
adr |= Read( PC + 1, 2 ) << 8;
Write( adr, A, 3 );
PC += 2;
cpu_timestamp += 4;
break;
}
}
-
teaguecl
- Posts: 211
- Joined: Thu Oct 21, 2004 4:02 pm
- Location: San Diego
A good example of how a perfectly legitimate questions becomes hilarious given the right context.Anonymous wrote:Have you written an emulator Quietust? If so do you have accurate CPU emulation?
For the benefit of the thread author, Q's emulation called Nintendulator is as close to hardware as you get.
-
Guest
Thanks I'll try that but the 6502_cpu.txt cycles explanation differs from WDC own w65c02s.pdf (basically the same CPU). This is what is concerning me.
http://www.westerndesigncenter.com/wdc/ ... 65c02s.pdf
Can anyone give a better explanation to the details of the PDF's cycle chart as I find them verry hard to understand.
http://www.westerndesigncenter.com/wdc/ ... 65c02s.pdf
Can anyone give a better explanation to the details of the PDF's cycle chart as I find them verry hard to understand.
-
Disch
- Posts: 1848
- Joined: Wed Nov 10, 2004 6:47 pm
that PDF document you linked to seems to be for a more recent processor than the processor used by the NES. It makes reference to various instructions unavailable on the 6502 (BRA, PLY, PLX) -- plus it does things 6502_cpu.txt says are CMOS processor behavior (such as doing read/write for Absolute Read/Modify/Write instrutcions, rather than dual writes) NES has an NMOS, not CMOS processor)
I'd stick with 6502_cpu.txt
I'd stick with 6502_cpu.txt
-
Guest
-
Anes
- Posts: 717
- Joined: Tue Dec 21, 2004 8:35 pm
- Location: Mendoza, Argentina
-
6502 Timing
-
jarodcanal
- Posts: 1
- Joined: Tue Sep 20, 2005 6:42 am
Hi,
I am having a look at nintendulator sources (955 beta).
I would like to be sure that I am understanding the base of your CPU emulation (I mean I am asking
). Please could you confirm that the following is correct?
Instead of having an external clock system synching CPU, PPU and APU, you use CPU cycles to synch PPU and APU.
To do that, you call RunCycle (which internally calls PPU_Run and APU_Run) from CPU_MemGet and CPU_MemSet.
CPU_MemGet and CPU_MemSet are called from opcodes and interrupts.
I suppose that this reflects the following lines from Kim programming manual:
Thanks.
Best regards
I am having a look at nintendulator sources (955 beta).
I would like to be sure that I am understanding the base of your CPU emulation (I mean I am asking
Instead of having an external clock system synching CPU, PPU and APU, you use CPU cycles to synch PPU and APU.
To do that, you call RunCycle (which internally calls PPU_Run and APU_Run) from CPU_MemGet and CPU_MemSet.
CPU_MemGet and CPU_MemSet are called from opcodes and interrupts.
I suppose that this reflects the following lines from Kim programming manual:
(http://users.telenet.be/kim1-6502/6502/proman.html#51)The major point to be noted is that every clock cycle in the MCS650X microprocessor is a memory cycle in which memory is either read or written. Simultaneously with the read or Write of memory, an internal operation of the microprocessor is also occurring.
Thanks.
Best regards
-
Quietust
- Posts: 2030
- Joined: Sun Sep 19, 2004 10:59 pm
That is correct.jarodcanal wrote:Instead of having an external clock system synching CPU, PPU and APU, you use CPU cycles to synch PPU and APU.
To do that, you call RunCycle (which internally calls PPU_Run and APU_Run) from CPU_MemGet and CPU_MemSet.
CPU_MemGet and CPU_MemSet are called from opcodes and interrupts.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
-
WedNESday
- Posts: 1311
- Joined: Thu Sep 15, 2005 9:23 am
- Location: London, England
(BTW: I started this post, under the (accidental) name of 6502 Timing)
An emulator without perfect timing would read that back as $80.
That is not true. Observe the following.Quietust wrote:Executing partial CPU instructions is largely a waste, since it takes so much overhead and provides no benefit. If you want the precision, just emulate the CPU one instruction at a time, but have each instruction update the PPU/APU/etc. during each cycle of each instruction.
...and provides no benefit.
Code: Select all
Clock Cycle #
1 2 3 4
| | | |
| | | +- Load From $2002 (i.e. $00)
| | | |
| | | |
| | | |
| +- VBlank Ends ($2002 = $00)
+- ($2002 = $80)