6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Apr 25, 2024 6:07 pm

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Thu Nov 11, 2021 5:24 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
BillO on Fri 23 Jul 2021 wrote:
A 74HCT148 and a 74AC245 might make a decent interrupt priority encoder that would work on a 6502 bus.


I worked through this exercise and I found one annoying edge case. Yep, 74x148 is a priority encoder and 74x244 (or more convenient 74x245) will place encoded priority onto a data bus.

I worked out for myself that it would be a good idea to pre-scale the priority encoder such JMP (VECTAB,X) uses even X. Dr Jefyll recommends the same although I did not work out Dr Jefyll's trick of using a larger pre-scale and using the priority encoder as the bottom byte of the vector address itself. That saves quite a few bus cycles but requires additional circuitry to handle the remainder of the vector - and all of the unrelated vectors.

74x148 has a "no selection" output and this is best wired on bit 4 such that nine even values may be produced. (0-16, not 0-14.) This leads to an 18 byte jump table where the last entry is for spurious interrupts or safe exit after all interrupt sources are serviced. It would be preferable if the spurious vector occupied jump table entry zero but this arrangement is sufficient.

I have yet to mention the annoying edge case. An interrupt may occur at any time. In particular, it may occur when the memory location of the priority encoder is read. In the worst case, the three or four signal lines from the priority encoder may be sampled in an inconsistent state. This occurs when the priority encoder transitions at the worst possible moment. At best, this will cause the wrong interrupt service routine to be executed. If the interrupt service routine is not written correctly, erroneous data may be queued - or worse. Furthermore, when the source of IRQ is not cleared, a second pass will be taken through the IRQ vector. This adversely affects the maximum frequency of periodic interrupts and may incur data loss.

In my attempt to resolve this situation, I sketched increasingly complicated circuits. After six chips, I thought that I might have the wrong approach. Indeed, a 74x573 *before* the 74x148 (and tied with the 74x245's output) is sufficient. This ensures that all *inputs* to the 74x148 settle during the read cycle for the priority encoding and guarantees that the multiple signal lines are in a consistent state when the data bus is sampled at the end of the cycle.

The 74x573 should itself be preceded with a network of eight pull-up resistors. Unless you plan to share priority encoded interrupts, this has the advantage that open collector variants of 6522 are immaterial and both variants may be mixed or substituted within one design. Unless there is a particularly clever way of scaling priority encoders, it remains possible to make a tree of interrupt sources with 8-16 fan-out at each branch.

Curious cases remain. A low priority device may interrupt. By the time the priority encoding is read, a higher priority device also wishes to interrupt. In this case, the last device to interrupt is serviced first. IRQs are typically executed sequentially. However, execution order may be significantly jumbled. This may lead to race conditions, priority inversion or resource exhaustion. The easiest way to avoid this is to aggregate or partition system interfaces.

As an example, a system with four UARTs should not place all input interrupts above all output interrupts. A continuous stream of input may exceed available buffers while output is starved. It is preferable to give priority to outputs or aggregate UART interrupt signals into a subordinate priority encoder which only aids the UART interrupt service routine.

Anyhow, four components are required: pull-up resistor network, transparent latch, priority encoder, tri-state buffer. I don't recall anyone getting the edge case correct with discrete logic. This would lead to experimental designs which mostly work but become increasingly unstable as interrupt sources are added. This is rather a shame because the very small number of registers in a 6502 contributes to its exceptionally good interrupt response time and it would be particularly suited to eight or more interrupt sources.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 11, 2021 7:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
How many interrupt sources do you plan to have enabled at once?  My workbench computer has 36 possible interrupt sources, but I don't recall even having more than three enabled at once; and with each I/O IC that's able to generate an interrupt, you still have to poll it to find out which possible source within that IC generated the interrupt.  Although the hardware interrupt prioritizers have long intrigued me, I have gone the route of having software that installs and prioritizes ISRs instead, such that the most-urgent or most-common interrupters get polled first, meaning that you'll usually get it right on the first try, and you never poll sources that aren't even enabled.  When you install an ISR, you tell the installer what the priority level is, and it inserts it in the list, scooting subsequent ones down to make room, then enables the interrupt.  When you delete an ISR, there's an associated interrupt de-activator routine address to run first, and then the ISR is removed from the list, scooting subsequent ones up to fill the hole.

_________________
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: Wed Feb 02, 2022 3:51 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
GARTHWILSON: You may not have stated such a requirement in one place but I appreciate the very desirable ability of a 2MHz 6502 to handle 48000 periodic interrupts per second. Unfortunately, it is a capability which is easily eroded by software overhead or the bus cycles required to store a larger program counter. The problem can be solved by increasing processor frequency. However, this increases overall energy consumption in addition to other implementation difficulties. Likewise, the drastic move of making a wider data bus has minimal gain unless all pieces of data are bus width aligned. Indeed, this would explain your hesitance with W65C816 and your advocacy of 65Org32.

You may not have set the interrupt criteria with the gravitas that I have accepted. Regardless, it is a question worth answering, partly for personal gratification but also because the current technology stack is a "house of cards" and getting worse. Unfortunately, I'm not the only one snagged with the problem of interrupts. It is a general cross-cutting concern which causes numerous problems. Indeed, if you get something working, add a privilege scheme and see if it still works. The answer is probably not.

Let's not be polite about the matter but the bodged NMI/IRQ/BRK system in 6502 is feature parity with MC6800. I hope that the Transputer fans, such as BigEd and drogon, would agree that a two level priority is preferable, in part because it avoids the rare but annoying case of priority inversion. Admittedly, we must credit to the Gang Of Eight for getting NMI/IRQ/BRK to work first time. With the benefit of 45 years hindsight (and all modern tools), amateurs (in which I include myself) struggle to achieve the same result on any timescale.

For example, MicroCoreLabs has weak implementation around reset and interrupts. randyhyde is silent on the matter. aleferri is similarly snagged with interrupts (although making good progress with this and other problems). Proxy and I share similar doubts. On anycpu.org, similar problems typically occur with unique processor architectures. Most unnervingly, we found that absolutely no-one knows if /ABORT may be used as a general purpose interrupt. Furthermore, Intel and AMD are both re-architecting x86 interrupts in a manner which is mutually incompatible. This leaves me with the concern that I might architect an interrupt methodology which would be considered obsolete by market leaders. Of particular note, I understand that Intel is collapsing previous work into a two level priority scheme.

After reading the forum archive in full (and then posting a bout of duplicate topics before data settled), it occurred to me that making a 6502 or 65816 system was tractable. This has its own gratification but it was not an objective when I joined the 6502 forum. Specifically, I was only interested in extending 6502 bytecode to 64 bit. Regardless, it occurred to me that it might be possible to advance a solution empirically - or at least understand the problem from personal experience. Unfortunately, I have now discovered that the reference material is wrong. Worse, we have multiple silos of expertize where any programmable logic expert could have corrected the discrete implementation if it were not quicker to type the correct solution into a CPLD or FPGA workflow. Indeed, while reading through anycpu.org, I subsequently discovered that the correct "double flop" solution was published on Fri 14 Jun 2019.

Anyhow, interrupts are a tough problem and I still don't have an answer. I have devised numerous schemes in an attempt to answer this problem. Some of them are quite elegant. However, it would be preferable if any of them worked. My favorite is a scheme which divides a 64 bit vector into a 4 bit priority field, a 12 bit core number, 8 bit for bytecode dialect and 40 bit for address with provision to shuffle these fields around by a few bits, if required. Unfortunately, there is no mechanism to queue lower priority interrupts. Meanwhile, allocating one interrupt per core only provides the guarantee that all interrupts run concurrently - which is extremely unhelpful.

A more promising avenue is a duplicate set of vectors for every address-space extension; much like 65816. Unlike 65816, vectors may be selected automatically based upon the top bits of the program counter and therefore execution mode is implicit. This allows a system to retain 6502 cycle count when operating within a 16 bit address-space. Interrupt performance only degrades as usage of the address-space grows. Hypothetically, it is possible to make a faster bus or a wider bus. However, both increase the difficulty of construction and both increase energy consumption. There are also cases where pushing extra data to a wider, unaligned stack obtains no speed advantage. We also have the minor problem that duplicate vectors within the same page break multiple legacy ABIs. Most notably, Commodore and Acorn ABIs are already incompatible with 65816. Compatibility workarounds may be incompatible with further vector extensions. There are further compatibility and performance problems when trying to get 16 bit RTI, 24 bit RTI, 32 bit RTI, 40 bit RTI and suchlike working with a high level language.

As a pragmatic example, audio sampling with 65816 in native mode has worse performance (lower maximum frequency, worse jitter) than 65C02. Whereas 65Org32 - with 32 bit aligned stack - always has better performance.

In an attempt to stay within a 16 bit address-space while minimizing interrupt cycle count, the general case of unlimited interrupt sources may be handled with a tree of priority interrupt encoders. However, after working through the details, designing a module and receiving example units, it occurred to me that CA1, CA2, CB1 and CB2 pins of a 6522 may be used to make a quad-tree of interrupts. This has the advantage of zero external components (beyond any pull-up resistor required for open collector compatibility) while retaining much of the functionality of dedicated circuitry. In this arrangement we have branch and leaf 6522 chips. Shift registers within branches may be unavailable but timers and parallel ports remain available.

GARTHWILSON on Thu 11 Nov 2021 wrote:
How many interrupt sources do you plan to have enabled at once?


Personally, I plan to have:-


In this arrangement, any interrupt source (such as subordinate 6522, I2C thermometer alarm or 65SIB peripheral) may be connected to the root 6522.

If anyone wants a priority interrupt encoder module, just ask. However, it appears that the magic of 6522 makes it largely redundant.


Attachments:
xr0215-0-2.png
xr0215-0-2.png [ 34.98 KiB | Viewed 490 times ]
xr0215.jpg
xr0215.jpg [ 41.9 KiB | Viewed 490 times ]

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!
Top
 Profile  
Reply with quote  
PostPosted: Sat Feb 05, 2022 12:43 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
Sheep64 wrote:
GARTHWILSON: You may not have stated such a requirement in one place but I appreciate the very desirable ability of a 2MHz 6502 to handle 48000 periodic interrupts per second. Unfortunately, it is a capability which is easily eroded by software overhead or the bus cycles required to store a larger program counter. The problem can be solved by increasing processor frequency. However, this increases overall energy consumption in addition to other implementation difficulties. Likewise, the drastic move of making a wider data bus has minimal gain unless all pieces of data are bus width aligned. Indeed, this would explain your hesitance with W65C816 and your advocacy of 65Org32.

I'm not sure what you're thinking of.  I very much like the '816, although Bill Mensch could have made it better if Apple hadn't needed it to run legacy 6502 software in their IIGS.  It's true however that its interrupt response is longer than the 6502's, and there is a little more jitter for periodic interrupts.  (For both the '816 and the '02, we could end the jitter, at the expense of interrupt-response time, by reading the counter to see how long ago it timed out, and adding just enough cycles in the ISR to make it come to the same number every time.)  My 65c02 workbench computer originally ran at 2MHz, but I bumped it up to 5MHz only four years into its so-far-28-year life.  I've done up to about 140,000 periodic interrupts per second at 5MHz, but there's not much point in that because of the jitter and only having 35 cycles from one interrupt to the next, which means the ISR has to be minimal and you won't get much done on the background task either.  Most of my audio sampling has been at 24,000 samples per second, even at 5MHz, with a 5th-order 5.6kHz anti-alias filter which is plenty for what I've used it for.  I'm not particularly concerned about all connected devices being 32-bit for the hypothetical 65Org32, as I have also connected a Saronix realtime clock IC with a 4-bit data bus directly to a 65c02 and it wasn't any problem that it didn't fill out the 8 bits.  Since the 65Org32 can stack an entire 32-bit register in a single cycle, it won't require as high a clock speed to get interrupt performance comparable to that an '02 or '816; so since for particular CMOS hardware the power consumption is approximately proportional to the clock speed, power consumption there may not be a problem.

Quote:
Regardless, it is a question worth answering, partly for personal gratification but also because the current technology stack is a "house of cards" and getting worse.

I'm interested to hear you out further on this (if I can read as much in an hour as you seem to be able to type in ten minutes!).

Quote:
Let's not be polite about the matter but the bodged NMI/IRQ/BRK system in 6502 is feature parity with MC6800.

Are you looking to use BRK for anything other than switching tasks?  I have not used it since that first class in 1982 where we had AIM65's in the lab, and then it was only to return to the monitor program.

Quote:

What do you need to know beyond what's at viewtopic.php?f=4&t=6835 and in the data sheet and around pages 261, 548, and 578 of the fixed Lichty & Eyes programming manual?

Quote:
Anyhow, interrupts are a tough problem and I still don't have an answer. I have devised numerous schemes in an attempt to answer this problem. Some of them are quite elegant. However, it would be preferable if any of them worked.

I've kept coming back to this over the years, but it does not seem to have been the problem that I keep envisioning, at least in my own uses.

Quote:
it occurred to me that CA1, CA2, CB1 and CB2 pins of a 6522 may be used to make a quad-tree of interrupts.

It's an interesting idea.  I take it you mean that in the ISR, you'd read the 22's status register into the accumulator and then shift the number to the right, branch on carry, with the highest-priority interrupt on CA2, next on CA1, then an interruption of one bit space for the shift register, then CB2, and lastly CB1, before the timer interrupt bits.  It assumes however that you'll always want the same connections; because otherwise if the application changes, interrupt inputs may not come in the right priority.  A little bit slower, but more flexible, is the system of installing ISRs as I mentioned earlier, and having the installer put them in order of priority, so the highest-priority ones get checked first.  It's still not like having the vector take you directly 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  
PostPosted: Tue Feb 22, 2022 8:20 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
GARTHWILSON: Oh, good grief! I did not intend negativity about 65816 - only that 65Org32 has superior interrupt performance. As one of the strongest proponents of 65816, I'm surprised that you haven't switched. Assuming that your system doesn't use hooky opcodes, PHI2 out, /SO or the alternate bus phase, the switch should be trivial. Have I wrongly assumed that you were looking to the larger address-space and cycle counts of 65Org32?

GARTHWILSON on Sat 5 Feb 2022 wrote:
Sheep64 on Wed 2 Feb 2022 wrote:
the current technology stack is a "house of cards" and getting worse.


I'm interested to hear you out further on this (if I can read as much in an hour as you seem to be able to type in ten minutes!).


My productivity seems like an illusion. I typically post weekly or much less frequently but I think about many topics in between. I also try to make my text flow by reading aloud. At the very least, it fixes some of the punctuation. I'm definitely not the infamous Rantarian who can type thousands of words per hour - on touchscreen!

I will write separately about security otherwise BigEd will quietly harrumph that another discussion has wandered off-topic.

Regarding ABORT, it appears to work perfectly in its intended form. However, I may assert ABORT during IRQ or NMI cycles. Does interrupt stack write or vector read get ignored or aborted? Unknown.

Regarding interrupts in general, they should work flawlessly between peripheral and processor. Designing a CPU's interrupt hardware is troublesome. Designing a larger CPU with the same interrupt performance is more troublesome.

Sheep64 on Wed 2 Feb 2022 wrote:
quad-tree of interrupts.


I initially considered LDA STAT_REG // AND #%00011011 // ASL // TAX // JMP (VEC_TAB,X) or similar. Unfortunately, this may require dynamically populating multiple entries in VEC_TAB. VEC_TAB also has a gap. It may be preferable to implement priority encoding and shifting with a 256 byte table. For example, LDX STAT_REG // LDA PRI_TAB,X // TAX // JMP (VEC_TAB,X). This only services one interrupt source per invocation, is slightly slower than a hardware priority encoder, has less fan-in than a hardware priority encoder and is less flexible than selectively installing interrupt handlers in frequency order. However, the long PRI_TAB replaces one or more *sets* of discrete chips (which are often implemented wrongly) and the short VEC_TAB has no gaps or duplicates.

For ad hoc applications, an installer remains preferable. For five or more heavy, fixed interrupt sources, a tree of 6522 interrupts may be preferable. For six or more frequent interrupt sources, hardware encoding is fastest. However, these techniques are not mutually exclusive. Therefore, it is possible to have an interrupt installer before a hardware encoder of 6522 quad-trees. That would allow audio sampling ahead of 40 or more interrupt sources while only using one 74x148 and associated components.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 22, 2022 10:11 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
Sheep64 wrote:
GARTHWILSON: Oh, good grief! I did not intend negativity about 65816 - only that 65Org32 has superior interrupt performance. As one of the strongest proponents of 65816, I'm surprised that you haven't switched. Assuming that your system doesn't use hooky opcodes, PHI2 out, /SO or the alternate bus phase, the switch should be trivial. Have I wrongly assumed that you were looking to the larger address-space and cycle counts of 65Org32?

The workbench computer actually has a 65802, on which I developed my bank-0-only '816 Forth (and will be extending for data in all banks when I get set up with such a system), but I have not put the '816 Forth to serious use, because most of what I do is with applications I developed years ago that just keep working, on my '02 Forth; and for the smaller frequent projects, it hardly matters.  It does use Φ2 out though.  I built it before WDC quit specifying or measuring the delays between the three clock pins, and, I think, before they started recommending against using Φ2 out.  It was probably even before I knew about WDC.  I started with a Rockwell R65C02.  My plans for the next workbench computer (using the '816, maybe two of them) have been evolving for 25 years, but upgrades I've managed to make to the existing one have delayed and reduced the need for the next one.  After finishing my last work project and now having a little free time again before the next one starts, I just pulled a project I started five years ago out of mothballs to make a little bootloader module to pre-load the 816's RAM (for a ROMless system).  I finished the board layout, and the boards are manufactured and on their way.  The microcontroller code is written but needs to be proven.

Quote:
Regarding ABORT, it appears to work perfectly in its intended form. However, I may assert ABORT during IRQ or NMI cycles. Does interrupt stack write or vector read get ignored or aborted? Unknown.

I have a gizmo I made to test things like that, and I could test it when I get time since it definitely takes time to set it up again.  It's an interesting question.  I think the consensus however is that it's better to use COP for another 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  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 12 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: