6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 10:12 pm

All times are UTC




Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 14, 2019 7:34 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
The nature of stacks means you can nest them as deeply as you want, with no interference in that regard. You would still have to be careful of course if there's a chance that a second or third nested ISR would use other resources before the first one is finished with them. I've brought a lot of products to market using PIC16 microcontrollers, and with those, since they don't give the programmer direct access to the stack (which is quite shallow anyway), you have to use variables to save your W (working register, like the 6502's accumulator), status register, PCLATH (program counter latch high byte, so you can get back to the right program memory page if you're using more than just page 0), meaning that a nested interrupt would step on the variables used by the outer one. The 6502 doesn't have this problem though.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 14, 2019 8:23 pm 
Offline

Joined: Wed Mar 02, 2016 12:00 pm
Posts: 343
Thank you for the insight. I will have to careful with the "stack" of memory page pointers that I keep in the background. Its as deep as the 6502 stack, but there is no way to read it (from the code) at the moment. Anyway with a proper defined logic I should be able to handle nested interrupts so that memory page pointers stick to were they are used.

With many interrupts, the obvious problem is to manage the page pointers for the different interrupts (as you said). Currently I only have one for IRQ and one for NMI, so I will have to think about how to make a handler for that..


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 14, 2019 8:40 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
If you're writing your own ISRs, you don't have to have nested IRQs unless you choose to. If you do use CLI in your ISR, then you may see nested interrupts, but if you don't, the RTI will clear the I flag for you and the ISR calls will be serialised.

But there's nothing you can do in software about the NMIs because they are non-maskable: it's a question of whether the hardware is able to raise them faster than they are serviced, I think.


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 14, 2019 9:30 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
kakemoms, you seem to be referring to an '02 system with banking, something I missed earlier. Perhaps you've been discussing it in another topic. It's hard to keep everyone's projects straight in my mind.

The need for nested IRQ ISRs should be pretty rare. The interrupts primer just mentions the possibility of needing to service a second, more-urgent one before getting back to the first one which may take longer to finish servicing. I've heard people advocate for ISRs that are so short they're basically just leaving a flag for the background program to poll and take care of; but if they're going to poll anyway, what's the point in generating and interrupt?!

The 6502 stacks treatise might prove helpful.

As for NMIs, they are by definition not maskable; but you can still tell the interrupt source to stop generating interrupts until further notice.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 21, 2019 6:38 pm 
Offline

Joined: Wed Mar 02, 2016 12:00 pm
Posts: 343
Thank you all for the helping comments.

I am currently working with a 6522 that generates IRQ and another that generates NMI for the 6502. I didn't think the NMI would be a problem since its only triggered by a key (or BRK) and that should only happen once when that key is pressed. A human being isn't fast enough to press this key twice, so the first NMI should be finished before another can happen.

Now, I see that it does happen several times. E.g. the key can trigger anything from 1 to 10+ NMIs in a row (probably due to the mechanical "switch" being a trigger) before one NMI has been finished (with a RTI). That is interesting in its own (the interrupt only lasting 20-50 CPU cycles), but I also have to handle it in the MMU. If one NMI happens before another one is finished, it does not seem to end in two RTI instances. E.g. the code returns to the address were the first NMI happened, but not to the second.

This is what seems to happen:
Code:
NMI (store ADDR) --> NMI handler
(some code)
    NMI (store ADDR2) --> NMI handler
    (some code)
    RTI
returns to ADDR


This is what I thought would happen:
Code:
NMI (store ADDR) --> NMI handler
(some code)
    NMI  (store ADDR2) --> NMI handler
    (some code)
    RTI
returns to ADDR2
(some code)
RTI
returns to ADDR


Is this how the non-maskable interrupt is supposed to work? If so, I have to keep record of recurring NMI instances without a RTI in between.

If I get a BRK and a NMI a few cycles after, will the first RTI return to the address of the BRK command and not the NMI?

Oh, and this is for NMOS 6502.


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 21, 2019 8:37 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
There's nothing magic about RTI. It's no different than an RTS with a free pop of the status register. Other than that, it has no special properties.

What I don't know, but I'm sure Garth's interrupt primer covers, is exactly when in the NMI processing cycle another NMI fires. But as I recall, NMI is edge triggered, vs IRQ which is level triggered. I don't think an NMI can actually interrupt an NMI until after it's pushed both the address and status register.

But also don't forget, that when the second NMI does fire, the address it does push is very likely in your NMI handler already, so it's easy to see how it looks like the NMI is returning back to just ADDR if you miss the part where it re-entered the NMI handler.


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Tue May 21, 2019 9:12 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
You can definitely nest NMI's, and the processor won't get confused as to where to return to. However, if for example the ISR starts processing a two-byte variable, and gets one byte through it, and starts over, you can see there could be trouble. [Edit: This if if the same part of the ISR runs, using the same variables (without stacking them) and other resources. If the initial polling determines that the interrupt came from a different source and requires different service, this particular problem probably won't arise; but having multiple NMI sources may lead to other (worse) problems, also discussed in the interrupts primer.]

Quote:
If I get a BRK and a NMI a few cycles after, will the first RTI return to the address of the BRK command and not the NMI?

Oh, and this is for NMOS 6502.

As mentioned in the interrupts primer, one of the NMOS 6502 bugs is that if an NMI hits during a BRK instruction, the BRK interrupt will not get executed. (This, as well as all other NMOS 6502 bugs, have been fixed in the CMOS 65C02.)

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed May 22, 2019 6:29 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1952
Location: Sacramento, CA, USA
If (and only if) your NMI handler is re-entrant, it should be able to nest within anything including itself comfortably (up to the stack limit) just like any other stack-based routine.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed May 22, 2019 11:44 am 
Offline

Joined: Wed Mar 02, 2016 12:00 pm
Posts: 343
Ok. Thanks for all the tips. Apparently I have some more debugging to do. :roll:


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed May 22, 2019 1:58 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Quote:
Now, I see that it does happen several times. E.g. the key can trigger anything from 1 to 10+ NMIs in a row (probably due to the mechanical "switch" being a trigger)
This issue alone could account for most or all of your difficulty. You could -- either for debugging or as a permanent solution -- add a debounce filter in hardware to guarantee the CPU's NMI input sees only a single transition for every keypress. An RC network followed by a Schmitt trigger would do the trick. Otherwise you could alter your NMI ISR and/or the use of the VIA's IFR to filter out the switch bounce.

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed May 22, 2019 7:02 pm 
Offline

Joined: Wed Mar 02, 2016 12:00 pm
Posts: 343
Dr Jefyll wrote:
This issue alone could account for most or all of your difficulty. You could -- either for debugging or as a permanent solution -- add a debounce filter in hardware to guarantee the CPU's NMI input sees only a single transition for every keypress. An RC network followed by a Schmitt trigger would do the trick. Otherwise you could alter your NMI ISR and/or the use of the VIA's IFR to filter out the switch bounce.

-- Jeff

Yes I added such a filter. In the event that more than one NMI happens, it will only care about one. I will remove it again since it will make a mess of the logic (that takes care of nested interrupts), but for now I keep it to find the other bug I am experiencing (see below).

Reading what happens in the 6502 based entirely on the data/address bus is not easy, and for IRQ/NMI it is less obvious. I can look for the IRQ and NMI vectors on the address bus, but what is making this difficult is that the last opcode (to run) is not the last thing that appears on the databus. I run this code on the 6502:

Code:
1F42   8A       loop0           TXA
1F43   FC 33 00                 NOP $0033,X
1F46   9D 00 A0                 STA $A000,X
1F49   E8                       INX
1F4A   D0 F6                    BNE loop0


The "NOP" opcode $FC is my MMU instruction that the Verilog code reads to switch memory page (here its page $33 which translates to address $33xxx). The STA $A000 accesses the external memory that is controlled by the MMU ($A000-$AFFF range) so that these two opcodes end in a STA to address $33000,X. This usually works but not if a IRQ happen. The following debug waveform shows what is happening:
Attachment:
File comment: Debug waveform
Debug.png
Debug.png [ 53 KiB | Viewed 5115 times ]


As you can see from the address and databus, an IRQ had been triggered and eventually access address $FFFE and $FFFF (this shows up as $3FFE and $3FFF here since I don't read A14 and A15). Anyway, the trigger happen after the "NOP $0033,X" instruction (with opcode $FC), but for some reason the next opcode byte $9D (STA) appears on the databus before the IRQ actually triggers. That is what was confusing my MMU decoder.

I have tested this in the Visual6502 simulator and it also happens there, so I just have to adjust the code to cope with this quirk..

Edit: I have adjusted the code and it now seems to work as expected.

Thanks to you all for all the help! (again!)


Last edited by kakemoms on Wed May 22, 2019 8:52 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed May 22, 2019 8:26 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
kakemoms wrote:
the trigger happen after the "NOP $0033,X" instruction (with opcode $FC), but for some reason the next opcode byte $9D (STA) appears on the databus before the IRQ actually triggers. That is what was confusing my MMU decoder.

I have tested this in the Visual6502 simulator and it also happens there, so I just have to adjust the code to cope with this quirk..

This is supported by the 65816 data sheet which has the cycle-by-cycle behavior of every addressing mode, as well as by my own testing.  The processor picks up the first byte of the following instruction and then discards it, as it is doing internal operations in preparation to handle the interrupt.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed Dec 06, 2023 3:55 am 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
I came to this topic looking for information on how the 6502 handles overlapping BRKs, IRQs, and NMIs - I think the visual6502 examples above are a great illustration of this for the older NMOS chips. On those it appears that an NMI, for example, occuring in the middle of a BRK instruction or IRQ sequence, will change the vector that gets loaded at the end of the sequence, to the NMI vector. This is actually a bug, as the program counter has already advanced past the BRK instruction, and it leads to the BRK being skipped.

In addition I found by modifying the visual6502 example that an NMI that occurs during the vector fetch is actually ignored; also, short low pulses on NMI seem to be ignored, it is necessary for NMI to be low at the falling edge of PHI2 for the low transition to be spotted by the NMOS CPU. This is consistent with the timing documentation in the datasheet even for the CMOS part.

Knowing that the bug in particular was fixed in the WDC 65C02, and that I'm going to be dependent on it, I thought it worth carrying out more tests on the newer hardware, and thought I'd share the results here as it differs quite a bit from the NMOS behaviour. I performed these tests by hooking up an Arduino to a bare 65C02 and having it drive the control signals and data bus appropriately, logging the results.

Firstly, as a reference I wanted to measure the timing behaviour of IRQB - after it goes low, how long is it before the interrupt sequence can begin? It appears that, for a sync cycle to start the interrupt sequence, IRQB needs to have been low back at the start of a full cycle before it (treating a cycle as the low phase followed by the high phase of the PHI2 clock) - i.e. it must have gone low during the high phase of the cycle two before the current cycle, otherwise the current sync cycle will execute its instruction as normal.

Here's a log taken by an Arduino that's carefully driving the CPU at a fairly slow clock rate. Each line is the bus state in the middle of a half-cycle. 'i' means IRQB is low; transitions happen in the middle of the half-cycle, before the state is printed. 'S' means it's a sync cycle.
Code:
  15 H  --  -S  0007  R  ea
  16 l  i-  --  0008  R  ea  <= IRQB goes low during phase 1
  16 H  i-  --  0008  R  ea
  17 l  i-  -S  0008  R  ea  <= Sync, too soon
  17 H  i-  -S  0008  R  ea
  18 l  i-  --  0009  R  ea
  18 H  i-  --  0009  R  ea
  19 l  i-  -S  0009  R  ea  <= Sync, interrupt sequence starts
  19 H  i-  -S  0009  R  ea
  20 l  i-  --  0009  R  ea
  20 H  i-  --  0009  R  ea
  21 l  i-  --  01ff  w  ea

  16 l  --  --  0008  R  ea
  16 H  i-  --  0008  R  ea   <= IRQB goes low during phase 2
  17 l  i-  -S  0008  R  ea   <= Sync, too soon
  17 H  i-  -S  0008  R  ea
  18 l  i-  --  0009  R  ea
  18 H  i-  --  0009  R  ea
  19 l  i-  -S  0009  R  ea   <= Sync, interrupt sequence starts
  19 H  i-  -S  0009  R  ea
  20 l  i-  --  0009  R  ea
  20 H  i-  --  0009  R  ea
  21 l  i-  --  01ff  w  ea

  15 l  i-  -S  0007  R  ea  <= IRQB goes low during phase 1
  15 H  i-  -S  0007  R  ea
  16 l  i-  --  0008  R  ea
  16 H  i-  --  0008  R  ea
  17 l  i-  -S  0008  R  ea  <= Sync, interrupt sequence starts
  17 H  i-  -S  0008  R  ea
  18 l  i-  --  0008  R  ea
  18 H  i-  --  0008  R  ea
  19 l  i-  --  01ff  w  ea

  15 l  --  -S  0007  R  ea
  15 H  i-  -S  0007  R  ea  <= IRQB goes low during phase 2
  16 l  i-  --  0008  R  ea
  16 H  i-  --  0008  R  ea
  17 l  i-  -S  0008  R  ea  <= Sync, interrupt sequence starts
  17 H  i-  -S  0008  R  ea
  18 l  i-  --  0008  R  ea
  18 H  i-  --  0008  R  ea
  19 l  i-  --  01ff  w  ea

So there's a baseline for IRQ latency. What about NMIB? Well as I said above, unlike the NMOS version, brief low pulses seem to be enough to trigger an NMI with the CMOS part, so it is clearly no longer being latched on a clock edge. Here are examples of that - 'n' indicates that NMIB was brought low then quickly high again, in the middle of the half-cycle. The timing is substantially the same as for IRQB.
Code:
  17 l  -n  --  00ff  R  00   <= NMIB pulse during phase 1
  17 H  --  --  00ff  R  00
  18 l  --  -S  0009  R  ea   <= Sync, too soon
  18 H  --  -S  0009  R  ea
  19 l  --  --  000a  R  ea
  19 H  --  --  000a  R  ea
  20 l  --  -S  000a  R  ea   <= Sync, interrupt sequence starts
  20 H  --  -S  000a  R  ea
  21 l  --  --  000a  R  ea
  21 H  --  --  000a  R  ea
  22 l  --  --  01ff  w  ea

  17 H  -n  --  00ff  R  00   <= NMIB pulse during phase 2
  18 l  --  -S  0009  R  ea   <= Sync, too soon
  18 H  --  -S  0009  R  ea
  19 l  --  --  000a  R  ea
  19 H  --  --  000a  R  ea
  20 l  --  -S  000a  R  ea   <= Sync, interrupt sequence starts
  20 H  --  -S  000a  R  ea
  21 l  --  --  000a  R  ea
  21 H  --  --  000a  R  ea
  22 l  --  --  01ff  w  ea

  18 l  -n  -S  0009  R  ea   <= NMIB pulse during phase 1
  18 H  --  -S  0009  R  ea
  19 l  --  --  000a  R  ea
  19 H  --  --  000a  R  ea
  20 l  --  -S  000a  R  ea   <= Sync, interrupt sequence starts
  20 H  --  -S  000a  R  ea
  21 l  --  --  000a  R  ea
  21 H  --  --  000a  R  ea
  22 l  --  --  01ff  w  ea

  18 H  -n  -S  0009  R  ea   <= NMIB pulse during phase 2
  19 l  --  --  000a  R  ea
  19 H  --  --  000a  R  ea
  20 l  --  -S  000a  R  ea   <= Sync, interrupt sequence starts
  20 H  --  -S  000a  R  ea
  21 l  --  --  000a  R  ea
  21 H  --  --  000a  R  ea
  22 l  --  --  01ff  w  ea


Next, here are typical BRK and IRQ sequences for reference:
Code:
  22 l  --  -S  000b  R  00   <= BRK
  22 H  --  -S  000b  R  00
  23 l  --  --  000c  R  00   <= PC incremented
  23 H  --  --  000c  R  00
  24 l  --  --  01ff  w  00
  24 H  --  --  01ff  w  00
  25 l  --  --  01fe  w  00
  25 H  --  --  01fe  w  0d
  26 l  --  --  01fd  w  0d
  26 H  --  --  01fd  w  32   <= flags bit 4 is set
  27 l  --  v-  fffe  R  00
  27 H  --  v-  fffe  R  00
  28 l  --  v-  ffff  R  00
  28 H  --  v-  ffff  R  00

  16 H  i-  --  0008  R  ff   <= IRQ
  17 l  i-  --  00ff  R  00
  17 H  i-  --  00ff  R  00
  18 l  i-  -S  0009  R  ea   <= Interrupt sequence
  18 H  i-  -S  0009  R  ea
  19 l  i-  --  0009  R  ea   <= No PC increment
  19 H  i-  --  0009  R  ea
  20 l  i-  --  01ff  w  ea
  20 H  i-  --  01ff  w  00
  21 l  i-  --  01fe  w  00
  21 H  i-  --  01fe  w  09
  22 l  i-  --  01fd  w  09
  22 H  i-  --  01fd  w  22   <= flags bit 4 is clear
  23 l  i-  v-  fffe  R  00
  23 H  i-  v-  fffe  R  00
  24 l  i-  v-  ffff  R  00
  24 H  i-  v-  ffff  R  00

What happens if IRQ and BRK happen at roughly the same time? On the NMOS CPUs the BRK sequence would be converted (mostly) into an IRQ sequence, just with the PC being incremented incorrectly. On the CMOS CPUs it depends which happens first:
Code:
IRQ during BRK - treated as BRK

  22 l  --  -S  000b  R  00   <= BRK
  22 H  i-  -S  000b  R  00   <= IRQB low
  23 l  i-  --  000c  R  00   <= PC incremented
  23 H  i-  --  000c  R  00
  24 l  i-  --  01ff  w  00
  24 H  i-  --  01ff  w  00
  25 l  i-  --  01fe  w  00
  25 H  i-  --  01fe  w  0d
  26 l  i-  --  01fd  w  0d
  26 H  i-  --  01fd  w  32   <= flags bit 4 is set
  27 l  i-  v-  fffe  R  00
  27 H  i-  v-  fffe  R  00
  28 l  i-  v-  ffff  R  00
  28 H  i-  v-  ffff  R  00

IRQ before BRK - treated as IRQ

  20 H  i-  -S  000a  R  ea   <= IRQB low
  21 l  i-  --  000b  R  00
  21 H  i-  --  000b  R  00
  22 l  i-  -S  000b  R  00   <= Interrupt sequence
  22 H  i-  -S  000b  R  00
  23 l  i-  --  000b  R  00   <= PC not incremented
  23 H  i-  --  000b  R  00
  24 l  i-  --  01ff  w  00
  24 H  i-  --  01ff  w  00
  25 l  i-  --  01fe  w  00
  25 H  i-  --  01fe  w  0b
  26 l  i-  --  01fd  w  0b
  26 H  i-  --  01fd  w  22   <= flags bit 4 clear
  27 l  i-  v-  fffe  R  00
  27 H  i-  v-  fffe  R  00
  28 l  i-  v-  ffff  R  00
  28 H  i-  v-  ffff  R  00

In the latter case of course the BRK will execute after the RTI from the interrupt handler's response to IRQB.

Finally, how do NMI and IRQ behave when they collide? On NMOS, an NMI during an IRQ sequence changes the vector to the NMI vector, effectively masking the IRQ. If IRQB is still low after the NMI returns then the IRQ sequence will run at that point.

However, on CMOS, if NMI is not triggered soon enough before the interrupt sequence begins, the CPU delays processing the NMI until after the interrupt sequence that's in progress. So we see the IRQ sequence run to completion, followed by an immediate NMI sequence:
Code:
  20 H  i-  -S  000a  R  ea   <= IRQB low
  21 l  in  --  000b  R  00   <= NMI pulse
  21 H  i-  --  000b  R  00
  22 l  i-  -S  000b  R  00   <= IRQ sequences starts
  22 H  i-  -S  000b  R  00
  23 l  i-  --  000b  R  00   <= No PC increment
  23 H  i-  --  000b  R  00
  24 l  i-  --  01ff  w  00
  24 H  i-  --  01ff  w  00
  25 l  i-  --  01fe  w  00
  25 H  i-  --  01fe  w  0b
  26 l  i-  --  01fd  w  0b
  26 H  i-  --  01fd  w  22
  27 l  i-  v-  fffe  R  00   <= IRQ vector read
  27 H  i-  v-  fffe  R  00
  28 l  i-  v-  ffff  R  00
  28 H  i-  v-  ffff  R  00
  29 l  i-  -S  0000  R  e6   <= NMI sequence starts
  29 H  i-  -S  0000  R  e6
  30 l  i-  --  0000  R  e6
  30 H  i-  --  0000  R  e6
  31 l  i-  --  01fc  w  e6
  31 H  i-  --  01fc  w  00
  32 l  i-  --  01fb  w  00
  32 H  i-  --  01fb  w  00
  33 l  i-  --  01fa  w  00
  33 H  i-  --  01fa  w  26
  34 l  i-  v-  fffa  R  00   <= NMI vector read
  34 H  i-  v-  fffa  R  00
  35 l  i-  v-  fffb  R  00
  35 H  i-  v-  fffb  R  00

The same is true for an NMI occuring during a BRK sequence. Essentially, the NMI has to wait until the next viable SYNC cycle, just as it would for any other instruction - the ability to modify the sequence that's already in progress is no longer there in the CMOS version. But even though it doesn't run the NMI sequence straight away, it does remember that NMIB was triggered and an NMI sequence is due, unlike the NMOS CPU in some cases.

I hope this is useful to some people - it has highlighted some issues that would have occured if I'd gone ahead as planned, especially in these differences to the behaviour seen for the NMOS CPU in visual6502. In case anybody else wants to try this out, I'll attach my Arduino code - it's set up for an Arduino Mega.


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed Dec 06, 2023 5:46 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Thanks for the analysis, George! And BTW there's another interrupt quirk worth mentioning. I don't know if you've already seen this, or whether it might affect your plans, but FWIW...

A taken branch delays interrupt handling by one instruction

-- Jeff

Edited to add: in some scenarios it's important for external logic to be "aware" that an interrupt sequence is beginning, and that -- although SYNC has gone high -- the opcode on the bus will NOT be executed. Luckily, it doesn't taken much to detect this. Normally, the address bus will always increment to fetch the next byte after the opcode, but this increment is absent if an interrupt sequence is beginning... and the missing increment can be detected by capturing A0 when SYNC is high and, in the following cycle, doing an XOR of the new A0 with the captured A0.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
 Post subject: Re: BRK/IRQ/NMI
PostPosted: Wed Dec 06, 2023 11:14 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
Dr Jefyll wrote:
Thanks for the analysis, George! And BTW there's another interrupt quirk worth mentioning. I don't know if you've already seen this, or whether it might affect your plans, but FWIW...

A taken branch delays interrupt handling by one instruction

Thanks Jeff - my plans were already scuppered by what I found, as I was going to rely on disabling NMIs in hardware based on the IRQ's vector fetch - and what I found above means that won't work as it's possible for an NMI triggered before an IRQ even begins to take place after the IRQ sequence. So I'm moving to some backup plans now :)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: