6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 6:01 pm

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: 65C816 WIKIPEDIA ARTICLE
PostPosted: Tue Sep 11, 2012 4:45 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
Something that I have intermittently worked on is rewriting the Wikipedia article on 6502 interrupts to make it factual, understandable and of value to someone learning about our favorite microprocessor. I've pretty much covered all the bases but would appreciate some input on the quality of my handiwork. :)

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2012 10:34 am 
Offline

Joined: Sun Apr 10, 2011 8:29 am
Posts: 597
Location: Norway/Japan
Great article, in my opinion. Easy read, factual, anyone reading it should feel very comfortable about 6502 interrupt handling.

-Tor


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2012 3:25 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
Tor wrote:
Great article, in my opinion. Easy read, factual, anyone reading it should feel very comfortable about 6502 interrupt handling.

-Tor

Now that's what I call a vote of confidence! :D Thanks!

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Sep 11, 2012 9:56 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
Great article! Some points though:

- you get pushed into 6502/65816 emulation/native mode quickly. Maybe one or two sentences are in order to explain them in the first paragraph would be in order

- As a hardware guy I wonder how I would determine this condition: "Hence the logic must not assert ABORT until the processor has asserted the VDA or VPA signals". How do I know the VDA/VPA signals are valid and not leftovers from the previous cycle? I think it's just a wording thing...

- In the "interrupt handler considerations" you write "For NMOS processors, ..." - you do not explicitly explain which ones are the NMOS. Same for other places. Maybe again a sentence in the first paragraph would be in order

- The wording for pushing the index registers and considering the size is a bit complex (at least for a non-native speaker - although I have been accused of the same... ;-) Not knowing much about the 65816 push/pull behaviour, I assume you mean that when you pull the registers with same size as you push them everything should work. I would assume so anyway, as the memory size on stack changes. But at the end of the ISR, how do you know which size you would have to use, if you had to change the index register width during the ISR? Do you have to pull the status then push it again to set the width bit before you pull the index registers? (Ah the next paragraph about the accumulator mentions the second copy of the SR...)

- when you explain using BRK as call operation, you should refer to the section with the BRK bug in NMOS processors

- I think the WAI/STP section has a wrong hrdware RESET vector address

- footnote 4: "no meaning" is a bit harsh... : it is not stored in the processor, only written to stack on ....

Great read!
André

_________________
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: Wed Sep 12, 2012 1:19 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
fachat wrote:
Great article! Some points though:

- you get pushed into 6502/65816 emulation/native mode quickly. Maybe one or two sentences are in order to explain them in the first paragraph would be in order

I've thought about doing so. However, the 65C816 article already describes that feature. The interrupt article is somewhat lengthy by Wikipedia standards, so I'm hesitant to add material that may not be entirely germane. For now, I'm inclined to assume that the reader will consult a data sheet if really interested in the '816 and its dual modes

Quote:
- As a hardware guy I wonder how I would determine this condition: "Hence the logic must not assert ABORT until the processor has asserted the VDA or VPA signals". How do I know the VDA/VPA signals are valid and not leftovers from the previous cycle? I think it's just a wording thing...

VDA and VPA exactly reflect the address bus status and what is being accessed (opcode, operand or data), so there wouldn't be a "leftover." For example, if both are asserted an opcode is being fetched. If both are quiescent an internal operation is being carried out and the address bus is invalid. If VPA is being asserted an operand is being fetched, etc. I didn't explain all that because the article is about interrupts and not bus management. I'm presuming that anyone reading the article who has interest in bus management details will consult the data sheet for timing, etc. The proper use of VDA and VPA is almost a subject unto itself, as I'm all too aware! :oops:

Quote:
- In the "interrupt handler considerations" you write "For NMOS processors, ..." - you do not explicitly explain which ones are the NMOS. Same for other places. Maybe again a sentence in the first paragraph would be in order

Other articles (e.g., the one for the 6502) spell out which processor series is which. Again, I was hesitant to insert hardware material into an article that is pretty long and is primarily geared to software implementation. Presumably, a reader interested enough to read something as arcane as 65xx interrupt processing would know which members of the family are NMOS and which are CMOS. In any case, I inserted examples of NMOS versions.

Quote:
- The wording for pushing the index registers and considering the size is a bit complex (at least for a non-native speaker - although I have been accused of the same... ;-)

You do have a point. In rereading that prose, I can see where a non-native speaker might experience some trouble with it. I'll have to see if I can clarify it somehow.

Quote:
Not knowing much about the 65816 push/pull behaviour...(Ah the next paragraph about the accumulator mentions the second copy of the SR...)

I describe two approaches to pushing and pulling the registers without information loss, one being the pushing of another SR copy for later restoration and the other being setting all register widths to 16 bits prior to pushing them. I only give an example of the latter, as while developing POC's interrupt handlers, I determined that always pushing and pulling the registers as 16 bits was more efficient and safer.

Quote:
- when you explain using BRK as call operation, you should refer to the section with the BRK bug in NMOS processors

I assume you're referring to the case where a hardware interrupt hits just as the MPU is about to execute BRK, causing BRK to be entirely skipped. That "feature" is referred to in an earlier section that you must have missed. :D

Quote:
- I think the WAI/STP section has a wrong hrdware RESET vector address

Yes it does. Me and my bad typing. :lol: I fixed it.

Quote:
- footnote 4: "no meaning" is a bit harsh... : it is not stored in the processor, only written to stack on ....

I agree and reworded it.

Quote:
Great read!
André

Sometimes I fool humans with my schmarts routine. :lol:

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


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 12, 2012 5:36 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Quote:
In all but the most trivial of ISRs, the accumulator and index registers must be preserved and later restored as the final steps prior to executing RTI.

I would say my ISRs seldom need all three; and I don't preserve or restore what I don't use in the ISR.  In my '816 Forth system that only runs in bank 0 and makes the other banks to be for data only (through long addressing), there's no need to preserve and restore the data bank register.  (MVN and MVP with a non-0 destination bank would require temporarily disabling interrupts though.)  In fact, for servicing interrupts in Forth, I don't even need to preserve & restore X & Y, since X is the data stack pointer and the Forth ISRs are stack-autonomous, and although primitives can use Y, the value of Y between primitives doesn't matter.  Also, the reset routine takes it out of emulation mode and it never goes back, so no worries about preserving native v. emulation mode.  So the interrupt-service process gets pretty efficient.

I have seen in others' code that they often waste time polling interrupt sources that are not even enabled (most of the possible sources are usually disabled), and also waste time doing things that are redundant like SEI at the beginning of the ISR, or even potentially troublesome like doing CLI right before the RTS.  That would be worth mentioning (not that you can't have CLI in the ISR if you want a quick, high-priority interrupt to be able to interrupt the service of a longer, lower-priority one, if you know what you're doing).

In the "For further reading" you could refer to articles on 6502.org.

I know, I'm being the 65xx salesman again, trying to show how efficient it can be in many applications.  :lol:

_________________
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 Sep 12, 2012 8:03 am 
Offline

Joined: Sun Apr 10, 2011 8:29 am
Posts: 597
Location: Norway/Japan
BigDumbDinosaur wrote:
fachat wrote:
- The wording for pushing the index registers and considering the size is a bit complex (at least for a non-native speaker - although I have been accused of the same... ;-)

You do have a point. In rereading that prose, I can see where a non-native speaker might experience some trouble with it. I'll have to see if I can clarify it somehow.

One thing I appreciated about the article is the language.. it's very clear and precise. These days one often see ambiguous sentences of the type "a man brought a friend his bike", for example.

I re-read the article but I'm not sure which part the quote about the index registers refers to - I too would like to give it another 'non-native speaker' lookover.. ;)

-Tor


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 12, 2012 5:48 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
GARTHWILSON wrote:
Quote:
In all but the most trivial of ISRs, the accumulator and index registers must be preserved and later restored as the final steps prior to executing RTI.

I would say my ISRs seldom need all three; and I don't preserve or restore what I don't use in the ISR...

As I was trying to target my prose to a wide audience, I worded that statement the way I did for a reason. If the ISR is part of a general purpose operating environment, it's difficult to get much done in the ISR if the registers aren't used. For example, if you have multiple interrupt sources enabled in a device, say a 6522, you may have to read an interrupt status register, test bits and route execution according to what was found. Use of the accumulator would help in that regard and perhaps make for a shorter and faster executing ISR. You may also have the case where reading the interrupt status register clears it and the interrupt sources, e.g., the behavior of the 53C94 SCSI controller in my POC unit. You can't use BIT for that purpose if more than one interrupt has been enabled in the device, as the status is ephemeral. Your only recourse is to load the status into a register for later reference.

So in the majority of cases, register preservation has to be considered. Of course, if the programmer can figure out how to limit register usage to just the accumulator, then the overhead of pushing and pulling .X and .Y can be avoided. Even then, if the majority of interrupts are synchronous in nature, e.g., the 100 Hz jiffy IRQ in my POC unit, the cost of preserving and restoring .X and .Y isn't all that great. The 65xx's stack operations are pretty efficient in terms of cycles used versus work done.

Now, if the ISR is geared to a very specific set of circumstances and if bit testing and value manipulation can be done solely with BIT and various R-M-W instructions, one could avoid touching the registers and thus skip the overhead of preserving them. However, even then, you'd have to be aware of the register widths on the 65C816, as the effects of BIT and R-M-W instructions are dependent on the width of .A—recall that REP #%00100000 not only sets .A to 16 bits it causes BIT and all R-M-W instructions to act on 16 bit values. The '816 takes care of register width preservation when it pushes the status register in response to the interrupt. Your ISR's only responsibility at that point would be to configure registers sizes as required and process the interrupt.

This sort of situation may be applicable to your workbench unit, which as you say, is geared to machine interaction, not human. An embedded machine controller using the SEI ... WAI method of servicing interrupts would also be a candidate for skipping register preservation on the stack. However, I don't think avoiding register usage is practical in a more general purpose scenario.

Quote:
I have seen in others' code that they often waste time polling interrupt sources that are not even enabled (most of the possible sources are usually disabled), and also waste time doing things that are redundant like SEI at the beginning of the ISR, or even potentially troublesome like doing CLI right before the RTS. That would be worth mentioning (not that you can't have CLI in the ISR if you want a quick, high-priority interrupt to be able to interrupt the service of a longer, lower-priority one, if you know what you're doing).

You bring up a valid point, which I reference at the start of the ISR section:

    A well-designed interrupt handler or interrupt service routine (ISR) will not only expeditiously service the event that caused the interrupt, it will do so without interfering in any way with the interrupted foreground task, that is, the ISR will be "transparent" to the interrupted task.

The key word is "expeditiously." It goes without saying that an ISR should be as succinct as possible and refer only to "live" interrupt services (an aspect of the ISR that would be considerably helped with interrupt priority hardware—vectored ISRs may be able to completely avoid register usage knowing what they are expected to process). Here it's a case of just how detailed should be in an encyclopedia article. I'm trying to achieve a balance between generally useful information about an arcane topic, yet avoid having the article become a "machine language for beginners" paraphrase. However, I did rephrase that first sentence to be a little more specific:

    A well-designed and succinct interrupt handler or interrupt service routine (ISR) will not only expeditiously service any event that causes an interrupt, it will do so without interfering in any way with the interrupted foreground task—the ISR must be "transparent" to the interrupted task (although exceptions may apply in specialized cases).

Quote:
In the "For further reading" you could refer to articles on 6502.org.

Since you posted I made some additions to that section. :D

Quote:
I know, I'm being the 65xx salesman again, trying to show how efficient it can be in many applications. :lol:

Aren't we all? :P I devoted a section to the use of WAI and STP to achieve the most rapid response to an interrupt (50ns at 20 MHz—can't beat that with a stick). I'll be willing to wager that many who read the article will not be familiar with just how those two instructions can be used in that context.

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


Top
 Profile  
Reply with quote  
PostPosted: Wed Sep 12, 2012 6:10 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
Tor wrote:
BigDumbDinosaur wrote:
fachat wrote:
- The wording for pushing the index registers and considering the size is a bit complex (at least for a non-native speaker - although I have been accused of the same... ;-)

You do have a point. In rereading that prose, I can see where a non-native speaker might experience some trouble with it. I'll have to see if I can clarify it somehow.

One thing I appreciated about the article is the language.. it's very clear and precise.

Thanks! Years of technical writing, especially in situations where non-technical readers are being addressed, has helped. I try to be as clear as I can, especially in a subject that is by nature somewhat difficult for a beginner to grasp.

While on the subject of clear and precise language, the conversational style that Garth used in his interrupt primer tends to help newbies in grasping the fundamentals. I used that style on my POC website to aid the reader who is contemplating the construction of his own 6502-powered contraption. I've generally felt that the first person, conversational style makes the text "friendlier." Of course, one wouldn't use that style in formal writings, e.g., a technical paper to be presented to a standards body, but it's appropriate in a lot of cases.

Quote:
These days one often see ambiguous sentences of the type "a man brought a friend his bike", for example.

Ah, yes. I recall those sorts of phrases from my elementary school days. One of the best characteristics of the English language is its great flexibility, especially with regard to word precedence. Unfortunately, one of the worst characteristics of the English language is its great flexibility, especially with regard to word precedence. :lol: My hat is always off to anyone who is not a native speaker and is able to use English to discuss technical subjects of the sort we kick around in this forum. English idioms can be quite a challenge to learn for a non-native speaker. Even for native speakers, regional or national differences can be a problem. In the UK, phrases that are commonly used usually result in some puzzlement here in the USA, and vice versa. I try to be aware of that at all times when posting here.

Quote:
I re-read the article but I'm not sure which part the quote about the index registers refers to - I too would like to give it another 'non-native speaker' lookover.. ;)

Anything that can help with the clarity is welcome. I'm hoping that by reading this article, as well as the material we have here, folks who are learning about the 6502 will not be apprehensive about using interrupt processing.

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


Top
 Profile  
Reply with quote  
PostPosted: Fri Sep 14, 2012 11:04 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Quote:
Of course, if the programmer can figure out how to limit register usage to just the accumulator, then the overhead of pushing and pulling .X and .Y can be avoided. Even then, if the majority of interrupts are synchronous in nature, e.g., the 100 Hz jiffy IRQ in my POC unit, the cost of preserving and restoring .X and .Y isn't all that great.

It would be pretty common to use just the accumulator.  My longest ISR ever is the software RTC one in my interrupts primer, and that only uses the accumulator.  Actually in my own use I left everything beyond the minutes to be taken care of outside the ISR.  In the same primer, I did use X in the RS-232 receive ISR as a pointer into the buffer, but not Y.  I've serviced over 100,000 interrupts per second though at 5MHz (on a 6502), and at that rate the extra clocks taken to push and pull a register you're not using become more significant.  (>100,000 was an extreme case.  More-normal applications have maxed out at 44,000, and mostly been at 24,000 and down.)

Quote:
An embedded machine controller using the SEI ... WAI method of servicing interrupts would also be a candidate for skipping register preservation on the stack.

That's a really neat way to get more immediate response and cut the jitter.  I envision it being for situations where the computer can be almost fully dedicated to the one job, using interrupts only to make the timing as precise as possible, at the expense of the ability to be productive while waiting for an 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  
PostPosted: Sat Sep 15, 2012 1:41 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
GARTHWILSON wrote:
Quote:
Of course, if the programmer can figure out how to limit register usage to just the accumulator, then the overhead of pushing and pulling .X and .Y can be avoided. Even then, if the majority of interrupts are synchronous in nature, e.g., the 100 Hz jiffy IRQ in my POC unit, the cost of preserving and restoring .X and .Y isn't all that great.

It would be pretty common to use just the accumulator. My longest ISR ever is the software RTC one in my interrupts primer, and that only uses the accumulator. Actually in my own use I left everything beyond the minutes to be taken care of outside the ISR. In the same primer, I did use X in the RS-232 receive ISR as a pointer into the buffer, but not Y. I've serviced over 100,000 interrupts per second though at 5MHz (on a 6502), and at that rate the extra clocks taken to push and pull a register you're not using become more significant. (>100,000 was an extreme case. More-normal applications have maxed out at 44,000, and mostly been at 24,000 and down.)

The key to this discussion is to carefully evaluate what your ISR has to accomplish and then try to accomplish it with minimal resources. In the case of my POC's ISR, it's not practical to solely rely on the accumulator—processing TIA-232 data flow requires indexing into the buffers. The X-register is a logical candidate for that purpose and is heavily used. Until I added the SCSI driver to the ROM, .Y wasn't being used at all in the ISR.

The SCSI ISR is more demanding of register usage, as it has to retrieve the 53C94's general status, interrupt status and state machine (command) status for analysis and foreground program routing. It became expedient to use all MPU registers for that purpose, especially since there is a defined order in which the 'C94 registers should be read (general status state machine status interrupt status) in order to not accidentally reset something and lose information:

Code:
                            ;HARDWARE INTERRUPT REQUEST SERVICE ROUTINE
                            ;
00E1BE  8B                : iirq            phb                     ;save current data bank
00E1BF  0B                :                 phd                     ;save zero page pointer
                                            longr                   ;save 16 bit user registers
                          +                 .longa  on
                          +                 .longi  on
00E1C0  C230              +                 rep     #$30
00E1C2  48                :                 pha
00E1C3  DA                :                 phx
00E1C4  5A                :                 phy
00E1C5  6C0601            :                 jmp     (ivirq)         ;IRQ indirect vector
                            ;
                            ;       ———————————————————————————————
                            ;       IRQ priority: a) SCSI
                            ;                     b) DUART ch A RHR
                            ;                     c) DUART ch B RHR
                            ;                     d) DUART ch A THR
                            ;                     e) DUART ch B THR
                            ;                     f) RTC
                            ;       ———————————————————————————————
                            ;
                            iirqa           shortr                  ;8 bit everything
                          +                 .longa  off
                          +                 .longi  off
00E1C8  E230              +                 sep     #$30
                            ;
                            ;———————————————————————————————————————————————————————————————————
        00000001          = iirq_yrx        .set    scstkptr+s_byte ;16 bit .Y
        00000003          = iirq_xrx        .set    iirq_yrx+s_word ;16 bit .X
        00000005          = iirq_arx        .set    iirq_xrx+s_word ;16 bit .A
        00000007          = iirq_dpx        .set    iirq_arx+s_word ;zero page pointer
        00000009          = iirq_dbx        .set    iirq_dpx+s_word ;data bank
        0000000A          = iirq_srx        .set    iirq_dbx+s_byte ;status
        0000000B          = iirq_pcx        .set    iirq_srx+s_mpusrx ;program counter
        0000000D          = iirq_pbx        .set    iirq_pcx+s_mpupcx ;program bank
                            ;———————————————————————————————————————————————————————————————————
                            ;
00E1CA  AC04D2            :                 ldy     stat_sr         ;53C94 general status
00E1CD  102D              :                 bpl     .iirq002        ;not a SCSI interrupt
                            ;
                            ;       ————————————————
                            ;       process SCSI IRQ
                            ;       ————————————————
                            ;
00E1CF  A900              :                 lda     #0
00E1D1  EB                :                 xba                     ;clear .B
00E1D2  AE06D2            :                 ldx     isr_sr          ;'C94 command status
00E1D5  AD05D2            :                 lda     irqst_sr        ;'C94 interrupt status

Note that the above is the listing output from BitWise's 65C816 assembler.

Here usage of all registers expedites the retrieval of the the 'C94's status, and because the interrupt status is gotten as soon as it is known that a SCSI IRQ has occurred, but after state machine status has been read (reading the interrupt status clears the interrupt, as well as bits associated with each possible interrupt source, so it must be read last), ample time is made available for the IRQ line to return high and avoid the generation of a spurious IRQ. There's also a programming consideration with the 'C94 in which one is not supposed to read the IRQ status unless an IRQ has actually occurred, as otherwise doing so may inadvertently clear a pending interrupt and cause a SCSI bus stall. It's a timing issue due to the 'C94 being sequenced by its own clock reference and thus running asynchronously to the MPU.

Later on, I take advantage of the '816's stack addressing to "mail" the three status values to the foreground task, as well as condition the MPU status in a certain way and route foreground execution:

Code:
                            ;       ————————————————————————————————————————————————————————————————————————
                            ;       The following code modifies some of the stack entries that were pushed
                            ;       by the ISR preamble.  The changes are as follows:
                            ;
                            ;           Register  Contains
                            ;           —-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
                            ;              .A     SCSI controller interrupt status
                            ;              .X     SCSI controller command status
                            ;              .Y     SCSI controller general status
                            ;              PC     SCSI foreground execution vector
                            ;              SR     C & D cleared, & m & x set
                            ;           —-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
                            ;
                            ;       The effect of these changes is to alter the SCSI driver execution path &
                            ;       make the SCSI controller's status available foreground part of the driv-
                            ;       er.  Also, registers are set to 8 bits, since the information being ret-
                            ;       urned in them is 8 bit data.
                            ;
                            ;       No analysis of status is made here, as doing so would lengthen the exec-
                            ;       ution time of the SCSI ISR to the detriment of other IRQ processing.
                            ;       ————————————————————————————————————————————————————————————————————————
                            ;
                                            longa
                          +                 .longa  on
00E1D8  C220              +                 rep     #$20
00E1DA  8305              :                 sta     iirq_arx,s      ;.A = interrupt status
00E1DC  8A                :                 txa
00E1DD  8303              :                 sta     iirq_xrx,s      ;.X = command status
00E1DF  98                :                 tya
00E1E0  8301              :                 sta     iirq_yrx,s      ;.Y = general status
00E1E2  AD0A01            :                 lda     ivscsi          ;get alternate driver vector
00E1E5  9C0A01            :                 stz     ivscsi          ;also invalidate it
00E1E8  D003              :                 bne     .iirq001        ;vector defined, so use it
                            ;
00E1EA  A9C4E6            :                 lda     #ssdsptch       ;use default driver vector
                            ;
00E1ED  830B              : .iirq001        sta     iirq_pcx,s      ;reroute driver foreground
                                            shorta                  ;8 bit .A
                          +                 .longa  off
00E1EF  E220              +                 sep     #$20
00E1F1  A30A              :                 lda     iirq_srx,s      ;get saved status register
00E1F3  29FE              :                 and     #sr_bdm|sr_car_i ;clear C & D flags
00E1F5  0930              :                 ora     #sr_amw | sr_ixw ;set m & x flags
00E1F7  830A              :                 sta     iirq_srx,s      ;change stack copy &...
00E1F9  4CDCE2            :                 jmp     crti            ;immediately return

The code at CRTI reverses the pushes at the start of the ISR and returns to the foreground process. As the stack copies of the MPU registers were modified by the above code, the foreground part of the SCSI driver automatically receives the information it needs to analyze the 'C94's status and determine what needs to occur next. Also, the RTI address has been altered, causing the foreground execution path to change, usually to the foreground analysis code block (an alternate vector can be set, however). All of this helps to reduce latency and partially automates the decision-making process of the driver. While it would be possible to do it using just .A, using all registers to get the 'C94's status takes fewer clock cycles.

As the POC's ISR has to function within the larger framework of the BIOS ROM and any other running program, generality is the key to true transparency. Hence I assume in the ISR preamble that all registers contain valuable 16 bit data, and that the data bank and zero page locations may not be the same when the interrupt hist as the environment in which the kernel would be running. While POC V1 has no addressing beyond $00FFFF and doesn't relocate zero page, I inserted the extra code for future use (POC V2 will have addressing to $0FFFFF—1 MB).

Quote:
Quote:
An embedded machine controller using the SEI ... WAI method of servicing interrupts would also be a candidate for skipping register preservation on the stack.

That's a really neat way to get more immediate response and cut the jitter. I envision it being for situations where the computer can be almost fully dedicated to the one job, using interrupts only to make the timing as precise as possible, at the expense of the ability to be productive while waiting for an interrupt.

Yeah, it would make sense for something where no processing is required until an external event occurs. Consider, for example, a controller for an engine lathe. If no one is using the machine then the controller literally has nothing to do. So it would be feasible to use the SEI...WAI sequence to "park" the MPU and place it in a low-power state until someone uses the lathe. As soon as they would operate a control, such as start the headstock spinning, doing so would generate an IRQ to the controller and the MPU would promptly wake up and go to work. Latency would be no more than one clock cycle. No register preservation would be required as well, since the MPU had nothing else to do while waiting for someone to use the machine.

_________________
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  [ 11 posts ] 

All times are UTC


Who is online

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