6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 11:33 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Fri Oct 21, 2016 11:34 am 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
The fact that I've implemented my method for interrupt routing in a HDL and programmable logic is probably just a detail - doubtless what I've done could be implemented in traditional 74xxx parts.

So my micro has around 8 interrupt sources. I had a few goals in mind:

:arrow: Fast - obviously it needs to be more efficient then simply polling each peripheral IC.
:arrow: Enabling/disabling particular interrupts, so if the IC - for whatever reasons - generates an interrupt it can be ignored.
:arrow: Work within the restrictions of my current circuit: there is no way to directly present a ISR vector on the databus due to some missing CPU pins at the programable logic part

So what I have is a register map like this:

SETINTMASK - write only: each bit that is a 1 is set in the "IRQ filter"
CLEARINTMASK - write only: each bit that is a 1 is cleared in the "IRQ filter"
INTSTATUS - read only: a priority encoded number for the interrupt bit that is currently active

At the same time as generating INTSTATUS the implementation also generates the CPUs IRQ line (by comparing the masked status against 0).

The reason for the SET and CLEAR action was to make the interrupt setup as simple as possible - no need to read in the current mask, OR the new mask and write it out again.

The priority encoding saves a whole bunch of code in the top-level ISR. It just has to read INTSTATUS, rotate it left once and extract the particular device's handler from a table. The value 0 means something has gone wrong (it should never happen because the IRQ line should be high in this case.) The priorities are hardcoded in the HDL, something I'm not especially pleased with (it could be nice to make them configurable from CPU code) but I can live with it. I'm not sure if this is how "real" interrupt routers deal with prioritising device interrupt lines?

I guess for efficiency I could rotate the INTSTATUS in the HDL, but that seems a bit dirty somehow.

One thing I've pondered is for the HDL itself to hold the table of the device ISRs. In theory that would reduce the CPU ISR code to reading the "INTSTATUS" 16 bit value and jumping through it, probably the next best thing to having the interrupt router present the device's vector directly. But this would consume a fair amount of resources in my limited FPGA.

What approaches have others taken for dealing with computers with "many" interrupt sources?

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 21, 2016 1:49 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Aslak3:

I use an approach similar to that which you suggest near the bottom of your post. IOW, the interrupt handler presents a vector from which is then fetched the ISR address. You can take a similar approach by making your INTSTATUS register a 16-bit register as you noted, and using jmp (INTSTATUS) to fetch the vector to the ISR. This approach should be fairly easy to implement with your fixed priority scheme, i.e. not wasteful of your limited FPGA resources, particularly since the upper half of the INTSTATUS register is likely to be a constant like 0xFF.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 21, 2016 9:20 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
I like your eight interrupt-request inputs, since it reduces the need for polling. With the standard '02 on my workbench computer, I put VIA1 on NMI\ to reduce the polling overhead, since the only interrupt I use on VIA1 is T1, for the real-time clock, and nothing else is on NMI. I'm really just using it to get for the additional interrupt input. When I need to turn it off, I just do
Code:
        LDA  #%01000000
        STA  VIA1IER
And to turn it back on:
Code:
        LDA  #%11000000
        STA  VIA1IER

I have the other interrupt sources on IRQ\.

Here are some things to keep in mind if you're going to use off-the-shelf outboard I/O ICs (rather than incorporating the I/O in the same FPGA with the processor).

Each I/O IC that can generate interrupts has a simple way to disable the interrupts, even individual interrupts within the same IC, as in the example above which requires no ANDing or ORing, and takes six cycles (or five cycles in the remote chance that you have your I/O in ZP).

A fast (single cycle!) way to keep generated interrupt signals from reaching the 65c02 would be to use OR gates with one input of a gate connected to an output from Jeff's circuits at http://wilsonminesco.com/6502primer/potpourri.html#Jeff, under "Some tricks from Jeff Laughton (Dr Jefyll on 6502.org's forum)." A high output bit from his circuit there would hold the output of the OR gate high, meaning no IRQ. All of this can of course be done in your programmable logic if desired.

As for making polling fast, remember:

  • An interrupt source will not generate any interrupts without first being enabled; so you already know that an interrupt didn't come from a chip that your program didn't set up to generate interrupts. Don't waste time polling it.

  • Next, you probably won't have more than just a few of the many possible interrupts enabled at any given time. My workbench computer has more than three dozen possible sources of interrupt; but I can't think of any time I had more than three interrupts enabled at once. The ISR should poll the most likely or the most urgent one first, and never poll ones that aren't even enabled. The ISR could start with for example (this is for Daryl's SBC-2 board which has two VIAs and an ACIA),
    Code:
    ISR:  BIT  VIA1_STATUS    ; Check 6522 VIA1's status register without loading.
          BMI  SERVICE_VIA1   ; If it caused the interrupt, branch to service it.

          BIT  VIA2_STATUS    ; Otherwise, check VIA2's status register.
          BMI  SERVICE_VIA2   ; If that one did the interrupt, branch to service it.

          JMP  SERVICE_ACIA   ; If both VIAs say "not me," it had to be the 6551 ACIA.
      ;-------------          ; (Don't forget that the last ISR instruction to be
                              ;    executed must be RTI, not RTS.)

    If this might sometimes need to change for maximum efficiency, you can have it get modified by your routine that installs and de-activates interrupts.

    After that, suppose it branches to SERVICE_VIA1. The VIA has seven possible interrupt sources. The only way to determine which of those sources generated the interrupt is with software. Again, poll only the activated ones, and first poll the most likely or the most urgent one.


The ISR examples I see in books are usually way more complicated and inefficient than they need to be.

_________________
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  
PostPosted: Sun Oct 23, 2016 11:05 am 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
MichaelM wrote:
... This approach should be fairly easy to implement with your fixed priority scheme, i.e. not wasteful of your limited FPGA resources, particularly since the upper half of the INTSTATUS register is likely to be a constant like 0xFF.


It's an interesting way to save resources if I fixed the entry point of handlers into a single page; I hadn't thought of that, thanks. I'm also going to see if I can use the RAM bits in the FPGA to hold the 16x8 pointers. If that's possible then it probably won't really matter. (I'm using a Altera Flex 10K (EPF10K10))

GARTHWILSON wrote:
I like your eight interrupt-request inputs, since it reduces the need for polling. With the standard '02 on my workbench computer, I put VIA1 on NMI\ to reduce the polling overhead, since the only interrupt I use on VIA1 is T1, for the real-time clock, and nothing else is on NMI. I'm really just using it to get for the additional interrupt input.


Yes, I have that option available too.

Quote:
Next, you probably won't have more than just a few of the many possible interrupts enabled at any given time. My workbench computer has more than three dozen possible sources of interrupt; but I can't think of any time I had more than three enabled at once. The ISR should poll the most likely or the most urgent one first, and never poll ones that aren't even enabled.


I probably should have put some additional context: the software is a multitasking OS, which complicates things somewhat. I'm assuming you either have multiple ROM images for different tasks, or some kind of self-modifying code solution? I don't really have that choice. From the point the ISR runs, any of the sources could be in use. Hence looking at hardware solutions.

Quote:
The ISR examples I see in books are usually way more complicated and inefficient than they need to be.


Indeed. Another reason, though, for making ISRs with "redundant" code in them is it can sometimes simplify debugging. I have a check against a unitialised handler pointer in my main ISR just because I know if I don't put it in (it should never trip, of course) I'll get bitten by some subtle and annoying bug later down the road.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 25, 2016 12:12 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
Quote:
The priority encoding saves a whole bunch of code in the top-level ISR. It just has to read INTSTATUS, rotate it left once and extract the particular device's handler from a table. The value 0 means something has gone wrong (it should never happen because the IRQ line should be high in this case.)

Make sure you shift, not rotate, so the resulting low bit won't be a surprise. Anyway, the scheme will most efficiently be for 7 interrupts, not 8, since the 8th bit will be shifted or rotated out.

The following is not particularly related to programmable logic, but I'll reply to these quotes in case it gives someone any ideas.

Aslak3 wrote:
I probably should have put some additional context: the software is a multitasking OS, which complicates things somewhat. I'm assuming you either have multiple ROM images for different tasks, or some kind of self-modifying code solution? I don't really have that choice. From the point the ISR runs, any of the sources could be in use. Hence looking at hardware solutions.

The routines that install and delete ISRs are (or can be) in ROM. The ISRs I use all the time are also in ROM on the workbench computer, but other ones get compiled and put in RAM on an as-needed basis. If I were to need multiple ones of the very highest-priority ISRs, especially without your multiple IRQ\ inputs, then yes, some kind of self-modifying code solution might be in order. See further down though.

I don't have any experience with preemptive multitasking OSs; but for several products, I've used a cyclic executive to do OS-less cooperative multitasking with extremely low overhead, in systems that lacked the resources to run a multitasking OS, or where hard realtime requirements would rule one out anyway. I wrote it up in my article on simple methods for multitasking without a multitasking OS. In the last major job, I used a PIC16 microcontroller switching tasks at approximately 10,000-16,000 times per second while running timer-generated interrupts at 39.0625kHz which is the 20MHz clock speed divided by 512, or one interrupt per 128 instruction cycles, with a jitter of only one instruction cycle in spite of the task switches which were neither related to, nor synchronous with, the interrupts. Since the tasks relinquish control only when they're at a good stopping point, the task-switch overhead was nothing more than a subroutine return and call, which can be interrupted. As mentioned in the article, if the task list needs to change from time to time, it would have to be in RAM, and the task called at the top of the list should probably be the one that adjusts the list, adding new tasks or deleting ones that are no longer needed. After deleting one, it can either move the following ones up to fill in the spot, or replace it with NOPs.

Quote:
Quote:
The ISR examples I see in books are usually way more complicated and inefficient than they need to be.

Indeed. Another reason, though, for making ISRs with "redundant" code in them is it can sometimes simplify debugging. I have a check against a unitialised handler pointer in my main ISR just because I know if I don't put it in (it should never trip, of course) I'll get bitten by some subtle and annoying bug later down the road.

What I have in my '816 Forth is that the ISR installer maintains a pair of lists of handler pointers (both for IRQ, no such list for NMI): one for assembly-language ISRs, and one for Forth-language ISRs. The assembly-language list gets higher priority (since, if they didn't need the highest performance, they'd be in Forth); but within each list, the pointers are in order of priority, given by the priority which is one of the input parameters for the ISR installer. The lists are initialized with a length of zero upon boot-up, and each subsequently-installed ISR increases the length. The ISR deleter disables the interrupt associated with the referenced ISR, and removes the entry from the list, scooting the following ones up to fill in the gap. The ISRs themselves are very simple, leaving little to debug.

On the '02, I only do the Forth-language ISRs this way. The '02 was too inefficient to do the assembly-language ones this way. It added a lot of overhead, whereas the '816 was able to do it while adding very little overhead. The way I install and delete assembly-language ISRs on the '02 is less automatic and requires care in making sure that each one takes the responsibility of correctly chaining to the next if it finds that its interrupt source was not the one that caused the interrupt.

All of this might sound awfully complicated, especially since I said he ISR examples I see in books are usually way more complicated and inefficient than they need to be; but the complication is in the ISR installer and deleter (and you can also list the ISRs). The ISRs themselves are very simple, and I've never had to spend much time at all debugging them.

I know this doesn't have much to do with having lots of IRQ inputs, but it might give someone ideas for their system.

_________________
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  
PostPosted: Tue Oct 25, 2016 9:27 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
Sorry for unexpectedly bumping in...
about having IRQs with different priorities:

Suddenly, I feel reminded to the Synertek Hardware Manual, page 120 (labeled page 107 in the PDF).

Attachment:
intvec.png
intvec.png [ 61.18 KiB | Viewed 6406 times ]

"Quad 2 input data select" -> 74HC\HCT157

"priority encoder" -> 74HC\HCT148

The concept looks pretty simple...

But when building it that way, I would be afraid that a IRQ with a higher priority might go active
between fetching the low_Byte and the high_Byte of the interrupt vector.

Edit:
If all of the 8 IRQ vectors would be pointing into the same 256 Bytes page in memory,
the high_Bytes of the vectors would be identical, and there would be nothing to worry about...


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 25, 2016 4:53 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8505
Location: Midwestern USA
ttlworks wrote:
But when building it that way, I would be afraid that a IRQ with a higher priority might go active between fetching the low_Byte and the high_Byte of the interrupt vector.

Proper programming would handle that situation. What the priority encoder is doing is producing an eight bit index. So your ISR would start by pushing the registers as required and then loading the interrupt index into, say, .X. After that, conditions will effectively be "static" and you can safely load the LSB and MSB of the relevant interrupt vector at your leisure (however, "leisure" doesn't mean "waste time").

Don't forget that upon responding to an IRQ the MPU will do the equivalent of an SEI instruction after it pushes PC and SR, thus preventing the pending interrupt from being interrupted by another IRQ source.

Incidentally, priority encoders are relatively slow devices, as they have a lot of gates. Priority encoding is a good job for a PLD.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 26, 2016 6:33 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
BigDumbDinosaur wrote:
What the priority encoder is doing is producing an eight bit index.
So your ISR would start by pushing the registers as required and then loading the interrupt index into, say, .X.

Sorry, the ISR isn't involved.

From what I have figured so far, the basic idea of the schematic from the Synertek manual seems to be
to decode when the CPU reads the memory addresses in the ROM which contain the IRQ vector.

If the CPU reads those two Bytes in memory (while responding to an IRQ for instance),
a 4 Bit 2:1 multiplexer is used for tweaking some of the address lines to make the CPU read
from different memory locations.

The priority encoder then selects from which memory locations the IRQ vector is fetched
according to the IRQ level.

Quote:
Don't forget that upon responding to an IRQ the MPU will do the equivalent of an SEI instruction
after it pushes PC and SR, thus preventing the pending interrupt from being interrupted by another IRQ source.

True, but unfortunately this doesn't affect the priority encoder.

For instance, if /IRQ6 at the 74148 priority encoder input is active, and the CPU starts fetching
the IRQ6 vector, it reads the low_Byte of the IRQ6 vector.
If /IRQ7 goes active shortly after the CPU has fetched the low_Byte of the IRQ6 vector,
the encoder would generate the address for fetching the high_Byte of the IRQ7 vector,
because IRQ7 has a higher priority than IRQ6.

Would suggest to place a 74574 latch clocked by SYNC at the inputs of the priority encoder,
this probably would fix this problem and the 74148 would have nearly one CPU clock cycle of time
(minus SYNC setup time and the other setup and propagation delay times etc.) for decoding.
// Maybe 74573 might work, too... somebody please post the schematic after building something like that.

Quote:
Incidentally, priority encoders are relatively slow devices, as they have a lot of gates.
Priority encoding is a good job for a PLD.

A simple GAL\PAL probably would do.

74F148 seems to be out of production, and there seems to be no 74AC\ACT148.
BTW: maybe 20ns propagation delay at 5V for a 74HC148 from TI.

But another problem is to decode when the CPU tries to read the memory addresses containing the IRQ vector.
The 74688 comparator is quite slow, and it isn't available as AC\ACT.
7430 eight input NAND gate is available as ACT, namely the 74ACT11030, but there seems to be no 74AC version of the 7430.
74133 (13 input NAND) only seems to be available as ALS.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2016 1:31 am 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
ttlworks wrote:
BigDumbDinosaur wrote:
Incidentally, priority encoders are relatively slow devices, as they have a lot of gates.
Priority encoding is a good job for a PLD.

74F148 seems to be out of production, and there seems to be no 74AC\ACT148.
BTW: maybe 20ns propagation delay at 5V for a 74HC148 from TI.

The datasheet says that for a HC device, all signals are under 40ns at 25°C. What on Earth are you people doing that makes a 40ns delay for an interrupt an issue?

Quote:
But another problem is to decode when the CPU tries to read the memory addresses containing the IRQ vector.

I presume that the vectors are where they are specifically to simplify decoding. Decoding the addresses FE and FF (for the IRQ vector) is just a matter of one 8-input (N)AND gate, and decoding page FF uses another one.

But of course on WDC silicon, you have the VPB output, for which the datasheet explicitly mentions interrupt vectoring as the intended use. Again, IRQ is the highest vector, so that decoding it can be done with just one gate.


The inputs to the priority encoder changing their state is still going to be a problem, since the signals are potentially asynchronous to the CPU's interrupt handling and we might be reading the outputs as they are changing, which might give invalid results. Ideally, you'd want to freeze them when fetching the vector, but I don't see an easy way to do that; by the time we know that vectors are being fetched it's too late. (Too late, unless we're latching the inputs on VPB and switching the high 8 bits of the address... But wasn't the "early interrupt warning" idea pretty simple, as in just one or two flip-flops?)


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2016 6:06 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
magetoo wrote:
The datasheet says that for a HC device, all signals are under 40ns at 25°C.
What on Earth are you people doing that makes a 40ns delay for an interrupt an issue?

Well, if your CPU would be running at 20MHz, one clock cycle would be 50ns,
and a 40ns delay probably would be an issue then... ;)

Quote:
I presume that the vectors are where they are specifically to simplify decoding.
Decoding the addresses FE and FF (for the IRQ vector) is just a matter of one 8-input (N)AND gate,
and decoding page FF uses another one.

But of course on WDC silicon, you have the VPB output, for which the datasheet explicitly mentions
interrupt vectoring as the intended use. Again, IRQ is the highest vector, so that decoding
it can be done with just one gate.

That's all "implementation specific"... and a "homework assignment" for somebody who might be
trying to build something like this, in other words, it's not "my homework assignment". :)

Of course, decoding the vector fetch will be a bit more more in the time critical signal path
than decoding the IRQ level, because vector decoding plus address multiplexer switching delay
adds _directly_ to the memory read delay.

It's just that the schematic is from an old Synertek manual,
and I think that 6502 CPUs manufactured by Synertek had no /VP output...
so somebody please post a schematic after modifying the circuitry for a W65C02.

Quote:
The inputs to the priority encoder changing their state is still going to be a problem,
since the signals are potentially asynchronous to the CPU's interrupt handling and we might be
reading the outputs as they are changing, which might give invalid results.
Ideally, you'd want to freeze them when fetching the vector

Yep, that's why I had suggested something like placing a 74574 latch clocked by SYNC
in front of the interrupt priority decoder...
after mentioning that having 8 IRQ vectors with an identical high_Byte also might fix the problem... ;)


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2016 10:02 am 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
ttlworks wrote:
Well, if your CPU would be running at 20MHz, one clock cycle would be 50ns, and a 40ns delay probably would be an issue then... ;)

Again, why? What could you possibly be doing that would be affected by an interrupt coming in one cycle late? (A maximum of one cycle late, with worst-case timings, at a system speed of 25MHz.)


Quote:
That's all "implementation specific"... and a "homework assignment" for somebody who might be trying to build something like this, in other words, it's not "my homework assignment". :)

I see, I misread you when you said it was "a problem".

Quote:
Of course, decoding the vector fetch will be a bit more more in the time critical signal path than decoding the IRQ level, because vector decoding plus address multiplexer switching delay adds _directly_ to the memory read delay.

Fortunately the logic needed is trivial (two gates), and both muxes and simple gates are available in extremely fast modern logic families.

Quote:
somebody please post a schematic after modifying the circuitry for a W65C02.

You just get rid of that 15-input AND gate, substitute /VP for its output and switch the A and B inputs on the mux (since /VP is active low rather than high).


Quote:
Quote:
The inputs to the priority encoder changing their state is still going to be a problem

Yep, that's why I had suggested something like placing a 74574 latch clocked by SYNC in front of the interrupt priority decoder...
after mentioning that having 8 IRQ vectors with an identical high_Byte also might fix the problem... ;)

Right, we'll need that latch, without it we might get invalid outputs from the priority encoder; that is, outputs that are not related to any interrupt signal being asserted. Temporary and short-lived invalid outputs, before settling to a valid state, but if that path is asynchronous we might still land in the wrong ISR.

That's not a catastrophic failure, but it means we would still have to check in our code that we are servicing an interrupt that has been actually triggered, and it means occasional delays whenever the logic glitches. That might be acceptable, or it might not.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2016 10:26 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
magetoo wrote:
Again, why? What could you possibly be doing that would be affected by an interrupt coming in one cycle late?

Priority decoder output better should be stable when the multiplexer switches, that's all.
Else, some of the priority decoder delay would add to the memory read delay.

Quote:
I see, I misread you when you said it was "a problem".

Should have phrased it more clearly and detailed, sorry. :)

Quote:
You just get rid of that 15-input AND gate, substitute /VP for its output and switch the A and B inputs on the mux
(since /VP is active low rather than high).

/VP also might go active for RES and NMI, so we need to check if the address lines A1 and A2 are '1', too...
the multiplexer shouldn't try to map RES and NMI to 8 different vectors.

Quote:
Right, we'll need that latch, without it we might get invalid outputs from the priority encoder;

We'll need that latch.
Clocking it with SYNC probably won't increase IRQ response time, but to me this looked like the most simple solution.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2016 6:29 pm 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
ttlworks wrote:
Priority decoder output better should be stable when the multiplexer switches, that's all.
Else, some of the priority decoder delay would add to the memory read delay.

If the priority encoder is slow, that just means that the IRQ line is pulled down a few ns later (from the /GS output). The address outputs are guaranteed to be stable before that happens, so the worst that could happen is that the interrupt is serviced one cycle late. (Assuming, of course, that its inputs are stable when the vector is fetched, but we already covered that.)

Quote:
/VP also might go active for RES and NMI, so we need to check if the address lines A1 and A2 are '1', too...
the multiplexer shouldn't try to map RES and NMI to 8 different vectors.

Right, that's where the "two gates" come from in the paragraph above. The details are left as a homework assignment.

Or maybe I should have expanded on that. But on a more serious note, the details will depend on how the rest of the system works too, what tradeoffs are acceptable, and that sort of thing. Strictly speaking we might not even need those extra gates if we aren't going to use NMI - leave the lowest priority input unconnected and put the reset vector on its address instead.

Quote:
Clocking it with SYNC probably won't increase IRQ response time, but to me this looked like the most simple solution.

There might be corner cases where a higher priority interrupt is ignored if comes in between SYNC and when the vector is fetched - but again, if that's important depends on other things.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 02, 2016 8:06 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
Had some spare time on my hands, so I tried to draw two schematics.

It's been a few years that I had tinkered with a 6502,
and it wasn't a W65C02, so I don't know if this will work as intended...

Since the interrupt vector address has to be stable during vector fetch,
I'm now using a 74573 latch which freezes when /VP goes active.

Because of the dinosaurs among the readers, I'm posting monochrome schematics:

Attachment:
irq1.png
irq1.png [ 6.37 KiB | Viewed 6223 times ]

Attachment:
irq2.png
irq2.png [ 6.85 KiB | Viewed 6223 times ]


/IRQ7 has highest priority.

/IRQ7 -> $FFE0,1
/IRQ6 -> $FFE2,3
/IRQ5 -> $FFE4,5
/IRQ4 -> $FFE6,7
/IRQ3 -> $FFE8,9
/IRQ2 -> $FFEA,B
/IRQ1 -> $FFEC,D
/IRQ0 -> $FFEE,F

;---

...If anybody has a better idea or knows how to improve this,
please post it here.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 11 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: