YM2149F MIDI Synth v2.1 May 2022


//  Arduino YM2149 MIDI Synth v2.1
//  Original Code by yukimizake
//  video: https://youtu.be/hUPs2pv5d_g
//  schematics: http://electronicfields.wordpress.com/?attachment_id=128 (Vcc/GND not shown)

// New PCB and re-jig for 2022 by Obakegaku and Dan Suter.
// Code re-factored in May 2022 as it would no longer conpile in the latest version of Arduino IDE
// contact webmidi@dansfing.uk      https://dansfing.uk for help.

//  This program 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 3 of the License, or
//  (at your option) any later version.

//  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <Arduino.h>
#include <U8x8lib.h>
#include <EEPROM.h>
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);         
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

//Port settings
const int ad0 = 8;
const int ad1 = 9;
const int ad2 = 2;
const int ad3 = 3;
const int ad4 = 4;
const int ad5 = 5;
const int ad6 = 6;
const int ad7 = 7;
const int pinBC1 = 10;   
const int pinBDIR = 11;
//BC2 to +5V
const int pinYMReset = 12;

//voicing
byte noteA = 0;
byte noteB = 0;
byte noteC = 0;
int periodA = 0;
int periodB = 0;
int periodC = 0;

//MIDI MUTES
int mm0=0;
int mm1=0;
int mm2=0;
int mm3=0;
int mm4=0;
int mm5=0;
int mm6=0;
int mm7=0;

//envelope
byte AmaxVolume = 0;
byte BmaxVolume = 0;
byte CmaxVolume = 0;

//unison detune
int detuneValue = 1;

//arpeggio settings
byte arpeggio[] = {0,7,12};
byte arpeggioLength = 3;
byte arpeggioCounter = 0;
boolean arpeggioFlipMe = false;

byte defaultLevel = 10;

//Fast pin switching macros
#define CLR(x,y) (x&=(~(1<<y)))
#define SET(x,y) (x|=(1<<y))

#define __BCPORT__ PORTB
#define __BC1__ 2
#define __BDIR__ 3

#define __LEDPORT__ PORTB
#define __LED__ 5

#define __RGBLEDPORT__ PORTC
#define __RGBLEDDDR__ DDRC
#define __RLED__ 0
#define __GLED__ 1
#define __BLED__ 2

const int ledPin = 13;

const int tp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4050,
                   3822, 3608, 3405, 3214, 3034, 2863, 2703, 2551, 2408, 2273, 2145, 4050, 3822,
                   3608, 3405, 3214, 3034, 2863, 2703, 2551, 2408, 2273, 2145, 2025, 1911, 1804, 1703,
                   1607, 1517, 1432, 1351, 1276, 1204, 1136, 1073, 1012, 956, 902, 851, 804, 758,
                   716, 676, 638, 602, 568, 536, 506, 478, 451, 426, 402, 379, 358, 338, 319, 301,
                   284, 268, 253, 239, 225, 213, 201, 190, 179, 169, 159, 150, 142, 134, 127, 119,
                   113, 106, 100, 95, 89, 84, 80, 75, 71, 67, 63, 60, 56, 53, 50, 47, 45, 42, 40,
                   38, 36, 34, 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13,
                   12, 11, 11, 10, 19, 18, 17, 16, 15, 14, 13, 13,
                   12, 11, 11, 10 };
                   
const int envTp[] = {3822, 3608, 3405, 3214, 3034, 2863, 2703, 2551, 2408, 2273, 2145, 2025, 1911, 1804, 1703, 1607, 1517, 1432, 1351, 1276, 1204, 1136, 1073, 1012, 956, 902, 851, 804, 758, 716, 676, 638, 602, 568, 536, 506, 478, 451, 426, 402, 379, 358, 338, 319, 301, 284, 268, 253, 239, 225, 213, 201, 190, 179, 169, 159, 150, 142, 134, 127, 119, 113, 106, 100, 95, 89, 84, 80, 75, 71, 67, 63, 60, 56, 53, 50, 47, 45, 42, 40, 38, 36, 34, 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2};

PROGMEM const char s0[] = {13, 14, 14, 13, 14, 15, 12, 14, 10, 14, 12, 14, 14, 13, 14, 12, 14, 13, 14, 12, 13, 12, 13, 11, 13, 12, 13, 12, 14, 13, 14, 14, 14, 15, 14, 15, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 12, 12, 11, 9, 7, 0, 0, 0, 0, 0, 5, 9, 11, 12, 12, 12, 13, 13, 14, 14, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 12, 11, 12, 10, 12, 11, 10, 12, 10, 12, 9, 11, 9, 8, 6, 8, 0, 5, 5, 6, 0, 4, 4, 10, 10, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 12, 12, 11, 11, 10, 9, 9, 8, 7, 7, 8, 7, 8, 7, 11, 0, 11, 8, 10, 10, 10, 11, 9, 12, 9, 12, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 12, 13, 12, 12, 12, 12, 12, 12, 13, 12, 13, 12, 12, 12, 13, 12, 12, 13, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 11, 11, 11, 11, 9, 9, 9, 8, 8, 5, 7, 5, 4, 4, 3, 6, 1, 4, 0, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 14, 14, 13, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 12, 11, 10};
const int s0Length = 931;
PROGMEM const char s1[] = {13, 14, 14, 14, 14, 14, 14, 13, 14, 14, 14, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 14, 13, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 14, 14, 15, 14, 15, 15, 15, 15, 15, 14, 14, 13, 12, 11, 9, 0, 0, 0, 0, 0, 0, 0, 5, 0, 13, 12, 14, 0, 15, 14, 9, 15, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 12, 12, 10, 9, 7, 0, 0, 0, 0, 0, 0, 4, 6, 8, 0, 0, 0, 0, 0, 0, 2, 9, 11, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 11, 11, 6, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 10, 12, 11, 13, 13, 13, 13, 12, 10, 11, 10, 12, 13, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 15, 14, 15, 13, 12, 14, 13, 13, 14, 14, 13, 13, 12, 9, 12, 12, 11, 11, 8, 8, 7, 0, 0, 4, 9, 10, 11, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 14, 13, 13, 14, 13, 13, 12, 12, 11, 9, 8, 6, 0, 0, 0, 0, 0, 0, 4, 9, 11, 13, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 12, 11, 11, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2, 9, 11, 11, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 12, 13, 13, 12, 13, 12, 12, 12, 12, 11, 9, 9, 12, 11, 12, 8, 6, 11, 4, 10, 11, 10, 11, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 14, 13, 13, 14, 13, 13, 14, 13, 14, 13, 13, 14, 14, 14, 13, 12, 12, 12, 12, 12, 11, 11, 10, 11, 10, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 14, 15, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 14, 13, 12, 13, 12, 12, 13, 13, 13, 10, 11, 10, 12, 10, 10, 12, 12, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 14, 14, 14, 15, 14, 14, 14, 14, 13, 13, 13, 14, 13, 13, 14, 13, 13, 12, 13, 13, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 14, 14, 14, 13, 13, 12, 12, 12, 13, 12, 12, 13, 13, 13, 13, 14, 13, 13, 13, 13, 12, 12, 12, 13, 13, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 12, 13, 12, 12, 11, 12, 11, 12, 12, 11, 12, 11, 12, 12, 12, 12, 13, 12, 13, 13, 13, 13, 14, 14, 15, 15, 15, 14, 14, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 12, 13, 12, 12, 12, 13, 13, 12, 12, 13, 12, 12, 12, 12, 11, 11, 10, 11, 11, 11, 12, 13, 13, 14, 14, 14, 14, 15, 14, 15, 15, 14, 14, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 13, 12, 11, 12, 12, 12, 12, 11, 12, 11, 12, 13, 12, 13, 14, 13, 13, 14, 14, 14, 14, 14, 15, 14, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 9, 11, 11, 10, 12, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 14, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 15, 14, 14, 14, 13, 14, 14, 14, 14, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 14, 13, 14, 14, 14, 14, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 12, 13, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 15, 15, 15, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 12, 13, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 14, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 14, 13, 13, 13, 12, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 14, 14, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 14, 13, 14, 14, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 13, 13, 14, 13};
const int s1Length = 1780;
PROGMEM const char s2[] = {15, 13, 12, 13, 13, 14, 13, 15, 14, 13, 14, 13, 13, 14, 13, 14, 14, 13, 14, 12, 14, 14, 13, 13, 14, 13, 13, 13, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 13, 13, 15, 13, 14, 13, 14, 13, 14, 12, 14, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 15, 12, 15, 13, 14, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 14, 13, 14, 13, 14, 13, 13, 13, 15, 14, 13, 14, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 14, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 14, 14, 13, 14, 13, 14, 13, 14, 14, 14, 13, 14, 13, 14, 13, 14, 13, 14, 13, 13, 14, 13, 14, 13, 13, 13, 14, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 14, 13, 13, 14, 13, 13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 13, 14, 13, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 13, 13, 14, 13, 14, 13, 14, 13, 14, 14, 14, 13, 13, 13, 14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 14, 13, 13, 13, 14, 13, 13, 14, 13, 14, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 14, 13, 13, 14, 13, 14, 13, 13, 14, 13, 14, 14, 13, 13, 14, 14, 13, 13, 14, 13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 13, 14, 13, 14, 13, 14, 14, 13, 14, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 13, 14, 13, 13, 14, 13, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 14, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13};
const int s2Length = 463;
PROGMEM const char s3[] = {13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 13, 13, 13, 13, 13, 14, 13, 14, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 13, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 15, 13, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 14, 12, 14, 14, 13, 14, 13, 13, 14, 13, 14, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 13, 13, 14, 13, 14, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 13, 14, 14, 13, 15, 14, 13, 14, 11, 13, 13, 13, 13, 13, 13, 12, 13, 13, 13, 14, 13, 15, 13, 13, 13, 13, 15, 11, 14, 15, 9, 14, 13, 11, 13, 13, 12, 13, 13, 13, 12, 14, 14, 14, 13, 15, 13, 13, 13, 14, 14, 12, 15, 12, 13, 14, 12, 13, 13, 13, 13, 13, 13, 12, 13, 14, 14, 14, 12, 15, 13, 12, 14, 14, 12, 14, 13, 13, 13, 13, 13, 11, 14, 13, 13, 14, 12, 14, 14, 12, 15, 14, 12, 15, 13, 14, 14, 13, 15, 12, 14, 13, 12, 13, 13, 12, 12, 14, 13, 12, 14, 13, 13, 14, 14, 14, 13, 15, 15, 11, 15, 14, 12, 14, 13, 12, 12, 12, 13, 13, 14, 13, 14, 14, 13, 14, 14, 14, 15, 14, 14, 15, 12, 15, 13, 13, 14, 12, 13, 13, 13, 13, 14, 14, 13, 14, 15, 13, 14, 14, 13, 14, 15, 14, 14, 13, 15, 13, 12, 14, 12, 12, 14, 13, 13, 14, 14, 13, 14, 14, 14, 13, 13, 13, 13, 15, 15, 14, 14, 15, 12, 13, 14, 13, 10, 13, 14, 12, 13, 15, 14, 14, 15, 14, 14, 14, 13, 13, 14, 15, 14, 13, 15, 13, 13, 15, 11, 13, 14, 12, 14, 14, 13, 14, 14, 14, 13, 14, 14, 12, 13, 13, 15, 15, 13, 15, 15, 13, 13, 13, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 14, 13, 12, 13, 15, 15, 14, 15, 14, 14, 14, 13, 11, 12, 13, 13, 13, 15, 15, 13, 15, 15, 13, 14, 14, 13, 11, 14, 15, 14, 15, 15, 12, 14, 14, 12, 11, 12, 13, 12, 13, 15, 14, 14, 15, 14, 13, 13, 13, 13, 12, 14, 14, 13, 15, 15, 12, 14, 14, 10, 12, 12, 13, 13, 14, 15, 14, 14, 15, 14, 13, 13, 13, 12, 13, 15, 13, 14, 15, 15, 14, 13, 14, 11, 11, 13, 12, 13, 14, 14, 15, 15, 13, 14, 14, 12, 12, 13, 14, 14, 13, 15, 15, 14, 15, 13, 12, 13, 11, 12, 12, 13, 14, 14, 14, 15, 14, 12, 13, 12, 11, 12, 14, 15, 13, 14, 15, 13, 14, 15, 10, 13, 14, 12, 13, 13, 14, 14, 13, 14, 14, 12, 12, 12, 12, 12, 14, 15, 14, 14, 15, 12, 13, 15, 12, 11, 14, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12, 13, 13, 13, 13, 15, 15, 12, 14, 13, 5, 15, 14, 0, 14, 14, 13, 12, 14, 14, 13, 10, 14, 14, 12, 13, 14, 13, 13, 15, 15, 12, 15, 13, 2, 13, 15, 12, 12, 15, 14, 12, 12, 14, 13, 11, 13, 15, 14, 12, 14, 14, 12, 15, 15, 12, 15, 13, 6, 13, 15, 14, 11, 15, 15, 12, 12, 13, 13, 12, 13, 14, 15, 13, 13, 14, 12, 14, 15, 10, 14, 14, 10, 11, 14, 15, 14, 12, 15, 13, 8, 13, 13, 13, 14, 14, 14, 14, 12, 13, 12, 13, 14, 11, 14, 14, 11, 12, 13, 14, 15, 12, 14, 14, 10, 12, 13, 13, 14, 14, 14, 14, 14, 13, 12, 13, 15, 12, 13, 14, 13, 11, 12, 14, 15, 13, 13, 15, 12, 11, 12, 12, 14, 14, 14, 14, 14, 13, 11, 12, 15, 12, 12, 15, 13, 11, 12, 13, 14, 15, 12, 14, 14, 11, 12, 11, 13, 14, 14, 14, 15, 13, 11, 13, 14, 13, 12, 14, 14, 12, 12, 13, 14, 15, 14, 13, 14, 12, 11, 12, 12, 14, 14, 13, 14, 14, 12, 12, 14, 14, 11, 13, 14, 12, 11, 13, 13, 15, 15, 13, 13, 13, 11, 12, 11, 14, 14, 14, 14, 15, 13, 11, 14, 14, 11, 13, 14, 13, 12, 13, 13, 14, 15, 14, 12, 13, 12, 12, 12, 13, 15, 14, 13, 15, 14, 10, 13, 14, 12, 11, 14, 14, 12, 13, 14, 13, 15, 14, 12, 13, 13, 11, 12, 13, 14, 14, 13, 14, 14, 9, 12, 14, 13, 12, 14, 14, 13, 12, 13, 13, 14, 15, 13, 13, 13, 11, 12, 12, 14, 14, 13, 14, 14, 11, 12, 14, 14, 12, 14, 14, 13, 12, 13, 14, 14, 14, 13, 13, 13, 12, 12, 11, 14, 14, 13, 13, 15, 13, 8, 14, 15, 11, 13, 15, 14, 12, 12, 14, 14, 15, 13, 13, 13, 12, 12, 12, 14, 14, 14, 14, 14, 13, 11, 13, 15, 13, 13, 14, 14, 12, 12, 13, 14, 14, 12, 13, 13, 11, 12, 12, 13, 14, 13, 14, 14, 13, 10, 13, 15, 13, 12, 15, 14, 12, 11, 14, 15, 14, 13, 14, 13, 12, 12, 12, 14, 14, 13, 14, 14, 13, 10, 13, 15, 13, 12, 15, 14, 11, 12, 14, 15, 14, 12, 15, 13, 10, 12, 13, 14, 14, 14, 14, 13, 13, 12, 13, 15, 13, 12, 15, 13, 11, 12, 14, 15, 13, 13, 15, 13, 10, 13, 13, 14, 13, 14, 15, 13, 12, 13, 13, 15, 13, 13, 15, 12, 11, 13, 15, 14, 11, 14, 14, 12, 11, 13, 14, 14, 13, 14, 15, 12, 11, 13, 14, 15, 13, 14, 15, 11, 10, 15, 15, 12, 13, 15, 14, 11, 11, 14, 14, 13, 14, 15, 14, 12, 12, 13, 14, 15, 13, 14, 14, 11, 12, 15, 14, 11, 14, 14, 14, 11, 13, 15, 13, 13, 14, 14, 13, 13, 13, 14, 15, 15, 13, 13, 13, 12, 14, 14, 13, 14, 14, 14, 13, 12, 15, 14, 12, 15, 14, 13, 13, 13, 13, 13, 15, 15, 12, 13, 13, 14, 13, 12, 14, 14, 13, 14, 13, 14, 14, 13, 14, 14, 13, 13, 13, 14, 14, 14, 15, 13, 12, 14, 15, 13, 11, 15, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 14, 15, 13, 11, 14, 14, 12, 11, 14, 14, 13, 13, 15, 14, 11, 13, 14, 12, 13, 14, 14, 14, 13, 13, 15, 14, 10, 15, 15, 11, 10, 14, 14, 13, 13, 15, 15, 12, 13, 14, 12, 13, 13, 14, 14, 13, 14, 14, 14, 12, 15, 14, 10, 13, 13, 14, 13, 14, 15, 14, 12, 14, 13, 11, 14, 14, 14, 14, 14, 14, 13, 15, 14, 13, 13, 12, 12, 13, 14, 13, 15, 15, 14, 13, 13, 13, 12, 13, 14, 14, 14, 14, 13, 12, 15, 15, 12, 13, 14, 12, 11, 14, 14, 15, 14, 14, 14, 11, 12, 13, 13, 14, 14, 15, 14, 11, 13, 15, 14, 10, 14, 13, 12, 12, 14, 15, 14, 14, 14, 13, 11, 12, 13, 14, 14, 15, 15, 13, 12, 15, 15, 9, 13, 14, 12, 11, 13, 15, 14, 13, 15, 14, 11, 12, 13, 13, 14, 14, 15, 14, 13, 14, 15, 14, 10, 14, 13, 12, 11, 15, 15, 13, 14, 14, 13, 10, 12, 14, 13, 14, 14, 14, 13, 14, 15, 14, 14, 11, 14, 12, 11, 14, 15, 14, 14, 14, 13, 12, 12, 14, 14, 13, 15, 14, 14, 14, 14, 12, 15, 13, 11, 14, 12, 14, 14, 14, 14, 14, 13, 13, 12, 13, 14, 13, 14, 14, 14, 15, 14, 11, 14, 15, 12, 13, 14, 14, 13, 13, 15, 14, 13, 14, 13, 12, 13, 14, 13, 14, 14, 15, 14, 10, 13, 15, 12, 10, 14, 15, 13, 12, 15, 13, 11, 14, 14, 13, 12, 14, 14, 13, 14, 15, 14, 13, 13, 14, 14, 8, 14, 15, 14, 12, 14, 14, 12, 12, 14, 14, 13, 13, 14, 12, 14, 15, 13, 13, 13, 13, 15, 11, 14, 15, 12, 13, 14, 14, 13, 12, 14, 14, 12, 14, 14, 12, 15, 15, 13, 13, 13, 13, 15, 13, 13, 15, 13, 12, 12, 14, 13, 13, 15, 15, 13, 13, 13, 13, 15, 14, 12, 14, 12, 11, 14, 14, 13, 14, 13, 13, 10, 13, 14, 13, 15, 14, 14, 12, 12, 14, 14, 13, 13, 14, 12, 12, 14, 15, 13, 14, 14, 13, 11, 13, 14, 13, 14, 14, 14, 11, 12, 15, 14, 12, 14, 13, 12, 12, 13, 15, 13, 12, 15, 13, 10, 12, 14, 14, 13, 14, 14, 11, 13, 15, 13, 11, 14, 13, 12, 12, 14, 15, 13, 12, 15, 12, 7, 13, 15, 14, 13, 14, 14, 11, 13, 15, 12, 13, 14, 13, 13, 12, 14, 15, 13, 13, 14, 12, 11, 12, 15, 14, 13, 14, 13, 11, 14, 14, 11, 13, 14, 13, 12, 12, 15, 15, 13, 12, 14, 11, 7, 13, 15, 14, 14, 14, 13, 13, 14, 12, 11, 13, 14, 13, 12, 14, 15, 14, 13, 13, 13, 11, 11, 13, 15, 14, 14, 14, 13, 14, 13, 11, 13, 13, 14, 13, 13, 15, 14, 15, 13, 11, 13, 12, 12, 13, 14, 14, 14, 13, 14, 14, 11, 12, 13, 12, 14, 13, 14, 14, 14, 15, 11, 12, 13, 10, 12, 14, 15, 13, 13, 14, 15, 13, 10, 14, 13, 13, 13, 13, 14, 14, 14, 15, 11, 13, 13, 11, 13, 14, 14, 14, 13, 14, 15, 10, 12, 13, 12, 13, 13, 14, 14, 12, 14, 15, 9, 12, 14, 13, 12, 13, 15, 13, 12, 15, 14, 8, 13, 14, 12, 13, 14, 15, 13, 13, 14, 14, 4, 13, 14, 13, 13, 14, 15, 12, 14, 15, 12, 10, 13, 13, 12, 14, 15, 14, 12, 13, 14, 14, 9, 13, 14, 13, 13, 14, 14, 13, 15, 14, 11, 10, 12, 13, 13, 14, 15, 14, 11, 13, 14, 13, 6, 14, 14, 12, 12, 14, 14, 14, 14, 13, 13, 10, 12, 13, 13, 15, 15, 14, 13, 12, 14, 13, 10, 15, 14, 12, 13, 14, 13, 15, 14, 12, 12, 10, 13, 13, 14, 15, 14, 13, 13, 12, 14, 12, 11, 15, 13, 12, 13, 14, 14, 14, 13, 14, 12, 0, 13, 13, 14, 15, 14, 13, 11, 12, 14, 11, 13, 15, 13, 12, 12, 14, 15, 13, 13, 14, 11, 11, 12, 14, 15, 14, 14, 13, 12, 12, 14, 11, 14, 14, 13, 12, 13, 15, 15, 12, 13, 14, 10, 12, 13, 14, 14, 14, 14, 13, 11, 14, 14, 10, 14, 14, 13, 12, 14, 15, 13, 12, 14, 12, 9, 13, 13, 14, 14, 14, 13, 12, 12, 15, 13, 13, 14, 13, 12, 12, 15, 15, 12, 13, 14, 12, 9, 13, 14, 15, 14, 13, 13, 12, 12, 15, 13, 13, 14, 13, 11, 14, 15, 13, 12, 14, 13, 11, 12, 13, 14, 14, 14, 13, 12, 12, 14, 14, 12, 14, 14, 12, 12, 15, 15, 12, 13, 14, 13, 11, 13, 14, 14, 14, 14, 13, 11, 12, 15, 14, 12, 14, 13, 11, 12, 15, 14, 11, 13, 14, 13, 10, 13, 15, 14, 14, 13, 12, 12, 12, 15, 14, 13, 14, 13, 12, 13, 15, 13, 12, 14, 14, 12, 11, 14, 14, 13, 14, 15, 12, 10, 14, 15, 13, 14, 15, 13, 11, 15, 15, 11, 13, 14, 14, 10, 13, 15, 13, 14, 14, 14, 12, 11, 14, 15, 13, 14, 14, 13, 13, 15, 14, 11, 13, 14, 14, 11, 13, 15, 13, 13, 14, 13, 13, 11, 14, 15, 12, 13, 14, 13, 13, 15, 13, 12, 13, 14, 13, 11, 15, 14, 13, 14, 14, 13, 12, 12, 15, 15, 13, 14, 14, 11, 14, 15, 13, 13, 14, 14, 12, 11, 15, 14, 13, 14, 14, 13, 11, 12, 15, 15, 13, 15, 14, 11, 14, 14, 12, 13, 14, 14, 13, 12, 14, 14, 13, 14, 14, 13, 12, 12, 14, 15, 13, 13, 15, 14, 14, 14, 13, 13, 13, 14, 13, 12, 14, 14, 13, 14, 14, 13, 12, 13, 14, 15, 14, 12, 14, 14, 15, 13, 13, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 15, 13, 13, 14, 15, 13, 12, 14, 14, 13, 12, 14, 14, 14, 13, 14, 14, 13, 13, 13, 14, 14, 15, 14, 12, 14, 15, 13, 12, 14, 14, 13, 12, 14, 14, 13, 14, 14, 14, 13, 13, 13, 14, 13, 14, 15, 13, 13, 15, 14, 11, 13, 14, 13, 13, 14, 15, 14, 13, 14, 13, 13, 13, 13, 14, 13, 13, 14, 14, 13, 15, 14, 12, 12, 14, 13, 13, 14, 15, 14, 13, 14, 13, 12, 13, 14, 14, 14, 13, 13, 14, 15, 14, 15, 13, 12, 12, 13, 13, 14, 15, 15, 14, 13, 13, 13, 11, 13, 15, 14, 14, 13, 13, 14, 15, 15, 13, 12, 13, 12, 13, 13, 15, 15, 15, 14, 13, 12, 12, 12, 14, 14, 14, 14, 14, 12, 14, 15, 14, 12, 14, 13, 12, 12, 14, 15, 15, 15, 14, 13, 12, 12, 12, 14, 14, 14, 14, 13, 12, 14, 15, 13, 13, 14, 13, 11, 13, 15, 15, 14, 15, 15, 12, 12, 13, 13, 14, 15, 15, 14, 12, 13, 15, 15, 13, 13, 14, 12, 8, 13, 15, 15, 14, 14, 14, 13, 11, 12, 14, 14, 14, 14, 14, 13, 13, 15, 15, 14, 12, 13, 13, 11, 12, 15, 15, 14, 14, 15, 13, 9, 12, 14, 14, 14, 14, 14, 13, 13, 15, 15, 14, 13, 12, 13, 12, 12, 14, 14, 15, 14, 14, 14, 11, 12, 14, 13, 14, 15, 14, 13, 14, 15, 14, 13, 14, 12, 12, 13, 13, 14, 14, 14, 14, 13, 13, 13, 11, 12, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 13, 13, 13, 12, 13, 14, 14, 14, 14, 14, 13, 10, 12, 13, 13, 14, 15, 14, 12, 13, 14, 12, 14, 14, 12, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 13, 13, 14, 13, 11, 12, 13, 14, 14, 14, 14, 13, 12, 13, 13, 12, 14, 14, 13, 13, 14, 14, 15, 13, 11, 13, 15, 12, 12, 13, 13, 12, 13, 14, 14, 13, 13, 13, 13, 13, 12, 13, 13, 13, 14, 14, 14, 13, 11, 13, 14, 13, 13, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 12, 13, 14, 14, 12, 13, 14, 13, 11, 13, 13, 13, 13, 14, 14, 13, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 10, 12, 14, 12, 12, 14, 14, 13, 12, 14, 13, 13, 14, 14, 13, 12, 13, 13, 13, 12, 14, 14, 14, 13, 12, 13, 14, 12, 12, 14, 14, 13, 13, 13, 14, 13, 12, 14, 12, 12, 13, 14, 14, 13, 13, 14, 14, 13, 12, 13, 14, 11, 10, 13, 13, 12, 13, 14, 14, 13, 13, 13, 12, 12, 14, 14, 13, 13, 14, 14, 14, 13, 11, 14, 14, 10, 11, 13, 14, 13, 13, 14, 14, 12, 13, 14, 13, 12, 13, 13, 12, 13, 14, 14, 14, 13, 12, 14, 13, 9, 13, 14, 14, 14, 14, 13, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 15, 14, 13, 12, 13, 14, 11, 13, 14, 14, 13, 14, 14, 13, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 12, 11, 13, 14, 13, 12, 13, 14, 13, 12, 13, 14, 13, 13, 14, 14, 12, 12, 13, 14, 13, 14, 14, 14, 12, 11, 14, 15, 12, 12, 13, 13, 13, 13, 14, 13, 12, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 12, 14, 15, 12, 10, 10, 13, 14, 14, 14, 14, 13, 13, 13, 13, 12, 13, 13, 14, 13, 14, 14, 14, 13, 11, 13, 15, 13, 8, 12, 14, 14, 13, 14, 14, 13, 11, 13, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 11, 13, 14, 12, 11, 13, 14, 14, 14, 14, 13, 13, 12, 13, 14, 14, 14, 13, 12, 13, 14, 14, 14, 14, 12, 12, 14, 14, 12, 13, 14, 13, 12, 14, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 15, 13, 10, 14, 15, 13, 11, 12, 14, 13, 13, 15, 14, 13, 13, 13, 13, 12, 13, 14, 13, 13, 14, 14, 14, 14, 11, 13, 14, 12, 13, 12, 13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 10, 13, 15, 12, 12, 14, 14, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 15, 14, 11, 13, 15, 13, 12, 13, 14, 14, 13, 14, 14, 14, 12, 14, 14, 13, 13, 13, 13, 13, 14, 15, 14, 14, 13, 13, 15, 13, 12, 13, 14, 13, 12, 13, 14, 14, 13, 14, 14, 12, 12, 13, 14, 14, 14, 15, 15, 14, 12, 13, 14, 13, 12, 13, 14, 14, 13, 14, 14, 14, 13, 12, 13, 13, 12, 14, 14, 14, 14, 15, 14, 14, 13, 13, 14, 13, 13, 13, 14, 15, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 15, 14, 14, 14, 14, 14, 14, 11, 14, 14, 13, 13, 14, 14, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 14, 14, 13, 15, 14, 14, 14, 11, 13, 14, 14, 13, 13, 15, 14, 12, 14, 14, 14, 13, 14, 14, 13, 14, 13, 14, 13, 14, 15, 14, 14, 12, 13, 14, 13, 12, 14, 14, 14, 13, 14, 14, 13, 13, 14, 14, 13, 14, 14, 13, 14, 15, 14, 14, 14, 12, 11, 14, 15, 13, 13, 15, 15, 12, 12, 13, 14, 14, 13, 14, 13, 13, 14, 14, 14, 14, 14, 15, 14, 11, 12, 14, 14, 13, 14, 15, 14, 12, 12, 14, 14, 13, 14, 14, 14, 13, 13, 14, 13, 13, 14, 14, 15, 13, 12, 14, 15, 13, 12, 14, 14, 12, 12, 14, 14, 14, 13, 14, 13, 13, 13, 13, 13, 14, 14, 15, 15, 13, 12, 13, 14, 14, 12, 15, 15, 13, 12, 14, 13, 14, 13, 14, 14, 12, 13, 13, 13, 13, 14, 15, 15, 13, 11, 13, 13, 14, 12, 14, 15, 14, 12, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 14, 13, 14, 15, 14, 11, 13, 14, 14, 13, 13, 14, 14, 12, 13, 13, 14, 14, 13, 14, 13, 13, 14, 14, 13, 14, 14, 15, 14, 12, 13, 13, 14, 13, 13, 15, 14, 12, 12, 13, 14, 14, 13, 14, 14, 13, 13, 13, 13, 14, 14, 15, 15, 12, 11, 14, 14, 13, 12, 14, 14, 13, 12, 14, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 15, 13, 11, 14, 14, 13, 12, 14, 15, 13, 12, 13, 13, 13, 14, 14, 14, 13, 13, 14, 13, 13, 14, 15, 15, 14, 12, 13, 13, 14, 13, 14, 14, 14, 12, 11, 13, 14, 13, 14, 14, 14, 13, 13, 14, 13, 13, 15, 15, 14, 12, 13, 13, 14, 13, 13, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 15, 13, 11, 13, 14, 14, 11, 13, 14, 13, 13, 13, 14, 14, 13, 14, 13, 13, 14, 13, 12, 14, 14, 15, 15, 14, 11, 12, 14, 14, 12, 12, 14, 13, 12, 14, 14, 13, 12, 13, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 13, 12, 13, 14, 13, 10, 13, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 14, 14, 13, 10, 14, 15, 13, 12, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 11, 12, 15, 14, 11, 12, 13, 13, 13, 14, 14, 13, 13, 13, 12, 12, 13, 14, 13, 13, 14, 13, 13, 14, 13, 12, 14, 14, 12, 11, 12, 13, 13, 14, 14, 14, 13, 13, 13, 12, 13, 13, 13, 14, 14, 13, 14, 13, 14, 13, 13, 15, 12, 12, 11, 11, 14, 14, 13, 14, 14, 13, 13, 11, 12, 13, 13, 14, 14, 13, 13, 14, 13, 14, 13, 15, 13, 10, 12, 10, 13, 14, 14, 14, 14, 13, 13, 11, 10, 14, 14, 14, 14, 14, 13, 12, 13, 14, 14, 15, 14, 10, 12, 11, 12, 13, 14, 14, 14, 13, 12, 13, 11, 12, 13, 14, 14, 14, 14, 12, 12, 14, 15, 14, 14, 13, 12, 12, 10, 12, 14, 14, 15, 13, 12, 14, 10, 5, 14, 14, 14, 13, 14, 14, 12, 11, 15, 15, 14, 12, 12, 12, 10, 12, 14, 14, 15, 15, 13, 11, 11, 7, 11, 14, 15, 15, 14, 12, 13, 11, 12, 15, 15, 14, 12, 13, 11, 0, 13, 15, 14, 14, 14, 13, 10, 0, 13, 15, 15, 14, 14, 13, 10, 10, 13, 15, 15, 14, 11, 10, 13, 11, 8, 14, 15, 15, 13, 12, 13, 12, 11, 13, 15, 14, 13, 14, 13, 9, 13, 15, 15, 14, 13, 11, 9, 8, 10, 14, 15, 15, 15, 13, 12, 9, 9, 9, 14, 15, 15, 14, 13, 11, 11, 13, 15, 15, 13, 10, 13, 12, 8, 13, 15, 15, 15, 13, 13, 8, 0, 11, 15, 15, 14, 15, 14, 12, 0, 12, 14, 15, 14, 12, 13, 13, 12, 12, 12, 15, 15, 13, 12, 13, 13, 10, 13, 15, 15, 14, 12, 12, 5, 9, 14, 15, 15, 12, 14, 13, 0, 0, 14, 15, 15, 14, 14, 12, 9, 11, 13, 14, 15, 15, 14, 13, 11, 11, 14, 15, 15, 14, 10, 11, 8, 8, 11, 15, 15, 14, 14, 14, 12, 5, 10, 13, 14, 15, 15, 14, 13, 10, 13, 15, 14, 14, 13, 12, 10, 10, 13, 13, 15, 15, 14, 13, 12, 8, 9, 13, 15, 15, 15, 14, 14, 11, 0, 14, 15, 15, 13, 13, 13, 8, 13, 13, 14, 15, 14, 14, 12, 11, 13, 13, 13, 14, 15, 15, 12, 12, 12, 12, 15, 15, 14, 14, 13, 9, 10, 11, 14, 15, 14, 15, 14, 12, 10, 11, 14, 14, 14, 15, 14, 10, 10, 13, 15, 15, 15, 14, 12, 0, 8, 13, 14, 15, 15, 15, 13, 11, 12, 10, 13, 15, 14, 14, 13, 13, 12, 13, 14, 15, 13, 13, 13, 12, 12, 13, 15, 14, 12, 14, 15, 12, 11, 13, 13, 13, 13, 15, 15, 13, 13, 13, 13, 13, 13, 14, 15, 14, 13, 12, 13, 13, 13, 14, 15, 14, 13, 10, 12, 14, 14, 13, 14, 14, 12, 12, 14, 14, 14, 14, 15, 14, 10, 12, 13, 13, 14, 14, 15, 14, 14, 14, 11, 13, 14, 13, 13, 14, 13, 14, 15, 14, 13, 12, 14, 15, 12, 11, 13, 14, 13, 12, 15, 15, 13, 12, 12, 12, 13, 13, 15, 15, 13, 13, 13, 14, 13, 13, 14, 15, 14, 10, 12, 14, 15, 13, 14, 15, 14, 12, 12, 13, 14, 14, 14, 13, 13, 13, 14, 15, 14, 13, 13, 13, 14, 13, 14, 14, 14, 13, 12, 13, 14, 14, 14, 14, 14, 13, 12, 13, 14, 14, 14, 15, 15, 11, 10, 14, 14, 14, 14, 14, 13, 12, 13, 13, 14, 15, 14, 13, 13, 13, 14, 14, 13, 13, 13, 14, 15, 15, 9, 12, 14, 14, 13, 12, 14, 14, 13, 13, 14, 13, 13, 14, 15, 14, 13, 14, 12, 11, 14, 15, 15, 14, 13, 12, 12, 13, 14, 14, 14, 14, 13, 12, 11, 14, 15, 13, 14, 14, 13, 13, 14, 13, 12, 14, 15, 15, 12, 11, 13, 13, 14, 14, 14, 14, 12, 13, 14, 11, 13, 14, 14, 15, 14, 13, 12, 12, 12, 14, 15, 15, 15, 11, 11, 12, 13, 13, 14, 15, 15, 11, 13, 12, 7, 14, 15, 15, 14, 13, 13, 11, 8, 14, 15, 15, 15, 13, 11, 4, 12, 15, 15, 14, 15, 13, 9, 13, 12, 12, 14, 15, 15, 13, 12, 13, 13, 11, 14, 15, 15, 12, 11, 12, 13, 13, 15, 15, 14, 14, 12, 12, 11, 9, 14, 15, 15, 15, 13, 12, 11, 12, 13, 14, 15, 15, 13, 12, 8, 12, 14, 15, 15, 14, 12, 12, 11, 0, 12, 15, 15, 15, 14, 13, 11, 9, 12, 14, 15, 15, 13, 12, 10, 12, 13, 14, 15, 15, 13, 10, 12, 12, 11, 14, 15, 15, 14, 13, 11, 11, 12, 14, 15, 15, 15, 13, 12, 10, 12, 14, 15, 14, 14, 13, 10, 12, 11, 13, 15, 15, 15, 14, 10, 11, 12, 12, 14, 15, 15, 13, 12, 12, 10, 12, 15, 15, 14, 13, 13, 12, 10, 11, 14, 15, 15, 15, 14, 11, 9, 13, 14, 14, 15, 15, 13, 10, 11, 13, 14, 15, 15, 14, 13, 12, 11, 12, 12, 15, 15, 15, 14, 12, 11, 10, 11, 14, 15, 15, 14, 13, 12, 10, 12, 15, 15, 14, 13, 14, 10, 10, 11, 13, 15, 15, 15, 13, 8, 8, 8, 13, 15, 15, 15, 14, 12, 8, 10, 13, 15, 15, 14, 14, 12, 8, 12, 13, 15, 15, 15, 15, 10, 0, 10, 13, 15, 15, 15, 14, 10, 0, 9, 12, 15, 15, 15, 13, 13, 0, 12, 13, 13, 15, 15, 14, 12, 9, 11, 13, 14, 15, 15, 13, 12, 8, 9, 12, 14, 15, 15, 14, 13, 12, 11, 12, 11, 15, 15, 14, 14, 13, 11, 11, 13, 15, 15, 14, 13, 11, 12, 12, 14, 14, 15, 15, 14, 13, 7, 9, 13, 13, 14, 15, 15, 14, 11, 9, 12, 13, 14, 14, 14, 13, 12, 12, 12, 13, 15, 15, 15, 12, 4, 7, 11, 11, 14, 15, 15, 15, 13, 6, 10, 10, 15, 15, 14, 13, 13, 12, 10, 12, 15, 15, 15, 13, 9, 0, 8, 12, 14, 15, 15, 15, 13, 2, 8, 9, 13, 15, 15, 14, 12, 12, 12, 11, 14, 15, 15, 14, 10, 9, 0, 12, 14, 15, 15, 15, 15, 11, 0, 0, 12, 15, 15, 14, 14, 12, 13, 11, 11, 15, 15, 14, 12, 5, 0, 12, 13, 14, 15, 15, 14, 12, 2, 0, 11, 14, 15, 14, 13, 13, 13, 7, 12, 14, 15, 15, 12, 11, 5, 10, 13, 13, 14, 15, 15, 14, 8, 8, 10, 13, 15, 14, 14, 14, 12, 11, 12, 13, 14, 15, 14, 13, 9, 7, 13, 13, 14, 15, 15, 14, 12, 0, 0, 11, 15, 15, 14, 14, 13, 8, 11, 12, 13, 15, 15, 13, 9, 0, 12, 13, 14, 15, 15, 14, 12, 8, 2, 10, 15, 15, 14, 14, 12, 11, 13, 12, 11, 14, 15, 14, 12, 10, 11, 13, 13, 14, 14, 14, 14, 11, 8, 11, 13, 15, 15, 14, 11, 12, 14, 8, 8, 14, 15, 15, 13, 11, 9, 11, 13, 14, 15, 14, 14, 12, 4, 9, 13, 15, 15, 14, 13, 10, 12, 11, 11, 14, 15, 15, 13, 11, 10, 11, 13, 14, 15, 14, 14, 14, 11, 8, 12, 15, 15, 14, 13, 12, 12, 12, 11, 13, 14, 15, 15, 12, 11, 11, 12, 14, 14, 14, 14, 14, 13, 11, 12, 14, 15, 14, 13, 13, 12, 11, 12, 13, 14, 15, 15, 14, 10, 6, 12, 14, 14, 14, 14, 14, 13, 12, 13, 14, 15, 15, 14, 13, 11, 11, 13, 13, 14, 15, 15, 15, 10, 0, 11, 13, 14, 14, 15, 14, 14, 12, 12, 14, 14, 14, 14, 14, 11, 12, 13, 13, 13, 15, 15, 15, 11, 9, 11, 12, 14, 14, 15, 14, 14, 14, 12, 12, 12, 14, 14, 14, 13, 12, 13, 13, 13, 14, 15, 15, 13, 9, 11, 13, 14, 14, 14, 14, 14, 13, 12, 12, 12, 14, 15, 15, 13, 9, 13, 14, 13, 14, 15, 15, 14, 10, 12, 12, 12, 14, 14, 15, 15, 13, 12, 12, 13, 13, 14, 15, 15, 11, 11, 12, 12, 14, 15, 15, 15, 14, 12, 13, 10, 14, 14, 14, 15, 13, 13, 14, 12, 11, 14, 15, 15, 12, 5, 13, 13, 14, 14, 15, 15, 14, 8, 11, 13, 13, 14, 13, 15, 14, 12, 14, 13, 12, 14, 15, 15, 13, 0, 12, 13, 13, 14, 15, 15, 14, 13, 11, 12, 12, 14, 14, 14, 15, 13, 14, 13, 11, 13, 15, 15, 14, 11, 11, 13, 13, 14, 14, 15, 15, 14, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 12, 14, 15, 14, 12, 8, 13, 13, 14, 14, 15, 15, 14, 13, 11, 12, 11, 14, 15, 14, 14, 13, 14, 13, 12, 13, 15, 15, 13, 10, 11, 13, 14, 14, 14, 15, 14, 13, 12, 11, 12, 13, 15, 14, 14, 14, 14, 13, 13, 12, 15, 15, 14, 11, 12, 13, 14, 14, 14, 15, 15, 14, 14, 12, 12, 12, 13, 14, 14, 14, 13, 14, 14, 12, 14, 15, 14, 12, 10, 13, 14, 14, 14, 15, 14, 13, 14, 13, 12, 11, 13, 15, 14, 14, 14, 14, 14, 13, 14, 15, 14, 11, 11, 13, 14, 13, 14, 15, 14, 13, 14, 13, 10, 11, 13, 14, 14, 14, 14, 14, 14, 13, 13, 15, 14, 11, 12, 13, 13, 13, 14, 15, 14, 13, 13, 14, 13, 12, 14, 14, 14, 14, 14, 13, 13, 14, 14, 15, 14, 12, 12, 13, 14, 14, 14, 14, 14, 13, 13, 13, 14, 13, 13, 14, 13, 14, 14, 13, 13, 14, 14, 15, 15, 10, 11, 12, 13, 14, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 13, 13, 15, 13, 12, 13, 14, 15, 15, 12, 10, 12, 13, 13, 13, 15, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 12, 14, 14, 15, 15, 14, 11, 11, 11, 13, 13, 14, 14, 14, 13, 13, 12, 13, 15, 14, 13, 13, 14, 14, 12, 13, 13, 14, 15, 15, 12, 6, 10, 14, 13, 14, 14, 15, 14, 12, 12, 13, 14, 15, 13, 13, 13, 13, 13, 13, 14, 14, 14, 15, 13, 9, 11, 13, 13, 14, 15, 15, 13, 12, 12, 12, 14, 15, 15, 13, 12, 11, 13, 14, 13, 12, 15, 15, 14, 8, 9, 12, 13, 13, 14, 15, 14, 13, 12, 11, 13, 15, 14, 14, 12, 12, 14, 14, 11, 12, 14, 15, 15, 11, 12, 12, 12, 13, 14, 14, 15, 13, 12, 12, 12, 14, 15, 14, 13, 12, 13, 13, 12, 12, 13, 14, 15, 13, 13, 11, 9, 12, 14, 14, 15, 14, 13, 13, 10, 12, 15, 15, 14, 13, 13, 13, 13, 10, 13, 15, 15, 14, 12, 12, 10, 11, 13, 14, 15, 15, 14, 13, 9, 11, 14, 15, 14, 13, 14, 13, 12, 11, 12, 13, 15, 15, 13, 13, 11, 9, 12, 14, 15, 15, 14, 13, 10, 10, 14, 15, 14, 14, 13, 13, 14, 11, 12, 13, 15, 15, 14, 12, 11, 9, 13, 14, 15, 15, 14, 13, 11, 11, 12, 14, 15, 14, 13, 13, 14, 12, 0, 13, 15, 15, 14, 13, 12, 7, 11, 13, 14, 15, 15, 14, 12, 0, 11, 14, 14, 14, 14, 14, 13, 12, 8, 11, 13, 15, 15, 13, 13, 11, 11, 12, 14, 15, 14, 14, 13, 9, 11, 14, 15, 15, 14, 14, 13, 12, 10, 11, 14, 15, 15, 13, 12, 8, 8, 13, 15, 15, 14, 14, 12, 8, 10, 14, 15, 15, 14, 13, 11, 12, 11, 10, 13, 15, 15, 13, 11, 8, 12, 12, 12, 15, 15, 14, 12, 11, 11, 13, 14, 15, 14, 13, 12, 13, 12, 10, 12, 15, 15, 14, 13, 14, 13, 13, 14, 14, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 13, 13, 13, 14, 13, 12, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 14, 14, 14, 13, 12, 14, 14, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 13, 14, 13, 13, 14, 13, 13, 13, 13, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 14, 13, 14, 13, 12, 13, 12, 13, 14, 14, 14, 14, 13, 13, 12, 12, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 12, 13, 12, 13, 13, 14, 14, 14, 13, 13, 13, 12, 13, 13, 14, 14, 14, 14, 13, 13, 14, 14, 13, 14, 13, 13, 13, 12, 13, 14, 14, 14, 13, 13, 14, 12, 12, 14, 14, 14, 13, 14, 14, 13, 13, 14, 14, 14, 13, 13, 13, 12, 13, 14, 14, 14, 14, 13, 12, 12, 12, 13, 14, 14, 15, 14, 13, 13, 12, 13, 14, 14, 14, 13, 13, 12, 11, 13, 14, 14, 14, 14, 13, 12, 11, 13, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 12, 12, 13, 13, 12, 14, 15, 14, 13, 13, 13, 13, 12, 13, 14, 14, 13, 14, 13, 12, 13, 14, 14, 14, 13, 13, 12, 12, 12, 14, 14, 15, 14, 13, 13, 12, 12, 12, 14, 14, 14, 14, 13, 13, 12, 13, 14, 14, 13, 12, 13, 13, 12, 13, 14, 15, 14, 13, 13, 12, 11, 12, 14, 14, 14, 14, 14, 13, 11, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 12, 13, 14, 14, 14, 13, 13, 12, 12, 14, 15, 14, 13, 14, 13, 11, 11, 14, 14, 14, 14, 13, 13, 12, 13, 13, 14, 14, 14, 13, 13, 12, 12, 14, 15, 15, 14, 12, 13, 12, 12, 13, 14, 15, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 14, 13, 12, 13, 14, 14, 14, 13, 13, 12, 12, 13, 13, 15, 14, 13, 13, 13, 12, 12, 13, 14, 14, 14, 14, 13, 13, 11, 14, 15, 14, 13, 13, 13, 12, 13, 13, 14, 14, 14, 14, 13, 12, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 12, 14, 14, 14, 14, 14, 12, 12, 13, 14, 14, 14, 14, 13, 11, 12, 13, 14, 14, 14, 14, 13, 12, 13, 12, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 12, 13, 14, 14, 13, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 14, 13, 13, 14, 13, 14, 14, 14, 13, 13, 14, 14, 13, 12, 13, 14, 13, 13, 15, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 14, 13, 13, 14, 14, 14, 12, 13, 14, 14, 13, 14, 14, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 13, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 13, 12, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 13, 13, 13, 13, 14, 14, 14, 12, 13, 14, 14, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 13, 14, 13, 12, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 14, 14, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 13, 13, 14, 12, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 15, 14, 13, 13, 13, 13, 13, 14, 15, 14, 13, 13, 13, 12, 14, 14, 14, 14, 13, 13, 12, 12, 14, 14, 15, 14, 13, 12, 12, 13, 14, 15, 14, 14, 13, 12, 13, 13, 13, 13, 14, 15, 13, 13, 13, 13, 13, 14, 15, 15, 13, 12, 13, 13, 13, 14, 15, 14, 14, 13, 13, 12, 12, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 15, 14, 13, 13, 12, 13, 14, 15, 14, 14, 13, 13, 12, 11, 13, 15, 15, 14, 14, 13, 12, 12, 13, 14, 15, 15, 13, 13, 12, 13, 13, 14, 15, 14, 13, 12, 13, 13, 13, 14, 15, 15, 14, 13, 13, 12, 13, 14, 14, 14, 14, 13, 13, 12, 13, 14, 14, 14, 14, 13, 12, 13, 13, 13, 14, 15, 14, 14, 12, 12, 13, 13, 14, 15, 14, 13, 13, 13, 12, 13, 14, 15, 14, 13, 13, 13, 12, 12, 14, 15, 14, 14, 14, 12, 12, 13, 14, 14, 14, 14, 13, 12, 13, 13, 14, 14, 15, 14, 13, 13, 12, 13, 13, 14, 15, 14, 14, 13, 13, 12, 13, 14, 14, 14, 14, 13, 13, 12, 13, 14, 15, 14, 13, 14, 12, 12, 13, 13, 15, 15, 14, 13, 12, 12, 12, 13, 14, 14, 14, 14, 13, 12, 12, 13, 14, 15, 14, 14, 13, 12, 13, 13, 15, 14, 14, 14, 12, 11, 12, 13, 14, 15, 14, 14, 12, 11, 12, 13, 14, 15, 14, 13, 13, 12, 13, 13, 13, 14, 15, 14, 13, 12, 13, 13, 14, 15, 15, 13, 13, 12, 12, 13, 14, 15, 15, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 12, 12, 13, 13, 14, 14, 14, 14, 12, 12, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 15, 14, 13, 12, 12, 13, 13, 13, 15, 14, 14, 13, 12, 12, 12, 14, 15, 14, 13, 13, 13, 12, 13, 14, 15, 14, 13, 12, 10, 12, 13, 14, 15, 15, 14, 13, 12, 12, 12, 13, 14, 14, 14, 13, 13, 13, 12, 14, 14, 15, 14, 12, 12, 11, 13, 14, 14, 14, 14, 14, 13, 11, 11, 13, 14, 14, 14, 14, 13, 13, 13, 13, 14, 15, 14, 13, 12, 11, 13, 13, 13, 14, 14, 14, 13, 12, 11, 13, 14, 15, 14, 13, 13, 13, 12, 13, 14, 14, 14, 13, 12, 12, 12, 13, 13, 14, 14, 14, 14, 12, 12, 12, 13, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 12, 12, 13, 13, 14, 14, 14, 14, 13, 11, 11, 13, 14, 14, 14, 14, 13, 12, 13, 13, 13, 14, 14, 13, 12, 12, 13, 13, 14, 14, 14, 14, 13, 12, 12, 12, 14, 15, 14, 14, 13, 12, 13, 13, 13, 14, 14, 14, 13, 12, 13, 13, 13, 14, 14, 14, 14, 12, 12, 12, 13, 15, 14, 14, 12, 13, 14, 12, 12, 14, 15, 14, 13, 12, 12, 13, 13, 14, 14, 14, 14, 13, 12, 12, 13, 15, 15, 14, 13, 12, 13, 12, 13, 14, 15, 15, 13, 12, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 13, 14, 15, 14, 13, 13, 13, 13, 12, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 14, 15, 14, 13, 13, 13, 13, 13, 13, 14, 15, 14, 14, 12, 12, 13, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 13, 12, 12, 13, 13, 14, 15, 15, 14, 12, 11, 12, 13, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 15, 14, 13, 12, 12, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 12, 13, 13, 13, 13, 14, 15, 14, 12, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 12, 14, 14, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 12, 12, 13, 13, 14, 13, 14, 14, 13, 14, 13, 13, 14, 14, 14, 13, 11, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 13, 13, 13, 14, 15, 14, 12, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 13, 13, 13, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 14, 14, 13, 14, 14, 14, 13, 12, 13, 14, 14, 14, 14, 14, 13, 14, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 13, 14, 14, 13, 13, 12, 13, 14, 13, 14, 14, 14, 13, 14, 13, 12, 13, 13, 14, 14, 14, 14, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 14, 13, 13, 13, 14, 14, 14, 14, 13, 13, 14, 14, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 14, 13, 13, 14, 13, 14, 14, 13, 13, 14, 14, 14, 14, 12, 12, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 13, 14, 13, 13, 13, 14, 14, 15, 13, 12, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 13, 12, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 14, 14, 13, 13, 13, 14, 14, 14, 13, 12, 12, 14, 13, 14, 14, 14, 14, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 15, 13, 12, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 13, 12, 13, 14, 13, 13, 14, 15, 14, 12, 12, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 13, 14, 14, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 12, 12, 13, 14, 14, 14, 14, 13, 13, 12, 13, 14, 14, 14, 13, 13, 13, 13, 12, 13, 14, 15, 14, 13, 13, 12, 13, 13, 14, 14, 14, 14, 13, 12, 12, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 15, 13, 13, 12, 12, 13, 14, 14, 14, 14, 13, 12, 12, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 15, 14, 13, 12, 12, 13, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 13, 13, 14, 13, 11, 13, 14, 15, 14, 13, 13, 12, 12, 13, 14, 14, 14, 14, 13, 11, 12, 14, 14, 14, 14, 14, 13, 13, 12, 12, 13, 15, 14, 13, 13, 12, 13, 13, 14, 14, 14, 14, 13, 12, 12, 14, 14, 14, 14, 14, 13, 13, 12, 13, 14, 15, 15, 13, 13, 12, 12, 13, 14, 14, 14, 13, 13, 12, 12, 14, 14, 14, 14, 13, 13, 13, 12, 12, 13, 14, 15, 13, 12, 12, 13, 13, 13, 14, 15, 14, 13, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 14, 14, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13, 13, 14, 14, 14, 14, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 13, 13, 14, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 10};
const int s3Length = 8011;
PROGMEM const char s4[] = {13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 13, 11, 13, 15, 15, 14, 0, 13, 15, 15, 14, 9, 13, 14, 12, 12, 15, 15, 14, 14, 14, 14, 14, 14, 13, 13, 15, 15, 15, 12, 8, 14, 15, 15, 13, 13, 14, 14, 14, 15, 14, 12, 13, 15, 15, 14, 1, 11, 15, 15, 15, 14, 14, 15, 11, 0, 12, 15, 15, 7, 13, 15, 15, 13, 7, 13, 9, 11, 14, 15, 15, 10, 10, 14, 15, 14, 13, 13, 13, 14, 14, 14, 14, 13, 14, 14, 14, 15, 14, 14, 14, 14, 15, 14, 9, 13, 15, 15, 14, 12, 13, 15, 15, 15, 12, 11, 13, 15, 15, 14, 12, 11, 14, 15, 14, 12, 10, 14, 15, 14, 11, 4, 13, 14, 14, 14, 12, 13, 14, 14, 15, 13, 13, 14, 14, 14, 13, 14, 14, 14, 14, 14, 14, 14, 12, 13, 13, 13, 14, 14, 13, 13, 13, 14, 15, 14, 13, 14, 15, 15, 15, 14, 14, 15, 15, 14, 14, 14, 15, 15, 14, 13, 14, 14, 14, 13, 14, 12, 11, 15, 15, 15, 13, 8, 0, 10, 14, 15, 14, 7, 0, 12, 15, 15, 14, 0, 12, 15, 15, 15, 13, 8, 12, 14, 15, 15, 14, 13, 9, 8, 14, 15, 14, 12, 8, 12, 15, 15, 15, 14, 15, 15, 15, 15, 15, 14, 13, 14, 14, 14, 13, 10, 4, 5, 10, 11, 7, 4, 7, 10, 13, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 14, 13, 13, 14, 14, 13, 10, 5, 7, 3, 13, 15, 14, 9, 6, 14, 15, 15, 15, 14, 14, 15, 15, 14, 14, 15, 13, 1, 6, 5, 11, 10, 4, 4, 10, 14, 15, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 15, 13, 7, 5, 3, 4, 4, 4, 4, 5, 11, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 13, 12, 12, 7, 4, 4, 4, 4, 5, 12, 15, 14, 11, 11, 15, 15, 15, 12, 13, 15, 15, 15, 15, 15, 15, 15, 15, 11, 4, 8, 0, 12, 12, 1, 6, 1, 8, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 14, 14, 14, 14, 14, 7, 6, 2, 7, 7, 5, 7, 13, 14, 15, 15, 15, 15, 15, 14, 14, 14, 15, 14, 14, 12, 8, 9, 7, 4, 8, 12, 13, 12, 7, 8, 14, 15, 15, 15, 15, 11, 0, 13, 15, 15, 15, 15, 11, 12, 14, 0, 14, 13, 13, 15, 10, 6, 7, 14, 14, 14, 12, 0, 11, 14, 15, 15, 15, 15, 15, 12, 13, 15, 15, 15, 15, 14, 6, 6, 7, 13, 15, 15, 13, 7, 4, 7, 14, 15, 15, 15, 15, 14, 13, 12, 13, 15, 15, 14, 9, 6, 2, 12, 14, 13, 8, 4, 5, 13, 15, 15, 15, 15, 15, 15, 11, 0, 7, 0, 14, 15, 15, 14, 12, 15, 11, 10, 15, 15, 15, 13, 5, 7, 8, 14, 14, 14, 14, 14, 14, 13, 14, 15, 15, 15, 15, 11, 0, 12, 14, 15, 15, 15, 14, 9, 6, 7, 14, 15, 15, 15, 14, 10, 6, 2, 12, 15, 15, 15, 11, 0, 9, 14, 15, 15, 14, 14, 14, 12, 5, 10, 10, 13, 14, 12, 14, 14, 15, 15, 15, 9, 5, 11, 12, 0, 13, 15, 15, 15, 14, 2, 12, 15, 15, 15, 12, 4, 8, 7, 3, 8, 14, 15, 15, 14, 0, 13, 15, 15, 15, 15, 8, 9, 9, 4, 8, 14, 15, 15, 14, 0, 13, 15, 15, 15, 15, 15, 14, 8, 7, 0, 11, 14, 14, 14, 15, 15, 15, 14, 14, 15, 15, 13, 10, 12, 10, 6, 4, 0, 12, 15, 15, 15, 15, 14, 8, 13, 12, 6, 0, 13, 15, 15, 15, 15, 12, 0, 13, 15, 15, 15, 11, 3, 6, 1, 13, 14, 15, 15, 15, 14, 0, 14, 15, 14, 12, 10, 4, 12, 9, 0, 13, 15, 15, 15, 15, 14, 15, 15, 11, 12, 14, 12, 2, 6, 0, 12, 14, 14, 15, 15, 15, 15, 15, 14, 15, 15, 11, 1, 6, 0, 10, 8, 10, 11, 14, 15, 15, 15, 14, 9, 3, 9, 0, 10, 15, 15, 15, 15, 12, 4, 6, 13, 15, 15, 15, 11, 3, 4, 5, 4, 12, 15, 15, 15, 13, 5, 4, 5, 6, 14, 15, 15, 14, 0, 12, 15, 15, 15, 15, 15, 15, 15, 13, 0, 7, 11, 9, 7, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 13, 2, 6, 9, 12, 5, 9, 6, 14, 15, 15, 15, 15, 14, 9, 0, 7, 0, 12, 15, 15, 15, 15, 13, 4, 6, 10, 15, 15, 15, 13, 11, 2, 6, 4, 13, 15, 15, 15, 14, 11, 9, 1, 4, 11, 15, 15, 15, 12, 13, 13, 14, 15, 15, 15, 15, 15, 13, 4, 6, 3, 6, 13, 14, 15, 15, 14, 14, 14, 14, 15, 15, 15, 15, 15, 12, 0, 6, 0, 8, 9, 14, 14, 15, 15, 15, 15, 15, 14, 5, 5, 6, 4, 14, 15, 15, 15, 14, 9, 7, 0, 13, 15, 15, 15, 14, 11, 0, 7, 2, 13, 15, 15, 15, 13, 13, 7, 6, 0, 10, 15, 15, 13, 14, 15, 14, 14, 15, 15, 15, 15, 13, 0, 8, 8, 0, 11, 15, 15, 15, 15, 14, 14, 14, 13, 14, 15, 15, 15, 14, 8, 6, 0, 6, 0, 13, 15, 15, 15, 15, 15, 15, 11, 2, 6, 1, 8, 14, 15, 15, 15, 15, 11, 6, 1, 12, 15, 15, 15, 15, 14, 0, 8, 0, 12, 15, 15, 15, 15, 15, 11, 0, 7, 0, 13, 15, 14, 15, 15, 14, 4, 13, 15, 15, 15, 13, 4, 6, 0, 5, 6, 14, 15, 15, 15, 12, 14, 15, 13, 11, 14, 15, 15, 14, 10, 0, 8, 8, 0, 10, 15, 15, 15, 15, 15, 15, 14, 10, 4, 7, 9, 0, 10, 14, 15, 15, 15, 14, 6, 5, 10, 14, 15, 14, 14, 15, 10, 4, 5, 0, 11, 15, 15, 15, 15, 15, 9, 7, 0, 10, 15, 15, 14, 15, 15, 14, 6, 8, 14, 15, 15, 13, 0, 13, 14, 7, 8, 12, 15, 15, 15, 14, 14, 15, 14, 7, 7, 14, 15, 15, 11, 0, 10, 10, 0, 12, 15, 15, 15, 15, 15, 15, 14, 14, 13, 0, 8, 4, 8, 0, 13, 15, 15, 15, 15, 10, 13, 11, 8, 15, 14, 14, 14, 9, 5, 9, 10, 1, 13, 15, 15, 15, 15, 11, 4, 5, 13, 15, 15, 15, 15, 15, 11, 0, 11, 14, 14, 14, 14, 15, 15, 13, 1, 9, 14, 15, 15, 15, 15, 15, 15, 12, 0, 11, 13, 12, 11, 12, 14, 15, 14, 0, 12, 15, 15, 15, 15, 15, 15, 15, 13, 10, 10, 4, 5, 7, 13, 15, 15, 14, 12, 15, 15, 14, 9, 11, 11, 14, 15, 14, 14, 12, 0, 12, 15, 14, 8, 12, 15, 15, 15, 15, 11, 3, 6, 5, 14, 15, 15, 15, 15, 12, 0, 8, 14, 15, 15, 15, 15, 15, 13, 7, 5, 9, 14, 15, 15, 15, 15, 14, 9, 7, 5, 14, 15, 15, 15, 15, 15, 11, 0, 12, 15, 15, 15, 15, 14, 12, 0, 7, 0, 13, 15, 15, 11, 8, 14, 12, 10, 12, 13, 15, 15, 15, 15, 14, 11, 0, 8, 10, 14, 15, 15, 11, 5, 5, 7, 14, 15, 15, 15, 15, 15, 11, 2, 6, 0, 13, 15, 15, 15, 15, 13, 3, 4, 12, 14, 14, 15, 15, 15, 13, 6, 6, 7, 14, 15, 15, 15, 15, 14, 4, 8, 3, 14, 15, 15, 15, 15, 13, 6, 4, 11, 15, 15, 15, 15, 15, 13, 0, 8, 0, 13, 15, 15, 15, 15, 12, 0, 7, 0, 7, 14, 15, 15, 15, 15, 15, 11, 5, 4, 6, 12, 15, 15, 15, 14, 8, 5, 9, 13, 15, 15, 15, 15, 15, 13, 3, 7, 0, 7, 12, 15, 15, 15, 15, 11, 0, 12, 13, 12, 15, 15, 15, 15, 12, 0, 7, 0, 10, 14, 15, 15, 15, 14, 5, 8, 11, 10, 12, 15, 15, 15, 14, 6, 6, 12, 14, 15, 15, 15, 15, 15, 13, 4, 6, 2, 6, 13, 15, 15, 15, 15, 11, 1, 6, 0, 7, 14, 15, 15, 15, 14, 13, 14, 9, 6, 0, 13, 15, 15, 15, 14, 6, 6, 0, 10, 15, 15, 15, 15, 15, 13, 5, 6, 4, 2, 13, 15, 15, 15, 14, 10, 0, 9, 6, 10, 15, 15, 15, 15, 13, 6, 7, 0, 8, 14, 15, 15, 15, 15, 11, 0, 10, 11, 3, 13, 15, 15, 15, 14, 5, 6, 13, 14, 14, 15, 15, 15, 14, 4, 7, 0, 9, 13, 14, 15, 15, 15, 15, 14, 9, 6, 7, 10, 0, 12, 15, 15, 15, 15, 15, 11, 4, 6, 2, 13, 15, 15, 15, 14, 9, 5, 4, 8, 14, 15, 15, 15, 15, 14, 10, 4, 5, 2, 12, 15, 15, 15, 15, 14, 0, 7, 0, 10, 13, 15, 15, 15, 14, 8, 5, 4, 5, 13, 15, 15, 15, 15, 14, 3, 6, 7, 12, 14, 15, 15, 15, 14, 6, 6, 3, 7, 14, 15, 15, 15, 15, 14, 10, 1, 5, 0, 10, 15, 15, 15, 14, 14, 14, 13, 14, 14, 8, 7, 12, 11, 0, 12, 15, 15, 15, 15, 14, 14, 13, 8, 6, 6, 14, 15, 15, 14, 9, 0, 12, 14, 14, 15, 15, 15, 15, 14, 5, 7, 4, 2, 10, 15, 15, 15, 15, 15, 12, 7, 13, 14, 7, 13, 15, 15, 12, 4, 5, 4, 4, 11, 14, 15, 15, 15, 14, 14, 12, 2, 5, 10, 15, 15, 15, 12, 5, 6, 2, 9, 14, 15, 15, 15, 15, 15, 14, 12, 4, 7, 0, 10, 15, 15, 15, 15, 15, 14, 12, 13, 14, 14, 15, 15, 11, 5, 6, 6, 1, 12, 15, 15, 15, 15, 15, 15, 15, 11, 7, 4, 13, 15, 15, 15, 14, 8, 11, 10, 1, 11, 15, 15, 15, 15, 15, 13, 9, 6, 7, 3, 12, 15, 15, 15, 15, 15, 13, 8, 6, 9, 14, 15, 15, 15, 14, 12, 8, 7, 8, 14, 15, 15, 15, 15, 15, 14, 11, 7, 8, 12, 14, 15, 15, 15, 14, 10, 7, 8, 13, 15, 15, 15, 15, 15, 14, 9, 8, 7, 9, 13, 15, 15, 15, 15, 15, 12, 8, 7, 11, 14, 15, 15, 15, 15, 11, 8, 8, 8, 7, 14, 15, 15, 15, 15, 14, 13, 8, 8, 8, 10, 14, 15, 15, 15, 11, 8, 8, 8, 9, 14, 15, 15, 15, 15, 12, 7, 9, 8, 10, 14, 15, 15, 15, 15, 12, 7, 9, 7, 11, 14, 15, 15, 15, 15, 13, 8, 10, 7, 12, 15, 15, 15, 15, 14, 11, 8, 9, 8, 13, 15, 15, 15, 15, 15, 12, 8, 9, 9, 13, 15, 14, 15, 15, 15, 13, 10, 9, 10, 11, 13, 14, 15, 15, 15, 14, 12, 12, 9, 9, 9, 12, 14, 15, 15, 14, 14, 15, 14, 11, 9, 10, 13, 14, 15, 15, 15, 15, 14, 14, 11, 13, 14, 10, 10, 14, 15, 14, 13, 9, 9, 12, 15, 15, 15, 15, 15, 15, 14, 10, 10, 10, 10, 9, 13, 15, 14, 11, 11, 13, 13, 13, 11, 14, 15, 15, 15, 14, 13, 13, 10, 10, 9, 12, 14, 14, 14, 14, 15, 14, 14, 14, 14, 15, 15, 13, 13, 14, 13, 11, 10, 12, 14, 15, 15, 15, 15, 14, 13, 12, 12, 14, 15, 15, 14, 13, 13, 12, 10, 10, 13, 14, 14, 14, 14, 14, 14, 13, 10, 11, 14, 15, 14, 15, 14, 14, 13, 11, 10, 11, 10, 12, 14, 14, 15, 14, 15, 14, 14, 13, 12, 12, 11, 11, 14, 15, 14, 12, 11, 11, 12, 14, 14, 14, 14, 14, 14, 14, 14, 12, 11, 11, 11, 11, 13, 14, 13, 14, 14, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12, 11, 11, 11, 11, 12, 14, 14, 14, 14, 14, 14, 14, 14, 13, 12, 13, 14, 13, 12, 13, 14, 14, 14, 12, 12, 14, 14, 14, 14, 14, 14, 14, 12, 11, 11, 12, 13, 14, 14, 14, 14, 13, 12, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 11, 11, 13, 14, 14, 14, 14, 14, 13, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 12, 11, 12, 11, 13, 14, 14, 14, 14, 13, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 12, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 12, 12, 12, 12, 13, 14, 14, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 12, 12, 14, 14, 14, 14, 14, 14, 13, 12, 12, 12, 12, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 12, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 12, 12, 13, 13, 12, 13, 14, 14, 14, 14, 14, 14, 13, 12, 12, 13, 14, 14, 14, 14, 14, 13, 12, 12, 12, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 12, 12, 12, 12, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 12, 13, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 14, 14, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 14, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 13, 14, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 14, 13, 13, 13, 14, 13, 13, 13, 14, 14, 13, 14, 13, 13, 14, 14, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 10};
const int s4Length = 2869;
//const char* samplePointers[] = {s0, s1, s2, s3, s4};
//int sampleLength[] = {931,1780,463,8011,2869};
 
//Timer
const char* sampleOffset;
int sampleCounter = 0;
int sampleLength = 0;
int timerTicks = 0;

ISR(TIMER1_COMPA_vect)
{
  if (sampleCounter < sampleLength) //send current sample
  {
    send_data(0x0A, pgm_read_byte_near(sampleOffset + sampleCounter++));
    if ((sampleLength - sampleCounter) == 1) CLR(__RGBLEDPORT__,__BLED__);
  }
  
  timerTicks++;
  if (timerTicks == 220 && false) //arpeggio on chan B
  {
    timerTicks = 0;
    
    if (noteB > 0)
    {
        periodB = tp[noteB + arpeggio[arpeggioCounter]];
        byte LSB = ( periodB & 0x00FF);
        byte MSB = ((periodB >> 8) & 0x000F);
        send_data(0x02, LSB);
        send_data(0x03, MSB);
        
        arpeggioCounter++;
        if (arpeggioCounter == arpeggioLength) arpeggioCounter = 0;
    }
  }
}

void setup(){
  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);
   //u8x8.setFont(u8x8_font_chroma48medium8_r);
   u8x8.drawString(0,2,"YM2149F");
   //u8x8.drawString(4,4,"MIDI");
   u8x8.drawString(3,6,"Synth");
  //init pins
  pinMode(ad0, OUTPUT);
  pinMode(ad1, OUTPUT);
  pinMode(ad2, OUTPUT);
  pinMode(ad3, OUTPUT);
  pinMode(ad4, OUTPUT);
  pinMode(ad5, OUTPUT);
  pinMode(ad6, OUTPUT);
  pinMode(ad7, OUTPUT);
  pinMode(pinBC1, OUTPUT);
  pinMode(pinBDIR, OUTPUT);
  pinMode(pinYMReset, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  __RGBLEDDDR__ |= ( 1 << __RLED__ | 1 << __GLED__ | 1 << __BLED__); //led pins as output
  
  resetYM();
  
  AmaxVolume = defaultLevel;
  BmaxVolume = defaultLevel;
  CmaxVolume = defaultLevel;
  
  //serial init
  Serial.begin(31250);
  
  //timer1 : sample player
  cli();
  TCCR1A = 0; //timer reset
  TCCR1B = 0; //timer reset
  OCR1A = 1450; //period for 11025 kHz at 16Mhz
  TCCR1B |= (1 << WGM12); //CTC mode
  TCCR1B |= (1 << CS10); // timer ticks = clock ticks
  TIMSK1 |= (1 << OCIE1A); // enable compare
  sei();
  
  //say hello
  //This is the bleep played on power on.
      ////note/velo/channel
  playNote(60, 127, 4);
  delay(40);
  playNote(64, 127, 4);
  delay(40);
  playNote(67, 127, 4);
  delay(40);
  playNote(72, 127, 4);
  delay(40);
   playNote(73, 127, 4);
  delay(40);
   playNote(74, 127, 4);
  delay(40);
   playNote(75, 127, 4);
  delay(40);
   playNote(76, 127, 4);
  delay(40);
   playNote(77, 127, 4);
  delay(40);
   playNote(79, 127, 4);
  delay(40);
   playNote(80, 127, 4);
  delay(40);
stopNote(80, 4);
  playDigidrum(60, 127);//Go Sample
  delay(2000);
   u8x8.clearDisplay();
}//END OF SETUP

// Main Loop
void loop() {
  
  byte command = getSerialByte();
  byte commandMSB  = command & 0xF0;
  byte midiChannel = command & 0x0F;
  
  if (commandMSB == 0x80) //Note off
  {
    byte note = getSerialByte();
    getSerialByte(); //discard 3rd byte
    stopNote(note, midiChannel);
  }
  else if (commandMSB == 0x90) //Note on
  {
    byte note = getSerialByte();
    byte velo = getSerialByte();
    
    if (velo != 0 && midiChannel == 0x09)
      playDigidrum(note, velo);
    else if (velo != 0)
      playNote(note, velo, midiChannel);
    else if (velo == 0)
      stopNote(note, midiChannel);
  }
  else if (commandMSB == 0xA0) // Key pressure
  {
    getSerialByte();
    getSerialByte();
  }
  else if (commandMSB == 0xB0) // Control change
  {
    byte controller = getSerialByte();
    byte value = getSerialByte();
    
    if (controller == 0x01) setDetune(value);
    if (controller == 0x07) setChannelVolume(value, midiChannel);
  }
  else if (commandMSB == 0xC0) // Program change
  {
    byte program = getSerialByte();
  }
  else if (commandMSB == 0xD0) // Channel pressure
  {
    byte pressure = getSerialByte();
  }
  else if (commandMSB == 0xE0) // Pitch bend
  {
    byte pitchBendLSB = getSerialByte();
    byte pitchBendMSB = getSerialByte();
  }
}

void setDetune(byte value)
{
  detuneValue = (value >> 3) & 0x0F; //downscaling to 4 bits
}

void setChannelVolume(byte value, byte chan)
{
  value = (value >> 3) & 0x0F; //downscaling to 4 bits
  
  if (chan == 0)
  {
    AmaxVolume = value;
    send_data(0x08, value);
  }  
  else if (chan == 1)
  {
    BmaxVolume = value;
    send_data(0x09, value);
  }
  else if (chan == 2)
  {
    CmaxVolume = value;
    send_data(0x0A, value);
  } 
}

void playNote(byte note, byte velo, byte chan)
{
  if (note < 24) return;
  
  if (chan == 0)//MIDI Channel 1
  {
    SET(__RGBLEDPORT__,__RLED__);
    noteA = note;
    periodA = tp[note];
    byte LSB = ( periodA & 0x00FF);
    byte MSB = ((periodA & 0x0F00) >> 8);
    cli();
    send_data(0x00, LSB);
    send_data(0x01, MSB);
    send_data(0x08, AmaxVolume); //can be set to 0 by envelope mode note off
    sei();
    u8x8.setFont(u8x8_font_chroma48medium8_r);
   u8x8.drawString(0,0,"MIDI 1 N-A ");
     u8x8.setCursor(13,0);
     u8x8.print(noteA);
     
  }
  else if (chan == 1)//MIDI Channel 2
  {
    SET(__RGBLEDPORT__,__GLED__);
    noteB = note;
    periodB = tp[note];
    byte LSB = ( periodB & 0x00FF);
    byte MSB = ((periodB >> 8) & 0x000F);
    cli();
    arpeggioCounter = 0; //arpeggio reset
    send_data(0x02, LSB);
    send_data(0x03, MSB);
    sei();
        u8x8.setFont(u8x8_font_chroma48medium8_r);
   u8x8.drawString(0,1,"MIDI 2 N-B ");
     u8x8.setCursor(13,1);
     u8x8.print(noteB);
  }
  else if (chan == 2)//MIDI Channel 3
  {
    SET(__RGBLEDPORT__,__BLED__);
    noteC = note;
    periodC = tp[note];
    byte LSB = ( periodC & 0x00FF);
    byte MSB = ((periodC >> 8) & 0x000F);
    cli();
    send_data(0x04, LSB);
    send_data(0x05, MSB);
    sei();
            u8x8.setFont(u8x8_font_chroma48medium8_r);
   u8x8.drawString(0,2,"MIDI 3 N-C ");
     u8x8.setCursor(13,2);
     u8x8.print(noteC);
  }
 else if (chan == 3)//MIDI Channel 4
  {
    if(mm3==0){
    SET(__RGBLEDPORT__,__RLED__);
    SET(__RGBLEDPORT__,__GLED__);
    noteA = note;
    noteB = note;
    periodA = tp[note];
    periodB = tp[note] + detuneValue;
    
    byte ALSB = ( periodA & 0x00FF);
    byte AMSB = ((periodA >> 8) & 0x000F); 
    byte BLSB = ( periodB & 0x00FF);
    byte BMSB = ((periodB >> 8) & 0x000F); 
    cli();
    send_data(0x00, ALSB);
    send_data(0x01, AMSB);
    send_data(0x02, BLSB);
    send_data(0x03, BMSB);
    sei();
                u8x8.setFont(u8x8_font_chroma48medium8_r);
                u8x8.clearLine(3);
   u8x8.drawString(0,3,"MIDI 4 N-AB ");
     u8x8.setCursor(13,3);
     u8x8.print(noteA);
     u8x8.clearLine(7);
      u8x8.setCursor(8,7);
     u8x8.print(analogRead(A0));
    }
     
  }
 else if (chan == 4)//MIDI Channel 5
  {
    SET(__RGBLEDPORT__,__RLED__);
    SET(__RGBLEDPORT__,__GLED__);
    SET(__RGBLEDPORT__,__BLED__);
    
    noteA = note;
    noteB = note;
    noteC = note;
    
    periodA = tp[note - 12];    
    periodB = tp[note] + detuneValue;
    periodC = tp[note] - detuneValue;
    
    byte ALSB = ( periodA & 0x00FF);
    byte AMSB = ((periodA >> 8) & 0x000F);
    byte BLSB = ( periodB & 0x00FF);
    byte BMSB = ((periodB >> 8) & 0x000F);
    byte CLSB = ( periodC & 0x00FF);
    byte CMSB = ((periodC >> 8) & 0x000F);    
    
    cli();
    send_data(0x00, ALSB);
    send_data(0x01, AMSB);
    send_data(0x02, BLSB);
    send_data(0x03, BMSB);
    send_data(0x04, CLSB);
    send_data(0x05, CMSB);
    sei();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clearLine(4);
u8x8.drawString(0,4,"MIDI 5 N-ABC ");
u8x8.setCursor(13,4);
u8x8.print(noteA);
  }
 else if (chan == 5)//MIDI Channel 6
  {
    SET(__RGBLEDPORT__,__RLED__);
    
    noteA = note;
    periodA = envTp[note];
    
    byte LSB = ( periodA & 0x00FF);
    byte MSB = ((periodA >> 8) & 0x000F);
    cli();
    send_data(0x08, 0x10);
    send_data(0x0B, LSB);
    send_data(0x0C, MSB);
    send_data(0x0D, 0b00001000);
    sei();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clearLine(5);
u8x8.drawString(0,5,"MIDI 6 N-A ");
u8x8.setCursor(13,5);
u8x8.print(noteA);
  }
 else if (chan == 6)//MIDI Channel 7
  {
    SET(__RGBLEDPORT__,__RLED__);
    
    noteA = note;
    periodA = envTp[note];
    
    byte LSB = ( periodA & 0x00FF);
    byte MSB = ((periodA >> 8) & 0x000F);
    cli();
    send_data(0x0B, LSB);
    send_data(0x0C, MSB);
    send_data(0x0D, 0b00001000);
    sei();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clearLine(6);
u8x8.drawString(0,6,"MIDI 7 N-A ");
u8x8.setCursor(13,6);
u8x8.print(noteA);
  }
  else if (chan == 7)//MIDI Channel 8
  {
    SET(__RGBLEDPORT__,__RLED__);
    SET(__RGBLEDPORT__,__GLED__);
    
    noteA = note;
    noteB = note;
    periodA = envTp[note];
    periodB = (tp[note - 12] + detuneValue) << 1;
    
    byte LSB = ( periodA & 0x00FF);
    byte MSB = ((periodA >> 8) & 0x000F);
    byte BLSB = ( periodB & 0x00FF);
    byte BMSB = ((periodB >> 8) & 0x000F);  
    cli();
    send_data(0x02, BLSB);
    send_data(0x03, BMSB);
    send_data(0x08, 0x10); //envelope mode on
    send_data(0x0B, LSB);
    send_data(0x0C, MSB);
    send_data(0x0D, 0b00001100);
    sei();
    u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clearLine(7);
u8x8.drawString(0,7,"MIDI 8 N-AB ");
u8x8.setCursor(13,7);
u8x8.print(noteA);
  }
}

void stopNote(byte note, byte chan)
{
  if (chan == 0 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    
    noteA = periodA = 0;
    cli();
    send_data(0x00, 0);
    send_data(0x01, 0);  
    sei();
  }
  else if (chan == 1 && note == noteB)
  {
    CLR(__RGBLEDPORT__,__GLED__);
    
    noteB = periodB = 0;
    cli();
    send_data(0x02, 0);
    send_data(0x03, 0);
    sei();
  }
  else if (chan == 2 && note == noteC)
  {
    CLR(__RGBLEDPORT__,__BLED__);
    
    noteC = periodC = 0;
    cli();
    send_data(0x04, 0);
    send_data(0x05, 0);
    sei();
  }
 else if (chan == 3 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    CLR(__RGBLEDPORT__,__GLED__);
    
    noteA = periodA = 0;
    noteA = periodB = 0;
    cli();
    send_data(0x00, 0);
    send_data(0x01, 0);
    send_data(0x02, 0);
    send_data(0x03, 0);
    sei();
  }
 else if (chan == 4 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    CLR(__RGBLEDPORT__,__GLED__);
    CLR(__RGBLEDPORT__,__BLED__);
    
    noteA = periodA = 0;
    noteB = periodB = 0;
    noteC = periodC = 0;
    cli();
    send_data(0x00, 0);
    send_data(0x01, 0);
    send_data(0x02, 0);
    send_data(0x03, 0);
    send_data(0x04, 0);
    send_data(0x05, 0);
    sei();
  }
 else if (chan == 5 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    
    noteA = periodA = 0;
    cli();
    send_data(0x0D, 0);
    send_data(0x08, AmaxVolume);
    sei();
  }
 else if (chan == 6 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    
    noteA = periodA = 0;
    cli();
    send_data(0x0D, 0);
    send_data(0x08, AmaxVolume);
    sei();
  }
 else if (chan == 7 && note == noteA)
  {
    CLR(__RGBLEDPORT__,__RLED__);
    CLR(__RGBLEDPORT__,__GLED__);
    
    noteA = periodA = 0;
    noteB = periodB = 0;
    cli();
    send_data(0x02, 0);
    send_data(0x03, 0);
    send_data(0x0D, 0);
    send_data(0x08, AmaxVolume);
    sei();
  }
}

void playDigidrum(byte index, byte velo)
{
  if (index == 48)
  {
    cli();
    SET(__RGBLEDPORT__,__BLED__);
    sampleOffset = s0;
    sampleLength = s0Length;
    sampleCounter = 0;
    sei();
  }
  else if (index == 49)
  {
    cli();
    SET(__RGBLEDPORT__,__BLED__);
    sampleOffset = s1;
    sampleLength = s1Length;
    sampleCounter = 0;
    sei();
  }
  else if (index == 50)
  {
    cli();
    SET(__RGBLEDPORT__,__BLED__);
    sampleOffset = s2;
    sampleLength = s2Length;
    sampleCounter = 0;
    sei();
  }
  else if (index == 51)
  {
    cli();
    SET(__RGBLEDPORT__,__BLED__);
    sampleOffset = s3;
    sampleLength = s3Length;
    sampleCounter = 0;
    sei();
  }
  else if (index == 60)
  {
    cli();
    SET(__RGBLEDPORT__,__BLED__);
    sampleOffset = s4;
    sampleLength = s4Length;
    sampleCounter = 0;
    sei();
  }
}

void resetYM()
{
    digitalWrite(pinYMReset, LOW);
    digitalWrite(pinYMReset, HIGH);
    delay(1);
    send_data(0x07, 0b00111000);
    for (byte i=0; i <= defaultLevel; i++)
    {
      send_data(0x08, i);
      send_data(0x09, i);
      send_data(0x0A, i);
      delay(1);
    }
}

void send_data(unsigned char address, unsigned char data)
{
  SET(__LEDPORT__,__LED__);
  boolean value[8];
  
  //put address in a 8-bit array
  for (int i; i < 8; i++)
  {
    value[i] = ((0x01 & address) == 1);
    address = address >> 1;
  }
  //write address to pins
  outputToYM(value);
  //validate addess
  __BCPORT__ |=   (1 << __BDIR__) | (1 << __BC1__);
  delayMicroseconds(1);
  __BCPORT__ &= ~((1 << __BDIR__) | (1 << __BC1__));

  //put data in a 8-bit array
  for (int i; i < 8; i++)
  {
    value[i] = ((0x01 & data) == 1);
    data = data >> 1;
  }
  //write data to pins
  outputToYM(value);
  //validate data
  SET(__BCPORT__,__BDIR__);
  delayMicroseconds(1);
  CLR(__BCPORT__,__BDIR__);
  CLR(__LEDPORT__,__LED__);
}

void outputToYM(boolean value[])
{
  value[0] ? SET(PORTB, 0) : CLR(PORTB, 0);
  value[1] ? SET(PORTB, 1) : CLR(PORTB, 1);
  value[2] ? SET(PORTD, 2) : CLR(PORTD, 2);
  value[3] ? SET(PORTD, 3) : CLR(PORTD, 3);
  value[4] ? SET(PORTD, 4) : CLR(PORTD, 4);
  value[5] ? SET(PORTD, 5) : CLR(PORTD, 5);
  value[6] ? SET(PORTD, 6) : CLR(PORTD, 6);
  value[7] ? SET(PORTD, 7) : CLR(PORTD, 7);
}

byte getSerialByte()
{
  while(Serial.available() < 1) __asm__("nop\n\t");
  return Serial.read();
}