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

incorrect speed switch implementation in CGB mode #31

Closed
Hanaasagi opened this issue Jun 1, 2021 · 5 comments
Closed

incorrect speed switch implementation in CGB mode #31

Hanaasagi opened this issue Jun 1, 2021 · 5 comments

Comments

@Hanaasagi
Copy link
Contributor

Hello, the speed switch code should get the value in the address that the PC register pointed instead of the value of in register.

if self.mmu.borrow().get(self.cpu.cpu.reg.pc) == 0x10 {

Reference: https://gbdev.gg8.se/wiki/articles/CGB_Registers#FF4D_-_KEY1_-_CGB_Mode_Only_-_Prepare_Speed_Switch

The actual speed switch is performed by executing a STOP command after Bit 0 has been set. After that Bit 0 will be cleared automatically, and the gameboy will operate at the 'other' speed.

@Hanaasagi
Copy link
Contributor Author

Sorry, my bad.

@Hanaasagi
Copy link
Contributor Author

But, if we handle a interrupt in the cpu next method. The switch_speed method will call twice. I'm not sure what will happen.

gameboy/src/cpu.rs

Lines 1677 to 1689 in e64757f

pub fn next(&mut self) -> u32 {
let mac = {
let c = self.hi();
if c != 0 {
c
} else if self.halted {
OP_CYCLES[0]
} else {
self.ex()
}
};
mac * 4
}

@mohanson
Copy link
Owner

mohanson commented Jun 1, 2021

if self.mmu.borrow().get(self.cpu.cpu.reg.pc) == 0x10 {

To be honest, I don't know why I wrote this code a few years ago, it looks completely wrong now.

@mohanson
Copy link
Owner

mohanson commented Jun 1, 2021

I think what I want to do is if mem.get(FF4D) == 0x01, but now I am not really sure

@Hanaasagi
Copy link
Contributor Author

Emm, I think there should be something here.

0x10 => {}

Maybe

            0x10 => {
                self.mem.switch_speed();  // It will need the CPU struct receive `Mmunit` type, instead of a `dyn Memory`.
                if self.mem.speed == Speed::Double {
                    // Incr the timer's div register.
                    // self.mem.timer.

                    // And more
                }
            }

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

2 participants