6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 11:02 pm

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Fri Sep 22, 2023 8:28 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Since day zero, VPB output tempted me to do something interesting with it

I don't have access to my workbench SBC at the moment to probe VPB, so I decided to do some brainstorming with my favorite circuit emulator while making some assumptions about how dose VPB really work.

According to WDC 65C02 datasheet,

Quote:
The Vector Pull (VPB) output indicates that a vector location is being addressed during an interrupt
sequence. VPB is low during the last interrupt sequence cycles, during which time the processor reads the
interrupt vector. The VPB signal may be used to select and prioritize interrupts from several sources by
modifying the vector addresses.


Here's the virtual problem I'm solving here, for fun and science: imagine we have 8x 6522 VIAs (yikes!) and we want to service them without having to poll each VIA when the IRQ line is pulled low.

My solution is:
- Peripheral IRQ lines are encoded into 3-bit address using '148
- VPB enables ROM that contains ISR addresses (6502 fetches ISR vector address in 2 cycles, so a D trigger tracks current byte)
- ROM puts 2-byte ISR vector address on the data bus, 1 byte at a time

Here is the circuit I came up with.

Attachment:
prio_interrupts.png
prio_interrupts.png [ 203.38 KiB | Viewed 13460 times ]


I used generic ROM for the sake of presentation. Actual EPROM can be used here. Also, 7400 family seems to have cute little ROMs, such as '88, but I've never used them.

In general, this approach gives you ability to have separate ISRs for each IRQ line with zero software overhead, with up to 8 individual IRQ lines (or 16 IRQs if you use '147 instead of '148).

I wonder if y'all did anything similar, or if there were similar solutions in real '02 systems.

EDIT: Here's a circuit file in case you want to emulate it yourself (yes, it actually works) - you'll need this tool: https://github.com/hneemann/Digital
Attachment:
vpb.zip [3.53 KiB]
Downloaded 40 times

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 22, 2023 9:39 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Okay, the D trigger is totally unnecessary: I can simply use A0 to detect whether the CPU is currently fetching low or high byte of vector address!
Attachment:
prio_interrupts_v2.png
prio_interrupts_v2.png [ 189.77 KiB | Viewed 13445 times ]

Attachment:
vpb.zip [3.42 KiB]
Downloaded 50 times

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 22, 2023 9:46 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
These always intrigue me, and I'll be interested in your progress.

Quote:
Here's the virtual problem I'm solving here, for fun and science: imagine we have 8x 6522 VIAs (yikes!) and we want to service them without having to poll each VIA when the IRQ line is pulled low.

Keep in mind however that there's no point in polling interrupt sources that are not even enabled, and it's highly unlikely that you'd have interrupts enabled in all of those VIAs at once.  Keep in mind also that each individual VIA has seven possible causes of interrupts, so once you've isolated which VIA interrupted, you still have to poll, in software, to find out which thing within that VIA caused the interrupt.  (But again, there's no point in wasting time polling for sources that are not enabled.)  My workbench computer has three VIAs and three ACIAs, and although I'm the interrupts junkie around here, I don't think I have ever had more than three interrupt sources enabled at once.

_________________
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: Fri Sep 22, 2023 10:05 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
GARTHWILSON wrote:
These always intrigue me, and I'll be interested in your progress.

Quote:
Here's the virtual problem I'm solving here, for fun and science: imagine we have 8x 6522 VIAs (yikes!) and we want to service them without having to poll each VIA when the IRQ line is pulled low.

Keep in mind however that there's no point in polling interrupt sources that are not even enabled, and it's highly unlikely that you'd have interrupts enabled in all of those VIAs at once.  Keep in mind also that each individual VIA has seven possible causes of interrupts, so once you've isolated which VIA interrupted, you still have to poll, in software, to find out which thing within that VIA caused the interrupt.  (But again, there's no point in wasting time polling for sources that are not enabled.)  My workbench computer has three VIAs and three ACIAs, and although I'm the interrupts junkie around here, I don't think I have ever had more than three interrupt sources enabled at once.


In my case, I can see certain wins from using separate ISRs:
- I'm writing a multitasking OS, and my VIA's time will be triggering interrupts really frequently. This means every time I get a context switching interrupt, I'll be polling VIA & ACIA.
- In my OS design, I want to have a clean separation of hardware ISRs instead of having single ISR entrypoint that calls other handlers. Yes, that can be done in software with little overhead, but making CPU actually aware of different ISR addresses sounds like a neat idea.
- Free inputs! Spare IRQ inputs can be wired to push buttons (with some hardware debouncing) to do cheap keyboard or shortcut buttons.
- OR gate is not needed when mixing chips that have totem pole IRQ output with chips that have open-collector IRQ (e. g. W65C22S & W65C51N) since open-collector IRQ lines can be individually pulled up.

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 22, 2023 10:33 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Just figured that by adding '257, it's possible to fetch all ISR addresses directly from ROM:

Attachment:
prio_interrupts_v3.png
prio_interrupts_v3.png [ 199.77 KiB | Viewed 13436 times ]

Attachment:
vpb_v3.zip [3.5 KiB]
Downloaded 42 times


ISR address is combined as follows:
- MSB from $FFFF (as usual)
- Lower nibble of LSB from $FFFE, and upper nibble of LSB from '148.

If ROM value at address $FFFF has value $AB, then interrupt vectors will be:
IRQ0 - $AB00
IRQ1 - $AB10
IRQ2 - $AB20
...and so on.

In this case, it's important that ROM/EN is asserted when /VP is active, and that lower nibble of ROM value at $FFFE is zero.

EDIT: Fixed many mistakes in image & description...

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 22, 2023 11:11 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
and3rson wrote:
In my case, I can see certain wins from using separate ISRs:
- I'm writing a multitasking OS, and my VIA's time will be triggering interrupts really frequently.

"Whatchoo talkin' 'bout, Willis?" (a frequent line of Gary Coleman's in the 1970's TV series "Diff'rent Strokes").  I did a cooperative-multitasking thing eight years ago for work that switched tasks 10,000+ times per second on a 20MHz PIC16; but that still pales in comparison to when I was doing 140,000 interrupts per second on my 5MHz 65c02 workbench computer.  (24,000 was much more common though.)  The only ISR entry point checked first the interrupt that it knew was firing so fast and so much more often than the others, so usually got it right on the very first poll.  I suspect the task-switching in a preemptive-multitasking system will be far less frequent than this.

Quote:
This means every time I get a context switching interrupt, I'll be polling VIA & ACIA.
- In my OS design, I want to have a clean separation of hardware ISRs instead of having single ISR entrypoint that calls other handlers. Yes, that can be done in software with little overhead, but making CPU actually aware of different ISR addresses

Task-switching in a preemptive multitasking system will probably always take longer than in cooperative multitasking, and probably not allow interrupts during the task switch.  The latter is not acceptable in my work; but maybe you'll find a way to use VPB and come up with a scheme that allows urgent interrupts to be serviced without waiting for a task-switch to complete.

Quote:
sounds like a neat idea.

Always.

Quote:
- OR gate is not needed when mixing chips that have totem pole IRQ output with chips that have open-collector IRQ (e. g. W65C22S & W65C51N) since open-collector IRQ lines can be individually pulled up.

er... Make than an AND gate.  All the inputs have to be high for the output to be high.

_________________
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: Fri Sep 22, 2023 11:26 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
For this application, I would simply lead the eight /IRQ lines to a tristate buffer mapped to some convenient place. Then your single ISR can use that as a bitmask of which VIAs need servicing. It wouldn't be necessary to override the vector using /VP…

…unless you need exceptionally low interrupt latency. This is one of the traditional strengths of the 6502, but something that's unlikely to combine happily with a multitasking OS.


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 23, 2023 6:41 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
One point not to forget is to disable normal memory in the top page (if you have any).

Second, I'd vote for using RAM instead of ROM, as ROMs these days are too slow if you want to go to higher frequencies.
Of course that makes it more complicated, eg ehat to do on powerup when the vector RAM is not yet initialized.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 23, 2023 6:47 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
Chromatix wrote:
For this application, I would simply lead the eight /IRQ lines to a tristate buffer mapped to some convenient place. Then your single ISR can use that as a bitmask of which VIAs need servicing. It wouldn't be necessary to override the vector using /VP…

…unless you need exceptionally low interrupt latency. This is one of the traditional strengths of the 6502, but something that's unlikely to combine happily with a multitasking OS.


I'd probably go with this approach also.

My experience with GeckOS shows that multi-level interrupt priorities would help much more.
I had to go to great lengths to make e.g. the scheduler interruptible, to enable higher throughput for rs232.
I even had to introduce NMI handling even though NMIs are really tricky if you have other timing sensitive stuff.
The Commodore IEC bus for example disables the NMI driver with a specific kernel call as an NMI would break that data transfer. And I used an UART with 15 (IIRC) bytes fifo instead of an ACIA that needs care for every byte.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sat Sep 23, 2023 6:53 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
Another feature you should do is a port to read the current state of the interrupt line.

Then you can stop polling IRQ sources early. My original CS/A target for GeckOS had that.

One reason in GeckOS for not returning after the first detected IRQ was that some devices needed to run in the timer interrupt. Actually a good idea to revisit that...

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sun Sep 24, 2023 6:20 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
GARTHWILSON wrote:
er... Make than an AND gate.  All the inputs have to be high for the output to be high.

Oh, yes, my bad - I meant AND.

fachat wrote:
Chromatix wrote:
For this application, I would simply lead the eight /IRQ lines to a tristate buffer mapped to some convenient place. Then your single ISR can use that as a bitmask of which VIAs need servicing. It wouldn't be necessary to override the vector using /VP…


I'd probably go with this approach also.

My experience with GeckOS shows that multi-level interrupt priorities would help much more.

That's a great idea. Looks like /VP really does not bring any significant benefits as opposed to using a latch for interrupts.

fachat wrote:
I'd vote for using RAM instead of ROM, as ROMs these days are too slow if you want to go to higher frequencies.


This is really interesting and I've never heard about this! Is there some specific reason why are RAMs faster? Am I'm missing something obvious or is it just due to the technology? I always assumed (EP)ROMs are going to be faster for reading data than RAMs. Please pardon me if that question sounds silly, I'd just love to learn more on this topic.

_________________
/Andrew

deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 26, 2023 4:00 am 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
EEPROMs have to read the data without disturbing the charges stored on single transistor gates to define that data. It's harder to do that quickly than to energise an SRAM cell that invariably has full totem-pole drive capability. This is also why DRAM chips take longer to switch rows (which reads a whole bank of capacitor charges into a buffer, then refreshes those charges to avoid destroying the stored data) than to switch columns within that row (just selecting one word from the buffer).

Generally the EEPROMs we use as hobbyists are also built using very old technology, so the advances that modern SSDs and SD cards rely on aren't available. To some extent that's also true for SRAM and DRAM, but the latter were also widely used in PCs well beyond the 1980s, so received more technological attention, with EEPROMs only being retained for booting (and usually shadowed into DRAM as part of the boot process, so a slow EEPROM was not overall a performance liability). It's easier to find newer tech in SPI EEPROMs than in parallel-interface ones, but SPI is more difficult to interface directly to the 65xx bus; these devices are normally used to initialise FPGAs and microcontrollers (eg. the RP2040), and provide configuration data on other devices.


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 26, 2023 4:44 am 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
Also note that it's not just EEPROMs, Parallel Flash chips like the SST39xF0x0 series are also pretty damn slow (55/70ns).
Which is (from what I can tell) pretty much on par with EEPROM speeds. But then again I never actually measured the access time to see if they could potentially go faster than they're rated for.


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

All times are UTC


Who is online

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