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

Z80 Interrupts Should Not Be 'Sticky' #14

Open
Clownacy opened this issue Jan 1, 2024 · 0 comments
Open

Z80 Interrupts Should Not Be 'Sticky' #14

Clownacy opened this issue Jan 1, 2024 · 0 comments

Comments

@Clownacy
Copy link
Owner

Clownacy commented Jan 1, 2024

vladikcomper — Today at 18:21
Hi, I have another bug report on Clownmdemu, this time quite serious~

Looks like timing of Z80 interrupts is quite buggy. From my observations, your emulator may trigger Z80's VInt mid-frame or even by the end of the frame; at any moment in time really, if interrupts were previously disabled or if Z80 was stopped. This should never happen and it may mess up some Z80 drivers in unexpected ways.

On real hardware, there's a time window of ~171 Z80 cycles since the start of VBlank when interrupt will be acknowledged. If Z80 is stopped during this time or interrupts are disabled, VInt should be missed. In Clownmdemu, however, interrupt request "sticks" and will fire whenever interrupts are re-enabled or Z80 starts again, which may happen mid-frame.
vladikcomper — Today at 18:28
... This is somewhat related to my issue with Z80<->68k access delays. You see, I attempted to implement a "calibration" check by measuring 68k ROM vs Z80 RAM access time (number of reads before VBlank) to detect and calibrate Mega PCM 2 loops for inaccurate emulators.

In inaccurate emulators ROM and RAM read count per frame match (while on real hardware ROM access is 24% slower), so it mostly worked well... Expect for Clownmdemu, which often refuses to properly calibrate, because it fires the first VBlank at arbitrary times :)

vladikcomper — Today at 18:57
There isn't much information available on the interrupts, so I gained some of this knowledge from various people or emulator's source code.

That 171 cycle window for VBlank I originally discovered in Blastem's source code. I then found it in at least one more source, so it should be really accurate:
#define Z80_INT_PULSE_MCLKS 2573 //measured value is ~171.5 Z80 clocks

When VBlanking period starts, INT pin is triggered on Z80 for roughly 171 cycles. If interrupts are enabled, Z80 disables them and executes VInt routine at 38h (I won't mention other modes useless on the MD).
If your VInt routine is shorter than 171 cycles or you re-enable interrupts (ei) immediately, the interrupt will be triggered again in the very same frame. This is why INT signal only lasts for 171 cycles and not the entire VBlank.

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

1 participant