/*version 0.6á 12-3-97*/
/*        0.5 first release
          0.6 some changes and bugfixes
18-5-97   0.7 changed and improved for the new Hi-Tech C Compiler
              by Clyde Smith-Stubbs*/

#include        <pic.h>

#define PORTBIT(adr, bit)       ((unsigned)(&adr)*8+(bit))
static bit      button0 @ PORTBIT(PORTB, 0);
static bit      button1 @ PORTBIT(PORTB, 1);
static bit      button2 @ PORTBIT(PORTB, 2);
static bit      button3 @ PORTBIT(PORTB, 3);
static bit      button4 @ PORTBIT(PORTB, 4);
static bit      button5 @ PORTBIT(PORTB, 5);
static bit      button6 @ PORTBIT(PORTB, 6);
static bit      button7 @ PORTBIT(PORTB, 7);
static bit      buttona @ PORTBIT(PORTA, 4);

static bit      om;
static bit      sho;
static bit      out;
static bit      bas;
static bit      ba0;
static bit      ba1;
static bit      ba2;
static bit      ba3;
static bit      kni;
static bit      de;
static bit      pc;

static bit      rev;
static bit      inv;
static bit      a2;
static bit      a3;


unsigned char const PAT[129] = {1, 3, 7, 15, 31, 63, 127, 255,
        1, 2, 4, 8, 16, 32, 64, 128,
        3, 6, 12, 24, 48, 96, 192, 128
        ,3, 14, 28, 56, 112, 224, 192, 128,
        129, 66, 36, 24, 24, 36, 66, 129,
        24, 66, 36, 129, 129, 66, 36, 24,
        195, 102, 24, 102, 195, 102, 24, 195,
        255, 0, 15, 240, 3, 192, 128, 1,
        170, 55, 170, 55, 170, 55, 170, 55,
        219, 109, 219, 109, 219, 109, 219, 109,
        0, 0, 0, 0, 0, 0, 0, 0, /* these patterns should be */
        0, 0, 0, 0, 0, 0, 0, 0, /* edited to be used */
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
};

void
dis_7(unsigned char w)
{
        TRISB = 0;
        PORTB = w % 10 << 4;
        if(w < 10)
                PORTB |= 15;
        else
                PORTB |= w/10;
        PORTA = 2;
        w = 4;
        while (--w)
                continue;
        PORTA = 0;
}

void
del()
{
        unsigned int    i = 6000;

        while (i)
                i--;
}

program(unsigned char ba)
{
        unsigned        i = 5000;
        unsigned char   d = 2;
        unsigned char   stat = 0;

        EEADR = 0;
        EEDATA = 0;
        rev = 0;
        inv = 0;
        a2 = 0;
        a3 = 0;
        pc = 1;
        for(;;) {
                TRISB = 255;
                PORTA = 8;
                while (i) {
                        i--;
                        if (button0 == 1) {
                                if (rev) {
                                        rev = 0;
                                        stat &= 254;
                                } else {
                                        rev = 1;
                                        stat |= 1;
                                } del();
                                del();
                        }
                        if (button1 == 1) {
                                return;
                        }
                        if (button2 == 1 && EEDATA > 0) {
                                EEDATA--;
                                del();
                                del();
                                i = 0;
                        }
                        if (button3 == 1 && EEDATA < 15) {
                                EEDATA++;
                                del();
                                del();
                                i = 0;
                        }
                        if (button4 == 1) {
                                if (inv) {
                                        inv = 0;
                                        stat &= 239;
                                } else {
                                        inv = 1;
                                        stat |= 16;
                                } del();
                                del();
                                i = 0;
                        }
                        if (button5 == 1) {
                                if (a2) {
                                        a2 = 0;
                                        stat &= 223;
                                } else {
                                        a2 = 1;
                                        stat |= 32;
                                } del();
                                del();
                                i = 0;
                        }
                        if (button6 == 1) {
                                if (a3) {
                                        a3 = 0;
                                        stat &= 191;
                                } else {
                                        a3 = 1;
                                        stat |= 64;
                                } del();
                                del();
                                i = 0;
                        }
                        if (button7 == 1) {
                                dis_7(EEADR + 1);
                                i = 45000;
                                while (i)
                                        i--;
                                if (rev)
                                        EEDATA += 128;
                                if (inv)
                                        EEDATA += 16;
                                if (a2)
                                        EEDATA += 64;
                                if (a3)
                                        EEDATA += 32;

                                EEADR += (ba * 16);
                                WREN = 1;
                                EECON2=0x55;
                                EECON2=0xAA;
                                WR=1;
                                while(WR)
                                        continue;
                                WREN=0;
                                EEADR &= 0xF;
                                EEDATA &= 0xF;
                                EEADR++;
                                if (EEADR == 16)
                                        EEADR = 0;
                                if (pc && ba == 3)
                                        EEADR = 0;
                        }
                }
                TRISB = 0;
                PORTA = 0;
                i = 5000;
                PORTB = stat;
                PORTA = 1;
                while (d)
                        d--;
                PORTA = 0;
                d = 2;
                dis_7(EEDATA + 1);
                pc = 0;

        }
}

main(void)
{
        unsigned        t = 5000;
        unsigned        st = 0;
        unsigned        i;
        unsigned char   nr = 0;
        unsigned char   h;
        unsigned char   ho;
        signed char     b = 0;
        unsigned char   status = 16;
        unsigned char   statkn = 0;
        unsigned char   ba = 0;
        unsigned char   nt = 0;
        unsigned char   pa = 0;

        om = 0;
        bas = 0;
        kni = 1;
        sho = 0;
        out = 0;
        de = 1;
        ba0 = 1;
        ba1 = 0;
        ba2 = 0;
        ba3 = 0;
        TRISA = 16;

        for(;;) {
                i = t;

                TRISB = 255;
                PORTA = 8;

                while (i) {
                        i--;
                        if (button0 == 1) {
                                if (out) {
                                        status &= 254;
                                        out = 0;
                                } else {
                                        status |= 1;
                                        out = 1;
                                } pa = 0;
                                del();
                                del();
                        }
                        if (button1 == 1) {
                                if (sho)
                                        sho = 0;
                                else
                                        sho = 1;
                                pa = 0;
                                del();
                                del();
                        }
                        if (button2 == 1 && button3 == 1) {
                                if (bas) {
                                        bas = 0;
                                        status &= 253;
                                } else {
                                        bas = 1;
                                        status |= 2;
                                } del();
                                del();
                        }
                        if (button2 == 1 && t > 150) {
                                t = t - 100;
                                del();
                                i = 0;
                        }
                        if (button3 == 1 && t < 25000) {
                                t = t + 100;
                                del();
                                i = 0;
                        }
                        if (button2 == 1 && button4 == 1) {
                                program(0);
                                ho = 0;
                                del();
                        }
                        if (button2 == 1 && button5 == 1) {
                                program(1);
                                ho = 0;
                                del();
                        }
                        if (button2 == 1 && button6 == 1) {
                                program(2);
                                ho = 0;
                                del();
                        }
                        if (button2 == 1 && button7 == 1) {
                                program(3);
                                ho = 0;
                                del();
                                del();
                        }
                        if (button4 == 1) {
                                if (ba0) {
                                        ba0 = 0;
                                        status &= 239;
                                } else {
                                        ba = 0;
                                        status |= 16;
                                        ba0 = 1;
                                } del();
                                del();
                        }
                        if (button5 == 1) {
                                if (ba1) {
                                        ba1 = 0;
                                        status &= 223;
                                } else {
                                        ba = 1;
                                        ba1 = 1;
                                        status |= 32;
                                } del();
                                del();
                        }
                        if (button6 == 1) {
                                if (ba2) {
                                        ba2 = 0;
                                        status &= 191;
                                } else {
                                        ba = 2;
                                        ba2 = 1;
                                        status |= 64;
                                } del();
                                del();
                        }
                        if (button7 == 1) {
                                if (ba3) {
                                        ba3 = 0;
                                        status &= 127;
                                } else {
                                        ba = 3;
                                        ba3 = 1;
                                        status |= 128;
                                } del();
                                del();
                        }
                }
                TRISB = 0;
                PORTA = 0;
                if (nt == 0) {
                        if (sho || out)
                                dis_7(pa + 1);
                        //asm("bcf 3,5");

                        EEADR = pa + (ba * 16);
                        RD = 1;
                        nr = EEDATA;
                        if (nr & 64)
                                nt = 4;
                        else if (nr & 32)
                                nt = 2;
                        else
                                nt = 1;
                        if ((nr & 96) == 96)
                                nt = 8;

                        if (nr & 128)
                                rev = 1;
                        else
                                rev = 0;
                        if (nr & 16)
                                inv = 1;
                        else
                                inv = 0;
                        nr = nr & 15;
                        pa++;
                        if (pa == 16) {
                                pa = 0;

                                if (ba == 0) {
                                        if (ba1)
                                                ba = 1;
                                        else if (ba2)
                                                ba = 2;
                                        else if (ba3)
                                                ba = 3;
                                } else if (ba == 1) {
                                        if (ba2)
                                                ba = 2;
                                        else if (ba3)
                                                ba = 3;
                                        else if (ba0)
                                                ba = 0;
                                } else if (ba == 2) {
                                        if (ba3)
                                                ba = 3;
                                        else if (ba0)
                                                ba = 0;
                                        else if (ba1)
                                                ba = 1;
                                } else if (ba0)
                                        ba = 0;
                                else if (ba1)
                                        ba = 1;
                                else if (ba2)
                                        ba = 2;
                        }
                }
                h = 40 - t / 200;
                if (h != ho)
                        dis_7(h);
                ho = h;

                if ((ba0 || ba1 || ba2 || ba3) && (out || sho)) {
                        if (inv)
                                PORTB = ~(PAT[b + (nr * 8)]);
                        else
                                PORTB = PAT[b + (nr * 8)];
                } else
                        PORTB = 0;


                if (out) {
                        PORTA = 4;
                        while (de)
                                de = 0;
                        PORTA = 0;
                        de = 1;
                }
                if (ba == 0)
                        statkn = status & 239;
                else if (ba == 1)
                        statkn = status & 223;
                else if (ba == 2)
                        statkn = status & 191;
                else if (ba == 3)
                        statkn = status & 127;
                if (kni) {
                        if (!sho)
                                PORTB = status;
                        kni = 0;
                } else {
                        if (!sho)
                                PORTB = statkn;
                        kni = 1;
                }

                PORTA = 1;
                while (de)
                        de = 0;
                PORTA = 0;
                de = 0;

                if (rev) {
                        if (om)
                                b--;
                        else
                                b++;
                        if (b == -1) {
                                om = 0;
                                b = 0;
                                nt--;
                        } else if (b == 8) {
                                om = 1;
                                b = 7;
                                nt--;
                        }
                } else {
                        b++;
                        if (b == 8) {
                                b = 0;
                                nt--;
                        }
                }
                if (bas) {
        WA:
                        if (!buttona) {
                                sho = 1;
                                out = 1;
                        } else {
                                st++;
                                if (st < 58000)
                                        goto WA;
                                else {
                                        sho = 0;
                                        out = 0;
                                }
                        }

                }
                st = 0;

        }
}
