-
Notifications
You must be signed in to change notification settings - Fork 10
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 halted CPU behaviour #40
Comments
Advance PC as part of executing HALT, then fetch (and discard) the next instruction opcode as long as the CPU remains halted.
I've made some test changes to give the behaviour described above in a halt_tweak branch. It may be incomplete but it was enough to pass the test I wrote to detect the difference in my emulator. |
What a nice catch! I'm playing with our new shiny transistor-level simulator, https://github.com/kosarev/z80/blob/c6ad460108c514df05f47e568b1ca0ea77e12705/tests/z80sim/z80sim.py, trying to understand what is supposed to happen in silicon on
|
Advance PC as part of executing HALT, then fetch (and discard) the next instruction opcode as long as the CPU remains halted.
The traditional way to implement HALT has been to keep PC on the same instruction and execute NOPs. PC is incremented as part of acknowledging the next interrupt to step over it. However, this has been shown to not match the real Z80 CPU behaviour, and it's possible to detect the difference in code.
The following article describes it, in the section "Halt and the special reset":
http://www.primrosebank.net/computers/z80/z80_special_reset.htm
When HALT is executed it puts the CPU into a halted state (already implemented in your core). It also advances PC to point to the next instruction. During the halted state the opcode fetch runs on this new PC value but a NOP is executed instead, and PC isn't advanced. When an interrupt occurs the halted state is cleared and execution continues from the current point as normal.
It's possible to detect this behaviour with a HALT in the last byte before a contention boundary, such as 0x7FFF on the ZX Spectrum. The incorrect behaviour reads from 0x7FFF for each NOP executed at the HALT, which has more contention than the correct fetches from 0x8000. The difference in timing can be detected by measuring how much has R changed when the next interrupt is ackknowledged.
The text was updated successfully, but these errors were encountered: