/****************************************************************
   ASCII 8N2 50baud RTTY(R) v1.00 2016.12.01
/****************************************************************/

#include <LiquidCrystal.h>
#include <FlexiTimer2.h>

LiquidCrystal lcd(4,5,6,7,8,9,10);

boolean  dsp;
boolean  org;
byte     ti;
int      x;
byte     y;
char     ch;
char     c[33];
uint8_t  ascii;

void setup()
{
        lcd.begin(16, 2);
        lcd.cursor();
        lcd.setCursor(0, 0);
        FlexiTimer2::set(1, timer_interrupt);
        FlexiTimer2::start();
}

void timer_interrupt(void)
{
        static byte rSq;
        
        ti++;
        if(rSq == 0 && digitalRead(19) == 0)
        {
                rSq = 1;
                ti = 0;
        }
        if(rSq == 1 && ti == 10)
        {
                if(digitalRead(19) == 0)
                {
                        rSq = 2;
                        ti = 0;
                }
                else
                {
                        rSq = 0;
                }
        }
        else if(rSq == 2 && ti == 20)
        {
                bitWrite(ascii, 0, digitalRead(19));
        }
        else if(rSq == 2 && ti == 40)
        {
                bitWrite(ascii, 1, digitalRead(19));
        }
        else if(rSq == 2 && ti == 60)
        {
                bitWrite(ascii, 2, digitalRead(19));
        }
        else if(rSq == 2 && ti == 80)
        {
                bitWrite(ascii, 3, digitalRead(19));
        }
        else if(rSq == 2 && ti == 100)
        {
                bitWrite(ascii, 4, digitalRead(19));
        }
        else if(rSq == 2 && ti == 120)
        {
                bitWrite(ascii, 5, digitalRead(19));
        }
        else if(rSq == 2 && ti == 140)
        {
                bitWrite(ascii, 6, digitalRead(19));
        }
        else if(rSq == 2 && ti == 160)
        {
                bitWrite(ascii, 7, digitalRead(19));
                dsp = 1;
        }
        if(rSq == 2 && ti == 190)
        {
                rSq = 0;
        }
}

//DISPLAYS CHARACTER
void lcdOut()
{
        int i;
        
        lcd.print(ch);
        c[16 * y + x] = ch;
        x++;
        if(x == 16 && y == 0)
        {
                x = 0; y = 1;
        }  
        else if(x == 16 && y == 1)
        {
                for(i = 0; i < 16; i++)
                {
                        c[i] = c[16 + i];
                }
                for(i = 0; i < 16; i++)
                {
                        c[16 + i] = '\0';
                }
                lcd.clear();
                lcd.noCursor();
                for(i = 0; i < 16; i++)
                {
                        lcd.print(c[i]);
                }
                lcd.cursor();
                x = 0; y = 1;
        }
        lcd.setCursor(x, y);
}

//HANDLES BACKSPACE
void lcdBs()
{
        int i;
        
        if(x == 0 && y == 0)
        {
                org = true;
        }
        else
        {
                org = false;
                x--;
                if(x == -1 && y == 1)
                {
                        x = 15; y = 0;
                        while(c[x] == '\0')
                        {
                                x--;
                        }
                        lcd.noCursor();
                        lcd.setCursor(x, y);
                        lcd.print(" ");
                        lcd.setCursor(x, y);
                        lcd.cursor();
                        c[x] = '\0';
                }
                else
                {
                        lcd.noCursor();
                        lcd.setCursor(x, y);
                        lcd.print(" ");
                        lcd.setCursor(x, y);
                        lcd.cursor();
                        c[16 * y + x] = '\0';
                }
        }
}

//HANDLES CRLF
void lcdCrLf()
{
        byte skip = (16 - x);
        int i;
        
        lcd.noCursor();
        for(i = 0; i < skip; i++)
        {
                if(i == 0)
                {
                        c[16 * y + x] = '\r';
                }
                else
                {
                        c[16 * y + x] = '\0';
                }
                x++;
        }
        if(y == 0)
        {
                x = 0; y = 1;
        }
        else
        {
                for(i = 0; i < 16; i++)
                {
                        c[i] = c[16 + i];
                }
                for(i = 0; i < 16; i++)
                {
                        c[16 + i] = '\0';
                }
                lcd.clear();
                for(i = 0; i < 16; i++)
                {
                        if(c[i] == '\r' || c[i] == '\0')
                        {
                                lcd.print(' ');
                        }
                        else
                        {
                                lcd.print(c[i]);
                        }
                }
                x = 0; y = 1;
        }
        lcd.setCursor(x, y);
        lcd.cursor();
}

void loop()
{
        if(dsp == 1)
        {
                ch = ascii;
                
                if(ch == '\r')
                {
                        //SKIP
                }
                else if(ch == '\n')
                {
                        lcdCrLf();
                }
                else if(ch == '\b')
                {
                        lcdBs();
                }
                else
                {
                        lcdOut();
                }
                dsp = 0;
        }
        delay(5);
}