/************************************************************/
/* Ruletti-ohjelma                           RULETTI.C      */
/* 13.1.2000   J.Koskinen  Tietomyrsky Oy                   */
/************************************************************/

#include <8051reg.h>
#include <8051bit.h>
#include <2051int.h>
#include <8051io.h>


#define   COL0  (P3 &= 0xFE)
#define   COL1  (P3 &= 0xFD)
#define   COL2  (P3 &= 0xFB)
#define   COL3  (P3 &= 0xF7)
#define   COL4  (P3 &= 0xEF)

#define   PZ_ON   (P3 &= 0x7F)
#define   PZ_OFF  (P3 |= 0x80)

#define   BUT     (~P3 & 0x20)

#define   OFF   0xFF

#define   SLEEP (PCON |= 0x01)    // nukuta prosessori


/***********************************************************/
/* Timer 0:n keskeytyspalveluohjelma                       */
/***********************************************************/
INTERRUPT(_TF0_) timerint0()
{
                          // ei tehdä mitään, herätään vain
}


/************************************************************/
/* timer_init alustaa timer0-keskeytyksen		  							*/
/************************************************************/
timer_init()
{
  TMOD &= 0xF0;      				        
  TMOD |= 0x00;           // Mode 0 = 13-bittinen toimintatila
  TH0 = TL0 = 0;          // 0...8192	 (1,3 ms @ 1,843 MHz)																			
  setbit(TCON.4);         // timer 0 käyntiin
  enable();
}                                 


/************************************************************/
/* Pääohjelma                                               */
/************************************************************/
void main(void)
{
  unsigned char row;
  unsigned char col;
  unsigned char plus;     // kertoo, kuinka monta kierrosta
                          // jatketaan napin päästämisen jälkeen
  row = 0x01;    
  col = 0;
  
  timer_init();           // alusta ajastin 0

  while(1)
  {   
 
    if (BUT || plus)
    {
      P3 = OFF;           // P3 lepotilaan
      PZ_ON;              // Piezo päälle
   
      P1 = ~row;          // asetetaan rivi aktiiviseksi
      row <<= 1;          // seuraava rivi
      plus--;             
  
      PZ_OFF;             // Piezo pois päältä

      switch (col)        // asetetaan oikea sarake aktiiviseksi
      {
        case 0: COL0;
                break;
        case 1: COL1;
                break;
        case 2: COL2;
                break;
        case 3: COL3;
                break;
        case 4: COL4;
                break;
      }


      if (!row)           // onko kaikki rivit käyty jo?
      {
        row = 0x01;       // jos on, aloitetaan alusta
        col++;
      }

      if (col == 4 && row == 0x20)  // oliko viimeinen numero (36)?
      {
        row = 0x01;
        col = 0;
      }

      if (!BUT && plus == 5)        // loppuhidastus 
        delay(10);                  // viidelle viimeiselle 
      if (!BUT && plus == 4)        // kasvatetaan viivettä
        delay(20);
      if (!BUT && plus == 3)
        delay(40);
      if (!BUT && plus == 2)
        delay(80);
      if (!BUT && plus == 1)
        delay(150);

    }                     // joka numerolle sama tod.näk.
                          // nukutetaan mikro-ohjain 
	  setbit(IE.1);         // sallitaan timer 0 keskeytys
    SLEEP;                // kierros kestää 8 ms
	  clrbit(IE.1);         // estä timer 0 keskeytys
  }   
}    

