maccasoft / P2

Projects based on the Parallax Propeller-2 multicore microcontroller.
4 stars 4 forks source link

Fix Z80 EI bug #2

Open Wuerfel21 opened 2 years ago

Wuerfel21 commented 2 years ago

There's an issue with how ZiKore implements the EI instruction - a pending IRQ should only execute after the next instruction. This is a real issue when code is written like this (from Sonic Wings 2 sound code): image

Fix is to jump directly into zk_nextop after the IRQ hooks from zk_irqon.

My fix looks like this, though it also delays NMI in cases where it shouldn't (megayume doesn't have NMI impl. Neoyume does, but the commit is more messy): https://github.com/IRQsome/MegaYume/commit/3817e5c32941b6853d7e5e92c4014bd290347602

maccasoft commented 2 years ago

Thanks for reporting. The 8086 has the same requirement and I have used a flag bit to delay the interrupt. I think I'll use the same for the Z80. Wondering if there are games that may be affected but this issue, the IRQ handling is a bit more "relaxed" in my emulators and generally is always enabled (or not used at all like the ColecoVision).

Wuerfel21 commented 2 years ago

Wondering if there are games that may be affected but this issue

I haven't properly verified it, but I think/hope this is cause of many intermittent issues I was having. Sonic Wings is just strange in that it reliably induces the edge case and fails catastrophically when it does (IRQ handler changes YM register address to ack the interrupt, unrelated main thread write then goes to timer control register, too, and stops the timer IRQ -> hang). In theory the hazard exists everywhere there is an address/data port style device that is used in interrupts.

Wuerfel21 commented 2 years ago

FYI, there's another one: in zk_i2a, there's a test that should be a testb. In effect it puts IFF1 into PF instead of IFF2. Not aware of this breaking/fixing anything, just noticed it while chasing yet more sound issues.