From 74dfe56d2b6d7ec3340e6eb665c686628f0f49e5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 2 Mar 2018 11:10:02 -0500 Subject: [PATCH] Expands documentation of NMI setting. Given that it was previously incorrect, explains logic behind request_status_ and last_request_status_ setting. Also takes the opportunity to ensure that NMI is 'sampled' at the same time as IRQ; whether the next thing should be the NMI routine now occurs one cycle before the end of any instruction. That's an assumption for now. Testing to come. --- .../Z80/Implementation/Z80Implementation.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Processors/Z80/Implementation/Z80Implementation.hpp b/Processors/Z80/Implementation/Z80Implementation.hpp index c3d8d9557..7f1442a4c 100644 --- a/Processors/Z80/Implementation/Z80Implementation.hpp +++ b/Processors/Z80/Implementation/Z80Implementation.hpp @@ -1002,12 +1002,24 @@ bool ProcessorBase::get_interrupt_line() { } void ProcessorBase::set_non_maskable_interrupt_line(bool value, HalfCycles offset) { - // NMIs are edge triggered and cannot be masked. + // NMIs are edge triggered, so react to changes only, particularly changes to active. if(nmi_line_ != value) { nmi_line_ = value; if(value) { + // request_status_ holds a bit mask of interrupt requests pending; since + // this was a new transition, an NMI is now definitely pending. request_status_ |= Interrupt::NMI; - if(offset.as_int() < 0) { + + // If the caller is indicating that this request actually happened in the + // recent past, and it happened long enough ago that it should have been + // spotted during this instruction* then change history to ensure that an + // NMI happens next. + // + // * it actually doesn't matter what sort of bus cycle is currently ongoing; + // either it is that which terminates a whole instruction, in which case this + // test is correct, or it isn't, in which case setting request_status_ above + // was sufficient and the below is merely redundant. + if(offset <= HalfCycles(-2)) { last_request_status_ |= Interrupt::NMI; } }