sinclair/specnext.cpp: Refactored NMI handling.#15086
sinclair/specnext.cpp: Refactored NMI handling.#15086holub wants to merge 2 commits intomamedev:masterfrom
Conversation
| macro check_interrupts | ||
| if (get_service_attention<SA_NMI_PENDING>()) { | ||
| m_nmiack_cb(1); | ||
| @take_nmi | ||
| } else if (m_irq_state != CLEAR_LINE && m_iff1 && !get_service_attention<SA_AFTER_EI>()) { // SA_IRQ_ON |
There was a problem hiding this comment.
As far as I can tell, the Z80 doesn’t actually produce a recognisable bus condition when it accepts non-maskable interrupt. It begins fetching instructions from 0x0066 with a regular instruction fetch cycle, i.e. with /M1, /MREQ and /RD asserted. MAME shouldn’t have a fake signal for a condition that isn’t externally visible.
The thing is, the IRQ acknowledge cycle (/M1 and /IORQ asserted) is needed so that:
- You can provide an interrupt handler instruction (mode 0) or vector table index (mode 2)
- You know when the interrupt has been serviced and can drop the signal, since it’s level-sensitive and interrupts can be masked
Non-maskable interrupts don’t need this because:
- There’s no need to supply an instruction or vector as the handler address is always 0x0066
- It’s edge-sensitive, so you don’t need to keep it asserted until it’s serviced
- The only things that will stop it from being serviced are reset and /BUSREQ.
Is the Z80N doing something different? If it does signal a non-maskable interrupt being serviced, how does it do so?
There was a problem hiding this comment.
I dropped everything in z80 and keep it local to z80n.
There are many challenges we still need to solve there. Read from 66 is not always NMI, it can be ordinary PC entering.
In Next we require precise state of all INT/NMI actors because depending on configuration we can have situation where DMA request is configured to be postponed in case any of this events are happening.
There was a problem hiding this comment.
The #1 question to ask, and answer, is what does the hardware do. If the softcore does not send a signal somehow to say an nmi has just been taken into account, then the system can not react to that.
Just checked the core, it has a INTcycle output, but no NMICycle (it has both internally, so it's deliberate).
No description provided.