home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_06_04 / v6n4070a.txt < prev    next >
Text File  |  1989-09-28  |  5KB  |  88 lines

  1. /* ibmint.dlc */        /***********************************************/
  2. #define BASAD 0x3f8     /* Ibm 1st serial port base address.           */
  3. #define INTNUM 0x0c     /* Ibm serial interrupt number, irq4.          */
  4. #define IBUFSIZ 8192    /* Ring buffer size for serial input.          */
  5. #define MASKIRQ 0xef    /* Irq4  mask pattern.                         */
  6. #define LOBAUD  128     /* For  300 baud, high byte,                   */
  7. #define HIBAUD 1        /*                low byte.                    */
  8. #define COMBITS 3       /* 8 data, 1 stop, no parity.                  */
  9.  
  10. static volatile int intptr1,intptr2  ;  /* Ring buffer pointers.       */
  11. static int enabled = 0 ;                /* Enable-disable flag.        */
  12. static int intmask ;                    /* Old 8259 interrupt mask.    */
  13. static char intbuf[IBUFSIZ] ;           /* Ring buffer.                */
  14. int comerror ;                          /* Error flags.                */
  15.  
  16. static int status() /******* Read 8250 line status, and update *********/
  17. { int byte ;                        /* comerror for framing, parity,   */
  18.   byte = inp(BASAD+5) ;             /* and overrun errors.             */
  19.   comerror |= ( (byte >> 1) & 7 ) ; /* Status bits only need shifting. */
  20.   return(byte) ;
  21. }
  22.  
  23. void cleanup()  /*** Disable communications, and restore vectors. ******/
  24. { if(! enabled ) return ;  /* Do nothing if not enabled.               */
  25.   int_restore(0x23) ;      /* Restore old ctrl-C vector.               */
  26.   outp(BASAD+1,0) ;        /* Disable 8250 interrupts.                 */
  27.   int_off() ;              /* Disable all interrupts.                  */
  28.   outp(0x21,intmask) ;     /* Restore old 8259 interrupt mask.         */
  29.   outp(0x20,0xc7) ;        /* Rotate to standard priorities.           */
  30.   int_on() ;               /* Enable interrupts.                       */
  31.   int_restore(INTNUM) ;    /* Restore old irq  interrupt vector.       */
  32.   enabled = 0 ;            /* Communications now disabled.             */
  33. }
  34.  
  35. static int control_C() { cleanup() ; return(0) ; }
  36.  
  37. static int rxint()   /***** Capture serial byte via interrupt.   *******/
  38. { int temp ;                                                         /**/
  39.   if( status() & 1 )                 /* Check for rx interrupt.        */
  40.     { intbuf[intptr1] = inp(BASAD) ;          /* Read to buffer.       */
  41.       temp = (intptr1 + 1) % IBUFSIZ ;        /* Add 1 to head ptr.    */
  42.       if( temp == intptr2 ) comerror |= 8 ;   /* Does head bite tail?  */
  43.       intptr1 = temp  ;                       /* Move head ptr.        */
  44.       outp(0x20,0x20) ;             /* Issue the 8259 EOI command.     */
  45.       return(1) ;                   /* Return directly.                */
  46.     }                                                                /**/
  47.   return(0) ;                       /* Chain to other service routines.*/
  48. }
  49.  
  50. void setcom()    /************** Enable communications. ****************/
  51. { if( enabled ) return ;            /* Do nothing if enabled already.  */
  52.   outp(BASAD+1,0) ;                 /* Disable 8250 interrupts.        */
  53.   outp(BASAD+3,128) ;               /* Access baud rate registers.     */
  54.   outp(BASAD,LOBAUD) ;              /* Set baud rate, high byte,       */
  55.   outp(BASAD+1,HIBAUD) ;            /*              low byte.          */
  56.   outp(BASAD+3,COMBITS) ;           /* Data, stop, parity.             */
  57.   outp(BASAD+4,0x0b) ;              /* Set DTR, RTS, OUT2.             */
  58.   int_intercept(0x23,&control_C,200) ; /* Reroute control-C.           */
  59.   int_intercept(INTNUM,&rxint,200)   ; /* Reroute irq.                 */
  60.   intptr1 = intptr2 = 0 ;           /* Initialize buffer pointers.     */
  61.   intmask = inp(0x21) ;             /* Save old 8259 int mask.         */
  62.   int_off() ;                       /* Disable all interrupts.         */
  63.   outp(0x21,MASKIRQ & intmask) ;    /* Unmask irq.                     */
  64.   outp(0x20,0xc3) ;       /* Rotate priorities to put irq4 on top.     */
  65.   int_on() ;                        /* Enable interrupts.              */
  66.   outp(BASAD+1,1) ;                 /* Enable 8250 rx interrupt.       */
  67.   comerror = 0 ;                    /* Initialize error flag.          */
  68.   enabled = 1 ;                     /* Communications enabled.         */
  69. }
  70.  
  71. int rxready() { return( intptr1 != intptr2 ) ; } /* Rx byte available? */
  72.  
  73. int rxbyte()                      /*******   Get rx byte.      *********/
  74. { int b ;                                                            /**/
  75.   b = intbuf[intptr2] ;             /*     Get byte at tail.           */
  76.   intptr2 = ++intptr2 % IBUFSIZ ;   /*     Bump tail pointer.          */
  77.   return(b) ;                       /*     Return byte from buffer.    */
  78. }
  79.  
  80. int txready() { return( status() & 32 ) ; }      /* Tx register empty? */
  81.  
  82. void txbyte(b) int b ;  { outp(BASAD,b) ; }      /* Send tx byte.      */
  83.  
  84. int kbhit() { return( bdos( 0x0b,0 ) ) ; }       /* Kb byte available? */
  85.  
  86. void putch(b) int b ; { bdos(0x02,b) ; }         /* Byte to screen.    */
  87.  
  88.