home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / APR94_1.ZIP / DIO.ASC < prev    next >
Text File  |  1994-02-27  |  7KB  |  217 lines

  1. _DIGITAL I/O WITH THE PC_
  2. by Brian Hook and Dennis Shuman
  3.  
  4. Listing One
  5.  
  6. //-----------------------------------------------------------------
  7. // PPDIO Parallel Port Digital IO routines
  8. // Version 1.0 Copyright 1993 by Brian Hook.  All Rights Reserved.
  9. // File: PPDIO.H -- header file for the PPDIO library
  10. // Compile with Borland C++ 3.1 -- porting to another compiler
  11. // should be extremely trivial.
  12. //-----------------------------------------------------------------
  13. #ifndef __PPDIO_H
  14. #define __PPDIO_H
  15.  
  16. //--- Pin definitions for control register ------------------------
  17. #define PIN_1        0x01
  18. #define PIN_14       0x02
  19. #define PIN_16       0x04
  20. #define PIN_17       0x08
  21.  
  22. //--- Pin definitions for status register -------------------------
  23. #define PIN_15       0x08
  24. #define PIN_13       0x10
  25. #define PIN_12       0x20
  26. #define PIN_10       0x40
  27. #define PIN_11       0x80
  28.  
  29. //--- Interrupt enable bit definition -----------------------------
  30. #define PTR_ENABLE_INT_BIT  0x10
  31.  
  32. //--- Function prototypes -----------------------------------------
  33. unsigned      PPDIO_GetLptAddress( int lpt_port );
  34. void          PPDIO_InstallISR( void interrupt (*fnc)(), int irq );
  35. unsigned char PPDIO_ReadControlRaw( void );
  36. unsigned char PPDIO_ReadStatusRaw( void );
  37. unsigned char PPDIO_ReadControlCooked( void );
  38. unsigned char PPDIO_ReadStatusRaw( void );
  39. void          PPDIO_RemoveISR( void );
  40. void          PPDIO_SendByte( unsigned char data );
  41. void          PPDIO_SetBaseAddress( unsigned base_address );
  42. void          PPDIO_SetLptPort( int lpt_port );
  43.  
  44. #endif
  45.  
  46.  
  47.  
  48. Listing Two 
  49.  
  50. //-----------------------------------------------------------------
  51. // PPDIO Parallel Port Digital IO routines
  52. // Version 1.0 Copyright 1993 by Brian Hook.  All Rights Reserved.
  53. // File:  PPDIO.C -- code and variables for the PPDIO library
  54. // Compile with Borland C++ 3.1 -- porting to another compiler
  55. // should be extremely trivial.
  56. //-----------------------------------------------------------------
  57. #include <dos.h>
  58. #include "ppdio.h"
  59.  
  60. static unsigned ppdio_data_register;
  61. static unsigned ppdio_control_register;
  62. static unsigned ppdio_status_register;
  63. static unsigned ppdio_interrupt_no;
  64. static unsigned ppdio_irq;
  65.  
  66. static unsigned char ppdio_old_control_value;
  67. static unsigned char ppdio_old_8259_mask;
  68. static void interrupt (*ppdio_old_intvec)();
  69.  
  70. unsigned PPDIO_GetLptAddress( int lpt_no )
  71. {
  72. unsigned far *pp = ( unsigned far * ) MK_FP( 0x40, 8 );
  73.    //--- Assumes values of 1, 2, or 3 -----------------------------
  74.    return ( pp[lpt_no-1] );
  75. }
  76. void PPDIO_InstallISR( void interrupt (*fnc)(), int irq_no )
  77. {
  78. static char mask[] = { 0xfa, 0xf7, 0xef, 0xdf, 0xaf, 0x7f };
  79. unsigned char temp;
  80.  
  81.    //--- Interrupt number = IRQ no + 8 ----------------------------
  82.    ppdio_interrupt_no = irq_no + 8;
  83.  
  84.    //--- Save original interrupt vector ---------------------------
  85.    ppdio_old_intvec = getvect( ppdio_interrupt_no );
  86.  
  87.    //--- Install new ISR ------------------------------------------
  88.    setvect( ppdio_interrupt_no, fnc );
  89.  
  90.    //--- Enable interrupts by setting the PTR_ENABLE_INT_BIT in
  91.    //--- the control register.  Also, OR it by 0x04 to send pin
  92.    //--- 16 high then write out a 0 to pins 1, 14, and 17 so
  93.    //--- that we can use the control register for input.
  94.    ppdio_old_control_value = inportb( ppdio_control_register );
  95.    temp = ppdio_old_control_value | PTR_ENABLE_INT_BIT | PIN_16;
  96.    temp &= ~ ( PIN_17 | PIN_14 | PIN_1 );
  97.    outportb( ppdio_control_register, temp );
  98.  
  99.    //--- Unmask our IRQ in the interrupt controller ---------------
  100.    ppdio_old_8259_mask = inportb( 0x21 );
  101.    temp = ppdio_old_8259_mask & mask[ppdio_interrupt_no-10];
  102.    outportb( 0x21, temp );
  103.  
  104.    //--- Clear pending interrupts ---------------------------------
  105.    outportb( 0x20, 0x20 );
  106. }
  107.  
  108. unsigned char PPDIO_ReadControlCooked( void )
  109. {
  110. unsigned char raw_control;
  111. unsigned char cooked_control = 0;
  112.    raw_control = PPDIO_ReadControlRaw();
  113.  
  114.    //--- Return a control register mask that compensates for the inverse logic
  115.    //--- of pins 1, 14, and 17, and with 0s where bits are reserved or unused.
  116.    if ( !( raw_control & PIN_1 ) )
  117.       cooked_control |= PIN_1;
  118.    if ( !( raw_control & PIN_14 ) )
  119.       cooked_control |= PIN_14;
  120.    if ( raw_control & PIN_16 )
  121.       cooked_control |= PIN_16;
  122.    if ( !( raw_control & PIN_17 ) )
  123.       cooked_control |= PIN_17;
  124.    return ( cooked_control );
  125. }
  126. unsigned char PPDIO_ReadControlRaw( void )
  127. {
  128.    return ( inportb( ppdio_control_register ) );
  129. }
  130. unsigned char PPDIO_ReadStatusCooked( void )
  131. {
  132. unsigned char raw_status;
  133. unsigned char cooked_status = 0;
  134.  
  135.    raw_status = PPDIO_ReadStatusRaw();
  136.    //--- Return a status register mask that compensates for the
  137.    //--- inverse logic of pin 11, and with 0s for any reserved or unused bits.
  138.    if ( raw_status & PIN_15 )
  139.       cooked_status |= PIN_15;
  140.    if ( raw_status & PIN_13 )
  141.       cooked_status |= PIN_13;
  142.    if ( raw_status & PIN_12 )
  143.       cooked_status |= PIN_12;
  144.    if ( !( raw_status & PIN_11 ) )
  145.       cooked_status |= PIN_11;
  146.    return ( cooked_status );
  147. }
  148. unsigned char PPDIO_ReadStatusRaw( void )
  149. {
  150.    return ( inportb( ppdio_status_register ) );
  151. }
  152. void PPDIO_RemoveISR( void )
  153. {
  154.    //--- Restore the interrupt controller's previous state --------
  155.    outportb( 0x21, ppdio_old_8259_mask );
  156.  
  157.    //--- Restore the original interrupt vector --------------------
  158.    setvect( ppdio_interrupt_no, ppdio_old_intvec );
  159.  
  160.    //--- Restore the printer control register ---------------------
  161.    outportb( ppdio_control_register, ppdio_old_control_value );
  162. }
  163. void PPDIO_SendByte( unsigned char data )
  164. {
  165.    outportb( ppdio_data_register, data );
  166. }
  167. void PPDIO_SetBaseAddress( unsigned base_address )
  168. {
  169.    ppdio_data_register    = base_address;
  170.    ppdio_status_register  = base_address + 1;
  171.    ppdio_control_register = base_address + 2;
  172. }
  173. void PPDIO_SetLptPort( int lpt_port )
  174. {
  175.    PPDIO_SetBaseAddress( PPDIO_GetLptAddress( lpt_port ) );
  176. }
  177.  
  178.  
  179. Listing Three
  180.  
  181. //-----------------------------------------------------------------
  182. // PPDIO Parallel Port Digital IO routines
  183. // Version 1.0 Copyright 1993 by Brian Hook.  All Rights Reserved.
  184. // File:  DIO.C -- this is an example how you could use the PPDIO
  185. // routines. This could be used as a framework upon which you 
  186. // could build real applications.
  187. // Compile with Borland C++ 3.1 -- porting to another compiler
  188. // should be extremely trivial.
  189. //-----------------------------------------------------------------
  190. #include <conio.h>
  191. #include "ppdio.h"
  192.  
  193. volatile int isr_called = 0;
  194. void huge interrupt MyISR( void )
  195. {
  196.    isr_called = 1;
  197.  
  198.    //--- Normally you would read the input pins here and do something important
  199.    //--- Signal end of interrupt to the interrupt controller ------
  200.    outportb( 0x20, 0x20 );
  201. }
  202. void main( void )
  203. {
  204.    //--- Use LPT1 -------------------------------------------------
  205.    PPDIO_SetLptPort( 1 );
  206.  
  207.    //--- Install our ISR on IRQ 5 ---------------------------------
  208.    PPDIO_InstallISR( MyISR, 5 );
  209.  
  210.    //--- Run until either a key is pressed or interrupt is generated on IRQ 5
  211.    while ( !kbhit() && !isr_called ) {
  212.    }
  213.    PPDIO_RemoveISR();
  214. }
  215.  
  216.  
  217.