Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APU Problems #22

Open
rdanbrook opened this issue Sep 30, 2016 · 6 comments
Open

APU Problems #22

rdanbrook opened this issue Sep 30, 2016 · 6 comments

Comments

@rdanbrook
Copy link

I have noticed you have the exact same problem I do in my emulator, which is that during the Zelda title screen, the pulse waves cut out too quickly; there is a bit of a gap that should not be there. Just thought I'd point it out in case you can figure out the root cause before I do; I suspect we may have used the same docs to write our APUs, and maybe there is a problem in the documentation. I have determined that in my emu, the pulse length counter hits 0 too quickly, but not sure why.

@fogleman
Copy link
Owner

Yeah, I've been suspicious of subtle APU bug(s)... let me know if you figure it out.

@rdanbrook
Copy link
Author

rdanbrook commented Oct 15, 2016

// mode 0:    mode 1:       function
// ---------  -----------  -----------------------------
//  - - - f    - - - - -    IRQ (if bit 6 is clear)
//  - l - l    l - l - -    Length counter and sweep
//  e e e e    e e e e -    Envelope and linear counter

This is incorrect for "mode 1" which is actually the 5-step mode. The correct timings are here: https://wiki.nesdev.com/w/index.php/APU_Frame_Counter

It appears your 5-step mode is simply backwards. I rewrote my frame sequencer code to reflect this, and now all of the problems have gone away.

@fogleman
Copy link
Owner

What do you mean "backwards"? Can you explain further?

@rdanbrook
Copy link
Author

rdanbrook commented Oct 15, 2016

    case 5:
        apu.frameValue = (apu.frameValue + 1) % 5
        switch apu.frameValue {
        case 1, 3:
            apu.stepEnvelope()
        case 0, 2:
            apu.stepEnvelope()
            apu.stepSweep()
            apu.stepLength()

Cases 1 and 3 should step Sweep and Length, cases 0 and 2 should not.

I can't figure out how to recompile your application to test (I used "go get github.com/fogleman/nes" and I'm not really familiar with the Go programming language). But this is what fixed my APU, as I also originally used blargg's apu_ref.txt.

@chrisd1100
Copy link

I actually think I've found the root of the problem:

https://github.com/fogleman/nes/blob/master/nes/apu.go#L5

When in mode 1 (5 step sequence), the steps happen at a lower frequency (see https://wiki.nesdev.com/w/index.php/APU_Frame_Counter). Simply divide the CPU frequency by 192 instead of 240 when in mode 1 and it will slow down the pulse.

@fogleman
Copy link
Owner

@chrisd1100 192 is 4/5 of 240. Note that nothing happens in one of the five cases in stepFrameCounter. So I think that's correct.

@rdanbrook I think I notice a difference on the Zelda title screen with that change. So I guess I'll commit it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants