#include #include "async.h" extern int UART_ports[]; extern int UART_interrupts[]; extern int UART_onmask[]; extern int UART_offmask[]; extern struct async_portS async_port[4]; extern int MSRStatus[NUMBEROFPORTS]; extern int LSRStatus[NUMBEROFPORTS]; // Prototypes for ISR's void interrupt UART_ISR1(void); void interrupt UART_ISR2(void); void interrupt UART_ISR3(void); void interrupt UART_ISR4(void); // Prototypes for ISR utilities. static void near ISRmodem(int comport); static void near ISRtx(int comport); static void near ISRrx(int comport); static void near ISRstatus(int comport); void init_ISR(int comport) { int icu, mcr; asm cli; // Get old interrupt vector async_port[comport].oldISR = getvect(UART_interrupts[comport]); // Set new interrupt vector switch (comport) { case COM1: setvect(UART_interrupts[comport], UART_ISR1); break; case COM2: setvect(UART_interrupts[comport], UART_ISR2); break; case COM3: setvect(UART_interrupts[comport], UART_ISR3); break; case COM4: setvect(UART_interrupts[comport], UART_ISR4); break; } // Set OUT2 bit to enable interrupts mcr = inportb(UART_ports[comport]+MCR); mcr |= MCR_OUT2; outportb(UART_ports[comport]+MCR, mcr); // Enable interrupts we want outportb(UART_ports[comport]+IER, 0x08); // Unmask the interrupts in the ICU icu = inportb(0x21); icu &= UART_onmask[comport]; outportb(0x21, icu); asm sti; } void deinit_ISR(int comport) { int icu; // Return the old interrupt vector to normal setvect(UART_interrupts[comport], async_port[comport].oldISR); // Remask the interrupts in the ICU icu = inportb(0x21); icu |= UART_offmask[comport]; outportb(0x21, icu); } // Interrupt Service Routines void interrupt far UART_ISR1() // ISR for COM1 { int iir; int done = 0; while (!done) { iir = inportb(UART_ports[COM1]+IIR); if (iir&1) { done = 1; } else { iir&=6; iir>>=1; switch (iir) { case 0: ISRmodem(COM1); break; case 1: ISRtx(COM1); break; case 2: ISRrx(COM1); break; case 3: ISRstatus(COM1); break; } } } outport(0x20, 0x20); } void interrupt far UART_ISR2() // ISR for COM2 { int iir; int done = 0; while (!done) { iir = inportb(UART_ports[COM2]+IIR); if (iir&1) { done = 1; } else { iir&=6; iir>>=1; switch (iir) { case 0: ISRmodem(COM2); break; case 1: ISRtx(COM2); break; case 2: ISRrx(COM2); break; case 3: ISRstatus(COM2); break; } } } outport(0x20, 0x20); } void interrupt far UART_ISR3() // ISR for COM3 { int iir; int done = 0; while (!done) { iir = inportb(UART_ports[COM3]+IIR); if (iir&1) { done = 1; } else { iir&=6; iir>>=1; switch (iir) { case 0: ISRmodem(COM3); break; case 1: ISRtx(COM3); break; case 2: ISRrx(COM3); break; case 3: ISRstatus(COM3); break; } } } outport(0x20, 0x20); } void interrupt far UART_ISR4() // ISR for COM4 { int iir; int done = 0; while (!done) { iir = inportb(UART_ports[COM4]+IIR); if (iir&1) { done = 1; } else { iir&=6; iir>>=1; switch (iir) { case 0: ISRmodem(COM4); break; case 1: ISRtx(COM4); break; case 2: ISRrx(COM4); break; case 3: ISRstatus(COM4); break; } } } outport(0x20, 0x20); } void near ISRmodem(int comport) { MSRStatus[comport] = inportb(UART_ports[comport]+MSR); } void near ISRtx(int comport) { int tst; // Read from buffer and transmit -- Only does one character right now, no fifo support YET. while (1) { if (async_port[comport].txbuflength) { // There is something waiting to be sent, send it outportb(UART_ports[comport], async_port[comport].txbuf[async_port[comport].txtail]); // Move buffer tail async_port[comport].txtail++; async_port[comport].txbuflength--; if (async_port[comport].txtail == TXBUFSIZE) { async_port[comport].txtail = 0; } tst = inport(UART_ports[comport]+LSR); if (tst != 0x20) { break; } } else { // There is nothing, so inhibit TX interrupts tst = inportb(UART_ports[comport]+IER); tst &= 13; outportb(UART_ports[comport]+IER, tst); break; } } } void near ISRrx(int comport) { int rx, tst; int done = 0; while (!done) { rx = inportb(UART_ports[comport]); // Place character into buffer async_port[comport].rxbuf[async_port[comport].rxhead] = rx; // Increment rx buffer head async_port[comport].rxhead++; async_port[comport].rxbuflength++; if (async_port[comport].rxhead == RXBUFSIZE) { async_port[comport].rxhead = 0; } tst = inportb(UART_ports[comport]+LSR); if (!(tst & 0x01)) { // Check for more in receive done = 1; } if (tst & 0x40) { // Check transmit shift register ISRtx(comport); } } } void near ISRstatus(int comport) { LSRStatus[comport] = inport(UART_ports[comport]+LSR); }