//  swchaserud.c -- PORTD switches control rate of up-down chaser on PORTB LEDs
//  implemented and tested on Atmel STK500 with AT90S8515 in rightmost socket
// 
//  Copyleft (!C) 2003 S. Mann
//  (http://www.gnu.org/copyleft/gpl.html);
//  based on Stephen Lacy's "mirror.c"

//#include <io-avr.h> (doesn't compile when this is there)
#include <avr/io.h>
//for the above, you need to apt-get install 
#include <avr/wdt.h> 
//#include <unistd.h>

void delay(long N) {
  long n;
  for (n=0; n<N; n++);
}

int main(void) {
  outp (0xFF,DDRB);/* Data Direction Register: 1 means output; 0 means input*/
  outp (0x00,DDRD);/* set all bits in PORTD to Direction 0 = input */

  //outp(0,PORTB);
  while (1) {
    unsigned char x, y, xi, yi, m, inc;
    long d;
    xi = inp(PIND); /* remembers switch input from last time programmed */
    x = 0xFF - xi; /* x from x inverse, due to common positive */
    //y = x;  /* your transformation goes here */
    //y = (x<<1) - 1;  /* your transformation, y=y(x), goes here */
    //y = 2*x-1;  /* your transformation goes here */
    //if (x==0) y=0;
    if (x!=0) d=1000* (long)x; /* poor implementation of mixed mode
				  aritmetic makes it NECESSARY to
				  typecast explicitly, otherwise it
				  uses short integer arithmetic by
				  default and SW6 and 7 go fast not slowest */
    y=0;
    outp (0xFF-y,PORTB);
    delay(d); /* chaser speed controlled by switches */
    y=1;
    m=1;
    inc=1; /* increment: 1=yes; 0=decrement */
    while (m>=1) {
      yi = 0xFF - y;
      outp (yi,PORTB);
      delay(d);
      if (inc) {y=(y<<1)+1; m++;};
      if (!inc) {y=(y>>1); m--;};
      if (m==8) inc=0; /* decrement */
    }
  }
}

