////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//   JI3BNB RTTY EnDECODER for ARDUINO UNO  - TX & RX VERSION -
//   2018.03.20 v6.0
//
//   DESIGNED FOR AMATEUR RADIO COMMUNICATION
//   - REALTIME KEYBOARD INPUT
//   - 5BIT BAUDOT CODE, 45.45baud
//   - EDIT MEMORY VIA PS/2 KEYBOARD
//   - LCD 16x2 (SC1602BBWB-XA-GB-G) or 20x4 (UC-204)
//
//   SCHEMATIC http://k183.bake-neko.net/ji3bnb/page13.html
//   ** THIS PROGRAM IS IN THE PUBLIC DOMAIN **
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                   -- BASIC SET UP AND PIN ASSIGNMENTS --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
     #include <TimerOne.h>

//   ** REQUIRE "TimerOne" LIBRARY **
//   http://playground.arduino.cc/code/timer1

     #define MARK  392   // 392 = (500000 / 1275 Hz)     
     #define SPACE 346   // 346 = (500000 / 1445 Hz)

//   #define MARK  346   // 346 = (500000 / 1445 Hz)
//   #define SPACE 392   // 392 = (500000 / 1275 Hz)

//   #define MARK  218   // 235 = (500000 / 2125 Hz)
//   #define SPACE 235   // 218 = (500000 / 2295 Hz)

//   #define MARK  235   // 218 = (500000 / 2295 Hz)
//   #define SPACE 218   // 235 = (500000 / 2125 Hz)

////////////////////////////////////////////////////////////////////////////////
     #include <FlexiTimer2.h>

//   ** REQUIRE "FlexiTimer2" LIBRARY **
//   http://playground.arduino.cc/Main/FlexiTimer2

////////////////////////////////////////////////////////////////////////////////
     #include <PS2Keyboard.h>

//   ** REQUIRE "PS2Keyboard" LIBRARY **
//   http://playground.arduino.cc/Main/PS2Keyboard

     PS2Keyboard keyboard;
     const int  DataPin = 2; //IO2 = "DATA"  PIN
     const int  IRQpin  = 3; //IO3 = "CLOCK" PIN (!!DO NOT CAHNGE THIS)

     const boolean jp106 = 0;
//   SELECT 0: ENGLISH  KEYBOARD
//   SELECT 1: JAPANESE KEYBOARD 日本語キーボード

////////////////////////////////////////////////////////////////////////////////
     #include <LiquidCrystal.h>

//   LCD DISPLAY (HITACHI HD44780 INTERFACE)

     const boolean lcdType = 1;
//   SELECT 0: 16x2
//   SELECT 1: 20x4

     LiquidCrystal lcd(4,5,6,7,8,9,10);
//   ARDUINO D10 -> LCD D7
//   ARDUINO D9  -> LCD D6
//   ARDUINO D8  -> LCD D5
//   ARDUINO D7  -> LCD D4
//   ARDUINO D6  -> LCD EN
//   ARDUINO D5  -> LCD R/W
//   ARDUINO D4  -> LCD RS


////////////////////////////////////////////////////////////////////////////////
//   20CH MEMORY '1'-'0','F1'-'F10' KEYS

     #include <EEPROM.h>
     
//   ADDRESS TABLE
     const int addrTb[] = {2,35,68,101,134,167,200,233,266,299,-1,332,365,398,431,464,545,626,659,692};
     
//   NUMBER KEY '1'-'0'
     char  n01[33]; //00  * MAX 32 CHARACTERS (INCLUDING CR & SPACE)
     char  n02[33]; //01  *
     char  n03[33]; //02  *
     char  n04[33]; //03  *
     char  n05[33]; //04  *
     char  n06[33]; //05  *
     char  n07[33]; //06  *
     char  n08[33]; //07  *
     char  n09[33]; //08  *
     char  n00[33]; //09  *
     
//   FUNCTION KEY 'F1'-'F10'
     char  f01[17]; //10          * MAX 16 CHARACTERS -- HIS/HER CALLSIGN -- (!! NOT SAVED TO EEPROM !!)
     char  f02[33]; //11  *
     char  f03[33]; //12  *
     char  f04[33]; //13  *
     char  f05[33]; //14  *
     char  f06[81]; //15          * MAX 80 CHARACTERS (INCLUDING CR & SPACE)
     char  f07[81]; //16          * MAX 80 CHARACTERS (INCLUDING CR & SPACE)
     char  f08[33]; //17  *
     char  f09[33]; //18  *
     char  f10[33]; //19  *
     
//   ALERTS
     char  a01[] = "EMPTY!";      //20
     char  a02[] = "OVERWRITE?";  //21
     char  a03[] = "SAVED!";      //22
     
//   ARRAY
     char* ms[] = {n00,n01,n02,n03,n04,n05,n06,n07,n08,n09,f01,f02,f03,f04,f05,f06,f07,f08,f09,f10,a01,a02,a03};

////////////////////////////////////////////////////////////////////////////////
//   D12 : ENCODER OUTPUT (AFSK AUDIO)

////////////////////////////////////////////////////////////////////////////////
//   D13 : ENCODER OUTPUT (0/5V TTL LEVEL)

////////////////////////////////////////////////////////////////////////////////
//   A0(=D14) : ESC INDICATOR

//   THIS INDICATOR MEANS "NOW IN 20CH MEMORY MODE"
//   WHEN FLASHING, IT MEANS "EDIT MODE ACTIVE"

////////////////////////////////////////////////////////////////////////////////
//   A1(=D15) : TX INDICATOR

//   ALSO PTT CONTROL VOLTAGE 

////////////////////////////////////////////////////////////////////////////////
//   A4(=D18) : TX SW

//   CONNECT TO GND WHEN TX

////////////////////////////////////////////////////////////////////////////////
//   A5(=D19) : DECODER INPUT

//   0/5V TTL LEVEL (NOT AUDIO SIGNAL)
//   EXTERNAL DEMODULATOR REQUIRED

////////////////////////////////////////////////////////////////////////////////
//   "BAUDOT" CODE HAS SOME TYPES OF VARIATION

     const boolean  usFig  = 1;
//   SELECT 0: "TONO THETA-5000E" COMPATIBLE (ALSO "MixW" COMPATIBLE)
//   SELECT 1: "Fldigi" COMPATIBLE (=USTTY, POPULARLY USED)

////////////////////////////////////////////////////////////////////////////////
//   DIDDLE ENABLE AND INTERVAL PERIOD

     const boolean  ddl     = 1;   //ENABLE
     const int      ddItv   = 260; //INTERVAL (ms)

////////////////////////////////////////////////////////////////////////////////
//   SPECIAL KEYS

//   [Esc]         : GO INTO OR GO OUT OF "20CH MEMORY MODE"
//   [DOWN  ARROW] : SAVE CHANGES
//   [RIGHT ARROW] : SKIP PLAYBACK


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                  -- GLOBAL VARIABLES, FLAGS, COUNTERS etc --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
boolean  space;
boolean  shift;
boolean  crLf;
boolean  fig;
boolean  fig_1;
int      fig_2;
int      x; //CURSOR POSITION
byte     y; //CURSOR POSITION
char     c[81]; //DISPLAY BUFFER
char     keyBuf[5]; //KEY BUFFER
char     ch;

volatile boolean  dsp;
volatile boolean  empCh;
volatile boolean  snd;
volatile boolean  f1Stord;
volatile int      ti;
volatile int      ddCnt;
volatile int      flshCnt;
volatile byte     tRx;
volatile byte     tRL;
volatile byte     rSq;
volatile byte     eSq;

uint8_t  baudot;
uint8_t  baudot_;


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                               -- setup() --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
void setup()
{
        Serial.begin(9600);
        
             if(lcdType == 0){lcd.begin(16, 2);}
        else if(lcdType == 1){lcd.begin(20, 4);}
        lcd.cursor();
        lcd.setCursor(0, 0);
        keyboard.begin(DataPin, IRQpin);
        pinMode(12, OUTPUT);
        pinMode(13, OUTPUT);
        pinMode(14, OUTPUT);
        pinMode(15, OUTPUT);
        digitalWrite(13, 1);
        digitalWrite(18, 1); //INTERNAL PULL UP
        
        Timer1.initialize();
        
        FlexiTimer2::set(1, timer2_interrupt);
        FlexiTimer2::start();
        
        //RESTORE MEMORIES WHEN START UP
        if(EEPROM.read(0) != 'N' || EEPROM.read(1) != 'N') //CLEAN UP
        {
                EEPROM.write(0, 'N');
                EEPROM.write(1, 'N');
                for(int i = 2; i < 1024; i++)
                {
                        EEPROM.write(i, '\0');
                }
        }
        for(int msNo = 0; msNo < 20; msNo++)
        {
                int startAddr = addrTb[msNo];
                if(msNo == 10)
                {
                        //SKIP
                }
                else if(msNo == 15 || msNo == 16)
                {
                        Serial.println(startAddr);
                        for(int m = 0; m < 80; m++)
                        {
                                ms[msNo][m] = EEPROM.read(startAddr + m);
                        }
                        Serial.println("RESTORED");
                }
                else
                {
                        Serial.println(startAddr);
                        for(int m = 0; m < 32; m++)
                        {
                                ms[msNo][m] = EEPROM.read(startAddr + m);
                        }
                        Serial.println("RESTORED");
                }
        }
}


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                           -- timer_interrupt --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
//AFSK TONE GENERATOR
void timer1_interrupt(void)
{
        static boolean toggle;
        
        toggle = toggle ^ 1;
        digitalWrite(12, toggle);
}

//5BIT BAUDOT GENERATOR AND DECODER
void timer2_interrupt(void)
{
        static boolean bit1;
        static boolean bit2;
        static boolean bit3;
        static boolean bit4;
        static boolean bit5;
        
        if(tRx == 0 && digitalRead(18) == 0)
        {
                tRx = 1;
                tRL = 1;
        }
        if(tRx == 0)
        {
                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;
                        }
                }
                if(rSq == 2 && ti == 22)
                {
                        bitWrite(baudot, 0, digitalRead(19));
                }
                else if(rSq == 2 && ti == 44)
                {
                        bitWrite(baudot, 1, digitalRead(19));
                }
                else if(rSq == 2 && ti == 66)
                {
                        bitWrite(baudot, 2, digitalRead(19));
                }
                else if(rSq == 2 && ti == 88)
                {
                        bitWrite(baudot, 3, digitalRead(19));
                }
                else if(rSq == 2 && ti == 110)
                {
                        bitWrite(baudot, 4, digitalRead(19));
                        if(eSq == 0)
                        {
                                dsp = 1;
                        }
                }
                else if(rSq == 2 && ti == 135)
                {
                        rSq = 0;
                }
        }
        else if(tRx == 1 || tRx == 2)
        {
                if(ddCnt < 2000)
                {
                        ddCnt++;
                }
                if(snd == 1)
                {
                        switch(ti)
                        {
                                case 0:
                                ddCnt = 0;
                                        digitalWrite(13, 0);
                                        Timer1.setPeriod(SPACE);
                                        bit1 = baudot & B00001;
                                        bit2 = baudot & B00010;
                                        bit3 = baudot & B00100;
                                        bit4 = baudot & B01000;
                                        bit5 = baudot & B10000;
                                        break;
                                case 22:
                                        digitalWrite(13, bit1);
                                        if(bit1){Timer1.setPeriod(MARK);}
                                            else{Timer1.setPeriod(SPACE);}
                                        break;
                                case 44:
                                        digitalWrite(13, bit2);
                                        if(bit2){Timer1.setPeriod(MARK);}
                                            else{Timer1.setPeriod(SPACE);}
                                        break;
                                case 66:
                                        digitalWrite(13, bit3);
                                        if(bit3){Timer1.setPeriod(MARK);}
                                            else{Timer1.setPeriod(SPACE);}
                                        break;
                                case 88:
                                        digitalWrite(13, bit4);
                                        if(bit4){Timer1.setPeriod(MARK);}
                                            else{Timer1.setPeriod(SPACE);}
                                        break;
                                case 110:
                                        digitalWrite(13, bit5);
                                        if(bit5){Timer1.setPeriod(MARK);}
                                            else{Timer1.setPeriod(SPACE);}
                                        break;
                                case 132:
                                        digitalWrite(13, 1);
                                        Timer1.setPeriod(MARK);
                                        break;
                                case 165:
                                        snd = 0;
                                        break;
                        }
                        ti++;
                }
        }
        if(tRx == 0 && eSq >= 2)
        {
                if(flshCnt == 250)
                {
                        digitalWrite(14, 1);
                }
                else if(flshCnt == 500)
                {
                        digitalWrite(14, 0);
                        flshCnt = 0;
                }
                flshCnt++;
        }
        else if(f1Stord == true)
        {
                switch(flshCnt)
                {
                        case 150:
                                digitalWrite(14, 0);
                                break;
                        case 300:
                                digitalWrite(14, 1);
                                break;
                        case 450:
                                digitalWrite(14, 0);
                                f1Stord = false;
                                break;
                }
                flshCnt++;
        }
        else if(empCh == true)
        {
                if(flshCnt == 230)
                {
                        digitalWrite(14, 0);
                        empCh = false;
                }
                flshCnt++;
        }
}


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                        -- OTHER FUNCTIONS etc --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
//DISPLAY CHARACTER
void lcdChOut()
{
        int i;
        
        if(lcdType == 0) //16x2
        {
                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);
        }
        else if(lcdType == 1) //20x4
        {
                lcd.print(ch);
                c[20 * y + x] = ch;
                x++;
                if(x == 20 && y <= 2)
                {
                        x = 0; y++;
                }
                else if(x == 20 && y == 3)
                {
                        for(i = 0; i < 60; i++)
                        {
                                c[i] = c[20 + i];
                        }
                        for(i = 0; i < 20; i++)
                        {
                                c[60 + i] = '\0';
                        }
                        lcd.clear();
                        lcd.noCursor();
                        for(y = 0; y < 3; y++)
                        {
                                lcd.setCursor(0, y);
                                for(i = 0; i < 20; i++)
                                {
                                        if(c[20 * y + i] == '\r' || c[20 * y + i] == '\0')
                                        {
                                                lcd.print(' ');
                                        }
                                        else
                                        {
                                                lcd.print(c[20 * y + i]);
                                        }
                                }
                        }
                        lcd.cursor();
                        x = 0; y = 3;
                }
                lcd.setCursor(x, y);
        }
}

//HANDLES BACKSPACE
void lcdBs()
{
        int i;
        
        if(lcdType == 0) //16x2
        {
                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[16 * y + x] = '\0';
        }
        else if(lcdType == 1) //20x4
        {
                x--;
                if(x == -1 && y >= 1)
                {
                        x = 19; y--;
                        while(c[20 * y + x] == '\0')
                        {
                                x--;
                        }
                }
                lcd.noCursor();
                lcd.setCursor(x, y);
                lcd.print(" ");
                lcd.setCursor(x, y);
                lcd.cursor();
                c[20 * y + x] = '\0';
        }
}

//HANDLES CRLF
void lcdCrLf()
{
        int i;
        
        if(lcdType == 0) //16x2
        {
                byte skip = (16 - x);
                
                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();
        }
        else if(lcdType == 1) //20x4
        {
                byte skip = (20 - x);
                
                lcd.noCursor();
                for(i = 0; i < skip; i++)
                {
                        if(i == 0)
                        {
                                c[20 * y + x] = '\r';
                        }
                        else
                        {
                                c[20 * y + x] = '\0';
                        }
                        x++;
                }
                if(y <= 2)
                {
                        x = 0; y++;
                }
                else if(y == 3)
                {
                        for(i = 0; i < 60; i++)
                        {
                                c[i] = c[20 + i];
                        }
                        for(i = 0; i < 20; i++)
                        {
                                c[60 + i] = '\0';
                        }
                        lcd.clear();
                        for(y = 0; y < 3; y++)
                        {
                                lcd.setCursor(0, y);
                                for(i = 0; i < 20; i++)
                                {
                                        if(c[20 * y + i] == '\r' || c[20 * y + i] == '\0')
                                        {
                                                lcd.print(' ');
                                        }
                                        else
                                        {
                                                lcd.print(c[20 * y + i]);
                                        }
                                }
                        }
                        x = 0; y = 3;
                }
                lcd.setCursor(x, y);
                lcd.cursor();
        }
}

//LOOK UP TABLE
void chTableT()
{
        if(usFig == 1) //"Fldigi" COMPATIBLE
        {
                fig_2 = -1;
                switch(ch){
                        case 'A': baudot = B00011; fig_2 = 0; break;
                        case 'B': baudot = B11001; fig_2 = 0; break;
                        case 'C': baudot = B01110; fig_2 = 0; break;
                        case 'D': baudot = B01001; fig_2 = 0; break;
                        case 'E': baudot = B00001; fig_2 = 0; break;
                        case 'F': baudot = B01101; fig_2 = 0; break;
                        case 'G': baudot = B11010; fig_2 = 0; break;
                        case 'H': baudot = B10100; fig_2 = 0; break;
                        case 'I': baudot = B00110; fig_2 = 0; break;
                        case 'J': baudot = B01011; fig_2 = 0; break;
                        case 'K': baudot = B01111; fig_2 = 0; break;
                        case 'L': baudot = B10010; fig_2 = 0; break;
                        case 'M': baudot = B11100; fig_2 = 0; break;
                        case 'N': baudot = B01100; fig_2 = 0; break;
                        case 'O': baudot = B11000; fig_2 = 0; break;
                        case 'P': baudot = B10110; fig_2 = 0; break;
                        case 'Q': baudot = B10111; fig_2 = 0; break;
                        case 'R': baudot = B01010; fig_2 = 0; break;
                        case 'S': baudot = B00101; fig_2 = 0; break;
                        case 'T': baudot = B10000; fig_2 = 0; break;
                        case 'U': baudot = B00111; fig_2 = 0; break;
                        case 'V': baudot = B11110; fig_2 = 0; break;
                        case 'W': baudot = B10011; fig_2 = 0; break;
                        case 'X': baudot = B11101; fig_2 = 0; break;
                        case 'Y': baudot = B10101; fig_2 = 0; break;
                        case 'Z': baudot = B10001; fig_2 = 0; break;
                        
                        case '0': baudot = B10110; fig_2 = 1; break;
                        case '1': baudot = B10111; fig_2 = 1; break;
                        case '2': baudot = B10011; fig_2 = 1; break;
                        case '3': baudot = B00001; fig_2 = 1; break;
                        case '4': baudot = B01010; fig_2 = 1; break;
                        case '5': baudot = B10000; fig_2 = 1; break;
                        case '6': baudot = B10101; fig_2 = 1; break;
                        case '7': baudot = B00111; fig_2 = 1; break;
                        case '8': baudot = B00110; fig_2 = 1; break;
                        case '9': baudot = B11000; fig_2 = 1; break;
                        case '-': baudot = B00011; fig_2 = 1; break;
                        case '?': baudot = B11001; fig_2 = 1; break;
                        case ':': baudot = B01110; fig_2 = 1; break;
                        case '(': baudot = B01111; fig_2 = 1; break;
                        case ')': baudot = B10010; fig_2 = 1; break;
                        case '.': baudot = B11100; fig_2 = 1; break;
                        case ',': baudot = B01100; fig_2 = 1; break;
                        case '/': baudot = B11101; fig_2 = 1; break;
                        
                        //"Fldigi" COMPATIBLE
                        case '$' : baudot = B01001; fig_2 = 1; break;
                        case '\'': baudot = B01011; fig_2 = 1; break;
                        case '!' : baudot = B01101; fig_2 = 1; break;
                        case '"' : baudot = B10001; fig_2 = 1; break;
                        case '#' : baudot = B10100; fig_2 = 1; break;
                        case '&' : baudot = B11010; fig_2 = 1; break;
                        case ';' : baudot = B11110; fig_2 = 1; break;
                        
                        case '\r':
                                baudot = B01000; //CR
                                crLf = 1;
                                break;
                        case ' ':
                                baudot = B00100; //SPACE
                                space = 1;
                                break;
                        
                        case PS2_ESC:
                                break;
                        case PS2_BACKSPACE:
                                break;
                        case PS2_DOWNARROW:
                                break;
                        case PS2_RIGHTARROW:
                                break;
                        case 14:
                        case 15:
                        case 16:
                        case 17:
                        case 18:
                        case 19:
                        case 20:
                        case 21:
                        case 22:
                        case 23:
                                break;
                        
                        default:
                                ch = ' ';
                                baudot = B00100; //SPACE
                                space = 1;
                                break;
                }
        }
        else if(usFig == 0) //"TONO THETA-5000E" COMPATIBLE
        {
                fig_2 = -1;
                switch(ch){
                        case 'A': baudot = B00011; fig_2 = 0; break;
                        case 'B': baudot = B11001; fig_2 = 0; break;
                        case 'C': baudot = B01110; fig_2 = 0; break;
                        case 'D': baudot = B01001; fig_2 = 0; break;
                        case 'E': baudot = B00001; fig_2 = 0; break;
                        case 'F': baudot = B01101; fig_2 = 0; break;
                        case 'G': baudot = B11010; fig_2 = 0; break;
                        case 'H': baudot = B10100; fig_2 = 0; break;
                        case 'I': baudot = B00110; fig_2 = 0; break;
                        case 'J': baudot = B01011; fig_2 = 0; break;
                        case 'K': baudot = B01111; fig_2 = 0; break;
                        case 'L': baudot = B10010; fig_2 = 0; break;
                        case 'M': baudot = B11100; fig_2 = 0; break;
                        case 'N': baudot = B01100; fig_2 = 0; break;
                        case 'O': baudot = B11000; fig_2 = 0; break;
                        case 'P': baudot = B10110; fig_2 = 0; break;
                        case 'Q': baudot = B10111; fig_2 = 0; break;
                        case 'R': baudot = B01010; fig_2 = 0; break;
                        case 'S': baudot = B00101; fig_2 = 0; break;
                        case 'T': baudot = B10000; fig_2 = 0; break;
                        case 'U': baudot = B00111; fig_2 = 0; break;
                        case 'V': baudot = B11110; fig_2 = 0; break;
                        case 'W': baudot = B10011; fig_2 = 0; break;
                        case 'X': baudot = B11101; fig_2 = 0; break;
                        case 'Y': baudot = B10101; fig_2 = 0; break;
                        case 'Z': baudot = B10001; fig_2 = 0; break;
                        
                        case '0': baudot = B10110; fig_2 = 1; break;
                        case '1': baudot = B10111; fig_2 = 1; break;
                        case '2': baudot = B10011; fig_2 = 1; break;
                        case '3': baudot = B00001; fig_2 = 1; break;
                        case '4': baudot = B01010; fig_2 = 1; break;
                        case '5': baudot = B10000; fig_2 = 1; break;
                        case '6': baudot = B10101; fig_2 = 1; break;
                        case '7': baudot = B00111; fig_2 = 1; break;
                        case '8': baudot = B00110; fig_2 = 1; break;
                        case '9': baudot = B11000; fig_2 = 1; break;
                        case '-': baudot = B00011; fig_2 = 1; break;
                        case '?': baudot = B11001; fig_2 = 1; break;
                        case ':': baudot = B01110; fig_2 = 1; break;
                        case '(': baudot = B01111; fig_2 = 1; break;
                        case ')': baudot = B10010; fig_2 = 1; break;
                        case '.': baudot = B11100; fig_2 = 1; break;
                        case ',': baudot = B01100; fig_2 = 1; break;
                        case '/': baudot = B11101; fig_2 = 1; break;
                        
                        //"TONO THETA-5000E" COMPATIBLE
                        case '\'': baudot = B00101; fig_2 = 1; break;
                        case '$' : baudot = B01001; fig_2 = 1; break;
                        case '!' : baudot = B01101; fig_2 = 1; break;
                        case '+' : baudot = B10001; fig_2 = 1; break;
                        case '#' : baudot = B10100; fig_2 = 1; break;
                        case '&' : baudot = B11010; fig_2 = 1; break;
                        case '=' : baudot = B11110; fig_2 = 1; break;
                        
                        case '\r':
                                baudot = B01000; //CR
                                crLf = 1;
                                break;
                        case ' ':
                                baudot = B00100; //SPACE
                                space = 1;
                                break;
                        
                        case PS2_ESC:
                                break;
                        case PS2_BACKSPACE:
                                break;
                        case PS2_DOWNARROW:
                                break;
                        case PS2_RIGHTARROW:
                                break;
                        case 14:
                        case 15:
                        case 16:
                        case 17:
                        case 18:
                        case 19:
                        case 20:
                        case 21:
                        case 22:
                        case 23:
                                break;
                        
                        default:
                                ch = ' ';
                                baudot = B00100; //SPACE
                                space = 1;
                                break;
                }
        }
}

void chConvt()
{
        if(jp106 == 1) //JP106 KEYBOARD
        {
                     if(ch == '@' ){ch = '"' ;}
                else if(ch == '^' ){ch = '&' ;}
                else if(ch == '&' ){ch = '\'';}
                else if(ch == '*' ){ch = '(' ;}
                else if(ch == '(' ){ch = ')' ;}
                else if(ch == ')' ){ch = '~' ;}
                else if(ch == '_' ){ch = '=' ;}
                else if(ch == '=' ){ch = '^' ;}
                else if(ch == '+' ){ch = '\0';}
                else if(ch == '[' ){ch = '@' ;}
                else if(ch == '{' ){ch = '`' ;}
                else if(ch == ']' ){ch = '[' ;}
                else if(ch == '}' ){ch = '{' ;}
                else if(ch == ':' ){ch = '+' ;}
                else if(ch == '\''){ch = ':' ;}
                else if(ch == '"' ){ch = '*' ;}
                else if(ch == '\\'){ch = ']' ;}
                else if(ch == '|' ){ch = '}' ;}
        }
        if(usFig == 1) //"Fldigi" SOFTWARE COMPATIBLE
        {
                if(ch >= 97 && ch <= 122) //CONVERT LOWER CASE TO UPPER CASE
                {
                        ch = ch - 32;
                }
                else if(ch == PS2_TAB       ){ch = '\0';} //IGNORE THESE KEYS
                else if(ch == PS2_DELETE    ){ch = '\0';}
                else if(ch == PS2_PAGEUP    ){ch = '\0';}
                else if(ch == PS2_PAGEDOWN  ){ch = '\0';}
                else if(ch == PS2_UPARROW   ){ch = '\0';}
                else if(ch == PS2_LEFTARROW ){ch = '\0';}
                else if(ch == 24            ){ch = '\0';}
                else if(ch == 25            ){ch = '\0';}
                else if(ch == '%'           ){ch = '\0';}
                else if(ch == '='           ){ch = '\0';}
                else if(ch == '^'           ){ch = '\0';}
                else if(ch == '~'           ){ch = '\0';}
                else if(ch == '|'           ){ch = '\0';}
                else if(ch == '@'           ){ch = '\0';}
                else if(ch == '`'           ){ch = '\0';}
                else if(ch == '['           ){ch = '\0';}
                else if(ch == '{'           ){ch = '\0';}
                else if(ch == '+'           ){ch = '\0';}
                else if(ch == '*'           ){ch = '\0';}
                else if(ch == ']'           ){ch = '\0';}
                else if(ch == '}'           ){ch = '\0';}
                else if(ch == '<'           ){ch = '\0';}
                else if(ch == '>'           ){ch = '\0';}
                else if(ch == '\\'          ){ch = '\0';}
                else if(ch == '_'           ){ch = '\0';}
        }
        else if(usFig == 0) //"TONO THETA-5000E" COMPATIBLE
        {
                if(ch >= 97 && ch <= 122) //CONVERT LOWER CASE TO UPPER CASE
                {
                        ch = ch - 32;
                }
                else if(ch == PS2_TAB       ){ch = '\0';} //IGNORE THESE KEYS
                else if(ch == PS2_DELETE    ){ch = '\0';}
                else if(ch == PS2_PAGEUP    ){ch = '\0';}
                else if(ch == PS2_PAGEDOWN  ){ch = '\0';}
                else if(ch == PS2_UPARROW   ){ch = '\0';}
                else if(ch == PS2_LEFTARROW ){ch = '\0';}
                else if(ch == 24            ){ch = '\0';}
                else if(ch == 25            ){ch = '\0';}
                else if(ch == '"'           ){ch = '\0';}
                else if(ch == '%'           ){ch = '\0';}
                else if(ch == '^'           ){ch = '\0';}
                else if(ch == '~'           ){ch = '\0';}
                else if(ch == '|'           ){ch = '\0';}
                else if(ch == '@'           ){ch = '\0';}
                else if(ch == '`'           ){ch = '\0';}
                else if(ch == '['           ){ch = '\0';}
                else if(ch == '{'           ){ch = '\0';}
                else if(ch == ';'           ){ch = '\0';}
                else if(ch == '*'           ){ch = '\0';}
                else if(ch == ']'           ){ch = '\0';}
                else if(ch == '}'           ){ch = '\0';}
                else if(ch == '<'           ){ch = '\0';}
                else if(ch == '>'           ){ch = '\0';}
                else if(ch == '\\'          ){ch = '\0';}
                else if(ch == '_'           ){ch = '\0';}
        }
}

void chFlush()
{
        while(keyboard.available())
        {
                ch = keyboard.read();
        }
        for(int i = 0; i < 4; i++)
        {
                keyBuf[i] = '\0';
        }
}

void chTableR()
{
        if(usFig == 1) //"Fldigi" COMPATIBLE
        {
                ch = '\0';
                     if(baudot == B11111){fig = 0; } //LETTERS
                else if(baudot == B11011){fig = 1; } //FIGURES            
                else if(baudot == B01000){         } //CR
                else if(baudot == B00010){ch = ' ';} //LF
                else if(baudot == B00100){ch = ' ';} //SPACE
                if(fig == 0)
                {
                             if(baudot == B00011){ch = 'A';}
                        else if(baudot == B11001){ch = 'B';}
                        else if(baudot == B01110){ch = 'C';}
                        else if(baudot == B01001){ch = 'D';}
                        else if(baudot == B00001){ch = 'E';}
                        else if(baudot == B01101){ch = 'F';}
                        else if(baudot == B11010){ch = 'G';}
                        else if(baudot == B10100){ch = 'H';}
                        else if(baudot == B00110){ch = 'I';}
                        else if(baudot == B01011){ch = 'J';}
                        else if(baudot == B01111){ch = 'K';}
                        else if(baudot == B10010){ch = 'L';}
                        else if(baudot == B11100){ch = 'M';}
                        else if(baudot == B01100){ch = 'N';}
                        else if(baudot == B11000){ch = 'O';}
                        else if(baudot == B10110){ch = 'P';}
                        else if(baudot == B10111){ch = 'Q';}
                        else if(baudot == B01010){ch = 'R';}
                        else if(baudot == B00101){ch = 'S';}
                        else if(baudot == B10000){ch = 'T';}
                        else if(baudot == B00111){ch = 'U';}
                        else if(baudot == B11110){ch = 'V';}
                        else if(baudot == B10011){ch = 'W';}
                        else if(baudot == B11101){ch = 'X';}
                        else if(baudot == B10101){ch = 'Y';}
                        else if(baudot == B10001){ch = 'Z';}
                }
                else if(fig == 1)
                {
                             if(baudot == B10110){ch = '0' ;}
                        else if(baudot == B10111){ch = '1' ;}
                        else if(baudot == B10011){ch = '2' ;}
                        else if(baudot == B00001){ch = '3' ;}
                        else if(baudot == B01010){ch = '4' ;}
                        else if(baudot == B10000){ch = '5' ;}
                        else if(baudot == B10101){ch = '6' ;}
                        else if(baudot == B00111){ch = '7' ;}
                        else if(baudot == B00110){ch = '8' ;}
                        else if(baudot == B11000){ch = '9' ;}
                        else if(baudot == B00011){ch = '-' ;}
                        else if(baudot == B11001){ch = '?' ;}
                        else if(baudot == B01110){ch = ':' ;}
                        else if(baudot == B01111){ch = '(' ;}
                        else if(baudot == B10010){ch = ')' ;}
                        else if(baudot == B11100){ch = '.' ;}
                        else if(baudot == B01100){ch = ',' ;}
                        else if(baudot == B11101){ch = '/' ;}
                        
                        //"Fldigi" SOFTWARE COMPATIBLE
                        else if(baudot == B01001){ch = '$' ;}
                        else if(baudot == B01011){ch = '\'';}
                        else if(baudot == B01101){ch = '!' ;}
                        else if(baudot == B10001){ch = '"' ;}
                        else if(baudot == B10100){ch = '#' ;}
                        else if(baudot == B11010){ch = '&' ;}
                        else if(baudot == B11110){ch = ';' ;}
                        else if(baudot == B00101){          } //BELL
                }
        }
        else if(usFig == 0) //"TONO THETA-5000E" COMPATIBLE
        {
                ch = '\0';
                     if(baudot == B11111){fig = 0; } //LETTERS
                else if(baudot == B11011){fig = 1; } //FIGURES            
                else if(baudot == B01000){         } //CR
                else if(baudot == B00010){ch = ' ';} //LF
                else if(baudot == B00100){ch = ' ';} //SPACE
                if(fig == 0)
                {
                             if(baudot == B00011){ch = 'A';}
                        else if(baudot == B11001){ch = 'B';}
                        else if(baudot == B01110){ch = 'C';}
                        else if(baudot == B01001){ch = 'D';}
                        else if(baudot == B00001){ch = 'E';}
                        else if(baudot == B01101){ch = 'F';}
                        else if(baudot == B11010){ch = 'G';}
                        else if(baudot == B10100){ch = 'H';}
                        else if(baudot == B00110){ch = 'I';}
                        else if(baudot == B01011){ch = 'J';}
                        else if(baudot == B01111){ch = 'K';}
                        else if(baudot == B10010){ch = 'L';}
                        else if(baudot == B11100){ch = 'M';}
                        else if(baudot == B01100){ch = 'N';}
                        else if(baudot == B11000){ch = 'O';}
                        else if(baudot == B10110){ch = 'P';}
                        else if(baudot == B10111){ch = 'Q';}
                        else if(baudot == B01010){ch = 'R';}
                        else if(baudot == B00101){ch = 'S';}
                        else if(baudot == B10000){ch = 'T';}
                        else if(baudot == B00111){ch = 'U';}
                        else if(baudot == B11110){ch = 'V';}
                        else if(baudot == B10011){ch = 'W';}
                        else if(baudot == B11101){ch = 'X';}
                        else if(baudot == B10101){ch = 'Y';}
                        else if(baudot == B10001){ch = 'Z';}
                }
                else if(fig == 1)
                {
                             if(baudot == B10110){ch = '0' ;}
                        else if(baudot == B10111){ch = '1' ;}
                        else if(baudot == B10011){ch = '2' ;}
                        else if(baudot == B00001){ch = '3' ;}
                        else if(baudot == B01010){ch = '4' ;}
                        else if(baudot == B10000){ch = '5' ;}
                        else if(baudot == B10101){ch = '6' ;}
                        else if(baudot == B00111){ch = '7' ;}
                        else if(baudot == B00110){ch = '8' ;}
                        else if(baudot == B11000){ch = '9' ;}
                        else if(baudot == B00011){ch = '-' ;}
                        else if(baudot == B11001){ch = '?' ;}
                        else if(baudot == B01110){ch = ':' ;}
                        else if(baudot == B01111){ch = '(' ;}
                        else if(baudot == B10010){ch = ')' ;}
                        else if(baudot == B11100){ch = '.' ;}
                        else if(baudot == B01100){ch = ',' ;}
                        else if(baudot == B11101){ch = '/' ;}
                        
                        //"TONO THETA-5000E" COMPATIBLE
                        else if(baudot == B00101){ch = '\'';}
                        else if(baudot == B01001){ch = '$' ;}
                        else if(baudot == B01101){ch = '!' ;}
                        else if(baudot == B10001){ch = '+' ;}
                        else if(baudot == B10100){ch = '#' ;}
                        else if(baudot == B11010){ch = '&' ;}
                        else if(baudot == B11110){ch = '=' ;}
                        else if(baudot == B01011){          } //BELL
                }
        }
}

void chSend1()
{
        if(fig_1 == 0 && fig_2 == 1) //SHIFT "UP"
        {
                baudot_ = baudot; //EVACUATE
                baudot = B11011; //SEND FIGURE CODE FIRST
                shift = 1;
        }
        else if(fig_1 == 1 && fig_2 == 0) //SHIFT "DOWN"
        {
                baudot_ = baudot; //EVACUATE
                baudot = B11111; //SEND LETTER CODE FIRST
                shift = 1;
        }
        else if(space == 1 && fig_2 == 1) //FIGURE AFTER SPACE (TX_UOS)
        {
                baudot_ = baudot; //EVACUATE
                baudot = B11011; //SEND FIGURE CODE FIRST
                shift = 1;
        }
        if(shift != 1 && crLf != 1)
        {
                lcdChOut();
        }
        if(fig_2 == 0 || fig_2 == 1)
        {
                space = 0;
                fig_1 = fig_2; //REGISTER LAST STATE (EXCEPT SPACE, CR&LF)
        }
        ti = 0; snd = 1; //SEND(1)
}

void chSend2()
{
        if(shift == 1) //2ND BYTE AFTER SENDING SHIFT CODE
        {
                baudot = baudot_; //RESTORE
                lcdChOut();
                shift = 0;
                ti = 0; snd = 1; //SEND(2)
        }
        else if(crLf == 1) //2ND BYTE AFTER SENDING "CR"
        {
                baudot = B00010; //LF
                lcdCrLf();
                crLf = 0;
                ti = 0; snd = 1; //SEND(2)
        }
}


////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//                             -- MAIN LOOP --
//
////////////////////////////////////////////////////////////////////////////////
                                        ////////////////////////////////////////
void loop()
{
        static boolean  esc;
        static int      msNo = -1;
        static int      msNo_;
        static byte     m;
        static byte     n;
        static byte     o;
        static char     mnBuf[8];
        static char     editBuf[81];
        static char     ch2;
        
        if(tRx == 0) //RX
        {
                if(eSq > 0) //EDIT MODE
                {
                        switch(eSq)
                        {
                                case 1: //PLAYBACK
                                
                                        ch = ms[msNo][m]; //READ MESSAGE
                                        if(ch == '\0') //END OF MESSAGE
                                        {
                                                if(m == 0) //EMPTY
                                                {
                                                        msNo_ = msNo;
                                                        msNo = 20;
                                                }
                                                else
                                                {
                                                        if(msNo == 20)
                                                        {
                                                                msNo = msNo_;
                                                        }
                                                        if(x != 0)
                                                        {
                                                                lcdCrLf();
                                                        }
                                                        chFlush();
                                                        for(m = 0; m < 80; m++)
                                                        {
                                                                editBuf[m] = '\0';
                                                        }
                                                        m = 0;
                                                        flshCnt = 0;
                                                        digitalWrite(14, 0);
                                                        eSq = 2;
                                                }
                                        }
                                        else
                                        {
                                                if(ch == '\r')
                                                {
                                                        lcdCrLf();
                                                }
                                                else
                                                {
                                                        lcdChOut();
                                                }
                                                delay(120); //--
                                                m++;
                                        }
                                        if(keyboard.available())
                                        {
                                                ch2 = keyboard.read();
                                                if(ch2 == PS2_RIGHTARROW) //SKIP
                                                {
                                                        if(msNo == 20)
                                                        {
                                                                msNo = msNo_;
                                                        }
                                                        if(x != 0)
                                                        {
                                                                lcdCrLf();
                                                        }
                                                        chFlush();
                                                        for(m = 0; m < 80; m++)
                                                        {
                                                                editBuf[m] = '\0';
                                                        }
                                                        m = 0;
                                                        flshCnt = 0;
                                                        digitalWrite(14, 0);
                                                        eSq = 2;
                                                }
                                        }
                                        break;
                                        
                                case 2: //INPUT
                                        
                                        while(keyboard.available())
                                        {
                                                ch = keyboard.read();
                                                chConvt();
                                                if(ch != '\0')
                                                {
                                                        switch(ch)
                                                        {
                                                                case PS2_ESC: //QUIT
                                                                        if(x != 0)
                                                                        {
                                                                                lcdCrLf();
                                                                        }
                                                                        chFlush();
                                                                        msNo = -1;
                                                                        esc = 0; digitalWrite(14, 0);
                                                                        eSq = 0;
                                                                        break;
                                                                
                                                                case PS2_DOWNARROW: //OVERWRITE?
                                                                        if(x != 0)
                                                                        {
                                                                                lcdCrLf();
                                                                        }
                                                                        msNo_ = msNo;
                                                                        msNo = 21;
                                                                        m = 0;
                                                                        eSq = 3;
                                                                        break;
                                                                
                                                                case '\r':
                                                                        if(msNo == 10)
                                                                        {
                                                                                if(m < 16  )
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdCrLf();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        else if(msNo == 15 || msNo == 16)
                                                                        {
                                                                                if(m < 80)
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdCrLf();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        else
                                                                        {
                                                                                if(m < 32)
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdCrLf();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        break;
                                                                
                                                                case PS2_BACKSPACE:
                                                                        if(m > 0)
                                                                        {
                                                                                if(x > 0 || y > 0)
                                                                                {
                                                                                        m--;
                                                                                        editBuf[m] = '\0';
                                                                                        lcdBs();
                                                                                }
                                                                        }
                                                                        break;
                                                                
                                                                case PS2_RIGHTARROW:
                                                                        break;
                                                                case 14:
                                                                case 15:
                                                                case 16:
                                                                case 17:
                                                                case 18:
                                                                case 19:
                                                                case 20:
                                                                case 21:
                                                                case 22:
                                                                case 23:
                                                                        break;
                                                                
                                                                default:
                                                                        if(msNo == 10)
                                                                        {
                                                                                if(m < 16  )
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdChOut();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        else if(msNo == 15 || msNo == 16)
                                                                        {
                                                                                if(m < 80)
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdChOut();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        else
                                                                        {
                                                                                if(m < 32)
                                                                                {
                                                                                        editBuf[m] = ch;
                                                                                        lcdChOut();
                                                                                        m++;
                                                                                }
                                                                        }
                                                                        break;
                                                        }
                                                }
                                        }
                                        break;
                                        
                                case 3: //ALERT
                                
                                        ch = ms[msNo][m]; //READ MESSAGE
                                        if(ch == '\0') //END OF MESSAGE
                                        {
                                                msNo = msNo_;
                                                if(x != 0)
                                                {
                                                        lcdCrLf();
                                                }
                                                chFlush();
                                                eSq = 4;
                                        }
                                        else
                                        {
                                                lcdChOut();
                                                delay(75); //--
                                                m++;
                                        }
                                        break;
                                        
                                case 4: //CONFIRM
                                
                                        while(keyboard.available())
                                        {
                                                ch = keyboard.read();
                                                if(ch != '\0')
                                                {
                                                        if(ch == PS2_ESC) //QUIT
                                                        {
                                                                chFlush();
                                                                esc = 0; digitalWrite(14, 0);
                                                                eSq = 0;
                                                        }
                                                        else if(ch == PS2_DOWNARROW) //TYPE AGAIN - SAVE
                                                        {
                                                                int startAddr = addrTb[msNo];
                                                                if(msNo == 10)
                                                                {
                                                                        for(m = 0; m < 16; m++)
                                                                        {
                                                                                ms[msNo][m] = editBuf[m];
                                                                        }
                                                                }
                                                                else if(msNo == 15 || msNo == 16)
                                                                {
                                                                        for(m = 0; m < 80; m++)
                                                                        {
                                                                                ms[msNo][m] = editBuf[m];
                                                                        }
                                                                        
                                                                        Serial.println(startAddr);
                                                                        for(m = 0; m < 80; m++)
                                                                        {
                                                                                EEPROM.write(startAddr + m, editBuf[m]);
                                                                        }
                                                                        EEPROM.write(startAddr + 80, '\0');
                                                                        Serial.println("SAVED!");
                                                                }
                                                                else
                                                                {
                                                                        for(m = 0; m < 32; m++)
                                                                        {
                                                                                ms[msNo][m] = editBuf[m];
                                                                        }
                                                                        
                                                                        Serial.println(startAddr);
                                                                        for(m = 0; m < 32; m++)
                                                                        {
                                                                                EEPROM.write(startAddr + m, editBuf[m]);
                                                                        }
                                                                        EEPROM.write(startAddr + 32, '\0');
                                                                        Serial.println("SAVED!");
                                                                }
                                                                msNo = 22;
                                                                m = 0;
                                                                eSq = 5;
                                                        }
                                                }
                                        }
                                        break;
                                        
                                case 5: //DONE
                                
                                        ch = ms[msNo][m]; //READ MESSAGE
                                        if(ch == '\0') //END OF MESSAGE
                                        {
                                                if(x != 0)
                                                {
                                                        lcdCrLf();
                                                }
                                                chFlush();
                                                esc = 0; digitalWrite(14, 0); //RETURN
                                                eSq = 0;
                                        }
                                        else
                                        {
                                                lcdChOut();
                                                delay(120); //--
                                                m++;
                                        }
                                        break;
                        }
                }
                else if(keyboard.available())
                {
                        ch = keyboard.read();
                        chConvt();
                        if(ch != '\0')
                        {
                                if(ch == PS2_ESC) //HANDLES [Esc] KEY
                                {
                                        esc = esc ^ 1;
                                        digitalWrite(14, esc);
                                        eSq = 0;
                                        
                                }
                                else if(esc == 1)
                                {
                                        if(ch >= 48 && ch <= 57) //'0'-'9'
                                        {
                                                msNo = ch - 48; //WHEN esc=1 AND A NUMBER KEY IS TYPED, START MESSAGE PLAYBACK
                                                //--Ini
                                                m = 0;
                                                o = 0;
                                                for(int i = 0; i < 80; i++)
                                                {
                                                        editBuf[i] = '\0';
                                                }
                                                //--
                                                if(x != 0)
                                                {
                                                        lcdCrLf();
                                                }
                                                eSq = 1;
                                        }
                                        else if(ch >= 14 && ch <= 23) //'F1'-'F10'
                                        {
                                                msNo = ch - 4; //WHEN esc=1 AND A FUNCTION KEY IS TYPED, START MESSAGE PLAYBACK
                                                //--Ini
                                                m = 0;
                                                o = 0;
                                                for(int i = 0; i < 80; i++)
                                                {
                                                        editBuf[i] = '\0';
                                                }
                                                //--
                                                if(x != 0)
                                                {
                                                        lcdCrLf();
                                                }
                                                eSq = 1;
                                        }
                                }
                                else if(esc == 0)
                                {
                                        if(ch >= 14 && ch <= 23) //'F1'-'F10'
                                        {
                                                esc = 1;
                                                digitalWrite(14, 1);
                                                
                                                msNo = ch - 4; //WHEN esc=0 AND A FUNCTION KEY IS TYPED, START MESSAGE PLAYBACK
                                                //--Ini
                                                m = 0;
                                                o = 0;
                                                for(int i = 0; i < 80; i++)
                                                {
                                                        editBuf[i] = '\0';
                                                }
                                                //--
                                                if(x != 0)
                                                {
                                                        lcdCrLf();
                                                }
                                                eSq = 1;
                                        }
                                }
                        }
                }
                else if(dsp == 1)
                {
                        chTableR();
                        if(ch != '\0')
                        {
                                lcdChOut();
                        }
                        dsp = 0;
                }
        }
        else if(tRx == 1) //RX to TX
        {
                if(snd == 0)
                {        
                        if(tRL == 1) //1st loop
                        {
                                chFlush();
                                msNo = -1;
                                esc  =  0; digitalWrite(14, 0);
                                eSq  =  0;
                                digitalWrite(15, 1); //PTT ON
                                Timer1.attachInterrupt(timer1_interrupt, MARK); //SOUND ON
                                delay(180);
                                //--
                                baudot = B01000; //-- CR --
                                ti = 0; snd = 1;
                                //--
                                tRL = 2;
                        }
                        else if(tRL == 2) //2nd loop
                        {
                                lcdCrLf();
                                //--
                                baudot = B00010; //-- LF --
                                ti = 0; snd = 1;
                                //--
                                tRL = 3;
                        }
                        else if(tRL == 3) //3rd loop
                        {
                                fig_1 = 0;
                                //--
                                baudot = B11111; //-- LTR (INITIALIZE "HIS/HER" DECODER) --
                                ti = 0; snd = 1;
                                //--
                                tRx = 2;
                        }
                }
        }
        else if(tRx == 2) //TX
        {
                int  i;
                
                //snd 0,1
                if(keyboard.available())
                {
                        if(keyBuf[3] == '\0')
                        {
                                for(i = 0; i < 4; i++) //SEEK POSITION
                                {
                                        if(keyBuf[i] == '\0')
                                        {
                                                break;
                                        }
                                }
                                char ch3 = keyboard.read();
                                if(ch3 == PS2_ESC) //CHECK [ESC]
                                {
                                        if(esc == 1)
                                        {
                                                msNo = -1;
                                                n = 0;
                                                esc = 0; digitalWrite(14, 0);
                                        }
                                        else
                                        {       
                                                esc = 1; digitalWrite(14, 1);
                                        }
                                }
                                else
                                {
                                        keyBuf[i] = ch3; //PUSH
                                }
                        }
                }
                if(snd == 0)
                {
                        if(shift == 1 || crLf == 1) //TOP PRIORITY (WHEN 2ND BYTE IS NEEDED)
                        {
                                chSend2();
                        }
                        else if(esc == 1 && msNo >= 0) //HANDLES MEMORY MESSAGES
                        {
                                if(digitalRead(18) == 1) //CHECK SW
                                {
                                        msNo = -1;
                                        n = 0;
                                        goto exitTx;
                                }
                                while(keyBuf[0] != '\0') //ALWAYS CHECK KEYBOARD
                                {
                                        //--keyBuf.read
                                        ch2 = keyBuf[0];
                                        for(i = 0; i < 4; i++)
                                        {
                                                keyBuf[i] = keyBuf[i + 1];
                                        }
                                        //--
                                        if(ch2 >= 48 && ch2 <= 57) //'0'-'9'
                                        {
                                                if(n < 7)
                                                {
                                                        mnBuf[n] = ch2; //REGISTER ADDITIONAL MESSAGE-NUMBERS, 7 NUMBERS AT MAXIMUM
                                                        n++;
                                                }
                                        }
                                        else if(ch2 >= 14 && ch2 <= 23) //'F1'-'F10'
                                        {
                                                if(n < 7)
                                                {
                                                        mnBuf[n] = ch2; //REGISTER ADDITIONAL MESSAGE-NUMBERS, 7 NUMBERS AT MAXIMUM
                                                        n++;
                                                }
                                        }
                                }
                                
                                ch = ms[msNo][m]; //READ MESSAGE
                                if(ch == '\0') //END OF MESSAGE
                                {
                                        if(m == 0 && n == 0) //EMPTY CH
                                        {
                                                flshCnt = 0;
                                                empCh = true;
                                                esc = 0;
                                        }
                                        else if(n == 0) //NO MESSAGE-NUMBER, EXIT
                                        {
                                                esc = 0; digitalWrite(14, 0);
                                        }
                                        msNo = -1;
                                }
                                
                                if(msNo >= 0) //--SEND MEMORY--
                                {
                                        chTableT();
                                        chSend1();
                                        m++;
                                }
                        }
                        else if(esc == 1 && n > 0) //COMPLETED SENDING <ONE> MESSAGE, AND OTHERS STILL REMAIN
                        {
                                ch = mnBuf[o]; //READ NUMBER
                                if(ch >= 48 && ch <= 57) //'0'-'9'
                                {
                                        msNo = ch - 48; //SPECIFY THE NEXT
                                        m = 0;
                                        o++;
                                }
                                else if(ch >= 14 && ch <= 23) //'F1'-'F10'
                                {
                                        msNo = ch - 4; //SPECIFY THE NEXT
                                        m = 0;
                                        o++;
                                }
                                else if(ch == '\0') //END OF MESSAGE-NUMBERS, EXIT
                                {
                                        n = 0;
                                        esc = 0; digitalWrite(14, 0);
                                }
                        }
                        else if(keyBuf[0] != '\0') //COMPLETED SENDING <ALL> MESSAGES, AND KEYBOARD IS TYPED
                        {
                                if(digitalRead(18) == 1) //CHECK SW
                                {
                                        goto exitTx;
                                }
                                //--keyBuf.read
                                ch = keyBuf[0];
                                for(i = 0; i < 4; i++)
                                {
                                        keyBuf[i] = keyBuf[i + 1];
                                }
                                //--
                                chConvt();
                                if(ch != '\0')
                                {
                                        chTableT();
                                        if(esc == 1)
                                        {
                                                if(ch >= 48 && ch <= 57) //'0'-'9'
                                                {
                                                        msNo = ch - 48; //WHEN esc=1 AND A NUMBER KEY IS TYPED, START SENDING A NEW MESSAGE
                                                        //--Ini
                                                        m = 0;
                                                        o = 0;
                                                        for(int i = 0; i < 7; i++)
                                                        {
                                                                mnBuf[i] = '\0';
                                                        }
                                                        //--
                                                }
                                                else if(ch >= 14 && ch <= 23) //'F1'-'F10'
                                                {
                                                        msNo = ch - 4; //WHEN esc=1 AND A FUNCTION KEY IS TYPED, START SENDING A NEW MESSAGE
                                                        //--Ini
                                                        m = 0;
                                                        o = 0;
                                                        for(int i = 0; i < 7; i++)
                                                        {
                                                                mnBuf[i] = '\0';
                                                        }
                                                        //--
                                                }
                                        }
                                        else if(esc == 0)
                                        {
                                                if(ch >= 14 && ch <= 23) //'F1'-'F10'
                                                {
                                                        esc = 1;
                                                        digitalWrite(14, 1);
                                                        
                                                        msNo = ch - 4; //WHEN esc=0 AND A FUNCTION KEY IS TYPED, START 20CH MEMORY MODE
                                                        //--Ini
                                                        m = 0;
                                                        o = 0;
                                                        for(int i = 0; i < 7; i++)
                                                        {
                                                                mnBuf[i] = '\0';
                                                        }
                                                        //--
                                                }
                                                else if(ch == PS2_DOWNARROW) //SAVE LAST WORD TO [F1]
                                                {
                                                        int m;
                                                        int i;
                                                        int msNo = 10; //[F1]
                                                        int endPos;
                                                        
                                                             if(lcdType == 0){i = y * 16 + x;} //CALC POSITION
                                                        else if(lcdType == 1){i = y * 20 + x;}
                                                        endPos = i;
                                                        
                                                        //SEEK LAST WORD
                                                        i--;
                                                        while(c[i] == ' ' || c[i] == '\0' || c[i] == '\r' && i >= 0)
                                                        {
                                                                i--;
                                                        }
                                                        while(c[i] != ' ' && c[i] != '\0' && c[i] != '\r' && i >= 0)
                                                        {
                                                                i--;
                                                        }
                                                        i++;
                                                        for(m = 0; m < 16; m++) //CLEAR [F1]
                                                        {
                                                                ms[msNo][m] = '\0';
                                                        }
                                                        m = 0;
                                                        while(c[i] != ' ' && c[i] != '\0' && c[i] != '\r' && i < endPos) //SAVE LAST WORD + ONE SPACE
                                                        {
                                                                ms[msNo][m] = c[i];
                                                                i++;
                                                                m++;
                                                                if(m == 16)
                                                                {
                                                                        break;
                                                                }
                                                        }
                                                        if(m < 16)
                                                        {
                                                                ms[msNo][m] = ' ';
                                                        }
                                                        
                                                        //DONE
                                                        digitalWrite(14, 1);
                                                        flshCnt = 0;
                                                        f1Stord = true;
                                                }
                                                else if(ch == PS2_RIGHTARROW || ch == PS2_BACKSPACE) //IGNORE THESE KEYS
                                                {
                                                        /////
                                                }
                                                else //--SEND FROM KEYBOARD--
                                                {
                                                        chSend1();
                                                }
                                        }
                                }
                        }
                        else
                        {
                                if(digitalRead(18) == 1) //CHECK SW
                                {
                                        exitTx: //-LABEL-
                                        delay(370); //LONG TONE
                                        digitalWrite(15, 0); //PTT OFF
                                        Timer1.detachInterrupt(); //SOUND OFF
                                        if(x != 0)
                                        {
                                                lcdCrLf();
                                        }
                                        esc = 0; digitalWrite(14, 0);
                                        snd = 0;
                                        rSq = 0;
                                        fig = 0;
                                        dsp = 0;
                                        tRx = 0;
                                }
                                else //NOTHING TO PROCESS, DIDDLE
                                {
                                        if(ddl == 1 && ddCnt > ddItv)
                                        {
                                                fig_1 = 0;
                                                baudot = B11111; //LTR (DIDDLE)
                                                ti = 0; snd = 1;
                                        }
                                }
                        }
                }
        }
}