How to get timings right?
Posted: Thu Jun 16, 2022 10:14 am
Hello all,
I'm currently writing my first (Gameboy) emulator and have a few questions for you. At the moment I am trying to get the timings for the CPU instructions correct. I already assumed that they are correct. However, the blargg timing test for the CPU instructions tells me something different. Unfortunately I have no idea what the problem could be. The following tests ran successfully: blargg tests for all CPU instructions, mooneye timer and first memory timing tests. blargg's CPU timing test always gives me the following output:
It seems like the timings are 3 M-cycles back (unsigned wrap-around)? Does anyone have any idea what this could be?
Attached are some other questions that came to me while writing the timer:
1. The Pan Docs documentation states that if there is a TIMA overflow, the TMA reload and also the interrupt request is delayed by 4 T-cycles. However, how does this behave when the overflow happens in the middle of an M-cycle? Is this then still 4 T-cycles? Or does this shorten and the TMA reload happens already at the beginning of the next M-cycle?
2. If a TMA reload happens in parallel to a CPU memory read access? Is this immediately visible to the CPU or only in the next M-cycle? This would conflict in my case, for example, because I normally handle this as follows:
However, a test did not run with this. So I had to solve this in the following way, that the correct value is read from memory.
3. How is this generally with visibilities of CPU write/read accesses with all the parallel subsystems? When does which subsystem see what within an M-cycle or T-cycle?
4. Do you guys have any other tips on how to get a Gameboy reasonably (doesn't have to be 100% perfect) cycle accurate?
Thanks in advance for your answers.
I'm currently writing my first (Gameboy) emulator and have a few questions for you. At the moment I am trying to get the timings for the CPU instructions correct. I already assumed that they are correct. However, the blargg timing test for the CPU instructions tells me something different. Unfortunately I have no idea what the problem could be. The following tests ran successfully: blargg tests for all CPU instructions, mooneye timer and first memory timing tests. blargg's CPU timing test always gives me the following output:
Code: Select all
00:254-1 01:0-3 02:255-2 03:255-2 04:254-1 05:254-1 06:255-2 07:254-1 08:2-5 09:255-2 0A:255-2 0B:255-2 0C:254-1 ...
Instruction byte : Actual timing - Target timing
Attached are some other questions that came to me while writing the timer:
1. The Pan Docs documentation states that if there is a TIMA overflow, the TMA reload and also the interrupt request is delayed by 4 T-cycles. However, how does this behave when the overflow happens in the middle of an M-cycle? Is this then still 4 T-cycles? Or does this shorten and the TMA reload happens already at the beginning of the next M-cycle?
2. If a TMA reload happens in parallel to a CPU memory read access? Is this immediately visible to the CPU or only in the next M-cycle? This would conflict in my case, for example, because I normally handle this as follows:
Code: Select all
read_byte()
{
read_byte_from_memory()
cycle(4) // 4 T-cycles, timer, LCD/PPU, etc.
}
Code: Select all
read_byte()
{
cycle(1)
read_byte_from_memory()
cycle(3)
}
4. Do you guys have any other tips on how to get a Gameboy reasonably (doesn't have to be 100% perfect) cycle accurate?
Thanks in advance for your answers.