// digi8a.c

#include "digi8a.h"

// ================================================================
//                         is_closure
// 1. Return -1 error indicator if the input
//    is less than 1 or greater than 88.
//
// 2. Return 1 if closure is on, 0 if it is off.

int is_closure(int input)
{
  int sw_in_port_val,shiftval;  // switch in port and shift values

  if(input < 1 || input > 88) // if the input is less than 1 or greater
    return -1;                // than 88, then return -1 showing an error

  // we fell through the above so see if the input is less than 25
  if(input < 25)
  {
    input--; // same as input = input - 1;

    shiftval = input/3; // divide and neglect the remainder

    // A 1 is shifted to the proper location.
    // The result of the shift is XORed with
    // 0xff and stored in the Port A value,
    // turning off the desired bit and leaving
    // all of the others on.
    // Use porta_val = 1 << shiftval
    // if the 74LS05 is used, because
    // the desired operation is to turn
    // on the bit.
    porta_val = 0xff ^ (1 << shiftval); // or porta_val = 1 << shiftval with 74LS05

    // clear the appropriate Port A bit 
    outp(ppi_porta, porta_val);

    shiftval = input % 3;  // divide and use only the remainder
    shiftval+=4; // same as shiftval = shiftval + 4;

    sw_in_port_val = inp(switch_port); // get a number out of the '244 buffer
    sw_in_port_val>>=shiftval; // shift it to the right shiftval
                           // places to put in bit 0 position
    sw_in_port_val&=1; // same as sw_in_port_val = sw_in_port_val & 1;
    sw_in_port_val^=1; // same as sw_in_port_val = sw_in_port_val ^ 1;

    return sw_in_port_val;
  }

  // it's >= 25 if it gets this far

  input-=25; // same as input = input - 25;

  shiftval = input/8; // divide and neglect the remainder

  // A 1 is shifted to the proper location.
  // The result of the shift is XORed with
  // 0xff and stored in the Port A value,
  // turning off the desired bit and leaving
  // all of the others on.
  // Use porta_val = 1 << shiftval
  // if the 74LS05 is used, because
  // the desired operation is to turn
  // on the bit.
  porta_val = 0xff ^ (1 << shiftval); // or porta_val = 1 << shiftval with 74LS05


  // clear the appropriate Port A bit 
  outp(ppi_porta, porta_val);

  shiftval = input % 8; // divide but use only the remainder

  portb_val = inp(ppi_portb); // get a number from Port B
  portb_val>>=shiftval; // shift it to the right shiftval
                        // places to put in bit 0 position
  portb_val&=1; // same as portb_val = portb_val & 1;
  portb_val^=1; // same as portb_val = portb_val ^ 1;

  return portb_val;

}// end is_closure()


// set up the ppi according to the dictates of the mode argument
void set_up_ppi(int mode)
{
  unsigned control = base + 0x23;
  int command;

  // make certain control locations start at NULL
  for(command=0; command<24; command++)
    OutputControl[command] = NULL;

  mode>>=6; // shift the mode value to the right 6 places

  command = (mode & 0x0c) << 1; // shift bits 2 and 3 into positions 4 and 5
  command += (mode & 3); // add in bits 0 and 2
  command |= 0x80; // OR in bit 7 for PPI set up

  outp(control, command); // set according to mode command

} // end set_up_ppi()



// get the port -- this will grow into an auto-detect function in the future 
unsigned get_port(void)
{
  base = 0x200; // all switches on -- change as required
  switch_port = base + 0x18;
  ppi_porta = base + 0x20;
  ppi_portb = base + 0x21;
  ppi_portc = base + 0x22;
  return base;
  
} // end get_port()



void blinker(long on, long off)
{
  int x;
  long y,z;

  for(x=0x80; x>0; x>>=1)
  {
    outp(ppi_porta, x);
    printf("%4X",x);
    for(y=0L; y<on; y++);

    outp(ppi_porta, 0);
    for(z=0L; z<off; z++);
  }

  for(x=2; x<0x80; x<<=1)
  {
    outp(ppi_porta, x);
    for(y=0L; y<on; y++);

    outp(ppi_porta, 0);
    for(z=0L; z<off; z++);
  }
}

void btoa(void)
{
  outp(ppi_porta, ~inp(ppi_portb));
}

void motor(long on, long off)
{
  int x;
  long y,z;

  printf("ON  ");
  outp(ppi_porta, 0xff);
  for(y=0L; y<on; y++);

  printf("OFF ");
  outp(ppi_porta, 0);
  for(z=0L; z<off; z++);
}

// turn port a on
void portaon(void)
{
  outp(ppi_porta, 0xff);
}

// turn port a off
void portaoff(void)
{
  outp(ppi_porta, 0);
}

void motor2(long on, long off)
{
  int x;
  long y,z;

  outp(ppi_porta, 0xff);
  for(y=0L; y<on; y++);

  outp(ppi_porta, 0);
  for(z=0L; z<off; z++);
}

 
// end digi8a.c

 


