Using the 8259A interupt controller with the 65C02

For discussing the 65xx hardware itself or electronics projects.
Post Reply
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Using the 8259A interupt controller with the 65C02

Post by smilingphoenix »

I'm slowly designing a new computer, based on the 65C02. One of the problems I'm having is that old circuit boards keep dropping into my lap, full of more chips which extend the possibilities of the design.

One recent aquisition includes the Intel 8259A programable interrupt controller. I've downloaded its datasheet and already found it's not the easiest chip to fit into a 6502 system - all the interrupt lines are active high instead of active low, which means a lot of inverters are going to be needed. AAggghhhhhh...

The real fun is going to be generating the interrupt acknowledge signal that the 8259A needs. If I was using a 65C816, I could use the VP line and some logic, but the 65C02 doesn't have this pin.

Has anybody tried to do this before? Can anybody offer me any advice? Even if it is along the lines of "Don't be stupid, use such-and-such a chip instead..."
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Since the 6502's interrupt performance is so much better than that of so many other processors (including the 80 family), generating the acknowledge signal is probably a waste of time.  Although I'm not familiar with the 8259A, I do mention this step in the 6502 interrupt primer.  There is also some mention in passing of hardware prioritizing.  Usually however you won't have enough interrupt sources going at once to worry about it, and software polling is enough.  If you have three interrupt sources enabled for example, there's no point in checking 20 or 30 possible ones like some programming books tell you.  The interrupt routine checks first the highest-priority interrupt source, followed by the next lower-priority, etc., or starts by checking the one it knows produces most of the interrupts.  This and much, much more is covered in the article linked above.
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?
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

Thanks for the reply. I've read your tutorials, they're very good.

This system will have quite a few potential interrupting devices, some of which will have multiple potential interrupt causes. Polling will take some time, especially for low priority interrupts. Of course, while you are polling, you can't accept a higher priority interrupt - you havn't yet cleared the first interrupt so you can't re-enable interrupts. In addition, some of the infrequent, lower priority interrupts may have quite long service routines, so I want to be able to re-enable interrupts for higher priority devices. Using an interrupt controller such as the 8259 will allow me to find out which device interrupted with a single byte read, and also allow me to prioritise and selectively enable and disable interrupts.

Ideally, I would like the 8259 to generate the bytes read when the CPU fetches the IRQ vector from $FFFE and $FFFF - this is where it all starts to get complicated, of course, because it was designed for the 8080 & 8086 CPUs, not the 6502.

If I use the 8259 in 8086 mode, it expects 2 interrupt acknowledge cycles. In the first one, it does nothing. In the second one, it puts a vector on the data bus. If I generate acknowledge cycles when the 6502 reads the IRQ vector, the first byte will read from ROM. The second byte will read from the 8259, which has an enable output which I can use to disable the ROM. This will space my interrupt routines at 256 bytes apart, but this is not a major problem.

If anyone knows of a better chip, I will be quite happy to hear about it, providing it's something I can get hold of. That's my main reason for using the 8259s - I've got them and I havn't got anything else.

It may sound as if I know what I'm doing - and I do have a fair idea. Putting this up for discussion makes me think the problem through again which helps to clarify my thinking. Also, I've seen just how amazing some of you are coming up with brilliant ideas on this forum and I'm hoping someone will suggest something I havn't thought of yet. Even if you just say "Yeah - that looks like it could work," at least you are giving me a second opinion on what I'm thinking.
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

Is the 8259 fast enough to use with a fastish 65c02 system?  I kind of doubt it, and if it's not, you'd have to slow the processor down to accommodate something that's supposed to improve performance.  Probably not a good trade-off.

You could use just a big AND gate for bringing the interrupts together at the processor's IRQ pin, and run each of the interrupt sources into an input port, so that merely reading the port like a memory location tells you who generated the interrupt(s).  Enabling and disabling of interrupts can be done with an output port and a set of 2-input OR gates, but this individual enabling and disabling seldom needs to be done so quickly or often that you can't just do it in software.

You're probably ahead of me on this, but to elaborate on polling for the interrupt sources and various causes within each source:  In many cases you will only have one possible cause (say a T1-timeout) within a source (say a 6522) enabled; so once you identify the source, there's no need to poll further.  The number of tests needed is n-1; so if you have two possible causes and the first test eliminates the higher-priority one (possibly with a single BIT instruction), you know by default that it's the second one.  So far I've never had more than one interrupt cause at a time that really needed the shortest and most deterministic response time, so I've been able to either put that one on NMI or just check for it first without incurring excessive delays to the other ones.  Since the processor can't service two top-priority interrupts at the same time anyway if they happen to hit simultaneously, there's not much point in going further than this.  If a lower-priority one can wait for a higher-priority one to get serviced, it can probably wait for a few polling instructions without adverse effect.

On the next workbench computer I build, I intend to put RAM where the vectors are.  One reason is that it will allow the vectors to be changed on the fly.  I would pre-load the boot-up part of memory before releasing the processor from RST.  (I've been talking about my "next computer" for years; but improvements on the old one keep breathing new life into it, postponing the need for the next one.)

What interrupts do you anticipate?
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?
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

The system is going to be using two processors - one handling all the I/O devices and the other will just be running user programs - rather like the BBC micro running with a second processor. The I/O processor will only be running at 2 or 3MHz which means the 8259A will be fast enougth. The main processor will probabally get its clock wound up until something starts smoking!

Planned interrupt sources include

2 off RS232 ports
2 off printer ports
Keyboard
Mouse
100Hz tick - for sound envelope processing
Main CPU communications link

There may well be others from other I/O devices I may add at a later date. Most of those listed don't require a very quick service, I just thought that adding the 8259A might make it easier to identify and enable/disable them.

The sound envelope processing is a somewhat long process, but it is of very low priority except for the first few instructions which update the sound chips. Then you have nearly 10,000 microseconds to calculate the next set of data. Other interrupts can and should interrupt this processing.

I like your idea of ANDing all the interrupt lines together to create a common interrupt and then feeding all the interrupt lines through an input port to identify which caused the interrupt.

I've been reading since my last post and have found a better way. Feed the interrupt lines to a 74LS148 priority encoder. This has an active low line which can interrupt the processor and also gives a binary encoded output giving the highest priority active input. The inputs are active low as well - ideal for 65xx series devices. You need to latch the data lines to the port, just in case an interrupt comes in while you are reading the port and they change. This is not my idea (wish it was, it's a good one) - you can find it on page 759 of "The Art Of Electronics" (2nd edition, by Horowitz and Hill, Cambridge University Press)

I suspect I will eventually get something going with the 8259 - unless something better comes may way first, or someone suggests something interesting - simply from pure bloodymindedness. "I've got the thing, I'm damn well going to use it, no matter how hard it makes things" sort of thing. Thanks for your advice, however, if nothing else it's giving me another perspective on things.
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
User avatar
Ruud
Posts: 259
Joined: 12 Dec 2003
Location: Heerlen, NL
Contact:

Re: Using the 8259A interupt controller with the 65C02

Post by Ruud »

Just an idea:
- first put a buffer between the IC generating the interrupt and the line towards the 6502.
- connect the original IRQ output to an input of a 74LS541 or 74LS244 8 bit tri-state buffer.
- connect the outputs of this buffer to the data bus
- wire the enable signal of this buffer some where in you memory map

The moment an IRQ occurs, the 6502 reads the 541 (or 244) buffer to see what IC generated the IRQ and acts accordingly. No more polling needed anymore.

Code: Select all

    ___
   / __|__
  / /  |_/     Groetjes, Ruud 
  \ \__|_\
   \___|       URL: www.baltissen.org

fachat
Posts: 1124
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Using the 8259A interupt controller with the 65C02

Post by fachat »

I found the 8xxx logic rather incompatible with the 65xx logic. You have to run circles around a 16550 UART to make it work in a 65xx system for example.
Quote:
If anyone knows of a better chip, I will be quite happy to hear about it, providing it's something I can get hold of. That's my main reason for using the 8259s - I've got them and I havn't got anything else.
Ever tried the 6525? IIRC one of the ports can be programmed as interrupt priority encoder. Although it might be hard to come by these days.
Ruud wrote:
Just an idea:
- first put a buffer between the IC generating the interrupt and the line towards the 6502.
- connect the original IRQ output to an input of a 74LS541 or 74LS244 8 bit tri-state buffer.
- connect the outputs of this buffer to the data bus
- wire the enable signal of this buffer some where in you memory map

The moment an IRQ occurs, the 6502 reads the 541 (or 244) buffer to see what IC generated the IRQ and acts accordingly. No more polling needed anymore.
Nice idea :-) Also allows for reading and determining the interrupt source without changing state! On some ICs reading the interrupt source register clears all interrupt sources, so the driver needs to be able to handle all interrupt sources in an IC, even if the IC handles two or more completely independent interrupt sources.

André
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Re: Using the 8259A interupt controller with the 65C02

Post by dclxvi »

smilingphoenix wrote:
If I was using a 65C816, I could use the VP line and some logic, but the 65C02 doesn't have this pin.
WDC 65C02s have the Vector Pull (Bar) signal; fortunately, this is the flavor being made these days, so you could order one. Older 65C02s (Rockwell, GTE, NCR) and NMOS 6502s don't have the signal, though.
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

I hadn't noticed that - just as well I havn't got a WDC 65C02 or I would have killed it - that pin is VSS on everyone elses 65C02s! I wonder why WDC didn't use pin 35 (NC) and retain pin compatibility?
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
Thrashbarg
Posts: 26
Joined: 24 Nov 2004
Location: Adelaide
Contact:

Post by Thrashbarg »

You could always use a 74LS148 priority encoder. They're used on some 68000 based systems to encode a 7 line interrupt structure to a 3-bit binary number. The missing number, zero, is used as a non-interrupt state, but in a 6502 system it can be used as an interrupt.

Looking at the datasheet, you would only need to OR (negative logic AND) the GS and EO outputs together and tie that to the interrupt input of the 6502. Then just attach the 3-bit output of the encoder to a port of some kind.
Check out my 8080 project: http://kaput.homeunix.org
smilingphoenix
Posts: 43
Joined: 20 May 2006
Location: Brighton, England

Post by smilingphoenix »

Thrashbarg wrote:
You could always use a 74LS148 priority encoder.
I've looked into this chip - I mention it in an earlier post - it certainally seems to do what is required and is currently my favourite option.
Thrashbarg wrote:
Looking at the datasheet, you would only need to OR (negative logic AND) the GS and EO outputs together and tie that to the interrupt input of the 6502. Then just attach the 3-bit output of the encoder to a port of some kind.
Nope. You just attach GS directly to the 6502's IRQ line. EO goes low when the chip is enabled but none of the inputs is active. Your suggestion would prevent the interrupts from reaching the CPU.

"The Art Of Electronics", where I first encountered this idea, recomends latching the output of the priority encoder - with a 6502 system this should be done on the rising edge of p2. This is because interrupts are asynchronous and if one became active just as the CPU was reading the port the CPU could read changing data and vector off to the wrong handler. I know the odds are against it, but better safe than sorry.

I've drawn up this idea and sent it off to Mike Naberezny for inclusion in the "Hardware Mini-Projects" section of the site - hopefully you should be seeing it soon.

I'm currently looking at adding a magnitude comparitor and latch to the circuit so that I can disable interrupts below a certain priority. This would allow me to re-enable interrupts within a handler routine, but only permit higher priority interrupts.
Shift to the left, shift to the right,
mask in, mask out,
BYTE! BYTE! BYTE!
Post Reply