[comp.lang.c] The 8259 interrupt controller

rargyle@wsccs.UUCP (Bob Argyle) (05/15/88)

Using Microsoft C, for a PCclone, I want to program the 8259
interrupt controller (ports 0x20 and 0x21) so that COM1
generates an interrupt (Int 0x0C) when the receive buffer is
full.  When setting up the interrupt mask, I want to read
the previous mask so I can leave it in the same state when
the application is done.  The data sheets I have on the 8259
does not even say which of the internal registers are at
which address.  Have any of you gurus or grues (I'll take
all the help I can get from any source!) had some experience
programming this chip or equivalents?  Can it be done in an
_extremely_ portable manner, i.e. is there now a BIOS call? 
          
The interrupt handler for 0x0C will be writing to the C
program's data space into a circular queue and so it would
be simplest if it were also written in C for compiling at
the same time.  Any pointers on this?  How do I put in a
return-from-interrupt in C?  If necessary I can program it
in assembly.  I would rather develop it in C and then
rewrite just the final belled-and-whistled code in assembly
once the entire package works, however slowly.  ("A program
not written yet takes longer to run than a slow program.") 

Bob Argyle @ wsccs 

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (05/19/88)

I don't have the info right here, but I did this, here's where to find
out how.
	IBM AT tech ref (or XT):
	  section on the serial interface:
	    tells how to set the USART
	  section on the motherboard:
	    how to program the 8259 (just clear a bit in the imask,
	    DON'T lose the values of the other bits)
	    There's a 1 bit output to enable serial ints on the MB
	Intel 8259 spec sheet:
	  How to use the beast, don't forget EOI, don't change
	  the rest of the settings or DOS won't work
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

baumann@hope.UUCP (Michael Baumann) (05/28/88)

In article <531@wsccs.UUCP> rargyle@wsccs.UUCP (Bob Argyle) writes:
>
>
>Using Microsoft C, for a PCclone, I want to program the 8259
>interrupt controller (ports 0x20 and 0x21) so that COM1
>generates an interrupt (Int 0x0C) when the receive buffer is
>full.  When setting up the interrupt mask, I want to read
>the previous mask so I can leave it in the same state when
>the application is done. ...
>...Any pointers on this?  How do I put in a
>return-from-interrupt in C?  

You asked for information on how to program an 8259a for masks etc.. here is
your answer. I have written some stuff for the pc's com port so I hope this
helps. First, I assume that you have no problem with programming the 8250.
Second, I assume that MSC has a way to write/read I/O ports, in Turbo C 1.5
the commands I use are   void outportb(int portid,char data) and 
char inportb(int portid).

To read the Interrupt Mask Register (IMR) do a read from port 0x21. (one
byte only!). As the Com port (for com 1) interrupts on IRQ4 you want to
clear bit 4 of the IMR, a bit-wise and with 0xef works just fine. write
the results back out to 0x21. To signal EOI write 0x20 to port 0x20. This
is the Nonspecific EOI, if you want to do a specific send 0x64 (for IRQ4).
That's all there is to it. I got this information from the Intel lit.

As for the return-from-interrupt, I don't know how MSC handles the writing
of interrupt routines, but Turbo C provides the following mech.:
interrupt <Function declaration>, this provides for saving of all registers,
restoreing them afterword, and issuing an IRET. If worst comes to worst you
could have the ISR entry be in assembly, save the registers there, call
your C routine to do the work, return to assembly, restore registers and 
issue IRET. Hope this helps.


-----------------------------------------------------------------------------
"Life is full of little suprises." -- Pandora  (as quoted by Robert Asprin)
UUCP:   {ucbvax!ucdavis,ucsd,ucivax}!ucrmath!hope!baumann
				or !ucrmath!jinx!baumann