/* tv_terminal - terminal software for Arduino/TellyMate text terminal. Copyright (C) 2010 Yana Artishcheva tv_terminal is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. tv_terminal is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with AdVegam Server; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA E-mail: yana_artis @ advegam . com (remove "anti-spam" spaces) */ #include byte decode_D090_D0BF[] PROGMEM = {0xE1,0xE2,0xF7,0xE7,0xE4,0xE5,0xF6,0xFA,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, // А-О 0xF0,0xF2,0xF3,0xF4,0xF5,0xE6,0xE8,0xE3,0xFE,0xFB,0xFD,0xFF,0xF9,0xF8,0xFC,0xE0,0xF1, // П-Я 0xC1,0xC2,0xD7,0xC7,0xC4,0xC5,0xD6,0xDA,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0 // а-п }; byte decode_D180_D18F[] PROGMEM = {0xD2,0xD3,0xD4,0xD5,0xC6,0xC8,0xC3,0xDE,0xDB,0xDD,0xDF,0xD9,0xD8,0xDC,0xC0,0xD1}; // р-я #define SCR_WIDTH (38) #define SCR_HEIGHT (25) #define BUF_LEN (16) byte buf[BUF_LEN]; byte bufLen = 0; #define CHAR_ESC "\x1B" void cursor_move( uint8_t row , uint8_t col ) { // Yrc Serial.print( CHAR_ESC "Y" ) ; Serial.print((unsigned char)(32 + row)) ; Serial.print((unsigned char)(32 + col)) ; } void cursor_show( bool show ) { // e or f Serial.print( CHAR_ESC ) ; Serial.print( show?'e':'f' ) ; } void screen_clear( void ) { // E Serial.print( CHAR_ESC "E" ); } void setup() { Serial.begin( 57600 ); // set to 57600 baud cursor_show( true ); // turn the cursor off cursor_move(0, 0); bufLen = 0; } int counter=0; void loop() { int ch; while (Serial.available() > 0) { ch = -1; buf[bufLen] = Serial.read(); switch (bufLen) { case 0: switch (buf[0]) { case 27: bufLen = 1; break; case 10: Serial.println(""); counter = 0; break; default: if (buf[0] < 0xC0) { ch = buf[0]; } else { bufLen = 1; } break; } // switch(buf[0]) break; // case bufLen == 0 case 1: ++bufLen; if (buf[0] == 27) { switch (buf[1]) { case 'A': case 'H': case 'I': case 'J': case 'Y': Serial.print(char(27)); Serial.print(char(buf[1])); bufLen = 0; break; case '[': break; default: Serial.print(char(27)); Serial.print(char(buf[1])); bufLen = 0; break; } } else if ((buf[0] & 0xE0) == 0xC0) { // Cyrillic letter ch = ((unsigned int)buf[0] << 8) | (unsigned int)buf[1]; if ((ch > 0xD08F) && (ch < 0xD0C0)) { ch = pgm_read_byte( &decode_D090_D0BF[ch - 0xD090]); } else if ((ch > 0xD17F) && (ch < 0xD190)) { ch = pgm_read_byte( &decode_D180_D18F[ch - 0xD180]); } else if (ch == 0xD081) { // Ё ch = 0xB3; } else if (ch == 0xD191) { // ё ch = 0xA3; } else { ch = 127; } } break; // case bufLen == 1 default: // case bufLen > 1 ++bufLen; if (buf[0] == 27) { if (buf[bufLen-1] == 'm') { // Execute command stored in buffer (we'll do it later - now just skip the command) bufLen = 0; } } else if ((buf[0] & 0xF0) == 0xE0) { if (bufLen == 3) { ch = ((unsigned int)buf[0] << 16) | ((unsigned int)buf[1] << 8) | (unsigned int)buf[2]; switch (ch) { case 0xE29480: ch = 0x80; //0xC4; break; case 0xE29482: ch = 0x81; //0xB3; break; case 0xE2948C: ch = 0x82; //0xDA; break; case 0xE29490: ch = 0x83; //0xBF; break; case 0xE29494: ch = 0x84; //0xC0; break; case 0xE29498: ch = 0x85; //0xD9; break; case 0xE2949C: ch = 0x86; //0xC3; break; case 0xE294A4: ch = 0x87; //0xB4; break; case 0xE294AC: ch = 0x88; //0xC2; break; case 0xE294B4: ch = 0x89; //0xC1; break; case 0xE294BC: ch = 0x8A; //0xC5; break; case 0xE29590: ch = 0xA0; //0xCD; break; case 0xE29591: ch = 0xA1; //0xBA; break; case 0xE29592: ch = 0xA2; //0xD5; break; case 0xE29593: ch = 0xA4; //0xD6; break; case 0xE29594: ch = 0xA5; //0xC9; break; case 0xE29595: ch = 0xA6; //0xB8; break; case 0xE29596: ch = 0xA7; //0xB7; break; case 0xE29597: ch = 0xA8; //0xBB; break; case 0xE29598: ch = 0xA9; //0xD4; break; case 0xE29599: ch = 0xAA; //0xD3; break; case 0xE2959A: ch = 0xAB; //0xC8; break; case 0xE2959B: ch = 0xAC; //0xBE; break; case 0xE2959C: ch = 0xAD; //0xBD; break; case 0xE2959D: ch = 0xAE; //0xBC; break; case 0xE2959E: ch = 0xAF; //0xC6; break; case 0xE2959F: ch = 0xB0; //0xC7; break; case 0xE295A0: ch = 0xB1; //0xCC; break; case 0xE295A1: ch = 0xB2; //0xB5; break; case 0xE295A2: ch = 0xB4; //0xB6; break; case 0xE295A3: ch = 0xB5; //0xB9; break; case 0xE295A4: ch = 0xB6; //0xD1; break; case 0xE295A5: ch = 0xB7; //0xD2; break; case 0xE295A6: ch = 0xB8; //0xCB; break; case 0xE295A7: ch = 0xB9; //0xCF; break; case 0xE295A8: ch = 0xBA; //0xD0; break; case 0xE295A9: ch = 0xBB; //0xCA; break; case 0xE295AA: ch = 0xBC; //0xD8; break; case 0xE295AB: ch = 0xBD; //0xD7; break; case 0xE295AC: ch = 0xBE; //0xCE; break; case 0xE29691: ch = 0x90; //0xB0; break; case 0xE29692: ch = 0x91; //0xB1; break; case 0xE29693: ch = 0x92; //0xB2; break; case 0xE29684: ch = 0x8C; //0xDC; break; case 0xE29688: ch = 0x8D; //0xDB; break; case 0xE2968C: ch = 0x8E; //0xDD; break; case 0xE29690: ch = 0x8F; //0xDE; break; case 0xE29680: ch = 0x8B; //0xDF; break; default: ch = 127; break; } } } else if ((buf[0] & 0xF8) == 0xF0) { if (bufLen == 4) { ch = 127; } } else { ch = 127; } break; } if (ch >= 0) { Serial.print(char(ch)); bufLen = 0; if (++counter >= SCR_WIDTH) { counter = 0; } } } }