////////////////////////////////////////////////////////////////////////////////
//  16F877 Clock Program
//      (c)2003 JimCom
////////////////////////////////////////////////////////////////////////////////

//  System Headers
#include <16F877.h>
#device *=16
#use delay(clock=12800000)
#fuses HS,PUT,BROWNOUT,NOWDT,NOPROTECT,NOLVP,NOCPD,WRT

//  IO Port Define
#byte   PA = 5
#byte   PB = 6
#byte   PC = 7
#byte   PD = 8
#byte   PE = 9

////////////////////////////////////////////////////////////////////////////////
//  Timer Counter Value
#define RTCVAL  3125

//  Key Wait Time
#define UPVAL   500

// Tone Freq.
#define TONE    568

//  Global Work
unsigned long  RTC = RTCVAL;
unsigned int   H10 = 0, H1 = 0;
unsigned int   M10 = 0, M1 = 0;
unsigned int   S10 = 0, S1 = 0;
int1           HourFlg = 0;

////////////////////////////////////////////////////////////////////////////////
//  Interrupt Routine
#int_RTCC
RTCC_isr()
{
    RTC--;

    if (RTC == 0)
    {
        RTC = RTCVAL;
        S1++;
        if (S1 > 9) {
            S1 = 0;
            S10++;
            if (S10 > 5) {
                S10 = 0;
                M1++;
                if (M1 > 9) {
                    M1 = 0;
                    M10++;
                    if (M10 > 5) {
                        M10 = 0;
                        H1++;
                        HourFlg = 1;
                        if (H1 > 9) {
                            H1 = 0;
                            H10++;
                        }
                    }
                }
            }
        }
        if ((H10 == 2) && (H1 == 4)) {
                H1  = 0;
                H10 = 0;
        }
        if ((S1 & 1) == 0) {
            if (S10 < 3) {
                PE = 0b011;
            }
            else {
                PE = 0b011;
            }
         }

         else {
           if (S10 < 3) {
                PE = 0b010;
            }
            else {
                PE = 0b001;
            }
         }

    }
}

////////////////////////////////////////////////////////////////////////////////

void timeup(){
    S1++;
    if (S1 > 9) {
        S1 = 0;
        S10++;
        if (S10 > 5) {
            S10 = 0;
            M1++;
            if (M1 > 9) {
                M1 = 0;
                M10++;
                if (M10 > 5) {
                    M10 = 0;
                    H1++;
                    if (H1 > 9) {
                        H1 = 0;
                        H10++;

                    }
                }
            }
        }
    }
    if ((H10 == 2) && (H1 == 4)) {
            H1  = 0;
            H10 = 0;
    }
}

//
void set_zero() {
    S1  = 0;
    if (S10 >= 3 ) {
        M1++;
        if (M1 > 9) {
            M1 = 0;
            M10++;
            if (M10 > 5) {
                M10 = 0;
                H1++;
                if (H1 > 9) {
                    H1 = 0;
                    H10++;

                }
            }
        }
        if ((H10 == 2) && (H1 == 4)) {
              H1  = 0;
              H10 = 0;
        }
     }
     S10 = 0;
     RTC = RTCVAL;
     set_timer0(0);

}

void up_min() {
    M1++;
    if (M1 > 9) {
        M1 = 0;
        M10++;
        if (M10 > 5) {
            M10 = 0;
            H1++;
            if (H1 >9) {
                H1 = 0;
                H10++;
            }
         }
    }
    if ((H10 == 2) && (H1 == 4)) {
                     H1  = 0;
                     H10 = 0;
    }
}

void up_hur() {
    H1++;
    if (H1 > 9) {
        H1 = 0;
        H10++;
    }
    if ((H10 == 2) && (H1 == 4)) {
             H1  = 0;
             H10 = 0;
    }
}


//  Display Routine
void Nix_disp(){
    PD = (S10*16)+S1;
    PC = (M10*16)+M1;
    PB = (H10*16)+H1;
}

//  Main Routine
void main() {

    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_CLOCK_DIV_2);
    setup_psp(PSP_DISABLED);
    setup_spi(FALSE);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    set_tris_A(0b111111);
    set_tris_B(0b00000000);
    set_tris_C(0b00000000);
    set_tris_D(0b00000000);
    set_tris_E(0b000);
    setup_counters(RTCC_INTERNAL,RTCC_DIV_4);

    RTC = RTCVAL;
    H10 = 0; H1 = 0;
    M10 = 0; M1 = 0;
    S10 = 0; S1 = 0;

    HourFlg = 0;

    PB = 0;
    PC = 0;
    PD = 0;
    PE = 0;

    set_timer0(0);
    enable_interrupts(INT_RTCC);
    enable_interrupts(global);

    while(1) {
        Nix_disp();

        switch ( PA & 0b111) {
            case 0b110 :set_zero();
                        Nix_disp();
                        DELAY_MS(900);
                        break;

            case 0b101 :up_min();
                        Nix_disp();
                        DELAY_MS(UPVAL);
                        break;

            case 0b011 :up_hur();
                        Nix_disp();
                        DELAY_MS(UPVAL);
                        break;

            default :
        }

        if (HourFlg == 1) {
            HourFlg = 0;
//            Beep();
        }

    }
}
