Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save z5ottu/93217e2e4674c950fd1e3df7529bf264 to your computer and use it in GitHub Desktop.
Save z5ottu/93217e2e4674c950fd1e3df7529bf264 to your computer and use it in GitHub Desktop.
Arduino YM2149 MIDI Synth
// Arduino YM2149 MIDI Synth
// by yukimizake
// video: https://youtu.be/hUPs2pv5d_g
// schematics: http://electronicfields.wordpress.com/?attachment_id=128 (Vcc/GND not shown)
// 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>
//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;
//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 prog_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 prog_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 prog_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 prog_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 prog_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;
//prog_char* samplePointers[] = {s0, s1, s2, s3, s4};
//int sampleLength[] = {931,1780,463,8011,2869};
//Timer
prog_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(){
//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
playNote(60, 127, 4);
delay(40);
playNote(64, 127, 4);
delay(40);
playNote(67, 127, 4);
delay(40);
playNote(72, 127, 4);
delay(40);
stopNote(72, 4);
}
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)
{
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();
}
else if (chan == 1)
{
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();
}
else if (chan == 2)
{
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();
}
else if (chan == 3)
{
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();
}
else if (chan == 4)
{
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();
}
else if (chan == 5)
{
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, 0b00001110);
sei();
}
else if (chan == 6)
{
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();
}
else if (chan == 7)
{
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, 0b00001000);
sei();
}
}
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 == 52)
{
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();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment