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;
-
- int uart; // io address
- enum {UART_8250, UART_16550} uart_type;
- int irq;
-
- int modem_status = -1;
- int line_status = -1;
-
- void interrupt (*oldirqvect) (void);
- int irqintnum;
-
- int comport;
-
- extern unsigned char bauddivl, usehardhand;
- extern int useextirq;
- extern int useextport;
-
- int accessTX;
- int accessRX;
- int accessIIR;
- int accessLCR;
- int accessMCR;
- int accessLSR;
- int accessMSR;
-
- long intRX;
- long intTX;
-
- /*
- ==============
- =
- = 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};
- int p;
-
- if (CheckParm ("-com2"))
- comport = 2;
- else if (CheckParm ("-com3"))
- comport = 3;
- else if (CheckParm ("-com4"))
- comport = 4;
- else
- comport = 1;
-
- regs.h.ah = 0xc0;
- int86x( 0x15, ®s, ®s, &sregs );
- if ( regs.x.cflag )
- {
- irq = ISA_IRQs[ comport-1 ];
- uart = ISA_uarts[ comport-1 ];
- return;
- }
- system_data = ( char far *) ( ( (long) sregs.es << 16 ) + regs.x.bx );
- if ( system_data[ 5 ] & 0x02 )
- {
- irq = MCA_IRQs[ comport-1 ];
- uart = MCA_uarts[ comport-1 ];
- }
- else
- {
- irq = ISA_IRQs[ comport-1 ];
- uart = ISA_uarts[ comport-1 ];
- }
-
- p = CheckParm ("-port");
- if (p)
- scanf (_argv[p+1],"0x%x",&uart);
- p = CheckParm ("-irq");
- if (p)
- scanf (_argv[p+1],"%i",&irq);
- if (useextirq)
- irq=useextirq;
- if (useextport)
- uart=useextport;
-
- printf ("Looking for UART at port 0x%x, irq %i\n",uart,irq);
- }
-
-
-
-
- /*
- ===============
- =
- = InitPort
- =
- ===============
- */
-
- void InitPort (void)
- {
- int mcr;
- int temp;
-
- //
- // find the irq and io address of the port
- //
- GetUart ();
-
- accessTX=uart+TRANSMIT_HOLDING_REGISTER;
- accessRX=uart+RECEIVE_BUFFER_REGISTER;
- accessIIR=uart+INTERRUPT_ID_REGISTER;
- accessLCR=uart+LINE_CONTROL_REGISTER;
- accessMCR=uart+MODEM_CONTROL_REGISTER;
- accessLSR=uart+LINE_STATUS_REGISTER;
- accessMSR=uart+MODEM_STATUS_REGISTER;
-
-
- //
- // init com port settings
- //
- regs.x.ax = 0xf3; //f3= 9600 n 8 1
- regs.x.dx = comport - 1;
- int86 (0x14, ®s, ®s);
-
- // Tony's add ons.
- // We should be setting the baud rate to 38400 and raising DTR
- // set speed to 38400
- OUTPUT(uart + LINE_CONTROL_REGISTER,
- INPUT(uart + LINE_CONTROL_REGISTER)|LCR_DLAB);
- OUTPUT(uart + DIVISOR_LATCH_LOW,bauddivl);
- OUTPUT(uart + DIVISOR_LATCH_HIGH,0x00);
- OUTPUT(uart + LINE_CONTROL_REGISTER,
- INPUT(uart + LINE_CONTROL_REGISTER)&~LCR_DLAB);
- OUTPUT(uart + LINE_CONTROL_REGISTER,0x03); //set 8N1
- // set DTR & RTS
- OUTPUT(uart + MODEM_CONTROL_REGISTER,
- INPUT(uart + MODEM_CONTROL_REGISTER) | MCR_DTR | MCR_RTS);
-
-
- //
- // check for a 16550
- //
- OUTPUT( uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE + FCR_TRIGGER_14 );
- 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
- //
- outque.head=0;
- outque.tail=0;
- inque.head=0;
- inque.tail=0;
- intTX=0;
- intRX=0;
-
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
- mcr = INPUT( uart + MODEM_CONTROL_REGISTER );
- mcr |= MCR_OUT2;
- mcr &= ~MCR_LOOPBACK;
- OUTPUT( uart + MODEM_CONTROL_REGISTER, mcr );
-
- INPUT( uart ); // Clear any pending interrupts
- INPUT( uart + INTERRUPT_ID_REGISTER );
-
- //
- // hook the irq vector
- //
- irqintnum = irq + 8;
-
- oldirqvect = getvect (irqintnum);
- if (uart_type == UART_16550)
- setvect (irqintnum,isr_16550);
- else
- setvect (irqintnum,isr_8250);
-
- OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) & ~(1<<irq) );
-
- CLI();
-
- // enable RX and TX interrupts at the uart
-
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER,
- IER_RX_DATA_READY + IER_TX_HOLDING_REGISTER_EMPTY);
-
- // enable interrupts through the interrupt controller
-
- OUTPUT( 0x20, 0xc2 );
-
- // set DTR
- OUTPUT( uart + MODEM_CONTROL_REGISTER
- , INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR);
-
-
- STI();
-
-
- }
-
-
- /*
- =============
- =
- = ShutdownPort
- =
- =============
- */
-
- void ShutdownPort ( void )
- {
- OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
- OUTPUT( uart + MODEM_CONTROL_REGISTER, 0 );
-
- OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) | (1<<irq) );
- OUTPUT( uart + FIFO_CONTROL_REGISTER, 0 );
-
- setvect (irqintnum,oldirqvect);
-
- //
- // init com port settings to defaults
- //
- regs.x.ax = 0xf3; //f3= 9600 n 8 1
- regs.x.dx = comport - 1;
- int86 (0x14, ®s, ®s);
- }
-
-
- int read_byte( void )
- {
- int c;
-
- // Tony's code again, raise RTS if buffer half empty
- if ((inque.head-inque.tail)<(QUESIZE/2))
- OUTPUT( accessMCR,INPUT(accessMCR) | MCR_RTS);
-
- if (inque.tail >= inque.head)
- return -1;
- c = inque.data[inque.tail&(QUESIZE-1)];
- inque.tail++;
- return c;
- }
-
-
- void write_byte( int c )
- {
- outque.data[outque.head&(QUESIZE-1)] = c;
- outque.head++;
- }
-
-
-
- //==========================================================================
-
-
- /*
- ==============
- =
- = isr_16550
- =
- ==============
- */
-
- void interrupt isr_16550(void)
- {
- int count;
-
- while (1)
- {
- switch( INPUT( accessIIR ) & 7 )
- {
- //
- // receive
- //
- case IIR_RX_DATA_READY_INTERRUPT :
- //I_ColorBlack (0,63,0);
- intRX++;
- do
- {
- inque.data[(inque.head++)&(QUESIZE-1)] = INPUT(accessRX);
- }
- while (INPUT(accessLSR) & LSR_DATA_READY );
- if (((outque.head-outque.tail)>(QUESIZE-1000))&&usehardhand)
- OUTPUT(accessMCR,INPUT(accessMCR) & ~MCR_RTS);
-
- break;
-
- //
- // transmit
- //
- case IIR_TX_HOLDING_REGISTER_INTERRUPT :
- //I_ColorBlack (63,0,0);
- if ((outque.tail < outque.head)&&
- ((INPUT(accessMSR)&MSR_CTS)||!usehardhand))
- {
- intTX++;
- count = 16;
- do
- {
- OUTPUT( accessTX, outque.data[(outque.tail++)&(QUESIZE-1)]);
- } while (--count && outque.tail < outque.head);
- }
- break;
-
- // not enabled
- case IIR_MODEM_STATUS_INTERRUPT :
- modem_status = INPUT(accessMSR);
- break;
-
- // not enabled
- case IIR_LINE_STATUS_INTERRUPT :
- line_status = INPUT( accessLSR );
- break;
-
- //
- // done
- //
- default :
- OUTPUT( 0x20, 0x20 );
- return;
- }
- }
- }
-
- void interrupt isr_8250(void)
- {
-
- while (1)
- {
- switch( INPUT(accessIIR) & 7 )
- {
- //
- // receive
- //
- case IIR_RX_DATA_READY_INTERRUPT :
-
- intRX++;
- inque.data[inque.head++&(QUESIZE-1)] = INPUT(accessRX);
-
- if (((outque.head-outque.tail)>(QUESIZE-1000))&&usehardhand)
- OUTPUT(accessMCR,INPUT(accessMCR) & ~MCR_RTS);
-
- break;
-
- //
- // transmit
- //
- case IIR_TX_HOLDING_REGISTER_INTERRUPT :
- if ((outque.tail < outque.head)&&
- ((INPUT(accessMSR)&MSR_CTS)||!usehardhand))
- {
- intTX++;
- OUTPUT( accessTX, outque.data[(outque.tail++)&(QUESIZE-1)]);
- }
- break;
-
- // not enabled
- case IIR_MODEM_STATUS_INTERRUPT :
- modem_status = INPUT( accessMSR );
- break;
-
- // not enabled
- case IIR_LINE_STATUS_INTERRUPT :
- line_status = INPUT( accessLSR );
- break;
-
- //
- // done
- //
- default :
- OUTPUT( 0x20, 0x20 );
- return;
- }
- }
- }
-
-
- /*
- ===============
- =
- = jump_start
- =
- = Start up the transmition interrupts by sending the first char
- ===============
- */
-
- void jump_start( void )
- {
- int c;
-
- if (outque.tail < outque.head)
- {
- c = outque.data [outque.tail&(QUESIZE-1)];
- outque.tail++;
- OUTPUT( uart, c );
- }
- }
-
-
-