Skip to content. | Skip to navigation

Personal tools

lcu/82c55.c

lcu/82c55.c

lcu/82c55.c

/////////////////////////////////////////////////////////////////////////
//  82C55.CPP
//
//  Last updated: 1/16/2005
//
//  Programs for handling the SBC1190 digital I/O
//  using the onboard 82C55 Parallel I/O Interface.
//
/////////////////////////////////////////////////////////////////////////

#include <conio.h>

#define DIOBASE 0xFE40
#define PORTA   DIOBASE+0
#define PORTB   DIOBASE+1
#define PORTC   DIOBASE+2
#define CTRL55  DIOBASE+3

/* The CTRL55 port determines the directions of Port A, B, and C in
   mode 0.  The simple digital I/O makes mode 0 the most commonly used mode.
   The following table shows effect of various control byte outputs to CTRL55.

   Port A   Port B   Port C   Port C     Control Byte
                     7-4      3-0        (CTRL55)

   Out      Out      Out      Out        0x80
   Out      Out      Out      In         0x81
   Out      Out      In       Out        0x88
   Out      Out      In       In         0x89
   Out      In       Out      Out        0x82
   Out      In       Out      In         0x83
   Out      In       In       Out        0x8A
   Out      In       In       In         0x8B
   In       Out      Out      Out        0x90
   In       Out      Out      In         0x91
   In       Out      In       Out        0x98
   In       Out      In       In         0x99
   In       In       Out      Out        0x92
   In       In       Out      In         0x93
   In       In       In       Out        0x9A
   In       In       In       In         0x9B
*/

// This global array holds the image values of the last write to each I/O
// ports. This allows bit manipulation routines to work without having to
// actually do a read-modify-write to the I/O port.
unsigned port_images[3];


///////////////////////////////////////////////////////////////////
// This function initializes all I/O pins for input or output
// It uses CTRL55 as the base I/O address of the 82C55 I/O Chip on the board.
void Init_IO(unsigned control_byte,unsigned PAInit,unsigned PCInit)
// control_byte: configures the three ports as inputs or output according
// to the table above.
// control_byte will usually be 0x82 =>
// Port A & Port C outputs, PortB inputs
// PAInit and PCInit are the initial values (set/clear)
// you want to output to the 8 lines in Port A and Port C

{
  int i;

  // initialize 82C55
  outp(CTRL55,control_byte);

  // Clear all of the I/O ports.
  // It is assumed that control_byte = 0x82, so we just
  // init PortA and PortC
  outp(PORTA,PAInit);
  //outp(PortB,PCInit);
  outp(PORTC,PCInit);

  // Init our image values as well
  port_images[0] = PAInit;
  port_images[1] = 0;
  port_images[2] = PCInit;
}

///////////////////////////////////////////////////////////////////
// This function returns the state of the current I/O pin specified by
// the argument bit_number.
int read_bit(int bit_number)
//  bit_number: The integer argument specifies the bit number to read.
//              Valid arguments are from 0 to 23.
//  Returns the current state of the specified bit, 1 or 0.
{
  unsigned port;
  int val;

  // Calculate the I/O port address based on the updated bit_number
  port = (bit_number / 8) + DIOBASE;
  // Get the current contents of the port
  val = inp(port);
  // Get just the bit we specified
  val = val & (1 << (bit_number % 8));
  // Adjust the return for a 0 or 1 value
  if(val)
    return 1;
  return 0;

  //data = (inp(PORTC)& 0xFF)>>4; /* read data from Port C high nibble */
  //printf("Port C reads %X\n", data);
}

///////////////////////////////////////////////////////////////////
// This function sets the specified I/O pin to either high or low as dictated
// by the val argument. A non zero value for val sets the bit.
// This routine considers port's C 8 bits to be just outputs or inputs
void write_bit(int bit_number, int val)
// bit_number: The I/O pin to access is specified by bit_number 0 to 23.
// val: The setting for the specified bit, either 1 or 0.
{
  unsigned port;
  unsigned temp;
  unsigned mask;

  // Calculate the I/O address of the port based on the bit number
  port = (bit_number / 8) + DIOBASE;
  // Use the image value to avoid having to read the port first.
  temp = port_images[bit_number / 8];   /* Get current value */
  // Calculate a bit mask for the specified bit
  mask = (1 << (bit_number % 8));
  /* Check whether the request was to set or clear and mask accordingly */
  if(val)               /* If the bit is to be set */
    temp = temp | mask;
  else
    temp = temp & ~mask;
  /* Update the image value with the value we're about to write */
  port_images[bit_number / 8] = temp;
  /* Now actually update the port. Only the specified bit is affected */
  outp(port,temp);
}

Generated by GNU Enscript 1.6.5.2.
Document Actions