It is currently Mon Nov 12, 2018 5:52 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Sat Aug 18, 2018 7:37 pm 
Offline
User avatar

Joined: Wed Apr 18, 2018 1:09 am
Posts: 21
Location: Australia
Hi All,

I am really stuck on my CPU vs PPU timings in my Swift NES emulator and was wondering if someone could have a quick parse of my step() function in my Emulator class. The step() function is called 60 times per second. It calculates a target number of cycles it needs the CPU to execute (usually 29830). Inside the loop I then call the step function on each of the CPU, PPU, and APU instances. CPU should have no bugs and matches output of a test log from the wiki, APU is currently empty, and PPU step function calls PPU tick function 3 times. In the tick function the tickCount is incremented every time, this is only for debug purposes. Also inside the tick function a cycle variable is incremented (x pos) and scalene is incremented when cycle reaches 340, the frame is incremented when scaling reaches 262. These numbers may be off by 1, haven't checked them yet.

My issue is that I expect the stepUntil() function to execute 29830 cycles on the CPU and a full 89,000 PPU ticks. I am only getting around 22,000 PPU ticks before the loop exits as the CPU has executed all of its cycles.

I don't think my bug is in the PPU, I think it is in my understanding of CPU cycles vs PPU ticks. Can anyone see what I have wrong here?

Code:
    func stepUntil( secondsElapsed seconds:TimeInterval)
    {
        guard state != .stopped else { return }

        var elapsedCycles : UInt16 = 0

        let targetCycles = Int(TimeInterval(cpu.frequencyHz) * seconds)

        ppu.tickCount = 0

        repeat
        {
            let (cont, instructionInfo) = cpu.step()
            ppu.step()
            apu.step()

            elapsedCycles += instructionInfo.cycles

            if cont == false
            {
                state = .stopped
            }

        } while state != .stopped && elapsedCycles < targetCycles

        print("Cycles: \(elapsedCycles) PPU:\(ppu.tickCount) frame:\(ppu.frame) scanline:\(ppu.scanline)")
    }

    @objc func step()
    {
        print("FPS:\(round(1.0/(displayLink.targetTimestamp - displayLink.timestamp)))")

        stepUntil( secondsElapsed:1.0/60.0)
    }


The output of this code is:
Code:
Cycles: 29830 PPU:22674 frame:4 scanline:240
Cycles: 29829 PPU:22068 frame:5 scanline:42
Cycles: 29834 PPU:22668 frame:5 scanline:109
Cycles: 29830 PPU:22674 frame:5 scanline:175
Cycles: 29859 PPU:22407 frame:5 scanline:241
Cycles: 29829 PPU:22161 frame:6 scanline:44


As you can see it takes 4 device Frames to output a single frame (Frame 5 here). My emulator step function gets called 60 FPS consistently and is not dropping frames (I have triple checked). My PPU is only getting to execute 22,000 ticks instead of 89,000.

Cheers,
Brett


Top
 Profile  
 
PostPosted: Sat Aug 18, 2018 8:40 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1440
It looks like you're only running the PPU and APU once per CPU instruction, not once per CPU cycle - put ppu.step() and apu.step() inside a loop that runs for instructionInfo.cycles iterations and you'll probably be a bit closer to desired behavior, though you might still have some extremely minor issues regarding reads and writes being bunched together at the end of CPU instructions (i.e. instead of being done during each instruction cycle).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
PostPosted: Sat Aug 18, 2018 9:48 pm 
Offline
User avatar

Joined: Wed Apr 18, 2018 1:09 am
Posts: 21
Location: Australia
OMG Quietust you are absolutely right, have been staring at this for a few days but couldn't see what I got wrong. Clear as day once it is pointed out.

Thanks heaps,
Brett


Top
 Profile  
 
PostPosted: Mon Aug 20, 2018 5:45 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4104
Meanwhile, I'm just doing the hack where you make events happen 12 ticks before they actually do for the purposes of polling.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 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