Making a calculator using an Arduino

Here the complete code:

/*
   size : 3118 bytes
   
   Calculator Version 1.0
   
   Just add a number enter by the keypad and display it.
   With 2 function : Add / Equal ===> * button 
                     Clear ==>  # button
   It will use a MAX7219 for display the data ( for the shiftOut() ).
   and a 4021 for the keypad input data with the use of 
   an NOT gate 74HC14. ( for the shiftin() )
   See the keypad example in the tread for details.
  
   The interrupt use a 72LS20 from the row pins, any LOW signal will
   produce a HIGH pulse to be use has an interrupt signal.

   By Serge J Desjardins
   aka techone / tech37
   Toronto, Ontario, Canada

   Compile and Tested.
   
   Bug :
   The add section need to be re-code.
*/

// Keypad Serial pins
const byte latchkeypin = 10;
const byte datakeypin = 12;
const byte clockkeypin = 11;

// Display Serial pins
const byte datadisplaypin = 9;
const byte clockdisplaypin = 8;
const byte latchdisplaypin = 7;

// Anykey and interrupt pin
const byte anykeypin = 2;

// MAX7419 init data
word initdata[5] = { 0x0C01, 0x0F00, 0x0A0B, 0x0B07, 0x09FF };

// Fill the Display array with a blank code
word display_data[8] = { 0x0100, 0x020F, 0x030F, 0x040F, 0x050F, 0x060F, 0x070F, 0x080F };  

// The digit array
byte digit_number[8] = {0,0,0,0,0,0,0,0};

// For the digits extraction calculation
long power_of_ten[8] = {1,10,100,1000,10000,100000,1000000,10000000};

// Key press keypad flag 
volatile boolean keystate;

// Overflow flag
boolean over_flow;
// add button flag
boolean add_flag;
// Clear button flag
boolean clear_flag;

// The keypad data 
byte keydata;
byte keynumber;

// the ADD calculation
long the_number;
long temp_number;
long add_number;


void setup() 
{
  //start serial
  //Serial.begin(9600);

  //define the pins modes
  pinMode(latchkeypin, OUTPUT);
  pinMode(clockkeypin, OUTPUT); 
  pinMode(datakeypin, INPUT);
  pinMode(datadisplaypin, OUTPUT);
  pinMode(clockdisplaypin, OUTPUT);
  pinMode(latchdisplaypin, OUTPUT);
  pinMode(anykeypin, INPUT);
  // setup the interrupt pin
  attachInterrupt(0,anykeypress,RISING);
  
  /* Init the MAX7419 : Normal Mode
                        Normal Operation
                        Setting the Intensity
                        Numbers of Digits being display
                        Set to Decode Mode
  */
 
  for (int i=0;i<5;i++)
  {  
     digitalWrite(latchdisplaypin, LOW);
     shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, highByte(initdata[i]));
     shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, lowByte(initdata[i]) );
     digitalWrite(latchdisplaypin, HIGH);
     delay(5);
  }
  // Blank the display
  display_the_numbers();
  // init the flags and the calculation variable
  keystate = 0;
  add_number = 0;
  add_flag = 0;
  over_flow = 0;
  clear_flag = 1;  
}  

void loop()
{  
  while ( keystate == 0) 
  { 
     // wait for a key press 
  }
  read_keypad();
  convert_the_keypad_data();
  // reset add flag and set the display 
  if ( (( add_flag == 1) || ( clear_flag = 1 )) && ( over_flow == 0 ) )
  {
    for (int i=0;i<8;i++)
    {
      digit_number[i] = 0;
      display_data[i] = word ( ( i+1 ), 0x0F );
    }
    add_flag = 0;
    clear_flag = 0;  
  }
  // Enter the numbers routine  
  if ( ( keynumber < 0x0A ) && ( over_flow == 0 ) )
  {      
     // Enter the key number and move the arrays data.     
     for (int i=7;i>0;i--)
     {
       digit_number[i] = digit_number[i-1];
       display_data[i]=display_data[i-1];
       display_data[i] = word ( (i+1) , lowByte( display_data[i] ) );
     }
     digit_number[0] = keynumber;     
     display_data[0] = word ( 1, keynumber );     
     display_the_numbers();
     keystate = 0;    
  }
  else
  {
    // Check for the "Add / Equal" button
    if ( ( keynumber == 0x0B ) && ( over_flow == 0) )
    {      
      the_number= 0;
      for (int i=0;i<8;i++)
      {
        temp_number = long(digit_number[i]) * power_of_ten[i];
        the_number = the_number + temp_number;       
      }  
      add_number = add_number + the_number;
      if (add_number <= 99999999)
      {
        for (int i=7;i>=0;i--)
        {
          digit_number[i] = byte(add_number / power_of_ten[i]);
          add_number = add_number - (long(digit_number[i]) * power_of_ten[i]); 
          display_data[i] = word ( ( i + 1) , digit_number[i] );        
        }
        for (int i=7;i>0;i++)
        {
          if ( digit_number[i] == 0 )
          {
             display_data[i] = word ( ( i + 1 ), 0x0F );
          }
          else 
          {
            break;
          }   
        }
        
        display_the_numbers();
        add_flag = 1;
        keystate = 0;
      }
      else
      {
        // Over Flow
        over_flow = 1;
        digit_number[0] = 0;
        display_data[0] = 0x010B;
        for ( int i=1;i<8;i++)
        {
           digit_number[i] = 0;
           display_data[i] = word( (i+1), 0x0F );               
        }      
        keystate = 0;      
        display_the_numbers();           
      }         
    }
    
    // Check for the "Clear" button 
    if ( keynumber == 0x0E )
    {
      digit_number[0] = 0;
      display_data[0] = 0x0100;
      for ( int i=1;i<8;i++)
      {
        digit_number[i] = 0;
        display_data[i] = word( (i+1), 0x0F );               
      }
      add_number = 0;
      keystate = 0;
      over_flow = 0;
      add_flag = 0;
      clear_flag = 1;
      display_the_numbers();     
    }    
  }   
  //For troubleshooting the program using Serial Monitor
 /*  
    Serial.print(keydata, BIN);
    Serial.print("  ");
    Serial.print(keydata, HEX);
    Serial.print("  ");
    Serial.print(keynumber, HEX);
    Serial.print("  ");
    Serial.println(keydata, DEC);
    delay(1000);
*/
}

// Read keypad data via a 74HC14 - Inverter from the 4021
void read_keypad()
{
  digitalWrite(latchkeypin,HIGH);
  delayMicroseconds(20);
  digitalWrite(latchkeypin,LOW);
  keydata = shiftIn(datakeypin, clockkeypin,LSBFIRST);  
} 

// Convert the keypad data into BCD
// And a code for *, 0, # button
void convert_the_keypad_data()
{
  byte what_row;
  
  what_row = ( keydata >> 3) & 0x0F;
  switch ( what_row)
  {
    case 1:
           keynumber = ( ( keydata >> 1 ) & 0x03 ) + 1;
           break;
    case 2:
           keynumber = (( keydata >> 1 ) & 0x03 ) + 4;
           break;
    case 4:
           keynumber = (( keydata >> 1 ) & 0x03 ) + 7;
           break;
    case 8:
           special_key();
           break;    
  }  
  
}  

// the display the data routine to the MAX7219 
void display_the_numbers()
{
   for (int i=0;i<8;i++)
   {
     digitalWrite(latchdisplaypin, LOW);
     shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, highByte(display_data[i]) );
     shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, lowByte(display_data[i]) );
     digitalWrite(latchdisplaypin, HIGH);
     delay(5);
   }  
}

// A special code for 0, *, # button
void special_key()
{
   byte special_case;
   
   special_case = ( ( keydata >> 1) & 0x03 ) + 1;
   switch ( special_case )
   {
     case 1:
            keynumber = 0x0E;
            break;
     case 2:
            keynumber = 0x00;
            break;
     case 3:
            keynumber = 0x0B;
            break;
   }        
}

// Interrupt Routibe
void anykeypress()
{
  keystate = 1; 
}