home *** CD-ROM | disk | FTP | other *** search
/ Doom I/II Collection / DM12.ISO / serial / dmsrcc / port.c < prev    next >
C/C++ Source or Header  |  1994-02-13  |  5KB  |  320 lines

  1. // port.c
  2.  
  3. #include "doomnet.h"
  4. #include "sersetup.h"
  5.  
  6. void jump_start( void );
  7.  
  8. void interrupt isr_8250 (void);
  9.  
  10. union    REGS    regs;
  11. struct    SREGS    sregs;
  12.  
  13. que_t        inque, outque;
  14.  
  15.  
  16. int            uart;            // io address
  17. enum {UART_8250, UART_16550} uart_type;
  18. int            irq;
  19.  
  20. int            modem_status = -1;
  21. int            line_status = -1;
  22.  
  23. void interrupt (*oldirqvect) (void);
  24. int            irqintnum;
  25.  
  26. int               comport;
  27.  
  28.  
  29. /*
  30. ==============
  31. =
  32. = GetUart
  33. =
  34. ==============
  35. */
  36.  
  37. void GetUart (void)
  38. {
  39.     char   far *system_data;
  40.     static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8};
  41.     static int ISA_IRQs[] = {4,3,4,3};
  42.     static int MCA_uarts[] = {0x03f8,0x02f8,0x3220,0x3228};
  43.     static int MCA_IRQs[] = {4,3,3,3};
  44.     int        p;
  45.  
  46.     if (CheckParm ("-com2"))
  47.         comport = 2;
  48.     else if (CheckParm ("-com3"))
  49.         comport = 3;
  50.     else if (CheckParm ("-com4"))
  51.         comport = 4;
  52.     else
  53.         comport = 1;
  54.  
  55.     regs.h.ah = 0xc0;
  56.     int86x( 0x15, ®s, ®s, &sregs );
  57.     if ( regs.x.cflag )
  58.     {
  59.         irq = ISA_IRQs[ comport-1 ];
  60.         uart = ISA_uarts[ comport-1 ];
  61.         return;
  62.     }
  63.     system_data = ( char far *) ( ( (long) sregs.es << 16 ) + regs.x.bx );
  64.     if ( system_data[ 5 ] & 0x02 )
  65.     {
  66.         irq = MCA_IRQs[ comport-1 ];
  67.         uart = MCA_uarts[ comport-1 ];
  68.     }
  69.     else
  70.     {
  71.         irq = ISA_IRQs[ comport-1 ];
  72.         uart = ISA_uarts[ comport-1 ];
  73.     }
  74.  
  75.     p = CheckParm ("-port");
  76.     if (p)
  77.         scanf (_argv[p+1],"0x%x",&uart);
  78.     p = CheckParm ("-irq");
  79.     if (p)
  80.         scanf (_argv[p+1],"%i",&irq);
  81.  
  82.  
  83.     printf ("Looking for UART at port 0x%x, irq %i\n",uart,irq);
  84. }
  85.  
  86.  
  87.  
  88.  
  89. /*
  90. ===============
  91. =
  92. = InitPort
  93. =
  94. ===============
  95. */
  96.  
  97. void InitPort (void)
  98. {
  99.     int mcr;
  100.     int    temp;
  101.  
  102. //
  103. // find the irq and io address of the port
  104. //
  105.     GetUart ();
  106.  
  107. //
  108. // init com port settings
  109. //
  110.     regs.x.ax = 0xf3;        //f3= 9600 n 8 1
  111.     regs.x.dx = comport - 1;
  112.     int86 (0x14, ®s, ®s);
  113.  
  114.  
  115. //
  116. // check for a 16550
  117. //
  118.     OUTPUT( uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE + FCR_TRIGGER_04 );
  119.     temp = INPUT( uart + INTERRUPT_ID_REGISTER );
  120.     if ( ( temp & 0xf8 ) == 0xc0 )
  121.     {
  122.         uart_type = UART_16550;
  123.         printf ("UART is a 16550\n\n");
  124.     }
  125.     else
  126.     {
  127.         uart_type = UART_8250;
  128.         OUTPUT( uart + FIFO_CONTROL_REGISTER, 0 );
  129.         printf ("UART is an 8250\n\n");
  130.     }
  131.  
  132. //
  133. // prepare for interrupts
  134. //
  135.     OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
  136.     mcr = INPUT( uart + MODEM_CONTROL_REGISTER );
  137.     mcr |= MCR_OUT2;
  138.     mcr &= ~MCR_LOOPBACK;
  139.     OUTPUT( uart + MODEM_CONTROL_REGISTER, mcr );
  140.  
  141.     INPUT( uart );  // Clear any pending interrupts
  142.     INPUT( uart + INTERRUPT_ID_REGISTER );
  143.  
  144. //
  145. // hook the irq vector
  146. //
  147.     irqintnum = irq + 8;
  148.  
  149.     oldirqvect = getvect (irqintnum);
  150.     setvect (irqintnum,isr_8250);
  151.  
  152.     OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) & ~(1<<irq) );
  153.  
  154.     CLI();
  155.  
  156. // enable RX and TX interrupts at the uart
  157.  
  158.     OUTPUT( uart + INTERRUPT_ENABLE_REGISTER,
  159.             IER_RX_DATA_READY + IER_TX_HOLDING_REGISTER_EMPTY);
  160.  
  161. // enable interrupts through the interrupt controller
  162.  
  163.     OUTPUT( 0x20, 0xc2 );
  164.  
  165. // set DTR
  166.     OUTPUT( uart + MODEM_CONTROL_REGISTER
  167.         , INPUT( uart + MODEM_CONTROL_REGISTER ) | MCR_DTR);
  168.  
  169.  
  170.     STI();
  171.  
  172.  
  173. }
  174.  
  175.  
  176. /*
  177. =============
  178. =
  179. = ShutdownPort
  180. =
  181. =============
  182. */
  183.  
  184. void ShutdownPort ( void )
  185. {
  186.     OUTPUT( uart + INTERRUPT_ENABLE_REGISTER, 0 );
  187.     OUTPUT( uart + MODEM_CONTROL_REGISTER, 0 );
  188.  
  189.     OUTPUT( 0x20 + 1, INPUT( 0x20 + 1 ) | (1<<irq) );
  190.  
  191.     setvect (irqintnum,oldirqvect);
  192.  
  193. //
  194. // init com port settings to defaults
  195. //
  196.     regs.x.ax = 0xf3;        //f3= 9600 n 8 1
  197.     regs.x.dx = comport - 1;
  198.     int86 (0x14, ®s, ®s);
  199. }
  200.  
  201.  
  202. int read_byte( void )
  203. {
  204.     int    c;
  205.  
  206.     if (inque.tail >= inque.head)
  207.         return -1;
  208.     c = inque.data[inque.tail%QUESIZE];
  209.     inque.tail++;
  210.     return c;
  211. }
  212.  
  213.  
  214. void write_byte( int c )
  215. {
  216.     outque.data[outque.head%QUESIZE] = c;
  217.     outque.head++;
  218. }
  219.  
  220.  
  221.  
  222. //==========================================================================
  223.  
  224.  
  225. /*
  226. ==============
  227. =
  228. = isr_8250
  229. =
  230. ==============
  231. */
  232.  
  233. void interrupt isr_8250(void)
  234. {
  235.     int c;
  236.     int    count;
  237.  
  238.     while (1)
  239.     {
  240.         switch( INPUT( uart + INTERRUPT_ID_REGISTER ) & 7 )
  241.         {
  242. // not enabled
  243.         case IIR_MODEM_STATUS_INTERRUPT :
  244.             modem_status = INPUT( uart + MODEM_STATUS_REGISTER );
  245.             break;
  246.  
  247. // not enabled
  248.         case IIR_LINE_STATUS_INTERRUPT :
  249.             line_status = INPUT( uart + LINE_STATUS_REGISTER );
  250.             break;
  251.  
  252. //
  253. // transmit
  254. //
  255.         case IIR_TX_HOLDING_REGISTER_INTERRUPT :
  256. //I_ColorBlack (63,0,0);
  257.             if (outque.tail < outque.head)
  258.             {
  259.                 if (uart_type == UART_16550)
  260.                     count = 16;
  261.                 else
  262.                     count = 1;
  263.                 do
  264.                 {
  265.                     c = outque.data[outque.tail%QUESIZE];
  266.                     outque.tail++;
  267.                     OUTPUT( uart + TRANSMIT_HOLDING_REGISTER, c );
  268.                 } while (--count && outque.tail < outque.head);
  269.             }
  270.             break;
  271.  
  272. //
  273. // receive
  274. //
  275.         case IIR_RX_DATA_READY_INTERRUPT :
  276. //I_ColorBlack (0,63,0);
  277.             do
  278.             {
  279.                 c = INPUT( uart + RECEIVE_BUFFER_REGISTER );
  280.                 inque.data[inque.head%QUESIZE] = c;
  281.                 inque.head++;
  282.             } while ( uart_type == UART_16550 && INPUT( uart + LINE_STATUS_REGISTER ) & LSR_DATA_READY );
  283.  
  284.             break;
  285.  
  286. //
  287. // done
  288. //
  289.         default :
  290. //I_ColorBlack (0,0,0);
  291.             OUTPUT( 0x20, 0x20 );
  292.             return;
  293.         }
  294.     }
  295. }
  296.  
  297.  
  298. /*
  299. ===============
  300. =
  301. = jump_start
  302. =
  303. = Start up the transmition interrupts by sending the first char
  304. ===============
  305. */
  306.  
  307. void jump_start( void )
  308. {
  309.     int c;
  310.  
  311.     if (outque.tail < outque.head)
  312.     {
  313.         c = outque.data [outque.tail%QUESIZE];
  314.         outque.tail++;
  315.         OUTPUT( uart, c );
  316.     }
  317. }
  318.  
  319.  
  320.