By: Larry Mayhew Re: Re: 8259 pic --------------------------------------------------------------------------- HS> How to use the 8259 programmable in controller. I know the I/O HS> ports to use but wht to put there and when? I wish there were some really simple answers to your question. :-) My answer will oversimplify some details (for example, I ignore the non-maskable interrupt), but it's a start. When a hardware interrupt N occurs (say N=9, keyboard interrupt), interrupts are disabled in two distinct ways: (1) The CPU's Interrupt Flag is cleared by the interrupt mechanism. This prevents any other hardware interrupt from occurring. (2) The PIC's internal registers prioritize interrupts so that only hardware interrupts numbered < N are allowed. Inside the handler for Int N, an STI will enable interrupts from the CPU's point of view, though leaving some still masked out by the PIC. In the case of a keyboard handler (INT 9), executing STI allows timer interrupts (INT 8) to interrupt the keyboard service routine. Before the IRET in a hardware interrupt handler, interrupts >= N must be re-enabled at the 8259. This requires sending an EOI command to the 8259, which is ordinarily done by this familiar code sequence: mov ah,20h out 20h,ah When the 8259 receives the EOI, it then notes to itself that it can reenable any interrupts that were previously disabled by the occurrence of INT N. A programmer's most common interaction with the 8259 is to send EOI to it. A fairly typical scenario is to use STI early in an interrupt handler, and to send EOI just before the IRET. Whether this is appropriate for _your_ hardware service routine is something you must decide by careful analysis of the whole system. IMO, PC programmers too often fail to do the necessary analysis and wind up writing interrupt service routines that have bugs, or at least that are likely to cause intermittent failures in other ISR's under special conditions. It's probably also worth mentioning the IMR (interrupt mask register) in the 8259. This allows hardware interrupts to be masked out individually for periods of time without otherwise affecting higher or lower numbered interrupts. Knowing when/ whether to use IMR-masking in the 8259 depends again upon an analysis of your application and normal system operation. There are other internal 8259 registers that control its operations but are normally of no interest to the programmer, (IRR,ISR). One might want to read these registers, however, when debugging a problem involving the 8259. Rarely, one may need to reprogram the 8259 to revector the hardware interrupts to other INT numbers. This sort of thing is ugly and should ordinarily be left to the people who write OS code. The best general advice I know to give would be this: (1) Keep higher priority (lower numbered) interrupts disabled for as short a time as possible. (2) Keep in mind that lower priority interrupts can be lost if you fail too long to send EOI to the 8259. (3) If you call the original owner of the interrupt before processing it, keep in mind that that owner may already have sent EOI to the 8259. To send EOI again creates subtle, very hard to find bugs in the system. (4) If EOI is sent to the 8259 before your routine is done, you need to choose between disabling all interrupts (usually a bad idea) or writing your routine so it's reentrant. (5) Your interrupt handler should set up its own stack and switch to it unless a careful analysis shows that stack overflow (when other routines interrupt yours) is impossible. (6) It's usually a good idea to CLI just before sending EOI, since conceivably another interrupt could occur just before your final register pop(s) and IRET. While this ordinarily won't hurt anything, it's conceivable that the few extra items on the stack could lead to stack overflow for the interrupting routine. To discuss all of this thoroughly here would take us beyond the scope of the C_Echo. I'd be happy to answer specific questions from you in NetMail, but the basic thrust of my answer is that to use the 8259 properly you need a pretty good understanding of how your interrupt routine is related to other interrupt routines in the system. Even so simple a question as when to send EOI can raise complex issues. .