home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_1.ZIP
/
DIO.ASC
< prev
next >
Wrap
Text File
|
1994-02-27
|
7KB
|
217 lines
_DIGITAL I/O WITH THE PC_
by Brian Hook and Dennis Shuman
Listing One
//-----------------------------------------------------------------
// PPDIO Parallel Port Digital IO routines
// Version 1.0 Copyright 1993 by Brian Hook. All Rights Reserved.
// File: PPDIO.H -- header file for the PPDIO library
// Compile with Borland C++ 3.1 -- porting to another compiler
// should be extremely trivial.
//-----------------------------------------------------------------
#ifndef __PPDIO_H
#define __PPDIO_H
//--- Pin definitions for control register ------------------------
#define PIN_1 0x01
#define PIN_14 0x02
#define PIN_16 0x04
#define PIN_17 0x08
//--- Pin definitions for status register -------------------------
#define PIN_15 0x08
#define PIN_13 0x10
#define PIN_12 0x20
#define PIN_10 0x40
#define PIN_11 0x80
//--- Interrupt enable bit definition -----------------------------
#define PTR_ENABLE_INT_BIT 0x10
//--- Function prototypes -----------------------------------------
unsigned PPDIO_GetLptAddress( int lpt_port );
void PPDIO_InstallISR( void interrupt (*fnc)(), int irq );
unsigned char PPDIO_ReadControlRaw( void );
unsigned char PPDIO_ReadStatusRaw( void );
unsigned char PPDIO_ReadControlCooked( void );
unsigned char PPDIO_ReadStatusRaw( void );
void PPDIO_RemoveISR( void );
void PPDIO_SendByte( unsigned char data );
void PPDIO_SetBaseAddress( unsigned base_address );
void PPDIO_SetLptPort( int lpt_port );
#endif
Listing Two
//-----------------------------------------------------------------
// PPDIO Parallel Port Digital IO routines
// Version 1.0 Copyright 1993 by Brian Hook. All Rights Reserved.
// File: PPDIO.C -- code and variables for the PPDIO library
// Compile with Borland C++ 3.1 -- porting to another compiler
// should be extremely trivial.
//-----------------------------------------------------------------
#include <dos.h>
#include "ppdio.h"
static unsigned ppdio_data_register;
static unsigned ppdio_control_register;
static unsigned ppdio_status_register;
static unsigned ppdio_interrupt_no;
static unsigned ppdio_irq;
static unsigned char ppdio_old_control_value;
static unsigned char ppdio_old_8259_mask;
static void interrupt (*ppdio_old_intvec)();
unsigned PPDIO_GetLptAddress( int lpt_no )
{
unsigned far *pp = ( unsigned far * ) MK_FP( 0x40, 8 );
//--- Assumes values of 1, 2, or 3 -----------------------------
return ( pp[lpt_no-1] );
}
void PPDIO_InstallISR( void interrupt (*fnc)(), int irq_no )
{
static char mask[] = { 0xfa, 0xf7, 0xef, 0xdf, 0xaf, 0x7f };
unsigned char temp;
//--- Interrupt number = IRQ no + 8 ----------------------------
ppdio_interrupt_no = irq_no + 8;
//--- Save original interrupt vector ---------------------------
ppdio_old_intvec = getvect( ppdio_interrupt_no );
//--- Install new ISR ------------------------------------------
setvect( ppdio_interrupt_no, fnc );
//--- Enable interrupts by setting the PTR_ENABLE_INT_BIT in
//--- the control register. Also, OR it by 0x04 to send pin
//--- 16 high then write out a 0 to pins 1, 14, and 17 so
//--- that we can use the control register for input.
ppdio_old_control_value = inportb( ppdio_control_register );
temp = ppdio_old_control_value | PTR_ENABLE_INT_BIT | PIN_16;
temp &= ~ ( PIN_17 | PIN_14 | PIN_1 );
outportb( ppdio_control_register, temp );
//--- Unmask our IRQ in the interrupt controller ---------------
ppdio_old_8259_mask = inportb( 0x21 );
temp = ppdio_old_8259_mask & mask[ppdio_interrupt_no-10];
outportb( 0x21, temp );
//--- Clear pending interrupts ---------------------------------
outportb( 0x20, 0x20 );
}
unsigned char PPDIO_ReadControlCooked( void )
{
unsigned char raw_control;
unsigned char cooked_control = 0;
raw_control = PPDIO_ReadControlRaw();
//--- Return a control register mask that compensates for the inverse logic
//--- of pins 1, 14, and 17, and with 0s where bits are reserved or unused.
if ( !( raw_control & PIN_1 ) )
cooked_control |= PIN_1;
if ( !( raw_control & PIN_14 ) )
cooked_control |= PIN_14;
if ( raw_control & PIN_16 )
cooked_control |= PIN_16;
if ( !( raw_control & PIN_17 ) )
cooked_control |= PIN_17;
return ( cooked_control );
}
unsigned char PPDIO_ReadControlRaw( void )
{
return ( inportb( ppdio_control_register ) );
}
unsigned char PPDIO_ReadStatusCooked( void )
{
unsigned char raw_status;
unsigned char cooked_status = 0;
raw_status = PPDIO_ReadStatusRaw();
//--- Return a status register mask that compensates for the
//--- inverse logic of pin 11, and with 0s for any reserved or unused bits.
if ( raw_status & PIN_15 )
cooked_status |= PIN_15;
if ( raw_status & PIN_13 )
cooked_status |= PIN_13;
if ( raw_status & PIN_12 )
cooked_status |= PIN_12;
if ( !( raw_status & PIN_11 ) )
cooked_status |= PIN_11;
return ( cooked_status );
}
unsigned char PPDIO_ReadStatusRaw( void )
{
return ( inportb( ppdio_status_register ) );
}
void PPDIO_RemoveISR( void )
{
//--- Restore the interrupt controller's previous state --------
outportb( 0x21, ppdio_old_8259_mask );
//--- Restore the original interrupt vector --------------------
setvect( ppdio_interrupt_no, ppdio_old_intvec );
//--- Restore the printer control register ---------------------
outportb( ppdio_control_register, ppdio_old_control_value );
}
void PPDIO_SendByte( unsigned char data )
{
outportb( ppdio_data_register, data );
}
void PPDIO_SetBaseAddress( unsigned base_address )
{
ppdio_data_register = base_address;
ppdio_status_register = base_address + 1;
ppdio_control_register = base_address + 2;
}
void PPDIO_SetLptPort( int lpt_port )
{
PPDIO_SetBaseAddress( PPDIO_GetLptAddress( lpt_port ) );
}
Listing Three
//-----------------------------------------------------------------
// PPDIO Parallel Port Digital IO routines
// Version 1.0 Copyright 1993 by Brian Hook. All Rights Reserved.
// File: DIO.C -- this is an example how you could use the PPDIO
// routines. This could be used as a framework upon which you
// could build real applications.
// Compile with Borland C++ 3.1 -- porting to another compiler
// should be extremely trivial.
//-----------------------------------------------------------------
#include <conio.h>
#include "ppdio.h"
volatile int isr_called = 0;
void huge interrupt MyISR( void )
{
isr_called = 1;
//--- Normally you would read the input pins here and do something important
//--- Signal end of interrupt to the interrupt controller ------
outportb( 0x20, 0x20 );
}
void main( void )
{
//--- Use LPT1 -------------------------------------------------
PPDIO_SetLptPort( 1 );
//--- Install our ISR on IRQ 5 ---------------------------------
PPDIO_InstallISR( MyISR, 5 );
//--- Run until either a key is pressed or interrupt is generated on IRQ 5
while ( !kbhit() && !isr_called ) {
}
PPDIO_RemoveISR();
}