+static uint16_t linebuf[128];
+
+static uint16_t russian_chars[64] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', // 0x
+ '8', '9', '+', '-', '/', ',', '.', ' ', // 1x
+ 0x2169, '^', '(', ')', 0x00d7, '=', ';', '[', // 2x
+ ']', '*', '`', '\'', 0x2260, '<', '>', ':', // 3x
+ 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, // 4x
+ 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f, // 5x
+ 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, // 6x
+ 0x428, 0x429, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, 0x2013 // 7x
+};
+
+static uint16_t latin_chars[64] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', // 0x
+ '8', '9', '+', '-', '/', ',', '.', ' ', // 1x
+ 0x2169, '^', '(', ')', 0x00d7, '=', ';', '[', // 2x
+ ']', '*', '`', '\'', 0x2260, '<', '>', ':', // 3x
+ 'A', 'B', 'W', 'G', 'D', 'E', 'V', 'Z', // 4x
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 5x
+ 'R', 'S', 'T', 'U', 'F', 'H', 'C', ' ', // 6x
+ ' ', ' ', 'Y', 'X', ' ', ' ', 'Q', 0x2013 // 7x
+};
+
+static void print_line(int r)
+{
+ /*
+ * Meaning of bits of r:
+ * 0 = perform line feed
+ * 1 = clear buffer
+ * 2 = actually print
+ */
+ if (r & 4)
+ {
+ for (int i=0; i<128; i++)
+ {
+ int ch = linebuf[i];
+ if (!ch)
+ ch = ' ';
+ if (ch < 0x80)
+ putchar(ch);
+ else if (ch < 0x800)
+ {
+ putchar(0xc0 | (ch >> 6));
+ putchar(0x80 | (ch & 0x3f));
+ }
+ else
+ {
+ putchar(0xe0 | (ch >> 12));
+ putchar(0x80 | ((ch >> 6) & 0x3f));
+ putchar(0x80 | (ch & 0x3f));
+ }
+ }
+ }
+ if (r & 2)
+ memset(linebuf, 0, sizeof(linebuf));
+ if (r & 1)
+ putchar('\n');
+ else
+ putchar('\r');
+ fflush(stdout);
+}
+