I think "PPU runs prior to CPU" is a rather ambiguous statement.
What I think this is getting at is that you get a subtly different timing result if CPU writes begin to affect the PPU on the following clock, or on the same clock.
The truth of it is that CPU instructions take multiple clocks, and different things happen on each clock of the instruction. I believe writes usually happen on the last clock of an instruction (don't take my word for this, look it up), but there are some exceptions.
Method for timing PPU with CPU
Moderator: Moderators
- rainwarrior
- Posts: 8735
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Method for timing PPU with CPU
Not in terms of emulation. Like run_cpu() then run_ppu() 3 times (NTSC). Look back.rainwarrior wrote:I think "PPU runs prior to CPU" is a rather ambiguous statement.
Exactly!What I think this is getting at is that you get a subtly different timing result if CPU writes begin to affect the PPU on the following clock, or on the same clock.
Yup.The truth of it is that CPU instructions take multiple clocks, and different things happen on each clock of the instruction. I believe writes usually happen on the last clock of an instruction (don't take my word for this, look it up), but there are some exceptions.
Re: Method for timing PPU with CPU
I was looking online at examples of what other emulator authors did to create their cycles and I think I've found a method that compromises between rainwarrior's catch-up method and the CPU/PPU/PPU/PPU loop method.
The CPU step method returns the number of cycles an instruction takes, and then the main loop runs the PPU for 3*cpuCycles cycles.
Thoughts?
Source: https://github.com/fogleman/nes/
The CPU step method returns the number of cycles an instruction takes, and then the main loop runs the PPU for 3*cpuCycles cycles.
Thoughts?
Code: Select all
//Modified from Go to C++
int cpuCycles = CPU.Step()
int ppuCycles = cpuCycles * 3
for(i := 0; i < ppuCycles; i++) {
PPU.Step()
}
Aliasmk- GitHub :: Twitter :: Website
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!
Current ALIAneS Emulator Progress: CPU complete, PPU indev - we have graphics and sprites!
Re: Method for timing PPU with CPU
Nintendulator's CPU executes each instruction as a sequence of microintructions. Each microinstruction takes 1 CPU cycle. And, every microinstruction triggers a main memory read or write. Within the read and write routines, the PPU is advanced. For NTSC, it is advanced by 3 PPU cycles. For PAL, it is normally advanced by 3 PPU cycles and by 4 PPU cycles every 5 advances, producing an average rate of 3.2 PPU cycles per CPU cycle.
The CPU and PPU will always be slightly out of sync. Nintendulator compensates by slightly adjusting the PPU rendering timings.
The CPU and PPU will always be slightly out of sync. Nintendulator compensates by slightly adjusting the PPU rendering timings.