home *** CD-ROM | disk | FTP | other *** search
- // port.c
-
- #include "doomnet.h"
- #include "sersetup.h"
-
- void jump_start( void );
-
- void interrupt isr_8250 (void);
- void interrupt isr_16550 (void);
-
- union REGS regs;
- struct SREGS sregs;
-
- que_t inque, outque;
-
-
- enum {UART_8250, UART_16550} uart_type;
- extern int uart; // io address
- extern int irq;
- extern unsigned long baud;
-
- int modem_status = -1;
- int line_status = -1;
-
- void interrupt (*oldirqvect) (void);
- int irqintnum;
-
- extern int comport;
-
-
- /* showUartErrors() counters. */
- extern unsigned long numBreak;
- extern unsigned long numFramingError;
- extern unsigned long numParityError;
- extern unsigned long numOverrunError;
- extern unsigned long numTxInterrupts;
- extern unsigned long numRxInterrupts;
-
-
- /*
- ==============
- =
- = GetUart
- =
- ==============
- */
-
- void GetUart (void)
- {
- char far *system_data;
- static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
- static int ISA_IRQs[] = {4,3,4,3};
- static int MCA_uarts[] = {0x03f8,0x02f8,0x3220,0x3228};
- static int MCA_IRQs[] = {4,3,3,3};
-
- regs.h.ah = 0xc0;
- int86x( 0x15, ®s, ®s, &sregs );
- if ( regs.x.cflag )
- {
- if (irq == -1)
- irq = ISA_IRQs[ comport-1 ];
- if (uart == -1)
- uart = ISA_uarts[ comport-1 ];
- return;
- }
- system_data = ( char far *) ( ( (long) sregs.es << 16 ) + regs.x.bx );
- if ( system_data[ 5 ] & 0x02 )
- {
- if (irq == -1)
- irq = MCA_IRQs[ comport-1 ];
- if (uart == -1)
- uart = MCA_uarts[ comport-1 ];
- }
- else
- {
- if (irq == -1)
- irq = ISA_IRQs[ comport-1 ];
- if (uart == -1)
- uart = ISA_uarts[ comport-1 ];
- }
-
- printf ("Looking for UART at port 0x%x, irq %d...\n\n",uart,irq);
- }
-
-
-
-
- /*
- ===============
- =
- = InitPort
- =
- ===============
- */
-
- void InitPort (void)
- {
- int mcr;
- int temp;
- unsigned long divisor;
-
- //
- // init com port settings
- //
-
- /*******
- regs.x.ax = 0xf3; //f3= 9600 n 8 1
- regs.x.dx = comport - 1;
- int86 (0x14, ®s, ®s);
- *******/
-
- if ((divisor = baud) == 14400)
- divisor = 19200;
-
- divisor = CLOCK_FREQUENCY / (16 * divisor); /* Calc. divisor */
- OUTPUT( uart + LINE_CONTROL_REGISTER, LCR_DLAB ); /* Enable divisor */
- OUTPUT( uart + DIVISOR_LATCH_HIGH, 0 ); /* Set divisor */
- OUTPUT( uart + DIVISOR_LATCH_LOW, (unsigned char) divisor);
- OUTPUT( uart + LINE_CONTROL_REGISTER, 3 ); /* Set 8,n,1 */
-
- //
- // check for a 16550
- //
- OUTPUT( uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE + FCR_TRIGGER_04 );
- temp = INPUT( uart + INTERRUPT_ID_REGISTER );
- if ( ( temp & 0xf8 ) == 0xc0 )
- {
- uart_type = UART_16550;
- printf ("UART is a 16550\n\n");
- }
- else
- {
- uart_type = UART_8250;
- OUTPUT( uart + FIFO_CONTROL_REGISTER, 0 );
- printf ("UART is an 8250\n\n");
- }
-
- //
- // prepare for interrupts
- //
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 ); /* Turn off interrupts */
-
- mcr = INPUT( uart + MODEM_CONTROL_REGISTER ); /* Get modem status */
- mcr |= MCR_OUT2; /* Set GPO 2 */
- mcr &= ~MCR_LOOPBACK; /* Turn off loopback test */
- mcr |= MCR_DTR; /* Set DTR */
- mcr |= MCR_RTS; /* Set RTS */
- OUTPUT( uart + MODEM_CONTROL_REGISTER, mcr ); /* Set modem status */
-
- INPUT( uart ); /* Clear Rx interrupts */
- INPUT( uart + INTERRUPT_ID_REGISTER ); /* Clear Tx interrupts */
-
- //
- // hook the irq vector
- //
- irqintnum = irq + 8;
-
- oldirqvect = getvect (irqintnum);
- if( uart_type == UART_8250 ) /* Use different interrupt routines */
- setvect (irqintnum, isr_8250);
- else
- setvect (irqintnum, isr_16550);
-
- OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) & ~(1<<irq) );
-
- CLI();
-
- // enable RX and TX interrupts at the uart
- // also enable Line Status interrupts to watch for errors.
-
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER,
- IER_RX_DATA_READY + IER_TX_HOLDING_REGISTER_EMPTY + IER_LINE_STATUS );
-
- // enable interrupts through the interrupt controller
-
- OUTPUT( 0x20, 0xc2 );
-
-
- STI();
-
-
- }
-
-
- /*
- =============
- =
- = ShutdownPort
- =
- =============
- */
-
- void ShutdownPort ( void )
- {
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 ); /* Turn off interrupts */
- OUTPUT( uart + MODEM_CONTROL_REGISTER, 0 ); /* Clear modem status */
- OUTPUT( uart + FIFO_CONTROL_REGISTER, 0 ); /* Clear fifo status */
-
- OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) | (1<<irq) );
-
- setvect (irqintnum,oldirqvect); /* Return to orig. inter. */
-
- #if 0 /* Leave port as it is. */
- *
- * regs.x.ax = 0xf3; //f3= 9600 n 8 1
- * regs.x.dx = comport - 1;
- * int86 (0x14, ®s, ®s);
- *
- #endif
-
- }
-
-
- int read_byte( void )
- {
- int c;
-
- if (inque.size == 0)
- return -1;
-
- c = inque.data[inque.tail++];
- inque.size--;
-
- if (inque.tail >= QUESIZE)
- inque.tail = 0; // wrap around
-
- return c;
- }
-
-
- void write_byte( unsigned char c )
- {
- outque.data[outque.head++] = c;
- outque.size++;
-
- if (outque.head >= QUESIZE)
- outque.head = 0; // wrap around
- }
-
-
- void write_bytes( char *buf, int count )
- {
- if (outque.head + count >= QUESIZE) /* About to wrap around */
- {
- while (count--)
- write_byte (*buf++);
- }
- else
- {
- memcpy(outque.data + outque.head, buf, count); /* Write all at once */
- outque.head += count;
- outque.size += count;
- }
- }
-
-
-
- //==========================================================================
- /*
- ==============
- =
- = isr_8250
- =
- ==============
- */
-
- void interrupt isr_8250(void)
- {
- int c;
- int count;
-
- while (1)
- {
- switch( INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
- {
-
- //
- // receive exactly one byte, since this is a UART 8250
- //
- case IIR_RX_DATA_READY_INTERRUPT :
- //I_ColorBlack (0,63,0);
- ++numRxInterrupts;
- c = INPUT( uart + RECEIVE_BUFFER_REGISTER );
- inque.data[inque.head++] = c;
- inque.size++;
- if (inque.head >= QUESIZE)
- inque.head = 0; // wrap around
- break;
-
- //
- // transmit exactly one byte, since this is a UART 8250
- //
- case IIR_TX_HOLDING_REGISTER_INTERRUPT :
- //I_ColorBlack (63,0,0);
- ++numTxInterrupts;
- if (outque.size != 0)
- {
- c = outque.data[outque.tail++];
- outque.size--;
- if (outque.tail >= QUESIZE)
- outque.tail = 0; // wrap around
- OUTPUT( uart + TRANSMIT_HOLDING_REGISTER, c );
- }
- break;
-
- #if 0 // not enabled
- * case IIR_MODEM_STATUS_INTERRUPT :
- * modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
- * break;
- #endif
-
- //
- // line status
- //
- case IIR_LINE_STATUS_INTERRUPT :
- line_status = INPUT( uart + LINE_STATUS_REGISTER );
-
- if ( line_status & LSR_OVERRUN_ERROR )
- ++numOverrunError;
-
- if ( line_status & LSR_PARITY_ERROR )
- ++numParityError;
-
- if ( line_status & LSR_FRAMING_ERROR )
- ++numFramingError;
-
- if ( line_status & LSR_BREAK_DETECT )
- ++numBreak;
-
- break;
-
- //
- // done
- //
- default :
- //I_ColorBlack (0,0,0);
- OUTPUT( 0x20, 0x20 );
- return;
- }
- }
- }
-
- //==========================================================================
- /*
- ==============
- =
- = isr_16550
- =
- ==============
- */
-
- void interrupt isr_16550(void)
- {
- int c;
- int count;
-
- while (1)
- {
- switch( INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
- {
- //
- // receive
- //
- case IIR_RX_DATA_READY_INTERRUPT :
- //I_ColorBlack (0,63,0);
- ++numRxInterrupts;
- do
- {
- c = INPUT( uart + RECEIVE_BUFFER_REGISTER );
- inque.data[inque.head++] = c;
- inque.size++;
- if (inque.head >= QUESIZE)
- inque.head = 0; // wrap around
- } while ( INPUT( uart + LINE_STATUS_REGISTER ) & LSR_DATA_READY );
-
- break;
-
- //
- // transmit
- //
- case IIR_TX_HOLDING_REGISTER_INTERRUPT :
- //I_ColorBlack (63,0,0);
- ++numTxInterrupts;
- if (outque.size != 0)
- {
- count = 16;
- do
- {
- c = outque.data[outque.tail++];
- outque.size--;
- if (outque.tail >= QUESIZE)
- outque.tail = 0; // wrap around
-
- OUTPUT( uart + TRANSMIT_HOLDING_REGISTER, c );
- } while (--count && outque.size != 0);
- }
- break;
-
- #if 0 // not enabled
- * case IIR_MODEM_STATUS_INTERRUPT :
- * modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
- * break;
- #endif
-
- //
- // line status
- //
- case IIR_LINE_STATUS_INTERRUPT :
- line_status = INPUT( uart + LINE_STATUS_REGISTER );
-
- if ( line_status & LSR_OVERRUN_ERROR )
- ++numOverrunError;
-
- if ( line_status & LSR_PARITY_ERROR )
- ++numParityError;
-
- if ( line_status & LSR_FRAMING_ERROR )
- ++numFramingError;
-
- if ( line_status & LSR_BREAK_DETECT )
- ++numBreak;
-
- break;
-
- //
- // done
- //
- default :
- //I_ColorBlack (0,0,0);
- OUTPUT( 0x20, 0x20 );
- return;
- }
- }
- }
-
- /*
- ===============
- =
- = jump_start
- =
- = Start up the transmition interrupts by sending the first char
- ===============
- */
-
- void jump_start( void )
- {
- int c;
-
- if (outque.size != 0)
- {
- c = outque.data [outque.tail++];
- outque.size--;
- if (outque.tail >= QUESIZE)
- outque.tail = 0; // wrap around
- OUTPUT( uart, c );
- }
- }
-
-
-