6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 7:16 pm

All times are UTC




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Jan 22, 2017 5:43 am 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
When we look at the SBC2.5 (http://sbc.rictor.org/sch2.html), on the page for serial, you will see a diode near jumper J3. I don't understand that part of the circuit.

Is it saying that the diode is only enabled with another jumper?

Am I correct is seeing that the cathode side of the diode is going IN to the /IRQ of the ACIA?

What is the purpose of that diode anyway?

Thanks.

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 22, 2017 7:01 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
cbmeeks wrote:
When we look at the SBC2.5 (http://sbc.rictor.org/sch2.html), on the page for serial, you will see a diode near jumper J3. I don't understand that part of the circuit.

Is it saying that the diode is only enabled with another jumper?

Am I correct is seeing that the cathode side of the diode is going IN to the /IRQ of the ACIA?

What is the purpose of that diode anyway?

Thanks.

I am puzzled about that as well. The 65C51's IRQ output is open drain, so it is suitable for direct connection to a wired-OR interrupt circuit. The device that may require diode isolation of its IRQ output is the 65C22S (note the S suffix), which has a totem-pole IRQ output that is incompatible with wired-OR.

Incidentally, the circuit illustrates a jumper setup to attach the UART to either /IRQ or /NMI. Use of /NMI in this fashion is generally not a good idea.

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


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 22, 2017 4:22 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1681
Location: Sacramento, CA
Back when I designed the SBC-2, I was using a mix of older 65C02 varieties which did have the open drain IRQ lines. However, late in the design, others who expressed interest in a bulk purchase wanted compatibility with the WDC parts that had totem pole IRQ's. It was discussed on the old forum and as I recall, someone offered up the use of diodes as a "quick and dirty" method of having multiple totem pole devices share the IRQ line. It was not the optimal solution but it would work and require the least amount of board rework. As far as options for using IRQ or NMI, that was also an attempt to offer a wider assortment of options. I admit that I didn't look at the practicality of that for either device.

Anyway, that is the history of it. SBC-3 and SBC-4 used buffered interrupts, which is the best solution.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 22, 2017 6:21 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
8BIT wrote:
Back when I designed the SBC-2, I was using a mix of older 65C02 varieties which did have the open drain IRQ lines. However, late in the design, others who expressed interest in a bulk purchase wanted compatibility with the WDC parts that had totem pole IRQ's. It was discussed on the old forum and as I recall, someone offered up the use of diodes as a "quick and dirty" method of having multiple totem pole devices share the IRQ line. It was not the optimal solution but it would work and require the least amount of board rework. As far as options for using IRQ or NMI, that was also an attempt to offer a wider assortment of options. I admit that I didn't look at the practicality of that for either device.

Anyway, that is the history of it. SBC-3 and SBC-4 used buffered interrupts, which is the best solution.

Daryl

A small-signal Schottky diode can provide the necessary isolation for the totem pole IRQ output without incurring a significant switching speed penalty. However, if there are multiple totem pole IRQ devices in the circuit buffered (i.e., gated) IRQs are best, since the gate will rapidly drive the MPU's IRQ input to Vcc or ground, greatly reducing the likelihood of a spurious interrupt.

The problems with using NMIs with I/O devices are several, including the inability to detect overlapping interrupts, as well as the risk of deadlock due to failure to clear one of the interrupts. NMI is best used with a single, high priority event. On the minis I worked with in the 1970s and 1980s, NMI was driven by the UPS, making power failure the high priority event.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 23, 2017 3:00 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1681
Location: Sacramento, CA
I forgot to mention that as long as only 1 device used interrupts, the diodes could be left out and a single jumper installed for the interrupting device. I know it wasn't the perfect solution... but it met the needs at the time.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 24, 2017 4:18 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
8BIT wrote:
Anyway, that is the history of it. SBC-3 and SBC-4 used buffered interrupts, which is the best solution.


Would you mind going into detail on this? I don't understand how the interrupts are buffered.

In my design, I plan on having a 65C51 and two 65C22's. On each one of them, I planned on having a jumper to allow the user to set either /IRQ or /NMI (or neither). But now I'm wondering the best approach on this. I'm leaning more towards the ACIA being on /NMI so that receiving a new byte would take priority.

But since my design will *eventually* have video input, serial input may not be required.

Thanks for any info.

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 25, 2017 3:25 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1681
Location: Sacramento, CA
In my sbc3 & 4, I use the CPLD to buffer interrupts. The equivalent of an octal D latch with the IRQ from each device connected to a data input pin. The data bus is connected to the outputs. I map a single IO to the /OE of that latch for READ access. Also, there is an equivalent 8 input AND gate connected to the latches input pins. Any low bit on the input will cause the AND gate output to be low. That output goes to the CPU's IRQ. This isolated each IRQ source from the CPU's IRQ Pin.

The IRQ service routine reads the latch's contents and decided which IRQ to service first. If multiple devices are requesting an IRQ, the service routines will reset the corresponding IRQ condition. It can reread the latch's inputs and service routines until it reads an 0xFF (no active interrupts). It then exits via RTI. The IRQ priority is decided in software. A jump table could be used point to the service routines. Unused inputs are tied to Vcc.

Attachment:
IRQ.jpg
IRQ.jpg [ 59.83 KiB | Viewed 9021 times ]


I hope that helps.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 25, 2017 1:17 pm 
Offline
User avatar

Joined: Wed Aug 17, 2005 12:07 am
Posts: 1207
Location: Soddy-Daisy, TN USA
Actually, that makes a lot of sense! Thanks for that explanation.

_________________
Cat; the other white meat.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 26, 2017 4:14 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1681
Location: Sacramento, CA
Happy to help.

Daryl

_________________
Please visit my website -> https://sbc.rictor.org/


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 02, 2017 4:50 am 
Offline
User avatar

Joined: Sat Dec 07, 2013 4:32 pm
Posts: 246
Location: The Kettle Moraine
cbmeeks wrote:
I'm leaning more towards the ACIA being on /NMI so that receiving a new byte would take priority.

Normally, you really don't want to use NMI for anything that happens more than once. It does not play well with other interrupts, and your NMI ISR absolutely must finish executing before another NMI occurs if you expect to be able to cleanly exit.

Of course there's also the obvious problem of never being able to ignore NMI, but, in simpe applications that may not come into play (outside the NMI ISR, that is).

Theoretically, NMI is reserved for pretty drastic events which you don't expect to recover from, such as power failure or hardware faults.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 02, 2017 5:14 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
If you put the '51 on NMI, it should be the only thing on NMI, and make sure you always clear all the possible interrupt sources in the '51 every time the NMI ISR runs, since NMI is edge-sensitive and the processor won't see another edge on NMI if it is still being held down for another reason you haven't taken care of yet.

We're often told to reserve the NMI for something drastic like power going down; but in most systems the people on 6502.org are making, what happens in the last milliseconds before power is gone is of no concern. If you have a system that remembers things when it's off, it probably has batteries and can turn itself off in an orderly fashion. Otherwise, if you accidentally pull the power cord, there's no time to store anything useful on a disc or flash anyway. I use NMI for the 100-times-per-second 65c22 VIA1 T1 interrupt that runs the software RTC. I don't have any of the other interrupts on VIA1 enabled, nor do I have any other ICs on NMI.

_________________
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: Thu Feb 02, 2017 6:05 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
cbmeeks wrote:
I'm leaning more towards the ACIA being on /NMI so that receiving a new byte would take priority.

That is not an arrangement that I would recommend. Your ISR would have to be very carefully written to guarantee that all possible interrupt causes in the UART are cleared before returning control to the foreground process. Otherwise, as Garth noted, subsequent NMIs will not be recognized.

In any case, IRQs will be responded to as fast as NMIs, as long as the I bit in SR is not set.

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


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 02, 2017 6:06 am 
Offline
User avatar

Joined: Sat Dec 07, 2013 4:32 pm
Posts: 246
Location: The Kettle Moraine
Interesting! I have thought about using NMI for RTC where accuracy would be critical, but since I had never tried it, I thought I would wait to hear if anyone else ever did something like that.

The only trouble I see is that I would want to implement a simple counter to only count the number of NMI hits since the last recalculation. The recalculation would be probably driven by a timer on IRQ, so as to keep the NMI ISR as short as possible, mainly to avoid any timing issues for other tasks. Just as a thought experiment, I imagine something on IRQ that might need to be timed nearly as accurate as the RTC on NMI. A caveat to this approach, is that the NMI count would have to be double-buffered because obviously the NMI can't be masked during the calculation. I'm not entirely sure if that's a valid approach, nor if counting via NMI separately from the calculation even has any advantages over a hardware counter doing the same thing.

So, I wonder if you did anything like that, or kept it simple and did any maths in the NMI ISR, or just kept the RTC as a simple count-from-epoch.

When using an RTC with a PLC, where there is no NMI, I've always used a hardware counter, and done no maths. But I see newer PLCs have built-in RTCs, with clock calculation already done. I assume they just use a high priority interrupt for the RTC. Given the clock rates of these modern PLCs, that would be more than accurate enough for the kind of RTCs I've seen.


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 02, 2017 7:26 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
I should add that the reason I put the 10ms RTC interrupt on NMI was just to reduce the polling load. There's only the one thing on NMI, so there's no need to poll in the NMI ISR to see who generated the interrupt, and that's also one less thing to poll for in the IRQ ISR. My RTC rarely gets turned off. Timing accuracy is not affected by interrupt response time; because T1 is set to roll over and generate an interrupt every 10ms whether you service it immediately or not. Each interrupt is 10ms after the previous one, not 10ms after you happened to get around to servicing that previous one. There will be a small amount of jitter, but it probably won't matter. If your crystal-controlled system clock speed is accurate, your time-of-day clock will be too.

When you read the clock bytes, do read them more than once and make sure you get the same thing twice in a row, to make sure there wasn't an increment from an interrupt while you were doing the reading. If you keep a set of bytes in the format of YY/MM/DD/HH/MM/SS/.ss, and start reading from the low bytes, you can see you would get a wrong reading if the MM/SS/.ss were on 59:59.99 and then the interrupt occurred and was serviced right before you read the hours, day, month, and year. You could get a time of 11:59:59.99 when it would have been 10:59:59.99 right before the interrupt or 11:00:00.00 right after. If you just read it once and don't check, your time in this case could be an hour off. In the rarest case you could be a year off. Make a loop that reads it until you get the same thing twice in a row. In most cases you'll only go through twice. Occasionally a third time through will be necessary. It would be a very rare case where other interrupts might be taking so much time that you'll need more tries to get two matching reads in a row.

Don't forget that although you can't mask NMI's, you can tell the IC to quit generating the interrupt. That's how I turn off the RTC above on those rare occasions I need to. I just clear the appropriate bit in the VIA's interrupt-enable register (IER).

There are RTC ICs, but I wanted the 10ms resolution for timing key debouncing, key repeat speed, and other things, and many of the RTC ICs only have 1-second or 1/10-second resolution which is much too coarse for that.

Much of this (plus lots more) is addressed in my 6502 interrupts primer. There's also sample code for running the RTC, and for interrupt support for RS-232 receive.

_________________
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: Thu Feb 02, 2017 5:39 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8144
Location: Midwestern USA
KC9UDX wrote:
Interesting! I have thought about using NMI for RTC where accuracy would be critical, but since I had never tried it, I thought I would wait to hear if anyone else ever did something like that.

As I earlier opined, this is not a good use of NMI, as I will explain.

In my POC units, the only thing attached to NMI is a push button header and a Maxim DS1813, the latter which dampens the push button. The NMI handler (to simplify the explanation) ultimately jumps to the BRK entry point of the machine language monitor. What this means is if I have a program running and it gets stuck in a loop I can non-destructively recover control by pulsing NMI. As the push button is the only possible source of an NMI I don't have to poll for multiple causes, nor do I have to be careful to clear all NMI sources. The jump into the BRK entry of the M/L monitor automatically dumps the MPU's registers, so I can see what was going on when the MPU got stuck.

Timekeeping on POC V1.1 and POC V2 is driven by a 100 Hz jiffy interrupt generated by a free-running timer in the UART, the latter which is attached to the IRQ line, not NMI. The timer IRQ drives two jiffy counters on page zero. One jiffy counter counts upward from $00 to $64 (100) and is for timekeeping. The other jiffy counter counts down from $64 to $00 and is for implementing a time delay feature. All timekeeping data are stored on page zero.

When the timekeeping jiffy counter hits $64 it is reloaded with $00, and a 32 bit uptime counter and a 40 bit time-of-day counter that keeps track of the number of seconds that have elapsed since the epoch are incremented. Uptime can be read through a BIOS API call. The time-of-day can be read or written through BIOS API calls.

If the time delay counter, which is 16 bits, is non-zero it will be decremented each time its associated jiffy counter reaches $00. A BIOS API call is used to set the delay and then stall the system until the time delay counter reaches $00:0000, where $00: is the jiffy counter itself.

External programs are used to convert the raw time-of-day value to human-readable form, as well as to set the time-of-day from human-readable form (with time zone and Daylight Saving Time correction). Hence the work that has to be done by the interrupt handler is minimal—only when human interaction is needed do things get complicated. A 40 bit time-of-day counter is sufficient in range to produce accurate timekeeping well beyond the year 10,000. For simplification, the conversion code I've written handles the range 00:00:00 UTC on October 1, 1752 (which is the epoch) to 23:59:59 UTC on December 31, 9999. If I and the POC are still around during the year 9999 I will update the software. :D

The accuracy of this mess is as good as the accuracy of the 3.6864 MHz clock generator that drives the UART, provided IRQ processing is not disabled for more than about 10 milliseconds, e.g., with the SEI instruction. Testing has demonstrated that the average time-of-day drift amounts to less than one second per month in the environment in my office, which is around 23° C.

Incidentally, the choice of epoch has to do with avoiding negative time values, as well as not having to deal with the complications that would arise in converting dates prior to September 14, 1752, which is when the British Empire abandoned the Julian calendar in favor of the modern Gregorian calendar.

Below is an excerpt from POC V1.1's interrupt handler, in which timekeeping is maintained. As you can see, it's not complicated. Since this is running on the 65C816, I am taking advantage of 16 bit processing in incrementing or decrementing counters. However, the additional code that would be required to do the same with the 65C02 is trivial.

Code:
;UART C/T IRQ PROCESSING
;
         lda io_acia+nx_isra   ;get block A ISR
         bne .iirq010          ;UART is interrupting
;
         jmp iirq02            ;UART is not interrupting
;
.iirq010 bit #nxpctirq         ;C/T interrupting?
         beq iirq01            ;no, must be I/O
;
         bit io_acia+nx_rcta   ;yes, clear interrupt
         longa                 ;16 bit accumulator operations
;
;
;   process time delay counter...
;
         lda tdsecct           ;seconds counter
         beq .iirq030          ;no delay in progress
;
         ldx tdjiffct          ;time delay jiffy counter
         dex                   ;decrement
         bne .iirq020          ;not zero, just decrement
;
         dec tdsecct           ;secs=secs-1
         ldx #hz               ;reset jiffy counter
;
.iirq020 stx tdjiffct          ;new counter value
;
;
;   process free-running clocks...
;
.iirq030 ldx jiffct            ;clock jiffy counter
         inx                   ;increment
         cpx #hz
         bcc .iirq050          ;not time to update
;
         ldx #0                ;reset jiffy count
         inc uptime            ;bump uptime LSW
         bne .iirq040          ;done with uptime
;
         inc uptime+s_word     ;bump uptime MSW
;
.iirq040 inc uxtime            ;bump UNIX time LSW
         bne .iirq050          ;done with UNIX time
;
         inc uxtime+s_word     ;bump UNIX time MID
         bne .iirq050
;
         inc uxtime+s_dword    ;bump UNIX time MSW
;
.iirq050 stx jiffct            ;set new jiffy count
;
          ...program continues...

In the above, C/T means "counter/timer" and the symbol hz is set to 100. LSW and MSW mean, respectively, least significant word and most significant word. "UNIX" time refers to the time-of-day counter, which is not actually UNIX time, since the latter uses a signed integer.

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


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

All times are UTC


Who is online

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